.../SecureBootConfigDxe/SecureBootConfig.vfr | 53 +- .../SecureBootConfigDxe/SecureBootConfigImpl.c | 1036 +++++++++++++++++++- .../SecureBootConfigDxe/SecureBootConfigImpl.h | 35 + .../SecureBootConfigDxe/SecureBootConfigNvData.h | 23 +- .../SecureBootConfigStrings.uni | 26 + 5 files changed, 1144 insertions(+), 29 deletions(-)
Use 2-level format to display signature list and signature data.
Support batch delete operation to delete signature list or signature data.
Display more useful information for each signature data.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
---
.../SecureBootConfigDxe/SecureBootConfig.vfr | 53 +-
.../SecureBootConfigDxe/SecureBootConfigImpl.c | 1036 +++++++++++++++++++-
.../SecureBootConfigDxe/SecureBootConfigImpl.h | 35 +
.../SecureBootConfigDxe/SecureBootConfigNvData.h | 23 +-
.../SecureBootConfigStrings.uni | 26 +
5 files changed, 1144 insertions(+), 29 deletions(-)
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
index bbecff2b08..296b9c9b9e 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
@@ -316,11 +316,11 @@ formset
subtitle text = STRING_TOKEN(STR_NULL);
- goto SECUREBOOT_DELETE_SIGNATURE_FROM_DBX,
+ goto SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
prompt = STRING_TOKEN (STR_SECURE_BOOT_DELETE_SIGNATURE),
help = STRING_TOKEN (STR_SECURE_BOOT_DELETE_SIGNATURE),
flags = INTERACTIVE,
- key = SECUREBOOT_DELETE_SIGNATURE_FROM_DBX;
+ key = KEY_VALUE_FROM_DBX_TO_LIST_FORM;
endform;
@@ -360,17 +360,58 @@ formset
endform;
//
- // Form: 'Delete Signature' for DBX Options.
+ // Form: Display Signature List.
//
- form formid = SECUREBOOT_DELETE_SIGNATURE_FROM_DBX,
- title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_SIGNATURE);
+ form formid = SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_LIST_FORM);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ grayoutif ideqval SECUREBOOT_CONFIGURATION.ListCount == 0;
+ label LABEL_DELETE_ALL_LIST_BUTTON;
+ //
+ // Will create a goto button dynamically here.
+ //
+ label LABEL_END;
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ label LABEL_SIGNATURE_LIST_START;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_NULL);
- label LABEL_DBX_DELETE;
+ endform;
+
+ //
+ // Form: Display Signature Data.
+ //
+ form formid = SECUREBOOT_DELETE_SIGNATURE_DATA_FORM,
+ title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_DATA_FORM);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ prompt = STRING_TOKEN(STR_SECURE_BOOT_DELETE_ALL_DATA),
+ help = STRING_TOKEN(STR_SECURE_BOOT_DELETE_ALL_DATA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SECURE_BOOT_DELETE_ALL_DATA;
+
+ grayoutif ideqval SECUREBOOT_CONFIGURATION.CheckedDataCount == 0;
+ goto SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ prompt = STRING_TOKEN(STR_SECURE_BOOT_DELETE_CHECK_DATA),
+ help = STRING_TOKEN(STR_SECURE_BOOT_DELETE_CHECK_DATA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SECURE_BOOT_DELETE_CHECK_DATA;
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ label LABEL_SIGNATURE_DATA_START;
label LABEL_END;
subtitle text = STRING_TOKEN(STR_NULL);
endform;
+
//
// Form: 'Delete Signature' for DBT Options.
//
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 2eaf24633d..3df1f431a9 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SecureBootConfigImpl.h"
+#include <Library/BaseCryptLib.h>
CHAR16 mSecureBootStorageName[] = L"SECUREBOOT_CONFIGURATION";
@@ -3051,6 +3052,184 @@ ON_EXIT:
}
/**
+ This function to delete signature list or data, according by DelType.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] DelType Indicate delete signature list or data.
+ @param[in] CheckedCount Indicate how many signature data have
+ been checked in current signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+DeleteSignatureEx (
+ IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData,
+ IN SIGNATURE_DELETE_TYPE DelType,
+ IN UINT32 CheckedCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_LIST *NewCertList;
+ EFI_SIGNATURE_DATA *DataWalker;
+ CHAR16 *VariableName;
+ UINT32 VariableAttr;
+ UINTN VariableDataSize;
+ UINTN RemainingSize;
+ UINTN ListIndex;
+ UINTN Index;
+ UINTN Offset;
+ UINT8 *VariableData;
+ UINT8 *NewVariableData;
+
+ Status = EFI_SUCCESS;
+ VariableName = NULL;
+ VariableAttr = 0;
+ VariableDataSize = 0;
+ ListIndex = 0;
+ Offset = 0;
+ VariableData = NULL;
+ NewVariableData = NULL;
+
+ VariableName = AllocateZeroPool (100);
+ if (VariableName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (PrivateData->VariableName == VARIABLE_DB) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == VARIABLE_DBX) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE1);
+ } else if (PrivateData->VariableName == VARIABLE_DBT) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE2);
+ } else {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ NewVariableData = AllocateZeroPool (VariableDataSize);
+ if (NewVariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ RemainingSize = VariableDataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)(VariableData);
+ if (DelType == DELETE_SIGNATURE_LIST_ALL) {
+ VariableDataSize = 0;
+ } else {
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex < PrivateData->ListIndex) {
+ CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, ListWalker->SignatureListSize);
+ Offset += ListWalker->SignatureListSize;
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ ListIndex++;
+ }
+
+ if (CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) || DelType == DELETE_SIGNATURE_LIST_ONE) {
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ } else {
+ NewCertList = (EFI_SIGNATURE_LIST *)(NewVariableData + Offset);
+ //
+ // Copy header.
+ //
+ CopyMem ((UINT8 *)NewVariableData, ListWalker, sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ Offset += sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize;
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof(EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS(ListWalker); Index = Index + 1) {
+ if (PrivateData->CheckArray[Index]) {
+ //
+ // Delete checked siganture data, and update the size of whole signature list.
+ //
+ NewCertList->SignatureListSize -= NewCertList->SignatureSize;
+ } else {
+ //
+ // Remain the unchecked signature data.
+ //
+ CopyMem ((UINT8 *)NewVariableData + Offset, DataWalker, ListWalker->SignatureSize);
+ Offset += ListWalker->SignatureSize;
+ }
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ }
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ }
+
+ //
+ // Copy remaining data, maybe 0.
+ //
+ CopyMem((UINT8 *)NewVariableData + Offset, ListWalker, RemainingSize);
+ Offset += RemainingSize;
+
+ VariableDataSize = Offset;
+ }
+
+ if ((VariableAttr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
+ Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ VariableAttr,
+ VariableDataSize,
+ NewVariableData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r", Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ SECUREBOOT_FREE_NON_NULL (VariableName);
+ SECUREBOOT_FREE_NON_NULL (VariableData);
+ SECUREBOOT_FREE_NON_NULL (NewVariableData);
+
+ return Status;
+}
+
+/**
Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT
and STR_CUR_SECURE_BOOT_MODE_CONTENT.
@@ -3381,6 +3560,731 @@ SecureBootRouteConfig (
}
/**
+ This function to load signature list, the update the menu page.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] LabelId 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.
+**/
+EFI_STATUS
+LoadSignatureList (
+ IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData,
+ IN UINT16 LabelId,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING_ID ListType;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_IFR_GUID_LABEL *StartGoto;
+ EFI_IFR_GUID_LABEL *EndGoto;
+ EFI_FORM_ID DstFormId;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ VOID *StartGotoHandle;
+ VOID *EndGotoHandle;
+ UINTN DataSize;
+ UINTN RemainingSize;
+ UINT16 Index;
+ UINT8 *VariableData;
+ CHAR16 *VariableName;
+ CHAR16 *NameBuffer;
+ CHAR16 *HelpBuffer;
+
+ Status = EFI_SUCCESS;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ Index = 0;
+ VariableData = NULL;
+ VariableName = NULL;
+ NameBuffer = NULL;
+ HelpBuffer = NULL;
+
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ StartGotoHandle = HiiAllocateOpCodeHandle ();
+ if (StartGotoHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndGotoHandle = HiiAllocateOpCodeHandle ();
+ if (EndGotoHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelId;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ StartGoto = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode(
+ StartGotoHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof(EFI_IFR_GUID_LABEL)
+ );
+ StartGoto->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartGoto->Number = LABEL_DELETE_ALL_LIST_BUTTON;
+
+ EndGoto = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode(
+ EndGotoHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof(EFI_IFR_GUID_LABEL)
+ );
+ EndGoto->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndGoto->Number = LABEL_END;
+
+ VariableName = AllocateZeroPool (100);
+ if (VariableName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (PrivateData->VariableName == VARIABLE_DB) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE);
+ DstFormId = FORMID_SECURE_BOOT_DB_OPTION_FORM;
+ } else if (PrivateData->VariableName == VARIABLE_DBX) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE1);
+ DstFormId = FORMID_SECURE_BOOT_DBX_OPTION_FORM;
+ } else if (PrivateData->VariableName == VARIABLE_DBT) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE2);
+ DstFormId = FORMID_SECURE_BOOT_DBT_OPTION_FORM;
+ } else {
+ goto ON_EXIT;
+ }
+
+ HiiCreateGotoOpCode (
+ StartGotoHandle,
+ DstFormId,
+ STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST),
+ STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST),
+ EFI_IFR_FLAG_CALLBACK,
+ KEY_SECURE_BOOT_DELETE_ALL_LIST
+ );
+
+ //
+ // Read Variable, the variable name save in the PrivateData->VariableName.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (DataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ NameBuffer = AllocateZeroPool (100);
+ if (NameBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ HelpBuffer = AllocateZeroPool (100);
+ if (HelpBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ RemainingSize = DataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
+ if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA384);
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha512Guid)) {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA512);
+ } else {
+ ListType = STRING_TOKEN (STR_LIST_TYPE_UNKNOWN);
+ }
+
+ UnicodeSPrint (NameBuffer,
+ 100,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_NAME_FORMAT), NULL),
+ Index + 1
+ );
+ UnicodeSPrint (HelpBuffer,
+ 100,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT), NULL),
+ HiiGetString (PrivateData->HiiHandle, ListType, NULL),
+ SIGNATURE_DATA_COUNTS (ListWalker)
+ );
+
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle,
+ SECUREBOOT_DELETE_SIGNATURE_DATA_FORM,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HiiSetString (PrivateData->HiiHandle, 0, HelpBuffer, NULL),
+ EFI_IFR_FLAG_CALLBACK,
+ QuestionIdBase + Index++
+ );
+
+ ZeroMem (NameBuffer, 100);
+ ZeroMem (HelpBuffer, 100);
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ }
+
+ON_EXIT:
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSecureBootConfigFormSetGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSecureBootConfigFormSetGuid,
+ FormId,
+ StartGotoHandle,
+ EndGotoHandle
+ );
+
+ SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle);
+ SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle);
+ SECUREBOOT_FREE_NON_OPCODE (StartGotoHandle);
+ SECUREBOOT_FREE_NON_OPCODE (EndGotoHandle);
+
+ SECUREBOOT_FREE_NON_NULL (VariableName);
+ SECUREBOOT_FREE_NON_NULL (VariableData);
+ SECUREBOOT_FREE_NON_NULL (NameBuffer);
+ SECUREBOOT_FREE_NON_NULL (HelpBuffer);
+
+ PrivateData->ListCount = Index;
+
+ return Status;
+}
+
+/**
+ Parse hash value from EFI_SIGANTURE_DATA, and save in the CHAR16 type array.
+ The buffer is callee allocated and should be freed by the caller.
+
+ @param[in] ListEntry The pointer point to the signature list.
+ @param[in] DataEntry The signature data we are processing.
+ @param[out] BufferToReturn Buffer to save the hash value.
+
+ @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval EFI_SUCCESS Operation success.
+**/
+EFI_STATUS
+ParseHashValue (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT CHAR16 **BufferToReturn
+ )
+{
+ UINTN Index;
+ UINTN BufferIndex;
+ UINTN TotalSize;
+ UINTN DataSize;
+ UINTN Line;
+ UINTN OneLineBytes;
+
+ //
+ // Assume that, display 8 bytes in one line.
+ //
+ OneLineBytes = 8;
+
+ if (ListEntry == NULL || DataEntry == NULL || BufferToReturn == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DataSize = ListEntry->SignatureSize - sizeof(EFI_GUID);
+ Line = (DataSize + OneLineBytes - 1) / OneLineBytes;
+
+ //
+ // Each byte will split two Hex-number, and each line need additional memory to save '\r\n'.
+ //
+ TotalSize = ((DataSize + Line) * 2 * sizeof(CHAR16));
+
+ *BufferToReturn = AllocateZeroPool(TotalSize);
+ if (*BufferToReturn == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Index = 0, BufferIndex = 0; Index < DataSize; Index = Index + 1) {
+ if ((Index > 0) && (Index % OneLineBytes == 0)) {
+ BufferIndex += UnicodeSPrint(&(*BufferToReturn)[BufferIndex], TotalSize - sizeof(CHAR16) * BufferIndex, L"\n");
+ }
+ BufferIndex += UnicodeSPrint(&(*BufferToReturn)[BufferIndex], TotalSize - sizeof(CHAR16) * BufferIndex, L"%02x", DataEntry->SignatureData[Index]);
+ }
+ BufferIndex += UnicodeSPrint(&(*BufferToReturn)[BufferIndex], TotalSize - sizeof(CHAR16) * BufferIndex, L"\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to get the common name from the X509 format certificate.
+ The buffer is callee allocated and should be freed by the caller.
+
+ @param[in] ListEntry The pointer point to the signature list.
+ @param[in] DataEntry The signature data we are processing.
+ @param[out] BufferToReturn Buffer to save the CN of X509 certificate.
+
+ @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval EFI_SUCCESS Operation success.
+ @retval EFI_NOT_FOUND Not found CN field in the X509 certificate.
+**/
+EFI_STATUS
+GetCommonNameFromX509 (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT CHAR16 **BufferToReturn
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *CNBuffer;
+
+ Status = EFI_SUCCESS;
+ CNBuffer = NULL;
+
+ CNBuffer = AllocateZeroPool(256);
+ if (CNBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ X509GetCommonName (
+ (UINT8 *)DataEntry + sizeof(EFI_GUID),
+ ListEntry->SignatureSize - sizeof(EFI_GUID),
+ CNBuffer,
+ 256
+ );
+
+ *BufferToReturn = AllocateZeroPool(256 * sizeof(CHAR16));
+ if (*BufferToReturn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ AsciiStrToUnicodeStrS (CNBuffer, *BufferToReturn, 256);
+
+ON_EXIT:
+ SECUREBOOT_FREE_NON_NULL (CNBuffer);
+
+ return Status;
+}
+
+/**
+ Format the help info for the signature data, each help info contain 3 parts.
+ 1. Onwer Guid.
+ 2. Content, depends on the type of the signature list.
+ 3. Revocation time.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] ListEntry Point to the signature list.
+ @param[in] DataEntry Point to the siganture data we are processing.
+ @param[out] StringId Save the string id of help info.
+
+ @retval EFI_SUCCESS Operation success.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+FormatHelpInfo (
+ IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData,
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT EFI_STRING_ID *StringId
+ )
+{
+ EFI_STATUS Status;
+ EFI_TIME *Time;
+ EFI_STRING_ID ListTypeId;
+ UINTN DataSize;
+ UINTN HelpInfoIndex;
+ UINTN TotalSize;
+ CHAR16 *GuidString;
+ CHAR16 *DataString;
+ CHAR16 *TimeString;
+ CHAR16 *HelpInfoString;
+ BOOLEAN IsCert;
+
+ Status = EFI_SUCCESS;
+ Time = NULL;
+ HelpInfoIndex = 0;
+ GuidString = NULL;
+ DataString = NULL;
+ TimeString = NULL;
+ HelpInfoString = NULL;
+ IsCert = FALSE;
+
+ if (CompareGuid(&ListEntry->SignatureType, &gEfiCertRsa2048Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_RSA2048_SHA256);
+ DataSize = ListEntry->SignatureSize - sizeof(EFI_GUID);
+ IsCert = TRUE;
+ } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509);
+ DataSize = ListEntry->SignatureSize - sizeof(EFI_GUID);
+ IsCert = TRUE;
+ } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertSha1Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA1);
+ DataSize = 20;
+ } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA256);
+ DataSize = 32;
+ } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA256);
+ DataSize = 32;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Sha384Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA384);
+ DataSize = 48;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Sha512Guid)) {
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA512);
+ DataSize = 64;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else {
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ }
+
+ GuidString = AllocateZeroPool (100);
+ if (GuidString == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ TotalSize = 1024;
+ HelpInfoString = AllocateZeroPool (TotalSize);
+ if (HelpInfoString == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Format GUID part.
+ //
+ GuidToString(&DataEntry->SignatureOwner, GuidString, 100);
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof(CHAR16) * HelpInfoIndex,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID), NULL),
+ GuidString
+ );
+
+ //
+ // Format content part, it depends on the type of signature list, hash value or CN.
+ //
+ if (IsCert) {
+ GetCommonNameFromX509 (ListEntry, DataEntry, &DataString);
+ HelpInfoIndex += UnicodeSPrint(
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof(CHAR16) * HelpInfoIndex,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_CN), NULL),
+ HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL),
+ DataSize,
+ DataString
+ );
+ } else {
+ //
+ // Format hash value for each signature data entry.
+ //
+ ParseHashValue (ListEntry, DataEntry, &DataString);
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof(CHAR16) * HelpInfoIndex,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH), NULL),
+ HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL),
+ DataSize,
+ DataString
+ );
+ }
+
+ //
+ // Format revocation time part.
+ //
+ if (Time != NULL) {
+ TimeString = AllocateZeroPool(100);
+ if (TimeString == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ UnicodeSPrint (
+ TimeString,
+ 100,
+ L"%d-%d-%d %d:%d:%d",
+ Time->Year,
+ Time->Month,
+ Time->Day,
+ Time->Hour,
+ Time->Minute,
+ Time->Second
+ );
+
+ UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME), NULL),
+ TimeString
+ );
+ }
+
+ *StringId = HiiSetString (PrivateData->HiiHandle, 0, HelpInfoString, NULL);
+
+ON_EXIT:
+ SECUREBOOT_FREE_NON_NULL (GuidString);
+ SECUREBOOT_FREE_NON_NULL (DataString);
+ SECUREBOOT_FREE_NON_NULL (TimeString);
+ SECUREBOOT_FREE_NON_NULL (HelpInfoString);
+
+ return Status;
+}
+
+/**
+ This functino to load signature data under the signature list.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] LabelId 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] ListIndex Indicate to load which signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureData (
+ IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData,
+ IN UINT16 LabelId,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINT16 ListIndex
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_DATA *DataWalker;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_STRING_ID HelpStringId;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ UINTN DataSize;
+ UINTN RemainingSize;
+ UINT16 Index;
+ UINT8 *VariableData;
+ CHAR16 *VariableName;
+ CHAR16 *NameBuffer;
+
+ Status = EFI_SUCCESS;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ Index = 0;
+ VariableData = NULL;
+ VariableName = NULL;
+ NameBuffer = NULL;
+
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelId;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ VariableName = AllocateZeroPool (100);
+ if (VariableName == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (PrivateData->VariableName == VARIABLE_DB) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == VARIABLE_DBX) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE1);
+ } else if (PrivateData->VariableName == VARIABLE_DBT) {
+ UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE2);
+ } else {
+ goto ON_EXIT;
+ }
+
+ //
+ // Read Variable, the variable name save in the PrivateData->VariableName.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (DataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ NameBuffer = AllocateZeroPool (100);
+ if (NameBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ RemainingSize = DataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
+
+ //
+ // Skip signature list.
+ //
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex-- > 0) {
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ }
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof(EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS(ListWalker); Index = Index + 1) {
+ //
+ // Format name buffer.
+ //
+ UnicodeSPrint (NameBuffer,
+ 100,
+ HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_NAME_FORMAT), NULL),
+ Index + 1
+ );
+
+ //
+ // Format help info buffer.
+ //
+ Status = FormatHelpInfo (PrivateData, ListWalker, DataWalker, &HelpStringId);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle,
+ (EFI_QUESTION_ID)(QuestionIdBase + Index),
+ 0,
+ 0,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HelpStringId,
+ EFI_IFR_FLAG_CALLBACK,
+ 0,
+ NULL
+ );
+
+ ZeroMem(NameBuffer, 100);
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ }
+
+ //
+ // Allocate a buffer to record which signature data will be checked.
+ // This memory buffer will be freed when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
+ //
+ PrivateData->CheckArray = AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker) * sizeof (BOOLEAN));
+
+ON_EXIT:
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSecureBootConfigFormSetGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle);
+ SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle);
+
+ SECUREBOOT_FREE_NON_NULL (VariableName);
+ SECUREBOOT_FREE_NON_NULL (VariableData);
+ SECUREBOOT_FREE_NON_NULL (NameBuffer);
+
+ return Status;
+}
+
+/**
This function is called to provide results data to the driver.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@@ -3474,6 +4378,13 @@ SecureBootCallback (
(QuestionId == KEY_SECURE_BOOT_DBX_OPTION) ||
(QuestionId == KEY_SECURE_BOOT_DBT_OPTION)) {
CloseEnrolledFile(Private->FileContext);
+ } else if (QuestionId == KEY_SECURE_BOOT_DELETE_ALL_LIST) {
+ //
+ // Update ListCount field in varstore
+ // Button "Delete All Signature List" is
+ // enable when ListCount is greater than 0.
+ //
+ IfrNvData->ListCount = Private->ListCount;
}
}
goto EXIT;
@@ -3665,16 +4576,89 @@ SecureBootCallback (
);
break;
- case SECUREBOOT_DELETE_SIGNATURE_FROM_DBX:
- UpdateDeletePage (
+ //
+ // From DBX option to the level-1 form, display signature list.
+ //
+ case KEY_VALUE_FROM_DBX_TO_LIST_FORM:
+ Private->VariableName = VARIABLE_DBX;
+ LoadSignatureList (
Private,
- EFI_IMAGE_SECURITY_DATABASE1,
- &gEfiImageSecurityDatabaseGuid,
- LABEL_DBX_DELETE,
- SECUREBOOT_DELETE_SIGNATURE_FROM_DBX,
- OPTION_DEL_DBX_QUESTION_ID
- );
+ LABEL_SIGNATURE_LIST_START,
+ SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ break;
+ //
+ // Delete all signature list and reload.
+ //
+ case KEY_SECURE_BOOT_DELETE_ALL_LIST:
+ CreatePopUp(
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature list.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') {
+ DeleteSignatureEx (Private, DELETE_SIGNATURE_LIST_ALL, IfrNvData->CheckedDataCount);
+ }
+
+ LoadSignatureList (
+ Private,
+ LABEL_SIGNATURE_LIST_START,
+ SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ break;
+
+ //
+ // Delete one signature list and reload.
+ //
+ case KEY_SECURE_BOOT_DELETE_ALL_DATA:
+ CreatePopUp(
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature data.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') {
+ DeleteSignatureEx (Private, DELETE_SIGNATURE_LIST_ONE, IfrNvData->CheckedDataCount);
+ }
+
+ LoadSignatureList (
+ Private,
+ LABEL_SIGNATURE_LIST_START,
+ SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ break;
+
+ //
+ // Delete checked signature data and reload.
+ //
+ case KEY_SECURE_BOOT_DELETE_CHECK_DATA:
+ CreatePopUp(
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature data.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') {
+ DeleteSignatureEx (Private, DELETE_SIGNATURE_DATA, IfrNvData->CheckedDataCount);
+ }
+
+ LoadSignatureList (
+ Private,
+ LABEL_SIGNATURE_LIST_START,
+ SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
break;
case SECUREBOOT_DELETE_SIGNATURE_FROM_DBT:
@@ -3799,17 +4783,25 @@ SecureBootCallback (
OPTION_DEL_DB_QUESTION_ID,
QuestionId - OPTION_DEL_DB_QUESTION_ID
);
- } else if ((QuestionId >= OPTION_DEL_DBX_QUESTION_ID) &&
- (QuestionId < (OPTION_DEL_DBX_QUESTION_ID + OPTION_CONFIG_RANGE))) {
- DeleteSignature (
+ } else if ((QuestionId >= OPTION_SIGNATURE_LIST_QUESTION_ID) &&
+ (QuestionId < (OPTION_SIGNATURE_LIST_QUESTION_ID + OPTION_CONFIG_RANGE))) {
+ LoadSignatureData (
Private,
- EFI_IMAGE_SECURITY_DATABASE1,
- &gEfiImageSecurityDatabaseGuid,
- LABEL_DBX_DELETE,
- SECUREBOOT_DELETE_SIGNATURE_FROM_DBX,
- OPTION_DEL_DBX_QUESTION_ID,
- QuestionId - OPTION_DEL_DBX_QUESTION_ID
- );
+ LABEL_SIGNATURE_DATA_START,
+ SECUREBOOT_DELETE_SIGNATURE_DATA_FORM,
+ OPTION_SIGNATURE_DATA_QUESTION_ID,
+ QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ Private->ListIndex = QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID;
+ } else if ((QuestionId >= OPTION_SIGNATURE_DATA_QUESTION_ID) &&
+ (QuestionId < (OPTION_SIGNATURE_DATA_QUESTION_ID + OPTION_CONFIG_RANGE))) {
+ if (Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID]) {
+ IfrNvData->CheckedDataCount--;
+ Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = FALSE;
+ } else {
+ IfrNvData->CheckedDataCount++;
+ Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = TRUE;
+ }
} else if ((QuestionId >= OPTION_DEL_DBT_QUESTION_ID) &&
(QuestionId < (OPTION_DEL_DBT_QUESTION_ID + OPTION_CONFIG_RANGE))) {
DeleteSignature (
@@ -3899,6 +4891,14 @@ SecureBootCallback (
if (SecureBootMode != NULL) {
FreePool (SecureBootMode);
}
+
+ if (QuestionId == KEY_SECURE_BOOT_DELETE_ALL_DATA) {
+ //
+ // Free memory when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
+ //
+ SECUREBOOT_FREE_NON_NULL (Private->CheckArray);
+ IfrNvData->CheckedDataCount = 0;
+ }
}
EXIT:
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
index 75b18f121c..501215cdf5 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
@@ -112,6 +112,23 @@ typedef struct {
UINT8 FileType;
} SECUREBOOT_FILE_CONTEXT;
+#define SECUREBOOT_FREE_NON_NULL(Pointer) \
+ do { \
+ if ((Pointer) != NULL) { \
+ FreePool((Pointer)); \
+ (Pointer) = NULL; \
+ } \
+ } while (FALSE)
+
+#define SECUREBOOT_FREE_NON_OPCODE(Handle) \
+ do{ \
+ if ((Handle) != NULL) { \
+ HiiFreeOpCodeHandle((Handle)); \
+ } \
+ } while (FALSE)
+
+#define SIGNATURE_DATA_COUNTS(List) \
+ (((List)->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - (List)->SignatureHeaderSize) / (List)->SignatureSize)
//
// We define another format of 5th directory entry: security directory
@@ -134,6 +151,19 @@ typedef struct {
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
+typedef enum {
+ VARIABLE_DB,
+ VARIABLE_DBX,
+ VARIABLE_DBT,
+ VARIABLE_MAX
+} CURRENT_VARIABLE_NAME;
+
+typedef enum {
+ DELETE_SIGNATURE_LIST_ALL,
+ DELETE_SIGNATURE_LIST_ONE,
+ DELETE_SIGNATURE_DATA
+}SIGNATURE_DELETE_TYPE;
+
typedef struct {
UINTN Signature;
@@ -144,6 +174,11 @@ typedef struct {
SECUREBOOT_FILE_CONTEXT *FileContext;
EFI_GUID *SignatureGUID;
+
+ CURRENT_VARIABLE_NAME VariableName; // The variable name we are processing.
+ UINT32 ListCount; // Record current variable has how many signature list.
+ UINTN ListIndex; // Record which signature list is processing.
+ BOOLEAN *CheckArray; // Record whcih siganture data checked.jj
} SECUREBOOT_CONFIG_PRIVATE_DATA;
extern SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate;
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
index 6b69f92b26..d112867e58 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
@@ -35,10 +35,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define SECUREBOOT_ENROLL_SIGNATURE_TO_DB 0x0b
#define SECUREBOOT_DELETE_SIGNATURE_FROM_DB 0x0c
#define SECUREBOOT_ENROLL_SIGNATURE_TO_DBX 0x0d
-#define SECUREBOOT_DELETE_SIGNATURE_FROM_DBX 0x0e
#define FORMID_SECURE_BOOT_DBT_OPTION_FORM 0x14
#define SECUREBOOT_ENROLL_SIGNATURE_TO_DBT 0x15
#define SECUREBOOT_DELETE_SIGNATURE_FROM_DBT 0x16
+#define SECUREBOOT_DELETE_SIGNATURE_LIST_FORM 0x17
+#define SECUREBOOT_DELETE_SIGNATURE_DATA_FORM 0x18
#define SECURE_BOOT_MODE_CUSTOM 0x01
#define SECURE_BOOT_MODE_STANDARD 0x00
@@ -57,6 +58,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define KEY_VALUE_SAVE_AND_EXIT_DBT 0x100d
#define KEY_VALUE_NO_SAVE_AND_EXIT_DBT 0x100e
+#define KEY_VALUE_FROM_DBX_TO_LIST_FORM 0x100f
+
#define KEY_SECURE_BOOT_OPTION 0x1100
#define KEY_SECURE_BOOT_PK_OPTION 0x1101
#define KEY_SECURE_BOOT_KEK_OPTION 0x1102
@@ -71,14 +74,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DBX 0x110c
#define KEY_SECURE_BOOT_DBT_OPTION 0x110d
#define KEY_SECURE_BOOT_SIGNATURE_GUID_DBT 0x110e
+#define KEY_SECURE_BOOT_DELETE_ALL_LIST 0x110f
+#define KEY_SECURE_BOOT_DELETE_ALL_DATA 0x1110
+#define KEY_SECURE_BOOT_DELETE_CHECK_DATA 0x1111
#define LABEL_KEK_DELETE 0x1200
#define LABEL_DB_DELETE 0x1201
-#define LABEL_DBX_DELETE 0x1202
+#define LABEL_SIGNATURE_LIST_START 0x1202
#define LABEL_DBT_DELETE 0x1203
+#define LABEL_SIGNATURE_DATA_START 0x1204
+#define LABEL_DELETE_ALL_LIST_BUTTON 0x1300
#define LABEL_END 0xffff
-
#define SECURE_BOOT_MAX_ATTEMPTS_NUM 255
#define CONFIG_OPTION_OFFSET 0x2000
@@ -95,9 +102,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
#define OPTION_DEL_DB_QUESTION_ID 0x3000
//
-// Question ID 0x4000 ~ 0x4FFF is for DBX
+// Question ID 0x4000 ~ 0x4FFF is for signature list.
+//
+#define OPTION_SIGNATURE_LIST_QUESTION_ID 0X4000
+//
+// Question ID 0x6000 ~ 0x6FFF is for signature data.
//
-#define OPTION_DEL_DBX_QUESTION_ID 0x4000
+#define OPTION_SIGNATURE_DATA_QUESTION_ID 0x6000
//
// Question ID 0x5000 ~ 0x5FFF is for DBT
@@ -128,6 +139,8 @@ typedef struct {
EFI_HII_DATE RevocationDate; // The revocation date of the certificate
EFI_HII_TIME RevocationTime; // The revocation time of the certificate
UINT8 FileEnrollType; // File type of sigunature enroll
+ UINT32 ListCount; // The count of signature list.
+ UINT32 CheckedDataCount; // The count of checked signature data.
} SECUREBOOT_CONFIGURATION;
#endif
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
index 320cc79c47..bf42598fa3 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
@@ -29,6 +29,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#string STR_SECURE_BOOT_ENROLL_SIGNATURE #language en-US "Enroll Signature"
#string STR_SECURE_BOOT_DELETE_SIGNATURE #language en-US "Delete Signature"
+#string STR_SECURE_BOOT_DELETE_LIST_FORM #language en-US "Delete Signature List Form"
+#string STR_SECURE_BOOT_DELETE_DATA_FORM #language en-US "Delete Signature Data Form"
+#string STR_SECURE_BOOT_DELETE_ALL_LIST #language en-US "Delete All Signature List"
+#string STR_SECURE_BOOT_DELETE_ALL_DATA #language en-US "Delete All Signature Data"
+#string STR_SECURE_BOOT_DELETE_CHECK_DATA #language en-US "Delete Checked Signature Data"
+#string STR_SECURE_BOOT_DELETE_ALL_DATA_HELP #language en-US "All signature data will be deleted, no matter how many signature data have you checked."
+#string STR_SECURE_BOOT_DELETE_CHECK_DATA_HELP #language en-US "All checked signature data will be deleted."
#string STR_SECURE_BOOT_SIGNATURE_GUID #language en-US "Signature GUID"
#string STR_SECURE_BOOT_SIGNATURE_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format."
@@ -114,3 +121,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#string STR_CERT_TYPE_X509_SHA256_GUID #language en-US "X509_SHA256_GUID"
#string STR_CERT_TYPE_X509_SHA384_GUID #language en-US "X509_SHA384_GUID"
#string STR_CERT_TYPE_X509_SHA512_GUID #language en-US "X509_SHA512_GUID"
+
+#string STR_LIST_TYPE_RSA2048_SHA256 #language en-US "RSA2048_SHA256"
+#string STR_LIST_TYPE_X509 #language en-US "X509"
+#string STR_LIST_TYPE_SHA1 #language en-US "SHA1"
+#string STR_LIST_TYPE_SHA256 #language en-US "SHA256"
+#string STR_LIST_TYPE_X509_SHA256 #language en-US "X509_SHA256"
+#string STR_LIST_TYPE_X509_SHA384 #language en-US "X509_SHA384"
+#string STR_LIST_TYPE_X509_SHA512 #language en-US "X509_SHA512"
+#string STR_LIST_TYPE_UNKNOWN #language en-US "UnKnown"
+
+#string STR_SIGNATURE_LIST_NAME_FORMAT #language en-US "Signature List, Entry-%d"
+#string STR_SIGNATURE_DATA_NAME_FORMAT #language en-US "Signature Data, Entry-%d"
+#string STR_SIGNATURE_LIST_HELP_FORMAT #language en-US "List Type:\n %s\n\nEntry Number:\n %d"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_GUID #language en-US "Owner GUID:\n%s\n\n"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_CN #language en-US "%s(%d bytes):\nCN = %s\n"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_HASH #language en-US "%s(%d bytes):\n%s\n"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_TIME #language en-US "Revocation Time:\n%s"
+
+#string STR_SIGNATURE_DELETE_ALL_CONFIRM #language en-US "Press 'Y' to delete all signature List."
--
2.13.2.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Reviewed-by: Chao Zhang <chao.b.zhang@intel.com> -----Original Message----- From: Chen, Chen A Sent: Friday, September 22, 2017 9:07 AM To: edk2-devel@lists.01.org Cc: Chen, Chen A <chen.a.chen@intel.com>; Zhang, Chao B <chao.b.zhang@intel.com>; Long, Qin <qin.long@intel.com> Subject: [PATCH] SecurityPkg/SecureBootConfigImpl.c: Secure Boot DBX UI Enhancement. Use 2-level format to display signature list and signature data. Support batch delete operation to delete signature list or signature data. Display more useful information for each signature data. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chen A Chen <chen.a.chen@intel.com> Cc: Zhang Chao B <chao.b.zhang@intel.com> Cc: Long Qin <qin.long@intel.com> --- .../SecureBootConfigDxe/SecureBootConfig.vfr | 53 +- .../SecureBootConfigDxe/SecureBootConfigImpl.c | 1036 +++++++++++++++++++- .../SecureBootConfigDxe/SecureBootConfigImpl.h | 35 + .../SecureBootConfigDxe/SecureBootConfigNvData.h | 23 +- .../SecureBootConfigStrings.uni | 26 + 5 files changed, 1144 insertions(+), 29 deletions(-) diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr index bbecff2b08..296b9c9b9e 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCo +++ nfig.vfr @@ -316,11 +316,11 @@ formset subtitle text = STRING_TOKEN(STR_NULL); - goto SECUREBOOT_DELETE_SIGNATURE_FROM_DBX, + goto SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, prompt = STRING_TOKEN (STR_SECURE_BOOT_DELETE_SIGNATURE), help = STRING_TOKEN (STR_SECURE_BOOT_DELETE_SIGNATURE), flags = INTERACTIVE, - key = SECUREBOOT_DELETE_SIGNATURE_FROM_DBX; + key = KEY_VALUE_FROM_DBX_TO_LIST_FORM; endform; @@ -360,17 +360,58 @@ formset endform; // - // Form: 'Delete Signature' for DBX Options. + // Form: Display Signature List. // - form formid = SECUREBOOT_DELETE_SIGNATURE_FROM_DBX, - title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_SIGNATURE); + form formid = SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_LIST_FORM); + + subtitle text = STRING_TOKEN(STR_NULL); + + grayoutif ideqval SECUREBOOT_CONFIGURATION.ListCount == 0; + label LABEL_DELETE_ALL_LIST_BUTTON; + // + // Will create a goto button dynamically here. + // + label LABEL_END; + endif; + + subtitle text = STRING_TOKEN(STR_NULL); + label LABEL_SIGNATURE_LIST_START; + label LABEL_END; + subtitle text = STRING_TOKEN(STR_NULL); - label LABEL_DBX_DELETE; + endform; + + // + // Form: Display Signature Data. + // + form formid = SECUREBOOT_DELETE_SIGNATURE_DATA_FORM, + title = STRING_TOKEN(STR_SECURE_BOOT_DELETE_DATA_FORM); + + subtitle text = STRING_TOKEN(STR_NULL); + + goto SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + prompt = STRING_TOKEN(STR_SECURE_BOOT_DELETE_ALL_DATA), + help = STRING_TOKEN(STR_SECURE_BOOT_DELETE_ALL_DATA_HELP), + flags = INTERACTIVE, + key = KEY_SECURE_BOOT_DELETE_ALL_DATA; + + grayoutif ideqval SECUREBOOT_CONFIGURATION.CheckedDataCount == 0; + goto SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + prompt = STRING_TOKEN(STR_SECURE_BOOT_DELETE_CHECK_DATA), + help = STRING_TOKEN(STR_SECURE_BOOT_DELETE_CHECK_DATA_HELP), + flags = INTERACTIVE, + key = KEY_SECURE_BOOT_DELETE_CHECK_DATA; + endif; + + subtitle text = STRING_TOKEN(STR_NULL); + label LABEL_SIGNATURE_DATA_START; label LABEL_END; subtitle text = STRING_TOKEN(STR_NULL); endform; + // // Form: 'Delete Signature' for DBT Options. // diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index 2eaf24633d..3df1f431a9 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCo +++ nfigImpl.c @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "SecureBootConfigImpl.h" +#include <Library/BaseCryptLib.h> CHAR16 mSecureBootStorageName[] = L"SECUREBOOT_CONFIGURATION"; @@ -3051,6 +3052,184 @@ ON_EXIT: } /** + This function to delete signature list or data, according by DelType. + + @param[in] PrivateData Module's private data. + @param[in] DelType Indicate delete signature list or data. + @param[in] CheckedCount Indicate how many signature data have + been checked in current signature list. + + @retval EFI_SUCCESS Success to update the signature list page + @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources. +**/ +EFI_STATUS +DeleteSignatureEx ( + IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, + IN SIGNATURE_DELETE_TYPE DelType, + IN UINT32 CheckedCount + ) +{ + EFI_STATUS Status; + EFI_SIGNATURE_LIST *ListWalker; + EFI_SIGNATURE_LIST *NewCertList; + EFI_SIGNATURE_DATA *DataWalker; + CHAR16 *VariableName; + UINT32 VariableAttr; + UINTN VariableDataSize; + UINTN RemainingSize; + UINTN ListIndex; + UINTN Index; + UINTN Offset; + UINT8 *VariableData; + UINT8 *NewVariableData; + + Status = EFI_SUCCESS; + VariableName = NULL; + VariableAttr = 0; + VariableDataSize = 0; + ListIndex = 0; + Offset = 0; + VariableData = NULL; + NewVariableData = NULL; + + VariableName = AllocateZeroPool (100); if (VariableName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + if (PrivateData->VariableName == VARIABLE_DB) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE); } + else if (PrivateData->VariableName == VARIABLE_DBX) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE1); } + else if (PrivateData->VariableName == VARIABLE_DBT) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE2); } + else { + goto ON_EXIT; + } + + Status = gRT->GetVariable ( + VariableName, + &gEfiImageSecurityDatabaseGuid, + &VariableAttr, + &VariableDataSize, + VariableData + ); + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + goto ON_EXIT; + } + + VariableData = AllocateZeroPool (VariableDataSize); if (VariableData + == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Status = gRT->GetVariable ( + VariableName, + &gEfiImageSecurityDatabaseGuid, + &VariableAttr, + &VariableDataSize, + VariableData + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE); if (EFI_ERROR + (Status)) { + goto ON_EXIT; + } + + NewVariableData = AllocateZeroPool (VariableDataSize); if + (NewVariableData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + RemainingSize = VariableDataSize; + ListWalker = (EFI_SIGNATURE_LIST *)(VariableData); if (DelType == + DELETE_SIGNATURE_LIST_ALL) { + VariableDataSize = 0; + } else { + while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex < PrivateData->ListIndex) { + CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, ListWalker->SignatureListSize); + Offset += ListWalker->SignatureListSize; + + RemainingSize -= ListWalker->SignatureListSize; + ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize); + ListIndex++; + } + + if (CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) || DelType == DELETE_SIGNATURE_LIST_ONE) { + RemainingSize -= ListWalker->SignatureListSize; + ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize); + } else { + NewCertList = (EFI_SIGNATURE_LIST *)(NewVariableData + Offset); + // + // Copy header. + // + CopyMem ((UINT8 *)NewVariableData, ListWalker, sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize); + Offset += sizeof (EFI_SIGNATURE_LIST) + + ListWalker->SignatureHeaderSize; + + DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof(EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize); + for (Index = 0; Index < SIGNATURE_DATA_COUNTS(ListWalker); Index = Index + 1) { + if (PrivateData->CheckArray[Index]) { + // + // Delete checked siganture data, and update the size of whole signature list. + // + NewCertList->SignatureListSize -= NewCertList->SignatureSize; + } else { + // + // Remain the unchecked signature data. + // + CopyMem ((UINT8 *)NewVariableData + Offset, DataWalker, ListWalker->SignatureSize); + Offset += ListWalker->SignatureSize; + } + DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize); + } + + RemainingSize -= ListWalker->SignatureListSize; + } + + // + // Copy remaining data, maybe 0. + // + CopyMem((UINT8 *)NewVariableData + Offset, ListWalker, RemainingSize); + Offset += RemainingSize; + + VariableDataSize = Offset; + } + + if ((VariableAttr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { + Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status)); + goto ON_EXIT; + } + } + + Status = gRT->SetVariable ( + VariableName, + &gEfiImageSecurityDatabaseGuid, + VariableAttr, + VariableDataSize, + NewVariableData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r", Status)); + goto ON_EXIT; + } + +ON_EXIT: + SECUREBOOT_FREE_NON_NULL (VariableName); + SECUREBOOT_FREE_NON_NULL (VariableData); + SECUREBOOT_FREE_NON_NULL (NewVariableData); + + return Status; +} + +/** Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT and STR_CUR_SECURE_BOOT_MODE_CONTENT. @@ -3381,6 +3560,731 @@ SecureBootRouteConfig ( } /** + This function to load signature list, the update the menu page. + + @param[in] PrivateData Module's private data. + @param[in] LabelId 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. +**/ +EFI_STATUS +LoadSignatureList ( + IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, + IN UINT16 LabelId, + IN EFI_FORM_ID FormId, + IN EFI_QUESTION_ID QuestionIdBase + ) +{ + EFI_STATUS Status; + EFI_STRING_ID ListType; + EFI_SIGNATURE_LIST *ListWalker; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + EFI_IFR_GUID_LABEL *StartGoto; + EFI_IFR_GUID_LABEL *EndGoto; + EFI_FORM_ID DstFormId; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + VOID *StartGotoHandle; + VOID *EndGotoHandle; + UINTN DataSize; + UINTN RemainingSize; + UINT16 Index; + UINT8 *VariableData; + CHAR16 *VariableName; + CHAR16 *NameBuffer; + CHAR16 *HelpBuffer; + + Status = EFI_SUCCESS; + StartOpCodeHandle = NULL; + EndOpCodeHandle = NULL; + Index = 0; + VariableData = NULL; + VariableName = NULL; + NameBuffer = NULL; + HelpBuffer = NULL; + + // + // Initialize the container for dynamic opcodes. + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); if + (StartOpCodeHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); if (EndOpCodeHandle == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + StartGotoHandle = HiiAllocateOpCodeHandle (); if (StartGotoHandle == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + EndGotoHandle = HiiAllocateOpCodeHandle (); if (EndGotoHandle == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Create Hii Extend Label OpCode. + // + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); StartLabel->ExtendOpCode = + EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LabelId; + + EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + + StartGoto = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode( + StartGotoHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof(EFI_IFR_GUID_LABEL) + ); + StartGoto->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartGoto->Number = LABEL_DELETE_ALL_LIST_BUTTON; + + EndGoto = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode( + EndGotoHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof(EFI_IFR_GUID_LABEL) + ); + EndGoto->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndGoto->Number = + LABEL_END; + + VariableName = AllocateZeroPool (100); if (VariableName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + if (PrivateData->VariableName == VARIABLE_DB) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE); + DstFormId = FORMID_SECURE_BOOT_DB_OPTION_FORM; + } else if (PrivateData->VariableName == VARIABLE_DBX) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE1); + DstFormId = FORMID_SECURE_BOOT_DBX_OPTION_FORM; + } else if (PrivateData->VariableName == VARIABLE_DBT) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE2); + DstFormId = FORMID_SECURE_BOOT_DBT_OPTION_FORM; + } else { + goto ON_EXIT; + } + + HiiCreateGotoOpCode ( + StartGotoHandle, + DstFormId, + STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST), + STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST), + EFI_IFR_FLAG_CALLBACK, + KEY_SECURE_BOOT_DELETE_ALL_LIST + ); + + // + // Read Variable, the variable name save in the PrivateData->VariableName. + // + DataSize = 0; + Status = gRT->GetVariable (VariableName, + &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData); if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + goto ON_EXIT; + } + + VariableData = AllocateZeroPool (DataSize); if (VariableData == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + Status = gRT->GetVariable (VariableName, + &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData); if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + NameBuffer = AllocateZeroPool (100); + if (NameBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + HelpBuffer = AllocateZeroPool (100); + if (HelpBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + RemainingSize = DataSize; + ListWalker = (EFI_SIGNATURE_LIST *)VariableData; + while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) { + if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256); + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_X509); + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1); + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256); + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256); + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA384); + } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha512Guid)) { + ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA512); + } else { + ListType = STRING_TOKEN (STR_LIST_TYPE_UNKNOWN); + } + + UnicodeSPrint (NameBuffer, + 100, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_NAME_FORMAT), NULL), + Index + 1 + ); + UnicodeSPrint (HelpBuffer, + 100, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT), NULL), + HiiGetString (PrivateData->HiiHandle, ListType, NULL), + SIGNATURE_DATA_COUNTS (ListWalker) + ); + + HiiCreateGotoOpCode ( + StartOpCodeHandle, + SECUREBOOT_DELETE_SIGNATURE_DATA_FORM, + HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL), + HiiSetString (PrivateData->HiiHandle, 0, HelpBuffer, NULL), + EFI_IFR_FLAG_CALLBACK, + QuestionIdBase + Index++ + ); + + ZeroMem (NameBuffer, 100); + ZeroMem (HelpBuffer, 100); + + RemainingSize -= ListWalker->SignatureListSize; + ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + + ListWalker->SignatureListSize); } + +ON_EXIT: + HiiUpdateForm ( + PrivateData->HiiHandle, + &gSecureBootConfigFormSetGuid, + FormId, + StartOpCodeHandle, + EndOpCodeHandle + ); + + HiiUpdateForm ( + PrivateData->HiiHandle, + &gSecureBootConfigFormSetGuid, + FormId, + StartGotoHandle, + EndGotoHandle + ); + + SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle); + SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle); + SECUREBOOT_FREE_NON_OPCODE (StartGotoHandle); + SECUREBOOT_FREE_NON_OPCODE (EndGotoHandle); + + SECUREBOOT_FREE_NON_NULL (VariableName); SECUREBOOT_FREE_NON_NULL + (VariableData); SECUREBOOT_FREE_NON_NULL (NameBuffer); + SECUREBOOT_FREE_NON_NULL (HelpBuffer); + + PrivateData->ListCount = Index; + + return Status; +} + +/** + Parse hash value from EFI_SIGANTURE_DATA, and save in the CHAR16 type array. + The buffer is callee allocated and should be freed by the caller. + + @param[in] ListEntry The pointer point to the signature list. + @param[in] DataEntry The signature data we are processing. + @param[out] BufferToReturn Buffer to save the hash value. + + @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_SUCCESS Operation success. +**/ +EFI_STATUS +ParseHashValue ( + IN EFI_SIGNATURE_LIST *ListEntry, + IN EFI_SIGNATURE_DATA *DataEntry, + OUT CHAR16 **BufferToReturn + ) +{ + UINTN Index; + UINTN BufferIndex; + UINTN TotalSize; + UINTN DataSize; + UINTN Line; + UINTN OneLineBytes; + + // + // Assume that, display 8 bytes in one line. + // + OneLineBytes = 8; + + if (ListEntry == NULL || DataEntry == NULL || BufferToReturn == NULL) { + return EFI_INVALID_PARAMETER; + } + + DataSize = ListEntry->SignatureSize - sizeof(EFI_GUID); Line = + (DataSize + OneLineBytes - 1) / OneLineBytes; + + // + // Each byte will split two Hex-number, and each line need additional memory to save '\r\n'. + // + TotalSize = ((DataSize + Line) * 2 * sizeof(CHAR16)); + + *BufferToReturn = AllocateZeroPool(TotalSize); if (*BufferToReturn + == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0, BufferIndex = 0; Index < DataSize; Index = Index + 1) { + if ((Index > 0) && (Index % OneLineBytes == 0)) { + BufferIndex += UnicodeSPrint(&(*BufferToReturn)[BufferIndex], TotalSize - sizeof(CHAR16) * BufferIndex, L"\n"); + } + BufferIndex += UnicodeSPrint(&(*BufferToReturn)[BufferIndex], + TotalSize - sizeof(CHAR16) * BufferIndex, L"%02x", + DataEntry->SignatureData[Index]); } BufferIndex += + UnicodeSPrint(&(*BufferToReturn)[BufferIndex], TotalSize - + sizeof(CHAR16) * BufferIndex, L"\n"); + + return EFI_SUCCESS; +} + +/** + Function to get the common name from the X509 format certificate. + The buffer is callee allocated and should be freed by the caller. + + @param[in] ListEntry The pointer point to the signature list. + @param[in] DataEntry The signature data we are processing. + @param[out] BufferToReturn Buffer to save the CN of X509 certificate. + + @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval EFI_SUCCESS Operation success. + @retval EFI_NOT_FOUND Not found CN field in the X509 certificate. +**/ +EFI_STATUS +GetCommonNameFromX509 ( + IN EFI_SIGNATURE_LIST *ListEntry, + IN EFI_SIGNATURE_DATA *DataEntry, + OUT CHAR16 **BufferToReturn + ) +{ + EFI_STATUS Status; + UINT8 *CNBuffer; + + Status = EFI_SUCCESS; + CNBuffer = NULL; + + CNBuffer = AllocateZeroPool(256); + if (CNBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + X509GetCommonName ( + (UINT8 *)DataEntry + sizeof(EFI_GUID), + ListEntry->SignatureSize - sizeof(EFI_GUID), + CNBuffer, + 256 + ); + + *BufferToReturn = AllocateZeroPool(256 * sizeof(CHAR16)); if + (*BufferToReturn == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + AsciiStrToUnicodeStrS (CNBuffer, *BufferToReturn, 256); + +ON_EXIT: + SECUREBOOT_FREE_NON_NULL (CNBuffer); + + return Status; +} + +/** + Format the help info for the signature data, each help info contain 3 parts. + 1. Onwer Guid. + 2. Content, depends on the type of the signature list. + 3. Revocation time. + + @param[in] PrivateData Module's private data. + @param[in] ListEntry Point to the signature list. + @param[in] DataEntry Point to the siganture data we are processing. + @param[out] StringId Save the string id of help info. + + @retval EFI_SUCCESS Operation success. + @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources. +**/ +EFI_STATUS +FormatHelpInfo ( + IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, + IN EFI_SIGNATURE_LIST *ListEntry, + IN EFI_SIGNATURE_DATA *DataEntry, + OUT EFI_STRING_ID *StringId + ) +{ + EFI_STATUS Status; + EFI_TIME *Time; + EFI_STRING_ID ListTypeId; + UINTN DataSize; + UINTN HelpInfoIndex; + UINTN TotalSize; + CHAR16 *GuidString; + CHAR16 *DataString; + CHAR16 *TimeString; + CHAR16 *HelpInfoString; + BOOLEAN IsCert; + + Status = EFI_SUCCESS; + Time = NULL; + HelpInfoIndex = 0; + GuidString = NULL; + DataString = NULL; + TimeString = NULL; + HelpInfoString = NULL; + IsCert = FALSE; + + if (CompareGuid(&ListEntry->SignatureType, &gEfiCertRsa2048Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_RSA2048_SHA256); + DataSize = ListEntry->SignatureSize - sizeof(EFI_GUID); + IsCert = TRUE; + } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509); + DataSize = ListEntry->SignatureSize - sizeof(EFI_GUID); + IsCert = TRUE; + } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertSha1Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA1); + DataSize = 20; + } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertSha256Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA256); + DataSize = 32; + } else if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA256); + DataSize = 32; + Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize); } else + if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Sha384Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA384); + DataSize = 48; + Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize); } else + if (CompareGuid(&ListEntry->SignatureType, &gEfiCertX509Sha512Guid)) { + ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA512); + DataSize = 64; + Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize); } else { + Status = EFI_UNSUPPORTED; + goto ON_EXIT; + } + + GuidString = AllocateZeroPool (100); + if (GuidString == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + TotalSize = 1024; + HelpInfoString = AllocateZeroPool (TotalSize); if (HelpInfoString == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Format GUID part. + // + GuidToString(&DataEntry->SignatureOwner, GuidString, 100); + HelpInfoIndex += UnicodeSPrint ( + &HelpInfoString[HelpInfoIndex], + TotalSize - sizeof(CHAR16) * HelpInfoIndex, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID), NULL), + GuidString + ); + + // + // Format content part, it depends on the type of signature list, hash value or CN. + // + if (IsCert) { + GetCommonNameFromX509 (ListEntry, DataEntry, &DataString); + HelpInfoIndex += UnicodeSPrint( + &HelpInfoString[HelpInfoIndex], + TotalSize - sizeof(CHAR16) * HelpInfoIndex, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_CN), NULL), + HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL), + DataSize, + DataString + ); + } else { + // + // Format hash value for each signature data entry. + // + ParseHashValue (ListEntry, DataEntry, &DataString); + HelpInfoIndex += UnicodeSPrint ( + &HelpInfoString[HelpInfoIndex], + TotalSize - sizeof(CHAR16) * HelpInfoIndex, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH), NULL), + HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL), + DataSize, + DataString + ); + } + + // + // Format revocation time part. + // + if (Time != NULL) { + TimeString = AllocateZeroPool(100); + if (TimeString == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + UnicodeSPrint ( + TimeString, + 100, + L"%d-%d-%d %d:%d:%d", + Time->Year, + Time->Month, + Time->Day, + Time->Hour, + Time->Minute, + Time->Second + ); + + UnicodeSPrint ( + &HelpInfoString[HelpInfoIndex], + TotalSize - sizeof (CHAR16) * HelpInfoIndex, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME), NULL), + TimeString + ); + } + + *StringId = HiiSetString (PrivateData->HiiHandle, 0, HelpInfoString, + NULL); + +ON_EXIT: + SECUREBOOT_FREE_NON_NULL (GuidString); + SECUREBOOT_FREE_NON_NULL (DataString); + SECUREBOOT_FREE_NON_NULL (TimeString); + SECUREBOOT_FREE_NON_NULL (HelpInfoString); + + return Status; +} + +/** + This functino to load signature data under the signature list. + + @param[in] PrivateData Module's private data. + @param[in] LabelId 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] ListIndex Indicate to load which signature list. + + @retval EFI_SUCCESS Success to update the signature list page + @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources. +**/ +EFI_STATUS +LoadSignatureData ( + IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, + IN UINT16 LabelId, + IN EFI_FORM_ID FormId, + IN EFI_QUESTION_ID QuestionIdBase, + IN UINT16 ListIndex + ) +{ + EFI_STATUS Status; + EFI_SIGNATURE_LIST *ListWalker; + EFI_SIGNATURE_DATA *DataWalker; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + EFI_STRING_ID HelpStringId; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + UINTN DataSize; + UINTN RemainingSize; + UINT16 Index; + UINT8 *VariableData; + CHAR16 *VariableName; + CHAR16 *NameBuffer; + + Status = EFI_SUCCESS; + StartOpCodeHandle = NULL; + EndOpCodeHandle = NULL; + Index = 0; + VariableData = NULL; + VariableName = NULL; + NameBuffer = NULL; + + // + // Initialize the container for dynamic opcodes. + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); if + (StartOpCodeHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); if (EndOpCodeHandle == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Create Hii Extend Label OpCode. + // + StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); StartLabel->ExtendOpCode = + EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LabelId; + + EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + + VariableName = AllocateZeroPool (100); if (VariableName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + if (PrivateData->VariableName == VARIABLE_DB) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE); } + else if (PrivateData->VariableName == VARIABLE_DBX) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE1); } + else if (PrivateData->VariableName == VARIABLE_DBT) { + UnicodeSPrint (VariableName, 100, EFI_IMAGE_SECURITY_DATABASE2); } + else { + goto ON_EXIT; + } + + // + // Read Variable, the variable name save in the PrivateData->VariableName. + // + DataSize = 0; + Status = gRT->GetVariable (VariableName, + &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData); if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + goto ON_EXIT; + } + + VariableData = AllocateZeroPool (DataSize); if (VariableData == + NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + Status = gRT->GetVariable (VariableName, + &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData); if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + NameBuffer = AllocateZeroPool (100); + if (NameBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + RemainingSize = DataSize; + ListWalker = (EFI_SIGNATURE_LIST *)VariableData; + + // + // Skip signature list. + // + while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex-- > 0) { + RemainingSize -= ListWalker->SignatureListSize; + ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + + ListWalker->SignatureListSize); } + + DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + + sizeof(EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize); for (Index = 0; Index < SIGNATURE_DATA_COUNTS(ListWalker); Index = Index + 1) { + // + // Format name buffer. + // + UnicodeSPrint (NameBuffer, + 100, + HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_NAME_FORMAT), NULL), + Index + 1 + ); + + // + // Format help info buffer. + // + Status = FormatHelpInfo (PrivateData, ListWalker, DataWalker, &HelpStringId); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, + (EFI_QUESTION_ID)(QuestionIdBase + Index), + 0, + 0, + HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL), + HelpStringId, + EFI_IFR_FLAG_CALLBACK, + 0, + NULL + ); + + ZeroMem(NameBuffer, 100); + DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + + ListWalker->SignatureSize); } + + // + // Allocate a buffer to record which signature data will be checked. + // This memory buffer will be freed when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form. + // + PrivateData->CheckArray = AllocateZeroPool (SIGNATURE_DATA_COUNTS + (ListWalker) * sizeof (BOOLEAN)); + +ON_EXIT: + HiiUpdateForm ( + PrivateData->HiiHandle, + &gSecureBootConfigFormSetGuid, + FormId, + StartOpCodeHandle, + EndOpCodeHandle + ); + + SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle); + SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle); + + SECUREBOOT_FREE_NON_NULL (VariableName); SECUREBOOT_FREE_NON_NULL + (VariableData); SECUREBOOT_FREE_NON_NULL (NameBuffer); + + return Status; +} + +/** This function is called to provide results data to the driver. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @@ -3474,6 +4378,13 @@ SecureBootCallback ( (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) || (QuestionId == KEY_SECURE_BOOT_DBT_OPTION)) { CloseEnrolledFile(Private->FileContext); + } else if (QuestionId == KEY_SECURE_BOOT_DELETE_ALL_LIST) { + // + // Update ListCount field in varstore + // Button "Delete All Signature List" is + // enable when ListCount is greater than 0. + // + IfrNvData->ListCount = Private->ListCount; } } goto EXIT; @@ -3665,16 +4576,89 @@ SecureBootCallback ( ); break; - case SECUREBOOT_DELETE_SIGNATURE_FROM_DBX: - UpdateDeletePage ( + // + // From DBX option to the level-1 form, display signature list. + // + case KEY_VALUE_FROM_DBX_TO_LIST_FORM: + Private->VariableName = VARIABLE_DBX; + LoadSignatureList ( Private, - EFI_IMAGE_SECURITY_DATABASE1, - &gEfiImageSecurityDatabaseGuid, - LABEL_DBX_DELETE, - SECUREBOOT_DELETE_SIGNATURE_FROM_DBX, - OPTION_DEL_DBX_QUESTION_ID - ); + LABEL_SIGNATURE_LIST_START, + SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + OPTION_SIGNATURE_LIST_QUESTION_ID + ); + break; + // + // Delete all signature list and reload. + // + case KEY_SECURE_BOOT_DELETE_ALL_LIST: + CreatePopUp( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Press 'Y' to delete signature list.", + L"Press other key to cancel and exit.", + NULL + ); + + if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') { + DeleteSignatureEx (Private, DELETE_SIGNATURE_LIST_ALL, IfrNvData->CheckedDataCount); + } + + LoadSignatureList ( + Private, + LABEL_SIGNATURE_LIST_START, + SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + OPTION_SIGNATURE_LIST_QUESTION_ID + ); + break; + + // + // Delete one signature list and reload. + // + case KEY_SECURE_BOOT_DELETE_ALL_DATA: + CreatePopUp( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Press 'Y' to delete signature data.", + L"Press other key to cancel and exit.", + NULL + ); + + if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') { + DeleteSignatureEx (Private, DELETE_SIGNATURE_LIST_ONE, IfrNvData->CheckedDataCount); + } + + LoadSignatureList ( + Private, + LABEL_SIGNATURE_LIST_START, + SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + OPTION_SIGNATURE_LIST_QUESTION_ID + ); + break; + + // + // Delete checked signature data and reload. + // + case KEY_SECURE_BOOT_DELETE_CHECK_DATA: + CreatePopUp( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Press 'Y' to delete signature data.", + L"Press other key to cancel and exit.", + NULL + ); + + if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') { + DeleteSignatureEx (Private, DELETE_SIGNATURE_DATA, IfrNvData->CheckedDataCount); + } + + LoadSignatureList ( + Private, + LABEL_SIGNATURE_LIST_START, + SECUREBOOT_DELETE_SIGNATURE_LIST_FORM, + OPTION_SIGNATURE_LIST_QUESTION_ID + ); break; case SECUREBOOT_DELETE_SIGNATURE_FROM_DBT: @@ -3799,17 +4783,25 @@ SecureBootCallback ( OPTION_DEL_DB_QUESTION_ID, QuestionId - OPTION_DEL_DB_QUESTION_ID ); - } else if ((QuestionId >= OPTION_DEL_DBX_QUESTION_ID) && - (QuestionId < (OPTION_DEL_DBX_QUESTION_ID + OPTION_CONFIG_RANGE))) { - DeleteSignature ( + } else if ((QuestionId >= OPTION_SIGNATURE_LIST_QUESTION_ID) && + (QuestionId < (OPTION_SIGNATURE_LIST_QUESTION_ID + OPTION_CONFIG_RANGE))) { + LoadSignatureData ( Private, - EFI_IMAGE_SECURITY_DATABASE1, - &gEfiImageSecurityDatabaseGuid, - LABEL_DBX_DELETE, - SECUREBOOT_DELETE_SIGNATURE_FROM_DBX, - OPTION_DEL_DBX_QUESTION_ID, - QuestionId - OPTION_DEL_DBX_QUESTION_ID - ); + LABEL_SIGNATURE_DATA_START, + SECUREBOOT_DELETE_SIGNATURE_DATA_FORM, + OPTION_SIGNATURE_DATA_QUESTION_ID, + QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID + ); + Private->ListIndex = QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID; + } else if ((QuestionId >= OPTION_SIGNATURE_DATA_QUESTION_ID) && + (QuestionId < (OPTION_SIGNATURE_DATA_QUESTION_ID + OPTION_CONFIG_RANGE))) { + if (Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID]) { + IfrNvData->CheckedDataCount--; + Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = FALSE; + } else { + IfrNvData->CheckedDataCount++; + Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = TRUE; + } } else if ((QuestionId >= OPTION_DEL_DBT_QUESTION_ID) && (QuestionId < (OPTION_DEL_DBT_QUESTION_ID + OPTION_CONFIG_RANGE))) { DeleteSignature ( @@ -3899,6 +4891,14 @@ SecureBootCallback ( if (SecureBootMode != NULL) { FreePool (SecureBootMode); } + + if (QuestionId == KEY_SECURE_BOOT_DELETE_ALL_DATA) { + // + // Free memory when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form. + // + SECUREBOOT_FREE_NON_NULL (Private->CheckArray); + IfrNvData->CheckedDataCount = 0; + } } EXIT: diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h index 75b18f121c..501215cdf5 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCo +++ nfigImpl.h @@ -112,6 +112,23 @@ typedef struct { UINT8 FileType; } SECUREBOOT_FILE_CONTEXT; +#define SECUREBOOT_FREE_NON_NULL(Pointer) \ + do { \ + if ((Pointer) != NULL) { \ + FreePool((Pointer)); \ + (Pointer) = NULL; \ + } \ + } while (FALSE) + +#define SECUREBOOT_FREE_NON_OPCODE(Handle) \ + do{ \ + if ((Handle) != NULL) { \ + HiiFreeOpCodeHandle((Handle)); \ + } \ + } while (FALSE) + +#define SIGNATURE_DATA_COUNTS(List) \ + (((List)->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - +(List)->SignatureHeaderSize) / (List)->SignatureSize) // // We define another format of 5th directory entry: security directory @@ -134,6 +151,19 @@ typedef struct { EFI_DEVICE_PATH_PROTOCOL End; } HII_VENDOR_DEVICE_PATH; +typedef enum { + VARIABLE_DB, + VARIABLE_DBX, + VARIABLE_DBT, + VARIABLE_MAX +} CURRENT_VARIABLE_NAME; + +typedef enum { + DELETE_SIGNATURE_LIST_ALL, + DELETE_SIGNATURE_LIST_ONE, + DELETE_SIGNATURE_DATA +}SIGNATURE_DELETE_TYPE; + typedef struct { UINTN Signature; @@ -144,6 +174,11 @@ typedef struct { SECUREBOOT_FILE_CONTEXT *FileContext; EFI_GUID *SignatureGUID; + + CURRENT_VARIABLE_NAME VariableName; // The variable name we are processing. + UINT32 ListCount; // Record current variable has how many signature list. + UINTN ListIndex; // Record which signature list is processing. + BOOLEAN *CheckArray; // Record whcih siganture data checked.jj } SECUREBOOT_CONFIG_PRIVATE_DATA; extern SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate; diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h index 6b69f92b26..d112867e58 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCo +++ nfigNvData.h @@ -35,10 +35,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define SECUREBOOT_ENROLL_SIGNATURE_TO_DB 0x0b #define SECUREBOOT_DELETE_SIGNATURE_FROM_DB 0x0c #define SECUREBOOT_ENROLL_SIGNATURE_TO_DBX 0x0d -#define SECUREBOOT_DELETE_SIGNATURE_FROM_DBX 0x0e #define FORMID_SECURE_BOOT_DBT_OPTION_FORM 0x14 #define SECUREBOOT_ENROLL_SIGNATURE_TO_DBT 0x15 #define SECUREBOOT_DELETE_SIGNATURE_FROM_DBT 0x16 +#define SECUREBOOT_DELETE_SIGNATURE_LIST_FORM 0x17 #define +SECUREBOOT_DELETE_SIGNATURE_DATA_FORM 0x18 #define SECURE_BOOT_MODE_CUSTOM 0x01 #define SECURE_BOOT_MODE_STANDARD 0x00 @@ -57,6 +58,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define KEY_VALUE_SAVE_AND_EXIT_DBT 0x100d #define KEY_VALUE_NO_SAVE_AND_EXIT_DBT 0x100e +#define KEY_VALUE_FROM_DBX_TO_LIST_FORM 0x100f + #define KEY_SECURE_BOOT_OPTION 0x1100 #define KEY_SECURE_BOOT_PK_OPTION 0x1101 #define KEY_SECURE_BOOT_KEK_OPTION 0x1102 @@ -71,14 +74,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define KEY_SECURE_BOOT_SIGNATURE_GUID_DBX 0x110c #define KEY_SECURE_BOOT_DBT_OPTION 0x110d #define KEY_SECURE_BOOT_SIGNATURE_GUID_DBT 0x110e +#define KEY_SECURE_BOOT_DELETE_ALL_LIST 0x110f +#define KEY_SECURE_BOOT_DELETE_ALL_DATA 0x1110 +#define KEY_SECURE_BOOT_DELETE_CHECK_DATA 0x1111 #define LABEL_KEK_DELETE 0x1200 #define LABEL_DB_DELETE 0x1201 -#define LABEL_DBX_DELETE 0x1202 +#define LABEL_SIGNATURE_LIST_START 0x1202 #define LABEL_DBT_DELETE 0x1203 +#define LABEL_SIGNATURE_DATA_START 0x1204 +#define LABEL_DELETE_ALL_LIST_BUTTON 0x1300 #define LABEL_END 0xffff - #define SECURE_BOOT_MAX_ATTEMPTS_NUM 255 #define CONFIG_OPTION_OFFSET 0x2000 @@ -95,9 +102,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // #define OPTION_DEL_DB_QUESTION_ID 0x3000 // -// Question ID 0x4000 ~ 0x4FFF is for DBX +// Question ID 0x4000 ~ 0x4FFF is for signature list. +// +#define OPTION_SIGNATURE_LIST_QUESTION_ID 0X4000 +// +// Question ID 0x6000 ~ 0x6FFF is for signature data. // -#define OPTION_DEL_DBX_QUESTION_ID 0x4000 +#define OPTION_SIGNATURE_DATA_QUESTION_ID 0x6000 // // Question ID 0x5000 ~ 0x5FFF is for DBT @@ -128,6 +139,8 @@ typedef struct { EFI_HII_DATE RevocationDate; // The revocation date of the certificate EFI_HII_TIME RevocationTime; // The revocation time of the certificate UINT8 FileEnrollType; // File type of sigunature enroll + UINT32 ListCount; // The count of signature list. + UINT32 CheckedDataCount; // The count of checked signature data. } SECUREBOOT_CONFIGURATION; #endif diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni index 320cc79c47..bf42598fa3 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootCo +++ nfigStrings.uni @@ -29,6 +29,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #string STR_SECURE_BOOT_ENROLL_SIGNATURE #language en-US "Enroll Signature" #string STR_SECURE_BOOT_DELETE_SIGNATURE #language en-US "Delete Signature" +#string STR_SECURE_BOOT_DELETE_LIST_FORM #language en-US "Delete Signature List Form" +#string STR_SECURE_BOOT_DELETE_DATA_FORM #language en-US "Delete Signature Data Form" +#string STR_SECURE_BOOT_DELETE_ALL_LIST #language en-US "Delete All Signature List" +#string STR_SECURE_BOOT_DELETE_ALL_DATA #language en-US "Delete All Signature Data" +#string STR_SECURE_BOOT_DELETE_CHECK_DATA #language en-US "Delete Checked Signature Data" +#string STR_SECURE_BOOT_DELETE_ALL_DATA_HELP #language en-US "All signature data will be deleted, no matter how many signature data have you checked." +#string STR_SECURE_BOOT_DELETE_CHECK_DATA_HELP #language en-US "All checked signature data will be deleted." #string STR_SECURE_BOOT_SIGNATURE_GUID #language en-US "Signature GUID" #string STR_SECURE_BOOT_SIGNATURE_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format." @@ -114,3 +121,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #string STR_CERT_TYPE_X509_SHA256_GUID #language en-US "X509_SHA256_GUID" #string STR_CERT_TYPE_X509_SHA384_GUID #language en-US "X509_SHA384_GUID" #string STR_CERT_TYPE_X509_SHA512_GUID #language en-US "X509_SHA512_GUID" + +#string STR_LIST_TYPE_RSA2048_SHA256 #language en-US "RSA2048_SHA256" +#string STR_LIST_TYPE_X509 #language en-US "X509" +#string STR_LIST_TYPE_SHA1 #language en-US "SHA1" +#string STR_LIST_TYPE_SHA256 #language en-US "SHA256" +#string STR_LIST_TYPE_X509_SHA256 #language en-US "X509_SHA256" +#string STR_LIST_TYPE_X509_SHA384 #language en-US "X509_SHA384" +#string STR_LIST_TYPE_X509_SHA512 #language en-US "X509_SHA512" +#string STR_LIST_TYPE_UNKNOWN #language en-US "UnKnown" + +#string STR_SIGNATURE_LIST_NAME_FORMAT #language en-US "Signature List, Entry-%d" +#string STR_SIGNATURE_DATA_NAME_FORMAT #language en-US "Signature Data, Entry-%d" +#string STR_SIGNATURE_LIST_HELP_FORMAT #language en-US "List Type:\n %s\n\nEntry Number:\n %d" +#string STR_SIGNATURE_DATA_HELP_FORMAT_GUID #language en-US "Owner GUID:\n%s\n\n" +#string STR_SIGNATURE_DATA_HELP_FORMAT_CN #language en-US "%s(%d bytes):\nCN = %s\n" +#string STR_SIGNATURE_DATA_HELP_FORMAT_HASH #language en-US "%s(%d bytes):\n%s\n" +#string STR_SIGNATURE_DATA_HELP_FORMAT_TIME #language en-US "Revocation Time:\n%s" + +#string STR_SIGNATURE_DELETE_ALL_CONFIRM #language en-US "Press 'Y' to delete all signature List." -- 2.13.2.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.