Fixed IV processing for CBC decryption with AES (x86ni implementation) when data length is not multiple of 64 bytes (the bug was breaking TLS 1.0 AES/CBC on recent x86 systems).
This commit is contained in:
parent
7f343eedfc
commit
eaa0d38fa8
2 changed files with 68 additions and 1 deletions
|
|
@ -78,14 +78,16 @@ br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx,
|
||||||
if (len >= 48) {
|
if (len >= 48) {
|
||||||
x2 = _mm_loadu_si128(
|
x2 = _mm_loadu_si128(
|
||||||
(void *)(buf + 32));
|
(void *)(buf + 32));
|
||||||
|
x3 = x2;
|
||||||
} else {
|
} else {
|
||||||
x2 = x0;
|
x2 = x0;
|
||||||
|
x3 = x1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x1 = x0;
|
x1 = x0;
|
||||||
x2 = x0;
|
x2 = x0;
|
||||||
|
x3 = x0;
|
||||||
}
|
}
|
||||||
x3 = x0;
|
|
||||||
}
|
}
|
||||||
e0 = x0;
|
e0 = x0;
|
||||||
e1 = x1;
|
e1 = x1;
|
||||||
|
|
|
||||||
|
|
@ -3133,6 +3133,71 @@ test_AES_generic(char *name,
|
||||||
check_equals("KAT CBC AES decrypt (2)",
|
check_equals("KAT CBC AES decrypt (2)",
|
||||||
buf, plain, data_len);
|
buf, plain, data_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We want to check proper IV management for CBC:
|
||||||
|
* encryption and decryption must properly copy the _last_
|
||||||
|
* encrypted block as new IV, for all sizes.
|
||||||
|
*/
|
||||||
|
for (u = 1; u <= 35; u ++) {
|
||||||
|
br_hmac_drbg_context rng;
|
||||||
|
unsigned char x;
|
||||||
|
size_t key_len, data_len;
|
||||||
|
size_t v;
|
||||||
|
|
||||||
|
br_hmac_drbg_init(&rng, &br_sha256_vtable,
|
||||||
|
"seed for AES/CBC", 16);
|
||||||
|
x = u;
|
||||||
|
br_hmac_drbg_update(&rng, &x, 1);
|
||||||
|
data_len = u << 4;
|
||||||
|
for (key_len = 16; key_len <= 32; key_len += 16) {
|
||||||
|
unsigned char key[32];
|
||||||
|
unsigned char iv[16], iv1[16], iv2[16];
|
||||||
|
unsigned char plain[35 * 16];
|
||||||
|
unsigned char tmp1[sizeof plain];
|
||||||
|
unsigned char tmp2[sizeof plain];
|
||||||
|
br_aes_gen_cbcenc_keys v_ec;
|
||||||
|
br_aes_gen_cbcdec_keys v_dc;
|
||||||
|
const br_block_cbcenc_class **ec;
|
||||||
|
const br_block_cbcdec_class **dc;
|
||||||
|
|
||||||
|
br_hmac_drbg_generate(&rng, key, key_len);
|
||||||
|
br_hmac_drbg_generate(&rng, iv, sizeof iv);
|
||||||
|
br_hmac_drbg_generate(&rng, plain, data_len);
|
||||||
|
|
||||||
|
ec = &v_ec.vtable;
|
||||||
|
ve->init(ec, key, key_len);
|
||||||
|
memcpy(iv1, iv, sizeof iv);
|
||||||
|
memcpy(tmp1, plain, data_len);
|
||||||
|
ve->run(ec, iv1, tmp1, data_len);
|
||||||
|
check_equals("IV CBC AES (1)",
|
||||||
|
tmp1 + data_len - 16, iv1, 16);
|
||||||
|
memcpy(iv2, iv, sizeof iv);
|
||||||
|
memcpy(tmp2, plain, data_len);
|
||||||
|
for (v = 0; v < data_len; v += 16) {
|
||||||
|
ve->run(ec, iv2, tmp2 + v, 16);
|
||||||
|
}
|
||||||
|
check_equals("IV CBC AES (2)",
|
||||||
|
tmp2 + data_len - 16, iv2, 16);
|
||||||
|
check_equals("IV CBC AES (3)",
|
||||||
|
tmp1, tmp2, data_len);
|
||||||
|
|
||||||
|
dc = &v_dc.vtable;
|
||||||
|
vd->init(dc, key, key_len);
|
||||||
|
memcpy(iv1, iv, sizeof iv);
|
||||||
|
vd->run(dc, iv1, tmp1, data_len);
|
||||||
|
check_equals("IV CBC AES (4)", iv1, iv2, 16);
|
||||||
|
check_equals("IV CBC AES (5)",
|
||||||
|
tmp1, plain, data_len);
|
||||||
|
memcpy(iv2, iv, sizeof iv);
|
||||||
|
for (v = 0; v < data_len; v += 16) {
|
||||||
|
vd->run(dc, iv2, tmp2 + v, 16);
|
||||||
|
}
|
||||||
|
check_equals("IV CBC AES (6)", iv1, iv2, 16);
|
||||||
|
check_equals("IV CBC AES (7)",
|
||||||
|
tmp2, plain, data_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vc != NULL) {
|
if (vc != NULL) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue