提交 0b96d77a 编写于 作者: M Matt Caswell

Update evp_test to make sure passing partial block to "Update" is ok

The previous commit fixed a bug where a partial block had been passed to
an "Update" function and it wasn't properly handled. We should catch this
type of error in evp_test.
Reviewed-by: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
上级 7c12c7b6
......@@ -880,12 +880,12 @@ static int cipher_test_parse(struct evp_test *t, const char *keyword,
}
static int cipher_test_enc(struct evp_test *t, int enc,
size_t out_misalign, size_t inp_misalign)
size_t out_misalign, size_t inp_misalign, int frag)
{
struct cipher_data *cdat = t->data;
unsigned char *in, *out, *tmp = NULL;
size_t in_len, out_len;
int tmplen, tmpflen;
size_t in_len, out_len, donelen = 0;
int tmplen, chunklen, tmpflen;
EVP_CIPHER_CTX *ctx = NULL;
const char *err;
err = "INTERNAL_ERROR";
......@@ -983,15 +983,62 @@ static int cipher_test_enc(struct evp_test *t, int enc,
}
}
if (cdat->aad) {
if (!EVP_CipherUpdate(ctx, NULL, &tmplen, cdat->aad, cdat->aad_len)) {
err = "AAD_SET_ERROR";
goto err;
err = "AAD_SET_ERROR";
if (!frag) {
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, cdat->aad,
cdat->aad_len))
goto err;
} else {
/*
* Supply the AAD in chunks less than the block size where possible
*/
if (cdat->aad_len > 0) {
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, cdat->aad, 1))
goto err;
donelen++;
}
if (cdat->aad_len > 2) {
if (!EVP_CipherUpdate(ctx, NULL, &chunklen, cdat->aad + donelen,
cdat->aad_len - 2))
goto err;
donelen += cdat->aad_len - 2;
}
if (cdat->aad_len > 1
&& !EVP_CipherUpdate(ctx, NULL, &chunklen,
cdat->aad + donelen, 1))
goto err;
}
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
err = "CIPHERUPDATE_ERROR";
if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &tmplen, in, in_len))
goto err;
tmplen = 0;
donelen = 0;
if (!frag) {
/* We supply the data all in one go */
if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &tmplen, in, in_len))
goto err;
} else {
/* Supply the data in chunks less than the block size where possible */
if (in_len > 0) {
if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &chunklen, in, 1))
goto err;
tmplen += chunklen;
donelen = 1;
}
if (in_len > 2) {
if (!EVP_CipherUpdate(ctx, tmp + out_misalign + tmplen, &chunklen,
in + donelen, in_len - 2))
goto err;
tmplen += chunklen;
donelen += in_len - 2;
}
if (in_len > 1 ) {
if (!EVP_CipherUpdate(ctx, tmp + out_misalign + tmplen, &chunklen,
in + donelen, 1))
goto err;
tmplen += chunklen;
}
}
if (cdat->aead == EVP_CIPH_CCM_MODE)
tmpflen = 0;
else {
......@@ -1032,7 +1079,7 @@ static int cipher_test_enc(struct evp_test *t, int enc,
static int cipher_test_run(struct evp_test *t)
{
struct cipher_data *cdat = t->data;
int rv;
int rv, frag = 0;
size_t out_misalign, inp_misalign;
if (!cdat->key) {
......@@ -1050,21 +1097,28 @@ static int cipher_test_run(struct evp_test *t)
t->err = "NO_TAG";
return 0;
}
for (out_misalign = 0; out_misalign <= 1; out_misalign++) {
for (out_misalign = 0; out_misalign <= 1;) {
static char aux_err[64];
t->aux_err = aux_err;
for (inp_misalign = (size_t)-1; inp_misalign != 2; inp_misalign++) {
if (frag && inp_misalign == (size_t)-1)
continue;
if (inp_misalign == (size_t)-1) {
/* kludge: inp_misalign == -1 means "exercise in-place" */
BIO_snprintf(aux_err, sizeof(aux_err), "%s in-place",
out_misalign ? "misaligned" : "aligned");
BIO_snprintf(aux_err, sizeof(aux_err),
"%s in-place, %sfragmented",
out_misalign ? "misaligned" : "aligned",
frag ? "" : "not ");
} else {
BIO_snprintf(aux_err, sizeof(aux_err), "%s output and %s input",
BIO_snprintf(aux_err, sizeof(aux_err),
"%s output and %s input, %sfragmented",
out_misalign ? "misaligned" : "aligned",
inp_misalign ? "misaligned" : "aligned");
inp_misalign ? "misaligned" : "aligned",
frag ? "" : "not ");
}
if (cdat->enc) {
rv = cipher_test_enc(t, 1, out_misalign, inp_misalign);
rv = cipher_test_enc(t, 1, out_misalign, inp_misalign, frag);
/* Not fatal errors: return */
if (rv != 1) {
if (rv < 0)
......@@ -1073,7 +1127,7 @@ static int cipher_test_run(struct evp_test *t)
}
}
if (cdat->enc != 1) {
rv = cipher_test_enc(t, 0, out_misalign, inp_misalign);
rv = cipher_test_enc(t, 0, out_misalign, inp_misalign, frag);
/* Not fatal errors: return */
if (rv != 1) {
if (rv < 0)
......@@ -1082,6 +1136,21 @@ static int cipher_test_run(struct evp_test *t)
}
}
}
if (out_misalign == 1 && frag == 0) {
/*
* XTS, CCM and Wrap modes have special requirements about input
* lengths so we don't fragment for those
*/
if (cdat->aead == EVP_CIPH_CCM_MODE
|| EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_XTS_MODE
|| EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE)
break;
out_misalign = 0;
frag++;
} else {
out_misalign++;
}
}
t->aux_err = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册