* [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions @ 2024-03-18 21:52 Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io ` (3 more replies) 0 siblings, 4 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-18 21:52 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin, Jiewen Yao, Yi Li, Wenxing Hou From: Chris Ruffin <v-chruffin@microsoft.com> Expand the availability of the RSAEP-OAEP crypto capability in BaseCryptLib. Applications using RSA crypto functions directly from OpensslLib can transition to BaseCryptLib to take advantage of the shared crypto feature in CryptoDxe. Pkcs1v2Decrypt(): decryption using DER-encoded private key RsaOaepEncrypt(): encryption using RSA contexts RsaOaepDecrypt(): decryption using RSA contexts Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Include/Library/BaseCryptLib.h | 102 ++++ .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 506 ++++++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 114 ++++ .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 114 ++++ 4 files changed, 789 insertions(+), 47 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index a52bd91ad6..7ad2bf21fe 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2147,6 +2147,108 @@ Pkcs1v2Encrypt ( OUT UINTN *EncryptedDataSize ); +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + /** The 3rd parameter of Pkcs7GetSigners will return all embedded X.509 certificate in one given PKCS7 signature. The format is: diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c index ea43c1381c..00e904dd6c 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -26,9 +26,8 @@ - Data size is too large for the provided key size (max size is a function of key size and hash digest size). - @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + @param[in] Pkey A pointer to an EVP_PKEY struct that will be used to encrypt the data. - @param[in] PublicKeySize Size of the X509 cert buffer. @param[in] InData Data to be encrypted. @param[in] InDataSize Size of the data buffer. @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer @@ -45,9 +44,8 @@ **/ BOOLEAN EFIAPI -Pkcs1v2Encrypt ( - IN CONST UINT8 *PublicKey, - IN UINTN PublicKeySize, +InternalPkcs1v2Encrypt ( + EVP_PKEY *Pkey, IN UINT8 *InData, IN UINTN InDataSize, IN CONST UINT8 *PrngSeed OPTIONAL, @@ -57,9 +55,6 @@ Pkcs1v2Encrypt ( ) { BOOLEAN Result; - CONST UINT8 *TempPointer; - X509 *CertData; - EVP_PKEY *InternalPublicKey; EVP_PKEY_CTX *PkeyCtx; UINT8 *OutData; UINTN OutDataSize; @@ -67,28 +62,15 @@ Pkcs1v2Encrypt ( // // Check input parameters. // - if ((PublicKey == NULL) || (InData == NULL) || + if ((Pkey == NULL) || (InData == NULL) || (EncryptedData == NULL) || (EncryptedDataSize == NULL)) { return FALSE; } - // - // Check public key size. - // - if (PublicKeySize > 0xFFFFFFFF) { - // - // Public key size is too large for implementation. - // - return FALSE; - } - *EncryptedData = NULL; *EncryptedDataSize = 0; Result = FALSE; - TempPointer = NULL; - CertData = NULL; - InternalPublicKey = NULL; PkeyCtx = NULL; OutData = NULL; OutDataSize = 0; @@ -104,6 +86,154 @@ Pkcs1v2Encrypt ( RandomSeed (NULL, 0); } + // + // Create a context for the public key operation. + // + PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); + if (PkeyCtx == NULL) { + // + // Fail to create contex. + // + goto _Exit; + } + + // + // Initialize the context and set the desired padding. + // + if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) || + (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) + { + // + // Fail to initialize the context. + // + goto _Exit; + } + + // + // Determine the required buffer length for malloc'ing. + // + if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to determine output buffer size. + // + goto _Exit; + } + + // + // Allocate a buffer for the output data. + // + OutData = AllocatePool (OutDataSize); + if (OutData == NULL) { + // + // Fail to allocate the output buffer. + // + goto _Exit; + } + + // + // Encrypt Data. + // + if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to encrypt data, need to free the output buffer. + // + FreePool (OutData); + OutData = NULL; + OutDataSize = 0; + goto _Exit; + } + + // + // Encrypt done. + // + *EncryptedData = OutData; + *EncryptedDataSize = OutDataSize; + Result = TRUE; + +_Exit: + // + // Release Resources + // + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to parse X509 certificate. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + will be used to encrypt the data. + @param[in] PublicKeySize Size of the X509 cert buffer. + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Encrypt ( + IN CONST UINT8 *PublicKey, + IN UINTN PublicKeySize, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + CONST UINT8 *TempPointer; + X509 *CertData; + EVP_PKEY *Pkey; + + // + // Check input parameters. + // + if ((PublicKey == NULL) || (InData == NULL) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + // + // Check public key size. + // + if (PublicKeySize > 0xFFFFFFFF) { + // + // Public key size is too large for implementation. + // + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + TempPointer = NULL; + CertData = NULL; + Pkey = NULL; + // // Parse the X509 cert and extract the public key. // @@ -120,52 +250,201 @@ Pkcs1v2Encrypt ( // Extract the public key from the x509 cert in a format that // OpenSSL can use. // - InternalPublicKey = X509_get_pubkey (CertData); - if (InternalPublicKey == NULL) { + Pkey = X509_get_pubkey (CertData); + if (Pkey == NULL) { // // Fail to extract public key. // goto _Exit; } + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize); + +_Exit: // - // Create a context for the public key operation. + // Release Resources + // + if (CertData != NULL) { + X509_free (CertData); + } + + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + // - PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, NULL); + // Check input parameters. + // + if (((RsaContext == NULL) || (InData == NULL)) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + Pkey = NULL; + + Pkey = EVP_PKEY_new (); + if (Pkey == NULL) { + goto _Exit; + } + + if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) { + goto _Exit; + } + + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize); + +_Exit: + // + // Release Resources + // + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } + + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] Pkey A pointer to an EVP_PKEY which will decrypt that data. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +InternalPkcs1v2Decrypt ( + EVP_PKEY *Pkey, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY_CTX *PkeyCtx; + UINT8 *TempData; + UINTN TempDataSize; + INTN ReturnCode; + + // + // Check input parameters. + // + if ((Pkey == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + PkeyCtx = NULL; + TempData = NULL; + TempDataSize = 0; + + // + // Create a context for the decryption operation. + // + PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); if (PkeyCtx == NULL) { // // Fail to create contex. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_CTK_new() failed\n", __func__)); goto _Exit; } // // Initialize the context and set the desired padding. // - if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) || + if ((EVP_PKEY_decrypt_init (PkeyCtx) <= 0) || (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) { // // Fail to initialize the context. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt_init() failed\n", __func__)); goto _Exit; } // // Determine the required buffer length for malloc'ing. // - if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { + ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { // // Fail to determine output buffer size. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt() failed to determine output buffer size (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // // Allocate a buffer for the output data. // - OutData = AllocatePool (OutDataSize); - if (OutData == NULL) { + TempData = AllocatePool (TempDataSize); + if (TempData == NULL) { // // Fail to allocate the output buffer. // @@ -173,39 +452,172 @@ Pkcs1v2Encrypt ( } // - // Encrypt Data. + // Decrypt Data. // - if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { + ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { // - // Fail to encrypt data, need to free the output buffer. + // Fail to decrypt data, need to free the output buffer. // - FreePool (OutData); - OutData = NULL; - OutDataSize = 0; + FreePool (TempData); + TempData = NULL; + TempDataSize = 0; + + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt(TempData) failed to decrypt (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // - // Encrypt done. + // Decrypt done. // - *EncryptedData = OutData; - *EncryptedDataSize = OutDataSize; - Result = TRUE; + *OutData = TempData; + *OutDataSize = TempDataSize; + Result = TRUE; _Exit: + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + CONST UINT8 *TempPointer; + // - // Release Resources + // Check input parameters. // - if (CertData != NULL) { - X509_free (CertData); + if ((PrivateKey == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + Pkey = NULL; + TempPointer = NULL; + + // + // Parse the private key. + // + TempPointer = PrivateKey; + Pkey = d2i_PrivateKey (EVP_PKEY_RSA, &Pkey, &TempPointer, (UINT32)PrivateKeySize); + if (Pkey == NULL) { + // + // Fail to parse private key. + // + DEBUG ((DEBUG_ERROR, "[%a] d2i_PrivateKey() failed\n", __func__)); + goto _Exit; } - if (InternalPublicKey != NULL) { - EVP_PKEY_free (InternalPublicKey); + Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize); + +_Exit: + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); } - if (PkeyCtx != NULL) { - EVP_PKEY_CTX_free (PkeyCtx); + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + + // + // Check input parameters. + // + if ((RsaContext == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + Pkey = NULL; + + // + // Create a context for the decryption operation. + // + + Pkey = EVP_PKEY_new (); + if (Pkey == NULL) { + goto _Exit; + } + + if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) { + goto _Exit; + } + + Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize); + +_Exit: + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); } return Result; diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116870): https://edk2.groups.io/g/devel/message/116870 Mute This Topic: https://groups.io/mt/105014749/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: add additional RSAEP-OAEP crypto functions 2024-03-18 21:52 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Chris Ruffin via groups.io @ 2024-03-18 21:52 ` Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-18 21:52 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin, Jiewen Yao, Yi Li, Wenxing Hou From: Chris Ruffin <v-chruffin@microsoft.com> Add new library members to CryptoPkg/Driver. Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Driver/Crypto.c | 116 +++++++++++++++++- .../Pcd/PcdCryptoServiceFamilyEnable.h | 3 + .../BaseCryptLibOnProtocolPpi/CryptLib.c | 100 +++++++++++++++ CryptoPkg/Private/Protocol/Crypto.h | 97 ++++++++++++++- 4 files changed, 314 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index bdbb4863a9..3bfce16fa6 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -3589,6 +3589,117 @@ CryptoServicePkcs1v2Encrypt ( return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs1v2Encrypt, Pkcs1v2Encrypt, (PublicKey, PublicKeySize, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); } +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceRsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + return CALL_BASECRYPTLIB (Rsa.Services.RsaOaepEncrypt, RsaOaepEncrypt, (RsaContext, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServicePkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs1v2Decrypt, Pkcs1v2Decrypt, (PrivateKey, PrivateKeySize, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceRsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + return CALL_BASECRYPTLIB (Rsa.Services.RsaOaepDecrypt, RsaOaepDecrypt, (RsaContext, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + /** Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7: Cryptographic Message Syntax Standard". The input signed data could be wrapped @@ -6987,5 +7098,8 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { CryptoServiceX509VerifyCertChain, CryptoServiceX509GetCertFromCertChain, CryptoServiceAsn1GetTag, - CryptoServiceX509GetExtendedBasicConstraints + CryptoServiceX509GetExtendedBasicConstraints, + CryptoServicePkcs1v2Decrypt, + CryptoServiceRsaOaepEncrypt, + CryptoServiceRsaOaepDecrypt, }; diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 74eaf44cca..6aee28afe5 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -124,6 +124,7 @@ typedef struct { UINT8 Pkcs7GetCertificatesList : 1; UINT8 AuthenticodeVerify : 1; UINT8 ImageTimestampVerify : 1; + UINT8 Pkcs1v2Decrypt : 1; } Services; UINT32 Family; } Pkcs; @@ -158,6 +159,8 @@ typedef struct { UINT8 Pkcs1Verify : 1; UINT8 GetPrivateKeyFromPem : 1; UINT8 GetPublicKeyFromX509 : 1; + UINT8 RsaOaepEncrypt : 1; + UINT8 RsaOaepDecrypt : 1; } Services; UINT32 Family; } Rsa; diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index 4e31bc278e..8bf3bf00ed 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -2825,6 +2825,105 @@ Pkcs1v2Encrypt ( CALL_CRYPTO_SERVICE (Pkcs1v2Encrypt, (PublicKey, PublicKeySize, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); } +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + CALL_CRYPTO_SERVICE (Pkcs1v2Decrypt, (PrivateKey, PrivateKeySize, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + CALL_CRYPTO_SERVICE (RsaOaepEncrypt, (RsaContext, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + CALL_CRYPTO_SERVICE (RsaOaepDecrypt, (RsaContext, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + /** Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7: Cryptographic Message Syntax Standard". The input signed data could be wrapped @@ -2850,6 +2949,7 @@ Pkcs1v2Encrypt ( @retval FALSE Error occurs during the operation. @retval FALSE This interface is not supported. + **/ BOOLEAN EFIAPI diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index 0e0b1d9401..2466d47dd9 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -21,7 +21,7 @@ /// the EDK II Crypto Protocol is extended, this version define must be /// increased. /// -#define EDKII_CRYPTO_VERSION 16 +#define EDKII_CRYPTO_VERSION 17 /// /// EDK II Crypto Protocol forward declaration @@ -688,6 +688,98 @@ BOOLEAN OUT UINTN *EncryptedDataSize ); +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_PKCS1V2_DECRYPT)( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +// FROM BaseCryptLib.h:2178 +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_RSA_OAEP_ENCRYPT)( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +// FROM BaseCryptLib.h:2243 +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_RSA_OAEP_DECRYPT)( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + // --------------------------------------------- // PKCS5 @@ -5603,6 +5695,9 @@ struct _EDKII_CRYPTO_PROTOCOL { EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN X509GetCertFromCertChain; EDKII_CRYPTO_ASN1_GET_TAG Asn1GetTag; EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS X509GetExtendedBasicConstraints; + EDKII_CRYPTO_PKCS1V2_DECRYPT Pkcs1v2Decrypt; + EDKII_CRYPTO_RSA_OAEP_ENCRYPT RsaOaepEncrypt; + EDKII_CRYPTO_RSA_OAEP_DECRYPT RsaOaepDecrypt; }; extern GUID gEdkiiCryptoProtocolGuid; -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116871): https://edk2.groups.io/g/devel/message/116871 Mute This Topic: https://groups.io/mt/105014811/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions 2024-03-18 21:52 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io @ 2024-03-18 21:52 ` Chris Ruffin via groups.io 2024-03-19 3:52 ` [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Li, Yi 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io 3 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-18 21:52 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin, Jiewen Yao, Yi Li, Wenxing Hou From: Chris Ruffin <v-chruffin@microsoft.com> Add unit test functions: TestVerifyPkcs1v2Decrypt() TestVerifyTestRsaOaepEncrypt() TestVerifyTestRsaOaepDecrypt() Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- .../Library/BaseCryptLib/OaepEncryptTests.c | 184 +++++++++++++++++- 1 file changed, 182 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c index 22a4ea7e46..2b5c6d04da 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c @@ -153,9 +153,42 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 PrivateKey[] = { 0x86, 0x10, 0x09, 0x88, 0x6C, 0x35, 0x60, 0xF2, }; +// +// Public Modulus of RSA Key +// +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 RsaN[] = { + 0xBB, 0xF8, 0x2F, 0x09, 0x06, 0x82, 0xCE, 0x9C, 0x23, 0x38, 0xAC, 0x2B, 0x9D, 0xA8, 0x71, 0xF7, + 0x36, 0x8D, 0x07, 0xEE, 0xD4, 0x10, 0x43, 0xA4, 0x40, 0xD6, 0xB6, 0xF0, 0x74, 0x54, 0xF5, 0x1F, + 0xB8, 0xDF, 0xBA, 0xAF, 0x03, 0x5C, 0x02, 0xAB, 0x61, 0xEA, 0x48, 0xCE, 0xEB, 0x6F, 0xCD, 0x48, + 0x76, 0xED, 0x52, 0x0D, 0x60, 0xE1, 0xEC, 0x46, 0x19, 0x71, 0x9D, 0x8A, 0x5B, 0x8B, 0x80, 0x7F, + 0xAF, 0xB8, 0xE0, 0xA3, 0xDF, 0xC7, 0x37, 0x72, 0x3E, 0xE6, 0xB4, 0xB7, 0xD9, 0x3A, 0x25, 0x84, + 0xEE, 0x6A, 0x64, 0x9D, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xB2, 0x45, 0x45, 0x98, 0x39, 0x4E, + 0xE0, 0xAA, 0xB1, 0x2D, 0x7B, 0x61, 0xA5, 0x1F, 0x52, 0x7A, 0x9A, 0x41, 0xF6, 0xC1, 0x68, 0x7F, + 0xE2, 0x53, 0x72, 0x98, 0xCA, 0x2A, 0x8F, 0x59, 0x46, 0xF8, 0xE5, 0xFD, 0x09, 0x1D, 0xBD, 0xCB +}; + +// +// Public Exponent of RSA Key +// +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 RsaE[] = { 0x11 }; + +// +// Private Exponent of RSA Key +// +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 RsaD[] = { + 0xA5, 0xDA, 0xFC, 0x53, 0x41, 0xFA, 0xF2, 0x89, 0xC4, 0xB9, 0x88, 0xDB, 0x30, 0xC1, 0xCD, 0xF8, + 0x3F, 0x31, 0x25, 0x1E, 0x06, 0x68, 0xB4, 0x27, 0x84, 0x81, 0x38, 0x01, 0x57, 0x96, 0x41, 0xB2, + 0x94, 0x10, 0xB3, 0xC7, 0x99, 0x8D, 0x6B, 0xC4, 0x65, 0x74, 0x5E, 0x5C, 0x39, 0x26, 0x69, 0xD6, + 0x87, 0x0D, 0xA2, 0xC0, 0x82, 0xA9, 0x39, 0xE3, 0x7F, 0xDC, 0xB8, 0x2E, 0xC9, 0x3E, 0xDA, 0xC9, + 0x7F, 0xF3, 0xAD, 0x59, 0x50, 0xAC, 0xCF, 0xBC, 0x11, 0x1C, 0x76, 0xF1, 0xA9, 0x52, 0x94, 0x44, + 0xE5, 0x6A, 0xAF, 0x68, 0xC5, 0x6C, 0x09, 0x2C, 0xD3, 0x8D, 0xC3, 0xBE, 0xF5, 0xD2, 0x0A, 0x93, + 0x99, 0x26, 0xED, 0x4F, 0x74, 0xA1, 0x3E, 0xDD, 0xFB, 0xE1, 0xA1, 0xCE, 0xCC, 0x48, 0x94, 0xAF, + 0x94, 0x28, 0xC2, 0xB7, 0xB8, 0x88, 0x3F, 0xE4, 0x46, 0x3A, 0x4B, 0xC8, 0x5B, 0x1C, 0xB3, 0xC1 +}; + UNIT_TEST_STATUS EFIAPI -TestVerifyOaepEncrypt ( +TestVerifyPkcs1v2Encrypt ( IN UNIT_TEST_CONTEXT Context ) { @@ -296,11 +329,158 @@ TestVerifyOaepEncrypt ( return UNIT_TEST_PASSED; } +UNIT_TEST_STATUS +EFIAPI +TestVerifyPkcs1v2Decrypt ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 PlaintextBuffer[4]; + UINT8 *EncryptedBuffer; + UINTN EncryptedBufferSize; + UINT8 *DecryptedBuffer; + UINTN DecryptedBufferSize; + + // Create a file and add content '123' in it + PlaintextBuffer[0] = '1'; + PlaintextBuffer[1] = '2'; + PlaintextBuffer[2] = '3'; + PlaintextBuffer[3] = 0; + + Status = Pkcs1v2Encrypt ( + SelfTestCert, + (UINTN)sizeof (SelfTestCert), + PlaintextBuffer, + (UINTN)sizeof (PlaintextBuffer), + NULL, + 0, + &EncryptedBuffer, + (UINTN *)&EncryptedBufferSize + ); + UT_ASSERT_TRUE (Status); + + Status = Pkcs1v2Decrypt ( + PrivateKey, + (UINTN)sizeof (PrivateKey), + EncryptedBuffer, + EncryptedBufferSize, + &DecryptedBuffer, + (UINTN *)&DecryptedBufferSize + ); + UT_ASSERT_TRUE (Status); + + UT_ASSERT_TRUE ((CompareMem (PlaintextBuffer, DecryptedBuffer, DecryptedBufferSize) == 0)); + + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyRsaOaepEncrypt ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 PlaintextBuffer[4]; + UINT8 *EncryptedBuffer; + UINTN EncryptedBufferSize; + VOID *RsaContext = NULL; + + // Create a file and add content '123' in it + PlaintextBuffer[0] = '1'; + PlaintextBuffer[1] = '2'; + PlaintextBuffer[2] = '3'; + PlaintextBuffer[3] = 0; + + RsaContext = RsaNew (); + UT_ASSERT_FALSE (RsaContext == NULL); + + Status = RsaSetKey (RsaContext, RsaKeyN, RsaN, sizeof (RsaN)); + UT_ASSERT_TRUE (Status); + + Status = RsaSetKey (RsaContext, RsaKeyE, RsaE, sizeof (RsaE)); + UT_ASSERT_TRUE (Status); + + Status = RsaOaepEncrypt ( + RsaContext, + PlaintextBuffer, + sizeof (PlaintextBuffer), + NULL, + 0, + &EncryptedBuffer, + &EncryptedBufferSize + ); + UT_ASSERT_TRUE (Status); + + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyRsaOaepDecrypt ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 PlaintextBuffer[4]; + UINT8 *EncryptedBuffer; + UINTN EncryptedBufferSize; + UINT8 *DecryptedBuffer; + UINTN DecryptedBufferSize; + VOID *RsaContext = NULL; + + // Create a file and add content '123' in it + PlaintextBuffer[0] = '1'; + PlaintextBuffer[1] = '2'; + PlaintextBuffer[2] = '3'; + PlaintextBuffer[3] = 0; + + RsaContext = RsaNew (); + UT_ASSERT_FALSE (RsaContext == NULL); + + Status = RsaSetKey (RsaContext, RsaKeyN, RsaN, sizeof (RsaN)); + UT_ASSERT_TRUE (Status); + + Status = RsaSetKey (RsaContext, RsaKeyE, RsaE, sizeof (RsaE)); + UT_ASSERT_TRUE (Status); + + Status = RsaOaepEncrypt ( + RsaContext, + PlaintextBuffer, + sizeof (PlaintextBuffer), + NULL, + 0, + &EncryptedBuffer, + &EncryptedBufferSize + ); + UT_ASSERT_TRUE (Status); + + Status = RsaSetKey (RsaContext, RsaKeyD, RsaD, sizeof (RsaD)); + UT_ASSERT_TRUE (Status); + + Status = RsaOaepDecrypt ( + RsaContext, + EncryptedBuffer, + EncryptedBufferSize, + &DecryptedBuffer, + &DecryptedBufferSize + ); + UT_ASSERT_TRUE (Status); + + UT_ASSERT_TRUE ((CompareMem (PlaintextBuffer, DecryptedBuffer, DecryptedBufferSize) == 0)); + + return UNIT_TEST_PASSED; +} + TEST_DESC mOaepTest[] = { // // -----Description--------------------------------------Class----------------------Function-----------------Pre---Post--Context // - { "TestVerifyOaepEncrypt()", "CryptoPkg.BaseCryptLib.Pkcs1v2Encrypt", TestVerifyOaepEncrypt, NULL, NULL, NULL }, + { "TestVerifyPkcs1v2Encrypt()", "CryptoPkg.BaseCryptLib.Pkcs1v2Encrypt", TestVerifyPkcs1v2Encrypt, NULL, NULL, NULL }, + { "TestVerifyPkcs1v2Decrypt()", "CryptoPkg.BaseCryptLib.Pkcs1v2Decrypt", TestVerifyPkcs1v2Decrypt, NULL, NULL, NULL }, + { "TestVerifyRsaOaepEncrypt()", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt", TestVerifyRsaOaepEncrypt, NULL, NULL, NULL }, + { "TestVerifyRsaOaepDecrypt()", "CryptoPkg.BaseCryptLib.RsaOaepDecrypt", TestVerifyRsaOaepDecrypt, NULL, NULL, NULL }, }; UINTN mOaepTestNum = ARRAY_SIZE (mOaepTest); -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116872): https://edk2.groups.io/g/devel/message/116872 Mute This Topic: https://groups.io/mt/105014813/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions 2024-03-18 21:52 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io @ 2024-03-19 3:52 ` Li, Yi 2024-03-19 14:15 ` Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io 3 siblings, 1 reply; 14+ messages in thread From: Li, Yi @ 2024-03-19 3:52 UTC (permalink / raw) To: Chris Ruffin, devel@edk2.groups.io Cc: Chris Ruffin, Yao, Jiewen, Hou, Wenxing Hi Chris, 1. Please create a feature request BugZilla to introduce the background of the new API, such as purpose and application scenarios. 2. I took a quick look, the new API will make Pkcs1v2De/Encrypt support RsaContext input and the rest is same as old API right? Regards, Yi -----Original Message----- From: Chris Ruffin <cruffin@millcore.com> Sent: Tuesday, March 19, 2024 5:52 AM To: devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Li, Yi1 <yi1.li@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions From: Chris Ruffin <v-chruffin@microsoft.com> Expand the availability of the RSAEP-OAEP crypto capability in BaseCryptLib. Applications using RSA crypto functions directly from OpensslLib can transition to BaseCryptLib to take advantage of the shared crypto feature in CryptoDxe. Pkcs1v2Decrypt(): decryption using DER-encoded private key RsaOaepEncrypt(): encryption using RSA contexts RsaOaepDecrypt(): decryption using RSA contexts Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Include/Library/BaseCryptLib.h | 102 ++++ .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 506 ++++++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 114 ++++ .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 114 ++++ 4 files changed, 789 insertions(+), 47 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index a52bd91ad6..7ad2bf21fe 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2147,6 +2147,108 @@ Pkcs1v2Encrypt ( OUT UINTN *EncryptedDataSize ); +/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ );++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ );++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ );+ /** The 3rd parameter of Pkcs7GetSigners will return all embedded X.509 certificate in one given PKCS7 signature. The format is:diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c index ea43c1381c..00e904dd6c 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -26,9 +26,8 @@ - Data size is too large for the provided key size (max size is a function of key size and hash digest size). - @param[in] PublicKey A pointer to the DER-encoded X509 certificate that+ @param[in] Pkey A pointer to an EVP_PKEY struct that will be used to encrypt the data.- @param[in] PublicKeySize Size of the X509 cert buffer. @param[in] InData Data to be encrypted. @param[in] InDataSize Size of the data buffer. @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer@@ -45,9 +44,8 @@ **/ BOOLEAN EFIAPI-Pkcs1v2Encrypt (- IN CONST UINT8 *PublicKey,- IN UINTN PublicKeySize,+InternalPkcs1v2Encrypt (+ EVP_PKEY *Pkey, IN UINT8 *InData, IN UINTN InDataSize, IN CONST UINT8 *PrngSeed OPTIONAL,@@ -57,9 +55,6 @@ Pkcs1v2Encrypt ( ) { BOOLEAN Result;- CONST UINT8 *TempPointer;- X509 *CertData;- EVP_PKEY *InternalPublicKey; EVP_PKEY_CTX *PkeyCtx; UINT8 *OutData; UINTN OutDataSize;@@ -67,28 +62,15 @@ Pkcs1v2Encrypt ( // // Check input parameters. //- if ((PublicKey == NULL) || (InData == NULL) ||+ if ((Pkey == NULL) || (InData == NULL) || (EncryptedData == NULL) || (EncryptedDataSize == NULL)) { return FALSE; } - //- // Check public key size.- //- if (PublicKeySize > 0xFFFFFFFF) {- //- // Public key size is too large for implementation.- //- return FALSE;- }- *EncryptedData = NULL; *EncryptedDataSize = 0; Result = FALSE;- TempPointer = NULL;- CertData = NULL;- InternalPublicKey = NULL; PkeyCtx = NULL; OutData = NULL; OutDataSize = 0;@@ -104,6 +86,154 @@ Pkcs1v2Encrypt ( RandomSeed (NULL, 0); } + //+ // Create a context for the public key operation.+ //+ PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL);+ if (PkeyCtx == NULL) {+ //+ // Fail to create contex.+ //+ goto _Exit;+ }++ //+ // Initialize the context and set the desired padding.+ //+ if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) ||+ (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0))+ {+ //+ // Fail to initialize the context.+ //+ goto _Exit;+ }++ //+ // Determine the required buffer length for malloc'ing.+ //+ if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) {+ //+ // Fail to determine output buffer size.+ //+ goto _Exit;+ }++ //+ // Allocate a buffer for the output data.+ //+ OutData = AllocatePool (OutDataSize);+ if (OutData == NULL) {+ //+ // Fail to allocate the output buffer.+ //+ goto _Exit;+ }++ //+ // Encrypt Data.+ //+ if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) {+ //+ // Fail to encrypt data, need to free the output buffer.+ //+ FreePool (OutData);+ OutData = NULL;+ OutDataSize = 0;+ goto _Exit;+ }++ //+ // Encrypt done.+ //+ *EncryptedData = OutData;+ *EncryptedDataSize = OutDataSize;+ Result = TRUE;++_Exit:+ //+ // Release Resources+ //+ if (PkeyCtx != NULL) {+ EVP_PKEY_CTX_free (PkeyCtx);+ }++ return Result;+}++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to parse X509 certificate.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] PublicKey A pointer to the DER-encoded X509 certificate that+ will be used to encrypt the data.+ @param[in] PublicKeySize Size of the X509 cert buffer.+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Encrypt (+ IN CONST UINT8 *PublicKey,+ IN UINTN PublicKeySize,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ BOOLEAN Result;+ CONST UINT8 *TempPointer;+ X509 *CertData;+ EVP_PKEY *Pkey;++ //+ // Check input parameters.+ //+ if ((PublicKey == NULL) || (InData == NULL) ||+ (EncryptedData == NULL) || (EncryptedDataSize == NULL))+ {+ return FALSE;+ }++ //+ // Check public key size.+ //+ if (PublicKeySize > 0xFFFFFFFF) {+ //+ // Public key size is too large for implementation.+ //+ return FALSE;+ }++ *EncryptedData = NULL;+ *EncryptedDataSize = 0;+ Result = FALSE;+ TempPointer = NULL;+ CertData = NULL;+ Pkey = NULL;+ // // Parse the X509 cert and extract the public key. //@@ -120,52 +250,201 @@ Pkcs1v2Encrypt ( // Extract the public key from the x509 cert in a format that // OpenSSL can use. //- InternalPublicKey = X509_get_pubkey (CertData);- if (InternalPublicKey == NULL) {+ Pkey = X509_get_pubkey (CertData);+ if (Pkey == NULL) { // // Fail to extract public key. // goto _Exit; } + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize);++_Exit: //- // Create a context for the public key operation.+ // Release Resources+ //+ if (CertData != NULL) {+ X509_free (CertData);+ }++ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey);+ }++ return Result;+}++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;+ //- PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, NULL);+ // Check input parameters.+ //+ if (((RsaContext == NULL) || (InData == NULL)) ||+ (EncryptedData == NULL) || (EncryptedDataSize == NULL))+ {+ return FALSE;+ }++ *EncryptedData = NULL;+ *EncryptedDataSize = 0;+ Result = FALSE;+ Pkey = NULL;++ Pkey = EVP_PKEY_new ();+ if (Pkey == NULL) {+ goto _Exit;+ }++ if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) {+ goto _Exit;+ }++ Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize);++_Exit:+ //+ // Release Resources+ //+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey);+ }++ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] Pkey A pointer to an EVP_PKEY which will decrypt that data.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+InternalPkcs1v2Decrypt (+ EVP_PKEY *Pkey,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY_CTX *PkeyCtx;+ UINT8 *TempData;+ UINTN TempDataSize;+ INTN ReturnCode;++ //+ // Check input parameters.+ //+ if ((Pkey == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ PkeyCtx = NULL;+ TempData = NULL;+ TempDataSize = 0;++ //+ // Create a context for the decryption operation.+ //+ PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); if (PkeyCtx == NULL) { // // Fail to create contex. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_CTK_new() failed\n", __func__)); goto _Exit; } // // Initialize the context and set the desired padding. //- if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) ||+ if ((EVP_PKEY_decrypt_init (PkeyCtx) <= 0) || (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) { // // Fail to initialize the context. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt_init() failed\n", __func__)); goto _Exit; } // // Determine the required buffer length for malloc'ing. //- if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) {+ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize);+ if (ReturnCode <= 0) { // // Fail to determine output buffer size. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt() failed to determine output buffer size (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // // Allocate a buffer for the output data. //- OutData = AllocatePool (OutDataSize);- if (OutData == NULL) {+ TempData = AllocatePool (TempDataSize);+ if (TempData == NULL) { // // Fail to allocate the output buffer. //@@ -173,39 +452,172 @@ Pkcs1v2Encrypt ( } //- // Encrypt Data.+ // Decrypt Data. //- if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) {+ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize);+ if (ReturnCode <= 0) { //- // Fail to encrypt data, need to free the output buffer.+ // Fail to decrypt data, need to free the output buffer. //- FreePool (OutData);- OutData = NULL;- OutDataSize = 0;+ FreePool (TempData);+ TempData = NULL;+ TempDataSize = 0;++ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt(TempData) failed to decrypt (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } //- // Encrypt done.+ // Decrypt done. //- *EncryptedData = OutData;- *EncryptedDataSize = OutDataSize;- Result = TRUE;+ *OutData = TempData;+ *OutDataSize = TempDataSize;+ Result = TRUE; _Exit:+ if (PkeyCtx != NULL) {+ EVP_PKEY_CTX_free (PkeyCtx);+ }++ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;+ CONST UINT8 *TempPointer;+ //- // Release Resources+ // Check input parameters. //- if (CertData != NULL) {- X509_free (CertData);+ if ((PrivateKey == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ Pkey = NULL;+ TempPointer = NULL;++ //+ // Parse the private key.+ //+ TempPointer = PrivateKey;+ Pkey = d2i_PrivateKey (EVP_PKEY_RSA, &Pkey, &TempPointer, (UINT32)PrivateKeySize);+ if (Pkey == NULL) {+ //+ // Fail to parse private key.+ //+ DEBUG ((DEBUG_ERROR, "[%a] d2i_PrivateKey() failed\n", __func__));+ goto _Exit; } - if (InternalPublicKey != NULL) {- EVP_PKEY_free (InternalPublicKey);+ Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize);++_Exit:+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey); } - if (PkeyCtx != NULL) {- EVP_PKEY_CTX_free (PkeyCtx);+ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;++ //+ // Check input parameters.+ //+ if ((RsaContext == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ Pkey = NULL;++ //+ // Create a context for the decryption operation.+ //++ Pkey = EVP_PKEY_new ();+ if (Pkey == NULL) {+ goto _Exit;+ }++ if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) {+ goto _Exit;+ }++ Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize);++_Exit:+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey); } return Result;diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; }++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; }++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}-- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116877): https://edk2.groups.io/g/devel/message/116877 Mute This Topic: https://groups.io/mt/105014749/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions 2024-03-19 3:52 ` [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Li, Yi @ 2024-03-19 14:15 ` Chris Ruffin via groups.io 2024-03-26 5:07 ` Li, Yi 0 siblings, 1 reply; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-19 14:15 UTC (permalink / raw) To: Li, Yi1, devel@edk2.groups.io; +Cc: Chris Ruffin, Yao, Jiewen, Hou, Wenxing Hi Yi, thanks for your email. I created a Bugzilla ticket for this, see Bugzilla ID #4732: https://bugzilla.tianocore.org/show_bug.cgi?id=4732. The Pkcs1v2Encrypt() API is maintained but the implementation is refactored. There is currently no Pkcs1v2Decrypt(), this is also a newly implemented API but the converse of Pkcs1v2Encypt(). Pkcs1v2Encrypt() (existing) and Pkcs1v2Decrypt() (new) both take they keys from DER-encoded certificates/keys. RsaOaepEncrypt() and RsaOaepDecrypt() both take keys from RsaContext. The internal functions use a common ENV_PKEY. More from the Bugzilla: BasecryptLib currently only provides RSAES-OAEP encryption capability with Pkcs1v2Encrypt() which takes as input a DER encoded x.509 certificate. A DXE application which needs access to RSAES-OAEP encryption and decryption capabilities currently only has the option of statically linking OpensslLib and using functions such as RSA_public_encrypt() and RSA_private_decrypt(). These applications would benefit from an expanded access to RSAES-OAEP encryption / decryption capability in BaseCryptLib so that the shared crypto driver can be used and the applciation can be migrated away from RSA_public_decrypt() and RSA_private_decrypt() which are deprecated in Openssl 3. There is the following challenges with migrating to BaseCryptLib interfaces: 1) BaseCryptLib Pkcs1v2Encrypt() requires the use of an X.509 DER-encoded certificate to pass the public key. This interface is dissimilar from the rest of the RSA APIs in BasecryptLib. Applications that have used other RSA APIs from BaseCryptLib for key generation and management such as RsaGenerateKey() and RsaSetKey() will not have such a structure available. 2) BaseCryptLib currently exposes no decryption capability. This feature provides an easy migration path for drivers/applications which need access to RSAES-OAEP encryption / decryption and that are currently using an RsaContext structure to pass key components to OpensslLib. These applications can be easily migrated to one of the new APIs to remove the direct dependency on OpensslLib, migrate away from deprecated interfaces, take advantage of CryptoPkg/Driver, and get BasecryptLib access to RSAES-OAEP decryption. Key changes proposed: InternalPkcs1v2Encrypt(): New internal-only function created from refactoring of Pkcs1v2Encrypt(). Takes key input from an ENV_PKEY and is used by both public functions Pkcs1v2Encrypt() and RsaOaepEncrypt(). Pkcs1v2Encrypt(): has been refactored to create InternalPkcs1v2Encrypt() but the public interface is maintained. RsaOaepEncrypt(): New function takes key input from an RsaContext, creates an ENV_PKEY, and calls InternalPkcs1v2Encrypt() InternalPkcs1v2Decrypt(): New internal-only function InternalPkcs1v2Decrypt() takes key input from an ENV_PKEY and provides the RSAES-OAEP decryption capability to Pkcs1v2Decrypt() and RsaOaepDecrypt(). Pkcs1v2Decrypt(): New public function Pkcs1v2Decrypt() takes a DER-encoded private key, creates an ENV_PKEY, and calls InternalPkcs1v2Decrypt() RsaOaepDecrypt(): New public function RsaOaepDecrypt() takes a pointer to RsaContext, creates an ENV_PKEY, and calls InternalPkcs1v2Decrypt() Thanks, Chris -----Original Message----- From: Li, Yi1 <yi1.li@intel.com> Sent: Monday, March 18, 2024 11:52 PM To: Chris Ruffin <cruffin@millcore.com>; devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: RE: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions [You don't often get email from yi1.li@intel.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] Hi Chris, 1. Please create a feature request BugZilla to introduce the background of the new API, such as purpose and application scenarios. 2. I took a quick look, the new API will make Pkcs1v2De/Encrypt support RsaContext input and the rest is same as old API right? Regards, Yi -----Original Message----- From: Chris Ruffin <cruffin@millcore.com> Sent: Tuesday, March 19, 2024 5:52 AM To: devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Li, Yi1 <yi1.li@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions From: Chris Ruffin <v-chruffin@microsoft.com> Expand the availability of the RSAEP-OAEP crypto capability in BaseCryptLib. Applications using RSA crypto functions directly from OpensslLib can transition to BaseCryptLib to take advantage of the shared crypto feature in CryptoDxe. Pkcs1v2Decrypt(): decryption using DER-encoded private key RsaOaepEncrypt(): encryption using RSA contexts RsaOaepDecrypt(): decryption using RSA contexts Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Include/Library/BaseCryptLib.h | 102 ++++ .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 506 ++++++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 114 ++++ .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 114 ++++ 4 files changed, 789 insertions(+), 47 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index a52bd91ad6..7ad2bf21fe 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2147,6 +2147,108 @@ Pkcs1v2Encrypt ( OUT UINTN *EncryptedDataSize ); +/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ );++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ );++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ );+ /** The 3rd parameter of Pkcs7GetSigners will return all embedded X.509 certificate in one given PKCS7 signature. The format is:diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c index ea43c1381c..00e904dd6c 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -26,9 +26,8 @@ - Data size is too large for the provided key size (max size is a function of key size and hash digest size). - @param[in] PublicKey A pointer to the DER-encoded X509 certificate that+ @param[in] Pkey A pointer to an EVP_PKEY struct that will be used to encrypt the data.- @param[in] PublicKeySize Size of the X509 cert buffer. @param[in] InData Data to be encrypted. @param[in] InDataSize Size of the data buffer. @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer@@ -45,9 +44,8 @@ **/ BOOLEAN EFIAPI-Pkcs1v2Encrypt (- IN CONST UINT8 *PublicKey,- IN UINTN PublicKeySize,+InternalPkcs1v2Encrypt (+ EVP_PKEY *Pkey, IN UINT8 *InData, IN UINTN InDataSize, IN CONST UINT8 *PrngSeed OPTIONAL,@@ -57,9 +55,6 @@ Pkcs1v2Encrypt ( ) { BOOLEAN Result;- CONST UINT8 *TempPointer;- X509 *CertData;- EVP_PKEY *InternalPublicKey; EVP_PKEY_CTX *PkeyCtx; UINT8 *OutData; UINTN OutDataSize;@@ -67,28 +62,15 @@ Pkcs1v2Encrypt ( // // Check input parameters. //- if ((PublicKey == NULL) || (InData == NULL) ||+ if ((Pkey == NULL) || (InData == NULL) || (EncryptedData == NULL) || (EncryptedDataSize == NULL)) { return FALSE; } - //- // Check public key size.- //- if (PublicKeySize > 0xFFFFFFFF) {- //- // Public key size is too large for implementation.- //- return FALSE;- }- *EncryptedData = NULL; *EncryptedDataSize = 0; Result = FALSE;- TempPointer = NULL;- CertData = NULL;- InternalPublicKey = NULL; PkeyCtx = NULL; OutData = NULL; OutDataSize = 0;@@ -104,6 +86,154 @@ Pkcs1v2Encrypt ( RandomSeed (NULL, 0); } + //+ // Create a context for the public key operation.+ //+ PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL);+ if (PkeyCtx == NULL) {+ //+ // Fail to create contex.+ //+ goto _Exit;+ }++ //+ // Initialize the context and set the desired padding.+ //+ if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) ||+ (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0))+ {+ //+ // Fail to initialize the context.+ //+ goto _Exit;+ }++ //+ // Determine the required buffer length for malloc'ing.+ //+ if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) {+ //+ // Fail to determine output buffer size.+ //+ goto _Exit;+ }++ //+ // Allocate a buffer for the output data.+ //+ OutData = AllocatePool (OutDataSize);+ if (OutData == NULL) {+ //+ // Fail to allocate the output buffer.+ //+ goto _Exit;+ }++ //+ // Encrypt Data.+ //+ if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) {+ //+ // Fail to encrypt data, need to free the output buffer.+ //+ FreePool (OutData);+ OutData = NULL;+ OutDataSize = 0;+ goto _Exit;+ }++ //+ // Encrypt done.+ //+ *EncryptedData = OutData;+ *EncryptedDataSize = OutDataSize;+ Result = TRUE;++_Exit:+ //+ // Release Resources+ //+ if (PkeyCtx != NULL) {+ EVP_PKEY_CTX_free (PkeyCtx);+ }++ return Result;+}++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to parse X509 certificate.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] PublicKey A pointer to the DER-encoded X509 certificate that+ will be used to encrypt the data.+ @param[in] PublicKeySize Size of the X509 cert buffer.+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Encrypt (+ IN CONST UINT8 *PublicKey,+ IN UINTN PublicKeySize,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ BOOLEAN Result;+ CONST UINT8 *TempPointer;+ X509 *CertData;+ EVP_PKEY *Pkey;++ //+ // Check input parameters.+ //+ if ((PublicKey == NULL) || (InData == NULL) ||+ (EncryptedData == NULL) || (EncryptedDataSize == NULL))+ {+ return FALSE;+ }++ //+ // Check public key size.+ //+ if (PublicKeySize > 0xFFFFFFFF) {+ //+ // Public key size is too large for implementation.+ //+ return FALSE;+ }++ *EncryptedData = NULL;+ *EncryptedDataSize = 0;+ Result = FALSE;+ TempPointer = NULL;+ CertData = NULL;+ Pkey = NULL;+ // // Parse the X509 cert and extract the public key. //@@ -120,52 +250,201 @@ Pkcs1v2Encrypt ( // Extract the public key from the x509 cert in a format that // OpenSSL can use. //- InternalPublicKey = X509_get_pubkey (CertData);- if (InternalPublicKey == NULL) {+ Pkey = X509_get_pubkey (CertData);+ if (Pkey == NULL) { // // Fail to extract public key. // goto _Exit; } + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize);++_Exit: //- // Create a context for the public key operation.+ // Release Resources+ //+ if (CertData != NULL) {+ X509_free (CertData);+ }++ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey);+ }++ return Result;+}++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;+ //- PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, NULL);+ // Check input parameters.+ //+ if (((RsaContext == NULL) || (InData == NULL)) ||+ (EncryptedData == NULL) || (EncryptedDataSize == NULL))+ {+ return FALSE;+ }++ *EncryptedData = NULL;+ *EncryptedDataSize = 0;+ Result = FALSE;+ Pkey = NULL;++ Pkey = EVP_PKEY_new ();+ if (Pkey == NULL) {+ goto _Exit;+ }++ if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) {+ goto _Exit;+ }++ Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize);++_Exit:+ //+ // Release Resources+ //+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey);+ }++ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] Pkey A pointer to an EVP_PKEY which will decrypt that data.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+InternalPkcs1v2Decrypt (+ EVP_PKEY *Pkey,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY_CTX *PkeyCtx;+ UINT8 *TempData;+ UINTN TempDataSize;+ INTN ReturnCode;++ //+ // Check input parameters.+ //+ if ((Pkey == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ PkeyCtx = NULL;+ TempData = NULL;+ TempDataSize = 0;++ //+ // Create a context for the decryption operation.+ //+ PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); if (PkeyCtx == NULL) { // // Fail to create contex. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_CTK_new() failed\n", __func__)); goto _Exit; } // // Initialize the context and set the desired padding. //- if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) ||+ if ((EVP_PKEY_decrypt_init (PkeyCtx) <= 0) || (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) { // // Fail to initialize the context. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt_init() failed\n", __func__)); goto _Exit; } // // Determine the required buffer length for malloc'ing. //- if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) {+ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize);+ if (ReturnCode <= 0) { // // Fail to determine output buffer size. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt() failed to determine output buffer size (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // // Allocate a buffer for the output data. //- OutData = AllocatePool (OutDataSize);- if (OutData == NULL) {+ TempData = AllocatePool (TempDataSize);+ if (TempData == NULL) { // // Fail to allocate the output buffer. //@@ -173,39 +452,172 @@ Pkcs1v2Encrypt ( } //- // Encrypt Data.+ // Decrypt Data. //- if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) {+ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize);+ if (ReturnCode <= 0) { //- // Fail to encrypt data, need to free the output buffer.+ // Fail to decrypt data, need to free the output buffer. //- FreePool (OutData);- OutData = NULL;- OutDataSize = 0;+ FreePool (TempData);+ TempData = NULL;+ TempDataSize = 0;++ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt(TempData) failed to decrypt (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } //- // Encrypt done.+ // Decrypt done. //- *EncryptedData = OutData;- *EncryptedDataSize = OutDataSize;- Result = TRUE;+ *OutData = TempData;+ *OutDataSize = TempDataSize;+ Result = TRUE; _Exit:+ if (PkeyCtx != NULL) {+ EVP_PKEY_CTX_free (PkeyCtx);+ }++ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;+ CONST UINT8 *TempPointer;+ //- // Release Resources+ // Check input parameters. //- if (CertData != NULL) {- X509_free (CertData);+ if ((PrivateKey == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ Pkey = NULL;+ TempPointer = NULL;++ //+ // Parse the private key.+ //+ TempPointer = PrivateKey;+ Pkey = d2i_PrivateKey (EVP_PKEY_RSA, &Pkey, &TempPointer, (UINT32)PrivateKeySize);+ if (Pkey == NULL) {+ //+ // Fail to parse private key.+ //+ DEBUG ((DEBUG_ERROR, "[%a] d2i_PrivateKey() failed\n", __func__));+ goto _Exit; } - if (InternalPublicKey != NULL) {- EVP_PKEY_free (InternalPublicKey);+ Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize);++_Exit:+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey); } - if (PkeyCtx != NULL) {- EVP_PKEY_CTX_free (PkeyCtx);+ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;++ //+ // Check input parameters.+ //+ if ((RsaContext == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ Pkey = NULL;++ //+ // Create a context for the decryption operation.+ //++ Pkey = EVP_PKEY_new ();+ if (Pkey == NULL) {+ goto _Exit;+ }++ if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) {+ goto _Exit;+ }++ Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize);++_Exit:+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey); } return Result;diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; }++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; }++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}-- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116900): https://edk2.groups.io/g/devel/message/116900 Mute This Topic: https://groups.io/mt/105014749/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions 2024-03-19 14:15 ` Chris Ruffin via groups.io @ 2024-03-26 5:07 ` Li, Yi 0 siblings, 0 replies; 14+ messages in thread From: Li, Yi @ 2024-03-26 5:07 UTC (permalink / raw) To: Chris Ruffin, devel@edk2.groups.io Cc: Chris Ruffin, Yao, Jiewen, Hou, Wenxing Hi Chris, 1. Add BZ link to commit message, 2. Add null implementation of new APIs to BaseCryptLibMbedTls to avoid build error. For other comments please check the PR: https://github.com/tianocore/edk2/pull/5473 Regards, Yi -----Original Message----- From: Chris Ruffin <cruffin@millcore.com> Sent: Tuesday, March 19, 2024 10:16 PM To: Li, Yi1 <yi1.li@intel.com>; devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: RE: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Hi Yi, thanks for your email. I created a Bugzilla ticket for this, see Bugzilla ID #4732: https://bugzilla.tianocore.org/show_bug.cgi?id=4732. The Pkcs1v2Encrypt() API is maintained but the implementation is refactored. There is currently no Pkcs1v2Decrypt(), this is also a newly implemented API but the converse of Pkcs1v2Encypt(). Pkcs1v2Encrypt() (existing) and Pkcs1v2Decrypt() (new) both take they keys from DER-encoded certificates/keys. RsaOaepEncrypt() and RsaOaepDecrypt() both take keys from RsaContext. The internal functions use a common ENV_PKEY. More from the Bugzilla: BasecryptLib currently only provides RSAES-OAEP encryption capability with Pkcs1v2Encrypt() which takes as input a DER encoded x.509 certificate. A DXE application which needs access to RSAES-OAEP encryption and decryption capabilities currently only has the option of statically linking OpensslLib and using functions such as RSA_public_encrypt() and RSA_private_decrypt(). These applications would benefit from an expanded access to RSAES-OAEP encryption / decryption capability in BaseCryptLib so that the shared crypto driver can be used and the applciation can be migrated away from RSA_public_decrypt() and RSA_private_decrypt() which are deprecated in Openssl 3. There is the following challenges with migrating to BaseCryptLib interfaces: 1) BaseCryptLib Pkcs1v2Encrypt() requires the use of an X.509 DER-encoded certificate to pass the public key. This interface is dissimilar from the rest of the RSA APIs in BasecryptLib. Applications that have used other RSA APIs from BaseCryptLib for key generation and management such as RsaGenerateKey() and RsaSetKey() will not have such a structure available. 2) BaseCryptLib currently exposes no decryption capability. This feature provides an easy migration path for drivers/applications which need access to RSAES-OAEP encryption / decryption and that are currently using an RsaContext structure to pass key components to OpensslLib. These applications can be easily migrated to one of the new APIs to remove the direct dependency on OpensslLib, migrate away from deprecated interfaces, take advantage of CryptoPkg/Driver, and get BasecryptLib access to RSAES-OAEP decryption. Key changes proposed: InternalPkcs1v2Encrypt(): New internal-only function created from refactoring of Pkcs1v2Encrypt(). Takes key input from an ENV_PKEY and is used by both public functions Pkcs1v2Encrypt() and RsaOaepEncrypt(). Pkcs1v2Encrypt(): has been refactored to create InternalPkcs1v2Encrypt() but the public interface is maintained. RsaOaepEncrypt(): New function takes key input from an RsaContext, creates an ENV_PKEY, and calls InternalPkcs1v2Encrypt() InternalPkcs1v2Decrypt(): New internal-only function InternalPkcs1v2Decrypt() takes key input from an ENV_PKEY and provides the RSAES-OAEP decryption capability to Pkcs1v2Decrypt() and RsaOaepDecrypt(). Pkcs1v2Decrypt(): New public function Pkcs1v2Decrypt() takes a DER-encoded private key, creates an ENV_PKEY, and calls InternalPkcs1v2Decrypt() RsaOaepDecrypt(): New public function RsaOaepDecrypt() takes a pointer to RsaContext, creates an ENV_PKEY, and calls InternalPkcs1v2Decrypt() Thanks, Chris -----Original Message----- From: Li, Yi1 <yi1.li@intel.com> Sent: Monday, March 18, 2024 11:52 PM To: Chris Ruffin <cruffin@millcore.com>; devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: RE: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions [You don't often get email from yi1.li@intel.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] Hi Chris, 1. Please create a feature request BugZilla to introduce the background of the new API, such as purpose and application scenarios. 2. I took a quick look, the new API will make Pkcs1v2De/Encrypt support RsaContext input and the rest is same as old API right? Regards, Yi -----Original Message----- From: Chris Ruffin <cruffin@millcore.com> Sent: Tuesday, March 19, 2024 5:52 AM To: devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Li, Yi1 <yi1.li@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions From: Chris Ruffin <v-chruffin@microsoft.com> Expand the availability of the RSAEP-OAEP crypto capability in BaseCryptLib. Applications using RSA crypto functions directly from OpensslLib can transition to BaseCryptLib to take advantage of the shared crypto feature in CryptoDxe. Pkcs1v2Decrypt(): decryption using DER-encoded private key RsaOaepEncrypt(): encryption using RSA contexts RsaOaepDecrypt(): decryption using RSA contexts Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Include/Library/BaseCryptLib.h | 102 ++++ .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 506 ++++++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 114 ++++ .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 114 ++++ 4 files changed, 789 insertions(+), 47 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index a52bd91ad6..7ad2bf21fe 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2147,6 +2147,108 @@ Pkcs1v2Encrypt ( OUT UINTN *EncryptedDataSize ); +/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ );++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ );++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ );+ /** The 3rd parameter of Pkcs7GetSigners will return all embedded X.509 certificate in one given PKCS7 signature. The format is:diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c index ea43c1381c..00e904dd6c 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -26,9 +26,8 @@ - Data size is too large for the provided key size (max size is a function of key size and hash digest size). - @param[in] PublicKey A pointer to the DER-encoded X509 certificate that+ @param[in] Pkey A pointer to an EVP_PKEY struct that will be used to encrypt the data.- @param[in] PublicKeySize Size of the X509 cert buffer. @param[in] InData Data to be encrypted. @param[in] InDataSize Size of the data buffer. @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer@@ -45,9 +44,8 @@ **/ BOOLEAN EFIAPI-Pkcs1v2Encrypt (- IN CONST UINT8 *PublicKey,- IN UINTN PublicKeySize,+InternalPkcs1v2Encrypt (+ EVP_PKEY *Pkey, IN UINT8 *InData, IN UINTN InDataSize, IN CONST UINT8 *PrngSeed OPTIONAL,@@ -57,9 +55,6 @@ Pkcs1v2Encrypt ( ) { BOOLEAN Result;- CONST UINT8 *TempPointer;- X509 *CertData;- EVP_PKEY *InternalPublicKey; EVP_PKEY_CTX *PkeyCtx; UINT8 *OutData; UINTN OutDataSize;@@ -67,28 +62,15 @@ Pkcs1v2Encrypt ( // // Check input parameters. //- if ((PublicKey == NULL) || (InData == NULL) ||+ if ((Pkey == NULL) || (InData == NULL) || (EncryptedData == NULL) || (EncryptedDataSize == NULL)) { return FALSE; } - //- // Check public key size.- //- if (PublicKeySize > 0xFFFFFFFF) {- //- // Public key size is too large for implementation.- //- return FALSE;- }- *EncryptedData = NULL; *EncryptedDataSize = 0; Result = FALSE;- TempPointer = NULL;- CertData = NULL;- InternalPublicKey = NULL; PkeyCtx = NULL; OutData = NULL; OutDataSize = 0;@@ -104,6 +86,154 @@ Pkcs1v2Encrypt ( RandomSeed (NULL, 0); } + //+ // Create a context for the public key operation.+ //+ PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL);+ if (PkeyCtx == NULL) {+ //+ // Fail to create contex.+ //+ goto _Exit;+ }++ //+ // Initialize the context and set the desired padding.+ //+ if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) ||+ (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0))+ {+ //+ // Fail to initialize the context.+ //+ goto _Exit;+ }++ //+ // Determine the required buffer length for malloc'ing.+ //+ if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) {+ //+ // Fail to determine output buffer size.+ //+ goto _Exit;+ }++ //+ // Allocate a buffer for the output data.+ //+ OutData = AllocatePool (OutDataSize);+ if (OutData == NULL) {+ //+ // Fail to allocate the output buffer.+ //+ goto _Exit;+ }++ //+ // Encrypt Data.+ //+ if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) {+ //+ // Fail to encrypt data, need to free the output buffer.+ //+ FreePool (OutData);+ OutData = NULL;+ OutDataSize = 0;+ goto _Exit;+ }++ //+ // Encrypt done.+ //+ *EncryptedData = OutData;+ *EncryptedDataSize = OutDataSize;+ Result = TRUE;++_Exit:+ //+ // Release Resources+ //+ if (PkeyCtx != NULL) {+ EVP_PKEY_CTX_free (PkeyCtx);+ }++ return Result;+}++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to parse X509 certificate.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] PublicKey A pointer to the DER-encoded X509 certificate that+ will be used to encrypt the data.+ @param[in] PublicKeySize Size of the X509 cert buffer.+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Encrypt (+ IN CONST UINT8 *PublicKey,+ IN UINTN PublicKeySize,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ BOOLEAN Result;+ CONST UINT8 *TempPointer;+ X509 *CertData;+ EVP_PKEY *Pkey;++ //+ // Check input parameters.+ //+ if ((PublicKey == NULL) || (InData == NULL) ||+ (EncryptedData == NULL) || (EncryptedDataSize == NULL))+ {+ return FALSE;+ }++ //+ // Check public key size.+ //+ if (PublicKeySize > 0xFFFFFFFF) {+ //+ // Public key size is too large for implementation.+ //+ return FALSE;+ }++ *EncryptedData = NULL;+ *EncryptedDataSize = 0;+ Result = FALSE;+ TempPointer = NULL;+ CertData = NULL;+ Pkey = NULL;+ // // Parse the X509 cert and extract the public key. //@@ -120,52 +250,201 @@ Pkcs1v2Encrypt ( // Extract the public key from the x509 cert in a format that // OpenSSL can use. //- InternalPublicKey = X509_get_pubkey (CertData);- if (InternalPublicKey == NULL) {+ Pkey = X509_get_pubkey (CertData);+ if (Pkey == NULL) { // // Fail to extract public key. // goto _Exit; } + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize);++_Exit: //- // Create a context for the public key operation.+ // Release Resources+ //+ if (CertData != NULL) {+ X509_free (CertData);+ }++ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey);+ }++ return Result;+}++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;+ //- PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, NULL);+ // Check input parameters.+ //+ if (((RsaContext == NULL) || (InData == NULL)) ||+ (EncryptedData == NULL) || (EncryptedDataSize == NULL))+ {+ return FALSE;+ }++ *EncryptedData = NULL;+ *EncryptedDataSize = 0;+ Result = FALSE;+ Pkey = NULL;++ Pkey = EVP_PKEY_new ();+ if (Pkey == NULL) {+ goto _Exit;+ }++ if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) {+ goto _Exit;+ }++ Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize);++_Exit:+ //+ // Release Resources+ //+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey);+ }++ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] Pkey A pointer to an EVP_PKEY which will decrypt that data.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+InternalPkcs1v2Decrypt (+ EVP_PKEY *Pkey,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY_CTX *PkeyCtx;+ UINT8 *TempData;+ UINTN TempDataSize;+ INTN ReturnCode;++ //+ // Check input parameters.+ //+ if ((Pkey == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ PkeyCtx = NULL;+ TempData = NULL;+ TempDataSize = 0;++ //+ // Create a context for the decryption operation.+ //+ PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); if (PkeyCtx == NULL) { // // Fail to create contex. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_CTK_new() failed\n", __func__)); goto _Exit; } // // Initialize the context and set the desired padding. //- if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) ||+ if ((EVP_PKEY_decrypt_init (PkeyCtx) <= 0) || (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) { // // Fail to initialize the context. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt_init() failed\n", __func__)); goto _Exit; } // // Determine the required buffer length for malloc'ing. //- if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) {+ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize);+ if (ReturnCode <= 0) { // // Fail to determine output buffer size. //+ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt() failed to determine output buffer size (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // // Allocate a buffer for the output data. //- OutData = AllocatePool (OutDataSize);- if (OutData == NULL) {+ TempData = AllocatePool (TempDataSize);+ if (TempData == NULL) { // // Fail to allocate the output buffer. //@@ -173,39 +452,172 @@ Pkcs1v2Encrypt ( } //- // Encrypt Data.+ // Decrypt Data. //- if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) {+ ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize);+ if (ReturnCode <= 0) { //- // Fail to encrypt data, need to free the output buffer.+ // Fail to decrypt data, need to free the output buffer. //- FreePool (OutData);- OutData = NULL;- OutDataSize = 0;+ FreePool (TempData);+ TempData = NULL;+ TempDataSize = 0;++ DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt(TempData) failed to decrypt (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } //- // Encrypt done.+ // Decrypt done. //- *EncryptedData = OutData;- *EncryptedDataSize = OutDataSize;- Result = TRUE;+ *OutData = TempData;+ *OutDataSize = TempDataSize;+ Result = TRUE; _Exit:+ if (PkeyCtx != NULL) {+ EVP_PKEY_CTX_free (PkeyCtx);+ }++ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;+ CONST UINT8 *TempPointer;+ //- // Release Resources+ // Check input parameters. //- if (CertData != NULL) {- X509_free (CertData);+ if ((PrivateKey == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ Pkey = NULL;+ TempPointer = NULL;++ //+ // Parse the private key.+ //+ TempPointer = PrivateKey;+ Pkey = d2i_PrivateKey (EVP_PKEY_RSA, &Pkey, &TempPointer, (UINT32)PrivateKeySize);+ if (Pkey == NULL) {+ //+ // Fail to parse private key.+ //+ DEBUG ((DEBUG_ERROR, "[%a] d2i_PrivateKey() failed\n", __func__));+ goto _Exit; } - if (InternalPublicKey != NULL) {- EVP_PKEY_free (InternalPublicKey);+ Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize);++_Exit:+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey); } - if (PkeyCtx != NULL) {- EVP_PKEY_CTX_free (PkeyCtx);+ return Result;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ BOOLEAN Result;+ EVP_PKEY *Pkey;++ //+ // Check input parameters.+ //+ if ((RsaContext == NULL) || (EncryptedData == NULL) ||+ (OutData == NULL) || (OutDataSize == NULL))+ {+ return FALSE;+ }++ Result = FALSE;+ Pkey = NULL;++ //+ // Create a context for the decryption operation.+ //++ Pkey = EVP_PKEY_new ();+ if (Pkey == NULL) {+ goto _Exit;+ }++ if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) {+ goto _Exit;+ }++ Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize);++_Exit:+ if (Pkey != NULL) {+ EVP_PKEY_free (Pkey); } return Result;diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; }++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; }++/**+ Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ encrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - X509 key size does not match any known key size.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.+ - Data size is too large for the provided key size (max size is a function of key size+ and hash digest size).++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a public key using RsaSetKey().+ @param[in] InData Data to be encrypted.+ @param[in] InDataSize Size of the data buffer.+ @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer+ to be used when initializing the PRNG. NULL otherwise.+ @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.+ 0 otherwise.+ @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] EncryptedDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepEncrypt (+ IN VOID *RsaContext,+ IN UINT8 *InData,+ IN UINTN InDataSize,+ IN CONST UINT8 *PrngSeed OPTIONAL,+ IN UINTN PrngSeedSize OPTIONAL,+ OUT UINT8 **EncryptedData,+ OUT UINTN *EncryptedDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] PrivateKey A pointer to the DER-encoded private key.+ @param[in] PrivateKeySize Size of the private key buffer.+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+Pkcs1v2Decrypt (+ IN CONST UINT8 *PrivateKey,+ IN UINTN PrivateKeySize,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}++/**+ Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the+ decrypted message in a newly allocated buffer.++ Things that can cause a failure include:+ - Fail to parse private key.+ - Fail to allocate an intermediate buffer.+ - Null pointer provided for a non-optional parameter.++ @param[in] RsaContext A pointer to an RSA context created by RsaNew() and+ provisioned with a private key using RsaSetKey().+ @param[in] EncryptedData Data to be decrypted.+ @param[in] EncryptedDataSize Size of the encrypted buffer.+ @param[out] OutData Pointer to an allocated buffer containing the encrypted+ message.+ @param[out] OutDataSize Size of the encrypted message buffer.++ @retval TRUE Encryption was successful.+ @retval FALSE Encryption failed.++**/+BOOLEAN+EFIAPI+RsaOaepDecrypt (+ IN VOID *RsaContext,+ IN UINT8 *EncryptedData,+ IN UINTN EncryptedDataSize,+ OUT UINT8 **OutData,+ OUT UINTN *OutDataSize+ )+{+ ASSERT (FALSE);+ return FALSE;+}-- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117102): https://edk2.groups.io/g/devel/message/117102 Mute This Topic: https://groups.io/mt/105014749/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions 2024-03-18 21:52 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Chris Ruffin via groups.io ` (2 preceding siblings ...) 2024-03-19 3:52 ` [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Li, Yi @ 2024-03-30 21:59 ` Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 1/3] " Chris Ruffin via groups.io ` (3 more replies) 3 siblings, 4 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-30 21:59 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin From: Chris Ruffin <v-chruffin@microsoft.com> v2 patchset adds: - Add digest length parameter to RsaOaepEncrypt(), RsaOaepDecrypt() so that SHA256, SHA384, SHA512 message digests and mask generation functions can be used with the API. - Add NullLib implementation for BaseCryptLibMbedTls - Cleanups from v1 review - Significantly refactored and expanded test suite: - Use UNIT_TEST_CONTEXT and abstaction to run same tests on Pkcs1v2Encrypt()/Pkcs1v2Decrypt() and RsaOaepEncrypt() RsaOaepDecrypt() - Align DER Certificate / PrivateKey used with Pkcs1v2 APIs with RsaN, RsaE, RsaD parameters used by RsaOaep APIs so that they represent the same keys. - Implement fixed ciphertext test for Pkcs1v2Decrypt(), RsaOaepDecrypt() - Implementation was also checked with wycheproof test vectors (not included in the patch). Chris Ruffin (3): CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions CryptoPkg/Driver: add additional RSAES-OAEP crypto functions CryptoPkg/BaseCryptLibUnitTest: add unit test functions CryptoPkg/Driver/Crypto.c | 130 ++- CryptoPkg/Include/Library/BaseCryptLib.h | 117 +++ .../Pcd/PcdCryptoServiceFamilyEnable.h | 4 + .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 598 ++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 130 ++- .../Pk/CryptPkcs1OaepNull.c | 135 +++- .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 130 ++- .../BaseCryptLibOnProtocolPpi/CryptLib.c | 114 +++ CryptoPkg/Private/Protocol/Crypto.h | 109 ++- .../Library/BaseCryptLib/OaepEncryptTests.c | 758 ++++++++++++++++-- 10 files changed, 2098 insertions(+), 127 deletions(-) -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117249): https://edk2.groups.io/g/devel/message/117249 Mute This Topic: https://groups.io/mt/105239222/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH v2 1/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io @ 2024-03-30 21:59 ` Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-30 21:59 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin, Chris Ruffin, Jiewen Yao, Yi Li, Wenxing Hou From: Chris Ruffin <v-chruffin@microsoft.com> Expand the availability of the RSAES-OAEP crypto capability in BaseCryptLib. Applications using RSA crypto functions directly from OpensslLib can transition to BaseCryptLib to take advantage of the shared crypto feature in CryptoDxe. Pkcs1v2Decrypt(): decryption using DER-encoded private key RsaOaepEncrypt(): encryption using RSA contexts RsaOaepDecrypt(): decryption using RSA contexts Fixes: https://bugzilla.tianocore.org/show_bug.cgi?id=4732 Gihub PR: https://github.com/tianocore/edk2/pull/5473 Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Chris Ruffin <cruffin@millcore.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Include/Library/BaseCryptLib.h | 117 ++++ .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 598 ++++++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 130 +++- .../Pk/CryptPkcs1OaepNull.c | 135 +++- .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 130 +++- 5 files changed, 1056 insertions(+), 54 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index a52bd91ad6..86f784a1d2 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -5,6 +5,7 @@ functionality enabling. Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR> +Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -2147,6 +2148,122 @@ Pkcs1v2Encrypt ( OUT UINTN *EncryptedDataSize ); +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + /** The 3rd parameter of Pkcs7GetSigners will return all embedded X.509 certificate in one given PKCS7 signature. The format is: diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c index ea43c1381c..7634ab1f6f 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -3,7 +3,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - Copyright (C) 2016 Microsoft Corporation. All Rights Reserved. + Copyright (C) Microsoft Corporation. All Rights Reserved. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> **/ @@ -14,6 +14,37 @@ #include <openssl/x509.h> #include <Library/MemoryAllocationLib.h> +/** + Retrieve a pointer to EVP message digest object. + + @param[in] DigestLen Length of the message digest. + +**/ +STATIC +const +EVP_MD * +GetEvpMD ( + IN UINT16 DigestLen + ) +{ + switch (DigestLen) { + case SHA1_DIGEST_SIZE: + return EVP_sha1 (); + break; + case SHA256_DIGEST_SIZE: + return EVP_sha256 (); + break; + case SHA384_DIGEST_SIZE: + return EVP_sha384 (); + break; + case SHA512_DIGEST_SIZE: + return EVP_sha512 (); + break; + default: + return NULL; + } +} + /** Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the encrypted message in a newly allocated buffer. @@ -26,15 +57,20 @@ - Data size is too large for the provided key size (max size is a function of key size and hash digest size). - @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + @param[in] Pkey A pointer to an EVP_PKEY struct that will be used to encrypt the data. - @param[in] PublicKeySize Size of the X509 cert buffer. @param[in] InData Data to be encrypted. @param[in] InDataSize Size of the data buffer. @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer to be used when initializing the PRNG. NULL otherwise. @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted message. @param[out] EncryptedDataSize Size of the encrypted message buffer. @@ -45,50 +81,35 @@ **/ BOOLEAN EFIAPI -Pkcs1v2Encrypt ( - IN CONST UINT8 *PublicKey, - IN UINTN PublicKeySize, +InternalPkcs1v2Encrypt ( + EVP_PKEY *Pkey, IN UINT8 *InData, IN UINTN InDataSize, IN CONST UINT8 *PrngSeed OPTIONAL, IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, OUT UINT8 **EncryptedData, OUT UINTN *EncryptedDataSize ) { BOOLEAN Result; - CONST UINT8 *TempPointer; - X509 *CertData; - EVP_PKEY *InternalPublicKey; EVP_PKEY_CTX *PkeyCtx; UINT8 *OutData; UINTN OutDataSize; + CONST EVP_MD *HashAlg; // // Check input parameters. // - if ((PublicKey == NULL) || (InData == NULL) || + if ((Pkey == NULL) || (InData == NULL) || (EncryptedData == NULL) || (EncryptedDataSize == NULL)) { return FALSE; } - // - // Check public key size. - // - if (PublicKeySize > 0xFFFFFFFF) { - // - // Public key size is too large for implementation. - // - return FALSE; - } - *EncryptedData = NULL; *EncryptedDataSize = 0; Result = FALSE; - TempPointer = NULL; - CertData = NULL; - InternalPublicKey = NULL; PkeyCtx = NULL; OutData = NULL; OutDataSize = 0; @@ -104,6 +125,169 @@ Pkcs1v2Encrypt ( RandomSeed (NULL, 0); } + // + // Create a context for the public key operation. + // + PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); + if (PkeyCtx == NULL) { + // + // Fail to create contex. + // + goto _Exit; + } + + // + // Initialize the context and set the desired padding. + // + if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) || + (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) + { + // + // Fail to initialize the context. + // + goto _Exit; + } + + if (DigestLen != 0) { + HashAlg = GetEvpMD (DigestLen); + if (HashAlg == NULL) { + goto _Exit; + } + + if (EVP_PKEY_CTX_set_rsa_oaep_md (PkeyCtx, HashAlg) <= 0) { + goto _Exit; + } + + if (EVP_PKEY_CTX_set_rsa_mgf1_md (PkeyCtx, HashAlg) <= 0) { + goto _Exit; + } + } + + // + // Determine the required buffer length for malloc'ing. + // + if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to determine output buffer size. + // + goto _Exit; + } + + // + // Allocate a buffer for the output data. + // + OutData = AllocatePool (OutDataSize); + if (OutData == NULL) { + // + // Fail to allocate the output buffer. + // + goto _Exit; + } + + // + // Encrypt Data. + // + if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to encrypt data, need to free the output buffer. + // + FreePool (OutData); + OutData = NULL; + OutDataSize = 0; + goto _Exit; + } + + // + // Encrypt done. + // + *EncryptedData = OutData; + *EncryptedDataSize = OutDataSize; + Result = TRUE; + +_Exit: + // + // Release Resources + // + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to parse X509 certificate. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + will be used to encrypt the data. + @param[in] PublicKeySize Size of the X509 cert buffer. + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Encrypt ( + IN CONST UINT8 *PublicKey, + IN UINTN PublicKeySize, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + CONST UINT8 *TempPointer; + X509 *CertData; + EVP_PKEY *Pkey; + + // + // Check input parameters. + // + if ((PublicKey == NULL) || (InData == NULL) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + // + // Check public key size. + // + if (PublicKeySize > 0xFFFFFFFF) { + // + // Public key size is too large for implementation. + // + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + TempPointer = NULL; + CertData = NULL; + Pkey = NULL; + // // Parse the X509 cert and extract the public key. // @@ -120,52 +304,230 @@ Pkcs1v2Encrypt ( // Extract the public key from the x509 cert in a format that // OpenSSL can use. // - InternalPublicKey = X509_get_pubkey (CertData); - if (InternalPublicKey == NULL) { + Pkey = X509_get_pubkey (CertData); + if (Pkey == NULL) { // // Fail to extract public key. // goto _Exit; } + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, 0, EncryptedData, EncryptedDataSize); + +_Exit: // - // Create a context for the public key operation. + // Release Resources + // + if (CertData != NULL) { + X509_free (CertData); + } + + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + // - PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, NULL); + // Check input parameters. + // + if (((RsaContext == NULL) || (InData == NULL)) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + Pkey = NULL; + + Pkey = EVP_PKEY_new (); + if (Pkey == NULL) { + goto _Exit; + } + + if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) { + goto _Exit; + } + + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, DigestLen, EncryptedData, EncryptedDataSize); + +_Exit: + // + // Release Resources + // + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } + + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] Pkey A pointer to an EVP_PKEY which will decrypt that data. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +InternalPkcs1v2Decrypt ( + EVP_PKEY *Pkey, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY_CTX *PkeyCtx; + UINT8 *TempData; + UINTN TempDataSize; + INTN ReturnCode; + CONST EVP_MD *HashAlg; + + // + // Check input parameters. + // + if ((Pkey == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + PkeyCtx = NULL; + TempData = NULL; + TempDataSize = 0; + + // + // Create a context for the decryption operation. + // + PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); if (PkeyCtx == NULL) { // // Fail to create contex. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_CTK_new() failed\n", __func__)); goto _Exit; } // // Initialize the context and set the desired padding. // - if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) || + if ((EVP_PKEY_decrypt_init (PkeyCtx) <= 0) || (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) { // // Fail to initialize the context. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt_init() failed\n", __func__)); goto _Exit; } + if (DigestLen != 0) { + HashAlg = GetEvpMD (DigestLen); + if (HashAlg == NULL) { + goto _Exit; + } + + if (EVP_PKEY_CTX_set_rsa_oaep_md (PkeyCtx, HashAlg) <= 0) { + goto _Exit; + } + + if (EVP_PKEY_CTX_set_rsa_mgf1_md (PkeyCtx, HashAlg) <= 0) { + goto _Exit; + } + } + // // Determine the required buffer length for malloc'ing. // - if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { + ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { // // Fail to determine output buffer size. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt() failed to determine output buffer size (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // // Allocate a buffer for the output data. // - OutData = AllocatePool (OutDataSize); - if (OutData == NULL) { + TempData = AllocatePool (TempDataSize); + if (TempData == NULL) { // // Fail to allocate the output buffer. // @@ -173,39 +535,179 @@ Pkcs1v2Encrypt ( } // - // Encrypt Data. + // Decrypt Data. // - if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { + ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { // - // Fail to encrypt data, need to free the output buffer. + // Fail to decrypt data, need to free the output buffer. // - FreePool (OutData); - OutData = NULL; - OutDataSize = 0; + FreePool (TempData); + TempData = NULL; + TempDataSize = 0; + + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt(TempData) failed to decrypt (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // - // Encrypt done. + // Decrypt done. // - *EncryptedData = OutData; - *EncryptedDataSize = OutDataSize; - Result = TRUE; + *OutData = TempData; + *OutDataSize = TempDataSize; + Result = TRUE; _Exit: + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + CONST UINT8 *TempPointer; + // - // Release Resources + // Check input parameters. // - if (CertData != NULL) { - X509_free (CertData); + if ((PrivateKey == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + Pkey = NULL; + TempPointer = NULL; + + // + // Parse the private key. + // + TempPointer = PrivateKey; + Pkey = d2i_PrivateKey (EVP_PKEY_RSA, &Pkey, &TempPointer, (UINT32)PrivateKeySize); + if (Pkey == NULL) { + // + // Fail to parse private key. + // + DEBUG ((DEBUG_ERROR, "[%a] d2i_PrivateKey() failed\n", __func__)); + goto _Exit; } - if (InternalPublicKey != NULL) { - EVP_PKEY_free (InternalPublicKey); + Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, 0, OutData, OutDataSize); + +_Exit: + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); } - if (PkeyCtx != NULL) { - EVP_PKEY_CTX_free (PkeyCtx); + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + + // + // Check input parameters. + // + if ((RsaContext == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + Pkey = NULL; + + // + // Create a context for the decryption operation. + // + + Pkey = EVP_PKEY_new (); + if (Pkey == NULL) { + goto _Exit; + } + + if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) { + goto _Exit; + } + + Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, DigestLen, OutData, OutDataSize); + +_Exit: + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); } return Result; diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c index 36508947c5..01d3c5a77f 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -3,7 +3,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - Copyright (C) 2016 Microsoft Corporation. All Rights Reserved. + Copyright (C) Microsoft Corporation. All Rights Reserved. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> **/ @@ -48,3 +48,131 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1OaepNull.c index a686308652..22ac4aefd5 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1OaepNull.c @@ -4,6 +4,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -38,10 +39,8 @@ Pkcs1v2Encrypt ( IN UINTN PublicKeySize, IN UINT8 *InData, IN UINTN InDataSize, - IN CONST UINT8 *PrngSeed, - OPTIONAL - IN UINTN PrngSeedSize, - OPTIONAL + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, OUT UINT8 **EncryptedData, OUT UINTN *EncryptedDataSize ) @@ -49,3 +48,131 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c index 36508947c5..01d3c5a77f 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c @@ -3,7 +3,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - Copyright (C) 2016 Microsoft Corporation. All Rights Reserved. + Copyright (C) Microsoft Corporation. All Rights Reserved. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> **/ @@ -48,3 +48,131 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117250): https://edk2.groups.io/g/devel/message/117250 Mute This Topic: https://groups.io/mt/105239223/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH v2 2/3] CryptoPkg/Driver: add additional RSAES-OAEP crypto functions 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 1/3] " Chris Ruffin via groups.io @ 2024-03-30 21:59 ` Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io 2024-04-01 1:46 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions Li, Yi 3 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-30 21:59 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin, Chris Ruffin, Jiewen Yao, Yi Li, Wenxing Hou From: Chris Ruffin <v-chruffin@microsoft.com> Add new functions to CryptoPkg/Driver. Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Chris Ruffin <cruffin@millcore.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Driver/Crypto.c | 130 +++++++++++++++++- .../Pcd/PcdCryptoServiceFamilyEnable.h | 4 + .../BaseCryptLibOnProtocolPpi/CryptLib.c | 114 +++++++++++++++ CryptoPkg/Private/Protocol/Crypto.h | 109 ++++++++++++++- 4 files changed, 355 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index bdbb4863a9..d11de00bce 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -3589,6 +3589,131 @@ CryptoServicePkcs1v2Encrypt ( return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs1v2Encrypt, Pkcs1v2Encrypt, (PublicKey, PublicKeySize, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); } +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceRsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + return CALL_BASECRYPTLIB (Rsa.Services.RsaOaepEncrypt, RsaOaepEncrypt, (RsaContext, InData, InDataSize, PrngSeed, PrngSeedSize, DigestLen, EncryptedData, EncryptedDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServicePkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs1v2Decrypt, Pkcs1v2Decrypt, (PrivateKey, PrivateKeySize, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceRsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + return CALL_BASECRYPTLIB (Rsa.Services.RsaOaepDecrypt, RsaOaepDecrypt, (RsaContext, EncryptedData, EncryptedDataSize, DigestLen, OutData, OutDataSize), FALSE); +} + /** Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7: Cryptographic Message Syntax Standard". The input signed data could be wrapped @@ -6987,5 +7112,8 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { CryptoServiceX509VerifyCertChain, CryptoServiceX509GetCertFromCertChain, CryptoServiceAsn1GetTag, - CryptoServiceX509GetExtendedBasicConstraints + CryptoServiceX509GetExtendedBasicConstraints, + CryptoServicePkcs1v2Decrypt, + CryptoServiceRsaOaepEncrypt, + CryptoServiceRsaOaepDecrypt, }; diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 74eaf44cca..7b3741381c 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -23,6 +23,7 @@ * Sha1 family Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR> + Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -124,6 +125,7 @@ typedef struct { UINT8 Pkcs7GetCertificatesList : 1; UINT8 AuthenticodeVerify : 1; UINT8 ImageTimestampVerify : 1; + UINT8 Pkcs1v2Decrypt : 1; } Services; UINT32 Family; } Pkcs; @@ -158,6 +160,8 @@ typedef struct { UINT8 Pkcs1Verify : 1; UINT8 GetPrivateKeyFromPem : 1; UINT8 GetPublicKeyFromX509 : 1; + UINT8 RsaOaepEncrypt : 1; + UINT8 RsaOaepDecrypt : 1; } Services; UINT32 Family; } Rsa; diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index 4e31bc278e..c48291b972 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -2825,6 +2825,119 @@ Pkcs1v2Encrypt ( CALL_CRYPTO_SERVICE (Pkcs1v2Encrypt, (PublicKey, PublicKeySize, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); } +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + CALL_CRYPTO_SERVICE (Pkcs1v2Decrypt, (PrivateKey, PrivateKeySize, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + CALL_CRYPTO_SERVICE (RsaOaepEncrypt, (RsaContext, InData, InDataSize, PrngSeed, PrngSeedSize, DigestLen, EncryptedData, EncryptedDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + CALL_CRYPTO_SERVICE (RsaOaepDecrypt, (RsaContext, EncryptedData, EncryptedDataSize, DigestLen, OutData, OutDataSize), FALSE); +} + /** Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7: Cryptographic Message Syntax Standard". The input signed data could be wrapped @@ -2850,6 +2963,7 @@ Pkcs1v2Encrypt ( @retval FALSE Error occurs during the operation. @retval FALSE This interface is not supported. + **/ BOOLEAN EFIAPI diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index 0e0b1d9401..5a471631f1 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -21,7 +21,7 @@ /// the EDK II Crypto Protocol is extended, this version define must be /// increased. /// -#define EDKII_CRYPTO_VERSION 16 +#define EDKII_CRYPTO_VERSION 17 /// /// EDK II Crypto Protocol forward declaration @@ -688,6 +688,110 @@ BOOLEAN OUT UINTN *EncryptedDataSize ); +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_PKCS1V2_DECRYPT)( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_RSA_OAEP_ENCRYPT)( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_RSA_OAEP_DECRYPT)( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + // --------------------------------------------- // PKCS5 @@ -5603,6 +5707,9 @@ struct _EDKII_CRYPTO_PROTOCOL { EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN X509GetCertFromCertChain; EDKII_CRYPTO_ASN1_GET_TAG Asn1GetTag; EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS X509GetExtendedBasicConstraints; + EDKII_CRYPTO_PKCS1V2_DECRYPT Pkcs1v2Decrypt; + EDKII_CRYPTO_RSA_OAEP_ENCRYPT RsaOaepEncrypt; + EDKII_CRYPTO_RSA_OAEP_DECRYPT RsaOaepDecrypt; }; extern GUID gEdkiiCryptoProtocolGuid; -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117251): https://edk2.groups.io/g/devel/message/117251 Mute This Topic: https://groups.io/mt/105239224/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH v2 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 1/3] " Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io @ 2024-03-30 21:59 ` Chris Ruffin via groups.io 2024-04-01 1:46 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions Li, Yi 3 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-30 21:59 UTC (permalink / raw) To: devel; +Cc: Chris Ruffin, Chris Ruffin, Jiewen Yao, Yi Li, Wenxing Hou From: Chris Ruffin <v-chruffin@microsoft.com> Add unit test functions: TestVerifyPkcs1v2EncryptInterface() TestVerifyRsaOaepEncryptInterface() TestVerifyEncrypt() TestVerifyDecrypt() TestVerifyEncryptDecrypt() Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Chris Ruffin <cruffin@millcore.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- .../Library/BaseCryptLib/OaepEncryptTests.c | 758 ++++++++++++++++-- 1 file changed, 687 insertions(+), 71 deletions(-) diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c index 22a4ea7e46..b4ecb4aff0 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/OaepEncryptTests.c @@ -1,20 +1,21 @@ /** @file - This is a unit test for RSA OAEP encrypt. + This is a unit test for RSA OAEP encrypt/decrypt. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + Copyright (c) Microsoft Corporation. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "TestBaseCryptLib.h" -CONST UINT8 RandSeed[] = "This is the random seed for PRNG verification."; +STATIC CONST UINT8 RandSeed[] = "This is the random seed for PRNG verification."; // // Self signed X509 certificate // CN = ca.self // O = Intel // -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 SelfTestCert[] = { +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 SelfTestCert[] = { 0x30, 0x82, 0x03, 0x90, 0x30, 0x82, 0x02, 0x78, 0x02, 0x09, 0x00, 0xE4, 0xDF, 0x47, 0x80, 0xEF, 0x4B, 0x3C, 0x6D, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x81, 0x89, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, @@ -75,7 +76,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 SelfTestCert[] = { 0x5B, 0x64, 0x81, 0x13, }; -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 PrivateKey[] = { +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 PrivateKey[] = { 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBC, 0xE4, 0x67, 0xDC, 0xC7, 0xEA, 0x6F, 0x8A, 0xA7, 0xCC, 0xB2, 0x54, 0x47, 0x48, 0x6A, 0xE2, 0x39, 0xFF, 0xC2, 0x48, 0x58, 0x34, 0x07, 0x03, 0x6D, 0x39, 0xB3, 0x67, 0x46, 0x4C, 0xBC, 0xA0, 0xFA, 0x4E, 0x64, 0x23, @@ -153,52 +154,310 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 PrivateKey[] = { 0x86, 0x10, 0x09, 0x88, 0x6C, 0x35, 0x60, 0xF2, }; -UNIT_TEST_STATUS +// The following RSA key componets were extracted from the above private key with openssl. +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 RsaN[] = { + 0x00, + 0xbc,0xe4, 0x67, 0xdc, 0xc7, 0xea, 0x6f, 0x8a, 0xa7, 0xcc, 0xb2, 0x54, 0x47, 0x48, 0x6a, 0xe2, + 0x39,0xff, 0xc2, 0x48, 0x58, 0x34, 0x07, 0x03, 0x6d, 0x39, 0xb3, 0x67, 0x46, 0x4c, 0xbc, 0xa0, + 0xfa,0x4e, 0x64, 0x23, 0x56, 0x47, 0x7b, 0xc9, 0x1a, 0x2a, 0x55, 0x42, 0x54, 0x10, 0x18, 0x30, + 0x92,0x60, 0x30, 0x5b, 0x9e, 0xc0, 0x65, 0xd2, 0xd4, 0x05, 0x4a, 0xa6, 0x10, 0x66, 0x04, 0xa9, + 0x54,0x4e, 0xee, 0x49, 0x39, 0x43, 0x65, 0x1e, 0x2e, 0x28, 0xde, 0x79, 0x24, 0xa9, 0x7e, 0xd8, + 0x5b,0xbc, 0x2f, 0x46, 0x6a, 0xb7, 0xb6, 0x0d, 0x17, 0x88, 0x37, 0x52, 0x5c, 0xfe, 0x93, 0xc0, + 0xe2,0xfd, 0x6a, 0x08, 0x1b, 0xfb, 0xd1, 0x87, 0xbd, 0xbd, 0x58, 0x57, 0x2c, 0x06, 0x5d, 0xd2, + 0x7d,0x52, 0xe2, 0x49, 0x8e, 0xdc, 0xe5, 0x26, 0xbd, 0x92, 0x60, 0xb0, 0x3f, 0x58, 0x5e, 0x52, + 0xd7,0x91, 0xda, 0x93, 0x62, 0x8d, 0x71, 0x80, 0x53, 0xba, 0x15, 0xc4, 0x1f, 0xf3, 0xbd, 0xe0, + 0xc5,0xa4, 0xb8, 0xd3, 0x64, 0x12, 0x14, 0x1b, 0x11, 0x6b, 0x7b, 0xc2, 0x92, 0xc7, 0xe2, 0x94, + 0x0b,0xb8, 0x67, 0x38, 0x48, 0x63, 0x11, 0x74, 0x25, 0x7c, 0x37, 0xc3, 0xb2, 0xae, 0xd9, 0xa7, + 0x17,0x9c, 0x4b, 0x9d, 0x6c, 0x27, 0xb0, 0x87, 0x16, 0x6b, 0xf2, 0x96, 0xe5, 0x1d, 0x37, 0x27, + 0xde,0xf2, 0x98, 0xb7, 0x81, 0x08, 0xd9, 0x7a, 0xba, 0x84, 0x14, 0x61, 0x60, 0x48, 0xce, 0xce, + 0x51,0x73, 0xf4, 0xdb, 0xf1, 0x5f, 0x7a, 0x17, 0x71, 0x4f, 0xc1, 0x0b, 0xce, 0xc7, 0x31, 0xc1, + 0x4e,0xa3, 0xee, 0x6f, 0x72, 0x97, 0x90, 0xfb, 0x8b, 0x54, 0x9f, 0x82, 0x5b, 0x48, 0x5a, 0xf1, + 0xad,0x8b, 0x3a, 0xcd, 0xca, 0xb2, 0x8b, 0x7a, 0x53, 0xd4, 0xf7, 0x71, 0x16, 0x75, 0xa7, 0x35, +}; + +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 RsaE[] = { + 0x01, 0x00, 0x01 +}; + +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 RsaD[] = { + 0x13, 0xf7, 0xd1, 0x42, 0xf5, 0x9f, 0x42, 0xcb, 0x55, 0x91, 0xbe, 0x08, 0x4a, 0xc0, 0xcd, 0x0b, + 0xbd, 0x35, 0xdc, 0x43, 0xe9, 0x8f, 0x16, 0x6e, 0xb6, 0x4d, 0x33, 0x39, 0xe7, 0xa4, 0x95, 0x0c, + 0x2f, 0x69, 0xba, 0x0c, 0x42, 0x42, 0xac, 0x43, 0x46, 0x10, 0xd3, 0x92, 0x7f, 0x70, 0x74, 0x1e, + 0x2e, 0x5b, 0x1c, 0xc1, 0x92, 0xb6, 0xa4, 0x0c, 0xf5, 0x7c, 0xd9, 0xb7, 0x54, 0x64, 0x74, 0x79, + 0xb1, 0xff, 0xe6, 0x10, 0xb7, 0x8c, 0xf8, 0x53, 0x88, 0x6d, 0xa9, 0x97, 0x04, 0xd9, 0x26, 0x1f, + 0x99, 0x12, 0xfb, 0xac, 0x65, 0xfb, 0xa5, 0xb3, 0x1c, 0x99, 0xb9, 0xbf, 0x6b, 0x35, 0x3e, 0x49, + 0x55, 0xb5, 0x94, 0x4f, 0xe7, 0x25, 0x67, 0xb1, 0x01, 0xcd, 0xd2, 0x58, 0xe4, 0xbe, 0x87, 0x8c, + 0x88, 0xd3, 0x0a, 0x38, 0xdc, 0x71, 0x5d, 0x88, 0x0a, 0xe2, 0x3e, 0x76, 0x63, 0x3b, 0xe4, 0x3c, + 0x8f, 0x2f, 0x29, 0x1d, 0xd1, 0x66, 0x8d, 0xc0, 0x4a, 0x68, 0x15, 0x90, 0x4c, 0x95, 0x61, 0xf4, + 0xfd, 0xe8, 0xfa, 0x9c, 0x6c, 0x00, 0x22, 0x23, 0xd5, 0x17, 0x6e, 0xee, 0xa8, 0xd8, 0x70, 0xc5, + 0x74, 0xea, 0x09, 0x13, 0x7f, 0x0c, 0x37, 0x4d, 0x50, 0xcd, 0xe9, 0x16, 0xc2, 0xd5, 0xde, 0x5e, + 0xc3, 0xfc, 0x46, 0x08, 0xf1, 0x99, 0xc0, 0xb4, 0x28, 0xfd, 0x2b, 0x29, 0xef, 0x76, 0xd7, 0x04, + 0x4f, 0x02, 0x54, 0x16, 0x54, 0x55, 0x20, 0xec, 0xbc, 0xbf, 0x85, 0x5f, 0x12, 0xcc, 0xfc, 0x0d, + 0xf2, 0xef, 0xfc, 0x4d, 0x3e, 0xa2, 0x5e, 0x97, 0xfe, 0x35, 0x10, 0x0f, 0x53, 0x1f, 0x80, 0xd5, + 0xc0, 0xb4, 0xe9, 0xe9, 0x31, 0x4c, 0x89, 0x14, 0x72, 0x39, 0x65, 0x89, 0xef, 0x7a, 0x51, 0x4a, + 0xb9, 0xa9, 0xcc, 0x1b, 0x52, 0xb0, 0x02, 0x52, 0x65, 0x2f, 0x0b, 0x89, 0x41, 0x70, 0x1e, 0x01, +}; + +// test case = "123\0" +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 Msg1230[] = { + 0x31, 0x32, 0x33, 0x00 +}; + +// Ciphertext of the test case using RSAES-OAEP2048 with SHA1 MD/BGF1 created with openssl. +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 Ct1230RsaesOaepMdSha1Mgf1Sha1[] = { + 0x88, 0x5d, 0xf3, 0x00, 0x66, 0x77, 0x91, 0x94, 0x5c, 0x8d, 0x45, 0xb6, 0xb2, 0x24, 0x26, 0x26, + 0x37, 0xbe, 0xe0, 0x87, 0x4f, 0x50, 0xbf, 0x88, 0xde, 0x5d, 0xe9, 0xe0, 0xb2, 0x7e, 0x66, 0xfa, + 0x6c, 0xfd, 0x0d, 0x19, 0x48, 0x41, 0xfe, 0x7a, 0x86, 0xa8, 0x28, 0xc2, 0x01, 0xcf, 0x76, 0xd7, + 0xea, 0xab, 0x6d, 0xc3, 0x5e, 0x2c, 0x36, 0x04, 0xc0, 0x54, 0xc2, 0x68, 0x67, 0xe7, 0x04, 0x27, + 0x56, 0xbe, 0x53, 0xb5, 0x80, 0x94, 0xd8, 0xde, 0x8c, 0x75, 0x69, 0x42, 0xba, 0x55, 0xd6, 0x2c, + 0xda, 0x22, 0xe6, 0x09, 0xf6, 0x90, 0x27, 0x4b, 0x10, 0x54, 0x40, 0xa0, 0x74, 0x31, 0xdb, 0x5f, + 0x80, 0x06, 0xc7, 0x67, 0x96, 0xe8, 0x45, 0xea, 0x7f, 0x72, 0x18, 0x24, 0xe8, 0x0d, 0x46, 0xc2, + 0xa0, 0x83, 0xca, 0x71, 0xca, 0x91, 0x4b, 0x89, 0x80, 0x61, 0x01, 0x8e, 0xcf, 0xa1, 0x68, 0x81, + 0x2d, 0xf2, 0x08, 0xd2, 0x02, 0x9e, 0xc0, 0xa4, 0x91, 0x71, 0x90, 0x84, 0x2f, 0x4e, 0x18, 0x37, + 0x9b, 0x61, 0x0b, 0xf5, 0x88, 0xf7, 0x6b, 0x87, 0xb9, 0x4e, 0x31, 0xda, 0xf3, 0xb5, 0xe2, 0x60, + 0x4d, 0xd9, 0x52, 0x99, 0x6b, 0x19, 0x98, 0xa2, 0x28, 0xaa, 0xeb, 0x5a, 0x33, 0xef, 0xf1, 0x4e, + 0x29, 0x86, 0xbf, 0x70, 0x08, 0xfd, 0x34, 0x8a, 0x8c, 0x6d, 0xef, 0xc4, 0xa1, 0xfe, 0xdf, 0x4d, + 0xeb, 0xf0, 0x2c, 0x4c, 0xf5, 0xb3, 0xe8, 0xf8, 0xc3, 0x45, 0xc7, 0x6b, 0x59, 0x1c, 0x9b, 0xd9, + 0x52, 0xdf, 0x65, 0x87, 0x18, 0xd2, 0x6d, 0xff, 0x8b, 0x98, 0x2a, 0x97, 0xeb, 0x93, 0xea, 0x6a, + 0x23, 0x23, 0xc6, 0x32, 0xf5, 0xea, 0x45, 0xe3, 0x99, 0xa0, 0x4d, 0x4b, 0x8f, 0xf8, 0x1d, 0xad, + 0xa9, 0x97, 0xa2, 0xd6, 0xaf, 0x5e, 0x11, 0xf7, 0x5f, 0x28, 0xfb, 0x38, 0x80, 0x38, 0x50, 0xc4, +}; + +// Ciphertext of the test case using RSAES-OAEP2048 with SHA256 MD/BGF1 created with openssl. +GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT8 Ct1230RsaesOaep2048MdSha256Mgf1Sha256[] = { + 0xa7, 0x20, 0xa9, 0x31, 0xb5, 0xad, 0x83, 0x0a, 0x07, 0xee, 0x36, 0x46, 0xa5, 0x78, 0x3a, 0xda, + 0x9d, 0xdf, 0xe6, 0x05, 0x0f, 0x7c, 0x46, 0xfe, 0x5f, 0xd6, 0x58, 0x16, 0xb6, 0xaa, 0x82, 0x7c, + 0x58, 0x8a, 0x52, 0x14, 0x12, 0x29, 0x6f, 0x62, 0x80, 0xa7, 0x61, 0xfe, 0x29, 0x72, 0x6f, 0x73, + 0xf6, 0x2f, 0x54, 0x38, 0x58, 0x7b, 0xbd, 0xa1, 0x2f, 0x9d, 0x12, 0x83, 0x72, 0xbc, 0x3d, 0x29, + 0x65, 0x39, 0xcb, 0x93, 0x95, 0x3e, 0x73, 0xc9, 0x6f, 0xb9, 0xe8, 0xd5, 0x8b, 0x91, 0x0d, 0x87, + 0x7e, 0x22, 0xb5, 0x93, 0x3d, 0xa8, 0x4a, 0xd9, 0x1a, 0x13, 0xf7, 0xf4, 0x7f, 0x16, 0x42, 0xfe, + 0x63, 0x10, 0x7e, 0xa1, 0xe5, 0x04, 0xcf, 0xed, 0x93, 0x2d, 0x16, 0x3b, 0x79, 0x1f, 0x53, 0x41, + 0xe3, 0xca, 0x69, 0x18, 0x6a, 0xe5, 0xec, 0x9a, 0xce, 0xbc, 0x47, 0xf6, 0x77, 0x9a, 0x5c, 0xea, + 0xac, 0x7e, 0x28, 0xeb, 0x1e, 0xfe, 0x75, 0xa6, 0xbf, 0x1e, 0xfd, 0x1c, 0x63, 0x69, 0x47, 0x04, + 0xaf, 0x69, 0x7e, 0x1c, 0xa1, 0x7f, 0x00, 0xcf, 0xec, 0x16, 0x34, 0xd9, 0xde, 0x91, 0x0e, 0x0f, + 0x0b, 0x1e, 0x66, 0xc3, 0x41, 0x88, 0x43, 0xbe, 0xa3, 0x2a, 0x7c, 0x87, 0xff, 0xc0, 0x67, 0xdc, + 0xc7, 0xeb, 0x28, 0x07, 0x00, 0x72, 0x85, 0x17, 0xca, 0x05, 0x9f, 0x29, 0x6b, 0xad, 0xc6, 0xae, + 0x1c, 0x4a, 0xf2, 0xfe, 0x97, 0xc7, 0x6e, 0x4b, 0xbf, 0xfd, 0x46, 0xbe, 0xf8, 0x76, 0xc9, 0x70, + 0x58, 0x3a, 0x73, 0xcc, 0x34, 0xda, 0xfe, 0x5b, 0x6d, 0x98, 0x74, 0x95, 0x85, 0xc7, 0xc9, 0x84, + 0x02, 0xa8, 0x97, 0x13, 0xa3, 0x83, 0xcb, 0x28, 0x3d, 0xbb, 0x2b, 0x3b, 0x45, 0xf1, 0x6e, 0xc5, + 0x37, 0x23, 0x21, 0xe6, 0x74, 0x2d, 0x48, 0x19, 0x97, 0xaf, 0xee, 0x3d, 0x9b, 0xd0, 0x05, 0xc7 +}; + +typedef struct _OAEP_ENC_DEC_TEST_CONTEXT OAEP_ENC_DEC_TEST_CONTEXT; +typedef +BOOLEAN +(EFIAPI *OAEP_TEST_ENCRYPT)( + IN OAEP_ENC_DEC_TEST_CONTEXT *TestContext, + IN CONST UINT8 *ClearText, + IN UINTN ClearTextSize, + IN CONST UINT8 *PrngSeed, + IN UINTN PrngSeedSize, + IN UINT16 DigestLen, + OUT UINT8 **CipherText, + OUT UINTN *CipherTextSize + ); + +typedef +BOOLEAN +(EFIAPI *OAEP_TEST_DECRYPT)( + IN OAEP_ENC_DEC_TEST_CONTEXT *TestContext, + IN CONST UINT8 *CipherText, + IN UINTN CipherTextSize, + IN UINT16 DigestLen, + OUT UINT8 **ClearText, + OUT UINTN *ClearTextSize + ); + +typedef struct _OAEP_ENC_DEC_TEST_CONTEXT { + CONST UINT8 *SelfTestCert; + UINTN SelfTestCertSize; + CONST UINT8 *PrivateKey; + UINTN PrivateKeySize; + CONST UINT8 *RsaN; + UINTN RsaNSize; + CONST UINT8 *RsaE; + UINTN RsaESize; + CONST UINT8 *RsaD; + UINTN RsaDSize; + CONST UINT8 *PrngSeed; + UINTN PrngSeedSize; + CONST UINT8 *ClearText; + UINTN ClearTextSize; + CONST UINT8 *CipherText; + UINTN CipherTextSize; + UINT16 DigestLen; + OAEP_TEST_ENCRYPT Encrypt; + OAEP_TEST_DECRYPT Decrypt; + UNIT_TEST_STATUS Expect; +} OAEP_ENC_DEC_TEST_CONTEXT; + +BOOLEAN EFIAPI -TestVerifyOaepEncrypt ( - IN UNIT_TEST_CONTEXT Context +CallPkcs1v2Encrypt ( + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx, + CONST UINT8 *ClearText, + UINTN ClearTextSize, + CONST UINT8 *PrngSeed, + UINTN PrngSeedSize, + UINT16 DigestLen, + UINT8 **CipherText, + UINTN *CipherTextSize ) { BOOLEAN Status; - UINT8 File[4]; - UINT8 *OutBuffer; - UINTN OutBufferSize; - UINT8 *OutBuffer2; - UINTN OutBuffer2Size; - // Create a file and add content '123' in it - File[0] = '1'; - File[1] = '2'; - File[2] = '3'; - File[3] = 0; + Status = Pkcs1v2Encrypt ( + TestCtx->SelfTestCert, + TestCtx->SelfTestCertSize, + (UINT8 *)ClearText, + ClearTextSize, + PrngSeed, + PrngSeedSize, + CipherText, + CipherTextSize + ); - OutBuffer = NULL; - OutBufferSize = 0; - OutBuffer2 = NULL; - OutBuffer2Size = 0; + return Status; +} - Status = Pkcs1v2Encrypt ( - SelfTestCert, - (UINTN)sizeof (SelfTestCert), - File, - (UINTN)sizeof (File), - NULL, - 0, - &OutBuffer, - (UINTN *)&OutBufferSize +BOOLEAN +EFIAPI +CallPkcs1v2Decrypt ( + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx, + CONST UINT8 *CipherText, + UINTN CipherTextSize, + UINT16 DigestLen, + UINT8 **ClearText, + UINTN *ClearTextSize + ) +{ + BOOLEAN Status; + + Status = Pkcs1v2Decrypt ( + TestCtx->PrivateKey, + TestCtx->PrivateKeySize, + (UINT8 *)CipherText, + CipherTextSize, + ClearText, + ClearTextSize ); + return Status; +} + +BOOLEAN +EFIAPI +CallRsaOaepEncrypt ( + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx, + CONST UINT8 *ClearText, + UINTN ClearTextSize, + CONST UINT8 *RandSeedIn, + UINTN RandSeedSizeIn, + UINT16 DigestLen, + UINT8 **CipherText, + UINTN *CipherTextSize + ) +{ + VOID *RsaContext = NULL; + BOOLEAN Status; + + RsaContext = RsaNew (); + UT_ASSERT_FALSE (RsaContext == NULL); + + Status = RsaSetKey (RsaContext, RsaKeyN, TestCtx->RsaN, TestCtx->RsaNSize); UT_ASSERT_TRUE (Status); - Status = Pkcs1v2Encrypt ( - SelfTestCert, - (UINTN)sizeof (SelfTestCert), - File, - (UINTN)4, - NULL, - 0, - &OutBuffer2, - (UINTN *)&OutBuffer2Size + Status = RsaSetKey (RsaContext, RsaKeyE, TestCtx->RsaE, TestCtx->RsaESize); + UT_ASSERT_TRUE (Status); + + Status = RsaOaepEncrypt ( + RsaContext, + (UINT8 *)ClearText, + ClearTextSize, + RandSeedIn, + RandSeedSizeIn, + DigestLen, + CipherText, + CipherTextSize ); + + return Status; +} + +BOOLEAN +EFIAPI +CallRsaOaepDecrypt ( + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx, + CONST UINT8 *CipherText, + UINTN CipherTextSize, + UINT16 DigestLen, + UINT8 **ClearText, + UINTN *ClearTextSize + ) +{ + VOID *RsaContext = NULL; + BOOLEAN Status; + + RsaContext = RsaNew (); + UT_ASSERT_FALSE (RsaContext == NULL); + + Status = RsaSetKey (RsaContext, RsaKeyN, TestCtx->RsaN, TestCtx->RsaNSize); + UT_ASSERT_TRUE (Status); + + Status = RsaSetKey (RsaContext, RsaKeyE, TestCtx->RsaE, TestCtx->RsaESize); + UT_ASSERT_TRUE (Status); + + Status = RsaSetKey (RsaContext, RsaKeyD, TestCtx->RsaD, TestCtx->RsaDSize); + UT_ASSERT_TRUE (Status); + + Status = RsaOaepDecrypt ( + RsaContext, + (UINT8 *)CipherText, + CipherTextSize, + DigestLen, + ClearText, + ClearTextSize + ); + + return Status; +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyEncrypt ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 *OutBuffer = NULL; + UINTN OutBufferSize = 0; + UINT8 *OutBuffer2 = NULL; + UINTN OutBuffer2Size = 0; + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx; + + TestCtx = (OAEP_ENC_DEC_TEST_CONTEXT *)Context; + + Status = TestCtx->Encrypt ( + TestCtx, + TestCtx->ClearText, + TestCtx->ClearTextSize, + TestCtx->PrngSeed, + TestCtx->PrngSeedSize, + TestCtx->DigestLen, + &OutBuffer, + &OutBufferSize + ); + UT_ASSERT_TRUE (Status); + + Status = TestCtx->Encrypt ( + TestCtx, + TestCtx->ClearText, + TestCtx->ClearTextSize, + TestCtx->PrngSeed, + TestCtx->PrngSeedSize, + TestCtx->DigestLen, + &OutBuffer2, + &OutBuffer2Size + ); UT_ASSERT_TRUE (Status); // TRUE - the two OutBuffers are indentical. That means the Oaep encrypt result is incorrect. @@ -217,33 +476,34 @@ TestVerifyOaepEncrypt ( OutBuffer2Size = 0; } - Status = Pkcs1v2Encrypt ( - SelfTestCert, - (UINTN)sizeof (SelfTestCert), - File, - (UINTN)4, - RandSeed, - (UINTN)sizeof (RandSeed), - &OutBuffer, - (UINTN *)&OutBufferSize - ); - UT_ASSERT_TRUE (Status); + return UNIT_TEST_PASSED; +} - Status = Pkcs1v2Encrypt ( - SelfTestCert, - (UINTN)sizeof (SelfTestCert), - File, - (UINTN)4, - RandSeed, - (UINTN)sizeof (RandSeed), - &OutBuffer2, - (UINTN *)&OutBuffer2Size - ); +UNIT_TEST_STATUS +EFIAPI +TestVerifyDecrypt ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 *OutBuffer = NULL; + UINTN OutBufferSize = 0; + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx; + + TestCtx = Context; + + Status = TestCtx->Decrypt ( + TestCtx, + TestCtx->CipherText, + TestCtx->CipherTextSize, + TestCtx->DigestLen, + &OutBuffer, + &OutBufferSize + ); UT_ASSERT_TRUE (Status); - // TRUE - the two OutBuffers are indentical. That means the Oaep encrypt result is incorrect. - Status = (CompareMem (OutBuffer, OutBuffer2, OutBufferSize >= OutBuffer2Size ? OutBufferSize : OutBuffer2Size) == 0); - UT_ASSERT_FALSE (Status); + UT_ASSERT_TRUE (CompareMem (OutBuffer, TestCtx->ClearText, OutBufferSize >= TestCtx->ClearTextSize ? OutBufferSize : TestCtx->ClearTextSize) == 0); + UT_ASSERT_TRUE (OutBufferSize == TestCtx->ClearTextSize); if (OutBuffer) { FreePool (OutBuffer); @@ -251,16 +511,85 @@ TestVerifyOaepEncrypt ( OutBufferSize = 0; } - if (OutBuffer2) { - FreePool (OutBuffer2); - OutBuffer2 = NULL; - OutBuffer2Size = 0; + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyEncryptDecrypt ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 *ClearText = NULL; + UINTN ClearTextSize = 0; + UINT8 *CipherText = NULL; + UINTN CipherTextSize = 0; + OAEP_ENC_DEC_TEST_CONTEXT *TestCtx; + + TestCtx = Context; + + Status = TestCtx->Encrypt ( + TestCtx, + TestCtx->ClearText, + TestCtx->ClearTextSize, + TestCtx->PrngSeed, + TestCtx->PrngSeedSize, + TestCtx->DigestLen, + &CipherText, + &CipherTextSize + ); + UT_ASSERT_TRUE (Status); + + Status = TestCtx->Decrypt ( + TestCtx, + CipherText, + CipherTextSize, + TestCtx->DigestLen, + &ClearText, + &ClearTextSize + ); + + if (TestCtx->Expect == UNIT_TEST_PASSED) { + UT_ASSERT_TRUE (Status); + } else { + UT_ASSERT_FALSE (Status); } + if (TestCtx->Expect == UNIT_TEST_PASSED) { + UT_ASSERT_TRUE (CompareMem (ClearText, TestCtx->ClearText, ClearTextSize >= TestCtx->ClearTextSize ? ClearTextSize : TestCtx->ClearTextSize) == 0); + UT_ASSERT_TRUE (ClearTextSize == TestCtx->ClearTextSize); + } + + if (CipherText) { + FreePool (CipherText); + CipherText = NULL; + CipherTextSize = 0; + } + + if (ClearText) { + FreePool (ClearText); + ClearText = NULL; + ClearTextSize = 0; + } + + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyPkcs1v2EncryptInterface ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BOOLEAN Status; + UINT8 *OutBuffer; + UINTN OutBufferSize; + Status = Pkcs1v2Encrypt ( NULL, (UINTN)sizeof (SelfTestCert), - File, + (UINT8 *)Msg1230, (UINTN)4, NULL, 0, @@ -272,7 +601,7 @@ TestVerifyOaepEncrypt ( Status = Pkcs1v2Encrypt ( SelfTestCert, (UINTN)sizeof (SelfTestCert), - File, + (UINT8 *)Msg1230, (UINTN)4, NULL, 0, @@ -284,7 +613,7 @@ TestVerifyOaepEncrypt ( Status = Pkcs1v2Encrypt ( SelfTestCert, (UINTN)sizeof (SelfTestCert), - File, + (UINT8 *)Msg1230, (UINTN)4, NULL, 0, @@ -296,11 +625,298 @@ TestVerifyOaepEncrypt ( return UNIT_TEST_PASSED; } +UNIT_TEST_STATUS +EFIAPI +TestVerifyRsaOaepEncryptInterface ( + IN UNIT_TEST_CONTEXT Context + ) +{ + VOID *RsaContext = NULL; + BOOLEAN Status; + UINT8 *OutBuffer; + UINTN OutBufferSize; + + RsaContext = RsaNew (); + UT_ASSERT_FALSE (RsaContext == NULL); + + Status = RsaSetKey (RsaContext, RsaKeyN, RsaN, sizeof (RsaN)); + UT_ASSERT_TRUE (Status); + + Status = RsaSetKey (RsaContext, RsaKeyE, RsaE, sizeof (RsaE)); + UT_ASSERT_TRUE (Status); + + Status = RsaOaepEncrypt ( + NULL, + (UINT8 *)Msg1230, + (UINTN)4, + NULL, + 0, + 0, + &OutBuffer, + (UINTN *)&OutBufferSize + ); + UT_ASSERT_FALSE (Status); + + Status = RsaOaepEncrypt ( + RsaContext, + (UINT8 *)Msg1230, + (UINTN)4, + NULL, + 0, + 0, + (UINT8 **)NULL, + (UINTN *)&OutBufferSize + ); + UT_ASSERT_FALSE (Status); + + Status = RsaOaepEncrypt ( + RsaContext, + (UINT8 *)Msg1230, + (UINTN)4, + NULL, + 0, + 0, + &OutBuffer, + (UINTN *)NULL + ); + UT_ASSERT_FALSE (Status); + + return UNIT_TEST_PASSED; +} + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyPkcs1v2Msg1230 = { + .SelfTestCert = SelfTestCert, + .SelfTestCertSize = sizeof (SelfTestCert), + .PrivateKey = PrivateKey, + .PrivateKeySize = sizeof (PrivateKey), + .RsaN = NULL, + .RsaNSize = 0, + .RsaE = NULL, + .RsaESize = 0, + .RsaD = NULL, + .RsaDSize = 0, + .PrngSeed = NULL, + .PrngSeedSize = 0, + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallPkcs1v2Encrypt, + .Decrypt = CallPkcs1v2Decrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyPkcs1v2Msg1230PrngSeed = { + .SelfTestCert = SelfTestCert, + .SelfTestCertSize = sizeof (SelfTestCert), + .PrivateKey = PrivateKey, + .PrivateKeySize = sizeof (PrivateKey), + .RsaN = NULL, + .RsaNSize = 0, + .RsaE = NULL, + .RsaESize = 0, + .RsaD = NULL, + .RsaDSize = 0, + .PrngSeed = RandSeed, + .PrngSeedSize = sizeof (RandSeed), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallPkcs1v2Encrypt, + .Decrypt = CallPkcs1v2Decrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyRsaOaepMsg1230 = { + .SelfTestCert = NULL, + .SelfTestCertSize = 0, + .PrivateKey = NULL, + .PrivateKeySize = 0, + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .PrngSeed = NULL, + .PrngSeedSize = 0, + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallRsaOaepEncrypt, + .Decrypt = CallRsaOaepDecrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyRsaOaepMsg1230PrngSeed = { + .SelfTestCert = NULL, + .SelfTestCertSize = 0, + .PrivateKey = NULL, + .PrivateKeySize = 0, + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .PrngSeed = RandSeed, + .PrngSeedSize = sizeof (RandSeed), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallRsaOaepEncrypt, + .Decrypt = CallRsaOaepDecrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyPkcs1v2EncryptRsaOaepDecrypt = { + .SelfTestCert = SelfTestCert, + .SelfTestCertSize = sizeof (SelfTestCert), + .PrivateKey = PrivateKey, + .PrivateKeySize = sizeof (PrivateKey), + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallPkcs1v2Encrypt, + .Decrypt = CallRsaOaepDecrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyRsaOaepEncryptPkcs1v2Decrypt = { + .SelfTestCert = SelfTestCert, + .SelfTestCertSize = sizeof (SelfTestCert), + .PrivateKey = PrivateKey, + .PrivateKeySize = sizeof (PrivateKey), + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallRsaOaepEncrypt, + .Decrypt = CallPkcs1v2Decrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyRsaesOaep2048MdDefaultBgf1Default = { + .SelfTestCert = NULL, + .SelfTestCertSize = 0, + .PrivateKey = NULL, + .PrivateKeySize = 0, + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = 0, + .Encrypt = CallRsaOaepEncrypt, + .Decrypt = CallRsaOaepDecrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyRsaesOaep2048MdSha1Mgf1Sha1 = { + .SelfTestCert = NULL, + .SelfTestCertSize = 0, + .PrivateKey = NULL, + .PrivateKeySize = 0, + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaepMdSha1Mgf1Sha1, + .CipherTextSize = sizeof (Ct1230RsaesOaepMdSha1Mgf1Sha1), + .DigestLen = SHA1_DIGEST_SIZE, + .Encrypt = CallRsaOaepEncrypt, + .Decrypt = CallRsaOaepDecrypt, + .Expect = UNIT_TEST_PASSED +}; + +OAEP_ENC_DEC_TEST_CONTEXT mTestVerifyRsaesOaep2048MdSha256Mgf1Sha256 = { + .SelfTestCert = NULL, + .SelfTestCertSize = 0, + .PrivateKey = NULL, + .PrivateKeySize = 0, + .RsaN = RsaN, + .RsaNSize = sizeof (RsaN), + .RsaE = RsaE, + .RsaESize = sizeof (RsaE), + .RsaD = RsaD, + .RsaDSize = sizeof (RsaD), + .ClearText = Msg1230, + .ClearTextSize = sizeof (Msg1230), + .CipherText = Ct1230RsaesOaep2048MdSha256Mgf1Sha256, + .CipherTextSize = sizeof (Ct1230RsaesOaep2048MdSha256Mgf1Sha256), + .DigestLen = SHA256_DIGEST_SIZE, + .Encrypt = CallRsaOaepEncrypt, + .Decrypt = CallRsaOaepDecrypt, + .Expect = UNIT_TEST_PASSED +}; + TEST_DESC mOaepTest[] = { // // -----Description--------------------------------------Class----------------------Function-----------------Pre---Post--Context // - { "TestVerifyOaepEncrypt()", "CryptoPkg.BaseCryptLib.Pkcs1v2Encrypt", TestVerifyOaepEncrypt, NULL, NULL, NULL }, + // Pkcs1v2Encrypt / Decrypt + { "Pkcs1v2Encrypt (Interface)", "CryptoPkg.BaseCryptLib.Pkcs1v2Encrypt.Interface", TestVerifyPkcs1v2EncryptInterface, NULL, NULL, &mTestVerifyPkcs1v2Msg1230 }, + { "Pkcs1v2Encrypt (NoSeed)", "CryptoPkg.BaseCryptLib.Pkcs1v2Encrypt.NoSeed", TestVerifyEncrypt, NULL, NULL, &mTestVerifyPkcs1v2Msg1230 }, + { "Pkcs1v2Encrypt (Seeded)", "CryptoPkg.BaseCryptLib.Pkcs1v2Encrypt.Seeded", TestVerifyEncrypt, NULL, NULL, &mTestVerifyPkcs1v2Msg1230PrngSeed }, + { "Pkcs1v2Decrypt", "CryptoPkg.BaseCryptLib.Pkcs1v2Decrypt", TestVerifyDecrypt, NULL, NULL, &mTestVerifyPkcs1v2Msg1230 }, + { "Pkcs1v2EncryptDecrypt", "CryptoPkg.BaseCryptLib.Pkcs1v2EncryptDecrypt", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyPkcs1v2Msg1230 }, + + // RsaOaepEncrypt / Decrypt + { "RsaOaepEncrypt (Interface)", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt.Interface", TestVerifyRsaOaepEncryptInterface, NULL, NULL, &mTestVerifyRsaOaepMsg1230 }, + { "RsaOaepEncrypt (NoSeed)", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt.NoSeed", TestVerifyEncrypt, NULL, NULL, &mTestVerifyRsaOaepMsg1230 }, + { "RsaOaepEncrypt (Seeded)", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt.Seeded", TestVerifyEncrypt, NULL, NULL, &mTestVerifyRsaOaepMsg1230PrngSeed }, + { "RsaOaepDecrypt", "CryptoPkg.BaseCryptLib.RsaOaepDecrypt", TestVerifyDecrypt, NULL, NULL, &mTestVerifyRsaOaepMsg1230 }, + { "RsaOaepEncryptDecrypt", "CryptoPkg.BaseCryptLib.RsaOaepEncryptDecrypt", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyRsaOaepMsg1230 }, + + // Mix interfaces + { "RsaOaepEncryptPkcs1v2Decrypt", "CryptoPkg.BaseCryptLib.RsaOaepEncryptPkcs1v2Decrypt", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyRsaOaepEncryptPkcs1v2Decrypt }, + { "Pkcs1v2EncryptRsaOaepDecrypt", "CryptoPkg.BaseCryptLib.Pkcs1v2EncryptRsaOaepDecrypt", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyPkcs1v2EncryptRsaOaepDecrypt }, + + // Message digest default / MGF1 default (SHA1) + { "RsaOaepEncrypt (MdDefaultMgf1Default)", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt.MdDefaultMgf1Default", TestVerifyEncrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdDefaultBgf1Default }, + { "RsaOaepDecrypt (MdDefaultMgf1Default)", "CryptoPkg.BaseCryptLib.RsaOaepDecrypt.MdDefaultMgf1Default", TestVerifyDecrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdDefaultBgf1Default }, + { "RsaOaepEncryptDecrypt (MdDefaultMgf1Default)", "CryptoPkg.BaseCryptLib.RsaOaepEncryptDecrypt.MdDefaultMgf1Default", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdDefaultBgf1Default }, + + // Message digest SHA1 / MGF1 SHA1 + { "RsaOaepEncrypt (MdSha1Bgf1Sha1", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt.MdSha1Bgf1Sha1", TestVerifyEncrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdSha1Mgf1Sha1 }, + { "RsaOaepDecrypt (MdSha1Bgf1Sha1)", "CryptoPkg.BaseCryptLib.RsaOaepDecrypt.MdSha1Bgf1Sha1", TestVerifyDecrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdSha1Mgf1Sha1 }, + { "RsaOaepEncryptDecrypt (MdSha1Bgf1Sha1)", "CryptoPkg.BaseCryptLib.RsaOaepEncryptDecrypt.MdSha1Bgf1Sha1", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdSha1Mgf1Sha1 }, + + // Message digest SHA256 / MGF1 SHA256 + { "RsaOaepEncrypt (MdSha256Bgf1Sha256)", "CryptoPkg.BaseCryptLib.RsaOaepEncrypt.MdSha256Bgf1Sha256", TestVerifyEncrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdSha256Mgf1Sha256 }, + { "RsaOaepDecrypt (MdSha256Bgf1Sha256)", "CryptoPkg.BaseCryptLib.RsaOaepDecrypt.MdSha256Bgf1Sha256", TestVerifyDecrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdSha256Mgf1Sha256 }, + { "RsaOaepEncryptDecrypt (MdSha256Bgf1Sha256)", "CryptoPkg.BaseCryptLib.RsaOaepEncryptDecryptMdSha256Bgf1Sha256", TestVerifyEncryptDecrypt, NULL, NULL, &mTestVerifyRsaesOaep2048MdSha256Mgf1Sha256 }, }; UINTN mOaepTestNum = ARRAY_SIZE (mOaepTest); -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117252): https://edk2.groups.io/g/devel/message/117252 Mute This Topic: https://groups.io/mt/105239225/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io ` (2 preceding siblings ...) 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io @ 2024-04-01 1:46 ` Li, Yi 2024-04-07 7:51 ` Li, Yi 3 siblings, 1 reply; 14+ messages in thread From: Li, Yi @ 2024-04-01 1:46 UTC (permalink / raw) To: devel@edk2.groups.io, cruffin@millcore.com Cc: Chris Ruffin, Yao, Jiewen, Hou, Wenxing Appreciate your efforts in optimization of unit test, for this patch set: Looks good to me. Reviewed-by: Yi Li <yi1.li@intel.com> -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chris Ruffin via groups.io Sent: Sunday, March 31, 2024 6:00 AM To: devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com> Subject: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions From: Chris Ruffin <v-chruffin@microsoft.com> v2 patchset adds: - Add digest length parameter to RsaOaepEncrypt(), RsaOaepDecrypt() so that SHA256, SHA384, SHA512 message digests and mask generation functions can be used with the API. - Add NullLib implementation for BaseCryptLibMbedTls - Cleanups from v1 review - Significantly refactored and expanded test suite: - Use UNIT_TEST_CONTEXT and abstaction to run same tests on Pkcs1v2Encrypt()/Pkcs1v2Decrypt() and RsaOaepEncrypt() RsaOaepDecrypt() - Align DER Certificate / PrivateKey used with Pkcs1v2 APIs with RsaN, RsaE, RsaD parameters used by RsaOaep APIs so that they represent the same keys. - Implement fixed ciphertext test for Pkcs1v2Decrypt(), RsaOaepDecrypt() - Implementation was also checked with wycheproof test vectors (not included in the patch). Chris Ruffin (3): CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions CryptoPkg/Driver: add additional RSAES-OAEP crypto functions CryptoPkg/BaseCryptLibUnitTest: add unit test functions CryptoPkg/Driver/Crypto.c | 130 ++- CryptoPkg/Include/Library/BaseCryptLib.h | 117 +++ .../Pcd/PcdCryptoServiceFamilyEnable.h | 4 + .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 598 ++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 130 ++- .../Pk/CryptPkcs1OaepNull.c | 135 +++- .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 130 ++- .../BaseCryptLibOnProtocolPpi/CryptLib.c | 114 +++ CryptoPkg/Private/Protocol/Crypto.h | 109 ++- .../Library/BaseCryptLib/OaepEncryptTests.c | 758 ++++++++++++++++-- 10 files changed, 2098 insertions(+), 127 deletions(-) -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117272): https://edk2.groups.io/g/devel/message/117272 Mute This Topic: https://groups.io/mt/105239222/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions 2024-04-01 1:46 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions Li, Yi @ 2024-04-07 7:51 ` Li, Yi 2024-04-07 12:53 ` Chris Ruffin via groups.io 0 siblings, 1 reply; 14+ messages in thread From: Li, Yi @ 2024-04-07 7:51 UTC (permalink / raw) To: devel@edk2.groups.io, cruffin@millcore.com Cc: Chris Ruffin, Yao, Jiewen, Hou, Wenxing Pushed: https://github.com/tianocore/edk2/pull/5532 Thanks, Yi -----Original Message----- From: Li, Yi1 Sent: Monday, April 1, 2024 9:46 AM To: devel@edk2.groups.io; cruffin@millcore.com Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> Subject: RE: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions Appreciate your efforts in optimization of unit test, for this patch set: Looks good to me. Reviewed-by: Yi Li <yi1.li@intel.com> -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chris Ruffin via groups.io Sent: Sunday, March 31, 2024 6:00 AM To: devel@edk2.groups.io Cc: Chris Ruffin <v-chruffin@microsoft.com> Subject: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions From: Chris Ruffin <v-chruffin@microsoft.com> v2 patchset adds: - Add digest length parameter to RsaOaepEncrypt(), RsaOaepDecrypt() so that SHA256, SHA384, SHA512 message digests and mask generation functions can be used with the API. - Add NullLib implementation for BaseCryptLibMbedTls - Cleanups from v1 review - Significantly refactored and expanded test suite: - Use UNIT_TEST_CONTEXT and abstaction to run same tests on Pkcs1v2Encrypt()/Pkcs1v2Decrypt() and RsaOaepEncrypt() RsaOaepDecrypt() - Align DER Certificate / PrivateKey used with Pkcs1v2 APIs with RsaN, RsaE, RsaD parameters used by RsaOaep APIs so that they represent the same keys. - Implement fixed ciphertext test for Pkcs1v2Decrypt(), RsaOaepDecrypt() - Implementation was also checked with wycheproof test vectors (not included in the patch). Chris Ruffin (3): CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions CryptoPkg/Driver: add additional RSAES-OAEP crypto functions CryptoPkg/BaseCryptLibUnitTest: add unit test functions CryptoPkg/Driver/Crypto.c | 130 ++- CryptoPkg/Include/Library/BaseCryptLib.h | 117 +++ .../Pcd/PcdCryptoServiceFamilyEnable.h | 4 + .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 598 ++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 130 ++- .../Pk/CryptPkcs1OaepNull.c | 135 +++- .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 130 ++- .../BaseCryptLibOnProtocolPpi/CryptLib.c | 114 +++ CryptoPkg/Private/Protocol/Crypto.h | 109 ++- .../Library/BaseCryptLib/OaepEncryptTests.c | 758 ++++++++++++++++-- 10 files changed, 2098 insertions(+), 127 deletions(-) -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117474): https://edk2.groups.io/g/devel/message/117474 Mute This Topic: https://groups.io/mt/105239222/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions 2024-04-07 7:51 ` Li, Yi @ 2024-04-07 12:53 ` Chris Ruffin via groups.io 0 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-04-07 12:53 UTC (permalink / raw) To: Li, Yi1; +Cc: devel@edk2.groups.io, Chris Ruffin, Yao, Jiewen, Hou, Wenxing Thank you sir! — Chris Ruffin Millcore Systems (803) 615-6155 https://millcore.com/ > On Apr 7, 2024, at 3:51 AM, Li, Yi1 <yi1.li@intel.com> wrote: > > Pushed: https://github.com/tianocore/edk2/pull/5532 > > Thanks, > Yi > > -----Original Message----- > From: Li, Yi1 > Sent: Monday, April 1, 2024 9:46 AM > To: devel@edk2.groups.io; cruffin@millcore.com > Cc: Chris Ruffin <v-chruffin@microsoft.com>; Yao, Jiewen <jiewen.yao@intel.com>; Hou, Wenxing <wenxing.hou@intel.com> > Subject: RE: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions > > Appreciate your efforts in optimization of unit test, for this patch set: > > Looks good to me. > Reviewed-by: Yi Li <yi1.li@intel.com> > > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chris Ruffin via groups.io > Sent: Sunday, March 31, 2024 6:00 AM > To: devel@edk2.groups.io > Cc: Chris Ruffin <v-chruffin@microsoft.com> > Subject: [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions > > From: Chris Ruffin <v-chruffin@microsoft.com> > > v2 patchset adds: > - Add digest length parameter to RsaOaepEncrypt(), RsaOaepDecrypt() so that SHA256, SHA384, SHA512 message digests and mask generation functions can be used with the API. > - Add NullLib implementation for BaseCryptLibMbedTls > - Cleanups from v1 review > - Significantly refactored and expanded test suite: > - Use UNIT_TEST_CONTEXT and abstaction to run same tests on > Pkcs1v2Encrypt()/Pkcs1v2Decrypt() and RsaOaepEncrypt() RsaOaepDecrypt() > - Align DER Certificate / PrivateKey used with Pkcs1v2 APIs > with RsaN, RsaE, RsaD parameters used by RsaOaep APIs > so that they represent the same keys. > - Implement fixed ciphertext test for Pkcs1v2Decrypt(), RsaOaepDecrypt() > - Implementation was also checked with wycheproof test vectors (not > included in the patch). > > Chris Ruffin (3): > CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions > CryptoPkg/Driver: add additional RSAES-OAEP crypto functions > CryptoPkg/BaseCryptLibUnitTest: add unit test functions > > CryptoPkg/Driver/Crypto.c | 130 ++- > CryptoPkg/Include/Library/BaseCryptLib.h | 117 +++ > .../Pcd/PcdCryptoServiceFamilyEnable.h | 4 + > .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 598 ++++++++++++-- > .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 130 ++- > .../Pk/CryptPkcs1OaepNull.c | 135 +++- > .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 130 ++- > .../BaseCryptLibOnProtocolPpi/CryptLib.c | 114 +++ > CryptoPkg/Private/Protocol/Crypto.h | 109 ++- > .../Library/BaseCryptLib/OaepEncryptTests.c | 758 ++++++++++++++++-- > 10 files changed, 2098 insertions(+), 127 deletions(-) > > -- > 2.44.0.windows.1 > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117475): https://edk2.groups.io/g/devel/message/117475 Mute This Topic: https://groups.io/mt/105239222/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions @ 2024-03-15 1:16 Chris Ruffin via groups.io 2024-03-15 1:16 ` [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io 0 siblings, 1 reply; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-15 1:16 UTC (permalink / raw) To: devel From: Chris Ruffin <v-chruffin@microsoft.com> Expand the availability of the RSAEP-OAEP crypto capability in BaseCryptLib. Applications using RSA crypto functions directly from OpensslLib can transition to BaseCryptLib to take advantage of the shared crypto feature in CryptoDxe. Pkcs1v2Decrypt(): decryption using DER-encoded private key RsaOaepEncrypt(): encryption using RSA contexts RsaOaepDecrypt(): decryption using RSA contexts Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Include/Library/BaseCryptLib.h | 102 ++++ .../Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 506 ++++++++++++++++-- .../BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 114 ++++ .../BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c | 114 ++++ 4 files changed, 789 insertions(+), 47 deletions(-) diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index a52bd91ad6..7ad2bf21fe 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2147,6 +2147,108 @@ Pkcs1v2Encrypt ( OUT UINTN *EncryptedDataSize ); +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + /** The 3rd parameter of Pkcs7GetSigners will return all embedded X.509 certificate in one given PKCS7 signature. The format is: diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c index ea43c1381c..00e904dd6c 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -26,9 +26,8 @@ - Data size is too large for the provided key size (max size is a function of key size and hash digest size). - @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + @param[in] Pkey A pointer to an EVP_PKEY struct that will be used to encrypt the data. - @param[in] PublicKeySize Size of the X509 cert buffer. @param[in] InData Data to be encrypted. @param[in] InDataSize Size of the data buffer. @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer @@ -45,9 +44,8 @@ **/ BOOLEAN EFIAPI -Pkcs1v2Encrypt ( - IN CONST UINT8 *PublicKey, - IN UINTN PublicKeySize, +InternalPkcs1v2Encrypt ( + EVP_PKEY *Pkey, IN UINT8 *InData, IN UINTN InDataSize, IN CONST UINT8 *PrngSeed OPTIONAL, @@ -57,9 +55,6 @@ Pkcs1v2Encrypt ( ) { BOOLEAN Result; - CONST UINT8 *TempPointer; - X509 *CertData; - EVP_PKEY *InternalPublicKey; EVP_PKEY_CTX *PkeyCtx; UINT8 *OutData; UINTN OutDataSize; @@ -67,28 +62,15 @@ Pkcs1v2Encrypt ( // // Check input parameters. // - if ((PublicKey == NULL) || (InData == NULL) || + if ((Pkey == NULL) || (InData == NULL) || (EncryptedData == NULL) || (EncryptedDataSize == NULL)) { return FALSE; } - // - // Check public key size. - // - if (PublicKeySize > 0xFFFFFFFF) { - // - // Public key size is too large for implementation. - // - return FALSE; - } - *EncryptedData = NULL; *EncryptedDataSize = 0; Result = FALSE; - TempPointer = NULL; - CertData = NULL; - InternalPublicKey = NULL; PkeyCtx = NULL; OutData = NULL; OutDataSize = 0; @@ -104,6 +86,154 @@ Pkcs1v2Encrypt ( RandomSeed (NULL, 0); } + // + // Create a context for the public key operation. + // + PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); + if (PkeyCtx == NULL) { + // + // Fail to create contex. + // + goto _Exit; + } + + // + // Initialize the context and set the desired padding. + // + if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) || + (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) + { + // + // Fail to initialize the context. + // + goto _Exit; + } + + // + // Determine the required buffer length for malloc'ing. + // + if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to determine output buffer size. + // + goto _Exit; + } + + // + // Allocate a buffer for the output data. + // + OutData = AllocatePool (OutDataSize); + if (OutData == NULL) { + // + // Fail to allocate the output buffer. + // + goto _Exit; + } + + // + // Encrypt Data. + // + if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { + // + // Fail to encrypt data, need to free the output buffer. + // + FreePool (OutData); + OutData = NULL; + OutDataSize = 0; + goto _Exit; + } + + // + // Encrypt done. + // + *EncryptedData = OutData; + *EncryptedDataSize = OutDataSize; + Result = TRUE; + +_Exit: + // + // Release Resources + // + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to parse X509 certificate. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + will be used to encrypt the data. + @param[in] PublicKeySize Size of the X509 cert buffer. + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Encrypt ( + IN CONST UINT8 *PublicKey, + IN UINTN PublicKeySize, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + CONST UINT8 *TempPointer; + X509 *CertData; + EVP_PKEY *Pkey; + + // + // Check input parameters. + // + if ((PublicKey == NULL) || (InData == NULL) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + // + // Check public key size. + // + if (PublicKeySize > 0xFFFFFFFF) { + // + // Public key size is too large for implementation. + // + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + TempPointer = NULL; + CertData = NULL; + Pkey = NULL; + // // Parse the X509 cert and extract the public key. // @@ -120,52 +250,201 @@ Pkcs1v2Encrypt ( // Extract the public key from the x509 cert in a format that // OpenSSL can use. // - InternalPublicKey = X509_get_pubkey (CertData); - if (InternalPublicKey == NULL) { + Pkey = X509_get_pubkey (CertData); + if (Pkey == NULL) { // // Fail to extract public key. // goto _Exit; } + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize); + +_Exit: // - // Create a context for the public key operation. + // Release Resources + // + if (CertData != NULL) { + X509_free (CertData); + } + + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + // - PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, NULL); + // Check input parameters. + // + if (((RsaContext == NULL) || (InData == NULL)) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + Pkey = NULL; + + Pkey = EVP_PKEY_new (); + if (Pkey == NULL) { + goto _Exit; + } + + if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) { + goto _Exit; + } + + Result = InternalPkcs1v2Encrypt (Pkey, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize); + +_Exit: + // + // Release Resources + // + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } + + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] Pkey A pointer to an EVP_PKEY which will decrypt that data. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +InternalPkcs1v2Decrypt ( + EVP_PKEY *Pkey, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY_CTX *PkeyCtx; + UINT8 *TempData; + UINTN TempDataSize; + INTN ReturnCode; + + // + // Check input parameters. + // + if ((Pkey == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + PkeyCtx = NULL; + TempData = NULL; + TempDataSize = 0; + + // + // Create a context for the decryption operation. + // + PkeyCtx = EVP_PKEY_CTX_new (Pkey, NULL); if (PkeyCtx == NULL) { // // Fail to create contex. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_CTK_new() failed\n", __func__)); goto _Exit; } // // Initialize the context and set the desired padding. // - if ((EVP_PKEY_encrypt_init (PkeyCtx) <= 0) || + if ((EVP_PKEY_decrypt_init (PkeyCtx) <= 0) || (EVP_PKEY_CTX_set_rsa_padding (PkeyCtx, RSA_PKCS1_OAEP_PADDING) <= 0)) { // // Fail to initialize the context. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt_init() failed\n", __func__)); goto _Exit; } // // Determine the required buffer length for malloc'ing. // - if (EVP_PKEY_encrypt (PkeyCtx, NULL, &OutDataSize, InData, InDataSize) <= 0) { + ReturnCode = EVP_PKEY_decrypt (PkeyCtx, NULL, &TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { // // Fail to determine output buffer size. // + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt() failed to determine output buffer size (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // // Allocate a buffer for the output data. // - OutData = AllocatePool (OutDataSize); - if (OutData == NULL) { + TempData = AllocatePool (TempDataSize); + if (TempData == NULL) { // // Fail to allocate the output buffer. // @@ -173,39 +452,172 @@ Pkcs1v2Encrypt ( } // - // Encrypt Data. + // Decrypt Data. // - if (EVP_PKEY_encrypt (PkeyCtx, OutData, &OutDataSize, InData, InDataSize) <= 0) { + ReturnCode = EVP_PKEY_decrypt (PkeyCtx, TempData, &TempDataSize, EncryptedData, EncryptedDataSize); + if (ReturnCode <= 0) { // - // Fail to encrypt data, need to free the output buffer. + // Fail to decrypt data, need to free the output buffer. // - FreePool (OutData); - OutData = NULL; - OutDataSize = 0; + FreePool (TempData); + TempData = NULL; + TempDataSize = 0; + + DEBUG ((DEBUG_ERROR, "[%a] EVP_PKEY_decrypt(TempData) failed to decrypt (rc=%d)\n", __func__, ReturnCode)); goto _Exit; } // - // Encrypt done. + // Decrypt done. // - *EncryptedData = OutData; - *EncryptedDataSize = OutDataSize; - Result = TRUE; + *OutData = TempData; + *OutDataSize = TempDataSize; + Result = TRUE; _Exit: + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + CONST UINT8 *TempPointer; + // - // Release Resources + // Check input parameters. // - if (CertData != NULL) { - X509_free (CertData); + if ((PrivateKey == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + Pkey = NULL; + TempPointer = NULL; + + // + // Parse the private key. + // + TempPointer = PrivateKey; + Pkey = d2i_PrivateKey (EVP_PKEY_RSA, &Pkey, &TempPointer, (UINT32)PrivateKeySize); + if (Pkey == NULL) { + // + // Fail to parse private key. + // + DEBUG ((DEBUG_ERROR, "[%a] d2i_PrivateKey() failed\n", __func__)); + goto _Exit; } - if (InternalPublicKey != NULL) { - EVP_PKEY_free (InternalPublicKey); + Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize); + +_Exit: + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); } - if (PkeyCtx != NULL) { - EVP_PKEY_CTX_free (PkeyCtx); + return Result; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + BOOLEAN Result; + EVP_PKEY *Pkey; + + // + // Check input parameters. + // + if ((RsaContext == NULL) || (EncryptedData == NULL) || + (OutData == NULL) || (OutDataSize == NULL)) + { + return FALSE; + } + + Result = FALSE; + Pkey = NULL; + + // + // Create a context for the decryption operation. + // + + Pkey = EVP_PKEY_new (); + if (Pkey == NULL) { + goto _Exit; + } + + if (EVP_PKEY_set1_RSA (Pkey, (RSA *)RsaContext) == 0) { + goto _Exit; + } + + Result = InternalPkcs1v2Decrypt (Pkey, EncryptedData, EncryptedDataSize, OutData, OutDataSize); + +_Exit: + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); } return Result; diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c index 36508947c5..05e074d18e 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptPkcs1OaepNull.c @@ -48,3 +48,117 @@ Pkcs1v2Encrypt ( ASSERT (FALSE); return FALSE; } + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116861): https://edk2.groups.io/g/devel/message/116861 Mute This Topic: https://groups.io/mt/105014749/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: add additional RSAEP-OAEP crypto functions 2024-03-15 1:16 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP " Chris Ruffin via groups.io @ 2024-03-15 1:16 ` Chris Ruffin via groups.io 0 siblings, 0 replies; 14+ messages in thread From: Chris Ruffin via groups.io @ 2024-03-15 1:16 UTC (permalink / raw) To: devel From: Chris Ruffin <v-chruffin@microsoft.com> Add new library members to CryptoPkg/Driver. Signed-off-by: Chris Ruffin <v-chruffin@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Cc: Wenxing Hou <wenxing.hou@intel.com> --- CryptoPkg/Driver/Crypto.c | 116 +++++++++++++++++- .../Pcd/PcdCryptoServiceFamilyEnable.h | 3 + .../BaseCryptLibOnProtocolPpi/CryptLib.c | 100 +++++++++++++++ CryptoPkg/Private/Protocol/Crypto.h | 97 ++++++++++++++- 4 files changed, 314 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index bdbb4863a9..3bfce16fa6 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -3589,6 +3589,117 @@ CryptoServicePkcs1v2Encrypt ( return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs1v2Encrypt, Pkcs1v2Encrypt, (PublicKey, PublicKeySize, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); } +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceRsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + return CALL_BASECRYPTLIB (Rsa.Services.RsaOaepEncrypt, RsaOaepEncrypt, (RsaContext, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServicePkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs1v2Decrypt, Pkcs1v2Decrypt, (PrivateKey, PrivateKeySize, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceRsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + return CALL_BASECRYPTLIB (Rsa.Services.RsaOaepDecrypt, RsaOaepDecrypt, (RsaContext, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + /** Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7: Cryptographic Message Syntax Standard". The input signed data could be wrapped @@ -6987,5 +7098,8 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { CryptoServiceX509VerifyCertChain, CryptoServiceX509GetCertFromCertChain, CryptoServiceAsn1GetTag, - CryptoServiceX509GetExtendedBasicConstraints + CryptoServiceX509GetExtendedBasicConstraints, + CryptoServicePkcs1v2Decrypt, + CryptoServiceRsaOaepEncrypt, + CryptoServiceRsaOaepDecrypt, }; diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 74eaf44cca..6aee28afe5 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -124,6 +124,7 @@ typedef struct { UINT8 Pkcs7GetCertificatesList : 1; UINT8 AuthenticodeVerify : 1; UINT8 ImageTimestampVerify : 1; + UINT8 Pkcs1v2Decrypt : 1; } Services; UINT32 Family; } Pkcs; @@ -158,6 +159,8 @@ typedef struct { UINT8 Pkcs1Verify : 1; UINT8 GetPrivateKeyFromPem : 1; UINT8 GetPublicKeyFromX509 : 1; + UINT8 RsaOaepEncrypt : 1; + UINT8 RsaOaepDecrypt : 1; } Services; UINT32 Family; } Rsa; diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index 4e31bc278e..8bf3bf00ed 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -2825,6 +2825,105 @@ Pkcs1v2Encrypt ( CALL_CRYPTO_SERVICE (Pkcs1v2Encrypt, (PublicKey, PublicKeySize, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); } +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + CALL_CRYPTO_SERVICE (Pkcs1v2Decrypt, (PrivateKey, PrivateKeySize, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + CALL_CRYPTO_SERVICE (RsaOaepEncrypt, (RsaContext, InData, InDataSize, PrngSeed, PrngSeedSize, EncryptedData, EncryptedDataSize), FALSE); +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + CALL_CRYPTO_SERVICE (RsaOaepDecrypt, (RsaContext, EncryptedData, EncryptedDataSize, OutData, OutDataSize), FALSE); +} + /** Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7: Cryptographic Message Syntax Standard". The input signed data could be wrapped @@ -2850,6 +2949,7 @@ Pkcs1v2Encrypt ( @retval FALSE Error occurs during the operation. @retval FALSE This interface is not supported. + **/ BOOLEAN EFIAPI diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index 0e0b1d9401..2466d47dd9 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -21,7 +21,7 @@ /// the EDK II Crypto Protocol is extended, this version define must be /// increased. /// -#define EDKII_CRYPTO_VERSION 16 +#define EDKII_CRYPTO_VERSION 17 /// /// EDK II Crypto Protocol forward declaration @@ -688,6 +688,98 @@ BOOLEAN OUT UINTN *EncryptedDataSize ); +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_PKCS1V2_DECRYPT)( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +// FROM BaseCryptLib.h:2178 +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_RSA_OAEP_ENCRYPT)( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ); + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. +**/ +// FROM BaseCryptLib.h:2243 +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_RSA_OAEP_DECRYPT)( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ); + // --------------------------------------------- // PKCS5 @@ -5603,6 +5695,9 @@ struct _EDKII_CRYPTO_PROTOCOL { EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN X509GetCertFromCertChain; EDKII_CRYPTO_ASN1_GET_TAG Asn1GetTag; EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS X509GetExtendedBasicConstraints; + EDKII_CRYPTO_PKCS1V2_DECRYPT Pkcs1v2Decrypt; + EDKII_CRYPTO_RSA_OAEP_ENCRYPT RsaOaepEncrypt; + EDKII_CRYPTO_RSA_OAEP_DECRYPT RsaOaepDecrypt; }; extern GUID gEdkiiCryptoProtocolGuid; -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116862): https://edk2.groups.io/g/devel/message/116862 Mute This Topic: https://groups.io/mt/105014753/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-04-07 12:53 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-03-18 21:52 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io 2024-03-18 21:52 ` [edk2-devel] [PATCH 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io 2024-03-19 3:52 ` [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions Li, Yi 2024-03-19 14:15 ` Chris Ruffin via groups.io 2024-03-26 5:07 ` Li, Yi 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 1/3] " Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io 2024-03-30 21:59 ` [edk2-devel] [PATCH v2 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io 2024-04-01 1:46 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions Li, Yi 2024-04-07 7:51 ` Li, Yi 2024-04-07 12:53 ` Chris Ruffin via groups.io -- strict thread matches above, loose matches on Subject: below -- 2024-03-15 1:16 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP " Chris Ruffin via groups.io 2024-03-15 1:16 ` [edk2-devel] [PATCH 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox