public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chris Ruffin via groups.io" <cruffin=millcore.com@groups.io>
To: "Li, Yi1" <yi1.li@intel.com>,
	"devel@edk2.groups.io" <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: [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP crypto functions
Date: Tue, 19 Mar 2024 14:15:57 +0000	[thread overview]
Message-ID: <IA2PR13MB6679819F9B59F7BF72C224ADC92C2@IA2PR13MB6679.namprd13.prod.outlook.com> (raw)
In-Reply-To: <SJ1PR11MB62278211D0250FE07D7F588AC52C2@SJ1PR11MB6227.namprd11.prod.outlook.com>


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]
-=-=-=-=-=-=-=-=-=-=-=-



  reply	other threads:[~2024-03-19 14:16 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2024-03-26  5:07     ` Li, Yi
2024-03-30 21:59 ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP " Chris Ruffin via groups.io
2024-03-30 21:59   ` [edk2-devel] [PATCH v2 1/3] " Chris Ruffin via groups.io
2024-03-30 21:59   ` [edk2-devel] [PATCH v2 2/3] CryptoPkg/Driver: " Chris Ruffin via groups.io
2024-03-30 21:59   ` [edk2-devel] [PATCH v2 3/3] CryptoPkg/BaseCryptLibUnitTest: add unit test functions Chris Ruffin via groups.io
2024-04-01  1:46   ` [edk2-devel] [PATCH v2 0/3] CryptoPkg/BaseCryptLib: add additional RSAES-OAEP crypto functions Li, Yi
2024-04-07  7:51     ` Li, Yi
2024-04-07 12:53       ` Chris Ruffin via groups.io
  -- strict thread matches above, loose matches on Subject: below --
2024-03-15  1:16 [edk2-devel] [PATCH 1/3] CryptoPkg/BaseCryptLib: add additional RSAEP-OAEP " Chris Ruffin via groups.io

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=IA2PR13MB6679819F9B59F7BF72C224ADC92C2@IA2PR13MB6679.namprd13.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox