public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ 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; 13+ 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] 13+ messages in thread

end of thread, other threads:[~2024-04-07 12:53 UTC | newest]

Thread overview: 13+ 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox