]> 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 e840316368919a4b75760769554d9da68dfb2a7d..4ec0f8d13a92a9d68bab170412a32488406ab5d9 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   HII Config Access protocol implementation of SecureBoot configuration module.\r
 \r
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -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
@@ -49,8 +50,6 @@ HII_VENDOR_DEVICE_PATH          mSecureBootHiiVendorDevicePath = {
 \r
 \r
 BOOLEAN mIsEnterSecureBootForm = FALSE;\r
-BOOLEAN mIsSelectedSecureBootModeForm = FALSE;\r
-BOOLEAN mIsSecureBootModeChanged = FALSE;\r
 \r
 //\r
 // OID ASN.1 Value for Hash Algorithms\r
@@ -65,7 +64,6 @@ UINT8 mHashOidValue[] = {
   };\r
 \r
 HASH_TABLE mHash[] = {\r
-  { L"SHA1",   20, &mHashOidValue[8],  5, Sha1GetContextSize,   Sha1Init,   Sha1Update,   Sha1Final  },\r
   { L"SHA224", 28, &mHashOidValue[13], 9, NULL,                 NULL,       NULL,         NULL       },\r
   { L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final},\r
   { L"SHA384", 48, &mHashOidValue[31], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final},\r
@@ -99,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
@@ -122,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
@@ -477,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
@@ -657,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
@@ -784,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
@@ -824,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
@@ -847,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
@@ -958,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
@@ -1522,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
@@ -1611,6 +1668,54 @@ ON_EXIT:
   return IsFound;\r
 }\r
 \r
+/**\r
+  Reads contents of a PE/COFF image in memory buffer.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  PE/COFF image is external input, so this function will make sure the PE/COFF image content\r
+  read is within the image buffer.\r
+\r
+  @param  FileHandle      Pointer to the file handle to read the PE/COFF image.\r
+  @param  FileOffset      Offset into the PE/COFF image to begin the read operation.\r
+  @param  ReadSize        On input, the size in bytes of the requested read operation.\r
+                          On output, the number of bytes actually read.\r
+  @param  Buffer          Output buffer that contains the data read from the PE/COFF image.\r
+\r
+  @retval EFI_SUCCESS     The specified portion of the PE/COFF image was read and the size\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecureBootConfigImageRead (\r
+  IN     VOID    *FileHandle,\r
+  IN     UINTN   FileOffset,\r
+  IN OUT UINTN   *ReadSize,\r
+  OUT    VOID    *Buffer\r
+  )\r
+{\r
+  UINTN               EndPosition;\r
+\r
+  if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (MAX_ADDRESS - FileOffset < *ReadSize) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  EndPosition = FileOffset + *ReadSize;\r
+  if (EndPosition > mImageSize) {\r
+    *ReadSize = (UINT32)(mImageSize - FileOffset);\r
+  }\r
+\r
+  if (FileOffset >= mImageSize) {\r
+    *ReadSize = 0;\r
+  }\r
+\r
+  CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Load PE/COFF image information into internal buffer and check its validity.\r
 \r
@@ -1627,9 +1732,28 @@ LoadPeImage (
   EFI_IMAGE_DOS_HEADER                  *DosHdr;\r
   EFI_IMAGE_NT_HEADERS32                *NtHeader32;\r
   EFI_IMAGE_NT_HEADERS64                *NtHeader64;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
+  EFI_STATUS                            Status;\r
 \r
   NtHeader32 = NULL;\r
   NtHeader64 = NULL;\r
+\r
+  ZeroMem (&ImageContext, sizeof (ImageContext));\r
+  ImageContext.Handle    = (VOID *) mImageBase;\r
+  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecureBootConfigImageRead;\r
+\r
+  //\r
+  // Get information about the image being loaded\r
+  //\r
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // The information can't be got from the invalid PeImage\r
+    //\r
+    DEBUG ((DEBUG_INFO, "SecureBootConfigDxe: PeImage invalid. \n"));\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Read the Dos header\r
   //\r
@@ -1691,6 +1815,9 @@ LoadPeImage (
   Calculate hash of Pe/Coff image based on the authenticode image hashing in\r
   PE/COFF Specification 8.0 Appendix A\r
 \r
+  Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in \r
+  the function LoadPeImage ().\r
+\r
   @param[in]    HashAlg   Hash algorithm type.\r
 \r
   @retval TRUE            Successfully hash image.\r
@@ -1718,7 +1845,7 @@ HashPeImage (
   SectionHeader = NULL;\r
   Status        = FALSE;\r
 \r
-  if ((HashAlg != HASHALG_SHA1) && (HashAlg != HASHALG_SHA256)) {\r
+  if (HashAlg != HASHALG_SHA256) {\r
     return FALSE;\r
   }\r
 \r
@@ -1727,13 +1854,8 @@ HashPeImage (
   //\r
   ZeroMem (mImageDigest, MAX_DIGEST_SIZE);\r
 \r
-  if (HashAlg == HASHALG_SHA1) {\r
-    mImageDigestSize  = SHA1_DIGEST_SIZE;\r
-    mCertType         = gEfiCertSha1Guid;\r
-  } else if (HashAlg == HASHALG_SHA256) {\r
-    mImageDigestSize  = SHA256_DIGEST_SIZE;\r
-    mCertType         = gEfiCertSha256Guid;\r
-  }\r
+  mImageDigestSize  = SHA256_DIGEST_SIZE;\r
+  mCertType         = gEfiCertSha256Guid;\r
 \r
   CtxSize   = mHash[HashAlg].GetContextSize();\r
 \r
@@ -1775,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
@@ -1797,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
@@ -1819,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
@@ -2004,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
@@ -2173,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
@@ -2243,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
@@ -2632,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
@@ -2642,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
@@ -2833,255 +3052,181 @@ ON_EXIT:
 }\r
 \r
 /**\r
-  Perform secure boot mode transition from User Mode by setting AuditMode \r
-  or DeployedMode variable.\r
+  This function to delete signature list or data, according by DelType.\r
 \r
-  @param[in]  NewMode          New secure boot mode.\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        Secure Boot mode transition is successful.\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
-TransitionFromUserMode(\r
-  IN  UINT8 NewMode\r
+DeleteSignatureEx (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA   *PrivateData,\r
+  IN SIGNATURE_DELETE_TYPE            DelType,\r
+  IN UINT32                           CheckedCount\r
   )\r
 {\r
-  UINT8      Data;\r
-  EFI_STATUS Status;\r
-\r
-  if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    Data = 1;\r
-    Status = gRT->SetVariable(\r
-                    EFI_AUDIT_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    return Status;\r
-  } else if (NewMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
-    Data = 1;\r
-    Status = gRT->SetVariable(\r
-                    EFI_DEPLOYED_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    return Status;\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
-  //\r
-  // Other case do nothing here. May Goto enroll PK page.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Perform secure boot mode transition from Setup Mode by setting AuditMode \r
-  variable.\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
-  @param[in]  NewMode          New secure boot mode.\r
+  VariableData = AllocateZeroPool (VariableDataSize);\r
+  if (VariableData == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ON_EXIT;\r
+  }\r
 \r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromSetupMode(\r
-  IN UINT8 NewMode\r
-  )\r
-{\r
-  UINT8      Data;\r
-  EFI_STATUS Status;\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 = EFI_INVALID_PARAMETER;\r
-\r
-  if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    Data = 1;\r
-    Status = gRT->SetVariable(\r
-                    EFI_AUDIT_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    return Status;\r
+  Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
   }\r
 \r
-  //\r
-  // Other case do nothing here. May Goto enroll PK page.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
+  NewVariableData = AllocateZeroPool (VariableDataSize);\r
+  if (NewVariableData == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ON_EXIT;\r
+  }\r
 \r
-/**\r
-  Perform secure boot mode transition from Audit Mode. Nothing is done here,\r
-  should goto enroll PK page.\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
-  @param[in]  NewMode          New secure boot mode.\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
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromAuditMode(\r
-  IN UINT8 NewMode\r
-  )\r
-{\r
-  //\r
-  // Other case do nothing here. Should Goto enroll PK page.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-   Perform secure boot mode transition from Deployed Mode by setting Deployed Mode\r
-   variable to 0.\r
-\r
-  @param[in]  NewMode          New secure boot mode.\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
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromDeployedMode(\r
-  IN UINT8 NewMode\r
-  )\r
-{\r
-  UINT8      Data;\r
-  EFI_STATUS Status;\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
-  //\r
-  // Platform specific logic. when physical presence,  Allow to set DeployedMode =:0\r
-  // to switch back to UserMode\r
-  //\r
-  if (NewMode == SECURE_BOOT_MODE_USER_MODE) {\r
-    Data = 0;\r
-    Status = gRT->SetVariable(\r
-                    EFI_DEPLOYED_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    DEBUG((EFI_D_INFO, "DeployedMode Status %x\n", Status));\r
-    return Status;\r
+    VariableDataSize = Offset;\r
   }\r
-  return EFI_SUCCESS;\r
-}\r
 \r
-/**\r
-   Perform main secure boot mode transition.\r
-\r
-  @param[in]  CurMode          New secure boot mode.\r
-  @param[in]  NewMode          New secure boot mode.\r
-\r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-SecureBootModeTransition(\r
-  IN  UINT8  CurMode,\r
-  IN  UINT8  NewMode\r
-  )\r
-{\r
-  EFI_STATUS                         Status;\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
-  //\r
-  // Set platform to be customized mode to ensure platform specific mode switch sucess\r
-  //\r
-  Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE);\r
+  Status = gRT->SetVariable (\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  VariableAttr,\r
+                  VariableDataSize,\r
+                  NewVariableData\r
+                );\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r", Status));\r
+    goto ON_EXIT;\r
   }\r
 \r
-  //\r
-  // SecureBootMode transition\r
-  //\r
-  switch (CurMode) {\r
-    case SECURE_BOOT_MODE_USER_MODE:\r
-      Status = TransitionFromUserMode(NewMode);\r
-      break;\r
-\r
-    case SECURE_BOOT_MODE_SETUP_MODE:\r
-      Status = TransitionFromSetupMode(NewMode);\r
-      break;\r
-\r
-    case SECURE_BOOT_MODE_AUDIT_MODE:\r
-      Status = TransitionFromAuditMode(NewMode);\r
-      break;\r
-\r
-    case SECURE_BOOT_MODE_DEPLOYED_MODE:\r
-      Status = TransitionFromDeployedMode(NewMode);\r
-      break;\r
-\r
-    default:\r
-      Status = EFI_INVALID_PARAMETER;\r
-      ASSERT(FALSE);\r
-  }\r
+ON_EXIT:\r
+  SECUREBOOT_FREE_NON_NULL (VariableData);\r
+  SECUREBOOT_FREE_NON_NULL (NewVariableData);\r
 \r
   return Status;\r
 }\r
 \r
-/**\r
-   Get current secure boot mode by retrieve data from SetupMode/AuditMode/DeployedMode.\r
-\r
-  @param[out]  SecureBootMode                Current secure boot mode.\r
-\r
-**/\r
-VOID\r
-ExtractSecureBootModeFromVariable(\r
-  OUT UINT8      *SecureBootMode\r
-  )\r
-{\r
-  UINT8     *SetupMode;\r
-  UINT8     *AuditMode;\r
-  UINT8     *DeployedMode;\r
-\r
-  SetupMode        = NULL;\r
-  AuditMode        = NULL;\r
-  DeployedMode     = NULL;\r
-\r
-  //\r
-  // Get AuditMode/DeployedMode from variable\r
-  //\r
-  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
-  GetVariable2 (EFI_AUDIT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&AuditMode, NULL);\r
-  GetVariable2 (EFI_DEPLOYED_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&DeployedMode, NULL);\r
-  if (SetupMode != NULL && AuditMode != NULL && DeployedMode != NULL) {\r
-    if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 0) {\r
-      //\r
-      // User Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_USER_MODE;\r
-    } else if (*SetupMode == 1 && *AuditMode == 0 && *DeployedMode == 0) {\r
-      //\r
-      // Setup Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_SETUP_MODE;\r
-    } else if (*SetupMode == 1 && *AuditMode == 1 && *DeployedMode == 0) {\r
-      //\r
-      // Audit Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_AUDIT_MODE;\r
-    } else if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 1) {\r
-      //\r
-      // Deployed Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_DEPLOYED_MODE;\r
-    } else {\r
-      ASSERT(FALSE);\r
-    }\r
-  }else {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  if (SetupMode != NULL) {\r
-    FreePool (SetupMode);\r
-  }\r
-  if (DeployedMode != NULL) {\r
-    FreePool (DeployedMode);\r
-  }\r
-  if (AuditMode != NULL) {\r
-    FreePool (AuditMode);\r
-  }\r
-}\r
-\r
 /**\r
 \r
   Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT\r
@@ -3098,7 +3243,6 @@ UpdateSecureBootString(
   IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private\r
   )\r
 {\r
-  UINT8       CurSecureBootMode;\r
   UINT8       *SecureBoot;\r
 \r
   SecureBoot = NULL;\r
@@ -3116,20 +3260,6 @@ UpdateSecureBootString(
   } else {\r
     HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);\r
   }\r
-  //\r
-  // Get current secure boot mode.\r
-  //\r
-  ExtractSecureBootModeFromVariable(&CurSecureBootMode);\r
-  \r
-  if (CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL);\r
-  } else if (CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL);\r
-  } else if (CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL);\r
-  } else if (CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL);\r
-  }\r
 \r
   FreePool(SecureBoot);\r
 \r
@@ -3139,19 +3269,23 @@ 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
   UINT8     *SecureBootEnable;\r
+  UINT8     *SetupMode;\r
   UINT8     *SecureBootMode;\r
   EFI_TIME  CurrTime;\r
 \r
   SecureBootEnable = NULL;\r
+  SetupMode        = NULL;\r
   SecureBootMode   = NULL;\r
 \r
   //\r
@@ -3166,20 +3300,10 @@ SecureBootExtractConfigFromVariable (
   ConfigData->RevocationTime.Hour   = CurrTime.Hour;\r
   ConfigData->RevocationTime.Minute = CurrTime.Minute;\r
   ConfigData->RevocationTime.Second = 0;\r
-\r
-  //\r
-  // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable\r
-  // Checkbox.\r
-  //\r
-  ConfigData->AttemptSecureBoot = FALSE;\r
-  GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);\r
-  if (SecureBootEnable == NULL) {\r
-    ConfigData->HideSecureBoot = TRUE;\r
+  if (Private->FileContext->FHandle != NULL) {\r
+    ConfigData->FileEnrollType = Private->FileContext->FileType;\r
   } else {\r
-    ConfigData->HideSecureBoot = FALSE;\r
-    if ((*SecureBootEnable) == SECURE_BOOT_ENABLE) {\r
-      ConfigData->AttemptSecureBoot = TRUE;\r
-    }\r
+    ConfigData->FileEnrollType = UNKNOWN_FILE_TYPE;\r
   }\r
 \r
   //\r
@@ -3192,33 +3316,51 @@ SecureBootExtractConfigFromVariable (
   }\r
 \r
   //\r
-  // Get the SecureBootMode from CustomMode variable.\r
+  // If there is no PK then the Delete Pk button will be gray.\r
   //\r
-  GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL);\r
-  if (SecureBootMode == NULL) {\r
-    ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;\r
-  } else {\r
-    ConfigData->SecureBootMode = *(SecureBootMode);\r
+  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
+  if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\r
+    ConfigData->HasPk = FALSE;\r
+  } else  {\r
+    ConfigData->HasPk = TRUE;\r
   }\r
 \r
   //\r
-  // Extact current Secure Boot Mode\r
+  // Check SecureBootEnable & Pk status, fix the inconsistence. \r
+  // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable\r
+  // Checkbox.\r
   //\r
-  ExtractSecureBootModeFromVariable(&ConfigData->CurSecureBootMode);\r
+  ConfigData->AttemptSecureBoot = FALSE;\r
+  GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);  \r
 \r
   //\r
-  // If there is no PK then the Delete Pk button will be gray.\r
+  // Fix Pk, SecureBootEnable inconsistence\r
   //\r
-  if (ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE || ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    ConfigData->HasPk = FALSE;\r
-  } else  {\r
-    ConfigData->HasPk = TRUE;\r
+  if ((SetupMode != NULL) && (*SetupMode) == USER_MODE) {\r
+    ConfigData->HideSecureBoot = FALSE;\r
+    if ((SecureBootEnable != NULL) && (*SecureBootEnable == SECURE_BOOT_ENABLE)) {\r
+      ConfigData->AttemptSecureBoot = TRUE;\r
+    }\r
+  } else {\r
+    ConfigData->HideSecureBoot = TRUE;\r
+  }\r
+\r
+  //\r
+  // Get the SecureBootMode from CustomMode variable.\r
+  //\r
+  GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL);\r
+  if (SecureBootMode == NULL) {\r
+    ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;\r
+  } else {\r
+    ConfigData->SecureBootMode = *(SecureBootMode);\r
   }\r
 \r
   if (SecureBootEnable != NULL) {\r
     FreePool (SecureBootEnable);\r
   }\r
-\r
+  if (SetupMode != NULL) {\r
+    FreePool (SetupMode);\r
+  }\r
   if (SecureBootMode != NULL) {\r
     FreePool (SecureBootMode);\r
   }\r
@@ -3285,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
@@ -3309,109 +3453,821 @@ SecureBootExtractConfig (
     ConfigRequestHdr = NULL;\r
   }\r
 \r
-  Status = gHiiConfigRouting->BlockToConfig (\r
-                                gHiiConfigRouting,\r
-                                ConfigRequest,\r
-                                (UINT8 *) &Configuration,\r
-                                BufferSize,\r
-                                Results,\r
-                                Progress\r
-                                );\r
+  Status = gHiiConfigRouting->BlockToConfig (\r
+                                gHiiConfigRouting,\r
+                                ConfigRequest,\r
+                                (UINT8 *) &Configuration,\r
+                                BufferSize,\r
+                                Results,\r
+                                Progress\r
+                                );\r
+\r
+  //\r
+  // Free the allocated config request string.\r
+  //\r
+  if (AllocatedRequest) {\r
+    FreePool (ConfigRequest);\r
+  }\r
+\r
+  //\r
+  // Set Progress string to the original request string.\r
+  //\r
+  if (Request == NULL) {\r
+    *Progress = NULL;\r
+  } else if (StrStr (Request, L"OFFSET") == NULL) {\r
+    *Progress = Request + StrLen (Request);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>\r
+                                 format.\r
+  @param[out] Progress           A pointer to a string filled in with the offset of\r
+                                 the most recent '&' before the first failing\r
+                                 name/value pair (or the beginning of the string if\r
+                                 the failure is in the first name/value pair) or\r
+                                 the terminating NULL if all was successful.\r
+\r
+  @retval EFI_SUCCESS            The Results is processed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecureBootRouteConfig (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN CONST EFI_STRING                          Configuration,\r
+       OUT EFI_STRING                          *Progress\r
+  )\r
+{\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
+  }\r
+\r
+  *Progress = Configuration;\r
+  if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
+\r
+  //\r
+  // Get Configuration from Variable.\r
+  //\r
+  SecureBootExtractConfigFromVariable (PrivateData, &IfrNvData);\r
+\r
+  //\r
+  // Map the Configuration to the configuration block.\r
+  //\r
+  BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
+  Status = gHiiConfigRouting->ConfigToBlock (\r
+                                gHiiConfigRouting,\r
+                                Configuration,\r
+                                (UINT8 *)&IfrNvData,\r
+                                &BufferSize,\r
+                                Progress\r
+                                );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Store Buffer Storage back to EFI variable if needed\r
+  //\r
+  if (!IfrNvData.HideSecureBoot) {\r
+    Status = SaveSecureBootVariable (IfrNvData.AttemptSecureBoot);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  *Progress = Configuration + StrLen (Configuration);\r
+  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_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
-  // Free the allocated config request string.\r
+  // Format GUID part.\r
   //\r
-  if (AllocatedRequest) {\r
-    FreePool (ConfigRequest);\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
-  // Set Progress string to the original request string.\r
+  // Format content part, it depends on the type of signature list, hash value or CN.\r
   //\r
-  if (Request == NULL) {\r
-    *Progress = NULL;\r
-  } else if (StrStr (Request, L"OFFSET") == NULL) {\r
-    *Progress = Request + StrLen (Request);\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 function processes the results of changes in configuration.\r
-\r
-  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
-  @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>\r
-                                 format.\r
-  @param[out] Progress           A pointer to a string filled in with the offset of\r
-                                 the most recent '&' before the first failing\r
-                                 name/value pair (or the beginning of the string if\r
-                                 the failure is in the first name/value pair) or\r
-                                 the terminating NULL if all was successful.\r
+  This functino to load signature data under the signature list.\r
 \r
-  @retval EFI_SUCCESS            The Results is processed successfully.\r
-  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
-  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
-                                 driver.\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
-EFIAPI\r
-SecureBootRouteConfig (\r
-  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
-  IN CONST EFI_STRING                          Configuration,\r
-       OUT EFI_STRING                          *Progress\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
-  UINT8                      *SecureBootEnable;\r
-  SECUREBOOT_CONFIGURATION   IfrNvData;\r
-  UINTN                      BufferSize;\r
-  EFI_STATUS                 Status;\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
-  if (Configuration == NULL || Progress == NULL) {\r
-    return EFI_INVALID_PARAMETER;\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
-  *Progress = Configuration;\r
-  if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {\r
-    return EFI_NOT_FOUND;\r
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  if (EndOpCodeHandle == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ON_EXIT;\r
   }\r
 \r
   //\r
-  // Get Configuration from Variable.\r
+  // Create Hii Extend Label OpCode.\r
   //\r
-  SecureBootExtractConfigFromVariable (&IfrNvData);\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
-  // Map the Configuration to the configuration block.\r
+  // Read Variable, the variable name save in the PrivateData->VariableName.\r
   //\r
-  BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
-  Status = gHiiConfigRouting->ConfigToBlock (\r
-                                gHiiConfigRouting,\r
-                                Configuration,\r
-                                (UINT8 *)&IfrNvData,\r
-                                &BufferSize,\r
-                                Progress\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
-    return Status;\r
+    goto ON_EXIT;\r
   }\r
 \r
+  RemainingSize = DataSize;\r
+  ListWalker = (EFI_SIGNATURE_LIST *)VariableData;\r
+\r
   //\r
-  // Store Buffer Storage back to EFI variable if needed\r
+  // Skip signature list.\r
   //\r
-  SecureBootEnable = NULL;\r
-  GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);\r
-  if (NULL != SecureBootEnable) {\r
-    FreePool (SecureBootEnable);\r
-    Status = SaveSecureBootVariable (IfrNvData.AttemptSecureBoot);\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
-      return 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
-  *Progress = Configuration + StrLen (Configuration);\r
-  return EFI_SUCCESS;\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
@@ -3449,24 +4305,31 @@ 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
   UINT16                          LabelId;\r
   UINT8                           *SecureBootEnable;\r
+  UINT8                           *Pk;\r
   UINT8                           *SecureBootMode;\r
+  UINT8                           *SetupMode;\r
   CHAR16                          PromptString[100];\r
-  UINT8                           CurSecureBootMode;\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
   SecureBootMode   = NULL;\r
+  SetupMode        = NULL;\r
   File             = NULL;\r
 \r
   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
 \r
   gSecureBootPrivateData = Private;\r
@@ -3488,15 +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 if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE){\r
+    } else {\r
       //\r
-      // Secure Boot Policy variable changes after transition. Re-sync CurSecureBootMode\r
+      // When entering SecureBoot OPTION Form\r
+      // always close opened file & free resource\r
       //\r
-      ExtractSecureBootModeFromVariable(&IfrNvData->CurSecureBootMode);\r
-      mIsSelectedSecureBootModeForm = TRUE;\r
-      mIsSecureBootModeChanged = FALSE;\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
@@ -3508,12 +4383,7 @@ SecureBootCallback (
         Value->u8 = SECURE_BOOT_MODE_STANDARD;\r
         Status = EFI_SUCCESS;\r
       }\r
-    } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE) {\r
-      if (mIsSelectedSecureBootModeForm) {\r
-        Value->u8 = IfrNvData->CurSecureBootMode;\r
-        Status = EFI_SUCCESS;\r
-      }\r
-    }\r
+    } \r
     goto EXIT;\r
   }\r
 \r
@@ -3555,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
@@ -3566,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
@@ -3603,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
@@ -3654,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
@@ -3712,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
@@ -3723,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
@@ -3731,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
@@ -3767,57 +4754,6 @@ SecureBootCallback (
           );\r
       }\r
       break;\r
-    case KEY_TRANS_SECURE_BOOT_MODE:\r
-      //\r
-      // Pop up to alert user want to change secure boot mode \r
-      //\r
-      if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && \r
-           (Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE || Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE))\r
-        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && \r
-           Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE)\r
-        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && \r
-          Value->u8 == SECURE_BOOT_MODE_USER_MODE && IfrNvData->PhysicalPresent == 1)){\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Are you sure you want to switch secure boot mode?",\r
-          L"Press 'Y' to switch secure boot mode, 'N' to discard change and return",\r
-          NULL\r
-          );\r
-        if (Key.UnicodeChar != 'y' && Key.UnicodeChar != 'Y') {\r
-          //\r
-          // If not 'Y'/''y' restore to defualt secure boot mode\r
-          //\r
-          Value->u8 = IfrNvData->CurSecureBootMode;\r
-          goto EXIT;\r
-        }\r
-      } else if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && Value->u8 == SECURE_BOOT_MODE_USER_MODE)\r
-               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)\r
-               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE && Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE)\r
-               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)) {\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Secure boot mode transition requires PK change",\r
-          L"Please go to link below to update PK",\r
-          NULL\r
-          );\r
-      } else {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto EXIT;\r
-      }\r
-\r
-      Status = SecureBootModeTransition(IfrNvData->CurSecureBootMode, Value->u8);\r
-      //\r
-      // Secure Boot Policy variable may change after transition. Re-sync CurSecureBootMode\r
-      //\r
-      ExtractSecureBootModeFromVariable(&CurSecureBootMode);\r
-      if (IfrNvData->CurSecureBootMode != CurSecureBootMode) {\r
-        IfrNvData->CurSecureBootMode = CurSecureBootMode;\r
-        mIsSecureBootModeChanged = TRUE;\r
-      }\r
-      break;\r
-\r
     default:\r
       if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) &&\r
                  (QuestionId < (OPTION_DEL_KEK_QUESTION_ID + OPTION_CONFIG_RANGE))) {\r
@@ -3833,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
@@ -3863,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
@@ -3886,32 +4823,22 @@ SecureBootCallback (
     case KEY_SECURE_BOOT_MODE:\r
       mIsEnterSecureBootForm = FALSE;\r
       break;\r
-    case KEY_TRANS_SECURE_BOOT_MODE:\r
-      mIsSelectedSecureBootModeForm = FALSE;\r
-      if (mIsSecureBootModeChanged) {\r
-        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
-      }\r
-      mIsSecureBootModeChanged = FALSE;\r
-      break;\r
     case KEY_SECURE_BOOT_KEK_GUID:\r
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:\r
     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
-      if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
+      GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
+      if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\r
         IfrNvData->DeletePk = TRUE;\r
         IfrNvData->HasPk    = FALSE;\r
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
@@ -3920,17 +4847,20 @@ SecureBootCallback (
         IfrNvData->HasPk    = TRUE;\r
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
       }\r
+      if (SetupMode != NULL) {\r
+        FreePool (SetupMode);\r
+      }\r
       break;\r
     default:\r
       break;\r
     }\r
   } else if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {\r
     if (QuestionId == KEY_HIDE_SECURE_BOOT) {\r
-      GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);\r
-      if (SecureBootEnable == NULL) {\r
+      GetVariable2 (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, (VOID**)&Pk, NULL);\r
+      if (Pk == NULL) {\r
         IfrNvData->HideSecureBoot = TRUE;\r
       } else {\r
-        FreePool (SecureBootEnable);\r
+        FreePool (Pk);\r
         IfrNvData->HideSecureBoot = FALSE;\r
       }\r
       Value->b = IfrNvData->HideSecureBoot;\r
@@ -3947,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