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 <cruf...@millcore.com> 
Sent: Tuesday, March 19, 2024 10:16 PM
To: Li, Yi1 <yi1...@intel.com>; devel@edk2.groups.io
Cc: Chris Ruffin <v-chruf...@microsoft.com>; Yao, Jiewen 
<jiewen....@intel.com>; Hou, Wenxing <wenxing....@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...@intel.com> 
Sent: Monday, March 18, 2024 11:52 PM
To: Chris Ruffin <cruf...@millcore.com>; devel@edk2.groups.io
Cc: Chris Ruffin <v-chruf...@microsoft.com>; Yao, Jiewen 
<jiewen....@intel.com>; Hou, Wenxing <wenxing....@intel.com>
Subject: RE: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP 
crypto functions

[You don't often get email from yi1...@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 <cruf...@millcore.com>
Sent: Tuesday, March 19, 2024 5:52 AM
To: devel@edk2.groups.io
Cc: Chris Ruffin <v-chruf...@microsoft.com>; Yao, Jiewen 
<jiewen....@intel.com>; Li, Yi1 <yi1...@intel.com>; Hou, Wenxing 
<wenxing....@intel.com>
Subject: [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto 
functions

From: Chris Ruffin <v-chruf...@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-chruf...@microsoft.com>
Cc: Jiewen Yao <jiewen....@intel.com>
Cc: Yi Li <yi1...@intel.com>
Cc: Wenxing Hou <wenxing....@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/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to