UEFI 2.4 X509 Certificate Hash and RFC3161 Timestamp Verification support for Secure Boot
Main ChangeLogs includes: 1. Introduce the new GUID and structure definitions for certificate hash and timestamp support; 2. Update Image Verification Library to support DBT signature checking; 3. Update the related SecureBoot Configuration Pages; Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qin Long <qin.long@intel.com> Reviewed-by: Guo Dong <guo.dong@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16380 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Image signature database are defined for the signed image validation.
|
Image signature database are defined for the signed image validation.
|
||||||
|
|
||||||
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -11,13 +11,14 @@
|
|||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
GUIDs defined in UEFI 2.3.1 spec.
|
GUIDs defined in UEFI 2.4 spec.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __IMAGE_AUTHTICATION_H__
|
#ifndef __IMAGE_AUTHTICATION_H__
|
||||||
#define __IMAGE_AUTHTICATION_H__
|
#define __IMAGE_AUTHTICATION_H__
|
||||||
|
|
||||||
#include <Guid/GlobalVariable.h>
|
#include <Guid/GlobalVariable.h>
|
||||||
|
#include <Protocol/Hash.h>
|
||||||
|
|
||||||
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
||||||
{ \
|
{ \
|
||||||
@ -34,6 +35,11 @@
|
|||||||
/// for the forbidden signature database.
|
/// for the forbidden signature database.
|
||||||
///
|
///
|
||||||
#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
|
#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
|
||||||
|
///
|
||||||
|
/// Variable name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
|
||||||
|
/// for the timestamp signature database.
|
||||||
|
///
|
||||||
|
#define EFI_IMAGE_SECURITY_DATABASE2 L"dbt"
|
||||||
|
|
||||||
#define SECURE_BOOT_MODE_ENABLE 1
|
#define SECURE_BOOT_MODE_ENABLE 1
|
||||||
#define SECURE_BOOT_MODE_DISABLE 0
|
#define SECURE_BOOT_MODE_DISABLE 0
|
||||||
@ -87,6 +93,39 @@ typedef struct {
|
|||||||
///
|
///
|
||||||
} EFI_SIGNATURE_LIST;
|
} EFI_SIGNATURE_LIST;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
///
|
||||||
|
/// The SHA256 hash of an X.509 certificate's To-Be-Signed contents.
|
||||||
|
///
|
||||||
|
EFI_SHA256_HASH ToBeSignedHash;
|
||||||
|
///
|
||||||
|
/// The time that the certificate shall be considered to be revoked.
|
||||||
|
///
|
||||||
|
EFI_TIME TimeOfRevocation;
|
||||||
|
} EFI_CERT_X509_SHA256;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
///
|
||||||
|
/// The SHA384 hash of an X.509 certificate's To-Be-Signed contents.
|
||||||
|
///
|
||||||
|
EFI_SHA384_HASH ToBeSignedHash;
|
||||||
|
///
|
||||||
|
/// The time that the certificate shall be considered to be revoked.
|
||||||
|
///
|
||||||
|
EFI_TIME TimeOfRevocation;
|
||||||
|
} EFI_CERT_X509_SHA384;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
///
|
||||||
|
/// The SHA512 hash of an X.509 certificate's To-Be-Signed contents.
|
||||||
|
///
|
||||||
|
EFI_SHA512_HASH ToBeSignedHash;
|
||||||
|
///
|
||||||
|
/// The time that the certificate shall be considered to be revoked.
|
||||||
|
///
|
||||||
|
EFI_TIME TimeOfRevocation;
|
||||||
|
} EFI_CERT_X509_SHA512;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -184,6 +223,45 @@ typedef struct {
|
|||||||
0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} \
|
0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// This identifies a signature containing the SHA256 hash of an X.509 certificate's
|
||||||
|
/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
|
||||||
|
/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
|
||||||
|
/// + 48 bytes for an EFI_CERT_X509_SHA256 structure. If the TimeOfRevocation is non-zero,
|
||||||
|
/// the certificate should be considered to be revoked from that time and onwards, and
|
||||||
|
/// otherwise the certificate shall be considered to always be revoked.
|
||||||
|
///
|
||||||
|
#define EFI_CERT_X509_SHA256_GUID \
|
||||||
|
{ \
|
||||||
|
0x3bd2a492, 0x96c0, 0x4079, {0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed } \
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// This identifies a signature containing the SHA384 hash of an X.509 certificate's
|
||||||
|
/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
|
||||||
|
/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
|
||||||
|
/// + 64 bytes for an EFI_CERT_X509_SHA384 structure. If the TimeOfRevocation is non-zero,
|
||||||
|
/// the certificate should be considered to be revoked from that time and onwards, and
|
||||||
|
/// otherwise the certificate shall be considered to always be revoked.
|
||||||
|
///
|
||||||
|
#define EFI_CERT_X509_SHA384_GUID \
|
||||||
|
{ \
|
||||||
|
0x7076876e, 0x80c2, 0x4ee6, {0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b } \
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// This identifies a signature containing the SHA512 hash of an X.509 certificate's
|
||||||
|
/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
|
||||||
|
/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
|
||||||
|
/// + 80 bytes for an EFI_CERT_X509_SHA512 structure. If the TimeOfRevocation is non-zero,
|
||||||
|
/// the certificate should be considered to be revoked from that time and onwards, and
|
||||||
|
/// otherwise the certificate shall be considered to always be revoked.
|
||||||
|
///
|
||||||
|
#define EFI_CERT_X509_SHA512_GUID \
|
||||||
|
{ \
|
||||||
|
0x446dbf63, 0x2502, 0x4cda, {0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d } \
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
|
/// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
|
||||||
/// SignedData value.
|
/// SignedData value.
|
||||||
@ -266,6 +344,9 @@ extern EFI_GUID gEfiCertX509Guid;
|
|||||||
extern EFI_GUID gEfiCertSha224Guid;
|
extern EFI_GUID gEfiCertSha224Guid;
|
||||||
extern EFI_GUID gEfiCertSha384Guid;
|
extern EFI_GUID gEfiCertSha384Guid;
|
||||||
extern EFI_GUID gEfiCertSha512Guid;
|
extern EFI_GUID gEfiCertSha512Guid;
|
||||||
|
extern EFI_GUID gEfiCertX509Sha256Guid;
|
||||||
|
extern EFI_GUID gEfiCertX509Sha384Guid;
|
||||||
|
extern EFI_GUID gEfiCertX509Sha512Guid;
|
||||||
extern EFI_GUID gEfiCertPkcs7Guid;
|
extern EFI_GUID gEfiCertPkcs7Guid;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -523,6 +523,11 @@
|
|||||||
## Include/Guid/FmpCapsule.h
|
## Include/Guid/FmpCapsule.h
|
||||||
gEfiFmpCapsuleGuid = { 0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a }}
|
gEfiFmpCapsuleGuid = { 0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a }}
|
||||||
|
|
||||||
|
## Include/Guid/ImageAuthentication.h
|
||||||
|
gEfiCertX509Sha256Guid = { 0x3bd2a492, 0x96c0, 0x4079, {0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed }}
|
||||||
|
gEfiCertX509Sha384Guid = { 0x7076876e, 0x80c2, 0x4ee6, {0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b }}
|
||||||
|
gEfiCertX509Sha512Guid = { 0x446dbf63, 0x2502, 0x4cda, {0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d }}
|
||||||
|
|
||||||
## Include/Protocol/Rng.h
|
## Include/Protocol/Rng.h
|
||||||
gEfiRngAlgorithmSp80090Hash256Guid = { 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 }}
|
gEfiRngAlgorithmSp80090Hash256Guid = { 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 }}
|
||||||
gEfiRngAlgorithmSp80090Hmac256Guid = { 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 }}
|
gEfiRngAlgorithmSp80090Hmac256Guid = { 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 }}
|
||||||
|
@ -67,8 +67,8 @@ HASH_TABLE mHash[] = {
|
|||||||
{ L"SHA1", 20, &mHashOidValue[0], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },
|
{ L"SHA1", 20, &mHashOidValue[0], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },
|
||||||
{ L"SHA224", 28, &mHashOidValue[5], 9, NULL, NULL, NULL, NULL },
|
{ L"SHA224", 28, &mHashOidValue[5], 9, NULL, NULL, NULL, NULL },
|
||||||
{ L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},
|
{ L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},
|
||||||
{ L"SHA384", 48, &mHashOidValue[23], 9, NULL, NULL, NULL, NULL },
|
{ L"SHA384", 48, &mHashOidValue[23], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final},
|
||||||
{ L"SHA512", 64, &mHashOidValue[32], 9, NULL, NULL, NULL, NULL }
|
{ L"SHA512", 64, &mHashOidValue[32], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -306,7 +306,7 @@ HashPeImage (
|
|||||||
SectionHeader = NULL;
|
SectionHeader = NULL;
|
||||||
Status = FALSE;
|
Status = FALSE;
|
||||||
|
|
||||||
if ((HashAlg != HASHALG_SHA1) && (HashAlg != HASHALG_SHA256)) {
|
if ((HashAlg >= HASHALG_MAX)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,13 +315,28 @@ HashPeImage (
|
|||||||
//
|
//
|
||||||
ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
|
ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
|
||||||
|
|
||||||
if (HashAlg == HASHALG_SHA1) {
|
switch (HashAlg) {
|
||||||
|
case HASHALG_SHA1:
|
||||||
mImageDigestSize = SHA1_DIGEST_SIZE;
|
mImageDigestSize = SHA1_DIGEST_SIZE;
|
||||||
mCertType = gEfiCertSha1Guid;
|
mCertType = gEfiCertSha1Guid;
|
||||||
} else if (HashAlg == HASHALG_SHA256) {
|
break;
|
||||||
|
|
||||||
|
case HASHALG_SHA256:
|
||||||
mImageDigestSize = SHA256_DIGEST_SIZE;
|
mImageDigestSize = SHA256_DIGEST_SIZE;
|
||||||
mCertType = gEfiCertSha256Guid;
|
mCertType = gEfiCertSha256Guid;
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
case HASHALG_SHA384:
|
||||||
|
mImageDigestSize = SHA384_DIGEST_SIZE;
|
||||||
|
mCertType = gEfiCertSha384Guid;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HASHALG_SHA512:
|
||||||
|
mImageDigestSize = SHA512_DIGEST_SIZE;
|
||||||
|
mCertType = gEfiCertSha512Guid;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +818,124 @@ AddImageExeInfo (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the hash of an given X.509 certificate is in forbidden database (DBX).
|
||||||
|
|
||||||
|
@param[in] Certificate Pointer to X.509 Certificate that is searched for.
|
||||||
|
@param[in] CertSize Size of X.509 Certificate.
|
||||||
|
@param[in] SignatureList Pointer to the Signature List in forbidden database.
|
||||||
|
@param[in] SignatureListSize Size of Signature List.
|
||||||
|
@param[out] RevocationTime Return the time that the certificate was revoked.
|
||||||
|
|
||||||
|
@return TRUE The certificate hash is found in the forbidden database.
|
||||||
|
@return FALSE The certificate hash is not found in the forbidden database.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsCertHashFoundInDatabase (
|
||||||
|
IN UINT8 *Certificate,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN EFI_SIGNATURE_LIST *SignatureList,
|
||||||
|
IN UINTN SignatureListSize,
|
||||||
|
OUT EFI_TIME *RevocationTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN IsFound;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_SIGNATURE_LIST *DbxList;
|
||||||
|
UINTN DbxSize;
|
||||||
|
EFI_SIGNATURE_DATA *CertHash;
|
||||||
|
UINTN CertHashCount;
|
||||||
|
UINTN Index;
|
||||||
|
UINT32 HashAlg;
|
||||||
|
VOID *HashCtx;
|
||||||
|
UINT8 CertDigest[MAX_DIGEST_SIZE];
|
||||||
|
UINT8 *DbxCertHash;
|
||||||
|
UINTN SiglistHeaderSize;
|
||||||
|
|
||||||
|
IsFound = FALSE;
|
||||||
|
DbxList = SignatureList;
|
||||||
|
DbxSize = SignatureListSize;
|
||||||
|
HashCtx = NULL;
|
||||||
|
HashAlg = HASHALG_MAX;
|
||||||
|
|
||||||
|
ASSERT (RevocationTime != NULL);
|
||||||
|
|
||||||
|
while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {
|
||||||
|
//
|
||||||
|
// Determine Hash Algorithm of Certificate in the forbidden database.
|
||||||
|
//
|
||||||
|
if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha256Guid)) {
|
||||||
|
HashAlg = HASHALG_SHA256;
|
||||||
|
} else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha384Guid)) {
|
||||||
|
HashAlg = HASHALG_SHA384;
|
||||||
|
} else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha512Guid)) {
|
||||||
|
HashAlg = HASHALG_SHA512;
|
||||||
|
} else {
|
||||||
|
DbxSize -= DbxList->SignatureListSize;
|
||||||
|
DbxList = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the hash value of current db certificate for comparision.
|
||||||
|
//
|
||||||
|
if (mHash[HashAlg].GetContextSize == NULL) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
ZeroMem (CertDigest, MAX_DIGEST_SIZE);
|
||||||
|
HashCtx = AllocatePool (mHash[HashAlg].GetContextSize ());
|
||||||
|
if (HashCtx == NULL) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
Status = mHash[HashAlg].HashInit (HashCtx);
|
||||||
|
if (!Status) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
Status = mHash[HashAlg].HashUpdate (HashCtx, Certificate, CertSize);
|
||||||
|
if (!Status) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
Status = mHash[HashAlg].HashFinal (HashCtx, CertDigest);
|
||||||
|
if (!Status) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;
|
||||||
|
CertHash = (EFI_SIGNATURE_DATA *) ((UINT8 *) DbxList + SiglistHeaderSize);
|
||||||
|
CertHashCount = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;
|
||||||
|
for (Index = 0; Index < CertHashCount; Index++) {
|
||||||
|
//
|
||||||
|
// Iterate each Signature Data Node within this CertList for verify.
|
||||||
|
//
|
||||||
|
DbxCertHash = CertHash->SignatureData;
|
||||||
|
if (CompareMem (DbxCertHash, CertDigest, mHash[HashAlg].DigestLength) == 0) {
|
||||||
|
//
|
||||||
|
// Hash of Certificate is found in forbidden database.
|
||||||
|
//
|
||||||
|
IsFound = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the revocation time.
|
||||||
|
//
|
||||||
|
CopyMem (RevocationTime, (EFI_TIME *)(DbxCertHash + mHash[HashAlg].DigestLength), sizeof (EFI_TIME));
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
CertHash = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertHash + DbxList->SignatureSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
DbxSize -= DbxList->SignatureListSize;
|
||||||
|
DbxList = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (HashCtx != NULL) {
|
||||||
|
FreePool (HashCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsFound;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check whether signature is in specified database.
|
Check whether signature is in specified database.
|
||||||
|
|
||||||
@ -831,6 +964,7 @@ IsSignatureFoundInDatabase (
|
|||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINTN CertCount;
|
UINTN CertCount;
|
||||||
BOOLEAN IsFound;
|
BOOLEAN IsFound;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read signature database variable.
|
// Read signature database variable.
|
||||||
//
|
//
|
||||||
@ -890,24 +1024,296 @@ Done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Verify PKCS#7 SignedData using certificate found in Variable which formatted
|
Check whether the timestamp is valid by comparing the signing time and the revocation time.
|
||||||
as EFI_SIGNATURE_LIST. The Variable may be PK, KEK, DB or DBX.
|
|
||||||
|
|
||||||
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed image.
|
@param SigningTime A pointer to the signing time.
|
||||||
@param[in] AuthDataSize Size of the Authenticode Signature in bytes.
|
@param RevocationTime A pointer to the revocation time.
|
||||||
@param[in] VariableName Name of Variable to search for Certificate.
|
|
||||||
@param[in] VendorGuid Variable vendor GUID.
|
|
||||||
|
|
||||||
@retval TRUE Image pass verification.
|
@retval TRUE The SigningTime is not later than the RevocationTime.
|
||||||
@retval FALSE Image fail verification.
|
@retval FALSE The SigningTime is later than the RevocationTime.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
IsPkcsSignedDataVerifiedBySignatureList (
|
IsValidSignatureByTimestamp (
|
||||||
|
IN EFI_TIME *SigningTime,
|
||||||
|
IN EFI_TIME *RevocationTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (SigningTime->Year != RevocationTime->Year) {
|
||||||
|
return (BOOLEAN) (SigningTime->Year < RevocationTime->Year);
|
||||||
|
} else if (SigningTime->Month != RevocationTime->Month) {
|
||||||
|
return (BOOLEAN) (SigningTime->Month < RevocationTime->Month);
|
||||||
|
} else if (SigningTime->Day != RevocationTime->Day) {
|
||||||
|
return (BOOLEAN) (SigningTime->Day < RevocationTime->Day);
|
||||||
|
} else if (SigningTime->Hour != RevocationTime->Hour) {
|
||||||
|
return (BOOLEAN) (SigningTime->Hour < RevocationTime->Hour);
|
||||||
|
} else if (SigningTime->Minute != RevocationTime->Minute) {
|
||||||
|
return (BOOLEAN) (SigningTime->Minute < RevocationTime->Minute);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (BOOLEAN) (SigningTime->Second <= RevocationTime->Second);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check if the given time value is zero.
|
||||||
|
|
||||||
|
@param[in] Time Pointer of a time value.
|
||||||
|
|
||||||
|
@retval TRUE The Time is Zero.
|
||||||
|
@retval FALSE The Time is not Zero.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsTimeZero (
|
||||||
|
IN EFI_TIME *Time
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ((Time->Year == 0) && (Time->Month == 0) && (Time->Day == 0) &&
|
||||||
|
(Time->Hour == 0) && (Time->Minute == 0) && (Time->Second == 0)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the timestamp signature is valid and the signing time is also earlier than
|
||||||
|
the revocation time.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode signature retrieved from signed image.
|
||||||
|
@param[in] AuthDataSize Size of the Authenticode signature in bytes.
|
||||||
|
@param[in] RevocationTime The time that the certificate was revoked.
|
||||||
|
|
||||||
|
@retval TRUE Timestamp signature is valid and signing time is no later than the
|
||||||
|
revocation time.
|
||||||
|
@retval FALSE Timestamp signature is not valid or the signing time is later than the
|
||||||
|
revocation time.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
PassTimestampCheck (
|
||||||
IN UINT8 *AuthData,
|
IN UINT8 *AuthData,
|
||||||
IN UINTN AuthDataSize,
|
IN UINTN AuthDataSize,
|
||||||
IN CHAR16 *VariableName,
|
IN EFI_TIME *RevocationTime
|
||||||
IN EFI_GUID *VendorGuid
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
BOOLEAN VerifyStatus;
|
||||||
|
EFI_SIGNATURE_LIST *CertList;
|
||||||
|
EFI_SIGNATURE_DATA *Cert;
|
||||||
|
UINT8 *DbtData;
|
||||||
|
UINTN DbtDataSize;
|
||||||
|
UINT8 *RootCert;
|
||||||
|
UINTN RootCertSize;
|
||||||
|
UINTN Index;
|
||||||
|
UINTN CertCount;
|
||||||
|
EFI_TIME SigningTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variable Initialization
|
||||||
|
//
|
||||||
|
VerifyStatus = FALSE;
|
||||||
|
DbtData = NULL;
|
||||||
|
CertList = NULL;
|
||||||
|
Cert = NULL;
|
||||||
|
RootCert = NULL;
|
||||||
|
RootCertSize = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If RevocationTime is zero, the certificate shall be considered to always be revoked.
|
||||||
|
//
|
||||||
|
if (IsTimeZero (RevocationTime)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// RevocationTime is non-zero, the certificate should be considered to be revoked from that time and onwards.
|
||||||
|
// Using the dbt to get the trusted TSA certificates.
|
||||||
|
//
|
||||||
|
DbtDataSize = 0;
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, NULL);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
DbtData = (UINT8 *) AllocateZeroPool (DbtDataSize);
|
||||||
|
if (DbtData == NULL) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, (VOID *) DbtData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CertList = (EFI_SIGNATURE_LIST *) DbtData;
|
||||||
|
while ((DbtDataSize > 0) && (DbtDataSize >= CertList->SignatureListSize)) {
|
||||||
|
if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
|
||||||
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
||||||
|
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
|
||||||
|
for (Index = 0; Index < CertCount; Index++) {
|
||||||
|
//
|
||||||
|
// Iterate each Signature Data Node within this CertList for verify.
|
||||||
|
//
|
||||||
|
RootCert = Cert->SignatureData;
|
||||||
|
RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);
|
||||||
|
//
|
||||||
|
// Get the signing time if the timestamp signature is valid.
|
||||||
|
//
|
||||||
|
if (ImageTimestampVerify (AuthData, AuthDataSize, RootCert, RootCertSize, &SigningTime)) {
|
||||||
|
//
|
||||||
|
// The signer signature is valid only when the signing time is earlier than revocation time.
|
||||||
|
//
|
||||||
|
if (IsValidSignatureByTimestamp (&SigningTime, RevocationTime)) {
|
||||||
|
VerifyStatus = TRUE;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DbtDataSize -= CertList->SignatureListSize;
|
||||||
|
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (DbtData != NULL) {
|
||||||
|
FreePool (DbtData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return VerifyStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the image signature is forbidden by the forbidden database (dbx).
|
||||||
|
The image is forbidden to load if any certificates for signing are revoked before signing time.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode signature retrieved from the signed image.
|
||||||
|
@param[in] AuthDataSize Size of the Authenticode signature in bytes.
|
||||||
|
|
||||||
|
@retval TRUE Image is forbidden by dbx.
|
||||||
|
@retval FALSE Image is not forbidden by dbx.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsForbiddenByDbx (
|
||||||
|
IN UINT8 *AuthData,
|
||||||
|
IN UINTN AuthDataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
BOOLEAN IsForbidden;
|
||||||
|
UINT8 *Data;
|
||||||
|
UINTN DataSize;
|
||||||
|
UINTN Index;
|
||||||
|
UINT8 *CertBuffer;
|
||||||
|
UINTN BufferLength;
|
||||||
|
UINT8 *TrustedCert;
|
||||||
|
UINTN TrustedCertLength;
|
||||||
|
UINT8 CertNumber;
|
||||||
|
UINT8 *CertPtr;
|
||||||
|
UINT8 *Cert;
|
||||||
|
UINTN CertSize;
|
||||||
|
EFI_TIME RevocationTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variable Initialization
|
||||||
|
//
|
||||||
|
IsForbidden = FALSE;
|
||||||
|
Data = NULL;
|
||||||
|
Cert = NULL;
|
||||||
|
CertBuffer = NULL;
|
||||||
|
BufferLength = 0;
|
||||||
|
TrustedCert = NULL;
|
||||||
|
TrustedCertLength = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The image will not be forbidden if dbx can't be got.
|
||||||
|
//
|
||||||
|
DataSize = 0;
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
Data = (UINT8 *) AllocateZeroPool (DataSize);
|
||||||
|
if (Data == NULL) {
|
||||||
|
return IsForbidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);
|
||||||
|
}
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return IsForbidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the certificate stack from AuthData
|
||||||
|
// The output CertStack format will be:
|
||||||
|
// UINT8 CertNumber;
|
||||||
|
// UINT32 Cert1Length;
|
||||||
|
// UINT8 Cert1[];
|
||||||
|
// UINT32 Cert2Length;
|
||||||
|
// UINT8 Cert2[];
|
||||||
|
// ...
|
||||||
|
// UINT32 CertnLength;
|
||||||
|
// UINT8 Certn[];
|
||||||
|
//
|
||||||
|
Pkcs7GetSigners (AuthData, AuthDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);
|
||||||
|
if (BufferLength == 0) {
|
||||||
|
IsForbidden = TRUE;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if any certificates in AuthData is in the forbidden database.
|
||||||
|
//
|
||||||
|
CertNumber = (UINT8) (*CertBuffer);
|
||||||
|
CertPtr = CertBuffer + 1;
|
||||||
|
for (Index = 0; Index < CertNumber; Index++) {
|
||||||
|
CertSize = (UINTN) ReadUnaligned32 ((UINT32 *)CertPtr);
|
||||||
|
Cert = (UINT8 *)CertPtr + sizeof (UINT32);
|
||||||
|
if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, Cert, &gEfiCertX509Guid, CertSize)) {
|
||||||
|
//
|
||||||
|
// Raw certificate in dbx means the image signed by the certificate is forbidden.
|
||||||
|
//
|
||||||
|
IsForbidden = TRUE;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsCertHashFoundInDatabase (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime)) {
|
||||||
|
//
|
||||||
|
// Check the timestamp signature and signing time to determine if the image can be trusted.
|
||||||
|
//
|
||||||
|
IsForbidden = TRUE;
|
||||||
|
if (PassTimestampCheck (AuthData, AuthDataSize, &RevocationTime)) {
|
||||||
|
IsForbidden = FALSE;
|
||||||
|
}
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
CertPtr = CertPtr + sizeof (UINT32) + CertSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (Data != NULL) {
|
||||||
|
FreePool (Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pkcs7FreeSigners (CertBuffer);
|
||||||
|
Pkcs7FreeSigners (TrustedCert);
|
||||||
|
|
||||||
|
return IsForbidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the image signature can be verified by the trusted certificates in DB database.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode signature retrieved from signed image.
|
||||||
|
@param[in] AuthDataSize Size of the Authenticode signature in bytes.
|
||||||
|
|
||||||
|
@retval TRUE Image passed verification using certificate in db.
|
||||||
|
@retval FALSE Image didn't pass verification using certificate in db.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsAllowedByDb (
|
||||||
|
IN UINT8 *AuthData,
|
||||||
|
IN UINTN AuthDataSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@ -929,14 +1335,14 @@ IsPkcsSignedDataVerifiedBySignatureList (
|
|||||||
VerifyStatus = FALSE;
|
VerifyStatus = FALSE;
|
||||||
|
|
||||||
DataSize = 0;
|
DataSize = 0;
|
||||||
Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
|
||||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
Data = (UINT8 *) AllocateZeroPool (DataSize);
|
Data = (UINT8 *) AllocateZeroPool (DataSize);
|
||||||
if (Data == NULL) {
|
if (Data == NULL) {
|
||||||
return VerifyStatus;
|
return VerifyStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, (VOID *) Data);
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
@ -949,6 +1355,7 @@ IsPkcsSignedDataVerifiedBySignatureList (
|
|||||||
if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
|
if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
|
||||||
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
||||||
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
|
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
|
||||||
|
|
||||||
for (Index = 0; Index < CertCount; Index++) {
|
for (Index = 0; Index < CertCount; Index++) {
|
||||||
//
|
//
|
||||||
// Iterate each Signature Data Node within this CertList for verify.
|
// Iterate each Signature Data Node within this CertList for verify.
|
||||||
@ -968,12 +1375,14 @@ IsPkcsSignedDataVerifiedBySignatureList (
|
|||||||
mImageDigestSize
|
mImageDigestSize
|
||||||
);
|
);
|
||||||
if (VerifyStatus) {
|
if (VerifyStatus) {
|
||||||
SecureBootHook (VariableName, VendorGuid, CertList->SignatureSize, Cert);
|
SecureBootHook (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, Cert);
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSize -= CertList->SignatureListSize;
|
DataSize -= CertList->SignatureListSize;
|
||||||
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
|
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
|
||||||
}
|
}
|
||||||
@ -1302,7 +1711,7 @@ DxeImageVerificationHandler (
|
|||||||
//
|
//
|
||||||
// Check the digital signature against the revoked certificate in forbidden database (dbx).
|
// Check the digital signature against the revoked certificate in forbidden database (dbx).
|
||||||
//
|
//
|
||||||
if (IsPkcsSignedDataVerifiedBySignatureList (AuthData, AuthDataSize, EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid)) {
|
if (IsForbiddenByDbx (AuthData, AuthDataSize)) {
|
||||||
Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;
|
Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;
|
||||||
VerifyStatus = EFI_ACCESS_DENIED;
|
VerifyStatus = EFI_ACCESS_DENIED;
|
||||||
break;
|
break;
|
||||||
@ -1312,7 +1721,7 @@ DxeImageVerificationHandler (
|
|||||||
// Check the digital signature against the valid certificate in allowed database (db).
|
// Check the digital signature against the valid certificate in allowed database (db).
|
||||||
//
|
//
|
||||||
if (EFI_ERROR (VerifyStatus)) {
|
if (EFI_ERROR (VerifyStatus)) {
|
||||||
if (IsPkcsSignedDataVerifiedBySignatureList (AuthData, AuthDataSize, EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid)) {
|
if (IsAllowedByDb (AuthData, AuthDataSize)) {
|
||||||
VerifyStatus = EFI_SUCCESS;
|
VerifyStatus = EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
The internal header file includes the common header files, defines
|
The internal header file includes the common header files, defines
|
||||||
internal structure and functions used by ImageVerificationLib.
|
internal structure and functions used by ImageVerificationLib.
|
||||||
|
|
||||||
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -76,9 +76,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#define HASHALG_MAX 0x00000005
|
#define HASHALG_MAX 0x00000005
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set max digest size as SHA256 Output (32 bytes) by far
|
// Set max digest size as SHA512 Output (64 bytes) by far
|
||||||
//
|
//
|
||||||
#define MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
|
#define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// PKCS7 Certificate definition
|
// PKCS7 Certificate definition
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
[Guids]
|
[Guids]
|
||||||
## SOMETIMES_CONSUMES ## Variable:L"DB"
|
## SOMETIMES_CONSUMES ## Variable:L"DB"
|
||||||
## SOMETIMES_CONSUMES ## Variable:L"DBX"
|
## SOMETIMES_CONSUMES ## Variable:L"DBX"
|
||||||
|
## SOMETIMES_CONSUMES ## Variable:L"DBT"
|
||||||
## PRODUCES ## SystemTable
|
## PRODUCES ## SystemTable
|
||||||
## CONSUMES ## SystemTable
|
## CONSUMES ## SystemTable
|
||||||
gEfiImageSecurityDatabaseGuid
|
gEfiImageSecurityDatabaseGuid
|
||||||
@ -79,11 +80,21 @@
|
|||||||
## 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
|
||||||
|
|
||||||
gEfiCertX509Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
gEfiCertX509Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||||
|
gEfiCertX509Sha256Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||||
|
gEfiCertX509Sha384Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||||
|
gEfiCertX509Sha512Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature.
|
||||||
gEfiCertPkcs7Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the certificate.
|
gEfiCertPkcs7Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the certificate.
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy ## SOMETIMES_CONSUMES
|
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy ## SOMETIMES_CONSUMES
|
||||||
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy ## SOMETIMES_CONSUMES
|
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy ## SOMETIMES_CONSUMES
|
||||||
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy ## SOMETIMES_CONSUMES
|
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy ## SOMETIMES_CONSUMES
|
||||||
|
|
@ -77,7 +77,10 @@ EFI_SIGNATURE_ITEM mSupportSigItem[] = {
|
|||||||
{EFI_CERT_X509_GUID, 0, ((UINT32) ~0)},
|
{EFI_CERT_X509_GUID, 0, ((UINT32) ~0)},
|
||||||
{EFI_CERT_SHA224_GUID, 0, 28 },
|
{EFI_CERT_SHA224_GUID, 0, 28 },
|
||||||
{EFI_CERT_SHA384_GUID, 0, 48 },
|
{EFI_CERT_SHA384_GUID, 0, 48 },
|
||||||
{EFI_CERT_SHA512_GUID, 0, 64 }
|
{EFI_CERT_SHA512_GUID, 0, 64 },
|
||||||
|
{EFI_CERT_X509_SHA256_GUID, 0, 48 },
|
||||||
|
{EFI_CERT_X509_SHA384_GUID, 0, 64 },
|
||||||
|
{EFI_CERT_X509_SHA512_GUID, 0, 80 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -885,7 +888,7 @@ UpdatePlatformMode (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK/db/dbx variable.
|
Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK/db/dbx/dbt variable.
|
||||||
|
|
||||||
@param[in] VariableName Name of Variable to be check.
|
@param[in] VariableName Name of Variable to be check.
|
||||||
@param[in] VendorGuid Variable vendor GUID.
|
@param[in] VendorGuid Variable vendor GUID.
|
||||||
@ -921,9 +924,10 @@ CheckSignatureListFormat(
|
|||||||
|
|
||||||
if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)){
|
if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)){
|
||||||
IsPk = TRUE;
|
IsPk = TRUE;
|
||||||
} else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0) ||
|
} else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) ||
|
||||||
(CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
|
(CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
|
||||||
(StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0 || StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))){
|
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||
|
||||||
|
(StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0)))) {
|
||||||
IsPk = FALSE;
|
IsPk = FALSE;
|
||||||
} else {
|
} else {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
@ -1096,7 +1100,7 @@ ProcessVarWithPk (
|
|||||||
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||
|
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||
|
||||||
(Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {
|
(Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {
|
||||||
//
|
//
|
||||||
// PK, KEK and db/dbx should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
|
// PK, KEK and db/dbx/dbt should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
|
||||||
// authenticated variable.
|
// authenticated variable.
|
||||||
//
|
//
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@ -1221,7 +1225,7 @@ ProcessVarWithKek (
|
|||||||
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||
|
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||
|
||||||
(Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {
|
(Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {
|
||||||
//
|
//
|
||||||
// DB and DBX should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
|
// DB, DBX and DBT should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
|
||||||
// authenticated variable.
|
// authenticated variable.
|
||||||
//
|
//
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@ -2349,7 +2353,7 @@ VerifyTimeBasedPayload (
|
|||||||
} else if (AuthVarType == AuthVarTypePriv) {
|
} else if (AuthVarType == AuthVarTypePriv) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Process common authenticated variable except PK/KEK/DB/DBX.
|
// Process common authenticated variable except PK/KEK/DB/DBX/DBT.
|
||||||
// Get signer's certificates from SignedData.
|
// Get signer's certificates from SignedData.
|
||||||
//
|
//
|
||||||
VerifyStatus = Pkcs7GetSigners (
|
VerifyStatus = Pkcs7GetSigners (
|
||||||
@ -2469,4 +2473,3 @@ Exit:
|
|||||||
&CertData->TimeStamp
|
&CertData->TimeStamp
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2108,7 +2108,8 @@ UpdateVariable (
|
|||||||
MaxDataSize = PcdGet32 (PcdMaxVariableSize) - DataOffset;
|
MaxDataSize = PcdGet32 (PcdMaxVariableSize) - DataOffset;
|
||||||
|
|
||||||
if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
|
if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
|
||||||
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) ||
|
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||
|
||||||
|
(StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||
|
||||||
(CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {
|
(CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {
|
||||||
//
|
//
|
||||||
// For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of
|
// For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of
|
||||||
@ -3185,7 +3186,8 @@ VariableServiceSetVariable (
|
|||||||
} else if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) {
|
} else if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) {
|
||||||
Status = ProcessVarWithPk (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes, FALSE);
|
Status = ProcessVarWithPk (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes, FALSE);
|
||||||
} else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
|
} else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
|
||||||
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) {
|
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))
|
||||||
|
|| (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2)) == 0) {
|
||||||
Status = ProcessVarWithPk (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes, FALSE);
|
Status = ProcessVarWithPk (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = ProcessVarWithKek (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes);
|
Status = ProcessVarWithKek (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes);
|
||||||
@ -3937,4 +3939,3 @@ GetFvbInfoByAddress (
|
|||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
VFR file used by the SecureBoot configuration component.
|
VFR file used by the SecureBoot configuration component.
|
||||||
|
|
||||||
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -136,6 +136,14 @@ formset
|
|||||||
flags = INTERACTIVE,
|
flags = INTERACTIVE,
|
||||||
key = KEY_SECURE_BOOT_DBX_OPTION;
|
key = KEY_SECURE_BOOT_DBX_OPTION;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
goto FORMID_SECURE_BOOT_DBT_OPTION_FORM,
|
||||||
|
prompt = STRING_TOKEN(STR_SECURE_BOOT_DBT_OPTION),
|
||||||
|
help = STRING_TOKEN(STR_SECURE_BOOT_DBT_OPTION_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_SECURE_BOOT_DBT_OPTION;
|
||||||
|
|
||||||
endform;
|
endform;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -326,6 +334,29 @@ formset
|
|||||||
|
|
||||||
endform;
|
endform;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ##9 Form: 'DBT Options'
|
||||||
|
//
|
||||||
|
form formid = FORMID_SECURE_BOOT_DBT_OPTION_FORM,
|
||||||
|
title = STRING_TOKEN(STR_SECURE_BOOT_DBT_OPTION);
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
goto SECUREBOOT_ENROLL_SIGNATURE_TO_DBT,
|
||||||
|
prompt = STRING_TOKEN (STR_SECURE_BOOT_ENROLL_SIGNATURE),
|
||||||
|
help = STRING_TOKEN (STR_SECURE_BOOT_ENROLL_SIGNATURE),
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
goto SECUREBOOT_DELETE_SIGNATURE_FROM_DBT,
|
||||||
|
prompt = STRING_TOKEN (STR_SECURE_BOOT_DELETE_SIGNATURE),
|
||||||
|
help = STRING_TOKEN (STR_SECURE_BOOT_DELETE_SIGNATURE),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = SECUREBOOT_DELETE_SIGNATURE_FROM_DBT;
|
||||||
|
|
||||||
|
endform;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Form: 'Delete Signature' for DB Options.
|
// Form: 'Delete Signature' for DB Options.
|
||||||
//
|
//
|
||||||
@ -350,6 +381,18 @@ formset
|
|||||||
|
|
||||||
endform;
|
endform;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Form: 'Delete Signature' for DBT Options.
|
||||||
|
//
|
||||||
|
form formid = SECUREBOOT_DELETE_SIGNATURE_FROM_DBT,
|
||||||
|
title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_SIGNATURE);
|
||||||
|
|
||||||
|
label LABEL_DBT_DELETE;
|
||||||
|
label LABEL_END;
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
endform;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Form: 'Enroll Signature' for DB options.
|
// Form: 'Enroll Signature' for DB options.
|
||||||
//
|
//
|
||||||
@ -409,7 +452,6 @@ formset
|
|||||||
flags = INTERACTIVE,
|
flags = INTERACTIVE,
|
||||||
key = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
key = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
||||||
|
|
||||||
subtitle text = STRING_TOKEN(STR_NULL);
|
|
||||||
label SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
label SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
||||||
label LABEL_END;
|
label LABEL_END;
|
||||||
subtitle text = STRING_TOKEN(STR_NULL);
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
@ -423,6 +465,38 @@ formset
|
|||||||
maxsize = SECURE_BOOT_GUID_SIZE,
|
maxsize = SECURE_BOOT_GUID_SIZE,
|
||||||
endstring;
|
endstring;
|
||||||
|
|
||||||
|
oneof name = SignatureFormatInDbx,
|
||||||
|
varid = SECUREBOOT_CONFIGURATION.CertificateFormat,
|
||||||
|
prompt = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_PROMPT),
|
||||||
|
help = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_HELP),
|
||||||
|
option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA256), value = 0x2, flags = DEFAULT;
|
||||||
|
option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA384), value = 0x3, flags = 0;
|
||||||
|
option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA512), value = 0x4, flags = 0;
|
||||||
|
option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_RAW), value = 0x5, flags = 0;
|
||||||
|
endoneof;
|
||||||
|
|
||||||
|
suppressif ideqval SECUREBOOT_CONFIGURATION.CertificateFormat == 5;
|
||||||
|
checkbox varid = SECUREBOOT_CONFIGURATION.AlwaysRevocation,
|
||||||
|
prompt = STRING_TOKEN(STR_ALWAYS_CERTIFICATE_REVOCATION_PROMPT),
|
||||||
|
help = STRING_TOKEN(STR_ALWAYS_CERTIFICATE_REVOCATION_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
endcheckbox;
|
||||||
|
|
||||||
|
suppressif ideqval SECUREBOOT_CONFIGURATION.AlwaysRevocation == 1;
|
||||||
|
date varid = SECUREBOOT_CONFIGURATION.RevocationDate,
|
||||||
|
prompt = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_DATE_PROMPT),
|
||||||
|
help = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_DATE_HELP),
|
||||||
|
flags = STORAGE_NORMAL,
|
||||||
|
enddate;
|
||||||
|
|
||||||
|
time varid = SECUREBOOT_CONFIGURATION.RevocationTime,
|
||||||
|
prompt = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_TIME_PROMPT),
|
||||||
|
help = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_TIME_HELP),
|
||||||
|
flags = STORAGE_NORMAL,
|
||||||
|
endtime;
|
||||||
|
endif;
|
||||||
|
endif;
|
||||||
|
|
||||||
subtitle text = STRING_TOKEN(STR_NULL);
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
subtitle text = STRING_TOKEN(STR_NULL);
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
@ -440,6 +514,51 @@ formset
|
|||||||
|
|
||||||
endform;
|
endform;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Form: 'Enroll Signature' for DBT options.
|
||||||
|
//
|
||||||
|
form formid = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT,
|
||||||
|
title = STRING_TOKEN(STR_SECURE_BOOT_ENROLL_SIGNATURE);
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
goto FORM_FILE_EXPLORER_ID_DBT,
|
||||||
|
prompt = STRING_TOKEN(STR_SECURE_BOOT_ADD_SIGNATURE_FILE),
|
||||||
|
help = STRING_TOKEN(STR_SECURE_BOOT_ADD_SIGNATURE_FILE),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
label SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
|
||||||
|
label LABEL_END;
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
string varid = SECUREBOOT_CONFIGURATION.SignatureGuid,
|
||||||
|
prompt = STRING_TOKEN(STR_SECURE_BOOT_SIGNATURE_GUID),
|
||||||
|
help = STRING_TOKEN(STR_SECURE_BOOT_SIGNATURE_GUID_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_SECURE_BOOT_SIGNATURE_GUID_DBT,
|
||||||
|
minsize = SECURE_BOOT_GUID_SIZE,
|
||||||
|
maxsize = SECURE_BOOT_GUID_SIZE,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
goto FORMID_SECURE_BOOT_OPTION_FORM,
|
||||||
|
prompt = STRING_TOKEN(STR_SAVE_AND_EXIT),
|
||||||
|
help = STRING_TOKEN(STR_SAVE_AND_EXIT),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_VALUE_SAVE_AND_EXIT_DBT;
|
||||||
|
|
||||||
|
goto FORMID_SECURE_BOOT_OPTION_FORM,
|
||||||
|
prompt = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
|
||||||
|
help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_VALUE_NO_SAVE_AND_EXIT_DBT;
|
||||||
|
|
||||||
|
endform;
|
||||||
|
|
||||||
//
|
//
|
||||||
// File Explorer for PK
|
// File Explorer for PK
|
||||||
//
|
//
|
||||||
@ -480,6 +599,15 @@ formset
|
|||||||
label LABEL_END;
|
label LABEL_END;
|
||||||
endform;
|
endform;
|
||||||
|
|
||||||
|
//
|
||||||
|
// File Explorer for DBT
|
||||||
|
//
|
||||||
|
form formid = FORM_FILE_EXPLORER_ID_DBT,
|
||||||
|
title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE);
|
||||||
|
|
||||||
|
label FORM_FILE_EXPLORER_ID;
|
||||||
|
label LABEL_END;
|
||||||
|
endform;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enroll Pk from File Commit Form
|
// Enroll Pk from File Commit Form
|
||||||
@ -495,12 +623,14 @@ formset
|
|||||||
text
|
text
|
||||||
help = STRING_TOKEN(STR_SAVE_AND_EXIT),
|
help = STRING_TOKEN(STR_SAVE_AND_EXIT),
|
||||||
text = STRING_TOKEN(STR_SAVE_AND_EXIT),
|
text = STRING_TOKEN(STR_SAVE_AND_EXIT),
|
||||||
|
text = STRING_TOKEN(STR_NULL),
|
||||||
flags = INTERACTIVE,
|
flags = INTERACTIVE,
|
||||||
key = KEY_VALUE_SAVE_AND_EXIT_PK;
|
key = KEY_VALUE_SAVE_AND_EXIT_PK;
|
||||||
|
|
||||||
text
|
text
|
||||||
help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
|
help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
|
||||||
text = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
|
text = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
|
||||||
|
text = STRING_TOKEN(STR_NULL),
|
||||||
flags = INTERACTIVE,
|
flags = INTERACTIVE,
|
||||||
key = KEY_VALUE_NO_SAVE_AND_EXIT_PK;
|
key = KEY_VALUE_NO_SAVE_AND_EXIT_PK;
|
||||||
|
|
||||||
|
@ -105,6 +105,10 @@
|
|||||||
gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type
|
gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type
|
||||||
gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type
|
gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type
|
||||||
|
|
||||||
|
gEfiCertX509Sha256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the certificate.
|
||||||
|
gEfiCertX509Sha384Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the certificate.
|
||||||
|
gEfiCertX509Sha512Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the certificate.
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
|
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
|
||||||
gEfiDevicePathProtocolGuid ## PRODUCES
|
gEfiDevicePathProtocolGuid ## PRODUCES
|
||||||
@ -119,4 +123,3 @@
|
|||||||
|
|
||||||
[UserExtensions.TianoCore."ExtraFiles"]
|
[UserExtensions.TianoCore."ExtraFiles"]
|
||||||
SecureBootConfigDxeExtra.uni
|
SecureBootConfigDxeExtra.uni
|
||||||
|
|
@ -1032,6 +1032,9 @@ UpdateFileExplorePage (
|
|||||||
} else if (FeCurrentState == FileExplorerStateEnrollSignatureFileToDbx) {
|
} else if (FeCurrentState == FileExplorerStateEnrollSignatureFileToDbx) {
|
||||||
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
||||||
FileFormId = FORM_FILE_EXPLORER_ID_DBX;
|
FileFormId = FORM_FILE_EXPLORER_ID_DBX;
|
||||||
|
} else if (FeCurrentState == FileExplorerStateEnrollSignatureFileToDbt) {
|
||||||
|
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
|
||||||
|
FileFormId = FORM_FILE_EXPLORER_ID_DBT;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1156,6 +1159,8 @@ UpdateFileExplorer (
|
|||||||
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
|
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
|
||||||
} else if (PrivateData->FeCurrentState == FileExplorerStateEnrollSignatureFileToDbx) {
|
} else if (PrivateData->FeCurrentState == FileExplorerStateEnrollSignatureFileToDbx) {
|
||||||
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
||||||
|
} else if (PrivateData->FeCurrentState == FileExplorerStateEnrollSignatureFileToDbt) {
|
||||||
|
FormId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
|
||||||
} else {
|
} else {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -1226,4 +1231,3 @@ CleanUpPage (
|
|||||||
mEndOpCodeHandle // LABEL_END
|
mEndOpCodeHandle // LABEL_END
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ HASH_TABLE mHash[] = {
|
|||||||
{ L"SHA1", 20, &mHashOidValue[8], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },
|
{ L"SHA1", 20, &mHashOidValue[8], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },
|
||||||
{ L"SHA224", 28, &mHashOidValue[13], 9, NULL, NULL, NULL, NULL },
|
{ L"SHA224", 28, &mHashOidValue[13], 9, NULL, NULL, NULL, NULL },
|
||||||
{ L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},
|
{ L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},
|
||||||
{ L"SHA384", 48, &mHashOidValue[31], 9, NULL, NULL, NULL, NULL },
|
{ L"SHA384", 48, &mHashOidValue[31], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final},
|
||||||
{ L"SHA512", 64, &mHashOidValue[40], 9, NULL, NULL, NULL, NULL }
|
{ L"SHA512", 64, &mHashOidValue[40], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -840,7 +840,7 @@ EnrollKeyExchangeKey (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enroll a new X509 certificate into Signature Database (DB or DBX) without
|
Enroll a new X509 certificate into Signature Database (DB or DBX or DBT) without
|
||||||
KEK's authentication.
|
KEK's authentication.
|
||||||
|
|
||||||
@param[in] PrivateData The module's private data.
|
@param[in] PrivateData The module's private data.
|
||||||
@ -966,6 +966,622 @@ ON_EXIT:
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether signature is in specified database.
|
||||||
|
|
||||||
|
@param[in] VariableName Name of database variable that is searched in.
|
||||||
|
@param[in] Signature Pointer to signature that is searched for.
|
||||||
|
@param[in] SignatureSize Size of Signature.
|
||||||
|
|
||||||
|
@return TRUE Found the signature in the variable database.
|
||||||
|
@return FALSE Not found the signature in the variable database.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsSignatureFoundInDatabase (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN UINT8 *Signature,
|
||||||
|
IN UINTN SignatureSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_SIGNATURE_LIST *CertList;
|
||||||
|
EFI_SIGNATURE_DATA *Cert;
|
||||||
|
UINTN DataSize;
|
||||||
|
UINT8 *Data;
|
||||||
|
UINTN Index;
|
||||||
|
UINTN CertCount;
|
||||||
|
BOOLEAN IsFound;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read signature database variable.
|
||||||
|
//
|
||||||
|
IsFound = FALSE;
|
||||||
|
Data = NULL;
|
||||||
|
DataSize = 0;
|
||||||
|
Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
|
||||||
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data = (UINT8 *) AllocateZeroPool (DataSize);
|
||||||
|
if (Data == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enumerate all signature data in SigDB to check if executable's signature exists.
|
||||||
|
//
|
||||||
|
CertList = (EFI_SIGNATURE_LIST *) Data;
|
||||||
|
while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {
|
||||||
|
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
|
||||||
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
||||||
|
if ((CertList->SignatureSize == sizeof(EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid(&CertList->SignatureType, &gEfiCertX509Guid))) {
|
||||||
|
for (Index = 0; Index < CertCount; Index++) {
|
||||||
|
if (CompareMem (Cert->SignatureData, Signature, SignatureSize) == 0) {
|
||||||
|
//
|
||||||
|
// Find the signature in database.
|
||||||
|
//
|
||||||
|
IsFound = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsFound) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSize -= CertList->SignatureListSize;
|
||||||
|
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (Data != NULL) {
|
||||||
|
FreePool (Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate the hash of a certificate data with the specified hash algorithm.
|
||||||
|
|
||||||
|
@param[in] CertData The certificate data to be hashed.
|
||||||
|
@param[in] CertSize The certificate size in bytes.
|
||||||
|
@param[in] HashAlg The specified hash algorithm.
|
||||||
|
@param[out] CertHash The output digest of the certificate
|
||||||
|
|
||||||
|
@retval TRUE Successfully got the hash of the CertData.
|
||||||
|
@retval FALSE Failed to get the hash of CertData.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
CalculateCertHash (
|
||||||
|
IN UINT8 *CertData,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN UINT32 HashAlg,
|
||||||
|
OUT UINT8 *CertHash
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
VOID *HashCtx;
|
||||||
|
UINTN CtxSize;
|
||||||
|
|
||||||
|
HashCtx = NULL;
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
if (HashAlg >= HASHALG_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Initialize context of hash.
|
||||||
|
//
|
||||||
|
CtxSize = mHash[HashAlg].GetContextSize ();
|
||||||
|
HashCtx = AllocatePool (CtxSize);
|
||||||
|
ASSERT (HashCtx != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2. Initialize a hash context.
|
||||||
|
//
|
||||||
|
Status = mHash[HashAlg].HashInit (HashCtx);
|
||||||
|
if (!Status) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 3. Calculate the hash.
|
||||||
|
//
|
||||||
|
Status = mHash[HashAlg].HashUpdate (HashCtx, CertData, CertSize);
|
||||||
|
if (!Status) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 4. Get the hash result.
|
||||||
|
//
|
||||||
|
ZeroMem (CertHash, mHash[HashAlg].DigestLength);
|
||||||
|
Status = mHash[HashAlg].HashFinal (HashCtx, CertHash);
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (HashCtx != NULL) {
|
||||||
|
FreePool (HashCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the hash of an X.509 certificate is in forbidden database (DBX).
|
||||||
|
|
||||||
|
@param[in] Certificate Pointer to X.509 Certificate that is searched for.
|
||||||
|
@param[in] CertSize Size of X.509 Certificate.
|
||||||
|
|
||||||
|
@return TRUE Found the certificate hash in the forbidden database.
|
||||||
|
@return FALSE Certificate hash is Not found in the forbidden database.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsCertHashFoundInDbx (
|
||||||
|
IN UINT8 *Certificate,
|
||||||
|
IN UINTN CertSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN IsFound;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_SIGNATURE_LIST *DbxList;
|
||||||
|
EFI_SIGNATURE_DATA *CertHash;
|
||||||
|
UINTN CertHashCount;
|
||||||
|
UINTN Index;
|
||||||
|
UINT32 HashAlg;
|
||||||
|
UINT8 CertDigest[MAX_DIGEST_SIZE];
|
||||||
|
UINT8 *DbxCertHash;
|
||||||
|
UINTN SiglistHeaderSize;
|
||||||
|
UINT8 *Data;
|
||||||
|
UINTN DataSize;
|
||||||
|
|
||||||
|
IsFound = FALSE;
|
||||||
|
HashAlg = HASHALG_MAX;
|
||||||
|
Data = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read signature database variable.
|
||||||
|
//
|
||||||
|
DataSize = 0;
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
|
||||||
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data = (UINT8 *) AllocateZeroPool (DataSize);
|
||||||
|
if (Data == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether the certificate hash exists in the forbidden database.
|
||||||
|
//
|
||||||
|
DbxList = (EFI_SIGNATURE_LIST *) Data;
|
||||||
|
while ((DataSize > 0) && (DataSize >= DbxList->SignatureListSize)) {
|
||||||
|
//
|
||||||
|
// Determine Hash Algorithm of Certificate in the forbidden database.
|
||||||
|
//
|
||||||
|
if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha256Guid)) {
|
||||||
|
HashAlg = HASHALG_SHA256;
|
||||||
|
} else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha384Guid)) {
|
||||||
|
HashAlg = HASHALG_SHA384;
|
||||||
|
} else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha512Guid)) {
|
||||||
|
HashAlg = HASHALG_SHA512;
|
||||||
|
} else {
|
||||||
|
DataSize -= DbxList->SignatureListSize;
|
||||||
|
DbxList = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the hash value of current db certificate for comparision.
|
||||||
|
//
|
||||||
|
if (!CalculateCertHash (Certificate, CertSize, HashAlg, CertDigest)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;
|
||||||
|
CertHash = (EFI_SIGNATURE_DATA *) ((UINT8 *) DbxList + SiglistHeaderSize);
|
||||||
|
CertHashCount = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;
|
||||||
|
for (Index = 0; Index < CertHashCount; Index++) {
|
||||||
|
//
|
||||||
|
// Iterate each Signature Data Node within this CertList for verify.
|
||||||
|
//
|
||||||
|
DbxCertHash = CertHash->SignatureData;
|
||||||
|
if (CompareMem (DbxCertHash, CertDigest, mHash[HashAlg].DigestLength) == 0) {
|
||||||
|
//
|
||||||
|
// Hash of Certificate is found in forbidden database.
|
||||||
|
//
|
||||||
|
IsFound = TRUE;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
CertHash = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertHash + DbxList->SignatureSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSize -= DbxList->SignatureListSize;
|
||||||
|
DbxList = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (Data != NULL) {
|
||||||
|
FreePool (Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether the signature list exists in given variable data.
|
||||||
|
|
||||||
|
It searches the signature list for the ceritificate hash by CertType.
|
||||||
|
If the signature list is found, get the offset of Database for the
|
||||||
|
next hash of a certificate.
|
||||||
|
|
||||||
|
@param[in] Database Variable data to save signature list.
|
||||||
|
@param[in] DatabaseSize Variable size.
|
||||||
|
@param[in] SignatureType The type of the signature.
|
||||||
|
@param[out] Offset The offset to save a new hash of certificate.
|
||||||
|
|
||||||
|
@return TRUE The signature list is found in the forbidden database.
|
||||||
|
@return FALSE The signature list is not found in the forbidden database.
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
GetSignaturelistOffset (
|
||||||
|
IN EFI_SIGNATURE_LIST *Database,
|
||||||
|
IN UINTN DatabaseSize,
|
||||||
|
IN EFI_GUID *SignatureType,
|
||||||
|
OUT UINTN *Offset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_SIGNATURE_LIST *SigList;
|
||||||
|
UINTN SiglistSize;
|
||||||
|
|
||||||
|
if ((Database == NULL) || (DatabaseSize == 0)) {
|
||||||
|
*Offset = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SigList = Database;
|
||||||
|
SiglistSize = DatabaseSize;
|
||||||
|
while ((SiglistSize > 0) && (SiglistSize >= SigList->SignatureListSize)) {
|
||||||
|
if (CompareGuid (&SigList->SignatureType, SignatureType)) {
|
||||||
|
*Offset = DatabaseSize - SiglistSize;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
SiglistSize -= SigList->SignatureListSize;
|
||||||
|
SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);
|
||||||
|
}
|
||||||
|
*Offset = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enroll a new X509 certificate hash into Signature Database (dbx) without
|
||||||
|
KEK's authentication.
|
||||||
|
|
||||||
|
@param[in] PrivateData The module's private data.
|
||||||
|
@param[in] HashAlg The hash algorithm to enroll the certificate.
|
||||||
|
@param[in] RevocationDate The revocation date of the certificate.
|
||||||
|
@param[in] RevocationTime The revocation time of the certificate.
|
||||||
|
@param[in] AlwaysRevocation Indicate whether the certificate is always revoked.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS New X509 is enrolled successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EnrollX509HashtoSigDB (
|
||||||
|
IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private,
|
||||||
|
IN UINT32 HashAlg,
|
||||||
|
IN EFI_HII_DATE *RevocationDate,
|
||||||
|
IN EFI_HII_TIME *RevocationTime,
|
||||||
|
IN BOOLEAN AlwaysRevocation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN X509DataSize;
|
||||||
|
VOID *X509Data;
|
||||||
|
EFI_SIGNATURE_LIST *SignatureList;
|
||||||
|
UINTN SignatureListSize;
|
||||||
|
UINT8 *Data;
|
||||||
|
UINT8 *NewData;
|
||||||
|
UINTN DataSize;
|
||||||
|
UINTN DbSize;
|
||||||
|
UINT32 Attr;
|
||||||
|
EFI_SIGNATURE_DATA *SignatureData;
|
||||||
|
UINTN SignatureSize;
|
||||||
|
EFI_GUID SignatureType;
|
||||||
|
UINTN Offset;
|
||||||
|
UINT8 CertHash[MAX_DIGEST_SIZE];
|
||||||
|
UINT16* FilePostFix;
|
||||||
|
UINTN NameLength;
|
||||||
|
EFI_TIME *Time;
|
||||||
|
|
||||||
|
X509DataSize = 0;
|
||||||
|
DbSize = 0;
|
||||||
|
X509Data = NULL;
|
||||||
|
SignatureData = NULL;
|
||||||
|
SignatureList = NULL;
|
||||||
|
Data = NULL;
|
||||||
|
NewData = NULL;
|
||||||
|
|
||||||
|
if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->SignatureGUID == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parse the file's postfix.
|
||||||
|
//
|
||||||
|
NameLength = StrLen (Private->FileContext->FileName);
|
||||||
|
if (NameLength <= 4) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
FilePostFix = Private->FileContext->FileName + NameLength - 4;
|
||||||
|
if (!IsDerEncodeCertificate(FilePostFix)) {
|
||||||
|
//
|
||||||
|
// Only supports DER-encoded X509 certificate.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the certificate from file and calculate its hash.
|
||||||
|
//
|
||||||
|
Status = ReadFileContent (
|
||||||
|
Private->FileContext->FHandle,
|
||||||
|
&X509Data,
|
||||||
|
&X509DataSize,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
ASSERT (X509Data != NULL);
|
||||||
|
|
||||||
|
if (!CalculateCertHash (X509Data, X509DataSize, HashAlg, CertHash)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the variable for enrollment.
|
||||||
|
//
|
||||||
|
DataSize = 0;
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
Data = (UINT8 *) AllocateZeroPool (DataSize);
|
||||||
|
if (Data == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate memory for Signature and fill the Signature
|
||||||
|
//
|
||||||
|
SignatureSize = sizeof(EFI_SIGNATURE_DATA) - 1 + sizeof (EFI_TIME) + mHash[HashAlg].DigestLength;
|
||||||
|
SignatureData = (EFI_SIGNATURE_DATA *) AllocateZeroPool (SignatureSize);
|
||||||
|
if (SignatureData == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
CopyGuid (&SignatureData->SignatureOwner, Private->SignatureGUID);
|
||||||
|
CopyMem (SignatureData->SignatureData, CertHash, mHash[HashAlg].DigestLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the time.
|
||||||
|
//
|
||||||
|
if (!AlwaysRevocation) {
|
||||||
|
Time = (EFI_TIME *)(&SignatureData->SignatureData + mHash[HashAlg].DigestLength);
|
||||||
|
Time->Year = RevocationDate->Year;
|
||||||
|
Time->Month = RevocationDate->Month;
|
||||||
|
Time->Day = RevocationDate->Day;
|
||||||
|
Time->Hour = RevocationTime->Hour;
|
||||||
|
Time->Minute = RevocationTime->Minute;
|
||||||
|
Time->Second = RevocationTime->Second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine the GUID for certificate hash.
|
||||||
|
//
|
||||||
|
switch (HashAlg) {
|
||||||
|
case HASHALG_SHA256:
|
||||||
|
SignatureType = gEfiCertX509Sha256Guid;
|
||||||
|
break;
|
||||||
|
case HASHALG_SHA384:
|
||||||
|
SignatureType = gEfiCertX509Sha384Guid;
|
||||||
|
break;
|
||||||
|
case HASHALG_SHA512:
|
||||||
|
SignatureType = gEfiCertX509Sha512Guid;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add signature into the new variable data buffer
|
||||||
|
//
|
||||||
|
if (GetSignaturelistOffset((EFI_SIGNATURE_LIST *)Data, DataSize, &SignatureType, &Offset)) {
|
||||||
|
//
|
||||||
|
// Add the signature to the found signaturelist.
|
||||||
|
//
|
||||||
|
DbSize = DataSize + SignatureSize;
|
||||||
|
NewData = AllocateZeroPool (DbSize);
|
||||||
|
if (NewData == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignatureList = (EFI_SIGNATURE_LIST *)(Data + Offset);
|
||||||
|
SignatureListSize = (UINTN) ReadUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize);
|
||||||
|
CopyMem (NewData, Data, Offset + SignatureListSize);
|
||||||
|
|
||||||
|
SignatureList = (EFI_SIGNATURE_LIST *)(NewData + Offset);
|
||||||
|
WriteUnaligned32 ((UINT32 *) &SignatureList->SignatureListSize, (UINT32)(SignatureListSize + SignatureSize));
|
||||||
|
|
||||||
|
Offset += SignatureListSize;
|
||||||
|
CopyMem (NewData + Offset, SignatureData, SignatureSize);
|
||||||
|
CopyMem (NewData + Offset + SignatureSize, Data + Offset, DataSize - Offset);
|
||||||
|
|
||||||
|
FreePool (Data);
|
||||||
|
Data = NewData;
|
||||||
|
DataSize = DbSize;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Create a new signaturelist, and add the signature into the signaturelist.
|
||||||
|
//
|
||||||
|
DbSize = DataSize + sizeof(EFI_SIGNATURE_LIST) + SignatureSize;
|
||||||
|
NewData = AllocateZeroPool (DbSize);
|
||||||
|
if (NewData == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Fill Certificate Database parameters.
|
||||||
|
//
|
||||||
|
SignatureList = (EFI_SIGNATURE_LIST*) (NewData + DataSize);
|
||||||
|
SignatureListSize = sizeof(EFI_SIGNATURE_LIST) + SignatureSize;
|
||||||
|
WriteUnaligned32 ((UINT32 *) &SignatureList->SignatureListSize, (UINT32) SignatureListSize);
|
||||||
|
WriteUnaligned32 ((UINT32 *) &SignatureList->SignatureSize, (UINT32) SignatureSize);
|
||||||
|
CopyGuid (&SignatureList->SignatureType, &SignatureType);
|
||||||
|
CopyMem ((UINT8* ) SignatureList + sizeof (EFI_SIGNATURE_LIST), SignatureData, SignatureSize);
|
||||||
|
if ((DataSize != 0) && (Data != NULL)) {
|
||||||
|
CopyMem (NewData, Data, DataSize);
|
||||||
|
FreePool (Data);
|
||||||
|
}
|
||||||
|
Data = NewData;
|
||||||
|
DataSize = DbSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = CreateTimeBasedPayload (&DataSize, (UINT8**) &Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
|
||||||
|
| EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
||||||
|
Status = gRT->SetVariable(
|
||||||
|
EFI_IMAGE_SECURITY_DATABASE1,
|
||||||
|
&gEfiImageSecurityDatabaseGuid,
|
||||||
|
Attr,
|
||||||
|
DataSize,
|
||||||
|
Data
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
CloseFile (Private->FileContext->FHandle);
|
||||||
|
Private->FileContext->FileName = NULL;
|
||||||
|
Private->FileContext->FHandle = NULL;
|
||||||
|
|
||||||
|
if (Private->SignatureGUID != NULL) {
|
||||||
|
FreePool (Private->SignatureGUID);
|
||||||
|
Private->SignatureGUID = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Data != NULL) {
|
||||||
|
FreePool (Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SignatureData != NULL) {
|
||||||
|
FreePool (SignatureData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (X509Data != NULL) {
|
||||||
|
FreePool (X509Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check whether a certificate from a file exists in dbx.
|
||||||
|
|
||||||
|
@param[in] PrivateData The module's private data.
|
||||||
|
@param[in] VariableName Variable name of signature database, must be
|
||||||
|
EFI_IMAGE_SECURITY_DATABASE1.
|
||||||
|
|
||||||
|
@retval TRUE The X509 certificate is found in dbx successfully.
|
||||||
|
@retval FALSE The X509 certificate is not found in dbx.
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsX509CertInDbx (
|
||||||
|
IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private,
|
||||||
|
IN CHAR16 *VariableName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN X509DataSize;
|
||||||
|
VOID *X509Data;
|
||||||
|
BOOLEAN IsFound;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the certificate from file
|
||||||
|
//
|
||||||
|
X509DataSize = 0;
|
||||||
|
X509Data = NULL;
|
||||||
|
Status = ReadFileContent (
|
||||||
|
Private->FileContext->FHandle,
|
||||||
|
&X509Data,
|
||||||
|
&X509DataSize,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the raw certificate.
|
||||||
|
//
|
||||||
|
IsFound = FALSE;
|
||||||
|
if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, X509Data, X509DataSize)) {
|
||||||
|
IsFound = TRUE;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the hash of certificate.
|
||||||
|
//
|
||||||
|
if (IsCertHashFoundInDbx (X509Data, X509DataSize)) {
|
||||||
|
IsFound = TRUE;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
if (X509Data != NULL) {
|
||||||
|
FreePool (X509Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsFound;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Load PE/COFF image information into internal buffer and check its validity.
|
Load PE/COFF image information into internal buffer and check its validity.
|
||||||
|
|
||||||
@ -1362,7 +1978,8 @@ HashPeImageByType (
|
|||||||
|
|
||||||
@param[in] PrivateData The module's private data.
|
@param[in] PrivateData The module's private data.
|
||||||
@param[in] VariableName Variable name of signature database, must be
|
@param[in] VariableName Variable name of signature database, must be
|
||||||
EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
|
EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
|
||||||
|
or EFI_IMAGE_SECURITY_DATABASE2.
|
||||||
|
|
||||||
@retval EFI_SUCCESS New signature is enrolled successfully.
|
@retval EFI_SUCCESS New signature is enrolled successfully.
|
||||||
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
@ -1388,6 +2005,10 @@ EnrollImageSignatureToSigDB (
|
|||||||
Data = NULL;
|
Data = NULL;
|
||||||
GuidCertData = NULL;
|
GuidCertData = NULL;
|
||||||
|
|
||||||
|
if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Form the SigDB certificate list.
|
// Form the SigDB certificate list.
|
||||||
// Format the data item into EFI_SIGNATURE_LIST type.
|
// Format the data item into EFI_SIGNATURE_LIST type.
|
||||||
@ -1543,7 +2164,7 @@ ON_EXIT:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enroll signature into DB/DBX without KEK's authentication.
|
Enroll signature into DB/DBX/DBT without KEK's authentication.
|
||||||
The SignatureOwner GUID will be Private->SignatureGUID.
|
The SignatureOwner GUID will be Private->SignatureGUID.
|
||||||
|
|
||||||
@param[in] PrivateData The module's private data.
|
@param[in] PrivateData The module's private data.
|
||||||
@ -1593,7 +2214,7 @@ EnrollSignatureDatabase (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
List all signatures in specified signature database (e.g. KEK/DB/DBX)
|
List all signatures in specified signature database (e.g. KEK/DB/DBX/DBT)
|
||||||
by GUID in the page for user to select and delete as needed.
|
by GUID in the page for user to select and delete as needed.
|
||||||
|
|
||||||
@param[in] PrivateData Module's private data.
|
@param[in] PrivateData Module's private data.
|
||||||
@ -1720,6 +2341,12 @@ UpdateDeletePage (
|
|||||||
Help = STRING_TOKEN (STR_CERT_TYPE_SHA1_GUID);
|
Help = STRING_TOKEN (STR_CERT_TYPE_SHA1_GUID);
|
||||||
} else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)) {
|
} else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)) {
|
||||||
Help = STRING_TOKEN (STR_CERT_TYPE_SHA256_GUID);
|
Help = STRING_TOKEN (STR_CERT_TYPE_SHA256_GUID);
|
||||||
|
} else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha256Guid)) {
|
||||||
|
Help = STRING_TOKEN (STR_CERT_TYPE_X509_SHA256_GUID);
|
||||||
|
} else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha384Guid)) {
|
||||||
|
Help = STRING_TOKEN (STR_CERT_TYPE_X509_SHA384_GUID);
|
||||||
|
} else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha512Guid)) {
|
||||||
|
Help = STRING_TOKEN (STR_CERT_TYPE_X509_SHA512_GUID);
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// The signature type is not supported in current implementation.
|
// The signature type is not supported in current implementation.
|
||||||
@ -2062,7 +2689,10 @@ DeleteSignature (
|
|||||||
if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
|
if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
|
||||||
CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
|
CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
|
||||||
CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
|
CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
|
||||||
CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)
|
CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
|
||||||
|
CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha256Guid) ||
|
||||||
|
CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha384Guid) ||
|
||||||
|
CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha512Guid)
|
||||||
) {
|
) {
|
||||||
//
|
//
|
||||||
// Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
|
// Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
|
||||||
@ -2181,11 +2811,25 @@ SecureBootExtractConfigFromVariable (
|
|||||||
UINT8 *SecureBootEnable;
|
UINT8 *SecureBootEnable;
|
||||||
UINT8 *SetupMode;
|
UINT8 *SetupMode;
|
||||||
UINT8 *SecureBootMode;
|
UINT8 *SecureBootMode;
|
||||||
|
EFI_TIME CurrTime;
|
||||||
|
|
||||||
SecureBootEnable = NULL;
|
SecureBootEnable = NULL;
|
||||||
SetupMode = NULL;
|
SetupMode = NULL;
|
||||||
SecureBootMode = NULL;
|
SecureBootMode = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initilize the Date and Time using system time.
|
||||||
|
//
|
||||||
|
ConfigData->CertificateFormat = HASHALG_RAW;
|
||||||
|
ConfigData->AlwaysRevocation = TRUE;
|
||||||
|
gRT->GetTime (&CurrTime, NULL);
|
||||||
|
ConfigData->RevocationDate.Year = CurrTime.Year;
|
||||||
|
ConfigData->RevocationDate.Month = CurrTime.Month;
|
||||||
|
ConfigData->RevocationDate.Day = CurrTime.Day;
|
||||||
|
ConfigData->RevocationTime.Hour = CurrTime.Hour;
|
||||||
|
ConfigData->RevocationTime.Minute = CurrTime.Minute;
|
||||||
|
ConfigData->RevocationTime.Second = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable
|
// If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable
|
||||||
// Checkbox.
|
// Checkbox.
|
||||||
@ -2573,6 +3217,7 @@ SecureBootCallback (
|
|||||||
case KEY_SECURE_BOOT_KEK_OPTION:
|
case KEY_SECURE_BOOT_KEK_OPTION:
|
||||||
case KEY_SECURE_BOOT_DB_OPTION:
|
case KEY_SECURE_BOOT_DB_OPTION:
|
||||||
case KEY_SECURE_BOOT_DBX_OPTION:
|
case KEY_SECURE_BOOT_DBX_OPTION:
|
||||||
|
case KEY_SECURE_BOOT_DBT_OPTION:
|
||||||
//
|
//
|
||||||
// Clear Signature GUID.
|
// Clear Signature GUID.
|
||||||
//
|
//
|
||||||
@ -2588,6 +3233,8 @@ SecureBootCallback (
|
|||||||
LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
|
LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
|
||||||
} else if (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) {
|
} else if (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) {
|
||||||
LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
|
||||||
|
} else if (QuestionId == KEY_SECURE_BOOT_DBT_OPTION) {
|
||||||
|
LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
|
||||||
} else {
|
} else {
|
||||||
LabelId = FORMID_ENROLL_KEK_FORM;
|
LabelId = FORMID_ENROLL_KEK_FORM;
|
||||||
}
|
}
|
||||||
@ -2602,14 +3249,18 @@ SecureBootCallback (
|
|||||||
case FORMID_ENROLL_KEK_FORM:
|
case FORMID_ENROLL_KEK_FORM:
|
||||||
case SECUREBOOT_ENROLL_SIGNATURE_TO_DB:
|
case SECUREBOOT_ENROLL_SIGNATURE_TO_DB:
|
||||||
case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX:
|
case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX:
|
||||||
|
case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT:
|
||||||
if (QuestionId == SECUREBOOT_ADD_PK_FILE_FORM_ID) {
|
if (QuestionId == SECUREBOOT_ADD_PK_FILE_FORM_ID) {
|
||||||
Private->FeCurrentState = FileExplorerStateEnrollPkFile;
|
Private->FeCurrentState = FileExplorerStateEnrollPkFile;
|
||||||
} else if (QuestionId == FORMID_ENROLL_KEK_FORM) {
|
} else if (QuestionId == FORMID_ENROLL_KEK_FORM) {
|
||||||
Private->FeCurrentState = FileExplorerStateEnrollKekFile;
|
Private->FeCurrentState = FileExplorerStateEnrollKekFile;
|
||||||
} else if (QuestionId == SECUREBOOT_ENROLL_SIGNATURE_TO_DB) {
|
} else if (QuestionId == SECUREBOOT_ENROLL_SIGNATURE_TO_DB) {
|
||||||
Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDb;
|
Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDb;
|
||||||
} else {
|
} else if (QuestionId == SECUREBOOT_ENROLL_SIGNATURE_TO_DBX) {
|
||||||
Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDbx;
|
Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDbx;
|
||||||
|
IfrNvData->CertificateFormat = HASHALG_SHA256;
|
||||||
|
} else {
|
||||||
|
Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Private->FeDisplayContext = FileExplorerDisplayUnknown;
|
Private->FeDisplayContext = FileExplorerDisplayUnknown;
|
||||||
@ -2674,6 +3325,18 @@ SecureBootCallback (
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SECUREBOOT_DELETE_SIGNATURE_FROM_DBT:
|
||||||
|
UpdateDeletePage (
|
||||||
|
Private,
|
||||||
|
EFI_IMAGE_SECURITY_DATABASE2,
|
||||||
|
&gEfiImageSecurityDatabaseGuid,
|
||||||
|
LABEL_DBT_DELETE,
|
||||||
|
SECUREBOOT_DELETE_SIGNATURE_FROM_DBT,
|
||||||
|
OPTION_DEL_DBT_QUESTION_ID
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case KEY_VALUE_SAVE_AND_EXIT_KEK:
|
case KEY_VALUE_SAVE_AND_EXIT_KEK:
|
||||||
Status = EnrollKeyExchangeKey (Private);
|
Status = EnrollKeyExchangeKey (Private);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
@ -2701,7 +3364,27 @@ SecureBootCallback (
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_VALUE_SAVE_AND_EXIT_DBX:
|
case KEY_VALUE_SAVE_AND_EXIT_DBX:
|
||||||
|
if (IsX509CertInDbx (Private, EFI_IMAGE_SECURITY_DATABASE1)) {
|
||||||
|
CreatePopUp (
|
||||||
|
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
||||||
|
&Key,
|
||||||
|
L"Enrollment failed! Same certificate had already been in the dbx!",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((IfrNvData != NULL) && (IfrNvData->CertificateFormat < HASHALG_MAX)) {
|
||||||
|
Status = EnrollX509HashtoSigDB (
|
||||||
|
Private,
|
||||||
|
IfrNvData->CertificateFormat,
|
||||||
|
&IfrNvData->RevocationDate,
|
||||||
|
&IfrNvData->RevocationTime,
|
||||||
|
IfrNvData->AlwaysRevocation
|
||||||
|
);
|
||||||
|
} else {
|
||||||
Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE1);
|
Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE1);
|
||||||
|
}
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
CreatePopUp (
|
CreatePopUp (
|
||||||
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
||||||
@ -2713,6 +3396,19 @@ SecureBootCallback (
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case KEY_VALUE_SAVE_AND_EXIT_DBT:
|
||||||
|
Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE2);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
CreatePopUp (
|
||||||
|
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
||||||
|
&Key,
|
||||||
|
L"ERROR: Unsupported file type!",
|
||||||
|
L"Only supports DER-encoded X509 certificate.",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {
|
if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {
|
||||||
UpdateFileExplorer (Private, QuestionId);
|
UpdateFileExplorer (Private, QuestionId);
|
||||||
@ -2741,6 +3437,17 @@ SecureBootCallback (
|
|||||||
OPTION_DEL_DBX_QUESTION_ID,
|
OPTION_DEL_DBX_QUESTION_ID,
|
||||||
QuestionId - OPTION_DEL_DBX_QUESTION_ID
|
QuestionId - OPTION_DEL_DBX_QUESTION_ID
|
||||||
);
|
);
|
||||||
|
} else if ((QuestionId >= OPTION_DEL_DBT_QUESTION_ID) &&
|
||||||
|
(QuestionId < (OPTION_DEL_DBT_QUESTION_ID + OPTION_CONFIG_RANGE))) {
|
||||||
|
DeleteSignature (
|
||||||
|
Private,
|
||||||
|
EFI_IMAGE_SECURITY_DATABASE2,
|
||||||
|
&gEfiImageSecurityDatabaseGuid,
|
||||||
|
LABEL_DBT_DELETE,
|
||||||
|
SECUREBOOT_DELETE_SIGNATURE_FROM_DBT,
|
||||||
|
OPTION_DEL_DBT_QUESTION_ID,
|
||||||
|
QuestionId - OPTION_DEL_DBT_QUESTION_ID
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2774,6 +3481,7 @@ SecureBootCallback (
|
|||||||
case KEY_VALUE_NO_SAVE_AND_EXIT_KEK:
|
case KEY_VALUE_NO_SAVE_AND_EXIT_KEK:
|
||||||
case KEY_VALUE_NO_SAVE_AND_EXIT_DB:
|
case KEY_VALUE_NO_SAVE_AND_EXIT_DB:
|
||||||
case KEY_VALUE_NO_SAVE_AND_EXIT_DBX:
|
case KEY_VALUE_NO_SAVE_AND_EXIT_DBX:
|
||||||
|
case KEY_VALUE_NO_SAVE_AND_EXIT_DBT:
|
||||||
if (Private->FileContext->FHandle != NULL) {
|
if (Private->FileContext->FHandle != NULL) {
|
||||||
CloseFile (Private->FileContext->FHandle);
|
CloseFile (Private->FileContext->FHandle);
|
||||||
Private->FileContext->FHandle = NULL;
|
Private->FileContext->FHandle = NULL;
|
||||||
@ -2794,6 +3502,7 @@ SecureBootCallback (
|
|||||||
case KEY_SECURE_BOOT_KEK_GUID:
|
case KEY_SECURE_BOOT_KEK_GUID:
|
||||||
case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:
|
case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:
|
||||||
case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:
|
case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:
|
||||||
|
case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT:
|
||||||
ASSERT (Private->SignatureGUID != NULL);
|
ASSERT (Private->SignatureGUID != NULL);
|
||||||
Status = StringToGuid (
|
Status = StringToGuid (
|
||||||
IfrNvData->SignatureGuid,
|
IfrNvData->SignatureGuid,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
The header file of HII Config Access protocol implementation of SecureBoot
|
The header file of HII Config Access protocol implementation of SecureBoot
|
||||||
configuration module.
|
configuration module.
|
||||||
|
|
||||||
Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -73,9 +73,18 @@ extern EFI_IFR_GUID_LABEL *mEndLabel;
|
|||||||
//
|
//
|
||||||
#define SHA256_DIGEST_SIZE 32
|
#define SHA256_DIGEST_SIZE 32
|
||||||
//
|
//
|
||||||
// Set max digest size as SHA256 Output (32 bytes) by far
|
// SHA-384 digest size in bytes
|
||||||
//
|
//
|
||||||
#define MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
|
#define SHA384_DIGEST_SIZE 48
|
||||||
|
//
|
||||||
|
// SHA-512 digest size in bytes
|
||||||
|
//
|
||||||
|
#define SHA512_DIGEST_SIZE 64
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set max digest size as SHA512 Output (64 bytes) by far
|
||||||
|
//
|
||||||
|
#define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
|
||||||
|
|
||||||
#define WIN_CERT_UEFI_RSA2048_SIZE 256
|
#define WIN_CERT_UEFI_RSA2048_SIZE 256
|
||||||
|
|
||||||
@ -87,6 +96,7 @@ extern EFI_IFR_GUID_LABEL *mEndLabel;
|
|||||||
#define HASHALG_SHA256 0x00000002
|
#define HASHALG_SHA256 0x00000002
|
||||||
#define HASHALG_SHA384 0x00000003
|
#define HASHALG_SHA384 0x00000003
|
||||||
#define HASHALG_SHA512 0x00000004
|
#define HASHALG_SHA512 0x00000004
|
||||||
|
#define HASHALG_RAW 0x00000005
|
||||||
#define HASHALG_MAX 0x00000005
|
#define HASHALG_MAX 0x00000005
|
||||||
|
|
||||||
|
|
||||||
@ -120,6 +130,7 @@ typedef enum _FILE_EXPLORER_STATE {
|
|||||||
FileExplorerStateEnrollKekFile,
|
FileExplorerStateEnrollKekFile,
|
||||||
FileExplorerStateEnrollSignatureFileToDb,
|
FileExplorerStateEnrollSignatureFileToDb,
|
||||||
FileExplorerStateEnrollSignatureFileToDbx,
|
FileExplorerStateEnrollSignatureFileToDbx,
|
||||||
|
FileExplorerStateEnrollSignatureFileToDbt,
|
||||||
FileExplorerStateUnknown
|
FileExplorerStateUnknown
|
||||||
} FILE_EXPLORER_STATE;
|
} FILE_EXPLORER_STATE;
|
||||||
|
|
||||||
|
@ -41,6 +41,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#define FORM_FILE_EXPLORER_ID_KEK 0x11
|
#define FORM_FILE_EXPLORER_ID_KEK 0x11
|
||||||
#define FORM_FILE_EXPLORER_ID_DB 0x12
|
#define FORM_FILE_EXPLORER_ID_DB 0x12
|
||||||
#define FORM_FILE_EXPLORER_ID_DBX 0x13
|
#define FORM_FILE_EXPLORER_ID_DBX 0x13
|
||||||
|
#define FORMID_SECURE_BOOT_DBT_OPTION_FORM 0x14
|
||||||
|
#define SECUREBOOT_ENROLL_SIGNATURE_TO_DBT 0x15
|
||||||
|
#define SECUREBOOT_DELETE_SIGNATURE_FROM_DBT 0x16
|
||||||
|
#define FORM_FILE_EXPLORER_ID_DBT 0x17
|
||||||
|
|
||||||
#define SECURE_BOOT_MODE_CUSTOM 0x01
|
#define SECURE_BOOT_MODE_CUSTOM 0x01
|
||||||
#define SECURE_BOOT_MODE_STANDARD 0x00
|
#define SECURE_BOOT_MODE_STANDARD 0x00
|
||||||
@ -56,6 +60,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#define KEY_VALUE_SAVE_AND_EXIT_DBX 0x100a
|
#define KEY_VALUE_SAVE_AND_EXIT_DBX 0x100a
|
||||||
#define KEY_VALUE_NO_SAVE_AND_EXIT_DBX 0x100b
|
#define KEY_VALUE_NO_SAVE_AND_EXIT_DBX 0x100b
|
||||||
#define KEY_HIDE_SECURE_BOOT 0x100c
|
#define KEY_HIDE_SECURE_BOOT 0x100c
|
||||||
|
#define KEY_VALUE_SAVE_AND_EXIT_DBT 0x100d
|
||||||
|
#define KEY_VALUE_NO_SAVE_AND_EXIT_DBT 0x100e
|
||||||
|
|
||||||
#define KEY_SECURE_BOOT_OPTION 0x1100
|
#define KEY_SECURE_BOOT_OPTION 0x1100
|
||||||
#define KEY_SECURE_BOOT_PK_OPTION 0x1101
|
#define KEY_SECURE_BOOT_PK_OPTION 0x1101
|
||||||
@ -69,10 +75,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#define KEY_SECURE_BOOT_KEK_GUID 0x110a
|
#define KEY_SECURE_BOOT_KEK_GUID 0x110a
|
||||||
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DB 0x110b
|
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DB 0x110b
|
||||||
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DBX 0x110c
|
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DBX 0x110c
|
||||||
|
#define KEY_SECURE_BOOT_DBT_OPTION 0x110d
|
||||||
|
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DBT 0x110e
|
||||||
|
|
||||||
#define LABEL_KEK_DELETE 0x1200
|
#define LABEL_KEK_DELETE 0x1200
|
||||||
#define LABEL_DB_DELETE 0x1201
|
#define LABEL_DB_DELETE 0x1201
|
||||||
#define LABEL_DBX_DELETE 0x1202
|
#define LABEL_DBX_DELETE 0x1202
|
||||||
|
#define LABEL_DBT_DELETE 0x1203
|
||||||
#define LABEL_END 0xffff
|
#define LABEL_END 0xffff
|
||||||
|
|
||||||
#define SECURE_BOOT_MAX_ATTEMPTS_NUM 255
|
#define SECURE_BOOT_MAX_ATTEMPTS_NUM 255
|
||||||
@ -95,6 +104,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
//
|
//
|
||||||
#define OPTION_DEL_DBX_QUESTION_ID 0x4000
|
#define OPTION_DEL_DBX_QUESTION_ID 0x4000
|
||||||
|
|
||||||
|
//
|
||||||
|
// Question ID 0x5000 ~ 0x5FFF is for DBT
|
||||||
|
//
|
||||||
|
#define OPTION_DEL_DBT_QUESTION_ID 0x5000
|
||||||
|
|
||||||
#define FILE_OPTION_GOTO_OFFSET 0xC000
|
#define FILE_OPTION_GOTO_OFFSET 0xC000
|
||||||
#define FILE_OPTION_OFFSET 0x8000
|
#define FILE_OPTION_OFFSET 0x8000
|
||||||
#define FILE_OPTION_MASK 0x3FFF
|
#define FILE_OPTION_MASK 0x3FFF
|
||||||
@ -102,18 +116,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#define SECURE_BOOT_GUID_SIZE 36
|
#define SECURE_BOOT_GUID_SIZE 36
|
||||||
#define SECURE_BOOT_GUID_STORAGE_SIZE 37
|
#define SECURE_BOOT_GUID_STORAGE_SIZE 37
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Nv Data structure referenced by IFR
|
// Nv Data structure referenced by IFR
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BOOLEAN AttemptSecureBoot; //Attempt to enable/disable Secure Boot.
|
BOOLEAN AttemptSecureBoot; // Attempt to enable/disable Secure Boot
|
||||||
BOOLEAN HideSecureBoot; // Hiden Attempt Secure Boot
|
BOOLEAN HideSecureBoot; // Hiden Attempt Secure Boot
|
||||||
CHAR16 SignatureGuid[SECURE_BOOT_GUID_STORAGE_SIZE];
|
CHAR16 SignatureGuid[SECURE_BOOT_GUID_STORAGE_SIZE];
|
||||||
BOOLEAN PhysicalPresent; //If a Physical Present User;
|
BOOLEAN PhysicalPresent; // If a Physical Present User
|
||||||
UINT8 SecureBootMode; // Secure Boot Mode: Standard Or Custom
|
UINT8 SecureBootMode; // Secure Boot Mode: Standard Or Custom
|
||||||
BOOLEAN DeletePk;
|
BOOLEAN DeletePk;
|
||||||
BOOLEAN HasPk; //If Pk is existed it is true;
|
BOOLEAN HasPk; // If Pk is existed it is true
|
||||||
|
BOOLEAN AlwaysRevocation; // If the certificate is always revoked. Revocation time is hidden
|
||||||
|
UINT8 CertificateFormat; // The type of the certificate
|
||||||
|
EFI_HII_DATE RevocationDate; // The revocation date of the certificate
|
||||||
|
EFI_HII_TIME RevocationTime; // The revocation time of the certificate
|
||||||
} SECUREBOOT_CONFIGURATION;
|
} SECUREBOOT_CONFIGURATION;
|
||||||
|
|
||||||
#endif
|
#endif
|
Binary file not shown.
Reference in New Issue
Block a user