From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 6E9AC941410 for ; Wed, 6 Sep 2023 08:16:38 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=bB6hsO+/W85itiaFOutcPHRImhQKvoNv5Q62Ookz90g=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1693988197; v=1; b=CkhFutBSqyjuvFbN/dkz6N29pOlvFJFKuZGoGJ5PGOEmdSoW+51jHjsASvCD20cN5Khqs5I8 BqJHyTfLkB47wecGCQ+73pMHfSbfOwDv1SLHZcv3Tm1WJYmLguENlN+REJWGi33Hhx23k7RnnSM u23j/DJXNXzqCoxlWxvclubM= X-Received: by 127.0.0.2 with SMTP id 7OJzYY7687511xoAxcxVo4Fa; Wed, 06 Sep 2023 01:16:37 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web10.3801.1693988194533547408 for ; Wed, 06 Sep 2023 01:16:36 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10824"; a="408003165" X-IronPort-AV: E=Sophos;i="6.02,231,1688454000"; d="scan'208";a="408003165" X-Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2023 01:16:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10824"; a="691216308" X-IronPort-AV: E=Sophos;i="6.02,231,1688454000"; d="scan'208";a="691216308" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.28]) by orsmga003.jf.intel.com with ESMTP; 06 Sep 2023 01:16:33 -0700 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Jiewen Yao , Jian J Wang , Min Xu , Zeyi Chen , Fiona Wang Subject: [edk2-devel] [PATCH V8 2/2] SecurityPkg/SecureBoot: Support RSA4096 and RSA3072 Date: Wed, 6 Sep 2023 16:16:26 +0800 Message-Id: <20230906081626.1871-3-w.sheng@intel.com> In-Reply-To: <20230906081626.1871-1-w.sheng@intel.com> References: <20230906081626.1871-1-w.sheng@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,w.sheng@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: VdtweV2PAtPH1doX6wOGuwi7x7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=CkhFutBS; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3413 Change-Id: Ic13595ffb0581a178db71d231ba34f17862fa5d8 Cc: Jiewen Yao Cc: Jian J Wang Cc: Min Xu Cc: Zeyi Chen Cc: Fiona Wang Signed-off-by: Sheng Wei --- .../Library/AuthVariableLib/AuthService.c | 225 +++++++++++++++--- .../AuthVariableLib/AuthServiceInternal.h | 4 +- .../Library/AuthVariableLib/AuthVariableLib.c | 42 ++-- .../DxeImageVerificationLib.c | 74 +++--- .../SecureBootConfigDxe.inf | 8 + .../SecureBootConfigImpl.c | 52 +++- .../SecureBootConfigImpl.h | 7 + .../SecureBootConfigStrings.uni | 2 + 8 files changed, 329 insertions(+), 85 deletions(-) diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPk= g/Library/AuthVariableLib/AuthService.c index d81c581d78..aec0fad28a 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c @@ -29,12 +29,125 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =0D #include =0D =0D +#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE=0D +=0D +/**=0D + Retrieves the size, in bytes, of the context buffer required for hash op= erations.=0D +=0D + If this interface is not supported, then return zero.=0D +=0D + @return The size, in bytes, of the context buffer required for hash ope= rations.=0D + @retval 0 This interface is not supported.=0D +=0D +**/=0D +typedef=0D +UINTN=0D +(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE)(=0D + VOID=0D + );=0D +=0D +/**=0D + Initializes user-supplied memory pointed by Sha1Context as hash context = for=0D + subsequent use.=0D +=0D + If HashContext is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[out] HashContext Pointer to Hashcontext being initialized.=0D +=0D + @retval TRUE Hash context initialization succeeded.=0D + @retval FALSE Hash context initialization failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_INIT)(=0D + OUT VOID *HashContext=0D + );=0D +=0D +/**=0D + Digests the input data and updates Hash context.=0D +=0D + This function performs Hash digest on a data buffer of the specified siz= e.=0D + It can be called multiple times to compute the digest of long or discont= inuous data streams.=0D + Hash context should be already correctly initialized by HashInit(), and = should not be finalized=0D + by HashFinal(). Behavior with invalid context is undefined.=0D +=0D + If HashContext is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in, out] HashContext Pointer to the Hash context.=0D + @param[in] Data Pointer to the buffer containing the data = to be hashed.=0D + @param[in] DataSize Size of Data buffer in bytes.=0D +=0D + @retval TRUE SHA-1 data digest succeeded.=0D + @retval FALSE SHA-1 data digest failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_UPDATE)(=0D + IN OUT VOID *HashContext,=0D + IN CONST VOID *Data,=0D + IN UINTN DataSize=0D + );=0D +=0D +/**=0D + Completes computation of the Hash digest value.=0D +=0D + This function completes hash computation and retrieves the digest value = into=0D + the specified memory. After this function has been called, the Hash cont= ext cannot=0D + be used again.=0D + Hash context should be already correctly initialized by HashInit(), and = should not be=0D + finalized by HashFinal(). Behavior with invalid Hash context is undefine= d.=0D +=0D + If HashContext is NULL, then return FALSE.=0D + If HashValue is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in, out] HashContext Pointer to the Hash context.=0D + @param[out] HashValue Pointer to a buffer that receives the Hash= digest=0D + value.=0D +=0D + @retval TRUE Hash digest computation succeeded.=0D + @retval FALSE Hash digest computation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +typedef=0D +BOOLEAN=0D +(EFIAPI *EFI_HASH_FINAL)(=0D + IN OUT VOID *HashContext,=0D + OUT UINT8 *HashValue=0D + );=0D +=0D +typedef struct {=0D + UINT32 HashSize;=0D + EFI_HASH_GET_CONTEXT_SIZE GetContextSize;=0D + EFI_HASH_INIT Init;=0D + EFI_HASH_UPDATE Update;=0D + EFI_HASH_FINAL Final;=0D + VOID **HashShaCtx;=0D + UINT8 *OidValue;=0D + UINTN OidLength;=0D +} EFI_HASH_INFO;=0D +=0D //=0D // Public Exponent of RSA Key.=0D //=0D CONST UINT8 mRsaE[] =3D { 0x01, 0x00, 0x01 };=0D =0D -CONST UINT8 mSha256OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0= x04, 0x02, 0x01 };=0D +UINT8 mSha256OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0= x02, 0x01 };=0D +UINT8 mSha384OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0= x02, 0x02 };=0D +UINT8 mSha512OidValue[] =3D { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0= x02, 0x03 };=0D +=0D +EFI_HASH_INFO mHashInfo[] =3D {=0D + { SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sh= a256Final, &mHashSha256Ctx, mSha256OidValue, 9 },=0D + { SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sh= a384Final, &mHashSha384Ctx, mSha384OidValue, 9 },=0D + { SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sh= a512Final, &mHashSha512Ctx, mSha512OidValue, 9 },=0D +};=0D =0D //=0D // Requirement for different signature type which have been defined in UEF= I spec.=0D @@ -1090,26 +1203,28 @@ AuthServiceInternalCompareTimeStamp ( }=0D =0D /**=0D - Calculate SHA256 digest of SignerCert CommonName + ToplevelCert tbsCerti= ficate=0D + Calculate SHA digest of SignerCert CommonName + ToplevelCert tbsCertific= ate.=0D SignerCert and ToplevelCert are inside the signer certificate chain.=0D =0D + @param[in] HashAlgId Hash algorithm index.=0D @param[in] SignerCert A pointer to SignerCert data.=0D @param[in] SignerCertSize Length of SignerCert data.=0D @param[in] TopLevelCert A pointer to TopLevelCert data.=0D @param[in] TopLevelCertSize Length of TopLevelCert data.=0D - @param[out] Sha256Digest Sha256 digest calculated.=0D + @param[out] ShaDigest Sha digest calculated.=0D =0D @return EFI_ABORTED Digest process failed.=0D - @return EFI_SUCCESS SHA256 Digest is successfully calculated.=0D + @return EFI_SUCCESS SHA Digest is successfully calculated.=0D =0D **/=0D EFI_STATUS=0D -CalculatePrivAuthVarSignChainSHA256Digest (=0D +CalculatePrivAuthVarSignChainSHADigest (=0D + IN UINT8 HashAlgId,=0D IN UINT8 *SignerCert,=0D IN UINTN SignerCertSize,=0D IN UINT8 *TopLevelCert,=0D IN UINTN TopLevelCertSize,=0D - OUT UINT8 *Sha256Digest=0D + OUT UINT8 *ShaDigest=0D )=0D {=0D UINT8 *TbsCert;=0D @@ -1119,6 +1234,11 @@ CalculatePrivAuthVarSignChainSHA256Digest ( BOOLEAN CryptoStatus;=0D EFI_STATUS Status;=0D =0D + if (HashAlgId >=3D (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {=0D + DEBUG ((DEBUG_INFO, "%a Unsupported Hash Algorithm %d\n", __func__, Ha= shAlgId));=0D + return EFI_ABORTED;=0D + }=0D +=0D CertCommonNameSize =3D sizeof (CertCommonName);=0D =0D //=0D @@ -1141,8 +1261,8 @@ CalculatePrivAuthVarSignChainSHA256Digest ( //=0D // Digest SignerCert CN + TopLevelCert tbsCertificate=0D //=0D - ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE);=0D - CryptoStatus =3D Sha256Init (mHashCtx);=0D + ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);=0D + CryptoStatus =3D mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashS= haCtx));=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D @@ -1150,21 +1270,21 @@ CalculatePrivAuthVarSignChainSHA256Digest ( //=0D // '\0' is forced in CertCommonName. No overflow issue=0D //=0D - CryptoStatus =3D Sha256Update (=0D - mHashCtx,=0D - CertCommonName,=0D - AsciiStrLen (CertCommonName)=0D - );=0D + CryptoStatus =3D mHashInfo[HashAlgId].Update (=0D + *(mHashInfo[HashAlgId].HashShaCtx)= ,=0D + CertCommonName,=0D + AsciiStrLen (CertCommonName)=0D + );=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D =0D - CryptoStatus =3D Sha256Update (mHashCtx, TbsCert, TbsCertSize);=0D + CryptoStatus =3D mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].Has= hShaCtx), TbsCert, TbsCertSize);=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D =0D - CryptoStatus =3D Sha256Final (mHashCtx, Sha256Digest);=0D + CryptoStatus =3D mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].Hash= ShaCtx), ShaDigest);=0D if (!CryptoStatus) {=0D return EFI_ABORTED;=0D }=0D @@ -1516,9 +1636,10 @@ DeleteCertsFromDb ( /**=0D Insert signer's certificates for common authenticated variable with Vari= ableName=0D and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according t= o=0D - time based authenticated variable attributes. CertData is the SHA256 dig= est of=0D + time based authenticated variable attributes. CertData is the SHA digest= of=0D SignerCert CommonName + TopLevelCert tbsCertificate.=0D =0D + @param[in] HashAlgId Hash algorithm index.=0D @param[in] VariableName Name of authenticated Variable.=0D @param[in] VendorGuid Vendor GUID of authenticated Variable.=0D @param[in] Attributes Attributes of authenticated variable.=0D @@ -1536,6 +1657,7 @@ DeleteCertsFromDb ( **/=0D EFI_STATUS=0D InsertCertsToDb (=0D + IN UINT8 HashAlgId,=0D IN CHAR16 *VariableName,=0D IN EFI_GUID *VendorGuid,=0D IN UINT32 Attributes,=0D @@ -1556,12 +1678,16 @@ InsertCertsToDb ( UINT32 CertDataSize;=0D AUTH_CERT_DB_DATA *Ptr;=0D CHAR16 *DbName;=0D - UINT8 Sha256Digest[SHA256_DIGEST_SIZE];=0D + UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];=0D =0D if ((VariableName =3D=3D NULL) || (VendorGuid =3D=3D NULL) || (SignerCer= t =3D=3D NULL) || (TopLevelCert =3D=3D NULL)) {=0D return EFI_INVALID_PARAMETER;=0D }=0D =0D + if (HashAlgId >=3D (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D if ((Attributes & EFI_VARIABLE_NON_VOLATILE) !=3D 0) {=0D //=0D // Get variable "certdb".=0D @@ -1618,20 +1744,22 @@ InsertCertsToDb ( // Construct new data content of variable "certdb" or "certdbv".=0D //=0D NameSize =3D (UINT32)StrLen (VariableName);=0D - CertDataSize =3D sizeof (Sha256Digest);=0D + CertDataSize =3D mHashInfo[HashAlgId].HashSize;=0D CertNodeSize =3D sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + Na= meSize * sizeof (CHAR16);=0D NewCertDbSize =3D (UINT32)DataSize + CertNodeSize;=0D if (NewCertDbSize > mMaxCertDbSize) {=0D return EFI_OUT_OF_RESOURCES;=0D }=0D =0D - Status =3D CalculatePrivAuthVarSignChainSHA256Digest (=0D + Status =3D CalculatePrivAuthVarSignChainSHADigest (=0D + HashAlgId,=0D SignerCert,=0D SignerCertSize,=0D TopLevelCert,=0D TopLevelCertSize,=0D - Sha256Digest=0D + ShaDigest=0D );=0D +=0D if (EFI_ERROR (Status)) {=0D return Status;=0D }=0D @@ -1663,7 +1791,7 @@ InsertCertsToDb ( =0D CopyMem (=0D (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16= ),=0D - Sha256Digest,=0D + ShaDigest,=0D CertDataSize=0D );=0D =0D @@ -1790,6 +1918,37 @@ CleanCertsFromDb ( return Status;=0D }=0D =0D +/**=0D + Find hash algorithm index.=0D +=0D + @param[in] SigData Pointer to the PKCS#7 message.=0D + @param[in] SigDataSize Length of the PKCS#7 message.=0D +=0D + @retval UINT8 Hash Algorithm Index.=0D +**/=0D +UINT8=0D +FindHashAlgorithmIndex (=0D + IN UINT8 *SigData,=0D + IN UINT32 SigDataSize=0D + )=0D +{=0D + UINT8 i;=0D +=0D + for (i =3D 0; i < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO)); i++) {= =0D + if ( ( (SigDataSize >=3D (13 + mHashInfo[i].OidLength))=0D + && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) =3D=3D TWO_BYTE_ENCODE= )=0D + && (CompareMem (SigData + 13, mHashInfo[i].OidValue, mHashInf= o[i].OidLength) =3D=3D 0)))=0D + || (( (SigDataSize >=3D (32 + mHashInfo[i].OidLength)))=0D + && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) =3D=3D TWO_BYTE_ENCOD= E)=0D + && (CompareMem (SigData + 32, mHashInfo[i].OidValue, mHashInf= o[i].OidLength) =3D=3D 0))))=0D + {=0D + break;=0D + }=0D + }=0D +=0D + return i;=0D +}=0D +=0D /**=0D Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS= set=0D =0D @@ -1857,8 +2016,9 @@ VerifyTimeBasedPayload ( UINTN CertStackSize;=0D UINT8 *CertsInCertDb;=0D UINT32 CertsSizeinDb;=0D - UINT8 Sha256Digest[SHA256_DIGEST_SIZE];=0D + UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];=0D EFI_CERT_DATA *CertDataPtr;=0D + UINT8 HashAlgId;=0D =0D //=0D // 1. TopLevelCert is the top-level issuer certificate in signature Sign= er Cert Chain=0D @@ -1928,7 +2088,7 @@ VerifyTimeBasedPayload ( =0D //=0D // SignedData.digestAlgorithms shall contain the digest algorithm used w= hen preparing the=0D - // signature. Only a digest algorithm of SHA-256 is accepted.=0D + // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is = accepted.=0D //=0D // According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc= 2315):=0D // SignedData ::=3D SEQUENCE {=0D @@ -1972,14 +2132,9 @@ VerifyTimeBasedPayload ( //=0D // Example generated with: https://wiki.archlinux.org/title/Unified_Exte= nsible_Firmware_Interface/Secure_Boot#Manual_process=0D //=0D + HashAlgId =3D FindHashAlgorithmIndex (SigData, SigDataSize);=0D if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != =3D 0) {=0D - if ( ( (SigDataSize >=3D (13 + sizeof (mSha256OidValue)))=0D - && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) !=3D TWO_BYTE_ENCODE)= =0D - || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha2= 56OidValue)) !=3D 0)))=0D - && ( (SigDataSize >=3D (32 + sizeof (mSha256OidValue)))=0D - && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) !=3D TWO_BYTE_ENCODE)= =0D - || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha2= 56OidValue)) !=3D 0))))=0D - {=0D + if (HashAlgId >=3D (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {=0D return EFI_SECURITY_VIOLATION;=0D }=0D }=0D @@ -2170,19 +2325,20 @@ VerifyTimeBasedPayload ( goto Exit;=0D }=0D =0D - if (CertsSizeinDb =3D=3D SHA256_DIGEST_SIZE) {=0D + if ((HashAlgId < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) && (= CertsSizeinDb =3D=3D mHashInfo[HashAlgId].HashSize)) {=0D //=0D // Check hash of signer cert CommonName + Top-level issuer tbsCert= ificate against data in CertDb=0D //=0D CertDataPtr =3D (EFI_CERT_DATA *)(SignerCerts + 1);=0D - Status =3D CalculatePrivAuthVarSignChainSHA256Digest (=0D + Status =3D CalculatePrivAuthVarSignChainSHADigest (=0D + HashAlgId,=0D CertDataPtr->CertDataBuffer,=0D ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertData= Length)),=0D TopLevelCert,=0D TopLevelCertSize,=0D - Sha256Digest=0D + ShaDigest=0D );=0D - if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb= , CertsSizeinDb) !=3D 0)) {=0D + if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, C= ertsSizeinDb) !=3D 0)) {=0D goto Exit;=0D }=0D } else {=0D @@ -2215,6 +2371,7 @@ VerifyTimeBasedPayload ( //=0D CertDataPtr =3D (EFI_CERT_DATA *)(SignerCerts + 1);=0D Status =3D InsertCertsToDb (=0D + HashAlgId,=0D VariableName,=0D VendorGuid,=0D Attributes,=0D diff --git a/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h b/Se= curityPkg/Library/AuthVariableLib/AuthServiceInternal.h index b202e613bc..f7bf771d55 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h +++ b/SecurityPkg/Library/AuthVariableLib/AuthServiceInternal.h @@ -92,7 +92,9 @@ extern UINT32 mMaxCertDbSize; extern UINT32 mPlatformMode;=0D extern UINT8 mVendorKeyState;=0D =0D -extern VOID *mHashCtx;=0D +extern VOID *mHashSha256Ctx;=0D +extern VOID *mHashSha384Ctx;=0D +extern VOID *mHashSha512Ctx;=0D =0D extern AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn;=0D =0D diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c b/Securi= tyPkg/Library/AuthVariableLib/AuthVariableLib.c index dc61ae840c..dc11f38cb3 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.c @@ -26,12 +26,14 @@ UINT32 mMaxCertDbSize; UINT32 mPlatformMode;=0D UINT8 mVendorKeyState;=0D =0D -EFI_GUID mSignatureSupport[] =3D { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GU= ID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID };=0D +EFI_GUID mSignatureSupport[] =3D { EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GU= ID, EFI_CERT_SHA384_GUID, EFI_CERT_SHA512_GUID, EFI_CERT_RSA2048_GUID, EFI_= CERT_X509_GUID };=0D =0D //=0D // Hash context pointer=0D //=0D -VOID *mHashCtx =3D NULL;=0D +VOID *mHashSha256Ctx =3D NULL;=0D +VOID *mHashSha384Ctx =3D NULL;=0D +VOID *mHashSha512Ctx =3D NULL;=0D =0D VARIABLE_ENTRY_PROPERTY mAuthVarEntry[] =3D {=0D {=0D @@ -91,7 +93,7 @@ VARIABLE_ENTRY_PROPERTY mAuthVarEntry[] =3D { },=0D };=0D =0D -VOID **mAuthVarAddressPointer[9];=0D +VOID **mAuthVarAddressPointer[11];=0D =0D AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn =3D NULL;=0D =0D @@ -120,7 +122,6 @@ AuthVariableLibInitialize ( UINT32 VarAttr;=0D UINT8 *Data;=0D UINTN DataSize;=0D - UINTN CtxSize;=0D UINT8 SecureBootMode;=0D UINT8 SecureBootEnable;=0D UINT8 CustomMode;=0D @@ -135,9 +136,18 @@ AuthVariableLibInitialize ( //=0D // Initialize hash context.=0D //=0D - CtxSize =3D Sha256GetContextSize ();=0D - mHashCtx =3D AllocateRuntimePool (CtxSize);=0D - if (mHashCtx =3D=3D NULL) {=0D + mHashSha256Ctx =3D AllocateRuntimePool (Sha256GetContextSize ());=0D + if (mHashSha256Ctx =3D=3D NULL) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + mHashSha384Ctx =3D AllocateRuntimePool (Sha384GetContextSize ());=0D + if (mHashSha384Ctx =3D=3D NULL) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + mHashSha512Ctx =3D AllocateRuntimePool (Sha512GetContextSize ());=0D + if (mHashSha512Ctx =3D=3D NULL) {=0D return EFI_OUT_OF_RESOURCES;=0D }=0D =0D @@ -356,14 +366,16 @@ AuthVariableLibInitialize ( AuthVarLibContextOut->AuthVarEntry =3D mAuthVarEntry;=0D AuthVarLibContextOut->AuthVarEntryCount =3D ARRAY_SIZE (mAuthVarEntry)= ;=0D mAuthVarAddressPointer[0] =3D (VOID **)&mCertDbStore;=0D - mAuthVarAddressPointer[1] =3D (VOID **)&mHashCtx;=0D - mAuthVarAddressPointer[2] =3D (VOID **)&mAuthVarLibConte= xtIn;=0D - mAuthVarAddressPointer[3] =3D (VOID **)&(mAuthVarLibCont= extIn->FindVariable),=0D - mAuthVarAddressPointer[4] =3D (VOID **)&(mAuthVarLibCont= extIn->FindNextVariable),=0D - mAuthVarAddressPointer[5] =3D (VOID **)&(mAuthVarLibCont= extIn->UpdateVariable),=0D - mAuthVarAddressPointer[6] =3D (VOID **)&(mAuthVarLibCont= extIn->GetScratchBuffer),=0D - mAuthVarAddressPointer[7] =3D (VOID **)&(mAuthVarLibCont= extIn->CheckRemainingSpaceForConsistency),=0D - mAuthVarAddressPointer[8] =3D (VOID **)&(mAuthVarLibCont= extIn->AtRuntime),=0D + mAuthVarAddressPointer[1] =3D (VOID **)&mHashSha256Ctx;= =0D + mAuthVarAddressPointer[2] =3D (VOID **)&mHashSha384Ctx;= =0D + mAuthVarAddressPointer[3] =3D (VOID **)&mHashSha512Ctx;= =0D + mAuthVarAddressPointer[4] =3D (VOID **)&mAuthVarLibConte= xtIn;=0D + mAuthVarAddressPointer[5] =3D (VOID **)&(mAuthVarLibCont= extIn->FindVariable),=0D + mAuthVarAddressPointer[6] =3D (VOID **)&(mAuthVarLibCont= extIn->FindNextVariable),=0D + mAuthVarAddressPointer[7] =3D (VOID **)&(mAuthVarLibCont= extIn->UpdateVariable),=0D + mAuthVarAddressPointer[8] =3D (VOID **)&(mAuthVarLibCont= extIn->GetScratchBuffer),=0D + mAuthVarAddressPointer[9] =3D (VOID **)&(mAuthVarLibCont= extIn->CheckRemainingSpaceForConsistency),=0D + mAuthVarAddressPointer[10] =3D (VOID **)&(mAuthVarLibCont= extIn->AtRuntime),=0D AuthVarLibContextOut->AddressPointer =3D mAuthVarAddressPointer;=0D AuthVarLibContextOut->AddressPointerCount =3D ARRAY_SIZE (mAuthVarAddres= sPointer);=0D =0D diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificati= onLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationL= ib.c index 5d8dbd5468..b05da19c2b 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -1620,7 +1620,7 @@ Done: in the security database "db", and no valid signature nor any hash v= alue of the image may=0D be reflected in the security database "dbx".=0D Otherwise, the image is not signed,=0D - The SHA256 hash value of the image must match a record in the securi= ty database "db", and=0D + The hash value of the image must match a record in the security data= base "db", and=0D not be reflected in the security data base "dbx".=0D =0D Caution: This function may receive untrusted input.=0D @@ -1690,6 +1690,8 @@ DxeImageVerificationHandler ( EFI_STATUS VarStatus;=0D UINT32 VarAttr;=0D BOOLEAN IsFound;=0D + UINT8 HashAlg;=0D + BOOLEAN IsFoundInDatabase;=0D =0D SignatureList =3D NULL;=0D SignatureListSize =3D 0;=0D @@ -1699,6 +1701,7 @@ DxeImageVerificationHandler ( Action =3D EFI_IMAGE_EXECUTION_AUTH_UNTESTED;=0D IsVerified =3D FALSE;=0D IsFound =3D FALSE;=0D + IsFoundInDatabase =3D FALSE;=0D =0D //=0D // Check the image type and get policy setting.=0D @@ -1837,40 +1840,51 @@ DxeImageVerificationHandler ( //=0D if ((SecDataDir =3D=3D NULL) || (SecDataDir->Size =3D=3D 0)) {=0D //=0D - // This image is not signed. The SHA256 hash value of the image must m= atch a record in the security database "db",=0D + // This image is not signed. The hash value of the image must match a = record in the security database "db",=0D // and not be reflected in the security data base "dbx".=0D //=0D - if (!HashPeImage (HASHALG_SHA256)) {=0D - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this im= age using %s.\n", mHashTypeStr));=0D - goto Failed;=0D - }=0D + HashAlg =3D sizeof (mHash) / sizeof (HASH_TABLE);=0D + while (HashAlg > 0) {=0D + HashAlg--;=0D + if ((mHash[HashAlg].GetContextSize =3D=3D NULL) || (mHash[HashAlg].H= ashInit =3D=3D NULL) || (mHash[HashAlg].HashUpdate =3D=3D NULL) || (mHash[H= ashAlg].HashFinal =3D=3D NULL)) {=0D + continue;=0D + }=0D =0D - DbStatus =3D IsSignatureFoundInDatabase (=0D - EFI_IMAGE_SECURITY_DATABASE1,=0D - mImageDigest,=0D - &mCertType,=0D - mImageDigestSize,=0D - &IsFound=0D - );=0D - if (EFI_ERROR (DbStatus) || IsFound) {=0D - //=0D - // Image Hash is in forbidden database (DBX).=0D - //=0D - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed an= d %s hash of image is forbidden by DBX.\n", mHashTypeStr));=0D - goto Failed;=0D + if (!HashPeImage (HashAlg)) {=0D + continue;=0D + }=0D +=0D + DbStatus =3D IsSignatureFoundInDatabase (=0D + EFI_IMAGE_SECURITY_DATABASE1,=0D + mImageDigest,=0D + &mCertType,=0D + mImageDigestSize,=0D + &IsFound=0D + );=0D + if (EFI_ERROR (DbStatus) || IsFound) {=0D + //=0D + // Image Hash is in forbidden database (DBX).=0D + //=0D + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed = and %s hash of image is forbidden by DBX.\n", mHashTypeStr));=0D + goto Failed;=0D + }=0D +=0D + DbStatus =3D IsSignatureFoundInDatabase (=0D + EFI_IMAGE_SECURITY_DATABASE,=0D + mImageDigest,=0D + &mCertType,=0D + mImageDigestSize,=0D + &IsFound=0D + );=0D + if (!EFI_ERROR (DbStatus) && IsFound) {=0D + //=0D + // Image Hash is in allowed database (DB).=0D + //=0D + IsFoundInDatabase =3D TRUE;=0D + }=0D }=0D =0D - DbStatus =3D IsSignatureFoundInDatabase (=0D - EFI_IMAGE_SECURITY_DATABASE,=0D - mImageDigest,=0D - &mCertType,=0D - mImageDigestSize,=0D - &IsFound=0D - );=0D - if (!EFI_ERROR (DbStatus) && IsFound) {=0D - //=0D - // Image Hash is in allowed database (DB).=0D - //=0D + if (IsFoundInDatabase) {=0D return EFI_SUCCESS;=0D }=0D =0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/Sec= ureBootConfigDxe.inf index 1671d5be7c..0602acf702 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gDxe.inf @@ -82,6 +82,14 @@ ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D gEfiCertSha256Guid=0D =0D + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D + gEfiCertSha384Guid=0D +=0D + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type o= f the signature.=0D + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type o= f the signature.=0D + gEfiCertSha512Guid=0D +=0D ## SOMETIMES_CONSUMES ## Variable:L"db"=0D ## SOMETIMES_PRODUCES ## Variable:L"db"=0D ## SOMETIMES_CONSUMES ## Variable:L"dbx"=0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/Secu= reBootConfigImpl.c index 0e31502b1b..2c11129526 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.c @@ -1847,7 +1847,7 @@ HashPeImage ( SectionHeader =3D NULL;=0D Status =3D FALSE;=0D =0D - if (HashAlg !=3D HASHALG_SHA256) {=0D + if ((HashAlg >=3D HASHALG_MAX)) {=0D return FALSE;=0D }=0D =0D @@ -1856,8 +1856,25 @@ HashPeImage ( //=0D ZeroMem (mImageDigest, MAX_DIGEST_SIZE);=0D =0D - mImageDigestSize =3D SHA256_DIGEST_SIZE;=0D - mCertType =3D gEfiCertSha256Guid;=0D + switch (HashAlg) {=0D + case HASHALG_SHA256:=0D + mImageDigestSize =3D SHA256_DIGEST_SIZE;=0D + mCertType =3D gEfiCertSha256Guid;=0D + break;=0D +=0D + case HASHALG_SHA384:=0D + mImageDigestSize =3D SHA384_DIGEST_SIZE;=0D + mCertType =3D gEfiCertSha384Guid;=0D + break;=0D +=0D + case HASHALG_SHA512:=0D + mImageDigestSize =3D SHA512_DIGEST_SIZE;=0D + mCertType =3D gEfiCertSha512Guid;=0D + break;=0D +=0D + default:=0D + return FALSE;=0D + }=0D =0D CtxSize =3D mHash[HashAlg].GetContextSize ();=0D =0D @@ -2251,6 +2268,7 @@ EnrollImageSignatureToSigDB ( UINT32 Attr;=0D WIN_CERTIFICATE_UEFI_GUID *GuidCertData;=0D EFI_TIME Time;=0D + UINT32 HashAlg;=0D =0D Data =3D NULL;=0D GuidCertData =3D NULL;=0D @@ -2289,8 +2307,22 @@ EnrollImageSignatureToSigDB ( }=0D =0D if (mSecDataDir->SizeOfCert =3D=3D 0) {=0D - if (!HashPeImage (HASHALG_SHA256)) {=0D - Status =3D EFI_SECURITY_VIOLATION;=0D + Status =3D EFI_SECURITY_VIOLATION;=0D + HashAlg =3D sizeof (mHash) / sizeof (HASH_TABLE);=0D + while (HashAlg > 0) {=0D + HashAlg--;=0D + if ((mHash[HashAlg].GetContextSize =3D=3D NULL) || (mHash[HashAlg].H= ashInit =3D=3D NULL) || (mHash[HashAlg].HashUpdate =3D=3D NULL) || (mHash[H= ashAlg].HashFinal =3D=3D NULL)) {=0D + continue;=0D + }=0D +=0D + if (HashPeImage (HashAlg)) {=0D + Status =3D EFI_SUCCESS;=0D + break;=0D + }=0D + }=0D +=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Fail to get hash digest: %r", Status));=0D goto ON_EXIT;=0D }=0D } else {=0D @@ -3764,6 +3796,10 @@ LoadSignatureList ( ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA1);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Gui= d)) {=0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA256);=0D + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Gui= d)) {=0D + ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA384);=0D + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Gui= d)) {=0D + ListType =3D STRING_TOKEN (STR_LIST_TYPE_SHA512);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha25= 6Guid)) {=0D ListType =3D STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);=0D } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha38= 4Guid)) {=0D @@ -4011,6 +4047,12 @@ FormatHelpInfo ( } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid))= {=0D ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_SHA256);=0D DataSize =3D 32;=0D + } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid))= {=0D + ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_SHA384);=0D + DataSize =3D 48;=0D + } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid))= {=0D + ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_SHA512);=0D + DataSize =3D 64;=0D } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Gu= id)) {=0D ListTypeId =3D STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);=0D DataSize =3D 32;=0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/Secu= reBootConfigImpl.h index 37c66f1b95..ff6e7301af 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gImpl.h @@ -82,6 +82,8 @@ extern EFI_IFR_GUID_LABEL *mEndLabel; #define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE=0D =0D #define WIN_CERT_UEFI_RSA2048_SIZE 256=0D +#define WIN_CERT_UEFI_RSA3072_SIZE 384=0D +#define WIN_CERT_UEFI_RSA4096_SIZE 512=0D =0D //=0D // Support hash types=0D @@ -98,6 +100,11 @@ extern EFI_IFR_GUID_LABEL *mEndLabel; //=0D #define CER_PUBKEY_MIN_SIZE 256=0D =0D +//=0D +// Define KeyType for public key storing file=0D +//=0D +#define KEY_TYPE_RSASSA 0=0D +=0D //=0D // Types of errors may occur during certificate enrollment.=0D //=0D diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBo= otConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe= /SecureBootConfigStrings.uni index 0d01701de7..177c585837 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gStrings.uni +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfi= gStrings.uni @@ -124,6 +124,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #string STR_LIST_TYPE_X509 #language en-US "X509"=0D #string STR_LIST_TYPE_SHA1 #language en-US "SHA1"=0D #string STR_LIST_TYPE_SHA256 #language en-US "SHA256"= =0D +#string STR_LIST_TYPE_SHA384 #language en-US "SHA384"= =0D +#string STR_LIST_TYPE_SHA512 #language en-US "SHA512"= =0D #string STR_LIST_TYPE_X509_SHA256 #language en-US "X509_SH= A256"=0D #string STR_LIST_TYPE_X509_SHA384 #language en-US "X509_SH= A384"=0D #string STR_LIST_TYPE_X509_SHA512 #language en-US "X509_SH= A512"=0D --=20 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108314): https://edk2.groups.io/g/devel/message/108314 Mute This Topic: https://groups.io/mt/101188634/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-