diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 68eea81e3..595095597 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -8484,6 +8484,9 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, #ifdef WC_RSA_BLINDING WC_RNG rng; #endif +#ifndef WC_NO_RSA_OAEP + word32 outLen; +#endif byte* encryptedKey = NULL; @@ -8649,9 +8652,26 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, return ASN_PARSE_E; /* key encryption algorithm must be RSA for now */ - if (encOID != RSAk) + if (encOID != RSAk + #ifndef WC_NO_RSA_OAEP + && encOID != RSAESOAEPk + #endif + ) return ALGO_ID_E; + #ifndef WC_NO_RSA_OAEP + if (encOID == RSAESOAEPk) { + if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) { + return ASN_PARSE_E; + } + if (length > 0) { + WOLFSSL_MSG("only supported default OAEP"); + WOLFSSL_ERROR(ALGO_ID_E); + return ALGO_ID_E; + } + } + #endif + /* read encryptedKey */ if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -8749,9 +8769,37 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if (keySz >= 0) #endif { - keySz = wc_RsaPrivateDecryptInline(encryptedKey, - encryptedKeySz, &outKey, - privKey); + #ifndef WC_NO_RSA_OAEP + if (encOID != RSAESOAEPk) { + #endif + keySz = wc_RsaPrivateDecryptInline(encryptedKey, + encryptedKeySz, &outKey, + privKey); + #ifndef WC_NO_RSA_OAEP + } + else { + outLen = wc_RsaEncryptSize(privKey); + outKey = (byte*)XMALLOC(outLen, pkcs7->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (!outKey) { + WOLFSSL_MSG("Failed to allocate out key buffer"); + wc_FreeRsaKey(privKey); + XFREE(encryptedKey, pkcs7->heap, + DYNAMIC_TYPE_WOLF_BIGINT); + #ifdef WOLFSSL_SMALL_STACK + XFREE(privKey, pkcs7->heap, + DYNAMIC_TYPE_TMP_BUFFER); + #endif + WOLFSSL_ERROR_VERBOSE(MEMORY_E); + return MEMORY_E; + } + + keySz = wc_RsaPrivateDecrypt_ex(encryptedKey, + encryptedKeySz, outKey, outLen, privKey, + WC_RSA_OAEP_PAD, + WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0); + } + #endif } #ifdef WOLFSSL_ASYNC_CRYPT } while (keySz == WC_PENDING_E); @@ -8769,6 +8817,13 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT); #ifdef WOLFSSL_SMALL_STACK XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifndef WC_NO_RSA_OAEP + if (encOID == RSAESOAEPk) { + if (!outKey) { + XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } #endif return keySz; } else { @@ -8781,7 +8836,13 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, #ifdef WOLFSSL_SMALL_STACK XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - + #ifndef WC_NO_RSA_OAEP + if (encOID == RSAESOAEPk) { + if (!outKey) { + XFREE(outKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } + #endif #ifndef NO_PKCS7_STREAM if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 72267f50c..0380cf2b1 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1081,6 +1081,7 @@ enum Key_Sum { DSAk = 515, RSAk = 645, RSAPSSk = 654, + RSAESOAEPk = 651, /* 1.2.840.113549.1.1.7 */ ECDSAk = 518, ED25519k = 256, /* 1.3.101.112 */ X25519k = 254, /* 1.3.101.110 */