Fix PKCS12 PBKDF mp variant buffer size to include password block

The mp API variant of wc_PKCS12_PBKDF_ex builds a working buffer holding
D || S || P, but totalLen was computed as dLen + sLen and so left out the
password block entirely. The fill loop writes pLen bytes starting at
S + sLen, which is past the end of the buffer, and DoPKCS12Hash was called
with the short length so the password was never absorbed into the digest.
A build with this variant enabled therefore derived the same key for every
password over a given salt, and overflowed the heap allocation or the
static buffer by pLen bytes depending on the salt length.

Sum dLen with iLen instead, matching the non-mp variant. That corrects the
allocation size, the hash input length, the I update bound and the
ForceZero coverage in one place.

Fixes F-7306.
pull/11093/head
Tobias Frauenschläger 2026-08-05 17:25:42 +02:00
parent d4755b4b62
commit b1e01d6d64
2 changed files with 10 additions and 2 deletions

View File

@ -340,5 +340,9 @@
{"name": "cryptonly-no-asn-rsa", "minutes": 0.2, "check": false,
"comment": "RSA with ASN.1 disabled. Build only, since wolfcrypt test and benchmark do not support this combination.",
"configure": ["--enable-cryptonly", "--disable-asn", "--enable-lowresource",
"--disable-crypttests", "--disable-examples"]}
"--disable-crypttests", "--disable-examples"]},
{"name": "pkcs12-pbkdf-mp-api", "minutes": 1.0,
"comment": "WC_PKCS12_PBKDF_USING_MP_API selects a second wc_PKCS12_PBKDF_ex implementation that no configure option reaches.",
"configure": ["--enable-pkcs12", "--enable-des3", "--enable-opensslextra",
"CPPFLAGS=-DWC_PKCS12_PBKDF_USING_MP_API"]}
]

View File

@ -470,6 +470,9 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
if (ret == 0)
return BAD_STATE_E;
v = (word32)ret;
/* the block size must not be mistaken for a result when kLen is 0 and the
* derivation loop below never runs */
ret = 0;
#ifdef WOLFSSL_SMALL_STACK
Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
@ -499,7 +502,8 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
return BAD_FUNC_ARG;
}
if (! WC_SAFE_SUM_UNSIGNED(word32, dLen, sLen, totalLen)) {
/* the working buffer holds D || S || P, so totalLen is dLen + iLen */
if (! WC_SAFE_SUM_UNSIGNED(word32, dLen, iLen, totalLen)) {
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BAD_FUNC_ARG;