From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web11.15861.1688625418924355112 for ; Wed, 05 Jul 2023 23:36:59 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=ICf6nVSv; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: w.sheng@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1688625418; x=1720161418; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=tHP0GTSgnA0r/xkrw4tCCp19+RSuFn0Y0g7QcpL2UGc=; b=ICf6nVSvpZsy2RF9/qLmayw3DDEEaIHffB2J5Xo9JPZG69wnLSHSZuXF CTxVgozMI1IyYH3Kc1IA+e2DPxYdJk3hL0pbbfn0dPi/G/0RJQsKuVgl9 Og++It9rSXV+QCoHrVaB81TB50SH4w3TzvdcbaeKqjVh+UdeT5/LBqAjb 24+rjKseqlRMju/KhUfoLdiEuHzLEjC+ddJVrczH8lDQ21m7FCgPeUvYJ tIiz7UblYmw1tDE6RXBur1rYtRE7Xmmq8YlYkadsDrFFFsYlLrT/6WA3k Z4wp1TsTwQbyFwnC/ETXeWIg8stcHduLEICsVuWjfh7G6iTKodXjxhWF8 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10762"; a="353356452" X-IronPort-AV: E=Sophos;i="6.01,185,1684825200"; d="scan'208";a="353356452" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2023 23:36:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10762"; a="719486708" X-IronPort-AV: E=Sophos;i="6.01,185,1684825200"; d="scan'208";a="719486708" Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.28]) by orsmga002.jf.intel.com with ESMTP; 05 Jul 2023 23:36:55 -0700 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Jiewen Yao , Jian J Wang , Min Xu , Zeyi Chen , Fiona Wang Subject: [PATCH v3] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384 Date: Thu, 6 Jul 2023 14:36:54 +0800 Message-Id: <20230706063654.1576-1-w.sheng@intel.com> X-Mailer: git-send-email 2.26.2.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3413 Cc: Jiewen Yao Cc: Jian J Wang Cc: Min Xu Cc: Zeyi Chen Cc: Fiona Wang Signed-off-by: Sheng Wei --- CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c | 3 +- MdePkg/Include/Guid/ImageAuthentication.h | 26 +++ MdePkg/MdePkg.dec | 2 + .../Library/AuthVariableLib/AuthService.c | 220 +++++++++++++++--- .../AuthVariableLib/AuthServiceInternal.h | 4 +- .../Library/AuthVariableLib/AuthVariableLib.c | 42 ++-- .../DxeImageVerificationLib.c | 73 +++--- .../SecureBootConfigDxe.inf | 16 ++ .../SecureBootConfigImpl.c | 108 +++++++-- .../SecureBootConfigImpl.h | 2 + .../SecureBootConfigStrings.uni | 6 + 11 files changed, 410 insertions(+), 92 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c b/CryptoPkg/Librar= y/BaseCryptLib/Pk/CryptTs.c index 027dbb6842..944bcf8d38 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c @@ -591,7 +591,8 @@ ImageTimestampVerify ( // Register & Initialize necessary digest algorithms for PKCS#7 Handling= .=0D //=0D if ((EVP_add_digest (EVP_md5 ()) =3D=3D 0) || (EVP_add_digest (EVP_sha1 = ()) =3D=3D 0) ||=0D - (EVP_add_digest (EVP_sha256 ()) =3D=3D 0) || ((EVP_add_digest_alias = (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) =3D=3D 0))=0D + (EVP_add_digest (EVP_sha256 ()) =3D=3D 0) || (EVP_add_digest (EVP_sh= a384 ()) =3D=3D 0) ||=0D + (EVP_add_digest (EVP_sha512 ()) =3D=3D 0) || ((EVP_add_digest_alias = (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) =3D=3D 0))=0D {=0D return FALSE;=0D }=0D diff --git a/MdePkg/Include/Guid/ImageAuthentication.h b/MdePkg/Include/Gui= d/ImageAuthentication.h index fe83596571..c8ea2c14fb 100644 --- a/MdePkg/Include/Guid/ImageAuthentication.h +++ b/MdePkg/Include/Guid/ImageAuthentication.h @@ -144,6 +144,30 @@ typedef struct { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3,= 0xb6} \=0D }=0D =0D +///=0D +/// This identifies a signature containing an RSA-3072 key. The key (only = the modulus=0D +/// since the public key exponent is known to be 0x10001) shall be stored = in big-endian=0D +/// order.=0D +/// The SignatureHeader size shall always be 0. The SignatureSize shall al= ways be 16 (size=0D +/// of SignatureOwner component) + 384 bytes.=0D +///=0D +#define EFI_CERT_RSA3072_GUID \=0D + { \=0D + 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee,= 0x92 } \=0D + }=0D +=0D +///=0D +/// This identifies a signature containing an RSA-4096 key. The key (only = the modulus=0D +/// since the public key exponent is known to be 0x10001) shall be stored = in big-endian=0D +/// order.=0D +/// The SignatureHeader size shall always be 0. The SignatureSize shall al= ways be 16 (size=0D +/// of SignatureOwner component) + 512 bytes.=0D +///=0D +#define EFI_CERT_RSA4096_GUID \=0D + { \=0D + 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98,= 0x2c } \=0D + }=0D +=0D ///=0D /// This identifies a signature containing a RSA-2048 signature of a SHA-2= 56 hash. The=0D /// SignatureHeader size shall always be 0. The SignatureSize shall always= be 16 (size of=0D @@ -330,6 +354,8 @@ typedef struct { extern EFI_GUID gEfiImageSecurityDatabaseGuid;=0D extern EFI_GUID gEfiCertSha256Guid;=0D extern EFI_GUID gEfiCertRsa2048Guid;=0D +extern EFI_GUID gEfiCertRsa3072Guid;=0D +extern EFI_GUID gEfiCertRsa4096Guid;=0D extern EFI_GUID gEfiCertRsa2048Sha256Guid;=0D extern EFI_GUID gEfiCertSha1Guid;=0D extern EFI_GUID gEfiCertRsa2048Sha1Guid;=0D diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index d6c4179b2a..c88e88fa6b 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -571,6 +571,8 @@ gEfiImageSecurityDatabaseGuid =3D { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, = 0xbc, 0xda, 0xd0, 0xe, 0x67, 0x65, 0x6f }}=0D gEfiCertSha256Guid =3D { 0xc1c41626, 0x504c, 0x4092, {0xac, = 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 }}=0D gEfiCertRsa2048Guid =3D { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, = 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}=0D + gEfiCertRsa3072Guid =3D { 0xedd320c2, 0xb057, 0x4b8e, {0xad, = 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}=0D + gEfiCertRsa4096Guid =3D { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, = 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}=0D gEfiCertRsa2048Sha256Guid =3D { 0xe2b36190, 0x879b, 0x4a3d, {0xad, = 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}=0D gEfiCertSha1Guid =3D { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, = 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd }}=0D gEfiCertRsa2048Sha1Guid =3D { 0x67f8444f, 0x8743, 0x48f1, {0xa3, = 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}=0D diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPk= g/Library/AuthVariableLib/AuthService.c index d81c581d78..4c268a85cd 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c @@ -29,12 +29,125 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =0D #include =0D =0D +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE=0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for hash op= erations.=0D +=0D + If this interface is not supported, then return zero.=0D +=0D + @return The size, in bytes, of the context buffer required for hash ope= rations.=0D + @retval 0 This interface is not supported.=0D +=0D +**/=0D +typedef=0D +UINTN=0D +(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE)(=0D + VOID=0D + );=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Sha1Context as hash context = for=0D + subsequent use.=0D +=0D + If HashContext is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[out] HashContext Pointer to Hashcontext being initialized.=0D +=0D + @retval TRUE Hash context initialization succeeded.=0D + @retval FALSE Hash context initialization failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_INIT)(=0D + OUT VOID *HashContext=0D + );=0D +=0D +/**=0D + Digests the input data and updates Hash context.=0D +=0D + This function performs Hash digest on a data buffer of the specified siz= e.=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + Hash context should be already correctly initialized by HashInit(), and = should not be finalized=0D + by HashFinal(). Behavior with invalid context is undefined.=0D +=0D + If HashContext is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in, out] HashContext Pointer to the Hash context.=0D + @param[in] Data Pointer to the buffer containing the data = to be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE SHA-1 data digest succeeded.=0D + @retval FALSE SHA-1 data digest failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_UPDATE)(=0D + IN OUT VOID *HashContext,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + );=0D +=0D +/**=0D + Completes computation of the Hash digest value.=0D +=0D + This function completes hash computation and retrieves the digest value = into=0D + the specified memory. After this function has been called, the Hash cont= ext cannot=0D + be used again.=0D + Hash context should be already correctly initialized by HashInit(), and = should not be=0D + finalized by HashFinal(). Behavior with invalid Hash context is undefine= d.=0D +=0D + If HashContext is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in, out] HashContext Pointer to the Hash context.=0D + @param[out] HashValue Pointer to a buffer that receives the Hash= digest=0D + value.=0D +=0D + @retval TRUE Hash digest computation succeeded.=0D + @retval FALSE Hash digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_FINAL)(=0D + IN OUT VOID *HashContext,=0D + OUT UINT8 *HashValue=0D + );=0D +=0D +typedef struct {=0D + UINT32 HashSize;=0D + EFI_HASH_GET_CONTEXT_SIZE GetContextSize;=0D + EFI_HASH_INIT Init;=0D + EFI_HASH_UPDATE Update;=0D + EFI_HASH_FINAL Final;=0D + VOID **HashShaCtx;=0D + UINT8 *OidValue;=0D + UINTN OidLength;=0D +} EFI_HASH_INFO;=0D +=0D //=0D // Public Exponent of RSA Key.=0D //=0D CONST UINT8 mRsaE[] =3D { 0x01, 0x00, 0x01 };=0D =0D -CONST UINT8 mSha256OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0= x04, 0x02, 0x01 };=0D +UINT8 mSha256OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0= x02, 0x01 };=0D +UINT8 mSha384OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0= x02, 0x02 };=0D +UINT8 mSha512OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0= x02, 0x03 };=0D +=0D +EFI_HASH_INFO mHashInfo[] =3D {=0D + {SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha= 256Final, &mHashSha256Ctx, mSha256OidValue, 9},=0D + {SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha= 384Final, &mHashSha384Ctx, mSha384OidValue, 9},=0D + {SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha= 512Final, &mHashSha512Ctx, mSha512OidValue, 9},=0D +};=0D =0D //=0D // Requirement for different signature type which have been defined in UEF= I spec.=0D @@ -44,6 +157,8 @@ EFI_SIGNATURE_ITEM mSupportSigItem[] =3D { // {SigType, SigHeaderSize, SigDataSize }=0D { EFI_CERT_SHA256_GUID, 0, 32 },=0D { EFI_CERT_RSA2048_GUID, 0, 256 },=0D + { EFI_CERT_RSA3072_GUID, 0, 384 },=0D + { EFI_CERT_RSA4096_GUID, 0, 512 },=0D { EFI_CERT_RSA2048_SHA256_GUID, 0, 256 },=0D { EFI_CERT_SHA1_GUID, 0, 20 },=0D { EFI_CERT_RSA2048_SHA1_GUID, 0, 256 },=0D @@ -1090,26 +1205,28 @@ AuthServiceInternalCompareTimeStamp ( }=0D =0D /**=0D - Calculate SHA256 digest of SignerCert CommonName + ToplevelCert tbsCerti= ficate=0D + Calculate SHA digest of SignerCert CommonName + ToplevelCert tbsCertific= ate=0D SignerCert and ToplevelCert are inside the signer certificate chain.=0D =0D + @param[in] HashAlgId Hash algorithm index=0D @param[in] SignerCert A pointer to SignerCert data.=0D @param[in] SignerCertSize Length of SignerCert data.=0D @param[in] TopLevelCert A pointer to TopLevelCert data.=0D @param[in] TopLevelCertSize Length of TopLevelCert data.=0D - @param[out] Sha256Digest Sha256 digest calculated.=0D + @param[out] ShaDigest Sha digest calculated.=0D =0D @return EFI_ABORTED Digest process failed.=0D - @return EFI_SUCCESS SHA256 Digest is successfully calculated.=0D + @return EFI_SUCCESS SHA Digest is successfully calculated.=0D =0D **/=0D EFI_STATUS=0D -CalculatePrivAuthVarSignChainSHA256Digest (=0D +CalculatePrivAuthVarSignChainSHADigest (=0D + IN UINT8 HashAlgId,=0D IN UINT8 *SignerCert,=0D IN UINTN SignerCertSize,=0D IN UINT8 *TopLevelCert,=0D IN UINTN TopLevelCertSize,=0D - OUT UINT8 *Sha256Digest=0D + OUT UINT8 *ShaDigest=0D )=0D {=0D UINT8 *TbsCert;=0D @@ -1119,6 +1236,11 @@ CalculatePrivAuthVarSignChainSHA256Digest ( BOOLEAN CryptoStatus;=0D EFI_STATUS Status;=0D =0D + if (HashAlgId >=3D (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {=0D + DEBUG ((DEBUG_INFO, "%a Unsupported Hash Algorithm %d\n", __func__, Ha= shAlgId));=0D + return EFI_ABORTED;=0D + }=0D +=0D CertCommonNameSize =3D sizeof (CertCommonName);=0D =0D //=0D @@ -1141,8 +1263,8 @@ CalculatePrivAuthVarSignChainSHA256Digest ( //=0D // Digest SignerCert CN + TopLevelCert tbsCertificate=0D //=0D - ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE);=0D - CryptoStatus =3D Sha256Init (mHashCtx);=0D + ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);=0D + CryptoStatus =3D mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashS= haCtx));=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D @@ -1150,8 +1272,8 @@ CalculatePrivAuthVarSignChainSHA256Digest ( //=0D // '\0' is forced in CertCommonName. No overflow issue=0D //=0D - CryptoStatus =3D Sha256Update (=0D - mHashCtx,=0D + CryptoStatus =3D mHashInfo[HashAlgId].Update (=0D + *(mHashInfo[HashAlgId].HashShaCtx),=0D CertCommonName,=0D AsciiStrLen (CertCommonName)=0D );=0D @@ -1159,12 +1281,12 @@ CalculatePrivAuthVarSignChainSHA256Digest ( return EFI_ABORTED;=0D }=0D =0D - CryptoStatus =3D Sha256Update (mHashCtx, TbsCert, TbsCertSize);=0D + CryptoStatus =3D mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].Has= hShaCtx), TbsCert, TbsCertSize);=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D =0D - CryptoStatus =3D Sha256Final (mHashCtx, Sha256Digest);=0D + CryptoStatus =3D mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].Hash= ShaCtx), ShaDigest);=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D @@ -1516,9 +1638,10 @@ DeleteCertsFromDb ( /**=0D Insert signer's certificates for common authenticated variable with Vari= ableName=0D and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according t= o=0D - time based authenticated variable attributes. CertData is the SHA256 dig= est of=0D + time based authenticated variable attributes. CertData is the SHA digest= of=0D SignerCert CommonName + TopLevelCert tbsCertificate.=0D =0D + @param[in] HashAlgId Hash algorithm index.=0D @param[in] VariableName Name of authenticated Variable.=0D @param[in] VendorGuid Vendor GUID of authenticated Variable.=0D @param[in] Attributes Attributes of authenticated variable.=0D @@ -1536,6 +1659,7 @@ DeleteCertsFromDb ( **/=0D EFI_STATUS=0D InsertCertsToDb (=0D + IN UINT8 HashAlgId,=0D IN CHAR16 *VariableName,=0D IN EFI_GUID *VendorGuid,=0D IN UINT32 Attributes,=0D @@ -1556,12 +1680,16 @@ InsertCertsToDb ( UINT32 CertDataSize;=0D AUTH_CERT_DB_DATA *Ptr;=0D CHAR16 *DbName;=0D - UINT8 Sha256Digest[SHA256_DIGEST_SIZE];=0D + UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];=0D =0D if ((VariableName =3D=3D NULL) || (VendorGuid =3D=3D NULL) || (SignerCer= t =3D=3D NULL) || (TopLevelCert =3D=3D NULL)) {=0D return EFI_INVALID_PARAMETER;=0D }=0D =0D + if (HashAlgId >=3D (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D if ((Attributes & EFI_VARIABLE_NON_VOLATILE) !=3D 0) {=0D //=0D // Get variable "certdb".=0D @@ -1618,20 +1746,22 @@ InsertCertsToDb ( // Construct new data content of variable "certdb" or "certdbv".=0D //=0D NameSize =3D (UINT32)StrLen (VariableName);=0D - CertDataSize =3D sizeof (Sha256Digest);=0D + CertDataSize =3D mHashInfo[HashAlgId].HashSize;=0D CertNodeSize =3D sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + Na= meSize * sizeof (CHAR16);=0D NewCertDbSize =3D (UINT32)DataSize + CertNodeSize;=0D if (NewCertDbSize > mMaxCertDbSize) {=0D return EFI_OUT_OF_RESOURCES;=0D }=0D =0D - Status =3D CalculatePrivAuthVarSignChainSHA256Digest (=0D + Status =3D CalculatePrivAuthVarSignChainSHADigest (=0D + HashAlgId,=0D SignerCert,=0D SignerCertSize,=0D TopLevelCert,=0D TopLevelCertSize,=0D - Sha256Digest=0D + ShaDigest=0D );=0D +=0D if (EFI_ERROR (Status)) {=0D return Status;=0D }=0D @@ -1663,7 +1793,7 @@ InsertCertsToDb ( =0D CopyMem (=0D (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16= ),=0D - Sha256Digest,=0D + ShaDigest,=0D CertDataSize=0D );=0D =0D @@ -1790,6 +1920,36 @@ CleanCertsFromDb ( return Status;=0D }=0D =0D +/**=0D + Find hash algorithm index=0D +=0D + @param[in] SigData Pointer to the PKCS#7 message=0D + @param[in] SigDataSize Length of the PKCS#7 message=0D +=0D + @retval UINT8 Hash Algorithm Index=0D +**/=0D +UINT8=0D +FindHashAlgorithmIndex (=0D + IN UINT8 *SigData,=0D + IN UINT32 SigDataSize=0D +)=0D +{=0D + UINT8 i;=0D +=0D + for (i =3D 0; i < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO)); i++) {= =0D + if ( ( (SigDataSize >=3D (13 + mHashInfo[i].OidLength))=0D + && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) =3D=3D TWO_BYTE_ENCODE= )=0D + && (CompareMem (SigData + 13, mHashInfo[i].OidValue, mHashInfo= [i].OidLength) =3D=3D 0)))=0D + || (( (SigDataSize >=3D (32 + mHashInfo[i].OidLength)))=0D + && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) =3D=3D TWO_BYTE_ENCODE)= =0D + && (CompareMem (SigData + 32, mHashInfo[i].OidValue, mHashInfo[i= ].OidLength) =3D=3D 0))))=0D + {=0D + break;=0D + }=0D + }=0D + return i;=0D +}=0D +=0D /**=0D Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS= set=0D =0D @@ -1857,8 +2017,9 @@ VerifyTimeBasedPayload ( UINTN CertStackSize;=0D UINT8 *CertsInCertDb;=0D UINT32 CertsSizeinDb;=0D - UINT8 Sha256Digest[SHA256_DIGEST_SIZE];=0D + UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];=0D EFI_CERT_DATA *CertDataPtr;=0D + UINT8 HashAlgId;=0D =0D //=0D // 1. TopLevelCert is the top-level issuer certificate in signature Sign= er Cert Chain=0D @@ -1928,7 +2089,7 @@ VerifyTimeBasedPayload ( =0D //=0D // SignedData.digestAlgorithms shall contain the digest algorithm used w= hen preparing the=0D - // signature. Only a digest algorithm of SHA-256 is accepted.=0D + // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is = accepted.=0D //=0D // According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc= 2315):=0D // SignedData ::=3D SEQUENCE {=0D @@ -1972,14 +2133,9 @@ VerifyTimeBasedPayload ( //=0D // Example generated with: https://wiki.archlinux.org/title/Unified_Exte= nsible_Firmware_Interface/Secure_Boot#Manual_process=0D //=0D + HashAlgId =3D FindHashAlgorithmIndex (SigData, SigDataSize);=0D if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != =3D 0) {=0D - if ( ( (SigDataSize >=3D (13 + sizeof (mSha256OidValue)))=0D - && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) !=3D TWO_BYTE_ENCODE)= =0D - || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha2= 56OidValue)) !=3D 0)))=0D - && ( (SigDataSize >=3D (32 + sizeof (mSha256OidValue)))=0D - && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) !=3D TWO_BYTE_ENCODE)= =0D - || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha2= 56OidValue)) !=3D 0))))=0D - {=0D + if (HashAlgId >=3D (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {=0D return EFI_SECURITY_VIOLATION;=0D }=0D }=0D @@ -2170,19 +2326,20 @@ VerifyTimeBasedPayload ( goto Exit;=0D }=0D =0D - if (CertsSizeinDb =3D=3D SHA256_DIGEST_SIZE) {=0D + if ((HashAlgId < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) && (= CertsSizeinDb =3D=3D mHashInfo[HashAlgId].HashSize)) {=0D //=0D // Check hash of signer cert CommonName + Top-level issuer tbsCert= ificate against data in CertDb=0D //=0D CertDataPtr =3D (EFI_CERT_DATA *)(SignerCerts + 1);=0D - Status =3D CalculatePrivAuthVarSignChainSHA256Digest (=0D + Status =3D CalculatePrivAuthVarSignChainSHADigest (=0D + HashAlgId,=0D CertDataPtr->CertDataBuffer,=0D ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertData= Length)),=0D TopLevelCert,=0D TopLevelCertSize,=0D - Sha256Digest=0D + ShaDigest=0D );=0D - if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb= , CertsSizeinDb) !=3D 0)) {=0D + if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, C= ertsSizeinDb) !=3D 0)) {=0D goto Exit;=0D }=0D } else {=0D @@ -2215,6 +2372,7 @@ VerifyTimeBasedPayload ( //=0D CertDataPtr =3D (EFI_CERT_DATA *)(SignerCerts + 1);=0D Status =3D InsertCertsToDb (=0D + HashAlgId,=0D VariableName,=0D VendorGuid,=0D Attributes,=0D diff --git a/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h b/Se= curityPkg/Library/AuthVariableLib/AuthServiceInternal.h index b202e613bc..f7bf771d55 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h +++ b/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h @@ -92,7 +92,9 @@ extern UINT32 mMaxCertDbSize; extern UINT32 mPlatformMode;=0D extern UINT8 mVendorKeyState;=0D =0D -extern VOID *mHashCtx;=0D +extern VOID *mHashSha256Ctx;=0D +extern VOID *mHashSha384Ctx;=0D +extern VOID *mHashSha512Ctx;=0D =0D extern AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn;=0D =0D diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c b/Securi= tyPkg/Library/AuthVariableLib/AuthVariableLib.c index dc61ae840c..19e0004699 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c @@ -26,12 +26,14 @@ UINT32 mMaxCertDbSize; UINT32 mPlatformMode;=0D UINT8 mVendorKeyState;=0D =0D -EFI_GUID mSignatureSupport[] =3D { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GU= ID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID };=0D +EFI_GUID mSignatureSupport[] =3D { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GU= ID, EFI_CERT_SHA384_GUID, EFI_CERT_SHA512_GUID, EFI_CERT_RSA2048_GUID, EFI_= CERT_RSA3072_GUID, EFI_CERT_RSA4096_GUID, EFI_CERT_X509_GUID };=0D =0D //=0D // Hash context pointer=0D //=0D -VOID *mHashCtx =3D NULL;=0D +VOID *mHashSha256Ctx =3D NULL;=0D +VOID *mHashSha384Ctx =3D NULL;=0D +VOID *mHashSha512Ctx =3D NULL;=0D =0D VARIABLE_ENTRY_PROPERTY mAuthVarEntry[] =3D {=0D {=0D @@ -91,7 +93,7 @@ VARIABLE_ENTRY_PROPERTY mAuthVarEntry[] =3D { },=0D };=0D =0D -VOID **mAuthVarAddressPointer[9];=0D +VOID **mAuthVarAddressPointer[11];=0D =0D AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn =3D NULL;=0D =0D @@ -120,7 +122,6 @@ AuthVariableLibInitialize ( UINT32 VarAttr;=0D UINT8 *Data;=0D UINTN DataSize;=0D - UINTN CtxSize;=0D UINT8 SecureBootMode;=0D UINT8 SecureBootEnable;=0D UINT8 CustomMode;=0D @@ -135,9 +136,18 @@ AuthVariableLibInitialize ( //=0D // Initialize hash context.=0D //=0D - CtxSize =3D Sha256GetContextSize ();=0D - mHashCtx =3D AllocateRuntimePool (CtxSize);=0D - if (mHashCtx =3D=3D NULL) {=0D + mHashSha256Ctx =3D AllocateRuntimePool (Sha256GetContextSize ());=0D + if (mHashSha256Ctx =3D=3D NULL) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + mHashSha384Ctx =3D AllocateRuntimePool (Sha384GetContextSize ());=0D + if (mHashSha384Ctx =3D=3D NULL) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + mHashSha512Ctx =3D AllocateRuntimePool (Sha512GetContextSize ());=0D + if (mHashSha512Ctx =3D=3D NULL) {=0D return EFI_OUT_OF_RESOURCES;=0D }=0D =0D @@ -356,14 +366,16 @@ AuthVariableLibInitialize ( AuthVarLibContextOut->AuthVarEntry =3D mAuthVarEntry;=0D AuthVarLibContextOut->AuthVarEntryCount =3D ARRAY_SIZE (mAuthVarEntry)= ;=0D mAuthVarAddressPointer[0] =3D (VOID **)&mCertDbStore;=0D - mAuthVarAddressPointer[1] =3D (VOID **)&mHashCtx;=0D - mAuthVarAddressPointer[2] =3D (VOID **)&mAuthVarLibConte= xtIn;=0D - mAuthVarAddressPointer[3] =3D (VOID **)&(mAuthVarLibCont= extIn->FindVariable),=0D - mAuthVarAddressPointer[4] =3D (VOID **)&(mAuthVarLibCont= extIn->FindNextVariable),=0D - mAuthVarAddressPointer[5] =3D (VOID **)&(mAuthVarLibCont= extIn->UpdateVariable),=0D - mAuthVarAddressPointer[6] =3D (VOID **)&(mAuthVarLibCont= extIn->GetScratchBuffer),=0D - mAuthVarAddressPointer[7] =3D (VOID **)&(mAuthVarLibCont= extIn->CheckRemainingSpaceForConsistency),=0D - mAuthVarAddressPointer[8] =3D (VOID **)&(mAuthVarLibCont= extIn->AtRuntime),=0D + mAuthVarAddressPointer[1] =3D (VOID **)&mHashSha256Ctx;= =0D + mAuthVarAddressPointer[2] =3D (VOID **)&mHashSha384Ctx;= =0D + mAuthVarAddressPointer[3] =3D (VOID **)&mHashSha512Ctx;= =0D + mAuthVarAddressPointer[4] =3D (VOID **)&mAuthVarLibConte= xtIn;=0D + mAuthVarAddressPointer[5] =3D (VOID **)&(mAuthVarLibCont= extIn->FindVariable),=0D + mAuthVarAddressPointer[6] =3D (VOID **)&(mAuthVarLibCont= extIn->FindNextVariable),=0D + mAuthVarAddressPointer[7] =3D (VOID **)&(mAuthVarLibCont= extIn->UpdateVariable),=0D + mAuthVarAddressPointer[8] =3D (VOID **)&(mAuthVarLibCont= extIn->GetScratchBuffer),=0D + mAuthVarAddressPointer[9] =3D (VOID **)&(mAuthVarLibCont= extIn->CheckRemainingSpaceForConsistency),=0D + mAuthVarAddressPointer[10] =3D (VOID **)&(mAuthVarLibCon= textIn->AtRuntime),=0D AuthVarLibContextOut->AddressPointer =3D mAuthVarAddressPointer;=0D AuthVarLibContextOut->AddressPointerCount =3D ARRAY_SIZE (mAuthVarAddres= sPointer);=0D =0D diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificati= onLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL= ib.c index 5d8dbd5468..88b2d3c6c1 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -1620,7 +1620,7 @@ Done: in the security database "db", and no valid signature nor any hash v= alue of the image may=0D be reflected in the security database "dbx".=0D Otherwise, the image is not signed,=0D - The SHA256 hash value of the image must match a record in the securi= ty database "db", and=0D + The hash value of the image must match a record in the security data= base "db", and=0D not be reflected in the security data base "dbx".=0D =0D Caution: This function may receive untrusted input.=0D @@ -1690,6 +1690,8 @@ DxeImageVerificationHandler ( EFI_STATUS VarStatus;=0D UINT32 VarAttr;=0D BOOLEAN IsFound;=0D + UINT8 HashAlg;=0D + BOOLEAN IsFoundInDatabase;=0D =0D SignatureList =3D NULL;=0D SignatureListSize =3D 0;=0D @@ -1699,6 +1701,7 @@ DxeImageVerificationHandler ( Action =3D EFI_IMAGE_EXECUTION_AUTH_UNTESTED;=0D IsVerified =3D FALSE;=0D IsFound =3D FALSE;=0D + IsFoundInDatabase =3D FALSE;=0D =0D //=0D // Check the image type and get policy setting.=0D @@ -1837,40 +1840,50 @@ DxeImageVerificationHandler ( //=0D if ((SecDataDir =3D=3D NULL) || (SecDataDir->Size =3D=3D 0)) {=0D //=0D - // This image is not signed. The SHA256 hash value of the image must m= atch a record in the security database "db",=0D + // This image is not signed. The hash value of the image must match a = record in the security database "db",=0D // and not be reflected in the security data base "dbx".=0D //=0D - if (!HashPeImage (HASHALG_SHA256)) {=0D - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this im= age using %s.\n", mHashTypeStr));=0D - goto Failed;=0D - }=0D + HashAlg =3D sizeof (mHash) / sizeof (HASH_TABLE);=0D + while (HashAlg > 0) {=0D + HashAlg--;=0D + if ((mHash[HashAlg].GetContextSize =3D=3D NULL) || (mHash[HashAlg].H= ashInit =3D=3D NULL) || (mHash[HashAlg].HashUpdate =3D=3D NULL) || (mHash[H= ashAlg].HashFinal =3D=3D NULL)) {=0D + continue;=0D + }=0D + if (!HashPeImage (HashAlg)) {=0D + continue;=0D + }=0D =0D - DbStatus =3D IsSignatureFoundInDatabase (=0D - EFI_IMAGE_SECURITY_DATABASE1,=0D - mImageDigest,=0D - &mCertType,=0D - mImageDigestSize,=0D - &IsFound=0D - );=0D - if (EFI_ERROR (DbStatus) || IsFound) {=0D - //=0D - // Image Hash is in forbidden database (DBX).=0D - //=0D - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed an= d %s hash of image is forbidden by DBX.\n", mHashTypeStr));=0D - goto Failed;=0D + DbStatus =3D IsSignatureFoundInDatabase (=0D + EFI_IMAGE_SECURITY_DATABASE1,=0D + mImageDigest,=0D + &mCertType,=0D + mImageDigestSize,=0D + &IsFound=0D + );=0D + if (EFI_ERROR (DbStatus) || IsFound) {=0D + //=0D + // Image Hash is in forbidden database (DBX).=0D + //=0D + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed = and %s hash of image is forbidden by DBX.\n", mHashTypeStr));=0D + goto Failed;=0D + }=0D +=0D + DbStatus =3D IsSignatureFoundInDatabase (=0D + EFI_IMAGE_SECURITY_DATABASE,=0D + mImageDigest,=0D + &mCertType,=0D + mImageDigestSize,=0D + &IsFound=0D + );=0D + if (!EFI_ERROR (DbStatus) && IsFound) {=0D + //=0D + // Image Hash is in allowed database (DB).=0D + //=0D + IsFoundInDatabase =3D TRUE;=0D + }=0D }=0D =0D - DbStatus =3D IsSignatureFoundInDatabase (=0D - EFI_IMAGE_SECURITY_DATABASE,=0D - mImageDigest,=0D - &mCertType,=0D - mImageDigestSize,=0D - &IsFound=0D - );=0D - if (!EFI_ERROR (DbStatus) && IsFound) {=0D - //=0D - // Image Hash is in allowed database (DB).=0D - //=0D + if (IsFoundInDatabase) {=0D return EFI_SUCCESS;=0D }=0D =0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/Sec= ureBootConfigDxe.inf index 1671d5be7c..cb52a16c09 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gDxe.inf @@ -70,6 +70,14 @@ ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D gEfiCertRsa2048Guid=0D =0D + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D + gEfiCertRsa3072Guid=0D +=0D + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D + gEfiCertRsa4096Guid=0D +=0D ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D gEfiCertX509Guid=0D @@ -82,6 +90,14 @@ ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D gEfiCertSha256Guid=0D =0D + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D + gEfiCertSha384Guid=0D +=0D + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D + gEfiCertSha512Guid=0D +=0D ## SOMETIMES_CONSUMES ## Variable:L"db"=0D ## SOMETIMES_PRODUCES ## Variable:L"db"=0D ## SOMETIMES_CONSUMES ## Variable:L"dbx"=0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/Secu= reBootConfigImpl.c index 0e31502b1b..3de6bf6139 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.c @@ -560,7 +560,7 @@ ON_EXIT: =0D **/=0D EFI_STATUS=0D -EnrollRsa2048ToKek (=0D +EnrollRsaToKek (=0D IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private=0D )=0D {=0D @@ -603,8 +603,13 @@ EnrollRsa2048ToKek ( =0D ASSERT (KeyBlob !=3D NULL);=0D KeyInfo =3D (CPL_KEY_INFO *)KeyBlob;=0D - if (KeyInfo->KeyLengthInBits / 8 !=3D WIN_CERT_UEFI_RSA2048_SIZE) {=0D - DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is supporte= d.\n"));=0D + switch (KeyInfo->KeyLengthInBits / 8) {=0D + case WIN_CERT_UEFI_RSA2048_SIZE:=0D + case WIN_CERT_UEFI_RSA3072_SIZE:=0D + case WIN_CERT_UEFI_RSA4096_SIZE:=0D + break;=0D + default :=0D + DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048, RSA3072 an= d RSA4096 are supported.\n"));=0D Status =3D EFI_UNSUPPORTED;=0D goto ON_EXIT;=0D }=0D @@ -632,7 +637,7 @@ EnrollRsa2048ToKek ( //=0D KekSigListSize =3D sizeof (EFI_SIGNATURE_LIST)=0D + sizeof (EFI_SIGNATURE_DATA) - 1=0D - + WIN_CERT_UEFI_RSA2048_SIZE;=0D + + KeyLenInBytes;=0D =0D KekSigList =3D (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);= =0D if (KekSigList =3D=3D NULL) {=0D @@ -642,17 +647,32 @@ EnrollRsa2048ToKek ( =0D KekSigList->SignatureListSize =3D sizeof (EFI_SIGNATURE_LIST)=0D + sizeof (EFI_SIGNATURE_DATA) - 1=0D - + WIN_CERT_UEFI_RSA2048_SIZE;=0D + + (UINT32) KeyLenInBytes;=0D KekSigList->SignatureHeaderSize =3D 0;=0D - KekSigList->SignatureSize =3D sizeof (EFI_SIGNATURE_DATA) - 1 + WI= N_CERT_UEFI_RSA2048_SIZE;=0D - CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);=0D + KekSigList->SignatureSize =3D sizeof (EFI_SIGNATURE_DATA) - 1 + (U= INT32) KeyLenInBytes;=0D + switch (KeyLenInBytes) {=0D + case WIN_CERT_UEFI_RSA2048_SIZE:=0D + CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);=0D + break;=0D + case WIN_CERT_UEFI_RSA3072_SIZE:=0D + CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);=0D + break;=0D + case WIN_CERT_UEFI_RSA4096_SIZE:=0D + CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);=0D + break;=0D + break;=0D + default :=0D + DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));=0D + Status =3D EFI_UNSUPPORTED;=0D + goto ON_EXIT;=0D + }=0D =0D KEKSigData =3D (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_= SIGNATURE_LIST));=0D CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);=0D CopyMem (=0D KEKSigData->SignatureData,=0D KeyBlob + sizeof (CPL_KEY_INFO),=0D - WIN_CERT_UEFI_RSA2048_SIZE=0D + KeyLenInBytes=0D );=0D =0D //=0D @@ -890,7 +910,7 @@ EnrollKeyExchangeKey ( if (IsDerEncodeCertificate (FilePostFix)) {=0D return EnrollX509ToKek (Private);=0D } else if (CompareMem (FilePostFix, L".pbk", 4) =3D=3D 0) {=0D - return EnrollRsa2048ToKek (Private);=0D + return EnrollRsaToKek (Private);=0D } else {=0D //=0D // File type is wrong, simply close it=0D @@ -1847,7 +1867,7 @@ HashPeImage ( SectionHeader =3D NULL;=0D Status =3D FALSE;=0D =0D - if (HashAlg !=3D HASHALG_SHA256) {=0D + if ((HashAlg >=3D HASHALG_MAX)) {=0D return FALSE;=0D }=0D =0D @@ -1856,8 +1876,25 @@ HashPeImage ( //=0D ZeroMem (mImageDigest, MAX_DIGEST_SIZE);=0D =0D - mImageDigestSize =3D SHA256_DIGEST_SIZE;=0D - mCertType =3D gEfiCertSha256Guid;=0D + switch (HashAlg) {=0D + case HASHALG_SHA256:=0D + mImageDigestSize =3D SHA256_DIGEST_SIZE;=0D + mCertType =3D gEfiCertSha256Guid;=0D + break;=0D +=0D + case HASHALG_SHA384:=0D + mImageDigestSize =3D SHA384_DIGEST_SIZE;=0D + mCertType =3D gEfiCertSha384Guid;=0D + break;=0D +=0D + case HASHALG_SHA512:=0D + mImageDigestSize =3D SHA512_DIGEST_SIZE;=0D + mCertType =3D gEfiCertSha512Guid;=0D + break;=0D +=0D + default:=0D + return FALSE;=0D + }=0D =0D CtxSize =3D mHash[HashAlg].GetContextSize ();=0D =0D @@ -2251,6 +2288,7 @@ EnrollImageSignatureToSigDB ( UINT32 Attr;=0D WIN_CERTIFICATE_UEFI_GUID *GuidCertData;=0D EFI_TIME Time;=0D + UINT32 HashAlg;=0D =0D Data =3D NULL;=0D GuidCertData =3D NULL;=0D @@ -2289,8 +2327,20 @@ EnrollImageSignatureToSigDB ( }=0D =0D if (mSecDataDir->SizeOfCert =3D=3D 0) {=0D - if (!HashPeImage (HASHALG_SHA256)) {=0D - Status =3D EFI_SECURITY_VIOLATION;=0D + Status =3D EFI_SECURITY_VIOLATION;=0D + HashAlg =3D sizeof (mHash) / sizeof (HASH_TABLE);=0D + while (HashAlg > 0) {=0D + HashAlg--;=0D + if ((mHash[HashAlg].GetContextSize =3D=3D NULL) || (mHash[HashAlg].H= ashInit =3D=3D NULL) || (mHash[HashAlg].HashUpdate =3D=3D NULL) || (mHash[H= ashAlg].HashFinal =3D=3D NULL)) {=0D + continue;=0D + }=0D + if (HashPeImage (HashAlg)) {=0D + Status =3D EFI_SUCCESS;=0D + break;=0D + }=0D + }=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Fail to get hash digest: %r", Status));=0D goto ON_EXIT;=0D }=0D } else {=0D @@ -2589,6 +2639,10 @@ UpdateDeletePage ( while ((ItemDataSize > 0) && (ItemDataSize >=3D CertList->SignatureListS= ize)) {=0D if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)) {=0D Help =3D STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);=0D + } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid= )) {=0D + Help =3D STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);=0D + } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid= )) {=0D + Help =3D STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);=0D } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) = {=0D Help =3D STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);=0D } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)) = {=0D @@ -2750,6 +2804,8 @@ DeleteKeyExchangeKey ( GuidIndex =3D 0;=0D while ((KekDataSize > 0) && (KekDataSize >=3D CertList->SignatureListSiz= e)) {=0D if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||=0D + CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||=0D + CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||=0D CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))=0D {=0D CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + Cer= tList->SignatureHeaderSize));=0D @@ -2952,6 +3008,8 @@ DeleteSignature ( GuidIndex =3D 0;=0D while ((ItemDataSize > 0) && (ItemDataSize >=3D CertList->SignatureListS= ize)) {=0D if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||=0D + CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||=0D + CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||=0D CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||=0D CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||=0D CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||=0D @@ -3758,12 +3816,20 @@ LoadSignatureList ( while ((RemainingSize > 0) && (RemainingSize >=3D ListWalker->SignatureL= istSize)) {=0D if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {= =0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);=0D + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa3072Gu= id)) {=0D + ListType =3D STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);=0D + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa4096Gu= id)) {=0D + ListType =3D STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)= ) {=0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_X509);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)= ) {=0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA1);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Gui= d)) {=0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA256);=0D + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Gui= d)) {=0D + ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA384);=0D + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Gui= d)) {=0D + ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA512);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha25= 6Guid)) {=0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha38= 4Guid)) {=0D @@ -4001,6 +4067,14 @@ FormatHelpInfo ( ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);=0D DataSize =3D ListEntry->SignatureSize - sizeof (EFI_GUID);=0D IsCert =3D TRUE;=0D + } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa3072Guid)= ) {=0D + ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);=0D + DataSize =3D ListEntry->SignatureSize - sizeof (EFI_GUID);=0D + IsCert =3D TRUE;=0D + } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa4096Guid)= ) {=0D + ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);=0D + DataSize =3D ListEntry->SignatureSize - sizeof (EFI_GUID);=0D + IsCert =3D TRUE;=0D } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {= =0D ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_X509);=0D DataSize =3D ListEntry->SignatureSize - sizeof (EFI_GUID);=0D @@ -4011,6 +4085,12 @@ FormatHelpInfo ( } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid))= {=0D ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_SHA256);=0D DataSize =3D 32;=0D + } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid))= {=0D + ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_SHA384);=0D + DataSize =3D 48;=0D + } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid))= {=0D + ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_SHA512);=0D + DataSize =3D 64;=0D } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Gu= id)) {=0D ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);=0D DataSize =3D 32;=0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/Secu= reBootConfigImpl.h index 37c66f1b95..ae50d929a7 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.h @@ -82,6 +82,8 @@ extern EFI_IFR_GUID_LABEL *mEndLabel; #define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE=0D =0D #define WIN_CERT_UEFI_RSA2048_SIZE 256=0D +#define WIN_CERT_UEFI_RSA3072_SIZE 384=0D +#define WIN_CERT_UEFI_RSA4096_SIZE 512=0D =0D //=0D // Support hash types=0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe= /SecureBootConfigStrings.uni index 0d01701de7..1b48acc800 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gStrings.uni +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gStrings.uni @@ -113,6 +113,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #string STR_FORM_ENROLL_KEK_FROM_FILE_TITLE_HELP #language en-US "Read = the public key of KEK from file"=0D #string STR_FILE_EXPLORER_TITLE #language en-US "File Ex= plorer"=0D #string STR_CERT_TYPE_RSA2048_SHA256_GUID #language en-US "RSA2048= _SHA256_GUID"=0D +#string STR_CERT_TYPE_RSA3072_SHA384_GUID #language en-US "RSA3072= _SHA384_GUID"=0D +#string STR_CERT_TYPE_RSA4096_SHA512_GUID #language en-US "RSA4096= _SHA512_GUID"=0D #string STR_CERT_TYPE_PCKS7_GUID #language en-US "PKCS7_G= UID"=0D #string STR_CERT_TYPE_SHA1_GUID #language en-US "SHA1_GU= ID"=0D #string STR_CERT_TYPE_SHA256_GUID #language en-US "SHA256_= GUID"=0D @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #string STR_CERT_TYPE_X509_SHA512_GUID #language en-US "X509_SH= A512_GUID"=0D =0D #string STR_LIST_TYPE_RSA2048_SHA256 #language en-US "RSA2048= _SHA256"=0D +#string STR_LIST_TYPE_RSA3072_SHA384 #language en-US "RSA3072= _SHA384"=0D +#string STR_LIST_TYPE_RSA4096_SHA512 #language en-US "RSA4096= _SHA512"=0D #string STR_LIST_TYPE_X509 #language en-US "X509"=0D #string STR_LIST_TYPE_SHA1 #language en-US "SHA1"=0D #string STR_LIST_TYPE_SHA256 #language en-US "SHA256"= =0D +#string STR_LIST_TYPE_SHA384 #language en-US "SHA384"= =0D +#string STR_LIST_TYPE_SHA512 #language en-US "SHA512"= =0D #string STR_LIST_TYPE_X509_SHA256 #language en-US "X509_SH= A256"=0D #string STR_LIST_TYPE_X509_SHA384 #language en-US "X509_SH= A384"=0D #string STR_LIST_TYPE_X509_SHA512 #language en-US "X509_SH= A512"=0D --=20 2.26.2.windows.1