@@ -12009,6 +12009,9 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1200912009
1201012010 int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;
1201112011 int hashOID = WC_SHA; /* default to SHA1 */
12012+ int keyLen = 0;
12013+ int keyLenPresent = 0;
12014+ word32 pbkdf2End = 0;
1201212015 word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
1201312016 byte* pkiMsg = in;
1201412017 word32 pkiMsgSz = inSz;
@@ -12055,6 +12058,7 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1205512058 /* get KDF params SEQ */
1205612059 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
1205712060 return ASN_PARSE_E;
12061+ pbkdf2End = *idx + (word32)length;
1205812062
1205912063 /* get KDF salt OCTET STRING */
1206012064 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
@@ -12080,6 +12084,44 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1208012084 return ASN_PARSE_E;
1208112085 }
1208212086
12087+ /* optional keyLength - validated below once kekKeySz is known */
12088+ if (*idx < pbkdf2End && pkiMsg[*idx] == ASN_INTEGER) {
12089+ if (GetMyVersion(pkiMsg, idx, &keyLen, pbkdf2End) < 0) {
12090+ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
12091+ return ASN_PARSE_E;
12092+ }
12093+ keyLenPresent = 1;
12094+ }
12095+
12096+ /* optional prf; default hmacWithSHA1 keeps hashOID at WC_SHA */
12097+ if (*idx < pbkdf2End &&
12098+ pkiMsg[*idx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
12099+ word32 prfOid = 0;
12100+ if (GetAlgoId(pkiMsg, idx, &prfOid, oidHmacType,
12101+ pbkdf2End) < 0) {
12102+ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
12103+ return ASN_PARSE_E;
12104+ }
12105+ switch ((int)prfOid) {
12106+ #ifdef WOLFSSL_SHA224
12107+ case HMAC_SHA224_OID: hashOID = WC_SHA224; break;
12108+ #endif
12109+ #ifndef NO_SHA256
12110+ case HMAC_SHA256_OID: hashOID = WC_SHA256; break;
12111+ #endif
12112+ #ifdef WOLFSSL_SHA384
12113+ case HMAC_SHA384_OID: hashOID = WC_SHA384; break;
12114+ #endif
12115+ #ifdef WOLFSSL_SHA512
12116+ case HMAC_SHA512_OID: hashOID = WC_SHA512; break;
12117+ #endif
12118+ default:
12119+ /* unknown id (incl. explicit hmacWithSHA1) - keep
12120+ * default WC_SHA; MAC unwrap fails if mismatched */
12121+ break;
12122+ }
12123+ }
12124+
1208312125 /* get KeyEncAlgoId SEQ */
1208412126 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
1208512127 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
@@ -12112,6 +12154,13 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1211212154 return kekKeySz;
1211312155 }
1211412156
12157+ /* RFC 8018: when present, PBKDF2 keyLength must equal the
12158+ * derived key length expected by the encryption algorithm */
12159+ if (keyLenPresent && keyLen != kekKeySz) {
12160+ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
12161+ return ASN_PARSE_E;
12162+ }
12163+
1211512164 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
1211612165 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
1211712166 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
0 commit comments