SecurityPkg/SecureBootConfigImpl.c: Secure Boot DBX UI Enhancement
authorchenc2 <chen.a.chen@intel.com>
Tue, 26 Sep 2017 00:44:19 +0000 (08:44 +0800)
committerZhang, Chao B <chao.b.zhang@intel.com>
Thu, 28 Sep 2017 07:02:00 +0000 (15:02 +0800)
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
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Reviewed-by: Long Qin <qin.long@intel.com>
Reviewed-by: Zhang Chao B <chao.b.zhang@intel.com>
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni

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