mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-05-20 13:29:41 +00:00
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: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2275)
This commit is contained in:
parent
7c12c7b61c
commit
0b96d77a62
103
test/evp_test.c
103
test/evp_test.c
@ -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");
|
||||
} else {
|
||||
BIO_snprintf(aux_err, sizeof(aux_err), "%s output and %s input",
|
||||
BIO_snprintf(aux_err, sizeof(aux_err),
|
||||
"%s in-place, %sfragmented",
|
||||
out_misalign ? "misaligned" : "aligned",
|
||||
inp_misalign ? "misaligned" : "aligned");
|
||||
frag ? "" : "not ");
|
||||
} else {
|
||||
BIO_snprintf(aux_err, sizeof(aux_err),
|
||||
"%s output and %s input, %sfragmented",
|
||||
out_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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user