/** @file
HII Config Access protocol implementation of SecureBoot configuration module.
Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
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
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SecureBootConfigImpl.h"
{
}
};
{
{
{
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
}
},
},
{
{
}
}
};
//
// OID ASN.1 Value for Hash Algorithms
//
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, // OBJ_md5
0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJ_sha1
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512
};
{ L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize,Sha256Init, Sha256Update, Sha256Final},
};
// Variable Definitions
/**
Set Secure Boot option into variable space.
@param[in] VarValue The option of Secure Boot.
@retval EFI_SUCCESS The operation is finished successfully.
@retval Others Other errors as indicated.
**/
)
{
sizeof (UINT8),
);
return Status;
}
/**
Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
descriptor with the input data. NO authentication is required in this function.
@param[in, out] DataSize On input, the size of Data buffer in bytes.
On output, the size of data returned in Data
buffer in bytes.
@param[in, out] Data On input, Pointer to data buffer to be wrapped or
pointer to NULL to wrap an empty payload.
On output, Pointer to the new payload date buffer allocated from pool,
it's caller's responsibility to free the memory when finish using it.
@retval EFI_SUCCESS Create time based payload successfully.
@retval EFI_OUT_OF_RESOURCES There are not enough memory resourses to create time based payload.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval Others Unexpected error happens.
**/
)
{
return EFI_INVALID_PARAMETER;
}
//
// In Setup mode or Custom mode, the variable does not need to be signed but the
// parameters to the SetVariable() call still need to be prepared as authenticated
// variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
// data in it.
//
PayloadSize = *DataSize;
DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
return EFI_OUT_OF_RESOURCES;
}
}
return Status;
}
Time.Nanosecond = 0;
}
return EFI_SUCCESS;
}
/**
Internal helper function to delete a Variable given its name and GUID, NO authentication
required.
@param[in] VariableName Name of the Variable.
@param[in] VendorGuid GUID of the Variable.
@retval EFI_SUCCESS Variable deleted successfully.
@retval Others The driver failed to start the device.
**/
)
{
return EFI_SUCCESS;
}
DataSize = 0;
return Status;
}
Attr,
);
}
return Status;
}
/**
Generate the PK signature list from the X509 Certificate storing file (.cer)
@param[in] X509File FileHandle of X509 Certificate storing file.
@param[out] PkCert Point to the data buffer to store the signature list.
@return EFI_UNSUPPORTED Unsupported Key Length.
@return EFI_OUT_OF_RESOURCES There are not enough memory resourses to form the signature list.
**/
)
{
PkCertData = NULL;
X509DataSize = 0;
goto ON_EXIT;
}
//
// Allocate space for PK certificate list and initialize it.
// Create PK database entry with SignatureHeaderSize equals 0.
//
);
goto ON_EXIT;
}
+ sizeof(EFI_SIGNATURE_DATA) - 1
+ X509DataSize);
(*PkCert)->SignatureHeaderSize = 0;
+ sizeof(EFI_SIGNATURE_LIST)
+ (*PkCert)->SignatureHeaderSize);
//
// Fill the PK database with PKpub data from X509 certificate file.
//
}
}
return Status;
}
/**
Enroll new PK into the System without original PK's authentication.
The SignatureOwner GUID will be the same with PK's vendorguid.
@param[in] PrivateData The module's private data.
@retval EFI_SUCCESS New PK enrolled successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
return EFI_INVALID_PARAMETER;
}
//
// Parse the file's postfix. Only support *.cer(X509) files.
//
return EFI_INVALID_PARAMETER;
}
//
// Prase the selected PK file and generature PK certificate list.
//
);
goto ON_EXIT;
}
//
// Set Platform Key variable.
//
goto ON_EXIT;
}
Attr,
);
if (Status == EFI_OUT_OF_RESOURCES) {
}
goto ON_EXIT;
}
}
}
return Status;
}
/**
Remove the PK variable.
@retval EFI_SUCCESS Delete PK successfully.
@retval Others Could not allow to delete PK.
**/
)
{
Status = DeleteVariable (
);
return Status;
}
/**
Enroll a new KEK item from public key storing file (*.pbk).
@param[in] PrivateData The module's private data.
@retval EFI_SUCCESS New KEK enrolled successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_UNSUPPORTED Unsupported command.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
Attr = 0;
DataSize = 0;
KeyBlobSize = 0;
KEKSigData = NULL;
KekSigList = NULL;
KekSigListSize = 0;
//
// Form the KeKpub certificate list into EFI_SIGNATURE_LIST type.
// First, We have to parse out public key data from the pbk key file.
//
0
);
goto ON_EXIT;
}
goto ON_EXIT;
}
//
// Convert the Public key to fix octet string format represented in RSA PKCS#1.
//
goto ON_EXIT;
}
KeyLenInBytes / sizeof (UINTN),
);
//
// Form an new EFI_SIGNATURE_LIST.
//
KekSigListSize = sizeof(EFI_SIGNATURE_LIST)
+ sizeof(EFI_SIGNATURE_DATA) - 1
if (KekSigList == NULL) {
goto ON_EXIT;
}
+ sizeof(EFI_SIGNATURE_DATA) - 1
CopyMem (
KeyBlob + sizeof(CPL_KEY_INFO),
);
//
// Check if KEK entry has been already existed.
// If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
// new KEK to original variable.
//
goto ON_EXIT;
}
NULL,
&DataSize,
);
if (Status == EFI_BUFFER_TOO_SMALL) {
} else if (Status != EFI_NOT_FOUND) {
goto ON_EXIT;
}
//
// Done. Now we have formed the correct KEKpub database item, just set it into variable storage,
//
Attr,
);
goto ON_EXIT;
}
}
}
}
if (KekSigList != NULL) {
}
return Status;
}
/**
Enroll a new KEK item from X509 certificate file.
@param[in] PrivateData The module's private data.
@retval EFI_SUCCESS New X509 is enrolled successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_UNSUPPORTED Unsupported command.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
X509DataSize = 0;
KekSigList = NULL;
KekSigListSize = 0;
DataSize = 0;
KEKSigData = NULL;
&X509Data,
0
);
goto ON_EXIT;
}
if (KekSigList == NULL) {
goto ON_EXIT;
}
//
// Fill Certificate Database parameters.
//
//
// Check if KEK been already existed.
// If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
// new kek to original variable
//
goto ON_EXIT;
}
NULL,
&DataSize,
);
if (Status == EFI_BUFFER_TOO_SMALL) {
} else if (Status != EFI_NOT_FOUND) {
goto ON_EXIT;
}
Attr,
);
goto ON_EXIT;
}
}
if (KekSigList != NULL) {
}
return Status;
}
/**
Enroll new KEK into the System without PK's authentication.
The SignatureOwner GUID will be Private->SignatureGUID.
@param[in] PrivateData The module's private data.
@retval EFI_SUCCESS New KEK enrolled successful.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval others Fail to enroll KEK data.
**/
)
{
return EFI_INVALID_PARAMETER;
}
//
// Parse the file's postfix. Supports .cer and .der file as X509 certificate,
// and .pbk as RSA public key file.
//
return EnrollX509ToKek (Private);
return EnrollRsa2048ToKek (Private);
} else {
return EFI_INVALID_PARAMETER;
}
}
/**
Enroll a new X509 certificate into Signature Database (DB or DBX) without
KEK's authentication.
@param[in] PrivateData The module's private data.
@param[in] VariableName Variable name of signature database, must be
EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
@retval EFI_SUCCESS New X509 is enrolled successfully.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
X509DataSize = 0;
SigDBSize = 0;
DataSize = 0;
&X509Data,
0
);
goto ON_EXIT;
}
goto ON_EXIT;
}
//
// Fill Certificate Database parameters.
//
SigDBCert->SignatureHeaderSize = 0;
//
// Check if signature database entry has been already existed.
// If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
// new signature data to original variable
//
goto ON_EXIT;
}
NULL,
&DataSize,
);
if (Status == EFI_BUFFER_TOO_SMALL) {
} else if (Status != EFI_NOT_FOUND) {
goto ON_EXIT;
}
Attr,
);
goto ON_EXIT;
}
}
}
}
return Status;
}
/**
@retval EFI_SUCCESS Successful
@retval EFI_ABORTED Serious error occurs, like file I/O error etc.
**/
)
{
NtHeader32 = NULL;
NtHeader64 = NULL;
//
// Read the Dos header
//
{
//
// DOS image header is present,
// So read the PE header after the DOS image header
//
}
else
{
mPeCoffHeaderOffset = 0;
}
//
// Read PE header and check the signature validity and machine compatibility
//
{
return EFI_UNSUPPORTED;
}
//
// Check the architecture field of PE header and get the Certificate Data Directory data
// Note the size of FileHeader field is constant for both IA32 and X64 arch
//
//
// IA-32 Architecture
//
mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY*) &(NtHeader32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]);
}
//
// 64-bits Architecture
//
mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY*) &(NtHeader64->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]);
} else {
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
/**
@param[in] HashAlg Hash algorithm type.
@retval TRUE Successfully hash image.
@retval FALSE Fail in hash image.
**/
)
{
return FALSE;
}
//
// Initialize context of hash.
//
if (HashAlg == HASHALG_SHA1) {
} else if (HashAlg == HASHALG_SHA256) {
}
// 1. Load the image header into memory.
// 2. Initialize a SHA hash context.
if (!Status) {
goto Done;
}
//
// But CheckSum field and SECURITY data directory (certificate) are excluded
//
//
// 3. Calculate the distance from the base of the image header to the image checksum address.
// 4. Hash the image header from its base to beginning of the image checksum.
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset.
//
} else {
//
// Use PE32+ offset.
//
}
if (!Status) {
goto Done;
}
//
// 5. Skip over the image checksum (it occupies a single ULONG).
// 6. Get the address of the beginning of the Cert Directory.
// 7. Hash everything from the end of the checksum to the start of the Cert Directory.
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset.
//
HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
} else {
//
// Use PE32+ offset.
//
HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
}
if (!Status) {
goto Done;
}
//
// 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
// 9. Hash everything from the end of the Cert Directory to the end of image header.
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
//
HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);
} else {
//
// Use PE32+ offset.
//
HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);
}
if (!Status) {
goto Done;
}
//
// 10. Set the SUM_OF_BYTES_HASHED to the size of the header.
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset.
//
} else {
//
// Use PE32+ offset
//
}
//
// 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
// structures in the image. The 'NumberOfSections' field of the image
// header indicates how big the table should be. Do not include any
// IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
//
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections);
//
// 12. Using the 'PointerToRawData' in the referenced section headers as
// a key, arrange the elements in the table in ascending order. In other
// words, sort the section headers according to the disk-file offset of
// the section.
//
Section = (EFI_IMAGE_SECTION_HEADER *) (
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
);
Pos--;
}
Section += 1;
}
//
// 13. Walk through the sorted table, bring the corresponding section
// into memory, and hash the entire section (using the 'SizeOfRawData'
// field in the section header to determine the amount of data to hash).
// 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
// 15. Repeat steps 13 and 14 for all the sections in the sorted table.
//
if (Section->SizeOfRawData == 0) {
continue;
}
if (!Status) {
goto Done;
}
}
//
// 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
// data in the file that needs to be added to the hash. This data begins
// at file offset SUM_OF_BYTES_HASHED and its length is:
// FileSize - (CertDirectory->Size)
//
if (mImageSize > SumOfBytesHashed) {
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset.
//
} else {
//
// Use PE32+ offset.
//
}
if (!Status) {
goto Done;
}
}
Done:
}
if (SectionHeader != NULL) {
}
return Status;
}
/**
8.0 Appendix A
@retval EFI_UNSUPPORTED Hash algorithm is not supported.
@retval EFI_SUCCESS Hash successfully.
**/
)
{
//
// According to PKCS#7 Definition:
// SignedData ::= SEQUENCE {
// version Version,
// digestAlgorithms DigestAlgorithmIdentifiers,
// contentInfo ContentInfo,
// .... }
// This field has the fixed offset (+32) in final Authenticode ASN.1 data.
// Fixed offset (+32) is calculated based on two bytes of length encoding.
//
//
// Only support two bytes of Long Form of Length Encoding.
//
continue;
}
//
break;
}
}
if (Index == HASHALG_MAX) {
return EFI_UNSUPPORTED;
}
//
//
if (!HashPeImage(Index)) {
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
/**
Enroll a new executable's signature into Signature Database.
@param[in] PrivateData The module's private data.
@param[in] VariableName Variable name of signature database, must be
EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
@retval EFI_SUCCESS New signature is enrolled successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_UNSUPPORTED Unsupported command.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
GuidCertData = NULL;
//
// Form the SigDB certificate list.
// Format the data item into EFI_SIGNATURE_LIST type.
//
// We need to parse executable's signature data from specified signed executable file.
// In current implementation, we simply trust the pass-in signed executable file.
// In reality, it's OS's responsibility to verify the signed executable file.
//
//
// Read the whole file content
//
(VOID **) &mImageBase,
0
);
goto ON_EXIT;
}
Status = LoadPeImage ();
goto ON_EXIT;
}
if (mSecDataDir->SizeOfCert == 0) {
if (!HashPeImage (HASHALG_SHA256)) {
goto ON_EXIT;
}
} else {
//
// Read the certificate data
//
goto ON_EXIT;
}
if (!HashPeImage (HASHALG_SHA256)) {
goto ON_EXIT;;
}
Status = HashPeImageByType ();
goto ON_EXIT;;
}
} else {
goto ON_EXIT;
}
}
//
// Create a new SigDB entry.
//
SigDBSize = sizeof(EFI_SIGNATURE_LIST)
+ sizeof(EFI_SIGNATURE_DATA) - 1
+ (UINT32) mImageDigestSize;
goto ON_EXIT;
}
//
// Adjust the Certificate Database parameters.
//
SigDBCert->SignatureHeaderSize = 0;
goto ON_EXIT;
}
//
// Check if SigDB variable has been already existed.
// If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
// new signature data to original variable
//
DataSize = 0;
NULL,
&DataSize,
);
if (Status == EFI_BUFFER_TOO_SMALL) {
} else if (Status != EFI_NOT_FOUND) {
goto ON_EXIT;
}
//
// Enroll the variable.
//
Attr,
);
goto ON_EXIT;
}
}
}
if (mImageBase != NULL) {
mImageBase = NULL;
}
return Status;
}
/**
The SignatureOwner GUID will be Private->SignatureGUID.
@param[in] PrivateData The module's private data.
@param[in] VariableName Variable name of signature database, must be
EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
@retval EFI_SUCCESS New signature enrolled successfully.
@retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval others Fail to enroll signature data.
**/
)
{
if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->SignatureGUID == NULL)) {
return EFI_INVALID_PARAMETER;
}
//
// Parse the file's postfix.
//
//
// Supports .cer and .der file as X509 certificate.
//
}
}
/**
by GUID in the page for user to select and delete as needed.
@param[in] PrivateData Module's private data.
@param[in] VariableName The variable name of the vendor's signature database.
@param[in] VendorGuid A unique identifier for the vendor.
@param[in] LabelNumber Label number to insert opcodes.
@param[in] FormId Form ID of current page.
@param[in] QuestionIdBase Base question id of the signature list.
@retval EFI_SUCCESS Success to update the signature list page
@retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
**/
)
{
//
// Initialize the container for dynamic opcodes.
//
if (StartOpCodeHandle == NULL) {
goto ON_EXIT;
}
if (EndOpCodeHandle == NULL) {
goto ON_EXIT;
}
//
// Create Hii Extend Label OpCode.
//
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
//
// Read Variable.
//
DataSize = 0;
goto ON_EXIT;
}
goto ON_EXIT;
}
goto ON_EXIT;
}
goto ON_EXIT;
}
//
// Enumerate all KEK pub data.
//
GuidIndex = 0;
} else {
//
// The signature type is not supported in current implementation.
//
continue;
}
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ sizeof (EFI_SIGNATURE_LIST)
//
// Display GUID and help
//
0,
0,
Help,
0,
);
}
}
);
if (StartOpCodeHandle != NULL) {
}
if (EndOpCodeHandle != NULL) {
}
}
}
return EFI_SUCCESS;
}
/**
Delete a KEK entry from KEK database.
@param[in] PrivateData Module's private data.
@param[in] QuestionId Question id of the KEK item to delete.
@retval EFI_SUCCESS Delete kek item successfully.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
Attr = 0;
//
// Get original KEK variable.
//
DataSize = 0;
Status = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, NULL, &DataSize, NULL);
goto ON_EXIT;
}
goto ON_EXIT;
}
Status = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, &Attr, &DataSize, OldData);
goto ON_EXIT;
}
//
// Allocate space for new variable.
//
goto ON_EXIT;
}
//
// Enumerate all KEK pub data and erasing the target item.
//
Offset = 0;
GuidIndex = 0;
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
if (GuidIndex == DeleteKekIndex ) {
//
// Find it! Skip it!
//
} else {
//
// This item doesn't match. Copy it to the Data buffer.
//
}
GuidIndex++;
}
} else {
//
// This List doesn't match. Copy it to the Data buffer.
//
}
}
if (!IsKEKItemFound) {
//
// Doesn't find the Kek Item!
//
goto ON_EXIT;
}
//
// Delete the Signature header if there is no signature in the list.
//
Offset = 0;
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
if (CertCount != 0) {
}
}
if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
goto ON_EXIT;
}
}
Attr,
);
goto ON_EXIT;
}
}
}
return UpdateDeletePage (
);
}
/**
Delete a signature entry from siganture database.
@param[in] PrivateData Module's private data.
@param[in] VariableName The variable name of the vendor's signature database.
@param[in] VendorGuid A unique identifier for the vendor.
@param[in] LabelNumber Label number to insert opcodes.
@param[in] FormId Form ID of current page.
@param[in] QuestionIdBase Base question id of the signature list.
@param[in] DeleteIndex Signature index to delete.
@retval EFI_SUCCESS Delete siganture successfully.
@retval EFI_NOT_FOUND Can't find the signature item,
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
**/
)
{
Attr = 0;
//
// Get original signature list data.
//
DataSize = 0;
goto ON_EXIT;
}
goto ON_EXIT;
}
goto ON_EXIT;
}
//
// Allocate space for new variable.
//
goto ON_EXIT;
}
//
// Enumerate all signature data and erasing the target item.
//
IsItemFound = FALSE;
Offset = 0;
GuidIndex = 0;
) {
//
// Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
//
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
if (GuidIndex == DeleteIndex) {
//
// Find it! Skip it!
//
IsItemFound = TRUE;
} else {
//
// This item doesn't match. Copy it to the Data buffer.
//
}
GuidIndex++;
}
} else {
//
// This List doesn't match. Just copy it to the Data buffer.
//
}
}
if (!IsItemFound) {
//
// Doesn't find the signature Item!
//
goto ON_EXIT;
}
//
// Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
//
Offset = 0;
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
if (CertCount != 0) {
}
}
if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
goto ON_EXIT;
}
}
Attr,
);
goto ON_EXIT;
}
}
}
return UpdateDeletePage (
);
}
/**
This function extracts configuration from variable.
@param[in, out] ConfigData Point to SecureBoot configuration private data.
**/
)
{
//
// Get the SecureBootEnable Variable
//
//
// Checkbox.
//
if (SecureBootEnable == NULL) {
} else {
}
//
// If it is Physical Presence User, set the PhysicalPresent to true.
//
if (UserPhysicalPresent()) {
} else {
}
//
// If there is no PK then the Delete Pk button will be gray.
//
} else {
}
//
// Get the SecureBootMode from CustomMode variable.
//
if (SecureBootMode == NULL) {
} else {
}
}
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Request A null-terminated Unicode string in
<ConfigRequest> format.
@param[out] Progress On return, points to a character in the Request
string. Points to the string's null terminator if
request was successful. Points to the most recent
the beginning of the string if the failure is in
successful.
@param[out] Results A null-terminated Unicode string in
<ConfigAltResp> format which has all values filled
in for the names in the Request string. String to
be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
)
{
return EFI_INVALID_PARAMETER;
}
Size = 0;
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {
return EFI_NOT_FOUND;
}
//
// Get Configuration from Variable.
//
BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
//
// Request is set to NULL or OFFSET is NULL, construct full request string.
//
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
//
ConfigRequestHdr = HiiConstructConfigHdr (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, PrivateData->DriverHandle);
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
}
(UINT8 *) &Configuration,
);
//
// Free the allocated config request string.
//
if (AllocatedRequest) {
}
//
// Set Progress string to the original request string.
//
}
return Status;
}
/**
This function processes the results of changes in configuration.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Configuration A null-terminated Unicode string in <ConfigResp>
format.
@param[out] Progress A pointer to a string filled in with the offset of
the most recent '&' before the first failing
the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
)
{
return EFI_INVALID_PARAMETER;
}
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
/**
This function is called to provide results data to the driver.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Action Specifies the type of action taken by the browser.
@param[in] QuestionId A unique value which is sent to the original
exporting driver so that it can identify the type
of data to expect.
@param[in] Type The type of value for the question.
@param[in] Value A pointer to the data being sent to the original
exporting driver.
@param[out] ActionRequest On return, points to the action requested by the
callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the
callback.
**/
)
{
return EFI_INVALID_PARAMETER;
}
return EFI_UNSUPPORTED;
}
//
// Retrieve uncommitted data from Browser
//
BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
return EFI_OUT_OF_RESOURCES;
}
if (Action == EFI_BROWSER_ACTION_CHANGING) {
switch (QuestionId) {
case KEY_SECURE_BOOT_ENABLE:
&Key,
L"Only Physical Presence User could disable secure boot!",
);
}
}
break;
case KEY_SECURE_BOOT_OPTION:
FreeMenu (&FsOptionMenu);
break;
//
// Clear Signature GUID.
//
return EFI_OUT_OF_RESOURCES;
}
}
if (QuestionId == KEY_SECURE_BOOT_DB_OPTION) {
} else if (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) {
} else {
}
//
// Refresh selected file.
//
break;
case FORMID_ENROLL_KEK_FORM:
if (QuestionId == SECUREBOOT_ADD_PK_FILE_FORM_ID) {
} else if (QuestionId == FORMID_ENROLL_KEK_FORM) {
} else if (QuestionId == SECUREBOOT_ENROLL_SIGNATURE_TO_DB) {
} else {
}
UpdateFileExplorer (Private, 0);
break;
Status = DeletePlatformKey ();
}
break;
case KEY_DELETE_KEK:
);
break;
);
break;
);
break;
break;
break;
break;
default:
if (QuestionId >= FILE_OPTION_OFFSET) {
} else if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) &&
} else if ((QuestionId >= OPTION_DEL_DB_QUESTION_ID) &&
);
} else if ((QuestionId >= OPTION_DEL_DBX_QUESTION_ID) &&
);
}
break;
}
} else if (Action == EFI_BROWSER_ACTION_CHANGED) {
switch (QuestionId) {
case KEY_SECURE_BOOT_ENABLE:
break;
&Key,
L"ERROR: Unsupported file type, only *.cer is supported!",
);
} else {
}
break;
}
}
break;
case KEY_SECURE_BOOT_MODE:
sizeof (UINT8),
);
}
break;
case KEY_SECURE_BOOT_KEK_GUID:
Status = StringToGuid (
);
break;
}
break;
}
break;
}
}
BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
}
return EFI_SUCCESS;
}
/**
This function publish the SecureBoot configuration Form.
@param[in, out] PrivateData Points to SecureBoot configuration private data.
@retval EFI_SUCCESS HII Form is installed successfully.
@retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
@retval Others Other errors as indicated.
**/
)
{
DriverHandle = NULL;
);
return Status;
}
//
// Publish the HII package list
//
);
);
return EFI_OUT_OF_RESOURCES;
}
return EFI_OUT_OF_RESOURCES;
}
//
// Init OpCode Handle and Allocate space for creation of Buffer
//
if (mStartOpCodeHandle == NULL) {
return EFI_OUT_OF_RESOURCES;
}
if (mEndOpCodeHandle == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Create Hii Extend Label OpCode as the start opcode
//
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
//
// Create Hii Extend Label OpCode as the end opcode
//
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
return EFI_SUCCESS;
}
/**
This function removes SecureBoot configuration Form.
@param[in, out] PrivateData Points to SecureBoot configuration private data.
**/
)
{
//
// Uninstall HII package list
//
}
//
// Uninstall HII Config Access Protocol
//
);
}
}
}
}
FreeMenu (&FsOptionMenu);
if (mStartOpCodeHandle != NULL) {
}
if (mEndOpCodeHandle != NULL) {
}
}