Skip to content

Commit 161a8fb

Browse files
committed
F-2375 - https://fenrir.wolfssl.com/finding/2375 - Fix AES-CBC-PAD single-shot C_Encrypt output length for block-aligned inputs
1 parent be7c9a4 commit 161a8fb

2 files changed

Lines changed: 83 additions & 5 deletions

File tree

src/crypto.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,9 +2272,9 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
22722272
if (!CK_ULONG_FITS_WORD32(ulDataLen))
22732273
return CKR_DATA_LEN_RANGE;
22742274

2275-
/* PKCS#5 pad makes the output a multiple of 16 */
2276-
encDataLen = (word32)((ulDataLen + AES_BLOCK_SIZE - 1) /
2277-
AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
2275+
/* PKCS#7 padding always adds at least 1 byte */
2276+
encDataLen = (word32)((ulDataLen / AES_BLOCK_SIZE) + 1) *
2277+
AES_BLOCK_SIZE;
22782278
if (pEncryptedData == NULL) {
22792279
*pulEncryptedDataLen = encDataLen;
22802280
return CKR_OK;

tests/pkcs11test.c

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10597,6 +10597,83 @@ static CK_RV test_aes_cbc_pad_len_test(void* args)
1059710597
return ret;
1059810598
}
1059910599

10600+
static CK_RV test_aes_cbc_pad_block_aligned_size(void* args)
10601+
{
10602+
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
10603+
CK_RV ret;
10604+
CK_OBJECT_HANDLE key;
10605+
CK_MECHANISM mech;
10606+
byte iv[16];
10607+
CK_ULONG ivSz = sizeof(iv);
10608+
CK_ULONG encSz;
10609+
CK_ULONG i;
10610+
/* Test block-aligned sizes: 0, 16, 32, 48 */
10611+
CK_ULONG sizes[] = { 0, 16, 32, 48 };
10612+
byte plain[48];
10613+
byte enc[48 + 16];
10614+
byte dec[48];
10615+
CK_ULONG decSz;
10616+
10617+
memset(plain, 9, sizeof(plain));
10618+
memset(iv, 9, sizeof(iv));
10619+
10620+
mech.mechanism = CKM_AES_CBC_PAD;
10621+
mech.ulParameterLen = ivSz;
10622+
mech.pParameter = iv;
10623+
10624+
ret = get_aes_128_key(session, NULL, 0, &key);
10625+
CHECK_CKR(ret, "Getting AES key");
10626+
10627+
for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]) && ret == CKR_OK; i++) {
10628+
CK_ULONG plainSz = sizes[i];
10629+
CK_ULONG expectedEncSz = plainSz + 16; /* PKCS#7 always adds padding */
10630+
10631+
/* Size query with pEncryptedData=NULL */
10632+
ret = funcList->C_EncryptInit(session, &mech, key);
10633+
CHECK_CKR(ret, "AES-CBC-PAD Encrypt Init for size query");
10634+
if (ret == CKR_OK) {
10635+
encSz = 0;
10636+
ret = funcList->C_Encrypt(session, plain, plainSz, NULL, &encSz);
10637+
CHECK_CKR(ret, "AES-CBC-PAD Encrypt size query");
10638+
}
10639+
if (ret == CKR_OK && encSz != expectedEncSz) {
10640+
ret = -1;
10641+
CHECK_CKR(ret, "AES-CBC-PAD size query must be plainSz+16");
10642+
}
10643+
10644+
/* Actual encrypt-then-decrypt roundtrip */
10645+
if (ret == CKR_OK) {
10646+
encSz = sizeof(enc);
10647+
ret = funcList->C_Encrypt(session, plain, plainSz, enc, &encSz);
10648+
CHECK_CKR(ret, "AES-CBC-PAD Encrypt");
10649+
}
10650+
if (ret == CKR_OK && encSz != expectedEncSz) {
10651+
ret = -1;
10652+
CHECK_CKR(ret, "AES-CBC-PAD encrypt output size must be plainSz+16");
10653+
}
10654+
if (ret == CKR_OK) {
10655+
ret = funcList->C_DecryptInit(session, &mech, key);
10656+
CHECK_CKR(ret, "AES-CBC-PAD Decrypt Init");
10657+
}
10658+
if (ret == CKR_OK) {
10659+
decSz = sizeof(dec);
10660+
ret = funcList->C_Decrypt(session, enc, encSz, dec, &decSz);
10661+
CHECK_CKR(ret, "AES-CBC-PAD Decrypt");
10662+
}
10663+
if (ret == CKR_OK && decSz != plainSz) {
10664+
ret = -1;
10665+
CHECK_CKR(ret, "AES-CBC-PAD roundtrip size mismatch");
10666+
}
10667+
if (ret == CKR_OK && plainSz > 0 &&
10668+
XMEMCMP(plain, dec, plainSz) != 0) {
10669+
ret = -1;
10670+
CHECK_CKR(ret, "AES-CBC-PAD roundtrip data mismatch");
10671+
}
10672+
}
10673+
10674+
return ret;
10675+
}
10676+
1060010677
static CK_RV test_aes_cbc_pad_encdec(CK_SESSION_HANDLE session,
1060110678
unsigned char* exp, CK_OBJECT_HANDLE key)
1060210679
{
@@ -10623,7 +10700,7 @@ static CK_RV test_aes_cbc_pad_encdec(CK_SESSION_HANDLE session,
1062310700
ret = funcList->C_Encrypt(session, plain, plainSz, NULL, &encSz);
1062410701
CHECK_CKR(ret, "AES-CBC Pad Encrypt no enc");
1062510702
}
10626-
if (ret == CKR_OK && encSz != plainSz) {
10703+
if (ret == CKR_OK && encSz != plainSz + 16) {
1062710704
ret = -1;
1062810705
CHECK_CKR(ret, "AES-CBC Pad Encrypt encrypted length");
1062910706
}
@@ -10652,7 +10729,7 @@ static CK_RV test_aes_cbc_pad_encdec(CK_SESSION_HANDLE session,
1065210729
ret = funcList->C_Decrypt(session, enc, encSz, NULL, &decSz);
1065310730
CHECK_CKR(ret, "AES-CBC Pad Decrypt");
1065410731
}
10655-
if (ret == CKR_OK && decSz != encSz-1) {
10732+
if (ret == CKR_OK && decSz != encSz - 1) {
1065610733
ret = -1;
1065710734
CHECK_CKR(ret, "AES-CBC Pad Decrypt decrypted length");
1065810735
}
@@ -16960,6 +17037,7 @@ static TEST_FUNC testFunc[] = {
1696017037
#ifndef NO_AES
1696117038
#ifdef HAVE_AES_CBC
1696217039
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_pad_len_test),
17040+
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_pad_block_aligned_size),
1696317041
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_fixed_key),
1696417042
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_fail),
1696517043
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_gen_key),

0 commit comments

Comments
 (0)