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>
This commit is contained in:
Baraneedharan Anbazhagan 2026-03-17 07:19:12 -05:00 committed by mergify[bot]
parent f1fc41cff2
commit b3fdc0994d
15 changed files with 924 additions and 37 deletions

View file

@ -4,6 +4,7 @@
Copyright (C) Microsoft Corporation. All rights reserved.
Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -5809,6 +5810,61 @@ CryptoServiceRsaPssVerify (
return CALL_BASECRYPTLIB (RsaPss.Services.Verify, RsaPssVerify, (RsaContext, Message, MsgSize, Signature, SigSize, DigestLen, SaltLen), FALSE);
}
/**
Carries out the RSA-PSS signature generation over a precomputed message digest.
@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
CryptoServiceRsaPssSignDigest (
IN VOID *RsaContext,
IN CONST UINT8 *Digest,
IN UINTN DigestSize,
OUT UINT8 *Signature,
IN OUT UINTN *SigSize
)
{
return CALL_BASECRYPTLIB (RsaPss.Services.SignDigest, RsaPssSignDigest, (RsaContext, Digest, DigestSize, Signature, SigSize), FALSE);
}
/**
Verifies an RSA-PSS signature over a precomputed message digest.
@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 (32=SHA-256, 48=SHA-384, 64=SHA-512).
@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
CryptoServiceRsaPssVerifyDigest (
IN VOID *RsaContext,
IN CONST UINT8 *Digest,
IN UINTN DigestSize,
IN CONST UINT8 *Signature,
IN UINTN SigSize
)
{
return CALL_BASECRYPTLIB (RsaPss.Services.VerifyDigest, RsaPssVerifyDigest, (RsaContext, Digest, DigestSize, Signature, SigSize), FALSE);
}
/**
Parallel hash function ParallelHash256, as defined in NIST's Special Publication 800-185,
published December 2016.
@ -7583,4 +7639,7 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
CryptoServiceEcGroupSetGenerator,
CryptoServiceEcPointMul2,
CryptoServiceEcPointsMul,
/// RSA PSS (Continued)
CryptoServiceRsaPssSignDigest,
CryptoServiceRsaPssVerifyDigest,
};

View file

@ -6,6 +6,7 @@
Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation. All rights reserved.
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -1915,6 +1916,73 @@ RsaPssVerify (
IN UINT16 SaltLen
);
/**
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
);
/**
Verifies an RSA-PSS signature over a precomputed message digest.
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 (32=SHA-256, 48=SHA-384, 64=SHA-512).
@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
);
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

View file

@ -24,6 +24,7 @@
Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation. All rights reserved.
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -354,8 +355,10 @@ typedef struct {
} TlsGet;
union {
struct {
UINT8 Sign : 1;
UINT8 Verify : 1;
UINT8 Sign : 1;
UINT8 Verify : 1;
UINT8 SignDigest : 1;
UINT8 VerifyDigest : 1;
} Services;
UINT32 Family;
} RsaPss;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -3,8 +3,10 @@
This file implements following APIs which provide basic capabilities for RSA:
1) RsaPssVerify
2) RsaPssVerifyDigest
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -120,3 +122,93 @@ RsaPssVerify (
return TRUE;
}
/**
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
)
{
INT32 Ret;
mbedtls_md_type_t MdAlg;
mbedtls_rsa_context *RsaKey;
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;
}
RsaKey = (mbedtls_rsa_context *)RsaContext;
if (mbedtls_rsa_complete (RsaKey) != 0) {
return FALSE;
}
switch (DigestSize) {
case SHA256_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA256;
break;
case SHA384_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA384;
break;
case SHA512_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA512;
break;
default:
return FALSE;
}
if (mbedtls_rsa_get_len (RsaContext) != SigSize) {
return FALSE;
}
mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V21, MdAlg);
Ret = mbedtls_rsa_rsassa_pss_verify (
RsaContext,
MdAlg,
(UINT32)DigestSize,
Digest,
Signature
);
if (Ret != 0) {
return FALSE;
}
return TRUE;
}

View file

@ -3,8 +3,10 @@
This file implements following APIs which provide basic capabilities for RSA:
1) RsaPssSign
2) RsaPssSignDigest
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -138,3 +140,95 @@ RsaPssSign (
*SigSize = ((mbedtls_rsa_context *)RsaContext)->len;
return TRUE;
}
/**
Carries out the RSA-PSS signature generation with EMSA-PSS encoding scheme
over a precomputed message digest.
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
)
{
INT32 Ret;
mbedtls_md_type_t MdAlg;
if (RsaContext == NULL) {
return FALSE;
}
if (mbedtls_rsa_complete ((mbedtls_rsa_context *)RsaContext) != 0) {
return FALSE;
}
if ((Digest == NULL) || (DigestSize == 0) || (DigestSize > INT_MAX) || (DigestSize > MAX_UINT16)) {
return FALSE;
}
switch (DigestSize) {
case SHA256_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA256;
break;
case SHA384_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA384;
break;
case SHA512_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA512;
break;
default:
return FALSE;
}
if (Signature == NULL) {
*SigSize = MBEDTLS_MPI_MAX_SIZE;
return FALSE;
}
Ret = mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V21, MdAlg);
if (Ret != 0) {
return FALSE;
}
Ret = mbedtls_rsa_rsassa_pss_sign (
RsaContext,
MbedtlsRand,
NULL,
MdAlg,
(UINT32)DigestSize,
Digest,
Signature
);
if (Ret != 0) {
return FALSE;
}
*SigSize = ((mbedtls_rsa_context *)RsaContext)->len;
return TRUE;
}

View file

@ -3,8 +3,10 @@
This file does not provide real capabilities for following APIs in RSA handling:
1) RsaPssSign
2) RsaPssSignDigest
Copyright (c) 2023, 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;
}

View file

@ -3,8 +3,10 @@
This file does not provide real capabilities for following APIs in RSA handling:
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
**/
@ -44,3 +46,30 @@ RsaPssVerify (
ASSERT (FALSE);
return FALSE;
}
/**
Verifies an RSA-PSS signature over a precomputed message digest.
@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.
@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
)
{
ASSERT (FALSE);
return FALSE;
}

View file

@ -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,32 @@ RsaPssSign (
ASSERT (FALSE);
return FALSE;
}
/**
Carries out the RSA-PSS signature generation over a precomputed message digest.
@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.
@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 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;
}

View file

@ -4,6 +4,7 @@
Copyright (C) Microsoft Corporation. All rights reserved.
Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -2068,39 +2069,6 @@ RsaPkcs1Verify (
CALL_CRYPTO_SERVICE (RsaPkcs1Verify, (RsaContext, MessageHash, HashSize, Signature, SigSize), FALSE);
}
/**
Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
Implementation determines salt length automatically from the signature encoding.
Mask generation function is the same as the message digest algorithm.
Salt length should be equal to digest length.
@param[in] RsaContext Pointer to RSA context for signature verification.
@param[in] Message Pointer to octet message to be verified.
@param[in] MsgSize Size of the message in bytes.
@param[in] Signature Pointer to RSASSA-PSS signature to be verified.
@param[in] SigSize Size of signature in bytes.
@param[in] DigestLen Length of digest for RSA operation.
@param[in] SaltLen Salt length for PSS encoding.
@retval TRUE Valid signature encoded in RSASSA-PSS.
@retval FALSE Invalid signature or invalid RSA context.
**/
BOOLEAN
EFIAPI
RsaPssVerify (
IN VOID *RsaContext,
IN CONST UINT8 *Message,
IN UINTN MsgSize,
IN CONST UINT8 *Signature,
IN UINTN SigSize,
IN UINT16 DigestLen,
IN UINT16 SaltLen
)
{
CALL_CRYPTO_SERVICE (RsaPssVerify, (RsaContext, Message, MsgSize, Signature, SigSize, DigestLen, SaltLen), FALSE);
}
/**
This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
RFC 8017.
@ -2146,6 +2114,94 @@ RsaPssSign (
CALL_CRYPTO_SERVICE (RsaPssSign, (RsaContext, Message, MsgSize, DigestLen, SaltLen, Signature, SigSize), FALSE);
}
/**
Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
Implementation determines salt length automatically from the signature encoding.
Mask generation function is the same as the message digest algorithm.
Salt length should be equal to digest length.
@param[in] RsaContext Pointer to RSA context for signature verification.
@param[in] Message Pointer to octet message to be verified.
@param[in] MsgSize Size of the message in bytes.
@param[in] Signature Pointer to RSASSA-PSS signature to be verified.
@param[in] SigSize Size of signature in bytes.
@param[in] DigestLen Length of digest for RSA operation.
@param[in] SaltLen Salt length for PSS encoding.
@retval TRUE Valid signature encoded in RSASSA-PSS.
@retval FALSE Invalid signature or invalid RSA context.
**/
BOOLEAN
EFIAPI
RsaPssVerify (
IN VOID *RsaContext,
IN CONST UINT8 *Message,
IN UINTN MsgSize,
IN CONST UINT8 *Signature,
IN UINTN SigSize,
IN UINT16 DigestLen,
IN UINT16 SaltLen
)
{
CALL_CRYPTO_SERVICE (RsaPssVerify, (RsaContext, Message, MsgSize, Signature, SigSize, DigestLen, SaltLen), FALSE);
}
/**
Carries out the RSA-PSS signature generation over a precomputed message digest.
@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
)
{
CALL_CRYPTO_SERVICE (RsaPssSignDigest, (RsaContext, Digest, DigestSize, Signature, SigSize), FALSE);
}
/**
Verifies an RSA-PSS signature over a precomputed message digest.
@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 (32=SHA-256, 48=SHA-384, 64=SHA-512).
@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
)
{
CALL_CRYPTO_SERVICE (RsaPssVerifyDigest, (RsaContext, Digest, DigestSize, Signature, SigSize), FALSE);
}
/**
Retrieve the RSA Private Key from the password-protected PEM key data.

View file

@ -3,6 +3,7 @@
Copyright (C) Microsoft Corporation. All rights reserved.
Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.<BR>
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -20,7 +21,7 @@
/// the EDK II Crypto Protocol is extended, this version define must be
/// increased.
///
#define EDKII_CRYPTO_VERSION 23
#define EDKII_CRYPTO_VERSION 24
///
/// EDK II Crypto Protocol forward declaration
@ -4472,6 +4473,55 @@ BOOLEAN
IN UINT16 SaltLen
);
/**
Carries out the RSA-PSS signature generation over a precomputed message digest.
@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.
**/
typedef
BOOLEAN
(EFIAPI *EDKII_CRYPTO_RSA_PSS_SIGN_DIGEST)(
IN VOID *RsaContext,
IN CONST UINT8 *Digest,
IN UINTN DigestSize,
OUT UINT8 *Signature,
IN OUT UINTN *SigSize
);
/**
Verifies an RSA-PSS signature over a precomputed message digest.
@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 (32=SHA-256, 48=SHA-384, 64=SHA-512).
@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.
**/
typedef
BOOLEAN
(EFIAPI *EDKII_CRYPTO_RSA_PSS_VERIFY_DIGEST)(
IN VOID *RsaContext,
IN CONST UINT8 *Digest,
IN UINTN DigestSize,
IN CONST UINT8 *Signature,
IN UINTN SigSize
);
/**
Parallel hash function ParallelHash256, as defined in NIST's Special Publication 800-185,
published December 2016.
@ -6121,6 +6171,9 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_EC_GROUP_SET_GENERATOR EcGroupSetGenerator;
EDKII_CRYPTO_EC_POINT_MUL2 EcPointMul2;
EDKII_CRYPTO_EC_POINTS_MUL EcPointsMul;
/// RSA PSS (Continued)
EDKII_CRYPTO_RSA_PSS_SIGN_DIGEST RsaPssSignDigest;
EDKII_CRYPTO_RSA_PSS_VERIFY_DIGEST RsaPssVerifyDigest;
};
extern GUID gEdkiiCryptoProtocolGuid;

View file

@ -227,6 +227,8 @@ also configured.
| TlsGet | N | N | | | C-Tls | | |
| RsaPss.Sign | N | N | | | C | | |
| RsaPss.Verify | N | N | | C | C | C | |
| RsaPss.SignDigest | N | N | | | C | | |
| RsaPss.VerifyDigest | N | N | | C | C | C | |
| ParallelHash | N | N | | | | C | |
| AeadAesGcm | N | N | | | C | | |
| Bn | N | N | | | C | C | |

View file

@ -2,6 +2,7 @@
Application for RSA PSS Primitives Validation.
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
(c) Copyright 2026 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -183,11 +184,79 @@ TestVerifyRsaPssSignVerify (
return UNIT_TEST_PASSED;
}
UNIT_TEST_STATUS
EFIAPI
TestVerifyRsaPssSignVerifyDigest (
IN UNIT_TEST_CONTEXT Context
)
{
UINT8 HashValue[SHA256_DIGEST_SIZE];
UINT8 *Signature;
UINTN SigSize;
BOOLEAN Status;
Status = RsaSetKey (mRsa, RsaKeyN, RsaPssN, sizeof (RsaPssN));
UT_ASSERT_TRUE (Status);
Status = RsaSetKey (mRsa, RsaKeyE, RsaPssE, sizeof (RsaPssE));
UT_ASSERT_TRUE (Status);
Status = RsaSetKey (mRsa, RsaKeyD, RsaPssD, sizeof (RsaPssD));
UT_ASSERT_TRUE (Status);
Status = Sha256HashAll (PssMessage, sizeof (PssMessage), HashValue);
UT_ASSERT_TRUE (Status);
//
// Query required signature buffer size
//
SigSize = 0;
Status = RsaPssSignDigest (mRsa, HashValue, sizeof (HashValue), NULL, &SigSize);
UT_ASSERT_FALSE (Status);
UT_ASSERT_NOT_EQUAL (SigSize, 0);
Signature = AllocatePool (SigSize);
if (Signature == NULL) {
UT_LOG_ERROR ("Failed to allocate memory for Signature");
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Sign the precomputed digest
//
Status = RsaPssSignDigest (mRsa, HashValue, sizeof (HashValue), Signature, &SigSize);
UT_ASSERT_TRUE (Status);
//
// Verify the signature using the digest-based verify API
//
Status = RsaPssVerifyDigest (mRsa, HashValue, sizeof (HashValue), Signature, SigSize);
UT_ASSERT_TRUE (Status);
//
// Corrupting one byte should fail digest-based verification
//
Signature[0] ^= 0xFF;
Status = RsaPssVerifyDigest (mRsa, HashValue, sizeof (HashValue), Signature, SigSize);
UT_ASSERT_FALSE (Status);
FreePool (Signature);
//
// Verify NIST FIPS 186-3 RSA test vector signature with precomputed digest
//
Status = RsaPssVerifyDigest (mRsa, HashValue, sizeof (HashValue), TestVectorSignature, sizeof (TestVectorSignature));
UT_ASSERT_TRUE (Status);
return UNIT_TEST_PASSED;
}
TEST_DESC mRsaPssTest[] = {
//
// -----Description--------------------------------------Class----------------------Function---------------------------------Pre---------------------Post---------Context
//
{ "TestVerifyRsaPssSignVerify()", "CryptoPkg.BaseCryptLib.Rsa", TestVerifyRsaPssSignVerify, TestVerifyRsaPssPreReq, TestVerifyRsaPssCleanUp, NULL },
{ "TestVerifyRsaPssSignVerify()", "CryptoPkg.BaseCryptLib.Rsa", TestVerifyRsaPssSignVerify, TestVerifyRsaPssPreReq, TestVerifyRsaPssCleanUp, NULL },
{ "TestVerifyRsaPssSignVerifyDigest()", "CryptoPkg.BaseCryptLib.Rsa", TestVerifyRsaPssSignVerifyDigest, TestVerifyRsaPssPreReq, TestVerifyRsaPssCleanUp, NULL },
};
UINTN mRsaPssTestNum = ARRAY_SIZE (mRsaPssTest);