From 503344cdbd289e6f360f900551d1cc7c23f4b27a Mon Sep 17 00:00:00 2001 From: Chris Ruffin Date: Sun, 31 Mar 2024 05:59:44 +0800 Subject: CryptoPkg/Driver: add additional RSAES-OAEP crypto functions Add new functions to CryptoPkg/Driver. Signed-off-by: Chris Ruffin Cc: Chris Ruffin Cc: Jiewen Yao Cc: Yi Li Cc: Wenxing Hou Reviewed-by: Yi Li --- CryptoPkg/Driver/Crypto.c | 130 ++++++++++++++++++++- .../Include/Pcd/PcdCryptoServiceFamilyEnable.h | 4 + .../Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 114 ++++++++++++++++++ CryptoPkg/Private/Protocol/Crypto.h | 109 ++++++++++++++++- 4 files changed, 355 insertions(+), 2 deletions(-) (limited to 'CryptoPkg') 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.
+ 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; -- cgit v1.2.3