[edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384

Sheng Wei posted 1 patch 11 months, 1 week ago
Failed in applying to current master (apply log)
There is a newer version of this series
CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
MdePkg/MdePkg.dec                             |   2 +
.../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++--
.../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
.../DxeImageVerificationLib.c                 |  35 ++-
.../DxeImageVerificationLib.inf               |   1 +
SecurityPkg/SecurityPkg.dec                   |   7 +
.../SecureBootConfigDxe.inf                   |  19 ++
.../SecureBootConfigImpl.c                    | 122 +++++++-
.../SecureBootConfigImpl.h                    |   2 +
.../SecureBootConfigStrings.uni               |   6 +
12 files changed, 463 insertions(+), 36 deletions(-)
[edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Sheng Wei 11 months, 1 week ago
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Zeyi Chen <zeyi.chen@intel.com>
Cc: Fiona Wang <fiona.wang@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
 CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
 MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
 MdePkg/MdePkg.dec                             |   2 +
 .../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++--
 .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
 .../DxeImageVerificationLib.c                 |  35 ++-
 .../DxeImageVerificationLib.inf               |   1 +
 SecurityPkg/SecurityPkg.dec                   |   7 +
 .../SecureBootConfigDxe.inf                   |  19 ++
 .../SecureBootConfigImpl.c                    | 122 +++++++-
 .../SecureBootConfigImpl.h                    |   2 +
 .../SecureBootConfigStrings.uni               |   6 +
 12 files changed, 463 insertions(+), 36 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c b/CryptoPkg/Library/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.
   //
   if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||
-      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
+      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest (EVP_sha384 ()) == 0) ||
+      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
   {
     return FALSE;
   }
diff --git a/MdePkg/Include/Guid/ImageAuthentication.h b/MdePkg/Include/Guid/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} \
   }
 
+///
+/// This identifies a signature containing an RSA-3072 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 384 bytes.
+///
+#define EFI_CERT_RSA3072_GUID \
+  { \
+    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 } \
+  }
+
+///
+/// This identifies a signature containing an RSA-4096 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 512 bytes.
+///
+#define EFI_CERT_RSA4096_GUID \
+  { \
+    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c } \
+  }
+
 ///
 /// This identifies a signature containing a RSA-2048 signature of a SHA-256 hash.  The
 /// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
@@ -330,6 +354,8 @@ typedef struct {
 extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
 extern EFI_GUID  gEfiCertSha256Guid;
 extern EFI_GUID  gEfiCertRsa2048Guid;
+extern EFI_GUID  gEfiCertRsa3072Guid;
+extern EFI_GUID  gEfiCertRsa4096Guid;
 extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
 extern EFI_GUID  gEfiCertSha1Guid;
 extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 80b6559053..782f6d184d 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -562,6 +562,8 @@
   gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
   gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 }}
   gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
+  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
+  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
   gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
   gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe,  0x1, 0x49, 0x66, 0x31, 0xbd }}
   gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPkg/Library/AuthVariableLib/AuthService.c
index 452ed491ea..288e44a359 100644
--- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
+++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
@@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Protocol/VariablePolicy.h>
 #include <Library/VariablePolicyLib.h>
 
+#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
+
 //
 // Public Exponent of RSA Key.
 //
 CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
 
 CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
+CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 };
+CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 };
 
 //
 // Requirement for different signature type which have been defined in UEFI spec.
@@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
   // {SigType,                       SigHeaderSize,   SigDataSize  }
   { EFI_CERT_SHA256_GUID,         0, 32            },
   { EFI_CERT_RSA2048_GUID,        0, 256           },
+  { EFI_CERT_RSA3072_GUID,        0, 384           },
+  { EFI_CERT_RSA4096_GUID,        0, 512           },
   { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
   { EFI_CERT_SHA1_GUID,           0, 20            },
   { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
@@ -1172,6 +1178,172 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   return EFI_SUCCESS;
 }
 
+/**
+  Calculate SHA38 digest of SignerCert CommonName + ToplevelCert tbsCertificate
+  SignerCert and ToplevelCert are inside the signer certificate chain.
+
+  @param[in]  SignerCert          A pointer to SignerCert data.
+  @param[in]  SignerCertSize      Length of SignerCert data.
+  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
+  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
+  @param[out] Sha384Digest       Sha384 digest calculated.
+
+  @return EFI_ABORTED          Digest process failed.
+  @return EFI_SUCCESS          SHA384 Digest is successfully calculated.
+
+**/
+EFI_STATUS
+CalculatePrivAuthVarSignChainSHA384Digest (
+  IN     UINT8  *SignerCert,
+  IN     UINTN  SignerCertSize,
+  IN     UINT8  *TopLevelCert,
+  IN     UINTN  TopLevelCertSize,
+  OUT    UINT8  *Sha384Digest
+  )
+{
+  UINT8       *TbsCert;
+  UINTN       TbsCertSize;
+  CHAR8       CertCommonName[128];
+  UINTN       CertCommonNameSize;
+  BOOLEAN     CryptoStatus;
+  EFI_STATUS  Status;
+
+  CertCommonNameSize = sizeof (CertCommonName);
+
+  //
+  // Get SignerCert CommonName
+  //
+  Status = X509GetCommonName (SignerCert, SignerCertSize, CertCommonName, &CertCommonNameSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with status %x\n", __FUNCTION__, Status));
+    return EFI_ABORTED;
+  }
+
+  //
+  // Get TopLevelCert tbsCertificate
+  //
+  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert, &TbsCertSize)) {
+    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n", __FUNCTION__));
+    return EFI_ABORTED;
+  }
+
+  //
+  // Digest SignerCert CN + TopLevelCert tbsCertificate
+  //
+  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
+  CryptoStatus = Sha384Init (mHashCtx);
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  //
+  // '\0' is forced in CertCommonName. No overflow issue
+  //
+  CryptoStatus = Sha384Update (
+                   mHashCtx,
+                   CertCommonName,
+                   AsciiStrLen (CertCommonName)
+                   );
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Calculate SHA512 digest of SignerCert CommonName + ToplevelCert tbsCertificate
+  SignerCert and ToplevelCert are inside the signer certificate chain.
+
+  @param[in]  SignerCert          A pointer to SignerCert data.
+  @param[in]  SignerCertSize      Length of SignerCert data.
+  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
+  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
+  @param[out] Sha512Digest       Sha512 digest calculated.
+
+  @return EFI_ABORTED          Digest process failed.
+  @return EFI_SUCCESS          SHA512 Digest is successfully calculated.
+
+**/
+EFI_STATUS
+CalculatePrivAuthVarSignChainSHA512Digest (
+  IN     UINT8  *SignerCert,
+  IN     UINTN  SignerCertSize,
+  IN     UINT8  *TopLevelCert,
+  IN     UINTN  TopLevelCertSize,
+  OUT    UINT8  *Sha512Digest
+  )
+{
+  UINT8       *TbsCert;
+  UINTN       TbsCertSize;
+  CHAR8       CertCommonName[128];
+  UINTN       CertCommonNameSize;
+  BOOLEAN     CryptoStatus;
+  EFI_STATUS  Status;
+
+  CertCommonNameSize = sizeof (CertCommonName);
+
+  //
+  // Get SignerCert CommonName
+  //
+  Status = X509GetCommonName (SignerCert, SignerCertSize, CertCommonName, &CertCommonNameSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with status %x\n", __FUNCTION__, Status));
+    return EFI_ABORTED;
+  }
+
+  //
+  // Get TopLevelCert tbsCertificate
+  //
+  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert, &TbsCertSize)) {
+    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n", __FUNCTION__));
+    return EFI_ABORTED;
+  }
+
+  //
+  // Digest SignerCert CN + TopLevelCert tbsCertificate
+  //
+  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
+  CryptoStatus = Sha512Init (mHashCtx);
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  //
+  // '\0' is forced in CertCommonName. No overflow issue
+  //
+  CryptoStatus = Sha512Update (
+                   mHashCtx,
+                   CertCommonName,
+                   AsciiStrLen (CertCommonName)
+                   );
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
+  if (!CryptoStatus) {
+    return EFI_ABORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
 /**
   Find matching signer's certificates for common authenticated variable
   by corresponding VariableName and VendorGuid from "certdb" or "certdbv".
@@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
   @param[in]  SignerCertSize    Length of signer certificate.
   @param[in]  TopLevelCert      Top-level certificate data.
   @param[in]  TopLevelCertSize  Length of top-level certificate.
+  @param[in]  DigestSize        Digest Size.
 
   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
   @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with same VariableName
@@ -1542,7 +1715,8 @@ InsertCertsToDb (
   IN     UINT8     *SignerCert,
   IN     UINTN     SignerCertSize,
   IN     UINT8     *TopLevelCert,
-  IN     UINTN     TopLevelCertSize
+  IN     UINTN     TopLevelCertSize,
+  IN     UINT32    DigestSize
   )
 {
   EFI_STATUS         Status;
@@ -1556,7 +1730,7 @@ InsertCertsToDb (
   UINT32             CertDataSize;
   AUTH_CERT_DB_DATA  *Ptr;
   CHAR16             *DbName;
-  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
+  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
 
   if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {
     return EFI_INVALID_PARAMETER;
@@ -1618,20 +1792,41 @@ InsertCertsToDb (
   // Construct new data content of variable "certdb" or "certdbv".
   //
   NameSize      = (UINT32)StrLen (VariableName);
-  CertDataSize  = sizeof (Sha256Digest);
+  CertDataSize  = DigestSize;
   CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);
   NewCertDbSize = (UINT32)DataSize + CertNodeSize;
   if (NewCertDbSize > mMaxCertDbSize) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  Status = CalculatePrivAuthVarSignChainSHA256Digest (
-             SignerCert,
-             SignerCertSize,
-             TopLevelCert,
-             TopLevelCertSize,
-             Sha256Digest
-             );
+  if (DigestSize == SHA256_DIGEST_SIZE) {
+    Status = CalculatePrivAuthVarSignChainSHA256Digest (
+               SignerCert,
+               SignerCertSize,
+               TopLevelCert,
+               TopLevelCertSize,
+               ShaDigest
+               );
+  } else if (DigestSize == SHA384_DIGEST_SIZE) {
+    Status = CalculatePrivAuthVarSignChainSHA384Digest (
+               SignerCert,
+               SignerCertSize,
+               TopLevelCert,
+               TopLevelCertSize,
+               ShaDigest
+               );
+  } else if (DigestSize == SHA512_DIGEST_SIZE) {
+    Status = CalculatePrivAuthVarSignChainSHA512Digest (
+               SignerCert,
+               SignerCertSize,
+               TopLevelCert,
+               TopLevelCertSize,
+               ShaDigest
+               );
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -1663,7 +1858,7 @@ InsertCertsToDb (
 
   CopyMem (
     (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
-    Sha256Digest,
+    ShaDigest,
     CertDataSize
     );
 
@@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
   UINTN                          CertStackSize;
   UINT8                          *CertsInCertDb;
   UINT32                         CertsSizeinDb;
-  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
+  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
   EFI_CERT_DATA                  *CertDataPtr;
 
   //
@@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
 
   //
   // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the
-  // signature. Only a digest algorithm of SHA-256 is accepted.
+  // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is accepted.
   //
   //    According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
   //        SignedData ::= SEQUENCE {
@@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
              || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))
        && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
           && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
-             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))))
+             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))
+       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
+          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
+             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof (mSha384OidValue)) != 0)))
+       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
+          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
+             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof (mSha384OidValue)) != 0)))
+       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
+          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
+             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof (mSha512OidValue)) != 0)))
+       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
+          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
+             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof (mSha512OidValue)) != 0))))
     {
       return EFI_SECURITY_VIOLATION;
     }
@@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
                         ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
                         TopLevelCert,
                         TopLevelCertSize,
-                        Sha256Digest
+                        ShaDigest
+                        );
+        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
+          goto Exit;
+        }
+      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
+        //
+        // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
+        //
+        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
+        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
+                        CertDataPtr->CertDataBuffer,
+                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
+                        TopLevelCert,
+                        TopLevelCertSize,
+                        ShaDigest
+                        );
+        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
+          goto Exit;
+        }
+      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
+        //
+        // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
+        //
+        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
+        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
+                        CertDataPtr->CertDataBuffer,
+                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
+                        TopLevelCert,
+                        TopLevelCertSize,
+                        ShaDigest
                         );
-        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb, CertsSizeinDb) != 0)) {
+        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
           goto Exit;
         }
       } else {
@@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
                       CertDataPtr->CertDataBuffer,
                       ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
                       TopLevelCert,
-                      TopLevelCertSize
+                      TopLevelCertSize,
+                      CertsSizeinDb
                       );
       if (EFI_ERROR (Status)) {
         VerifyStatus = FALSE;
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
index dc61ae840c..552c0e99be 100644
--- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
+++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
@@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
 UINT32  mPlatformMode;
 UINT8   mVendorKeyState;
 
-EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID };
+EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID, EFI_CERT_SHA512_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID, EFI_CERT_RSA4096_GUID, EFI_CERT_X509_GUID };
 
 //
 // Hash context pointer
@@ -135,7 +135,7 @@ AuthVariableLibInitialize (
   //
   // Initialize hash context.
   //
-  CtxSize  = Sha256GetContextSize ();
+  CtxSize  = Sha512GetContextSize ();
   mHashCtx = AllocateRuntimePool (CtxSize);
   if (mHashCtx == NULL) {
     return EFI_OUT_OF_RESOURCES;
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
index 66e2f5eaa3..f642aad64d 100644
--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
+++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
@@ -1606,6 +1606,35 @@ Done:
   return VerifyStatus;
 }
 
+/**
+  Get Hash Alg by PcdSecureBootDefaultHashAlg
+
+  @retval  UINT32       Hash Alg
+  **/
+UINT32
+GetDefaultHashAlg (
+  VOID
+  )
+{
+  UINT32  HashAlg;
+
+  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
+  case 1:
+    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
+    HashAlg = HASHALG_SHA384;
+    break;
+  case 2:
+    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
+    HashAlg = HASHALG_SHA512;
+    break;
+  default:
+    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
+    HashAlg = HASHALG_SHA256;
+    break;
+  }
+  return HashAlg;
+}
+
 /**
   Provide verification service for signed images, which include both signature validation
   and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and
@@ -1620,7 +1649,7 @@ Done:
       in the security database "db", and no valid signature nor any hash value of the image may
       be reflected in the security database "dbx".
     Otherwise, the image is not signed,
-      The SHA256 hash value of the image must match a record in the security database "db", and
+      The hash value of the image must match a record in the security database "db", and
       not be reflected in the security data base "dbx".
 
   Caution: This function may receive untrusted input.
@@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
   //
   if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
     //
-    // This image is not signed. The SHA256 hash value of the image must match a record in the security database "db",
+    // This image is not signed. The hash value of the image must match a record in the security database "db",
     // and not be reflected in the security data base "dbx".
     //
-    if (!HashPeImage (HASHALG_SHA256)) {
+    if (!HashPeImage (GetDefaultHashAlg ())) {
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr));
       goto Failed;
     }
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
index 1e1a639857..f1ef9236c2 100644
--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
@@ -93,3 +93,4 @@
   gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy          ## SOMETIMES_CONSUMES
   gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy     ## SOMETIMES_CONSUMES
   gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy         ## SOMETIMES_CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg                  ## CONSUMES
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 0382090f4e..4adc2a72ab 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -521,6 +521,13 @@
   # @Prompt Skip Hdd Password prompt.
   gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLEAN|0x00010021
 
+  ## Indicates default hash algorithm in Secure Boot
+  #   0 - Use SHA256
+  #   1 - Use SHA384
+  #   2 - Use SHA512
+  # @Prompt Secure Boot default hash algorithm
+  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x00010040
+
 [PcdsDynamic, PcdsDynamicEx]
 
   ## This PCD indicates Hash mask for TPM 2.0. Bit definition strictly follows TCG Algorithm Registry.<BR><BR>
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
index 1671d5be7c..4b0012d033 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
@@ -70,6 +70,14 @@
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertRsa2048Guid
 
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertRsa3072Guid
+
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertRsa4096Guid
+
   ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertX509Guid
@@ -82,6 +90,14 @@
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertSha256Guid
 
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertSha384Guid
+
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertSha512Guid
+
   ## SOMETIMES_CONSUMES      ## Variable:L"db"
   ## SOMETIMES_PRODUCES      ## Variable:L"db"
   ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
@@ -107,6 +123,9 @@
   gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES  ## GUID  # Unique ID for the type of the certificate.
   gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES  ## GUID  # Unique ID for the type of the certificate.
 
+[Pcd]
+  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg                  ## CONSUMES
+
 [Protocols]
   gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
   gEfiDevicePathProtocolGuid                    ## PRODUCES
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 4299a6b5e5..0ba029a394 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -560,7 +560,7 @@ ON_EXIT:
 
 **/
 EFI_STATUS
-EnrollRsa2048ToKek (
+EnrollRsaToKek (
   IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
   )
 {
@@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
 
   ASSERT (KeyBlob != NULL);
   KeyInfo = (CPL_KEY_INFO *)KeyBlob;
-  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
-    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is supported.\n"));
+  switch (KeyInfo->KeyLengthInBits / 8) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    break;
+  default :
+    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048, RSA3072 and RSA4096 are supported.\n"));
     Status = EFI_UNSUPPORTED;
     goto ON_EXIT;
   }
@@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
   //
   KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
                    + sizeof (EFI_SIGNATURE_DATA) - 1
-                   + WIN_CERT_UEFI_RSA2048_SIZE;
+                   + KeyLenInBytes;
 
   KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
   if (KekSigList == NULL) {
@@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
 
   KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
                                   + sizeof (EFI_SIGNATURE_DATA) - 1
-                                  + WIN_CERT_UEFI_RSA2048_SIZE;
+                                  + (UINT32) KeyLenInBytes;
   KekSigList->SignatureHeaderSize = 0;
-  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + WIN_CERT_UEFI_RSA2048_SIZE;
-  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32) KeyLenInBytes;
+  switch (KeyLenInBytes) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+    break;
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
+    break;
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
+    break;
+    break;
+  default :
+    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
 
   KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
   CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
   CopyMem (
     KEKSigData->SignatureData,
     KeyBlob + sizeof (CPL_KEY_INFO),
-    WIN_CERT_UEFI_RSA2048_SIZE
+    KeyLenInBytes
     );
 
   //
@@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
   if (IsDerEncodeCertificate (FilePostFix)) {
     return EnrollX509ToKek (Private);
   } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
-    return EnrollRsa2048ToKek (Private);
+    return EnrollRsaToKek (Private);
   } else {
     //
     // File type is wrong, simply close it
@@ -1847,7 +1867,7 @@ HashPeImage (
   SectionHeader = NULL;
   Status        = FALSE;
 
-  if (HashAlg != HASHALG_SHA256) {
+  if ((HashAlg >= HASHALG_MAX)) {
     return FALSE;
   }
 
@@ -1856,8 +1876,25 @@ HashPeImage (
   //
   ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
 
-  mImageDigestSize = SHA256_DIGEST_SIZE;
-  mCertType        = gEfiCertSha256Guid;
+   switch (HashAlg) {
+    case HASHALG_SHA256:
+      mImageDigestSize = SHA256_DIGEST_SIZE;
+      mCertType        = gEfiCertSha256Guid;
+      break;
+
+    case HASHALG_SHA384:
+      mImageDigestSize = SHA384_DIGEST_SIZE;
+      mCertType        = gEfiCertSha384Guid;
+      break;
+
+    case HASHALG_SHA512:
+      mImageDigestSize = SHA512_DIGEST_SIZE;
+      mCertType        = gEfiCertSha512Guid;
+      break;
+
+    default:
+      return FALSE;
+  }
 
   CtxSize = mHash[HashAlg].GetContextSize ();
 
@@ -2222,6 +2259,35 @@ ON_EXIT:
   return Status;
 }
 
+/**
+  Get Hash Alg by PcdSecureBootDefaultHashAlg
+
+  @retval  UINT32       Hash Alg
+  **/
+UINT32
+GetDefaultHashAlg (
+  VOID
+  )
+{
+  UINT32  HashAlg;
+
+  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
+  case 1:
+    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
+    HashAlg = HASHALG_SHA384;
+    break;
+  case 2:
+    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
+    HashAlg = HASHALG_SHA512;
+    break;
+  default:
+    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
+    HashAlg = HASHALG_SHA256;
+    break;
+  }
+  return HashAlg;
+}
+
 /**
   Enroll a new signature of executable into Signature Database.
 
@@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
   }
 
   if (mSecDataDir->SizeOfCert == 0) {
-    if (!HashPeImage (HASHALG_SHA256)) {
+    if (!HashPeImage (GetDefaultHashAlg ())) {
       Status =  EFI_SECURITY_VIOLATION;
       goto ON_EXIT;
     }
@@ -2589,6 +2655,10 @@ UpdateDeletePage (
   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)) {
       Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
+    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)) {
+      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
+    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)) {
+      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
     } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
       Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
     } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)) {
@@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
   GuidIndex      = 0;
   while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
     {
       CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
@@ -2952,6 +3024,8 @@ DeleteSignature (
   GuidIndex    = 0;
   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
@@ -3758,12 +3832,20 @@ LoadSignatureList (
   while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
     if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa3072Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa4096Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
@@ -4001,6 +4083,14 @@ FormatHelpInfo (
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
     DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
     IsCert     = TRUE;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa3072Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
+    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
+    IsCert     = TRUE;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa4096Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
+    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
+    IsCert     = TRUE;
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
     DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
@@ -4011,6 +4101,12 @@ FormatHelpInfo (
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
     DataSize   = 32;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+    DataSize   = 48;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
+    DataSize   = 64;
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
     DataSize   = 32;
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
index 37c66f1b95..ae50d929a7 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
@@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
 #define MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
 
 #define WIN_CERT_UEFI_RSA2048_SIZE  256
+#define WIN_CERT_UEFI_RSA3072_SIZE  384
+#define WIN_CERT_UEFI_RSA4096_SIZE  512
 
 //
 // Support hash types
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
index 0d01701de7..1b48acc800 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.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"
 #string STR_FILE_EXPLORER_TITLE                   #language en-US "File Explorer"
 #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US "RSA2048_SHA256_GUID"
+#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US "RSA3072_SHA384_GUID"
+#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US "RSA4096_SHA512_GUID"
 #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US "PKCS7_GUID"
 #string STR_CERT_TYPE_SHA1_GUID                   #language en-US "SHA1_GUID"
 #string STR_CERT_TYPE_SHA256_GUID                 #language en-US "SHA256_GUID"
@@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US "X509_SHA512_GUID"
 
 #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US "RSA2048_SHA256"
+#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US "RSA3072_SHA384"
+#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US "RSA4096_SHA512"
 #string STR_LIST_TYPE_X509                        #language en-US "X509"
 #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
 #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
+#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
+#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
 #string STR_LIST_TYPE_X509_SHA256                 #language en-US "X509_SHA256"
 #string STR_LIST_TYPE_X509_SHA384                 #language en-US "X509_SHA384"
 #string STR_LIST_TYPE_X509_SHA512                 #language en-US "X509_SHA512"
-- 
2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#105296): https://edk2.groups.io/g/devel/message/105296
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Yao, Jiewen 10 months, 1 week ago
Thank you very much to contribute this patch. Here is my feedback.

1) I don't believe that you cannot use digest size to determine the algorithm, because different hash algorithm may have same time. E.g. SHA256 and SHA3_256.

+  if (DigestSize == SHA256_DIGEST_SIZE) {
+    Status = CalculatePrivAuthVarSignChainSHA256Digest (
+               SignerCert,
+               SignerCertSize,
+               TopLevelCert,
+               TopLevelCertSize,
+               ShaDigest
+               );

2) I don't believe that you cannot assuming CtxSize of SHA512 is bigger than SHA256. I think we may need create context for each algo.

@@ -135,7 +135,7 @@ AuthVariableLibInitialize (
   //
   // Initialize hash context.
   //
-  CtxSize  = Sha256GetContextSize ();
+  CtxSize  = Sha512GetContextSize ();
   mHashCtx = AllocateRuntimePool (CtxSize);
   if (mHashCtx == NULL) {

3) I believe we should use 0 for SHA256 and ASSERT in default.

+  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
+  case 1:
+    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
+    HashAlg = HASHALG_SHA384;
+    break;
+  case 2:
+    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
+    HashAlg = HASHALG_SHA512;
+    break;
+  default:
+    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
+    HashAlg = HASHALG_SHA256;
+    break;
+  }

4) I am not sure why we need this PCD. Why cannot we support all of hash algo?

+  ## Indicates default hash algorithm in Secure Boot
+  #   0 - Use SHA256
+  #   1 - Use SHA384
+  #   2 - Use SHA512
+  # @Prompt Secure Boot default hash algorithm
+  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x00010040

5) I don't believe that you can use size to determine the algorithm. We need a more robust way, such as algorithm ID.

+  switch (KeyLenInBytes) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+    break;
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
+    break;
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
+    break;
+    break;

Thank you
Yao, Jiewen

> -----Original Message-----
> From: Sheng, W <w.sheng@intel.com>
> Sent: Thursday, May 25, 2023 1:23 PM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Xu, Min M <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang,
> Fiona <fiona.wang@intel.com>
> Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Zeyi Chen <zeyi.chen@intel.com>
> Cc: Fiona Wang <fiona.wang@intel.com>
> Signed-off-by: Sheng Wei <w.sheng@intel.com>
> ---
>  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
>  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
>  MdePkg/MdePkg.dec                             |   2 +
>  .../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++--
>  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
>  .../DxeImageVerificationLib.c                 |  35 ++-
>  .../DxeImageVerificationLib.inf               |   1 +
>  SecurityPkg/SecurityPkg.dec                   |   7 +
>  .../SecureBootConfigDxe.inf                   |  19 ++
>  .../SecureBootConfigImpl.c                    | 122 +++++++-
>  .../SecureBootConfigImpl.h                    |   2 +
>  .../SecureBootConfigStrings.uni               |   6 +
>  12 files changed, 463 insertions(+), 36 deletions(-)
> 
> diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> b/CryptoPkg/Library/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.
> 
>    //
> 
>    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0)
> ||
> 
> -      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias
> (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> 
> +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest (EVP_sha384 ())
> == 0) ||
> 
> +      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias
> (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> 
>    {
> 
>      return FALSE;
> 
>    }
> 
> diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> b/MdePkg/Include/Guid/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} \
> 
>    }
> 
> 
> 
> +///
> 
> +/// This identifies a signature containing an RSA-3072 key. The key (only the
> modulus
> 
> +/// since the public key exponent is known to be 0x10001) shall be stored in big-
> endian
> 
> +/// order.
> 
> +/// The SignatureHeader size shall always be 0. The SignatureSize shall always
> be 16 (size
> 
> +/// of SignatureOwner component) + 384 bytes.
> 
> +///
> 
> +#define EFI_CERT_RSA3072_GUID \
> 
> +  { \
> 
> +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee,
> 0x92 } \
> 
> +  }
> 
> +
> 
> +///
> 
> +/// This identifies a signature containing an RSA-4096 key. The key (only the
> modulus
> 
> +/// since the public key exponent is known to be 0x10001) shall be stored in big-
> endian
> 
> +/// order.
> 
> +/// The SignatureHeader size shall always be 0. The SignatureSize shall always
> be 16 (size
> 
> +/// of SignatureOwner component) + 512 bytes.
> 
> +///
> 
> +#define EFI_CERT_RSA4096_GUID \
> 
> +  { \
> 
> +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98,
> 0x2c } \
> 
> +  }
> 
> +
> 
>  ///
> 
>  /// This identifies a signature containing a RSA-2048 signature of a SHA-256
> hash.  The
> 
>  /// SignatureHeader size shall always be 0. The SignatureSize shall always be 16
> (size of
> 
> @@ -330,6 +354,8 @@ typedef struct {
>  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> 
>  extern EFI_GUID  gEfiCertSha256Guid;
> 
>  extern EFI_GUID  gEfiCertRsa2048Guid;
> 
> +extern EFI_GUID  gEfiCertRsa3072Guid;
> 
> +extern EFI_GUID  gEfiCertRsa4096Guid;
> 
>  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> 
>  extern EFI_GUID  gEfiCertSha1Guid;
> 
>  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> 
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 80b6559053..782f6d184d 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -562,6 +562,8 @@
>    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc,
> 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> 
>    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41,
> 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> 
>    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed,
> 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> 
> +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46,
> 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> 
> +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73,
> 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> 
>    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d,
> 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> 
>    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe,
> 0x1, 0x49, 0x66, 0x31, 0xbd }}
> 
>    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28,
> 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> 
> diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> index 452ed491ea..288e44a359 100644
> --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #include <Protocol/VariablePolicy.h>
> 
>  #include <Library/VariablePolicyLib.h>
> 
> 
> 
> +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> 
> +
> 
>  //
> 
>  // Public Exponent of RSA Key.
> 
>  //
> 
>  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> 
> 
> 
>  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
> 0x02, 0x01 };
> 
> +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
> 0x04, 0x02, 0x02 };
> 
> +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
> 0x04, 0x02, 0x03 };
> 
> 
> 
>  //
> 
>  // Requirement for different signature type which have been defined in UEFI
> spec.
> 
> @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
>    // {SigType,                       SigHeaderSize,   SigDataSize  }
> 
>    { EFI_CERT_SHA256_GUID,         0, 32            },
> 
>    { EFI_CERT_RSA2048_GUID,        0, 256           },
> 
> +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> 
> +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> 
>    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> 
>    { EFI_CERT_SHA1_GUID,           0, 20            },
> 
>    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> 
> @@ -1172,6 +1178,172 @@ CalculatePrivAuthVarSignChainSHA256Digest (
>    return EFI_SUCCESS;
> 
>  }
> 
> 
> 
> +/**
> 
> +  Calculate SHA38 digest of SignerCert CommonName + ToplevelCert
> tbsCertificate
> 
> +  SignerCert and ToplevelCert are inside the signer certificate chain.
> 
> +
> 
> +  @param[in]  SignerCert          A pointer to SignerCert data.
> 
> +  @param[in]  SignerCertSize      Length of SignerCert data.
> 
> +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> 
> +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> 
> +  @param[out] Sha384Digest       Sha384 digest calculated.
> 
> +
> 
> +  @return EFI_ABORTED          Digest process failed.
> 
> +  @return EFI_SUCCESS          SHA384 Digest is successfully calculated.
> 
> +
> 
> +**/
> 
> +EFI_STATUS
> 
> +CalculatePrivAuthVarSignChainSHA384Digest (
> 
> +  IN     UINT8  *SignerCert,
> 
> +  IN     UINTN  SignerCertSize,
> 
> +  IN     UINT8  *TopLevelCert,
> 
> +  IN     UINTN  TopLevelCertSize,
> 
> +  OUT    UINT8  *Sha384Digest
> 
> +  )
> 
> +{
> 
> +  UINT8       *TbsCert;
> 
> +  UINTN       TbsCertSize;
> 
> +  CHAR8       CertCommonName[128];
> 
> +  UINTN       CertCommonNameSize;
> 
> +  BOOLEAN     CryptoStatus;
> 
> +  EFI_STATUS  Status;
> 
> +
> 
> +  CertCommonNameSize = sizeof (CertCommonName);
> 
> +
> 
> +  //
> 
> +  // Get SignerCert CommonName
> 
> +  //
> 
> +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> CertCommonName, &CertCommonNameSize);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with
> status %x\n", __FUNCTION__, Status));
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  //
> 
> +  // Get TopLevelCert tbsCertificate
> 
> +  //
> 
> +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> &TbsCertSize)) {
> 
> +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n",
> __FUNCTION__));
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  //
> 
> +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> 
> +  //
> 
> +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> 
> +  CryptoStatus = Sha384Init (mHashCtx);
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  //
> 
> +  // '\0' is forced in CertCommonName. No overflow issue
> 
> +  //
> 
> +  CryptoStatus = Sha384Update (
> 
> +                   mHashCtx,
> 
> +                   CertCommonName,
> 
> +                   AsciiStrLen (CertCommonName)
> 
> +                   );
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  return EFI_SUCCESS;
> 
> +}
> 
> +
> 
> +/**
> 
> +  Calculate SHA512 digest of SignerCert CommonName + ToplevelCert
> tbsCertificate
> 
> +  SignerCert and ToplevelCert are inside the signer certificate chain.
> 
> +
> 
> +  @param[in]  SignerCert          A pointer to SignerCert data.
> 
> +  @param[in]  SignerCertSize      Length of SignerCert data.
> 
> +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> 
> +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> 
> +  @param[out] Sha512Digest       Sha512 digest calculated.
> 
> +
> 
> +  @return EFI_ABORTED          Digest process failed.
> 
> +  @return EFI_SUCCESS          SHA512 Digest is successfully calculated.
> 
> +
> 
> +**/
> 
> +EFI_STATUS
> 
> +CalculatePrivAuthVarSignChainSHA512Digest (
> 
> +  IN     UINT8  *SignerCert,
> 
> +  IN     UINTN  SignerCertSize,
> 
> +  IN     UINT8  *TopLevelCert,
> 
> +  IN     UINTN  TopLevelCertSize,
> 
> +  OUT    UINT8  *Sha512Digest
> 
> +  )
> 
> +{
> 
> +  UINT8       *TbsCert;
> 
> +  UINTN       TbsCertSize;
> 
> +  CHAR8       CertCommonName[128];
> 
> +  UINTN       CertCommonNameSize;
> 
> +  BOOLEAN     CryptoStatus;
> 
> +  EFI_STATUS  Status;
> 
> +
> 
> +  CertCommonNameSize = sizeof (CertCommonName);
> 
> +
> 
> +  //
> 
> +  // Get SignerCert CommonName
> 
> +  //
> 
> +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> CertCommonName, &CertCommonNameSize);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with
> status %x\n", __FUNCTION__, Status));
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  //
> 
> +  // Get TopLevelCert tbsCertificate
> 
> +  //
> 
> +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> &TbsCertSize)) {
> 
> +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n",
> __FUNCTION__));
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  //
> 
> +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> 
> +  //
> 
> +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> 
> +  CryptoStatus = Sha512Init (mHashCtx);
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  //
> 
> +  // '\0' is forced in CertCommonName. No overflow issue
> 
> +  //
> 
> +  CryptoStatus = Sha512Update (
> 
> +                   mHashCtx,
> 
> +                   CertCommonName,
> 
> +                   AsciiStrLen (CertCommonName)
> 
> +                   );
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> 
> +  if (!CryptoStatus) {
> 
> +    return EFI_ABORTED;
> 
> +  }
> 
> +
> 
> +  return EFI_SUCCESS;
> 
> +}
> 
> +
> 
>  /**
> 
>    Find matching signer's certificates for common authenticated variable
> 
>    by corresponding VariableName and VendorGuid from "certdb" or "certdbv".
> 
> @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
>    @param[in]  SignerCertSize    Length of signer certificate.
> 
>    @param[in]  TopLevelCert      Top-level certificate data.
> 
>    @param[in]  TopLevelCertSize  Length of top-level certificate.
> 
> +  @param[in]  DigestSize        Digest Size.
> 
> 
> 
>    @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
> 
>    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with same
> VariableName
> 
> @@ -1542,7 +1715,8 @@ InsertCertsToDb (
>    IN     UINT8     *SignerCert,
> 
>    IN     UINTN     SignerCertSize,
> 
>    IN     UINT8     *TopLevelCert,
> 
> -  IN     UINTN     TopLevelCertSize
> 
> +  IN     UINTN     TopLevelCertSize,
> 
> +  IN     UINT32    DigestSize
> 
>    )
> 
>  {
> 
>    EFI_STATUS         Status;
> 
> @@ -1556,7 +1730,7 @@ InsertCertsToDb (
>    UINT32             CertDataSize;
> 
>    AUTH_CERT_DB_DATA  *Ptr;
> 
>    CHAR16             *DbName;
> 
> -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> 
> +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> 
> 
> 
>    if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL)
> || (TopLevelCert == NULL)) {
> 
>      return EFI_INVALID_PARAMETER;
> 
> @@ -1618,20 +1792,41 @@ InsertCertsToDb (
>    // Construct new data content of variable "certdb" or "certdbv".
> 
>    //
> 
>    NameSize      = (UINT32)StrLen (VariableName);
> 
> -  CertDataSize  = sizeof (Sha256Digest);
> 
> +  CertDataSize  = DigestSize;
> 
>    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize +
> NameSize * sizeof (CHAR16);
> 
>    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> 
>    if (NewCertDbSize > mMaxCertDbSize) {
> 
>      return EFI_OUT_OF_RESOURCES;
> 
>    }
> 
> 
> 
> -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> 
> -             SignerCert,
> 
> -             SignerCertSize,
> 
> -             TopLevelCert,
> 
> -             TopLevelCertSize,
> 
> -             Sha256Digest
> 
> -             );
> 
> +  if (DigestSize == SHA256_DIGEST_SIZE) {
> 
> +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> 
> +               SignerCert,
> 
> +               SignerCertSize,
> 
> +               TopLevelCert,
> 
> +               TopLevelCertSize,
> 
> +               ShaDigest
> 
> +               );
> 
> +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> 
> +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> 
> +               SignerCert,
> 
> +               SignerCertSize,
> 
> +               TopLevelCert,
> 
> +               TopLevelCertSize,
> 
> +               ShaDigest
> 
> +               );
> 
> +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> 
> +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> 
> +               SignerCert,
> 
> +               SignerCertSize,
> 
> +               TopLevelCert,
> 
> +               TopLevelCertSize,
> 
> +               ShaDigest
> 
> +               );
> 
> +  } else {
> 
> +    return EFI_UNSUPPORTED;
> 
> +  }
> 
> +
> 
>    if (EFI_ERROR (Status)) {
> 
>      return Status;
> 
>    }
> 
> @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> 
> 
>    CopyMem (
> 
>      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
> 
> -    Sha256Digest,
> 
> +    ShaDigest,
> 
>      CertDataSize
> 
>      );
> 
> 
> 
> @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
>    UINTN                          CertStackSize;
> 
>    UINT8                          *CertsInCertDb;
> 
>    UINT32                         CertsSizeinDb;
> 
> -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> 
> +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> 
>    EFI_CERT_DATA                  *CertDataPtr;
> 
> 
> 
>    //
> 
> @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> 
> 
>    //
> 
>    // SignedData.digestAlgorithms shall contain the digest algorithm used when
> preparing the
> 
> -  // signature. Only a digest algorithm of SHA-256 is accepted.
> 
> +  // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is
> accepted.
> 
>    //
> 
>    //    According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
> 
>    //        SignedData ::= SEQUENCE {
> 
> @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
>               || (CompareMem (SigData + 13, &mSha256OidValue, sizeof
> (mSha256OidValue)) != 0)))
> 
>         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> 
>            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
> 
> -             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> (mSha256OidValue)) != 0))))
> 
> +             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> (mSha256OidValue)) != 0)))
> 
> +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> 
> +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
> 
> +             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof
> (mSha384OidValue)) != 0)))
> 
> +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> 
> +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
> 
> +             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof
> (mSha384OidValue)) != 0)))
> 
> +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> 
> +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
> 
> +             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof
> (mSha512OidValue)) != 0)))
> 
> +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> 
> +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
> 
> +             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof
> (mSha512OidValue)) != 0))))
> 
>      {
> 
>        return EFI_SECURITY_VIOLATION;
> 
>      }
> 
> @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
>                          ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
> 
>                          TopLevelCert,
> 
>                          TopLevelCertSize,
> 
> -                        Sha256Digest
> 
> +                        ShaDigest
> 
> +                        );
> 
> +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb,
> CertsSizeinDb) != 0)) {
> 
> +          goto Exit;
> 
> +        }
> 
> +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> 
> +        //
> 
> +        // Check hash of signer cert CommonName + Top-level issuer
> tbsCertificate against data in CertDb
> 
> +        //
> 
> +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> 
> +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> 
> +                        CertDataPtr->CertDataBuffer,
> 
> +                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
> 
> +                        TopLevelCert,
> 
> +                        TopLevelCertSize,
> 
> +                        ShaDigest
> 
> +                        );
> 
> +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb,
> CertsSizeinDb) != 0)) {
> 
> +          goto Exit;
> 
> +        }
> 
> +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> 
> +        //
> 
> +        // Check hash of signer cert CommonName + Top-level issuer
> tbsCertificate against data in CertDb
> 
> +        //
> 
> +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> 
> +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> 
> +                        CertDataPtr->CertDataBuffer,
> 
> +                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
> 
> +                        TopLevelCert,
> 
> +                        TopLevelCertSize,
> 
> +                        ShaDigest
> 
>                          );
> 
> -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb,
> CertsSizeinDb) != 0)) {
> 
> +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb,
> CertsSizeinDb) != 0)) {
> 
>            goto Exit;
> 
>          }
> 
>        } else {
> 
> @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
>                        CertDataPtr->CertDataBuffer,
> 
>                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
> 
>                        TopLevelCert,
> 
> -                      TopLevelCertSize
> 
> +                      TopLevelCertSize,
> 
> +                      CertsSizeinDb
> 
>                        );
> 
>        if (EFI_ERROR (Status)) {
> 
>          VerifyStatus = FALSE;
> 
> diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> index dc61ae840c..552c0e99be 100644
> --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
>  UINT32  mPlatformMode;
> 
>  UINT8   mVendorKeyState;
> 
> 
> 
> -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID };
> 
> +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID, EFI_CERT_SHA512_GUID,
> EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID, EFI_CERT_RSA4096_GUID,
> EFI_CERT_X509_GUID };
> 
> 
> 
>  //
> 
>  // Hash context pointer
> 
> @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
>    //
> 
>    // Initialize hash context.
> 
>    //
> 
> -  CtxSize  = Sha256GetContextSize ();
> 
> +  CtxSize  = Sha512GetContextSize ();
> 
>    mHashCtx = AllocateRuntimePool (CtxSize);
> 
>    if (mHashCtx == NULL) {
> 
>      return EFI_OUT_OF_RESOURCES;
> 
> diff --git
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
> index 66e2f5eaa3..f642aad64d 100644
> --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
> +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
> @@ -1606,6 +1606,35 @@ Done:
>    return VerifyStatus;
> 
>  }
> 
> 
> 
> +/**
> 
> +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> 
> +
> 
> +  @retval  UINT32       Hash Alg
> 
> +  **/
> 
> +UINT32
> 
> +GetDefaultHashAlg (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  UINT32  HashAlg;
> 
> +
> 
> +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> 
> +  case 1:
> 
> +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> 
> +    HashAlg = HASHALG_SHA384;
> 
> +    break;
> 
> +  case 2:
> 
> +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> 
> +    HashAlg = HASHALG_SHA512;
> 
> +    break;
> 
> +  default:
> 
> +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> 
> +    HashAlg = HASHALG_SHA256;
> 
> +    break;
> 
> +  }
> 
> +  return HashAlg;
> 
> +}
> 
> +
> 
>  /**
> 
>    Provide verification service for signed images, which include both signature
> validation
> 
>    and platform policy control. For signature types, both UEFI
> WIN_CERTIFICATE_UEFI_GUID and
> 
> @@ -1620,7 +1649,7 @@ Done:
>        in the security database "db", and no valid signature nor any hash value of
> the image may
> 
>        be reflected in the security database "dbx".
> 
>      Otherwise, the image is not signed,
> 
> -      The SHA256 hash value of the image must match a record in the security
> database "db", and
> 
> +      The hash value of the image must match a record in the security database
> "db", and
> 
>        not be reflected in the security data base "dbx".
> 
> 
> 
>    Caution: This function may receive untrusted input.
> 
> @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
>    //
> 
>    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> 
>      //
> 
> -    // This image is not signed. The SHA256 hash value of the image must match
> a record in the security database "db",
> 
> +    // This image is not signed. The hash value of the image must match a record
> in the security database "db",
> 
>      // and not be reflected in the security data base "dbx".
> 
>      //
> 
> -    if (!HashPeImage (HASHALG_SHA256)) {
> 
> +    if (!HashPeImage (GetDefaultHashAlg ())) {
> 
>        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image
> using %s.\n", mHashTypeStr));
> 
>        goto Failed;
> 
>      }
> 
> diff --git
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
> index 1e1a639857..f1ef9236c2 100644
> --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
> +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
> @@ -93,3 +93,4 @@
>    gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> ## SOMETIMES_CONSUMES
> 
>    gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy
> ## SOMETIMES_CONSUMES
> 
>    gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy         ##
> SOMETIMES_CONSUMES
> 
> +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg                  ##
> CONSUMES
> 
> diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
> index 0382090f4e..4adc2a72ab 100644
> --- a/SecurityPkg/SecurityPkg.dec
> +++ b/SecurityPkg/SecurityPkg.dec
> @@ -521,6 +521,13 @@
>    # @Prompt Skip Hdd Password prompt.
> 
> 
> gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLEAN|
> 0x00010021
> 
> 
> 
> +  ## Indicates default hash algorithm in Secure Boot
> 
> +  #   0 - Use SHA256
> 
> +  #   1 - Use SHA384
> 
> +  #   2 - Use SHA512
> 
> +  # @Prompt Secure Boot default hash algorithm
> 
> +
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x000
> 10040
> 
> +
> 
>  [PcdsDynamic, PcdsDynamicEx]
> 
> 
> 
>    ## This PCD indicates Hash mask for TPM 2.0. Bit definition strictly follows TCG
> Algorithm Registry.<BR><BR>
> 
> diff --git
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig
> Dxe.inf
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig
> Dxe.inf
> index 1671d5be7c..4b0012d033 100644
> ---
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig
> Dxe.inf
> +++
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig
> Dxe.inf
> @@ -70,6 +70,14 @@
>    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
>    gEfiCertRsa2048Guid
> 
> 
> 
> +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  gEfiCertRsa3072Guid
> 
> +
> 
> +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  gEfiCertRsa4096Guid
> 
> +
> 
>    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the
> signature.
> 
>    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
>    gEfiCertX509Guid
> 
> @@ -82,6 +90,14 @@
>    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
>    gEfiCertSha256Guid
> 
> 
> 
> +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  gEfiCertSha384Guid
> 
> +
> 
> +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the
> signature.
> 
> +  gEfiCertSha512Guid
> 
> +
> 
>    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> 
>    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> 
>    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> 
> @@ -107,6 +123,9 @@
>    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES  ## GUID  #
> Unique ID for the type of the certificate.
> 
>    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES  ## GUID  #
> Unique ID for the type of the certificate.
> 
> 
> 
> +[Pcd]
> 
> +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg                  ##
> CONSUMES
> 
> +
> 
>  [Protocols]
> 
>    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> 
>    gEfiDevicePathProtocolGuid                    ## PRODUCES
> 
> diff --git
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.c
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.c
> index 4299a6b5e5..0ba029a394 100644
> ---
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.c
> +++
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.c
> @@ -560,7 +560,7 @@ ON_EXIT:
> 
> 
>  **/
> 
>  EFI_STATUS
> 
> -EnrollRsa2048ToKek (
> 
> +EnrollRsaToKek (
> 
>    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> 
>    )
> 
>  {
> 
> @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> 
> 
>    ASSERT (KeyBlob != NULL);
> 
>    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> 
> -  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
> 
> -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is
> supported.\n"));
> 
> +  switch (KeyInfo->KeyLengthInBits / 8) {
> 
> +  case WIN_CERT_UEFI_RSA2048_SIZE:
> 
> +  case WIN_CERT_UEFI_RSA3072_SIZE:
> 
> +  case WIN_CERT_UEFI_RSA4096_SIZE:
> 
> +    break;
> 
> +  default :
> 
> +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048, RSA3072
> and RSA4096 are supported.\n"));
> 
>      Status = EFI_UNSUPPORTED;
> 
>      goto ON_EXIT;
> 
>    }
> 
> @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
>    //
> 
>    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> 
>                     + sizeof (EFI_SIGNATURE_DATA) - 1
> 
> -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> 
> +                   + KeyLenInBytes;
> 
> 
> 
>    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
> 
>    if (KekSigList == NULL) {
> 
> @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> 
> 
>    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> 
>                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> 
> -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> 
> +                                  + (UINT32) KeyLenInBytes;
> 
>    KekSigList->SignatureHeaderSize = 0;
> 
> -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> WIN_CERT_UEFI_RSA2048_SIZE;
> 
> -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> 
> +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32)
> KeyLenInBytes;
> 
> +  switch (KeyLenInBytes) {
> 
> +  case WIN_CERT_UEFI_RSA2048_SIZE:
> 
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> 
> +    break;
> 
> +  case WIN_CERT_UEFI_RSA3072_SIZE:
> 
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> 
> +    break;
> 
> +  case WIN_CERT_UEFI_RSA4096_SIZE:
> 
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> 
> +    break;
> 
> +    break;
> 
> +  default :
> 
> +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> 
> +    Status = EFI_UNSUPPORTED;
> 
> +    goto ON_EXIT;
> 
> +  }
> 
> 
> 
>    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof
> (EFI_SIGNATURE_LIST));
> 
>    CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
> 
>    CopyMem (
> 
>      KEKSigData->SignatureData,
> 
>      KeyBlob + sizeof (CPL_KEY_INFO),
> 
> -    WIN_CERT_UEFI_RSA2048_SIZE
> 
> +    KeyLenInBytes
> 
>      );
> 
> 
> 
>    //
> 
> @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
>    if (IsDerEncodeCertificate (FilePostFix)) {
> 
>      return EnrollX509ToKek (Private);
> 
>    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> 
> -    return EnrollRsa2048ToKek (Private);
> 
> +    return EnrollRsaToKek (Private);
> 
>    } else {
> 
>      //
> 
>      // File type is wrong, simply close it
> 
> @@ -1847,7 +1867,7 @@ HashPeImage (
>    SectionHeader = NULL;
> 
>    Status        = FALSE;
> 
> 
> 
> -  if (HashAlg != HASHALG_SHA256) {
> 
> +  if ((HashAlg >= HASHALG_MAX)) {
> 
>      return FALSE;
> 
>    }
> 
> 
> 
> @@ -1856,8 +1876,25 @@ HashPeImage (
>    //
> 
>    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> 
> 
> 
> -  mImageDigestSize = SHA256_DIGEST_SIZE;
> 
> -  mCertType        = gEfiCertSha256Guid;
> 
> +   switch (HashAlg) {
> 
> +    case HASHALG_SHA256:
> 
> +      mImageDigestSize = SHA256_DIGEST_SIZE;
> 
> +      mCertType        = gEfiCertSha256Guid;
> 
> +      break;
> 
> +
> 
> +    case HASHALG_SHA384:
> 
> +      mImageDigestSize = SHA384_DIGEST_SIZE;
> 
> +      mCertType        = gEfiCertSha384Guid;
> 
> +      break;
> 
> +
> 
> +    case HASHALG_SHA512:
> 
> +      mImageDigestSize = SHA512_DIGEST_SIZE;
> 
> +      mCertType        = gEfiCertSha512Guid;
> 
> +      break;
> 
> +
> 
> +    default:
> 
> +      return FALSE;
> 
> +  }
> 
> 
> 
>    CtxSize = mHash[HashAlg].GetContextSize ();
> 
> 
> 
> @@ -2222,6 +2259,35 @@ ON_EXIT:
>    return Status;
> 
>  }
> 
> 
> 
> +/**
> 
> +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> 
> +
> 
> +  @retval  UINT32       Hash Alg
> 
> +  **/
> 
> +UINT32
> 
> +GetDefaultHashAlg (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  UINT32  HashAlg;
> 
> +
> 
> +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> 
> +  case 1:
> 
> +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> 
> +    HashAlg = HASHALG_SHA384;
> 
> +    break;
> 
> +  case 2:
> 
> +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> 
> +    HashAlg = HASHALG_SHA512;
> 
> +    break;
> 
> +  default:
> 
> +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> 
> +    HashAlg = HASHALG_SHA256;
> 
> +    break;
> 
> +  }
> 
> +  return HashAlg;
> 
> +}
> 
> +
> 
>  /**
> 
>    Enroll a new signature of executable into Signature Database.
> 
> 
> 
> @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
>    }
> 
> 
> 
>    if (mSecDataDir->SizeOfCert == 0) {
> 
> -    if (!HashPeImage (HASHALG_SHA256)) {
> 
> +    if (!HashPeImage (GetDefaultHashAlg ())) {
> 
>        Status =  EFI_SECURITY_VIOLATION;
> 
>        goto ON_EXIT;
> 
>      }
> 
> @@ -2589,6 +2655,10 @@ UpdateDeletePage (
>    while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
> 
>      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)) {
> 
>        Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> 
> +    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)) {
> 
> +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> 
> +    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)) {
> 
> +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> 
>      } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
> 
>        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> 
>      } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)) {
> 
> @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
>    GuidIndex      = 0;
> 
>    while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
> 
>      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
> 
> +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
> 
> +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
> 
>          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
> 
>      {
> 
>        CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList-
> >SignatureHeaderSize));
> 
> @@ -2952,6 +3024,8 @@ DeleteSignature (
>    GuidIndex    = 0;
> 
>    while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
> 
>      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
> 
> +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
> 
> +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
> 
>          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
> 
>          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
> 
>          CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
> 
> @@ -3758,12 +3832,20 @@ LoadSignatureList (
>    while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize))
> {
> 
>      if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {
> 
>        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> 
> +    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa3072Guid))
> {
> 
> +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> 
> +    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa4096Guid))
> {
> 
> +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> 
>      } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
> 
>        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> 
>      } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) {
> 
>        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> 
>      } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
> 
>        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> 
> +    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Guid))
> {
> 
> +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> 
> +    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Guid))
> {
> 
> +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> 
>      } else if (CompareGuid (&ListWalker->SignatureType,
> &gEfiCertX509Sha256Guid)) {
> 
>        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> 
>      } else if (CompareGuid (&ListWalker->SignatureType,
> &gEfiCertX509Sha384Guid)) {
> 
> @@ -4001,6 +4083,14 @@ FormatHelpInfo (
>      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> 
>      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> 
>      IsCert     = TRUE;
> 
> +  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa3072Guid)) {
> 
> +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> 
> +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> 
> +    IsCert     = TRUE;
> 
> +  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa4096Guid)) {
> 
> +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> 
> +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> 
> +    IsCert     = TRUE;
> 
>    } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
> 
>      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> 
>      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> 
> @@ -4011,6 +4101,12 @@ FormatHelpInfo (
>    } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
> 
>      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> 
>      DataSize   = 32;
> 
> +  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
> 
> +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> 
> +    DataSize   = 48;
> 
> +  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
> 
> +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> 
> +    DataSize   = 64;
> 
>    } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid))
> {
> 
>      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> 
>      DataSize   = 32;
> 
> diff --git
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.h
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.h
> index 37c66f1b95..ae50d929a7 100644
> ---
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.h
> +++
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigI
> mpl.h
> @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
>  #define MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> 
> 
> 
>  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> 
> +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> 
> +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> 
> 
> 
>  //
> 
>  // Support hash types
> 
> diff --git
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigS
> trings.uni
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigS
> trings.uni
> index 0d01701de7..1b48acc800 100644
> ---
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigS
> trings.uni
> +++
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigS
> trings.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"
> 
>  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File Explorer"
> 
>  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US
> "RSA2048_SHA256_GUID"
> 
> +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US
> "RSA3072_SHA384_GUID"
> 
> +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US
> "RSA4096_SHA512_GUID"
> 
>  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US "PKCS7_GUID"
> 
>  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US "SHA1_GUID"
> 
>  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> "SHA256_GUID"
> 
> @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US
> "X509_SHA512_GUID"
> 
> 
> 
>  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> "RSA2048_SHA256"
> 
> +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> "RSA3072_SHA384"
> 
> +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> "RSA4096_SHA512"
> 
>  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> 
>  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> 
>  #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
> 
> +#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
> 
> +#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
> 
>  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> "X509_SHA256"
> 
>  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> "X509_SHA384"
> 
>  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> "X509_SHA512"
> 
> --
> 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106279): https://edk2.groups.io/g/devel/message/106279
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Sheng Wei 10 months ago
Hi Jiewen,
I raised the patch V2.
I do the fix for 1) , 2), 3).
But for 4) 5), I have below comments.

4) I am not sure why we need this PCD. Why cannot we support all of hash algo?

+  ## Indicates default hash algorithm in Secure Boot
+  #   0 - Use SHA256
+  #   1 - Use SHA384
+  #   2 - Use SHA512
+  # @Prompt Secure Boot default hash algorithm
+  
+ gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x00
+ 010040

PCD PcdSecureBootDefaultHashAlg is used for the only case of enroll an unsigned image.
The original logic is BIOS will genrate SHA256 digest for this unsigned image and save it.
The PCD is used to select the hash algorithm for this case.
So we have to use a PCD to select the algorithm manully.


5) I don’t believe that you can use size to determine the algorithm. We need a more robust way, such as algorithm ID.

+  switch (KeyLenInBytes) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+    break;
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
+    break;
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
+    break;
+    break;

This code is used when enroll a RSA public key storing file (*.pbk).
Here is the header Struct of this file.
typedef struct _CPL_KEY_INFO {
  UINT32    KeyLengthInBits;        // Key Length In Bits
  UINT32    BlockSize;              // Operation Block Size in Bytes
  UINT32    CipherBlockSize;        // Output Cipher Block Size in Bytes
  UINT32    KeyType;                // Key Type
  UINT32    CipherMode;             // Cipher Mode for Symmetric Algorithm
  UINT32    Flags;                  // Additional Key Property Flags
} CPL_KEY_INFO;
Edk2/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
We can only get to know the RSA algorithm by KeyLengthInBits. (RSA2048/RSA3072/RSA4096)

Thank you.
BR
Sheng Wei

> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: 2023年6月22日 15:22
> To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>;
> Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> Thank you very much to contribute this patch. Here is my feedback.
> 
> 1) I don’t believe that you cannot use digest size to determine the algorithm,
> because different hash algorithm may have same time. E.g. SHA256 and
> SHA3_256.
> 
> +  if (DigestSize == SHA256_DIGEST_SIZE) {
> +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> +               SignerCert,
> +               SignerCertSize,
> +               TopLevelCert,
> +               TopLevelCertSize,
> +               ShaDigest
> +               );
> 
> 2) I don’t believe that you cannot assuming CtxSize of SHA512 is bigger than
> SHA256. I think we may need create context for each algo.
> 
> @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
>    //
>    // Initialize hash context.
>    //
> -  CtxSize  = Sha256GetContextSize ();
> +  CtxSize  = Sha512GetContextSize ();
>    mHashCtx = AllocateRuntimePool (CtxSize);
>    if (mHashCtx == NULL) {
> 
> 3) I believe we should use 0 for SHA256 and ASSERT in default.
> 
> +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {  case 1:
> +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> +    HashAlg = HASHALG_SHA384;
> +    break;
> +  case 2:
> +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> +    HashAlg = HASHALG_SHA512;
> +    break;
> +  default:
> +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> +    HashAlg = HASHALG_SHA256;
> +    break;
> +  }
> 
> 4) I am not sure why we need this PCD. Why cannot we support all of hash
> algo?
> 
> +  ## Indicates default hash algorithm in Secure Boot
> +  #   0 - Use SHA256
> +  #   1 - Use SHA384
> +  #   2 - Use SHA512
> +  # @Prompt Secure Boot default hash algorithm
> +
> +
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> 00
> + 010040
> 
> 5) I don’t believe that you can use size to determine the algorithm. We need
> a more robust way, such as algorithm ID.
> 
> +  switch (KeyLenInBytes) {
> +  case WIN_CERT_UEFI_RSA2048_SIZE:
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> +    break;
> +  case WIN_CERT_UEFI_RSA3072_SIZE:
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> +    break;
> +  case WIN_CERT_UEFI_RSA4096_SIZE:
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> +    break;
> +    break;
> 
> Thank you
> Yao, Jiewen
> 
> > -----Original Message-----
> > From: Sheng, W <w.sheng@intel.com>
> > Sent: Thursday, May 25, 2023 1:23 PM
> > To: devel@edk2.groups.io
> > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>; Chen, Zeyi
> > <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> >
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Min Xu <min.m.xu@intel.com>
> > Cc: Zeyi Chen <zeyi.chen@intel.com>
> > Cc: Fiona Wang <fiona.wang@intel.com>
> > Signed-off-by: Sheng Wei <w.sheng@intel.com>
> > ---
> >  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
> >  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
> >  MdePkg/MdePkg.dec                             |   2 +
> >  .../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++--
> >  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
> >  .../DxeImageVerificationLib.c                 |  35 ++-
> >  .../DxeImageVerificationLib.inf               |   1 +
> >  SecurityPkg/SecurityPkg.dec                   |   7 +
> >  .../SecureBootConfigDxe.inf                   |  19 ++
> >  .../SecureBootConfigImpl.c                    | 122 +++++++-
> >  .../SecureBootConfigImpl.h                    |   2 +
> >  .../SecureBootConfigStrings.uni               |   6 +
> >  12 files changed, 463 insertions(+), 36 deletions(-)
> >
> > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> > b/CryptoPkg/Library/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.
> >
> >    //
> >
> >    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1
> > ()) == 0)
> > ||
> >
> > -      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias
> > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> >
> > +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest
> > + (EVP_sha384 ())
> > == 0) ||
> >
> > +      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias
> > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> >
> >    {
> >
> >      return FALSE;
> >
> >    }
> >
> > diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> > b/MdePkg/Include/Guid/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} \
> >
> >    }
> >
> >
> >
> > +///
> >
> > +/// This identifies a signature containing an RSA-3072 key. The key
> > +(only the
> > modulus
> >
> > +/// since the public key exponent is known to be 0x10001) shall be
> > +stored in big-
> > endian
> >
> > +/// order.
> >
> > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > +shall always
> > be 16 (size
> >
> > +/// of SignatureOwner component) + 384 bytes.
> >
> > +///
> >
> > +#define EFI_CERT_RSA3072_GUID \
> >
> > +  { \
> >
> > +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89,
> > + 0xee,
> > 0x92 } \
> >
> > +  }
> >
> > +
> >
> > +///
> >
> > +/// This identifies a signature containing an RSA-4096 key. The key
> > +(only the
> > modulus
> >
> > +/// since the public key exponent is known to be 0x10001) shall be
> > +stored in big-
> > endian
> >
> > +/// order.
> >
> > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > +shall always
> > be 16 (size
> >
> > +/// of SignatureOwner component) + 512 bytes.
> >
> > +///
> >
> > +#define EFI_CERT_RSA4096_GUID \
> >
> > +  { \
> >
> > +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00,
> > + 0x98,
> > 0x2c } \
> >
> > +  }
> >
> > +
> >
> >  ///
> >
> >  /// This identifies a signature containing a RSA-2048 signature of a
> > SHA-256 hash.  The
> >
> >  /// SignatureHeader size shall always be 0. The SignatureSize shall
> > always be 16 (size of
> >
> > @@ -330,6 +354,8 @@ typedef struct {
> >  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> >
> >  extern EFI_GUID  gEfiCertSha256Guid;
> >
> >  extern EFI_GUID  gEfiCertRsa2048Guid;
> >
> > +extern EFI_GUID  gEfiCertRsa3072Guid;
> >
> > +extern EFI_GUID  gEfiCertRsa4096Guid;
> >
> >  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> >
> >  extern EFI_GUID  gEfiCertSha1Guid;
> >
> >  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> >
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > 80b6559053..782f6d184d 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -562,6 +562,8 @@
> >    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596,
> > {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> >
> >    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9,
> 0x41,
> > 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> >
> >    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14,
> 0xed,
> > 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> >
> > +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46,
> > 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> >
> > +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73,
> > 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> >
> >    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad,
> 0x8d,
> > 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> >
> >    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe,
> > 0x1, 0x49, 0x66, 0x31, 0xbd }}
> >
> >    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28,
> > 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> >
> > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > index 452ed491ea..288e44a359 100644
> > --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > #include <Protocol/VariablePolicy.h>
> >
> >  #include <Library/VariablePolicyLib.h>
> >
> >
> >
> > +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> >
> > +
> >
> >  //
> >
> >  // Public Exponent of RSA Key.
> >
> >  //
> >
> >  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> >
> >
> >
> >  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > 0x03, 0x04, 0x02, 0x01 };
> >
> > +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > +0x03,
> > 0x04, 0x02, 0x02 };
> >
> > +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > +0x03,
> > 0x04, 0x02, 0x03 };
> >
> >
> >
> >  //
> >
> >  // Requirement for different signature type which have been defined
> > in UEFI spec.
> >
> > @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
> >    // {SigType,                       SigHeaderSize,   SigDataSize  }
> >
> >    { EFI_CERT_SHA256_GUID,         0, 32            },
> >
> >    { EFI_CERT_RSA2048_GUID,        0, 256           },
> >
> > +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> >
> > +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> >
> >    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> >
> >    { EFI_CERT_SHA1_GUID,           0, 20            },
> >
> >    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> >
> > @@ -1172,6 +1178,172 @@ CalculatePrivAuthVarSignChainSHA256Digest (
> >    return EFI_SUCCESS;
> >
> >  }
> >
> >
> >
> > +/**
> >
> > +  Calculate SHA38 digest of SignerCert CommonName + ToplevelCert
> > tbsCertificate
> >
> > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> >
> > +
> >
> > +  @param[in]  SignerCert          A pointer to SignerCert data.
> >
> > +  @param[in]  SignerCertSize      Length of SignerCert data.
> >
> > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> >
> > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> >
> > +  @param[out] Sha384Digest       Sha384 digest calculated.
> >
> > +
> >
> > +  @return EFI_ABORTED          Digest process failed.
> >
> > +  @return EFI_SUCCESS          SHA384 Digest is successfully calculated.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +CalculatePrivAuthVarSignChainSHA384Digest (
> >
> > +  IN     UINT8  *SignerCert,
> >
> > +  IN     UINTN  SignerCertSize,
> >
> > +  IN     UINT8  *TopLevelCert,
> >
> > +  IN     UINTN  TopLevelCertSize,
> >
> > +  OUT    UINT8  *Sha384Digest
> >
> > +  )
> >
> > +{
> >
> > +  UINT8       *TbsCert;
> >
> > +  UINTN       TbsCertSize;
> >
> > +  CHAR8       CertCommonName[128];
> >
> > +  UINTN       CertCommonNameSize;
> >
> > +  BOOLEAN     CryptoStatus;
> >
> > +  EFI_STATUS  Status;
> >
> > +
> >
> > +  CertCommonNameSize = sizeof (CertCommonName);
> >
> > +
> >
> > +  //
> >
> > +  // Get SignerCert CommonName
> >
> > +  //
> >
> > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > CertCommonName, &CertCommonNameSize);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with
> > status %x\n", __FUNCTION__, Status));
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Get TopLevelCert tbsCertificate
> >
> > +  //
> >
> > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > &TbsCertSize)) {
> >
> > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > + failed!\n",
> > __FUNCTION__));
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> >
> > +  //
> >
> > +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> >
> > +  CryptoStatus = Sha384Init (mHashCtx);
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // '\0' is forced in CertCommonName. No overflow issue
> >
> > +  //
> >
> > +  CryptoStatus = Sha384Update (
> >
> > +                   mHashCtx,
> >
> > +                   CertCommonName,
> >
> > +                   AsciiStrLen (CertCommonName)
> >
> > +                   );
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Calculate SHA512 digest of SignerCert CommonName + ToplevelCert
> > tbsCertificate
> >
> > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> >
> > +
> >
> > +  @param[in]  SignerCert          A pointer to SignerCert data.
> >
> > +  @param[in]  SignerCertSize      Length of SignerCert data.
> >
> > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> >
> > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> >
> > +  @param[out] Sha512Digest       Sha512 digest calculated.
> >
> > +
> >
> > +  @return EFI_ABORTED          Digest process failed.
> >
> > +  @return EFI_SUCCESS          SHA512 Digest is successfully calculated.
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +CalculatePrivAuthVarSignChainSHA512Digest (
> >
> > +  IN     UINT8  *SignerCert,
> >
> > +  IN     UINTN  SignerCertSize,
> >
> > +  IN     UINT8  *TopLevelCert,
> >
> > +  IN     UINTN  TopLevelCertSize,
> >
> > +  OUT    UINT8  *Sha512Digest
> >
> > +  )
> >
> > +{
> >
> > +  UINT8       *TbsCert;
> >
> > +  UINTN       TbsCertSize;
> >
> > +  CHAR8       CertCommonName[128];
> >
> > +  UINTN       CertCommonNameSize;
> >
> > +  BOOLEAN     CryptoStatus;
> >
> > +  EFI_STATUS  Status;
> >
> > +
> >
> > +  CertCommonNameSize = sizeof (CertCommonName);
> >
> > +
> >
> > +  //
> >
> > +  // Get SignerCert CommonName
> >
> > +  //
> >
> > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > CertCommonName, &CertCommonNameSize);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with
> > status %x\n", __FUNCTION__, Status));
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Get TopLevelCert tbsCertificate
> >
> > +  //
> >
> > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > &TbsCertSize)) {
> >
> > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > + failed!\n",
> > __FUNCTION__));
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> >
> > +  //
> >
> > +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> >
> > +  CryptoStatus = Sha512Init (mHashCtx);
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  //
> >
> > +  // '\0' is forced in CertCommonName. No overflow issue
> >
> > +  //
> >
> > +  CryptoStatus = Sha512Update (
> >
> > +                   mHashCtx,
> >
> > +                   CertCommonName,
> >
> > +                   AsciiStrLen (CertCommonName)
> >
> > +                   );
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> >
> > +  if (!CryptoStatus) {
> >
> > +    return EFI_ABORTED;
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > +
> >
> >  /**
> >
> >    Find matching signer's certificates for common authenticated
> > variable
> >
> >    by corresponding VariableName and VendorGuid from "certdb" or
> "certdbv".
> >
> > @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
> >    @param[in]  SignerCertSize    Length of signer certificate.
> >
> >    @param[in]  TopLevelCert      Top-level certificate data.
> >
> >    @param[in]  TopLevelCertSize  Length of top-level certificate.
> >
> > +  @param[in]  DigestSize        Digest Size.
> >
> >
> >
> >    @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
> >
> >    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with
> same
> > VariableName
> >
> > @@ -1542,7 +1715,8 @@ InsertCertsToDb (
> >    IN     UINT8     *SignerCert,
> >
> >    IN     UINTN     SignerCertSize,
> >
> >    IN     UINT8     *TopLevelCert,
> >
> > -  IN     UINTN     TopLevelCertSize
> >
> > +  IN     UINTN     TopLevelCertSize,
> >
> > +  IN     UINT32    DigestSize
> >
> >    )
> >
> >  {
> >
> >    EFI_STATUS         Status;
> >
> > @@ -1556,7 +1730,7 @@ InsertCertsToDb (
> >    UINT32             CertDataSize;
> >
> >    AUTH_CERT_DB_DATA  *Ptr;
> >
> >    CHAR16             *DbName;
> >
> > -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> >
> > +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> >
> >
> >
> >    if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert
> > == NULL)
> > || (TopLevelCert == NULL)) {
> >
> >      return EFI_INVALID_PARAMETER;
> >
> > @@ -1618,20 +1792,41 @@ InsertCertsToDb (
> >    // Construct new data content of variable "certdb" or "certdbv".
> >
> >    //
> >
> >    NameSize      = (UINT32)StrLen (VariableName);
> >
> > -  CertDataSize  = sizeof (Sha256Digest);
> >
> > +  CertDataSize  = DigestSize;
> >
> >    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize +
> > NameSize * sizeof (CHAR16);
> >
> >    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> >
> >    if (NewCertDbSize > mMaxCertDbSize) {
> >
> >      return EFI_OUT_OF_RESOURCES;
> >
> >    }
> >
> >
> >
> > -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> >
> > -             SignerCert,
> >
> > -             SignerCertSize,
> >
> > -             TopLevelCert,
> >
> > -             TopLevelCertSize,
> >
> > -             Sha256Digest
> >
> > -             );
> >
> > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> >
> > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> >
> > +               SignerCert,
> >
> > +               SignerCertSize,
> >
> > +               TopLevelCert,
> >
> > +               TopLevelCertSize,
> >
> > +               ShaDigest
> >
> > +               );
> >
> > +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> >
> > +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> >
> > +               SignerCert,
> >
> > +               SignerCertSize,
> >
> > +               TopLevelCert,
> >
> > +               TopLevelCertSize,
> >
> > +               ShaDigest
> >
> > +               );
> >
> > +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> >
> > +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> >
> > +               SignerCert,
> >
> > +               SignerCertSize,
> >
> > +               TopLevelCert,
> >
> > +               TopLevelCertSize,
> >
> > +               ShaDigest
> >
> > +               );
> >
> > +  } else {
> >
> > +    return EFI_UNSUPPORTED;
> >
> > +  }
> >
> > +
> >
> >    if (EFI_ERROR (Status)) {
> >
> >      return Status;
> >
> >    }
> >
> > @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> >
> >
> >    CopyMem (
> >
> >      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof
> > (CHAR16),
> >
> > -    Sha256Digest,
> >
> > +    ShaDigest,
> >
> >      CertDataSize
> >
> >      );
> >
> >
> >
> > @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
> >    UINTN                          CertStackSize;
> >
> >    UINT8                          *CertsInCertDb;
> >
> >    UINT32                         CertsSizeinDb;
> >
> > -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> >
> > +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> >
> >    EFI_CERT_DATA                  *CertDataPtr;
> >
> >
> >
> >    //
> >
> > @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> >
> >
> >    //
> >
> >    // SignedData.digestAlgorithms shall contain the digest algorithm
> > used when preparing the
> >
> > -  // signature. Only a digest algorithm of SHA-256 is accepted.
> >
> > +  // signature. Only a digest algorithm of SHA-256, SHA-384 or
> > + SHA-512 is
> > accepted.
> >
> >    //
> >
> >    //    According to PKCS#7 Definition (https://www.rfc-
> editor.org/rfc/rfc2315):
> >
> >    //        SignedData ::= SEQUENCE {
> >
> > @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
> >               || (CompareMem (SigData + 13, &mSha256OidValue, sizeof
> > (mSha256OidValue)) != 0)))
> >
> >         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> >
> >            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > TWO_BYTE_ENCODE)
> >
> > -             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > (mSha256OidValue)) != 0))))
> >
> > +             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > (mSha256OidValue)) != 0)))
> >
> > +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> >
> > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > + TWO_BYTE_ENCODE)
> >
> > +             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof
> > (mSha384OidValue)) != 0)))
> >
> > +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> >
> > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > + TWO_BYTE_ENCODE)
> >
> > +             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof
> > (mSha384OidValue)) != 0)))
> >
> > +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> >
> > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > + TWO_BYTE_ENCODE)
> >
> > +             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof
> > (mSha512OidValue)) != 0)))
> >
> > +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> >
> > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > + TWO_BYTE_ENCODE)
> >
> > +             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof
> > (mSha512OidValue)) != 0))))
> >
> >      {
> >
> >        return EFI_SECURITY_VIOLATION;
> >
> >      }
> >
> > @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
> >                          ReadUnaligned32 ((UINT32
> > *)&(CertDataPtr->CertDataLength)),
> >
> >                          TopLevelCert,
> >
> >                          TopLevelCertSize,
> >
> > -                        Sha256Digest
> >
> > +                        ShaDigest
> >
> > +                        );
> >
> > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > + CertsInCertDb,
> > CertsSizeinDb) != 0)) {
> >
> > +          goto Exit;
> >
> > +        }
> >
> > +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> >
> > +        //
> >
> > +        // Check hash of signer cert CommonName + Top-level issuer
> > tbsCertificate against data in CertDb
> >
> > +        //
> >
> > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> >
> > +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> >
> > +                        CertDataPtr->CertDataBuffer,
> >
> > +                        ReadUnaligned32 ((UINT32
> > + *)&(CertDataPtr->CertDataLength)),
> >
> > +                        TopLevelCert,
> >
> > +                        TopLevelCertSize,
> >
> > +                        ShaDigest
> >
> > +                        );
> >
> > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > + CertsInCertDb,
> > CertsSizeinDb) != 0)) {
> >
> > +          goto Exit;
> >
> > +        }
> >
> > +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> >
> > +        //
> >
> > +        // Check hash of signer cert CommonName + Top-level issuer
> > tbsCertificate against data in CertDb
> >
> > +        //
> >
> > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> >
> > +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> >
> > +                        CertDataPtr->CertDataBuffer,
> >
> > +                        ReadUnaligned32 ((UINT32
> > + *)&(CertDataPtr->CertDataLength)),
> >
> > +                        TopLevelCert,
> >
> > +                        TopLevelCertSize,
> >
> > +                        ShaDigest
> >
> >                          );
> >
> > -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest,
> CertsInCertDb,
> > CertsSizeinDb) != 0)) {
> >
> > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > + CertsInCertDb,
> > CertsSizeinDb) != 0)) {
> >
> >            goto Exit;
> >
> >          }
> >
> >        } else {
> >
> > @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
> >                        CertDataPtr->CertDataBuffer,
> >
> >                        ReadUnaligned32 ((UINT32
> > *)&(CertDataPtr->CertDataLength)),
> >
> >                        TopLevelCert,
> >
> > -                      TopLevelCertSize
> >
> > +                      TopLevelCertSize,
> >
> > +                      CertsSizeinDb
> >
> >                        );
> >
> >        if (EFI_ERROR (Status)) {
> >
> >          VerifyStatus = FALSE;
> >
> > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > index dc61ae840c..552c0e99be 100644
> > --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
> >  UINT32  mPlatformMode;
> >
> >  UINT8   mVendorKeyState;
> >
> >
> >
> > -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID,
> EFI_CERT_X509_GUID };
> >
> > +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID,
> EFI_CERT_SHA512_GUID,
> > EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID,
> EFI_CERT_RSA4096_GUID,
> > EFI_CERT_X509_GUID };
> >
> >
> >
> >  //
> >
> >  // Hash context pointer
> >
> > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> >    //
> >
> >    // Initialize hash context.
> >
> >    //
> >
> > -  CtxSize  = Sha256GetContextSize ();
> >
> > +  CtxSize  = Sha512GetContextSize ();
> >
> >    mHashCtx = AllocateRuntimePool (CtxSize);
> >
> >    if (mHashCtx == NULL) {
> >
> >      return EFI_OUT_OF_RESOURCES;
> >
> > diff --git
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > c
> > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > c
> > index 66e2f5eaa3..f642aad64d 100644
> > ---
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > c
> > +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > +++ Lib.c
> > @@ -1606,6 +1606,35 @@ Done:
> >    return VerifyStatus;
> >
> >  }
> >
> >
> >
> > +/**
> >
> > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> >
> > +
> >
> > +  @retval  UINT32       Hash Alg
> >
> > +  **/
> >
> > +UINT32
> >
> > +GetDefaultHashAlg (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  UINT32  HashAlg;
> >
> > +
> >
> > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> >
> > +  case 1:
> >
> > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> >
> > +    HashAlg = HASHALG_SHA384;
> >
> > +    break;
> >
> > +  case 2:
> >
> > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> >
> > +    HashAlg = HASHALG_SHA512;
> >
> > +    break;
> >
> > +  default:
> >
> > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> >
> > +    HashAlg = HASHALG_SHA256;
> >
> > +    break;
> >
> > +  }
> >
> > +  return HashAlg;
> >
> > +}
> >
> > +
> >
> >  /**
> >
> >    Provide verification service for signed images, which include both
> > signature validation
> >
> >    and platform policy control. For signature types, both UEFI
> > WIN_CERTIFICATE_UEFI_GUID and
> >
> > @@ -1620,7 +1649,7 @@ Done:
> >        in the security database "db", and no valid signature nor any
> > hash value of the image may
> >
> >        be reflected in the security database "dbx".
> >
> >      Otherwise, the image is not signed,
> >
> > -      The SHA256 hash value of the image must match a record in the
> security
> > database "db", and
> >
> > +      The hash value of the image must match a record in the security
> > + database
> > "db", and
> >
> >        not be reflected in the security data base "dbx".
> >
> >
> >
> >    Caution: This function may receive untrusted input.
> >
> > @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
> >    //
> >
> >    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> >
> >      //
> >
> > -    // This image is not signed. The SHA256 hash value of the image must
> match
> > a record in the security database "db",
> >
> > +    // This image is not signed. The hash value of the image must
> > + match a record
> > in the security database "db",
> >
> >      // and not be reflected in the security data base "dbx".
> >
> >      //
> >
> > -    if (!HashPeImage (HASHALG_SHA256)) {
> >
> > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> >
> >        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash
> > this image using %s.\n", mHashTypeStr));
> >
> >        goto Failed;
> >
> >      }
> >
> > diff --git
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > inf
> > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > inf
> > index 1e1a639857..f1ef9236c2 100644
> > ---
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > inf
> > +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > +++ Lib.inf
> > @@ -93,3 +93,4 @@
> >    gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> > ## SOMETIMES_CONSUMES
> >
> >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolic
> y
> > ## SOMETIMES_CONSUMES
> >
> >    gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy
> ##
> > SOMETIMES_CONSUMES
> >
> > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> ##
> > CONSUMES
> >
> > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
> > index 0382090f4e..4adc2a72ab 100644
> > --- a/SecurityPkg/SecurityPkg.dec
> > +++ b/SecurityPkg/SecurityPkg.dec
> > @@ -521,6 +521,13 @@
> >    # @Prompt Skip Hdd Password prompt.
> >
> >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLE
> AN|
> > 0x00010021
> >
> >
> >
> > +  ## Indicates default hash algorithm in Secure Boot
> >
> > +  #   0 - Use SHA256
> >
> > +  #   1 - Use SHA384
> >
> > +  #   2 - Use SHA512
> >
> > +  # @Prompt Secure Boot default hash algorithm
> >
> > +
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> 00
> > 0
> > 10040
> >
> > +
> >
> >  [PcdsDynamic, PcdsDynamicEx]
> >
> >
> >
> >    ## This PCD indicates Hash mask for TPM 2.0. Bit definition
> > strictly follows TCG Algorithm Registry.<BR><BR>
> >
> > diff --git
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > ig
> > Dxe.inf
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > ig
> > Dxe.inf
> > index 1671d5be7c..4b0012d033 100644
> > ---
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > ig
> > Dxe.inf
> > +++
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > ig
> > Dxe.inf
> > @@ -70,6 +70,14 @@
> >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> >    gEfiCertRsa2048Guid
> >
> >
> >
> > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  gEfiCertRsa3072Guid
> >
> > +
> >
> > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  gEfiCertRsa4096Guid
> >
> > +
> >
> >    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> >    gEfiCertX509Guid
> >
> > @@ -82,6 +90,14 @@
> >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> >    gEfiCertSha256Guid
> >
> >
> >
> > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  gEfiCertSha384Guid
> >
> > +
> >
> > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> the
> > signature.
> >
> > +  gEfiCertSha512Guid
> >
> > +
> >
> >    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> >
> >    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> >
> >    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> >
> > @@ -107,6 +123,9 @@
> >    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES  ## GUID
> #
> > Unique ID for the type of the certificate.
> >
> >    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES  ## GUID
> #
> > Unique ID for the type of the certificate.
> >
> >
> >
> > +[Pcd]
> >
> > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> ##
> > CONSUMES
> >
> > +
> >
> >  [Protocols]
> >
> >    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> >
> >    gEfiDevicePathProtocolGuid                    ## PRODUCES
> >
> > diff --git
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.c
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.c
> > index 4299a6b5e5..0ba029a394 100644
> > ---
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.c
> > +++
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.c
> > @@ -560,7 +560,7 @@ ON_EXIT:
> >
> >
> >  **/
> >
> >  EFI_STATUS
> >
> > -EnrollRsa2048ToKek (
> >
> > +EnrollRsaToKek (
> >
> >    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> >
> >    )
> >
> >  {
> >
> > @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> >
> >
> >    ASSERT (KeyBlob != NULL);
> >
> >    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> >
> > -  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
> >
> > -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is
> > supported.\n"));
> >
> > +  switch (KeyInfo->KeyLengthInBits / 8) {
> >
> > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> >
> > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> >
> > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> >
> > +    break;
> >
> > +  default :
> >
> > +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048,
> > + RSA3072
> > and RSA4096 are supported.\n"));
> >
> >      Status = EFI_UNSUPPORTED;
> >
> >      goto ON_EXIT;
> >
> >    }
> >
> > @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
> >    //
> >
> >    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> >
> >                     + sizeof (EFI_SIGNATURE_DATA) - 1
> >
> > -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> >
> > +                   + KeyLenInBytes;
> >
> >
> >
> >    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool
> > (KekSigListSize);
> >
> >    if (KekSigList == NULL) {
> >
> > @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> >
> >
> >    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> >
> >                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> >
> > -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> >
> > +                                  + (UINT32) KeyLenInBytes;
> >
> >    KekSigList->SignatureHeaderSize = 0;
> >
> > -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > WIN_CERT_UEFI_RSA2048_SIZE;
> >
> > -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> >
> > +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> (UINT32)
> > KeyLenInBytes;
> >
> > +  switch (KeyLenInBytes) {
> >
> > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> >
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> >
> > +    break;
> >
> > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> >
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> >
> > +    break;
> >
> > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> >
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> >
> > +    break;
> >
> > +    break;
> >
> > +  default :
> >
> > +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> >
> > +    Status = EFI_UNSUPPORTED;
> >
> > +    goto ON_EXIT;
> >
> > +  }
> >
> >
> >
> >    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof
> > (EFI_SIGNATURE_LIST));
> >
> >    CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
> >
> >    CopyMem (
> >
> >      KEKSigData->SignatureData,
> >
> >      KeyBlob + sizeof (CPL_KEY_INFO),
> >
> > -    WIN_CERT_UEFI_RSA2048_SIZE
> >
> > +    KeyLenInBytes
> >
> >      );
> >
> >
> >
> >    //
> >
> > @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
> >    if (IsDerEncodeCertificate (FilePostFix)) {
> >
> >      return EnrollX509ToKek (Private);
> >
> >    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> >
> > -    return EnrollRsa2048ToKek (Private);
> >
> > +    return EnrollRsaToKek (Private);
> >
> >    } else {
> >
> >      //
> >
> >      // File type is wrong, simply close it
> >
> > @@ -1847,7 +1867,7 @@ HashPeImage (
> >    SectionHeader = NULL;
> >
> >    Status        = FALSE;
> >
> >
> >
> > -  if (HashAlg != HASHALG_SHA256) {
> >
> > +  if ((HashAlg >= HASHALG_MAX)) {
> >
> >      return FALSE;
> >
> >    }
> >
> >
> >
> > @@ -1856,8 +1876,25 @@ HashPeImage (
> >    //
> >
> >    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> >
> >
> >
> > -  mImageDigestSize = SHA256_DIGEST_SIZE;
> >
> > -  mCertType        = gEfiCertSha256Guid;
> >
> > +   switch (HashAlg) {
> >
> > +    case HASHALG_SHA256:
> >
> > +      mImageDigestSize = SHA256_DIGEST_SIZE;
> >
> > +      mCertType        = gEfiCertSha256Guid;
> >
> > +      break;
> >
> > +
> >
> > +    case HASHALG_SHA384:
> >
> > +      mImageDigestSize = SHA384_DIGEST_SIZE;
> >
> > +      mCertType        = gEfiCertSha384Guid;
> >
> > +      break;
> >
> > +
> >
> > +    case HASHALG_SHA512:
> >
> > +      mImageDigestSize = SHA512_DIGEST_SIZE;
> >
> > +      mCertType        = gEfiCertSha512Guid;
> >
> > +      break;
> >
> > +
> >
> > +    default:
> >
> > +      return FALSE;
> >
> > +  }
> >
> >
> >
> >    CtxSize = mHash[HashAlg].GetContextSize ();
> >
> >
> >
> > @@ -2222,6 +2259,35 @@ ON_EXIT:
> >    return Status;
> >
> >  }
> >
> >
> >
> > +/**
> >
> > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> >
> > +
> >
> > +  @retval  UINT32       Hash Alg
> >
> > +  **/
> >
> > +UINT32
> >
> > +GetDefaultHashAlg (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  UINT32  HashAlg;
> >
> > +
> >
> > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> >
> > +  case 1:
> >
> > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> >
> > +    HashAlg = HASHALG_SHA384;
> >
> > +    break;
> >
> > +  case 2:
> >
> > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> >
> > +    HashAlg = HASHALG_SHA512;
> >
> > +    break;
> >
> > +  default:
> >
> > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> >
> > +    HashAlg = HASHALG_SHA256;
> >
> > +    break;
> >
> > +  }
> >
> > +  return HashAlg;
> >
> > +}
> >
> > +
> >
> >  /**
> >
> >    Enroll a new signature of executable into Signature Database.
> >
> >
> >
> > @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
> >    }
> >
> >
> >
> >    if (mSecDataDir->SizeOfCert == 0) {
> >
> > -    if (!HashPeImage (HASHALG_SHA256)) {
> >
> > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> >
> >        Status =  EFI_SECURITY_VIOLATION;
> >
> >        goto ON_EXIT;
> >
> >      }
> >
> > @@ -2589,6 +2655,10 @@ UpdateDeletePage (
> >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > CertList->SignatureListSize)) {
> >
> >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid))
> > {
> >
> >        Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> >
> > +    } else if (CompareGuid (&CertList->SignatureType,
> > + &gEfiCertRsa3072Guid)) {
> >
> > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> >
> > +    } else if (CompareGuid (&CertList->SignatureType,
> > + &gEfiCertRsa4096Guid)) {
> >
> > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> >
> >      } else if (CompareGuid (&CertList->SignatureType,
> > &gEfiCertX509Guid)) {
> >
> >        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> >
> >      } else if (CompareGuid (&CertList->SignatureType,
> > &gEfiCertSha1Guid)) {
> >
> > @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
> >    GuidIndex      = 0;
> >
> >    while ((KekDataSize > 0) && (KekDataSize >=
> > CertList->SignatureListSize)) {
> >
> >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > ||
> >
> > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > + ||
> >
> > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > + ||
> >
> >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
> >
> >      {
> >
> >        CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST)
> > + CertList-
> > >SignatureHeaderSize));
> >
> > @@ -2952,6 +3024,8 @@ DeleteSignature (
> >    GuidIndex    = 0;
> >
> >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > CertList->SignatureListSize)) {
> >
> >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > ||
> >
> > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > + ||
> >
> > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > + ||
> >
> >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
> >
> >          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
> >
> >          CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)
> > ||
> >
> > @@ -3758,12 +3832,20 @@ LoadSignatureList (
> >    while ((RemainingSize > 0) && (RemainingSize >=
> > ListWalker->SignatureListSize)) {
> >
> >      if (CompareGuid (&ListWalker->SignatureType,
> > &gEfiCertRsa2048Guid)) {
> >
> >        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> >
> > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > + &gEfiCertRsa3072Guid))
> > {
> >
> > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> >
> > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > + &gEfiCertRsa4096Guid))
> > {
> >
> > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> >
> >      } else if (CompareGuid (&ListWalker->SignatureType,
> > &gEfiCertX509Guid)) {
> >
> >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> >
> >      } else if (CompareGuid (&ListWalker->SignatureType,
> > &gEfiCertSha1Guid)) {
> >
> >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> >
> >      } else if (CompareGuid (&ListWalker->SignatureType,
> > &gEfiCertSha256Guid)) {
> >
> >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> >
> > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > + &gEfiCertSha384Guid))
> > {
> >
> > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> >
> > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > + &gEfiCertSha512Guid))
> > {
> >
> > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> >
> >      } else if (CompareGuid (&ListWalker->SignatureType,
> > &gEfiCertX509Sha256Guid)) {
> >
> >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> >
> >      } else if (CompareGuid (&ListWalker->SignatureType,
> > &gEfiCertX509Sha384Guid)) {
> >
> > @@ -4001,6 +4083,14 @@ FormatHelpInfo (
> >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> >
> >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> >
> >      IsCert     = TRUE;
> >
> > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > + &gEfiCertRsa3072Guid)) {
> >
> > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> >
> > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> >
> > +    IsCert     = TRUE;
> >
> > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > + &gEfiCertRsa4096Guid)) {
> >
> > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> >
> > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> >
> > +    IsCert     = TRUE;
> >
> >    } else if (CompareGuid (&ListEntry->SignatureType,
> > &gEfiCertX509Guid)) {
> >
> >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> >
> >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> >
> > @@ -4011,6 +4101,12 @@ FormatHelpInfo (
> >    } else if (CompareGuid (&ListEntry->SignatureType,
> > &gEfiCertSha256Guid)) {
> >
> >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> >
> >      DataSize   = 32;
> >
> > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > + &gEfiCertSha384Guid)) {
> >
> > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> >
> > +    DataSize   = 48;
> >
> > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > + &gEfiCertSha512Guid)) {
> >
> > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> >
> > +    DataSize   = 64;
> >
> >    } else if (CompareGuid (&ListEntry->SignatureType,
> > &gEfiCertX509Sha256Guid)) {
> >
> >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> >
> >      DataSize   = 32;
> >
> > diff --git
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.h
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.h
> > index 37c66f1b95..ae50d929a7 100644
> > ---
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.h
> > +++
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igI
> > mpl.h
> > @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;  #define
> > MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> >
> >
> >
> >  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> >
> > +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> >
> > +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> >
> >
> >
> >  //
> >
> >  // Support hash types
> >
> > diff --git
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igS
> > trings.uni
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igS
> > trings.uni
> > index 0d01701de7..1b48acc800 100644
> > ---
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igS
> > trings.uni
> > +++
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> f
> > igS
> > trings.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"
> >
> >  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File
> Explorer"
> >
> >  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US
> > "RSA2048_SHA256_GUID"
> >
> > +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US
> > "RSA3072_SHA384_GUID"
> >
> > +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US
> > "RSA4096_SHA512_GUID"
> >
> >  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US
> "PKCS7_GUID"
> >
> >  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US
> "SHA1_GUID"
> >
> >  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> > "SHA256_GUID"
> >
> > @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> >  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US
> > "X509_SHA512_GUID"
> >
> >
> >
> >  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> > "RSA2048_SHA256"
> >
> > +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> > "RSA3072_SHA384"
> >
> > +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> > "RSA4096_SHA512"
> >
> >  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> >
> >  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> >
> >  #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
> >
> > +#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
> >
> > +#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
> >
> >  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> > "X509_SHA256"
> >
> >  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> > "X509_SHA384"
> >
> >  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> > "X509_SHA512"
> >
> > --
> > 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106563): https://edk2.groups.io/g/devel/message/106563
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Yao, Jiewen 10 months ago
For 4, I think we can enroll all supported algorithms, or the active algorithm. I don’t think the PCD is needed.

For 5, I suggest to change the data structure to include the algorithm ID.

Thank you
Yao, Jiewen


> -----Original Message-----
> From: Sheng, W <w.sheng@intel.com>
> Sent: Friday, June 30, 2023 3:52 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>;
> Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> Hi Jiewen,
> I raised the patch V2.
> I do the fix for 1) , 2), 3).
> But for 4) 5), I have below comments.
> 
> 4) I am not sure why we need this PCD. Why cannot we support all of hash algo?
> 
> +  ## Indicates default hash algorithm in Secure Boot
> +  #   0 - Use SHA256
> +  #   1 - Use SHA384
> +  #   2 - Use SHA512
> +  # @Prompt Secure Boot default hash algorithm
> +
> +
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x00
> + 010040
> 
> PCD PcdSecureBootDefaultHashAlg is used for the only case of enroll an
> unsigned image.
> The original logic is BIOS will genrate SHA256 digest for this unsigned image and
> save it.
> The PCD is used to select the hash algorithm for this case.
> So we have to use a PCD to select the algorithm manully.
> 
> 
> 5) I don’t believe that you can use size to determine the algorithm. We need a
> more robust way, such as algorithm ID.
> 
> +  switch (KeyLenInBytes) {
> +  case WIN_CERT_UEFI_RSA2048_SIZE:
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> +    break;
> +  case WIN_CERT_UEFI_RSA3072_SIZE:
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> +    break;
> +  case WIN_CERT_UEFI_RSA4096_SIZE:
> +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> +    break;
> +    break;
> 
> This code is used when enroll a RSA public key storing file (*.pbk).
> Here is the header Struct of this file.
> typedef struct _CPL_KEY_INFO {
>   UINT32    KeyLengthInBits;        // Key Length In Bits
>   UINT32    BlockSize;              // Operation Block Size in Bytes
>   UINT32    CipherBlockSize;        // Output Cipher Block Size in Bytes
>   UINT32    KeyType;                // Key Type
>   UINT32    CipherMode;             // Cipher Mode for Symmetric Algorithm
>   UINT32    Flags;                  // Additional Key Property Flags
> } CPL_KEY_INFO;
> Edk2/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> figImpl.h
> We can only get to know the RSA algorithm by KeyLengthInBits.
> (RSA2048/RSA3072/RSA4096)
> 
> Thank you.
> BR
> Sheng Wei
> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: 2023年6月22日 15:22
> > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>;
> > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> >
> > Thank you very much to contribute this patch. Here is my feedback.
> >
> > 1) I don’t believe that you cannot use digest size to determine the algorithm,
> > because different hash algorithm may have same time. E.g. SHA256 and
> > SHA3_256.
> >
> > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > +               SignerCert,
> > +               SignerCertSize,
> > +               TopLevelCert,
> > +               TopLevelCertSize,
> > +               ShaDigest
> > +               );
> >
> > 2) I don’t believe that you cannot assuming CtxSize of SHA512 is bigger than
> > SHA256. I think we may need create context for each algo.
> >
> > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> >    //
> >    // Initialize hash context.
> >    //
> > -  CtxSize  = Sha256GetContextSize ();
> > +  CtxSize  = Sha512GetContextSize ();
> >    mHashCtx = AllocateRuntimePool (CtxSize);
> >    if (mHashCtx == NULL) {
> >
> > 3) I believe we should use 0 for SHA256 and ASSERT in default.
> >
> > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {  case 1:
> > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > +    HashAlg = HASHALG_SHA384;
> > +    break;
> > +  case 2:
> > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > +    HashAlg = HASHALG_SHA512;
> > +    break;
> > +  default:
> > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > +    HashAlg = HASHALG_SHA256;
> > +    break;
> > +  }
> >
> > 4) I am not sure why we need this PCD. Why cannot we support all of hash
> > algo?
> >
> > +  ## Indicates default hash algorithm in Secure Boot
> > +  #   0 - Use SHA256
> > +  #   1 - Use SHA384
> > +  #   2 - Use SHA512
> > +  # @Prompt Secure Boot default hash algorithm
> > +
> > +
> > gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > 00
> > + 010040
> >
> > 5) I don’t believe that you can use size to determine the algorithm. We need
> > a more robust way, such as algorithm ID.
> >
> > +  switch (KeyLenInBytes) {
> > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > +    break;
> > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > +    break;
> > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > +    break;
> > +    break;
> >
> > Thank you
> > Yao, Jiewen
> >
> > > -----Original Message-----
> > > From: Sheng, W <w.sheng@intel.com>
> > > Sent: Thursday, May 25, 2023 1:23 PM
> > > To: devel@edk2.groups.io
> > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>; Chen, Zeyi
> > > <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> > >
> > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > Cc: Min Xu <min.m.xu@intel.com>
> > > Cc: Zeyi Chen <zeyi.chen@intel.com>
> > > Cc: Fiona Wang <fiona.wang@intel.com>
> > > Signed-off-by: Sheng Wei <w.sheng@intel.com>
> > > ---
> > >  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
> > >  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
> > >  MdePkg/MdePkg.dec                             |   2 +
> > >  .../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++--
> > >  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
> > >  .../DxeImageVerificationLib.c                 |  35 ++-
> > >  .../DxeImageVerificationLib.inf               |   1 +
> > >  SecurityPkg/SecurityPkg.dec                   |   7 +
> > >  .../SecureBootConfigDxe.inf                   |  19 ++
> > >  .../SecureBootConfigImpl.c                    | 122 +++++++-
> > >  .../SecureBootConfigImpl.h                    |   2 +
> > >  .../SecureBootConfigStrings.uni               |   6 +
> > >  12 files changed, 463 insertions(+), 36 deletions(-)
> > >
> > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> > > b/CryptoPkg/Library/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.
> > >
> > >    //
> > >
> > >    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1
> > > ()) == 0)
> > > ||
> > >
> > > -      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias
> > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > >
> > > +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest
> > > + (EVP_sha384 ())
> > > == 0) ||
> > >
> > > +      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias
> > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > >
> > >    {
> > >
> > >      return FALSE;
> > >
> > >    }
> > >
> > > diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> > > b/MdePkg/Include/Guid/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} \
> > >
> > >    }
> > >
> > >
> > >
> > > +///
> > >
> > > +/// This identifies a signature containing an RSA-3072 key. The key
> > > +(only the
> > > modulus
> > >
> > > +/// since the public key exponent is known to be 0x10001) shall be
> > > +stored in big-
> > > endian
> > >
> > > +/// order.
> > >
> > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > +shall always
> > > be 16 (size
> > >
> > > +/// of SignatureOwner component) + 384 bytes.
> > >
> > > +///
> > >
> > > +#define EFI_CERT_RSA3072_GUID \
> > >
> > > +  { \
> > >
> > > +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89,
> > > + 0xee,
> > > 0x92 } \
> > >
> > > +  }
> > >
> > > +
> > >
> > > +///
> > >
> > > +/// This identifies a signature containing an RSA-4096 key. The key
> > > +(only the
> > > modulus
> > >
> > > +/// since the public key exponent is known to be 0x10001) shall be
> > > +stored in big-
> > > endian
> > >
> > > +/// order.
> > >
> > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > +shall always
> > > be 16 (size
> > >
> > > +/// of SignatureOwner component) + 512 bytes.
> > >
> > > +///
> > >
> > > +#define EFI_CERT_RSA4096_GUID \
> > >
> > > +  { \
> > >
> > > +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00,
> > > + 0x98,
> > > 0x2c } \
> > >
> > > +  }
> > >
> > > +
> > >
> > >  ///
> > >
> > >  /// This identifies a signature containing a RSA-2048 signature of a
> > > SHA-256 hash.  The
> > >
> > >  /// SignatureHeader size shall always be 0. The SignatureSize shall
> > > always be 16 (size of
> > >
> > > @@ -330,6 +354,8 @@ typedef struct {
> > >  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> > >
> > >  extern EFI_GUID  gEfiCertSha256Guid;
> > >
> > >  extern EFI_GUID  gEfiCertRsa2048Guid;
> > >
> > > +extern EFI_GUID  gEfiCertRsa3072Guid;
> > >
> > > +extern EFI_GUID  gEfiCertRsa4096Guid;
> > >
> > >  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> > >
> > >  extern EFI_GUID  gEfiCertSha1Guid;
> > >
> > >  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> > >
> > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > > 80b6559053..782f6d184d 100644
> > > --- a/MdePkg/MdePkg.dec
> > > +++ b/MdePkg/MdePkg.dec
> > > @@ -562,6 +562,8 @@
> > >    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596,
> > > {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> > >
> > >    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9,
> > 0x41,
> > > 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> > >
> > >    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14,
> > 0xed,
> > > 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> > >
> > > +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46,
> > > 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> > >
> > > +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73,
> > > 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> > >
> > >    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad,
> > 0x8d,
> > > 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> > >
> > >    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87,
> 0xbe,
> > > 0x1, 0x49, 0x66, 0x31, 0xbd }}
> > >
> > >    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28,
> > > 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> > >
> > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > index 452ed491ea..288e44a359 100644
> > > --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > #include <Protocol/VariablePolicy.h>
> > >
> > >  #include <Library/VariablePolicyLib.h>
> > >
> > >
> > >
> > > +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> > >
> > > +
> > >
> > >  //
> > >
> > >  // Public Exponent of RSA Key.
> > >
> > >  //
> > >
> > >  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> > >
> > >
> > >
> > >  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > 0x03, 0x04, 0x02, 0x01 };
> > >
> > > +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > +0x03,
> > > 0x04, 0x02, 0x02 };
> > >
> > > +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > +0x03,
> > > 0x04, 0x02, 0x03 };
> > >
> > >
> > >
> > >  //
> > >
> > >  // Requirement for different signature type which have been defined
> > > in UEFI spec.
> > >
> > > @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
> > >    // {SigType,                       SigHeaderSize,   SigDataSize  }
> > >
> > >    { EFI_CERT_SHA256_GUID,         0, 32            },
> > >
> > >    { EFI_CERT_RSA2048_GUID,        0, 256           },
> > >
> > > +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> > >
> > > +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> > >
> > >    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> > >
> > >    { EFI_CERT_SHA1_GUID,           0, 20            },
> > >
> > >    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> > >
> > > @@ -1172,6 +1178,172 @@ CalculatePrivAuthVarSignChainSHA256Digest (
> > >    return EFI_SUCCESS;
> > >
> > >  }
> > >
> > >
> > >
> > > +/**
> > >
> > > +  Calculate SHA38 digest of SignerCert CommonName + ToplevelCert
> > > tbsCertificate
> > >
> > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > >
> > > +
> > >
> > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > >
> > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > >
> > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > >
> > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > >
> > > +  @param[out] Sha384Digest       Sha384 digest calculated.
> > >
> > > +
> > >
> > > +  @return EFI_ABORTED          Digest process failed.
> > >
> > > +  @return EFI_SUCCESS          SHA384 Digest is successfully calculated.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +EFI_STATUS
> > >
> > > +CalculatePrivAuthVarSignChainSHA384Digest (
> > >
> > > +  IN     UINT8  *SignerCert,
> > >
> > > +  IN     UINTN  SignerCertSize,
> > >
> > > +  IN     UINT8  *TopLevelCert,
> > >
> > > +  IN     UINTN  TopLevelCertSize,
> > >
> > > +  OUT    UINT8  *Sha384Digest
> > >
> > > +  )
> > >
> > > +{
> > >
> > > +  UINT8       *TbsCert;
> > >
> > > +  UINTN       TbsCertSize;
> > >
> > > +  CHAR8       CertCommonName[128];
> > >
> > > +  UINTN       CertCommonNameSize;
> > >
> > > +  BOOLEAN     CryptoStatus;
> > >
> > > +  EFI_STATUS  Status;
> > >
> > > +
> > >
> > > +  CertCommonNameSize = sizeof (CertCommonName);
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // Get SignerCert CommonName
> > >
> > > +  //
> > >
> > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > CertCommonName, &CertCommonNameSize);
> > >
> > > +  if (EFI_ERROR (Status)) {
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with
> > > status %x\n", __FUNCTION__, Status));
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // Get TopLevelCert tbsCertificate
> > >
> > > +  //
> > >
> > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > &TbsCertSize)) {
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > + failed!\n",
> > > __FUNCTION__));
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > >
> > > +  //
> > >
> > > +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> > >
> > > +  CryptoStatus = Sha384Init (mHashCtx);
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // '\0' is forced in CertCommonName. No overflow issue
> > >
> > > +  //
> > >
> > > +  CryptoStatus = Sha384Update (
> > >
> > > +                   mHashCtx,
> > >
> > > +                   CertCommonName,
> > >
> > > +                   AsciiStrLen (CertCommonName)
> > >
> > > +                   );
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  return EFI_SUCCESS;
> > >
> > > +}
> > >
> > > +
> > >
> > > +/**
> > >
> > > +  Calculate SHA512 digest of SignerCert CommonName + ToplevelCert
> > > tbsCertificate
> > >
> > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > >
> > > +
> > >
> > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > >
> > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > >
> > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > >
> > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > >
> > > +  @param[out] Sha512Digest       Sha512 digest calculated.
> > >
> > > +
> > >
> > > +  @return EFI_ABORTED          Digest process failed.
> > >
> > > +  @return EFI_SUCCESS          SHA512 Digest is successfully calculated.
> > >
> > > +
> > >
> > > +**/
> > >
> > > +EFI_STATUS
> > >
> > > +CalculatePrivAuthVarSignChainSHA512Digest (
> > >
> > > +  IN     UINT8  *SignerCert,
> > >
> > > +  IN     UINTN  SignerCertSize,
> > >
> > > +  IN     UINT8  *TopLevelCert,
> > >
> > > +  IN     UINTN  TopLevelCertSize,
> > >
> > > +  OUT    UINT8  *Sha512Digest
> > >
> > > +  )
> > >
> > > +{
> > >
> > > +  UINT8       *TbsCert;
> > >
> > > +  UINTN       TbsCertSize;
> > >
> > > +  CHAR8       CertCommonName[128];
> > >
> > > +  UINTN       CertCommonNameSize;
> > >
> > > +  BOOLEAN     CryptoStatus;
> > >
> > > +  EFI_STATUS  Status;
> > >
> > > +
> > >
> > > +  CertCommonNameSize = sizeof (CertCommonName);
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // Get SignerCert CommonName
> > >
> > > +  //
> > >
> > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > CertCommonName, &CertCommonNameSize);
> > >
> > > +  if (EFI_ERROR (Status)) {
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with
> > > status %x\n", __FUNCTION__, Status));
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // Get TopLevelCert tbsCertificate
> > >
> > > +  //
> > >
> > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > &TbsCertSize)) {
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > + failed!\n",
> > > __FUNCTION__));
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > >
> > > +  //
> > >
> > > +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> > >
> > > +  CryptoStatus = Sha512Init (mHashCtx);
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  //
> > >
> > > +  // '\0' is forced in CertCommonName. No overflow issue
> > >
> > > +  //
> > >
> > > +  CryptoStatus = Sha512Update (
> > >
> > > +                   mHashCtx,
> > >
> > > +                   CertCommonName,
> > >
> > > +                   AsciiStrLen (CertCommonName)
> > >
> > > +                   );
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> > >
> > > +  if (!CryptoStatus) {
> > >
> > > +    return EFI_ABORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > > +  return EFI_SUCCESS;
> > >
> > > +}
> > >
> > > +
> > >
> > >  /**
> > >
> > >    Find matching signer's certificates for common authenticated
> > > variable
> > >
> > >    by corresponding VariableName and VendorGuid from "certdb" or
> > "certdbv".
> > >
> > > @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
> > >    @param[in]  SignerCertSize    Length of signer certificate.
> > >
> > >    @param[in]  TopLevelCert      Top-level certificate data.
> > >
> > >    @param[in]  TopLevelCertSize  Length of top-level certificate.
> > >
> > > +  @param[in]  DigestSize        Digest Size.
> > >
> > >
> > >
> > >    @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
> > >
> > >    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with
> > same
> > > VariableName
> > >
> > > @@ -1542,7 +1715,8 @@ InsertCertsToDb (
> > >    IN     UINT8     *SignerCert,
> > >
> > >    IN     UINTN     SignerCertSize,
> > >
> > >    IN     UINT8     *TopLevelCert,
> > >
> > > -  IN     UINTN     TopLevelCertSize
> > >
> > > +  IN     UINTN     TopLevelCertSize,
> > >
> > > +  IN     UINT32    DigestSize
> > >
> > >    )
> > >
> > >  {
> > >
> > >    EFI_STATUS         Status;
> > >
> > > @@ -1556,7 +1730,7 @@ InsertCertsToDb (
> > >    UINT32             CertDataSize;
> > >
> > >    AUTH_CERT_DB_DATA  *Ptr;
> > >
> > >    CHAR16             *DbName;
> > >
> > > -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> > >
> > > +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> > >
> > >
> > >
> > >    if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert
> > > == NULL)
> > > || (TopLevelCert == NULL)) {
> > >
> > >      return EFI_INVALID_PARAMETER;
> > >
> > > @@ -1618,20 +1792,41 @@ InsertCertsToDb (
> > >    // Construct new data content of variable "certdb" or "certdbv".
> > >
> > >    //
> > >
> > >    NameSize      = (UINT32)StrLen (VariableName);
> > >
> > > -  CertDataSize  = sizeof (Sha256Digest);
> > >
> > > +  CertDataSize  = DigestSize;
> > >
> > >    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize +
> > > NameSize * sizeof (CHAR16);
> > >
> > >    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> > >
> > >    if (NewCertDbSize > mMaxCertDbSize) {
> > >
> > >      return EFI_OUT_OF_RESOURCES;
> > >
> > >    }
> > >
> > >
> > >
> > > -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > >
> > > -             SignerCert,
> > >
> > > -             SignerCertSize,
> > >
> > > -             TopLevelCert,
> > >
> > > -             TopLevelCertSize,
> > >
> > > -             Sha256Digest
> > >
> > > -             );
> > >
> > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > >
> > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > >
> > > +               SignerCert,
> > >
> > > +               SignerCertSize,
> > >
> > > +               TopLevelCert,
> > >
> > > +               TopLevelCertSize,
> > >
> > > +               ShaDigest
> > >
> > > +               );
> > >
> > > +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> > >
> > > +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> > >
> > > +               SignerCert,
> > >
> > > +               SignerCertSize,
> > >
> > > +               TopLevelCert,
> > >
> > > +               TopLevelCertSize,
> > >
> > > +               ShaDigest
> > >
> > > +               );
> > >
> > > +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> > >
> > > +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> > >
> > > +               SignerCert,
> > >
> > > +               SignerCertSize,
> > >
> > > +               TopLevelCert,
> > >
> > > +               TopLevelCertSize,
> > >
> > > +               ShaDigest
> > >
> > > +               );
> > >
> > > +  } else {
> > >
> > > +    return EFI_UNSUPPORTED;
> > >
> > > +  }
> > >
> > > +
> > >
> > >    if (EFI_ERROR (Status)) {
> > >
> > >      return Status;
> > >
> > >    }
> > >
> > > @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> > >
> > >
> > >    CopyMem (
> > >
> > >      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof
> > > (CHAR16),
> > >
> > > -    Sha256Digest,
> > >
> > > +    ShaDigest,
> > >
> > >      CertDataSize
> > >
> > >      );
> > >
> > >
> > >
> > > @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
> > >    UINTN                          CertStackSize;
> > >
> > >    UINT8                          *CertsInCertDb;
> > >
> > >    UINT32                         CertsSizeinDb;
> > >
> > > -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> > >
> > > +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> > >
> > >    EFI_CERT_DATA                  *CertDataPtr;
> > >
> > >
> > >
> > >    //
> > >
> > > @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> > >
> > >
> > >    //
> > >
> > >    // SignedData.digestAlgorithms shall contain the digest algorithm
> > > used when preparing the
> > >
> > > -  // signature. Only a digest algorithm of SHA-256 is accepted.
> > >
> > > +  // signature. Only a digest algorithm of SHA-256, SHA-384 or
> > > + SHA-512 is
> > > accepted.
> > >
> > >    //
> > >
> > >    //    According to PKCS#7 Definition (https://www.rfc-
> > editor.org/rfc/rfc2315):
> > >
> > >    //        SignedData ::= SEQUENCE {
> > >
> > > @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
> > >               || (CompareMem (SigData + 13, &mSha256OidValue, sizeof
> > > (mSha256OidValue)) != 0)))
> > >
> > >         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> > >
> > >            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > TWO_BYTE_ENCODE)
> > >
> > > -             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > (mSha256OidValue)) != 0))))
> > >
> > > +             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > (mSha256OidValue)) != 0)))
> > >
> > > +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> > >
> > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > + TWO_BYTE_ENCODE)
> > >
> > > +             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof
> > > (mSha384OidValue)) != 0)))
> > >
> > > +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> > >
> > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > + TWO_BYTE_ENCODE)
> > >
> > > +             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof
> > > (mSha384OidValue)) != 0)))
> > >
> > > +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> > >
> > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > + TWO_BYTE_ENCODE)
> > >
> > > +             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof
> > > (mSha512OidValue)) != 0)))
> > >
> > > +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> > >
> > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > + TWO_BYTE_ENCODE)
> > >
> > > +             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof
> > > (mSha512OidValue)) != 0))))
> > >
> > >      {
> > >
> > >        return EFI_SECURITY_VIOLATION;
> > >
> > >      }
> > >
> > > @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
> > >                          ReadUnaligned32 ((UINT32
> > > *)&(CertDataPtr->CertDataLength)),
> > >
> > >                          TopLevelCert,
> > >
> > >                          TopLevelCertSize,
> > >
> > > -                        Sha256Digest
> > >
> > > +                        ShaDigest
> > >
> > > +                        );
> > >
> > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > + CertsInCertDb,
> > > CertsSizeinDb) != 0)) {
> > >
> > > +          goto Exit;
> > >
> > > +        }
> > >
> > > +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> > >
> > > +        //
> > >
> > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > tbsCertificate against data in CertDb
> > >
> > > +        //
> > >
> > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > >
> > > +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> > >
> > > +                        CertDataPtr->CertDataBuffer,
> > >
> > > +                        ReadUnaligned32 ((UINT32
> > > + *)&(CertDataPtr->CertDataLength)),
> > >
> > > +                        TopLevelCert,
> > >
> > > +                        TopLevelCertSize,
> > >
> > > +                        ShaDigest
> > >
> > > +                        );
> > >
> > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > + CertsInCertDb,
> > > CertsSizeinDb) != 0)) {
> > >
> > > +          goto Exit;
> > >
> > > +        }
> > >
> > > +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> > >
> > > +        //
> > >
> > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > tbsCertificate against data in CertDb
> > >
> > > +        //
> > >
> > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > >
> > > +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> > >
> > > +                        CertDataPtr->CertDataBuffer,
> > >
> > > +                        ReadUnaligned32 ((UINT32
> > > + *)&(CertDataPtr->CertDataLength)),
> > >
> > > +                        TopLevelCert,
> > >
> > > +                        TopLevelCertSize,
> > >
> > > +                        ShaDigest
> > >
> > >                          );
> > >
> > > -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest,
> > CertsInCertDb,
> > > CertsSizeinDb) != 0)) {
> > >
> > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > + CertsInCertDb,
> > > CertsSizeinDb) != 0)) {
> > >
> > >            goto Exit;
> > >
> > >          }
> > >
> > >        } else {
> > >
> > > @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
> > >                        CertDataPtr->CertDataBuffer,
> > >
> > >                        ReadUnaligned32 ((UINT32
> > > *)&(CertDataPtr->CertDataLength)),
> > >
> > >                        TopLevelCert,
> > >
> > > -                      TopLevelCertSize
> > >
> > > +                      TopLevelCertSize,
> > >
> > > +                      CertsSizeinDb
> > >
> > >                        );
> > >
> > >        if (EFI_ERROR (Status)) {
> > >
> > >          VerifyStatus = FALSE;
> > >
> > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > index dc61ae840c..552c0e99be 100644
> > > --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
> > >  UINT32  mPlatformMode;
> > >
> > >  UINT8   mVendorKeyState;
> > >
> > >
> > >
> > > -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID,
> > EFI_CERT_X509_GUID };
> > >
> > > +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID,
> > EFI_CERT_SHA512_GUID,
> > > EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID,
> > EFI_CERT_RSA4096_GUID,
> > > EFI_CERT_X509_GUID };
> > >
> > >
> > >
> > >  //
> > >
> > >  // Hash context pointer
> > >
> > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > >    //
> > >
> > >    // Initialize hash context.
> > >
> > >    //
> > >
> > > -  CtxSize  = Sha256GetContextSize ();
> > >
> > > +  CtxSize  = Sha512GetContextSize ();
> > >
> > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > >
> > >    if (mHashCtx == NULL) {
> > >
> > >      return EFI_OUT_OF_RESOURCES;
> > >
> > > diff --git
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > c
> > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > c
> > > index 66e2f5eaa3..f642aad64d 100644
> > > ---
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > c
> > > +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > +++ Lib.c
> > > @@ -1606,6 +1606,35 @@ Done:
> > >    return VerifyStatus;
> > >
> > >  }
> > >
> > >
> > >
> > > +/**
> > >
> > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > >
> > > +
> > >
> > > +  @retval  UINT32       Hash Alg
> > >
> > > +  **/
> > >
> > > +UINT32
> > >
> > > +GetDefaultHashAlg (
> > >
> > > +  VOID
> > >
> > > +  )
> > >
> > > +{
> > >
> > > +  UINT32  HashAlg;
> > >
> > > +
> > >
> > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > >
> > > +  case 1:
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > >
> > > +    HashAlg = HASHALG_SHA384;
> > >
> > > +    break;
> > >
> > > +  case 2:
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > >
> > > +    HashAlg = HASHALG_SHA512;
> > >
> > > +    break;
> > >
> > > +  default:
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > >
> > > +    HashAlg = HASHALG_SHA256;
> > >
> > > +    break;
> > >
> > > +  }
> > >
> > > +  return HashAlg;
> > >
> > > +}
> > >
> > > +
> > >
> > >  /**
> > >
> > >    Provide verification service for signed images, which include both
> > > signature validation
> > >
> > >    and platform policy control. For signature types, both UEFI
> > > WIN_CERTIFICATE_UEFI_GUID and
> > >
> > > @@ -1620,7 +1649,7 @@ Done:
> > >        in the security database "db", and no valid signature nor any
> > > hash value of the image may
> > >
> > >        be reflected in the security database "dbx".
> > >
> > >      Otherwise, the image is not signed,
> > >
> > > -      The SHA256 hash value of the image must match a record in the
> > security
> > > database "db", and
> > >
> > > +      The hash value of the image must match a record in the security
> > > + database
> > > "db", and
> > >
> > >        not be reflected in the security data base "dbx".
> > >
> > >
> > >
> > >    Caution: This function may receive untrusted input.
> > >
> > > @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
> > >    //
> > >
> > >    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> > >
> > >      //
> > >
> > > -    // This image is not signed. The SHA256 hash value of the image must
> > match
> > > a record in the security database "db",
> > >
> > > +    // This image is not signed. The hash value of the image must
> > > + match a record
> > > in the security database "db",
> > >
> > >      // and not be reflected in the security data base "dbx".
> > >
> > >      //
> > >
> > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > >
> > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > >
> > >        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash
> > > this image using %s.\n", mHashTypeStr));
> > >
> > >        goto Failed;
> > >
> > >      }
> > >
> > > diff --git
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > inf
> > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > inf
> > > index 1e1a639857..f1ef9236c2 100644
> > > ---
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > inf
> > > +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > +++ Lib.inf
> > > @@ -93,3 +93,4 @@
> > >    gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> > > ## SOMETIMES_CONSUMES
> > >
> > >
> > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolic
> > y
> > > ## SOMETIMES_CONSUMES
> > >
> > >    gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy
> > ##
> > > SOMETIMES_CONSUMES
> > >
> > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > ##
> > > CONSUMES
> > >
> > > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
> > > index 0382090f4e..4adc2a72ab 100644
> > > --- a/SecurityPkg/SecurityPkg.dec
> > > +++ b/SecurityPkg/SecurityPkg.dec
> > > @@ -521,6 +521,13 @@
> > >    # @Prompt Skip Hdd Password prompt.
> > >
> > >
> > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLE
> > AN|
> > > 0x00010021
> > >
> > >
> > >
> > > +  ## Indicates default hash algorithm in Secure Boot
> > >
> > > +  #   0 - Use SHA256
> > >
> > > +  #   1 - Use SHA384
> > >
> > > +  #   2 - Use SHA512
> > >
> > > +  # @Prompt Secure Boot default hash algorithm
> > >
> > > +
> > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > 00
> > > 0
> > > 10040
> > >
> > > +
> > >
> > >  [PcdsDynamic, PcdsDynamicEx]
> > >
> > >
> > >
> > >    ## This PCD indicates Hash mask for TPM 2.0. Bit definition
> > > strictly follows TCG Algorithm Registry.<BR><BR>
> > >
> > > diff --git
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > ig
> > > Dxe.inf
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > ig
> > > Dxe.inf
> > > index 1671d5be7c..4b0012d033 100644
> > > ---
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > ig
> > > Dxe.inf
> > > +++
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > ig
> > > Dxe.inf
> > > @@ -70,6 +70,14 @@
> > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > >    gEfiCertRsa2048Guid
> > >
> > >
> > >
> > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  gEfiCertRsa3072Guid
> > >
> > > +
> > >
> > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  gEfiCertRsa4096Guid
> > >
> > > +
> > >
> > >    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > >    gEfiCertX509Guid
> > >
> > > @@ -82,6 +90,14 @@
> > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > >    gEfiCertSha256Guid
> > >
> > >
> > >
> > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  gEfiCertSha384Guid
> > >
> > > +
> > >
> > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of
> > the
> > > signature.
> > >
> > > +  gEfiCertSha512Guid
> > >
> > > +
> > >
> > >    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> > >
> > >    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> > >
> > >    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> > >
> > > @@ -107,6 +123,9 @@
> > >    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES  ## GUID
> > #
> > > Unique ID for the type of the certificate.
> > >
> > >    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES  ## GUID
> > #
> > > Unique ID for the type of the certificate.
> > >
> > >
> > >
> > > +[Pcd]
> > >
> > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > ##
> > > CONSUMES
> > >
> > > +
> > >
> > >  [Protocols]
> > >
> > >    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> > >
> > >    gEfiDevicePathProtocolGuid                    ## PRODUCES
> > >
> > > diff --git
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.c
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.c
> > > index 4299a6b5e5..0ba029a394 100644
> > > ---
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.c
> > > +++
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.c
> > > @@ -560,7 +560,7 @@ ON_EXIT:
> > >
> > >
> > >  **/
> > >
> > >  EFI_STATUS
> > >
> > > -EnrollRsa2048ToKek (
> > >
> > > +EnrollRsaToKek (
> > >
> > >    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> > >
> > >    )
> > >
> > >  {
> > >
> > > @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> > >
> > >
> > >    ASSERT (KeyBlob != NULL);
> > >
> > >    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> > >
> > > -  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
> > >
> > > -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is
> > > supported.\n"));
> > >
> > > +  switch (KeyInfo->KeyLengthInBits / 8) {
> > >
> > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > >
> > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > >
> > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > >
> > > +    break;
> > >
> > > +  default :
> > >
> > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048,
> > > + RSA3072
> > > and RSA4096 are supported.\n"));
> > >
> > >      Status = EFI_UNSUPPORTED;
> > >
> > >      goto ON_EXIT;
> > >
> > >    }
> > >
> > > @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
> > >    //
> > >
> > >    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> > >
> > >                     + sizeof (EFI_SIGNATURE_DATA) - 1
> > >
> > > -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> > >
> > > +                   + KeyLenInBytes;
> > >
> > >
> > >
> > >    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool
> > > (KekSigListSize);
> > >
> > >    if (KekSigList == NULL) {
> > >
> > > @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> > >
> > >
> > >    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> > >
> > >                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> > >
> > > -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> > >
> > > +                                  + (UINT32) KeyLenInBytes;
> > >
> > >    KekSigList->SignatureHeaderSize = 0;
> > >
> > > -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > > WIN_CERT_UEFI_RSA2048_SIZE;
> > >
> > > -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > >
> > > +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > (UINT32)
> > > KeyLenInBytes;
> > >
> > > +  switch (KeyLenInBytes) {
> > >
> > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > >
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > >
> > > +    break;
> > >
> > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > >
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > >
> > > +    break;
> > >
> > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > >
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > >
> > > +    break;
> > >
> > > +    break;
> > >
> > > +  default :
> > >
> > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> > >
> > > +    Status = EFI_UNSUPPORTED;
> > >
> > > +    goto ON_EXIT;
> > >
> > > +  }
> > >
> > >
> > >
> > >    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof
> > > (EFI_SIGNATURE_LIST));
> > >
> > >    CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
> > >
> > >    CopyMem (
> > >
> > >      KEKSigData->SignatureData,
> > >
> > >      KeyBlob + sizeof (CPL_KEY_INFO),
> > >
> > > -    WIN_CERT_UEFI_RSA2048_SIZE
> > >
> > > +    KeyLenInBytes
> > >
> > >      );
> > >
> > >
> > >
> > >    //
> > >
> > > @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
> > >    if (IsDerEncodeCertificate (FilePostFix)) {
> > >
> > >      return EnrollX509ToKek (Private);
> > >
> > >    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> > >
> > > -    return EnrollRsa2048ToKek (Private);
> > >
> > > +    return EnrollRsaToKek (Private);
> > >
> > >    } else {
> > >
> > >      //
> > >
> > >      // File type is wrong, simply close it
> > >
> > > @@ -1847,7 +1867,7 @@ HashPeImage (
> > >    SectionHeader = NULL;
> > >
> > >    Status        = FALSE;
> > >
> > >
> > >
> > > -  if (HashAlg != HASHALG_SHA256) {
> > >
> > > +  if ((HashAlg >= HASHALG_MAX)) {
> > >
> > >      return FALSE;
> > >
> > >    }
> > >
> > >
> > >
> > > @@ -1856,8 +1876,25 @@ HashPeImage (
> > >    //
> > >
> > >    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> > >
> > >
> > >
> > > -  mImageDigestSize = SHA256_DIGEST_SIZE;
> > >
> > > -  mCertType        = gEfiCertSha256Guid;
> > >
> > > +   switch (HashAlg) {
> > >
> > > +    case HASHALG_SHA256:
> > >
> > > +      mImageDigestSize = SHA256_DIGEST_SIZE;
> > >
> > > +      mCertType        = gEfiCertSha256Guid;
> > >
> > > +      break;
> > >
> > > +
> > >
> > > +    case HASHALG_SHA384:
> > >
> > > +      mImageDigestSize = SHA384_DIGEST_SIZE;
> > >
> > > +      mCertType        = gEfiCertSha384Guid;
> > >
> > > +      break;
> > >
> > > +
> > >
> > > +    case HASHALG_SHA512:
> > >
> > > +      mImageDigestSize = SHA512_DIGEST_SIZE;
> > >
> > > +      mCertType        = gEfiCertSha512Guid;
> > >
> > > +      break;
> > >
> > > +
> > >
> > > +    default:
> > >
> > > +      return FALSE;
> > >
> > > +  }
> > >
> > >
> > >
> > >    CtxSize = mHash[HashAlg].GetContextSize ();
> > >
> > >
> > >
> > > @@ -2222,6 +2259,35 @@ ON_EXIT:
> > >    return Status;
> > >
> > >  }
> > >
> > >
> > >
> > > +/**
> > >
> > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > >
> > > +
> > >
> > > +  @retval  UINT32       Hash Alg
> > >
> > > +  **/
> > >
> > > +UINT32
> > >
> > > +GetDefaultHashAlg (
> > >
> > > +  VOID
> > >
> > > +  )
> > >
> > > +{
> > >
> > > +  UINT32  HashAlg;
> > >
> > > +
> > >
> > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > >
> > > +  case 1:
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > >
> > > +    HashAlg = HASHALG_SHA384;
> > >
> > > +    break;
> > >
> > > +  case 2:
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > >
> > > +    HashAlg = HASHALG_SHA512;
> > >
> > > +    break;
> > >
> > > +  default:
> > >
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > >
> > > +    HashAlg = HASHALG_SHA256;
> > >
> > > +    break;
> > >
> > > +  }
> > >
> > > +  return HashAlg;
> > >
> > > +}
> > >
> > > +
> > >
> > >  /**
> > >
> > >    Enroll a new signature of executable into Signature Database.
> > >
> > >
> > >
> > > @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
> > >    }
> > >
> > >
> > >
> > >    if (mSecDataDir->SizeOfCert == 0) {
> > >
> > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > >
> > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > >
> > >        Status =  EFI_SECURITY_VIOLATION;
> > >
> > >        goto ON_EXIT;
> > >
> > >      }
> > >
> > > @@ -2589,6 +2655,10 @@ UpdateDeletePage (
> > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > CertList->SignatureListSize)) {
> > >
> > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid))
> > > {
> > >
> > >        Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> > >
> > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > + &gEfiCertRsa3072Guid)) {
> > >
> > > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> > >
> > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > + &gEfiCertRsa4096Guid)) {
> > >
> > > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> > >
> > >      } else if (CompareGuid (&CertList->SignatureType,
> > > &gEfiCertX509Guid)) {
> > >
> > >        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> > >
> > >      } else if (CompareGuid (&CertList->SignatureType,
> > > &gEfiCertSha1Guid)) {
> > >
> > > @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
> > >    GuidIndex      = 0;
> > >
> > >    while ((KekDataSize > 0) && (KekDataSize >=
> > > CertList->SignatureListSize)) {
> > >
> > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > > ||
> > >
> > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > > + ||
> > >
> > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > > + ||
> > >
> > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
> > >
> > >      {
> > >
> > >        CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST)
> > > + CertList-
> > > >SignatureHeaderSize));
> > >
> > > @@ -2952,6 +3024,8 @@ DeleteSignature (
> > >    GuidIndex    = 0;
> > >
> > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > CertList->SignatureListSize)) {
> > >
> > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > > ||
> > >
> > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > > + ||
> > >
> > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > > + ||
> > >
> > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
> > >
> > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
> > >
> > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)
> > > ||
> > >
> > > @@ -3758,12 +3832,20 @@ LoadSignatureList (
> > >    while ((RemainingSize > 0) && (RemainingSize >=
> > > ListWalker->SignatureListSize)) {
> > >
> > >      if (CompareGuid (&ListWalker->SignatureType,
> > > &gEfiCertRsa2048Guid)) {
> > >
> > >        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > >
> > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > + &gEfiCertRsa3072Guid))
> > > {
> > >
> > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > >
> > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > + &gEfiCertRsa4096Guid))
> > > {
> > >
> > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > >
> > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > &gEfiCertX509Guid)) {
> > >
> > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> > >
> > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > &gEfiCertSha1Guid)) {
> > >
> > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> > >
> > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > &gEfiCertSha256Guid)) {
> > >
> > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > >
> > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > + &gEfiCertSha384Guid))
> > > {
> > >
> > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > >
> > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > + &gEfiCertSha512Guid))
> > > {
> > >
> > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > >
> > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > &gEfiCertX509Sha256Guid)) {
> > >
> > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > >
> > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > &gEfiCertX509Sha384Guid)) {
> > >
> > > @@ -4001,6 +4083,14 @@ FormatHelpInfo (
> > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > >
> > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > >
> > >      IsCert     = TRUE;
> > >
> > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > + &gEfiCertRsa3072Guid)) {
> > >
> > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > >
> > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > >
> > > +    IsCert     = TRUE;
> > >
> > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > + &gEfiCertRsa4096Guid)) {
> > >
> > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > >
> > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > >
> > > +    IsCert     = TRUE;
> > >
> > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > &gEfiCertX509Guid)) {
> > >
> > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> > >
> > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > >
> > > @@ -4011,6 +4101,12 @@ FormatHelpInfo (
> > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > &gEfiCertSha256Guid)) {
> > >
> > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > >
> > >      DataSize   = 32;
> > >
> > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > + &gEfiCertSha384Guid)) {
> > >
> > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > >
> > > +    DataSize   = 48;
> > >
> > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > + &gEfiCertSha512Guid)) {
> > >
> > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > >
> > > +    DataSize   = 64;
> > >
> > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > &gEfiCertX509Sha256Guid)) {
> > >
> > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > >
> > >      DataSize   = 32;
> > >
> > > diff --git
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.h
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.h
> > > index 37c66f1b95..ae50d929a7 100644
> > > ---
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.h
> > > +++
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igI
> > > mpl.h
> > > @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;  #define
> > > MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> > >
> > >
> > >
> > >  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> > >
> > > +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> > >
> > > +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> > >
> > >
> > >
> > >  //
> > >
> > >  // Support hash types
> > >
> > > diff --git
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igS
> > > trings.uni
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igS
> > > trings.uni
> > > index 0d01701de7..1b48acc800 100644
> > > ---
> > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igS
> > > trings.uni
> > > +++
> > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > f
> > > igS
> > > trings.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"
> > >
> > >  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File
> > Explorer"
> > >
> > >  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US
> > > "RSA2048_SHA256_GUID"
> > >
> > > +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US
> > > "RSA3072_SHA384_GUID"
> > >
> > > +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US
> > > "RSA4096_SHA512_GUID"
> > >
> > >  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US
> > "PKCS7_GUID"
> > >
> > >  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US
> > "SHA1_GUID"
> > >
> > >  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> > > "SHA256_GUID"
> > >
> > > @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > >  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US
> > > "X509_SHA512_GUID"
> > >
> > >
> > >
> > >  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> > > "RSA2048_SHA256"
> > >
> > > +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> > > "RSA3072_SHA384"
> > >
> > > +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> > > "RSA4096_SHA512"
> > >
> > >  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> > >
> > >  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> > >
> > >  #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
> > >
> > > +#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
> > >
> > > +#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
> > >
> > >  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> > > "X509_SHA256"
> > >
> > >  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> > > "X509_SHA384"
> > >
> > >  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> > > "X509_SHA512"
> > >
> > > --
> > > 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106565): https://edk2.groups.io/g/devel/message/106565
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Sheng Wei 9 months, 3 weeks ago
Hi Jiewen,
I raised the patch V3, And I also attached the patch file.
For 4, 
My solution is below.
When enroll the unsigned image, BIOS will select the most supported complex hash algorithm to get the hash.
When do the verification, BIOS will try all supported hash algorithm in "db" and "dbx".

For 5. 
The struct of CPL_KEY_INFO should be binded to .pbk file format. 
I cannot find the spec of .pbk file. I can not change the struct items.
Do you know where to find the spec of public key storing file (*.pbk) ?
Or is *.pbk file a legacy file format? We do not need to change this part and keep it for RSA 2048 only ?

Thank you
BR
Sheng Wei

> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: 2023年6月30日 19:57
> To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> <fiona.wang@intel.com>
> Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> For 4, I think we can enroll all supported algorithms, or the active algorithm. I
> don’t think the PCD is needed.
> 
> For 5, I suggest to change the data structure to include the algorithm ID.
> 
> Thank you
> Yao, Jiewen
> 
> 
> > -----Original Message-----
> > From: Sheng, W <w.sheng@intel.com>
> > Sent: Friday, June 30, 2023 3:52 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> <min.m.xu@intel.com>;
> > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> 384
> >
> > Hi Jiewen,
> > I raised the patch V2.
> > I do the fix for 1) , 2), 3).
> > But for 4) 5), I have below comments.
> >
> > 4) I am not sure why we need this PCD. Why cannot we support all of hash
> algo?
> >
> > +  ## Indicates default hash algorithm in Secure Boot
> > +  #   0 - Use SHA256
> > +  #   1 - Use SHA384
> > +  #   2 - Use SHA512
> > +  # @Prompt Secure Boot default hash algorithm
> > +
> > +
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> 00
> > + 010040
> >
> > PCD PcdSecureBootDefaultHashAlg is used for the only case of enroll an
> > unsigned image.
> > The original logic is BIOS will genrate SHA256 digest for this unsigned image
> and
> > save it.
> > The PCD is used to select the hash algorithm for this case.
> > So we have to use a PCD to select the algorithm manully.
> >
> >
> > 5) I don’t believe that you can use size to determine the algorithm. We
> need a
> > more robust way, such as algorithm ID.
> >
> > +  switch (KeyLenInBytes) {
> > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > +    break;
> > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > +    break;
> > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > +    break;
> > +    break;
> >
> > This code is used when enroll a RSA public key storing file (*.pbk).
> > Here is the header Struct of this file.
> > typedef struct _CPL_KEY_INFO {
> >   UINT32    KeyLengthInBits;        // Key Length In Bits
> >   UINT32    BlockSize;              // Operation Block Size in Bytes
> >   UINT32    CipherBlockSize;        // Output Cipher Block Size in Bytes
> >   UINT32    KeyType;                // Key Type
> >   UINT32    CipherMode;             // Cipher Mode for Symmetric Algorithm
> >   UINT32    Flags;                  // Additional Key Property Flags
> > } CPL_KEY_INFO;
> >
> Edk2/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBoot
> Con
> > figImpl.h
> > We can only get to know the RSA algorithm by KeyLengthInBits.
> > (RSA2048/RSA3072/RSA4096)
> >
> > Thank you.
> > BR
> > Sheng Wei
> >
> > > -----Original Message-----
> > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > Sent: 2023年6月22日 15:22
> > > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> <min.m.xu@intel.com>;
> > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> 384
> > >
> > > Thank you very much to contribute this patch. Here is my feedback.
> > >
> > > 1) I don’t believe that you cannot use digest size to determine the
> algorithm,
> > > because different hash algorithm may have same time. E.g. SHA256 and
> > > SHA3_256.
> > >
> > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > +               SignerCert,
> > > +               SignerCertSize,
> > > +               TopLevelCert,
> > > +               TopLevelCertSize,
> > > +               ShaDigest
> > > +               );
> > >
> > > 2) I don’t believe that you cannot assuming CtxSize of SHA512 is bigger
> than
> > > SHA256. I think we may need create context for each algo.
> > >
> > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > >    //
> > >    // Initialize hash context.
> > >    //
> > > -  CtxSize  = Sha256GetContextSize ();
> > > +  CtxSize  = Sha512GetContextSize ();
> > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > >    if (mHashCtx == NULL) {
> > >
> > > 3) I believe we should use 0 for SHA256 and ASSERT in default.
> > >
> > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {  case 1:
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > +    HashAlg = HASHALG_SHA384;
> > > +    break;
> > > +  case 2:
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > +    HashAlg = HASHALG_SHA512;
> > > +    break;
> > > +  default:
> > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > +    HashAlg = HASHALG_SHA256;
> > > +    break;
> > > +  }
> > >
> > > 4) I am not sure why we need this PCD. Why cannot we support all of
> hash
> > > algo?
> > >
> > > +  ## Indicates default hash algorithm in Secure Boot
> > > +  #   0 - Use SHA256
> > > +  #   1 - Use SHA384
> > > +  #   2 - Use SHA512
> > > +  # @Prompt Secure Boot default hash algorithm
> > > +
> > > +
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > 00
> > > + 010040
> > >
> > > 5) I don’t believe that you can use size to determine the algorithm. We
> need
> > > a more robust way, such as algorithm ID.
> > >
> > > +  switch (KeyLenInBytes) {
> > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > +    break;
> > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > +    break;
> > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > +    break;
> > > +    break;
> > >
> > > Thank you
> > > Yao, Jiewen
> > >
> > > > -----Original Message-----
> > > > From: Sheng, W <w.sheng@intel.com>
> > > > Sent: Thursday, May 25, 2023 1:23 PM
> > > > To: devel@edk2.groups.io
> > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > > <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>; Chen,
> Zeyi
> > > > <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > > Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> 384
> > > >
> > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> > > >
> > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > > Cc: Min Xu <min.m.xu@intel.com>
> > > > Cc: Zeyi Chen <zeyi.chen@intel.com>
> > > > Cc: Fiona Wang <fiona.wang@intel.com>
> > > > Signed-off-by: Sheng Wei <w.sheng@intel.com>
> > > > ---
> > > >  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
> > > >  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
> > > >  MdePkg/MdePkg.dec                             |   2 +
> > > >  .../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++-
> -
> > > >  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
> > > >  .../DxeImageVerificationLib.c                 |  35 ++-
> > > >  .../DxeImageVerificationLib.inf               |   1 +
> > > >  SecurityPkg/SecurityPkg.dec                   |   7 +
> > > >  .../SecureBootConfigDxe.inf                   |  19 ++
> > > >  .../SecureBootConfigImpl.c                    | 122 +++++++-
> > > >  .../SecureBootConfigImpl.h                    |   2 +
> > > >  .../SecureBootConfigStrings.uni               |   6 +
> > > >  12 files changed, 463 insertions(+), 36 deletions(-)
> > > >
> > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> > > > b/CryptoPkg/Library/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.
> > > >
> > > >    //
> > > >
> > > >    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest
> (EVP_sha1
> > > > ()) == 0)
> > > > ||
> > > >
> > > > -      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias
> > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > >
> > > > +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest
> > > > + (EVP_sha384 ())
> > > > == 0) ||
> > > >
> > > > +      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias
> > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > >
> > > >    {
> > > >
> > > >      return FALSE;
> > > >
> > > >    }
> > > >
> > > > diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> > > > b/MdePkg/Include/Guid/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} \
> > > >
> > > >    }
> > > >
> > > >
> > > >
> > > > +///
> > > >
> > > > +/// This identifies a signature containing an RSA-3072 key. The key
> > > > +(only the
> > > > modulus
> > > >
> > > > +/// since the public key exponent is known to be 0x10001) shall be
> > > > +stored in big-
> > > > endian
> > > >
> > > > +/// order.
> > > >
> > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > +shall always
> > > > be 16 (size
> > > >
> > > > +/// of SignatureOwner component) + 384 bytes.
> > > >
> > > > +///
> > > >
> > > > +#define EFI_CERT_RSA3072_GUID \
> > > >
> > > > +  { \
> > > >
> > > > +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89,
> > > > + 0xee,
> > > > 0x92 } \
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +///
> > > >
> > > > +/// This identifies a signature containing an RSA-4096 key. The key
> > > > +(only the
> > > > modulus
> > > >
> > > > +/// since the public key exponent is known to be 0x10001) shall be
> > > > +stored in big-
> > > > endian
> > > >
> > > > +/// order.
> > > >
> > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > +shall always
> > > > be 16 (size
> > > >
> > > > +/// of SignatureOwner component) + 512 bytes.
> > > >
> > > > +///
> > > >
> > > > +#define EFI_CERT_RSA4096_GUID \
> > > >
> > > > +  { \
> > > >
> > > > +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00,
> > > > + 0x98,
> > > > 0x2c } \
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > >  ///
> > > >
> > > >  /// This identifies a signature containing a RSA-2048 signature of a
> > > > SHA-256 hash.  The
> > > >
> > > >  /// SignatureHeader size shall always be 0. The SignatureSize shall
> > > > always be 16 (size of
> > > >
> > > > @@ -330,6 +354,8 @@ typedef struct {
> > > >  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> > > >
> > > >  extern EFI_GUID  gEfiCertSha256Guid;
> > > >
> > > >  extern EFI_GUID  gEfiCertRsa2048Guid;
> > > >
> > > > +extern EFI_GUID  gEfiCertRsa3072Guid;
> > > >
> > > > +extern EFI_GUID  gEfiCertRsa4096Guid;
> > > >
> > > >  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> > > >
> > > >  extern EFI_GUID  gEfiCertSha1Guid;
> > > >
> > > >  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> > > >
> > > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > > > 80b6559053..782f6d184d 100644
> > > > --- a/MdePkg/MdePkg.dec
> > > > +++ b/MdePkg/MdePkg.dec
> > > > @@ -562,6 +562,8 @@
> > > >    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596,
> > > > {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> > > >
> > > >    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9,
> > > 0x41,
> > > > 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> > > >
> > > >    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14,
> > > 0xed,
> > > > 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> > > >
> > > > +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad,
> 0x46,
> > > > 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> > > >
> > > > +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85,
> 0x73,
> > > > 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> > > >
> > > >    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad,
> > > 0x8d,
> > > > 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> > > >
> > > >    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87,
> > 0xbe,
> > > > 0x1, 0x49, 0x66, 0x31, 0xbd }}
> > > >
> > > >    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3,
> 0x28,
> > > > 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> > > >
> > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > index 452ed491ea..288e44a359 100644
> > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > #include <Protocol/VariablePolicy.h>
> > > >
> > > >  #include <Library/VariablePolicyLib.h>
> > > >
> > > >
> > > >
> > > > +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> > > >
> > > > +
> > > >
> > > >  //
> > > >
> > > >  // Public Exponent of RSA Key.
> > > >
> > > >  //
> > > >
> > > >  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> > > >
> > > >
> > > >
> > > >  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > 0x03, 0x04, 0x02, 0x01 };
> > > >
> > > > +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > +0x03,
> > > > 0x04, 0x02, 0x02 };
> > > >
> > > > +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > +0x03,
> > > > 0x04, 0x02, 0x03 };
> > > >
> > > >
> > > >
> > > >  //
> > > >
> > > >  // Requirement for different signature type which have been defined
> > > > in UEFI spec.
> > > >
> > > > @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
> > > >    // {SigType,                       SigHeaderSize,   SigDataSize  }
> > > >
> > > >    { EFI_CERT_SHA256_GUID,         0, 32            },
> > > >
> > > >    { EFI_CERT_RSA2048_GUID,        0, 256           },
> > > >
> > > > +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> > > >
> > > > +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> > > >
> > > >    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> > > >
> > > >    { EFI_CERT_SHA1_GUID,           0, 20            },
> > > >
> > > >    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> > > >
> > > > @@ -1172,6 +1178,172 @@
> CalculatePrivAuthVarSignChainSHA256Digest (
> > > >    return EFI_SUCCESS;
> > > >
> > > >  }
> > > >
> > > >
> > > >
> > > > +/**
> > > >
> > > > +  Calculate SHA38 digest of SignerCert CommonName + ToplevelCert
> > > > tbsCertificate
> > > >
> > > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > > >
> > > > +
> > > >
> > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > >
> > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > >
> > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > >
> > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > >
> > > > +  @param[out] Sha384Digest       Sha384 digest calculated.
> > > >
> > > > +
> > > >
> > > > +  @return EFI_ABORTED          Digest process failed.
> > > >
> > > > +  @return EFI_SUCCESS          SHA384 Digest is successfully calculated.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +EFI_STATUS
> > > >
> > > > +CalculatePrivAuthVarSignChainSHA384Digest (
> > > >
> > > > +  IN     UINT8  *SignerCert,
> > > >
> > > > +  IN     UINTN  SignerCertSize,
> > > >
> > > > +  IN     UINT8  *TopLevelCert,
> > > >
> > > > +  IN     UINTN  TopLevelCertSize,
> > > >
> > > > +  OUT    UINT8  *Sha384Digest
> > > >
> > > > +  )
> > > >
> > > > +{
> > > >
> > > > +  UINT8       *TbsCert;
> > > >
> > > > +  UINTN       TbsCertSize;
> > > >
> > > > +  CHAR8       CertCommonName[128];
> > > >
> > > > +  UINTN       CertCommonNameSize;
> > > >
> > > > +  BOOLEAN     CryptoStatus;
> > > >
> > > > +  EFI_STATUS  Status;
> > > >
> > > > +
> > > >
> > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // Get SignerCert CommonName
> > > >
> > > > +  //
> > > >
> > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > CertCommonName, &CertCommonNameSize);
> > > >
> > > > +  if (EFI_ERROR (Status)) {
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed
> with
> > > > status %x\n", __FUNCTION__, Status));
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // Get TopLevelCert tbsCertificate
> > > >
> > > > +  //
> > > >
> > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > &TbsCertSize)) {
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > + failed!\n",
> > > > __FUNCTION__));
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > >
> > > > +  //
> > > >
> > > > +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> > > >
> > > > +  CryptoStatus = Sha384Init (mHashCtx);
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > >
> > > > +  //
> > > >
> > > > +  CryptoStatus = Sha384Update (
> > > >
> > > > +                   mHashCtx,
> > > >
> > > > +                   CertCommonName,
> > > >
> > > > +                   AsciiStrLen (CertCommonName)
> > > >
> > > > +                   );
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  return EFI_SUCCESS;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > > +/**
> > > >
> > > > +  Calculate SHA512 digest of SignerCert CommonName + ToplevelCert
> > > > tbsCertificate
> > > >
> > > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > > >
> > > > +
> > > >
> > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > >
> > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > >
> > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > >
> > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > >
> > > > +  @param[out] Sha512Digest       Sha512 digest calculated.
> > > >
> > > > +
> > > >
> > > > +  @return EFI_ABORTED          Digest process failed.
> > > >
> > > > +  @return EFI_SUCCESS          SHA512 Digest is successfully calculated.
> > > >
> > > > +
> > > >
> > > > +**/
> > > >
> > > > +EFI_STATUS
> > > >
> > > > +CalculatePrivAuthVarSignChainSHA512Digest (
> > > >
> > > > +  IN     UINT8  *SignerCert,
> > > >
> > > > +  IN     UINTN  SignerCertSize,
> > > >
> > > > +  IN     UINT8  *TopLevelCert,
> > > >
> > > > +  IN     UINTN  TopLevelCertSize,
> > > >
> > > > +  OUT    UINT8  *Sha512Digest
> > > >
> > > > +  )
> > > >
> > > > +{
> > > >
> > > > +  UINT8       *TbsCert;
> > > >
> > > > +  UINTN       TbsCertSize;
> > > >
> > > > +  CHAR8       CertCommonName[128];
> > > >
> > > > +  UINTN       CertCommonNameSize;
> > > >
> > > > +  BOOLEAN     CryptoStatus;
> > > >
> > > > +  EFI_STATUS  Status;
> > > >
> > > > +
> > > >
> > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // Get SignerCert CommonName
> > > >
> > > > +  //
> > > >
> > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > CertCommonName, &CertCommonNameSize);
> > > >
> > > > +  if (EFI_ERROR (Status)) {
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed
> with
> > > > status %x\n", __FUNCTION__, Status));
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // Get TopLevelCert tbsCertificate
> > > >
> > > > +  //
> > > >
> > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > &TbsCertSize)) {
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > + failed!\n",
> > > > __FUNCTION__));
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > >
> > > > +  //
> > > >
> > > > +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> > > >
> > > > +  CryptoStatus = Sha512Init (mHashCtx);
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  //
> > > >
> > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > >
> > > > +  //
> > > >
> > > > +  CryptoStatus = Sha512Update (
> > > >
> > > > +                   mHashCtx,
> > > >
> > > > +                   CertCommonName,
> > > >
> > > > +                   AsciiStrLen (CertCommonName)
> > > >
> > > > +                   );
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> > > >
> > > > +  if (!CryptoStatus) {
> > > >
> > > > +    return EFI_ABORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > > +  return EFI_SUCCESS;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > >  /**
> > > >
> > > >    Find matching signer's certificates for common authenticated
> > > > variable
> > > >
> > > >    by corresponding VariableName and VendorGuid from "certdb" or
> > > "certdbv".
> > > >
> > > > @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
> > > >    @param[in]  SignerCertSize    Length of signer certificate.
> > > >
> > > >    @param[in]  TopLevelCert      Top-level certificate data.
> > > >
> > > >    @param[in]  TopLevelCertSize  Length of top-level certificate.
> > > >
> > > > +  @param[in]  DigestSize        Digest Size.
> > > >
> > > >
> > > >
> > > >    @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
> > > >
> > > >    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with
> > > same
> > > > VariableName
> > > >
> > > > @@ -1542,7 +1715,8 @@ InsertCertsToDb (
> > > >    IN     UINT8     *SignerCert,
> > > >
> > > >    IN     UINTN     SignerCertSize,
> > > >
> > > >    IN     UINT8     *TopLevelCert,
> > > >
> > > > -  IN     UINTN     TopLevelCertSize
> > > >
> > > > +  IN     UINTN     TopLevelCertSize,
> > > >
> > > > +  IN     UINT32    DigestSize
> > > >
> > > >    )
> > > >
> > > >  {
> > > >
> > > >    EFI_STATUS         Status;
> > > >
> > > > @@ -1556,7 +1730,7 @@ InsertCertsToDb (
> > > >    UINT32             CertDataSize;
> > > >
> > > >    AUTH_CERT_DB_DATA  *Ptr;
> > > >
> > > >    CHAR16             *DbName;
> > > >
> > > > -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> > > >
> > > > +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > >
> > > >
> > > >
> > > >    if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert
> > > > == NULL)
> > > > || (TopLevelCert == NULL)) {
> > > >
> > > >      return EFI_INVALID_PARAMETER;
> > > >
> > > > @@ -1618,20 +1792,41 @@ InsertCertsToDb (
> > > >    // Construct new data content of variable "certdb" or "certdbv".
> > > >
> > > >    //
> > > >
> > > >    NameSize      = (UINT32)StrLen (VariableName);
> > > >
> > > > -  CertDataSize  = sizeof (Sha256Digest);
> > > >
> > > > +  CertDataSize  = DigestSize;
> > > >
> > > >    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) +
> (UINT32)CertDataSize +
> > > > NameSize * sizeof (CHAR16);
> > > >
> > > >    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> > > >
> > > >    if (NewCertDbSize > mMaxCertDbSize) {
> > > >
> > > >      return EFI_OUT_OF_RESOURCES;
> > > >
> > > >    }
> > > >
> > > >
> > > >
> > > > -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > >
> > > > -             SignerCert,
> > > >
> > > > -             SignerCertSize,
> > > >
> > > > -             TopLevelCert,
> > > >
> > > > -             TopLevelCertSize,
> > > >
> > > > -             Sha256Digest
> > > >
> > > > -             );
> > > >
> > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > >
> > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > >
> > > > +               SignerCert,
> > > >
> > > > +               SignerCertSize,
> > > >
> > > > +               TopLevelCert,
> > > >
> > > > +               TopLevelCertSize,
> > > >
> > > > +               ShaDigest
> > > >
> > > > +               );
> > > >
> > > > +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> > > >
> > > > +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> > > >
> > > > +               SignerCert,
> > > >
> > > > +               SignerCertSize,
> > > >
> > > > +               TopLevelCert,
> > > >
> > > > +               TopLevelCertSize,
> > > >
> > > > +               ShaDigest
> > > >
> > > > +               );
> > > >
> > > > +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> > > >
> > > > +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> > > >
> > > > +               SignerCert,
> > > >
> > > > +               SignerCertSize,
> > > >
> > > > +               TopLevelCert,
> > > >
> > > > +               TopLevelCertSize,
> > > >
> > > > +               ShaDigest
> > > >
> > > > +               );
> > > >
> > > > +  } else {
> > > >
> > > > +    return EFI_UNSUPPORTED;
> > > >
> > > > +  }
> > > >
> > > > +
> > > >
> > > >    if (EFI_ERROR (Status)) {
> > > >
> > > >      return Status;
> > > >
> > > >    }
> > > >
> > > > @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> > > >
> > > >
> > > >    CopyMem (
> > > >
> > > >      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof
> > > > (CHAR16),
> > > >
> > > > -    Sha256Digest,
> > > >
> > > > +    ShaDigest,
> > > >
> > > >      CertDataSize
> > > >
> > > >      );
> > > >
> > > >
> > > >
> > > > @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
> > > >    UINTN                          CertStackSize;
> > > >
> > > >    UINT8                          *CertsInCertDb;
> > > >
> > > >    UINT32                         CertsSizeinDb;
> > > >
> > > > -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> > > >
> > > > +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > >
> > > >    EFI_CERT_DATA                  *CertDataPtr;
> > > >
> > > >
> > > >
> > > >    //
> > > >
> > > > @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> > > >
> > > >
> > > >    //
> > > >
> > > >    // SignedData.digestAlgorithms shall contain the digest algorithm
> > > > used when preparing the
> > > >
> > > > -  // signature. Only a digest algorithm of SHA-256 is accepted.
> > > >
> > > > +  // signature. Only a digest algorithm of SHA-256, SHA-384 or
> > > > + SHA-512 is
> > > > accepted.
> > > >
> > > >    //
> > > >
> > > >    //    According to PKCS#7 Definition (https://www.rfc-
> > > editor.org/rfc/rfc2315):
> > > >
> > > >    //        SignedData ::= SEQUENCE {
> > > >
> > > > @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
> > > >               || (CompareMem (SigData + 13, &mSha256OidValue, sizeof
> > > > (mSha256OidValue)) != 0)))
> > > >
> > > >         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> > > >
> > > >            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > TWO_BYTE_ENCODE)
> > > >
> > > > -             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > > (mSha256OidValue)) != 0))))
> > > >
> > > > +             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > > (mSha256OidValue)) != 0)))
> > > >
> > > > +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> > > >
> > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > + TWO_BYTE_ENCODE)
> > > >
> > > > +             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof
> > > > (mSha384OidValue)) != 0)))
> > > >
> > > > +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> > > >
> > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > + TWO_BYTE_ENCODE)
> > > >
> > > > +             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof
> > > > (mSha384OidValue)) != 0)))
> > > >
> > > > +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> > > >
> > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > + TWO_BYTE_ENCODE)
> > > >
> > > > +             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof
> > > > (mSha512OidValue)) != 0)))
> > > >
> > > > +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> > > >
> > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > + TWO_BYTE_ENCODE)
> > > >
> > > > +             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof
> > > > (mSha512OidValue)) != 0))))
> > > >
> > > >      {
> > > >
> > > >        return EFI_SECURITY_VIOLATION;
> > > >
> > > >      }
> > > >
> > > > @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
> > > >                          ReadUnaligned32 ((UINT32
> > > > *)&(CertDataPtr->CertDataLength)),
> > > >
> > > >                          TopLevelCert,
> > > >
> > > >                          TopLevelCertSize,
> > > >
> > > > -                        Sha256Digest
> > > >
> > > > +                        ShaDigest
> > > >
> > > > +                        );
> > > >
> > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > + CertsInCertDb,
> > > > CertsSizeinDb) != 0)) {
> > > >
> > > > +          goto Exit;
> > > >
> > > > +        }
> > > >
> > > > +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> > > >
> > > > +        //
> > > >
> > > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > > tbsCertificate against data in CertDb
> > > >
> > > > +        //
> > > >
> > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > >
> > > > +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> > > >
> > > > +                        CertDataPtr->CertDataBuffer,
> > > >
> > > > +                        ReadUnaligned32 ((UINT32
> > > > + *)&(CertDataPtr->CertDataLength)),
> > > >
> > > > +                        TopLevelCert,
> > > >
> > > > +                        TopLevelCertSize,
> > > >
> > > > +                        ShaDigest
> > > >
> > > > +                        );
> > > >
> > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > + CertsInCertDb,
> > > > CertsSizeinDb) != 0)) {
> > > >
> > > > +          goto Exit;
> > > >
> > > > +        }
> > > >
> > > > +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> > > >
> > > > +        //
> > > >
> > > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > > tbsCertificate against data in CertDb
> > > >
> > > > +        //
> > > >
> > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > >
> > > > +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> > > >
> > > > +                        CertDataPtr->CertDataBuffer,
> > > >
> > > > +                        ReadUnaligned32 ((UINT32
> > > > + *)&(CertDataPtr->CertDataLength)),
> > > >
> > > > +                        TopLevelCert,
> > > >
> > > > +                        TopLevelCertSize,
> > > >
> > > > +                        ShaDigest
> > > >
> > > >                          );
> > > >
> > > > -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest,
> > > CertsInCertDb,
> > > > CertsSizeinDb) != 0)) {
> > > >
> > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > + CertsInCertDb,
> > > > CertsSizeinDb) != 0)) {
> > > >
> > > >            goto Exit;
> > > >
> > > >          }
> > > >
> > > >        } else {
> > > >
> > > > @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
> > > >                        CertDataPtr->CertDataBuffer,
> > > >
> > > >                        ReadUnaligned32 ((UINT32
> > > > *)&(CertDataPtr->CertDataLength)),
> > > >
> > > >                        TopLevelCert,
> > > >
> > > > -                      TopLevelCertSize
> > > >
> > > > +                      TopLevelCertSize,
> > > >
> > > > +                      CertsSizeinDb
> > > >
> > > >                        );
> > > >
> > > >        if (EFI_ERROR (Status)) {
> > > >
> > > >          VerifyStatus = FALSE;
> > > >
> > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > index dc61ae840c..552c0e99be 100644
> > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
> > > >  UINT32  mPlatformMode;
> > > >
> > > >  UINT8   mVendorKeyState;
> > > >
> > > >
> > > >
> > > > -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID,
> > > EFI_CERT_X509_GUID };
> > > >
> > > > +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID,
> > > EFI_CERT_SHA512_GUID,
> > > > EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID,
> > > EFI_CERT_RSA4096_GUID,
> > > > EFI_CERT_X509_GUID };
> > > >
> > > >
> > > >
> > > >  //
> > > >
> > > >  // Hash context pointer
> > > >
> > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > >    //
> > > >
> > > >    // Initialize hash context.
> > > >
> > > >    //
> > > >
> > > > -  CtxSize  = Sha256GetContextSize ();
> > > >
> > > > +  CtxSize  = Sha512GetContextSize ();
> > > >
> > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > >
> > > >    if (mHashCtx == NULL) {
> > > >
> > > >      return EFI_OUT_OF_RESOURCES;
> > > >
> > > > diff --git
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > c
> > > >
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > c
> > > > index 66e2f5eaa3..f642aad64d 100644
> > > > ---
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > c
> > > > +++
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > +++ Lib.c
> > > > @@ -1606,6 +1606,35 @@ Done:
> > > >    return VerifyStatus;
> > > >
> > > >  }
> > > >
> > > >
> > > >
> > > > +/**
> > > >
> > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > >
> > > > +
> > > >
> > > > +  @retval  UINT32       Hash Alg
> > > >
> > > > +  **/
> > > >
> > > > +UINT32
> > > >
> > > > +GetDefaultHashAlg (
> > > >
> > > > +  VOID
> > > >
> > > > +  )
> > > >
> > > > +{
> > > >
> > > > +  UINT32  HashAlg;
> > > >
> > > > +
> > > >
> > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > >
> > > > +  case 1:
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > >
> > > > +    HashAlg = HASHALG_SHA384;
> > > >
> > > > +    break;
> > > >
> > > > +  case 2:
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > >
> > > > +    HashAlg = HASHALG_SHA512;
> > > >
> > > > +    break;
> > > >
> > > > +  default:
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > >
> > > > +    HashAlg = HASHALG_SHA256;
> > > >
> > > > +    break;
> > > >
> > > > +  }
> > > >
> > > > +  return HashAlg;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > >  /**
> > > >
> > > >    Provide verification service for signed images, which include both
> > > > signature validation
> > > >
> > > >    and platform policy control. For signature types, both UEFI
> > > > WIN_CERTIFICATE_UEFI_GUID and
> > > >
> > > > @@ -1620,7 +1649,7 @@ Done:
> > > >        in the security database "db", and no valid signature nor any
> > > > hash value of the image may
> > > >
> > > >        be reflected in the security database "dbx".
> > > >
> > > >      Otherwise, the image is not signed,
> > > >
> > > > -      The SHA256 hash value of the image must match a record in the
> > > security
> > > > database "db", and
> > > >
> > > > +      The hash value of the image must match a record in the security
> > > > + database
> > > > "db", and
> > > >
> > > >        not be reflected in the security data base "dbx".
> > > >
> > > >
> > > >
> > > >    Caution: This function may receive untrusted input.
> > > >
> > > > @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
> > > >    //
> > > >
> > > >    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> > > >
> > > >      //
> > > >
> > > > -    // This image is not signed. The SHA256 hash value of the image must
> > > match
> > > > a record in the security database "db",
> > > >
> > > > +    // This image is not signed. The hash value of the image must
> > > > + match a record
> > > > in the security database "db",
> > > >
> > > >      // and not be reflected in the security data base "dbx".
> > > >
> > > >      //
> > > >
> > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > >
> > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > >
> > > >        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash
> > > > this image using %s.\n", mHashTypeStr));
> > > >
> > > >        goto Failed;
> > > >
> > > >      }
> > > >
> > > > diff --git
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > inf
> > > >
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > inf
> > > > index 1e1a639857..f1ef9236c2 100644
> > > > ---
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > inf
> > > > +++
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > +++ Lib.inf
> > > > @@ -93,3 +93,4 @@
> > > >
> gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> > > > ## SOMETIMES_CONSUMES
> > > >
> > > >
> > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolic
> > > y
> > > > ## SOMETIMES_CONSUMES
> > > >
> > > >
> gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy
> > > ##
> > > > SOMETIMES_CONSUMES
> > > >
> > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > ##
> > > > CONSUMES
> > > >
> > > > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
> > > > index 0382090f4e..4adc2a72ab 100644
> > > > --- a/SecurityPkg/SecurityPkg.dec
> > > > +++ b/SecurityPkg/SecurityPkg.dec
> > > > @@ -521,6 +521,13 @@
> > > >    # @Prompt Skip Hdd Password prompt.
> > > >
> > > >
> > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLE
> > > AN|
> > > > 0x00010021
> > > >
> > > >
> > > >
> > > > +  ## Indicates default hash algorithm in Secure Boot
> > > >
> > > > +  #   0 - Use SHA256
> > > >
> > > > +  #   1 - Use SHA384
> > > >
> > > > +  #   2 - Use SHA512
> > > >
> > > > +  # @Prompt Secure Boot default hash algorithm
> > > >
> > > > +
> > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > 00
> > > > 0
> > > > 10040
> > > >
> > > > +
> > > >
> > > >  [PcdsDynamic, PcdsDynamicEx]
> > > >
> > > >
> > > >
> > > >    ## This PCD indicates Hash mask for TPM 2.0. Bit definition
> > > > strictly follows TCG Algorithm Registry.<BR><BR>
> > > >
> > > > diff --git
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > ig
> > > > Dxe.inf
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > ig
> > > > Dxe.inf
> > > > index 1671d5be7c..4b0012d033 100644
> > > > ---
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > ig
> > > > Dxe.inf
> > > > +++
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > ig
> > > > Dxe.inf
> > > > @@ -70,6 +70,14 @@
> > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > >    gEfiCertRsa2048Guid
> > > >
> > > >
> > > >
> > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> type of
> > > the
> > > > signature.
> > > >
> > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > > +  gEfiCertRsa3072Guid
> > > >
> > > > +
> > > >
> > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> type of
> > > the
> > > > signature.
> > > >
> > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > > +  gEfiCertRsa4096Guid
> > > >
> > > > +
> > > >
> > > >    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > >    gEfiCertX509Guid
> > > >
> > > > @@ -82,6 +90,14 @@
> > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > >    gEfiCertSha256Guid
> > > >
> > > >
> > > >
> > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> type of
> > > the
> > > > signature.
> > > >
> > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > > +  gEfiCertSha384Guid
> > > >
> > > > +
> > > >
> > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> type of
> > > the
> > > > signature.
> > > >
> > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> of
> > > the
> > > > signature.
> > > >
> > > > +  gEfiCertSha512Guid
> > > >
> > > > +
> > > >
> > > >    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> > > >
> > > >    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> > > >
> > > >    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> > > >
> > > > @@ -107,6 +123,9 @@
> > > >    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES  ##
> GUID
> > > #
> > > > Unique ID for the type of the certificate.
> > > >
> > > >    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES  ##
> GUID
> > > #
> > > > Unique ID for the type of the certificate.
> > > >
> > > >
> > > >
> > > > +[Pcd]
> > > >
> > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > ##
> > > > CONSUMES
> > > >
> > > > +
> > > >
> > > >  [Protocols]
> > > >
> > > >    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> > > >
> > > >    gEfiDevicePathProtocolGuid                    ## PRODUCES
> > > >
> > > > diff --git
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.c
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.c
> > > > index 4299a6b5e5..0ba029a394 100644
> > > > ---
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.c
> > > > +++
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.c
> > > > @@ -560,7 +560,7 @@ ON_EXIT:
> > > >
> > > >
> > > >  **/
> > > >
> > > >  EFI_STATUS
> > > >
> > > > -EnrollRsa2048ToKek (
> > > >
> > > > +EnrollRsaToKek (
> > > >
> > > >    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> > > >
> > > >    )
> > > >
> > > >  {
> > > >
> > > > @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> > > >
> > > >
> > > >    ASSERT (KeyBlob != NULL);
> > > >
> > > >    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> > > >
> > > > -  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
> > > >
> > > > -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is
> > > > supported.\n"));
> > > >
> > > > +  switch (KeyInfo->KeyLengthInBits / 8) {
> > > >
> > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > >
> > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > >
> > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > >
> > > > +    break;
> > > >
> > > > +  default :
> > > >
> > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048,
> > > > + RSA3072
> > > > and RSA4096 are supported.\n"));
> > > >
> > > >      Status = EFI_UNSUPPORTED;
> > > >
> > > >      goto ON_EXIT;
> > > >
> > > >    }
> > > >
> > > > @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
> > > >    //
> > > >
> > > >    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> > > >
> > > >                     + sizeof (EFI_SIGNATURE_DATA) - 1
> > > >
> > > > -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> > > >
> > > > +                   + KeyLenInBytes;
> > > >
> > > >
> > > >
> > > >    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool
> > > > (KekSigListSize);
> > > >
> > > >    if (KekSigList == NULL) {
> > > >
> > > > @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> > > >
> > > >
> > > >    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> > > >
> > > >                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> > > >
> > > > -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> > > >
> > > > +                                  + (UINT32) KeyLenInBytes;
> > > >
> > > >    KekSigList->SignatureHeaderSize = 0;
> > > >
> > > > -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > > > WIN_CERT_UEFI_RSA2048_SIZE;
> > > >
> > > > -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > >
> > > > +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > > (UINT32)
> > > > KeyLenInBytes;
> > > >
> > > > +  switch (KeyLenInBytes) {
> > > >
> > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > >
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > >
> > > > +    break;
> > > >
> > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > >
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > >
> > > > +    break;
> > > >
> > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > >
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > >
> > > > +    break;
> > > >
> > > > +    break;
> > > >
> > > > +  default :
> > > >
> > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> > > >
> > > > +    Status = EFI_UNSUPPORTED;
> > > >
> > > > +    goto ON_EXIT;
> > > >
> > > > +  }
> > > >
> > > >
> > > >
> > > >    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof
> > > > (EFI_SIGNATURE_LIST));
> > > >
> > > >    CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
> > > >
> > > >    CopyMem (
> > > >
> > > >      KEKSigData->SignatureData,
> > > >
> > > >      KeyBlob + sizeof (CPL_KEY_INFO),
> > > >
> > > > -    WIN_CERT_UEFI_RSA2048_SIZE
> > > >
> > > > +    KeyLenInBytes
> > > >
> > > >      );
> > > >
> > > >
> > > >
> > > >    //
> > > >
> > > > @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
> > > >    if (IsDerEncodeCertificate (FilePostFix)) {
> > > >
> > > >      return EnrollX509ToKek (Private);
> > > >
> > > >    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> > > >
> > > > -    return EnrollRsa2048ToKek (Private);
> > > >
> > > > +    return EnrollRsaToKek (Private);
> > > >
> > > >    } else {
> > > >
> > > >      //
> > > >
> > > >      // File type is wrong, simply close it
> > > >
> > > > @@ -1847,7 +1867,7 @@ HashPeImage (
> > > >    SectionHeader = NULL;
> > > >
> > > >    Status        = FALSE;
> > > >
> > > >
> > > >
> > > > -  if (HashAlg != HASHALG_SHA256) {
> > > >
> > > > +  if ((HashAlg >= HASHALG_MAX)) {
> > > >
> > > >      return FALSE;
> > > >
> > > >    }
> > > >
> > > >
> > > >
> > > > @@ -1856,8 +1876,25 @@ HashPeImage (
> > > >    //
> > > >
> > > >    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> > > >
> > > >
> > > >
> > > > -  mImageDigestSize = SHA256_DIGEST_SIZE;
> > > >
> > > > -  mCertType        = gEfiCertSha256Guid;
> > > >
> > > > +   switch (HashAlg) {
> > > >
> > > > +    case HASHALG_SHA256:
> > > >
> > > > +      mImageDigestSize = SHA256_DIGEST_SIZE;
> > > >
> > > > +      mCertType        = gEfiCertSha256Guid;
> > > >
> > > > +      break;
> > > >
> > > > +
> > > >
> > > > +    case HASHALG_SHA384:
> > > >
> > > > +      mImageDigestSize = SHA384_DIGEST_SIZE;
> > > >
> > > > +      mCertType        = gEfiCertSha384Guid;
> > > >
> > > > +      break;
> > > >
> > > > +
> > > >
> > > > +    case HASHALG_SHA512:
> > > >
> > > > +      mImageDigestSize = SHA512_DIGEST_SIZE;
> > > >
> > > > +      mCertType        = gEfiCertSha512Guid;
> > > >
> > > > +      break;
> > > >
> > > > +
> > > >
> > > > +    default:
> > > >
> > > > +      return FALSE;
> > > >
> > > > +  }
> > > >
> > > >
> > > >
> > > >    CtxSize = mHash[HashAlg].GetContextSize ();
> > > >
> > > >
> > > >
> > > > @@ -2222,6 +2259,35 @@ ON_EXIT:
> > > >    return Status;
> > > >
> > > >  }
> > > >
> > > >
> > > >
> > > > +/**
> > > >
> > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > >
> > > > +
> > > >
> > > > +  @retval  UINT32       Hash Alg
> > > >
> > > > +  **/
> > > >
> > > > +UINT32
> > > >
> > > > +GetDefaultHashAlg (
> > > >
> > > > +  VOID
> > > >
> > > > +  )
> > > >
> > > > +{
> > > >
> > > > +  UINT32  HashAlg;
> > > >
> > > > +
> > > >
> > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > >
> > > > +  case 1:
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > >
> > > > +    HashAlg = HASHALG_SHA384;
> > > >
> > > > +    break;
> > > >
> > > > +  case 2:
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > >
> > > > +    HashAlg = HASHALG_SHA512;
> > > >
> > > > +    break;
> > > >
> > > > +  default:
> > > >
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > >
> > > > +    HashAlg = HASHALG_SHA256;
> > > >
> > > > +    break;
> > > >
> > > > +  }
> > > >
> > > > +  return HashAlg;
> > > >
> > > > +}
> > > >
> > > > +
> > > >
> > > >  /**
> > > >
> > > >    Enroll a new signature of executable into Signature Database.
> > > >
> > > >
> > > >
> > > > @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
> > > >    }
> > > >
> > > >
> > > >
> > > >    if (mSecDataDir->SizeOfCert == 0) {
> > > >
> > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > >
> > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > >
> > > >        Status =  EFI_SECURITY_VIOLATION;
> > > >
> > > >        goto ON_EXIT;
> > > >
> > > >      }
> > > >
> > > > @@ -2589,6 +2655,10 @@ UpdateDeletePage (
> > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > CertList->SignatureListSize)) {
> > > >
> > > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid))
> > > > {
> > > >
> > > >        Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> > > >
> > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > + &gEfiCertRsa3072Guid)) {
> > > >
> > > > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> > > >
> > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > + &gEfiCertRsa4096Guid)) {
> > > >
> > > > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> > > >
> > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > &gEfiCertX509Guid)) {
> > > >
> > > >        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> > > >
> > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > &gEfiCertSha1Guid)) {
> > > >
> > > > @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
> > > >    GuidIndex      = 0;
> > > >
> > > >    while ((KekDataSize > 0) && (KekDataSize >=
> > > > CertList->SignatureListSize)) {
> > > >
> > > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > > > ||
> > > >
> > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > > > + ||
> > > >
> > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > > > + ||
> > > >
> > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
> > > >
> > > >      {
> > > >
> > > >        CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST)
> > > > + CertList-
> > > > >SignatureHeaderSize));
> > > >
> > > > @@ -2952,6 +3024,8 @@ DeleteSignature (
> > > >    GuidIndex    = 0;
> > > >
> > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > CertList->SignatureListSize)) {
> > > >
> > > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > > > ||
> > > >
> > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > > > + ||
> > > >
> > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > > > + ||
> > > >
> > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
> > > >
> > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
> > > >
> > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)
> > > > ||
> > > >
> > > > @@ -3758,12 +3832,20 @@ LoadSignatureList (
> > > >    while ((RemainingSize > 0) && (RemainingSize >=
> > > > ListWalker->SignatureListSize)) {
> > > >
> > > >      if (CompareGuid (&ListWalker->SignatureType,
> > > > &gEfiCertRsa2048Guid)) {
> > > >
> > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > >
> > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > + &gEfiCertRsa3072Guid))
> > > > {
> > > >
> > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > >
> > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > + &gEfiCertRsa4096Guid))
> > > > {
> > > >
> > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > >
> > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > &gEfiCertX509Guid)) {
> > > >
> > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > >
> > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > &gEfiCertSha1Guid)) {
> > > >
> > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> > > >
> > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > &gEfiCertSha256Guid)) {
> > > >
> > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > >
> > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > + &gEfiCertSha384Guid))
> > > > {
> > > >
> > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > >
> > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > + &gEfiCertSha512Guid))
> > > > {
> > > >
> > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > >
> > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > &gEfiCertX509Sha256Guid)) {
> > > >
> > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > >
> > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > &gEfiCertX509Sha384Guid)) {
> > > >
> > > > @@ -4001,6 +4083,14 @@ FormatHelpInfo (
> > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > >
> > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > >
> > > >      IsCert     = TRUE;
> > > >
> > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > + &gEfiCertRsa3072Guid)) {
> > > >
> > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > >
> > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > >
> > > > +    IsCert     = TRUE;
> > > >
> > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > + &gEfiCertRsa4096Guid)) {
> > > >
> > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > >
> > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > >
> > > > +    IsCert     = TRUE;
> > > >
> > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > &gEfiCertX509Guid)) {
> > > >
> > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > >
> > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > >
> > > > @@ -4011,6 +4101,12 @@ FormatHelpInfo (
> > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > &gEfiCertSha256Guid)) {
> > > >
> > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > >
> > > >      DataSize   = 32;
> > > >
> > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > + &gEfiCertSha384Guid)) {
> > > >
> > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > >
> > > > +    DataSize   = 48;
> > > >
> > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > + &gEfiCertSha512Guid)) {
> > > >
> > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > >
> > > > +    DataSize   = 64;
> > > >
> > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > &gEfiCertX509Sha256Guid)) {
> > > >
> > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > >
> > > >      DataSize   = 32;
> > > >
> > > > diff --git
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.h
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.h
> > > > index 37c66f1b95..ae50d929a7 100644
> > > > ---
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.h
> > > > +++
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igI
> > > > mpl.h
> > > > @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
> #define
> > > > MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> > > >
> > > >
> > > >
> > > >  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> > > >
> > > > +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> > > >
> > > > +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> > > >
> > > >
> > > >
> > > >  //
> > > >
> > > >  // Support hash types
> > > >
> > > > diff --git
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igS
> > > > trings.uni
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igS
> > > > trings.uni
> > > > index 0d01701de7..1b48acc800 100644
> > > > ---
> > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igS
> > > > trings.uni
> > > > +++
> > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > f
> > > > igS
> > > > trings.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"
> > > >
> > > >  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File
> > > Explorer"
> > > >
> > > >  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US
> > > > "RSA2048_SHA256_GUID"
> > > >
> > > > +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US
> > > > "RSA3072_SHA384_GUID"
> > > >
> > > > +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US
> > > > "RSA4096_SHA512_GUID"
> > > >
> > > >  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US
> > > "PKCS7_GUID"
> > > >
> > > >  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US
> > > "SHA1_GUID"
> > > >
> > > >  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> > > > "SHA256_GUID"
> > > >
> > > > @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > >  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US
> > > > "X509_SHA512_GUID"
> > > >
> > > >
> > > >
> > > >  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> > > > "RSA2048_SHA256"
> > > >
> > > > +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> > > > "RSA3072_SHA384"
> > > >
> > > > +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> > > > "RSA4096_SHA512"
> > > >
> > > >  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> > > >
> > > >  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> > > >
> > > >  #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
> > > >
> > > > +#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
> > > >
> > > > +#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
> > > >
> > > >  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> > > > "X509_SHA256"
> > > >
> > > >  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> > > > "X509_SHA384"
> > > >
> > > >  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> > > > "X509_SHA512"
> > > >
> > > > --
> > > > 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106678): https://edk2.groups.io/g/devel/message/106678
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


From 8929b03a2b0f04208bb3810ddddf904cdc95c3c6 Mon Sep 17 00:00:00 2001
From: Sheng Wei <w.sheng@intel.com>
Date: Fri, 28 Apr 2023 16:08:25 +0800
Subject: [PATCH v3] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Zeyi Chen <zeyi.chen@intel.com>
Cc: Fiona Wang <fiona.wang@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
 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/Library/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.
   //
   if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||
-      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
+      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest (EVP_sha384 ()) == 0) ||
+      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
   {
     return FALSE;
   }
diff --git a/MdePkg/Include/Guid/ImageAuthentication.h b/MdePkg/Include/Guid/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} \
   }
 
+///
+/// This identifies a signature containing an RSA-3072 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 384 bytes.
+///
+#define EFI_CERT_RSA3072_GUID \
+  { \
+    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 } \
+  }
+
+///
+/// This identifies a signature containing an RSA-4096 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 512 bytes.
+///
+#define EFI_CERT_RSA4096_GUID \
+  { \
+    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c } \
+  }
+
 ///
 /// This identifies a signature containing a RSA-2048 signature of a SHA-256 hash.  The
 /// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
@@ -330,6 +354,8 @@ typedef struct {
 extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
 extern EFI_GUID  gEfiCertSha256Guid;
 extern EFI_GUID  gEfiCertRsa2048Guid;
+extern EFI_GUID  gEfiCertRsa3072Guid;
+extern EFI_GUID  gEfiCertRsa4096Guid;
 extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
 extern EFI_GUID  gEfiCertSha1Guid;
 extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
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  = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
   gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 }}
   gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
+  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
+  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
   gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
   gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe,  0x1, 0x49, 0x66, 0x31, 0xbd }}
   gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPkg/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 <Protocol/VariablePolicy.h>
 #include <Library/VariablePolicyLib.h>
 
+#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
+
+/**
+  Retrieves the size, in bytes, of the context buffer required for hash operations.
+
+  If this interface is not supported, then return zero.
+
+  @return  The size, in bytes, of the context buffer required for hash operations.
+  @retval  0   This interface is not supported.
+
+**/
+typedef
+UINTN
+(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE)(
+  VOID
+  );
+
+/**
+  Initializes user-supplied memory pointed by Sha1Context as hash context for
+  subsequent use.
+
+  If HashContext is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[out]  HashContext  Pointer to Hashcontext being initialized.
+
+  @retval TRUE   Hash context initialization succeeded.
+  @retval FALSE  Hash context initialization failed.
+  @retval FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_HASH_INIT)(
+  OUT  VOID  *HashContext
+  );
+
+/**
+  Digests the input data and updates Hash context.
+
+  This function performs Hash digest on a data buffer of the specified size.
+  It can be called multiple times to compute the digest of long or discontinuous data streams.
+  Hash context should be already correctly initialized by HashInit(), and should not be finalized
+  by HashFinal(). Behavior with invalid context is undefined.
+
+  If HashContext is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in, out]  HashContext  Pointer to the Hash context.
+  @param[in]       Data         Pointer to the buffer containing the data to be hashed.
+  @param[in]       DataSize     Size of Data buffer in bytes.
+
+  @retval TRUE   SHA-1 data digest succeeded.
+  @retval FALSE  SHA-1 data digest failed.
+  @retval FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_HASH_UPDATE)(
+  IN OUT  VOID        *HashContext,
+  IN      CONST VOID  *Data,
+  IN      UINTN       DataSize
+  );
+
+/**
+  Completes computation of the Hash digest value.
+
+  This function completes hash computation and retrieves the digest value into
+  the specified memory. After this function has been called, the Hash context cannot
+  be used again.
+  Hash context should be already correctly initialized by HashInit(), and should not be
+  finalized by HashFinal(). Behavior with invalid Hash context is undefined.
+
+  If HashContext is NULL, then return FALSE.
+  If HashValue is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in, out]  HashContext  Pointer to the Hash context.
+  @param[out]      HashValue    Pointer to a buffer that receives the Hash digest
+                                value.
+
+  @retval TRUE   Hash digest computation succeeded.
+  @retval FALSE  Hash digest computation failed.
+  @retval FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_HASH_FINAL)(
+  IN OUT  VOID   *HashContext,
+  OUT     UINT8  *HashValue
+  );
+
+typedef struct {
+  UINT32                       HashSize;
+  EFI_HASH_GET_CONTEXT_SIZE    GetContextSize;
+  EFI_HASH_INIT                Init;
+  EFI_HASH_UPDATE              Update;
+  EFI_HASH_FINAL               Final;
+  VOID                         **HashShaCtx;
+  UINT8                        *OidValue;
+  UINTN                        OidLength;
+} EFI_HASH_INFO;
+
 //
 // Public Exponent of RSA Key.
 //
 CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
 
-CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
+UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
+UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 };
+UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 };
+
+EFI_HASH_INFO  mHashInfo[] = {
+  {SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final, &mHashSha256Ctx, mSha256OidValue, 9},
+  {SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final, &mHashSha384Ctx, mSha384OidValue, 9},
+  {SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final, &mHashSha512Ctx, mSha512OidValue, 9},
+};
 
 //
 // Requirement for different signature type which have been defined in UEFI spec.
@@ -44,6 +157,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
   // {SigType,                       SigHeaderSize,   SigDataSize  }
   { EFI_CERT_SHA256_GUID,         0, 32            },
   { EFI_CERT_RSA2048_GUID,        0, 256           },
+  { EFI_CERT_RSA3072_GUID,        0, 384           },
+  { EFI_CERT_RSA4096_GUID,        0, 512           },
   { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
   { EFI_CERT_SHA1_GUID,           0, 20            },
   { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
@@ -1090,26 +1205,28 @@ AuthServiceInternalCompareTimeStamp (
 }
 
 /**
-  Calculate SHA256 digest of SignerCert CommonName + ToplevelCert tbsCertificate
+  Calculate SHA digest of SignerCert CommonName + ToplevelCert tbsCertificate
   SignerCert and ToplevelCert are inside the signer certificate chain.
 
+  @param[in]  HashAlgId           Hash algorithm index
   @param[in]  SignerCert          A pointer to SignerCert data.
   @param[in]  SignerCertSize      Length of SignerCert data.
   @param[in]  TopLevelCert        A pointer to TopLevelCert data.
   @param[in]  TopLevelCertSize    Length of TopLevelCert data.
-  @param[out] Sha256Digest       Sha256 digest calculated.
+  @param[out] ShaDigest           Sha digest calculated.
 
   @return EFI_ABORTED          Digest process failed.
-  @return EFI_SUCCESS          SHA256 Digest is successfully calculated.
+  @return EFI_SUCCESS          SHA Digest is successfully calculated.
 
 **/
 EFI_STATUS
-CalculatePrivAuthVarSignChainSHA256Digest (
+CalculatePrivAuthVarSignChainSHADigest (
+  IN     UINT8  HashAlgId,
   IN     UINT8  *SignerCert,
   IN     UINTN  SignerCertSize,
   IN     UINT8  *TopLevelCert,
   IN     UINTN  TopLevelCertSize,
-  OUT    UINT8  *Sha256Digest
+  OUT    UINT8  *ShaDigest
   )
 {
   UINT8       *TbsCert;
@@ -1119,6 +1236,11 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   BOOLEAN     CryptoStatus;
   EFI_STATUS  Status;
 
+  if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
+    DEBUG ((DEBUG_INFO, "%a Unsupported Hash Algorithm %d\n", __func__, HashAlgId));
+    return EFI_ABORTED;
+  }
+
   CertCommonNameSize = sizeof (CertCommonName);
 
   //
@@ -1141,8 +1263,8 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   //
   // Digest SignerCert CN + TopLevelCert tbsCertificate
   //
-  ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE);
-  CryptoStatus = Sha256Init (mHashCtx);
+  ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);
+  CryptoStatus = mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashShaCtx));
   if (!CryptoStatus) {
     return EFI_ABORTED;
   }
@@ -1150,8 +1272,8 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   //
   // '\0' is forced in CertCommonName. No overflow issue
   //
-  CryptoStatus = Sha256Update (
-                   mHashCtx,
+  CryptoStatus = mHashInfo[HashAlgId].Update (
+                   *(mHashInfo[HashAlgId].HashShaCtx),
                    CertCommonName,
                    AsciiStrLen (CertCommonName)
                    );
@@ -1159,12 +1281,12 @@ CalculatePrivAuthVarSignChainSHA256Digest (
     return EFI_ABORTED;
   }
 
-  CryptoStatus = Sha256Update (mHashCtx, TbsCert, TbsCertSize);
+  CryptoStatus = mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].HashShaCtx), TbsCert, TbsCertSize);
   if (!CryptoStatus) {
     return EFI_ABORTED;
   }
 
-  CryptoStatus = Sha256Final (mHashCtx, Sha256Digest);
+  CryptoStatus = mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].HashShaCtx), ShaDigest);
   if (!CryptoStatus) {
     return EFI_ABORTED;
   }
@@ -1516,9 +1638,10 @@ DeleteCertsFromDb (
 /**
   Insert signer's certificates for common authenticated variable with VariableName
   and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to
-  time based authenticated variable attributes. CertData is the SHA256 digest of
+  time based authenticated variable attributes. CertData is the SHA digest of
   SignerCert CommonName + TopLevelCert tbsCertificate.
 
+  @param[in]  HashAlgId         Hash algorithm index.
   @param[in]  VariableName      Name of authenticated Variable.
   @param[in]  VendorGuid        Vendor GUID of authenticated Variable.
   @param[in]  Attributes        Attributes of authenticated variable.
@@ -1536,6 +1659,7 @@ DeleteCertsFromDb (
 **/
 EFI_STATUS
 InsertCertsToDb (
+  IN     UINT8     HashAlgId,
   IN     CHAR16    *VariableName,
   IN     EFI_GUID  *VendorGuid,
   IN     UINT32    Attributes,
@@ -1556,12 +1680,16 @@ InsertCertsToDb (
   UINT32             CertDataSize;
   AUTH_CERT_DB_DATA  *Ptr;
   CHAR16             *DbName;
-  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
+  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
 
   if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
 
+  if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
   if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
     //
     // Get variable "certdb".
@@ -1618,20 +1746,22 @@ InsertCertsToDb (
   // Construct new data content of variable "certdb" or "certdbv".
   //
   NameSize      = (UINT32)StrLen (VariableName);
-  CertDataSize  = sizeof (Sha256Digest);
+  CertDataSize  = mHashInfo[HashAlgId].HashSize;
   CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);
   NewCertDbSize = (UINT32)DataSize + CertNodeSize;
   if (NewCertDbSize > mMaxCertDbSize) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  Status = CalculatePrivAuthVarSignChainSHA256Digest (
+  Status = CalculatePrivAuthVarSignChainSHADigest (
+             HashAlgId,
              SignerCert,
              SignerCertSize,
              TopLevelCert,
              TopLevelCertSize,
-             Sha256Digest
+             ShaDigest
              );
+
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -1663,7 +1793,7 @@ InsertCertsToDb (
 
   CopyMem (
     (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
-    Sha256Digest,
+    ShaDigest,
     CertDataSize
     );
 
@@ -1790,6 +1920,36 @@ CleanCertsFromDb (
   return Status;
 }
 
+/**
+  Find hash algorithm index
+
+  @param[in]  SigData      Pointer to the PKCS#7 message
+  @param[in]  SigDataSize  Length of the PKCS#7 message
+
+  @retval UINT8        Hash Algorithm Index
+**/
+UINT8
+FindHashAlgorithmIndex (
+  IN     UINT8         *SigData,
+  IN     UINT32        SigDataSize
+)
+{
+  UINT8 i;
+
+  for (i = 0; i < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO)); i++) {
+    if (  (  (SigDataSize >= (13 + mHashInfo[i].OidLength))
+          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
+            && (CompareMem (SigData + 13, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0)))
+      || ((  (SigDataSize >= (32 +  mHashInfo[i].OidLength)))
+        && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
+          && (CompareMem (SigData + 32, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0))))
+    {
+      break;
+    }
+  }
+  return i;
+}
+
 /**
   Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
 
@@ -1857,8 +2017,9 @@ VerifyTimeBasedPayload (
   UINTN                          CertStackSize;
   UINT8                          *CertsInCertDb;
   UINT32                         CertsSizeinDb;
-  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
+  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
   EFI_CERT_DATA                  *CertDataPtr;
+  UINT8                          HashAlgId;
 
   //
   // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain
@@ -1928,7 +2089,7 @@ VerifyTimeBasedPayload (
 
   //
   // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the
-  // signature. Only a digest algorithm of SHA-256 is accepted.
+  // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is accepted.
   //
   //    According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
   //        SignedData ::= SEQUENCE {
@@ -1972,14 +2133,9 @@ VerifyTimeBasedPayload (
   //
   // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process
   //
+  HashAlgId = FindHashAlgorithmIndex (SigData, SigDataSize);
   if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
-    if (  (  (SigDataSize >= (13 + sizeof (mSha256OidValue)))
-          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
-             || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))
-       && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
-          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
-             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))))
-    {
+    if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
       return EFI_SECURITY_VIOLATION;
     }
   }
@@ -2170,19 +2326,20 @@ VerifyTimeBasedPayload (
         goto Exit;
       }
 
-      if (CertsSizeinDb == SHA256_DIGEST_SIZE) {
+      if ((HashAlgId < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) && (CertsSizeinDb == mHashInfo[HashAlgId].HashSize)) {
         //
         // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
         //
         CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
-        Status      = CalculatePrivAuthVarSignChainSHA256Digest (
+        Status      = CalculatePrivAuthVarSignChainSHADigest (
+                        HashAlgId,
                         CertDataPtr->CertDataBuffer,
                         ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
                         TopLevelCert,
                         TopLevelCertSize,
-                        Sha256Digest
+                        ShaDigest
                         );
-        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb, CertsSizeinDb) != 0)) {
+        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
           goto Exit;
         }
       } else {
@@ -2215,6 +2372,7 @@ VerifyTimeBasedPayload (
       //
       CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
       Status      = InsertCertsToDb (
+                      HashAlgId,
                       VariableName,
                       VendorGuid,
                       Attributes,
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h b/SecurityPkg/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;
 extern UINT8   mVendorKeyState;
 
-extern VOID  *mHashCtx;
+extern VOID  *mHashSha256Ctx;
+extern VOID  *mHashSha384Ctx;
+extern VOID  *mHashSha512Ctx;
 
 extern AUTH_VAR_LIB_CONTEXT_IN  *mAuthVarLibContextIn;
 
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c b/SecurityPkg/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;
 UINT8   mVendorKeyState;
 
-EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID };
+EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID, EFI_CERT_SHA512_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID, EFI_CERT_RSA4096_GUID, EFI_CERT_X509_GUID };
 
 //
 // Hash context pointer
 //
-VOID  *mHashCtx = NULL;
+VOID  *mHashSha256Ctx = NULL;
+VOID  *mHashSha384Ctx = NULL;
+VOID  *mHashSha512Ctx = NULL;
 
 VARIABLE_ENTRY_PROPERTY  mAuthVarEntry[] = {
   {
@@ -91,7 +93,7 @@ VARIABLE_ENTRY_PROPERTY  mAuthVarEntry[] = {
   },
 };
 
-VOID  **mAuthVarAddressPointer[9];
+VOID  **mAuthVarAddressPointer[11];
 
 AUTH_VAR_LIB_CONTEXT_IN  *mAuthVarLibContextIn = NULL;
 
@@ -120,7 +122,6 @@ AuthVariableLibInitialize (
   UINT32      VarAttr;
   UINT8       *Data;
   UINTN       DataSize;
-  UINTN       CtxSize;
   UINT8       SecureBootMode;
   UINT8       SecureBootEnable;
   UINT8       CustomMode;
@@ -135,9 +136,18 @@ AuthVariableLibInitialize (
   //
   // Initialize hash context.
   //
-  CtxSize  = Sha256GetContextSize ();
-  mHashCtx = AllocateRuntimePool (CtxSize);
-  if (mHashCtx == NULL) {
+  mHashSha256Ctx = AllocateRuntimePool (Sha256GetContextSize ());
+  if (mHashSha256Ctx == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mHashSha384Ctx = AllocateRuntimePool (Sha384GetContextSize ());
+  if (mHashSha384Ctx == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mHashSha512Ctx = AllocateRuntimePool (Sha512GetContextSize ());
+  if (mHashSha512Ctx == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
@@ -356,14 +366,16 @@ AuthVariableLibInitialize (
   AuthVarLibContextOut->AuthVarEntry        = mAuthVarEntry;
   AuthVarLibContextOut->AuthVarEntryCount   = ARRAY_SIZE (mAuthVarEntry);
   mAuthVarAddressPointer[0]                 = (VOID **)&mCertDbStore;
-  mAuthVarAddressPointer[1]                 = (VOID **)&mHashCtx;
-  mAuthVarAddressPointer[2]                 = (VOID **)&mAuthVarLibContextIn;
-  mAuthVarAddressPointer[3]                 = (VOID **)&(mAuthVarLibContextIn->FindVariable),
-  mAuthVarAddressPointer[4]                 = (VOID **)&(mAuthVarLibContextIn->FindNextVariable),
-  mAuthVarAddressPointer[5]                 = (VOID **)&(mAuthVarLibContextIn->UpdateVariable),
-  mAuthVarAddressPointer[6]                 = (VOID **)&(mAuthVarLibContextIn->GetScratchBuffer),
-  mAuthVarAddressPointer[7]                 = (VOID **)&(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),
-  mAuthVarAddressPointer[8]                 = (VOID **)&(mAuthVarLibContextIn->AtRuntime),
+  mAuthVarAddressPointer[1]                 = (VOID **)&mHashSha256Ctx;
+  mAuthVarAddressPointer[2]                 = (VOID **)&mHashSha384Ctx;
+  mAuthVarAddressPointer[3]                 = (VOID **)&mHashSha512Ctx;
+  mAuthVarAddressPointer[4]                 = (VOID **)&mAuthVarLibContextIn;
+  mAuthVarAddressPointer[5]                 = (VOID **)&(mAuthVarLibContextIn->FindVariable),
+  mAuthVarAddressPointer[6]                 = (VOID **)&(mAuthVarLibContextIn->FindNextVariable),
+  mAuthVarAddressPointer[7]                 = (VOID **)&(mAuthVarLibContextIn->UpdateVariable),
+  mAuthVarAddressPointer[8]                 = (VOID **)&(mAuthVarLibContextIn->GetScratchBuffer),
+  mAuthVarAddressPointer[9]                 = (VOID **)&(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),
+  mAuthVarAddressPointer[10]                 = (VOID **)&(mAuthVarLibContextIn->AtRuntime),
   AuthVarLibContextOut->AddressPointer      = mAuthVarAddressPointer;
   AuthVarLibContextOut->AddressPointerCount = ARRAY_SIZE (mAuthVarAddressPointer);
 
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.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 value of the image may
       be reflected in the security database "dbx".
     Otherwise, the image is not signed,
-      The SHA256 hash value of the image must match a record in the security database "db", and
+      The hash value of the image must match a record in the security database "db", and
       not be reflected in the security data base "dbx".
 
   Caution: This function may receive untrusted input.
@@ -1690,6 +1690,8 @@ DxeImageVerificationHandler (
   EFI_STATUS                    VarStatus;
   UINT32                        VarAttr;
   BOOLEAN                       IsFound;
+  UINT8                         HashAlg;
+  BOOLEAN                       IsFoundInDatabase;
 
   SignatureList     = NULL;
   SignatureListSize = 0;
@@ -1699,6 +1701,7 @@ DxeImageVerificationHandler (
   Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;
   IsVerified        = FALSE;
   IsFound           = FALSE;
+  IsFoundInDatabase = FALSE;
 
   //
   // Check the image type and get policy setting.
@@ -1837,40 +1840,50 @@ DxeImageVerificationHandler (
   //
   if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
     //
-    // This image is not signed. The SHA256 hash value of the image must match a record in the security database "db",
+    // This image is not signed. The hash value of the image must match a record in the security database "db",
     // and not be reflected in the security data base "dbx".
     //
-    if (!HashPeImage (HASHALG_SHA256)) {
-      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr));
-      goto Failed;
-    }
+    HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
+    while (HashAlg > 0) {
+      HashAlg--;
+      if ((mHash[HashAlg].GetContextSize == NULL) || (mHash[HashAlg].HashInit == NULL) || (mHash[HashAlg].HashUpdate == NULL) || (mHash[HashAlg].HashFinal == NULL)) {
+        continue;
+      }
+      if (!HashPeImage (HashAlg)) {
+        continue;
+      }
 
-    DbStatus = IsSignatureFoundInDatabase (
-                 EFI_IMAGE_SECURITY_DATABASE1,
-                 mImageDigest,
-                 &mCertType,
-                 mImageDigestSize,
-                 &IsFound
-                 );
-    if (EFI_ERROR (DbStatus) || IsFound) {
-      //
-      // Image Hash is in forbidden database (DBX).
-      //
-      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));
-      goto Failed;
+      DbStatus = IsSignatureFoundInDatabase (
+                   EFI_IMAGE_SECURITY_DATABASE1,
+                   mImageDigest,
+                   &mCertType,
+                   mImageDigestSize,
+                   &IsFound
+                   );
+      if (EFI_ERROR (DbStatus) || IsFound) {
+        //
+        // Image Hash is in forbidden database (DBX).
+        //
+        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));
+        goto Failed;
+      }
+
+      DbStatus = IsSignatureFoundInDatabase (
+                   EFI_IMAGE_SECURITY_DATABASE,
+                   mImageDigest,
+                   &mCertType,
+                   mImageDigestSize,
+                   &IsFound
+                   );
+      if (!EFI_ERROR (DbStatus) && IsFound) {
+        //
+        // Image Hash is in allowed database (DB).
+        //
+        IsFoundInDatabase = TRUE;
+      }
     }
 
-    DbStatus = IsSignatureFoundInDatabase (
-                 EFI_IMAGE_SECURITY_DATABASE,
-                 mImageDigest,
-                 &mCertType,
-                 mImageDigestSize,
-                 &IsFound
-                 );
-    if (!EFI_ERROR (DbStatus) && IsFound) {
-      //
-      // Image Hash is in allowed database (DB).
-      //
+    if (IsFoundInDatabase) {
       return EFI_SUCCESS;
     }
 
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
index 1671d5be7c..cb52a16c09 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
@@ -70,6 +70,14 @@
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertRsa2048Guid
 
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertRsa3072Guid
+
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertRsa4096Guid
+
   ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertX509Guid
@@ -82,6 +90,14 @@
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertSha256Guid
 
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertSha384Guid
+
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertSha512Guid
+
   ## SOMETIMES_CONSUMES      ## Variable:L"db"
   ## SOMETIMES_PRODUCES      ## Variable:L"db"
   ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 0e31502b1b..3de6bf6139 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -560,7 +560,7 @@ ON_EXIT:
 
 **/
 EFI_STATUS
-EnrollRsa2048ToKek (
+EnrollRsaToKek (
   IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
   )
 {
@@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
 
   ASSERT (KeyBlob != NULL);
   KeyInfo = (CPL_KEY_INFO *)KeyBlob;
-  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
-    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is supported.\n"));
+  switch (KeyInfo->KeyLengthInBits / 8) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    break;
+  default :
+    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048, RSA3072 and RSA4096 are supported.\n"));
     Status = EFI_UNSUPPORTED;
     goto ON_EXIT;
   }
@@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
   //
   KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
                    + sizeof (EFI_SIGNATURE_DATA) - 1
-                   + WIN_CERT_UEFI_RSA2048_SIZE;
+                   + KeyLenInBytes;
 
   KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
   if (KekSigList == NULL) {
@@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
 
   KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
                                   + sizeof (EFI_SIGNATURE_DATA) - 1
-                                  + WIN_CERT_UEFI_RSA2048_SIZE;
+                                  + (UINT32) KeyLenInBytes;
   KekSigList->SignatureHeaderSize = 0;
-  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + WIN_CERT_UEFI_RSA2048_SIZE;
-  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32) KeyLenInBytes;
+  switch (KeyLenInBytes) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+    break;
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
+    break;
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
+    break;
+    break;
+  default :
+    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
 
   KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
   CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
   CopyMem (
     KEKSigData->SignatureData,
     KeyBlob + sizeof (CPL_KEY_INFO),
-    WIN_CERT_UEFI_RSA2048_SIZE
+    KeyLenInBytes
     );
 
   //
@@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
   if (IsDerEncodeCertificate (FilePostFix)) {
     return EnrollX509ToKek (Private);
   } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
-    return EnrollRsa2048ToKek (Private);
+    return EnrollRsaToKek (Private);
   } else {
     //
     // File type is wrong, simply close it
@@ -1847,7 +1867,7 @@ HashPeImage (
   SectionHeader = NULL;
   Status        = FALSE;
 
-  if (HashAlg != HASHALG_SHA256) {
+  if ((HashAlg >= HASHALG_MAX)) {
     return FALSE;
   }
 
@@ -1856,8 +1876,25 @@ HashPeImage (
   //
   ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
 
-  mImageDigestSize = SHA256_DIGEST_SIZE;
-  mCertType        = gEfiCertSha256Guid;
+   switch (HashAlg) {
+    case HASHALG_SHA256:
+      mImageDigestSize = SHA256_DIGEST_SIZE;
+      mCertType        = gEfiCertSha256Guid;
+      break;
+
+    case HASHALG_SHA384:
+      mImageDigestSize = SHA384_DIGEST_SIZE;
+      mCertType        = gEfiCertSha384Guid;
+      break;
+
+    case HASHALG_SHA512:
+      mImageDigestSize = SHA512_DIGEST_SIZE;
+      mCertType        = gEfiCertSha512Guid;
+      break;
+
+    default:
+      return FALSE;
+  }
 
   CtxSize = mHash[HashAlg].GetContextSize ();
 
@@ -2251,6 +2288,7 @@ EnrollImageSignatureToSigDB (
   UINT32                     Attr;
   WIN_CERTIFICATE_UEFI_GUID  *GuidCertData;
   EFI_TIME                   Time;
+  UINT32                     HashAlg;
 
   Data         = NULL;
   GuidCertData = NULL;
@@ -2289,8 +2327,20 @@ EnrollImageSignatureToSigDB (
   }
 
   if (mSecDataDir->SizeOfCert == 0) {
-    if (!HashPeImage (HASHALG_SHA256)) {
-      Status =  EFI_SECURITY_VIOLATION;
+    Status = EFI_SECURITY_VIOLATION;
+    HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
+    while (HashAlg > 0) {
+      HashAlg--;
+      if ((mHash[HashAlg].GetContextSize == NULL) || (mHash[HashAlg].HashInit == NULL) || (mHash[HashAlg].HashUpdate == NULL) || (mHash[HashAlg].HashFinal == NULL)) {
+        continue;
+      }
+      if (HashPeImage (HashAlg)) {
+        Status = EFI_SUCCESS;
+        break;
+      }
+    }
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to get hash digest: %r", Status));
       goto ON_EXIT;
     }
   } else {
@@ -2589,6 +2639,10 @@ UpdateDeletePage (
   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)) {
       Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
+    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)) {
+      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
+    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)) {
+      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
     } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
       Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
     } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)) {
@@ -2750,6 +2804,8 @@ DeleteKeyExchangeKey (
   GuidIndex      = 0;
   while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
     {
       CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
@@ -2952,6 +3008,8 @@ DeleteSignature (
   GuidIndex    = 0;
   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
@@ -3758,12 +3816,20 @@ LoadSignatureList (
   while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
     if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa3072Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa4096Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
@@ -4001,6 +4067,14 @@ FormatHelpInfo (
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
     DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
     IsCert     = TRUE;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa3072Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
+    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
+    IsCert     = TRUE;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa4096Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
+    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
+    IsCert     = TRUE;
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
     DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
@@ -4011,6 +4085,12 @@ FormatHelpInfo (
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
     DataSize   = 32;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+    DataSize   = 48;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
+    DataSize   = 64;
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
     DataSize   = 32;
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
index 37c66f1b95..ae50d929a7 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
@@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
 #define MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
 
 #define WIN_CERT_UEFI_RSA2048_SIZE  256
+#define WIN_CERT_UEFI_RSA3072_SIZE  384
+#define WIN_CERT_UEFI_RSA4096_SIZE  512
 
 //
 // Support hash types
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
index 0d01701de7..1b48acc800 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.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"
 #string STR_FILE_EXPLORER_TITLE                   #language en-US "File Explorer"
 #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US "RSA2048_SHA256_GUID"
+#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US "RSA3072_SHA384_GUID"
+#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US "RSA4096_SHA512_GUID"
 #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US "PKCS7_GUID"
 #string STR_CERT_TYPE_SHA1_GUID                   #language en-US "SHA1_GUID"
 #string STR_CERT_TYPE_SHA256_GUID                 #language en-US "SHA256_GUID"
@@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US "X509_SHA512_GUID"
 
 #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US "RSA2048_SHA256"
+#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US "RSA3072_SHA384"
+#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US "RSA4096_SHA512"
 #string STR_LIST_TYPE_X509                        #language en-US "X509"
 #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
 #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
+#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
+#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
 #string STR_LIST_TYPE_X509_SHA256                 #language en-US "X509_SHA256"
 #string STR_LIST_TYPE_X509_SHA384                 #language en-US "X509_SHA384"
 #string STR_LIST_TYPE_X509_SHA512                 #language en-US "X509_SHA512"
-- 
2.26.2.windows.1

Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Yao, Jiewen 9 months, 3 weeks ago
CPL_KEY_INFO is not standard, but implementation choice.

I notice KeyType field is not used today. I assume it is 0 today.

Can we use 0 to indicate RSASSA?

Thank you
Yao, Jiewen



> -----Original Message-----
> From: Sheng, W <w.sheng@intel.com>
> Sent: Thursday, July 6, 2023 2:48 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>;
> Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> Hi Jiewen,
> I raised the patch V3, And I also attached the patch file.
> For 4,
> My solution is below.
> When enroll the unsigned image, BIOS will select the most supported complex
> hash algorithm to get the hash.
> When do the verification, BIOS will try all supported hash algorithm in "db" and
> "dbx".
> 
> For 5.
> The struct of CPL_KEY_INFO should be binded to .pbk file format.
> I cannot find the spec of .pbk file. I can not change the struct items.
> Do you know where to find the spec of public key storing file (*.pbk) ?
> Or is *.pbk file a legacy file format? We do not need to change this part and
> keep it for RSA 2048 only ?
> 
> Thank you
> BR
> Sheng Wei
> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: 2023年6月30日 19:57
> > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> > <fiona.wang@intel.com>
> > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> >
> > For 4, I think we can enroll all supported algorithms, or the active algorithm. I
> > don’t think the PCD is needed.
> >
> > For 5, I suggest to change the data structure to include the algorithm ID.
> >
> > Thank you
> > Yao, Jiewen
> >
> >
> > > -----Original Message-----
> > > From: Sheng, W <w.sheng@intel.com>
> > > Sent: Friday, June 30, 2023 3:52 PM
> > > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > <min.m.xu@intel.com>;
> > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > 384
> > >
> > > Hi Jiewen,
> > > I raised the patch V2.
> > > I do the fix for 1) , 2), 3).
> > > But for 4) 5), I have below comments.
> > >
> > > 4) I am not sure why we need this PCD. Why cannot we support all of hash
> > algo?
> > >
> > > +  ## Indicates default hash algorithm in Secure Boot
> > > +  #   0 - Use SHA256
> > > +  #   1 - Use SHA384
> > > +  #   2 - Use SHA512
> > > +  # @Prompt Secure Boot default hash algorithm
> > > +
> > > +
> > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > 00
> > > + 010040
> > >
> > > PCD PcdSecureBootDefaultHashAlg is used for the only case of enroll an
> > > unsigned image.
> > > The original logic is BIOS will genrate SHA256 digest for this unsigned image
> > and
> > > save it.
> > > The PCD is used to select the hash algorithm for this case.
> > > So we have to use a PCD to select the algorithm manully.
> > >
> > >
> > > 5) I don’t believe that you can use size to determine the algorithm. We
> > need a
> > > more robust way, such as algorithm ID.
> > >
> > > +  switch (KeyLenInBytes) {
> > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > +    break;
> > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > +    break;
> > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > +    break;
> > > +    break;
> > >
> > > This code is used when enroll a RSA public key storing file (*.pbk).
> > > Here is the header Struct of this file.
> > > typedef struct _CPL_KEY_INFO {
> > >   UINT32    KeyLengthInBits;        // Key Length In Bits
> > >   UINT32    BlockSize;              // Operation Block Size in Bytes
> > >   UINT32    CipherBlockSize;        // Output Cipher Block Size in Bytes
> > >   UINT32    KeyType;                // Key Type
> > >   UINT32    CipherMode;             // Cipher Mode for Symmetric Algorithm
> > >   UINT32    Flags;                  // Additional Key Property Flags
> > > } CPL_KEY_INFO;
> > >
> > Edk2/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBoot
> > Con
> > > figImpl.h
> > > We can only get to know the RSA algorithm by KeyLengthInBits.
> > > (RSA2048/RSA3072/RSA4096)
> > >
> > > Thank you.
> > > BR
> > > Sheng Wei
> > >
> > > > -----Original Message-----
> > > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > > Sent: 2023年6月22日 15:22
> > > > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > <min.m.xu@intel.com>;
> > > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > 384
> > > >
> > > > Thank you very much to contribute this patch. Here is my feedback.
> > > >
> > > > 1) I don’t believe that you cannot use digest size to determine the
> > algorithm,
> > > > because different hash algorithm may have same time. E.g. SHA256 and
> > > > SHA3_256.
> > > >
> > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > +               SignerCert,
> > > > +               SignerCertSize,
> > > > +               TopLevelCert,
> > > > +               TopLevelCertSize,
> > > > +               ShaDigest
> > > > +               );
> > > >
> > > > 2) I don’t believe that you cannot assuming CtxSize of SHA512 is bigger
> > than
> > > > SHA256. I think we may need create context for each algo.
> > > >
> > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > >    //
> > > >    // Initialize hash context.
> > > >    //
> > > > -  CtxSize  = Sha256GetContextSize ();
> > > > +  CtxSize  = Sha512GetContextSize ();
> > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > >    if (mHashCtx == NULL) {
> > > >
> > > > 3) I believe we should use 0 for SHA256 and ASSERT in default.
> > > >
> > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {  case 1:
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > +    HashAlg = HASHALG_SHA384;
> > > > +    break;
> > > > +  case 2:
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > +    HashAlg = HASHALG_SHA512;
> > > > +    break;
> > > > +  default:
> > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > +    HashAlg = HASHALG_SHA256;
> > > > +    break;
> > > > +  }
> > > >
> > > > 4) I am not sure why we need this PCD. Why cannot we support all of
> > hash
> > > > algo?
> > > >
> > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > +  #   0 - Use SHA256
> > > > +  #   1 - Use SHA384
> > > > +  #   2 - Use SHA512
> > > > +  # @Prompt Secure Boot default hash algorithm
> > > > +
> > > > +
> > > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > 00
> > > > + 010040
> > > >
> > > > 5) I don’t believe that you can use size to determine the algorithm. We
> > need
> > > > a more robust way, such as algorithm ID.
> > > >
> > > > +  switch (KeyLenInBytes) {
> > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > +    break;
> > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > +    break;
> > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > +    break;
> > > > +    break;
> > > >
> > > > Thank you
> > > > Yao, Jiewen
> > > >
> > > > > -----Original Message-----
> > > > > From: Sheng, W <w.sheng@intel.com>
> > > > > Sent: Thursday, May 25, 2023 1:23 PM
> > > > > To: devel@edk2.groups.io
> > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > > > <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>; Chen,
> > Zeyi
> > > > > <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > > > Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > 384
> > > > >
> > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> > > > >
> > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > > > Cc: Min Xu <min.m.xu@intel.com>
> > > > > Cc: Zeyi Chen <zeyi.chen@intel.com>
> > > > > Cc: Fiona Wang <fiona.wang@intel.com>
> > > > > Signed-off-by: Sheng Wei <w.sheng@intel.com>
> > > > > ---
> > > > >  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
> > > > >  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
> > > > >  MdePkg/MdePkg.dec                             |   2 +
> > > > >  .../Library/AuthVariableLib/AuthService.c     | 272 ++++++++++++++++-
> > -
> > > > >  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
> > > > >  .../DxeImageVerificationLib.c                 |  35 ++-
> > > > >  .../DxeImageVerificationLib.inf               |   1 +
> > > > >  SecurityPkg/SecurityPkg.dec                   |   7 +
> > > > >  .../SecureBootConfigDxe.inf                   |  19 ++
> > > > >  .../SecureBootConfigImpl.c                    | 122 +++++++-
> > > > >  .../SecureBootConfigImpl.h                    |   2 +
> > > > >  .../SecureBootConfigStrings.uni               |   6 +
> > > > >  12 files changed, 463 insertions(+), 36 deletions(-)
> > > > >
> > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> > > > > b/CryptoPkg/Library/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.
> > > > >
> > > > >    //
> > > > >
> > > > >    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest
> > (EVP_sha1
> > > > > ()) == 0)
> > > > > ||
> > > > >
> > > > > -      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias
> > > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > > >
> > > > > +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest
> > > > > + (EVP_sha384 ())
> > > > > == 0) ||
> > > > >
> > > > > +      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias
> > > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > > >
> > > > >    {
> > > > >
> > > > >      return FALSE;
> > > > >
> > > > >    }
> > > > >
> > > > > diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> > > > > b/MdePkg/Include/Guid/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} \
> > > > >
> > > > >    }
> > > > >
> > > > >
> > > > >
> > > > > +///
> > > > >
> > > > > +/// This identifies a signature containing an RSA-3072 key. The key
> > > > > +(only the
> > > > > modulus
> > > > >
> > > > > +/// since the public key exponent is known to be 0x10001) shall be
> > > > > +stored in big-
> > > > > endian
> > > > >
> > > > > +/// order.
> > > > >
> > > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > > +shall always
> > > > > be 16 (size
> > > > >
> > > > > +/// of SignatureOwner component) + 384 bytes.
> > > > >
> > > > > +///
> > > > >
> > > > > +#define EFI_CERT_RSA3072_GUID \
> > > > >
> > > > > +  { \
> > > > >
> > > > > +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89,
> > > > > + 0xee,
> > > > > 0x92 } \
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +///
> > > > >
> > > > > +/// This identifies a signature containing an RSA-4096 key. The key
> > > > > +(only the
> > > > > modulus
> > > > >
> > > > > +/// since the public key exponent is known to be 0x10001) shall be
> > > > > +stored in big-
> > > > > endian
> > > > >
> > > > > +/// order.
> > > > >
> > > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > > +shall always
> > > > > be 16 (size
> > > > >
> > > > > +/// of SignatureOwner component) + 512 bytes.
> > > > >
> > > > > +///
> > > > >
> > > > > +#define EFI_CERT_RSA4096_GUID \
> > > > >
> > > > > +  { \
> > > > >
> > > > > +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00,
> > > > > + 0x98,
> > > > > 0x2c } \
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > >  ///
> > > > >
> > > > >  /// This identifies a signature containing a RSA-2048 signature of a
> > > > > SHA-256 hash.  The
> > > > >
> > > > >  /// SignatureHeader size shall always be 0. The SignatureSize shall
> > > > > always be 16 (size of
> > > > >
> > > > > @@ -330,6 +354,8 @@ typedef struct {
> > > > >  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> > > > >
> > > > >  extern EFI_GUID  gEfiCertSha256Guid;
> > > > >
> > > > >  extern EFI_GUID  gEfiCertRsa2048Guid;
> > > > >
> > > > > +extern EFI_GUID  gEfiCertRsa3072Guid;
> > > > >
> > > > > +extern EFI_GUID  gEfiCertRsa4096Guid;
> > > > >
> > > > >  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> > > > >
> > > > >  extern EFI_GUID  gEfiCertSha1Guid;
> > > > >
> > > > >  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> > > > >
> > > > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > > > > 80b6559053..782f6d184d 100644
> > > > > --- a/MdePkg/MdePkg.dec
> > > > > +++ b/MdePkg/MdePkg.dec
> > > > > @@ -562,6 +562,8 @@
> > > > >    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596,
> > > > > {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> > > > >
> > > > >    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9,
> > > > 0x41,
> > > > > 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> > > > >
> > > > >    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa,
> 0x14,
> > > > 0xed,
> > > > > 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> > > > >
> > > > > +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad,
> > 0x46,
> > > > > 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> > > > >
> > > > > +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85,
> > 0x73,
> > > > > 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> > > > >
> > > > >    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad,
> > > > 0x8d,
> > > > > 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> > > > >
> > > > >    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87,
> > > 0xbe,
> > > > > 0x1, 0x49, 0x66, 0x31, 0xbd }}
> > > > >
> > > > >    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3,
> > 0x28,
> > > > > 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> > > > >
> > > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > index 452ed491ea..288e44a359 100644
> > > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > > #include <Protocol/VariablePolicy.h>
> > > > >
> > > > >  #include <Library/VariablePolicyLib.h>
> > > > >
> > > > >
> > > > >
> > > > > +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> > > > >
> > > > > +
> > > > >
> > > > >  //
> > > > >
> > > > >  // Public Exponent of RSA Key.
> > > > >
> > > > >  //
> > > > >
> > > > >  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> > > > >
> > > > >
> > > > >
> > > > >  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > 0x03, 0x04, 0x02, 0x01 };
> > > > >
> > > > > +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > +0x03,
> > > > > 0x04, 0x02, 0x02 };
> > > > >
> > > > > +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > +0x03,
> > > > > 0x04, 0x02, 0x03 };
> > > > >
> > > > >
> > > > >
> > > > >  //
> > > > >
> > > > >  // Requirement for different signature type which have been defined
> > > > > in UEFI spec.
> > > > >
> > > > > @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
> > > > >    // {SigType,                       SigHeaderSize,   SigDataSize  }
> > > > >
> > > > >    { EFI_CERT_SHA256_GUID,         0, 32            },
> > > > >
> > > > >    { EFI_CERT_RSA2048_GUID,        0, 256           },
> > > > >
> > > > > +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> > > > >
> > > > > +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> > > > >
> > > > >    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> > > > >
> > > > >    { EFI_CERT_SHA1_GUID,           0, 20            },
> > > > >
> > > > >    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> > > > >
> > > > > @@ -1172,6 +1178,172 @@
> > CalculatePrivAuthVarSignChainSHA256Digest (
> > > > >    return EFI_SUCCESS;
> > > > >
> > > > >  }
> > > > >
> > > > >
> > > > >
> > > > > +/**
> > > > >
> > > > > +  Calculate SHA38 digest of SignerCert CommonName + ToplevelCert
> > > > > tbsCertificate
> > > > >
> > > > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > > > >
> > > > > +
> > > > >
> > > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > > >
> > > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > > >
> > > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > > >
> > > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > > >
> > > > > +  @param[out] Sha384Digest       Sha384 digest calculated.
> > > > >
> > > > > +
> > > > >
> > > > > +  @return EFI_ABORTED          Digest process failed.
> > > > >
> > > > > +  @return EFI_SUCCESS          SHA384 Digest is successfully calculated.
> > > > >
> > > > > +
> > > > >
> > > > > +**/
> > > > >
> > > > > +EFI_STATUS
> > > > >
> > > > > +CalculatePrivAuthVarSignChainSHA384Digest (
> > > > >
> > > > > +  IN     UINT8  *SignerCert,
> > > > >
> > > > > +  IN     UINTN  SignerCertSize,
> > > > >
> > > > > +  IN     UINT8  *TopLevelCert,
> > > > >
> > > > > +  IN     UINTN  TopLevelCertSize,
> > > > >
> > > > > +  OUT    UINT8  *Sha384Digest
> > > > >
> > > > > +  )
> > > > >
> > > > > +{
> > > > >
> > > > > +  UINT8       *TbsCert;
> > > > >
> > > > > +  UINTN       TbsCertSize;
> > > > >
> > > > > +  CHAR8       CertCommonName[128];
> > > > >
> > > > > +  UINTN       CertCommonNameSize;
> > > > >
> > > > > +  BOOLEAN     CryptoStatus;
> > > > >
> > > > > +  EFI_STATUS  Status;
> > > > >
> > > > > +
> > > > >
> > > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // Get SignerCert CommonName
> > > > >
> > > > > +  //
> > > > >
> > > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > > CertCommonName, &CertCommonNameSize);
> > > > >
> > > > > +  if (EFI_ERROR (Status)) {
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed
> > with
> > > > > status %x\n", __FUNCTION__, Status));
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // Get TopLevelCert tbsCertificate
> > > > >
> > > > > +  //
> > > > >
> > > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > > &TbsCertSize)) {
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > > + failed!\n",
> > > > > __FUNCTION__));
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > > >
> > > > > +  //
> > > > >
> > > > > +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> > > > >
> > > > > +  CryptoStatus = Sha384Init (mHashCtx);
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > > >
> > > > > +  //
> > > > >
> > > > > +  CryptoStatus = Sha384Update (
> > > > >
> > > > > +                   mHashCtx,
> > > > >
> > > > > +                   CertCommonName,
> > > > >
> > > > > +                   AsciiStrLen (CertCommonName)
> > > > >
> > > > > +                   );
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  return EFI_SUCCESS;
> > > > >
> > > > > +}
> > > > >
> > > > > +
> > > > >
> > > > > +/**
> > > > >
> > > > > +  Calculate SHA512 digest of SignerCert CommonName + ToplevelCert
> > > > > tbsCertificate
> > > > >
> > > > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > > > >
> > > > > +
> > > > >
> > > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > > >
> > > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > > >
> > > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > > >
> > > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > > >
> > > > > +  @param[out] Sha512Digest       Sha512 digest calculated.
> > > > >
> > > > > +
> > > > >
> > > > > +  @return EFI_ABORTED          Digest process failed.
> > > > >
> > > > > +  @return EFI_SUCCESS          SHA512 Digest is successfully calculated.
> > > > >
> > > > > +
> > > > >
> > > > > +**/
> > > > >
> > > > > +EFI_STATUS
> > > > >
> > > > > +CalculatePrivAuthVarSignChainSHA512Digest (
> > > > >
> > > > > +  IN     UINT8  *SignerCert,
> > > > >
> > > > > +  IN     UINTN  SignerCertSize,
> > > > >
> > > > > +  IN     UINT8  *TopLevelCert,
> > > > >
> > > > > +  IN     UINTN  TopLevelCertSize,
> > > > >
> > > > > +  OUT    UINT8  *Sha512Digest
> > > > >
> > > > > +  )
> > > > >
> > > > > +{
> > > > >
> > > > > +  UINT8       *TbsCert;
> > > > >
> > > > > +  UINTN       TbsCertSize;
> > > > >
> > > > > +  CHAR8       CertCommonName[128];
> > > > >
> > > > > +  UINTN       CertCommonNameSize;
> > > > >
> > > > > +  BOOLEAN     CryptoStatus;
> > > > >
> > > > > +  EFI_STATUS  Status;
> > > > >
> > > > > +
> > > > >
> > > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // Get SignerCert CommonName
> > > > >
> > > > > +  //
> > > > >
> > > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > > CertCommonName, &CertCommonNameSize);
> > > > >
> > > > > +  if (EFI_ERROR (Status)) {
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed
> > with
> > > > > status %x\n", __FUNCTION__, Status));
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // Get TopLevelCert tbsCertificate
> > > > >
> > > > > +  //
> > > > >
> > > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > > &TbsCertSize)) {
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > > + failed!\n",
> > > > > __FUNCTION__));
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > > >
> > > > > +  //
> > > > >
> > > > > +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> > > > >
> > > > > +  CryptoStatus = Sha512Init (mHashCtx);
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  //
> > > > >
> > > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > > >
> > > > > +  //
> > > > >
> > > > > +  CryptoStatus = Sha512Update (
> > > > >
> > > > > +                   mHashCtx,
> > > > >
> > > > > +                   CertCommonName,
> > > > >
> > > > > +                   AsciiStrLen (CertCommonName)
> > > > >
> > > > > +                   );
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> > > > >
> > > > > +  if (!CryptoStatus) {
> > > > >
> > > > > +    return EFI_ABORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > > +  return EFI_SUCCESS;
> > > > >
> > > > > +}
> > > > >
> > > > > +
> > > > >
> > > > >  /**
> > > > >
> > > > >    Find matching signer's certificates for common authenticated
> > > > > variable
> > > > >
> > > > >    by corresponding VariableName and VendorGuid from "certdb" or
> > > > "certdbv".
> > > > >
> > > > > @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
> > > > >    @param[in]  SignerCertSize    Length of signer certificate.
> > > > >
> > > > >    @param[in]  TopLevelCert      Top-level certificate data.
> > > > >
> > > > >    @param[in]  TopLevelCertSize  Length of top-level certificate.
> > > > >
> > > > > +  @param[in]  DigestSize        Digest Size.
> > > > >
> > > > >
> > > > >
> > > > >    @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
> > > > >
> > > > >    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with
> > > > same
> > > > > VariableName
> > > > >
> > > > > @@ -1542,7 +1715,8 @@ InsertCertsToDb (
> > > > >    IN     UINT8     *SignerCert,
> > > > >
> > > > >    IN     UINTN     SignerCertSize,
> > > > >
> > > > >    IN     UINT8     *TopLevelCert,
> > > > >
> > > > > -  IN     UINTN     TopLevelCertSize
> > > > >
> > > > > +  IN     UINTN     TopLevelCertSize,
> > > > >
> > > > > +  IN     UINT32    DigestSize
> > > > >
> > > > >    )
> > > > >
> > > > >  {
> > > > >
> > > > >    EFI_STATUS         Status;
> > > > >
> > > > > @@ -1556,7 +1730,7 @@ InsertCertsToDb (
> > > > >    UINT32             CertDataSize;
> > > > >
> > > > >    AUTH_CERT_DB_DATA  *Ptr;
> > > > >
> > > > >    CHAR16             *DbName;
> > > > >
> > > > > -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> > > > >
> > > > > +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > > >
> > > > >
> > > > >
> > > > >    if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert
> > > > > == NULL)
> > > > > || (TopLevelCert == NULL)) {
> > > > >
> > > > >      return EFI_INVALID_PARAMETER;
> > > > >
> > > > > @@ -1618,20 +1792,41 @@ InsertCertsToDb (
> > > > >    // Construct new data content of variable "certdb" or "certdbv".
> > > > >
> > > > >    //
> > > > >
> > > > >    NameSize      = (UINT32)StrLen (VariableName);
> > > > >
> > > > > -  CertDataSize  = sizeof (Sha256Digest);
> > > > >
> > > > > +  CertDataSize  = DigestSize;
> > > > >
> > > > >    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) +
> > (UINT32)CertDataSize +
> > > > > NameSize * sizeof (CHAR16);
> > > > >
> > > > >    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> > > > >
> > > > >    if (NewCertDbSize > mMaxCertDbSize) {
> > > > >
> > > > >      return EFI_OUT_OF_RESOURCES;
> > > > >
> > > > >    }
> > > > >
> > > > >
> > > > >
> > > > > -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > >
> > > > > -             SignerCert,
> > > > >
> > > > > -             SignerCertSize,
> > > > >
> > > > > -             TopLevelCert,
> > > > >
> > > > > -             TopLevelCertSize,
> > > > >
> > > > > -             Sha256Digest
> > > > >
> > > > > -             );
> > > > >
> > > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > > >
> > > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > >
> > > > > +               SignerCert,
> > > > >
> > > > > +               SignerCertSize,
> > > > >
> > > > > +               TopLevelCert,
> > > > >
> > > > > +               TopLevelCertSize,
> > > > >
> > > > > +               ShaDigest
> > > > >
> > > > > +               );
> > > > >
> > > > > +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> > > > >
> > > > > +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> > > > >
> > > > > +               SignerCert,
> > > > >
> > > > > +               SignerCertSize,
> > > > >
> > > > > +               TopLevelCert,
> > > > >
> > > > > +               TopLevelCertSize,
> > > > >
> > > > > +               ShaDigest
> > > > >
> > > > > +               );
> > > > >
> > > > > +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> > > > >
> > > > > +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> > > > >
> > > > > +               SignerCert,
> > > > >
> > > > > +               SignerCertSize,
> > > > >
> > > > > +               TopLevelCert,
> > > > >
> > > > > +               TopLevelCertSize,
> > > > >
> > > > > +               ShaDigest
> > > > >
> > > > > +               );
> > > > >
> > > > > +  } else {
> > > > >
> > > > > +    return EFI_UNSUPPORTED;
> > > > >
> > > > > +  }
> > > > >
> > > > > +
> > > > >
> > > > >    if (EFI_ERROR (Status)) {
> > > > >
> > > > >      return Status;
> > > > >
> > > > >    }
> > > > >
> > > > > @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> > > > >
> > > > >
> > > > >    CopyMem (
> > > > >
> > > > >      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof
> > > > > (CHAR16),
> > > > >
> > > > > -    Sha256Digest,
> > > > >
> > > > > +    ShaDigest,
> > > > >
> > > > >      CertDataSize
> > > > >
> > > > >      );
> > > > >
> > > > >
> > > > >
> > > > > @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
> > > > >    UINTN                          CertStackSize;
> > > > >
> > > > >    UINT8                          *CertsInCertDb;
> > > > >
> > > > >    UINT32                         CertsSizeinDb;
> > > > >
> > > > > -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> > > > >
> > > > > +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > > >
> > > > >    EFI_CERT_DATA                  *CertDataPtr;
> > > > >
> > > > >
> > > > >
> > > > >    //
> > > > >
> > > > > @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> > > > >
> > > > >
> > > > >    //
> > > > >
> > > > >    // SignedData.digestAlgorithms shall contain the digest algorithm
> > > > > used when preparing the
> > > > >
> > > > > -  // signature. Only a digest algorithm of SHA-256 is accepted.
> > > > >
> > > > > +  // signature. Only a digest algorithm of SHA-256, SHA-384 or
> > > > > + SHA-512 is
> > > > > accepted.
> > > > >
> > > > >    //
> > > > >
> > > > >    //    According to PKCS#7 Definition (https://www.rfc-
> > > > editor.org/rfc/rfc2315):
> > > > >
> > > > >    //        SignedData ::= SEQUENCE {
> > > > >
> > > > > @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
> > > > >               || (CompareMem (SigData + 13, &mSha256OidValue, sizeof
> > > > > (mSha256OidValue)) != 0)))
> > > > >
> > > > >         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> > > > >
> > > > >            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > TWO_BYTE_ENCODE)
> > > > >
> > > > > -             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > > > (mSha256OidValue)) != 0))))
> > > > >
> > > > > +             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > > > (mSha256OidValue)) != 0)))
> > > > >
> > > > > +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> > > > >
> > > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > > + TWO_BYTE_ENCODE)
> > > > >
> > > > > +             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof
> > > > > (mSha384OidValue)) != 0)))
> > > > >
> > > > > +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> > > > >
> > > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > + TWO_BYTE_ENCODE)
> > > > >
> > > > > +             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof
> > > > > (mSha384OidValue)) != 0)))
> > > > >
> > > > > +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> > > > >
> > > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > > + TWO_BYTE_ENCODE)
> > > > >
> > > > > +             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof
> > > > > (mSha512OidValue)) != 0)))
> > > > >
> > > > > +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> > > > >
> > > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > + TWO_BYTE_ENCODE)
> > > > >
> > > > > +             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof
> > > > > (mSha512OidValue)) != 0))))
> > > > >
> > > > >      {
> > > > >
> > > > >        return EFI_SECURITY_VIOLATION;
> > > > >
> > > > >      }
> > > > >
> > > > > @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
> > > > >                          ReadUnaligned32 ((UINT32
> > > > > *)&(CertDataPtr->CertDataLength)),
> > > > >
> > > > >                          TopLevelCert,
> > > > >
> > > > >                          TopLevelCertSize,
> > > > >
> > > > > -                        Sha256Digest
> > > > >
> > > > > +                        ShaDigest
> > > > >
> > > > > +                        );
> > > > >
> > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > + CertsInCertDb,
> > > > > CertsSizeinDb) != 0)) {
> > > > >
> > > > > +          goto Exit;
> > > > >
> > > > > +        }
> > > > >
> > > > > +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> > > > >
> > > > > +        //
> > > > >
> > > > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > > > tbsCertificate against data in CertDb
> > > > >
> > > > > +        //
> > > > >
> > > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > > >
> > > > > +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> > > > >
> > > > > +                        CertDataPtr->CertDataBuffer,
> > > > >
> > > > > +                        ReadUnaligned32 ((UINT32
> > > > > + *)&(CertDataPtr->CertDataLength)),
> > > > >
> > > > > +                        TopLevelCert,
> > > > >
> > > > > +                        TopLevelCertSize,
> > > > >
> > > > > +                        ShaDigest
> > > > >
> > > > > +                        );
> > > > >
> > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > + CertsInCertDb,
> > > > > CertsSizeinDb) != 0)) {
> > > > >
> > > > > +          goto Exit;
> > > > >
> > > > > +        }
> > > > >
> > > > > +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> > > > >
> > > > > +        //
> > > > >
> > > > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > > > tbsCertificate against data in CertDb
> > > > >
> > > > > +        //
> > > > >
> > > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > > >
> > > > > +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> > > > >
> > > > > +                        CertDataPtr->CertDataBuffer,
> > > > >
> > > > > +                        ReadUnaligned32 ((UINT32
> > > > > + *)&(CertDataPtr->CertDataLength)),
> > > > >
> > > > > +                        TopLevelCert,
> > > > >
> > > > > +                        TopLevelCertSize,
> > > > >
> > > > > +                        ShaDigest
> > > > >
> > > > >                          );
> > > > >
> > > > > -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest,
> > > > CertsInCertDb,
> > > > > CertsSizeinDb) != 0)) {
> > > > >
> > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > + CertsInCertDb,
> > > > > CertsSizeinDb) != 0)) {
> > > > >
> > > > >            goto Exit;
> > > > >
> > > > >          }
> > > > >
> > > > >        } else {
> > > > >
> > > > > @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
> > > > >                        CertDataPtr->CertDataBuffer,
> > > > >
> > > > >                        ReadUnaligned32 ((UINT32
> > > > > *)&(CertDataPtr->CertDataLength)),
> > > > >
> > > > >                        TopLevelCert,
> > > > >
> > > > > -                      TopLevelCertSize
> > > > >
> > > > > +                      TopLevelCertSize,
> > > > >
> > > > > +                      CertsSizeinDb
> > > > >
> > > > >                        );
> > > > >
> > > > >        if (EFI_ERROR (Status)) {
> > > > >
> > > > >          VerifyStatus = FALSE;
> > > > >
> > > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > index dc61ae840c..552c0e99be 100644
> > > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
> > > > >  UINT32  mPlatformMode;
> > > > >
> > > > >  UINT8   mVendorKeyState;
> > > > >
> > > > >
> > > > >
> > > > > -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > > EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID,
> > > > EFI_CERT_X509_GUID };
> > > > >
> > > > > +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > > EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID,
> > > > EFI_CERT_SHA512_GUID,
> > > > > EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID,
> > > > EFI_CERT_RSA4096_GUID,
> > > > > EFI_CERT_X509_GUID };
> > > > >
> > > > >
> > > > >
> > > > >  //
> > > > >
> > > > >  // Hash context pointer
> > > > >
> > > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > > >    //
> > > > >
> > > > >    // Initialize hash context.
> > > > >
> > > > >    //
> > > > >
> > > > > -  CtxSize  = Sha256GetContextSize ();
> > > > >
> > > > > +  CtxSize  = Sha512GetContextSize ();
> > > > >
> > > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > > >
> > > > >    if (mHashCtx == NULL) {
> > > > >
> > > > >      return EFI_OUT_OF_RESOURCES;
> > > > >
> > > > > diff --git
> > > > >
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > c
> > > > >
> > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > c
> > > > > index 66e2f5eaa3..f642aad64d 100644
> > > > > ---
> > > > >
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > c
> > > > > +++
> > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > > +++ Lib.c
> > > > > @@ -1606,6 +1606,35 @@ Done:
> > > > >    return VerifyStatus;
> > > > >
> > > > >  }
> > > > >
> > > > >
> > > > >
> > > > > +/**
> > > > >
> > > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > > >
> > > > > +
> > > > >
> > > > > +  @retval  UINT32       Hash Alg
> > > > >
> > > > > +  **/
> > > > >
> > > > > +UINT32
> > > > >
> > > > > +GetDefaultHashAlg (
> > > > >
> > > > > +  VOID
> > > > >
> > > > > +  )
> > > > >
> > > > > +{
> > > > >
> > > > > +  UINT32  HashAlg;
> > > > >
> > > > > +
> > > > >
> > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > > >
> > > > > +  case 1:
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > >
> > > > > +    HashAlg = HASHALG_SHA384;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  case 2:
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > >
> > > > > +    HashAlg = HASHALG_SHA512;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  default:
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > >
> > > > > +    HashAlg = HASHALG_SHA256;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  }
> > > > >
> > > > > +  return HashAlg;
> > > > >
> > > > > +}
> > > > >
> > > > > +
> > > > >
> > > > >  /**
> > > > >
> > > > >    Provide verification service for signed images, which include both
> > > > > signature validation
> > > > >
> > > > >    and platform policy control. For signature types, both UEFI
> > > > > WIN_CERTIFICATE_UEFI_GUID and
> > > > >
> > > > > @@ -1620,7 +1649,7 @@ Done:
> > > > >        in the security database "db", and no valid signature nor any
> > > > > hash value of the image may
> > > > >
> > > > >        be reflected in the security database "dbx".
> > > > >
> > > > >      Otherwise, the image is not signed,
> > > > >
> > > > > -      The SHA256 hash value of the image must match a record in the
> > > > security
> > > > > database "db", and
> > > > >
> > > > > +      The hash value of the image must match a record in the security
> > > > > + database
> > > > > "db", and
> > > > >
> > > > >        not be reflected in the security data base "dbx".
> > > > >
> > > > >
> > > > >
> > > > >    Caution: This function may receive untrusted input.
> > > > >
> > > > > @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
> > > > >    //
> > > > >
> > > > >    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> > > > >
> > > > >      //
> > > > >
> > > > > -    // This image is not signed. The SHA256 hash value of the image must
> > > > match
> > > > > a record in the security database "db",
> > > > >
> > > > > +    // This image is not signed. The hash value of the image must
> > > > > + match a record
> > > > > in the security database "db",
> > > > >
> > > > >      // and not be reflected in the security data base "dbx".
> > > > >
> > > > >      //
> > > > >
> > > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > > >
> > > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > > >
> > > > >        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash
> > > > > this image using %s.\n", mHashTypeStr));
> > > > >
> > > > >        goto Failed;
> > > > >
> > > > >      }
> > > > >
> > > > > diff --git
> > > > >
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > inf
> > > > >
> > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > inf
> > > > > index 1e1a639857..f1ef9236c2 100644
> > > > > ---
> > > > >
> > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > inf
> > > > > +++
> > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > > +++ Lib.inf
> > > > > @@ -93,3 +93,4 @@
> > > > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> > > > > ## SOMETIMES_CONSUMES
> > > > >
> > > > >
> > > > >
> > > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolic
> > > > y
> > > > > ## SOMETIMES_CONSUMES
> > > > >
> > > > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy
> > > > ##
> > > > > SOMETIMES_CONSUMES
> > > > >
> > > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > > ##
> > > > > CONSUMES
> > > > >
> > > > > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
> > > > > index 0382090f4e..4adc2a72ab 100644
> > > > > --- a/SecurityPkg/SecurityPkg.dec
> > > > > +++ b/SecurityPkg/SecurityPkg.dec
> > > > > @@ -521,6 +521,13 @@
> > > > >    # @Prompt Skip Hdd Password prompt.
> > > > >
> > > > >
> > > > >
> > > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLE
> > > > AN|
> > > > > 0x00010021
> > > > >
> > > > >
> > > > >
> > > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > >
> > > > > +  #   0 - Use SHA256
> > > > >
> > > > > +  #   1 - Use SHA384
> > > > >
> > > > > +  #   2 - Use SHA512
> > > > >
> > > > > +  # @Prompt Secure Boot default hash algorithm
> > > > >
> > > > > +
> > > > >
> > > >
> > gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > 00
> > > > > 0
> > > > > 10040
> > > > >
> > > > > +
> > > > >
> > > > >  [PcdsDynamic, PcdsDynamicEx]
> > > > >
> > > > >
> > > > >
> > > > >    ## This PCD indicates Hash mask for TPM 2.0. Bit definition
> > > > > strictly follows TCG Algorithm Registry.<BR><BR>
> > > > >
> > > > > diff --git
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > ig
> > > > > Dxe.inf
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > ig
> > > > > Dxe.inf
> > > > > index 1671d5be7c..4b0012d033 100644
> > > > > ---
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > ig
> > > > > Dxe.inf
> > > > > +++
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > ig
> > > > > Dxe.inf
> > > > > @@ -70,6 +70,14 @@
> > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > >    gEfiCertRsa2048Guid
> > > > >
> > > > >
> > > > >
> > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > type of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  gEfiCertRsa3072Guid
> > > > >
> > > > > +
> > > > >
> > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > type of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  gEfiCertRsa4096Guid
> > > > >
> > > > > +
> > > > >
> > > > >    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > >    gEfiCertX509Guid
> > > > >
> > > > > @@ -82,6 +90,14 @@
> > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > >    gEfiCertSha256Guid
> > > > >
> > > > >
> > > > >
> > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > type of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  gEfiCertSha384Guid
> > > > >
> > > > > +
> > > > >
> > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > type of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type
> > of
> > > > the
> > > > > signature.
> > > > >
> > > > > +  gEfiCertSha512Guid
> > > > >
> > > > > +
> > > > >
> > > > >    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> > > > >
> > > > >    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> > > > >
> > > > >    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> > > > >
> > > > > @@ -107,6 +123,9 @@
> > > > >    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES  ##
> > GUID
> > > > #
> > > > > Unique ID for the type of the certificate.
> > > > >
> > > > >    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES  ##
> > GUID
> > > > #
> > > > > Unique ID for the type of the certificate.
> > > > >
> > > > >
> > > > >
> > > > > +[Pcd]
> > > > >
> > > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > > ##
> > > > > CONSUMES
> > > > >
> > > > > +
> > > > >
> > > > >  [Protocols]
> > > > >
> > > > >    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> > > > >
> > > > >    gEfiDevicePathProtocolGuid                    ## PRODUCES
> > > > >
> > > > > diff --git
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.c
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.c
> > > > > index 4299a6b5e5..0ba029a394 100644
> > > > > ---
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.c
> > > > > +++
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.c
> > > > > @@ -560,7 +560,7 @@ ON_EXIT:
> > > > >
> > > > >
> > > > >  **/
> > > > >
> > > > >  EFI_STATUS
> > > > >
> > > > > -EnrollRsa2048ToKek (
> > > > >
> > > > > +EnrollRsaToKek (
> > > > >
> > > > >    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> > > > >
> > > > >    )
> > > > >
> > > > >  {
> > > > >
> > > > > @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> > > > >
> > > > >
> > > > >    ASSERT (KeyBlob != NULL);
> > > > >
> > > > >    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> > > > >
> > > > > -  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
> > > > >
> > > > > -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is
> > > > > supported.\n"));
> > > > >
> > > > > +  switch (KeyInfo->KeyLengthInBits / 8) {
> > > > >
> > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > >
> > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > >
> > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  default :
> > > > >
> > > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048,
> > > > > + RSA3072
> > > > > and RSA4096 are supported.\n"));
> > > > >
> > > > >      Status = EFI_UNSUPPORTED;
> > > > >
> > > > >      goto ON_EXIT;
> > > > >
> > > > >    }
> > > > >
> > > > > @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
> > > > >    //
> > > > >
> > > > >    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> > > > >
> > > > >                     + sizeof (EFI_SIGNATURE_DATA) - 1
> > > > >
> > > > > -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> > > > >
> > > > > +                   + KeyLenInBytes;
> > > > >
> > > > >
> > > > >
> > > > >    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool
> > > > > (KekSigListSize);
> > > > >
> > > > >    if (KekSigList == NULL) {
> > > > >
> > > > > @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> > > > >
> > > > >
> > > > >    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> > > > >
> > > > >                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> > > > >
> > > > > -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> > > > >
> > > > > +                                  + (UINT32) KeyLenInBytes;
> > > > >
> > > > >    KekSigList->SignatureHeaderSize = 0;
> > > > >
> > > > > -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > > > > WIN_CERT_UEFI_RSA2048_SIZE;
> > > > >
> > > > > -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > >
> > > > > +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 +
> > > > (UINT32)
> > > > > KeyLenInBytes;
> > > > >
> > > > > +  switch (KeyLenInBytes) {
> > > > >
> > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > >
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > >
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > >
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > >
> > > > > +    break;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  default :
> > > > >
> > > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> > > > >
> > > > > +    Status = EFI_UNSUPPORTED;
> > > > >
> > > > > +    goto ON_EXIT;
> > > > >
> > > > > +  }
> > > > >
> > > > >
> > > > >
> > > > >    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof
> > > > > (EFI_SIGNATURE_LIST));
> > > > >
> > > > >    CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
> > > > >
> > > > >    CopyMem (
> > > > >
> > > > >      KEKSigData->SignatureData,
> > > > >
> > > > >      KeyBlob + sizeof (CPL_KEY_INFO),
> > > > >
> > > > > -    WIN_CERT_UEFI_RSA2048_SIZE
> > > > >
> > > > > +    KeyLenInBytes
> > > > >
> > > > >      );
> > > > >
> > > > >
> > > > >
> > > > >    //
> > > > >
> > > > > @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
> > > > >    if (IsDerEncodeCertificate (FilePostFix)) {
> > > > >
> > > > >      return EnrollX509ToKek (Private);
> > > > >
> > > > >    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> > > > >
> > > > > -    return EnrollRsa2048ToKek (Private);
> > > > >
> > > > > +    return EnrollRsaToKek (Private);
> > > > >
> > > > >    } else {
> > > > >
> > > > >      //
> > > > >
> > > > >      // File type is wrong, simply close it
> > > > >
> > > > > @@ -1847,7 +1867,7 @@ HashPeImage (
> > > > >    SectionHeader = NULL;
> > > > >
> > > > >    Status        = FALSE;
> > > > >
> > > > >
> > > > >
> > > > > -  if (HashAlg != HASHALG_SHA256) {
> > > > >
> > > > > +  if ((HashAlg >= HASHALG_MAX)) {
> > > > >
> > > > >      return FALSE;
> > > > >
> > > > >    }
> > > > >
> > > > >
> > > > >
> > > > > @@ -1856,8 +1876,25 @@ HashPeImage (
> > > > >    //
> > > > >
> > > > >    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> > > > >
> > > > >
> > > > >
> > > > > -  mImageDigestSize = SHA256_DIGEST_SIZE;
> > > > >
> > > > > -  mCertType        = gEfiCertSha256Guid;
> > > > >
> > > > > +   switch (HashAlg) {
> > > > >
> > > > > +    case HASHALG_SHA256:
> > > > >
> > > > > +      mImageDigestSize = SHA256_DIGEST_SIZE;
> > > > >
> > > > > +      mCertType        = gEfiCertSha256Guid;
> > > > >
> > > > > +      break;
> > > > >
> > > > > +
> > > > >
> > > > > +    case HASHALG_SHA384:
> > > > >
> > > > > +      mImageDigestSize = SHA384_DIGEST_SIZE;
> > > > >
> > > > > +      mCertType        = gEfiCertSha384Guid;
> > > > >
> > > > > +      break;
> > > > >
> > > > > +
> > > > >
> > > > > +    case HASHALG_SHA512:
> > > > >
> > > > > +      mImageDigestSize = SHA512_DIGEST_SIZE;
> > > > >
> > > > > +      mCertType        = gEfiCertSha512Guid;
> > > > >
> > > > > +      break;
> > > > >
> > > > > +
> > > > >
> > > > > +    default:
> > > > >
> > > > > +      return FALSE;
> > > > >
> > > > > +  }
> > > > >
> > > > >
> > > > >
> > > > >    CtxSize = mHash[HashAlg].GetContextSize ();
> > > > >
> > > > >
> > > > >
> > > > > @@ -2222,6 +2259,35 @@ ON_EXIT:
> > > > >    return Status;
> > > > >
> > > > >  }
> > > > >
> > > > >
> > > > >
> > > > > +/**
> > > > >
> > > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > > >
> > > > > +
> > > > >
> > > > > +  @retval  UINT32       Hash Alg
> > > > >
> > > > > +  **/
> > > > >
> > > > > +UINT32
> > > > >
> > > > > +GetDefaultHashAlg (
> > > > >
> > > > > +  VOID
> > > > >
> > > > > +  )
> > > > >
> > > > > +{
> > > > >
> > > > > +  UINT32  HashAlg;
> > > > >
> > > > > +
> > > > >
> > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > > >
> > > > > +  case 1:
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > >
> > > > > +    HashAlg = HASHALG_SHA384;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  case 2:
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > >
> > > > > +    HashAlg = HASHALG_SHA512;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  default:
> > > > >
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > >
> > > > > +    HashAlg = HASHALG_SHA256;
> > > > >
> > > > > +    break;
> > > > >
> > > > > +  }
> > > > >
> > > > > +  return HashAlg;
> > > > >
> > > > > +}
> > > > >
> > > > > +
> > > > >
> > > > >  /**
> > > > >
> > > > >    Enroll a new signature of executable into Signature Database.
> > > > >
> > > > >
> > > > >
> > > > > @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
> > > > >    }
> > > > >
> > > > >
> > > > >
> > > > >    if (mSecDataDir->SizeOfCert == 0) {
> > > > >
> > > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > > >
> > > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > > >
> > > > >        Status =  EFI_SECURITY_VIOLATION;
> > > > >
> > > > >        goto ON_EXIT;
> > > > >
> > > > >      }
> > > > >
> > > > > @@ -2589,6 +2655,10 @@ UpdateDeletePage (
> > > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > > CertList->SignatureListSize)) {
> > > > >
> > > > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid))
> > > > > {
> > > > >
> > > > >        Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> > > > >
> > > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > > + &gEfiCertRsa3072Guid)) {
> > > > >
> > > > > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> > > > >
> > > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > > + &gEfiCertRsa4096Guid)) {
> > > > >
> > > > > +      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> > > > >
> > > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > > &gEfiCertX509Guid)) {
> > > > >
> > > > >        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> > > > >
> > > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > > &gEfiCertSha1Guid)) {
> > > > >
> > > > > @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
> > > > >    GuidIndex      = 0;
> > > > >
> > > > >    while ((KekDataSize > 0) && (KekDataSize >=
> > > > > CertList->SignatureListSize)) {
> > > > >
> > > > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > > > > ||
> > > > >
> > > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > > > > + ||
> > > > >
> > > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > > > > + ||
> > > > >
> > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
> > > > >
> > > > >      {
> > > > >
> > > > >        CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST)
> > > > > + CertList-
> > > > > >SignatureHeaderSize));
> > > > >
> > > > > @@ -2952,6 +3024,8 @@ DeleteSignature (
> > > > >    GuidIndex    = 0;
> > > > >
> > > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > > CertList->SignatureListSize)) {
> > > > >
> > > > >      if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)
> > > > > ||
> > > > >
> > > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)
> > > > > + ||
> > > > >
> > > > > +        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)
> > > > > + ||
> > > > >
> > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
> > > > >
> > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
> > > > >
> > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)
> > > > > ||
> > > > >
> > > > > @@ -3758,12 +3832,20 @@ LoadSignatureList (
> > > > >    while ((RemainingSize > 0) && (RemainingSize >=
> > > > > ListWalker->SignatureListSize)) {
> > > > >
> > > > >      if (CompareGuid (&ListWalker->SignatureType,
> > > > > &gEfiCertRsa2048Guid)) {
> > > > >
> > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > > >
> > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > + &gEfiCertRsa3072Guid))
> > > > > {
> > > > >
> > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > > >
> > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > + &gEfiCertRsa4096Guid))
> > > > > {
> > > > >
> > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > > >
> > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > &gEfiCertX509Guid)) {
> > > > >
> > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > > >
> > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > &gEfiCertSha1Guid)) {
> > > > >
> > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> > > > >
> > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > &gEfiCertSha256Guid)) {
> > > > >
> > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > > >
> > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > + &gEfiCertSha384Guid))
> > > > > {
> > > > >
> > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > > >
> > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > + &gEfiCertSha512Guid))
> > > > > {
> > > > >
> > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > > >
> > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > &gEfiCertX509Sha256Guid)) {
> > > > >
> > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > > >
> > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > &gEfiCertX509Sha384Guid)) {
> > > > >
> > > > > @@ -4001,6 +4083,14 @@ FormatHelpInfo (
> > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > > >
> > > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > >
> > > > >      IsCert     = TRUE;
> > > > >
> > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > + &gEfiCertRsa3072Guid)) {
> > > > >
> > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > > >
> > > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > >
> > > > > +    IsCert     = TRUE;
> > > > >
> > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > + &gEfiCertRsa4096Guid)) {
> > > > >
> > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > > >
> > > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > >
> > > > > +    IsCert     = TRUE;
> > > > >
> > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > &gEfiCertX509Guid)) {
> > > > >
> > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > > >
> > > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > >
> > > > > @@ -4011,6 +4101,12 @@ FormatHelpInfo (
> > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > &gEfiCertSha256Guid)) {
> > > > >
> > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > > >
> > > > >      DataSize   = 32;
> > > > >
> > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > + &gEfiCertSha384Guid)) {
> > > > >
> > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > > >
> > > > > +    DataSize   = 48;
> > > > >
> > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > + &gEfiCertSha512Guid)) {
> > > > >
> > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > > >
> > > > > +    DataSize   = 64;
> > > > >
> > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > &gEfiCertX509Sha256Guid)) {
> > > > >
> > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > > >
> > > > >      DataSize   = 32;
> > > > >
> > > > > diff --git
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.h
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.h
> > > > > index 37c66f1b95..ae50d929a7 100644
> > > > > ---
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.h
> > > > > +++
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igI
> > > > > mpl.h
> > > > > @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
> > #define
> > > > > MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> > > > >
> > > > >
> > > > >
> > > > >  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> > > > >
> > > > > +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> > > > >
> > > > > +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> > > > >
> > > > >
> > > > >
> > > > >  //
> > > > >
> > > > >  // Support hash types
> > > > >
> > > > > diff --git
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igS
> > > > > trings.uni
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igS
> > > > > trings.uni
> > > > > index 0d01701de7..1b48acc800 100644
> > > > > ---
> > > > >
> > > >
> > a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igS
> > > > > trings.uni
> > > > > +++
> > > > >
> > > >
> > b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > f
> > > > > igS
> > > > > trings.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"
> > > > >
> > > > >  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File
> > > > Explorer"
> > > > >
> > > > >  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US
> > > > > "RSA2048_SHA256_GUID"
> > > > >
> > > > > +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US
> > > > > "RSA3072_SHA384_GUID"
> > > > >
> > > > > +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US
> > > > > "RSA4096_SHA512_GUID"
> > > > >
> > > > >  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US
> > > > "PKCS7_GUID"
> > > > >
> > > > >  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US
> > > > "SHA1_GUID"
> > > > >
> > > > >  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> > > > > "SHA256_GUID"
> > > > >
> > > > > @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > > > >  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US
> > > > > "X509_SHA512_GUID"
> > > > >
> > > > >
> > > > >
> > > > >  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> > > > > "RSA2048_SHA256"
> > > > >
> > > > > +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> > > > > "RSA3072_SHA384"
> > > > >
> > > > > +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> > > > > "RSA4096_SHA512"
> > > > >
> > > > >  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> > > > >
> > > > >  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> > > > >
> > > > >  #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
> > > > >
> > > > > +#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
> > > > >
> > > > > +#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
> > > > >
> > > > >  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> > > > > "X509_SHA256"
> > > > >
> > > > >  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> > > > > "X509_SHA384"
> > > > >
> > > > >  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> > > > > "X509_SHA512"
> > > > >
> > > > > --
> > > > > 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106679): https://edk2.groups.io/g/devel/message/106679
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Sheng Wei 9 months, 3 weeks ago
Hi Jiewen,
As your suggestion.
I will check if CPL_KEY_INFO. KeyType == 0 first.
If true, I will use below table to select RSA algorithm.
KeyLengthInBits    RSA algorithm
2048                        RSA 2K
3072                        RSA 3K
4096                        RSA 4K
Do you have any comment about this solution ?

Thank you
BR
Sheng Wei


> -----Original Message-----
> From: Yao, Jiewen <jiewen.yao@intel.com>
> Sent: 2023年7月6日 15:06
> To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> <fiona.wang@intel.com>
> Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> CPL_KEY_INFO is not standard, but implementation choice.
> 
> I notice KeyType field is not used today. I assume it is 0 today.
> 
> Can we use 0 to indicate RSASSA?
> 
> Thank you
> Yao, Jiewen
> 
> 
> 
> > -----Original Message-----
> > From: Sheng, W <w.sheng@intel.com>
> > Sent: Thursday, July 6, 2023 2:48 PM
> > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> <min.m.xu@intel.com>;
> > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> 384
> >
> > Hi Jiewen,
> > I raised the patch V3, And I also attached the patch file.
> > For 4,
> > My solution is below.
> > When enroll the unsigned image, BIOS will select the most supported
> complex
> > hash algorithm to get the hash.
> > When do the verification, BIOS will try all supported hash algorithm in "db"
> and
> > "dbx".
> >
> > For 5.
> > The struct of CPL_KEY_INFO should be binded to .pbk file format.
> > I cannot find the spec of .pbk file. I can not change the struct items.
> > Do you know where to find the spec of public key storing file (*.pbk) ?
> > Or is *.pbk file a legacy file format? We do not need to change this part and
> > keep it for RSA 2048 only ?
> >
> > Thank you
> > BR
> > Sheng Wei
> >
> > > -----Original Message-----
> > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > Sent: 2023年6月30日 19:57
> > > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > > <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> > > <fiona.wang@intel.com>
> > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> 384
> > >
> > > For 4, I think we can enroll all supported algorithms, or the active
> algorithm. I
> > > don’t think the PCD is needed.
> > >
> > > For 5, I suggest to change the data structure to include the algorithm ID.
> > >
> > > Thank you
> > > Yao, Jiewen
> > >
> > >
> > > > -----Original Message-----
> > > > From: Sheng, W <w.sheng@intel.com>
> > > > Sent: Friday, June 30, 2023 3:52 PM
> > > > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > > <min.m.xu@intel.com>;
> > > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> <fiona.wang@intel.com>
> > > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > > 384
> > > >
> > > > Hi Jiewen,
> > > > I raised the patch V2.
> > > > I do the fix for 1) , 2), 3).
> > > > But for 4) 5), I have below comments.
> > > >
> > > > 4) I am not sure why we need this PCD. Why cannot we support all of
> hash
> > > algo?
> > > >
> > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > +  #   0 - Use SHA256
> > > > +  #   1 - Use SHA384
> > > > +  #   2 - Use SHA512
> > > > +  # @Prompt Secure Boot default hash algorithm
> > > > +
> > > > +
> > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > 00
> > > > + 010040
> > > >
> > > > PCD PcdSecureBootDefaultHashAlg is used for the only case of enroll an
> > > > unsigned image.
> > > > The original logic is BIOS will genrate SHA256 digest for this unsigned
> image
> > > and
> > > > save it.
> > > > The PCD is used to select the hash algorithm for this case.
> > > > So we have to use a PCD to select the algorithm manully.
> > > >
> > > >
> > > > 5) I don’t believe that you can use size to determine the algorithm. We
> > > need a
> > > > more robust way, such as algorithm ID.
> > > >
> > > > +  switch (KeyLenInBytes) {
> > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > +    break;
> > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > +    break;
> > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > +    break;
> > > > +    break;
> > > >
> > > > This code is used when enroll a RSA public key storing file (*.pbk).
> > > > Here is the header Struct of this file.
> > > > typedef struct _CPL_KEY_INFO {
> > > >   UINT32    KeyLengthInBits;        // Key Length In Bits
> > > >   UINT32    BlockSize;              // Operation Block Size in Bytes
> > > >   UINT32    CipherBlockSize;        // Output Cipher Block Size in Bytes
> > > >   UINT32    KeyType;                // Key Type
> > > >   UINT32    CipherMode;             // Cipher Mode for Symmetric Algorithm
> > > >   UINT32    Flags;                  // Additional Key Property Flags
> > > > } CPL_KEY_INFO;
> > > >
> > >
> Edk2/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBoot
> > > Con
> > > > figImpl.h
> > > > We can only get to know the RSA algorithm by KeyLengthInBits.
> > > > (RSA2048/RSA3072/RSA4096)
> > > >
> > > > Thank you.
> > > > BR
> > > > Sheng Wei
> > > >
> > > > > -----Original Message-----
> > > > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > > > Sent: 2023年6月22日 15:22
> > > > > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > > > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > > <min.m.xu@intel.com>;
> > > > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> <fiona.wang@intel.com>
> > > > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and
> RSA
> > > 384
> > > > >
> > > > > Thank you very much to contribute this patch. Here is my feedback.
> > > > >
> > > > > 1) I don’t believe that you cannot use digest size to determine the
> > > algorithm,
> > > > > because different hash algorithm may have same time. E.g. SHA256
> and
> > > > > SHA3_256.
> > > > >
> > > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > +               SignerCert,
> > > > > +               SignerCertSize,
> > > > > +               TopLevelCert,
> > > > > +               TopLevelCertSize,
> > > > > +               ShaDigest
> > > > > +               );
> > > > >
> > > > > 2) I don’t believe that you cannot assuming CtxSize of SHA512 is
> bigger
> > > than
> > > > > SHA256. I think we may need create context for each algo.
> > > > >
> > > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > > >    //
> > > > >    // Initialize hash context.
> > > > >    //
> > > > > -  CtxSize  = Sha256GetContextSize ();
> > > > > +  CtxSize  = Sha512GetContextSize ();
> > > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > > >    if (mHashCtx == NULL) {
> > > > >
> > > > > 3) I believe we should use 0 for SHA256 and ASSERT in default.
> > > > >
> > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {  case 1:
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > > +    HashAlg = HASHALG_SHA384;
> > > > > +    break;
> > > > > +  case 2:
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > > +    HashAlg = HASHALG_SHA512;
> > > > > +    break;
> > > > > +  default:
> > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > > +    HashAlg = HASHALG_SHA256;
> > > > > +    break;
> > > > > +  }
> > > > >
> > > > > 4) I am not sure why we need this PCD. Why cannot we support all of
> > > hash
> > > > > algo?
> > > > >
> > > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > > +  #   0 - Use SHA256
> > > > > +  #   1 - Use SHA384
> > > > > +  #   2 - Use SHA512
> > > > > +  # @Prompt Secure Boot default hash algorithm
> > > > > +
> > > > > +
> > > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > > 00
> > > > > + 010040
> > > > >
> > > > > 5) I don’t believe that you can use size to determine the algorithm.
> We
> > > need
> > > > > a more robust way, such as algorithm ID.
> > > > >
> > > > > +  switch (KeyLenInBytes) {
> > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > > +    break;
> > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > > +    break;
> > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > > +    break;
> > > > > +    break;
> > > > >
> > > > > Thank you
> > > > > Yao, Jiewen
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Sheng, W <w.sheng@intel.com>
> > > > > > Sent: Thursday, May 25, 2023 1:23 PM
> > > > > > To: devel@edk2.groups.io
> > > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > > > > <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>; Chen,
> > > Zeyi
> > > > > > <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > > > > Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > > 384
> > > > > >
> > > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> > > > > >
> > > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > > > > Cc: Min Xu <min.m.xu@intel.com>
> > > > > > Cc: Zeyi Chen <zeyi.chen@intel.com>
> > > > > > Cc: Fiona Wang <fiona.wang@intel.com>
> > > > > > Signed-off-by: Sheng Wei <w.sheng@intel.com>
> > > > > > ---
> > > > > >  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
> > > > > >  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
> > > > > >  MdePkg/MdePkg.dec                             |   2 +
> > > > > >  .../Library/AuthVariableLib/AuthService.c     | 272
> ++++++++++++++++-
> > > -
> > > > > >  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
> > > > > >  .../DxeImageVerificationLib.c                 |  35 ++-
> > > > > >  .../DxeImageVerificationLib.inf               |   1 +
> > > > > >  SecurityPkg/SecurityPkg.dec                   |   7 +
> > > > > >  .../SecureBootConfigDxe.inf                   |  19 ++
> > > > > >  .../SecureBootConfigImpl.c                    | 122 +++++++-
> > > > > >  .../SecureBootConfigImpl.h                    |   2 +
> > > > > >  .../SecureBootConfigStrings.uni               |   6 +
> > > > > >  12 files changed, 463 insertions(+), 36 deletions(-)
> > > > > >
> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> > > > > > b/CryptoPkg/Library/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.
> > > > > >
> > > > > >    //
> > > > > >
> > > > > >    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest
> > > (EVP_sha1
> > > > > > ()) == 0)
> > > > > > ||
> > > > > >
> > > > > > -      (EVP_add_digest (EVP_sha256 ()) == 0) ||
> ((EVP_add_digest_alias
> > > > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > > > >
> > > > > > +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest
> > > > > > + (EVP_sha384 ())
> > > > > > == 0) ||
> > > > > >
> > > > > > +      (EVP_add_digest (EVP_sha512 ()) == 0) ||
> ((EVP_add_digest_alias
> > > > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > > > >
> > > > > >    {
> > > > > >
> > > > > >      return FALSE;
> > > > > >
> > > > > >    }
> > > > > >
> > > > > > diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> > > > > > b/MdePkg/Include/Guid/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} \
> > > > > >
> > > > > >    }
> > > > > >
> > > > > >
> > > > > >
> > > > > > +///
> > > > > >
> > > > > > +/// This identifies a signature containing an RSA-3072 key. The key
> > > > > > +(only the
> > > > > > modulus
> > > > > >
> > > > > > +/// since the public key exponent is known to be 0x10001) shall be
> > > > > > +stored in big-
> > > > > > endian
> > > > > >
> > > > > > +/// order.
> > > > > >
> > > > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > > > +shall always
> > > > > > be 16 (size
> > > > > >
> > > > > > +/// of SignatureOwner component) + 384 bytes.
> > > > > >
> > > > > > +///
> > > > > >
> > > > > > +#define EFI_CERT_RSA3072_GUID \
> > > > > >
> > > > > > +  { \
> > > > > >
> > > > > > +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89,
> > > > > > + 0xee,
> > > > > > 0x92 } \
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +///
> > > > > >
> > > > > > +/// This identifies a signature containing an RSA-4096 key. The key
> > > > > > +(only the
> > > > > > modulus
> > > > > >
> > > > > > +/// since the public key exponent is known to be 0x10001) shall be
> > > > > > +stored in big-
> > > > > > endian
> > > > > >
> > > > > > +/// order.
> > > > > >
> > > > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > > > +shall always
> > > > > > be 16 (size
> > > > > >
> > > > > > +/// of SignatureOwner component) + 512 bytes.
> > > > > >
> > > > > > +///
> > > > > >
> > > > > > +#define EFI_CERT_RSA4096_GUID \
> > > > > >
> > > > > > +  { \
> > > > > >
> > > > > > +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00,
> > > > > > + 0x98,
> > > > > > 0x2c } \
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  ///
> > > > > >
> > > > > >  /// This identifies a signature containing a RSA-2048 signature of a
> > > > > > SHA-256 hash.  The
> > > > > >
> > > > > >  /// SignatureHeader size shall always be 0. The SignatureSize shall
> > > > > > always be 16 (size of
> > > > > >
> > > > > > @@ -330,6 +354,8 @@ typedef struct {
> > > > > >  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> > > > > >
> > > > > >  extern EFI_GUID  gEfiCertSha256Guid;
> > > > > >
> > > > > >  extern EFI_GUID  gEfiCertRsa2048Guid;
> > > > > >
> > > > > > +extern EFI_GUID  gEfiCertRsa3072Guid;
> > > > > >
> > > > > > +extern EFI_GUID  gEfiCertRsa4096Guid;
> > > > > >
> > > > > >  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> > > > > >
> > > > > >  extern EFI_GUID  gEfiCertSha1Guid;
> > > > > >
> > > > > >  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> > > > > >
> > > > > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > > > > > 80b6559053..782f6d184d 100644
> > > > > > --- a/MdePkg/MdePkg.dec
> > > > > > +++ b/MdePkg/MdePkg.dec
> > > > > > @@ -562,6 +562,8 @@
> > > > > >    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596,
> > > > > > {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> > > > > >
> > > > > >    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac,
> 0xa9,
> > > > > 0x41,
> > > > > > 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> > > > > >
> > > > > >    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa,
> > 0x14,
> > > > > 0xed,
> > > > > > 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> > > > > >
> > > > > > +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad,
> > > 0x46,
> > > > > > 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> > > > > >
> > > > > > +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85,
> > > 0x73,
> > > > > > 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> > > > > >
> > > > > >    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d,
> {0xad,
> > > > > 0x8d,
> > > > > > 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> > > > > >
> > > > > >    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1,
> 0x87,
> > > > 0xbe,
> > > > > > 0x1, 0x49, 0x66, 0x31, 0xbd }}
> > > > > >
> > > > > >    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3,
> > > 0x28,
> > > > > > 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> > > > > >
> > > > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > index 452ed491ea..288e44a359 100644
> > > > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-
> Patent
> > > > > > #include <Protocol/VariablePolicy.h>
> > > > > >
> > > > > >  #include <Library/VariablePolicyLib.h>
> > > > > >
> > > > > >
> > > > > >
> > > > > > +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  //
> > > > > >
> > > > > >  // Public Exponent of RSA Key.
> > > > > >
> > > > > >  //
> > > > > >
> > > > > >  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> > > > > >
> > > > > >
> > > > > >
> > > > > >  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > > 0x03, 0x04, 0x02, 0x01 };
> > > > > >
> > > > > > +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > > +0x03,
> > > > > > 0x04, 0x02, 0x02 };
> > > > > >
> > > > > > +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > > +0x03,
> > > > > > 0x04, 0x02, 0x03 };
> > > > > >
> > > > > >
> > > > > >
> > > > > >  //
> > > > > >
> > > > > >  // Requirement for different signature type which have been
> defined
> > > > > > in UEFI spec.
> > > > > >
> > > > > > @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
> > > > > >    // {SigType,                       SigHeaderSize,   SigDataSize  }
> > > > > >
> > > > > >    { EFI_CERT_SHA256_GUID,         0, 32            },
> > > > > >
> > > > > >    { EFI_CERT_RSA2048_GUID,        0, 256           },
> > > > > >
> > > > > > +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> > > > > >
> > > > > > +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> > > > > >
> > > > > >    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> > > > > >
> > > > > >    { EFI_CERT_SHA1_GUID,           0, 20            },
> > > > > >
> > > > > >    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> > > > > >
> > > > > > @@ -1172,6 +1178,172 @@
> > > CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > >    return EFI_SUCCESS;
> > > > > >
> > > > > >  }
> > > > > >
> > > > > >
> > > > > >
> > > > > > +/**
> > > > > >
> > > > > > +  Calculate SHA38 digest of SignerCert CommonName +
> ToplevelCert
> > > > > > tbsCertificate
> > > > > >
> > > > > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > > > >
> > > > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > > > >
> > > > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > > > >
> > > > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > > > >
> > > > > > +  @param[out] Sha384Digest       Sha384 digest calculated.
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  @return EFI_ABORTED          Digest process failed.
> > > > > >
> > > > > > +  @return EFI_SUCCESS          SHA384 Digest is successfully
> calculated.
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +**/
> > > > > >
> > > > > > +EFI_STATUS
> > > > > >
> > > > > > +CalculatePrivAuthVarSignChainSHA384Digest (
> > > > > >
> > > > > > +  IN     UINT8  *SignerCert,
> > > > > >
> > > > > > +  IN     UINTN  SignerCertSize,
> > > > > >
> > > > > > +  IN     UINT8  *TopLevelCert,
> > > > > >
> > > > > > +  IN     UINTN  TopLevelCertSize,
> > > > > >
> > > > > > +  OUT    UINT8  *Sha384Digest
> > > > > >
> > > > > > +  )
> > > > > >
> > > > > > +{
> > > > > >
> > > > > > +  UINT8       *TbsCert;
> > > > > >
> > > > > > +  UINTN       TbsCertSize;
> > > > > >
> > > > > > +  CHAR8       CertCommonName[128];
> > > > > >
> > > > > > +  UINTN       CertCommonNameSize;
> > > > > >
> > > > > > +  BOOLEAN     CryptoStatus;
> > > > > >
> > > > > > +  EFI_STATUS  Status;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // Get SignerCert CommonName
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > > > CertCommonName, &CertCommonNameSize);
> > > > > >
> > > > > > +  if (EFI_ERROR (Status)) {
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName
> failed
> > > with
> > > > > > status %x\n", __FUNCTION__, Status));
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // Get TopLevelCert tbsCertificate
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > > > &TbsCertSize)) {
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > > > + failed!\n",
> > > > > > __FUNCTION__));
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> > > > > >
> > > > > > +  CryptoStatus = Sha384Init (mHashCtx);
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  CryptoStatus = Sha384Update (
> > > > > >
> > > > > > +                   mHashCtx,
> > > > > >
> > > > > > +                   CertCommonName,
> > > > > >
> > > > > > +                   AsciiStrLen (CertCommonName)
> > > > > >
> > > > > > +                   );
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  return EFI_SUCCESS;
> > > > > >
> > > > > > +}
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +/**
> > > > > >
> > > > > > +  Calculate SHA512 digest of SignerCert CommonName +
> ToplevelCert
> > > > > > tbsCertificate
> > > > > >
> > > > > > +  SignerCert and ToplevelCert are inside the signer certificate chain.
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > > > >
> > > > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > > > >
> > > > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > > > >
> > > > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > > > >
> > > > > > +  @param[out] Sha512Digest       Sha512 digest calculated.
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  @return EFI_ABORTED          Digest process failed.
> > > > > >
> > > > > > +  @return EFI_SUCCESS          SHA512 Digest is successfully
> calculated.
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +**/
> > > > > >
> > > > > > +EFI_STATUS
> > > > > >
> > > > > > +CalculatePrivAuthVarSignChainSHA512Digest (
> > > > > >
> > > > > > +  IN     UINT8  *SignerCert,
> > > > > >
> > > > > > +  IN     UINTN  SignerCertSize,
> > > > > >
> > > > > > +  IN     UINT8  *TopLevelCert,
> > > > > >
> > > > > > +  IN     UINTN  TopLevelCertSize,
> > > > > >
> > > > > > +  OUT    UINT8  *Sha512Digest
> > > > > >
> > > > > > +  )
> > > > > >
> > > > > > +{
> > > > > >
> > > > > > +  UINT8       *TbsCert;
> > > > > >
> > > > > > +  UINTN       TbsCertSize;
> > > > > >
> > > > > > +  CHAR8       CertCommonName[128];
> > > > > >
> > > > > > +  UINTN       CertCommonNameSize;
> > > > > >
> > > > > > +  BOOLEAN     CryptoStatus;
> > > > > >
> > > > > > +  EFI_STATUS  Status;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // Get SignerCert CommonName
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > > > CertCommonName, &CertCommonNameSize);
> > > > > >
> > > > > > +  if (EFI_ERROR (Status)) {
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName
> failed
> > > with
> > > > > > status %x\n", __FUNCTION__, Status));
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // Get TopLevelCert tbsCertificate
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > > > &TbsCertSize)) {
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > > > + failed!\n",
> > > > > > __FUNCTION__));
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> > > > > >
> > > > > > +  CryptoStatus = Sha512Init (mHashCtx);
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > > > >
> > > > > > +  //
> > > > > >
> > > > > > +  CryptoStatus = Sha512Update (
> > > > > >
> > > > > > +                   mHashCtx,
> > > > > >
> > > > > > +                   CertCommonName,
> > > > > >
> > > > > > +                   AsciiStrLen (CertCommonName)
> > > > > >
> > > > > > +                   );
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> > > > > >
> > > > > > +  if (!CryptoStatus) {
> > > > > >
> > > > > > +    return EFI_ABORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  return EFI_SUCCESS;
> > > > > >
> > > > > > +}
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  /**
> > > > > >
> > > > > >    Find matching signer's certificates for common authenticated
> > > > > > variable
> > > > > >
> > > > > >    by corresponding VariableName and VendorGuid from "certdb" or
> > > > > "certdbv".
> > > > > >
> > > > > > @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
> > > > > >    @param[in]  SignerCertSize    Length of signer certificate.
> > > > > >
> > > > > >    @param[in]  TopLevelCert      Top-level certificate data.
> > > > > >
> > > > > >    @param[in]  TopLevelCertSize  Length of top-level certificate.
> > > > > >
> > > > > > +  @param[in]  DigestSize        Digest Size.
> > > > > >
> > > > > >
> > > > > >
> > > > > >    @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
> > > > > >
> > > > > >    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry
> with
> > > > > same
> > > > > > VariableName
> > > > > >
> > > > > > @@ -1542,7 +1715,8 @@ InsertCertsToDb (
> > > > > >    IN     UINT8     *SignerCert,
> > > > > >
> > > > > >    IN     UINTN     SignerCertSize,
> > > > > >
> > > > > >    IN     UINT8     *TopLevelCert,
> > > > > >
> > > > > > -  IN     UINTN     TopLevelCertSize
> > > > > >
> > > > > > +  IN     UINTN     TopLevelCertSize,
> > > > > >
> > > > > > +  IN     UINT32    DigestSize
> > > > > >
> > > > > >    )
> > > > > >
> > > > > >  {
> > > > > >
> > > > > >    EFI_STATUS         Status;
> > > > > >
> > > > > > @@ -1556,7 +1730,7 @@ InsertCertsToDb (
> > > > > >    UINT32             CertDataSize;
> > > > > >
> > > > > >    AUTH_CERT_DB_DATA  *Ptr;
> > > > > >
> > > > > >    CHAR16             *DbName;
> > > > > >
> > > > > > -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> > > > > >
> > > > > > +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > > > >
> > > > > >
> > > > > >
> > > > > >    if ((VariableName == NULL) || (VendorGuid == NULL) ||
> (SignerCert
> > > > > > == NULL)
> > > > > > || (TopLevelCert == NULL)) {
> > > > > >
> > > > > >      return EFI_INVALID_PARAMETER;
> > > > > >
> > > > > > @@ -1618,20 +1792,41 @@ InsertCertsToDb (
> > > > > >    // Construct new data content of variable "certdb" or "certdbv".
> > > > > >
> > > > > >    //
> > > > > >
> > > > > >    NameSize      = (UINT32)StrLen (VariableName);
> > > > > >
> > > > > > -  CertDataSize  = sizeof (Sha256Digest);
> > > > > >
> > > > > > +  CertDataSize  = DigestSize;
> > > > > >
> > > > > >    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) +
> > > (UINT32)CertDataSize +
> > > > > > NameSize * sizeof (CHAR16);
> > > > > >
> > > > > >    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> > > > > >
> > > > > >    if (NewCertDbSize > mMaxCertDbSize) {
> > > > > >
> > > > > >      return EFI_OUT_OF_RESOURCES;
> > > > > >
> > > > > >    }
> > > > > >
> > > > > >
> > > > > >
> > > > > > -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > >
> > > > > > -             SignerCert,
> > > > > >
> > > > > > -             SignerCertSize,
> > > > > >
> > > > > > -             TopLevelCert,
> > > > > >
> > > > > > -             TopLevelCertSize,
> > > > > >
> > > > > > -             Sha256Digest
> > > > > >
> > > > > > -             );
> > > > > >
> > > > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > > > >
> > > > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > >
> > > > > > +               SignerCert,
> > > > > >
> > > > > > +               SignerCertSize,
> > > > > >
> > > > > > +               TopLevelCert,
> > > > > >
> > > > > > +               TopLevelCertSize,
> > > > > >
> > > > > > +               ShaDigest
> > > > > >
> > > > > > +               );
> > > > > >
> > > > > > +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> > > > > >
> > > > > > +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> > > > > >
> > > > > > +               SignerCert,
> > > > > >
> > > > > > +               SignerCertSize,
> > > > > >
> > > > > > +               TopLevelCert,
> > > > > >
> > > > > > +               TopLevelCertSize,
> > > > > >
> > > > > > +               ShaDigest
> > > > > >
> > > > > > +               );
> > > > > >
> > > > > > +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> > > > > >
> > > > > > +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> > > > > >
> > > > > > +               SignerCert,
> > > > > >
> > > > > > +               SignerCertSize,
> > > > > >
> > > > > > +               TopLevelCert,
> > > > > >
> > > > > > +               TopLevelCertSize,
> > > > > >
> > > > > > +               ShaDigest
> > > > > >
> > > > > > +               );
> > > > > >
> > > > > > +  } else {
> > > > > >
> > > > > > +    return EFI_UNSUPPORTED;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +
> > > > > >
> > > > > >    if (EFI_ERROR (Status)) {
> > > > > >
> > > > > >      return Status;
> > > > > >
> > > > > >    }
> > > > > >
> > > > > > @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> > > > > >
> > > > > >
> > > > > >    CopyMem (
> > > > > >
> > > > > >      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize *
> sizeof
> > > > > > (CHAR16),
> > > > > >
> > > > > > -    Sha256Digest,
> > > > > >
> > > > > > +    ShaDigest,
> > > > > >
> > > > > >      CertDataSize
> > > > > >
> > > > > >      );
> > > > > >
> > > > > >
> > > > > >
> > > > > > @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
> > > > > >    UINTN                          CertStackSize;
> > > > > >
> > > > > >    UINT8                          *CertsInCertDb;
> > > > > >
> > > > > >    UINT32                         CertsSizeinDb;
> > > > > >
> > > > > > -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> > > > > >
> > > > > > +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > > > >
> > > > > >    EFI_CERT_DATA                  *CertDataPtr;
> > > > > >
> > > > > >
> > > > > >
> > > > > >    //
> > > > > >
> > > > > > @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> > > > > >
> > > > > >
> > > > > >    //
> > > > > >
> > > > > >    // SignedData.digestAlgorithms shall contain the digest algorithm
> > > > > > used when preparing the
> > > > > >
> > > > > > -  // signature. Only a digest algorithm of SHA-256 is accepted.
> > > > > >
> > > > > > +  // signature. Only a digest algorithm of SHA-256, SHA-384 or
> > > > > > + SHA-512 is
> > > > > > accepted.
> > > > > >
> > > > > >    //
> > > > > >
> > > > > >    //    According to PKCS#7 Definition (https://www.rfc-
> > > > > editor.org/rfc/rfc2315):
> > > > > >
> > > > > >    //        SignedData ::= SEQUENCE {
> > > > > >
> > > > > > @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
> > > > > >               || (CompareMem (SigData + 13, &mSha256OidValue, sizeof
> > > > > > (mSha256OidValue)) != 0)))
> > > > > >
> > > > > >         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> > > > > >
> > > > > >            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > > TWO_BYTE_ENCODE)
> > > > > >
> > > > > > -             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > > > > (mSha256OidValue)) != 0))))
> > > > > >
> > > > > > +             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof
> > > > > > (mSha256OidValue)) != 0)))
> > > > > >
> > > > > > +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> > > > > >
> > > > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > > > + TWO_BYTE_ENCODE)
> > > > > >
> > > > > > +             || (CompareMem (SigData + 13, &mSha384OidValue, sizeof
> > > > > > (mSha384OidValue)) != 0)))
> > > > > >
> > > > > > +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> > > > > >
> > > > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > > + TWO_BYTE_ENCODE)
> > > > > >
> > > > > > +             || (CompareMem (SigData + 32, &mSha384OidValue, sizeof
> > > > > > (mSha384OidValue)) != 0)))
> > > > > >
> > > > > > +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> > > > > >
> > > > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > > > + TWO_BYTE_ENCODE)
> > > > > >
> > > > > > +             || (CompareMem (SigData + 13, &mSha512OidValue, sizeof
> > > > > > (mSha512OidValue)) != 0)))
> > > > > >
> > > > > > +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> > > > > >
> > > > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > > + TWO_BYTE_ENCODE)
> > > > > >
> > > > > > +             || (CompareMem (SigData + 32, &mSha512OidValue, sizeof
> > > > > > (mSha512OidValue)) != 0))))
> > > > > >
> > > > > >      {
> > > > > >
> > > > > >        return EFI_SECURITY_VIOLATION;
> > > > > >
> > > > > >      }
> > > > > >
> > > > > > @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
> > > > > >                          ReadUnaligned32 ((UINT32
> > > > > > *)&(CertDataPtr->CertDataLength)),
> > > > > >
> > > > > >                          TopLevelCert,
> > > > > >
> > > > > >                          TopLevelCertSize,
> > > > > >
> > > > > > -                        Sha256Digest
> > > > > >
> > > > > > +                        ShaDigest
> > > > > >
> > > > > > +                        );
> > > > > >
> > > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > > + CertsInCertDb,
> > > > > > CertsSizeinDb) != 0)) {
> > > > > >
> > > > > > +          goto Exit;
> > > > > >
> > > > > > +        }
> > > > > >
> > > > > > +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> > > > > >
> > > > > > +        //
> > > > > >
> > > > > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > > > > tbsCertificate against data in CertDb
> > > > > >
> > > > > > +        //
> > > > > >
> > > > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > > > >
> > > > > > +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> > > > > >
> > > > > > +                        CertDataPtr->CertDataBuffer,
> > > > > >
> > > > > > +                        ReadUnaligned32 ((UINT32
> > > > > > + *)&(CertDataPtr->CertDataLength)),
> > > > > >
> > > > > > +                        TopLevelCert,
> > > > > >
> > > > > > +                        TopLevelCertSize,
> > > > > >
> > > > > > +                        ShaDigest
> > > > > >
> > > > > > +                        );
> > > > > >
> > > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > > + CertsInCertDb,
> > > > > > CertsSizeinDb) != 0)) {
> > > > > >
> > > > > > +          goto Exit;
> > > > > >
> > > > > > +        }
> > > > > >
> > > > > > +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> > > > > >
> > > > > > +        //
> > > > > >
> > > > > > +        // Check hash of signer cert CommonName + Top-level issuer
> > > > > > tbsCertificate against data in CertDb
> > > > > >
> > > > > > +        //
> > > > > >
> > > > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > > > >
> > > > > > +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> > > > > >
> > > > > > +                        CertDataPtr->CertDataBuffer,
> > > > > >
> > > > > > +                        ReadUnaligned32 ((UINT32
> > > > > > + *)&(CertDataPtr->CertDataLength)),
> > > > > >
> > > > > > +                        TopLevelCert,
> > > > > >
> > > > > > +                        TopLevelCertSize,
> > > > > >
> > > > > > +                        ShaDigest
> > > > > >
> > > > > >                          );
> > > > > >
> > > > > > -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest,
> > > > > CertsInCertDb,
> > > > > > CertsSizeinDb) != 0)) {
> > > > > >
> > > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > > + CertsInCertDb,
> > > > > > CertsSizeinDb) != 0)) {
> > > > > >
> > > > > >            goto Exit;
> > > > > >
> > > > > >          }
> > > > > >
> > > > > >        } else {
> > > > > >
> > > > > > @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
> > > > > >                        CertDataPtr->CertDataBuffer,
> > > > > >
> > > > > >                        ReadUnaligned32 ((UINT32
> > > > > > *)&(CertDataPtr->CertDataLength)),
> > > > > >
> > > > > >                        TopLevelCert,
> > > > > >
> > > > > > -                      TopLevelCertSize
> > > > > >
> > > > > > +                      TopLevelCertSize,
> > > > > >
> > > > > > +                      CertsSizeinDb
> > > > > >
> > > > > >                        );
> > > > > >
> > > > > >        if (EFI_ERROR (Status)) {
> > > > > >
> > > > > >          VerifyStatus = FALSE;
> > > > > >
> > > > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > index dc61ae840c..552c0e99be 100644
> > > > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
> > > > > >  UINT32  mPlatformMode;
> > > > > >
> > > > > >  UINT8   mVendorKeyState;
> > > > > >
> > > > > >
> > > > > >
> > > > > > -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > > > EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID,
> > > > > EFI_CERT_X509_GUID };
> > > > > >
> > > > > > +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > > > EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID,
> > > > > EFI_CERT_SHA512_GUID,
> > > > > > EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID,
> > > > > EFI_CERT_RSA4096_GUID,
> > > > > > EFI_CERT_X509_GUID };
> > > > > >
> > > > > >
> > > > > >
> > > > > >  //
> > > > > >
> > > > > >  // Hash context pointer
> > > > > >
> > > > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > > > >    //
> > > > > >
> > > > > >    // Initialize hash context.
> > > > > >
> > > > > >    //
> > > > > >
> > > > > > -  CtxSize  = Sha256GetContextSize ();
> > > > > >
> > > > > > +  CtxSize  = Sha512GetContextSize ();
> > > > > >
> > > > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > > > >
> > > > > >    if (mHashCtx == NULL) {
> > > > > >
> > > > > >      return EFI_OUT_OF_RESOURCES;
> > > > > >
> > > > > > diff --git
> > > > > >
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > c
> > > > > >
> > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > c
> > > > > > index 66e2f5eaa3..f642aad64d 100644
> > > > > > ---
> > > > > >
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > c
> > > > > > +++
> > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > > > +++ Lib.c
> > > > > > @@ -1606,6 +1606,35 @@ Done:
> > > > > >    return VerifyStatus;
> > > > > >
> > > > > >  }
> > > > > >
> > > > > >
> > > > > >
> > > > > > +/**
> > > > > >
> > > > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  @retval  UINT32       Hash Alg
> > > > > >
> > > > > > +  **/
> > > > > >
> > > > > > +UINT32
> > > > > >
> > > > > > +GetDefaultHashAlg (
> > > > > >
> > > > > > +  VOID
> > > > > >
> > > > > > +  )
> > > > > >
> > > > > > +{
> > > > > >
> > > > > > +  UINT32  HashAlg;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > > > >
> > > > > > +  case 1:
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > > >
> > > > > > +    HashAlg = HASHALG_SHA384;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  case 2:
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > > >
> > > > > > +    HashAlg = HASHALG_SHA512;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  default:
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > > >
> > > > > > +    HashAlg = HASHALG_SHA256;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +  return HashAlg;
> > > > > >
> > > > > > +}
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  /**
> > > > > >
> > > > > >    Provide verification service for signed images, which include both
> > > > > > signature validation
> > > > > >
> > > > > >    and platform policy control. For signature types, both UEFI
> > > > > > WIN_CERTIFICATE_UEFI_GUID and
> > > > > >
> > > > > > @@ -1620,7 +1649,7 @@ Done:
> > > > > >        in the security database "db", and no valid signature nor any
> > > > > > hash value of the image may
> > > > > >
> > > > > >        be reflected in the security database "dbx".
> > > > > >
> > > > > >      Otherwise, the image is not signed,
> > > > > >
> > > > > > -      The SHA256 hash value of the image must match a record in the
> > > > > security
> > > > > > database "db", and
> > > > > >
> > > > > > +      The hash value of the image must match a record in the security
> > > > > > + database
> > > > > > "db", and
> > > > > >
> > > > > >        not be reflected in the security data base "dbx".
> > > > > >
> > > > > >
> > > > > >
> > > > > >    Caution: This function may receive untrusted input.
> > > > > >
> > > > > > @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
> > > > > >    //
> > > > > >
> > > > > >    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> > > > > >
> > > > > >      //
> > > > > >
> > > > > > -    // This image is not signed. The SHA256 hash value of the image
> must
> > > > > match
> > > > > > a record in the security database "db",
> > > > > >
> > > > > > +    // This image is not signed. The hash value of the image must
> > > > > > + match a record
> > > > > > in the security database "db",
> > > > > >
> > > > > >      // and not be reflected in the security data base "dbx".
> > > > > >
> > > > > >      //
> > > > > >
> > > > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > > > >
> > > > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > > > >
> > > > > >        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash
> > > > > > this image using %s.\n", mHashTypeStr));
> > > > > >
> > > > > >        goto Failed;
> > > > > >
> > > > > >      }
> > > > > >
> > > > > > diff --git
> > > > > >
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > inf
> > > > > >
> > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > inf
> > > > > > index 1e1a639857..f1ef9236c2 100644
> > > > > > ---
> > > > > >
> > > a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > inf
> > > > > > +++
> > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > > > +++ Lib.inf
> > > > > > @@ -93,3 +93,4 @@
> > > > > >
> > > gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> > > > > > ## SOMETIMES_CONSUMES
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolic
> > > > > y
> > > > > > ## SOMETIMES_CONSUMES
> > > > > >
> > > > > >
> > > gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy
> > > > > ##
> > > > > > SOMETIMES_CONSUMES
> > > > > >
> > > > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > > > ##
> > > > > > CONSUMES
> > > > > >
> > > > > > diff --git a/SecurityPkg/SecurityPkg.dec
> b/SecurityPkg/SecurityPkg.dec
> > > > > > index 0382090f4e..4adc2a72ab 100644
> > > > > > --- a/SecurityPkg/SecurityPkg.dec
> > > > > > +++ b/SecurityPkg/SecurityPkg.dec
> > > > > > @@ -521,6 +521,13 @@
> > > > > >    # @Prompt Skip Hdd Password prompt.
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLE
> > > > > AN|
> > > > > > 0x00010021
> > > > > >
> > > > > >
> > > > > >
> > > > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > > >
> > > > > > +  #   0 - Use SHA256
> > > > > >
> > > > > > +  #   1 - Use SHA384
> > > > > >
> > > > > > +  #   2 - Use SHA512
> > > > > >
> > > > > > +  # @Prompt Secure Boot default hash algorithm
> > > > > >
> > > > > > +
> > > > > >
> > > > >
> > >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > > 00
> > > > > > 0
> > > > > > 10040
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  [PcdsDynamic, PcdsDynamicEx]
> > > > > >
> > > > > >
> > > > > >
> > > > > >    ## This PCD indicates Hash mask for TPM 2.0. Bit definition
> > > > > > strictly follows TCG Algorithm Registry.<BR><BR>
> > > > > >
> > > > > > diff --git
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > ig
> > > > > > Dxe.inf
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > ig
> > > > > > Dxe.inf
> > > > > > index 1671d5be7c..4b0012d033 100644
> > > > > > ---
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > ig
> > > > > > Dxe.inf
> > > > > > +++
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > ig
> > > > > > Dxe.inf
> > > > > > @@ -70,6 +70,14 @@
> > > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > >    gEfiCertRsa2048Guid
> > > > > >
> > > > > >
> > > > > >
> > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > > type of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  gEfiCertRsa3072Guid
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > > type of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  gEfiCertRsa4096Guid
> > > > > >
> > > > > > +
> > > > > >
> > > > > >    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > >    gEfiCertX509Guid
> > > > > >
> > > > > > @@ -82,6 +90,14 @@
> > > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > >    gEfiCertSha256Guid
> > > > > >
> > > > > >
> > > > > >
> > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > > type of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  gEfiCertSha384Guid
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the
> > > type of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> type
> > > of
> > > > > the
> > > > > > signature.
> > > > > >
> > > > > > +  gEfiCertSha512Guid
> > > > > >
> > > > > > +
> > > > > >
> > > > > >    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> > > > > >
> > > > > >    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> > > > > >
> > > > > >    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> > > > > >
> > > > > > @@ -107,6 +123,9 @@
> > > > > >    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES
> ##
> > > GUID
> > > > > #
> > > > > > Unique ID for the type of the certificate.
> > > > > >
> > > > > >    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES
> ##
> > > GUID
> > > > > #
> > > > > > Unique ID for the type of the certificate.
> > > > > >
> > > > > >
> > > > > >
> > > > > > +[Pcd]
> > > > > >
> > > > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > > > ##
> > > > > > CONSUMES
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  [Protocols]
> > > > > >
> > > > > >    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> > > > > >
> > > > > >    gEfiDevicePathProtocolGuid                    ## PRODUCES
> > > > > >
> > > > > > diff --git
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.c
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.c
> > > > > > index 4299a6b5e5..0ba029a394 100644
> > > > > > ---
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.c
> > > > > > +++
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.c
> > > > > > @@ -560,7 +560,7 @@ ON_EXIT:
> > > > > >
> > > > > >
> > > > > >  **/
> > > > > >
> > > > > >  EFI_STATUS
> > > > > >
> > > > > > -EnrollRsa2048ToKek (
> > > > > >
> > > > > > +EnrollRsaToKek (
> > > > > >
> > > > > >    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> > > > > >
> > > > > >    )
> > > > > >
> > > > > >  {
> > > > > >
> > > > > > @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> > > > > >
> > > > > >
> > > > > >    ASSERT (KeyBlob != NULL);
> > > > > >
> > > > > >    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> > > > > >
> > > > > > -  if (KeyInfo->KeyLengthInBits / 8 !=
> WIN_CERT_UEFI_RSA2048_SIZE) {
> > > > > >
> > > > > > -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only
> RSA2048 is
> > > > > > supported.\n"));
> > > > > >
> > > > > > +  switch (KeyInfo->KeyLengthInBits / 8) {
> > > > > >
> > > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > >
> > > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > >
> > > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  default :
> > > > > >
> > > > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only
> RSA2048,
> > > > > > + RSA3072
> > > > > > and RSA4096 are supported.\n"));
> > > > > >
> > > > > >      Status = EFI_UNSUPPORTED;
> > > > > >
> > > > > >      goto ON_EXIT;
> > > > > >
> > > > > >    }
> > > > > >
> > > > > > @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
> > > > > >    //
> > > > > >
> > > > > >    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> > > > > >
> > > > > >                     + sizeof (EFI_SIGNATURE_DATA) - 1
> > > > > >
> > > > > > -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> > > > > >
> > > > > > +                   + KeyLenInBytes;
> > > > > >
> > > > > >
> > > > > >
> > > > > >    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool
> > > > > > (KekSigListSize);
> > > > > >
> > > > > >    if (KekSigList == NULL) {
> > > > > >
> > > > > > @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> > > > > >
> > > > > >
> > > > > >    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> > > > > >
> > > > > >                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> > > > > >
> > > > > > -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> > > > > >
> > > > > > +                                  + (UINT32) KeyLenInBytes;
> > > > > >
> > > > > >    KekSigList->SignatureHeaderSize = 0;
> > > > > >
> > > > > > -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1
> +
> > > > > > WIN_CERT_UEFI_RSA2048_SIZE;
> > > > > >
> > > > > > -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > > >
> > > > > > +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1
> +
> > > > > (UINT32)
> > > > > > KeyLenInBytes;
> > > > > >
> > > > > > +  switch (KeyLenInBytes) {
> > > > > >
> > > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > >
> > > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > >
> > > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > >
> > > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  default :
> > > > > >
> > > > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> > > > > >
> > > > > > +    Status = EFI_UNSUPPORTED;
> > > > > >
> > > > > > +    goto ON_EXIT;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > >
> > > > > >
> > > > > >    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList +
> sizeof
> > > > > > (EFI_SIGNATURE_LIST));
> > > > > >
> > > > > >    CopyGuid (&KEKSigData->SignatureOwner, Private-
> >SignatureGUID);
> > > > > >
> > > > > >    CopyMem (
> > > > > >
> > > > > >      KEKSigData->SignatureData,
> > > > > >
> > > > > >      KeyBlob + sizeof (CPL_KEY_INFO),
> > > > > >
> > > > > > -    WIN_CERT_UEFI_RSA2048_SIZE
> > > > > >
> > > > > > +    KeyLenInBytes
> > > > > >
> > > > > >      );
> > > > > >
> > > > > >
> > > > > >
> > > > > >    //
> > > > > >
> > > > > > @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
> > > > > >    if (IsDerEncodeCertificate (FilePostFix)) {
> > > > > >
> > > > > >      return EnrollX509ToKek (Private);
> > > > > >
> > > > > >    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> > > > > >
> > > > > > -    return EnrollRsa2048ToKek (Private);
> > > > > >
> > > > > > +    return EnrollRsaToKek (Private);
> > > > > >
> > > > > >    } else {
> > > > > >
> > > > > >      //
> > > > > >
> > > > > >      // File type is wrong, simply close it
> > > > > >
> > > > > > @@ -1847,7 +1867,7 @@ HashPeImage (
> > > > > >    SectionHeader = NULL;
> > > > > >
> > > > > >    Status        = FALSE;
> > > > > >
> > > > > >
> > > > > >
> > > > > > -  if (HashAlg != HASHALG_SHA256) {
> > > > > >
> > > > > > +  if ((HashAlg >= HASHALG_MAX)) {
> > > > > >
> > > > > >      return FALSE;
> > > > > >
> > > > > >    }
> > > > > >
> > > > > >
> > > > > >
> > > > > > @@ -1856,8 +1876,25 @@ HashPeImage (
> > > > > >    //
> > > > > >
> > > > > >    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> > > > > >
> > > > > >
> > > > > >
> > > > > > -  mImageDigestSize = SHA256_DIGEST_SIZE;
> > > > > >
> > > > > > -  mCertType        = gEfiCertSha256Guid;
> > > > > >
> > > > > > +   switch (HashAlg) {
> > > > > >
> > > > > > +    case HASHALG_SHA256:
> > > > > >
> > > > > > +      mImageDigestSize = SHA256_DIGEST_SIZE;
> > > > > >
> > > > > > +      mCertType        = gEfiCertSha256Guid;
> > > > > >
> > > > > > +      break;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +    case HASHALG_SHA384:
> > > > > >
> > > > > > +      mImageDigestSize = SHA384_DIGEST_SIZE;
> > > > > >
> > > > > > +      mCertType        = gEfiCertSha384Guid;
> > > > > >
> > > > > > +      break;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +    case HASHALG_SHA512:
> > > > > >
> > > > > > +      mImageDigestSize = SHA512_DIGEST_SIZE;
> > > > > >
> > > > > > +      mCertType        = gEfiCertSha512Guid;
> > > > > >
> > > > > > +      break;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +    default:
> > > > > >
> > > > > > +      return FALSE;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > >
> > > > > >
> > > > > >    CtxSize = mHash[HashAlg].GetContextSize ();
> > > > > >
> > > > > >
> > > > > >
> > > > > > @@ -2222,6 +2259,35 @@ ON_EXIT:
> > > > > >    return Status;
> > > > > >
> > > > > >  }
> > > > > >
> > > > > >
> > > > > >
> > > > > > +/**
> > > > > >
> > > > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  @retval  UINT32       Hash Alg
> > > > > >
> > > > > > +  **/
> > > > > >
> > > > > > +UINT32
> > > > > >
> > > > > > +GetDefaultHashAlg (
> > > > > >
> > > > > > +  VOID
> > > > > >
> > > > > > +  )
> > > > > >
> > > > > > +{
> > > > > >
> > > > > > +  UINT32  HashAlg;
> > > > > >
> > > > > > +
> > > > > >
> > > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > > > >
> > > > > > +  case 1:
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > > >
> > > > > > +    HashAlg = HASHALG_SHA384;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  case 2:
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > > >
> > > > > > +    HashAlg = HASHALG_SHA512;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  default:
> > > > > >
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > > >
> > > > > > +    HashAlg = HASHALG_SHA256;
> > > > > >
> > > > > > +    break;
> > > > > >
> > > > > > +  }
> > > > > >
> > > > > > +  return HashAlg;
> > > > > >
> > > > > > +}
> > > > > >
> > > > > > +
> > > > > >
> > > > > >  /**
> > > > > >
> > > > > >    Enroll a new signature of executable into Signature Database.
> > > > > >
> > > > > >
> > > > > >
> > > > > > @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
> > > > > >    }
> > > > > >
> > > > > >
> > > > > >
> > > > > >    if (mSecDataDir->SizeOfCert == 0) {
> > > > > >
> > > > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > > > >
> > > > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > > > >
> > > > > >        Status =  EFI_SECURITY_VIOLATION;
> > > > > >
> > > > > >        goto ON_EXIT;
> > > > > >
> > > > > >      }
> > > > > >
> > > > > > @@ -2589,6 +2655,10 @@ UpdateDeletePage (
> > > > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > > > CertList->SignatureListSize)) {
> > > > > >
> > > > > >      if (CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa2048Guid))
> > > > > > {
> > > > > >
> > > > > >        Help = STRING_TOKEN
> (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> > > > > >
> > > > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > > > + &gEfiCertRsa3072Guid)) {
> > > > > >
> > > > > > +      Help = STRING_TOKEN
> (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> > > > > >
> > > > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > > > + &gEfiCertRsa4096Guid)) {
> > > > > >
> > > > > > +      Help = STRING_TOKEN
> (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> > > > > >
> > > > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > > > &gEfiCertX509Guid)) {
> > > > > >
> > > > > >        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> > > > > >
> > > > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > > > &gEfiCertSha1Guid)) {
> > > > > >
> > > > > > @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
> > > > > >    GuidIndex      = 0;
> > > > > >
> > > > > >    while ((KekDataSize > 0) && (KekDataSize >=
> > > > > > CertList->SignatureListSize)) {
> > > > > >
> > > > > >      if (CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa2048Guid)
> > > > > > ||
> > > > > >
> > > > > > +        CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa3072Guid)
> > > > > > + ||
> > > > > >
> > > > > > +        CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa4096Guid)
> > > > > > + ||
> > > > > >
> > > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
> > > > > >
> > > > > >      {
> > > > > >
> > > > > >        CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST)
> > > > > > + CertList-
> > > > > > >SignatureHeaderSize));
> > > > > >
> > > > > > @@ -2952,6 +3024,8 @@ DeleteSignature (
> > > > > >    GuidIndex    = 0;
> > > > > >
> > > > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > > > CertList->SignatureListSize)) {
> > > > > >
> > > > > >      if (CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa2048Guid)
> > > > > > ||
> > > > > >
> > > > > > +        CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa3072Guid)
> > > > > > + ||
> > > > > >
> > > > > > +        CompareGuid (&CertList->SignatureType,
> &gEfiCertRsa4096Guid)
> > > > > > + ||
> > > > > >
> > > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)
> ||
> > > > > >
> > > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)
> ||
> > > > > >
> > > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)
> > > > > > ||
> > > > > >
> > > > > > @@ -3758,12 +3832,20 @@ LoadSignatureList (
> > > > > >    while ((RemainingSize > 0) && (RemainingSize >=
> > > > > > ListWalker->SignatureListSize)) {
> > > > > >
> > > > > >      if (CompareGuid (&ListWalker->SignatureType,
> > > > > > &gEfiCertRsa2048Guid)) {
> > > > > >
> > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > > > >
> > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > + &gEfiCertRsa3072Guid))
> > > > > > {
> > > > > >
> > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > > > >
> > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > + &gEfiCertRsa4096Guid))
> > > > > > {
> > > > > >
> > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > > > >
> > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > &gEfiCertX509Guid)) {
> > > > > >
> > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > > > >
> > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > &gEfiCertSha1Guid)) {
> > > > > >
> > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> > > > > >
> > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > &gEfiCertSha256Guid)) {
> > > > > >
> > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > > > >
> > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > + &gEfiCertSha384Guid))
> > > > > > {
> > > > > >
> > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > > > >
> > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > + &gEfiCertSha512Guid))
> > > > > > {
> > > > > >
> > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > > > >
> > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > &gEfiCertX509Sha256Guid)) {
> > > > > >
> > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > > > >
> > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > &gEfiCertX509Sha384Guid)) {
> > > > > >
> > > > > > @@ -4001,6 +4083,14 @@ FormatHelpInfo (
> > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > > > >
> > > > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > >
> > > > > >      IsCert     = TRUE;
> > > > > >
> > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > + &gEfiCertRsa3072Guid)) {
> > > > > >
> > > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > > > >
> > > > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > >
> > > > > > +    IsCert     = TRUE;
> > > > > >
> > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > + &gEfiCertRsa4096Guid)) {
> > > > > >
> > > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > > > >
> > > > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > >
> > > > > > +    IsCert     = TRUE;
> > > > > >
> > > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > &gEfiCertX509Guid)) {
> > > > > >
> > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > > > >
> > > > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > >
> > > > > > @@ -4011,6 +4101,12 @@ FormatHelpInfo (
> > > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > &gEfiCertSha256Guid)) {
> > > > > >
> > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > > > >
> > > > > >      DataSize   = 32;
> > > > > >
> > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > + &gEfiCertSha384Guid)) {
> > > > > >
> > > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > > > >
> > > > > > +    DataSize   = 48;
> > > > > >
> > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > + &gEfiCertSha512Guid)) {
> > > > > >
> > > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > > > >
> > > > > > +    DataSize   = 64;
> > > > > >
> > > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > &gEfiCertX509Sha256Guid)) {
> > > > > >
> > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > > > >
> > > > > >      DataSize   = 32;
> > > > > >
> > > > > > diff --git
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.h
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.h
> > > > > > index 37c66f1b95..ae50d929a7 100644
> > > > > > ---
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.h
> > > > > > +++
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igI
> > > > > > mpl.h
> > > > > > @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
> > > #define
> > > > > > MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> > > > > >
> > > > > >
> > > > > >
> > > > > >  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> > > > > >
> > > > > > +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> > > > > >
> > > > > > +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> > > > > >
> > > > > >
> > > > > >
> > > > > >  //
> > > > > >
> > > > > >  // Support hash types
> > > > > >
> > > > > > diff --git
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igS
> > > > > > trings.uni
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igS
> > > > > > trings.uni
> > > > > > index 0d01701de7..1b48acc800 100644
> > > > > > ---
> > > > > >
> > > > >
> > >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igS
> > > > > > trings.uni
> > > > > > +++
> > > > > >
> > > > >
> > >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > f
> > > > > > igS
> > > > > > trings.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"
> > > > > >
> > > > > >  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File
> > > > > Explorer"
> > > > > >
> > > > > >  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-
> US
> > > > > > "RSA2048_SHA256_GUID"
> > > > > >
> > > > > > +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language
> en-US
> > > > > > "RSA3072_SHA384_GUID"
> > > > > >
> > > > > > +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language
> en-US
> > > > > > "RSA4096_SHA512_GUID"
> > > > > >
> > > > > >  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US
> > > > > "PKCS7_GUID"
> > > > > >
> > > > > >  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US
> > > > > "SHA1_GUID"
> > > > > >
> > > > > >  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> > > > > > "SHA256_GUID"
> > > > > >
> > > > > > @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-
> Patent
> > > > > >  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-
> US
> > > > > > "X509_SHA512_GUID"
> > > > > >
> > > > > >
> > > > > >
> > > > > >  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> > > > > > "RSA2048_SHA256"
> > > > > >
> > > > > > +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> > > > > > "RSA3072_SHA384"
> > > > > >
> > > > > > +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> > > > > > "RSA4096_SHA512"
> > > > > >
> > > > > >  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> > > > > >
> > > > > >  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> > > > > >
> > > > > >  #string STR_LIST_TYPE_SHA256                      #language en-US
> "SHA256"
> > > > > >
> > > > > > +#string STR_LIST_TYPE_SHA384                      #language en-US
> "SHA384"
> > > > > >
> > > > > > +#string STR_LIST_TYPE_SHA512                      #language en-US
> "SHA512"
> > > > > >
> > > > > >  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> > > > > > "X509_SHA256"
> > > > > >
> > > > > >  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> > > > > > "X509_SHA384"
> > > > > >
> > > > > >  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> > > > > > "X509_SHA512"
> > > > > >
> > > > > > --
> > > > > > 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106681): https://edk2.groups.io/g/devel/message/106681
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
Posted by Sheng Wei 9 months, 3 weeks ago
Hi Jiewen,
I just raised the patch V4 for this suggestion.
Do you have any comment about this solution ?
Thank you
BR
Sheng Wei

> -----Original Message-----
> From: Sheng, W
> Sent: 2023年7月6日 15:29
> To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>;
> Chen, Zeyi <Zeyi.Chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384
> 
> Hi Jiewen,
> As your suggestion.
> I will check if CPL_KEY_INFO. KeyType == 0 first.
> If true, I will use below table to select RSA algorithm.
> KeyLengthInBits    RSA algorithm
> 2048                        RSA 2K
> 3072                        RSA 3K
> 4096                        RSA 4K
> Do you have any comment about this solution ?
> 
> Thank you
> BR
> Sheng Wei
> 
> 
> > -----Original Message-----
> > From: Yao, Jiewen <jiewen.yao@intel.com>
> > Sent: 2023年7月6日 15:06
> > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> > <fiona.wang@intel.com>
> > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> 384
> >
> > CPL_KEY_INFO is not standard, but implementation choice.
> >
> > I notice KeyType field is not used today. I assume it is 0 today.
> >
> > Can we use 0 to indicate RSASSA?
> >
> > Thank you
> > Yao, Jiewen
> >
> >
> >
> > > -----Original Message-----
> > > From: Sheng, W <w.sheng@intel.com>
> > > Sent: Thursday, July 6, 2023 2:48 PM
> > > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > <min.m.xu@intel.com>;
> > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > 384
> > >
> > > Hi Jiewen,
> > > I raised the patch V3, And I also attached the patch file.
> > > For 4,
> > > My solution is below.
> > > When enroll the unsigned image, BIOS will select the most supported
> > complex
> > > hash algorithm to get the hash.
> > > When do the verification, BIOS will try all supported hash algorithm in
> "db"
> > and
> > > "dbx".
> > >
> > > For 5.
> > > The struct of CPL_KEY_INFO should be binded to .pbk file format.
> > > I cannot find the spec of .pbk file. I can not change the struct items.
> > > Do you know where to find the spec of public key storing file (*.pbk) ?
> > > Or is *.pbk file a legacy file format? We do not need to change this part
> and
> > > keep it for RSA 2048 only ?
> > >
> > > Thank you
> > > BR
> > > Sheng Wei
> > >
> > > > -----Original Message-----
> > > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > > Sent: 2023年6月30日 19:57
> > > > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > > > <min.m.xu@intel.com>; Chen, Zeyi <zeyi.chen@intel.com>; Wang,
> Fiona
> > > > <fiona.wang@intel.com>
> > > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and RSA
> > 384
> > > >
> > > > For 4, I think we can enroll all supported algorithms, or the active
> > algorithm. I
> > > > don’t think the PCD is needed.
> > > >
> > > > For 5, I suggest to change the data structure to include the algorithm ID.
> > > >
> > > > Thank you
> > > > Yao, Jiewen
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Sheng, W <w.sheng@intel.com>
> > > > > Sent: Friday, June 30, 2023 3:52 PM
> > > > > To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
> > > > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > > > <min.m.xu@intel.com>;
> > > > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> > <fiona.wang@intel.com>
> > > > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and
> RSA
> > > > 384
> > > > >
> > > > > Hi Jiewen,
> > > > > I raised the patch V2.
> > > > > I do the fix for 1) , 2), 3).
> > > > > But for 4) 5), I have below comments.
> > > > >
> > > > > 4) I am not sure why we need this PCD. Why cannot we support all of
> > hash
> > > > algo?
> > > > >
> > > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > > +  #   0 - Use SHA256
> > > > > +  #   1 - Use SHA384
> > > > > +  #   2 - Use SHA512
> > > > > +  # @Prompt Secure Boot default hash algorithm
> > > > > +
> > > > > +
> > > > >
> > > >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > 00
> > > > > + 010040
> > > > >
> > > > > PCD PcdSecureBootDefaultHashAlg is used for the only case of enroll
> an
> > > > > unsigned image.
> > > > > The original logic is BIOS will genrate SHA256 digest for this unsigned
> > image
> > > > and
> > > > > save it.
> > > > > The PCD is used to select the hash algorithm for this case.
> > > > > So we have to use a PCD to select the algorithm manully.
> > > > >
> > > > >
> > > > > 5) I don’t believe that you can use size to determine the algorithm.
> We
> > > > need a
> > > > > more robust way, such as algorithm ID.
> > > > >
> > > > > +  switch (KeyLenInBytes) {
> > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > > +    break;
> > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > > +    break;
> > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > > +    break;
> > > > > +    break;
> > > > >
> > > > > This code is used when enroll a RSA public key storing file (*.pbk).
> > > > > Here is the header Struct of this file.
> > > > > typedef struct _CPL_KEY_INFO {
> > > > >   UINT32    KeyLengthInBits;        // Key Length In Bits
> > > > >   UINT32    BlockSize;              // Operation Block Size in Bytes
> > > > >   UINT32    CipherBlockSize;        // Output Cipher Block Size in Bytes
> > > > >   UINT32    KeyType;                // Key Type
> > > > >   UINT32    CipherMode;             // Cipher Mode for Symmetric
> Algorithm
> > > > >   UINT32    Flags;                  // Additional Key Property Flags
> > > > > } CPL_KEY_INFO;
> > > > >
> > > >
> >
> Edk2/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBoot
> > > > Con
> > > > > figImpl.h
> > > > > We can only get to know the RSA algorithm by KeyLengthInBits.
> > > > > (RSA2048/RSA3072/RSA4096)
> > > > >
> > > > > Thank you.
> > > > > BR
> > > > > Sheng Wei
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Yao, Jiewen <jiewen.yao@intel.com>
> > > > > > Sent: 2023年6月22日 15:22
> > > > > > To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> > > > > > Cc: Wang, Jian J <jian.j.wang@intel.com>; Xu, Min M
> > > > <min.m.xu@intel.com>;
> > > > > > Chen, Zeyi <zeyi.chen@intel.com>; Wang, Fiona
> > <fiona.wang@intel.com>
> > > > > > Subject: RE: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and
> > RSA
> > > > 384
> > > > > >
> > > > > > Thank you very much to contribute this patch. Here is my feedback.
> > > > > >
> > > > > > 1) I don’t believe that you cannot use digest size to determine the
> > > > algorithm,
> > > > > > because different hash algorithm may have same time. E.g. SHA256
> > and
> > > > > > SHA3_256.
> > > > > >
> > > > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > > +               SignerCert,
> > > > > > +               SignerCertSize,
> > > > > > +               TopLevelCert,
> > > > > > +               TopLevelCertSize,
> > > > > > +               ShaDigest
> > > > > > +               );
> > > > > >
> > > > > > 2) I don’t believe that you cannot assuming CtxSize of SHA512 is
> > bigger
> > > > than
> > > > > > SHA256. I think we may need create context for each algo.
> > > > > >
> > > > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > > > >    //
> > > > > >    // Initialize hash context.
> > > > > >    //
> > > > > > -  CtxSize  = Sha256GetContextSize ();
> > > > > > +  CtxSize  = Sha512GetContextSize ();
> > > > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > > > >    if (mHashCtx == NULL) {
> > > > > >
> > > > > > 3) I believe we should use 0 for SHA256 and ASSERT in default.
> > > > > >
> > > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {  case 1:
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > > > +    HashAlg = HASHALG_SHA384;
> > > > > > +    break;
> > > > > > +  case 2:
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > > > +    HashAlg = HASHALG_SHA512;
> > > > > > +    break;
> > > > > > +  default:
> > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > > > +    HashAlg = HASHALG_SHA256;
> > > > > > +    break;
> > > > > > +  }
> > > > > >
> > > > > > 4) I am not sure why we need this PCD. Why cannot we support all
> of
> > > > hash
> > > > > > algo?
> > > > > >
> > > > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > > > +  #   0 - Use SHA256
> > > > > > +  #   1 - Use SHA384
> > > > > > +  #   2 - Use SHA512
> > > > > > +  # @Prompt Secure Boot default hash algorithm
> > > > > > +
> > > > > > +
> > > > > >
> > > >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > > > 00
> > > > > > + 010040
> > > > > >
> > > > > > 5) I don’t believe that you can use size to determine the algorithm.
> > We
> > > > need
> > > > > > a more robust way, such as algorithm ID.
> > > > > >
> > > > > > +  switch (KeyLenInBytes) {
> > > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > > > +    break;
> > > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
> > > > > > +    break;
> > > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > > +    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
> > > > > > +    break;
> > > > > > +    break;
> > > > > >
> > > > > > Thank you
> > > > > > Yao, Jiewen
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Sheng, W <w.sheng@intel.com>
> > > > > > > Sent: Thursday, May 25, 2023 1:23 PM
> > > > > > > To: devel@edk2.groups.io
> > > > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J
> > > > > > > <jian.j.wang@intel.com>; Xu, Min M <min.m.xu@intel.com>;
> Chen,
> > > > Zeyi
> > > > > > > <zeyi.chen@intel.com>; Wang, Fiona <fiona.wang@intel.com>
> > > > > > > Subject: [PATCH] SecurityPkg/SecureBoot: Support RSA 512 and
> RSA
> > > > 384
> > > > > > >
> > > > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413
> > > > > > >
> > > > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > > > Cc: Jian J Wang <jian.j.wang@intel.com>
> > > > > > > Cc: Min Xu <min.m.xu@intel.com>
> > > > > > > Cc: Zeyi Chen <zeyi.chen@intel.com>
> > > > > > > Cc: Fiona Wang <fiona.wang@intel.com>
> > > > > > > Signed-off-by: Sheng Wei <w.sheng@intel.com>
> > > > > > > ---
> > > > > > >  CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c   |   3 +-
> > > > > > >  MdePkg/Include/Guid/ImageAuthentication.h     |  26 ++
> > > > > > >  MdePkg/MdePkg.dec                             |   2 +
> > > > > > >  .../Library/AuthVariableLib/AuthService.c     | 272
> > ++++++++++++++++-
> > > > -
> > > > > > >  .../Library/AuthVariableLib/AuthVariableLib.c |   4 +-
> > > > > > >  .../DxeImageVerificationLib.c                 |  35 ++-
> > > > > > >  .../DxeImageVerificationLib.inf               |   1 +
> > > > > > >  SecurityPkg/SecurityPkg.dec                   |   7 +
> > > > > > >  .../SecureBootConfigDxe.inf                   |  19 ++
> > > > > > >  .../SecureBootConfigImpl.c                    | 122 +++++++-
> > > > > > >  .../SecureBootConfigImpl.h                    |   2 +
> > > > > > >  .../SecureBootConfigStrings.uni               |   6 +
> > > > > > >  12 files changed, 463 insertions(+), 36 deletions(-)
> > > > > > >
> > > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
> > > > > > > b/CryptoPkg/Library/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.
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > >    if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest
> > > > (EVP_sha1
> > > > > > > ()) == 0)
> > > > > > > ||
> > > > > > >
> > > > > > > -      (EVP_add_digest (EVP_sha256 ()) == 0) ||
> > ((EVP_add_digest_alias
> > > > > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > > > > >
> > > > > > > +      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest
> > > > > > > + (EVP_sha384 ())
> > > > > > > == 0) ||
> > > > > > >
> > > > > > > +      (EVP_add_digest (EVP_sha512 ()) == 0) ||
> > ((EVP_add_digest_alias
> > > > > > > (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
> > > > > > >
> > > > > > >    {
> > > > > > >
> > > > > > >      return FALSE;
> > > > > > >
> > > > > > >    }
> > > > > > >
> > > > > > > diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> > > > > > > b/MdePkg/Include/Guid/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} \
> > > > > > >
> > > > > > >    }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +///
> > > > > > >
> > > > > > > +/// This identifies a signature containing an RSA-3072 key. The
> key
> > > > > > > +(only the
> > > > > > > modulus
> > > > > > >
> > > > > > > +/// since the public key exponent is known to be 0x10001) shall
> be
> > > > > > > +stored in big-
> > > > > > > endian
> > > > > > >
> > > > > > > +/// order.
> > > > > > >
> > > > > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > > > > +shall always
> > > > > > > be 16 (size
> > > > > > >
> > > > > > > +/// of SignatureOwner component) + 384 bytes.
> > > > > > >
> > > > > > > +///
> > > > > > >
> > > > > > > +#define EFI_CERT_RSA3072_GUID \
> > > > > > >
> > > > > > > +  { \
> > > > > > >
> > > > > > > +    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85,
> 0x89,
> > > > > > > + 0xee,
> > > > > > > 0x92 } \
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +///
> > > > > > >
> > > > > > > +/// This identifies a signature containing an RSA-4096 key. The
> key
> > > > > > > +(only the
> > > > > > > modulus
> > > > > > >
> > > > > > > +/// since the public key exponent is known to be 0x10001) shall
> be
> > > > > > > +stored in big-
> > > > > > > endian
> > > > > > >
> > > > > > > +/// order.
> > > > > > >
> > > > > > > +/// The SignatureHeader size shall always be 0. The SignatureSize
> > > > > > > +shall always
> > > > > > > be 16 (size
> > > > > > >
> > > > > > > +/// of SignatureOwner component) + 512 bytes.
> > > > > > >
> > > > > > > +///
> > > > > > >
> > > > > > > +#define EFI_CERT_RSA4096_GUID \
> > > > > > >
> > > > > > > +  { \
> > > > > > >
> > > > > > > +    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d,
> 0x00,
> > > > > > > + 0x98,
> > > > > > > 0x2c } \
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  ///
> > > > > > >
> > > > > > >  /// This identifies a signature containing a RSA-2048 signature of a
> > > > > > > SHA-256 hash.  The
> > > > > > >
> > > > > > >  /// SignatureHeader size shall always be 0. The SignatureSize shall
> > > > > > > always be 16 (size of
> > > > > > >
> > > > > > > @@ -330,6 +354,8 @@ typedef struct {
> > > > > > >  extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
> > > > > > >
> > > > > > >  extern EFI_GUID  gEfiCertSha256Guid;
> > > > > > >
> > > > > > >  extern EFI_GUID  gEfiCertRsa2048Guid;
> > > > > > >
> > > > > > > +extern EFI_GUID  gEfiCertRsa3072Guid;
> > > > > > >
> > > > > > > +extern EFI_GUID  gEfiCertRsa4096Guid;
> > > > > > >
> > > > > > >  extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
> > > > > > >
> > > > > > >  extern EFI_GUID  gEfiCertSha1Guid;
> > > > > > >
> > > > > > >  extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
> > > > > > >
> > > > > > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > > > > > > 80b6559053..782f6d184d 100644
> > > > > > > --- a/MdePkg/MdePkg.dec
> > > > > > > +++ b/MdePkg/MdePkg.dec
> > > > > > > @@ -562,6 +562,8 @@
> > > > > > >    gEfiImageSecurityDatabaseGuid  = { 0xd719b2cb, 0x3d3a, 0x4596,
> > > > > > > {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
> > > > > > >
> > > > > > >    gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac,
> > 0xa9,
> > > > > > 0x41,
> > > > > > > 0xf9, 0x36, 0x93, 0x43, 0x28 }}
> > > > > > >
> > > > > > >    gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa,
> > > 0x14,
> > > > > > 0xed,
> > > > > > > 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
> > > > > > >
> > > > > > > +  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e,
> {0xad,
> > > > 0x46,
> > > > > > > 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
> > > > > > >
> > > > > > > +  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412,
> {0x85,
> > > > 0x73,
> > > > > > > 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
> > > > > > >
> > > > > > >    gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d,
> > {0xad,
> > > > > > 0x8d,
> > > > > > > 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
> > > > > > >
> > > > > > >    gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1,
> > 0x87,
> > > > > 0xbe,
> > > > > > > 0x1, 0x49, 0x66, 0x31, 0xbd }}
> > > > > > >
> > > > > > >    gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1,
> {0xa3,
> > > > 0x28,
> > > > > > > 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
> > > > > > >
> > > > > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > > b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > > index 452ed491ea..288e44a359 100644
> > > > > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c
> > > > > > > @@ -29,12 +29,16 @@ SPDX-License-Identifier: BSD-2-Clause-
> > Patent
> > > > > > > #include <Protocol/VariablePolicy.h>
> > > > > > >
> > > > > > >  #include <Library/VariablePolicyLib.h>
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  //
> > > > > > >
> > > > > > >  // Public Exponent of RSA Key.
> > > > > > >
> > > > > > >  //
> > > > > > >
> > > > > > >  CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >  CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65,
> > > > > > > 0x03, 0x04, 0x02, 0x01 };
> > > > > > >
> > > > > > > +CONST UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01,
> 0x65,
> > > > > > > +0x03,
> > > > > > > 0x04, 0x02, 0x02 };
> > > > > > >
> > > > > > > +CONST UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01,
> 0x65,
> > > > > > > +0x03,
> > > > > > > 0x04, 0x02, 0x03 };
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >  //
> > > > > > >
> > > > > > >  // Requirement for different signature type which have been
> > defined
> > > > > > > in UEFI spec.
> > > > > > >
> > > > > > > @@ -44,6 +48,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] =
> {
> > > > > > >    // {SigType,                       SigHeaderSize,   SigDataSize  }
> > > > > > >
> > > > > > >    { EFI_CERT_SHA256_GUID,         0, 32            },
> > > > > > >
> > > > > > >    { EFI_CERT_RSA2048_GUID,        0, 256           },
> > > > > > >
> > > > > > > +  { EFI_CERT_RSA3072_GUID,        0, 384           },
> > > > > > >
> > > > > > > +  { EFI_CERT_RSA4096_GUID,        0, 512           },
> > > > > > >
> > > > > > >    { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
> > > > > > >
> > > > > > >    { EFI_CERT_SHA1_GUID,           0, 20            },
> > > > > > >
> > > > > > >    { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
> > > > > > >
> > > > > > > @@ -1172,6 +1178,172 @@
> > > > CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > > >    return EFI_SUCCESS;
> > > > > > >
> > > > > > >  }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +/**
> > > > > > >
> > > > > > > +  Calculate SHA38 digest of SignerCert CommonName +
> > ToplevelCert
> > > > > > > tbsCertificate
> > > > > > >
> > > > > > > +  SignerCert and ToplevelCert are inside the signer certificate
> chain.
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > > > > >
> > > > > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > > > > >
> > > > > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > > > > >
> > > > > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > > > > >
> > > > > > > +  @param[out] Sha384Digest       Sha384 digest calculated.
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  @return EFI_ABORTED          Digest process failed.
> > > > > > >
> > > > > > > +  @return EFI_SUCCESS          SHA384 Digest is successfully
> > calculated.
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +**/
> > > > > > >
> > > > > > > +EFI_STATUS
> > > > > > >
> > > > > > > +CalculatePrivAuthVarSignChainSHA384Digest (
> > > > > > >
> > > > > > > +  IN     UINT8  *SignerCert,
> > > > > > >
> > > > > > > +  IN     UINTN  SignerCertSize,
> > > > > > >
> > > > > > > +  IN     UINT8  *TopLevelCert,
> > > > > > >
> > > > > > > +  IN     UINTN  TopLevelCertSize,
> > > > > > >
> > > > > > > +  OUT    UINT8  *Sha384Digest
> > > > > > >
> > > > > > > +  )
> > > > > > >
> > > > > > > +{
> > > > > > >
> > > > > > > +  UINT8       *TbsCert;
> > > > > > >
> > > > > > > +  UINTN       TbsCertSize;
> > > > > > >
> > > > > > > +  CHAR8       CertCommonName[128];
> > > > > > >
> > > > > > > +  UINTN       CertCommonNameSize;
> > > > > > >
> > > > > > > +  BOOLEAN     CryptoStatus;
> > > > > > >
> > > > > > > +  EFI_STATUS  Status;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // Get SignerCert CommonName
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > > > > CertCommonName, &CertCommonNameSize);
> > > > > > >
> > > > > > > +  if (EFI_ERROR (Status)) {
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName
> > failed
> > > > with
> > > > > > > status %x\n", __FUNCTION__, Status));
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // Get TopLevelCert tbsCertificate
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > > > > &TbsCertSize)) {
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > > > > + failed!\n",
> > > > > > > __FUNCTION__));
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  ZeroMem (Sha384Digest, SHA384_DIGEST_SIZE);
> > > > > > >
> > > > > > > +  CryptoStatus = Sha384Init (mHashCtx);
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  CryptoStatus = Sha384Update (
> > > > > > >
> > > > > > > +                   mHashCtx,
> > > > > > >
> > > > > > > +                   CertCommonName,
> > > > > > >
> > > > > > > +                   AsciiStrLen (CertCommonName)
> > > > > > >
> > > > > > > +                   );
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  CryptoStatus = Sha384Update (mHashCtx, TbsCert, TbsCertSize);
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  CryptoStatus = Sha384Final (mHashCtx, Sha384Digest);
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  return EFI_SUCCESS;
> > > > > > >
> > > > > > > +}
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +/**
> > > > > > >
> > > > > > > +  Calculate SHA512 digest of SignerCert CommonName +
> > ToplevelCert
> > > > > > > tbsCertificate
> > > > > > >
> > > > > > > +  SignerCert and ToplevelCert are inside the signer certificate
> chain.
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  @param[in]  SignerCert          A pointer to SignerCert data.
> > > > > > >
> > > > > > > +  @param[in]  SignerCertSize      Length of SignerCert data.
> > > > > > >
> > > > > > > +  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
> > > > > > >
> > > > > > > +  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
> > > > > > >
> > > > > > > +  @param[out] Sha512Digest       Sha512 digest calculated.
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  @return EFI_ABORTED          Digest process failed.
> > > > > > >
> > > > > > > +  @return EFI_SUCCESS          SHA512 Digest is successfully
> > calculated.
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +**/
> > > > > > >
> > > > > > > +EFI_STATUS
> > > > > > >
> > > > > > > +CalculatePrivAuthVarSignChainSHA512Digest (
> > > > > > >
> > > > > > > +  IN     UINT8  *SignerCert,
> > > > > > >
> > > > > > > +  IN     UINTN  SignerCertSize,
> > > > > > >
> > > > > > > +  IN     UINT8  *TopLevelCert,
> > > > > > >
> > > > > > > +  IN     UINTN  TopLevelCertSize,
> > > > > > >
> > > > > > > +  OUT    UINT8  *Sha512Digest
> > > > > > >
> > > > > > > +  )
> > > > > > >
> > > > > > > +{
> > > > > > >
> > > > > > > +  UINT8       *TbsCert;
> > > > > > >
> > > > > > > +  UINTN       TbsCertSize;
> > > > > > >
> > > > > > > +  CHAR8       CertCommonName[128];
> > > > > > >
> > > > > > > +  UINTN       CertCommonNameSize;
> > > > > > >
> > > > > > > +  BOOLEAN     CryptoStatus;
> > > > > > >
> > > > > > > +  EFI_STATUS  Status;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  CertCommonNameSize = sizeof (CertCommonName);
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // Get SignerCert CommonName
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  Status = X509GetCommonName (SignerCert, SignerCertSize,
> > > > > > > CertCommonName, &CertCommonNameSize);
> > > > > > >
> > > > > > > +  if (EFI_ERROR (Status)) {
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName
> > failed
> > > > with
> > > > > > > status %x\n", __FUNCTION__, Status));
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // Get TopLevelCert tbsCertificate
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert,
> > > > > > > &TbsCertSize)) {
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate
> > > > > > > + failed!\n",
> > > > > > > __FUNCTION__));
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // Digest SignerCert CN + TopLevelCert tbsCertificate
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  ZeroMem (Sha512Digest, SHA512_DIGEST_SIZE);
> > > > > > >
> > > > > > > +  CryptoStatus = Sha512Init (mHashCtx);
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  // '\0' is forced in CertCommonName. No overflow issue
> > > > > > >
> > > > > > > +  //
> > > > > > >
> > > > > > > +  CryptoStatus = Sha512Update (
> > > > > > >
> > > > > > > +                   mHashCtx,
> > > > > > >
> > > > > > > +                   CertCommonName,
> > > > > > >
> > > > > > > +                   AsciiStrLen (CertCommonName)
> > > > > > >
> > > > > > > +                   );
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  CryptoStatus = Sha512Update (mHashCtx, TbsCert, TbsCertSize);
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  CryptoStatus = Sha512Final (mHashCtx, Sha512Digest);
> > > > > > >
> > > > > > > +  if (!CryptoStatus) {
> > > > > > >
> > > > > > > +    return EFI_ABORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  return EFI_SUCCESS;
> > > > > > >
> > > > > > > +}
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  /**
> > > > > > >
> > > > > > >    Find matching signer's certificates for common authenticated
> > > > > > > variable
> > > > > > >
> > > > > > >    by corresponding VariableName and VendorGuid from "certdb"
> or
> > > > > > "certdbv".
> > > > > > >
> > > > > > > @@ -1526,6 +1698,7 @@ DeleteCertsFromDb (
> > > > > > >    @param[in]  SignerCertSize    Length of signer certificate.
> > > > > > >
> > > > > > >    @param[in]  TopLevelCert      Top-level certificate data.
> > > > > > >
> > > > > > >    @param[in]  TopLevelCertSize  Length of top-level certificate.
> > > > > > >
> > > > > > > +  @param[in]  DigestSize        Digest Size.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    @retval  EFI_INVALID_PARAMETER Any input parameter is
> invalid.
> > > > > > >
> > > > > > >    @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry
> > with
> > > > > > same
> > > > > > > VariableName
> > > > > > >
> > > > > > > @@ -1542,7 +1715,8 @@ InsertCertsToDb (
> > > > > > >    IN     UINT8     *SignerCert,
> > > > > > >
> > > > > > >    IN     UINTN     SignerCertSize,
> > > > > > >
> > > > > > >    IN     UINT8     *TopLevelCert,
> > > > > > >
> > > > > > > -  IN     UINTN     TopLevelCertSize
> > > > > > >
> > > > > > > +  IN     UINTN     TopLevelCertSize,
> > > > > > >
> > > > > > > +  IN     UINT32    DigestSize
> > > > > > >
> > > > > > >    )
> > > > > > >
> > > > > > >  {
> > > > > > >
> > > > > > >    EFI_STATUS         Status;
> > > > > > >
> > > > > > > @@ -1556,7 +1730,7 @@ InsertCertsToDb (
> > > > > > >    UINT32             CertDataSize;
> > > > > > >
> > > > > > >    AUTH_CERT_DB_DATA  *Ptr;
> > > > > > >
> > > > > > >    CHAR16             *DbName;
> > > > > > >
> > > > > > > -  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
> > > > > > >
> > > > > > > +  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    if ((VariableName == NULL) || (VendorGuid == NULL) ||
> > (SignerCert
> > > > > > > == NULL)
> > > > > > > || (TopLevelCert == NULL)) {
> > > > > > >
> > > > > > >      return EFI_INVALID_PARAMETER;
> > > > > > >
> > > > > > > @@ -1618,20 +1792,41 @@ InsertCertsToDb (
> > > > > > >    // Construct new data content of variable "certdb" or "certdbv".
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > >    NameSize      = (UINT32)StrLen (VariableName);
> > > > > > >
> > > > > > > -  CertDataSize  = sizeof (Sha256Digest);
> > > > > > >
> > > > > > > +  CertDataSize  = DigestSize;
> > > > > > >
> > > > > > >    CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) +
> > > > (UINT32)CertDataSize +
> > > > > > > NameSize * sizeof (CHAR16);
> > > > > > >
> > > > > > >    NewCertDbSize = (UINT32)DataSize + CertNodeSize;
> > > > > > >
> > > > > > >    if (NewCertDbSize > mMaxCertDbSize) {
> > > > > > >
> > > > > > >      return EFI_OUT_OF_RESOURCES;
> > > > > > >
> > > > > > >    }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > -  Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > > >
> > > > > > > -             SignerCert,
> > > > > > >
> > > > > > > -             SignerCertSize,
> > > > > > >
> > > > > > > -             TopLevelCert,
> > > > > > >
> > > > > > > -             TopLevelCertSize,
> > > > > > >
> > > > > > > -             Sha256Digest
> > > > > > >
> > > > > > > -             );
> > > > > > >
> > > > > > > +  if (DigestSize == SHA256_DIGEST_SIZE) {
> > > > > > >
> > > > > > > +    Status = CalculatePrivAuthVarSignChainSHA256Digest (
> > > > > > >
> > > > > > > +               SignerCert,
> > > > > > >
> > > > > > > +               SignerCertSize,
> > > > > > >
> > > > > > > +               TopLevelCert,
> > > > > > >
> > > > > > > +               TopLevelCertSize,
> > > > > > >
> > > > > > > +               ShaDigest
> > > > > > >
> > > > > > > +               );
> > > > > > >
> > > > > > > +  } else if (DigestSize == SHA384_DIGEST_SIZE) {
> > > > > > >
> > > > > > > +    Status = CalculatePrivAuthVarSignChainSHA384Digest (
> > > > > > >
> > > > > > > +               SignerCert,
> > > > > > >
> > > > > > > +               SignerCertSize,
> > > > > > >
> > > > > > > +               TopLevelCert,
> > > > > > >
> > > > > > > +               TopLevelCertSize,
> > > > > > >
> > > > > > > +               ShaDigest
> > > > > > >
> > > > > > > +               );
> > > > > > >
> > > > > > > +  } else if (DigestSize == SHA512_DIGEST_SIZE) {
> > > > > > >
> > > > > > > +    Status = CalculatePrivAuthVarSignChainSHA512Digest (
> > > > > > >
> > > > > > > +               SignerCert,
> > > > > > >
> > > > > > > +               SignerCertSize,
> > > > > > >
> > > > > > > +               TopLevelCert,
> > > > > > >
> > > > > > > +               TopLevelCertSize,
> > > > > > >
> > > > > > > +               ShaDigest
> > > > > > >
> > > > > > > +               );
> > > > > > >
> > > > > > > +  } else {
> > > > > > >
> > > > > > > +    return EFI_UNSUPPORTED;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >    if (EFI_ERROR (Status)) {
> > > > > > >
> > > > > > >      return Status;
> > > > > > >
> > > > > > >    }
> > > > > > >
> > > > > > > @@ -1663,7 +1858,7 @@ InsertCertsToDb (
> > > > > > >
> > > > > > >
> > > > > > >    CopyMem (
> > > > > > >
> > > > > > >      (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize *
> > sizeof
> > > > > > > (CHAR16),
> > > > > > >
> > > > > > > -    Sha256Digest,
> > > > > > >
> > > > > > > +    ShaDigest,
> > > > > > >
> > > > > > >      CertDataSize
> > > > > > >
> > > > > > >      );
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > @@ -1857,7 +2052,7 @@ VerifyTimeBasedPayload (
> > > > > > >    UINTN                          CertStackSize;
> > > > > > >
> > > > > > >    UINT8                          *CertsInCertDb;
> > > > > > >
> > > > > > >    UINT32                         CertsSizeinDb;
> > > > > > >
> > > > > > > -  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
> > > > > > >
> > > > > > > +  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
> > > > > > >
> > > > > > >    EFI_CERT_DATA                  *CertDataPtr;
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > > @@ -1928,7 +2123,7 @@ VerifyTimeBasedPayload (
> > > > > > >
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > >    // SignedData.digestAlgorithms shall contain the digest algorithm
> > > > > > > used when preparing the
> > > > > > >
> > > > > > > -  // signature. Only a digest algorithm of SHA-256 is accepted.
> > > > > > >
> > > > > > > +  // signature. Only a digest algorithm of SHA-256, SHA-384 or
> > > > > > > + SHA-512 is
> > > > > > > accepted.
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > >    //    According to PKCS#7 Definition (https://www.rfc-
> > > > > > editor.org/rfc/rfc2315):
> > > > > > >
> > > > > > >    //        SignedData ::= SEQUENCE {
> > > > > > >
> > > > > > > @@ -1978,7 +2173,19 @@ VerifyTimeBasedPayload (
> > > > > > >               || (CompareMem (SigData + 13, &mSha256OidValue,
> sizeof
> > > > > > > (mSha256OidValue)) != 0)))
> > > > > > >
> > > > > > >         && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
> > > > > > >
> > > > > > >            && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > > > TWO_BYTE_ENCODE)
> > > > > > >
> > > > > > > -             || (CompareMem (SigData + 32, &mSha256OidValue,
> sizeof
> > > > > > > (mSha256OidValue)) != 0))))
> > > > > > >
> > > > > > > +             || (CompareMem (SigData + 32, &mSha256OidValue,
> sizeof
> > > > > > > (mSha256OidValue)) != 0)))
> > > > > > >
> > > > > > > +       && (  (SigDataSize >= (13 + sizeof (mSha384OidValue)))
> > > > > > >
> > > > > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > > > > + TWO_BYTE_ENCODE)
> > > > > > >
> > > > > > > +             || (CompareMem (SigData + 13, &mSha384OidValue,
> sizeof
> > > > > > > (mSha384OidValue)) != 0)))
> > > > > > >
> > > > > > > +       && (  (SigDataSize >= (32 + sizeof (mSha384OidValue)))
> > > > > > >
> > > > > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > > > + TWO_BYTE_ENCODE)
> > > > > > >
> > > > > > > +             || (CompareMem (SigData + 32, &mSha384OidValue,
> sizeof
> > > > > > > (mSha384OidValue)) != 0)))
> > > > > > >
> > > > > > > +       && (  (SigDataSize >= (13 + sizeof (mSha512OidValue)))
> > > > > > >
> > > > > > > +          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) !=
> > > > > > > + TWO_BYTE_ENCODE)
> > > > > > >
> > > > > > > +             || (CompareMem (SigData + 13, &mSha512OidValue,
> sizeof
> > > > > > > (mSha512OidValue)) != 0)))
> > > > > > >
> > > > > > > +       && (  (SigDataSize >= (32 + sizeof (mSha512OidValue)))
> > > > > > >
> > > > > > > +          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) !=
> > > > > > > + TWO_BYTE_ENCODE)
> > > > > > >
> > > > > > > +             || (CompareMem (SigData + 32, &mSha512OidValue,
> sizeof
> > > > > > > (mSha512OidValue)) != 0))))
> > > > > > >
> > > > > > >      {
> > > > > > >
> > > > > > >        return EFI_SECURITY_VIOLATION;
> > > > > > >
> > > > > > >      }
> > > > > > >
> > > > > > > @@ -2180,9 +2387,39 @@ VerifyTimeBasedPayload (
> > > > > > >                          ReadUnaligned32 ((UINT32
> > > > > > > *)&(CertDataPtr->CertDataLength)),
> > > > > > >
> > > > > > >                          TopLevelCert,
> > > > > > >
> > > > > > >                          TopLevelCertSize,
> > > > > > >
> > > > > > > -                        Sha256Digest
> > > > > > >
> > > > > > > +                        ShaDigest
> > > > > > >
> > > > > > > +                        );
> > > > > > >
> > > > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > > > + CertsInCertDb,
> > > > > > > CertsSizeinDb) != 0)) {
> > > > > > >
> > > > > > > +          goto Exit;
> > > > > > >
> > > > > > > +        }
> > > > > > >
> > > > > > > +      } else if (CertsSizeinDb == SHA384_DIGEST_SIZE) {
> > > > > > >
> > > > > > > +        //
> > > > > > >
> > > > > > > +        // Check hash of signer cert CommonName + Top-level
> issuer
> > > > > > > tbsCertificate against data in CertDb
> > > > > > >
> > > > > > > +        //
> > > > > > >
> > > > > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > > > > >
> > > > > > > +        Status      = CalculatePrivAuthVarSignChainSHA384Digest (
> > > > > > >
> > > > > > > +                        CertDataPtr->CertDataBuffer,
> > > > > > >
> > > > > > > +                        ReadUnaligned32 ((UINT32
> > > > > > > + *)&(CertDataPtr->CertDataLength)),
> > > > > > >
> > > > > > > +                        TopLevelCert,
> > > > > > >
> > > > > > > +                        TopLevelCertSize,
> > > > > > >
> > > > > > > +                        ShaDigest
> > > > > > >
> > > > > > > +                        );
> > > > > > >
> > > > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > > > + CertsInCertDb,
> > > > > > > CertsSizeinDb) != 0)) {
> > > > > > >
> > > > > > > +          goto Exit;
> > > > > > >
> > > > > > > +        }
> > > > > > >
> > > > > > > +      } else if (CertsSizeinDb == SHA512_DIGEST_SIZE) {
> > > > > > >
> > > > > > > +        //
> > > > > > >
> > > > > > > +        // Check hash of signer cert CommonName + Top-level
> issuer
> > > > > > > tbsCertificate against data in CertDb
> > > > > > >
> > > > > > > +        //
> > > > > > >
> > > > > > > +        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
> > > > > > >
> > > > > > > +        Status      = CalculatePrivAuthVarSignChainSHA512Digest (
> > > > > > >
> > > > > > > +                        CertDataPtr->CertDataBuffer,
> > > > > > >
> > > > > > > +                        ReadUnaligned32 ((UINT32
> > > > > > > + *)&(CertDataPtr->CertDataLength)),
> > > > > > >
> > > > > > > +                        TopLevelCert,
> > > > > > >
> > > > > > > +                        TopLevelCertSize,
> > > > > > >
> > > > > > > +                        ShaDigest
> > > > > > >
> > > > > > >                          );
> > > > > > >
> > > > > > > -        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest,
> > > > > > CertsInCertDb,
> > > > > > > CertsSizeinDb) != 0)) {
> > > > > > >
> > > > > > > +        if (EFI_ERROR (Status) || (CompareMem (ShaDigest,
> > > > > > > + CertsInCertDb,
> > > > > > > CertsSizeinDb) != 0)) {
> > > > > > >
> > > > > > >            goto Exit;
> > > > > > >
> > > > > > >          }
> > > > > > >
> > > > > > >        } else {
> > > > > > >
> > > > > > > @@ -2221,7 +2458,8 @@ VerifyTimeBasedPayload (
> > > > > > >                        CertDataPtr->CertDataBuffer,
> > > > > > >
> > > > > > >                        ReadUnaligned32 ((UINT32
> > > > > > > *)&(CertDataPtr->CertDataLength)),
> > > > > > >
> > > > > > >                        TopLevelCert,
> > > > > > >
> > > > > > > -                      TopLevelCertSize
> > > > > > >
> > > > > > > +                      TopLevelCertSize,
> > > > > > >
> > > > > > > +                      CertsSizeinDb
> > > > > > >
> > > > > > >                        );
> > > > > > >
> > > > > > >        if (EFI_ERROR (Status)) {
> > > > > > >
> > > > > > >          VerifyStatus = FALSE;
> > > > > > >
> > > > > > > diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > > b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > > index dc61ae840c..552c0e99be 100644
> > > > > > > --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > > +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c
> > > > > > > @@ -26,7 +26,7 @@ UINT32  mMaxCertDbSize;
> > > > > > >  UINT32  mPlatformMode;
> > > > > > >
> > > > > > >  UINT8   mVendorKeyState;
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > -EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > > > > EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID,
> > > > > > EFI_CERT_X509_GUID };
> > > > > > >
> > > > > > > +EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID,
> > > > > > > EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID,
> > > > > > EFI_CERT_SHA512_GUID,
> > > > > > > EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID,
> > > > > > EFI_CERT_RSA4096_GUID,
> > > > > > > EFI_CERT_X509_GUID };
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >  //
> > > > > > >
> > > > > > >  // Hash context pointer
> > > > > > >
> > > > > > > @@ -135,7 +135,7 @@ AuthVariableLibInitialize (
> > > > > > >    //
> > > > > > >
> > > > > > >    // Initialize hash context.
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > > -  CtxSize  = Sha256GetContextSize ();
> > > > > > >
> > > > > > > +  CtxSize  = Sha512GetContextSize ();
> > > > > > >
> > > > > > >    mHashCtx = AllocateRuntimePool (CtxSize);
> > > > > > >
> > > > > > >    if (mHashCtx == NULL) {
> > > > > > >
> > > > > > >      return EFI_OUT_OF_RESOURCES;
> > > > > > >
> > > > > > > diff --git
> > > > > > >
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > > c
> > > > > > >
> > > >
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > > c
> > > > > > > index 66e2f5eaa3..f642aad64d 100644
> > > > > > > ---
> > > > > > >
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > > c
> > > > > > > +++
> > > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > > > > +++ Lib.c
> > > > > > > @@ -1606,6 +1606,35 @@ Done:
> > > > > > >    return VerifyStatus;
> > > > > > >
> > > > > > >  }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +/**
> > > > > > >
> > > > > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  @retval  UINT32       Hash Alg
> > > > > > >
> > > > > > > +  **/
> > > > > > >
> > > > > > > +UINT32
> > > > > > >
> > > > > > > +GetDefaultHashAlg (
> > > > > > >
> > > > > > > +  VOID
> > > > > > >
> > > > > > > +  )
> > > > > > >
> > > > > > > +{
> > > > > > >
> > > > > > > +  UINT32  HashAlg;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > > > > >
> > > > > > > +  case 1:
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > > > >
> > > > > > > +    HashAlg = HASHALG_SHA384;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  case 2:
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > > > >
> > > > > > > +    HashAlg = HASHALG_SHA512;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  default:
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > > > >
> > > > > > > +    HashAlg = HASHALG_SHA256;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +  return HashAlg;
> > > > > > >
> > > > > > > +}
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  /**
> > > > > > >
> > > > > > >    Provide verification service for signed images, which include
> both
> > > > > > > signature validation
> > > > > > >
> > > > > > >    and platform policy control. For signature types, both UEFI
> > > > > > > WIN_CERTIFICATE_UEFI_GUID and
> > > > > > >
> > > > > > > @@ -1620,7 +1649,7 @@ Done:
> > > > > > >        in the security database "db", and no valid signature nor any
> > > > > > > hash value of the image may
> > > > > > >
> > > > > > >        be reflected in the security database "dbx".
> > > > > > >
> > > > > > >      Otherwise, the image is not signed,
> > > > > > >
> > > > > > > -      The SHA256 hash value of the image must match a record in
> the
> > > > > > security
> > > > > > > database "db", and
> > > > > > >
> > > > > > > +      The hash value of the image must match a record in the
> security
> > > > > > > + database
> > > > > > > "db", and
> > > > > > >
> > > > > > >        not be reflected in the security data base "dbx".
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    Caution: This function may receive untrusted input.
> > > > > > >
> > > > > > > @@ -1832,10 +1861,10 @@ DxeImageVerificationHandler (
> > > > > > >    //
> > > > > > >
> > > > > > >    if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
> > > > > > >
> > > > > > >      //
> > > > > > >
> > > > > > > -    // This image is not signed. The SHA256 hash value of the image
> > must
> > > > > > match
> > > > > > > a record in the security database "db",
> > > > > > >
> > > > > > > +    // This image is not signed. The hash value of the image must
> > > > > > > + match a record
> > > > > > > in the security database "db",
> > > > > > >
> > > > > > >      // and not be reflected in the security data base "dbx".
> > > > > > >
> > > > > > >      //
> > > > > > >
> > > > > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > > > > >
> > > > > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > > > > >
> > > > > > >        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to
> hash
> > > > > > > this image using %s.\n", mHashTypeStr));
> > > > > > >
> > > > > > >        goto Failed;
> > > > > > >
> > > > > > >      }
> > > > > > >
> > > > > > > diff --git
> > > > > > >
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > > inf
> > > > > > >
> > > >
> b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > > inf
> > > > > > > index 1e1a639857..f1ef9236c2 100644
> > > > > > > ---
> > > > > > >
> > > >
> a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.
> > > > > > > inf
> > > > > > > +++
> > > > b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerification
> > > > > > > +++ Lib.inf
> > > > > > > @@ -93,3 +93,4 @@
> > > > > > >
> > > > gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
> > > > > > > ## SOMETIMES_CONSUMES
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolic
> > > > > > y
> > > > > > > ## SOMETIMES_CONSUMES
> > > > > > >
> > > > > > >
> > > > gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy
> > > > > > ##
> > > > > > > SOMETIMES_CONSUMES
> > > > > > >
> > > > > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > > > > ##
> > > > > > > CONSUMES
> > > > > > >
> > > > > > > diff --git a/SecurityPkg/SecurityPkg.dec
> > b/SecurityPkg/SecurityPkg.dec
> > > > > > > index 0382090f4e..4adc2a72ab 100644
> > > > > > > --- a/SecurityPkg/SecurityPkg.dec
> > > > > > > +++ b/SecurityPkg/SecurityPkg.dec
> > > > > > > @@ -521,6 +521,13 @@
> > > > > > >    # @Prompt Skip Hdd Password prompt.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSkipHddPasswordPrompt|FALSE|BOOLE
> > > > > > AN|
> > > > > > > 0x00010021
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +  ## Indicates default hash algorithm in Secure Boot
> > > > > > >
> > > > > > > +  #   0 - Use SHA256
> > > > > > >
> > > > > > > +  #   1 - Use SHA384
> > > > > > >
> > > > > > > +  #   2 - Use SHA512
> > > > > > >
> > > > > > > +  # @Prompt Secure Boot default hash algorithm
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > >
> > > >
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg|0|UINT8|0x
> > > > > > 00
> > > > > > > 0
> > > > > > > 10040
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  [PcdsDynamic, PcdsDynamicEx]
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    ## This PCD indicates Hash mask for TPM 2.0. Bit definition
> > > > > > > strictly follows TCG Algorithm Registry.<BR><BR>
> > > > > > >
> > > > > > > diff --git
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > ig
> > > > > > > Dxe.inf
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > ig
> > > > > > > Dxe.inf
> > > > > > > index 1671d5be7c..4b0012d033 100644
> > > > > > > ---
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > ig
> > > > > > > Dxe.inf
> > > > > > > +++
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > ig
> > > > > > > Dxe.inf
> > > > > > > @@ -70,6 +70,14 @@
> > > > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > >    gEfiCertRsa2048Guid
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for
> the
> > > > type of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for
> the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  gEfiCertRsa3072Guid
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for
> the
> > > > type of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for
> the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  gEfiCertRsa4096Guid
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >    ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for
> the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > >    gEfiCertX509Guid
> > > > > > >
> > > > > > > @@ -82,6 +90,14 @@
> > > > > > >    ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > >    gEfiCertSha256Guid
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for
> the
> > > > type of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for
> the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  gEfiCertSha384Guid
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for
> the
> > > > type of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for
> the
> > type
> > > > of
> > > > > > the
> > > > > > > signature.
> > > > > > >
> > > > > > > +  gEfiCertSha512Guid
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >    ## SOMETIMES_CONSUMES      ## Variable:L"db"
> > > > > > >
> > > > > > >    ## SOMETIMES_PRODUCES      ## Variable:L"db"
> > > > > > >
> > > > > > >    ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
> > > > > > >
> > > > > > > @@ -107,6 +123,9 @@
> > > > > > >    gEfiCertX509Sha384Guid                        ## SOMETIMES_PRODUCES
> > ##
> > > > GUID
> > > > > > #
> > > > > > > Unique ID for the type of the certificate.
> > > > > > >
> > > > > > >    gEfiCertX509Sha512Guid                        ## SOMETIMES_PRODUCES
> > ##
> > > > GUID
> > > > > > #
> > > > > > > Unique ID for the type of the certificate.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +[Pcd]
> > > > > > >
> > > > > > > +  gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultHashAlg
> > > > > > ##
> > > > > > > CONSUMES
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  [Protocols]
> > > > > > >
> > > > > > >    gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> > > > > > >
> > > > > > >    gEfiDevicePathProtocolGuid                    ## PRODUCES
> > > > > > >
> > > > > > > diff --git
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.c
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.c
> > > > > > > index 4299a6b5e5..0ba029a394 100644
> > > > > > > ---
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.c
> > > > > > > +++
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.c
> > > > > > > @@ -560,7 +560,7 @@ ON_EXIT:
> > > > > > >
> > > > > > >
> > > > > > >  **/
> > > > > > >
> > > > > > >  EFI_STATUS
> > > > > > >
> > > > > > > -EnrollRsa2048ToKek (
> > > > > > >
> > > > > > > +EnrollRsaToKek (
> > > > > > >
> > > > > > >    IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
> > > > > > >
> > > > > > >    )
> > > > > > >
> > > > > > >  {
> > > > > > >
> > > > > > > @@ -603,8 +603,13 @@ EnrollRsa2048ToKek (
> > > > > > >
> > > > > > >
> > > > > > >    ASSERT (KeyBlob != NULL);
> > > > > > >
> > > > > > >    KeyInfo = (CPL_KEY_INFO *)KeyBlob;
> > > > > > >
> > > > > > > -  if (KeyInfo->KeyLengthInBits / 8 !=
> > WIN_CERT_UEFI_RSA2048_SIZE) {
> > > > > > >
> > > > > > > -    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only
> > RSA2048 is
> > > > > > > supported.\n"));
> > > > > > >
> > > > > > > +  switch (KeyInfo->KeyLengthInBits / 8) {
> > > > > > >
> > > > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > > >
> > > > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > > >
> > > > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  default :
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only
> > RSA2048,
> > > > > > > + RSA3072
> > > > > > > and RSA4096 are supported.\n"));
> > > > > > >
> > > > > > >      Status = EFI_UNSUPPORTED;
> > > > > > >
> > > > > > >      goto ON_EXIT;
> > > > > > >
> > > > > > >    }
> > > > > > >
> > > > > > > @@ -632,7 +637,7 @@ EnrollRsa2048ToKek (
> > > > > > >    //
> > > > > > >
> > > > > > >    KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
> > > > > > >
> > > > > > >                     + sizeof (EFI_SIGNATURE_DATA) - 1
> > > > > > >
> > > > > > > -                   + WIN_CERT_UEFI_RSA2048_SIZE;
> > > > > > >
> > > > > > > +                   + KeyLenInBytes;
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool
> > > > > > > (KekSigListSize);
> > > > > > >
> > > > > > >    if (KekSigList == NULL) {
> > > > > > >
> > > > > > > @@ -642,17 +647,32 @@ EnrollRsa2048ToKek (
> > > > > > >
> > > > > > >
> > > > > > >    KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
> > > > > > >
> > > > > > >                                    + sizeof (EFI_SIGNATURE_DATA) - 1
> > > > > > >
> > > > > > > -                                  + WIN_CERT_UEFI_RSA2048_SIZE;
> > > > > > >
> > > > > > > +                                  + (UINT32) KeyLenInBytes;
> > > > > > >
> > > > > > >    KekSigList->SignatureHeaderSize = 0;
> > > > > > >
> > > > > > > -  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) -
> 1
> > +
> > > > > > > WIN_CERT_UEFI_RSA2048_SIZE;
> > > > > > >
> > > > > > > -  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
> > > > > > >
> > > > > > > +  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) -
> 1
> > +
> > > > > > (UINT32)
> > > > > > > KeyLenInBytes;
> > > > > > >
> > > > > > > +  switch (KeyLenInBytes) {
> > > > > > >
> > > > > > > +  case WIN_CERT_UEFI_RSA2048_SIZE:
> > > > > > >
> > > > > > > +    CopyGuid (&KekSigList->SignatureType,
> &gEfiCertRsa2048Guid);
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  case WIN_CERT_UEFI_RSA3072_SIZE:
> > > > > > >
> > > > > > > +    CopyGuid (&KekSigList->SignatureType,
> &gEfiCertRsa3072Guid);
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  case WIN_CERT_UEFI_RSA4096_SIZE:
> > > > > > >
> > > > > > > +    CopyGuid (&KekSigList->SignatureType,
> &gEfiCertRsa4096Guid);
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  default :
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
> > > > > > >
> > > > > > > +    Status = EFI_UNSUPPORTED;
> > > > > > >
> > > > > > > +    goto ON_EXIT;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList +
> > sizeof
> > > > > > > (EFI_SIGNATURE_LIST));
> > > > > > >
> > > > > > >    CopyGuid (&KEKSigData->SignatureOwner, Private-
> > >SignatureGUID);
> > > > > > >
> > > > > > >    CopyMem (
> > > > > > >
> > > > > > >      KEKSigData->SignatureData,
> > > > > > >
> > > > > > >      KeyBlob + sizeof (CPL_KEY_INFO),
> > > > > > >
> > > > > > > -    WIN_CERT_UEFI_RSA2048_SIZE
> > > > > > >
> > > > > > > +    KeyLenInBytes
> > > > > > >
> > > > > > >      );
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    //
> > > > > > >
> > > > > > > @@ -890,7 +910,7 @@ EnrollKeyExchangeKey (
> > > > > > >    if (IsDerEncodeCertificate (FilePostFix)) {
> > > > > > >
> > > > > > >      return EnrollX509ToKek (Private);
> > > > > > >
> > > > > > >    } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
> > > > > > >
> > > > > > > -    return EnrollRsa2048ToKek (Private);
> > > > > > >
> > > > > > > +    return EnrollRsaToKek (Private);
> > > > > > >
> > > > > > >    } else {
> > > > > > >
> > > > > > >      //
> > > > > > >
> > > > > > >      // File type is wrong, simply close it
> > > > > > >
> > > > > > > @@ -1847,7 +1867,7 @@ HashPeImage (
> > > > > > >    SectionHeader = NULL;
> > > > > > >
> > > > > > >    Status        = FALSE;
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > -  if (HashAlg != HASHALG_SHA256) {
> > > > > > >
> > > > > > > +  if ((HashAlg >= HASHALG_MAX)) {
> > > > > > >
> > > > > > >      return FALSE;
> > > > > > >
> > > > > > >    }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > @@ -1856,8 +1876,25 @@ HashPeImage (
> > > > > > >    //
> > > > > > >
> > > > > > >    ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > -  mImageDigestSize = SHA256_DIGEST_SIZE;
> > > > > > >
> > > > > > > -  mCertType        = gEfiCertSha256Guid;
> > > > > > >
> > > > > > > +   switch (HashAlg) {
> > > > > > >
> > > > > > > +    case HASHALG_SHA256:
> > > > > > >
> > > > > > > +      mImageDigestSize = SHA256_DIGEST_SIZE;
> > > > > > >
> > > > > > > +      mCertType        = gEfiCertSha256Guid;
> > > > > > >
> > > > > > > +      break;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +    case HASHALG_SHA384:
> > > > > > >
> > > > > > > +      mImageDigestSize = SHA384_DIGEST_SIZE;
> > > > > > >
> > > > > > > +      mCertType        = gEfiCertSha384Guid;
> > > > > > >
> > > > > > > +      break;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +    case HASHALG_SHA512:
> > > > > > >
> > > > > > > +      mImageDigestSize = SHA512_DIGEST_SIZE;
> > > > > > >
> > > > > > > +      mCertType        = gEfiCertSha512Guid;
> > > > > > >
> > > > > > > +      break;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +    default:
> > > > > > >
> > > > > > > +      return FALSE;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    CtxSize = mHash[HashAlg].GetContextSize ();
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > @@ -2222,6 +2259,35 @@ ON_EXIT:
> > > > > > >    return Status;
> > > > > > >
> > > > > > >  }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > +/**
> > > > > > >
> > > > > > > +  Get Hash Alg by PcdSecureBootDefaultHashAlg
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  @retval  UINT32       Hash Alg
> > > > > > >
> > > > > > > +  **/
> > > > > > >
> > > > > > > +UINT32
> > > > > > >
> > > > > > > +GetDefaultHashAlg (
> > > > > > >
> > > > > > > +  VOID
> > > > > > >
> > > > > > > +  )
> > > > > > >
> > > > > > > +{
> > > > > > >
> > > > > > > +  UINT32  HashAlg;
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > > +  switch (PcdGet8 (PcdSecureBootDefaultHashAlg)) {
> > > > > > >
> > > > > > > +  case 1:
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA384", __func__));
> > > > > > >
> > > > > > > +    HashAlg = HASHALG_SHA384;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  case 2:
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA512", __func__));
> > > > > > >
> > > > > > > +    HashAlg = HASHALG_SHA512;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  default:
> > > > > > >
> > > > > > > +    DEBUG ((DEBUG_INFO, "%a use SHA256", __func__));
> > > > > > >
> > > > > > > +    HashAlg = HASHALG_SHA256;
> > > > > > >
> > > > > > > +    break;
> > > > > > >
> > > > > > > +  }
> > > > > > >
> > > > > > > +  return HashAlg;
> > > > > > >
> > > > > > > +}
> > > > > > >
> > > > > > > +
> > > > > > >
> > > > > > >  /**
> > > > > > >
> > > > > > >    Enroll a new signature of executable into Signature Database.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > @@ -2289,7 +2355,7 @@ EnrollImageSignatureToSigDB (
> > > > > > >    }
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >    if (mSecDataDir->SizeOfCert == 0) {
> > > > > > >
> > > > > > > -    if (!HashPeImage (HASHALG_SHA256)) {
> > > > > > >
> > > > > > > +    if (!HashPeImage (GetDefaultHashAlg ())) {
> > > > > > >
> > > > > > >        Status =  EFI_SECURITY_VIOLATION;
> > > > > > >
> > > > > > >        goto ON_EXIT;
> > > > > > >
> > > > > > >      }
> > > > > > >
> > > > > > > @@ -2589,6 +2655,10 @@ UpdateDeletePage (
> > > > > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > > > > CertList->SignatureListSize)) {
> > > > > > >
> > > > > > >      if (CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa2048Guid))
> > > > > > > {
> > > > > > >
> > > > > > >        Help = STRING_TOKEN
> > (STR_CERT_TYPE_RSA2048_SHA256_GUID);
> > > > > > >
> > > > > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > > > > + &gEfiCertRsa3072Guid)) {
> > > > > > >
> > > > > > > +      Help = STRING_TOKEN
> > (STR_CERT_TYPE_RSA3072_SHA384_GUID);
> > > > > > >
> > > > > > > +    } else if (CompareGuid (&CertList->SignatureType,
> > > > > > > + &gEfiCertRsa4096Guid)) {
> > > > > > >
> > > > > > > +      Help = STRING_TOKEN
> > (STR_CERT_TYPE_RSA4096_SHA512_GUID);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > > > > &gEfiCertX509Guid)) {
> > > > > > >
> > > > > > >        Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&CertList->SignatureType,
> > > > > > > &gEfiCertSha1Guid)) {
> > > > > > >
> > > > > > > @@ -2750,6 +2820,8 @@ DeleteKeyExchangeKey (
> > > > > > >    GuidIndex      = 0;
> > > > > > >
> > > > > > >    while ((KekDataSize > 0) && (KekDataSize >=
> > > > > > > CertList->SignatureListSize)) {
> > > > > > >
> > > > > > >      if (CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa2048Guid)
> > > > > > > ||
> > > > > > >
> > > > > > > +        CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa3072Guid)
> > > > > > > + ||
> > > > > > >
> > > > > > > +        CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa4096Guid)
> > > > > > > + ||
> > > > > > >
> > > > > > >          CompareGuid (&CertList->SignatureType,
> &gEfiCertX509Guid))
> > > > > > >
> > > > > > >      {
> > > > > > >
> > > > > > >        CopyMem (Data + Offset, CertList, (sizeof
> (EFI_SIGNATURE_LIST)
> > > > > > > + CertList-
> > > > > > > >SignatureHeaderSize));
> > > > > > >
> > > > > > > @@ -2952,6 +3024,8 @@ DeleteSignature (
> > > > > > >    GuidIndex    = 0;
> > > > > > >
> > > > > > >    while ((ItemDataSize > 0) && (ItemDataSize >=
> > > > > > > CertList->SignatureListSize)) {
> > > > > > >
> > > > > > >      if (CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa2048Guid)
> > > > > > > ||
> > > > > > >
> > > > > > > +        CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa3072Guid)
> > > > > > > + ||
> > > > > > >
> > > > > > > +        CompareGuid (&CertList->SignatureType,
> > &gEfiCertRsa4096Guid)
> > > > > > > + ||
> > > > > > >
> > > > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)
> > ||
> > > > > > >
> > > > > > >          CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)
> > ||
> > > > > > >
> > > > > > >          CompareGuid (&CertList->SignatureType,
> &gEfiCertSha256Guid)
> > > > > > > ||
> > > > > > >
> > > > > > > @@ -3758,12 +3832,20 @@ LoadSignatureList (
> > > > > > >    while ((RemainingSize > 0) && (RemainingSize >=
> > > > > > > ListWalker->SignatureListSize)) {
> > > > > > >
> > > > > > >      if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > &gEfiCertRsa2048Guid)) {
> > > > > > >
> > > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
> > > > > > >
> > > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > + &gEfiCertRsa3072Guid))
> > > > > > > {
> > > > > > >
> > > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
> > > > > > >
> > > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > + &gEfiCertRsa4096Guid))
> > > > > > > {
> > > > > > >
> > > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > &gEfiCertX509Guid)) {
> > > > > > >
> > > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > &gEfiCertSha1Guid)) {
> > > > > > >
> > > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > &gEfiCertSha256Guid)) {
> > > > > > >
> > > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > > > > >
> > > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > + &gEfiCertSha384Guid))
> > > > > > > {
> > > > > > >
> > > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > > > > >
> > > > > > > +    } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > + &gEfiCertSha512Guid))
> > > > > > > {
> > > > > > >
> > > > > > > +      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > &gEfiCertX509Sha256Guid)) {
> > > > > > >
> > > > > > >        ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > > > > >
> > > > > > >      } else if (CompareGuid (&ListWalker->SignatureType,
> > > > > > > &gEfiCertX509Sha384Guid)) {
> > > > > > >
> > > > > > > @@ -4001,6 +4083,14 @@ FormatHelpInfo (
> > > > > > >      ListTypeId = STRING_TOKEN
> (STR_LIST_TYPE_RSA2048_SHA256);
> > > > > > >
> > > > > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > > >
> > > > > > >      IsCert     = TRUE;
> > > > > > >
> > > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > + &gEfiCertRsa3072Guid)) {
> > > > > > >
> > > > > > > +    ListTypeId = STRING_TOKEN
> (STR_LIST_TYPE_RSA3072_SHA384);
> > > > > > >
> > > > > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > > >
> > > > > > > +    IsCert     = TRUE;
> > > > > > >
> > > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > + &gEfiCertRsa4096Guid)) {
> > > > > > >
> > > > > > > +    ListTypeId = STRING_TOKEN
> (STR_LIST_TYPE_RSA4096_SHA512);
> > > > > > >
> > > > > > > +    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > > >
> > > > > > > +    IsCert     = TRUE;
> > > > > > >
> > > > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > &gEfiCertX509Guid)) {
> > > > > > >
> > > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
> > > > > > >
> > > > > > >      DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
> > > > > > >
> > > > > > > @@ -4011,6 +4101,12 @@ FormatHelpInfo (
> > > > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > &gEfiCertSha256Guid)) {
> > > > > > >
> > > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
> > > > > > >
> > > > > > >      DataSize   = 32;
> > > > > > >
> > > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > + &gEfiCertSha384Guid)) {
> > > > > > >
> > > > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
> > > > > > >
> > > > > > > +    DataSize   = 48;
> > > > > > >
> > > > > > > +  } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > + &gEfiCertSha512Guid)) {
> > > > > > >
> > > > > > > +    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
> > > > > > >
> > > > > > > +    DataSize   = 64;
> > > > > > >
> > > > > > >    } else if (CompareGuid (&ListEntry->SignatureType,
> > > > > > > &gEfiCertX509Sha256Guid)) {
> > > > > > >
> > > > > > >      ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
> > > > > > >
> > > > > > >      DataSize   = 32;
> > > > > > >
> > > > > > > diff --git
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.h
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.h
> > > > > > > index 37c66f1b95..ae50d929a7 100644
> > > > > > > ---
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.h
> > > > > > > +++
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igI
> > > > > > > mpl.h
> > > > > > > @@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
> > > > #define
> > > > > > > MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >  #define WIN_CERT_UEFI_RSA2048_SIZE  256
> > > > > > >
> > > > > > > +#define WIN_CERT_UEFI_RSA3072_SIZE  384
> > > > > > >
> > > > > > > +#define WIN_CERT_UEFI_RSA4096_SIZE  512
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >  //
> > > > > > >
> > > > > > >  // Support hash types
> > > > > > >
> > > > > > > diff --git
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igS
> > > > > > > trings.uni
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igS
> > > > > > > trings.uni
> > > > > > > index 0d01701de7..1b48acc800 100644
> > > > > > > ---
> > > > > > >
> > > > > >
> > > >
> >
> a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igS
> > > > > > > trings.uni
> > > > > > > +++
> > > > > > >
> > > > > >
> > > >
> >
> b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCon
> > > > > > f
> > > > > > > igS
> > > > > > > trings.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"
> > > > > > >
> > > > > > >  #string STR_FILE_EXPLORER_TITLE                   #language en-US "File
> > > > > > Explorer"
> > > > > > >
> > > > > > >  #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language
> en-
> > US
> > > > > > > "RSA2048_SHA256_GUID"
> > > > > > >
> > > > > > > +#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language
> > en-US
> > > > > > > "RSA3072_SHA384_GUID"
> > > > > > >
> > > > > > > +#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language
> > en-US
> > > > > > > "RSA4096_SHA512_GUID"
> > > > > > >
> > > > > > >  #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US
> > > > > > "PKCS7_GUID"
> > > > > > >
> > > > > > >  #string STR_CERT_TYPE_SHA1_GUID                   #language en-US
> > > > > > "SHA1_GUID"
> > > > > > >
> > > > > > >  #string STR_CERT_TYPE_SHA256_GUID                 #language en-US
> > > > > > > "SHA256_GUID"
> > > > > > >
> > > > > > > @@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-
> > Patent
> > > > > > >  #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-
> > US
> > > > > > > "X509_SHA512_GUID"
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US
> > > > > > > "RSA2048_SHA256"
> > > > > > >
> > > > > > > +#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US
> > > > > > > "RSA3072_SHA384"
> > > > > > >
> > > > > > > +#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US
> > > > > > > "RSA4096_SHA512"
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_X509                        #language en-US "X509"
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_SHA256                      #language en-US
> > "SHA256"
> > > > > > >
> > > > > > > +#string STR_LIST_TYPE_SHA384                      #language en-US
> > "SHA384"
> > > > > > >
> > > > > > > +#string STR_LIST_TYPE_SHA512                      #language en-US
> > "SHA512"
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_X509_SHA256                 #language en-US
> > > > > > > "X509_SHA256"
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_X509_SHA384                 #language en-US
> > > > > > > "X509_SHA384"
> > > > > > >
> > > > > > >  #string STR_LIST_TYPE_X509_SHA512                 #language en-US
> > > > > > > "X509_SHA512"
> > > > > > >
> > > > > > > --
> > > > > > > 2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#106684): https://edk2.groups.io/g/devel/message/106684
Mute This Topic: https://groups.io/mt/99124387/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


From 49fe0f82317421c1b9ea999ed864181ab575a71a Mon Sep 17 00:00:00 2001
From: Sheng Wei <w.sheng@intel.com>
Date: Fri, 28 Apr 2023 16:08:25 +0800
Subject: [PATCH v4] SecurityPkg/SecureBoot: Support RSA 512 and RSA 384

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3413

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Zeyi Chen <zeyi.chen@intel.com>
Cc: Fiona Wang <fiona.wang@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
 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                    | 114 +++++++--
 .../SecureBootConfigImpl.h                    |   2 +
 .../SecureBootConfigStrings.uni               |   6 +
 11 files changed, 416 insertions(+), 92 deletions(-)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c b/CryptoPkg/Library/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.
   //
   if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||
-      (EVP_add_digest (EVP_sha256 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
+      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest (EVP_sha384 ()) == 0) ||
+      (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
   {
     return FALSE;
   }
diff --git a/MdePkg/Include/Guid/ImageAuthentication.h b/MdePkg/Include/Guid/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} \
   }
 
+///
+/// This identifies a signature containing an RSA-3072 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 384 bytes.
+///
+#define EFI_CERT_RSA3072_GUID \
+  { \
+    0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 } \
+  }
+
+///
+/// This identifies a signature containing an RSA-4096 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 512 bytes.
+///
+#define EFI_CERT_RSA4096_GUID \
+  { \
+    0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c } \
+  }
+
 ///
 /// This identifies a signature containing a RSA-2048 signature of a SHA-256 hash.  The
 /// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
@@ -330,6 +354,8 @@ typedef struct {
 extern EFI_GUID  gEfiImageSecurityDatabaseGuid;
 extern EFI_GUID  gEfiCertSha256Guid;
 extern EFI_GUID  gEfiCertRsa2048Guid;
+extern EFI_GUID  gEfiCertRsa3072Guid;
+extern EFI_GUID  gEfiCertRsa4096Guid;
 extern EFI_GUID  gEfiCertRsa2048Sha256Guid;
 extern EFI_GUID  gEfiCertSha1Guid;
 extern EFI_GUID  gEfiCertRsa2048Sha1Guid;
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  = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }}
   gEfiCertSha256Guid             = { 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 }}
   gEfiCertRsa2048Guid            = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6 }}
+  gEfiCertRsa3072Guid            = { 0xedd320c2, 0xb057, 0x4b8e, {0xad, 0x46, 0x2c, 0x9b, 0x85, 0x89, 0xee, 0x92 }}
+  gEfiCertRsa4096Guid            = { 0xb23e89a6, 0x8c8b, 0x4412, {0x85, 0x73, 0x15, 0x4e, 0x8d, 0x00, 0x98, 0x2c }}
   gEfiCertRsa2048Sha256Guid      = { 0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 }}
   gEfiCertSha1Guid               = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe,  0x1, 0x49, 0x66, 0x31, 0xbd }}
   gEfiCertRsa2048Sha1Guid        = { 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 }}
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPkg/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 <Protocol/VariablePolicy.h>
 #include <Library/VariablePolicyLib.h>
 
+#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
+
+/**
+  Retrieves the size, in bytes, of the context buffer required for hash operations.
+
+  If this interface is not supported, then return zero.
+
+  @return  The size, in bytes, of the context buffer required for hash operations.
+  @retval  0   This interface is not supported.
+
+**/
+typedef
+UINTN
+(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE)(
+  VOID
+  );
+
+/**
+  Initializes user-supplied memory pointed by Sha1Context as hash context for
+  subsequent use.
+
+  If HashContext is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[out]  HashContext  Pointer to Hashcontext being initialized.
+
+  @retval TRUE   Hash context initialization succeeded.
+  @retval FALSE  Hash context initialization failed.
+  @retval FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_HASH_INIT)(
+  OUT  VOID  *HashContext
+  );
+
+/**
+  Digests the input data and updates Hash context.
+
+  This function performs Hash digest on a data buffer of the specified size.
+  It can be called multiple times to compute the digest of long or discontinuous data streams.
+  Hash context should be already correctly initialized by HashInit(), and should not be finalized
+  by HashFinal(). Behavior with invalid context is undefined.
+
+  If HashContext is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in, out]  HashContext  Pointer to the Hash context.
+  @param[in]       Data         Pointer to the buffer containing the data to be hashed.
+  @param[in]       DataSize     Size of Data buffer in bytes.
+
+  @retval TRUE   SHA-1 data digest succeeded.
+  @retval FALSE  SHA-1 data digest failed.
+  @retval FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_HASH_UPDATE)(
+  IN OUT  VOID        *HashContext,
+  IN      CONST VOID  *Data,
+  IN      UINTN       DataSize
+  );
+
+/**
+  Completes computation of the Hash digest value.
+
+  This function completes hash computation and retrieves the digest value into
+  the specified memory. After this function has been called, the Hash context cannot
+  be used again.
+  Hash context should be already correctly initialized by HashInit(), and should not be
+  finalized by HashFinal(). Behavior with invalid Hash context is undefined.
+
+  If HashContext is NULL, then return FALSE.
+  If HashValue is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in, out]  HashContext  Pointer to the Hash context.
+  @param[out]      HashValue    Pointer to a buffer that receives the Hash digest
+                                value.
+
+  @retval TRUE   Hash digest computation succeeded.
+  @retval FALSE  Hash digest computation failed.
+  @retval FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_HASH_FINAL)(
+  IN OUT  VOID   *HashContext,
+  OUT     UINT8  *HashValue
+  );
+
+typedef struct {
+  UINT32                       HashSize;
+  EFI_HASH_GET_CONTEXT_SIZE    GetContextSize;
+  EFI_HASH_INIT                Init;
+  EFI_HASH_UPDATE              Update;
+  EFI_HASH_FINAL               Final;
+  VOID                         **HashShaCtx;
+  UINT8                        *OidValue;
+  UINTN                        OidLength;
+} EFI_HASH_INFO;
+
 //
 // Public Exponent of RSA Key.
 //
 CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };
 
-CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
+UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
+UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 };
+UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 };
+
+EFI_HASH_INFO  mHashInfo[] = {
+  {SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final, &mHashSha256Ctx, mSha256OidValue, 9},
+  {SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final, &mHashSha384Ctx, mSha384OidValue, 9},
+  {SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final, &mHashSha512Ctx, mSha512OidValue, 9},
+};
 
 //
 // Requirement for different signature type which have been defined in UEFI spec.
@@ -44,6 +157,8 @@ EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
   // {SigType,                       SigHeaderSize,   SigDataSize  }
   { EFI_CERT_SHA256_GUID,         0, 32            },
   { EFI_CERT_RSA2048_GUID,        0, 256           },
+  { EFI_CERT_RSA3072_GUID,        0, 384           },
+  { EFI_CERT_RSA4096_GUID,        0, 512           },
   { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
   { EFI_CERT_SHA1_GUID,           0, 20            },
   { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
@@ -1090,26 +1205,28 @@ AuthServiceInternalCompareTimeStamp (
 }
 
 /**
-  Calculate SHA256 digest of SignerCert CommonName + ToplevelCert tbsCertificate
+  Calculate SHA digest of SignerCert CommonName + ToplevelCert tbsCertificate
   SignerCert and ToplevelCert are inside the signer certificate chain.
 
+  @param[in]  HashAlgId           Hash algorithm index
   @param[in]  SignerCert          A pointer to SignerCert data.
   @param[in]  SignerCertSize      Length of SignerCert data.
   @param[in]  TopLevelCert        A pointer to TopLevelCert data.
   @param[in]  TopLevelCertSize    Length of TopLevelCert data.
-  @param[out] Sha256Digest       Sha256 digest calculated.
+  @param[out] ShaDigest           Sha digest calculated.
 
   @return EFI_ABORTED          Digest process failed.
-  @return EFI_SUCCESS          SHA256 Digest is successfully calculated.
+  @return EFI_SUCCESS          SHA Digest is successfully calculated.
 
 **/
 EFI_STATUS
-CalculatePrivAuthVarSignChainSHA256Digest (
+CalculatePrivAuthVarSignChainSHADigest (
+  IN     UINT8  HashAlgId,
   IN     UINT8  *SignerCert,
   IN     UINTN  SignerCertSize,
   IN     UINT8  *TopLevelCert,
   IN     UINTN  TopLevelCertSize,
-  OUT    UINT8  *Sha256Digest
+  OUT    UINT8  *ShaDigest
   )
 {
   UINT8       *TbsCert;
@@ -1119,6 +1236,11 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   BOOLEAN     CryptoStatus;
   EFI_STATUS  Status;
 
+  if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
+    DEBUG ((DEBUG_INFO, "%a Unsupported Hash Algorithm %d\n", __func__, HashAlgId));
+    return EFI_ABORTED;
+  }
+
   CertCommonNameSize = sizeof (CertCommonName);
 
   //
@@ -1141,8 +1263,8 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   //
   // Digest SignerCert CN + TopLevelCert tbsCertificate
   //
-  ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE);
-  CryptoStatus = Sha256Init (mHashCtx);
+  ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);
+  CryptoStatus = mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashShaCtx));
   if (!CryptoStatus) {
     return EFI_ABORTED;
   }
@@ -1150,8 +1272,8 @@ CalculatePrivAuthVarSignChainSHA256Digest (
   //
   // '\0' is forced in CertCommonName. No overflow issue
   //
-  CryptoStatus = Sha256Update (
-                   mHashCtx,
+  CryptoStatus = mHashInfo[HashAlgId].Update (
+                   *(mHashInfo[HashAlgId].HashShaCtx),
                    CertCommonName,
                    AsciiStrLen (CertCommonName)
                    );
@@ -1159,12 +1281,12 @@ CalculatePrivAuthVarSignChainSHA256Digest (
     return EFI_ABORTED;
   }
 
-  CryptoStatus = Sha256Update (mHashCtx, TbsCert, TbsCertSize);
+  CryptoStatus = mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].HashShaCtx), TbsCert, TbsCertSize);
   if (!CryptoStatus) {
     return EFI_ABORTED;
   }
 
-  CryptoStatus = Sha256Final (mHashCtx, Sha256Digest);
+  CryptoStatus = mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].HashShaCtx), ShaDigest);
   if (!CryptoStatus) {
     return EFI_ABORTED;
   }
@@ -1516,9 +1638,10 @@ DeleteCertsFromDb (
 /**
   Insert signer's certificates for common authenticated variable with VariableName
   and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to
-  time based authenticated variable attributes. CertData is the SHA256 digest of
+  time based authenticated variable attributes. CertData is the SHA digest of
   SignerCert CommonName + TopLevelCert tbsCertificate.
 
+  @param[in]  HashAlgId         Hash algorithm index.
   @param[in]  VariableName      Name of authenticated Variable.
   @param[in]  VendorGuid        Vendor GUID of authenticated Variable.
   @param[in]  Attributes        Attributes of authenticated variable.
@@ -1536,6 +1659,7 @@ DeleteCertsFromDb (
 **/
 EFI_STATUS
 InsertCertsToDb (
+  IN     UINT8     HashAlgId,
   IN     CHAR16    *VariableName,
   IN     EFI_GUID  *VendorGuid,
   IN     UINT32    Attributes,
@@ -1556,12 +1680,16 @@ InsertCertsToDb (
   UINT32             CertDataSize;
   AUTH_CERT_DB_DATA  *Ptr;
   CHAR16             *DbName;
-  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];
+  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];
 
   if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
 
+  if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
   if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
     //
     // Get variable "certdb".
@@ -1618,20 +1746,22 @@ InsertCertsToDb (
   // Construct new data content of variable "certdb" or "certdbv".
   //
   NameSize      = (UINT32)StrLen (VariableName);
-  CertDataSize  = sizeof (Sha256Digest);
+  CertDataSize  = mHashInfo[HashAlgId].HashSize;
   CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);
   NewCertDbSize = (UINT32)DataSize + CertNodeSize;
   if (NewCertDbSize > mMaxCertDbSize) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  Status = CalculatePrivAuthVarSignChainSHA256Digest (
+  Status = CalculatePrivAuthVarSignChainSHADigest (
+             HashAlgId,
              SignerCert,
              SignerCertSize,
              TopLevelCert,
              TopLevelCertSize,
-             Sha256Digest
+             ShaDigest
              );
+
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -1663,7 +1793,7 @@ InsertCertsToDb (
 
   CopyMem (
     (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
-    Sha256Digest,
+    ShaDigest,
     CertDataSize
     );
 
@@ -1790,6 +1920,36 @@ CleanCertsFromDb (
   return Status;
 }
 
+/**
+  Find hash algorithm index
+
+  @param[in]  SigData      Pointer to the PKCS#7 message
+  @param[in]  SigDataSize  Length of the PKCS#7 message
+
+  @retval UINT8        Hash Algorithm Index
+**/
+UINT8
+FindHashAlgorithmIndex (
+  IN     UINT8         *SigData,
+  IN     UINT32        SigDataSize
+)
+{
+  UINT8 i;
+
+  for (i = 0; i < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO)); i++) {
+    if (  (  (SigDataSize >= (13 + mHashInfo[i].OidLength))
+          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
+            && (CompareMem (SigData + 13, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0)))
+      || ((  (SigDataSize >= (32 +  mHashInfo[i].OidLength)))
+        && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
+          && (CompareMem (SigData + 32, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0))))
+    {
+      break;
+    }
+  }
+  return i;
+}
+
 /**
   Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
 
@@ -1857,8 +2017,9 @@ VerifyTimeBasedPayload (
   UINTN                          CertStackSize;
   UINT8                          *CertsInCertDb;
   UINT32                         CertsSizeinDb;
-  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];
+  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
   EFI_CERT_DATA                  *CertDataPtr;
+  UINT8                          HashAlgId;
 
   //
   // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain
@@ -1928,7 +2089,7 @@ VerifyTimeBasedPayload (
 
   //
   // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the
-  // signature. Only a digest algorithm of SHA-256 is accepted.
+  // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is accepted.
   //
   //    According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
   //        SignedData ::= SEQUENCE {
@@ -1972,14 +2133,9 @@ VerifyTimeBasedPayload (
   //
   // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process
   //
+  HashAlgId = FindHashAlgorithmIndex (SigData, SigDataSize);
   if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
-    if (  (  (SigDataSize >= (13 + sizeof (mSha256OidValue)))
-          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
-             || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))
-       && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))
-          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)
-             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))))
-    {
+    if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
       return EFI_SECURITY_VIOLATION;
     }
   }
@@ -2170,19 +2326,20 @@ VerifyTimeBasedPayload (
         goto Exit;
       }
 
-      if (CertsSizeinDb == SHA256_DIGEST_SIZE) {
+      if ((HashAlgId < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) && (CertsSizeinDb == mHashInfo[HashAlgId].HashSize)) {
         //
         // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
         //
         CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
-        Status      = CalculatePrivAuthVarSignChainSHA256Digest (
+        Status      = CalculatePrivAuthVarSignChainSHADigest (
+                        HashAlgId,
                         CertDataPtr->CertDataBuffer,
                         ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
                         TopLevelCert,
                         TopLevelCertSize,
-                        Sha256Digest
+                        ShaDigest
                         );
-        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb, CertsSizeinDb) != 0)) {
+        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
           goto Exit;
         }
       } else {
@@ -2215,6 +2372,7 @@ VerifyTimeBasedPayload (
       //
       CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
       Status      = InsertCertsToDb (
+                      HashAlgId,
                       VariableName,
                       VendorGuid,
                       Attributes,
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h b/SecurityPkg/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;
 extern UINT8   mVendorKeyState;
 
-extern VOID  *mHashCtx;
+extern VOID  *mHashSha256Ctx;
+extern VOID  *mHashSha384Ctx;
+extern VOID  *mHashSha512Ctx;
 
 extern AUTH_VAR_LIB_CONTEXT_IN  *mAuthVarLibContextIn;
 
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c b/SecurityPkg/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;
 UINT8   mVendorKeyState;
 
-EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID };
+EFI_GUID  mSignatureSupport[] = { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_SHA384_GUID, EFI_CERT_SHA512_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_RSA3072_GUID, EFI_CERT_RSA4096_GUID, EFI_CERT_X509_GUID };
 
 //
 // Hash context pointer
 //
-VOID  *mHashCtx = NULL;
+VOID  *mHashSha256Ctx = NULL;
+VOID  *mHashSha384Ctx = NULL;
+VOID  *mHashSha512Ctx = NULL;
 
 VARIABLE_ENTRY_PROPERTY  mAuthVarEntry[] = {
   {
@@ -91,7 +93,7 @@ VARIABLE_ENTRY_PROPERTY  mAuthVarEntry[] = {
   },
 };
 
-VOID  **mAuthVarAddressPointer[9];
+VOID  **mAuthVarAddressPointer[11];
 
 AUTH_VAR_LIB_CONTEXT_IN  *mAuthVarLibContextIn = NULL;
 
@@ -120,7 +122,6 @@ AuthVariableLibInitialize (
   UINT32      VarAttr;
   UINT8       *Data;
   UINTN       DataSize;
-  UINTN       CtxSize;
   UINT8       SecureBootMode;
   UINT8       SecureBootEnable;
   UINT8       CustomMode;
@@ -135,9 +136,18 @@ AuthVariableLibInitialize (
   //
   // Initialize hash context.
   //
-  CtxSize  = Sha256GetContextSize ();
-  mHashCtx = AllocateRuntimePool (CtxSize);
-  if (mHashCtx == NULL) {
+  mHashSha256Ctx = AllocateRuntimePool (Sha256GetContextSize ());
+  if (mHashSha256Ctx == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mHashSha384Ctx = AllocateRuntimePool (Sha384GetContextSize ());
+  if (mHashSha384Ctx == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mHashSha512Ctx = AllocateRuntimePool (Sha512GetContextSize ());
+  if (mHashSha512Ctx == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
@@ -356,14 +366,16 @@ AuthVariableLibInitialize (
   AuthVarLibContextOut->AuthVarEntry        = mAuthVarEntry;
   AuthVarLibContextOut->AuthVarEntryCount   = ARRAY_SIZE (mAuthVarEntry);
   mAuthVarAddressPointer[0]                 = (VOID **)&mCertDbStore;
-  mAuthVarAddressPointer[1]                 = (VOID **)&mHashCtx;
-  mAuthVarAddressPointer[2]                 = (VOID **)&mAuthVarLibContextIn;
-  mAuthVarAddressPointer[3]                 = (VOID **)&(mAuthVarLibContextIn->FindVariable),
-  mAuthVarAddressPointer[4]                 = (VOID **)&(mAuthVarLibContextIn->FindNextVariable),
-  mAuthVarAddressPointer[5]                 = (VOID **)&(mAuthVarLibContextIn->UpdateVariable),
-  mAuthVarAddressPointer[6]                 = (VOID **)&(mAuthVarLibContextIn->GetScratchBuffer),
-  mAuthVarAddressPointer[7]                 = (VOID **)&(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),
-  mAuthVarAddressPointer[8]                 = (VOID **)&(mAuthVarLibContextIn->AtRuntime),
+  mAuthVarAddressPointer[1]                 = (VOID **)&mHashSha256Ctx;
+  mAuthVarAddressPointer[2]                 = (VOID **)&mHashSha384Ctx;
+  mAuthVarAddressPointer[3]                 = (VOID **)&mHashSha512Ctx;
+  mAuthVarAddressPointer[4]                 = (VOID **)&mAuthVarLibContextIn;
+  mAuthVarAddressPointer[5]                 = (VOID **)&(mAuthVarLibContextIn->FindVariable),
+  mAuthVarAddressPointer[6]                 = (VOID **)&(mAuthVarLibContextIn->FindNextVariable),
+  mAuthVarAddressPointer[7]                 = (VOID **)&(mAuthVarLibContextIn->UpdateVariable),
+  mAuthVarAddressPointer[8]                 = (VOID **)&(mAuthVarLibContextIn->GetScratchBuffer),
+  mAuthVarAddressPointer[9]                 = (VOID **)&(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),
+  mAuthVarAddressPointer[10]                 = (VOID **)&(mAuthVarLibContextIn->AtRuntime),
   AuthVarLibContextOut->AddressPointer      = mAuthVarAddressPointer;
   AuthVarLibContextOut->AddressPointerCount = ARRAY_SIZE (mAuthVarAddressPointer);
 
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.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 value of the image may
       be reflected in the security database "dbx".
     Otherwise, the image is not signed,
-      The SHA256 hash value of the image must match a record in the security database "db", and
+      The hash value of the image must match a record in the security database "db", and
       not be reflected in the security data base "dbx".
 
   Caution: This function may receive untrusted input.
@@ -1690,6 +1690,8 @@ DxeImageVerificationHandler (
   EFI_STATUS                    VarStatus;
   UINT32                        VarAttr;
   BOOLEAN                       IsFound;
+  UINT8                         HashAlg;
+  BOOLEAN                       IsFoundInDatabase;
 
   SignatureList     = NULL;
   SignatureListSize = 0;
@@ -1699,6 +1701,7 @@ DxeImageVerificationHandler (
   Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;
   IsVerified        = FALSE;
   IsFound           = FALSE;
+  IsFoundInDatabase = FALSE;
 
   //
   // Check the image type and get policy setting.
@@ -1837,40 +1840,50 @@ DxeImageVerificationHandler (
   //
   if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
     //
-    // This image is not signed. The SHA256 hash value of the image must match a record in the security database "db",
+    // This image is not signed. The hash value of the image must match a record in the security database "db",
     // and not be reflected in the security data base "dbx".
     //
-    if (!HashPeImage (HASHALG_SHA256)) {
-      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr));
-      goto Failed;
-    }
+    HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
+    while (HashAlg > 0) {
+      HashAlg--;
+      if ((mHash[HashAlg].GetContextSize == NULL) || (mHash[HashAlg].HashInit == NULL) || (mHash[HashAlg].HashUpdate == NULL) || (mHash[HashAlg].HashFinal == NULL)) {
+        continue;
+      }
+      if (!HashPeImage (HashAlg)) {
+        continue;
+      }
 
-    DbStatus = IsSignatureFoundInDatabase (
-                 EFI_IMAGE_SECURITY_DATABASE1,
-                 mImageDigest,
-                 &mCertType,
-                 mImageDigestSize,
-                 &IsFound
-                 );
-    if (EFI_ERROR (DbStatus) || IsFound) {
-      //
-      // Image Hash is in forbidden database (DBX).
-      //
-      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));
-      goto Failed;
+      DbStatus = IsSignatureFoundInDatabase (
+                   EFI_IMAGE_SECURITY_DATABASE1,
+                   mImageDigest,
+                   &mCertType,
+                   mImageDigestSize,
+                   &IsFound
+                   );
+      if (EFI_ERROR (DbStatus) || IsFound) {
+        //
+        // Image Hash is in forbidden database (DBX).
+        //
+        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));
+        goto Failed;
+      }
+
+      DbStatus = IsSignatureFoundInDatabase (
+                   EFI_IMAGE_SECURITY_DATABASE,
+                   mImageDigest,
+                   &mCertType,
+                   mImageDigestSize,
+                   &IsFound
+                   );
+      if (!EFI_ERROR (DbStatus) && IsFound) {
+        //
+        // Image Hash is in allowed database (DB).
+        //
+        IsFoundInDatabase = TRUE;
+      }
     }
 
-    DbStatus = IsSignatureFoundInDatabase (
-                 EFI_IMAGE_SECURITY_DATABASE,
-                 mImageDigest,
-                 &mCertType,
-                 mImageDigestSize,
-                 &IsFound
-                 );
-    if (!EFI_ERROR (DbStatus) && IsFound) {
-      //
-      // Image Hash is in allowed database (DB).
-      //
+    if (IsFoundInDatabase) {
       return EFI_SUCCESS;
     }
 
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
index 1671d5be7c..cb52a16c09 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
@@ -70,6 +70,14 @@
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertRsa2048Guid
 
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertRsa3072Guid
+
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertRsa4096Guid
+
   ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertX509Guid
@@ -82,6 +90,14 @@
   ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
   gEfiCertSha256Guid
 
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertSha384Guid
+
+  ## SOMETIMES_CONSUMES      ## GUID            # Unique ID for the type of the signature.
+  ## SOMETIMES_PRODUCES      ## GUID            # Unique ID for the type of the signature.
+  gEfiCertSha512Guid
+
   ## SOMETIMES_CONSUMES      ## Variable:L"db"
   ## SOMETIMES_PRODUCES      ## Variable:L"db"
   ## SOMETIMES_CONSUMES      ## Variable:L"dbx"
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 0e31502b1b..90268d34d3 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -560,7 +560,7 @@ ON_EXIT:
 
 **/
 EFI_STATUS
-EnrollRsa2048ToKek (
+EnrollRsaToKek (
   IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private
   )
 {
@@ -603,8 +603,19 @@ EnrollRsa2048ToKek (
 
   ASSERT (KeyBlob != NULL);
   KeyInfo = (CPL_KEY_INFO *)KeyBlob;
-  if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
-    DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is supported.\n"));
+  if (KeyInfo->KeyType == 0) {
+    switch (KeyInfo->KeyLengthInBits / 8) {
+    case WIN_CERT_UEFI_RSA2048_SIZE:
+    case WIN_CERT_UEFI_RSA3072_SIZE:
+    case WIN_CERT_UEFI_RSA4096_SIZE:
+      break;
+    default :
+      DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048, RSA3072 and RSA4096 are supported.\n"));
+      Status = EFI_UNSUPPORTED;
+      goto ON_EXIT;
+    }
+  } else {
+    DEBUG ((DEBUG_ERROR, "Unsupported key type : %d, only 0 is supported.\n", KeyInfo->KeyType));
     Status = EFI_UNSUPPORTED;
     goto ON_EXIT;
   }
@@ -632,7 +643,7 @@ EnrollRsa2048ToKek (
   //
   KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
                    + sizeof (EFI_SIGNATURE_DATA) - 1
-                   + WIN_CERT_UEFI_RSA2048_SIZE;
+                   + KeyLenInBytes;
 
   KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
   if (KekSigList == NULL) {
@@ -642,17 +653,32 @@ EnrollRsa2048ToKek (
 
   KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
                                   + sizeof (EFI_SIGNATURE_DATA) - 1
-                                  + WIN_CERT_UEFI_RSA2048_SIZE;
+                                  + (UINT32) KeyLenInBytes;
   KekSigList->SignatureHeaderSize = 0;
-  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + WIN_CERT_UEFI_RSA2048_SIZE;
-  CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+  KekSigList->SignatureSize       = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32) KeyLenInBytes;
+  switch (KeyLenInBytes) {
+  case WIN_CERT_UEFI_RSA2048_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
+    break;
+  case WIN_CERT_UEFI_RSA3072_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa3072Guid);
+    break;
+  case WIN_CERT_UEFI_RSA4096_SIZE:
+    CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa4096Guid);
+    break;
+    break;
+  default :
+    DEBUG ((DEBUG_ERROR, "Unsupported key length.\n"));
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
 
   KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
   CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
   CopyMem (
     KEKSigData->SignatureData,
     KeyBlob + sizeof (CPL_KEY_INFO),
-    WIN_CERT_UEFI_RSA2048_SIZE
+    KeyLenInBytes
     );
 
   //
@@ -890,7 +916,7 @@ EnrollKeyExchangeKey (
   if (IsDerEncodeCertificate (FilePostFix)) {
     return EnrollX509ToKek (Private);
   } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
-    return EnrollRsa2048ToKek (Private);
+    return EnrollRsaToKek (Private);
   } else {
     //
     // File type is wrong, simply close it
@@ -1847,7 +1873,7 @@ HashPeImage (
   SectionHeader = NULL;
   Status        = FALSE;
 
-  if (HashAlg != HASHALG_SHA256) {
+  if ((HashAlg >= HASHALG_MAX)) {
     return FALSE;
   }
 
@@ -1856,8 +1882,25 @@ HashPeImage (
   //
   ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
 
-  mImageDigestSize = SHA256_DIGEST_SIZE;
-  mCertType        = gEfiCertSha256Guid;
+   switch (HashAlg) {
+    case HASHALG_SHA256:
+      mImageDigestSize = SHA256_DIGEST_SIZE;
+      mCertType        = gEfiCertSha256Guid;
+      break;
+
+    case HASHALG_SHA384:
+      mImageDigestSize = SHA384_DIGEST_SIZE;
+      mCertType        = gEfiCertSha384Guid;
+      break;
+
+    case HASHALG_SHA512:
+      mImageDigestSize = SHA512_DIGEST_SIZE;
+      mCertType        = gEfiCertSha512Guid;
+      break;
+
+    default:
+      return FALSE;
+  }
 
   CtxSize = mHash[HashAlg].GetContextSize ();
 
@@ -2251,6 +2294,7 @@ EnrollImageSignatureToSigDB (
   UINT32                     Attr;
   WIN_CERTIFICATE_UEFI_GUID  *GuidCertData;
   EFI_TIME                   Time;
+  UINT32                     HashAlg;
 
   Data         = NULL;
   GuidCertData = NULL;
@@ -2289,8 +2333,20 @@ EnrollImageSignatureToSigDB (
   }
 
   if (mSecDataDir->SizeOfCert == 0) {
-    if (!HashPeImage (HASHALG_SHA256)) {
-      Status =  EFI_SECURITY_VIOLATION;
+    Status = EFI_SECURITY_VIOLATION;
+    HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
+    while (HashAlg > 0) {
+      HashAlg--;
+      if ((mHash[HashAlg].GetContextSize == NULL) || (mHash[HashAlg].HashInit == NULL) || (mHash[HashAlg].HashUpdate == NULL) || (mHash[HashAlg].HashFinal == NULL)) {
+        continue;
+      }
+      if (HashPeImage (HashAlg)) {
+        Status = EFI_SUCCESS;
+        break;
+      }
+    }
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to get hash digest: %r", Status));
       goto ON_EXIT;
     }
   } else {
@@ -2589,6 +2645,10 @@ UpdateDeletePage (
   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)) {
       Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
+    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid)) {
+      Help = STRING_TOKEN (STR_CERT_TYPE_RSA3072_SHA384_GUID);
+    } else if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid)) {
+      Help = STRING_TOKEN (STR_CERT_TYPE_RSA4096_SHA512_GUID);
     } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
       Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
     } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)) {
@@ -2750,6 +2810,8 @@ DeleteKeyExchangeKey (
   GuidIndex      = 0;
   while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
     {
       CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
@@ -2952,6 +3014,8 @@ DeleteSignature (
   GuidIndex    = 0;
   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
     if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa3072Guid) ||
+        CompareGuid (&CertList->SignatureType, &gEfiCertRsa4096Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
         CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
@@ -3758,12 +3822,20 @@ LoadSignatureList (
   while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
     if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa3072Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa4096Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+    } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Guid)) {
+      ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
       ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
     } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
@@ -4001,6 +4073,14 @@ FormatHelpInfo (
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
     DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
     IsCert     = TRUE;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa3072Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA3072_SHA384);
+    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
+    IsCert     = TRUE;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa4096Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA4096_SHA512);
+    DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
+    IsCert     = TRUE;
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
     DataSize   = ListEntry->SignatureSize - sizeof (EFI_GUID);
@@ -4011,6 +4091,12 @@ FormatHelpInfo (
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
     DataSize   = 32;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+    DataSize   = 48;
+  } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
+    ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
+    DataSize   = 64;
   } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
     ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
     DataSize   = 32;
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
index 37c66f1b95..ae50d929a7 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
@@ -82,6 +82,8 @@ extern  EFI_IFR_GUID_LABEL  *mEndLabel;
 #define MAX_DIGEST_SIZE  SHA512_DIGEST_SIZE
 
 #define WIN_CERT_UEFI_RSA2048_SIZE  256
+#define WIN_CERT_UEFI_RSA3072_SIZE  384
+#define WIN_CERT_UEFI_RSA4096_SIZE  512
 
 //
 // Support hash types
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
index 0d01701de7..1b48acc800 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.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"
 #string STR_FILE_EXPLORER_TITLE                   #language en-US "File Explorer"
 #string STR_CERT_TYPE_RSA2048_SHA256_GUID         #language en-US "RSA2048_SHA256_GUID"
+#string STR_CERT_TYPE_RSA3072_SHA384_GUID         #language en-US "RSA3072_SHA384_GUID"
+#string STR_CERT_TYPE_RSA4096_SHA512_GUID         #language en-US "RSA4096_SHA512_GUID"
 #string STR_CERT_TYPE_PCKS7_GUID                  #language en-US "PKCS7_GUID"
 #string STR_CERT_TYPE_SHA1_GUID                   #language en-US "SHA1_GUID"
 #string STR_CERT_TYPE_SHA256_GUID                 #language en-US "SHA256_GUID"
@@ -121,9 +123,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #string STR_CERT_TYPE_X509_SHA512_GUID            #language en-US "X509_SHA512_GUID"
 
 #string STR_LIST_TYPE_RSA2048_SHA256              #language en-US "RSA2048_SHA256"
+#string STR_LIST_TYPE_RSA3072_SHA384              #language en-US "RSA3072_SHA384"
+#string STR_LIST_TYPE_RSA4096_SHA512              #language en-US "RSA4096_SHA512"
 #string STR_LIST_TYPE_X509                        #language en-US "X509"
 #string STR_LIST_TYPE_SHA1                        #language en-US "SHA1"
 #string STR_LIST_TYPE_SHA256                      #language en-US "SHA256"
+#string STR_LIST_TYPE_SHA384                      #language en-US "SHA384"
+#string STR_LIST_TYPE_SHA512                      #language en-US "SHA512"
 #string STR_LIST_TYPE_X509_SHA256                 #language en-US "X509_SHA256"
 #string STR_LIST_TYPE_X509_SHA384                 #language en-US "X509_SHA384"
 #string STR_LIST_TYPE_X509_SHA512                 #language en-US "X509_SHA512"
-- 
2.26.2.windows.1