]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
SecurityPkg: AuthVariableLib & SecureBootConfigDxe: Fix SecureBootEnable & PK inconsi...
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigImpl.c
index 5b8ae7e8d8e2ff4933ca299ab4aceedbffaeb393..c8f4d977d92a5506d7a4cdd2c556276d9a5087ae 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   HII Config Access protocol implementation of SecureBoot configuration module.\r
 \r
-Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2016, 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,6 +49,8 @@ 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
@@ -95,6 +97,8 @@ CHAR16* mDerEncodedSuffix[] = {
 };\r
 CHAR16* mSupportX509Suffix = L"*.cer/der/crt";\r
 \r
+SECUREBOOT_CONFIG_PRIVATE_DATA  *gSecureBootPrivateData = NULL;\r
+\r
 /**\r
   This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.\r
 \r
@@ -655,7 +659,11 @@ ON_EXIT:
 \r
   CloseFile (Private->FileContext->FHandle);\r
   Private->FileContext->FHandle = NULL;\r
-  Private->FileContext->FileName = NULL;\r
+\r
+  if (Private->FileContext->FileName != NULL){\r
+    FreePool(Private->FileContext->FileName);\r
+    Private->FileContext->FileName = NULL;\r
+  }\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -777,7 +785,11 @@ EnrollX509ToKek (
 ON_EXIT:\r
 \r
   CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FileName = NULL;\r
+  if (Private->FileContext->FileName != NULL){\r
+    FreePool(Private->FileContext->FileName);\r
+    Private->FileContext->FileName = NULL;\r
+  }\r
+\r
   Private->FileContext->FHandle = NULL;\r
 \r
   if (Private->SignatureGUID != NULL) {\r
@@ -947,7 +959,11 @@ EnrollX509toSigDB (
 ON_EXIT:\r
 \r
   CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FileName = NULL;\r
+  if (Private->FileContext->FileName != NULL){\r
+    FreePool(Private->FileContext->FileName);\r
+    Private->FileContext->FileName = NULL;\r
+  }\r
+\r
   Private->FileContext->FHandle = NULL;\r
 \r
   if (Private->SignatureGUID != NULL) {\r
@@ -1507,7 +1523,11 @@ EnrollX509HashtoSigDB (
 \r
 ON_EXIT:\r
   CloseFile (Private->FileContext->FHandle);\r
-  Private->FileContext->FileName = NULL;\r
+  if (Private->FileContext->FileName != NULL){\r
+    FreePool(Private->FileContext->FileName);\r
+    Private->FileContext->FileName = NULL;\r
+  }\r
+\r
   Private->FileContext->FHandle = NULL;\r
 \r
   if (Private->SignatureGUID != NULL) {\r
@@ -1643,15 +1663,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
@@ -1924,7 +1946,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
@@ -2153,7 +2175,11 @@ ON_EXIT:
 \r
   CloseFile (Private->FileContext->FHandle);\r
   Private->FileContext->FHandle = NULL;\r
-  Private->FileContext->FileName = NULL;\r
+\r
+  if (Private->FileContext->FileName != NULL){\r
+    FreePool(Private->FileContext->FileName);\r
+    Private->FileContext->FileName = NULL;\r
+  }\r
 \r
   if (Private->SignatureGUID != NULL) {\r
     FreePool (Private->SignatureGUID);\r
@@ -2806,6 +2832,310 @@ 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
+ 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       CurSecureBootMode;\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
+  // 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
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This function extracts configuration from variable.\r
 \r
@@ -2818,12 +3148,10 @@ SecureBootExtractConfigFromVariable (
   )\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
@@ -2839,20 +3167,6 @@ SecureBootExtractConfigFromVariable (
   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
-  } else {\r
-    ConfigData->HideSecureBoot = FALSE;\r
-    if ((*SecureBootEnable) == SECURE_BOOT_ENABLE) {\r
-      ConfigData->AttemptSecureBoot = TRUE;\r
-    }\r
-  }\r
 \r
   //\r
   // If it is Physical Presence User, set the PhysicalPresent to true.\r
@@ -2863,32 +3177,54 @@ SecureBootExtractConfigFromVariable (
     ConfigData->PhysicalPresent = FALSE;\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
+  //\r
+  // Extact current Secure Boot Mode\r
+  //\r
+  ExtractSecureBootModeFromVariable(&ConfigData->CurSecureBootMode);\r
+\r
   //\r
   // If there is no PK then the Delete Pk button will be gray.\r
   //\r
-  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL);\r
-  if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {\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
   }\r
 \r
   //\r
-  // Get the SecureBootMode from CustomMode variable.\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
-  GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL);\r
-  if (SecureBootMode == NULL) {\r
-    ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;\r
+  ConfigData->AttemptSecureBoot = FALSE;\r
+  GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL);  \r
+\r
+  //\r
+  // Fix Pk, SecureBootEnable inconsistence\r
+  //\r
+  if (ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
+    ConfigData->HideSecureBoot = FALSE;\r
+    if ((SecureBootEnable != NULL) && (*SecureBootEnable == SECURE_BOOT_ENABLE)) {\r
+      ConfigData->AttemptSecureBoot = TRUE;\r
+    }\r
   } else {\r
-    ConfigData->SecureBootMode = *(SecureBootMode);\r
+    ConfigData->HideSecureBoot = TRUE;\r
   }\r
 \r
   if (SecureBootEnable != NULL) {\r
     FreePool (SecureBootEnable);\r
   }\r
-  if (SetupMode != NULL) {\r
-    FreePool (SetupMode);\r
-  }\r
+\r
   if (SecureBootMode != NULL) {\r
     FreePool (SecureBootMode);\r
   }\r
@@ -2937,7 +3273,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 +3282,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
@@ -2962,19 +3296,6 @@ SecureBootExtractConfig (
   //\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
-\r
   BufferSize = sizeof (SECUREBOOT_CONFIGURATION);\r
   ConfigRequest = Request;\r
   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
@@ -3048,7 +3369,6 @@ SecureBootRouteConfig (
        OUT EFI_STRING                          *Progress\r
   )\r
 {\r
-  UINT8                      *SecureBootEnable;\r
   SECUREBOOT_CONFIGURATION   IfrNvData;\r
   UINTN                      BufferSize;\r
   EFI_STATUS                 Status;\r
@@ -3085,10 +3405,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
@@ -3139,24 +3456,52 @@ SecureBootCallback (
   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
 \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
+  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
+  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 (IfrNvData);\r
       mIsEnterSecureBootForm = TRUE;\r
+    } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE){\r
+      //\r
+      // Secure Boot Policy variable changes after transition. Re-sync CurSecureBootMode\r
+      //\r
+      ExtractSecureBootModeFromVariable(&IfrNvData->CurSecureBootMode);\r
+      mIsSelectedSecureBootModeForm = TRUE;\r
+      mIsSecureBootModeChanged = FALSE;\r
     }\r
-\r
-    return EFI_SUCCESS;\r
+    goto EXIT;\r
   }\r
 \r
   if (Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
@@ -3166,32 +3511,23 @@ 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
-    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,11 +3554,6 @@ 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
@@ -3253,28 +3584,32 @@ 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
-      }\r
+      ChooseFile (NULL, NULL, UpdateDBXFromFile, &File);\r
+      break;\r
 \r
-      Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
-      CleanUpPage (FORM_FILE_EXPLORER_ID, Private);\r
-      UpdateFileExplorer (Private, 0);\r
+    case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT:\r
+      ChooseFile (NULL, NULL, UpdateDBTFromFile, &File);\r
       break;\r
 \r
     case KEY_SECURE_BOOT_DELETE_PK:\r
@@ -3417,11 +3752,77 @@ SecureBootCallback (
           );\r
       }\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
+      }\r
+      break;\r
+    case KEY_TRANS_SECURE_BOOT_MODE:\r
+      //\r
+      // Pop up to alert user want to change secure boot mode \r
+      //\r
+      if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && \r
+           (Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE || Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE))\r
+        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && \r
+           Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE)\r
+        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && \r
+          Value->u8 == SECURE_BOOT_MODE_USER_MODE && IfrNvData->PhysicalPresent == 1)){\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Are you sure you want to switch secure boot mode?",\r
+          L"Press 'Y' to switch secure boot mode, 'N' to discard change and return",\r
+          NULL\r
+          );\r
+        if (Key.UnicodeChar != 'y' && Key.UnicodeChar != 'Y') {\r
+          //\r
+          // If not 'Y'/''y' restore to defualt secure boot mode\r
+          //\r
+          Value->u8 = IfrNvData->CurSecureBootMode;\r
+          goto EXIT;\r
+        }\r
+      } else if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && Value->u8 == SECURE_BOOT_MODE_USER_MODE)\r
+               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)\r
+               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE && Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE)\r
+               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Secure boot mode transition requires PK change",\r
+          L"Please go to link below to update PK",\r
+          NULL\r
+          );\r
+      } else {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto EXIT;\r
+      }\r
+\r
+      Status = SecureBootModeTransition(IfrNvData->CurSecureBootMode, Value->u8);\r
+      //\r
+      // Secure Boot Policy variable may change after transition. Re-sync CurSecureBootMode\r
+      //\r
+      ExtractSecureBootModeFromVariable(&CurSecureBootMode);\r
+      if (IfrNvData->CurSecureBootMode != CurSecureBootMode) {\r
+        IfrNvData->CurSecureBootMode = CurSecureBootMode;\r
+        mIsSecureBootModeChanged = TRUE;\r
+      }\r
+      break;\r
 \r
     default:\r
-      if (QuestionId >= 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
@@ -3459,32 +3860,6 @@ 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
@@ -3494,20 +3869,33 @@ SecureBootCallback (
       if (Private->FileContext->FHandle != NULL) {\r
         CloseFile (Private->FileContext->FHandle);\r
         Private->FileContext->FHandle = NULL;\r
-        Private->FileContext->FileName = NULL;\r
+        if (Private->FileContext->FileName!= NULL){\r
+          FreePool(Private->FileContext->FileName);\r
+          Private->FileContext->FileName = NULL;\r
+        }\r
       }\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_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
@@ -3526,8 +3914,7 @@ SecureBootCallback (
       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
+      if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {\r
         IfrNvData->DeletePk = TRUE;\r
         IfrNvData->HasPk    = FALSE;\r
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
@@ -3536,25 +3923,17 @@ 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
@@ -3573,12 +3952,20 @@ SecureBootCallback (
     }\r
   }\r
 \r
+EXIT:\r
+\r
   if (!EFI_ERROR (Status)) {\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 +4030,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 +4115,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