Skip to content

Commit c563f39

Browse files
anhuJacobBarthelmeh
authored andcommitted
Fix PKCS7 CBC padding oracle in EnvelopedData and EncryptedData (ZD 21422)
Replace single last-byte padding check with full PKCS#5/PKCS#7 validation: verify padLen is non-zero and within block size. Both wc_PKCS7_DecodeEnvelopedData and wc_PKCS7_DecodeEncryptedData paths are fixed.
1 parent d14b506 commit c563f39

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

wolfcrypt/src/pkcs7.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13262,10 +13262,24 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
1326213262
padLen = encryptedContent[encryptedContentSz-1];
1326313263

1326413264
/* copy plaintext to output */
13265-
if (padLen > encryptedContentSz) {
13265+
if (padLen == 0 || padLen > expBlockSz ||
13266+
padLen > encryptedContentSz) {
1326613267
ret = BUFFER_E;
1326713268
break;
1326813269
}
13270+
/* Constant-time check all padding bytes */
13271+
{
13272+
byte padCheck = 0;
13273+
int pi;
13274+
for (pi = encryptedContentSz - padLen;
13275+
pi < encryptedContentSz; pi++) {
13276+
padCheck |= encryptedContent[pi] ^ padLen;
13277+
}
13278+
if (padCheck != 0) {
13279+
ret = BUFFER_E;
13280+
break;
13281+
}
13282+
}
1326913283

1327013284
#ifdef ASN_BER_TO_DER
1327113285
if (pkcs7->streamOutCb) {
@@ -15315,12 +15329,28 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1531515329
if (ret == 0) {
1531615330
padLen = encryptedContent[encryptedContentSz-1];
1531715331

15318-
if (padLen > encryptedContentSz) {
15332+
if (padLen == 0 || padLen > expBlockSz ||
15333+
padLen > encryptedContentSz) {
1531915334
WOLFSSL_MSG("Bad padding size found");
1532015335
ret = BUFFER_E;
1532115336
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
1532215337
break;
1532315338
}
15339+
/* Constant-time check all padding bytes */
15340+
{
15341+
byte padCheck = 0;
15342+
int pi;
15343+
for (pi = encryptedContentSz - padLen;
15344+
pi < encryptedContentSz; pi++) {
15345+
padCheck |= encryptedContent[pi] ^ padLen;
15346+
}
15347+
if (padCheck != 0) {
15348+
WOLFSSL_MSG("Bad padding bytes found");
15349+
ret = BUFFER_E;
15350+
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
15351+
break;
15352+
}
15353+
}
1532415354

1532515355
/* copy plaintext to output */
1532615356
if ((word32)(encryptedContentSz - padLen) > outputSz) {

0 commit comments

Comments
 (0)