Skip to content

Commit eadc6f9

Browse files
committed
PKCS7 PWRI decrypt: parse PBKDF2 prf
1 parent 6e8f90a commit eadc6f9

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

wolfcrypt/src/pkcs7.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)