From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com []) by mx.groups.io with SMTP id smtpd.web09.4724.1618884113163528677 for ; Mon, 19 Apr 2021 19:01:53 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: sachin.agrawal@intel.com) IronPort-SDR: sTx4Xxgg+9QjOfrqLdymWBcEt9qBzVikp7v1N+sp7NIGHMQGSZWh+N1vx3Ue7EDyF7mUJ7HORw mwClc57dPHzQ== X-IronPort-AV: E=McAfee;i="6200,9189,9959"; a="192241826" X-IronPort-AV: E=Sophos;i="5.82,235,1613462400"; d="scan'208";a="192241826" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2021 19:01:51 -0700 IronPort-SDR: /DgigqG1R+TstKFm7RFe+qZQvnX5W8/WW/N8QMknxTfVtNMjqeJCvVy4oWtS+5m/Si4C1FDJX2 R14gaDarUxLQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,235,1613462400"; d="scan'208";a="602316795" Received: from sagraw2-desk1.amr.corp.intel.com ([10.72.4.190]) by orsmga005.jf.intel.com with ESMTP; 19 Apr 2021 19:01:51 -0700 From: "Agrawal, Sachin" To: devel@edk2.groups.io Cc: Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang , Sachin Agrawal Subject: [PATCH v1 1/1] CryptoPkg: BaseCryptLib: Add RSA PSS verify support Date: Mon, 19 Apr 2021 19:01:50 -0700 Message-Id: <20210420020150.29212-2-sachin.agrawal@intel.com> X-Mailer: git-send-email 2.14.3.windows.1 In-Reply-To: <20210420020150.29212-1-sachin.agrawal@intel.com> References: <20210420020150.29212-1-sachin.agrawal@intel.com> 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 --- CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c | 139 ++++++++++++++++++++ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c | 43 ++++++ CryptoPkg/Include/Library/BaseCryptLib.h | 27 ++++ CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 + 7 files changed, 213 insertions(+) diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c new file mode 100644 index 000000000000..acf5eb689cd8 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPss.c @@ -0,0 +1,139 @@ +/** @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 +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. + + @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. + + @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 + ) +{ + 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; + } + + 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, RSA_PSS_SALTLEN_AUTO) > 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..8d84b4c1426c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaPssNull.c @@ -0,0 +1,43 @@ +/** @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. + + @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. + + @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 + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index 496121e6a4ed..36d560b8d691 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -1363,6 +1363,33 @@ RsaPkcs1Verify ( IN 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. + + @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. + + @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 + ); + /** Retrieve the RSA Private Key from the password-protected PEM key data.