SecurityPkg/SecureBoot: Support RSA4096 and RSA3072

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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Sheng Wei
2023-09-07 09:57:19 +08:00
committed by mergify[bot]
parent 24da5c2f28
commit bbf1822295
8 changed files with 330 additions and 86 deletions

View File

@ -29,12 +29,125 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Protocol/VariablePolicy.h> #include <Protocol/VariablePolicy.h>
#include <Library/VariablePolicyLib.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. // Public Exponent of RSA Key.
// //
CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 }; 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. // Requirement for different signature type which have been defined in UEFI spec.
@ -1090,26 +1203,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. 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] SignerCert A pointer to SignerCert data.
@param[in] SignerCertSize Length of SignerCert data. @param[in] SignerCertSize Length of SignerCert data.
@param[in] TopLevelCert A pointer to TopLevelCert data. @param[in] TopLevelCert A pointer to TopLevelCert data.
@param[in] TopLevelCertSize Length of 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_ABORTED Digest process failed.
@return EFI_SUCCESS SHA256 Digest is successfully calculated. @return EFI_SUCCESS SHA Digest is successfully calculated.
**/ **/
EFI_STATUS EFI_STATUS
CalculatePrivAuthVarSignChainSHA256Digest ( CalculatePrivAuthVarSignChainSHADigest (
IN UINT8 HashAlgId,
IN UINT8 *SignerCert, IN UINT8 *SignerCert,
IN UINTN SignerCertSize, IN UINTN SignerCertSize,
IN UINT8 *TopLevelCert, IN UINT8 *TopLevelCert,
IN UINTN TopLevelCertSize, IN UINTN TopLevelCertSize,
OUT UINT8 *Sha256Digest OUT UINT8 *ShaDigest
) )
{ {
UINT8 *TbsCert; UINT8 *TbsCert;
@ -1119,6 +1234,11 @@ CalculatePrivAuthVarSignChainSHA256Digest (
BOOLEAN CryptoStatus; BOOLEAN CryptoStatus;
EFI_STATUS Status; 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); CertCommonNameSize = sizeof (CertCommonName);
// //
@ -1141,8 +1261,8 @@ CalculatePrivAuthVarSignChainSHA256Digest (
// //
// Digest SignerCert CN + TopLevelCert tbsCertificate // Digest SignerCert CN + TopLevelCert tbsCertificate
// //
ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE); ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);
CryptoStatus = Sha256Init (mHashCtx); CryptoStatus = mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashShaCtx));
if (!CryptoStatus) { if (!CryptoStatus) {
return EFI_ABORTED; return EFI_ABORTED;
} }
@ -1150,8 +1270,8 @@ CalculatePrivAuthVarSignChainSHA256Digest (
// //
// '\0' is forced in CertCommonName. No overflow issue // '\0' is forced in CertCommonName. No overflow issue
// //
CryptoStatus = Sha256Update ( CryptoStatus = mHashInfo[HashAlgId].Update (
mHashCtx, *(mHashInfo[HashAlgId].HashShaCtx),
CertCommonName, CertCommonName,
AsciiStrLen (CertCommonName) AsciiStrLen (CertCommonName)
); );
@ -1159,12 +1279,12 @@ CalculatePrivAuthVarSignChainSHA256Digest (
return EFI_ABORTED; return EFI_ABORTED;
} }
CryptoStatus = Sha256Update (mHashCtx, TbsCert, TbsCertSize); CryptoStatus = mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].HashShaCtx), TbsCert, TbsCertSize);
if (!CryptoStatus) { if (!CryptoStatus) {
return EFI_ABORTED; return EFI_ABORTED;
} }
CryptoStatus = Sha256Final (mHashCtx, Sha256Digest); CryptoStatus = mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].HashShaCtx), ShaDigest);
if (!CryptoStatus) { if (!CryptoStatus) {
return EFI_ABORTED; return EFI_ABORTED;
} }
@ -1516,9 +1636,10 @@ DeleteCertsFromDb (
/** /**
Insert signer's certificates for common authenticated variable with VariableName Insert signer's certificates for common authenticated variable with VariableName
and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to 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. SignerCert CommonName + TopLevelCert tbsCertificate.
@param[in] HashAlgId Hash algorithm index.
@param[in] VariableName Name of authenticated Variable. @param[in] VariableName Name of authenticated Variable.
@param[in] VendorGuid Vendor GUID of authenticated Variable. @param[in] VendorGuid Vendor GUID of authenticated Variable.
@param[in] Attributes Attributes of authenticated variable. @param[in] Attributes Attributes of authenticated variable.
@ -1536,6 +1657,7 @@ DeleteCertsFromDb (
**/ **/
EFI_STATUS EFI_STATUS
InsertCertsToDb ( InsertCertsToDb (
IN UINT8 HashAlgId,
IN CHAR16 *VariableName, IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid, IN EFI_GUID *VendorGuid,
IN UINT32 Attributes, IN UINT32 Attributes,
@ -1556,12 +1678,16 @@ InsertCertsToDb (
UINT32 CertDataSize; UINT32 CertDataSize;
AUTH_CERT_DB_DATA *Ptr; AUTH_CERT_DB_DATA *Ptr;
CHAR16 *DbName; CHAR16 *DbName;
UINT8 Sha256Digest[SHA256_DIGEST_SIZE]; UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];
if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) { if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
return EFI_INVALID_PARAMETER;
}
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
// //
// Get variable "certdb". // Get variable "certdb".
@ -1618,20 +1744,22 @@ InsertCertsToDb (
// Construct new data content of variable "certdb" or "certdbv". // Construct new data content of variable "certdb" or "certdbv".
// //
NameSize = (UINT32)StrLen (VariableName); NameSize = (UINT32)StrLen (VariableName);
CertDataSize = sizeof (Sha256Digest); CertDataSize = mHashInfo[HashAlgId].HashSize;
CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16); CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);
NewCertDbSize = (UINT32)DataSize + CertNodeSize; NewCertDbSize = (UINT32)DataSize + CertNodeSize;
if (NewCertDbSize > mMaxCertDbSize) { if (NewCertDbSize > mMaxCertDbSize) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
Status = CalculatePrivAuthVarSignChainSHA256Digest ( Status = CalculatePrivAuthVarSignChainSHADigest (
HashAlgId,
SignerCert, SignerCert,
SignerCertSize, SignerCertSize,
TopLevelCert, TopLevelCert,
TopLevelCertSize, TopLevelCertSize,
Sha256Digest ShaDigest
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@ -1663,7 +1791,7 @@ InsertCertsToDb (
CopyMem ( CopyMem (
(UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16), (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
Sha256Digest, ShaDigest,
CertDataSize CertDataSize
); );
@ -1790,6 +1918,37 @@ CleanCertsFromDb (
return Status; 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 Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
@ -1857,8 +2016,9 @@ VerifyTimeBasedPayload (
UINTN CertStackSize; UINTN CertStackSize;
UINT8 *CertsInCertDb; UINT8 *CertsInCertDb;
UINT32 CertsSizeinDb; UINT32 CertsSizeinDb;
UINT8 Sha256Digest[SHA256_DIGEST_SIZE]; UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];
EFI_CERT_DATA *CertDataPtr; EFI_CERT_DATA *CertDataPtr;
UINT8 HashAlgId;
// //
// 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain
@ -1928,7 +2088,7 @@ VerifyTimeBasedPayload (
// //
// SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the // 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): // According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
// SignedData ::= SEQUENCE { // SignedData ::= SEQUENCE {
@ -1972,14 +2132,9 @@ VerifyTimeBasedPayload (
// //
// Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process // 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 ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
if ( ( (SigDataSize >= (13 + sizeof (mSha256OidValue))) if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
&& ( ((*(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))))
{
return EFI_SECURITY_VIOLATION; return EFI_SECURITY_VIOLATION;
} }
} }
@ -2170,19 +2325,20 @@ VerifyTimeBasedPayload (
goto Exit; 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 // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
// //
CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1); CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
Status = CalculatePrivAuthVarSignChainSHA256Digest ( Status = CalculatePrivAuthVarSignChainSHADigest (
HashAlgId,
CertDataPtr->CertDataBuffer, CertDataPtr->CertDataBuffer,
ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)), ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
TopLevelCert, TopLevelCert,
TopLevelCertSize, TopLevelCertSize,
Sha256Digest ShaDigest
); );
if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb, CertsSizeinDb) != 0)) { if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
goto Exit; goto Exit;
} }
} else { } else {
@ -2215,6 +2371,7 @@ VerifyTimeBasedPayload (
// //
CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1); CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
Status = InsertCertsToDb ( Status = InsertCertsToDb (
HashAlgId,
VariableName, VariableName,
VendorGuid, VendorGuid,
Attributes, Attributes,

View File

@ -92,7 +92,9 @@ extern UINT32 mMaxCertDbSize;
extern UINT32 mPlatformMode; extern UINT32 mPlatformMode;
extern UINT8 mVendorKeyState; extern UINT8 mVendorKeyState;
extern VOID *mHashCtx; extern VOID *mHashSha256Ctx;
extern VOID *mHashSha384Ctx;
extern VOID *mHashSha512Ctx;
extern AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn; extern AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn;

View File

@ -26,12 +26,14 @@ UINT32 mMaxCertDbSize;
UINT32 mPlatformMode; UINT32 mPlatformMode;
UINT8 mVendorKeyState; 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_X509_GUID };
// //
// Hash context pointer // Hash context pointer
// //
VOID *mHashCtx = NULL; VOID *mHashSha256Ctx = NULL;
VOID *mHashSha384Ctx = NULL;
VOID *mHashSha512Ctx = NULL;
VARIABLE_ENTRY_PROPERTY mAuthVarEntry[] = { 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; AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn = NULL;
@ -120,7 +122,6 @@ AuthVariableLibInitialize (
UINT32 VarAttr; UINT32 VarAttr;
UINT8 *Data; UINT8 *Data;
UINTN DataSize; UINTN DataSize;
UINTN CtxSize;
UINT8 SecureBootMode; UINT8 SecureBootMode;
UINT8 SecureBootEnable; UINT8 SecureBootEnable;
UINT8 CustomMode; UINT8 CustomMode;
@ -135,9 +136,18 @@ AuthVariableLibInitialize (
// //
// Initialize hash context. // Initialize hash context.
// //
CtxSize = Sha256GetContextSize (); mHashSha256Ctx = AllocateRuntimePool (Sha256GetContextSize ());
mHashCtx = AllocateRuntimePool (CtxSize); if (mHashSha256Ctx == NULL) {
if (mHashCtx == 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; return EFI_OUT_OF_RESOURCES;
} }
@ -356,14 +366,16 @@ AuthVariableLibInitialize (
AuthVarLibContextOut->AuthVarEntry = mAuthVarEntry; AuthVarLibContextOut->AuthVarEntry = mAuthVarEntry;
AuthVarLibContextOut->AuthVarEntryCount = ARRAY_SIZE (mAuthVarEntry); AuthVarLibContextOut->AuthVarEntryCount = ARRAY_SIZE (mAuthVarEntry);
mAuthVarAddressPointer[0] = (VOID **)&mCertDbStore; mAuthVarAddressPointer[0] = (VOID **)&mCertDbStore;
mAuthVarAddressPointer[1] = (VOID **)&mHashCtx; mAuthVarAddressPointer[1] = (VOID **)&mHashSha256Ctx;
mAuthVarAddressPointer[2] = (VOID **)&mAuthVarLibContextIn; mAuthVarAddressPointer[2] = (VOID **)&mHashSha384Ctx;
mAuthVarAddressPointer[3] = (VOID **)&(mAuthVarLibContextIn->FindVariable), mAuthVarAddressPointer[3] = (VOID **)&mHashSha512Ctx;
mAuthVarAddressPointer[4] = (VOID **)&(mAuthVarLibContextIn->FindNextVariable), mAuthVarAddressPointer[4] = (VOID **)&mAuthVarLibContextIn;
mAuthVarAddressPointer[5] = (VOID **)&(mAuthVarLibContextIn->UpdateVariable), mAuthVarAddressPointer[5] = (VOID **)&(mAuthVarLibContextIn->FindVariable),
mAuthVarAddressPointer[6] = (VOID **)&(mAuthVarLibContextIn->GetScratchBuffer), mAuthVarAddressPointer[6] = (VOID **)&(mAuthVarLibContextIn->FindNextVariable),
mAuthVarAddressPointer[7] = (VOID **)&(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency), mAuthVarAddressPointer[7] = (VOID **)&(mAuthVarLibContextIn->UpdateVariable),
mAuthVarAddressPointer[8] = (VOID **)&(mAuthVarLibContextIn->AtRuntime), mAuthVarAddressPointer[8] = (VOID **)&(mAuthVarLibContextIn->GetScratchBuffer),
mAuthVarAddressPointer[9] = (VOID **)&(mAuthVarLibContextIn->CheckRemainingSpaceForConsistency),
mAuthVarAddressPointer[10] = (VOID **)&(mAuthVarLibContextIn->AtRuntime),
AuthVarLibContextOut->AddressPointer = mAuthVarAddressPointer; AuthVarLibContextOut->AddressPointer = mAuthVarAddressPointer;
AuthVarLibContextOut->AddressPointerCount = ARRAY_SIZE (mAuthVarAddressPointer); AuthVarLibContextOut->AddressPointerCount = ARRAY_SIZE (mAuthVarAddressPointer);

View File

@ -1620,7 +1620,7 @@ Done:
in the security database "db", and no valid signature nor any hash value of the image may in the security database "db", and no valid signature nor any hash value of the image may
be reflected in the security database "dbx". be reflected in the security database "dbx".
Otherwise, the image is not signed, 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". not be reflected in the security data base "dbx".
Caution: This function may receive untrusted input. Caution: This function may receive untrusted input.
@ -1690,6 +1690,8 @@ DxeImageVerificationHandler (
EFI_STATUS VarStatus; EFI_STATUS VarStatus;
UINT32 VarAttr; UINT32 VarAttr;
BOOLEAN IsFound; BOOLEAN IsFound;
UINT8 HashAlg;
BOOLEAN IsFoundInDatabase;
SignatureList = NULL; SignatureList = NULL;
SignatureListSize = 0; SignatureListSize = 0;
@ -1699,6 +1701,7 @@ DxeImageVerificationHandler (
Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED; Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;
IsVerified = FALSE; IsVerified = FALSE;
IsFound = FALSE; IsFound = FALSE;
IsFoundInDatabase = FALSE;
// //
// Check the image type and get policy setting. // Check the image type and get policy setting.
@ -1837,12 +1840,18 @@ DxeImageVerificationHandler (
// //
if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) { 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". // and not be reflected in the security data base "dbx".
// //
if (!HashPeImage (HASHALG_SHA256)) { HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr)); while (HashAlg > 0) {
goto Failed; 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 ( DbStatus = IsSignatureFoundInDatabase (
@ -1871,6 +1880,11 @@ DxeImageVerificationHandler (
// //
// Image Hash is in allowed database (DB). // Image Hash is in allowed database (DB).
// //
IsFoundInDatabase = TRUE;
}
}
if (IsFoundInDatabase) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -82,6 +82,14 @@
## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature.
gEfiCertSha256Guid 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_CONSUMES ## Variable:L"db"
## SOMETIMES_PRODUCES ## Variable:L"db" ## SOMETIMES_PRODUCES ## Variable:L"db"
## SOMETIMES_CONSUMES ## Variable:L"dbx" ## SOMETIMES_CONSUMES ## Variable:L"dbx"

View File

@ -1847,7 +1847,7 @@ HashPeImage (
SectionHeader = NULL; SectionHeader = NULL;
Status = FALSE; Status = FALSE;
if (HashAlg != HASHALG_SHA256) { if ((HashAlg >= HASHALG_MAX)) {
return FALSE; return FALSE;
} }
@ -1856,8 +1856,25 @@ HashPeImage (
// //
ZeroMem (mImageDigest, MAX_DIGEST_SIZE); ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
switch (HashAlg) {
case HASHALG_SHA256:
mImageDigestSize = SHA256_DIGEST_SIZE; mImageDigestSize = SHA256_DIGEST_SIZE;
mCertType = gEfiCertSha256Guid; 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 (); CtxSize = mHash[HashAlg].GetContextSize ();
@ -2251,6 +2268,7 @@ EnrollImageSignatureToSigDB (
UINT32 Attr; UINT32 Attr;
WIN_CERTIFICATE_UEFI_GUID *GuidCertData; WIN_CERTIFICATE_UEFI_GUID *GuidCertData;
EFI_TIME Time; EFI_TIME Time;
UINT32 HashAlg;
Data = NULL; Data = NULL;
GuidCertData = NULL; GuidCertData = NULL;
@ -2289,8 +2307,22 @@ EnrollImageSignatureToSigDB (
} }
if (mSecDataDir->SizeOfCert == 0) { 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; goto ON_EXIT;
} }
} else { } else {
@ -3764,6 +3796,10 @@ LoadSignatureList (
ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1); ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
} else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) { } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256); 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)) { } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256); ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
} else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) { } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
@ -4011,6 +4047,12 @@ FormatHelpInfo (
} else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) { } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256); ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
DataSize = 32; 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)) { } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256); ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
DataSize = 32; DataSize = 32;

View File

@ -82,6 +82,8 @@ extern EFI_IFR_GUID_LABEL *mEndLabel;
#define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE #define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
#define WIN_CERT_UEFI_RSA2048_SIZE 256 #define WIN_CERT_UEFI_RSA2048_SIZE 256
#define WIN_CERT_UEFI_RSA3072_SIZE 384
#define WIN_CERT_UEFI_RSA4096_SIZE 512
// //
// Support hash types // Support hash types
@ -98,6 +100,11 @@ extern EFI_IFR_GUID_LABEL *mEndLabel;
// //
#define CER_PUBKEY_MIN_SIZE 256 #define CER_PUBKEY_MIN_SIZE 256
//
// Define KeyType for public key storing file
//
#define KEY_TYPE_RSASSA 0
// //
// Types of errors may occur during certificate enrollment. // Types of errors may occur during certificate enrollment.
// //

View File

@ -124,6 +124,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#string STR_LIST_TYPE_X509 #language en-US "X509" #string STR_LIST_TYPE_X509 #language en-US "X509"
#string STR_LIST_TYPE_SHA1 #language en-US "SHA1" #string STR_LIST_TYPE_SHA1 #language en-US "SHA1"
#string STR_LIST_TYPE_SHA256 #language en-US "SHA256" #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_SHA256 #language en-US "X509_SHA256"
#string STR_LIST_TYPE_X509_SHA384 #language en-US "X509_SHA384" #string STR_LIST_TYPE_X509_SHA384 #language en-US "X509_SHA384"
#string STR_LIST_TYPE_X509_SHA512 #language en-US "X509_SHA512" #string STR_LIST_TYPE_X509_SHA512 #language en-US "X509_SHA512"