Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Zhang, Chao <chao.b.zh...@intel.com>
---
 .../SecureBootConfigDxe/SecureBootConfig.vfr       |  77 +++-
 .../SecureBootConfigDxe/SecureBootConfigImpl.c     | 432 ++++++++++++++++++---
 .../SecureBootConfigDxe/SecureBootConfigNvData.h   |  11 +-
 .../SecureBootConfigStrings.uni                    | Bin 13086 -> 14876 bytes
 4 files changed, 464 insertions(+), 56 deletions(-)

diff --git 
a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr 
b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
index 3c99431..1eb3599 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
@@ -1,7 +1,7 @@
 /** @file
   VFR file used by the SecureBoot configuration component.
 
-Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -33,6 +33,14 @@ formset
 
     subtitle text = STRING_TOKEN(STR_NULL);
 
+    //
+    // Display current secure boot mode(one of 
SetupMode/AuditMode/UserMode/DeployedMode)
+    //
+    text
+      help   = STRING_TOKEN(STR_CUR_SECURE_BOOT_MODE_HELP),
+      text   = STRING_TOKEN(STR_CUR_SECURE_BOOT_MODE_PROMPT),
+        text   = STRING_TOKEN(STR_CUR_SECURE_BOOT_MODE_CONTENT);
+
     text
       help   = STRING_TOKEN(STR_SECURE_BOOT_STATE_HELP),
       text   = STRING_TOKEN(STR_SECURE_BOOT_STATE_PROMPT),
@@ -84,18 +92,18 @@ formset
       endoneof;
 
     //
-    //
-    // Display of 'Current Secure Boot Mode'
+    // Display PK include page
     //
     suppressif questionref(SecureBootMode) == SECURE_BOOT_MODE_STANDARD;
-      grayoutif NOT ideqval SECUREBOOT_CONFIGURATION.PhysicalPresent == 1;
-      goto FORMID_SECURE_BOOT_OPTION_FORM,
-           prompt = STRING_TOKEN(STR_SECURE_BOOT_OPTION),
-           help   = STRING_TOKEN(STR_SECURE_BOOT_OPTION_HELP),
-           flags  = INTERACTIVE,
-           key    = KEY_SECURE_BOOT_OPTION;
-      endif;
+    grayoutif NOT ideqval SECUREBOOT_CONFIGURATION.PhysicalPresent == 1;
+    goto FORMID_SECURE_BOOT_OPTION_FORM,
+         prompt = STRING_TOKEN(STR_SECURE_BOOT_OPTION),
+         help   = STRING_TOKEN(STR_SECURE_BOOT_OPTION_HELP),
+         flags  = INTERACTIVE,
+         key    = KEY_SECURE_BOOT_OPTION;
+    endif;
     endif;
+
   endform;
 
   //
@@ -106,6 +114,55 @@ formset
 
     subtitle text = STRING_TOKEN(STR_NULL);
 
+    //
+    // Display of SetupMode/UserMode/AuditMode/DeployedMode transition
+    //
+    disableif TRUE;
+      oneof varid  = SECUREBOOT_CONFIGURATION.TransSecureBootMode,
+            prompt = STRING_TOKEN(STR_TRANS_SECURE_BOOT_MODE_PROMPT),
+            help   = STRING_TOKEN(STR_TRANS_SECURE_BOOT_MODE_HELP),
+            flags  = INTERACTIVE,
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_AUDIT_MODE
+              OR (ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE AND
+                  ideqval SECUREBOOT_CONFIGURATION.PhysicalPresent == 0);
+            option text = STRING_TOKEN(STR_USER_MODE),     value = 
SECURE_BOOT_MODE_USER_MODE,   flags = 0;
+      endif
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_AUDIT_MODE;
+            option text = STRING_TOKEN(STR_SETUP_MODE),    value = 
SECURE_BOOT_MODE_SETUP_MODE,  flags = 0;
+      endif
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE;
+            option text = STRING_TOKEN(STR_AUDIT_MODE),    value = 
SECURE_BOOT_MODE_AUDIT_MODE,  flags = 0;
+      endif
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_SETUP_MODE;
+            option text = STRING_TOKEN(STR_DEPLOYED_MODE), value = 
SECURE_BOOT_MODE_DEPLOYED_MODE,  flags = 0;
+      endif
+            option text = STRING_TOKEN(STR_DEPLOYED_MODE), value = 4,  flags = 
0;
+      endoneof;
+    endif;
+      oneof name   = TransSecureBootMode,
+            questionid = KEY_TRANS_SECURE_BOOT_MODE,
+            prompt = STRING_TOKEN(STR_TRANS_SECURE_BOOT_MODE_PROMPT),
+            help   = STRING_TOKEN(STR_TRANS_SECURE_BOOT_MODE_HELP),
+            flags  = INTERACTIVE | NUMERIC_SIZE_1,
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_AUDIT_MODE 
+              OR (ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE AND
+                  ideqval SECUREBOOT_CONFIGURATION.PhysicalPresent == 0);
+            option text = STRING_TOKEN(STR_USER_MODE),     value = 
SECURE_BOOT_MODE_USER_MODE,   flags = 0;
+      endif
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_AUDIT_MODE;
+            option text = STRING_TOKEN(STR_SETUP_MODE),    value = 
SECURE_BOOT_MODE_SETUP_MODE,  flags = 0;
+      endif
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE;
+            option text = STRING_TOKEN(STR_AUDIT_MODE),    value = 
SECURE_BOOT_MODE_AUDIT_MODE,  flags = 0;
+      endif
+      suppressif ideqval SECUREBOOT_CONFIGURATION.CurSecureBootMode == 
SECURE_BOOT_MODE_SETUP_MODE;
+            option text = STRING_TOKEN(STR_DEPLOYED_MODE), value = 
SECURE_BOOT_MODE_DEPLOYED_MODE,  flags = 0;
+      endif
+
+      endoneof;
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+
     goto FORMID_SECURE_BOOT_PK_OPTION_FORM,
          prompt = STRING_TOKEN(STR_SECURE_BOOT_PK_OPTION),
          help   = STRING_TOKEN(STR_SECURE_BOOT_PK_OPTION_HELP),
diff --git 
a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c 
b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index e43c6e0..a685b40 100644
--- 
a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ 
b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -49,6 +49,8 @@ HII_VENDOR_DEVICE_PATH          
mSecureBootHiiVendorDevicePath = {
 
 
 BOOLEAN mIsEnterSecureBootForm = FALSE;
+BOOLEAN mIsSelectedSecureBootModeForm = FALSE;
+BOOLEAN mIsSecureBootModeChanged = FALSE;
 
 //
 // OID ASN.1 Value for Hash Algorithms
@@ -2809,6 +2811,256 @@ ON_EXIT:
 }
 
 /**
+  Perform secure boot mode transition from User Mode by setting AuditMode 
+  or DeployedMode variable.
+
+  @param[in]  NewMode          New secure boot mode.
+
+  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.
+**/
+EFI_STATUS
+TransitionFromUserMode(
+  IN  UINT8 NewMode
+  )
+{
+  UINT8      Data;
+  EFI_STATUS Status;
+
+  if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {
+    Data = 1;
+    Status = gRT->SetVariable(
+                    EFI_AUDIT_MODE_NAME,
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof(UINT8),
+                    &Data
+                    );
+    return Status;
+  } else if (NewMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {
+    Data = 1;
+    Status = gRT->SetVariable(
+                    EFI_DEPLOYED_MODE_NAME,
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof(UINT8),
+                    &Data
+                    );
+    return Status;
+  }
+
+  //
+  // Other case do nothing here. May Goto enroll PK page.
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+  Perform secure boot mode transition from Setup Mode by setting AuditMode 
+  variable.
+
+  @param[in]  NewMode          New secure boot mode.
+
+  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.
+**/
+EFI_STATUS
+TransitionFromSetupMode(
+  IN UINT8 NewMode
+  )
+{
+  UINT8      Data;
+  EFI_STATUS Status;
+
+  Status = EFI_INVALID_PARAMETER;
+
+  if (NewMode == SECURE_BOOT_MODE_AUDIT_MODE) {
+    Data = 1;
+    Status = gRT->SetVariable(
+                    EFI_AUDIT_MODE_NAME,
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof(UINT8),
+                    &Data
+                    );
+    return Status;
+  }
+
+  //
+  // Other case do nothing here. May Goto enroll PK page.
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+  Perform secure boot mode transition from Audit Mode. Nothing is done here,
+  should goto enroll PK page.
+
+  @param[in]  NewMode          New secure boot mode.
+
+  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.
+**/
+EFI_STATUS
+TransitionFromAuditMode(
+  IN UINT8 NewMode
+  )
+{
+  //
+  // Other case do nothing here. Should Goto enroll PK page.
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+   Perform secure boot mode transition from Deployed Mode by setting Deployed 
Mode
+   variable to 0.
+
+  @param[in]  NewMode          New secure boot mode.
+
+  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.
+**/
+EFI_STATUS
+TransitionFromDeployedMode(
+  IN UINT8 NewMode
+  )
+{
+  UINT8      Data;
+  EFI_STATUS Status;
+
+  //
+  // Platform specific logic. when physical presence,  Allow to set 
DeployedMode =:0
+  // to switch back to UserMode
+  //
+  if (NewMode == SECURE_BOOT_MODE_USER_MODE) {
+    Data = 0;
+    Status = gRT->SetVariable(
+                    EFI_DEPLOYED_MODE_NAME,
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof(UINT8),
+                    &Data
+                    );
+    DEBUG((EFI_D_INFO, "DeployedMode Status %x\n", Status));
+    return Status;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+   Perform main secure boot mode transition.
+
+  @param[in]  CurMode          New secure boot mode.
+  @param[in]  NewMode          New secure boot mode.
+
+  @retval   EFI_SUCCESS        Secure Boot mode transition is successful.
+**/
+EFI_STATUS
+SecureBootModeTransition(
+  IN  UINT8  CurMode,
+  IN  UINT8  NewMode
+  )
+{
+  EFI_STATUS                         Status;
+
+  //
+  // Set platform to be customized mode to ensure platform specific mode 
switch sucess
+  //
+  Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // SecureBootMode transition
+  //
+  switch (CurMode) {
+    case SECURE_BOOT_MODE_USER_MODE:
+      Status = TransitionFromUserMode(NewMode);
+      break;
+
+    case SECURE_BOOT_MODE_SETUP_MODE:
+      Status = TransitionFromSetupMode(NewMode);
+      break;
+
+    case SECURE_BOOT_MODE_AUDIT_MODE:
+      Status = TransitionFromAuditMode(NewMode);
+      break;
+
+    case SECURE_BOOT_MODE_DEPLOYED_MODE:
+      Status = TransitionFromDeployedMode(NewMode);
+      break;
+
+    default:
+      Status = EFI_INVALID_PARAMETER;
+      ASSERT(FALSE);
+  }
+
+  return Status;
+}
+
+/**
+   Get current secure boot mode by retrieve data from 
SetupMode/AuditMode/DeployedMode.
+
+  @param[out]  SecureBootMode                Current secure boot mode.
+
+**/
+VOID
+ExtractSecureBootModeFromVariable(
+  OUT UINT8      *SecureBootMode
+  )
+{
+  UINT8     *SetupMode;
+  UINT8     *AuditMode;
+  UINT8     *DeployedMode;
+
+  SetupMode        = NULL;
+  AuditMode        = NULL;
+  DeployedMode     = NULL;
+
+  //
+  // Get AuditMode/DeployedMode from variable
+  //
+  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, 
(VOID**)&SetupMode, NULL);
+  GetVariable2 (EFI_AUDIT_MODE_NAME, &gEfiGlobalVariableGuid, 
(VOID**)&AuditMode, NULL);
+  GetVariable2 (EFI_DEPLOYED_MODE_NAME, &gEfiGlobalVariableGuid, 
(VOID**)&DeployedMode, NULL);
+  if (SetupMode != NULL && AuditMode != NULL && DeployedMode != NULL) {
+    if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 0) {
+      //
+      // User Mode
+      //
+      *SecureBootMode = SECURE_BOOT_MODE_USER_MODE;
+    } else if (*SetupMode == 1 && *AuditMode == 0 && *DeployedMode == 0) {
+      //
+      // Setup Mode
+      //
+      *SecureBootMode = SECURE_BOOT_MODE_SETUP_MODE;
+    } else if (*SetupMode == 1 && *AuditMode == 1 && *DeployedMode == 0) {
+      //
+      // Audit Mode
+      //
+      *SecureBootMode = SECURE_BOOT_MODE_AUDIT_MODE;
+    } else if (*SetupMode == 0 && *AuditMode == 0 && *DeployedMode == 1) {
+      //
+      // Deployed Mode
+      //
+      *SecureBootMode = SECURE_BOOT_MODE_DEPLOYED_MODE;
+    } else {
+      ASSERT(FALSE);
+    }
+  }else {
+    ASSERT(FALSE);
+  }
+
+  if (SetupMode != NULL) {
+    FreePool (SetupMode);
+  }
+  if (DeployedMode != NULL) {
+    FreePool (DeployedMode);
+  }
+  if (AuditMode != NULL) {
+    FreePool (AuditMode);
+  }
+}
+
+/**
   This function extracts configuration from variable.
 
   @param[in, out]  ConfigData   Point to SecureBoot configuration private data.
@@ -2820,12 +3072,10 @@ SecureBootExtractConfigFromVariable (
   )
 {
   UINT8     *SecureBootEnable;
-  UINT8     *SetupMode;
   UINT8     *SecureBootMode;
   EFI_TIME  CurrTime;
 
   SecureBootEnable = NULL;
-  SetupMode        = NULL;
   SecureBootMode   = NULL;
 
   //
@@ -2866,16 +3116,6 @@ SecureBootExtractConfigFromVariable (
   }
 
   //
-  // If there is no PK then the Delete Pk button will be gray.
-  //
-  GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, 
(VOID**)&SetupMode, NULL);
-  if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {
-    ConfigData->HasPk = FALSE;
-  } else  {
-    ConfigData->HasPk = TRUE;
-  }
-
-  //
   // Get the SecureBootMode from CustomMode variable.
   //
   GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, 
(VOID**)&SecureBootMode, NULL);
@@ -2885,12 +3125,24 @@ SecureBootExtractConfigFromVariable (
     ConfigData->SecureBootMode = *(SecureBootMode);
   }
 
+  //
+  // Extact current Secure Boot Mode
+  //
+  ExtractSecureBootModeFromVariable(&ConfigData->CurSecureBootMode);
+
+  //
+  // If there is no PK then the Delete Pk button will be gray.
+  //
+  if (ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE || 
ConfigData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {
+    ConfigData->HasPk = FALSE;
+  } else  {
+    ConfigData->HasPk = TRUE;
+  }
+
   if (SecureBootEnable != NULL) {
     FreePool (SecureBootEnable);
   }
-  if (SetupMode != NULL) {
-    FreePool (SetupMode);
-  }
+
   if (SecureBootMode != NULL) {
     FreePool (SecureBootMode);
   }
@@ -2965,16 +3217,28 @@ SecureBootExtractConfig (
   SecureBootExtractConfigFromVariable (&Configuration);
 
   //
-  // Update current secure boot state.
+  // Get current secure boot state.
   //
   GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, 
(VOID**)&SecureBoot, NULL);
+
   if (SecureBoot != NULL && *SecureBoot == SECURE_BOOT_MODE_ENABLE) {
     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN 
(STR_SECURE_BOOT_STATE_CONTENT), L"Enabled", NULL);
   } else {
     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN 
(STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);
   }
-  if (SecureBoot != NULL) {
-    FreePool (SecureBoot);
+
+  //
+  // Get current secure boot mode
+  //
+  DEBUG((EFI_D_INFO, "Configuration.CurSecureBootMode %d\n", 
Configuration.CurSecureBootMode));
+  if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) {
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL);
+  } else if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE) {
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL);
+  } else if (Configuration.CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE) {
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL);
+  } else if (Configuration.CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE) {
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL);
   }
 
   BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
@@ -3021,6 +3285,10 @@ SecureBootExtractConfig (
     *Progress = Request + StrLen (Request);
   }
 
+  if (SecureBoot != NULL) {
+    FreePool (SecureBoot);
+  }
+
   return Status;
 }
 
@@ -3142,23 +3410,41 @@ SecureBootCallback (
   UINT16                          LabelId;
   UINT8                           *SecureBootEnable;
   UINT8                           *SecureBootMode;
-  UINT8                           *SetupMode;
   CHAR16                          PromptString[100];
+  UINT8                           CurSecureBootMode;
 
+  Status           = EFI_SUCCESS;
   SecureBootEnable = NULL;
   SecureBootMode   = NULL;
-  SetupMode        = NULL;
 
   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
+  Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
+
+  //
+  // Retrieve uncommitted data from Browser
+  //
+  BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
+  IfrNvData = AllocateZeroPool (BufferSize);
+  if (IfrNvData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, 
BufferSize, (UINT8 *) IfrNvData);
 
   if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
     if (QuestionId == KEY_SECURE_BOOT_MODE) {
       mIsEnterSecureBootForm = TRUE;
+    } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE){
+      //
+      // Secure Boot Policy variable changes after tranistion. Re-sync 
CurSecureBootMode
+      //
+      ExtractSecureBootModeFromVariable(&IfrNvData->CurSecureBootMode);
+      mIsSelectedSecureBootModeForm = TRUE;
+      mIsSecureBootModeChanged = FALSE;
     }
-
-    return EFI_SUCCESS;
+    goto EXIT;
   }
 
   if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
@@ -3168,32 +3454,23 @@ SecureBootCallback (
         Value->u8 = SECURE_BOOT_MODE_STANDARD;
         Status = EFI_SUCCESS;
       }
+    } else if (QuestionId == KEY_TRANS_SECURE_BOOT_MODE) {
+      if (mIsSelectedSecureBootModeForm) {
+        Value->u8 = IfrNvData->CurSecureBootMode;
+        Status = EFI_SUCCESS;
+      }
     }
-    return Status;
+    goto EXIT;
   }
 
   if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
       (Action != EFI_BROWSER_ACTION_CHANGING) &&
       (Action != EFI_BROWSER_ACTION_FORM_CLOSE) &&
       (Action != EFI_BROWSER_ACTION_DEFAULT_STANDARD)) {
-    return EFI_UNSUPPORTED;
-  }
-
-  Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
-
-  //
-  // Retrieve uncommitted data from Browser
-  //
-  BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
-  IfrNvData = AllocateZeroPool (BufferSize);
-  if (IfrNvData == NULL) {
-    return EFI_OUT_OF_RESOURCES;
+    Status = EFI_UNSUPPORTED;
+    goto EXIT;
   }
 
-  Status = EFI_SUCCESS;
-
-  HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, 
BufferSize, (UINT8 *) IfrNvData);
-
   if (Action == EFI_BROWSER_ACTION_CHANGING) {
 
     switch (QuestionId) {
@@ -3419,6 +3696,66 @@ SecureBootCallback (
           );
       }
       break;
+    case KEY_TRANS_SECURE_BOOT_MODE:
+      //
+      // Pop up to alert user want to change secure boot mode 
+      //
+      if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE && 
+           (Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE || Value->u8 == 
SECURE_BOOT_MODE_DEPLOYED_MODE))
+        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE && 
+           Value->u8 == SECURE_BOOT_MODE_AUDIT_MODE)
+        ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE && 
+          Value->u8 == SECURE_BOOT_MODE_USER_MODE && 
IfrNvData->PhysicalPresent == 1)){
+        CreatePopUp (
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+          &Key,
+          L"Are you sure you want to switch secure boot mode?",
+          L"Press 'Y' to switch secure boot mode, 'N' to discard change and 
return",
+          NULL
+          );
+        if (Key.UnicodeChar != 'y' && Key.UnicodeChar != 'Y') {
+          //
+          // If not 'Y'/''y' restore to defualt secure boot mode
+          //
+          Value->u8 = IfrNvData->CurSecureBootMode;
+          goto EXIT;
+        }
+      } else if ((IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_SETUP_MODE 
&& Value->u8 == SECURE_BOOT_MODE_USER_MODE)
+               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE 
&& Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)
+               ||(IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_AUDIT_MODE 
&& Value->u8 == SECURE_BOOT_MODE_DEPLOYED_MODE)
+               ||(IfrNvData->CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE && Value->u8 == SECURE_BOOT_MODE_SETUP_MODE)) {
+        CreatePopUp (
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+          &Key,
+          L"Secure boot mode tranistion requires PK change",
+          L"Please go to link below to update PK",
+          NULL
+          );
+      } else {
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+      }
+
+      Status = SecureBootModeTransition(IfrNvData->CurSecureBootMode, 
Value->u8);
+      //
+      // Secure Boot Policy variable may change after tranistion. Re-sync 
CurSecureBootMode
+      //
+      ExtractSecureBootModeFromVariable(&CurSecureBootMode);
+      if (IfrNvData->CurSecureBootMode != CurSecureBootMode) {
+        IfrNvData->CurSecureBootMode = CurSecureBootMode;
+        mIsSecureBootModeChanged = TRUE;
+
+        if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE) {
+          HiiSetString (Private->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"UserMode", NULL);
+        } else if (IfrNvData->CurSecureBootMode == 
SECURE_BOOT_MODE_SETUP_MODE) {
+          HiiSetString (Private->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"SetupMode", NULL);
+        } else if (IfrNvData->CurSecureBootMode == 
SECURE_BOOT_MODE_AUDIT_MODE) {
+          HiiSetString (Private->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"AuditMode", NULL);
+        } else if (IfrNvData->CurSecureBootMode == 
SECURE_BOOT_MODE_DEPLOYED_MODE) {
+          HiiSetString (Private->HiiHandle, STRING_TOKEN 
(STR_CUR_SECURE_BOOT_MODE_CONTENT), L"DeployedMode", NULL);
+        }
+      }
+      break;
 
     default:
       if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {
@@ -3509,7 +3846,13 @@ SecureBootCallback (
     case KEY_SECURE_BOOT_MODE:
       mIsEnterSecureBootForm = FALSE;
       break;
-
+    case KEY_TRANS_SECURE_BOOT_MODE:
+      mIsSelectedSecureBootModeForm = FALSE;
+      if (mIsSecureBootModeChanged) {
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;
+      }
+      mIsSecureBootModeChanged = FALSE;
+      break;
     case KEY_SECURE_BOOT_KEK_GUID:
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:
@@ -3528,8 +3871,7 @@ SecureBootCallback (
       break;
 
     case KEY_SECURE_BOOT_DELETE_PK:
-      GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, 
(VOID**)&SetupMode, NULL);
-      if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) {
+      if (IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_USER_MODE || 
IfrNvData->CurSecureBootMode == SECURE_BOOT_MODE_DEPLOYED_MODE) {
         IfrNvData->DeletePk = TRUE;
         IfrNvData->HasPk    = FALSE;
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
@@ -3538,9 +3880,6 @@ SecureBootCallback (
         IfrNvData->HasPk    = TRUE;
         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
       }
-      if (SetupMode != NULL) {
-        FreePool (SetupMode);
-      }
       break;
     default:
       if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < 
FILE_OPTION_GOTO_OFFSET) {
@@ -3575,10 +3914,13 @@ SecureBootCallback (
     }
   }
 
+EXIT:
+
   if (!EFI_ERROR (Status)) {
     BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
     HiiSetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, 
BufferSize, (UINT8*) IfrNvData, NULL);
   }
+
   FreePool (IfrNvData);
 
   return EFI_SUCCESS;
diff --git 
a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
 
b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
index b628bcb..95787eb 100644
--- 
a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
+++ 
b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for NV data structure definition.
 
-Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -84,6 +84,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #define LABEL_DBT_DELETE                      0x1203
 #define LABEL_END                             0xffff
 
+#define KEY_TRANS_SECURE_BOOT_MODE            0x2000
+
 #define SECURE_BOOT_MAX_ATTEMPTS_NUM          255
 
 #define CONFIG_OPTION_OFFSET                  0x2000
@@ -116,6 +118,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #define SECURE_BOOT_GUID_SIZE                 36
 #define SECURE_BOOT_GUID_STORAGE_SIZE         37
 
+#define SECURE_BOOT_MODE_USER_MODE            0
+#define SECURE_BOOT_MODE_SETUP_MODE           1
+#define SECURE_BOOT_MODE_AUDIT_MODE           2
+#define SECURE_BOOT_MODE_DEPLOYED_MODE        3
+
 //
 // Nv Data structure referenced by IFR
 //
@@ -125,6 +132,8 @@ typedef struct {
   CHAR16  SignatureGuid[SECURE_BOOT_GUID_STORAGE_SIZE];
   BOOLEAN PhysicalPresent;     // If a Physical Present User
   UINT8   SecureBootMode;      // Secure Boot Mode: Standard Or Custom
+  UINT8   CurSecureBootMode;   // Current SecureBoot Mode 
SetupMode/UserMode/AuditMode/DeployedMode
+  UINT8   TransSecureBootMode; // Trans Next SecureBoot Mode
   BOOLEAN DeletePk;
   BOOLEAN HasPk;               // If Pk is existed it is true
   BOOLEAN AlwaysRevocation;    // If the certificate is always revoked. 
Revocation time is hidden
diff --git 
a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
 
b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni
index 
063a10d44d125cda13a2b62d56dc4cbed528f01c..263811b05216b72148392d968fc12c65fd8591ff
 100644
GIT binary patch
delta 801
zcmZ`%K~EDw7<~rY*%|^~h%CF{*wiMai3Jlc#7n~(H7QVGo9Mxq(iYjIwuKgrUep^W
zqWP}I_!A(#crx-&<R5tI**9a?HdQY>^Sw9k&71wc&wHPGAHH9@b9VkdDL>V8zoar#
zQ|qY6d2&%6yGyd{XJuK<8&bZy*+1NX+=-Kxtnv-_bOUYF(ZCuscDVL%gbre~fFkQU
zBH|;gf-X-Ujv)c-4x03O&0Rfaq~P3$Z%%Ar3xTv9SJvjza_ZdeA77cDm6AW5i0}pt
zDW<k$;64~bE|i=99ju2cS~RZm+BynYXRIzmwef=Cs3v+#E|mASOsq+)#wZ#uts>%g
zmuQ0;O~!a>A`M%$S?y8roSui)N#m7$@;<$ec#EdOtovkJT#b9xu12d_n{Ulz@(GWJ
z(yTi1Q8{yN%D07<+;)~E^qOiIT^=po?_c$2u1O}TQz5qb+c&Wz2g+kJvvR63^2OD2
z8X*&!^pSmiMDv!cI@c#OgOR2-(sb>ctmeP%{=2pR8i0v*%g2Shs&IVnVOySgtMV?F
zW^IQ=@?K8L&gDdi3d&>)@?#~VhJ$9<RFO=8hX^f8Es^2S8GbgPZy6<y&lBzfp30dU
N{D~CoKs=&p`~pRlwo(89

delta 181
zcmbPJGB0hy0Y;OJ2OHToyRhpqPwwNFn9QfixA_7O7yo1_R*A`Z<{Xp%Sjd4T9Ju8s
zACPC6Y+&v-c>_0#sWU?<Loq`MLq0<;g93vukWOJp1+wxPihyJ=P$rQf4=9!h<fp(?
zOjZ<7oxDM|VDcvmjmZk!ER&t&GT5QI!Ezuc%#-Jtyg*rGvVf_^<OZOc0}5u7KPVe)
Jo+qCn1^|lbGc*7I

-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to