]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
SecurityPkg: SecureBootConfigDxe: Update CloseEnrolledFile comment
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigImpl.c
index e2340e63023d9ebf1a32110bb4acec2eb698cdcc..2eaf24633db15d880c95c23ae493b12ed551de49 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   HII Config Access protocol implementation of SecureBoot configuration module.\r
 \r
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -49,8 +49,6 @@ HII_VENDOR_DEVICE_PATH          mSecureBootHiiVendorDevicePath = {
 \r
 \r
 BOOLEAN mIsEnterSecureBootForm = FALSE;\r
-BOOLEAN mIsSelectedSecureBootModeForm = FALSE;\r
-BOOLEAN mIsSecureBootModeChanged = FALSE;\r
 \r
 //\r
 // OID ASN.1 Value for Hash Algorithms\r
@@ -65,7 +63,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
@@ -97,6 +94,33 @@ CHAR16* mDerEncodedSuffix[] = {
 };\r
 CHAR16* mSupportX509Suffix = L"*.cer/der/crt";\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
@@ -120,6 +144,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
@@ -475,10 +554,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
@@ -655,9 +731,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
@@ -778,9 +852,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
@@ -814,7 +886,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
@@ -837,6 +909,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
@@ -948,9 +1025,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
@@ -1508,9 +1583,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
@@ -1593,6 +1667,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
@@ -1609,9 +1731,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
@@ -1673,6 +1814,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
@@ -1700,7 +1844,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
@@ -1709,13 +1853,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
@@ -1757,12 +1896,12 @@ HashPeImage (
     //\r
     // Use PE32 offset.\r
     //\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
   } else {\r
     //\r
     // Use PE32+ offset.\r
     //\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
   }\r
 \r
   Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
@@ -1779,13 +1918,13 @@ HashPeImage (
     // Use PE32 offset.\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
   } else {\r
     //\r
     // Use PE32+ offset.\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
-    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+    HashSize = (UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
   }\r
 \r
   Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
@@ -1801,13 +1940,13 @@ HashPeImage (
     // Use PE32 offset\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
-    HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
+    HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN) mImageBase);\r
   } else {\r
     //\r
     // Use PE32+ offset.\r
     //\r
     HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
-    HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
+    HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN) mImageBase);\r
   }\r
 \r
   Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
@@ -1986,6 +2125,107 @@ HashPeImageByType (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Enroll a new executable's signature into Signature Database.\r
+\r
+  @param[in] PrivateData     The module's private data.\r
+  @param[in] VariableName    Variable name of signature database, must be\r
+                             EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1\r
+                             or EFI_IMAGE_SECURITY_DATABASE2.\r
+\r
+  @retval   EFI_SUCCESS            New signature is enrolled successfully.\r
+  @retval   EFI_INVALID_PARAMETER  The parameter is invalid.\r
+  @retval   EFI_UNSUPPORTED        Unsupported command.\r
+  @retval   EFI_OUT_OF_RESOURCES   Could not allocate needed resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EnrollAuthentication2Descriptor (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private,\r
+  IN CHAR16                         *VariableName\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  VOID                              *Data;\r
+  UINTN                             DataSize;\r
+  UINT32                            Attr;\r
+\r
+  Data = NULL;\r
+\r
+  //\r
+  // DBT only support DER-X509 Cert Enrollment\r
+  //\r
+  if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Read the whole file content\r
+  //\r
+  Status = ReadFileContent(\r
+             Private->FileContext->FHandle,\r
+             (VOID **) &mImageBase,\r
+             &mImageSize,\r
+             0\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
+  ASSERT (mImageBase != NULL);\r
+\r
+  Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS\r
+         | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+\r
+  //\r
+  // Check if SigDB variable has been already existed.\r
+  // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the\r
+  // new signature data to original variable\r
+  //\r
+  DataSize = 0;\r
+  Status = gRT->GetVariable(\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  NULL\r
+                  );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Attr |= EFI_VARIABLE_APPEND_WRITE;\r
+  } else if (Status != EFI_NOT_FOUND) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Diretly set AUTHENTICATION_2 data to SetVariable\r
+  //\r
+  Status = gRT->SetVariable(\r
+                  VariableName,\r
+                  &gEfiImageSecurityDatabaseGuid,\r
+                  Attr,\r
+                  mImageSize,\r
+                  mImageBase\r
+                  );\r
+\r
+  DEBUG((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status));\r
+\r
+ON_EXIT:\r
+\r
+  CloseEnrolledFile(Private->FileContext);\r
+\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
+\r
+  if (mImageBase != NULL) {\r
+    FreePool (mImageBase);\r
+    mImageBase = NULL;\r
+  }\r
+\r
+  return Status;\r
+\r
+}\r
+\r
+\r
 /**\r
   Enroll a new executable's signature into Signature Database.\r
 \r
@@ -2155,9 +2395,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
@@ -2221,9 +2459,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
@@ -2810,256 +3050,6 @@ ON_EXIT:
            );\r
 }\r
 \r
-/**\r
-  Perform secure boot mode transition from User Mode by setting AuditMode \r
-  or DeployedMode variable.\r
-\r
-  @param[in]  NewMode          New secure boot mode.\r
-\r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromUserMode(\r
-  IN  UINT8 NewMode\r
-  )\r
-{\r
-  UINT8      Data;\r
-  EFI_STATUS Status;\r
-\r
-  if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    Data = 1;\r
-    Status = gRT->SetVariable(\r
-                    EFI_AUDIT_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    return Status;\r
-  } else if (NewMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
-    Data = 1;\r
-    Status = gRT->SetVariable(\r
-                    EFI_DEPLOYED_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Other case do nothing here. May Goto enroll PK page.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Perform secure boot mode transition from Setup Mode by setting AuditMode \r
-  variable.\r
-\r
-  @param[in]  NewMode          New secure boot mode.\r
-\r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromSetupMode(\r
-  IN UINT8 NewMode\r
-  )\r
-{\r
-  UINT8      Data;\r
-  EFI_STATUS Status;\r
-\r
-  Status = EFI_INVALID_PARAMETER;\r
-\r
-  if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    Data = 1;\r
-    Status = gRT->SetVariable(\r
-                    EFI_AUDIT_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Other case do nothing here. May Goto enroll PK page.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Perform secure boot mode transition from Audit Mode. Nothing is done here,\r
-  should goto enroll PK page.\r
-\r
-  @param[in]  NewMode          New secure boot mode.\r
-\r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromAuditMode(\r
-  IN UINT8 NewMode\r
-  )\r
-{\r
-  //\r
-  // Other case do nothing here. Should Goto enroll PK page.\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-   Perform secure boot mode transition from Deployed Mode by setting Deployed Mode\r
-   variable to 0.\r
-\r
-  @param[in]  NewMode          New secure boot mode.\r
-\r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-TransitionFromDeployedMode(\r
-  IN UINT8 NewMode\r
-  )\r
-{\r
-  UINT8      Data;\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  // Platform specific logic. when physical presence,  Allow to set DeployedMode =:0\r
-  // to switch back to UserMode\r
-  //\r
-  if (NewMode == SECURE_BOOT_MODE_USER_MODE) {\r
-    Data = 0;\r
-    Status = gRT->SetVariable(\r
-                    EFI_DEPLOYED_MODE_NAME,\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    sizeof(UINT8),\r
-                    &Data\r
-                    );\r
-    DEBUG((EFI_D_INFO, "DeployedMode Status %x\n", Status));\r
-    return Status;\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-   Perform main secure boot mode transition.\r
-\r
-  @param[in]  CurMode          New secure boot mode.\r
-  @param[in]  NewMode          New secure boot mode.\r
-\r
-  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.\r
-**/\r
-EFI_STATUS\r
-SecureBootModeTransition(\r
-  IN  UINT8  CurMode,\r
-  IN  UINT8  NewMode\r
-  )\r
-{\r
-  EFI_STATUS                         Status;\r
-\r
-  //\r
-  // Set platform to be customized mode to ensure platform specific mode switch sucess\r
-  //\r
-  Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // SecureBootMode transition\r
-  //\r
-  switch (CurMode) {\r
-    case SECURE_BOOT_MODE_USER_MODE:\r
-      Status = TransitionFromUserMode(NewMode);\r
-      break;\r
-\r
-    case SECURE_BOOT_MODE_SETUP_MODE:\r
-      Status = TransitionFromSetupMode(NewMode);\r
-      break;\r
-\r
-    case SECURE_BOOT_MODE_AUDIT_MODE:\r
-      Status = TransitionFromAuditMode(NewMode);\r
-      break;\r
-\r
-    case SECURE_BOOT_MODE_DEPLOYED_MODE:\r
-      Status = TransitionFromDeployedMode(NewMode);\r
-      break;\r
-\r
-    default:\r
-      Status = EFI_INVALID_PARAMETER;\r
-      ASSERT(FALSE);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-   Get current secure boot mode by retrieve data from SetupMode/AuditMode/DeployedMode.\r
-\r
-  @param[out]  SecureBootMode                Current secure boot mode.\r
-\r
-**/\r
-VOID\r
-ExtractSecureBootModeFromVariable(\r
-  OUT UINT8      *SecureBootMode\r
-  )\r
-{\r
-  UINT8     *SetupMode;\r
-  UINT8     *AuditMode;\r
-  UINT8     *DeployedMode;\r
-\r
-  SetupMode        = NULL;\r
-  AuditMode        = NULL;\r
-  DeployedMode     = NULL;\r
-\r
-  //\r
-  // Get AuditMode/DeployedMode from variable\r
-  //\r
-  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
-  GetVariable2 (EFI_AUDIT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&AuditMode, NULL);\r
-  GetVariable2 (EFI_DEPLOYED_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&DeployedMode, NULL);\r
-  if (SetupMode != NULL && AuditMode != NULL && DeployedMode != NULL) {\r
-    if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 0) {\r
-      //\r
-      // User Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_USER_MODE;\r
-    } else if (*SetupMode == 1 && *AuditMode == 0 && *DeployedMode == 0) {\r
-      //\r
-      // Setup Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_SETUP_MODE;\r
-    } else if (*SetupMode == 1 && *AuditMode == 1 && *DeployedMode == 0) {\r
-      //\r
-      // Audit Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_AUDIT_MODE;\r
-    } else if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 1) {\r
-      //\r
-      // Deployed Mode\r
-      //\r
-      *SecureBootMode = SECURE_BOOT_MODE_DEPLOYED_MODE;\r
-    } else {\r
-      ASSERT(FALSE);\r
-    }\r
-  }else {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  if (SetupMode != NULL) {\r
-    FreePool (SetupMode);\r
-  }\r
-  if (DeployedMode != NULL) {\r
-    FreePool (DeployedMode);\r
-  }\r
-  if (AuditMode != NULL) {\r
-    FreePool (AuditMode);\r
-  }\r
-}\r
-\r
 /**\r
 \r
   Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT\r
@@ -3074,8 +3064,8 @@ ExtractSecureBootModeFromVariable(
 EFI_STATUS\r
 UpdateSecureBootString(\r
   IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private\r
-  ) {\r
-  UINT8       CurSecureBootMode;\r
+  )\r
+{\r
   UINT8       *SecureBoot;\r
 \r
   SecureBoot = NULL;\r
@@ -3093,20 +3083,6 @@ UpdateSecureBootString(
   } else {\r
     HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);\r
   }\r
-  //\r
-  // Get current secure boot mode.\r
-  //\r
-  ExtractSecureBootModeFromVariable(&CurSecureBootMode);\r
-  \r
-  if (CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL);\r
-  } else if (CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL);\r
-  } else if (CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL);\r
-  } else if (CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
-    HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL);\r
-  }\r
 \r
   FreePool(SecureBoot);\r
 \r
@@ -3116,19 +3092,23 @@ UpdateSecureBootString(
 /**\r
   This function extracts configuration from variable.\r
 \r
+  @param[in]       Private      Point to SecureBoot configuration driver private data.\r
   @param[in, out]  ConfigData   Point to SecureBoot configuration private data.\r
 \r
 **/\r
 VOID\r
 SecureBootExtractConfigFromVariable (\r
+  IN SECUREBOOT_CONFIG_PRIVATE_DATA  *Private,\r
   IN OUT SECUREBOOT_CONFIGURATION    *ConfigData\r
   )\r
 {\r
   UINT8     *SecureBootEnable;\r
+  UINT8     *SetupMode;\r
   UINT8     *SecureBootMode;\r
   EFI_TIME  CurrTime;\r
 \r
   SecureBootEnable = NULL;\r
+  SetupMode        = NULL;\r
   SecureBootMode   = NULL;\r
 \r
   //\r
@@ -3143,20 +3123,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
@@ -3169,33 +3139,51 @@ SecureBootExtractConfigFromVariable (
   }\r
 \r
   //\r
-  // Get the SecureBootMode from CustomMode variable.\r
+  // If there is no PK then the Delete Pk button will be gray.\r
   //\r
-  GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL);\r
-  if (SecureBootMode == NULL) {\r
-    ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;\r
-  } else {\r
-    ConfigData->SecureBootMode = *(SecureBootMode);\r
+  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
+  if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\r
+    ConfigData->HasPk = FALSE;\r
+  } else  {\r
+    ConfigData->HasPk = TRUE;\r
   }\r
 \r
   //\r
-  // Extact current Secure Boot Mode\r
+  // Check SecureBootEnable & Pk status, fix the inconsistence. \r
+  // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable\r
+  // Checkbox.\r
   //\r
-  ExtractSecureBootModeFromVariable(&ConfigData->CurSecureBootMode);\r
+  ConfigData->AttemptSecureBoot = FALSE;\r
+  GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);  \r
 \r
   //\r
-  // If there is no PK then the Delete Pk button will be gray.\r
+  // Fix Pk, SecureBootEnable inconsistence\r
   //\r
-  if (ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE || ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {\r
-    ConfigData->HasPk = FALSE;\r
-  } else  {\r
-    ConfigData->HasPk = TRUE;\r
+  if ((SetupMode != NULL) && (*SetupMode) == USER_MODE) {\r
+    ConfigData->HideSecureBoot = FALSE;\r
+    if ((SecureBootEnable != NULL) && (*SecureBootEnable == SECURE_BOOT_ENABLE)) {\r
+      ConfigData->AttemptSecureBoot = TRUE;\r
+    }\r
+  } else {\r
+    ConfigData->HideSecureBoot = TRUE;\r
+  }\r
+\r
+  //\r
+  // Get the SecureBootMode from CustomMode variable.\r
+  //\r
+  GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL);\r
+  if (SecureBootMode == NULL) {\r
+    ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;\r
+  } else {\r
+    ConfigData->SecureBootMode = *(SecureBootMode);\r
   }\r
 \r
   if (SecureBootEnable != NULL) {\r
     FreePool (SecureBootEnable);\r
   }\r
-\r
+  if (SetupMode != NULL) {\r
+    FreePool (SetupMode);\r
+  }\r
   if (SecureBootMode != NULL) {\r
     FreePool (SecureBootMode);\r
   }\r
@@ -3262,10 +3250,12 @@ SecureBootExtractConfig (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  ZeroMem(&Configuration, sizeof(SECUREBOOT_CONFIGURATION));\r
+\r
   //\r
   // Get Configuration from Variable.\r
   //\r
-  SecureBootExtractConfigFromVariable (&Configuration);\r
+  SecureBootExtractConfigFromVariable (PrivateData, &Configuration);\r
 \r
   BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
   ConfigRequest = Request;\r
@@ -3340,10 +3330,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
@@ -3354,10 +3344,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
@@ -3377,10 +3369,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
@@ -3426,24 +3415,35 @@ SecureBootCallback (
 {\r
   EFI_INPUT_KEY                   Key;\r
   EFI_STATUS                      Status;\r
+  RETURN_STATUS                   RStatus;\r
   SECUREBOOT_CONFIG_PRIVATE_DATA  *Private;\r
   UINTN                           BufferSize;\r
   SECUREBOOT_CONFIGURATION        *IfrNvData;\r
   UINT16                          LabelId;\r
   UINT8                           *SecureBootEnable;\r
+  UINT8                           *Pk;\r
   UINT8                           *SecureBootMode;\r
+  UINT8                           *SetupMode;\r
   CHAR16                          PromptString[100];\r
-  UINT8                           CurSecureBootMode;\r
+  EFI_DEVICE_PATH_PROTOCOL        *File;\r
+  UINTN                           NameLength;\r
+  UINT16                          *FilePostFix;\r
+  SECUREBOOT_CONFIG_PRIVATE_DATA  *PrivateData;\r
 \r
   Status           = EFI_SUCCESS;\r
   SecureBootEnable = NULL;\r
   SecureBootMode   = NULL;\r
+  SetupMode        = NULL;\r
+  File             = NULL;\r
 \r
   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);\r
 \r
+  gSecureBootPrivateData = Private;\r
+\r
   //\r
   // Retrieve uncommitted data from Browser\r
   //\r
@@ -3461,14 +3461,20 @@ SecureBootCallback (
       // Update secure boot strings when opening this form\r
       //\r
       Status = UpdateSecureBootString(Private);\r
+      SecureBootExtractConfigFromVariable (Private, IfrNvData);\r
       mIsEnterSecureBootForm = TRUE;\r
-    } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE){\r
+    } else {\r
       //\r
-      // Secure Boot Policy variable changes after transition. Re-sync CurSecureBootMode\r
+      // When entering SecureBoot OPTION Form\r
+      // always close opened file & free resource\r
       //\r
-      ExtractSecureBootModeFromVariable(&IfrNvData->CurSecureBootMode);\r
-      mIsSelectedSecureBootModeForm = TRUE;\r
-      mIsSecureBootModeChanged = FALSE;\r
+      if ((QuestionId == KEY_SECURE_BOOT_PK_OPTION) ||\r
+          (QuestionId == KEY_SECURE_BOOT_KEK_OPTION) ||\r
+          (QuestionId == KEY_SECURE_BOOT_DB_OPTION) ||\r
+          (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) ||\r
+          (QuestionId == KEY_SECURE_BOOT_DBT_OPTION)) {\r
+        CloseEnrolledFile(Private->FileContext);\r
+      }\r
     }\r
     goto EXIT;\r
   }\r
@@ -3480,12 +3486,7 @@ SecureBootCallback (
         Value->u8 = SECURE_BOOT_MODE_STANDARD;\r
         Status = EFI_SUCCESS;\r
       }\r
-    } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE) {\r
-      if (mIsSelectedSecureBootModeForm) {\r
-        Value->u8 = IfrNvData->CurSecureBootMode;\r
-        Status = EFI_SUCCESS;\r
-      }\r
-    }\r
+    } \r
     goto EXIT;\r
   }\r
 \r
@@ -3523,15 +3524,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
@@ -3543,6 +3540,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
@@ -3558,28 +3560,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
@@ -3685,7 +3723,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
@@ -3696,6 +3739,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
@@ -3704,7 +3748,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
@@ -3722,61 +3766,26 @@ SecureBootCallback (
           );\r
       }\r
       break;\r
-    case KEY_TRANS_SECURE_BOOT_MODE:\r
-      //\r
-      // Pop up to alert user want to change secure boot mode \r
-      //\r
-      if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && \r
-           (Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE || Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE))\r
-        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && \r
-           Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE)\r
-        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && \r
-          Value->u8 == SECURE_BOOT_MODE_USER_MODE && IfrNvData->PhysicalPresent == 1)){\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Are you sure you want to switch secure boot mode?",\r
-          L"Press 'Y' to switch secure boot mode, 'N' to discard change and return",\r
-          NULL\r
+    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
-        if (Key.UnicodeChar != 'y' && Key.UnicodeChar != 'Y') {\r
-          //\r
-          // If not 'Y'/''y' restore to defualt secure boot mode\r
-          //\r
-          Value->u8 = IfrNvData->CurSecureBootMode;\r
-          goto EXIT;\r
-        }\r
-      } else if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && Value->u8 == SECURE_BOOT_MODE_USER_MODE)\r
-               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)\r
-               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE && Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE)\r
-               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)) {\r
         CreatePopUp (\r
           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
           &Key,\r
-          L"Secure boot mode transition requires PK change",\r
-          L"Please go to link below to update PK",\r
+          L"ERROR: Unsupported file type!",\r
+          PromptString,\r
           NULL\r
           );\r
-      } else {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto EXIT;\r
-      }\r
-\r
-      Status = SecureBootModeTransition(IfrNvData->CurSecureBootMode, Value->u8);\r
-      //\r
-      // Secure Boot Policy variable may change after transition. Re-sync CurSecureBootMode\r
-      //\r
-      ExtractSecureBootModeFromVariable(&CurSecureBootMode);\r
-      if (IfrNvData->CurSecureBootMode != CurSecureBootMode) {\r
-        IfrNvData->CurSecureBootMode = CurSecureBootMode;\r
-        mIsSecureBootModeChanged = TRUE;\r
       }\r
       break;\r
-\r
     default:\r
-      if (QuestionId >= 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
@@ -3814,80 +3823,44 @@ 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
-    case KEY_TRANS_SECURE_BOOT_MODE:\r
-      mIsSelectedSecureBootModeForm = FALSE;\r
-      if (mIsSecureBootModeChanged) {\r
-        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
-      }\r
-      mIsSecureBootModeChanged = FALSE;\r
-      break;\r
     case KEY_SECURE_BOOT_KEK_GUID:\r
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:\r
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:\r
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT:\r
       ASSERT (Private->SignatureGUID != NULL);\r
-      Status = StringToGuid (\r
-                 IfrNvData->SignatureGuid,\r
-                 StrLen (IfrNvData->SignatureGuid),\r
-                 Private->SignatureGUID\r
-                 );\r
-      if (EFI_ERROR (Status)) {\r
+      RStatus = StrToGuid (IfrNvData->SignatureGuid, Private->SignatureGUID);\r
+      if (RETURN_ERROR (RStatus) || (IfrNvData->SignatureGuid[GUID_STRING_LENGTH] != L'\0')) {\r
+        Status = EFI_INVALID_PARAMETER;\r
         break;\r
       }\r
 \r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
       break;\r
-\r
     case KEY_SECURE_BOOT_DELETE_PK:\r
-      if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
+      GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
+      if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\r
         IfrNvData->DeletePk = TRUE;\r
         IfrNvData->HasPk    = FALSE;\r
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
@@ -3896,22 +3869,20 @@ SecureBootCallback (
         IfrNvData->HasPk    = TRUE;\r
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
       }\r
+      if (SetupMode != NULL) {\r
+        FreePool (SetupMode);\r
+      }\r
       break;\r
     default:\r
-      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
@@ -3939,6 +3910,11 @@ EXIT:
 \r
   FreePool (IfrNvData);\r
 \r
+  if (File != NULL){\r
+    FreePool(File);\r
+    File = NULL;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -4003,19 +3979,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
@@ -4095,19 +4064,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