From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=zhichao.gao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B4506211E3483 for ; Sun, 24 Mar 2019 21:01:30 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Mar 2019 21:01:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,256,1549958400"; d="scan'208";a="310115911" Received: from gaozhic-mobl.ccr.corp.intel.com ([10.239.196.107]) by orsmga005.jf.intel.com with ESMTP; 24 Mar 2019 21:01:28 -0700 From: Zhichao Gao To: edk2-devel@lists.01.org Cc: Bret Barkelew , Ting Ye , Gang Wei , Wang Jian J , Liming Gao , Sean Brogan , Michael Turner Date: Mon, 25 Mar 2019 12:01:13 +0800 Message-Id: <20190325040113.18848-7-zhichao.gao@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20190325040113.18848-1-zhichao.gao@intel.com> References: <20190325040113.18848-1-zhichao.gao@intel.com> Subject: [PATCH 6/6] CryptoPkg/BaseCryptLib: Add PKCS1v2 (RSAES-OAEP) support. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Mar 2019 04:01:31 -0000 From: Bret Barkelew REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1403 Add support for PKCS 1v2 RSAES-OAEP PKI encryption in BaseCryptLib. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Zhichao Gao Cc: Ting Ye Cc: Gang Wei Cc: Wang Jian J Cc: Liming Gao Cc: Sean Brogan Cc: Michael Turner Cc: Bret Barkelew --- CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c | 218 +++++++++++++++++++++ .../Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c | 61 ++++++ CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 + 6 files changed, 283 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index dbddd98c59..55a6be83c6 100644 --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -47,6 +47,7 @@ Cipher/CryptArc4.c Pk/CryptRsaBasic.c Pk/CryptRsaExt.c + Pk/CryptPkcs1Oaep.c Pk/CryptPkcs5Pbkdf2.c Pk/CryptPkcs7Sign.c Pk/CryptPkcs7VerifyCommon.c diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf index 5dbb115734..3427000416 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -54,6 +54,7 @@ Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs1OaepNull.c Pk/CryptPkcs5Pbkdf2Null.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7VerifyCommon.c diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c new file mode 100644 index 0000000000..df5cd75049 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1Oaep.c @@ -0,0 +1,218 @@ +/** @file + This file contains UEFI wrapper functions for RSA PKCS1v2 OAEP encryption routines. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2016 Microsoft Corporation. All Rights Reserved. + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ +**/ + +#include "InternalCryptLib.h" +#include +#include +#include +#include + +/** + 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 *InternalPublicKey; + EVP_PKEY_CTX *PkeyCtx; + UINT8 *OutData; + UINTN OutDataSize; + + // + // 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; + InternalPublicKey = NULL; + PkeyCtx = NULL; + OutData = NULL; + OutDataSize = 0; + + // + // If it provides a seed then use it. + // Ohterwise, we'll seed with fixed values and hope that the PRNG has already been + // used enough to generate sufficient entropy. + // + if (PrngSeed != NULL) { + RandomSeed (PrngSeed, PrngSeedSize); + } else { + RandomSeed (NULL, 0); + } + + // + // Parse the X509 cert and extract the public key. + // + TempPointer = PublicKey; + CertData = d2i_X509 (&CertData, &TempPointer, (UINT32)PublicKeySize); + if (CertData == NULL) { + // + // Fail to parse X509 cert. + // + goto _Exit; + } + + // + // Extract the public key from the x509 cert in a format that + // OpenSSL can use. + // + InternalPublicKey = X509_get_pubkey (CertData); + if (InternalPublicKey == NULL) { + // + // Fail to extract public key. + // + goto _Exit; + } + + // + // Create a context for the public key operation. + // + PkeyCtx = EVP_PKEY_CTX_new (InternalPublicKey, 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 (CertData != NULL) { + X509_free (CertData ); + } + if (InternalPublicKey != NULL) { + EVP_PKEY_free (InternalPublicKey); + } + if (PkeyCtx != NULL) { + EVP_PKEY_CTX_free (PkeyCtx); + } + + return Result; +} + diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c new file mode 100644 index 0000000000..6e0d2f04a4 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs1OaepNull.c @@ -0,0 +1,61 @@ +/** @file + This file contains UEFI wrapper functions for RSA PKCS1v2 OAEP encryption routines. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2016 Microsoft Corporation. All Rights Reserved. + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ +**/ + +#include "InternalCryptLib.h" + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Return FALSE to indicate this interface is not supported. + + @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 FALSE This interface is not supported. + +**/ +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 + ) +{ + ASSERT (FALSE); + return FALSE; +} + diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf index f24cb91f33..54b3c8850f 100644 --- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf @@ -52,6 +52,7 @@ Cipher/CryptArc4Null.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs1OaepNull.c Pk/CryptPkcs5Pbkdf2Null.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7VerifyCommon.c diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf index 81d4bbe463..b5c55b7ab6 100644 --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf @@ -52,6 +52,7 @@ Cipher/CryptArc4Null.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs1Oaep.c Pk/CryptPkcs5Pbkdf2.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7VerifyCommon.c -- 2.16.2.windows.1