diff options
| author | Baraneedharan Anbazhagan <anbazhagan@hp.com> | 2026-03-17 15:19:12 +0300 |
|---|---|---|
| committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2026-04-07 15:26:54 +0300 |
| commit | b3fdc0994db62b72a8b56ea25ffd024ab5e4e017 (patch) | |
| tree | 98e00057ce0dbfebbd779fab5a5f7f11612609d4 /CryptoPkg/Library/BaseCryptLib/Pk | |
| parent | f1fc41cff2a2022e67da3f9f525f9087cf2de507 (diff) | |
| download | edk2-b3fdc0994db62b72a8b56ea25ffd024ab5e4e017.tar.xz | |
CryptoPkg: Add digest-based RSA-PSS sign and verify APIs
Add RsaPssSignDigest() and RsaPssVerifyDigest() to BaseCryptLib for
signing/verifying precomputed digests. Provide OpenSSL/MbedTLS/Null
implementations, expose via EDKII_CRYPTO_PROTOCOL (v24), and add PCD
controls for independent service enabling. Include unit tests.
Signed-off-by: Anbazhagan Baraneedharan <anbazhagan@hp.com>
Diffstat (limited to 'CryptoPkg/Library/BaseCryptLib/Pk')
| -rw-r--r-- | CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 114 | ||||
| -rw-r--r-- | CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 127 | ||||
| -rw-r--r-- | CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c | 45 |
3 files changed, 286 insertions, 0 deletions
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c index bdc9155e1f..cd4d22ae85 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c @@ -3,8 +3,10 @@ This file implements following APIs which provide basic capabilities for RSA:
1) RsaPssVerify
+ 2) RsaPssVerifyDigest
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -156,3 +158,115 @@ _Exit: return Result;
}
+
+/**
+ Verifies an RSA-PSS signature over a precomputed message digest.
+ Mask generation function is the same as the message digest algorithm.
+
+ If RsaContext is NULL, then return FALSE.
+ If Digest is NULL, then return FALSE.
+ If Signature is NULL, then return FALSE.
+ If DigestSize is not one of SHA-256, SHA-384 or SHA-512 digest sizes,
+ then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] Digest Pointer to the message digest.
+ @param[in] DigestSize Digest size in bytes
+ SHA256_DIGEST_SIZE
+ SHA384_DIGEST_SIZE
+ SHA512_DIGEST_SIZE
+ @param[in] Signature Pointer to RSASSA-PSS signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+
+ @retval TRUE Valid signature encoded in RSASSA-PSS.
+ @retval FALSE Invalid signature or invalid RSA context.
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerifyDigest (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Digest,
+ IN UINTN DigestSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize
+ )
+{
+ BOOLEAN Result;
+ EVP_PKEY *EvpRsaKey;
+ EVP_PKEY_CTX *EvpVerifyCtx;
+ CONST EVP_MD *HashAlg;
+
+ Result = FALSE;
+ EvpRsaKey = NULL;
+ EvpVerifyCtx = NULL;
+ HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+
+ if ((Digest == NULL) || (DigestSize == 0) || (DigestSize > INT_MAX) || (DigestSize > MAX_UINT16)) {
+ return FALSE;
+ }
+
+ if ((Signature == NULL) || (SigSize == 0) || (SigSize > INT_MAX)) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD ((UINT16)DigestSize);
+
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ EvpRsaKey = EVP_PKEY_new ();
+ if (EvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA (EvpRsaKey, RsaContext);
+
+ EvpVerifyCtx = EVP_PKEY_CTX_new (EvpRsaKey, NULL);
+ if (EvpVerifyCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_PKEY_verify_init (EvpVerifyCtx) > 0;
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding (EvpVerifyCtx, RSA_PKCS1_PSS_PADDING) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_signature_md (EvpVerifyCtx, HashAlg) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md (EvpVerifyCtx, HashAlg) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen (EvpVerifyCtx, (INT32)DigestSize) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_verify (
+ EvpVerifyCtx,
+ Signature,
+ (UINT32)SigSize,
+ Digest,
+ (UINT32)DigestSize
+ ) > 0;
+ }
+
+_Exit:
+ if (EvpVerifyCtx != NULL) {
+ EVP_PKEY_CTX_free (EvpVerifyCtx);
+ }
+
+ if (EvpRsaKey != NULL) {
+ EVP_PKEY_free (EvpRsaKey);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c index 07c24f6e8d..4835f81168 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c @@ -3,8 +3,10 @@ This file implements following APIs which provide basic capabilities for RSA:
1) RsaPssSign
+ 2) RsaPssSignDigest
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -177,3 +179,128 @@ _Exit: return Result;
}
+
+/**
+ Carries out the RSA-PSS signature generation with EMSA-PSS encoding scheme
+ over a precomputed message digest.
+
+ This function carries out the RSA-PSS signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Digest is NULL, then return FALSE.
+ If DigestSize is not one of SHA-256, SHA-384 or SHA-512 digest sizes, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Digest Pointer to the precomputed message digest.
+ @param[in] DigestSize Digest size in bytes (32=SHA-256, 48=SHA-384, 64=SHA-512).
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSignDigest (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Digest,
+ IN UINTN DigestSize,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ BOOLEAN Result;
+ UINTN RsaSigSize;
+ EVP_PKEY *EvpRsaKey;
+ EVP_PKEY_CTX *EvpSignCtx;
+ CONST EVP_MD *HashAlg;
+
+ Result = FALSE;
+ EvpRsaKey = NULL;
+ EvpSignCtx = NULL;
+ HashAlg = NULL;
+
+ if (RsaContext == NULL) {
+ return FALSE;
+ }
+
+ if ((Digest == NULL) || (DigestSize == 0) || (DigestSize > INT_MAX) || (DigestSize > MAX_UINT16)) {
+ return FALSE;
+ }
+
+ RsaSigSize = RSA_size (RsaContext);
+ if (*SigSize < RsaSigSize) {
+ *SigSize = RsaSigSize;
+ return FALSE;
+ }
+
+ if (Signature == NULL) {
+ return FALSE;
+ }
+
+ HashAlg = GetEvpMD ((UINT16)DigestSize);
+ if (HashAlg == NULL) {
+ return FALSE;
+ }
+
+ EvpRsaKey = EVP_PKEY_new ();
+ if (EvpRsaKey == NULL) {
+ goto _Exit;
+ }
+
+ EVP_PKEY_set1_RSA (EvpRsaKey, RsaContext);
+
+ EvpSignCtx = EVP_PKEY_CTX_new (EvpRsaKey, NULL);
+ if (EvpSignCtx == NULL) {
+ goto _Exit;
+ }
+
+ Result = EVP_PKEY_sign_init (EvpSignCtx) > 0;
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_padding (EvpSignCtx, RSA_PKCS1_PSS_PADDING) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_signature_md (EvpSignCtx, HashAlg) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_mgf1_md (EvpSignCtx, HashAlg) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_CTX_set_rsa_pss_saltlen (EvpSignCtx, (INT32)DigestSize) > 0;
+ }
+
+ if (Result) {
+ Result = EVP_PKEY_sign (
+ EvpSignCtx,
+ Signature,
+ SigSize,
+ Digest,
+ (UINT32)DigestSize
+ ) > 0;
+ }
+
+_Exit:
+ if (EvpSignCtx != NULL) {
+ EVP_PKEY_CTX_free (EvpSignCtx);
+ }
+
+ if (EvpRsaKey != NULL) {
+ EVP_PKEY_free (EvpRsaKey);
+ }
+
+ return Result;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c index 911b972521..66ae8a7855 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c @@ -3,8 +3,10 @@ This file does not provide real capabilities for following APIs in RSA handling:
1) RsaPssSign
+ 2) RsaPssSignDigest
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -58,3 +60,46 @@ RsaPssSign ( ASSERT (FALSE);
return FALSE;
}
+
+/**
+ Carries out the RSA-PSS signature generation with EMSA-PSS encoding scheme
+ over a precomputed message digest.
+
+ This function carries out the RSA-PSS signature generation with EMSA-PSS encoding scheme defined in
+ RFC 8017.
+ Mask generation function is the same as the message digest algorithm.
+ If the Signature buffer is too small to hold the contents of signature, FALSE
+ is returned and SigSize is set to the required buffer size to obtain the signature.
+
+ If RsaContext is NULL, then return FALSE.
+ If Digest is NULL, then return FALSE.
+ If DigestSize is not one of SHA-256, SHA-384 or SHA-512 digest sizes, then return FALSE.
+ If SigSize is large enough but Signature is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature generation.
+ @param[in] Digest Pointer to the precomputed message digest.
+ @param[in] DigestSize Digest size in bytes (32=SHA-256, 48=SHA-384, 64=SHA-512).
+ @param[out] Signature Pointer to buffer to receive RSA PSS signature.
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.
+ On output, the size of data returned in Signature buffer in bytes.
+
+ @retval TRUE Signature successfully generated in RSASSA-PSS.
+ @retval FALSE Signature generation failed.
+ @retval FALSE SigSize is too small.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSignDigest (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *Digest,
+ IN UINTN DigestSize,
+ OUT UINT8 *Signature,
+ IN OUT UINTN *SigSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
|
