From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by mx.groups.io with SMTP id smtpd.web09.16266.1621240568228056678 for ; Mon, 17 May 2021 01:36:08 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MgcaaUKp; spf=pass (domain: kernel.org, ip: 198.145.29.99, mailfrom: ardb@kernel.org) Received: by mail.kernel.org (Postfix) with ESMTPSA id 8762B610C9 for ; Mon, 17 May 2021 08:36:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1621240567; bh=VIxVfjSwtgmly+fAIOsNKBgk0WMyQBrUcVh071U2oBQ=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=MgcaaUKpwpkh7Kq6i4fwe60+6zojv3ICbn1kzMVgTvmJrnBQxxw4mMv1wMTwH9lVV aSF926mANT8R2CT1roPduQhtAk7cmjRTbKuaym0cEE+YCyeZt2hrQPoXNaeqHh3NwB yZKaVQ+pzkRb8N35qBME0WdkxLdSqM7OhmwSroOahYB/BUVJ23gpFR/Vk2a3Z6VN4R O4P3CzRBrmunxRlWCYx8qEBKbXEZOwn12RI+lySs+90qPJ1X6MEuTCxE7NHODdiTrt NhyBpk+z5LHYMZjmvOKrGqDs9IHOaQcB8TyINoOn/I2qRIvyGpAA9Tpkw2uYF6JoeU CaWgRFU4Te1hA== Received: by mail-oo1-f44.google.com with SMTP id s1-20020a4ac1010000b02901cfd9170ce2so1288822oop.12 for ; Mon, 17 May 2021 01:36:07 -0700 (PDT) X-Gm-Message-State: AOAM530WT34PU/IwMaHwtF4dHXhP80sanff91mXm70BSiHVtXs2MY9bw qiqkwOGxEBgDkxgt9Kl2BZau7O4jBe5qrX78JU0= X-Google-Smtp-Source: ABdhPJxuWKaihWrP645mKhGmqXog/DQ4JCQOMSk+SBSis36m6af7qQLV8LsFrmK9GTUn1oGmu8CN5O7IUW7DvZbKLFs= X-Received: by 2002:a4a:8706:: with SMTP id z6mr28600740ooh.41.1621240566779; Mon, 17 May 2021 01:36:06 -0700 (PDT) MIME-Version: 1.0 References: <20210504175445.21980-1-sachin.agrawal@intel.com> <20210504175445.21980-2-sachin.agrawal@intel.com> In-Reply-To: <20210504175445.21980-2-sachin.agrawal@intel.com> From: "Ard Biesheuvel" Date: Mon, 17 May 2021 10:35:55 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [edk2-devel] [PATCH v3 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support To: edk2-devel-groups-io , sachin.agrawal@intel.com Cc: Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Content-Type: text/plain; charset="UTF-8" On Tue, 4 May 2021 at 19:54, Agrawal, Sachin wrote: > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3314 > > This patch uses Openssl's EVP API's to perform RSASSA-PSS verification > of a binary blob. > > Cc: Jiewen Yao > Cc: Jian J Wang > Cc: Xiaoyu Lu > Cc: Guomin Jiang > > Signed-off-by: Sachin Agrawal This patch is now merged, and is breaking the build on AARCH64/CLANG38: CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c:117:7: error: variable 'Result' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] if (EvpVerifyCtx == NULL) { ^~~~~~~~~~~~~~~~~~~~ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note: uninitialized use occurs here return Result; ^~~~~~ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:117:3: note: remove the 'if' if its condition is always false if (EvpVerifyCtx == NULL) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:7: error: variable 'Result' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] if (EvpRsaKey == NULL) { ^~~~~~~~~~~~~~~~~ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:150:10: note: uninitialized use occurs here return Result; ^~~~~~ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:110:3: note: remove the 'if' if its condition is always false if (EvpRsaKey == NULL) { ^~~~~~~~~~~~~~~~~~~~~~~~ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c>:79:17: note: initialize the variable 'Result' to silence this warning BOOLEAN Result; ^ The diagnostic seems accurate: 'Result' is returned on the _Exit path, regardless of whether is has ever been initialized or not. Please fix this asap - it is affecting our CI. Thanks, Ard. > --- > > Notes: > v3: > - Fixed gcc compilation error [CI System] > > CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 146 +++++++++++++++ > CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 46 +++++ > CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c | 169 +++++++++++++++++ > CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c | 60 ++++++ > CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c | 46 +++++ > CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c | 60 ++++++ > CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 66 +++++++ > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c | 1 + > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c | 191 ++++++++++++++++++++ > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c | 2 + > CryptoPkg/Include/Library/BaseCryptLib.h | 74 ++++++++ > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 2 + > CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 2 + > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 2 + > CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 2 + > CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf | 2 + > CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 2 + > CryptoPkg/Private/Protocol/Crypto.h | 78 ++++++++ > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h | 3 + > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf | 1 + > CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf | 1 + > 21 files changed, 956 insertions(+) > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c > new file mode 100644 > index 000000000000..af7cdafa4c47 > --- /dev/null > +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c > @@ -0,0 +1,146 @@ > +/** @file > + RSA Asymmetric Cipher Wrapper Implementation over OpenSSL. > + > + This file implements following APIs which provide basic capabilities for RSA: > + 1) RsaPssVerify > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "InternalCryptLib.h" > + > +#include > +#include > +#include > +#include > + > + > +/** > + Retrieve a pointer to EVP message digest object. > + > + @param[in] DigestLen Length of the message digest. > + > +**/ > +STATIC > +const > +EVP_MD* > +GetEvpMD ( > + IN UINT16 DigestLen > + ) > +{ > + switch (DigestLen){ > + case SHA256_DIGEST_SIZE: > + return EVP_sha256(); > + break; > + case SHA384_DIGEST_SIZE: > + return EVP_sha384(); > + break; > + case SHA512_DIGEST_SIZE: > + return EVP_sha512(); > + break; > + default: > + return NULL; > + } > +} > + > + > +/** > + 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 atleast 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 > + ) > +{ > + BOOLEAN Result; > + EVP_PKEY *pEvpRsaKey = NULL; > + EVP_MD_CTX *pEvpVerifyCtx = NULL; > + EVP_PKEY_CTX *pKeyCtx = NULL; > + CONST EVP_MD *HashAlg = NULL; > + > + if (RsaContext == NULL) { > + return FALSE; > + } > + if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) { > + return FALSE; > + } > + if (Signature == NULL || SigSize == 0 || SigSize > INT_MAX) { > + return FALSE; > + } > + if (SaltLen < DigestLen) { > + return FALSE; > + } > + > + HashAlg = GetEvpMD(DigestLen); > + > + if (HashAlg == NULL) { > + return FALSE; > + } > + > + pEvpRsaKey = EVP_PKEY_new(); > + if (pEvpRsaKey == NULL) { > + goto _Exit; > + } > + > + EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext); > + > + pEvpVerifyCtx = EVP_MD_CTX_create(); > + if (pEvpVerifyCtx == NULL) { > + goto _Exit; > + } > + > + Result = EVP_DigestVerifyInit(pEvpVerifyCtx, &pKeyCtx, HashAlg, NULL, pEvpRsaKey) > 0; > + if (pKeyCtx == NULL) { > + goto _Exit; > + } > + > + if (Result) { > + Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING) > 0; > + } > + if (Result) { > + Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, SaltLen) > 0; > + } > + if (Result) { > + Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0; > + } > + if (Result) { > + Result = EVP_DigestVerifyUpdate(pEvpVerifyCtx, Message, (UINT32)MsgSize) > 0; > + } > + if (Result) { > + Result = EVP_DigestVerifyFinal(pEvpVerifyCtx, Signature, (UINT32)SigSize) > 0; > + } > + > +_Exit : > + if (pEvpRsaKey) { > + EVP_PKEY_free(pEvpRsaKey); > + } > + if (pEvpVerifyCtx) { > + EVP_MD_CTX_destroy(pEvpVerifyCtx); > + } > + > + return Result; > +} > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c > new file mode 100644 > index 000000000000..69c6889fbc4b > --- /dev/null > +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c > @@ -0,0 +1,46 @@ > +/** @file > + RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL. > + > + This file does not provide real capabilities for following APIs in RSA handling: > + 1) RsaPssVerify > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "InternalCryptLib.h" > + > +/** > + 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 atleast 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 > + ) > +{ > + ASSERT (FALSE); > + return FALSE; > +} > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c > new file mode 100644 > index 000000000000..1ed076e4192c > --- /dev/null > +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSign.c > @@ -0,0 +1,169 @@ > +/** @file > + RSA PSS Asymmetric Cipher Wrapper Implementation over OpenSSL. > + > + This file implements following APIs which provide basic capabilities for RSA: > + 1) RsaPssSign > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "InternalCryptLib.h" > + > +#include > +#include > +#include > +#include > + > + > +/** > + Retrieve a pointer to EVP message digest object. > + > + @param[in] DigestLen Length of the message digest. > + > +**/ > +STATIC > +const > +EVP_MD* > +GetEvpMD ( > + IN UINT16 DigestLen > + ) > +{ > + switch (DigestLen){ > + case SHA256_DIGEST_SIZE: > + return EVP_sha256(); > + break; > + case SHA384_DIGEST_SIZE: > + return EVP_sha384(); > + break; > + case SHA512_DIGEST_SIZE: > + return EVP_sha512(); > + break; > + default: > + return NULL; > + } > +} > + > + > +/** > + Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme. > + > + This function carries out the RSA-SSA 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 Message is NULL, then return FALSE. > + If MsgSize is zero or > INT_MAX, then return FALSE. > + If DigestLen is NOT 32, 48 or 64, return FALSE. > + If SaltLen is < DigestLen, 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] Message Pointer to octet message to be signed. > + @param[in] MsgSize Size of the message in bytes. > + @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation. > + @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding. > + @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 > +RsaPssSign ( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen, > + OUT UINT8 *Signature, > + IN OUT UINTN *SigSize > + ) > +{ > + BOOLEAN Result; > + UINTN RsaSigSize; > + EVP_PKEY *pEvpRsaKey = NULL; > + EVP_MD_CTX *pEvpVerifyCtx = NULL; > + EVP_PKEY_CTX *pKeyCtx = NULL; > + CONST EVP_MD *HashAlg = NULL; > + > + if (RsaContext == NULL) { > + return FALSE; > + } > + if (Message == NULL || MsgSize == 0 || MsgSize > INT_MAX) { > + return FALSE; > + } > + > + RsaSigSize = RSA_size (RsaContext); > + if (*SigSize < RsaSigSize) { > + *SigSize = RsaSigSize; > + return FALSE; > + } > + > + if (Signature == NULL) { > + return FALSE; > + } > + > + if (SaltLen < DigestLen) { > + return FALSE; > + } > + > + HashAlg = GetEvpMD(DigestLen); > + > + if (HashAlg == NULL) { > + return FALSE; > + } > + > + pEvpRsaKey = EVP_PKEY_new(); > + if (pEvpRsaKey == NULL) { > + goto _Exit; > + } > + > + EVP_PKEY_set1_RSA(pEvpRsaKey, RsaContext); > + > + pEvpVerifyCtx = EVP_MD_CTX_create(); > + if (pEvpVerifyCtx == NULL) { > + goto _Exit; > + } > + > + Result = EVP_DigestSignInit(pEvpVerifyCtx, &pKeyCtx, HashAlg, NULL, pEvpRsaKey) > 0; > + if (pKeyCtx == NULL) { > + goto _Exit; > + } > + > + if (Result) { > + Result = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING) > 0; > + } > + if (Result) { > + Result = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, SaltLen) > 0; > + } > + if (Result) { > + Result = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, HashAlg) > 0; > + } > + if (Result) { > + Result = EVP_DigestSignUpdate(pEvpVerifyCtx, Message, (UINT32)MsgSize) > 0; > + } > + if (Result) { > + Result = EVP_DigestSignFinal(pEvpVerifyCtx, Signature, SigSize) > 0; > + } > + > +_Exit : > + if (pEvpRsaKey) { > + EVP_PKEY_free(pEvpRsaKey); > + } > + if (pEvpVerifyCtx) { > + EVP_MD_CTX_destroy(pEvpVerifyCtx); > + } > + > + return Result; > +} > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c > new file mode 100644 > index 000000000000..4ed2dfce992a > --- /dev/null > +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssSignNull.c > @@ -0,0 +1,60 @@ > +/** @file > + RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL. > + > + This file does not provide real capabilities for following APIs in RSA handling: > + 1) RsaPssSign > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "InternalCryptLib.h" > + > +/** > + Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme. > + > + This function carries out the RSA-SSA 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 Message is NULL, then return FALSE. > + If MsgSize is zero or > INT_MAX, then return FALSE. > + If DigestLen is NOT 32, 48 or 64, return FALSE. > + If SaltLen is < DigestLen, 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] Message Pointer to octet message to be signed. > + @param[in] MsgSize Size of the message in bytes. > + @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation. > + @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding. > + @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 > +RsaPssSign ( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen, > + OUT UINT8 *Signature, > + IN OUT UINTN *SigSize > + ) > +{ > + ASSERT (FALSE); > + return FALSE; > +} > diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c > new file mode 100644 > index 000000000000..69c6889fbc4b > --- /dev/null > +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssNull.c > @@ -0,0 +1,46 @@ > +/** @file > + RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL. > + > + This file does not provide real capabilities for following APIs in RSA handling: > + 1) RsaPssVerify > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "InternalCryptLib.h" > + > +/** > + 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 atleast 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 > + ) > +{ > + ASSERT (FALSE); > + return FALSE; > +} > diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c > new file mode 100644 > index 000000000000..4ed2dfce992a > --- /dev/null > +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptRsaPssSignNull.c > @@ -0,0 +1,60 @@ > +/** @file > + RSA-PSS Asymmetric Cipher Wrapper Implementation over OpenSSL. > + > + This file does not provide real capabilities for following APIs in RSA handling: > + 1) RsaPssSign > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "InternalCryptLib.h" > + > +/** > + Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme. > + > + This function carries out the RSA-SSA 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 Message is NULL, then return FALSE. > + If MsgSize is zero or > INT_MAX, then return FALSE. > + If DigestLen is NOT 32, 48 or 64, return FALSE. > + If SaltLen is < DigestLen, 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] Message Pointer to octet message to be signed. > + @param[in] MsgSize Size of the message in bytes. > + @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation. > + @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding. > + @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 > +RsaPssSign ( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen, > + OUT UINT8 *Signature, > + IN OUT UINTN *SigSize > + ) > +{ > + ASSERT (FALSE); > + return FALSE; > +} > diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c > index 8b43d1363cb9..412fbdbff52c 100644 > --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c > +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c > @@ -1552,6 +1552,72 @@ 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 atleast 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); > +} > + > +/** > + 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 atleast 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 > +RsaPssSign ( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen, > + OUT UINT8 *Signature, > + IN OUT UINTN *SigSize > + ) > +{ > + CALL_CRYPTO_SERVICE (RsaPssSign, (RsaContext, Message, MsgSize, DigestLen, SaltLen, Signature, SigSize), FALSE); > +} > + > /** > Retrieve the RSA Private Key from the password-protected PEM key data. > > diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c > index b7fcea3ff7e4..3873de973064 100644 > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c > @@ -16,6 +16,7 @@ SUITE_DESC mSuiteDesc[] = { > {"HMAC verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mHmacTestNum, mHmacTest}, > {"BlockCipher verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mBlockCipherTestNum, mBlockCipherTest}, > {"RSA verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mRsaTestNum, mRsaTest}, > + {"RSA PSS verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mRsaPssTestNum, mRsaPssTest}, > {"RSACert verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mRsaCertTestNum, mRsaCertTest}, > {"PKCS7 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mPkcs7TestNum, mPkcs7Test}, > {"PKCS5 verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mPkcs5TestNum, mPkcs5Test}, > diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c > new file mode 100644 > index 000000000000..5ac2f325fbdd > --- /dev/null > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPssTests.c > @@ -0,0 +1,191 @@ > +/** @file > + Application for RSA PSS Primitives Validation. > + > +Copyright (c) 2021, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "TestBaseCryptLib.h" > + > +// > +// RSA PSS test vectors from NIST FIPS 186-3 RSA files > +// > + > +// > +// Public Modulus of RSA Key > +// > +UINT8 RsaPssN[]={ > + 0xa4, 0x7d, 0x04, 0xe7, 0xca, 0xcd, 0xba, 0x4e, 0xa2, 0x6e, 0xca, 0x8a, 0x4c, 0x6e, 0x14, 0x56, > + 0x3c, 0x2c, 0xe0, 0x3b, 0x62, 0x3b, 0x76, 0x8c, 0x0d, 0x49, 0x86, 0x8a, 0x57, 0x12, 0x13, 0x01, > + 0xdb, 0xf7, 0x83, 0xd8, 0x2f, 0x4c, 0x05, 0x5e, 0x73, 0x96, 0x0e, 0x70, 0x55, 0x01, 0x87, 0xd0, > + 0xaf, 0x62, 0xac, 0x34, 0x96, 0xf0, 0xa3, 0xd9, 0x10, 0x3c, 0x2e, 0xb7, 0x91, 0x9a, 0x72, 0x75, > + 0x2f, 0xa7, 0xce, 0x8c, 0x68, 0x8d, 0x81, 0xe3, 0xae, 0xe9, 0x94, 0x68, 0x88, 0x7a, 0x15, 0x28, > + 0x8a, 0xfb, 0xb7, 0xac, 0xb8, 0x45, 0xb7, 0xc5, 0x22, 0xb5, 0xc6, 0x4e, 0x67, 0x8f, 0xcd, 0x3d, > + 0x22, 0xfe, 0xb8, 0x4b, 0x44, 0x27, 0x27, 0x00, 0xbe, 0x52, 0x7d, 0x2b, 0x20, 0x25, 0xa3, 0xf8, > + 0x3c, 0x23, 0x83, 0xbf, 0x6a, 0x39, 0xcf, 0x5b, 0x4e, 0x48, 0xb3, 0xcf, 0x2f, 0x56, 0xee, 0xf0, > + 0xdf, 0xff, 0x18, 0x55, 0x5e, 0x31, 0x03, 0x7b, 0x91, 0x52, 0x48, 0x69, 0x48, 0x76, 0xf3, 0x04, > + 0x78, 0x14, 0x41, 0x51, 0x64, 0xf2, 0xc6, 0x60, 0x88, 0x1e, 0x69, 0x4b, 0x58, 0xc2, 0x80, 0x38, > + 0xa0, 0x32, 0xad, 0x25, 0x63, 0x4a, 0xad, 0x7b, 0x39, 0x17, 0x1d, 0xee, 0x36, 0x8e, 0x3d, 0x59, > + 0xbf, 0xb7, 0x29, 0x9e, 0x46, 0x01, 0xd4, 0x58, 0x7e, 0x68, 0xca, 0xaf, 0x8d, 0xb4, 0x57, 0xb7, > + 0x5a, 0xf4, 0x2f, 0xc0, 0xcf, 0x1a, 0xe7, 0xca, 0xce, 0xd2, 0x86, 0xd7, 0x7f, 0xac, 0x6c, 0xed, > + 0xb0, 0x3a, 0xd9, 0x4f, 0x14, 0x33, 0xd2, 0xc9, 0x4d, 0x08, 0xe6, 0x0b, 0xc1, 0xfd, 0xef, 0x05, > + 0x43, 0xcd, 0x29, 0x51, 0xe7, 0x65, 0xb3, 0x82, 0x30, 0xfd, 0xd1, 0x8d, 0xe5, 0xd2, 0xca, 0x62, > + 0x7d, 0xdc, 0x03, 0x2f, 0xe0, 0x5b, 0xbd, 0x2f, 0xf2, 0x1e, 0x2d, 0xb1, 0xc2, 0xf9, 0x4d, 0x8b, > + }; > + > +// > +// Public Exponent of RSA Key > +// > +UINT8 RsaPssE[]={ 0x10, 0xe4, 0x3f }; > + > +// > +// Private Exponent of RSA Key > +// > +UINT8 RsaPssD[]={ > + 0x11, 0xa0, 0xdd, 0x28, 0x5f, 0x66, 0x47, 0x1a, 0x8d, 0xa3, 0x0b, 0xcb, 0x8c, 0x24, 0xa1, 0xd5, > + 0xc8, 0xdb, 0x94, 0x2f, 0xc9, 0x92, 0x07, 0x97, 0xca, 0x44, 0x24, 0x60, 0xa8, 0x00, 0xb7, 0x5b, > + 0xbc, 0x73, 0x8b, 0xeb, 0x8e, 0xe0, 0xe8, 0x74, 0xb0, 0x53, 0xe6, 0x47, 0x07, 0xdf, 0x4c, 0xfc, > + 0x78, 0x37, 0xc4, 0x0e, 0x5b, 0xe6, 0x8b, 0x8a, 0x8e, 0x1d, 0x01, 0x45, 0x16, 0x9c, 0xa6, 0x27, > + 0x1d, 0x81, 0x88, 0x7e, 0x19, 0xa1, 0xcd, 0x95, 0xb2, 0xfd, 0x0d, 0xe0, 0xdb, 0xa3, 0x47, 0xfe, > + 0x63, 0x7b, 0xcc, 0x6c, 0xdc, 0x24, 0xee, 0xbe, 0x03, 0xc2, 0x4d, 0x4c, 0xf3, 0xa5, 0xc6, 0x15, > + 0x4d, 0x78, 0xf1, 0x41, 0xfe, 0x34, 0x16, 0x99, 0x24, 0xd0, 0xf8, 0x95, 0x33, 0x65, 0x8e, 0xac, > + 0xfd, 0xea, 0xe9, 0x9c, 0xe1, 0xa8, 0x80, 0x27, 0xc1, 0x8f, 0xf9, 0x26, 0x53, 0xa8, 0x35, 0xaa, > + 0x38, 0x91, 0xbf, 0xff, 0xcd, 0x38, 0x8f, 0xfc, 0x23, 0x88, 0xce, 0x2b, 0x10, 0x56, 0x85, 0x43, > + 0x75, 0x05, 0x02, 0xcc, 0xbc, 0x69, 0xc0, 0x08, 0x8f, 0x1d, 0x69, 0x0e, 0x97, 0xa5, 0xf5, 0xbd, > + 0xd1, 0x88, 0x8c, 0xd2, 0xfa, 0xa4, 0x3c, 0x04, 0xae, 0x24, 0x53, 0x95, 0x22, 0xdd, 0xe2, 0xd9, > + 0xc2, 0x02, 0xf6, 0x55, 0xfc, 0x55, 0x75, 0x44, 0x40, 0xb5, 0x3a, 0x15, 0x32, 0xaa, 0xb4, 0x78, > + 0x51, 0xf6, 0x0b, 0x7a, 0x06, 0x7e, 0x24, 0x0b, 0x73, 0x8e, 0x1b, 0x1d, 0xaa, 0xe6, 0xca, 0x0d, > + 0x59, 0xee, 0xae, 0x27, 0x68, 0x6c, 0xd8, 0x88, 0x57, 0xe9, 0xad, 0xad, 0xc2, 0xd4, 0xb8, 0x2b, > + 0x07, 0xa6, 0x1a, 0x35, 0x84, 0x56, 0xaa, 0xf8, 0x07, 0x66, 0x96, 0x93, 0xff, 0xb1, 0x3c, 0x99, > + 0x64, 0xa6, 0x36, 0x54, 0xca, 0xdc, 0x81, 0xee, 0x59, 0xdf, 0x51, 0x1c, 0xa3, 0xa4, 0xbd, 0x67, > + }; > + > +// > +// Binary message to be signed and verified > +// > +UINT8 PssMessage[]={ > + 0xe0, 0x02, 0x37, 0x7a, 0xff, 0xb0, 0x4f, 0x0f, 0xe4, 0x59, 0x8d, 0xe9, 0xd9, 0x2d, 0x31, 0xd6, > + 0xc7, 0x86, 0x04, 0x0d, 0x57, 0x76, 0x97, 0x65, 0x56, 0xa2, 0xcf, 0xc5, 0x5e, 0x54, 0xa1, 0xdc, > + 0xb3, 0xcb, 0x1b, 0x12, 0x6b, 0xd6, 0xa4, 0xbe, 0xd2, 0xa1, 0x84, 0x99, 0x0c, 0xce, 0xa7, 0x73, > + 0xfc, 0xc7, 0x9d, 0x24, 0x65, 0x53, 0xe6, 0xc6, 0x4f, 0x68, 0x6d, 0x21, 0xad, 0x41, 0x52, 0x67, > + 0x3c, 0xaf, 0xec, 0x22, 0xae, 0xb4, 0x0f, 0x6a, 0x08, 0x4e, 0x8a, 0x5b, 0x49, 0x91, 0xf4, 0xc6, > + 0x4c, 0xf8, 0xa9, 0x27, 0xef, 0xfd, 0x0f, 0xd7, 0x75, 0xe7, 0x1e, 0x83, 0x29, 0xe4, 0x1f, 0xdd, > + 0x44, 0x57, 0xb3, 0x91, 0x11, 0x73, 0x18, 0x7b, 0x4f, 0x09, 0xa8, 0x17, 0xd7, 0x9e, 0xa2, 0x39, > + 0x7f, 0xc1, 0x2d, 0xfe, 0x3d, 0x9c, 0x9a, 0x02, 0x90, 0xc8, 0xea, 0xd3, 0x1b, 0x66, 0x90, 0xa6, > + }; > + > +// > +// Binary message to be signed and verified > +// > +UINT8 PssSalt[]={ > + 0xd6, 0x6f, 0x72, 0xf1, 0x0b, 0x69, 0x00, 0x1a, 0x5b, 0x59, 0xcf, 0x10, 0x92, 0xad, 0x27, 0x4d, > + 0x50, 0x56, 0xc4, 0xe9, 0x5c, 0xcc, 0xcf, 0xbe, 0x3b, 0x53, 0x0d, 0xcb, 0x02, 0x7e, 0x57, 0xd6 > + }; > + > +// > +// RSASSA-PSS Signature over above message using above keys, salt and SHA256 digest(and MGF1) algo. > +// > +UINT8 TestVectorSignature[]={ > + 0x4f, 0x9b, 0x42, 0x5c, 0x20, 0x58, 0x46, 0x0e, 0x4a, 0xb2, 0xf5, 0xc9, 0x63, 0x84, 0xda, 0x23, > + 0x27, 0xfd, 0x29, 0x15, 0x0f, 0x01, 0x95, 0x5a, 0x76, 0xb4, 0xef, 0xe9, 0x56, 0xaf, 0x06, 0xdc, > + 0x08, 0x77, 0x9a, 0x37, 0x4e, 0xe4, 0x60, 0x7e, 0xab, 0x61, 0xa9, 0x3a, 0xdc, 0x56, 0x08, 0xf4, > + 0xec, 0x36, 0xe4, 0x7f, 0x2a, 0x0f, 0x75, 0x4e, 0x8f, 0xf8, 0x39, 0xa8, 0xa1, 0x9b, 0x1d, 0xb1, > + 0xe8, 0x84, 0xea, 0x4c, 0xf3, 0x48, 0xcd, 0x45, 0x50, 0x69, 0xeb, 0x87, 0xaf, 0xd5, 0x36, 0x45, > + 0xb4, 0x4e, 0x28, 0xa0, 0xa5, 0x68, 0x08, 0xf5, 0x03, 0x1d, 0xa5, 0xba, 0x91, 0x12, 0x76, 0x8d, > + 0xfb, 0xfc, 0xa4, 0x4e, 0xbe, 0x63, 0xa0, 0xc0, 0x57, 0x2b, 0x73, 0x1d, 0x66, 0x12, 0x2f, 0xb7, > + 0x16, 0x09, 0xbe, 0x14, 0x80, 0xfa, 0xa4, 0xe4, 0xf7, 0x5e, 0x43, 0x95, 0x51, 0x59, 0xd7, 0x0f, > + 0x08, 0x1e, 0x2a, 0x32, 0xfb, 0xb1, 0x9a, 0x48, 0xb9, 0xf1, 0x62, 0xcf, 0x6b, 0x2f, 0xb4, 0x45, > + 0xd2, 0xd6, 0x99, 0x4b, 0xc5, 0x89, 0x10, 0xa2, 0x6b, 0x59, 0x43, 0x47, 0x78, 0x03, 0xcd, 0xaa, > + 0xa1, 0xbd, 0x74, 0xb0, 0xda, 0x0a, 0x5d, 0x05, 0x3d, 0x8b, 0x1d, 0xc5, 0x93, 0x09, 0x1d, 0xb5, > + 0x38, 0x83, 0x83, 0xc2, 0x60, 0x79, 0xf3, 0x44, 0xe2, 0xae, 0xa6, 0x00, 0xd0, 0xe3, 0x24, 0x16, > + 0x4b, 0x45, 0x0f, 0x7b, 0x9b, 0x46, 0x51, 0x11, 0xb7, 0x26, 0x5f, 0x3b, 0x1b, 0x06, 0x30, 0x89, > + 0xae, 0x7e, 0x26, 0x23, 0xfc, 0x0f, 0xda, 0x80, 0x52, 0xcf, 0x4b, 0xf3, 0x37, 0x91, 0x02, 0xfb, > + 0xf7, 0x1d, 0x7c, 0x98, 0xe8, 0x25, 0x86, 0x64, 0xce, 0xed, 0x63, 0x7d, 0x20, 0xf9, 0x5f, 0xf0, > + 0x11, 0x18, 0x81, 0xe6, 0x50, 0xce, 0x61, 0xf2, 0x51, 0xd9, 0xc3, 0xa6, 0x29, 0xef, 0x22, 0x2d, > + }; > + > + > +VOID *mRsa; > + > +UNIT_TEST_STATUS > +EFIAPI > +TestVerifyRsaPssPreReq ( > + UNIT_TEST_CONTEXT Context > + ) > +{ > + mRsa = RsaNew (); > + > + if (mRsa == NULL) { > + return UNIT_TEST_ERROR_TEST_FAILED; > + } > + > + return UNIT_TEST_PASSED; > +} > + > +VOID > +EFIAPI > +TestVerifyRsaPssCleanUp ( > + UNIT_TEST_CONTEXT Context > + ) > +{ > + if (mRsa != NULL) { > + RsaFree (mRsa); > + mRsa = NULL; > + } > +} > + > + > +UNIT_TEST_STATUS > +EFIAPI > +TestVerifyRsaPssSignVerify ( > + IN UNIT_TEST_CONTEXT Context > + ) > +{ > + 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); > + > + SigSize = 0; > + Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage), SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, NULL, &SigSize); > + UT_ASSERT_FALSE (Status); > + UT_ASSERT_NOT_EQUAL (SigSize, 0); > + > + Signature = AllocatePool (SigSize); > + Status = RsaPssSign (mRsa, PssMessage, sizeof(PssMessage), SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, Signature, &SigSize); > + UT_ASSERT_TRUE (Status); > + > + // > + // Verify RSA PSS encoded Signature generated in above step > + // > + Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage), Signature, SigSize, SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE); > + UT_ASSERT_TRUE (Status); > + > + // > + // Verify NIST FIPS 186-3 RSA test vector signature > + // > + Status = RsaPssVerify (mRsa, PssMessage, sizeof(PssMessage), TestVectorSignature, sizeof(TestVectorSignature), SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE); > + UT_ASSERT_TRUE (Status); > + > + FreePool(Signature); > + return UNIT_TEST_PASSED; > +} > + > + > +TEST_DESC mRsaPssTest[] = { > + // > + // -----Description--------------------------------------Class----------------------Function---------------------------------Pre---------------------Post---------Context > + // > + {"TestVerifyRsaPssSignVerify()", "CryptoPkg.BaseCryptLib.Rsa", TestVerifyRsaPssSignVerify, TestVerifyRsaPssPreReq, TestVerifyRsaPssCleanUp, NULL}, > +}; > + > +UINTN mRsaPssTestNum = ARRAY_SIZE(mRsaPssTest); > diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c > index 7ce20d2e778f..0969b6aea660 100644 > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c > @@ -295,6 +295,8 @@ TestVerifyRsaPkcs1SignVerify ( > Status = RsaPkcs1Verify (mRsa, HashValue, HashSize, Signature, SigSize); > UT_ASSERT_TRUE (Status); > > + FreePool(Signature); > + > return UNIT_TEST_PASSED; > } > > diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h > index 496121e6a4ed..8c7d5922ef96 100644 > --- a/CryptoPkg/Include/Library/BaseCryptLib.h > +++ b/CryptoPkg/Include/Library/BaseCryptLib.h > @@ -1363,6 +1363,80 @@ RsaPkcs1Verify ( > IN UINTN SigSize > ); > > +/** > + Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme. > + > + This function carries out the RSA-SSA 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 Message is NULL, then return FALSE. > + If MsgSize is zero or > INT_MAX, then return FALSE. > + If DigestLen is NOT 32, 48 or 64, return FALSE. > + If SaltLen is < DigestLen, 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] Message Pointer to octet message to be signed. > + @param[in] MsgSize Size of the message in bytes. > + @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation. > + @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding. > + @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 > +RsaPssSign ( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen, > + OUT UINT8 *Signature, > + IN OUT UINTN *SigSize > + ); > + > +/** > + 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 atleast 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 > + ); > + > /** > Retrieve the RSA Private Key from the password-protected PEM key data. > > diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf > index 4aae2aba95d6..49703fa4c963 100644 > --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf > +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf > @@ -49,6 +49,8 @@ > Pk/CryptX509.c > Pk/CryptAuthenticode.c > Pk/CryptTs.c > + Pk/CryptRsaPss.c > + Pk/CryptRsaPssSign.c > Pem/CryptPem.c > > SysCall/CrtWrapper.c > diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf > index 7509e4273028..0cab5f3ce36c 100644 > --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf > +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf > @@ -55,6 +55,8 @@ > Pk/CryptX509Null.c > Pk/CryptAuthenticodeNull.c > Pk/CryptTsNull.c > + Pk/CryptRsaPss.c > + Pk/CryptRsaPssSignNull.c > Pem/CryptPemNull.c > Rand/CryptRandNull.c > > diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf > index 70c985ec93dc..3d3a6fb94a77 100644 > --- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf > +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf > @@ -55,6 +55,8 @@ > Pk/CryptX509.c > Pk/CryptAuthenticodeNull.c > Pk/CryptTsNull.c > + Pk/CryptRsaPssNull.c > + Pk/CryptRsaPssSignNull.c > Pem/CryptPem.c > > SysCall/CrtWrapper.c > diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf > index 91ec3e03bf5e..07c376ce04bb 100644 > --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf > +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf > @@ -53,6 +53,8 @@ > Pk/CryptX509.c > Pk/CryptAuthenticodeNull.c > Pk/CryptTsNull.c > + Pk/CryptRsaPss.c > + Pk/CryptRsaPssSignNull.c > Pem/CryptPem.c > > SysCall/CrtWrapper.c > diff --git a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf > index db506c32f724..b98f9635b27b 100644 > --- a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf > +++ b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf > @@ -44,6 +44,8 @@ > Pk/CryptAuthenticode.c > Pk/CryptTs.c > Pem/CryptPem.c > + Pk/CryptRsaPss.c > + Pk/CryptRsaPssSign.c > > SysCall/UnitTestHostCrtWrapper.c > > diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf > index 689af4fedd68..faf959827b90 100644 > --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf > +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf > @@ -50,6 +50,8 @@ > Pk/CryptTsNull.c > Pem/CryptPemNull.c > Rand/CryptRandNull.c > + Pk/CryptRsaPssNull.c > + Pk/CryptRsaPssSignNull.c > > [Packages] > MdePkg/MdePkg.dec > diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h > index 17930a77a60e..e304302c9445 100644 > --- a/CryptoPkg/Private/Protocol/Crypto.h > +++ b/CryptoPkg/Private/Protocol/Crypto.h > @@ -3408,6 +3408,81 @@ EFI_STATUS > IN OUT UINTN *DataSize > ); > > +/** > + Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme. > + > + This function carries out the RSA-SSA 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 Message is NULL, then return FALSE. > + If MsgSize is zero or > INT_MAX, then return FALSE. > + If DigestLen is NOT 32, 48 or 64, return FALSE. > + If SaltLen is < DigestLen, 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] Message Pointer to octet message to be signed. > + @param[in] MsgSize Size of the message in bytes. > + @param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation. > + @param[in] SaltLen Length of the salt in bytes to be used for PSS encoding. > + @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)( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen, > + OUT UINT8 *Signature, > + IN OUT UINTN *SigSize > + ); > + > +/** > + 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 atleast 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. > + > +**/ > +typedef > +BOOLEAN > +(EFIAPI* EDKII_CRYPTO_RSA_PSS_VERIFY)( > + IN VOID *RsaContext, > + IN CONST UINT8 *Message, > + IN UINTN MsgSize, > + IN CONST UINT8 *Signature, > + IN UINTN SigSize, > + IN UINT16 DigestLen, > + IN UINT16 SaltLen > + ); > + > + > > /// > /// EDK II Crypto Protocol > @@ -3593,6 +3668,9 @@ struct _EDKII_CRYPTO_PROTOCOL { > EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert; > EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey; > EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocationList; > + /// RSA PSS > + EDKII_CRYPTO_RSA_PSS_SIGN RsaPssSign; > + EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify; > }; > > extern GUID gEdkiiCryptoProtocolGuid; > diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h > index 9d1cb150a113..25c1379f1a77 100644 > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h > @@ -83,6 +83,9 @@ extern TEST_DESC mPrngTest[]; > extern UINTN mOaepTestNum; > extern TEST_DESC mOaepTest[]; > > +extern UINTN mRsaPssTestNum; > +extern TEST_DESC mRsaPssTest[]; > + > /** Creates a framework you can use */ > EFI_STATUS > EFIAPI > diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf > index 300b98e40b33..00c869265080 100644 > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf > @@ -34,6 +34,7 @@ > RandTests.c > Pkcs7EkuTests.c > OaepEncryptTests.c > + RsaPssTests.c > > [Packages] > MdePkg/MdePkg.dec > diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf > index d5e7e0d01446..ca789aa6ada3 100644 > --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf > +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf > @@ -35,6 +35,7 @@ > RandTests.c > Pkcs7EkuTests.c > OaepEncryptTests.c > + RsaPssTests.c > > [Packages] > MdePkg/MdePkg.dec > -- > 2.14.3.windows.1 > > > > > >