]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/AuthVariableLib/AuthService.c
SecurityPkg/AuthVariableLib: Check SHA-256 OID with ContentInfo present
[mirror_edk2.git] / SecurityPkg / Library / AuthVariableLib / AuthService.c
index 5546c2e5c9065082ba5d850db9e35305537798b3..9beeca09aebaf5dfa0afd1040a2b43b4ed5575f1 100644 (file)
   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
-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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "AuthServiceInternal.h"\r
 \r
+#include <Protocol/VariablePolicy.h>\r
+#include <Library/VariablePolicyLib.h>\r
+\r
 //\r
 // Public Exponent of RSA Key.\r
 //\r
-CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };\r
+CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };\r
+\r
+CONST UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };\r
 \r
 //\r
 // Requirement for different signature type which have been defined in UEFI spec.\r
 // These data are used to perform SignatureList format check while setting PK/KEK variable.\r
 //\r
-EFI_SIGNATURE_ITEM mSupportSigItem[] = {\r
-//{SigType,                       SigHeaderSize,   SigDataSize  }\r
-  {EFI_CERT_SHA256_GUID,          0,               32           },\r
-  {EFI_CERT_RSA2048_GUID,         0,               256          },\r
-  {EFI_CERT_RSA2048_SHA256_GUID,  0,               256          },\r
-  {EFI_CERT_SHA1_GUID,            0,               20           },\r
-  {EFI_CERT_RSA2048_SHA1_GUID,    0,               256          },\r
-  {EFI_CERT_X509_GUID,            0,               ((UINT32) ~0)},\r
-  {EFI_CERT_SHA224_GUID,          0,               28           },\r
-  {EFI_CERT_SHA384_GUID,          0,               48           },\r
-  {EFI_CERT_SHA512_GUID,          0,               64           },\r
-  {EFI_CERT_X509_SHA256_GUID,     0,               48           },\r
-  {EFI_CERT_X509_SHA384_GUID,     0,               64           },\r
-  {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
+EFI_SIGNATURE_ITEM  mSupportSigItem[] = {\r
+  // {SigType,                       SigHeaderSize,   SigDataSize  }\r
+  { EFI_CERT_SHA256_GUID,         0, 32            },\r
+  { EFI_CERT_RSA2048_GUID,        0, 256           },\r
+  { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },\r
+  { EFI_CERT_SHA1_GUID,           0, 20            },\r
+  { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },\r
+  { EFI_CERT_X509_GUID,           0, ((UINT32) ~0) },\r
+  { EFI_CERT_SHA224_GUID,         0, 28            },\r
+  { EFI_CERT_SHA384_GUID,         0, 48            },\r
+  { EFI_CERT_SHA512_GUID,         0, 64            },\r
+  { EFI_CERT_X509_SHA256_GUID,    0, 48            },\r
+  { EFI_CERT_X509_SHA384_GUID,    0, 64            },\r
+  { EFI_CERT_X509_SHA512_GUID,    0, 80            }\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
@@ -124,22 +76,22 @@ SECURE_BOOT_MODE_TYPE  mSecureBootMode;
 **/\r
 EFI_STATUS\r
 AuthServiceInternalFindVariable (\r
-  IN  CHAR16            *VariableName,\r
-  IN  EFI_GUID          *VendorGuid,\r
-  OUT VOID              **Data,\r
-  OUT UINTN             *DataSize\r
+  IN  CHAR16    *VariableName,\r
+  IN  EFI_GUID  *VendorGuid,\r
+  OUT VOID      **Data,\r
+  OUT UINTN     *DataSize\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  AUTH_VARIABLE_INFO    AuthVariableInfo;\r
+  EFI_STATUS          Status;\r
+  AUTH_VARIABLE_INFO  AuthVariableInfo;\r
 \r
   ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
   Status = mAuthVarLibContextIn->FindVariable (\r
-           VariableName,\r
-           VendorGuid,\r
-           &AuthVariableInfo\r
-           );\r
-  *Data = AuthVariableInfo.Data;\r
+                                   VariableName,\r
+                                   VendorGuid,\r
+                                   &AuthVariableInfo\r
+                                   );\r
+  *Data     = AuthVariableInfo.Data;\r
   *DataSize = AuthVariableInfo.DataSize;\r
   return Status;\r
 }\r
@@ -161,1048 +113,97 @@ AuthServiceInternalFindVariable (
 **/\r
 EFI_STATUS\r
 AuthServiceInternalUpdateVariable (\r
-  IN CHAR16             *VariableName,\r
-  IN EFI_GUID           *VendorGuid,\r
-  IN VOID               *Data,\r
-  IN UINTN              DataSize,\r
-  IN UINT32             Attributes\r
-  )\r
-{\r
-  AUTH_VARIABLE_INFO    AuthVariableInfo;\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
-\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] KeyIndex               Index of associated public key.\r
-  @param[in] MonotonicCount         Value of associated monotonic count.\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
-AuthServiceInternalUpdateVariableWithMonotonicCount (\r
-  IN CHAR16             *VariableName,\r
-  IN EFI_GUID           *VendorGuid,\r
-  IN VOID               *Data,\r
-  IN UINTN              DataSize,\r
-  IN UINT32             Attributes,\r
-  IN UINT32             KeyIndex,\r
-  IN UINT64             MonotonicCount\r
-  )\r
-{\r
-  AUTH_VARIABLE_INFO    AuthVariableInfo;\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.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
+  IN CHAR16    *VariableName,\r
+  IN EFI_GUID  *VendorGuid,\r
+  IN VOID      *Data,\r
+  IN UINTN     DataSize,\r
+  IN UINT32    Attributes\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
+  AUTH_VARIABLE_INFO  AuthVariableInfo;\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
-  UINT8       *AuditVarData;\r
-  UINT8       *DeployedVarData;\r
-  UINT8       *SetupVarData;\r
-  UINT8       *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
-  UINT8       *DeployedVarData;\r
-  UINT8       *SetupVarData;\r
-  UINT8       *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
-  UINT8        *AuditVarData;\r
-  UINT8        *DeployedVarData;\r
-  UINT8        *SetupVarData;\r
-  UINT8        *PkVarData;\r
-  UINT8        *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
-  UINT8        *AuditVarData;\r
-  UINT8        *SetupVarData;\r
-  UINT8        *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
+  AuthVariableInfo.VendorGuid   = VendorGuid;\r
+  AuthVariableInfo.Data         = Data;\r
+  AuthVariableInfo.DataSize     = DataSize;\r
+  AuthVariableInfo.Attributes   = Attributes;\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
+      //\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
@@ -1216,14 +217,18 @@ SecureBootModeTransition(
 \r
 **/\r
 BOOLEAN\r
-NeedPhysicallyPresent(\r
-  IN     CHAR16         *VariableName,\r
-  IN     EFI_GUID       *VendorGuid\r
+NeedPhysicallyPresent (\r
+  IN     CHAR16    *VariableName,\r
+  IN     EFI_GUID  *VendorGuid\r
   )\r
 {\r
-  if ((CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))\r
-    || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0))) {\r
-    return TRUE;\r
+  // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.\r
+  if (IsVariablePolicyEnabled ()) {\r
+    if (  (CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))\r
+       || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0)))\r
+    {\r
+      return TRUE;\r
+    }\r
   }\r
 \r
   return FALSE;\r
@@ -1241,12 +246,12 @@ InCustomMode (
   VOID\r
   )\r
 {\r
-  EFI_STATUS    Status;\r
-  VOID          *Data;\r
-  UINTN         DataSize;\r
+  EFI_STATUS  Status;\r
+  VOID        *Data;\r
+  UINTN       DataSize;\r
 \r
   Status = AuthServiceInternalFindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Data, &DataSize);\r
-  if (!EFI_ERROR (Status) && (*(UINT8 *) Data == CUSTOM_SECURE_BOOT_MODE)) {\r
+  if (!EFI_ERROR (Status) && (*(UINT8 *)Data == CUSTOM_SECURE_BOOT_MODE)) {\r
     return TRUE;\r
   }\r
 \r
@@ -1254,305 +259,129 @@ InCustomMode (
 }\r
 \r
 /**\r
-  Get available public key index.\r
+  Update platform mode.\r
 \r
-  @param[in] PubKey     Pointer to Public Key data.\r
+  @param[in]      Mode                    SETUP_MODE or USER_MODE.\r
 \r
-  @return Public key index, 0 if no any public key index available.\r
+  @return EFI_INVALID_PARAMETER           Invalid parameter.\r
+  @return EFI_SUCCESS                     Update platform mode successfully.\r
 \r
 **/\r
-UINT32\r
-GetAvailableKeyIndex (\r
-  IN  UINT8             *PubKey\r
+EFI_STATUS\r
+UpdatePlatformMode (\r
+  IN  UINT32  Mode\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  UINT8                 *Data;\r
-  UINTN                 DataSize;\r
-  UINT8                 *Ptr;\r
-  UINT32                Index;\r
-  BOOLEAN               IsFound;\r
-  EFI_GUID              VendorGuid;\r
-  CHAR16                Name[1];\r
-  AUTH_VARIABLE_INFO    AuthVariableInfo;\r
-  UINT32                KeyIndex;\r
+  EFI_STATUS  Status;\r
+  VOID        *Data;\r
+  UINTN       DataSize;\r
+  UINT8       SecureBootMode;\r
+  UINT8       SecureBootEnable;\r
+  UINTN       VariableDataSize;\r
 \r
   Status = AuthServiceInternalFindVariable (\r
-             AUTHVAR_KEYDB_NAME,\r
-             &gEfiAuthenticatedVariableGuid,\r
-             (VOID **) &Data,\r
+             EFI_SETUP_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Data,\r
              &DataSize\r
              );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status));\r
-    return 0;\r
-  }\r
-\r
-  if (mPubKeyNumber == mMaxKeyNumber) {\r
-    Name[0] = 0;\r
-    AuthVariableInfo.VariableName = Name;\r
-    ZeroMem (&VendorGuid, sizeof (VendorGuid));\r
-    AuthVariableInfo.VendorGuid = &VendorGuid;\r
-    mPubKeyNumber = 0;\r
-    //\r
-    // Collect valid key data.\r
-    //\r
-    do {\r
-      Status = mAuthVarLibContextIn->FindNextVariable (AuthVariableInfo.VariableName, AuthVariableInfo.VendorGuid, &AuthVariableInfo);\r
-      if (!EFI_ERROR (Status)) {\r
-        if (AuthVariableInfo.PubKeyIndex != 0) {\r
-          for (Ptr = Data; Ptr < (Data + DataSize); Ptr += sizeof (AUTHVAR_KEY_DB_DATA)) {\r
-            if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) Ptr)->KeyIndex)) == AuthVariableInfo.PubKeyIndex) {\r
-              //\r
-              // Check if the key data has been collected.\r
-              //\r
-              for (Index = 0; Index < mPubKeyNumber; Index++) {\r
-                if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex)) == AuthVariableInfo.PubKeyIndex) {\r
-                  break;\r
-                }\r
-              }\r
-              if (Index == mPubKeyNumber) {\r
-                //\r
-                // New key data.\r
-                //\r
-                CopyMem ((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber, Ptr, sizeof (AUTHVAR_KEY_DB_DATA));\r
-                mPubKeyNumber++;\r
-              }\r
-              break;\r
-            }\r
-          }\r
-        }\r
-      }\r
-    } while (Status != EFI_NOT_FOUND);\r
-\r
-    //\r
-    // No available space to add new public key.\r
-    //\r
-    if (mPubKeyNumber == mMaxKeyNumber) {\r
-      return 0;\r
-    }\r
+    return Status;\r
   }\r
 \r
   //\r
-  // Find available public key index.\r
+  // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
+  // variable storage reclaim at runtime.\r
   //\r
-  for (KeyIndex = 1; KeyIndex <= mMaxKeyNumber; KeyIndex++) {\r
-    IsFound = FALSE;\r
-    for (Ptr = mPubKeyStore; Ptr < (mPubKeyStore + mPubKeyNumber * sizeof (AUTHVAR_KEY_DB_DATA)); Ptr += sizeof (AUTHVAR_KEY_DB_DATA)) {\r
-      if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) Ptr)->KeyIndex)) == KeyIndex) {\r
-        IsFound = TRUE;\r
-        break;\r
-      }\r
-    }\r
-    if (!IsFound) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  return KeyIndex;\r
-}\r
-\r
-/**\r
-  Add public key in store and return its index.\r
-\r
-  @param[in] PubKey             Input pointer to Public Key data.\r
-  @param[in] VariableDataEntry  The variable data entry.\r
-\r
-  @return Index of new added public key.\r
-\r
-**/\r
-UINT32\r
-AddPubKeyInStore (\r
-  IN  UINT8                        *PubKey,\r
-  IN  VARIABLE_ENTRY_CONSISTENCY   *VariableDataEntry\r
-  )\r
-{\r
-  EFI_STATUS                       Status;\r
-  UINT32                           Index;\r
-  VARIABLE_ENTRY_CONSISTENCY       PublicKeyEntry;\r
-  UINT32                           Attributes;\r
-  UINT32                           KeyIndex;\r
+  mPlatformMode = (UINT8)Mode;\r
+  CopyMem (Data, &mPlatformMode, sizeof (UINT8));\r
 \r
-  if (PubKey == NULL) {\r
-    return 0;\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 whether the public key entry does exist.\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
-  for (Index = 0; Index < mPubKeyNumber; Index++) {\r
-    if (CompareMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
-      return ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex));\r
-    }\r
-  }\r
-\r
-  KeyIndex = GetAvailableKeyIndex (PubKey);\r
-  if (KeyIndex == 0) {\r
-    return 0;\r
-  }\r
-\r
+  Status = AuthServiceInternalFindVariable (\r
+             EFI_SECURE_BOOT_MODE_NAME,\r
+             &gEfiGlobalVariableGuid,\r
+             &Data,\r
+             &DataSize\r
+             );\r
   //\r
-  // Check the variable space for both public key and variable data.\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
-  PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * sizeof (AUTHVAR_KEY_DB_DATA);\r
-  PublicKeyEntry.Guid         = &gEfiAuthenticatedVariableGuid;\r
-  PublicKeyEntry.Name         = AUTHVAR_KEYDB_NAME;\r
-  Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
-\r
-  if (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {\r
-    //\r
-    // No enough variable space.\r
-    //\r
-    return 0;\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
-  WriteUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber)->KeyIndex), KeyIndex);\r
-  CopyMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
-  mPubKeyNumber++;\r
-\r
-  //\r
-  // Update public key database variable.\r
-  //\r
   Status = AuthServiceInternalUpdateVariable (\r
-             AUTHVAR_KEYDB_NAME,\r
-             &gEfiAuthenticatedVariableGuid,\r
-             mPubKeyStore,\r
-             mPubKeyNumber * sizeof (AUTHVAR_KEY_DB_DATA),\r
-             Attributes\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
-    DEBUG ((EFI_D_ERROR, "Update public key database variable failure, Status = %r\n", Status));\r
-    return 0;\r
-  }\r
-\r
-  return KeyIndex;\r
-}\r
-\r
-/**\r
-  Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256_GUID type.\r
-  Follow the steps in UEFI2.2.\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
-\r
-  @param[in]      Data                    Pointer to data with AuthInfo.\r
-  @param[in]      DataSize                Size of Data.\r
-  @param[in]      PubKey                  Public key used for verification.\r
-\r
-  @retval EFI_INVALID_PARAMETER       Invalid parameter.\r
-  @retval EFI_SECURITY_VIOLATION      If authentication failed.\r
-  @retval EFI_SUCCESS                 Authentication successful.\r
-\r
-**/\r
-EFI_STATUS\r
-VerifyCounterBasedPayload (\r
-  IN     UINT8          *Data,\r
-  IN     UINTN          DataSize,\r
-  IN     UINT8          *PubKey\r
-  )\r
-{\r
-  BOOLEAN                         Status;\r
-  EFI_VARIABLE_AUTHENTICATION     *CertData;\r
-  EFI_CERT_BLOCK_RSA_2048_SHA256  *CertBlock;\r
-  UINT8                           Digest[SHA256_DIGEST_SIZE];\r
-  VOID                            *Rsa;\r
-  UINTN                           PayloadSize;\r
-\r
-  PayloadSize = DataSize - AUTHINFO_SIZE;\r
-  Rsa         = NULL;\r
-  CertData    = NULL;\r
-  CertBlock   = NULL;\r
-\r
-  if (Data == NULL || PubKey == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+    return Status;\r
   }\r
 \r
-  CertData  = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
-  CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
-\r
   //\r
-  // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.\r
-  // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256_GUID.\r
-  //\r
-  if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
-      !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
-    //\r
-    // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
-    //\r
-    return EFI_SECURITY_VIOLATION;\r
-  }\r
-  //\r
-  // Hash data payload with SHA256.\r
-  //\r
-  ZeroMem (Digest, SHA256_DIGEST_SIZE);\r
-  Status  = Sha256Init (mHashCtx);\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  Status  = Sha256Update (mHashCtx, Data + AUTHINFO_SIZE, PayloadSize);\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  //\r
-  // Hash Size.\r
-  //\r
-  Status  = Sha256Update (mHashCtx, &PayloadSize, sizeof (UINTN));\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  //\r
-  // Hash Monotonic Count.\r
+  // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.\r
   //\r
-  Status  = Sha256Update (mHashCtx, &CertData->MonotonicCount, sizeof (UINT64));\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  Status  = Sha256Final (mHashCtx, Digest);\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  //\r
-  // Generate & Initialize RSA Context.\r
-  //\r
-  Rsa = RsaNew ();\r
-  ASSERT (Rsa != NULL);\r
-  //\r
-  // Set RSA Key Components.\r
-  // NOTE: Only N and E are needed to be set as RSA public key for signature verification.\r
-  //\r
-  Status = RsaSetKey (Rsa, RsaKeyN, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));\r
-  if (!Status) {\r
-    goto Done;\r
-  }\r
-  //\r
-  // Verify the signature.\r
-  //\r
-  Status = RsaPkcs1Verify (\r
-             Rsa,\r
-             Digest,\r
-             SHA256_DIGEST_SIZE,\r
-             CertBlock->Signature,\r
-             EFI_CERT_TYPE_RSA2048_SHA256_SIZE\r
+  Status = AuthServiceInternalFindVariable (\r
+             EFI_SECURE_BOOT_ENABLE_NAME,\r
+             &gEfiSecureBootEnableDisableGuid,\r
+             &Data,\r
+             &DataSize\r
              );\r
 \r
-Done:\r
-  if (Rsa != NULL) {\r
-    RsaFree (Rsa);\r
-  }\r
-  if (Status) {\r
-    return EFI_SUCCESS;\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
-    return EFI_SECURITY_VIOLATION;\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
+\r
+    SecureBootEnable = SECURE_BOOT_DISABLE;\r
+    VariableDataSize = 0;\r
   }\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
@@ -1567,21 +396,21 @@ Done:
 \r
 **/\r
 EFI_STATUS\r
-CheckSignatureListFormat(\r
-  IN  CHAR16                    *VariableName,\r
-  IN  EFI_GUID                  *VendorGuid,\r
-  IN  VOID                      *Data,\r
-  IN  UINTN                     DataSize\r
+CheckSignatureListFormat (\r
+  IN  CHAR16    *VariableName,\r
+  IN  EFI_GUID  *VendorGuid,\r
+  IN  VOID      *Data,\r
+  IN  UINTN     DataSize\r
   )\r
 {\r
-  EFI_SIGNATURE_LIST     *SigList;\r
-  UINTN                  SigDataSize;\r
-  UINT32                 Index;\r
-  UINT32                 SigCount;\r
-  BOOLEAN                IsPk;\r
-  VOID                   *RsaContext;\r
-  EFI_SIGNATURE_DATA     *CertData;\r
-  UINTN                  CertLen;\r
+  EFI_SIGNATURE_LIST  *SigList;\r
+  UINTN               SigDataSize;\r
+  UINT32              Index;\r
+  UINT32              SigCount;\r
+  BOOLEAN             IsPk;\r
+  VOID                *RsaContext;\r
+  EFI_SIGNATURE_DATA  *CertData;\r
+  UINTN               CertLen;\r
 \r
   if (DataSize == 0) {\r
     return EFI_SUCCESS;\r
@@ -1589,24 +418,25 @@ CheckSignatureListFormat(
 \r
   ASSERT (VariableName != NULL && VendorGuid != NULL && Data != NULL);\r
 \r
-  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)){\r
+  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)) {\r
     IsPk = TRUE;\r
   } else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) ||\r
              (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
+              ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
+               (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))))\r
+  {\r
     IsPk = FALSE;\r
   } else {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  SigCount = 0;\r
-  SigList  = (EFI_SIGNATURE_LIST *) Data;\r
-  SigDataSize  = DataSize;\r
-  RsaContext = NULL;\r
+  SigCount    = 0;\r
+  SigList     = (EFI_SIGNATURE_LIST *)Data;\r
+  SigDataSize = DataSize;\r
+  RsaContext  = NULL;\r
 \r
   //\r
-  // Walk throuth the input signature list and check the data format.\r
+  // Walk through the input signature list and check the data format.\r
   // If any signature is incorrectly formed, the whole check will fail.\r
   //\r
   while ((SigDataSize > 0) && (SigDataSize >= SigList->SignatureListSize)) {\r
@@ -1616,14 +446,18 @@ CheckSignatureListFormat(
         // The value of SignatureSize should always be 16 (size of SignatureOwner\r
         // component) add the data length according to signature type.\r
         //\r
-        if (mSupportSigItem[Index].SigDataSize != ((UINT32) ~0) &&\r
-          (SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize) {\r
+        if ((mSupportSigItem[Index].SigDataSize != ((UINT32) ~0)) &&\r
+            ((SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize))\r
+        {\r
           return EFI_INVALID_PARAMETER;\r
         }\r
-        if (mSupportSigItem[Index].SigHeaderSize != ((UINT32) ~0) &&\r
-          SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize) {\r
+\r
+        if ((mSupportSigItem[Index].SigHeaderSize != ((UINT32) ~0)) &&\r
+            (SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize))\r
+        {\r
           return EFI_INVALID_PARAMETER;\r
         }\r
+\r
         break;\r
       }\r
     }\r
@@ -1644,29 +478,32 @@ CheckSignatureListFormat(
       if (RsaContext == NULL) {\r
         return EFI_INVALID_PARAMETER;\r
       }\r
-      CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);\r
-      CertLen = SigList->SignatureSize - sizeof (EFI_GUID);\r
+\r
+      CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);\r
+      CertLen  = SigList->SignatureSize - sizeof (EFI_GUID);\r
       if (!RsaGetPublicKeyFromX509 (CertData->SignatureData, CertLen, &RsaContext)) {\r
         RsaFree (RsaContext);\r
         return EFI_INVALID_PARAMETER;\r
       }\r
+\r
       RsaFree (RsaContext);\r
     }\r
 \r
     if ((SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) % SigList->SignatureSize != 0) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     SigCount += (SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) / SigList->SignatureSize;\r
 \r
     SigDataSize -= SigList->SignatureListSize;\r
-    SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);\r
+    SigList      = (EFI_SIGNATURE_LIST *)((UINT8 *)SigList + SigList->SignatureListSize);\r
   }\r
 \r
-  if (((UINTN) SigList - (UINTN) Data) != DataSize) {\r
+  if (((UINTN)SigList - (UINTN)Data) != DataSize) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (IsPk && SigCount > 1) {\r
+  if (IsPk && (SigCount > 1)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1685,11 +522,12 @@ VendorKeyIsModified (
   VOID\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   if (mVendorKeyState == VENDOR_KEYS_MODIFIED) {\r
     return EFI_SUCCESS;\r
   }\r
+\r
   mVendorKeyState = VENDOR_KEYS_MODIFIED;\r
 \r
   Status = AuthServiceInternalUpdateVariable (\r
@@ -1712,121 +550,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
-  UINT8         *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 (*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,22 +576,22 @@ ProcessSecureBootModeVar (
 **/\r
 EFI_STATUS\r
 ProcessVarWithPk (\r
-  IN  CHAR16                    *VariableName,\r
-  IN  EFI_GUID                  *VendorGuid,\r
-  IN  VOID                      *Data,\r
-  IN  UINTN                     DataSize,\r
-  IN  UINT32                    Attributes OPTIONAL,\r
-  IN  BOOLEAN                   IsPk\r
+  IN  CHAR16    *VariableName,\r
+  IN  EFI_GUID  *VendorGuid,\r
+  IN  VOID      *Data,\r
+  IN  UINTN     DataSize,\r
+  IN  UINT32    Attributes OPTIONAL,\r
+  IN  BOOLEAN   IsPk\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  BOOLEAN                     Del;\r
-  UINT8                       *Payload;\r
-  UINTN                       PayloadSize;\r
-  VARIABLE_ENTRY_CONSISTENCY  VariableEntry[2];\r
+  EFI_STATUS  Status;\r
+  BOOLEAN     Del;\r
+  UINT8       *Payload;\r
+  UINTN       PayloadSize;\r
 \r
-  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||\r
-      (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+  if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||\r
+      ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0))\r
+  {\r
     //\r
     // PK, KEK and db/dbx/dbt should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based\r
     // authenticated variable.\r
@@ -1879,75 +602,35 @@ ProcessVarWithPk (
   //\r
   // 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
+  Del = FALSE;\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
+    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
                Payload,\r
                PayloadSize,\r
                Attributes,\r
-               &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp\r
+               &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp\r
                );\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status)) {\r
       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 +645,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
@@ -1986,31 +658,17 @@ ProcessVarWithPk (
                );\r
   }\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 (!EFI_ERROR (Status) && IsPk) {\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
@@ -2042,19 +700,20 @@ ProcessVarWithPk (
 **/\r
 EFI_STATUS\r
 ProcessVarWithKek (\r
-  IN  CHAR16                               *VariableName,\r
-  IN  EFI_GUID                             *VendorGuid,\r
-  IN  VOID                                 *Data,\r
-  IN  UINTN                                DataSize,\r
-  IN  UINT32                               Attributes OPTIONAL\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
-  UINT8                           *Payload;\r
-  UINTN                           PayloadSize;\r
+  EFI_STATUS  Status;\r
+  UINT8       *Payload;\r
+  UINTN       PayloadSize;\r
 \r
-  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||\r
-      (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+  if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||\r
+      ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0))\r
+  {\r
     //\r
     // DB, DBX and DBT should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based\r
     // authenticated variable.\r
@@ -2063,8 +722,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
@@ -2081,10 +739,10 @@ ProcessVarWithKek (
     //\r
     // If in setup mode or custom secure boot mode, no authentication needed.\r
     //\r
-    Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data);\r
+    Payload     = (UINT8 *)Data + AUTHINFO2_SIZE (Data);\r
     PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
 \r
-    Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize);\r
+    Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -2095,13 +753,13 @@ ProcessVarWithKek (
                Payload,\r
                PayloadSize,\r
                Attributes,\r
-               &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp\r
+               &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp\r
                );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
 \r
-    if ((mSecureBootMode != SecureBootModeTypeSetupMode) && (mSecureBootMode != SecureBootModeTypeAuditMode)) {\r
+    if (mPlatformMode != SETUP_MODE) {\r
       Status = VendorKeyIsModified ();\r
     }\r
   }\r
@@ -2123,14 +781,14 @@ ProcessVarWithKek (
 **/\r
 BOOLEAN\r
 IsDeleteAuthVariable (\r
-  IN  UINT32                    OrgAttributes,\r
-  IN  VOID                      *Data,\r
-  IN  UINTN                     DataSize,\r
-  IN  UINT32                    Attributes\r
+  IN  UINT32  OrgAttributes,\r
+  IN  VOID    *Data,\r
+  IN  UINTN   DataSize,\r
+  IN  UINT32  Attributes\r
   )\r
 {\r
-  BOOLEAN                       Del;\r
-  UINTN                         PayloadSize;\r
+  BOOLEAN  Del;\r
+  UINTN    PayloadSize;\r
 \r
   Del = FALSE;\r
 \r
@@ -2141,7 +799,8 @@ IsDeleteAuthVariable (
   // and the DataSize set to the size of the AuthInfo descriptor.\r
   //\r
   if ((Attributes == OrgAttributes) &&\r
-      ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0)) {\r
+      ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0))\r
+  {\r
     if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
       PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
       if (PayloadSize == 0) {\r
@@ -2159,7 +818,7 @@ IsDeleteAuthVariable (
 }\r
 \r
 /**\r
-  Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
+  Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\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
@@ -2176,9 +835,9 @@ IsDeleteAuthVariable (
 \r
   @return EFI_INVALID_PARAMETER           Invalid parameter.\r
   @return EFI_WRITE_PROTECTED             Variable is write-protected and needs authentication with\r
-                                          EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
+                                          EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
   @return EFI_OUT_OF_RESOURCES            The Database to save the public key is full.\r
-  @return EFI_SECURITY_VIOLATION          The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+  @return EFI_SECURITY_VIOLATION          The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
                                           set, but the AuthInfo does NOT pass the validation\r
                                           check carried out by the firmware.\r
   @return EFI_SUCCESS                     Variable is not write-protected or pass validation successfully.\r
@@ -2186,58 +845,45 @@ IsDeleteAuthVariable (
 **/\r
 EFI_STATUS\r
 ProcessVariable (\r
-  IN     CHAR16                             *VariableName,\r
-  IN     EFI_GUID                           *VendorGuid,\r
-  IN     VOID                               *Data,\r
-  IN     UINTN                              DataSize,\r
-  IN     UINT32                             Attributes OPTIONAL\r
+  IN     CHAR16    *VariableName,\r
+  IN     EFI_GUID  *VendorGuid,\r
+  IN     VOID      *Data,\r
+  IN     UINTN     DataSize,\r
+  IN     UINT32    Attributes\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  BOOLEAN                         IsDeletion;\r
-  BOOLEAN                         IsFirstTime;\r
-  UINT8                           *PubKey;\r
-  EFI_VARIABLE_AUTHENTICATION     *CertData;\r
-  EFI_CERT_BLOCK_RSA_2048_SHA256  *CertBlock;\r
-  UINT32                          KeyIndex;\r
-  UINT64                          MonotonicCount;\r
-  VARIABLE_ENTRY_CONSISTENCY      VariableDataEntry;\r
-  UINT32                          Index;\r
-  AUTH_VARIABLE_INFO              OrgVariableInfo;\r
-\r
-  KeyIndex    = 0;\r
-  CertData    = NULL;\r
-  CertBlock   = NULL;\r
-  PubKey      = NULL;\r
-  IsDeletion  = FALSE;\r
-  Status      = EFI_SUCCESS;\r
+  EFI_STATUS          Status;\r
+  AUTH_VARIABLE_INFO  OrgVariableInfo;\r
+\r
+  Status = EFI_SUCCESS;\r
 \r
   ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));\r
   Status = mAuthVarLibContextIn->FindVariable (\r
-             VariableName,\r
-             VendorGuid,\r
-             &OrgVariableInfo\r
-             );\r
+                                   VariableName,\r
+                                   VendorGuid,\r
+                                   &OrgVariableInfo\r
+                                   );\r
 \r
-  if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && UserPhysicalPresent()) {\r
+  // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.\r
+  if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && (UserPhysicalPresent () || !IsVariablePolicyEnabled ())) {\r
     //\r
-    // Allow the delete operation of common authenticated variable at user physical presence.\r
+    // Allow the delete operation of common authenticated variable(AT or AW) at user physical presence.\r
     //\r
     Status = AuthServiceInternalUpdateVariable (\r
-              VariableName,\r
-              VendorGuid,\r
-              NULL,\r
-              0,\r
-              0\r
-              );\r
+               VariableName,\r
+               VendorGuid,\r
+               NULL,\r
+               0,\r
+               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
   }\r
 \r
-  if (NeedPhysicallyPresent (VariableName, VendorGuid) && !UserPhysicalPresent()) {\r
+  if (NeedPhysicallyPresent (VariableName, VendorGuid) && !UserPhysicalPresent ()) {\r
     //\r
     // This variable is protected, only physical present user could modify its value.\r
     //\r
@@ -2245,25 +891,15 @@ ProcessVariable (
   }\r
 \r
   //\r
-  // A time-based authenticated variable and a count-based authenticated variable\r
-  // can't be updated by each other.\r
-  //\r
-  if (OrgVariableInfo.Data != NULL) {\r
-    if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
-        ((OrgVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
-      return EFI_SECURITY_VIOLATION;\r
-    }\r
-\r
-    if (((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
-        ((OrgVariableInfo.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
-      return EFI_SECURITY_VIOLATION;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Process Time-based Authenticated variable.\r
-  //\r
-  if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+  if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+    //\r
+    // Reject Counter Based Auth Variable processing request.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+    //\r
+    // Process Time-based Authenticated variable.\r
+    //\r
     return VerifyTimeBasedPayloadAndUpdate (\r
              VariableName,\r
              VendorGuid,\r
@@ -2275,117 +911,20 @@ ProcessVariable (
              );\r
   }\r
 \r
-  //\r
-  // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.\r
-  //\r
-  if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
-    //\r
-    // Determine current operation type.\r
-    //\r
-    if (DataSize == AUTHINFO_SIZE) {\r
-      IsDeletion = TRUE;\r
-    }\r
-    //\r
-    // Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
-    //\r
-    if (OrgVariableInfo.Data == NULL) {\r
-      IsFirstTime = TRUE;\r
-    } else if ((OrgVariableInfo.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
-      IsFirstTime = TRUE;\r
-    } else {\r
-      KeyIndex   = OrgVariableInfo.PubKeyIndex;\r
-      IsFirstTime = FALSE;\r
-    }\r
-  } else if ((OrgVariableInfo.Data != NULL) &&\r
-             ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0)\r
-            ) {\r
+  if ((OrgVariableInfo.Data != NULL) &&\r
+      ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0))\r
+  {\r
     //\r
     // If the variable is already write-protected, it always needs authentication before update.\r
     //\r
     return EFI_WRITE_PROTECTED;\r
-  } else {\r
-    //\r
-    // If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.\r
-    // That means it is not authenticated variable, just update variable as usual.\r
-    //\r
-    Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Get PubKey and check Monotonic Count value corresponding to the variable.\r
-  //\r
-  CertData  = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
-  CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
-  PubKey    = CertBlock->PublicKey;\r
-\r
-  //\r
-  // Update Monotonic Count value.\r
-  //\r
-  MonotonicCount = CertData->MonotonicCount;\r
-\r
-  if (!IsFirstTime) {\r
-    //\r
-    // 2 cases need to check here\r
-    //   1. Internal PubKey variable. PubKeyIndex is always 0\r
-    //   2. Other counter-based AuthVariable. Check input PubKey.\r
-    //\r
-    if (KeyIndex == 0) {\r
-      return EFI_SECURITY_VIOLATION;\r
-    }\r
-    for (Index = 0; Index < mPubKeyNumber; Index++) {\r
-      if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex)) == KeyIndex) {\r
-        if (CompareMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
-          break;\r
-        } else {\r
-          return EFI_SECURITY_VIOLATION;\r
-        }\r
-      }\r
-    }\r
-    if (Index == mPubKeyNumber) {\r
-      return EFI_SECURITY_VIOLATION;\r
-    }\r
-\r
-    //\r
-    // Compare the current monotonic count and ensure that it is greater than the last SetVariable\r
-    // operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.\r
-    //\r
-    if (MonotonicCount <= OrgVariableInfo.MonotonicCount) {\r
-      //\r
-      // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.\r
-      //\r
-      return EFI_SECURITY_VIOLATION;\r
-    }\r
-  }\r
-  //\r
-  // Verify the certificate in Data payload.\r
-  //\r
-  Status = VerifyCounterBasedPayload (Data, DataSize, PubKey);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Now, the signature has been verified!\r
-  //\r
-  if (IsFirstTime && !IsDeletion) {\r
-    VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;\r
-    VariableDataEntry.Guid         = VendorGuid;\r
-    VariableDataEntry.Name         = VariableName;\r
-\r
-    //\r
-    // Update public key database variable if need.\r
-    //\r
-    KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);\r
-    if (KeyIndex == 0) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
   }\r
 \r
   //\r
-  // Verification pass.\r
+  // Not authenticated variable, just update variable as usual.\r
   //\r
-  return AuthServiceInternalUpdateVariableWithMonotonicCount (VariableName, VendorGuid, (UINT8*)Data + AUTHINFO_SIZE, DataSize - AUTHINFO_SIZE, Attributes, KeyIndex, MonotonicCount);\r
+  Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -2399,56 +938,57 @@ ProcessVariable (
 **/\r
 EFI_STATUS\r
 FilterSignatureList (\r
-  IN     VOID       *Data,\r
-  IN     UINTN      DataSize,\r
-  IN OUT VOID       *NewData,\r
-  IN OUT UINTN      *NewDataSize\r
+  IN     VOID   *Data,\r
+  IN     UINTN  DataSize,\r
+  IN OUT VOID   *NewData,\r
+  IN OUT UINTN  *NewDataSize\r
   )\r
 {\r
-  EFI_SIGNATURE_LIST    *CertList;\r
-  EFI_SIGNATURE_DATA    *Cert;\r
-  UINTN                 CertCount;\r
-  EFI_SIGNATURE_LIST    *NewCertList;\r
-  EFI_SIGNATURE_DATA    *NewCert;\r
-  UINTN                 NewCertCount;\r
-  UINTN                 Index;\r
-  UINTN                 Index2;\r
-  UINTN                 Size;\r
-  UINT8                 *Tail;\r
-  UINTN                 CopiedCount;\r
-  UINTN                 SignatureListSize;\r
-  BOOLEAN               IsNewCert;\r
-  UINT8                 *TempData;\r
-  UINTN                 TempDataSize;\r
-  EFI_STATUS            Status;\r
+  EFI_SIGNATURE_LIST  *CertList;\r
+  EFI_SIGNATURE_DATA  *Cert;\r
+  UINTN               CertCount;\r
+  EFI_SIGNATURE_LIST  *NewCertList;\r
+  EFI_SIGNATURE_DATA  *NewCert;\r
+  UINTN               NewCertCount;\r
+  UINTN               Index;\r
+  UINTN               Index2;\r
+  UINTN               Size;\r
+  UINT8               *Tail;\r
+  UINTN               CopiedCount;\r
+  UINTN               SignatureListSize;\r
+  BOOLEAN             IsNewCert;\r
+  UINT8               *TempData;\r
+  UINTN               TempDataSize;\r
+  EFI_STATUS          Status;\r
 \r
   if (*NewDataSize == 0) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   TempDataSize = *NewDataSize;\r
-  Status = mAuthVarLibContextIn->GetScratchBuffer (&TempDataSize, (VOID **) &TempData);\r
+  Status       = mAuthVarLibContextIn->GetScratchBuffer (&TempDataSize, (VOID **)&TempData);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   Tail = TempData;\r
 \r
-  NewCertList = (EFI_SIGNATURE_LIST *) NewData;\r
+  NewCertList = (EFI_SIGNATURE_LIST *)NewData;\r
   while ((*NewDataSize > 0) && (*NewDataSize >= NewCertList->SignatureListSize)) {\r
-    NewCert      = (EFI_SIGNATURE_DATA *) ((UINT8 *) NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
+    NewCert      = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
     NewCertCount = (NewCertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - NewCertList->SignatureHeaderSize) / NewCertList->SignatureSize;\r
 \r
     CopiedCount = 0;\r
     for (Index = 0; Index < NewCertCount; Index++) {\r
       IsNewCert = TRUE;\r
 \r
-      Size = DataSize;\r
-      CertList = (EFI_SIGNATURE_LIST *) Data;\r
+      Size     = DataSize;\r
+      CertList = (EFI_SIGNATURE_LIST *)Data;\r
       while ((Size > 0) && (Size >= CertList->SignatureListSize)) {\r
         if (CompareGuid (&CertList->SignatureType, &NewCertList->SignatureType) &&\r
-           (CertList->SignatureSize == NewCertList->SignatureSize)) {\r
-          Cert      = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+            (CertList->SignatureSize == NewCertList->SignatureSize))\r
+        {\r
+          Cert      = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
           CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
           for (Index2 = 0; Index2 < CertCount; Index2++) {\r
             //\r
@@ -2458,15 +998,17 @@ FilterSignatureList (
               IsNewCert = FALSE;\r
               break;\r
             }\r
-            Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+\r
+            Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
           }\r
         }\r
 \r
         if (!IsNewCert) {\r
           break;\r
         }\r
-        Size -= CertList->SignatureListSize;\r
-        CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+\r
+        Size    -= CertList->SignatureListSize;\r
+        CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
       }\r
 \r
       if (IsNewCert) {\r
@@ -2486,23 +1028,23 @@ FilterSignatureList (
         CopiedCount++;\r
       }\r
 \r
-      NewCert = (EFI_SIGNATURE_DATA *) ((UINT8 *) NewCert + NewCertList->SignatureSize);\r
+      NewCert = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCert + NewCertList->SignatureSize);\r
     }\r
 \r
     //\r
     // Update SignatureListSize in the kept EFI_SIGNATURE_LIST.\r
     //\r
     if (CopiedCount != 0) {\r
-      SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);\r
-      CertList = (EFI_SIGNATURE_LIST *) (Tail - SignatureListSize);\r
-      CertList->SignatureListSize = (UINT32) SignatureListSize;\r
+      SignatureListSize           = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);\r
+      CertList                    = (EFI_SIGNATURE_LIST *)(Tail - SignatureListSize);\r
+      CertList->SignatureListSize = (UINT32)SignatureListSize;\r
     }\r
 \r
     *NewDataSize -= NewCertList->SignatureListSize;\r
-    NewCertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) NewCertList + NewCertList->SignatureListSize);\r
+    NewCertList   = (EFI_SIGNATURE_LIST *)((UINT8 *)NewCertList + NewCertList->SignatureListSize);\r
   }\r
 \r
-  TempDataSize = (Tail - (UINT8 *) TempData);\r
+  TempDataSize = (Tail - (UINT8 *)TempData);\r
 \r
   CopyMem (NewData, TempData, TempDataSize);\r
   *NewDataSize = TempDataSize;\r
@@ -2523,30 +1065,113 @@ FilterSignatureList (
 **/\r
 BOOLEAN\r
 AuthServiceInternalCompareTimeStamp (\r
-  IN EFI_TIME               *FirstTime,\r
-  IN EFI_TIME               *SecondTime\r
+  IN EFI_TIME  *FirstTime,\r
+  IN EFI_TIME  *SecondTime\r
   )\r
 {\r
   if (FirstTime->Year != SecondTime->Year) {\r
-    return (BOOLEAN) (FirstTime->Year < SecondTime->Year);\r
+    return (BOOLEAN)(FirstTime->Year < SecondTime->Year);\r
   } else if (FirstTime->Month != SecondTime->Month) {\r
-    return (BOOLEAN) (FirstTime->Month < SecondTime->Month);\r
+    return (BOOLEAN)(FirstTime->Month < SecondTime->Month);\r
   } else if (FirstTime->Day != SecondTime->Day) {\r
-    return (BOOLEAN) (FirstTime->Day < SecondTime->Day);\r
+    return (BOOLEAN)(FirstTime->Day < SecondTime->Day);\r
   } else if (FirstTime->Hour != SecondTime->Hour) {\r
-    return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);\r
+    return (BOOLEAN)(FirstTime->Hour < SecondTime->Hour);\r
   } else if (FirstTime->Minute != SecondTime->Minute) {\r
-    return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute);\r
+    return (BOOLEAN)(FirstTime->Minute < SecondTime->Minute);\r
+  }\r
+\r
+  return (BOOLEAN)(FirstTime->Second <= SecondTime->Second);\r
+}\r
+\r
+/**\r
+  Calculate SHA256 digest of SignerCert CommonName + ToplevelCert tbsCertificate\r
+  SignerCert and ToplevelCert are inside the signer certificate chain.\r
+\r
+  @param[in]  SignerCert          A pointer to SignerCert data.\r
+  @param[in]  SignerCertSize      Length of SignerCert data.\r
+  @param[in]  TopLevelCert        A pointer to TopLevelCert data.\r
+  @param[in]  TopLevelCertSize    Length of TopLevelCert data.\r
+  @param[out] Sha256Digest       Sha256 digest calculated.\r
+\r
+  @return EFI_ABORTED          Digest process failed.\r
+  @return EFI_SUCCESS          SHA256 Digest is successfully calculated.\r
+\r
+**/\r
+EFI_STATUS\r
+CalculatePrivAuthVarSignChainSHA256Digest (\r
+  IN     UINT8  *SignerCert,\r
+  IN     UINTN  SignerCertSize,\r
+  IN     UINT8  *TopLevelCert,\r
+  IN     UINTN  TopLevelCertSize,\r
+  OUT    UINT8  *Sha256Digest\r
+  )\r
+{\r
+  UINT8       *TbsCert;\r
+  UINTN       TbsCertSize;\r
+  CHAR8       CertCommonName[128];\r
+  UINTN       CertCommonNameSize;\r
+  BOOLEAN     CryptoStatus;\r
+  EFI_STATUS  Status;\r
+\r
+  CertCommonNameSize = sizeof (CertCommonName);\r
+\r
+  //\r
+  // Get SignerCert CommonName\r
+  //\r
+  Status = X509GetCommonName (SignerCert, SignerCertSize, CertCommonName, &CertCommonNameSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with status %x\n", __FUNCTION__, Status));\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Get TopLevelCert tbsCertificate\r
+  //\r
+  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert, &TbsCertSize)) {\r
+    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n", __FUNCTION__));\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Digest SignerCert CN + TopLevelCert tbsCertificate\r
+  //\r
+  ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE);\r
+  CryptoStatus = Sha256Init (mHashCtx);\r
+  if (!CryptoStatus) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // '\0' is forced in CertCommonName. No overflow issue\r
+  //\r
+  CryptoStatus = Sha256Update (\r
+                   mHashCtx,\r
+                   CertCommonName,\r
+                   AsciiStrLen (CertCommonName)\r
+                   );\r
+  if (!CryptoStatus) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  CryptoStatus = Sha256Update (mHashCtx, TbsCert, TbsCertSize);\r
+  if (!CryptoStatus) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  CryptoStatus = Sha256Final (mHashCtx, Sha256Digest);\r
+  if (!CryptoStatus) {\r
+    return EFI_ABORTED;\r
   }\r
 \r
-  return (BOOLEAN) (FirstTime->Second <= SecondTime->Second);\r
+  return EFI_SUCCESS;\r
 }\r
 \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 +1182,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
@@ -2572,22 +1197,22 @@ AuthServiceInternalCompareTimeStamp (
 **/\r
 EFI_STATUS\r
 FindCertsFromDb (\r
-  IN     CHAR16           *VariableName,\r
-  IN     EFI_GUID         *VendorGuid,\r
-  IN     UINT8            *Data,\r
-  IN     UINTN            DataSize,\r
-  OUT    UINT32           *CertOffset,    OPTIONAL\r
-  OUT    UINT32           *CertDataSize,  OPTIONAL\r
-  OUT    UINT32           *CertNodeOffset,OPTIONAL\r
-  OUT    UINT32           *CertNodeSize   OPTIONAL\r
+  IN     CHAR16    *VariableName,\r
+  IN     EFI_GUID  *VendorGuid,\r
+  IN     UINT8     *Data,\r
+  IN     UINTN     DataSize,\r
+  OUT    UINT32    *CertOffset     OPTIONAL,\r
+  OUT    UINT32    *CertDataSize   OPTIONAL,\r
+  OUT    UINT32    *CertNodeOffset OPTIONAL,\r
+  OUT    UINT32    *CertNodeSize   OPTIONAL\r
   )\r
 {\r
-  UINT32                  Offset;\r
-  AUTH_CERT_DB_DATA       *Ptr;\r
-  UINT32                  CertSize;\r
-  UINT32                  NameSize;\r
-  UINT32                  NodeSize;\r
-  UINT32                  CertDbListSize;\r
+  UINT32             Offset;\r
+  AUTH_CERT_DB_DATA  *Ptr;\r
+  UINT32             CertSize;\r
+  UINT32             NameSize;\r
+  UINT32             NodeSize;\r
+  UINT32             CertDbListSize;\r
 \r
   if ((VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2600,9 +1225,9 @@ FindCertsFromDb (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  CertDbListSize = ReadUnaligned32 ((UINT32 *) Data);\r
+  CertDbListSize = ReadUnaligned32 ((UINT32 *)Data);\r
 \r
-  if (CertDbListSize != (UINT32) DataSize) {\r
+  if (CertDbListSize != (UINT32)DataSize) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -2611,8 +1236,8 @@ FindCertsFromDb (
   //\r
   // Get corresponding certificates by VendorGuid and VariableName.\r
   //\r
-  while (Offset < (UINT32) DataSize) {\r
-    Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
+  while (Offset < (UINT32)DataSize) {\r
+    Ptr = (AUTH_CERT_DB_DATA *)(Data + Offset);\r
     //\r
     // Check whether VendorGuid matches.\r
     //\r
@@ -2622,7 +1247,8 @@ FindCertsFromDb (
       CertSize = ReadUnaligned32 (&Ptr->CertDataSize);\r
 \r
       if (NodeSize != sizeof (EFI_GUID) + sizeof (UINT32) * 3 + CertSize +\r
-          sizeof (CHAR16) * NameSize) {\r
+          sizeof (CHAR16) * NameSize)\r
+      {\r
         return EFI_INVALID_PARAMETER;\r
       }\r
 \r
@@ -2631,7 +1257,8 @@ FindCertsFromDb (
       // Check whether VariableName matches.\r
       //\r
       if ((NameSize == StrLen (VariableName)) &&\r
-          (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0)) {\r
+          (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0))\r
+      {\r
         Offset = Offset + NameSize * sizeof (CHAR16);\r
 \r
         if (CertOffset != NULL) {\r
@@ -2643,7 +1270,7 @@ FindCertsFromDb (
         }\r
 \r
         if (CertNodeOffset != NULL) {\r
-          *CertNodeOffset = (UINT32) ((UINT8 *) Ptr - Data);\r
+          *CertNodeOffset = (UINT32)((UINT8 *)Ptr - Data);\r
         }\r
 \r
         if (CertNodeSize != NULL) {\r
@@ -2665,42 +1292,58 @@ 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
 EFI_STATUS\r
 GetCertsFromDb (\r
-  IN     CHAR16           *VariableName,\r
-  IN     EFI_GUID         *VendorGuid,\r
-  OUT    UINT8            **CertData,\r
-  OUT    UINT32           *CertDataSize\r
+  IN     CHAR16    *VariableName,\r
+  IN     EFI_GUID  *VendorGuid,\r
+  IN     UINT32    Attributes,\r
+  OUT    UINT8     **CertData,\r
+  OUT    UINT32    *CertDataSize\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  UINT8                   *Data;\r
-  UINTN                   DataSize;\r
-  UINT32                  CertOffset;\r
+  EFI_STATUS  Status;\r
+  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
+  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
+             (VOID **)&Data,\r
              &DataSize\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2733,45 +1376,61 @@ 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
 **/\r
 EFI_STATUS\r
 DeleteCertsFromDb (\r
-  IN     CHAR16           *VariableName,\r
-  IN     EFI_GUID         *VendorGuid\r
+  IN     CHAR16    *VariableName,\r
+  IN     EFI_GUID  *VendorGuid,\r
+  IN     UINT32    Attributes\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  UINT8                   *Data;\r
-  UINTN                   DataSize;\r
-  UINT32                  VarAttr;\r
-  UINT32                  CertNodeOffset;\r
-  UINT32                  CertNodeSize;\r
-  UINT8                   *NewCertDb;\r
-  UINT32                  NewCertDbSize;\r
+  EFI_STATUS  Status;\r
+  UINT8       *Data;\r
+  UINTN       DataSize;\r
+  UINT32      VarAttr;\r
+  UINT32      CertNodeOffset;\r
+  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
+             (VOID **)&Data,\r
              &DataSize\r
              );\r
+\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -2783,13 +1442,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,10 +1470,10 @@ 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
+  NewCertDbSize = (UINT32)DataSize - CertNodeSize;\r
+  NewCertDb     = (UINT8 *)mCertDbStore;\r
 \r
   //\r
   // Copy the DB entries before deleting node.\r
@@ -2836,65 +1495,89 @@ 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
-               &gEfiCertDbGuid,\r
-               NewCertDb,\r
-               NewCertDbSize,\r
-               VarAttr\r
-               );\r
+  Status = AuthServiceInternalUpdateVariable (\r
+             DbName,\r
+             &gEfiCertDbGuid,\r
+             NewCertDb,\r
+             NewCertDbSize,\r
+             VarAttr\r
+             );\r
 \r
   return Status;\r
 }\r
 \r
 /**\r
   Insert signer's certificates for common authenticated variable with VariableName\r
-  and VendorGuid in AUTH_CERT_DB_DATA to "certdb".\r
-\r
-  @param[in]  VariableName   Name of authenticated Variable.\r
-  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.\r
-  @param[in]  CertData       Pointer to signer's certificates.\r
-  @param[in]  CertDataSize   Length of CertData in bytes.\r
+  and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to\r
+  time based authenticated variable attributes. CertData is the SHA256 digest of\r
+  SignerCert CommonName + TopLevelCert tbsCertificate.\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]  SignerCert        Signer certificate data.\r
+  @param[in]  SignerCertSize    Length of signer certificate.\r
+  @param[in]  TopLevelCert      Top-level certificate data.\r
+  @param[in]  TopLevelCertSize  Length of top-level certificate.\r
 \r
   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
   @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     UINT8            *CertData,\r
-  IN     UINTN            CertDataSize\r
+  IN     CHAR16    *VariableName,\r
+  IN     EFI_GUID  *VendorGuid,\r
+  IN     UINT32    Attributes,\r
+  IN     UINT8     *SignerCert,\r
+  IN     UINTN     SignerCertSize,\r
+  IN     UINT8     *TopLevelCert,\r
+  IN     UINTN     TopLevelCertSize\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  UINT8                   *Data;\r
-  UINTN                   DataSize;\r
-  UINT32                  VarAttr;\r
-  UINT8                   *NewCertDb;\r
-  UINT32                  NewCertDbSize;\r
-  UINT32                  CertNodeSize;\r
-  UINT32                  NameSize;\r
-  AUTH_CERT_DB_DATA       *Ptr;\r
-\r
-  if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL)) {\r
+  EFI_STATUS         Status;\r
+  UINT8              *Data;\r
+  UINTN              DataSize;\r
+  UINT32             VarAttr;\r
+  UINT8              *NewCertDb;\r
+  UINT32             NewCertDbSize;\r
+  UINT32             CertNodeSize;\r
+  UINT32             NameSize;\r
+  UINT32             CertDataSize;\r
+  AUTH_CERT_DB_DATA  *Ptr;\r
+  CHAR16             *DbName;\r
+  UINT8              Sha256Digest[SHA256_DIGEST_SIZE];\r
+\r
+  if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == 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
+             (VOID **)&Data,\r
              &DataSize\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2907,7 +1590,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,15 +1610,28 @@ 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
-  NewCertDbSize = (UINT32) DataSize + CertNodeSize;\r
+  NameSize      = (UINT32)StrLen (VariableName);\r
+  CertDataSize  = sizeof (Sha256Digest);\r
+  CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);\r
+  NewCertDbSize = (UINT32)DataSize + CertNodeSize;\r
   if (NewCertDbSize > mMaxCertDbSize) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  NewCertDb     = (UINT8*) mCertDbStore;\r
+\r
+  Status = CalculatePrivAuthVarSignChainSHA256Digest (\r
+             SignerCert,\r
+             SignerCertSize,\r
+             TopLevelCert,\r
+             TopLevelCertSize,\r
+             Sha256Digest\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  NewCertDb = (UINT8 *)mCertDbStore;\r
 \r
   //\r
   // Copy the DB entries before inserting node.\r
@@ -2948,35 +1644,34 @@ InsertCertsToDb (
   //\r
   // Construct new cert node.\r
   //\r
-  Ptr = (AUTH_CERT_DB_DATA *) (NewCertDb + DataSize);\r
+  Ptr = (AUTH_CERT_DB_DATA *)(NewCertDb + DataSize);\r
   CopyGuid (&Ptr->VendorGuid, VendorGuid);\r
   CopyMem (&Ptr->CertNodeSize, &CertNodeSize, sizeof (UINT32));\r
   CopyMem (&Ptr->NameSize, &NameSize, sizeof (UINT32));\r
   CopyMem (&Ptr->CertDataSize, &CertDataSize, sizeof (UINT32));\r
 \r
   CopyMem (\r
-    (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA),\r
+    (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA),\r
     VariableName,\r
     NameSize * sizeof (CHAR16)\r
     );\r
 \r
   CopyMem (\r
-    (UINT8 *) Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),\r
-    CertData,\r
+    (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),\r
+    Sha256Digest,\r
     CertDataSize\r
     );\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
-               &gEfiCertDbGuid,\r
-               NewCertDb,\r
-               NewCertDbSize,\r
-               VarAttr\r
-               );\r
+  Status = AuthServiceInternalUpdateVariable (\r
+             DbName,\r
+             &gEfiCertDbGuid,\r
+             NewCertDb,\r
+             NewCertDbSize,\r
+             VarAttr\r
+             );\r
 \r
   return Status;\r
 }\r
@@ -2984,12 +1679,13 @@ InsertCertsToDb (
 /**\r
   Clean up signer's certificates for common authenticated variable\r
   by corresponding VariableName and VendorGuid from "certdb".\r
-  Sytem may break down during Timebased Variable update & certdb update,\r
-  make them inconsistent,  this function is called in AuthVariable Init to ensure \r
-  consistency\r
-  \r
-  @retval  EFI_NOT_FOUND         Fail to find matching certs.\r
-  @retval  EFI_SUCCESS           Find matching certs and output parameters.\r
+  System may break down during Timebased Variable update & certdb update,\r
+  make them inconsistent,  this function is called in AuthVariable Init\r
+  to ensure consistency.\r
+\r
+  @retval  EFI_NOT_FOUND         Fail to find variable "certdb".\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
 **/\r
 EFI_STATUS\r
@@ -2997,18 +1693,17 @@ CleanCertsFromDb (
   VOID\r
   )\r
 {\r
-  UINT32                  Offset;\r
-  AUTH_CERT_DB_DATA       *Ptr;\r
-  UINT32                  NameSize;\r
-  UINT32                  NodeSize;\r
-  CHAR16                  *VariableName;\r
-  EFI_STATUS              Status;\r
-  BOOLEAN                 CertCleaned;\r
-  UINT8                   *Data;\r
-  UINTN                   DataSize;\r
-  UINT8                   *AuthVarData;\r
-  UINTN                   AuthVarDataSize;\r
-  EFI_GUID                AuthVarGuid;\r
+  UINT32              Offset;\r
+  AUTH_CERT_DB_DATA   *Ptr;\r
+  UINT32              NameSize;\r
+  UINT32              NodeSize;\r
+  CHAR16              *VariableName;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             CertCleaned;\r
+  UINT8               *Data;\r
+  UINTN               DataSize;\r
+  EFI_GUID            AuthVarGuid;\r
+  AUTH_VARIABLE_INFO  AuthVariableInfo;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -3024,7 +1719,7 @@ CleanCertsFromDb (
     Status = AuthServiceInternalFindVariable (\r
                EFI_CERT_DB_NAME,\r
                &gEfiCertDbGuid,\r
-               (VOID **) &Data,\r
+               (VOID **)&Data,\r
                &DataSize\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -3038,46 +1733,51 @@ CleanCertsFromDb (
 \r
     Offset = sizeof (UINT32);\r
 \r
-    while (Offset < (UINT32) DataSize) {\r
-      Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
-      //\r
-      // Check whether VendorGuid matches.\r
-      //\r
+    while (Offset < (UINT32)DataSize) {\r
+      Ptr      = (AUTH_CERT_DB_DATA *)(Data + Offset);\r
       NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);\r
       NameSize = ReadUnaligned32 (&Ptr->NameSize);\r
 \r
       //\r
       // Get VarName tailed with '\0'\r
       //\r
-      VariableName = AllocateZeroPool((NameSize + 1) * sizeof(CHAR16));\r
+      VariableName = AllocateZeroPool ((NameSize + 1) * sizeof (CHAR16));\r
       if (VariableName == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
-      CopyMem (VariableName, (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof(CHAR16));\r
+\r
+      CopyMem (VariableName, (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof (CHAR16));\r
       //\r
       // Keep VarGuid  aligned\r
       //\r
-      CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof(EFI_GUID));\r
+      CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof (EFI_GUID));\r
 \r
       //\r
       // Find corresponding time auth variable\r
       //\r
-      Status = AuthServiceInternalFindVariable (\r
-                 VariableName,\r
-                 &AuthVarGuid,\r
-                 (VOID **) &AuthVarData,\r
-                 &AuthVarDataSize\r
-                 );\r
+      ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
+      Status = mAuthVarLibContextIn->FindVariable (\r
+                                       VariableName,\r
+                                       &AuthVarGuid,\r
+                                       &AuthVariableInfo\r
+                                       );\r
 \r
-      if (EFI_ERROR(Status)) {\r
-        Status      = DeleteCertsFromDb(VariableName, &AuthVarGuid);\r
+      if (EFI_ERROR (Status) || ((AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0)) {\r
+        //\r
+        // While cleaning certdb, always delete the variable in certdb regardless of it attributes.\r
+        //\r
+        Status = DeleteCertsFromDb (\r
+                   VariableName,\r
+                   &AuthVarGuid,\r
+                   AuthVariableInfo.Attributes | EFI_VARIABLE_NON_VOLATILE\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
+        DEBUG ((DEBUG_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));\r
+        FreePool (VariableName);\r
         break;\r
       }\r
 \r
-      FreePool(VariableName);\r
+      FreePool (VariableName);\r
       Offset = Offset + NodeSize;\r
     }\r
   } while (CertCleaned);\r
@@ -3116,48 +1816,58 @@ CleanCertsFromDb (
 **/\r
 EFI_STATUS\r
 VerifyTimeBasedPayload (\r
-  IN     CHAR16                             *VariableName,\r
-  IN     EFI_GUID                           *VendorGuid,\r
-  IN     VOID                               *Data,\r
-  IN     UINTN                              DataSize,\r
-  IN     UINT32                             Attributes,\r
-  IN     AUTHVAR_TYPE                       AuthVarType,\r
-  IN     EFI_TIME                           *OrgTimeStamp,\r
-  OUT    UINT8                              **VarPayloadPtr,\r
-  OUT    UINTN                              *VarPayloadSize\r
+  IN     CHAR16        *VariableName,\r
+  IN     EFI_GUID      *VendorGuid,\r
+  IN     VOID          *Data,\r
+  IN     UINTN         DataSize,\r
+  IN     UINT32        Attributes,\r
+  IN     AUTHVAR_TYPE  AuthVarType,\r
+  IN     EFI_TIME      *OrgTimeStamp,\r
+  OUT    UINT8         **VarPayloadPtr,\r
+  OUT    UINTN         *VarPayloadSize\r
   )\r
 {\r
-  EFI_VARIABLE_AUTHENTICATION_2    *CertData;\r
-  UINT8                            *SigData;\r
-  UINT32                           SigDataSize;\r
-  UINT8                            *PayloadPtr;\r
-  UINTN                            PayloadSize;\r
-  UINT32                           Attr;\r
-  BOOLEAN                          VerifyStatus;\r
-  EFI_STATUS                       Status;\r
-  EFI_SIGNATURE_LIST               *CertList;\r
-  EFI_SIGNATURE_DATA               *Cert;\r
-  UINTN                            Index;\r
-  UINTN                            CertCount;\r
-  UINT32                           KekDataSize;\r
-  UINT8                            *NewData;\r
-  UINTN                            NewDataSize;\r
-  UINT8                            *Buffer;\r
-  UINTN                            Length;\r
-  UINT8                            *RootCert;\r
-  UINTN                            RootCertSize;\r
-  UINT8                            *SignerCerts;\r
-  UINTN                            CertStackSize;\r
-  UINT8                            *CertsInCertDb;\r
-  UINT32                           CertsSizeinDb;\r
-\r
-  VerifyStatus           = FALSE;\r
-  CertData               = NULL;\r
-  NewData                = NULL;\r
-  Attr                   = Attributes;\r
-  SignerCerts            = NULL;\r
-  RootCert               = NULL;\r
-  CertsInCertDb          = NULL;\r
+  EFI_VARIABLE_AUTHENTICATION_2  *CertData;\r
+  UINT8                          *SigData;\r
+  UINT32                         SigDataSize;\r
+  UINT8                          *PayloadPtr;\r
+  UINTN                          PayloadSize;\r
+  UINT32                         Attr;\r
+  BOOLEAN                        VerifyStatus;\r
+  EFI_STATUS                     Status;\r
+  EFI_SIGNATURE_LIST             *CertList;\r
+  EFI_SIGNATURE_DATA             *Cert;\r
+  UINTN                          Index;\r
+  UINTN                          CertCount;\r
+  UINT32                         KekDataSize;\r
+  UINT8                          *NewData;\r
+  UINTN                          NewDataSize;\r
+  UINT8                          *Buffer;\r
+  UINTN                          Length;\r
+  UINT8                          *TopLevelCert;\r
+  UINTN                          TopLevelCertSize;\r
+  UINT8                          *TrustedCert;\r
+  UINTN                          TrustedCertSize;\r
+  UINT8                          *SignerCerts;\r
+  UINTN                          CertStackSize;\r
+  UINT8                          *CertsInCertDb;\r
+  UINT32                         CertsSizeinDb;\r
+  UINT8                          Sha256Digest[SHA256_DIGEST_SIZE];\r
+  EFI_CERT_DATA                  *CertDataPtr;\r
+\r
+  //\r
+  // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain\r
+  // 2. TrustedCert is the certificate which firmware trusts. It could be saved in protected\r
+  //     storage or PK payload on PK init\r
+  //\r
+  VerifyStatus  = FALSE;\r
+  CertData      = NULL;\r
+  NewData       = NULL;\r
+  Attr          = Attributes;\r
+  SignerCerts   = NULL;\r
+  TopLevelCert  = NULL;\r
+  CertsInCertDb = NULL;\r
+  CertDataPtr   = NULL;\r
 \r
   //\r
   // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is\r
@@ -3167,7 +1877,7 @@ VerifyTimeBasedPayload (
   // variable value. The authentication descriptor is not part of the variable data and is not\r
   // returned by subsequent calls to GetVariable().\r
   //\r
-  CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;\r
+  CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;\r
 \r
   //\r
   // Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the\r
@@ -3177,7 +1887,8 @@ VerifyTimeBasedPayload (
       (CertData->TimeStamp.Nanosecond != 0) ||\r
       (CertData->TimeStamp.TimeZone != 0) ||\r
       (CertData->TimeStamp.Daylight != 0) ||\r
-      (CertData->TimeStamp.Pad2 != 0)) {\r
+      (CertData->TimeStamp.Pad2 != 0))\r
+  {\r
     return EFI_SECURITY_VIOLATION;\r
   }\r
 \r
@@ -3195,7 +1906,8 @@ VerifyTimeBasedPayload (
   // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.\r
   //\r
   if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
-      !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid)) {\r
+      !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid))\r
+  {\r
     //\r
     // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
     //\r
@@ -3206,14 +1918,78 @@ VerifyTimeBasedPayload (
   // Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.\r
   // AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.\r
   //\r
-  SigData = CertData->AuthInfo.CertData;\r
-  SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32) (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
+  SigData     = CertData->AuthInfo.CertData;\r
+  SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32)(OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
+\r
+  //\r
+  // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the\r
+  // signature. Only a digest algorithm of SHA-256 is accepted.\r
+  //\r
+  //    According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):\r
+  //        SignedData ::= SEQUENCE {\r
+  //            version Version,\r
+  //            digestAlgorithms DigestAlgorithmIdentifiers,\r
+  //            contentInfo ContentInfo,\r
+  //            .... }\r
+  //    The DigestAlgorithmIdentifiers can be used to determine the hash algorithm\r
+  //    in VARIABLE_AUTHENTICATION_2 descriptor.\r
+  //    This field has the fixed offset (+13) or (+32) based on whether the DER-encoded\r
+  //    ContentInfo structure is present or not, and can be calculated based on two\r
+  //    bytes of length encoding.\r
+  //\r
+  //    Both condition can be handled in WrapPkcs7Data() in CryptPkcs7VerifyCommon.c.\r
+  //\r
+  //    See below examples:\r
+  //\r
+  // 1. Without ContentInfo\r
+  //    30 82 0c da // SEQUENCE (5 element) (3294 BYTES) -- SignedData\r
+  //       02 01 01 // INTEGER 1 -- Version\r
+  //       31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers\r
+  //          30 0d // SEQUENCE (2 element) (13 BYTES) -- AlgorithmIdentifier\r
+  //             06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm\r
+  //                60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]\r
+  //             05 00 // NULL (0 BYTES) -- parameters\r
+  //\r
+  // Example from: https://uefi.org/revocationlistfile\r
+  //\r
+  // 2. With ContentInfo\r
+  //    30 82 05 90 // SEQUENCE (1424 BYTES) -- ContentInfo\r
+  //       06 09 // OBJECT-IDENTIFIER (9 BYTES) -- ContentType\r
+  //          2a 86 48 86 f7 0d 01 07 02 // signedData [1.2.840.113549.1.7.2]\r
+  //       a0 82 05 81 // CONTEXT-SPECIFIC CONSTRUCTED TAG 0 (1409 BYTES) -- content\r
+  //          30 82 05 7d // SEQUENCE (1405 BYTES) -- SignedData\r
+  //             02 01 01 // INTEGER 1 -- Version\r
+  //             31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers\r
+  //                30 0d // SEQUENCE (13 BYTES) -- AlgorithmIdentifier\r
+  //                   06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm\r
+  //                      60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]\r
+  //                   05 00 // NULL (0 BYTES) -- parameters\r
+  //\r
+  // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process\r
+  //\r
+  if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+    if (  (  (SigDataSize >= (13 + sizeof (mSha256OidValue)))\r
+          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)\r
+             || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))\r
+       && (  (SigDataSize >= (32 + sizeof (mSha256OidValue)))\r
+          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)\r
+             || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))))\r
+    {\r
+      return EFI_SECURITY_VIOLATION;\r
+    }\r
+  }\r
 \r
   //\r
   // Find out the new data payload which follows Pkcs7 SignedData directly.\r
   //\r
-  PayloadPtr = SigData + SigDataSize;\r
-  PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN) SigDataSize;\r
+  PayloadPtr  = SigData + SigDataSize;\r
+  PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN)SigDataSize;\r
+\r
+  // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.\r
+  if ((PayloadSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && !IsVariablePolicyEnabled ()) {\r
+    VerifyStatus = TRUE;\r
+    goto Exit;\r
+  }\r
 \r
   //\r
   // Construct a serialization buffer of the values of the VariableName, VendorGuid and Attributes\r
@@ -3231,7 +2007,7 @@ VerifyTimeBasedPayload (
   // because it is only used at here to do verification temporarily first\r
   // and then used in UpdateVariable() for a time based auth variable set.\r
   //\r
-  Status = mAuthVarLibContextIn->GetScratchBuffer (&NewDataSize, (VOID **) &NewData);\r
+  Status = mAuthVarLibContextIn->GetScratchBuffer (&NewDataSize, (VOID **)&NewData);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -3265,8 +2041,8 @@ VerifyTimeBasedPayload (
                      SigDataSize,\r
                      &SignerCerts,\r
                      &CertStackSize,\r
-                     &RootCert,\r
-                     &RootCertSize\r
+                     &TopLevelCert,\r
+                     &TopLevelCertSize\r
                      );\r
     if (!VerifyStatus) {\r
       goto Exit;\r
@@ -3286,10 +2062,12 @@ VerifyTimeBasedPayload (
       VerifyStatus = FALSE;\r
       goto Exit;\r
     }\r
-    CertList = (EFI_SIGNATURE_LIST *) Data;\r
-    Cert     = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
-    if ((RootCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||\r
-        (CompareMem (Cert->SignatureData, RootCert, RootCertSize) != 0)) {\r
+\r
+    CertList = (EFI_SIGNATURE_LIST *)Data;\r
+    Cert     = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+    if ((TopLevelCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||\r
+        (CompareMem (Cert->SignatureData, TopLevelCert, TopLevelCertSize) != 0))\r
+    {\r
       VerifyStatus = FALSE;\r
       goto Exit;\r
     }\r
@@ -3300,14 +2078,12 @@ VerifyTimeBasedPayload (
     VerifyStatus = Pkcs7Verify (\r
                      SigData,\r
                      SigDataSize,\r
-                     RootCert,\r
-                     RootCertSize,\r
+                     TopLevelCert,\r
+                     TopLevelCertSize,\r
                      NewData,\r
                      NewDataSize\r
                      );\r
-\r
   } else if (AuthVarType == AuthVarTypeKek) {\r
-\r
     //\r
     // Get KEK database from variable.\r
     //\r
@@ -3324,18 +2100,18 @@ VerifyTimeBasedPayload (
     //\r
     // Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.\r
     //\r
-    KekDataSize      = (UINT32) DataSize;\r
-    CertList         = (EFI_SIGNATURE_LIST *) Data;\r
+    KekDataSize = (UINT32)DataSize;\r
+    CertList    = (EFI_SIGNATURE_LIST *)Data;\r
     while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {\r
       if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
-        Cert       = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
-        CertCount  = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+        Cert      = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+        CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
         for (Index = 0; Index < CertCount; Index++) {\r
           //\r
           // Iterate each Signature Data Node within this CertList for a verify\r
           //\r
-          RootCert      = Cert->SignatureData;\r
-          RootCertSize  = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
+          TrustedCert     = Cert->SignatureData;\r
+          TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
 \r
           //\r
           // Verify Pkcs7 SignedData via Pkcs7Verify library.\r
@@ -3343,22 +2119,23 @@ VerifyTimeBasedPayload (
           VerifyStatus = Pkcs7Verify (\r
                            SigData,\r
                            SigDataSize,\r
-                           RootCert,\r
-                           RootCertSize,\r
+                           TrustedCert,\r
+                           TrustedCertSize,\r
                            NewData,\r
                            NewDataSize\r
                            );\r
           if (VerifyStatus) {\r
             goto Exit;\r
           }\r
-          Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+\r
+          Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
         }\r
       }\r
+\r
       KekDataSize -= CertList->SignatureListSize;\r
-      CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+      CertList     = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
     }\r
   } else if (AuthVarType == AuthVarTypePriv) {\r
-\r
     //\r
     // Process common authenticated variable except PK/KEK/DB/DBX/DBT.\r
     // Get signer's certificates from SignedData.\r
@@ -3368,37 +2145,58 @@ VerifyTimeBasedPayload (
                      SigDataSize,\r
                      &SignerCerts,\r
                      &CertStackSize,\r
-                     &RootCert,\r
-                     &RootCertSize\r
+                     &TopLevelCert,\r
+                     &TopLevelCertSize\r
                      );\r
     if (!VerifyStatus) {\r
       goto Exit;\r
     }\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
 \r
-      if ((CertStackSize != CertsSizeinDb) ||\r
-          (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0)) {\r
-        goto Exit;\r
+      if (CertsSizeinDb == SHA256_DIGEST_SIZE) {\r
+        //\r
+        // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb\r
+        //\r
+        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);\r
+        Status      = CalculatePrivAuthVarSignChainSHA256Digest (\r
+                        CertDataPtr->CertDataBuffer,\r
+                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),\r
+                        TopLevelCert,\r
+                        TopLevelCertSize,\r
+                        Sha256Digest\r
+                        );\r
+        if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb, CertsSizeinDb) != 0)) {\r
+          goto Exit;\r
+        }\r
+      } else {\r
+        //\r
+        // Keep backward compatible with previous solution which saves whole signer certs stack in CertDb\r
+        //\r
+        if ((CertStackSize != CertsSizeinDb) ||\r
+            (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0))\r
+        {\r
+          goto Exit;\r
+        }\r
       }\r
     }\r
 \r
     VerifyStatus = Pkcs7Verify (\r
                      SigData,\r
                      SigDataSize,\r
-                     RootCert,\r
-                     RootCertSize,\r
+                     TopLevelCert,\r
+                     TopLevelCertSize,\r
                      NewData,\r
                      NewDataSize\r
                      );\r
@@ -3408,27 +2206,36 @@ VerifyTimeBasedPayload (
 \r
     if ((OrgTimeStamp == NULL) && (PayloadSize != 0)) {\r
       //\r
-      // Insert signer's certificates when adding a new common authenticated variable.\r
-      //\r
-      Status = InsertCertsToDb (VariableName, VendorGuid, SignerCerts, CertStackSize);\r
+      // When adding a new common authenticated variable, always save Hash of cn of signer cert + tbsCertificate of Top-level issuer\r
+      //\r
+      CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);\r
+      Status      = InsertCertsToDb (\r
+                      VariableName,\r
+                      VendorGuid,\r
+                      Attributes,\r
+                      CertDataPtr->CertDataBuffer,\r
+                      ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),\r
+                      TopLevelCert,\r
+                      TopLevelCertSize\r
+                      );\r
       if (EFI_ERROR (Status)) {\r
         VerifyStatus = FALSE;\r
         goto Exit;\r
       }\r
     }\r
   } else if (AuthVarType == AuthVarTypePayload) {\r
-    CertList = (EFI_SIGNATURE_LIST *) PayloadPtr;\r
-    Cert     = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
-    RootCert      = Cert->SignatureData;\r
-    RootCertSize  = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
+    CertList        = (EFI_SIGNATURE_LIST *)PayloadPtr;\r
+    Cert            = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+    TrustedCert     = Cert->SignatureData;\r
+    TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
     //\r
     // Verify Pkcs7 SignedData via Pkcs7Verify library.\r
     //\r
     VerifyStatus = Pkcs7Verify (\r
                      SigData,\r
                      SigDataSize,\r
-                     RootCert,\r
-                     RootCertSize,\r
+                     TrustedCert,\r
+                     TrustedCertSize,\r
                      NewData,\r
                      NewDataSize\r
                      );\r
@@ -3438,21 +2245,26 @@ VerifyTimeBasedPayload (
 \r
 Exit:\r
 \r
-  if (AuthVarType == AuthVarTypePk || AuthVarType == AuthVarTypePriv) {\r
-    Pkcs7FreeSigners (RootCert);\r
-    Pkcs7FreeSigners (SignerCerts);\r
+  if ((AuthVarType == AuthVarTypePk) || (AuthVarType == AuthVarTypePriv)) {\r
+    if (TopLevelCert != NULL) {\r
+      Pkcs7FreeSigners (TopLevelCert);\r
+    }\r
+\r
+    if (SignerCerts != NULL) {\r
+      Pkcs7FreeSigners (SignerCerts);\r
+    }\r
   }\r
 \r
   if (!VerifyStatus) {\r
     return EFI_SECURITY_VIOLATION;\r
   }\r
 \r
-  Status = CheckSignatureListFormat(VariableName, VendorGuid, PayloadPtr, PayloadSize);\r
+  Status = CheckSignatureListFormat (VariableName, VendorGuid, PayloadPtr, PayloadSize);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  *VarPayloadPtr = PayloadPtr;\r
+  *VarPayloadPtr  = PayloadPtr;\r
   *VarPayloadSize = PayloadSize;\r
 \r
   return EFI_SUCCESS;\r
@@ -3486,29 +2298,29 @@ Exit:
 **/\r
 EFI_STATUS\r
 VerifyTimeBasedPayloadAndUpdate (\r
-  IN     CHAR16                             *VariableName,\r
-  IN     EFI_GUID                           *VendorGuid,\r
-  IN     VOID                               *Data,\r
-  IN     UINTN                              DataSize,\r
-  IN     UINT32                             Attributes,\r
-  IN     AUTHVAR_TYPE                       AuthVarType,\r
-  OUT    BOOLEAN                            *VarDel\r
+  IN     CHAR16        *VariableName,\r
+  IN     EFI_GUID      *VendorGuid,\r
+  IN     VOID          *Data,\r
+  IN     UINTN         DataSize,\r
+  IN     UINT32        Attributes,\r
+  IN     AUTHVAR_TYPE  AuthVarType,\r
+  OUT    BOOLEAN       *VarDel\r
   )\r
 {\r
-  EFI_STATUS                       Status;\r
-  EFI_STATUS                       FindStatus;\r
-  UINT8                            *PayloadPtr;\r
-  UINTN                            PayloadSize;\r
-  EFI_VARIABLE_AUTHENTICATION_2    *CertData;\r
-  AUTH_VARIABLE_INFO               OrgVariableInfo;\r
-  BOOLEAN                          IsDel;\r
+  EFI_STATUS                     Status;\r
+  EFI_STATUS                     FindStatus;\r
+  UINT8                          *PayloadPtr;\r
+  UINTN                          PayloadSize;\r
+  EFI_VARIABLE_AUTHENTICATION_2  *CertData;\r
+  AUTH_VARIABLE_INFO             OrgVariableInfo;\r
+  BOOLEAN                        IsDel;\r
 \r
   ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));\r
   FindStatus = mAuthVarLibContextIn->FindVariable (\r
-             VariableName,\r
-             VendorGuid,\r
-             &OrgVariableInfo\r
-             );\r
+                                       VariableName,\r
+                                       VendorGuid,\r
+                                       &OrgVariableInfo\r
+                                       );\r
 \r
   Status = VerifyTimeBasedPayload (\r
              VariableName,\r
@@ -3525,15 +2337,16 @@ VerifyTimeBasedPayloadAndUpdate (
     return Status;\r
   }\r
 \r
-  if (!EFI_ERROR(FindStatus)\r
-   && (PayloadSize == 0)\r
-   && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
+  if (  !EFI_ERROR (FindStatus)\r
+     && (PayloadSize == 0)\r
+     && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0))\r
+  {\r
     IsDel = TRUE;\r
   } else {\r
     IsDel = FALSE;\r
   }\r
 \r
-  CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;\r
+  CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;\r
 \r
   //\r
   // Final step: Update/Append Variable if it pass Pkcs7Verify\r
@@ -3550,12 +2363,12 @@ VerifyTimeBasedPayloadAndUpdate (
   //\r
   // 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
+  if (IsDel && (AuthVarType == AuthVarTypePriv) && !EFI_ERROR (Status)) {\r
+    Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);\r
   }\r
 \r
   if (VarDel != NULL) {\r
-    if (IsDel && !EFI_ERROR(Status)) {\r
+    if (IsDel && !EFI_ERROR (Status)) {\r
       *VarDel = TRUE;\r
     } else {\r
       *VarDel = FALSE;\r