]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
SecurityPkg: Add constraints on PK strength
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigImpl.c
index 5b8ae7e8d8e2ff4933ca299ab4aceedbffaeb393..e82bfe77570de0960daa8fb2e0a226ac44cbf55a 100644 (file)
@@ -1,18 +1,14 @@
 /** @file\r
   HII Config Access protocol implementation of SecureBoot configuration module.\r
 \r
-Copyright (c) 2011 - 2014, 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "SecureBootConfigImpl.h"\r
+#include <Library/BaseCryptLib.h>\r
 \r
 CHAR16              mSecureBootStorageName[] = L"SECUREBOOT_CONFIGURATION";\r
 \r
@@ -63,7 +59,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
@@ -95,6 +90,49 @@ CHAR16* mDerEncodedSuffix[] = {
 };\r
 CHAR16* mSupportX509Suffix = L"*.cer/der/crt";\r
 \r
+//\r
+// Prompt strings during certificate enrollment.\r
+//\r
+CHAR16* mX509EnrollPromptTitle[] = {\r
+  L"",\r
+  L"ERROR: Unsupported file type!",\r
+  L"ERROR: Unsupported certificate!",\r
+  NULL\r
+};\r
+CHAR16* mX509EnrollPromptString[] = {\r
+  L"",\r
+  L"Only DER encoded certificate file (*.cer/der/crt) is supported.",\r
+  L"Public key length should be equal to or greater than 2048 bits.",\r
+  NULL\r
+};\r
+\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
@@ -118,6 +156,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
@@ -157,7 +250,7 @@ SaveSecureBootVariable (
                                    it's caller's responsibility to free the memory when finish using it.\r
 \r
   @retval EFI_SUCCESS              Create time based payload successfully.\r
-  @retval EFI_OUT_OF_RESOURCES     There are not enough memory resourses to create time based payload.\r
+  @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources to create time based payload.\r
   @retval EFI_INVALID_PARAMETER    The parameter is invalid.\r
   @retval Others                   Unexpected error happens.\r
 \r
@@ -306,6 +399,102 @@ SetSecureBootMode (
                 );\r
 }\r
 \r
+/**\r
+  This code checks if the encode type and key strength of X.509\r
+  certificate is qualified.\r
+\r
+  @param[in]  X509FileContext     FileContext of X.509 certificate storing\r
+                                  file.\r
+  @param[out] Error               Error type checked in the certificate.\r
+\r
+  @return EFI_SUCCESS             The certificate checked successfully.\r
+  @return EFI_INVALID_PARAMETER   The parameter is invalid.\r
+  @return EFI_OUT_OF_RESOURCES    Memory allocation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+CheckX509Certificate (\r
+  IN    SECUREBOOT_FILE_CONTEXT*    X509FileContext,\r
+  OUT   ENROLL_KEY_ERROR*           Error\r
+)\r
+{\r
+  EFI_STATUS     Status;\r
+  UINT16*        FilePostFix;\r
+  UINTN          NameLength;\r
+  UINT8*         X509Data;\r
+  UINTN          X509DataSize;\r
+  void*          X509PubKey;\r
+  UINTN          PubKeyModSize;\r
+\r
+  if (X509FileContext->FileName == NULL) {\r
+    *Error = Unsupported_Type;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  X509Data       = NULL;\r
+  X509DataSize   = 0;\r
+  X509PubKey     = NULL;\r
+  PubKeyModSize  = 0;\r
+\r
+  //\r
+  // Parse the file's postfix. Only support DER encoded X.509 certificate files.\r
+  //\r
+  NameLength = StrLen (X509FileContext->FileName);\r
+  if (NameLength <= 4) {\r
+    DEBUG ((DEBUG_ERROR, "Wrong X509 NameLength\n"));\r
+    *Error = Unsupported_Type;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  FilePostFix = X509FileContext->FileName + NameLength - 4;\r
+  if (!IsDerEncodeCertificate (FilePostFix)) {\r
+    DEBUG ((DEBUG_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.\n", mSupportX509Suffix));\r
+    *Error = Unsupported_Type;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  DEBUG ((DEBUG_INFO, "FileName= %s\n", X509FileContext->FileName));\r
+  DEBUG ((DEBUG_INFO, "FilePostFix = %s\n", FilePostFix));\r
+\r
+  //\r
+  // Read the certificate file content\r
+  //\r
+  Status = ReadFileContent (X509FileContext->FHandle, (VOID**) &X509Data, &X509DataSize, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Error occured while reading the file.\n"));\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Parse the public key context.\r
+  //\r
+  if (RsaGetPublicKeyFromX509 (X509Data, X509DataSize, &X509PubKey) == FALSE) {\r
+    DEBUG ((DEBUG_ERROR, "Error occured while parsing the pubkey from certificate.\n"));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    *Error = Unsupported_Type;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Parse Module size of public key using interface provided by CryptoPkg, which is\r
+  // actually the size of public key.\r
+  //\r
+  if (X509PubKey != NULL) {\r
+    RsaGetKey (X509PubKey, RsaKeyN, NULL, &PubKeyModSize);\r
+    if (PubKeyModSize < CER_PUBKEY_MIN_SIZE) {\r
+      DEBUG ((DEBUG_ERROR, "Unqualified PK size, key size should be equal to or greater than 2048 bits.\n"));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *Error = Unqualified_Key;\r
+    }\r
+    RsaFree (X509PubKey);\r
+  }\r
+\r
+ ON_EXIT:\r
+  if (X509Data != NULL) {\r
+    FreePool (X509Data);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Generate the PK signature list from the X509 Certificate storing file (.cer)\r
 \r
@@ -313,7 +502,7 @@ SetSecureBootMode (
   @param[out]  PkCert                Point to the data buffer to store the signature list.\r
 \r
   @return EFI_UNSUPPORTED            Unsupported Key Length.\r
-  @return EFI_OUT_OF_RESOURCES       There are not enough memory resourses to form the signature list.\r
+  @return EFI_OUT_OF_RESOURCES       There are not enough memory resources to form the signature list.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -400,12 +589,6 @@ EnrollPlatformKey (
   UINT32                          Attr;\r
   UINTN                           DataSize;\r
   EFI_SIGNATURE_LIST              *PkCert;\r
-  UINT16*                         FilePostFix;\r
-  UINTN                           NameLength;\r
-\r
-  if (Private->FileContext->FileName == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
 \r
   PkCert = NULL;\r
 \r
@@ -415,22 +598,7 @@ EnrollPlatformKey (
   }\r
 \r
   //\r
-  // Parse the file's postfix. Only support DER encoded X.509 certificate files.\r
-  //\r
-  NameLength = StrLen (Private->FileContext->FileName);\r
-  if (NameLength <= 4) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  FilePostFix = Private->FileContext->FileName + NameLength - 4;\r
-  if (!IsDerEncodeCertificate(FilePostFix)) {\r
-    DEBUG ((EFI_D_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.", mSupportX509Suffix));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  DEBUG ((EFI_D_INFO, "FileName= %s\n", Private->FileContext->FileName));\r
-  DEBUG ((EFI_D_INFO, "FilePostFix = %s\n", FilePostFix));\r
-\r
-  //\r
-  // Prase the selected PK file and generature PK certificate list.\r
+  // Prase the selected PK file and generate PK certificate list.\r
   //\r
   Status = CreatePkX509SignatureList (\r
             Private->FileContext->FHandle,\r
@@ -473,10 +641,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
@@ -653,9 +818,7 @@ EnrollRsa2048ToKek (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FHandle = NULL;\r
-  Private->FileContext->FileName = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -776,9 +939,7 @@ EnrollX509ToKek (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FileName = NULL;\r
-  Private->FileContext->FHandle = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -812,7 +973,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
@@ -835,6 +996,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
@@ -946,9 +1112,7 @@ EnrollX509toSigDB (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FileName = NULL;\r
-  Private->FileContext->FHandle = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -1015,7 +1179,7 @@ IsSignatureFoundInDatabase (
   }\r
 \r
   //\r
-  // Enumerate all signature data in SigDB to check if executable's signature exists.\r
+  // Enumerate all signature data in SigDB to check if signature exists for executable.\r
   //\r
   CertList = (EFI_SIGNATURE_LIST *) Data;\r
   while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
@@ -1239,7 +1403,7 @@ Done:
 /**\r
   Check whether the signature list exists in given variable data.\r
 \r
-  It searches the signature list for the ceritificate hash by CertType.\r
+  It searches the signature list for the certificate hash by CertType.\r
   If the signature list is found, get the offset of Database for the\r
   next hash of a certificate.\r
 \r
@@ -1506,9 +1670,8 @@ EnrollX509HashtoSigDB (
   }\r
 \r
 ON_EXIT:\r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FileName = NULL;\r
-  Private->FileContext->FHandle = NULL;\r
+\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -1591,6 +1754,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
@@ -1607,9 +1818,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
@@ -1643,15 +1873,17 @@ LoadPeImage (
   // Note the size of FileHeader field is constant for both IA32 and X64 arch\r
   //\r
   if ((NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32)\r
-      || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_EBC)) {\r
+      || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_EBC)\r
+      || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED)) {\r
     //\r
-    // IA-32 Architecture\r
+    // 32-bits Architecture\r
     //\r
     mImageType = ImageType_IA32;\r
     mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY*) &(NtHeader32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]);\r
   }\r
   else if ((NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64)\r
-          || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64)) {\r
+          || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64)\r
+          || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_AARCH64)) {\r
     //\r
     // 64-bits Architecture\r
     //\r
@@ -1669,6 +1901,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
@@ -1681,7 +1916,6 @@ HashPeImage (
   )\r
 {\r
   BOOLEAN                   Status;\r
-  UINT16                    Magic;\r
   EFI_IMAGE_SECTION_HEADER  *Section;\r
   VOID                      *HashCtx;\r
   UINTN                     CtxSize;\r
@@ -1696,7 +1930,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
@@ -1705,13 +1939,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
@@ -1729,36 +1958,22 @@ HashPeImage (
   // Measuring PE/COFF Image Header;\r
   // But CheckSum field and SECURITY data directory (certificate) are excluded\r
   //\r
-  if (mNtHeader.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-    //\r
-    // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value\r
-    //       in the PE/COFF Header. If the MachineType is Itanium(IA64) and the\r
-    //       Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
-    //       then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
-    //\r
-    Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
-  } else {\r
-    //\r
-    // Get the magic value from the PE/COFF Optional Header\r
-    //\r
-    Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
-  }\r
 \r
   //\r
   // 3.  Calculate the distance from the base of the image header to the image checksum address.\r
   // 4.  Hash the image header from its base to beginning of the image checksum.\r
   //\r
   HashBase = mImageBase;\r
-  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
     //\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
@@ -1770,18 +1985,18 @@ HashPeImage (
   // 6.  Get the address of the beginning of the Cert Directory.\r
   // 7.  Hash everything from the end of the checksum to the start of the Cert Directory.\r
   //\r
-  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
     //\r
     // 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
@@ -1792,18 +2007,18 @@ HashPeImage (
   // 8.  Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
   // 9.  Hash everything from the end of the Cert Directory to the end of image header.\r
   //\r
-  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
     //\r
     // 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
@@ -1813,7 +2028,7 @@ HashPeImage (
   //\r
   // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.\r
   //\r
-  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
     //\r
     // Use PE32 offset.\r
     //\r
@@ -1887,7 +2102,7 @@ HashPeImage (
   //\r
   if (mImageSize > SumOfBytesHashed) {\r
     HashBase = mImageBase + SumOfBytesHashed;\r
-    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
       //\r
       // Use PE32 offset.\r
       //\r
@@ -1924,7 +2139,7 @@ Done:
 }\r
 \r
 /**\r
-  Recognize the Hash algorithm in PE/COFF Authenticode and caculate hash of\r
+  Recognize the Hash algorithm in PE/COFF Authenticode and calculate hash of\r
   Pe/Coff image based on the authenticated image hashing in PE/COFF Specification\r
   8.0 Appendix A\r
 \r
@@ -1983,7 +2198,7 @@ HashPeImageByType (
 }\r
 \r
 /**\r
-  Enroll a new executable's signature into Signature Database.\r
+  Enroll a new signature of executable 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
@@ -1997,36 +2212,25 @@ HashPeImageByType (
 \r
 **/\r
 EFI_STATUS\r
-EnrollImageSignatureToSigDB (\r
+EnrollAuthentication2Descriptor (\r
   IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private,\r
   IN CHAR16                         *VariableName\r
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  EFI_SIGNATURE_LIST                *SigDBCert;\r
-  EFI_SIGNATURE_DATA                *SigDBCertData;\r
   VOID                              *Data;\r
   UINTN                             DataSize;\r
-  UINTN                             SigDBSize;\r
   UINT32                            Attr;\r
-  WIN_CERTIFICATE_UEFI_GUID         *GuidCertData;\r
 \r
   Data = NULL;\r
-  GuidCertData = 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
-  // Form the SigDB certificate list.\r
-  // Format the data item into EFI_SIGNATURE_LIST type.\r
-  //\r
-  // We need to parse executable's signature data from specified signed executable file.\r
-  // In current implementation, we simply trust the pass-in signed executable file.\r
-  // In reality, it's OS's responsibility to verify the signed executable file.\r
-  //\r
-\r
   //\r
   // Read the whole file content\r
   //\r
@@ -2041,53 +2245,165 @@ EnrollImageSignatureToSigDB (
   }\r
   ASSERT (mImageBase != NULL);\r
 \r
-  Status = LoadPeImage ();\r
-  if (EFI_ERROR (Status)) {\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
-  if (mSecDataDir->SizeOfCert == 0) {\r
-    if (!HashPeImage (HASHALG_SHA256)) {\r
-      Status =  EFI_SECURITY_VIOLATION;\r
-      goto ON_EXIT;\r
-    }\r
-  } else {\r
+  //\r
+  // Directly set AUTHENTICATION_2 data to SetVariable\r
+  //\r
+  Status = gRT->SetVariable(\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  Attr,\r
+                  mImageSize,\r
+                  mImageBase\r
+                  );\r
 \r
-    //\r
-    // Read the certificate data\r
-    //\r
-    mCertificate = (WIN_CERTIFICATE *)(mImageBase + mSecDataDir->Offset);\r
+  DEBUG((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status));\r
 \r
-    if (mCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {\r
-      GuidCertData = (WIN_CERTIFICATE_UEFI_GUID*) mCertificate;\r
-      if (CompareMem (&GuidCertData->CertType, &gEfiCertTypeRsa2048Sha256Guid, sizeof(EFI_GUID)) != 0) {\r
-        Status = EFI_ABORTED;\r
-        goto ON_EXIT;\r
-      }\r
+ON_EXIT:\r
 \r
-      if (!HashPeImage (HASHALG_SHA256)) {\r
-        Status = EFI_ABORTED;\r
-        goto ON_EXIT;;\r
-      }\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
-    } else if (mCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
 \r
-      Status = HashPeImageByType ();\r
-      if (EFI_ERROR (Status)) {\r
-        goto ON_EXIT;;\r
-      }\r
-    } else {\r
-      Status = EFI_ABORTED;\r
-      goto ON_EXIT;\r
-    }\r
+  if (mImageBase != NULL) {\r
+    FreePool (mImageBase);\r
+    mImageBase = NULL;\r
   }\r
 \r
-  //\r
-  // Create a new SigDB entry.\r
-  //\r
-  SigDBSize = sizeof(EFI_SIGNATURE_LIST)\r
-              + sizeof(EFI_SIGNATURE_DATA) - 1\r
-              + (UINT32) mImageDigestSize;\r
+  return Status;\r
+\r
+}\r
+\r
+\r
+/**\r
+  Enroll a new signature of executable 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
+EnrollImageSignatureToSigDB (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private,\r
+  IN CHAR16                         *VariableName\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_SIGNATURE_LIST                *SigDBCert;\r
+  EFI_SIGNATURE_DATA                *SigDBCertData;\r
+  VOID                              *Data;\r
+  UINTN                             DataSize;\r
+  UINTN                             SigDBSize;\r
+  UINT32                            Attr;\r
+  WIN_CERTIFICATE_UEFI_GUID         *GuidCertData;\r
+\r
+  Data = NULL;\r
+  GuidCertData = NULL;\r
+\r
+  if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Form the SigDB certificate list.\r
+  // Format the data item into EFI_SIGNATURE_LIST type.\r
+  //\r
+  // We need to parse signature data of executable from specified signed executable file.\r
+  // In current implementation, we simply trust the pass-in signed executable file.\r
+  // In reality, it's OS's responsibility to verify the signed executable file.\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
+  Status = LoadPeImage ();\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (mSecDataDir->SizeOfCert == 0) {\r
+    if (!HashPeImage (HASHALG_SHA256)) {\r
+      Status =  EFI_SECURITY_VIOLATION;\r
+      goto ON_EXIT;\r
+    }\r
+  } else {\r
+\r
+    //\r
+    // Read the certificate data\r
+    //\r
+    mCertificate = (WIN_CERTIFICATE *)(mImageBase + mSecDataDir->Offset);\r
+\r
+    if (mCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {\r
+      GuidCertData = (WIN_CERTIFICATE_UEFI_GUID*) mCertificate;\r
+      if (CompareMem (&GuidCertData->CertType, &gEfiCertTypeRsa2048Sha256Guid, sizeof(EFI_GUID)) != 0) {\r
+        Status = EFI_ABORTED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      if (!HashPeImage (HASHALG_SHA256)) {\r
+        Status = EFI_ABORTED;\r
+        goto ON_EXIT;;\r
+      }\r
+\r
+    } else if (mCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {\r
+\r
+      Status = HashPeImageByType ();\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_EXIT;;\r
+      }\r
+    } else {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Create a new SigDB entry.\r
+  //\r
+  SigDBSize = sizeof(EFI_SIGNATURE_LIST)\r
+              + sizeof(EFI_SIGNATURE_DATA) - 1\r
+              + (UINT32) mImageDigestSize;\r
 \r
   Data = (UINT8*) AllocateZeroPool (SigDBSize);\r
   if (Data == NULL) {\r
@@ -2151,9 +2467,7 @@ EnrollImageSignatureToSigDB (
 \r
 ON_EXIT:\r
 \r
-  CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FHandle = NULL;\r
-  Private->FileContext->FileName = NULL;\r
+  CloseEnrolledFile(Private->FileContext);\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -2217,9 +2531,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
@@ -2606,7 +2922,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
@@ -2616,7 +2932,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
@@ -2806,14 +3122,231 @@ 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
+    //\r
+    //  Traverse to target EFI_SIGNATURE_LIST but others will be skipped.\r
+    //\r
+    while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex < PrivateData->ListIndex) {\r
+      CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, ListWalker->SignatureListSize);\r
+      Offset += ListWalker->SignatureListSize;\r
+\r
+      RemainingSize -= ListWalker->SignatureListSize;\r
+      ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);\r
+      ListIndex++;\r
+    }\r
+\r
+    //\r
+    //  Handle the target EFI_SIGNATURE_LIST.\r
+    //  If CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) or DelType == Delete_Signature_List_One\r
+    //  it means delete the whole EFI_SIGNATURE_LIST, So we just skip this EFI_SIGNATURE_LIST.\r
+    //\r
+    if (CheckedCount < SIGNATURE_DATA_COUNTS (ListWalker) && DelType == Delete_Signature_Data) {\r
+      NewCertList = (EFI_SIGNATURE_LIST *)(NewVariableData + Offset);\r
+      //\r
+      // Copy header.\r
+      //\r
+      CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);\r
+      Offset += sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize;\r
+\r
+      DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof(EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);\r
+      for (Index = 0; Index < SIGNATURE_DATA_COUNTS(ListWalker); Index = Index + 1) {\r
+        if (PrivateData->CheckArray[Index]) {\r
+          //\r
+          // Delete checked signature data, and update the size of whole signature list.\r
+          //\r
+          NewCertList->SignatureListSize -= NewCertList->SignatureSize;\r
+        } else {\r
+          //\r
+          // Remain the unchecked signature data.\r
+          //\r
+          CopyMem ((UINT8 *)NewVariableData + Offset, DataWalker, ListWalker->SignatureSize);\r
+          Offset += ListWalker->SignatureSize;\r
+        }\r
+        DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);\r
+      }\r
+    }\r
+\r
+    RemainingSize -= ListWalker->SignatureListSize;\r
+    ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);\r
+\r
+    //\r
+    // Copy remaining data, maybe 0.\r
+    //\r
+    CopyMem((UINT8 *)NewVariableData + Offset, ListWalker, RemainingSize);\r
+    Offset += RemainingSize;\r
+\r
+    VariableDataSize = Offset;\r
+  }\r
+\r
+  if ((VariableAttr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+    Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
+  Status = gRT->SetVariable (\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  VariableAttr,\r
+                  VariableDataSize,\r
+                  NewVariableData\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r", Status));\r
+    goto ON_EXIT;\r
+  }\r
+\r
+ON_EXIT:\r
+  SECUREBOOT_FREE_NON_NULL (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
+ and STR_CUR_SECURE_BOOT_MODE_CONTENT.\r
+\r
+  @param[in]    PrivateData         Module's private data.\r
+\r
+  @return EFI_SUCCESS              Update secure boot strings successfully.\r
+  @return other                          Fail to update secure boot strings.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateSecureBootString(\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private\r
+  )\r
+{\r
+  UINT8       *SecureBoot;\r
+\r
+  SecureBoot = NULL;\r
+\r
+  //\r
+  // Get current secure boot state.\r
+  //\r
+  GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SecureBoot, NULL);\r
+  if (SecureBoot == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (*SecureBoot == SECURE_BOOT_MODE_ENABLE) {\r
+    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Enabled", NULL);\r
+  } else {\r
+    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);\r
+  }\r
+\r
+  FreePool(SecureBoot);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\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
@@ -2827,7 +3360,7 @@ SecureBootExtractConfigFromVariable (
   SecureBootMode   = NULL;\r
 \r
   //\r
-  // Initilize the Date and Time using system time.\r
+  // Initialize the Date and Time using system time.\r
   //\r
   ConfigData->CertificateFormat = HASHALG_RAW;\r
   ConfigData->AlwaysRevocation = TRUE;\r
@@ -2838,20 +3371,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
@@ -2873,6 +3396,26 @@ SecureBootExtractConfigFromVariable (
     ConfigData->HasPk = TRUE;\r
   }\r
 \r
+  //\r
+  // Check SecureBootEnable & Pk status, fix the inconsistency.\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
+\r
+  //\r
+  // Fix Pk and SecureBootEnable inconsistency\r
+  //\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
@@ -2937,7 +3480,6 @@ SecureBootExtractConfig (
   EFI_STRING                        ConfigRequestHdr;\r
   SECUREBOOT_CONFIG_PRIVATE_DATA    *PrivateData;\r
   BOOLEAN                           AllocatedRequest;\r
-  UINT8                             *SecureBoot;\r
 \r
   if (Progress == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2947,7 +3489,6 @@ SecureBootExtractConfig (
   ConfigRequestHdr = NULL;\r
   ConfigRequest    = NULL;\r
   Size             = 0;\r
-  SecureBoot       = NULL;\r
 \r
   ZeroMem (&Configuration, sizeof (Configuration));\r
   PrivateData      = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
@@ -2957,23 +3498,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
-\r
-  //\r
-  // Update current secure boot state.\r
-  //\r
-  GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SecureBoot, NULL);\r
-  if (SecureBoot != NULL && *SecureBoot == SECURE_BOOT_MODE_ENABLE) {\r
-    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Enabled", NULL);\r
-  } else {\r
-    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);\r
-  }\r
-  if (SecureBoot != NULL) {\r
-    FreePool (SecureBoot);\r
-  }\r
+  SecureBootExtractConfigFromVariable (PrivateData, &Configuration);\r
 \r
   BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
   ConfigRequest = Request;\r
@@ -3048,10 +3578,10 @@ SecureBootRouteConfig (
        OUT EFI_STRING                          *Progress\r
   )\r
 {\r
-  UINT8                      *SecureBootEnable;\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
@@ -3062,10 +3592,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
@@ -3085,10 +3617,7 @@ SecureBootRouteConfig (
   //\r
   // Store Buffer Storage back to EFI variable if needed\r
   //\r
-  SecureBootEnable = NULL;\r
-  GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);\r
-  if (NULL != SecureBootEnable) {\r
-    FreePool (SecureBootEnable);\r
+  if (!IfrNvData.HideSecureBoot) {\r
     Status = SaveSecureBootVariable (IfrNvData.AttemptSecureBoot);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
@@ -3099,6 +3628,719 @@ SecureBootRouteConfig (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  This function to load signature list, the update the menu page.\r
+\r
+  @param[in]  PrivateData         Module's private data.\r
+  @param[in]  LabelId             Label number to insert opcodes.\r
+  @param[in]  FormId              Form ID of current page.\r
+  @param[in]  QuestionIdBase      Base question id of the signature list.\r
+\r
+  @retval   EFI_SUCCESS           Success to update the signature list page\r
+  @retval   EFI_OUT_OF_RESOURCES  Unable to allocate required resources.\r
+**/\r
+EFI_STATUS\r
+LoadSignatureList (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData,\r
+  IN UINT16                         LabelId,\r
+  IN EFI_FORM_ID                    FormId,\r
+  IN EFI_QUESTION_ID                QuestionIdBase\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_STRING_ID         ListType;\r
+  EFI_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 function 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
@@ -3134,29 +4376,78 @@ 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
-\r
-  SecureBootEnable = NULL;\r
-  SecureBootMode   = NULL;\r
-  SetupMode        = NULL;\r
+  EFI_DEVICE_PATH_PROTOCOL        *File;\r
+  UINTN                           NameLength;\r
+  UINT16                          *FilePostFix;\r
+  SECUREBOOT_CONFIG_PRIVATE_DATA  *PrivateData;\r
+  BOOLEAN                         GetBrowserDataResult;\r
+  ENROLL_KEY_ERROR                EnrollKeyErrorCode;\r
+\r
+  Status             = EFI_SUCCESS;\r
+  SecureBootEnable   = NULL;\r
+  SecureBootMode     = NULL;\r
+  SetupMode          = NULL;\r
+  File               = NULL;\r
+  EnrollKeyErrorCode = None_Error;\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
+\r
+  //\r
+  // Retrieve uncommitted data from Browser\r
+  //\r
+  BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
+  IfrNvData = AllocateZeroPool (BufferSize);\r
+  if (IfrNvData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  GetBrowserDataResult = HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *) IfrNvData);\r
+\r
   if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
     if (QuestionId == KEY_SECURE_BOOT_MODE) {\r
+      //\r
+      // Update secure boot strings when opening this form\r
+      //\r
+      Status = UpdateSecureBootString(Private);\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
-\r
-    return EFI_SUCCESS;\r
+    goto EXIT;\r
   }\r
 \r
   if (Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
@@ -3167,31 +4458,17 @@ SecureBootCallback (
         Status = EFI_SUCCESS;\r
       }\r
     }\r
-    return Status;\r
+    goto EXIT;\r
   }\r
 \r
   if ((Action != EFI_BROWSER_ACTION_CHANGED) &&\r
       (Action != EFI_BROWSER_ACTION_CHANGING) &&\r
       (Action != EFI_BROWSER_ACTION_FORM_CLOSE) &&\r
       (Action != EFI_BROWSER_ACTION_DEFAULT_STANDARD)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
-\r
-  //\r
-  // Retrieve uncommitted data from Browser\r
-  //\r
-  BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
-  IfrNvData = AllocateZeroPool (BufferSize);\r
-  if (IfrNvData == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_UNSUPPORTED;\r
+    goto EXIT;\r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
-\r
-  HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *) IfrNvData);\r
-\r
   if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
 \r
     switch (QuestionId) {\r
@@ -3218,15 +4495,11 @@ SecureBootCallback (
       }\r
       break;\r
 \r
-    case KEY_SECURE_BOOT_OPTION:\r
-      FreeMenu (&DirectoryMenu);\r
-      FreeMenu (&FsOptionMenu);\r
-      break;\r
-\r
     case KEY_SECURE_BOOT_KEK_OPTION:\r
     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
@@ -3238,6 +4511,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
@@ -3253,28 +4531,64 @@ SecureBootCallback (
       //\r
       CleanUpPage (LabelId, Private);\r
       break;\r
+    case KEY_SECURE_BOOT_PK_OPTION:\r
+      LabelId = FORMID_ENROLL_PK_FORM;\r
+      //\r
+      // Refresh selected file.\r
+      //\r
+      CleanUpPage (LabelId, Private);\r
+      break;\r
+\r
+    case FORMID_ENROLL_PK_FORM:\r
+      ChooseFile (NULL, NULL, UpdatePKFromFile, &File);\r
+      break;\r
 \r
-    case SECUREBOOT_ADD_PK_FILE_FORM_ID:\r
     case FORMID_ENROLL_KEK_FORM:\r
+      ChooseFile (NULL, NULL, UpdateKEKFromFile, &File);\r
+      break;\r
+\r
     case SECUREBOOT_ENROLL_SIGNATURE_TO_DB:\r
+      ChooseFile (NULL, NULL, UpdateDBFromFile, &File);\r
+      break;\r
+\r
     case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX:\r
-    case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT:\r
-      if (QuestionId == SECUREBOOT_ADD_PK_FILE_FORM_ID) {\r
-        Private->FeCurrentState = FileExplorerStateEnrollPkFile;\r
-      } else if (QuestionId == FORMID_ENROLL_KEK_FORM) {\r
-        Private->FeCurrentState = FileExplorerStateEnrollKekFile;\r
-      } else if (QuestionId == SECUREBOOT_ENROLL_SIGNATURE_TO_DB) {\r
-        Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDb;\r
-      } else if (QuestionId == SECUREBOOT_ENROLL_SIGNATURE_TO_DBX) {\r
-        Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDbx;\r
-        IfrNvData->CertificateFormat = HASHALG_SHA256;\r
-      } else {\r
-        Private->FeCurrentState = FileExplorerStateEnrollSignatureFileToDbt;\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
-      Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
-      CleanUpPage (FORM_FILE_EXPLORER_ID, Private);\r
-      UpdateFileExplorer (Private, 0);\r
+      break;\r
+\r
+    case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT:\r
+      ChooseFile (NULL, NULL, UpdateDBTFromFile, &File);\r
       break;\r
 \r
     case KEY_SECURE_BOOT_DELETE_PK:\r
@@ -3322,16 +4636,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
@@ -3380,7 +4767,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
@@ -3391,6 +4783,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
@@ -3399,7 +4792,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
@@ -3417,11 +4810,43 @@ SecureBootCallback (
           );\r
       }\r
       break;\r
-\r
+    case KEY_VALUE_SAVE_AND_EXIT_PK:\r
+      //\r
+      // Check the suffix, encode type and the key strength of PK certificate.\r
+      //\r
+      Status = CheckX509Certificate (Private->FileContext, &EnrollKeyErrorCode);\r
+      if (EFI_ERROR (Status)) {\r
+        if (EnrollKeyErrorCode != None_Error && EnrollKeyErrorCode < Enroll_Error_Max) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            mX509EnrollPromptTitle[EnrollKeyErrorCode],\r
+            mX509EnrollPromptString[EnrollKeyErrorCode],\r
+            NULL\r
+            );\r
+          break;\r
+        }\r
+      } else {\r
+        Status = EnrollPlatformKey (Private);\r
+      }\r
+      if (EFI_ERROR (Status)) {\r
+        UnicodeSPrint (\r
+          PromptString,\r
+          sizeof (PromptString),\r
+          L"Error status: %x.",\r
+          Status\r
+          );\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"ERROR: Enrollment failed!",\r
+          PromptString,\r
+          NULL\r
+          );\r
+      }\r
+      break;\r
     default:\r
-      if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {\r
-        UpdateFileExplorer (Private, QuestionId);\r
-      } else if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) &&\r
+      if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) &&\r
                  (QuestionId < (OPTION_DEL_KEK_QUESTION_ID + OPTION_CONFIG_RANGE))) {\r
         DeleteKeyExchangeKey (Private, QuestionId);\r
       } else if ((QuestionId >= OPTION_DEL_DB_QUESTION_ID) &&\r
@@ -3435,17 +4860,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
@@ -3459,72 +4892,41 @@ SecureBootCallback (
           );\r
       }\r
       break;\r
-    }\r
-  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
-    switch (QuestionId) {\r
-    case KEY_SECURE_BOOT_ENABLE:\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
-      break;\r
-    case KEY_VALUE_SAVE_AND_EXIT_PK:\r
-      Status = EnrollPlatformKey (Private);\r
-      if (EFI_ERROR (Status)) {\r
-        UnicodeSPrint (\r
-          PromptString,\r
-          sizeof (PromptString),\r
-          L"Only DER encoded certificate file (%s) is supported.",\r
-          mSupportX509Suffix\r
-          );\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"ERROR: Unsupported file type!",\r
-          PromptString,\r
-          NULL\r
-          );\r
-      } else {\r
-        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
-      }\r
-      break;\r
 \r
     case KEY_VALUE_NO_SAVE_AND_EXIT_PK:\r
     case KEY_VALUE_NO_SAVE_AND_EXIT_KEK:\r
     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
-        Private->FileContext->FileName = NULL;\r
-      }\r
+      CloseEnrolledFile(Private->FileContext);\r
 \r
       if (Private->SignatureGUID != NULL) {\r
         FreePool (Private->SignatureGUID);\r
         Private->SignatureGUID = NULL;\r
       }\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
       break;\r
-\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    switch (QuestionId) {\r
+    case KEY_SECURE_BOOT_ENABLE:\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+      break;\r
     case KEY_SECURE_BOOT_MODE:\r
       mIsEnterSecureBootForm = FALSE;\r
       break;\r
-\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
       GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
       if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\r
@@ -3541,20 +4943,15 @@ SecureBootCallback (
       }\r
       break;\r
     default:\r
-      if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) {\r
-        if (UpdateFileExplorer (Private, QuestionId)) {\r
-          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
-        }\r
-      }\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
@@ -3571,14 +4968,30 @@ 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
-  if (!EFI_ERROR (Status)) {\r
+EXIT:\r
+\r
+  if (!EFI_ERROR (Status) && GetBrowserDataResult) {\r
     BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
     HiiSetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8*) IfrNvData, NULL);\r
   }\r
+\r
   FreePool (IfrNvData);\r
 \r
+  if (File != NULL){\r
+    FreePool(File);\r
+    File = NULL;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -3643,19 +5056,12 @@ InstallSecureBootConfigForm (
   PrivateData->HiiHandle = HiiHandle;\r
 \r
   PrivateData->FileContext = AllocateZeroPool (sizeof (SECUREBOOT_FILE_CONTEXT));\r
-  PrivateData->MenuEntry   = AllocateZeroPool (sizeof (SECUREBOOT_MENU_ENTRY));\r
 \r
-  if (PrivateData->FileContext == NULL || PrivateData->MenuEntry == NULL) {\r
+  if (PrivateData->FileContext == NULL) {\r
     UninstallSecureBootConfigForm (PrivateData);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  PrivateData->FeCurrentState = FileExplorerStateInActive;\r
-  PrivateData->FeDisplayContext = FileExplorerDisplayUnknown;\r
-\r
-  InitializeListHead (&FsOptionMenu.Head);\r
-  InitializeListHead (&DirectoryMenu.Head);\r
-\r
   //\r
   // Init OpCode Handle and Allocate space for creation of Buffer\r
   //\r
@@ -3735,19 +5141,12 @@ UninstallSecureBootConfigForm (
     FreePool (PrivateData->SignatureGUID);\r
   }\r
 \r
-  if (PrivateData->MenuEntry != NULL) {\r
-    FreePool (PrivateData->MenuEntry);\r
-  }\r
-\r
   if (PrivateData->FileContext != NULL) {\r
     FreePool (PrivateData->FileContext);\r
   }\r
 \r
   FreePool (PrivateData);\r
 \r
-  FreeMenu (&DirectoryMenu);\r
-  FreeMenu (&FsOptionMenu);\r
-\r
   if (mStartOpCodeHandle != NULL) {\r
     HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
   }\r