]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
SecurityPkg/SecureBootConfigDxe: Fix deleting signature data issue.
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigImpl.c
index 6f587291e226ed901b58b438fbc5c3ba8923a660..4ec0f8d13a92a9d68bab170412a32488406ab5d9 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
@@ -96,6 +97,31 @@ CHAR16* mSupportX509Suffix = L"*.cer/der/crt";
 \r
 SECUREBOOT_CONFIG_PRIVATE_DATA  *gSecureBootPrivateData = NULL;\r
 \r
+/**\r
+  This code cleans up enrolled file by closing file & free related resources attached to\r
+  enrolled file.\r
+\r
+  @param[in] FileContext            FileContext cached in SecureBootConfig driver\r
+\r
+**/\r
+VOID\r
+CloseEnrolledFile(\r
+  IN SECUREBOOT_FILE_CONTEXT *FileContext\r
+)\r
+{\r
+  if (FileContext->FHandle != NULL) {\r
+    CloseFile (FileContext->FHandle);\r
+    FileContext->FHandle = NULL;\r
+  }\r
+\r
+  if (FileContext->FileName != NULL){\r
+    FreePool(FileContext->FileName);\r
+    FileContext->FileName = NULL;\r
+  }\r
+  FileContext->FileType = UNKNOWN_FILE_TYPE;\r
+\r
+}\r
+\r
 /**\r
   This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.\r
 \r
@@ -119,6 +145,61 @@ IsDerEncodeCertificate (
   return FALSE;\r
 }\r
 \r
+/**\r
+  This code checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format\r
+The function reads file content but won't open/close given FileHandle.\r
+\r
+  @param[in] FileHandle            The FileHandle to be checked\r
+\r
+  @retval    TRUE            The content is EFI_VARIABLE_AUTHENTICATION_2 format.\r
+  @retval    FALSE          The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format.\r
+\r
+**/\r
+BOOLEAN\r
+IsAuthentication2Format (\r
+  IN   EFI_FILE_HANDLE    FileHandle\r
+)\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_VARIABLE_AUTHENTICATION_2  *Auth2;\r
+  BOOLEAN                        IsAuth2Format;\r
+\r
+  IsAuth2Format = FALSE;\r
+\r
+  //\r
+  // Read the whole file content\r
+  //\r
+  Status = ReadFileContent(\r
+             FileHandle,\r
+             (VOID **) &mImageBase,\r
+             &mImageSize,\r
+             0\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)mImageBase;\r
+  if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (CompareGuid(&gEfiCertPkcs7Guid, &Auth2->AuthInfo.CertType)) {\r
+    IsAuth2Format = TRUE;\r
+  }\r
+\r
+ON_EXIT:\r
+  //\r
+  // Do not close File. simply check file content\r
+  //\r
+  if (mImageBase != NULL) {\r
+    FreePool (mImageBase);\r
+    mImageBase = NULL;\r
+  }\r
+\r
+  return IsAuth2Format;\r
+}\r
+\r
 /**\r
   Set Secure Boot option into variable space.\r
 \r
@@ -474,10 +555,7 @@ ON_EXIT:
     FreePool(PkCert);\r
   }\r
 \r
-  if (Private->FileContext->FHandle != NULL) {\r
-    CloseFile (Private->FileContext->FHandle);\r
-    Private->FileContext->FHandle = NULL;\r
-  }\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   return Status;\r
 }\r
@@ -654,13 +732,7 @@ EnrollRsa2048ToKek (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FHandle = NULL;\r
-\r
-  if (Private->FileContext->FileName != NULL){\r
-    FreePool(Private->FileContext->FileName);\r
-    Private->FileContext->FileName = NULL;\r
-  }\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -781,13 +853,7 @@ EnrollX509ToKek (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  if (Private->FileContext->FileName != NULL){\r
-    FreePool(Private->FileContext->FileName);\r
-    Private->FileContext->FileName = NULL;\r
-  }\r
-\r
-  Private->FileContext->FHandle = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -821,7 +887,7 @@ EnrollKeyExchangeKey (
   EFI_STATUS  Status;\r
   UINTN       NameLength;\r
 \r
-  if ((Private->FileContext->FileName == NULL) || (Private->SignatureGUID == NULL)) {\r
+  if ((Private->FileContext->FHandle == NULL) || (Private->FileContext->FileName == NULL) || (Private->SignatureGUID == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -844,6 +910,11 @@ EnrollKeyExchangeKey (
   } else if (CompareMem (FilePostFix, L".pbk",4) == 0) {\r
     return EnrollRsa2048ToKek (Private);\r
   } else {\r
+    //\r
+    // File type is wrong, simply close it\r
+    //\r
+    CloseEnrolledFile(Private->FileContext);\r
+\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 }\r
@@ -955,13 +1026,7 @@ EnrollX509toSigDB (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  if (Private->FileContext->FileName != NULL){\r
-    FreePool(Private->FileContext->FileName);\r
-    Private->FileContext->FileName = NULL;\r
-  }\r
-\r
-  Private->FileContext->FHandle = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -1519,13 +1584,8 @@ EnrollX509HashtoSigDB (
   }\r
 \r
 ON_EXIT:\r
-  CloseFile (Private->FileContext->FHandle);\r
-  if (Private->FileContext->FileName != NULL){\r
-    FreePool(Private->FileContext->FileName);\r
-    Private->FileContext->FileName = NULL;\r
-  }\r
 \r
-  Private->FileContext->FHandle = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -1837,12 +1897,12 @@ HashPeImage (
     //\r
     // Use PE32 offset.\r
     //\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
   } else {\r
     //\r
     // Use PE32+ offset.\r
     //\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
   }\r
 \r
   Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
@@ -1859,13 +1919,13 @@ HashPeImage (
     // Use PE32 offset.\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
   } else {\r
     //\r
     // Use PE32+ offset.\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
   }\r
 \r
   Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
@@ -1881,13 +1941,13 @@ HashPeImage (
     // Use PE32 offset\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
-    HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
+    HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN) mImageBase);\r
   } else {\r
     //\r
     // Use PE32+ offset.\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
-    HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
+    HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN) mImageBase);\r
   }\r
 \r
   Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
@@ -2066,6 +2126,107 @@ HashPeImageByType (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Enroll a new executable's signature into Signature Database.\r
+\r
+  @param[in] PrivateData     The module's private data.\r
+  @param[in] VariableName    Variable name of signature database, must be\r
+                             EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1\r
+                             or EFI_IMAGE_SECURITY_DATABASE2.\r
+\r
+  @retval   EFI_SUCCESS            New signature is enrolled successfully.\r
+  @retval   EFI_INVALID_PARAMETER  The parameter is invalid.\r
+  @retval   EFI_UNSUPPORTED        Unsupported command.\r
+  @retval   EFI_OUT_OF_RESOURCES   Could not allocate needed resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EnrollAuthentication2Descriptor (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private,\r
+  IN CHAR16                         *VariableName\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  VOID                              *Data;\r
+  UINTN                             DataSize;\r
+  UINT32                            Attr;\r
+\r
+  Data = NULL;\r
+\r
+  //\r
+  // DBT only support DER-X509 Cert Enrollment\r
+  //\r
+  if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Read the whole file content\r
+  //\r
+  Status = ReadFileContent(\r
+             Private->FileContext->FHandle,\r
+             (VOID **) &mImageBase,\r
+             &mImageSize,\r
+             0\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
+  ASSERT (mImageBase != NULL);\r
+\r
+  Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS\r
+         | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+\r
+  //\r
+  // Check if SigDB variable has been already existed.\r
+  // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the\r
+  // new signature data to original variable\r
+  //\r
+  DataSize = 0;\r
+  Status = gRT->GetVariable(\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  NULL\r
+                  );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Attr |= EFI_VARIABLE_APPEND_WRITE;\r
+  } else if (Status != EFI_NOT_FOUND) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Diretly set AUTHENTICATION_2 data to SetVariable\r
+  //\r
+  Status = gRT->SetVariable(\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  Attr,\r
+                  mImageSize,\r
+                  mImageBase\r
+                  );\r
+\r
+  DEBUG((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status));\r
+\r
+ON_EXIT:\r
+\r
+  CloseEnrolledFile(Private->FileContext);\r
+\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
+\r
+  if (mImageBase != NULL) {\r
+    FreePool (mImageBase);\r
+    mImageBase = NULL;\r
+  }\r
+\r
+  return Status;\r
+\r
+}\r
+\r
+\r
 /**\r
   Enroll a new executable's signature into Signature Database.\r
 \r
@@ -2235,13 +2396,7 @@ EnrollImageSignatureToSigDB (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FHandle = NULL;\r
-\r
-  if (Private->FileContext->FileName != NULL){\r
-    FreePool(Private->FileContext->FileName);\r
-    Private->FileContext->FileName = NULL;\r
-  }\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -2305,9 +2460,11 @@ EnrollSignatureDatabase (
     // Supports DER-encoded X509 certificate.\r
     //\r
     return EnrollX509toSigDB (Private, VariableName);\r
+  } else if (IsAuthentication2Format(Private->FileContext->FHandle)){\r
+    return EnrollAuthentication2Descriptor(Private, VariableName);\r
+  } else {\r
+    return EnrollImageSignatureToSigDB (Private, VariableName);\r
   }\r
-\r
-  return EnrollImageSignatureToSigDB (Private, VariableName);\r
 }\r
 \r
 /**\r
@@ -2694,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
@@ -2704,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
@@ -2894,6 +3051,182 @@ 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[BUFFER_MAX_SIZE];\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
+  VariableAttr        = 0;\r
+  VariableDataSize    = 0;\r
+  ListIndex           = 0;\r
+  Offset              = 0;\r
+  VariableData        = NULL;\r
+  NewVariableData     = NULL;\r
+\r
+  if (PrivateData->VariableName == Variable_DB) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);\r
+  } else if (PrivateData->VariableName == Variable_DBX) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);\r
+  } else if (PrivateData->VariableName == Variable_DBT) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), 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
+    //
+    //  Traverse to target EFI_SIGNATURE_LIST but others will be skipped.
+    //
+    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
+    //
+    //  Handle the target EFI_SIGNATURE_LIST.
+    //  If CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) or DelType == Delete_Signature_List_One
+    //  it means delete the whole EFI_SIGNATURE_LIST, So we just skip this EFI_SIGNATURE_LIST.
+    //
+    if (CheckedCount < SIGNATURE_DATA_COUNTS (ListWalker) && DelType == Delete_Signature_Data) {
+      NewCertList = (EFI_SIGNATURE_LIST *)(NewVariableData + Offset);\r
+      //\r
+      // Copy header.\r
+      //\r
+      CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+      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
+\r
+    RemainingSize -= ListWalker->SignatureListSize;
+    ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+
+    //\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 (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
@@ -2936,11 +3269,13 @@ UpdateSecureBootString(
 /**\r
   This function extracts configuration from variable.\r
 \r
+  @param[in]       Private      Point to SecureBoot configuration driver private data.\r
   @param[in, out]  ConfigData   Point to SecureBoot configuration private data.\r
 \r
 **/\r
 VOID\r
 SecureBootExtractConfigFromVariable (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private,\r
   IN OUT SECUREBOOT_CONFIGURATION    *ConfigData\r
   )\r
 {\r
@@ -2965,7 +3300,11 @@ SecureBootExtractConfigFromVariable (
   ConfigData->RevocationTime.Hour   = CurrTime.Hour;\r
   ConfigData->RevocationTime.Minute = CurrTime.Minute;\r
   ConfigData->RevocationTime.Second = 0;\r
-\r
+  if (Private->FileContext->FHandle != NULL) {\r
+    ConfigData->FileEnrollType = Private->FileContext->FileType;\r
+  } else {\r
+    ConfigData->FileEnrollType = UNKNOWN_FILE_TYPE;\r
+  }\r
 \r
   //\r
   // If it is Physical Presence User, set the PhysicalPresent to true.\r
@@ -3088,10 +3427,12 @@ SecureBootExtractConfig (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  ZeroMem(&Configuration, sizeof(SECUREBOOT_CONFIGURATION));\r
+\r
   //\r
   // Get Configuration from Variable.\r
   //\r
-  SecureBootExtractConfigFromVariable (&Configuration);\r
+  SecureBootExtractConfigFromVariable (PrivateData, &Configuration);\r
 \r
   BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
   ConfigRequest = Request;\r
@@ -3166,9 +3507,10 @@ SecureBootRouteConfig (
        OUT EFI_STRING                          *Progress\r
   )\r
 {\r
-  SECUREBOOT_CONFIGURATION   IfrNvData;\r
-  UINTN                      BufferSize;\r
-  EFI_STATUS                 Status;\r
+  SECUREBOOT_CONFIGURATION          IfrNvData;\r
+  UINTN                             BufferSize;\r
+  SECUREBOOT_CONFIG_PRIVATE_DATA    *PrivateData;\r
+  EFI_STATUS                        Status;\r
 \r
   if (Configuration == NULL || Progress == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -3179,10 +3521,12 @@ SecureBootRouteConfig (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
+\r
   //\r
   // Get Configuration from Variable.\r
   //\r
-  SecureBootExtractConfigFromVariable (&IfrNvData);\r
+  SecureBootExtractConfigFromVariable (PrivateData, &IfrNvData);\r
 \r
   //\r
   // Map the Configuration to the configuration block.\r
@@ -3214,12 +3558,725 @@ SecureBootRouteConfig (
 }\r
 \r
 /**\r
-  This function is called to provide results data to the driver.\r
+  This function to load signature list, the update the menu page.\r
 \r
-  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
-  @param[in]  Action             Specifies the type of action taken by the browser.\r
-  @param[in]  QuestionId         A unique value which is sent to the original\r
-                                 exporting driver so that it can identify the type\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_STRING            FormatNameString;\r
+  EFI_STRING            FormatHelpString;\r
+  EFI_STRING            FormatTypeString;\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[BUFFER_MAX_SIZE];\r
+  CHAR16                NameBuffer[BUFFER_MAX_SIZE];\r
+  CHAR16                HelpBuffer[BUFFER_MAX_SIZE];\r
+\r
+  Status                = EFI_SUCCESS;\r
+  FormatNameString      = NULL;\r
+  FormatHelpString      = NULL;\r
+  StartOpCodeHandle     = NULL;\r
+  EndOpCodeHandle       = NULL;\r
+  StartGotoHandle       = NULL;\r
+  EndGotoHandle         = NULL;\r
+  Index                 = 0;\r
+  VariableData          = 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
+  if (PrivateData->VariableName == Variable_DB) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);\r
+    DstFormId = FORMID_SECURE_BOOT_DB_OPTION_FORM;\r
+  } else if (PrivateData->VariableName == Variable_DBX) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);\r
+    DstFormId = FORMID_SECURE_BOOT_DBX_OPTION_FORM;\r
+  } else if (PrivateData->VariableName == Variable_DBT) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), 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
+  FormatNameString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_NAME_FORMAT), NULL);\r
+  FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT), NULL);\r
+  if (FormatNameString == NULL || FormatHelpString == NULL) {\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
+    FormatTypeString = HiiGetString (PrivateData->HiiHandle, ListType, NULL);\r
+    if (FormatTypeString == NULL) {\r
+      goto ON_EXIT;\r
+    }\r
+\r
+    ZeroMem (NameBuffer, sizeof (NameBuffer));\r
+    UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1);\r
+\r
+    ZeroMem (HelpBuffer, sizeof (HelpBuffer));\r
+    UnicodeSPrint (HelpBuffer,\r
+      sizeof (HelpBuffer),\r
+      FormatHelpString,\r
+      FormatTypeString,\r
+      SIGNATURE_DATA_COUNTS (ListWalker)\r
+    );\r
+    SECUREBOOT_FREE_NON_NULL (FormatTypeString);\r
+    FormatTypeString = NULL;\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
+    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 (VariableData);\r
+  SECUREBOOT_FREE_NON_NULL (FormatNameString);\r
+  SECUREBOOT_FREE_NON_NULL (FormatHelpString);\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
+  EFI_STRING      FormatHelpString;\r
+  EFI_STRING      FormatTypeString;\r
+  UINTN           DataSize;\r
+  UINTN           HelpInfoIndex;\r
+  UINTN           TotalSize;\r
+  CHAR16          GuidString[BUFFER_MAX_SIZE];\r
+  CHAR16          TimeString[BUFFER_MAX_SIZE];\r
+  CHAR16          *DataString;\r
+  CHAR16          *HelpInfoString;\r
+  BOOLEAN         IsCert;\r
+\r
+  Status            = EFI_SUCCESS;\r
+  Time              = NULL;\r
+  FormatTypeString  = NULL;\r
+  HelpInfoIndex     = 0;\r
+  DataString        = 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
+  FormatTypeString = HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL);\r
+  if (FormatTypeString == NULL) {\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
+  ZeroMem (GuidString, sizeof (GuidString));\r
+  GuidToString(&DataEntry->SignatureOwner, GuidString, BUFFER_MAX_SIZE);\r
+  FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID), NULL);\r
+  if (FormatHelpString == NULL) {\r
+    goto ON_EXIT;\r
+  }\r
+  HelpInfoIndex += UnicodeSPrint (\r
+                     &HelpInfoString[HelpInfoIndex],\r
+                     TotalSize - sizeof(CHAR16) * HelpInfoIndex,\r
+                     FormatHelpString,\r
+                     GuidString\r
+                   );\r
+  SECUREBOOT_FREE_NON_NULL (FormatHelpString);\r
+  FormatHelpString = NULL;\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
+    FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_CN), NULL);\r
+  } else {\r
+    //\r
+    //  Format hash value for each signature data entry.\r
+    //\r
+    ParseHashValue (ListEntry, DataEntry, &DataString);\r
+    FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH), NULL);\r
+  }\r
+  if (FormatHelpString == NULL) {\r
+    goto ON_EXIT;\r
+  }\r
+  HelpInfoIndex += UnicodeSPrint (\r
+                     &HelpInfoString[HelpInfoIndex],\r
+                     TotalSize - sizeof (CHAR16) * HelpInfoIndex,\r
+                     FormatHelpString,\r
+                     FormatTypeString,\r
+                     DataSize,\r
+                     DataString\r
+                   );\r
+  SECUREBOOT_FREE_NON_NULL (FormatHelpString);\r
+  FormatHelpString = NULL;\r
+\r
+  //\r
+  // Format revocation time part.\r
+  //\r
+  if (Time != NULL) {\r
+    ZeroMem (TimeString, sizeof (TimeString));\r
+    UnicodeSPrint (\r
+      TimeString,\r
+      sizeof (TimeString),\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
+    FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME), NULL);\r
+    if (FormatHelpString == NULL) {\r
+      goto ON_EXIT;\r
+    }\r
+    UnicodeSPrint (\r
+      &HelpInfoString[HelpInfoIndex],\r
+      TotalSize - sizeof (CHAR16) * HelpInfoIndex,\r
+      FormatHelpString,\r
+      TimeString\r
+    );\r
+    SECUREBOOT_FREE_NON_NULL (FormatHelpString);\r
+    FormatHelpString = NULL;\r
+  }\r
+\r
+  *StringId = HiiSetString (PrivateData->HiiHandle, 0, HelpInfoString, NULL);\r
+ON_EXIT:\r
+  SECUREBOOT_FREE_NON_NULL (DataString);\r
+  SECUREBOOT_FREE_NON_NULL (HelpInfoString);\r
+\r
+  SECUREBOOT_FREE_NON_NULL (FormatTypeString);\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
+  EFI_STRING            FormatNameString;\r
+  VOID                  *StartOpCodeHandle;\r
+  VOID                  *EndOpCodeHandle;\r
+  UINTN                 DataSize;\r
+  UINTN                 RemainingSize;\r
+  UINT16                Index;\r
+  UINT8                 *VariableData;\r
+  CHAR16                VariableName[BUFFER_MAX_SIZE];\r
+  CHAR16                NameBuffer[BUFFER_MAX_SIZE];\r
+\r
+  Status              = EFI_SUCCESS;\r
+  FormatNameString    = NULL;\r
+  StartOpCodeHandle   = NULL;\r
+  EndOpCodeHandle     = NULL;\r
+  Index               = 0;\r
+  VariableData        = 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
+  if (PrivateData->VariableName == Variable_DB) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);\r
+  } else if (PrivateData->VariableName == Variable_DBX) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);\r
+  } else if (PrivateData->VariableName == Variable_DBT) {\r
+    UnicodeSPrint (VariableName, sizeof (VariableName), 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
+  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
+  FormatNameString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_NAME_FORMAT), NULL);\r
+  if (FormatNameString == NULL) {\r
+    goto ON_EXIT;\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
+    ZeroMem (NameBuffer, sizeof (NameBuffer));\r
+    UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1);\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
+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 (VariableData);\r
+  SECUREBOOT_FREE_NON_NULL (FormatNameString);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function is called to provide results data to the driver.\r
+\r
+  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Action             Specifies the type of action taken by the browser.\r
+  @param[in]  QuestionId         A unique value which is sent to the original\r
+                                 exporting driver so that it can identify the type\r
                                  of data to expect.\r
   @param[in]  Type               The type of value for the question.\r
   @param[in]  Value              A pointer to the data being sent to the original\r
@@ -3248,6 +4305,7 @@ SecureBootCallback (
 {\r
   EFI_INPUT_KEY                   Key;\r
   EFI_STATUS                      Status;\r
+  RETURN_STATUS                   RStatus;\r
   SECUREBOOT_CONFIG_PRIVATE_DATA  *Private;\r
   UINTN                           BufferSize;\r
   SECUREBOOT_CONFIGURATION        *IfrNvData;\r
@@ -3258,6 +4316,9 @@ SecureBootCallback (
   UINT8                           *SetupMode;\r
   CHAR16                          PromptString[100];\r
   EFI_DEVICE_PATH_PROTOCOL        *File;\r
+  UINTN                           NameLength;\r
+  UINT16                          *FilePostFix;\r
+  SECUREBOOT_CONFIG_PRIVATE_DATA  *PrivateData;\r
 \r
   Status           = EFI_SUCCESS;\r
   SecureBootEnable = NULL;\r
@@ -3290,8 +4351,27 @@ SecureBootCallback (
       // Update secure boot strings when opening this form\r
       //\r
       Status = UpdateSecureBootString(Private);\r
-      SecureBootExtractConfigFromVariable (IfrNvData);\r
+      SecureBootExtractConfigFromVariable (Private, IfrNvData);\r
       mIsEnterSecureBootForm = TRUE;\r
+    } else {\r
+      //\r
+      // When entering SecureBoot OPTION Form\r
+      // always close opened file & free resource\r
+      //\r
+      if ((QuestionId == KEY_SECURE_BOOT_PK_OPTION) ||\r
+          (QuestionId == KEY_SECURE_BOOT_KEK_OPTION) ||\r
+          (QuestionId == KEY_SECURE_BOOT_DB_OPTION) ||\r
+          (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
   }\r
@@ -3345,6 +4425,7 @@ SecureBootCallback (
     case KEY_SECURE_BOOT_DB_OPTION:\r
     case KEY_SECURE_BOOT_DBX_OPTION:\r
     case KEY_SECURE_BOOT_DBT_OPTION:\r
+      PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
       //\r
       // Clear Signature GUID.\r
       //\r
@@ -3356,6 +4437,11 @@ SecureBootCallback (
         }\r
       }\r
 \r
+      //\r
+      // Cleanup VFRData once leaving PK/KEK/DB/DBX/DBT enroll/delete page\r
+      //\r
+      SecureBootExtractConfigFromVariable (PrivateData, IfrNvData);\r
+\r
       if (QuestionId == KEY_SECURE_BOOT_DB_OPTION) {\r
         LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;\r
       } else if (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) {\r
@@ -3393,6 +4479,38 @@ SecureBootCallback (
 \r
     case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX:\r
       ChooseFile (NULL, NULL, UpdateDBXFromFile, &File);\r
+\r
+      if (Private->FileContext->FHandle != NULL) {\r
+        //\r
+        // Parse the file's postfix.\r
+        //\r
+        NameLength = StrLen (Private->FileContext->FileName);\r
+        if (NameLength <= 4) {\r
+          return FALSE;\r
+        }\r
+        FilePostFix = Private->FileContext->FileName + NameLength - 4;\r
+\r
+        if (IsDerEncodeCertificate (FilePostFix)) {\r
+          //\r
+          // Supports DER-encoded X509 certificate.\r
+          //\r
+          IfrNvData->FileEnrollType = X509_CERT_FILE_TYPE;\r
+        } else if (IsAuthentication2Format(Private->FileContext->FHandle)){\r
+          IfrNvData->FileEnrollType = AUTHENTICATION_2_FILE_TYPE;\r
+        } else {\r
+          IfrNvData->FileEnrollType = PE_IMAGE_FILE_TYPE;\r
+        }\r
+        Private->FileContext->FileType = IfrNvData->FileEnrollType;\r
+\r
+        //\r
+        // Clean up Certificate Format if File type is not X509 DER\r
+        //\r
+        if (IfrNvData->FileEnrollType != X509_CERT_FILE_TYPE) {\r
+          IfrNvData->CertificateFormat = HASHALG_RAW;\r
+        }\r
+        DEBUG((DEBUG_ERROR, "IfrNvData->FileEnrollType %d\n", Private->FileContext->FileType));\r
+      }\r
+\r
       break;\r
 \r
     case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT:\r
@@ -3444,16 +4562,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
@@ -3502,7 +4693,12 @@ SecureBootCallback (
           L"Enrollment failed! Same certificate had already been in the dbx!",\r
           NULL\r
           );\r
-          break;\r
+\r
+        //\r
+        // Cert already exists in DBX. Close opened file before exit.\r
+        //\r
+        CloseEnrolledFile(Private->FileContext);\r
+        break;\r
       }\r
 \r
       if ((IfrNvData != NULL) && (IfrNvData->CertificateFormat < HASHALG_MAX)) {\r
@@ -3513,6 +4709,7 @@ SecureBootCallback (
                    &IfrNvData->RevocationTime,\r
                    IfrNvData->AlwaysRevocation\r
                    );\r
+        IfrNvData->CertificateFormat = HASHALG_RAW;\r
       } else {\r
         Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE1);\r
       }\r
@@ -3521,7 +4718,7 @@ SecureBootCallback (
           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
           &Key,\r
           L"ERROR: Unsupported file type!",\r
-          L"Only supports DER-encoded X509 certificate and executable EFI image",\r
+          L"Only supports DER-encoded X509 certificate, AUTH_2 format data & executable EFI image",\r
           NULL\r
           );\r
       }\r
@@ -3572,17 +4769,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
@@ -3602,14 +4807,7 @@ SecureBootCallback (
     case KEY_VALUE_NO_SAVE_AND_EXIT_DB:\r
     case KEY_VALUE_NO_SAVE_AND_EXIT_DBX:\r
     case KEY_VALUE_NO_SAVE_AND_EXIT_DBT:\r
-      if (Private->FileContext->FHandle != NULL) {\r
-        CloseFile (Private->FileContext->FHandle);\r
-        Private->FileContext->FHandle = NULL;\r
-        if (Private->FileContext->FileName!= NULL){\r
-          FreePool(Private->FileContext->FileName);\r
-          Private->FileContext->FileName = NULL;\r
-        }\r
-      }\r
+      CloseEnrolledFile(Private->FileContext);\r
 \r
       if (Private->SignatureGUID != NULL) {\r
         FreePool (Private->SignatureGUID);\r
@@ -3630,18 +4828,14 @@ SecureBootCallback (
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:\r
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT:\r
       ASSERT (Private->SignatureGUID != NULL);\r
-      Status = StringToGuid (\r
-                 IfrNvData->SignatureGuid,\r
-                 StrLen (IfrNvData->SignatureGuid),\r
-                 Private->SignatureGUID\r
-                 );\r
-      if (EFI_ERROR (Status)) {\r
+      RStatus = StrToGuid (IfrNvData->SignatureGuid, Private->SignatureGUID);\r
+      if (RETURN_ERROR (RStatus) || (IfrNvData->SignatureGuid[GUID_STRING_LENGTH] != L'\0')) {\r
+        Status = EFI_INVALID_PARAMETER;\r
         break;\r
       }\r
 \r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
       break;\r
-\r
     case KEY_SECURE_BOOT_DELETE_PK:\r
       GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
       if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\r
@@ -3683,6 +4877,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