]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/AuthVariableLib/AuthService.c
SecurityPkg: AuthVariableLib: Fix inconsistent CertDB case
[mirror_edk2.git] / SecurityPkg / Library / AuthVariableLib / AuthService.c
index 4649e50e5e083584532d047a9ec7c002f3d22eab..b013d420f62e29097e418143e19b85d866b3af76 100644 (file)
@@ -56,54 +56,6 @@ EFI_SIGNATURE_ITEM mSupportSigItem[] = {
   {EFI_CERT_X509_SHA512_GUID,     0,               80           }\r
 };\r
 \r
-//\r
-// Secure Boot Mode state machine\r
-//\r
-SECURE_BOOT_MODE mSecureBootState[SecureBootModeTypeMax] = {\r
-  // USER MODE\r
-  {\r
-      AUDIT_MODE_DISABLE,                        // AuditMode\r
-      FALSE,                                     // IsAuditModeRO, AuditMode is RW\r
-      DEPLOYED_MODE_DISABLE,                     // DeployedMode\r
-      FALSE,                                     // IsDeployedModeRO, DeployedMode is RW\r
-      SETUP_MODE_DISABLE,                        // SetupMode\r
-                                                 // SetupMode is always RO\r
-      SECURE_BOOT_MODE_ENABLE                    // SecureBoot\r
-  },\r
-  // SETUP MODE\r
-  {\r
-      AUDIT_MODE_DISABLE,                        // AuditMode\r
-      FALSE,                                     // IsAuditModeRO, AuditMode is RW\r
-      DEPLOYED_MODE_DISABLE,                     // DeployedMode\r
-      TRUE,                                      // IsDeployedModeRO, DeployedMode is RO\r
-      SETUP_MODE_ENABLE,                         // SetupMode\r
-                                                 // SetupMode is always RO\r
-      SECURE_BOOT_MODE_DISABLE                   // SecureBoot\r
-  },\r
-  // AUDIT MODE\r
-  {\r
-      AUDIT_MODE_ENABLE,                         // AuditMode\r
-      TRUE,                                      // AuditModeValAttr RO, AuditMode is RO\r
-      DEPLOYED_MODE_DISABLE,                     // DeployedMode\r
-      TRUE,                                      // DeployedModeValAttr RO, DeployedMode is RO\r
-      SETUP_MODE_ENABLE,                         // SetupMode\r
-                                                 // SetupMode is always RO\r
-      SECURE_BOOT_MODE_DISABLE                   // SecureBoot\r
-  },\r
-  // DEPLOYED MODE\r
-  {\r
-      AUDIT_MODE_DISABLE,                        // AuditMode, AuditMode is RO\r
-      TRUE,                                      // AuditModeValAttr RO\r
-      DEPLOYED_MODE_ENABLE,                      // DeployedMode\r
-      TRUE,                                      // DeployedModeValAttr RO, DeployedMode is RO\r
-      SETUP_MODE_DISABLE,                        // SetupMode\r
-                                                 // SetupMode is always RO\r
-      SECURE_BOOT_MODE_ENABLE                    // SecureBoot\r
-  }\r
-};\r
-\r
-SECURE_BOOT_MODE_TYPE  mSecureBootMode;\r
-\r
 /**\r
   Finds variable in storage blocks of volatile and non-volatile storage areas.\r
 \r
@@ -221,976 +173,80 @@ AuthServiceInternalUpdateVariableWithMonotonicCount (
   AuthVariableInfo.PubKeyIndex = KeyIndex;\r
   AuthVariableInfo.MonotonicCount = MonotonicCount;\r
 \r
-  return mAuthVarLibContextIn->UpdateVariable (\r
-           &AuthVariableInfo\r
-           );\r
-}\r
-\r
-/**\r
-  Update the variable region with Variable information.\r
-\r
-  @param[in] VariableName           Name of variable.\r
-  @param[in] VendorGuid             Guid of variable.\r
-  @param[in] Data                   Data pointer.\r
-  @param[in] DataSize               Size of Data.\r
-  @param[in] Attributes             Attribute value of the variable.\r
-  @param[in] TimeStamp              Value of associated TimeStamp.\r
-\r
-  @retval EFI_SUCCESS               The update operation is success.\r
-  @retval EFI_INVALID_PARAMETER     Invalid parameter.\r
-  @retval EFI_WRITE_PROTECTED       Variable is write-protected.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-AuthServiceInternalUpdateVariableWithTimeStamp (\r
-  IN CHAR16             *VariableName,\r
-  IN EFI_GUID           *VendorGuid,\r
-  IN VOID               *Data,\r
-  IN UINTN              DataSize,\r
-  IN UINT32             Attributes,\r
-  IN EFI_TIME           *TimeStamp\r
-  )\r
-{\r
-  EFI_STATUS            FindStatus;\r
-  VOID                  *OrgData;\r
-  UINTN                 OrgDataSize;\r
-  AUTH_VARIABLE_INFO    AuthVariableInfo;\r
-\r
-  FindStatus = AuthServiceInternalFindVariable (\r
-                 VariableName,\r
-                 VendorGuid,\r
-                 &OrgData,\r
-                 &OrgDataSize\r
-                 );\r
-\r
-  //\r
-  // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable\r
-  //\r
-  if (!EFI_ERROR (FindStatus) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {\r
-    if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
-        ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
-        (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||\r
-        (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {\r
-      //\r
-      // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of\r
-      // EFI_SIGNATURE_DATA values that are already part of the existing variable value.\r
-      //\r
-      FilterSignatureList (\r
-        OrgData,\r
-        OrgDataSize,\r
-        Data,\r
-        &DataSize\r
-        );\r
-    }\r
-  }\r
-\r
-  ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
-  AuthVariableInfo.VariableName = VariableName;\r
-  AuthVariableInfo.VendorGuid = VendorGuid;\r
-  AuthVariableInfo.Data = Data;\r
-  AuthVariableInfo.DataSize = DataSize;\r
-  AuthVariableInfo.Attributes = Attributes;\r
-  AuthVariableInfo.TimeStamp = TimeStamp;\r
-  return mAuthVarLibContextIn->UpdateVariable (\r
-           &AuthVariableInfo\r
-           );\r
-}\r
-\r
-/**\r
-  Initialize Secure Boot variables.\r
-\r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-InitSecureBootVariables (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS             Status;\r
-  UINT8                  *Data;\r
-  UINTN                  DataSize;\r
-  UINT32                 SecureBoot;\r
-  UINT8                  SecureBootEnable;\r
-  SECURE_BOOT_MODE_TYPE  SecureBootMode;\r
-  BOOLEAN                IsPkPresent;\r
-\r
-  //\r
-  // Find "PK" variable\r
-  //\r
-  Status = AuthServiceInternalFindVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);\r
-  if (EFI_ERROR (Status)) {\r
-    IsPkPresent = FALSE;\r
-    DEBUG ((EFI_D_INFO, "Variable %s does not exist.\n", EFI_PLATFORM_KEY_NAME));\r
-  } else {\r
-    IsPkPresent = TRUE;\r
-    DEBUG ((EFI_D_INFO, "Variable %s exists.\n", EFI_PLATFORM_KEY_NAME));\r
-  }\r
-\r
-  //\r
-  // Init "SecureBootMode" variable.\r
-  // Initial case\r
-  //   SecureBootMode doesn't exist. Init it with PK state\r
-  // 3 inconsistency cases need to sync\r
-  //   1.1 Add PK     -> system break -> update SecureBootMode Var\r
-  //   1.2 Delete PK  -> system break -> update SecureBootMode Var\r
-  //   1.3 Set AuditMode ->Delete PK  -> system break -> Update SecureBootMode Var\r
-  //\r
-  Status = AuthServiceInternalFindVariable (EDKII_SECURE_BOOT_MODE_NAME, &gEdkiiSecureBootModeGuid, (VOID **)&Data, &DataSize);\r
-  if (EFI_ERROR(Status)) {\r
-    //\r
-    // Variable driver Initial Case\r
-    //\r
-    if (IsPkPresent) {\r
-      SecureBootMode = SecureBootModeTypeUserMode;\r
-    } else {\r
-      SecureBootMode = SecureBootModeTypeSetupMode;\r
-    }\r
-  } else {\r
-    //\r
-    // 3 inconsistency cases need to sync\r
-    //\r
-    SecureBootMode = (SECURE_BOOT_MODE_TYPE)*Data;\r
-    ASSERT(SecureBootMode < SecureBootModeTypeMax);\r
-\r
-    if (IsPkPresent) {\r
-      //\r
-      // 3.1 Add PK     -> system break -> update SecureBootMode Var\r
-      //\r
-      if (SecureBootMode == SecureBootModeTypeSetupMode) {\r
-        SecureBootMode = SecureBootModeTypeUserMode;\r
-      } else if (SecureBootMode == SecureBootModeTypeAuditMode) {\r
-        SecureBootMode = SecureBootModeTypeDeployedMode;\r
-      }\r
-    } else {\r
-      //\r
-      // 3.2 Delete PK -> system break -> update SecureBootMode Var\r
-      // 3.3 Set AuditMode ->Delete PK  -> system break -> Update SecureBootMode Var. Reinit to be SetupMode\r
-      //\r
-      if ((SecureBootMode == SecureBootModeTypeUserMode) || (SecureBootMode == SecureBootModeTypeDeployedMode)) {\r
-        SecureBootMode = SecureBootModeTypeSetupMode;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (EFI_ERROR(Status) || (SecureBootMode != (SECURE_BOOT_MODE_TYPE)*Data)) {\r
-    //\r
-    // Update SecureBootMode Var\r
-    //\r
-    Status = AuthServiceInternalUpdateVariable (\r
-               EDKII_SECURE_BOOT_MODE_NAME,\r
-               &gEdkiiSecureBootModeGuid,\r
-               &SecureBootMode,\r
-               sizeof (UINT8),\r
-               EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
-               );\r
-    if (EFI_ERROR(Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Init "AuditMode"\r
-  //\r
-  Status = AuthServiceInternalUpdateVariable (\r
-             EFI_AUDIT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &mSecureBootState[SecureBootMode].AuditMode,\r
-             sizeof(UINT8),\r
-             EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
-             );\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Init "DeployedMode"\r
-  //\r
-  Status = AuthServiceInternalUpdateVariable (\r
-             EFI_DEPLOYED_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &mSecureBootState[SecureBootMode].DeployedMode,\r
-             sizeof(UINT8),\r
-             EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
-             );\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Init "SetupMode"\r
-  //\r
-  Status = AuthServiceInternalUpdateVariable (\r
-             EFI_SETUP_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &mSecureBootState[SecureBootMode].SetupMode,\r
-             sizeof(UINT8),\r
-             EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
-             );\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // If "SecureBootEnable" variable exists, then update "SecureBoot" variable.\r
-  // If "SecureBootEnable" variable is SECURE_BOOT_ENABLE and in User Mode or Deployed Mode, Set "SecureBoot" variable to SECURE_BOOT_MODE_ENABLE.\r
-  // If "SecureBootEnable" variable is SECURE_BOOT_DISABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_DISABLE.\r
-  //\r
-  SecureBootEnable = SECURE_BOOT_DISABLE;\r
-  Status = AuthServiceInternalFindVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID **)&Data, &DataSize);\r
-  if (!EFI_ERROR(Status)) {\r
-    if (IsPkPresent) {\r
-      SecureBootEnable = *Data;\r
-    }\r
-  } else if ((SecureBootMode == SecureBootModeTypeUserMode) || (SecureBootMode == SecureBootModeTypeDeployedMode)) {\r
-    //\r
-    // "SecureBootEnable" not exist, initialize it in User Mode or Deployed Mode.\r
-    //\r
-    SecureBootEnable = SECURE_BOOT_ENABLE;\r
-    Status = AuthServiceInternalUpdateVariable (\r
-               EFI_SECURE_BOOT_ENABLE_NAME,\r
-               &gEfiSecureBootEnableDisableGuid,\r
-               &SecureBootEnable,\r
-               sizeof (UINT8),\r
-               EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Create "SecureBoot" variable with BS+RT attribute set.\r
-  //\r
-  if ((SecureBootEnable == SECURE_BOOT_ENABLE) \r
-  && ((SecureBootMode == SecureBootModeTypeUserMode) || (SecureBootMode == SecureBootModeTypeDeployedMode))) {\r
-    SecureBoot = SECURE_BOOT_MODE_ENABLE;\r
-  } else {\r
-    SecureBoot = SECURE_BOOT_MODE_DISABLE;\r
-  }\r
-  Status = AuthServiceInternalUpdateVariable (\r
-             EFI_SECURE_BOOT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SecureBoot,\r
-             sizeof (UINT8),\r
-             EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-             );\r
-\r
-  DEBUG ((EFI_D_INFO, "SecureBootMode is %x\n", SecureBootMode));\r
-  DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_SECURE_BOOT_MODE_NAME, SecureBoot));\r
-  DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_SECURE_BOOT_ENABLE_NAME, SecureBootEnable));\r
-\r
-  //\r
-  // Save SecureBootMode in global space\r
-  //\r
-  mSecureBootMode = SecureBootMode;\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Update SecureBootMode variable.\r
-\r
-  @param[in] NewMode                New Secure Boot Mode.\r
-\r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateSecureBootMode(\r
-  IN  SECURE_BOOT_MODE_TYPE  NewMode\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  //\r
-  // Update "SecureBootMode" variable to new Secure Boot Mode\r
-  //\r
-  Status = AuthServiceInternalUpdateVariable (\r
-             EDKII_SECURE_BOOT_MODE_NAME,\r
-             &gEdkiiSecureBootModeGuid,\r
-             &NewMode,\r
-             sizeof (UINT8),\r
-             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
-             );\r
-\r
-  if (!EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_INFO, "SecureBootMode Update to %x\n", NewMode));\r
-    mSecureBootMode = NewMode;\r
-  } else {\r
-    DEBUG((EFI_D_ERROR, "SecureBootMode Update failure %x\n", Status));\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Current secure boot mode is AuditMode. This function performs secure boot mode transition\r
-  to a new mode.\r
-\r
-  @param[in] NewMode                New Secure Boot Mode.\r
-\r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromAuditMode(\r
-  IN  SECURE_BOOT_MODE_TYPE               NewMode\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  VOID        *AuditVarData;\r
-  VOID        *DeployedVarData;\r
-  VOID        *SetupVarData;\r
-  VOID        *SecureBootVarData;\r
-  UINT8       SecureBootEnable;\r
-  UINTN       DataSize;\r
-\r
-  //\r
-  // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
-  // they can be RW. but can't be deleted. so they can always be found.\r
-  //\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_AUDIT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &AuditVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_DEPLOYED_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &DeployedVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SETUP_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SetupVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SECURE_BOOT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SecureBootVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  //\r
-  // Make Secure Boot Mode transition ATOMIC\r
-  // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow.\r
-  // other tranisition logic are all memory operations.\r
-  //\r
-  Status = UpdateSecureBootMode(NewMode);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
-  }\r
-\r
-  if (NewMode == SecureBootModeTypeDeployedMode) {\r
-    //\r
-    // Since PK is enrolled, can't rollback, always update SecureBootMode in memory\r
-    //\r
-    mSecureBootMode = NewMode;\r
-    Status          = EFI_SUCCESS;\r
-\r
-    //\r
-    // AuditMode ----> DeployedMode\r
-    // Side Effects\r
-    //   AuditMode =: 0 / DeployedMode := 1 / SetupMode := 0\r
-    //\r
-    // Update the value of AuditMode variable by a simple mem copy, this could avoid possible\r
-    // variable storage reclaim at runtime.\r
-    //\r
-    CopyMem (AuditVarData, &mSecureBootState[NewMode].AuditMode, sizeof(UINT8));\r
-    //\r
-    // Update the value of DeployedMode variable by a simple mem copy, this could avoid possible\r
-    // variable storage reclaim at runtime.\r
-    //\r
-    CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
-    //\r
-    // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
-    // variable storage reclaim at runtime.\r
-    //\r
-    CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
-    if (mAuthVarLibContextIn->AtRuntime ()) {\r
-      //\r
-      // SecureBoot Variable indicates whether the platform firmware is operating\r
-      // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
-      // Variable in runtime.\r
-      //\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
-    // variable storage reclaim at runtime.\r
-    //\r
-    CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
-    //\r
-    // Create "SecureBootEnable" variable  as secure boot is enabled.\r
-    //\r
-    SecureBootEnable = SECURE_BOOT_ENABLE;\r
-    AuthServiceInternalUpdateVariable (\r
-      EFI_SECURE_BOOT_ENABLE_NAME,\r
-      &gEfiSecureBootEnableDisableGuid,\r
-      &SecureBootEnable,\r
-      sizeof (SecureBootEnable),\r
-      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-      );\r
-  } else {\r
-    DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeAuditMode, NewMode));\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Current secure boot mode is DeployedMode. This function performs secure boot mode transition\r
-  to a new mode.\r
-\r
-  @param[in] NewMode                New Secure Boot Mode.\r
-\r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromDeployedMode(\r
-  IN  SECURE_BOOT_MODE_TYPE               NewMode\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  VOID        *DeployedVarData;\r
-  VOID        *SetupVarData;\r
-  VOID        *SecureBootVarData;\r
-  UINT8       SecureBootEnable;\r
-  UINTN       DataSize;\r
-\r
-  //\r
-  // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
-  // they can be RW. but can't be deleted. so they can always be found.\r
-  //\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_DEPLOYED_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &DeployedVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SETUP_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SetupVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SECURE_BOOT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SecureBootVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  //\r
-  // Make Secure Boot Mode transition ATOMIC\r
-  // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow.\r
-  // other tranisition logic are all memory operations.\r
-  //\r
-  Status = UpdateSecureBootMode(NewMode);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
-  }\r
-\r
-  switch(NewMode) {\r
-    case SecureBootModeTypeUserMode:\r
-      //\r
-      // DeployedMode ----> UserMode\r
-      // Side Effects\r
-      //   DeployedMode := 0\r
-      //\r
-      // Platform Specific DeployedMode clear. UpdateSecureBootMode fails and no other variables are updated before. rollback this transition\r
-      //\r
-      if (EFI_ERROR(Status)) {\r
-        return Status;\r
-      }\r
-      CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
-\r
-      break;\r
-\r
-    case SecureBootModeTypeSetupMode:\r
-      //\r
-      // Since PK is processed before, can't rollback, still update SecureBootMode in memory\r
-      //\r
-      mSecureBootMode = NewMode;\r
-      Status          = EFI_SUCCESS;\r
-\r
-      //\r
-      // DeployedMode ----> SetupMode\r
-      //\r
-      // Platform Specific PKpub clear or Delete Pkpub\r
-      // Side Effects\r
-      //   DeployedMode := 0 / SetupMode := 1 / SecureBoot := 0\r
-      //\r
-      // Update the value of DeployedMode variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
-      //\r
-      // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
-      if (mAuthVarLibContextIn->AtRuntime ()) {\r
-        //\r
-        // SecureBoot Variable indicates whether the platform firmware is operating\r
-        // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
-        // Variable in runtime.\r
-        //\r
-        return Status;\r
-      }\r
-\r
-      //\r
-      // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
-      //\r
-      // Delete the "SecureBootEnable" variable as secure boot is Disabled.\r
-      //\r
-      SecureBootEnable = SECURE_BOOT_DISABLE;\r
-      AuthServiceInternalUpdateVariable (\r
-        EFI_SECURE_BOOT_ENABLE_NAME,\r
-        &gEfiSecureBootEnableDisableGuid,\r
-        &SecureBootEnable,\r
-        0,\r
-        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-        );\r
-      break;\r
-\r
-    default:\r
-      DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeDeployedMode, NewMode));\r
-      ASSERT(FALSE);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Current secure boot mode is UserMode. This function performs secure boot mode transition\r
-  to a new mode.\r
-\r
-  @param[in] NewMode                New Secure Boot Mode.\r
-\r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromUserMode(\r
-  IN  SECURE_BOOT_MODE_TYPE               NewMode\r
-  )\r
-{\r
-  EFI_STATUS   Status;\r
-  VOID         *AuditVarData;\r
-  VOID         *DeployedVarData;\r
-  VOID         *SetupVarData;\r
-  VOID         *PkVarData;\r
-  VOID         *SecureBootVarData;\r
-  UINT8        SecureBootEnable;\r
-  UINTN        DataSize;\r
-  VARIABLE_ENTRY_CONSISTENCY  VariableEntry;\r
-\r
-  //\r
-  // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
-  // they can be RW. but can't be deleted. so they can always be found.\r
-  //\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_AUDIT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &AuditVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_DEPLOYED_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &DeployedVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SETUP_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SetupVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SECURE_BOOT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SecureBootVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  //\r
-  // Make Secure Boot Mode transition ATOMIC\r
-  // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow. \r
-  // Other tranisition logic are all memory operations and PK delete is assumed to be always successful.\r
-  //\r
-  if (NewMode != SecureBootModeTypeAuditMode) {\r
-    Status = UpdateSecureBootMode(NewMode);\r
-    if (EFI_ERROR(Status)) {\r
-      DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
-    }\r
-  } else {\r
-    //\r
-    // UserMode -----> AuditMode. Check RemainingSpace for SecureBootMode var first.\r
-    // Will update SecureBootMode after DeletePK logic\r
-    //\r
-    VariableEntry.VariableSize = sizeof(UINT8);\r
-    VariableEntry.Guid         = &gEdkiiSecureBootModeGuid;\r
-    VariableEntry.Name         = EDKII_SECURE_BOOT_MODE_NAME;\r
-    if (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry, NULL)) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-  }\r
-\r
-  switch(NewMode) {\r
-    case SecureBootModeTypeDeployedMode:\r
-      //\r
-      // UpdateSecureBootMode fails and no other variables are updated before. rollback this transition\r
-      //\r
-      if (EFI_ERROR(Status)) {\r
-        return Status;\r
-      }\r
-\r
-      //\r
-      // UserMode ----> DeployedMode\r
-      // Side Effects\r
-      //   DeployedMode := 1\r
-      //\r
-      CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
-      break;\r
-\r
-    case SecureBootModeTypeAuditMode:\r
-      //\r
-      // UserMode ----> AuditMode\r
-      // Side Effects\r
-      //   Delete PKpub / SetupMode := 1 / SecureBoot := 0\r
-      //\r
-      // Delete PKpub without verification. Should always succeed.\r
-      //\r
-      PkVarData = NULL;\r
-      Status = AuthServiceInternalUpdateVariable (\r
-                 EFI_PLATFORM_KEY_NAME,\r
-                 &gEfiGlobalVariableGuid,\r
-                 PkVarData,\r
-                 0,\r
-                 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
-                 );\r
-      if (EFI_ERROR(Status)) {\r
-        DEBUG((EFI_D_ERROR, "UserMode -> AuditMode. Delete PK fail %x\n", Status));\r
-        ASSERT(FALSE);\r
-      }\r
-\r
-      //\r
-      // Update Private NV SecureBootMode Variable\r
-      //\r
-      Status = UpdateSecureBootMode(NewMode);\r
-      if (EFI_ERROR(Status)) {\r
-        //\r
-        // Since PK is deleted successfully, Doesn't break, continue to update other variable.\r
-        //\r
-        DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
-      }\r
-      CopyMem (AuditVarData, &mSecureBootState[NewMode].AuditMode, sizeof(UINT8));\r
-\r
-      //\r
-      // Fall into SetupMode logic\r
-      //\r
-    case SecureBootModeTypeSetupMode:\r
-      //\r
-      // Since PK is deleted before , can't rollback, still update SecureBootMode in memory\r
-      //\r
-      mSecureBootMode = NewMode;\r
-      Status          = EFI_SUCCESS;\r
-\r
-      //\r
-      // UserMode ----> SetupMode\r
-      //  Side Effects\r
-      //    DeployedMode :=0 / SetupMode :=1 / SecureBoot :=0\r
-      //\r
-      // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
-      if (mAuthVarLibContextIn->AtRuntime ()) {\r
-        //\r
-        // SecureBoot Variable indicates whether the platform firmware is operating\r
-        // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
-        // Variable in runtime.\r
-        //\r
-        return Status;\r
-      }\r
-\r
-      //\r
-      // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
-      //\r
-      // Delete the "SecureBootEnable" variable as secure boot is Disabled.\r
-      //\r
-      SecureBootEnable = SECURE_BOOT_DISABLE;\r
-      AuthServiceInternalUpdateVariable (\r
-        EFI_SECURE_BOOT_ENABLE_NAME,\r
-        &gEfiSecureBootEnableDisableGuid,\r
-        &SecureBootEnable,\r
-        0,\r
-        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-        );\r
-\r
-      break;\r
-\r
-    default:\r
-      DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeUserMode, NewMode));\r
-      ASSERT(FALSE);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Current secure boot mode is SetupMode. This function performs secure boot mode transition\r
-  to a new mode.\r
-\r
-  @param[in] NewMode                New Secure Boot Mode.\r
-\r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromSetupMode(\r
-  IN  SECURE_BOOT_MODE_TYPE              NewMode\r
-  )\r
-{\r
-  EFI_STATUS   Status;\r
-  VOID         *AuditVarData;\r
-  VOID         *SetupVarData;\r
-  VOID         *SecureBootVarData;\r
-  UINT8        SecureBootEnable;\r
-  UINTN        DataSize;\r
-\r
-  //\r
-  // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
-  // they can be RW. but can't be deleted. so they can always be found.\r
-  //\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_AUDIT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &AuditVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SETUP_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SetupVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  Status = AuthServiceInternalFindVariable (\r
-             EFI_SECURE_BOOT_MODE_NAME,\r
-             &gEfiGlobalVariableGuid,\r
-             &SecureBootVarData,\r
-             &DataSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  //\r
-  // Make Secure Boot Mode transition ATOMIC\r
-  // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow.\r
-  // Other tranisition logic are all memory operations and PK delete is assumed to be always successful.\r
-  //\r
-  Status = UpdateSecureBootMode(NewMode);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
-  }\r
-\r
-  switch(NewMode) {\r
-    case SecureBootModeTypeAuditMode:\r
-      //\r
-      // UpdateSecureBootMode fails and no other variables are updated before. rollback this transition\r
-      //\r
-      if (EFI_ERROR(Status)) {\r
-        return Status;\r
-      }\r
-\r
-      //\r
-      // SetupMode ----> AuditMode\r
-      // Side Effects\r
-      //   AuditMode := 1\r
-      //\r
-      // Update the value of AuditMode variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (AuditVarData, &mSecureBootState[NewMode].AuditMode, sizeof(UINT8));\r
-      break;\r
-\r
-    case SecureBootModeTypeUserMode:\r
-      //\r
-      // Since PK is enrolled before, can't rollback, still update SecureBootMode in memory\r
-      //\r
-      mSecureBootMode = NewMode;\r
-      Status          = EFI_SUCCESS;\r
-\r
-      //\r
-      // SetupMode ----> UserMode\r
-      // Side Effects\r
-      //   SetupMode := 0 / SecureBoot := 1\r
-      //\r
-      // Update the value of AuditMode variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
-      if (mAuthVarLibContextIn->AtRuntime ()) {\r
-        //\r
-        // SecureBoot Variable indicates whether the platform firmware is operating\r
-        // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
-        // Variable in runtime.\r
-        //\r
-        return Status;\r
-      }\r
-\r
-      //\r
-      // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
-      // variable storage reclaim at runtime.\r
-      //\r
-      CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
-      //\r
-      // Create the "SecureBootEnable" variable as secure boot is enabled.\r
-      //\r
-      SecureBootEnable = SECURE_BOOT_ENABLE;\r
-      AuthServiceInternalUpdateVariable (\r
-        EFI_SECURE_BOOT_ENABLE_NAME,\r
-        &gEfiSecureBootEnableDisableGuid,\r
-        &SecureBootEnable,\r
-        sizeof (SecureBootEnable),\r
-        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-        );\r
-      break;\r
-\r
-    default:\r
-      DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeSetupMode, NewMode));\r
-      ASSERT(FALSE);\r
-  }\r
-\r
-  return Status;\r
+  return mAuthVarLibContextIn->UpdateVariable (\r
+           &AuthVariableInfo\r
+           );\r
 }\r
 \r
 /**\r
-  This function performs main secure boot mode transition logic.\r
+  Update the variable region with Variable information.\r
 \r
-  @param[in] CurMode                Current Secure Boot Mode.\r
-  @param[in] NewMode                New Secure Boot Mode.\r
+  @param[in] VariableName           Name of variable.\r
+  @param[in] VendorGuid             Guid of variable.\r
+  @param[in] Data                   Data pointer.\r
+  @param[in] DataSize               Size of Data.\r
+  @param[in] Attributes             Attribute value of the variable.\r
+  @param[in] TimeStamp              Value of associated TimeStamp.\r
 \r
-  @retval EFI_SUCCESS               The initialization operation is successful.\r
+  @retval EFI_SUCCESS               The update operation is success.\r
+  @retval EFI_INVALID_PARAMETER     Invalid parameter.\r
+  @retval EFI_WRITE_PROTECTED       Variable is write-protected.\r
   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.\r
-  @retval EFI_INVALID_PARAMETER     The Current Secure Boot Mode is wrong.\r
 \r
 **/\r
 EFI_STATUS\r
-SecureBootModeTransition(\r
-  IN  SECURE_BOOT_MODE_TYPE  CurMode,\r
-  IN  SECURE_BOOT_MODE_TYPE  NewMode\r
+AuthServiceInternalUpdateVariableWithTimeStamp (\r
+  IN CHAR16             *VariableName,\r
+  IN EFI_GUID           *VendorGuid,\r
+  IN VOID               *Data,\r
+  IN UINTN              DataSize,\r
+  IN UINT32             Attributes,\r
+  IN EFI_TIME           *TimeStamp\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_STATUS            FindStatus;\r
+  VOID                  *OrgData;\r
+  UINTN                 OrgDataSize;\r
+  AUTH_VARIABLE_INFO    AuthVariableInfo;\r
+\r
+  FindStatus = AuthServiceInternalFindVariable (\r
+                 VariableName,\r
+                 VendorGuid,\r
+                 &OrgData,\r
+                 &OrgDataSize\r
+                 );\r
 \r
   //\r
-  // SecureBootMode transition\r
+  // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable\r
   //\r
-  switch (CurMode) {\r
-    case SecureBootModeTypeUserMode:\r
-      Status = TransitionFromUserMode(NewMode);\r
-      break;\r
-\r
-    case SecureBootModeTypeSetupMode:\r
-      Status = TransitionFromSetupMode(NewMode);\r
-      break;\r
-\r
-    case SecureBootModeTypeAuditMode:\r
-      Status = TransitionFromAuditMode(NewMode);\r
-      break;\r
-\r
-    case SecureBootModeTypeDeployedMode:\r
-      Status = TransitionFromDeployedMode(NewMode);\r
-      break;\r
-\r
-    default:\r
-      Status = EFI_INVALID_PARAMETER;\r
-      ASSERT(FALSE);\r
+  if (!EFI_ERROR (FindStatus) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {\r
+    if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
+        ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
+        (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||\r
+        (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {\r
+      //\r
+      // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of\r
+      // EFI_SIGNATURE_DATA values that are already part of the existing variable value.\r
+      //\r
+      FilterSignatureList (\r
+        OrgData,\r
+        OrgDataSize,\r
+        Data,\r
+        &DataSize\r
+        );\r
+    }\r
   }\r
 \r
-  return Status;\r
-\r
+  ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
+  AuthVariableInfo.VariableName = VariableName;\r
+  AuthVariableInfo.VendorGuid = VendorGuid;\r
+  AuthVariableInfo.Data = Data;\r
+  AuthVariableInfo.DataSize = DataSize;\r
+  AuthVariableInfo.Attributes = Attributes;\r
+  AuthVariableInfo.TimeStamp = TimeStamp;\r
+  return mAuthVarLibContextIn->UpdateVariable (\r
+           &AuthVariableInfo\r
+           );\r
 }\r
 \r
 /**\r
@@ -1541,6 +597,129 @@ Done:
   }\r
 }\r
 \r
+/**\r
+  Update platform mode.\r
+\r
+  @param[in]      Mode                    SETUP_MODE or USER_MODE.\r
+\r
+  @return EFI_INVALID_PARAMETER           Invalid parameter.\r
+  @return EFI_SUCCESS                     Update platform mode successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdatePlatformMode (\r
+  IN  UINT32                    Mode\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  VOID                    *Data;\r
+  UINTN                   DataSize;\r
+  UINT8                   SecureBootMode;\r
+  UINT8                   SecureBootEnable;\r
+  UINTN                   VariableDataSize;\r
+\r
+  Status = AuthServiceInternalFindVariable (\r
+             EFI_SETUP_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Data,\r
+             &DataSize\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
+  // variable storage reclaim at runtime.\r
+  //\r
+  mPlatformMode = (UINT8) Mode;\r
+  CopyMem (Data, &mPlatformMode, sizeof(UINT8));\r
+\r
+  if (mAuthVarLibContextIn->AtRuntime ()) {\r
+    //\r
+    // SecureBoot Variable indicates whether the platform firmware is operating\r
+    // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
+    // Variable in runtime.\r
+    //\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Check "SecureBoot" variable's existence.\r
+  // If it doesn't exist, firmware has no capability to perform driver signing verification,\r
+  // then set "SecureBoot" to 0.\r
+  //\r
+  Status = AuthServiceInternalFindVariable (\r
+             EFI_SECURE_BOOT_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Data,\r
+             &DataSize\r
+             );\r
+  //\r
+  // If "SecureBoot" variable exists, then check "SetupMode" variable update.\r
+  // If "SetupMode" variable is USER_MODE, "SecureBoot" variable is set to 1.\r
+  // If "SetupMode" variable is SETUP_MODE, "SecureBoot" variable is set to 0.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
+  } else {\r
+    if (mPlatformMode == USER_MODE) {\r
+      SecureBootMode = SECURE_BOOT_MODE_ENABLE;\r
+    } else if (mPlatformMode == SETUP_MODE) {\r
+      SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
+    } else {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  Status  = AuthServiceInternalUpdateVariable (\r
+              EFI_SECURE_BOOT_MODE_NAME,\r
+              &gEfiGlobalVariableGuid,\r
+              &SecureBootMode,\r
+              sizeof(UINT8),\r
+              EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
+              );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.\r
+  //\r
+  Status = AuthServiceInternalFindVariable (\r
+             EFI_SECURE_BOOT_ENABLE_NAME,\r
+             &gEfiSecureBootEnableDisableGuid,\r
+             &Data,\r
+             &DataSize\r
+             );\r
+\r
+  if (SecureBootMode == SECURE_BOOT_MODE_ENABLE) {\r
+    //\r
+    // Create the "SecureBootEnable" variable as secure boot is enabled.\r
+    //\r
+    SecureBootEnable = SECURE_BOOT_ENABLE;\r
+    VariableDataSize = sizeof (SecureBootEnable);\r
+  } else {\r
+    //\r
+    // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"\r
+    // variable is not in secure boot state.\r
+    //\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    SecureBootEnable = SECURE_BOOT_DISABLE;\r
+    VariableDataSize = 0;\r
+  }\r
+\r
+  Status = AuthServiceInternalUpdateVariable (\r
+             EFI_SECURE_BOOT_ENABLE_NAME,\r
+             &gEfiSecureBootEnableDisableGuid,\r
+             &SecureBootEnable,\r
+             VariableDataSize,\r
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
+             );\r
+  return Status;\r
+}\r
 \r
 /**\r
   Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK/db/dbx/dbt variable.\r
@@ -1700,121 +879,6 @@ VendorKeyIsModified (
            );\r
 }\r
 \r
-/**\r
-  Process Secure Boot Mode variable.\r
-\r
-  Caution: This function may receive untrusted input.\r
-  This function may be invoked in SMM mode, and datasize and data are external input.\r
-  This function will do basic validation, before parse the data.\r
-  This function will parse the authentication carefully to avoid security issues, like\r
-  buffer overflow, integer overflow.\r
-  This function will check attribute carefully to avoid authentication bypass.\r
-\r
-  @param[in]  VariableName                Name of Variable to be found.\r
-  @param[in]  VendorGuid                  Variable vendor GUID.\r
-  @param[in]  Data                        Data pointer.\r
-  @param[in]  DataSize                    Size of Data found. If size is less than the\r
-                                          data, this value contains the required size.\r
-  @param[in]  Attributes                  Attribute value of the variable\r
-\r
-  @return EFI_INVALID_PARAMETER           Invalid parameter\r
-  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation\r
-                                          check carried out by the firmware.\r
-  @return EFI_WRITE_PROTECTED             Variable is Read-Only.\r
-  @return EFI_SUCCESS                     Variable passed validation successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-ProcessSecureBootModeVar (\r
-  IN  CHAR16         *VariableName,\r
-  IN  EFI_GUID       *VendorGuid,\r
-  IN  VOID           *Data,\r
-  IN  UINTN          DataSize,\r
-  IN  UINT32         Attributes OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  VOID          *VarData;\r
-  UINTN         VarDataSize;\r
-\r
-  //\r
-  // Check "AuditMode", "DeployedMode" Variable ReadWrite Attributes\r
-  //  if in Runtime,  Always RO\r
-  //  if in Boottime, Depends on current Secure Boot Mode\r
-  //\r
-  if (mAuthVarLibContextIn->AtRuntime()) {\r
-    return EFI_WRITE_PROTECTED;\r
-  }\r
-\r
-  //\r
-  // Delete not OK\r
-  //\r
-  if ((DataSize != sizeof(UINT8)) || (Attributes == 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (StrCmp (VariableName, EFI_AUDIT_MODE_NAME) == 0) {\r
-    if(mSecureBootState[mSecureBootMode].IsAuditModeRO) {\r
-      return EFI_WRITE_PROTECTED;\r
-    }\r
-  } else {\r
-    //\r
-    // Platform specific deployedMode clear. Set DeployedMode = RW\r
-    //\r
-    if (!InCustomMode() || !UserPhysicalPresent() || mSecureBootMode != SecureBootModeTypeDeployedMode) {\r
-      if(mSecureBootState[mSecureBootMode].IsDeployedModeRO) {\r
-        return EFI_WRITE_PROTECTED;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (*(UINT8 *)Data != 0 && *(UINT8 *)Data != 1) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
-  // they can be RW. but can't be deleted. so they can always be found.\r
-  //\r
-  Status = AuthServiceInternalFindVariable (\r
-             VariableName,\r
-             VendorGuid,\r
-             &VarData,\r
-             &VarDataSize\r
-             );\r
-  if (EFI_ERROR(Status)) {\r
-    ASSERT(FALSE);\r
-  }\r
-\r
-  //\r
-  // If AuditMode/DeployedMode is assigned same value. Simply return EFI_SUCCESS\r
-  //\r
-  if (*(UINT8 *)VarData == *(UINT8 *)Data) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Perform SecureBootMode transition\r
-  //\r
-  if (StrCmp (VariableName, EFI_AUDIT_MODE_NAME) == 0) {\r
-    DEBUG((EFI_D_INFO, "Current SecureBootMode %x Transfer to SecureBootMode %x\n", mSecureBootMode, SecureBootModeTypeAuditMode));\r
-    return SecureBootModeTransition(mSecureBootMode, SecureBootModeTypeAuditMode);\r
-  } else if (StrCmp (VariableName, EFI_DEPLOYED_MODE_NAME) == 0) {\r
-    if (mSecureBootMode == SecureBootModeTypeDeployedMode) {\r
-      //\r
-      // Platform specific DeployedMode clear. InCustomMode() && UserPhysicalPresent() is checked before\r
-      //\r
-      DEBUG((EFI_D_INFO, "Current SecureBootMode %x. Transfer to SecureBootMode %x\n", mSecureBootMode, SecureBootModeTypeUserMode));\r
-      return SecureBootModeTransition(mSecureBootMode, SecureBootModeTypeUserMode);\r
-    } else {\r
-      DEBUG((EFI_D_INFO, "Current SecureBootMode %x. Transfer to SecureBootMode %x\n", mSecureBootMode, SecureBootModeTypeDeployedMode));\r
-      return SecureBootModeTransition(mSecureBootMode, SecureBootModeTypeDeployedMode);\r
-    }\r
-  }\r
-\r
-  return EFI_INVALID_PARAMETER;\r
-}\r
-\r
 /**\r
   Process variable with platform key for verification.\r
 \r
@@ -1853,7 +917,6 @@ ProcessVarWithPk (
   BOOLEAN                     Del;\r
   UINT8                       *Payload;\r
   UINTN                       PayloadSize;\r
-  VARIABLE_ENTRY_CONSISTENCY  VariableEntry[2];\r
 \r
   if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||\r
       (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
@@ -1868,51 +931,18 @@ ProcessVarWithPk (
   // Init state of Del. State may change due to secure check\r
   //\r
   Del = FALSE;\r
-  Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data);\r
-  PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
-  if (PayloadSize == 0) {\r
-    Del = TRUE;\r
-  }\r
-\r
-  //\r
-  // Check the variable space for both PKpub and SecureBootMode variable.\r
-  //\r
-  VariableEntry[0].VariableSize = PayloadSize;\r
-  VariableEntry[0].Guid         = &gEfiGlobalVariableGuid;\r
-  VariableEntry[0].Name         = EFI_PLATFORM_KEY_NAME;\r
-\r
-  VariableEntry[1].VariableSize = sizeof(UINT8);\r
-  VariableEntry[1].Guid         = &gEdkiiSecureBootModeGuid;\r
-  VariableEntry[1].Name         = EDKII_SECURE_BOOT_MODE_NAME;\r
-\r
-  if ((InCustomMode() && UserPhysicalPresent()) || \r
-      (((mSecureBootMode == SecureBootModeTypeSetupMode) || (mSecureBootMode == SecureBootModeTypeAuditMode)) && !IsPk)) {\r
+  if ((InCustomMode() && UserPhysicalPresent()) || (mPlatformMode == SETUP_MODE && !IsPk)) {\r
+    Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data);\r
+    PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
+    if (PayloadSize == 0) {\r
+      Del = TRUE;\r
+    }\r
 \r
     Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
 \r
-    //\r
-    // If delete PKpub, only check for "SecureBootMode" only\r
-    // if update / add PKpub, check both NewPKpub & "SecureBootMode"\r
-    //\r
-    if (IsPk) {\r
-      //\r
-      // Delete PKpub\r
-      //\r
-      if (Del && ((mSecureBootMode == SecureBootModeTypeUserMode) || (mSecureBootMode == SecureBootModeTypeDeployedMode)) \r
-          && !mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[1], NULL)){\r
-        return EFI_OUT_OF_RESOURCES;\r
-      //\r
-      // Add PKpub\r
-      //\r
-      } else if (!Del && ((mSecureBootMode == SecureBootModeTypeSetupMode) || (mSecureBootMode == SecureBootModeTypeAuditMode))\r
-                 && !mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-    }\r
-\r
     Status = AuthServiceInternalUpdateVariableWithTimeStamp (\r
                VariableName,\r
                VendorGuid,\r
@@ -1925,17 +955,10 @@ ProcessVarWithPk (
       return Status;\r
     }\r
 \r
-    if (((mSecureBootMode != SecureBootModeTypeSetupMode) && (mSecureBootMode != SecureBootModeTypeAuditMode)) || IsPk) {\r
+    if ((mPlatformMode != SETUP_MODE) || IsPk) {\r
       Status = VendorKeyIsModified ();\r
     }\r
-  } else if (mSecureBootMode == SecureBootModeTypeUserMode || mSecureBootMode == SecureBootModeTypeDeployedMode) {\r
-    //\r
-    // If delete PKpub, check "SecureBootMode" only\r
-    //\r
-    if (IsPk && Del && !mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[1], NULL)){\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
+  } else if (mPlatformMode == USER_MODE) {\r
     //\r
     // Verify against X509 Cert in PK database.\r
     //\r
@@ -1950,19 +973,8 @@ ProcessVarWithPk (
                );\r
   } else {\r
     //\r
-    // SetupMode or  AuditMode to add PK\r
     // Verify against the certificate in data payload.\r
     //\r
-    //\r
-    // Check PKpub & SecureBootMode variable space consistency\r
-    //\r
-    if (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
-      //\r
-      // No enough variable space to set PK successfully.\r
-      //\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
     Status = VerifyTimeBasedPayloadAndUpdate (\r
                VariableName,\r
                VendorGuid,\r
@@ -1975,30 +987,16 @@ ProcessVarWithPk (
   }\r
 \r
   if (!EFI_ERROR(Status) && IsPk) {\r
-    //\r
-    // Delete or Enroll PK causes SecureBootMode change\r
-    //\r
-    if (!Del) {\r
-      if (mSecureBootMode == SecureBootModeTypeSetupMode) {\r
-        //\r
-        // If enroll PK in setup mode,  change to user mode.\r
-        //\r
-        Status = SecureBootModeTransition (mSecureBootMode, SecureBootModeTypeUserMode);\r
-      } else if (mSecureBootMode == SecureBootModeTypeAuditMode) {\r
-        //\r
-        // If enroll PK in Audit mode,  change to Deployed mode.\r
-        //\r
-        Status = SecureBootModeTransition (mSecureBootMode, SecureBootModeTypeDeployedMode);\r
-      } else {\r
-        DEBUG((EFI_D_INFO, "PK is updated in %x mode. No SecureBootMode change.\n", mSecureBootMode));\r
-      }\r
-    } else {\r
-      if ((mSecureBootMode == SecureBootModeTypeUserMode) || (mSecureBootMode == SecureBootModeTypeDeployedMode)) {\r
-        //\r
-        // If delete PK in User Mode or DeployedMode,  change to Setup Mode.\r
-        //\r
-        Status = SecureBootModeTransition (mSecureBootMode, SecureBootModeTypeSetupMode);\r
-      }\r
+    if (mPlatformMode == SETUP_MODE && !Del) {\r
+      //\r
+      // If enroll PK in setup mode, need change to user mode.\r
+      //\r
+      Status = UpdatePlatformMode (USER_MODE);\r
+    } else if (mPlatformMode == USER_MODE && Del){\r
+      //\r
+      // If delete PK in user mode, need change to setup mode.\r
+      //\r
+      Status = UpdatePlatformMode (SETUP_MODE);\r
     }\r
   }\r
 \r
@@ -2051,8 +1049,7 @@ ProcessVarWithKek (
   }\r
 \r
   Status = EFI_SUCCESS;\r
-  if ((mSecureBootMode == SecureBootModeTypeUserMode || mSecureBootMode == SecureBootModeTypeDeployedMode)\r
-   && !(InCustomMode() && UserPhysicalPresent())) {\r
+  if (mPlatformMode == USER_MODE && !(InCustomMode() && UserPhysicalPresent())) {\r
     //\r
     // Time-based, verify against X509 Cert KEK.\r
     //\r
@@ -2089,7 +1086,7 @@ ProcessVarWithKek (
       return Status;\r
     }\r
 \r
-    if ((mSecureBootMode != SecureBootModeTypeSetupMode) && (mSecureBootMode != SecureBootModeTypeAuditMode)) {\r
+    if (mPlatformMode != SETUP_MODE) {\r
       Status = VendorKeyIsModified ();\r
     }\r
   }\r
@@ -3103,7 +2100,7 @@ CleanCertsFromDb (
                                        &AuthVariableInfo\r
                                        );\r
 \r
-      if (EFI_ERROR(Status)) {\r
+      if (EFI_ERROR(Status) || (AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
         Status      = DeleteCertsFromDb(\r
                         VariableName,\r
                         &AuthVarGuid,\r