@@ -12009,6 +12009,8 @@ 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; /* PBKDF2 keyLength; 0 means absent */
12013+ word32 pbkdf2End = 0;
1201212014 word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
1201312015 byte* pkiMsg = in;
1201412016 word32 pkiMsgSz = inSz;
@@ -12055,6 +12057,7 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1205512057 /* get KDF params SEQ */
1205612058 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
1205712059 return ASN_PARSE_E;
12060+ pbkdf2End = *idx + (word32)length;
1205812061
1205912062 /* get KDF salt OCTET STRING */
1206012063 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
@@ -12080,6 +12083,43 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1208012083 return ASN_PARSE_E;
1208112084 }
1208212085
12086+ /* optional keyLength - validated below once kekKeySz is known */
12087+ if (*idx < pbkdf2End && pkiMsg[*idx] == ASN_INTEGER) {
12088+ if (GetMyVersion(pkiMsg, idx, &keyLen, pbkdf2End) < 0) {
12089+ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
12090+ return ASN_PARSE_E;
12091+ }
12092+ }
12093+
12094+ /* optional prf; default hmacWithSHA1 keeps hashOID at WC_SHA */
12095+ if (*idx < pbkdf2End &&
12096+ pkiMsg[*idx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
12097+ word32 prfOid = 0;
12098+ if (GetAlgoId(pkiMsg, idx, &prfOid, oidHmacType,
12099+ pbkdf2End) < 0) {
12100+ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
12101+ return ASN_PARSE_E;
12102+ }
12103+ switch ((int)prfOid) {
12104+ #ifdef WOLFSSL_SHA224
12105+ case HMAC_SHA224_OID: hashOID = WC_SHA224; break;
12106+ #endif
12107+ #ifndef NO_SHA256
12108+ case HMAC_SHA256_OID: hashOID = WC_SHA256; break;
12109+ #endif
12110+ #ifdef WOLFSSL_SHA384
12111+ case HMAC_SHA384_OID: hashOID = WC_SHA384; break;
12112+ #endif
12113+ #ifdef WOLFSSL_SHA512
12114+ case HMAC_SHA512_OID: hashOID = WC_SHA512; break;
12115+ #endif
12116+ default:
12117+ /* unknown id (incl. explicit hmacWithSHA1) - keep
12118+ * default WC_SHA; MAC unwrap fails if mismatched */
12119+ break;
12120+ }
12121+ }
12122+
1208312123 /* get KeyEncAlgoId SEQ */
1208412124 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
1208512125 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
@@ -12112,6 +12152,13 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
1211212152 return kekKeySz;
1211312153 }
1211412154
12155+ /* RFC 8018: when present, PBKDF2 keyLength must equal the
12156+ * derived key length expected by the encryption algorithm */
12157+ if (keyLen != 0 && keyLen != kekKeySz) {
12158+ XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
12159+ return ASN_PARSE_E;
12160+ }
12161+
1211512162 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
1211612163 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
1211712164 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
0 commit comments