]> 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 1c5c2f32da02e5ffcb65627b903f799b9178c0c6..b013d420f62e29097e418143e19b85d866b3af76 100644 (file)
@@ -18,7 +18,7 @@
   They will do basic validation for authentication data structure, then call crypto library\r
   to verify the signature.\r
 \r
-Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 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
@@ -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
@@ -258,951 +210,43 @@ AuthServiceInternalUpdateVariableWithTimeStamp (
   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
-      //\r
-      // PK is cleared in runtime. "SecureBootMode" is not updated before reboot\r
-      // Delete "SecureBootMode"\r
-      //\r
-      Status = AuthServiceInternalUpdateVariable (\r
-                 EFI_SECURE_BOOT_ENABLE_NAME,\r
-                 &gEfiSecureBootEnableDisableGuid,\r
-                 &SecureBootEnable,\r
-                 0,\r
-                 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
-                 );\r
-    } else {\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
-}\r
-\r
-/**\r
-  This function performs main secure boot mode transition logic.\r
-\r
-  @param[in] CurMode                Current Secure Boot Mode.\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
-  @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
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  // SecureBootMode transition\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
+                 VariableName,\r
+                 VendorGuid,\r
+                 &OrgData,\r
+                 &OrgDataSize\r
+                 );\r
 \r
-    default:\r
-      Status = EFI_INVALID_PARAMETER;\r
-      ASSERT(FALSE);\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
-  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
@@ -1553,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
@@ -1712,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
@@ -1865,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
@@ -1880,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
@@ -1937,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
@@ -1962,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
@@ -1987,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
@@ -2063,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
@@ -2101,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
@@ -2190,7 +1175,7 @@ ProcessVariable (
   IN     EFI_GUID                           *VendorGuid,\r
   IN     VOID                               *Data,\r
   IN     UINTN                              DataSize,\r
-  IN     UINT32                             Attributes OPTIONAL\r
+  IN     UINT32                             Attributes\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
@@ -2231,7 +1216,7 @@ ProcessVariable (
               0\r
               );\r
     if (!EFI_ERROR (Status) && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
-      Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
+      Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);\r
     }\r
 \r
     return Status;\r
@@ -2544,9 +1529,9 @@ AuthServiceInternalCompareTimeStamp (
 \r
 /**\r
   Find matching signer's certificates for common authenticated variable\r
-  by corresponding VariableName and VendorGuid from "certdb".\r
+  by corresponding VariableName and VendorGuid from "certdb" or "certdbv".\r
 \r
-  The data format of "certdb":\r
+  The data format of "certdb" or "certdbv":\r
   //\r
   //     UINT32 CertDbListSize;\r
   // /// AUTH_CERT_DB_DATA Certs1[];\r
@@ -2557,8 +1542,8 @@ AuthServiceInternalCompareTimeStamp (
 \r
   @param[in]  VariableName   Name of authenticated Variable.\r
   @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
-  @param[in]  Data           Pointer to variable "certdb".\r
-  @param[in]  DataSize       Size of variable "certdb".\r
+  @param[in]  Data           Pointer to variable "certdb" or "certdbv".\r
+  @param[in]  DataSize       Size of variable "certdb" or "certdbv".\r
   @param[out] CertOffset     Offset of matching CertData, from starting of Data.\r
   @param[out] CertDataSize   Length of CertData in bytes.\r
   @param[out] CertNodeOffset Offset of matching AUTH_CERT_DB_DATA , from\r
@@ -2665,15 +1650,17 @@ FindCertsFromDb (
 \r
 /**\r
   Retrieve signer's certificates for common authenticated variable\r
-  by corresponding VariableName and VendorGuid from "certdb".\r
+  by corresponding VariableName and VendorGuid from "certdb"\r
+  or "certdbv" according to authenticated variable attributes.\r
 \r
   @param[in]  VariableName   Name of authenticated Variable.\r
   @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+  @param[in]  Attributes        Attributes of authenticated variable.\r
   @param[out] CertData       Pointer to signer's certificates.\r
   @param[out] CertDataSize   Length of CertData in bytes.\r
 \r
   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
-  @retval  EFI_NOT_FOUND         Fail to find "certdb" or matching certs.\r
+  @retval  EFI_NOT_FOUND         Fail to find "certdb"/"certdbv" or matching certs.\r
   @retval  EFI_SUCCESS           Get signer's certificates successfully.\r
 \r
 **/\r
@@ -2681,6 +1668,7 @@ EFI_STATUS
 GetCertsFromDb (\r
   IN     CHAR16           *VariableName,\r
   IN     EFI_GUID         *VendorGuid,\r
+  IN     UINT32           Attributes,\r
   OUT    UINT8            **CertData,\r
   OUT    UINT32           *CertDataSize\r
   )\r
@@ -2689,16 +1677,30 @@ GetCertsFromDb (
   UINT8                   *Data;\r
   UINTN                   DataSize;\r
   UINT32                  CertOffset;\r
+  CHAR16                  *DbName;\r
 \r
   if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL) || (CertDataSize == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  \r
+  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+    //\r
+    // Get variable "certdb".\r
+    //\r
+    DbName = EFI_CERT_DB_NAME;\r
+  } else {\r
+    //\r
+    // Get variable "certdbv".\r
+    //\r
+    DbName = EFI_CERT_DB_VOLATILE_NAME;\r
+  }\r
+\r
   //\r
-  // Get variable "certdb".\r
+  // Get variable "certdb" or "certdbv".\r
   //\r
   Status = AuthServiceInternalFindVariable (\r
-             EFI_CERT_DB_NAME,\r
+             DbName,\r
              &gEfiCertDbGuid,\r
              (VOID **) &Data,\r
              &DataSize\r
@@ -2733,13 +1735,15 @@ GetCertsFromDb (
 \r
 /**\r
   Delete matching signer's certificates when deleting common authenticated\r
-  variable by corresponding VariableName and VendorGuid from "certdb".\r
+  variable by corresponding VariableName and VendorGuid from "certdb" or \r
+  "certdbv" according to authenticated variable attributes.\r
 \r
   @param[in]  VariableName   Name of authenticated Variable.\r
   @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+  @param[in]  Attributes        Attributes of authenticated variable.\r
 \r
   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
-  @retval  EFI_NOT_FOUND         Fail to find "certdb" or matching certs.\r
+  @retval  EFI_NOT_FOUND         Fail to find "certdb"/"certdbv" or matching certs.\r
   @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.\r
   @retval  EFI_SUCCESS           The operation is completed successfully.\r
 \r
@@ -2747,7 +1751,8 @@ GetCertsFromDb (
 EFI_STATUS\r
 DeleteCertsFromDb (\r
   IN     CHAR16           *VariableName,\r
-  IN     EFI_GUID         *VendorGuid\r
+  IN     EFI_GUID         *VendorGuid,\r
+  IN     UINT32           Attributes\r
   )\r
 {\r
   EFI_STATUS              Status;\r
@@ -2758,20 +1763,33 @@ DeleteCertsFromDb (
   UINT32                  CertNodeSize;\r
   UINT8                   *NewCertDb;\r
   UINT32                  NewCertDbSize;\r
+  CHAR16                  *DbName;\r
 \r
   if ((VariableName == NULL) || (VendorGuid == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Get variable "certdb".\r
-  //\r
+  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+    //\r
+    // Get variable "certdb".\r
+    //\r
+    DbName = EFI_CERT_DB_NAME;\r
+    VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+  } else {\r
+    //\r
+    // Get variable "certdbv".\r
+    //\r
+    DbName = EFI_CERT_DB_VOLATILE_NAME;\r
+    VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+  }\r
+\r
   Status = AuthServiceInternalFindVariable (\r
-             EFI_CERT_DB_NAME,\r
+             DbName,\r
              &gEfiCertDbGuid,\r
              (VOID **) &Data,\r
              &DataSize\r
              );\r
+\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -2783,13 +1801,13 @@ DeleteCertsFromDb (
 \r
   if (DataSize == sizeof (UINT32)) {\r
     //\r
-    // There is no certs in certdb.\r
+    // There is no certs in "certdb" or "certdbv".\r
     //\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
-  // Get corresponding cert node from certdb.\r
+  // Get corresponding cert node from "certdb" or "certdbv".\r
   //\r
   Status = FindCertsFromDb (\r
              VariableName,\r
@@ -2811,7 +1829,7 @@ DeleteCertsFromDb (
   }\r
 \r
   //\r
-  // Construct new data content of variable "certdb".\r
+  // Construct new data content of variable "certdb" or "certdbv".\r
   //\r
   NewCertDbSize = (UINT32) DataSize - CertNodeSize;\r
   NewCertDb     = (UINT8*) mCertDbStore;\r
@@ -2836,11 +1854,10 @@ DeleteCertsFromDb (
   }\r
 \r
   //\r
-  // Set "certdb".\r
+  // Set "certdb" or "certdbv".\r
   //\r
-  VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
   Status   = AuthServiceInternalUpdateVariable (\r
-               EFI_CERT_DB_NAME,\r
+               DbName,\r
                &gEfiCertDbGuid,\r
                NewCertDb,\r
                NewCertDbSize,\r
@@ -2852,10 +1869,12 @@ DeleteCertsFromDb (
 \r
 /**\r
   Insert signer's certificates for common authenticated variable with VariableName\r
-  and VendorGuid in AUTH_CERT_DB_DATA to "certdb".\r
+  and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to\r
+  time based authenticated variable attributes.\r
 \r
   @param[in]  VariableName   Name of authenticated Variable.\r
   @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
+  @param[in]  Attributes     Attributes of authenticated variable.\r
   @param[in]  CertData       Pointer to signer's certificates.\r
   @param[in]  CertDataSize   Length of CertData in bytes.\r
 \r
@@ -2863,13 +1882,14 @@ DeleteCertsFromDb (
   @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with same VariableName\r
                                  and VendorGuid already exists.\r
   @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.\r
-  @retval  EFI_SUCCESS           Insert an AUTH_CERT_DB_DATA entry to "certdb"\r
+  @retval  EFI_SUCCESS           Insert an AUTH_CERT_DB_DATA entry to "certdb" or "certdbv"\r
 \r
 **/\r
 EFI_STATUS\r
 InsertCertsToDb (\r
   IN     CHAR16           *VariableName,\r
   IN     EFI_GUID         *VendorGuid,\r
+  IN     UINT32           Attributes,\r
   IN     UINT8            *CertData,\r
   IN     UINTN            CertDataSize\r
   )\r
@@ -2883,16 +1903,31 @@ InsertCertsToDb (
   UINT32                  CertNodeSize;\r
   UINT32                  NameSize;\r
   AUTH_CERT_DB_DATA       *Ptr;\r
+  CHAR16                  *DbName;\r
 \r
   if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+    //\r
+    // Get variable "certdb".\r
+    //\r
+    DbName = EFI_CERT_DB_NAME;\r
+    VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+  } else {\r
+    //\r
+    // Get variable "certdbv".\r
+    //\r
+    DbName = EFI_CERT_DB_VOLATILE_NAME;\r
+    VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+  }\r
+\r
   //\r
-  // Get variable "certdb".\r
+  // Get variable "certdb" or "certdbv".\r
   //\r
   Status = AuthServiceInternalFindVariable (\r
-             EFI_CERT_DB_NAME,\r
+             DbName,\r
              &gEfiCertDbGuid,\r
              (VOID **) &Data,\r
              &DataSize\r
@@ -2907,7 +1942,7 @@ InsertCertsToDb (
   }\r
 \r
   //\r
-  // Find whether matching cert node already exists in "certdb".\r
+  // Find whether matching cert node already exists in "certdb" or "certdbv".\r
   // If yes return error.\r
   //\r
   Status = FindCertsFromDb (\r
@@ -2927,7 +1962,7 @@ InsertCertsToDb (
   }\r
 \r
   //\r
-  // Construct new data content of variable "certdb".\r
+  // Construct new data content of variable "certdb" or "certdbv".\r
   //\r
   NameSize      = (UINT32) StrLen (VariableName);\r
   CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32) CertDataSize + NameSize * sizeof (CHAR16);\r
@@ -2967,11 +2002,10 @@ InsertCertsToDb (
     );\r
 \r
   //\r
-  // Set "certdb".\r
+  // Set "certdb" or "certdbv".\r
   //\r
-  VarAttr  = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
   Status   = AuthServiceInternalUpdateVariable (\r
-               EFI_CERT_DB_NAME,\r
+               DbName,\r
                &gEfiCertDbGuid,\r
                NewCertDb,\r
                NewCertDbSize,\r
@@ -3007,9 +2041,8 @@ CleanCertsFromDb (
   BOOLEAN                 CertCleaned;\r
   UINT8                   *Data;\r
   UINTN                   DataSize;\r
-  UINT8                   *AuthVarData;\r
-  UINTN                   AuthVarDataSize;\r
   EFI_GUID                AuthVarGuid;\r
+  AUTH_VARIABLE_INFO      AuthVariableInfo;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -3060,15 +2093,19 @@ CleanCertsFromDb (
       //\r
       // Find corresponding time auth variable\r
       //\r
-      Status = AuthServiceInternalFindVariable (\r
-                 VariableName,\r
-                 &AuthVarGuid,\r
-                 (VOID **) &AuthVarData,\r
-                 &AuthVarDataSize\r
-                 );\r
-\r
-      if (EFI_ERROR(Status)) {\r
-        Status      = DeleteCertsFromDb(VariableName, &AuthVarGuid);\r
+      ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
+      Status = mAuthVarLibContextIn->FindVariable (\r
+                                       VariableName,\r
+                                       &AuthVarGuid,\r
+                                       &AuthVariableInfo\r
+                                       );\r
+\r
+      if (EFI_ERROR(Status) || (AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+        Status      = DeleteCertsFromDb(\r
+                        VariableName,\r
+                        &AuthVarGuid,\r
+                        AuthVariableInfo.Attributes\r
+                        );\r
         CertCleaned = TRUE;\r
         DEBUG((EFI_D_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));\r
         FreePool(VariableName);\r
@@ -3374,14 +2411,14 @@ VerifyTimeBasedPayload (
     }\r
 \r
     //\r
-    // Get previously stored signer's certificates from certdb for existing\r
+    // Get previously stored signer's certificates from certdb or certdbv for existing\r
     // variable. Check whether they are identical with signer's certificates\r
     // in SignedData. If not, return error immediately.\r
     //\r
     if (OrgTimeStamp != NULL) {\r
       VerifyStatus = FALSE;\r
 \r
-      Status = GetCertsFromDb (VariableName, VendorGuid, &CertsInCertDb, &CertsSizeinDb);\r
+      Status = GetCertsFromDb (VariableName, VendorGuid, Attributes, &CertsInCertDb, &CertsSizeinDb);\r
       if (EFI_ERROR (Status)) {\r
         goto Exit;\r
       }\r
@@ -3408,7 +2445,7 @@ VerifyTimeBasedPayload (
       //\r
       // Insert signer's certificates when adding a new common authenticated variable.\r
       //\r
-      Status = InsertCertsToDb (VariableName, VendorGuid, SignerCerts, CertStackSize);\r
+      Status = InsertCertsToDb (VariableName, VendorGuid, Attributes, SignerCerts, CertStackSize);\r
       if (EFI_ERROR (Status)) {\r
         VerifyStatus = FALSE;\r
         goto Exit;\r
@@ -3549,7 +2586,7 @@ VerifyTimeBasedPayloadAndUpdate (
   // Delete signer's certificates when delete the common authenticated variable.\r
   //\r
   if (IsDel && AuthVarType == AuthVarTypePriv && !EFI_ERROR(Status) ) {\r
-    Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
+    Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);\r
   }\r
 \r
   if (VarDel != NULL) {\r