From c563f3932a3aa01ce8d779d038e9cbf90ffc0e41 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 27 Mar 2026 09:15:14 -0400 Subject: [PATCH] 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. --- wolfcrypt/src/pkcs7.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index c46885b168..1c38516631 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -13262,10 +13262,24 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, padLen = encryptedContent[encryptedContentSz-1]; /* copy plaintext to output */ - if (padLen > encryptedContentSz) { + if (padLen == 0 || padLen > expBlockSz || + padLen > encryptedContentSz) { ret = BUFFER_E; break; } + /* Constant-time check all padding bytes */ + { + byte padCheck = 0; + int pi; + for (pi = encryptedContentSz - padLen; + pi < encryptedContentSz; pi++) { + padCheck |= encryptedContent[pi] ^ padLen; + } + if (padCheck != 0) { + ret = BUFFER_E; + break; + } + } #ifdef ASN_BER_TO_DER if (pkcs7->streamOutCb) { @@ -15315,12 +15329,28 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, if (ret == 0) { padLen = encryptedContent[encryptedContentSz-1]; - if (padLen > encryptedContentSz) { + if (padLen == 0 || padLen > expBlockSz || + padLen > encryptedContentSz) { WOLFSSL_MSG("Bad padding size found"); ret = BUFFER_E; XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); break; } + /* Constant-time check all padding bytes */ + { + byte padCheck = 0; + int pi; + for (pi = encryptedContentSz - padLen; + pi < encryptedContentSz; pi++) { + padCheck |= encryptedContent[pi] ^ padLen; + } + if (padCheck != 0) { + WOLFSSL_MSG("Bad padding bytes found"); + ret = BUFFER_E; + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + break; + } + } /* copy plaintext to output */ if ((word32)(encryptedContentSz - padLen) > outputSz) {