/** @file
  Implement authentication services for the authenticated variables.

  Caution: This module requires additional review when modified.
  This driver will have external input - variable data. It may be input in SMM mode.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.
  Variable attribute should also be checked to avoid authentication bypass.
     The whole SMM authentication variable design relies on the integrity of flash part and SMM.
  which is assumed to be protected by platform.  All variable code and metadata in flash/SMM Memory
  may not be modified without authorization. If platform fails to protect these resources,
  the authentication service provided in this driver will be broken, and the behavior is undefined.

  ProcessVarWithPk(), ProcessVarWithKek() and ProcessVariable() are the function to do
  variable authentication.

  VerifyTimeBasedPayloadAndUpdate() and VerifyCounterBasedPayload() are sub function to do verification.
  They will do basic validation for authentication data structure, then call crypto library
  to verify the signature.

Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.
(c) Copyright 2025 HP Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "AuthServiceInternal.h"

#include <Protocol/VariablePolicy.h>
#include <Library/VariablePolicyLib.h>

#define SHA_DIGEST_SIZE_MAX  SHA512_DIGEST_SIZE

/**
  Retrieves the size, in bytes, of the context buffer required for hash operations.

  If this interface is not supported, then return zero.

  @return  The size, in bytes, of the context buffer required for hash operations.
  @retval  0   This interface is not supported.

**/
typedef
UINTN
(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE)(
  VOID
  );

/**
  Initializes user-supplied memory pointed by Sha1Context as hash context for
  subsequent use.

  If HashContext is NULL, then return FALSE.
  If this interface is not supported, then return FALSE.

  @param[out]  HashContext  Pointer to Hashcontext being initialized.

  @retval TRUE   Hash context initialization succeeded.
  @retval FALSE  Hash context initialization failed.
  @retval FALSE  This interface is not supported.

**/
typedef
BOOLEAN
(EFIAPI *EFI_HASH_INIT)(
  OUT  VOID  *HashContext
  );

/**
  Digests the input data and updates Hash context.

  This function performs Hash digest on a data buffer of the specified size.
  It can be called multiple times to compute the digest of long or discontinuous data streams.
  Hash context should be already correctly initialized by HashInit(), and should not be finalized
  by HashFinal(). Behavior with invalid context is undefined.

  If HashContext is NULL, then return FALSE.
  If this interface is not supported, then return FALSE.

  @param[in, out]  HashContext  Pointer to the Hash context.
  @param[in]       Data         Pointer to the buffer containing the data to be hashed.
  @param[in]       DataSize     Size of Data buffer in bytes.

  @retval TRUE   SHA-1 data digest succeeded.
  @retval FALSE  SHA-1 data digest failed.
  @retval FALSE  This interface is not supported.

**/
typedef
BOOLEAN
(EFIAPI *EFI_HASH_UPDATE)(
  IN OUT  VOID        *HashContext,
  IN      CONST VOID  *Data,
  IN      UINTN       DataSize
  );

/**
  Completes computation of the Hash digest value.

  This function completes hash computation and retrieves the digest value into
  the specified memory. After this function has been called, the Hash context cannot
  be used again.
  Hash context should be already correctly initialized by HashInit(), and should not be
  finalized by HashFinal(). Behavior with invalid Hash context is undefined.

  If HashContext is NULL, then return FALSE.
  If HashValue is NULL, then return FALSE.
  If this interface is not supported, then return FALSE.

  @param[in, out]  HashContext  Pointer to the Hash context.
  @param[out]      HashValue    Pointer to a buffer that receives the Hash digest
                                value.

  @retval TRUE   Hash digest computation succeeded.
  @retval FALSE  Hash digest computation failed.
  @retval FALSE  This interface is not supported.

**/
typedef
BOOLEAN
(EFIAPI *EFI_HASH_FINAL)(
  IN OUT  VOID   *HashContext,
  OUT     UINT8  *HashValue
  );

typedef struct {
  UINT32                       HashSize;
  EFI_HASH_GET_CONTEXT_SIZE    GetContextSize;
  EFI_HASH_INIT                Init;
  EFI_HASH_UPDATE              Update;
  EFI_HASH_FINAL               Final;
  VOID                         **HashShaCtx;
  UINT8                        *OidValue;
  UINTN                        OidLength;
} EFI_HASH_INFO;

//
// Public Exponent of RSA Key.
//
CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };

UINT8  mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
UINT8  mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 };
UINT8  mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 };

EFI_HASH_INFO  mHashInfo[] = {
  { SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final, &mHashSha256Ctx, mSha256OidValue, 9 },
  { SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final, &mHashSha384Ctx, mSha384OidValue, 9 },
  { SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final, &mHashSha512Ctx, mSha512OidValue, 9 },
};

//
// Requirement for different signature type which have been defined in UEFI spec.
// These data are used to perform SignatureList format check while setting PK/KEK variable.
//
EFI_SIGNATURE_ITEM  mSupportSigItem[] = {
  // {SigType,                       SigHeaderSize,   SigDataSize  }
  { EFI_CERT_SHA256_GUID,         0, 32            },
  { EFI_CERT_RSA2048_GUID,        0, 256           },
  { EFI_CERT_RSA2048_SHA256_GUID, 0, 256           },
  { EFI_CERT_SHA1_GUID,           0, 20            },
  { EFI_CERT_RSA2048_SHA1_GUID,   0, 256           },
  { EFI_CERT_X509_GUID,           0, ((UINT32) ~0) },
  { EFI_CERT_SHA224_GUID,         0, 28            },
  { EFI_CERT_SHA384_GUID,         0, 48            },
  { EFI_CERT_SHA512_GUID,         0, 64            },
  { EFI_CERT_X509_SHA256_GUID,    0, 48            },
  { EFI_CERT_X509_SHA384_GUID,    0, 64            },
  { EFI_CERT_X509_SHA512_GUID,    0, 80            }
};

/**
  Finds variable in storage blocks of volatile and non-volatile storage areas.

  This code finds variable in storage blocks of volatile and non-volatile storage areas.
  If VariableName is an empty string, then we just return the first
  qualified variable without comparing VariableName and VendorGuid.

  @param[in]  VariableName          Name of the variable to be found.
  @param[in]  VendorGuid            Variable vendor GUID to be found.
  @param[out] Data                  Pointer to data address.
  @param[out] DataSize              Pointer to data size.

  @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
                                    while VendorGuid is NULL.
  @retval EFI_SUCCESS               Variable successfully found.
  @retval EFI_NOT_FOUND             Variable not found

**/
EFI_STATUS
AuthServiceInternalFindVariable (
  IN  CHAR16    *VariableName,
  IN  EFI_GUID  *VendorGuid,
  OUT VOID      **Data,
  OUT UINTN     *DataSize
  )
{
  EFI_STATUS          Status;
  AUTH_VARIABLE_INFO  AuthVariableInfo;

  ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
  Status = mAuthVarLibContextIn->FindVariable (
                                   VariableName,
                                   VendorGuid,
                                   &AuthVariableInfo
                                   );
  *Data     = AuthVariableInfo.Data;
  *DataSize = AuthVariableInfo.DataSize;
  return Status;
}

/**
  Update the variable region with Variable information.

  @param[in] VariableName           Name of variable.
  @param[in] VendorGuid             Guid of variable.
  @param[in] Data                   Data pointer.
  @param[in] DataSize               Size of Data.
  @param[in] Attributes             Attribute value of the variable.

  @retval EFI_SUCCESS               The update operation is success.
  @retval EFI_INVALID_PARAMETER     Invalid parameter.
  @retval EFI_WRITE_PROTECTED       Variable is write-protected.
  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.

**/
EFI_STATUS
AuthServiceInternalUpdateVariable (
  IN CHAR16    *VariableName,
  IN EFI_GUID  *VendorGuid,
  IN VOID      *Data,
  IN UINTN     DataSize,
  IN UINT32    Attributes
  )
{
  AUTH_VARIABLE_INFO  AuthVariableInfo;

  ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
  AuthVariableInfo.VariableName = VariableName;
  AuthVariableInfo.VendorGuid   = VendorGuid;
  AuthVariableInfo.Data         = Data;
  AuthVariableInfo.DataSize     = DataSize;
  AuthVariableInfo.Attributes   = Attributes;

  return mAuthVarLibContextIn->UpdateVariable (
                                 &AuthVariableInfo
                                 );
}

/**
  Update the variable region with Variable information.

  @param[in] VariableName           Name of variable.
  @param[in] VendorGuid             Guid of variable.
  @param[in] Data                   Data pointer.
  @param[in] DataSize               Size of Data.
  @param[in] Attributes             Attribute value of the variable.
  @param[in] TimeStamp              Value of associated TimeStamp.

  @retval EFI_SUCCESS               The update operation is success.
  @retval EFI_INVALID_PARAMETER     Invalid parameter.
  @retval EFI_WRITE_PROTECTED       Variable is write-protected.
  @retval EFI_OUT_OF_RESOURCES      There is not enough resource.

**/
EFI_STATUS
AuthServiceInternalUpdateVariableWithTimeStamp (
  IN CHAR16    *VariableName,
  IN EFI_GUID  *VendorGuid,
  IN VOID      *Data,
  IN UINTN     DataSize,
  IN UINT32    Attributes,
  IN EFI_TIME  *TimeStamp
  )
{
  EFI_STATUS          Status;
  EFI_STATUS          FindStatus;
  VOID                *OrgData;
  UINTN               OrgDataSize;
  AUTH_VARIABLE_INFO  AuthVariableInfo;

  FindStatus = AuthServiceInternalFindVariable (
                 VariableName,
                 VendorGuid,
                 &OrgData,
                 &OrgDataSize
                 );

  //
  // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable
  //
  if (!EFI_ERROR (FindStatus) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {
    if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
         ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||
          (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||
        (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)))
    {
      //
      // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of
      // EFI_SIGNATURE_DATA values that are already part of the existing variable value.
      //
      Status = FilterSignatureList (
                 OrgData,
                 OrgDataSize,
                 Data,
                 &DataSize
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
  }

  ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
  AuthVariableInfo.VariableName = VariableName;
  AuthVariableInfo.VendorGuid   = VendorGuid;
  AuthVariableInfo.Data         = Data;
  AuthVariableInfo.DataSize     = DataSize;
  AuthVariableInfo.Attributes   = Attributes;
  AuthVariableInfo.TimeStamp    = TimeStamp;
  return mAuthVarLibContextIn->UpdateVariable (
                                 &AuthVariableInfo
                                 );
}

/**
  Determine whether this operation needs a physical present user.

  @param[in]      VariableName            Name of the Variable.
  @param[in]      VendorGuid              GUID of the Variable.

  @retval TRUE      This variable is protected, only a physical present user could set this variable.
  @retval FALSE     This variable is not protected.

**/
BOOLEAN
NeedPhysicallyPresent (
  IN     CHAR16    *VariableName,
  IN     EFI_GUID  *VendorGuid
  )
{
  // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.
  if (IsVariablePolicyEnabled ()) {
    if (  (CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))
       || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0)))
    {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Determine whether the platform is operating in Custom Secure Boot mode.

  @retval TRUE           The platform is operating in Custom mode.
  @retval FALSE          The platform is operating in Standard mode.

**/
BOOLEAN
InCustomMode (
  VOID
  )
{
  EFI_STATUS  Status;
  VOID        *Data;
  UINTN       DataSize;

  Status = AuthServiceInternalFindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Data, &DataSize);
  if (!EFI_ERROR (Status) && (*(UINT8 *)Data == CUSTOM_SECURE_BOOT_MODE)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Update platform mode.

  @param[in]      Mode                    SETUP_MODE or USER_MODE.

  @return EFI_INVALID_PARAMETER           Invalid parameter.
  @return EFI_SUCCESS                     Update platform mode successfully.

**/
EFI_STATUS
UpdatePlatformMode (
  IN  UINT32  Mode
  )
{
  EFI_STATUS  Status;
  VOID        *Data;
  UINTN       DataSize;
  UINT8       SecureBootMode;
  UINT8       SecureBootEnable;
  UINTN       VariableDataSize;

  Status = AuthServiceInternalFindVariable (
             EFI_SETUP_MODE_NAME,
             &gEfiGlobalVariableGuid,
             &Data,
             &DataSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Update the value of SetupMode variable by a simple mem copy, this could avoid possible
  // variable storage reclaim at runtime.
  //
  mPlatformMode = (UINT8)Mode;
  CopyMem (Data, &mPlatformMode, sizeof (UINT8));

  if (mAuthVarLibContextIn->AtRuntime ()) {
    //
    // SecureBoot Variable indicates whether the platform firmware is operating
    // in Secure boot mode (1) or not (0), so we should not change SecureBoot
    // Variable in runtime.
    //
    return Status;
  }

  //
  // Check "SecureBoot" variable's existence.
  // If it doesn't exist, firmware has no capability to perform driver signing verification,
  // then set "SecureBoot" to 0.
  //
  Status = AuthServiceInternalFindVariable (
             EFI_SECURE_BOOT_MODE_NAME,
             &gEfiGlobalVariableGuid,
             &Data,
             &DataSize
             );
  //
  // If "SecureBoot" variable exists, then check "SetupMode" variable update.
  // If "SetupMode" variable is USER_MODE, "SecureBoot" variable is set to 1.
  // If "SetupMode" variable is SETUP_MODE, "SecureBoot" variable is set to 0.
  //
  if (EFI_ERROR (Status)) {
    SecureBootMode = SECURE_BOOT_MODE_DISABLE;
  } else {
    if (mPlatformMode == USER_MODE) {
      SecureBootMode = SECURE_BOOT_MODE_ENABLE;
    } else if (mPlatformMode == SETUP_MODE) {
      SecureBootMode = SECURE_BOOT_MODE_DISABLE;
    } else {
      return EFI_NOT_FOUND;
    }
  }

  Status = AuthServiceInternalUpdateVariable (
             EFI_SECURE_BOOT_MODE_NAME,
             &gEfiGlobalVariableGuid,
             &SecureBootMode,
             sizeof (UINT8),
             EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.
  //
  Status = AuthServiceInternalFindVariable (
             EFI_SECURE_BOOT_ENABLE_NAME,
             &gEfiSecureBootEnableDisableGuid,
             &Data,
             &DataSize
             );

  if (SecureBootMode == SECURE_BOOT_MODE_ENABLE) {
    //
    // Create the "SecureBootEnable" variable as secure boot is enabled.
    //
    SecureBootEnable = SECURE_BOOT_ENABLE;
    VariableDataSize = sizeof (SecureBootEnable);
  } else {
    //
    // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"
    // variable is not in secure boot state.
    //
    if (EFI_ERROR (Status)) {
      return EFI_SUCCESS;
    }

    SecureBootEnable = SECURE_BOOT_DISABLE;
    VariableDataSize = 0;
  }

  Status = AuthServiceInternalUpdateVariable (
             EFI_SECURE_BOOT_ENABLE_NAME,
             &gEfiSecureBootEnableDisableGuid,
             &SecureBootEnable,
             VariableDataSize,
             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS
             );
  return Status;
}

/**
  Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK/db/dbx/dbt variable.

  @param[in]  VariableName                Name of Variable to be check.
  @param[in]  VendorGuid                  Variable vendor GUID.
  @param[in]  Data                        Point to the variable data to be checked.
  @param[in]  DataSize                    Size of Data.

  @return EFI_INVALID_PARAMETER           Invalid signature list format.
  @return EFI_SUCCESS                     Passed signature list format check successfully.

**/
EFI_STATUS
CheckSignatureListFormat (
  IN  CHAR16    *VariableName,
  IN  EFI_GUID  *VendorGuid,
  IN  VOID      *Data,
  IN  UINTN     DataSize
  )
{
  EFI_SIGNATURE_LIST  *SigList;
  UINTN               SigDataSize;
  UINT32              Index;
  UINT32              SigCount;
  BOOLEAN             IsPk;
  VOID                *RsaContext;
  EFI_SIGNATURE_DATA  *CertData;
  UINTN               CertLen;

  if (DataSize == 0) {
    return EFI_SUCCESS;
  }

  ASSERT (VariableName != NULL && VendorGuid != NULL && Data != NULL);

  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)) {
    IsPk = TRUE;
  } else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) ||
             (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
              ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||
               (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))))
  {
    IsPk = FALSE;
  } else {
    return EFI_SUCCESS;
  }

  SigCount    = 0;
  SigList     = (EFI_SIGNATURE_LIST *)Data;
  SigDataSize = DataSize;
  RsaContext  = NULL;

  //
  // Walk through the input signature list and check the data format.
  // If any signature is incorrectly formed, the whole check will fail.
  //
  while ((SigDataSize > 0) && (SigDataSize >= SigList->SignatureListSize)) {
    for (Index = 0; Index < (sizeof (mSupportSigItem) / sizeof (EFI_SIGNATURE_ITEM)); Index++ ) {
      if (CompareGuid (&SigList->SignatureType, &mSupportSigItem[Index].SigType)) {
        //
        // The value of SignatureSize should always be 16 (size of SignatureOwner
        // component) add the data length according to signature type.
        //
        if ((mSupportSigItem[Index].SigDataSize != ((UINT32) ~0)) &&
            ((SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize))
        {
          return EFI_INVALID_PARAMETER;
        }

        if ((mSupportSigItem[Index].SigHeaderSize != ((UINT32) ~0)) &&
            (SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize))
        {
          return EFI_INVALID_PARAMETER;
        }

        break;
      }
    }

    if (Index == (sizeof (mSupportSigItem) / sizeof (EFI_SIGNATURE_ITEM))) {
      //
      // Undefined signature type.
      //
      return EFI_INVALID_PARAMETER;
    }

    if (CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
      //
      // Try to retrieve the RSA public key from the X.509 certificate.
      // If this operation fails, it's not a valid certificate.
      //
      CertData   = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);
      CertLen    = SigList->SignatureSize - sizeof (EFI_GUID);
      RsaContext = NULL;
      if ((CertLen > 0) && !RsaGetPublicKeyFromX509 (CertData->SignatureData, CertLen, &RsaContext)) {
        return EFI_INVALID_PARAMETER;
      }

      RsaFree (RsaContext);
    }

    if ((SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) % SigList->SignatureSize != 0) {
      return EFI_INVALID_PARAMETER;
    }

    SigCount += (SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) / SigList->SignatureSize;

    SigDataSize -= SigList->SignatureListSize;
    SigList      = (EFI_SIGNATURE_LIST *)((UINT8 *)SigList + SigList->SignatureListSize);
  }

  if (((UINTN)SigList - (UINTN)Data) != DataSize) {
    return EFI_INVALID_PARAMETER;
  }

  if (IsPk && (SigCount > 1)) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Update "VendorKeys" variable to record the out of band secure boot key modification.

  @return EFI_SUCCESS           Variable is updated successfully.
  @return Others                Failed to update variable.

**/
EFI_STATUS
VendorKeyIsModified (
  VOID
  )
{
  EFI_STATUS  Status;

  if (mVendorKeyState == VENDOR_KEYS_MODIFIED) {
    return EFI_SUCCESS;
  }

  mVendorKeyState = VENDOR_KEYS_MODIFIED;

  Status = AuthServiceInternalUpdateVariable (
             EFI_VENDOR_KEYS_NV_VARIABLE_NAME,
             &gEfiVendorKeysNvGuid,
             &mVendorKeyState,
             sizeof (UINT8),
             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AuthServiceInternalUpdateVariable (
           EFI_VENDOR_KEYS_VARIABLE_NAME,
           &gEfiGlobalVariableGuid,
           &mVendorKeyState,
           sizeof (UINT8),
           EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
           );
}

/**
  Process variable with platform key for verification.

  Caution: This function may receive untrusted input.
  This function may be invoked in SMM mode, and datasize and data are external input.
  This function will do basic validation, before parse the data.
  This function will parse the authentication carefully to avoid security issues, like
  buffer overflow, integer overflow.
  This function will check attribute carefully to avoid authentication bypass.

  @param[in]  VariableName                Name of Variable to be found.
  @param[in]  VendorGuid                  Variable vendor GUID.
  @param[in]  Data                        Data pointer.
  @param[in]  DataSize                    Size of Data found. If size is less than the
                                          data, this value contains the required size.
  @param[in]  Attributes                  Attribute value of the variable
  @param[in]  IsPk                        Indicate whether it is to process pk.

  @return EFI_INVALID_PARAMETER           Invalid parameter.
  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation.
                                          check carried out by the firmware.
  @return EFI_SUCCESS                     Variable passed validation successfully.

**/
EFI_STATUS
ProcessVarWithPk (
  IN  CHAR16    *VariableName,
  IN  EFI_GUID  *VendorGuid,
  IN  VOID      *Data,
  IN  UINTN     DataSize,
  IN  UINT32    Attributes OPTIONAL,
  IN  BOOLEAN   IsPk
  )
{
  EFI_STATUS  Status;
  BOOLEAN     Del;
  UINT8       *Payload;
  UINTN       PayloadSize;

  if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||
      ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0))
  {
    //
    // PK, KEK and db/dbx/dbt should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
    // authenticated variable.
    //
    return EFI_INVALID_PARAMETER;
  }

  //
  // Init state of Del. State may change due to secure check
  //
  Del = FALSE;
  if (  (InCustomMode () && UserPhysicalPresent ())
     || (  (mPlatformMode == SETUP_MODE)
        && !(FeaturePcdGet (PcdRequireSelfSignedPk) && IsPk)))
  {
    Payload     = (UINT8 *)Data + AUTHINFO2_SIZE (Data);
    PayloadSize = DataSize - AUTHINFO2_SIZE (Data);
    if (PayloadSize == 0) {
      Del = TRUE;
    }

    Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = AuthServiceInternalUpdateVariableWithTimeStamp (
               VariableName,
               VendorGuid,
               Payload,
               PayloadSize,
               Attributes,
               &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (  (mPlatformMode != SETUP_MODE)
       || (FeaturePcdGet (PcdRequireSelfSignedPk) && IsPk))
    {
      Status = VendorKeyIsModified ();
    }
  } else if (mPlatformMode == USER_MODE) {
    //
    // Verify against X509 Cert in PK database.
    //
    Status = VerifyTimeBasedPayloadAndUpdate (
               VariableName,
               VendorGuid,
               Data,
               DataSize,
               Attributes,
               AuthVarTypePk,
               &Del
               );
  } else {
    //
    // Verify against the certificate in data payload.
    //
    Status = VerifyTimeBasedPayloadAndUpdate (
               VariableName,
               VendorGuid,
               Data,
               DataSize,
               Attributes,
               AuthVarTypePayload,
               &Del
               );
  }

  if (!EFI_ERROR (Status) && IsPk) {
    if ((mPlatformMode == SETUP_MODE) && !Del) {
      //
      // If enroll PK in setup mode, need change to user mode.
      //
      Status = UpdatePlatformMode (USER_MODE);
    } else if ((mPlatformMode == USER_MODE) && Del) {
      //
      // If delete PK in user mode, need change to setup mode.
      //
      Status = UpdatePlatformMode (SETUP_MODE);
    }
  }

  return Status;
}

/**
  Process variable with key exchange key for verification.

  Caution: This function may receive untrusted input.
  This function may be invoked in SMM mode, and datasize and data are external input.
  This function will do basic validation, before parse the data.
  This function will parse the authentication carefully to avoid security issues, like
  buffer overflow, integer overflow.
  This function will check attribute carefully to avoid authentication bypass.

  @param[in]  VariableName                Name of Variable to be found.
  @param[in]  VendorGuid                  Variable vendor GUID.
  @param[in]  Data                        Data pointer.
  @param[in]  DataSize                    Size of Data found. If size is less than the
                                          data, this value contains the required size.
  @param[in]  Attributes                  Attribute value of the variable.

  @return EFI_INVALID_PARAMETER           Invalid parameter.
  @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
                                          check carried out by the firmware.
  @return EFI_SUCCESS                     Variable pass validation successfully.

**/
EFI_STATUS
ProcessVarWithKek (
  IN  CHAR16    *VariableName,
  IN  EFI_GUID  *VendorGuid,
  IN  VOID      *Data,
  IN  UINTN     DataSize,
  IN  UINT32    Attributes OPTIONAL
  )
{
  EFI_STATUS  Status;
  UINT8       *Payload;
  UINTN       PayloadSize;

  if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||
      ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0))
  {
    //
    // DB, DBX and DBT should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
    // authenticated variable.
    //
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_SUCCESS;
  if ((mPlatformMode == USER_MODE) && !(InCustomMode () && UserPhysicalPresent ())) {
    //
    // Time-based, verify against X509 Cert KEK.
    //
    return VerifyTimeBasedPayloadAndUpdate (
             VariableName,
             VendorGuid,
             Data,
             DataSize,
             Attributes,
             AuthVarTypeKek,
             NULL
             );
  } else {
    //
    // If in setup mode or custom secure boot mode, no authentication needed.
    //
    Payload     = (UINT8 *)Data + AUTHINFO2_SIZE (Data);
    PayloadSize = DataSize - AUTHINFO2_SIZE (Data);

    Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = AuthServiceInternalUpdateVariableWithTimeStamp (
               VariableName,
               VendorGuid,
               Payload,
               PayloadSize,
               Attributes,
               &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (mPlatformMode != SETUP_MODE) {
      Status = VendorKeyIsModified ();
    }
  }

  return Status;
}

/**
  Check if it is to delete auth variable.

  @param[in] OrgAttributes      Original attribute value of the variable.
  @param[in] Data               Data pointer.
  @param[in] DataSize           Size of Data.
  @param[in] Attributes         Attribute value of the variable.

  @retval TRUE                  It is to delete auth variable.
  @retval FALSE                 It is not to delete auth variable.

**/
BOOLEAN
IsDeleteAuthVariable (
  IN  UINT32  OrgAttributes,
  IN  VOID    *Data,
  IN  UINTN   DataSize,
  IN  UINT32  Attributes
  )
{
  BOOLEAN  Del;
  UINTN    PayloadSize;

  Del = FALSE;

  //
  // To delete a variable created with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
  // or the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute,
  // SetVariable must be used with attributes matching the existing variable
  // and the DataSize set to the size of the AuthInfo descriptor.
  //
  if ((Attributes == OrgAttributes) &&
      ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0))
  {
    if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
      PayloadSize = DataSize - AUTHINFO2_SIZE (Data);
      if (PayloadSize == 0) {
        Del = TRUE;
      }
    } else {
      PayloadSize = DataSize - AUTHINFO_SIZE;
      if (PayloadSize == 0) {
        Del = TRUE;
      }
    }
  }

  return Del;
}

/**
  Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set

  Caution: This function may receive untrusted input.
  This function may be invoked in SMM mode, and datasize and data are external input.
  This function will do basic validation, before parse the data.
  This function will parse the authentication carefully to avoid security issues, like
  buffer overflow, integer overflow.
  This function will check attribute carefully to avoid authentication bypass.

  @param[in]  VariableName                Name of the variable.
  @param[in]  VendorGuid                  Variable vendor GUID.
  @param[in]  Data                        Data pointer.
  @param[in]  DataSize                    Size of Data.
  @param[in]  Attributes                  Attribute value of the variable.

  @return EFI_INVALID_PARAMETER           Invalid parameter.
  @return EFI_WRITE_PROTECTED             Variable is write-protected and needs authentication with
                                          EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
  @return EFI_OUT_OF_RESOURCES            The Database to save the public key is full.
  @return EFI_SECURITY_VIOLATION          The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
                                          set, but the AuthInfo does NOT pass the validation
                                          check carried out by the firmware.
  @return EFI_SUCCESS                     Variable is not write-protected or pass validation successfully.

**/
EFI_STATUS
ProcessVariable (
  IN     CHAR16    *VariableName,
  IN     EFI_GUID  *VendorGuid,
  IN     VOID      *Data,
  IN     UINTN     DataSize,
  IN     UINT32    Attributes
  )
{
  EFI_STATUS          Status;
  AUTH_VARIABLE_INFO  OrgVariableInfo;

  Status = EFI_SUCCESS;

  ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));
  Status = mAuthVarLibContextIn->FindVariable (
                                   VariableName,
                                   VendorGuid,
                                   &OrgVariableInfo
                                   );

  // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.
  if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && (UserPhysicalPresent () || !IsVariablePolicyEnabled ())) {
    //
    // Allow the delete operation of common authenticated variable(AT or AW) at user physical presence.
    //
    Status = AuthServiceInternalUpdateVariable (
               VariableName,
               VendorGuid,
               NULL,
               0,
               0
               );
    if (!EFI_ERROR (Status) && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {
      Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);
    }

    return Status;
  }

  if (NeedPhysicallyPresent (VariableName, VendorGuid) && !UserPhysicalPresent ()) {
    //
    // This variable is protected, only physical present user could modify its value.
    //
    return EFI_SECURITY_VIOLATION;
  }

  //
  if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
    //
    // Reject Counter Based Auth Variable processing request.
    //
    return EFI_UNSUPPORTED;
  } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
    //
    // Process Time-based Authenticated variable.
    //
    return VerifyTimeBasedPayloadAndUpdate (
             VariableName,
             VendorGuid,
             Data,
             DataSize,
             Attributes,
             AuthVarTypePriv,
             NULL
             );
  }

  if ((OrgVariableInfo.Data != NULL) &&
      ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0))
  {
    //
    // If the variable is already write-protected, it always needs authentication before update.
    //
    return EFI_WRITE_PROTECTED;
  }

  //
  // Not authenticated variable, just update variable as usual.
  //
  Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);
  return Status;
}

/**
  Validate that an EFI_SIGNATURE_LIST can be traversed safely.

  This helper performs only the structural checks needed by FilterSignatureList()
  before walking list entries. Callers still perform the full semantic validation
  through CheckSignatureListFormat().

  @param[in]  SigList       Pointer to the EFI_SIGNATURE_LIST header.
  @param[in]  BufferSize    Bytes available starting at SigList.
  @param[out] SigCount      Number of signature entries in SigList.

  @retval EFI_SUCCESS            The signature list layout is self-consistent.
  @retval EFI_INVALID_PARAMETER  The signature list header is malformed.

**/
STATIC
EFI_STATUS
GetSignatureListEntryCount (
  IN  EFI_SIGNATURE_LIST  *SigList,
  IN  UINTN               BufferSize,
  OUT UINTN               *SigCount
  )
{
  UINTN  HeaderSize;
  UINTN  PayloadSize;

  if ((SigList == NULL) || (SigCount == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((BufferSize < sizeof (EFI_SIGNATURE_LIST)) ||
      (SigList->SignatureListSize < sizeof (EFI_SIGNATURE_LIST)) ||
      (SigList->SignatureListSize > BufferSize))
  {
    return EFI_INVALID_PARAMETER;
  }

  HeaderSize = sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize;
  if ((HeaderSize < sizeof (EFI_SIGNATURE_LIST)) || (HeaderSize > SigList->SignatureListSize)) {
    return EFI_INVALID_PARAMETER;
  }

  if (SigList->SignatureSize == 0) {
    return EFI_INVALID_PARAMETER;
  }

  PayloadSize = SigList->SignatureListSize - HeaderSize;
  if ((PayloadSize % SigList->SignatureSize) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  *SigCount = PayloadSize / SigList->SignatureSize;
  return EFI_SUCCESS;
}

/**
  Filter out the duplicated EFI_SIGNATURE_DATA from the new data by comparing to the original data.

  @param[in]        Data          Pointer to original EFI_SIGNATURE_LIST.
  @param[in]        DataSize      Size of Data buffer.
  @param[in, out]   NewData       Pointer to new EFI_SIGNATURE_LIST.
  @param[in, out]   NewDataSize   Size of NewData buffer.

  @retval EFI_SUCCESS            Duplicated signatures were filtered successfully.
  @retval EFI_INVALID_PARAMETER  Input signature list data is malformed.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate scratch buffer.

**/
EFI_STATUS
FilterSignatureList (
  IN     VOID   *Data,
  IN     UINTN  DataSize,
  IN OUT VOID   *NewData,
  IN OUT UINTN  *NewDataSize
  )
{
  EFI_SIGNATURE_LIST  *CertList;
  EFI_SIGNATURE_DATA  *Cert;
  UINTN               CertCount;
  EFI_SIGNATURE_LIST  *NewCertList;
  EFI_SIGNATURE_DATA  *NewCert;
  UINTN               NewCertCount;
  UINTN               Index;
  UINTN               Index2;
  UINTN               Size;
  UINT8               *Tail;
  UINTN               CopiedCount;
  UINTN               SignatureListSize;
  BOOLEAN             IsNewCert;
  UINT8               *TempData;
  UINTN               TempDataSize;
  EFI_STATUS          Status;

  if (*NewDataSize == 0) {
    return EFI_SUCCESS;
  }

  TempDataSize = *NewDataSize;
  Status       = mAuthVarLibContextIn->GetScratchBuffer (&TempDataSize, (VOID **)&TempData);
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  Tail = TempData;

  NewCertList = (EFI_SIGNATURE_LIST *)NewData;
  while (*NewDataSize > 0) {
    Status = GetSignatureListEntryCount (NewCertList, *NewDataSize, &NewCertCount);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    NewCert     = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);
    CopiedCount = 0;
    for (Index = 0; Index < NewCertCount; Index++) {
      IsNewCert = TRUE;

      Size     = DataSize;
      CertList = (EFI_SIGNATURE_LIST *)Data;
      while (Size > 0) {
        Status = GetSignatureListEntryCount (CertList, Size, &CertCount);
        if (EFI_ERROR (Status)) {
          return Status;
        }

        if (CompareGuid (&CertList->SignatureType, &NewCertList->SignatureType) &&
            (CertList->SignatureSize == NewCertList->SignatureSize))
        {
          Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
          for (Index2 = 0; Index2 < CertCount; Index2++) {
            //
            // Iterate each Signature Data in this Signature List.
            //
            if (CompareMem (NewCert, Cert, CertList->SignatureSize) == 0) {
              IsNewCert = FALSE;
              break;
            }

            Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
          }
        }

        if (!IsNewCert) {
          break;
        }

        Size    -= CertList->SignatureListSize;
        CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
      }

      if (IsNewCert) {
        //
        // New EFI_SIGNATURE_DATA, keep it.
        //
        if (CopiedCount == 0) {
          //
          // Copy EFI_SIGNATURE_LIST header for only once.
          //
          CopyMem (Tail, NewCertList, sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);
          Tail = Tail + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize;
        }

        CopyMem (Tail, NewCert, NewCertList->SignatureSize);
        Tail += NewCertList->SignatureSize;
        CopiedCount++;
      }

      NewCert = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCert + NewCertList->SignatureSize);
    }

    //
    // Update SignatureListSize in the kept EFI_SIGNATURE_LIST.
    //
    if (CopiedCount != 0) {
      SignatureListSize           = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);
      CertList                    = (EFI_SIGNATURE_LIST *)(Tail - SignatureListSize);
      CertList->SignatureListSize = (UINT32)SignatureListSize;
    }

    *NewDataSize -= NewCertList->SignatureListSize;
    NewCertList   = (EFI_SIGNATURE_LIST *)((UINT8 *)NewCertList + NewCertList->SignatureListSize);
  }

  TempDataSize = (Tail - (UINT8 *)TempData);

  CopyMem (NewData, TempData, TempDataSize);
  *NewDataSize = TempDataSize;

  return EFI_SUCCESS;
}

/**
  Compare two EFI_TIME data.


  @param FirstTime           A pointer to the first EFI_TIME data.
  @param SecondTime          A pointer to the second EFI_TIME data.

  @retval  TRUE              The FirstTime is not later than the SecondTime.
  @retval  FALSE             The FirstTime is later than the SecondTime.

**/
BOOLEAN
AuthServiceInternalCompareTimeStamp (
  IN EFI_TIME  *FirstTime,
  IN EFI_TIME  *SecondTime
  )
{
  if (FirstTime->Year != SecondTime->Year) {
    return (BOOLEAN)(FirstTime->Year < SecondTime->Year);
  } else if (FirstTime->Month != SecondTime->Month) {
    return (BOOLEAN)(FirstTime->Month < SecondTime->Month);
  } else if (FirstTime->Day != SecondTime->Day) {
    return (BOOLEAN)(FirstTime->Day < SecondTime->Day);
  } else if (FirstTime->Hour != SecondTime->Hour) {
    return (BOOLEAN)(FirstTime->Hour < SecondTime->Hour);
  } else if (FirstTime->Minute != SecondTime->Minute) {
    return (BOOLEAN)(FirstTime->Minute < SecondTime->Minute);
  }

  return (BOOLEAN)(FirstTime->Second <= SecondTime->Second);
}

/**
  Calculate SHA digest of SignerCert CommonName + ToplevelCert tbsCertificate.
  SignerCert and ToplevelCert are inside the signer certificate chain.

  @param[in]  HashAlgId           Hash algorithm index.
  @param[in]  SignerCert          A pointer to SignerCert data.
  @param[in]  SignerCertSize      Length of SignerCert data.
  @param[in]  TopLevelCert        A pointer to TopLevelCert data.
  @param[in]  TopLevelCertSize    Length of TopLevelCert data.
  @param[out] ShaDigest           Sha digest calculated.

  @return EFI_ABORTED          Digest process failed.
  @return EFI_SUCCESS          SHA Digest is successfully calculated.

**/
EFI_STATUS
CalculatePrivAuthVarSignChainSHADigest (
  IN     UINT8  HashAlgId,
  IN     UINT8  *SignerCert,
  IN     UINTN  SignerCertSize,
  IN     UINT8  *TopLevelCert,
  IN     UINTN  TopLevelCertSize,
  OUT    UINT8  *ShaDigest
  )
{
  UINT8       *TbsCert;
  UINTN       TbsCertSize;
  CHAR8       CertCommonName[128];
  UINTN       CertCommonNameSize;
  BOOLEAN     CryptoStatus;
  EFI_STATUS  Status;

  if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
    DEBUG ((DEBUG_INFO, "%a Unsupported Hash Algorithm %d\n", __func__, HashAlgId));
    return EFI_ABORTED;
  }

  CertCommonNameSize = sizeof (CertCommonName);

  //
  // Get SignerCert CommonName
  //
  Status = X509GetCommonName (SignerCert, SignerCertSize, CertCommonName, &CertCommonNameSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with status %x\n", __func__, Status));
    return EFI_ABORTED;
  }

  //
  // Get TopLevelCert tbsCertificate
  //
  if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert, &TbsCertSize)) {
    DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n", __func__));
    return EFI_ABORTED;
  }

  //
  // Digest SignerCert CN + TopLevelCert tbsCertificate
  //
  ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);
  CryptoStatus = mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashShaCtx));
  if (!CryptoStatus) {
    return EFI_ABORTED;
  }

  //
  // '\0' is forced in CertCommonName. No overflow issue
  //
  CryptoStatus = mHashInfo[HashAlgId].Update (
                                        *(mHashInfo[HashAlgId].HashShaCtx),
                                        CertCommonName,
                                        AsciiStrLen (CertCommonName)
                                        );
  if (!CryptoStatus) {
    return EFI_ABORTED;
  }

  CryptoStatus = mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].HashShaCtx), TbsCert, TbsCertSize);
  if (!CryptoStatus) {
    return EFI_ABORTED;
  }

  CryptoStatus = mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].HashShaCtx), ShaDigest);
  if (!CryptoStatus) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Find matching signer's certificates for common authenticated variable
  by corresponding VariableName and VendorGuid from "certdb" or "certdbv".

  The data format of "certdb" or "certdbv":
  //
  //     UINT32 CertDbListSize;
  // /// AUTH_CERT_DB_DATA Certs1[];
  // /// AUTH_CERT_DB_DATA Certs2[];
  // /// ...
  // /// AUTH_CERT_DB_DATA Certsn[];
  //

  @param[in]  VariableName   Name of authenticated Variable.
  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.
  @param[in]  Data           Pointer to variable "certdb" or "certdbv".
  @param[in]  DataSize       Size of variable "certdb" or "certdbv".
  @param[out] CertOffset     Offset of matching CertData, from starting of Data.
  @param[out] CertDataSize   Length of CertData in bytes.
  @param[out] CertNodeOffset Offset of matching AUTH_CERT_DB_DATA , from
                             starting of Data.
  @param[out] CertNodeSize   Length of AUTH_CERT_DB_DATA in bytes.

  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
  @retval  EFI_NOT_FOUND         Fail to find matching certs.
  @retval  EFI_SUCCESS           Find matching certs and output parameters.

**/
EFI_STATUS
FindCertsFromDb (
  IN     CHAR16    *VariableName,
  IN     EFI_GUID  *VendorGuid,
  IN     UINT8     *Data,
  IN     UINTN     DataSize,
  OUT    UINT32    *CertOffset     OPTIONAL,
  OUT    UINT32    *CertDataSize   OPTIONAL,
  OUT    UINT32    *CertNodeOffset OPTIONAL,
  OUT    UINT32    *CertNodeSize   OPTIONAL
  )
{
  UINT32             Offset;
  AUTH_CERT_DB_DATA  *Ptr;
  UINT32             CertSize;
  UINT32             NameSize;
  UINT32             NodeSize;
  UINT32             CertDbListSize;

  if ((VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check whether DataSize matches recorded CertDbListSize.
  //
  if (DataSize < sizeof (UINT32)) {
    return EFI_INVALID_PARAMETER;
  }

  CertDbListSize = ReadUnaligned32 ((UINT32 *)Data);

  if (CertDbListSize != (UINT32)DataSize) {
    return EFI_INVALID_PARAMETER;
  }

  Offset = sizeof (UINT32);

  //
  // Get corresponding certificates by VendorGuid and VariableName.
  //
  while (Offset < (UINT32)DataSize) {
    Ptr = (AUTH_CERT_DB_DATA *)(Data + Offset);
    //
    // Check whether VendorGuid matches.
    //
    if (CompareGuid (&Ptr->VendorGuid, VendorGuid)) {
      NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);
      NameSize = ReadUnaligned32 (&Ptr->NameSize);
      CertSize = ReadUnaligned32 (&Ptr->CertDataSize);

      if (NodeSize != sizeof (EFI_GUID) + sizeof (UINT32) * 3 + CertSize +
          sizeof (CHAR16) * NameSize)
      {
        return EFI_INVALID_PARAMETER;
      }

      Offset = Offset + sizeof (EFI_GUID) + sizeof (UINT32) * 3;
      //
      // Check whether VariableName matches.
      //
      if ((NameSize == StrLen (VariableName)) &&
          (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0))
      {
        Offset = Offset + NameSize * sizeof (CHAR16);

        if (CertOffset != NULL) {
          *CertOffset = Offset;
        }

        if (CertDataSize != NULL) {
          *CertDataSize = CertSize;
        }

        if (CertNodeOffset != NULL) {
          *CertNodeOffset = (UINT32)((UINT8 *)Ptr - Data);
        }

        if (CertNodeSize != NULL) {
          *CertNodeSize = NodeSize;
        }

        return EFI_SUCCESS;
      } else {
        Offset = Offset + NameSize * sizeof (CHAR16) + CertSize;
      }
    } else {
      NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);
      Offset   = Offset + NodeSize;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Retrieve signer's certificates for common authenticated variable
  by corresponding VariableName and VendorGuid from "certdb"
  or "certdbv" according to authenticated variable attributes.

  @param[in]  VariableName   Name of authenticated Variable.
  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.
  @param[in]  Attributes        Attributes of authenticated variable.
  @param[out] CertData       Pointer to signer's certificates.
  @param[out] CertDataSize   Length of CertData in bytes.

  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
  @retval  EFI_NOT_FOUND         Fail to find "certdb"/"certdbv" or matching certs.
  @retval  EFI_SUCCESS           Get signer's certificates successfully.

**/
EFI_STATUS
GetCertsFromDb (
  IN     CHAR16    *VariableName,
  IN     EFI_GUID  *VendorGuid,
  IN     UINT32    Attributes,
  OUT    UINT8     **CertData,
  OUT    UINT32    *CertDataSize
  )
{
  EFI_STATUS  Status;
  UINT8       *Data;
  UINTN       DataSize;
  UINT32      CertOffset;
  CHAR16      *DbName;

  if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL) || (CertDataSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
    //
    // Get variable "certdb".
    //
    DbName = EFI_CERT_DB_NAME;
  } else {
    //
    // Get variable "certdbv".
    //
    DbName = EFI_CERT_DB_VOLATILE_NAME;
  }

  //
  // Get variable "certdb" or "certdbv".
  //
  Status = AuthServiceInternalFindVariable (
             DbName,
             &gEfiCertDbGuid,
             (VOID **)&Data,
             &DataSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((DataSize == 0) || (Data == NULL)) {
    ASSERT (FALSE);
    return EFI_NOT_FOUND;
  }

  Status = FindCertsFromDb (
             VariableName,
             VendorGuid,
             Data,
             DataSize,
             &CertOffset,
             CertDataSize,
             NULL,
             NULL
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  *CertData = Data + CertOffset;
  return EFI_SUCCESS;
}

/**
  Delete matching signer's certificates when deleting common authenticated
  variable by corresponding VariableName and VendorGuid from "certdb" or
  "certdbv" according to authenticated variable attributes.

  @param[in]  VariableName   Name of authenticated Variable.
  @param[in]  VendorGuid     Vendor GUID of authenticated Variable.
  @param[in]  Attributes        Attributes of authenticated variable.

  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
  @retval  EFI_NOT_FOUND         Fail to find "certdb"/"certdbv" or matching certs.
  @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.
  @retval  EFI_SUCCESS           The operation is completed successfully.

**/
EFI_STATUS
DeleteCertsFromDb (
  IN     CHAR16    *VariableName,
  IN     EFI_GUID  *VendorGuid,
  IN     UINT32    Attributes
  )
{
  EFI_STATUS  Status;
  UINT8       *Data;
  UINTN       DataSize;
  UINT32      VarAttr;
  UINT32      CertNodeOffset;
  UINT32      CertNodeSize;
  UINT8       *NewCertDb;
  UINT32      NewCertDbSize;
  CHAR16      *DbName;

  if ((VariableName == NULL) || (VendorGuid == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
    //
    // Get variable "certdb".
    //
    DbName  = EFI_CERT_DB_NAME;
    VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  } else {
    //
    // Get variable "certdbv".
    //
    DbName  = EFI_CERT_DB_VOLATILE_NAME;
    VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  }

  Status = AuthServiceInternalFindVariable (
             DbName,
             &gEfiCertDbGuid,
             (VOID **)&Data,
             &DataSize
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((DataSize == 0) || (Data == NULL)) {
    ASSERT (FALSE);
    return EFI_NOT_FOUND;
  }

  if (DataSize == sizeof (UINT32)) {
    //
    // There is no certs in "certdb" or "certdbv".
    //
    return EFI_SUCCESS;
  }

  //
  // Get corresponding cert node from "certdb" or "certdbv".
  //
  Status = FindCertsFromDb (
             VariableName,
             VendorGuid,
             Data,
             DataSize,
             NULL,
             NULL,
             &CertNodeOffset,
             &CertNodeSize
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (DataSize < (CertNodeOffset + CertNodeSize)) {
    return EFI_NOT_FOUND;
  }

  //
  // Construct new data content of variable "certdb" or "certdbv".
  //
  NewCertDbSize = (UINT32)DataSize - CertNodeSize;
  NewCertDb     = (UINT8 *)mCertDbStore;

  //
  // Copy the DB entries before deleting node.
  //
  CopyMem (NewCertDb, Data, CertNodeOffset);
  //
  // Update CertDbListSize.
  //
  CopyMem (NewCertDb, &NewCertDbSize, sizeof (UINT32));
  //
  // Copy the DB entries after deleting node.
  //
  if (DataSize > (CertNodeOffset + CertNodeSize)) {
    CopyMem (
      NewCertDb + CertNodeOffset,
      Data + CertNodeOffset + CertNodeSize,
      DataSize - CertNodeOffset - CertNodeSize
      );
  }

  //
  // Set "certdb" or "certdbv".
  //
  Status = AuthServiceInternalUpdateVariable (
             DbName,
             &gEfiCertDbGuid,
             NewCertDb,
             NewCertDbSize,
             VarAttr
             );

  return Status;
}

/**
  Insert signer's certificates for common authenticated variable with VariableName
  and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to
  time based authenticated variable attributes. CertData is the SHA digest of
  SignerCert CommonName + TopLevelCert tbsCertificate.

  @param[in]  HashAlgId         Hash algorithm index.
  @param[in]  VariableName      Name of authenticated Variable.
  @param[in]  VendorGuid        Vendor GUID of authenticated Variable.
  @param[in]  Attributes        Attributes of authenticated variable.
  @param[in]  SignerCert        Signer certificate data.
  @param[in]  SignerCertSize    Length of signer certificate.
  @param[in]  TopLevelCert      Top-level certificate data.
  @param[in]  TopLevelCertSize  Length of top-level certificate.

  @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
  @retval  EFI_ACCESS_DENIED     An AUTH_CERT_DB_DATA entry with same VariableName
                                 and VendorGuid already exists.
  @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.
  @retval  EFI_SUCCESS           Insert an AUTH_CERT_DB_DATA entry to "certdb" or "certdbv"

**/
EFI_STATUS
InsertCertsToDb (
  IN     UINT8     HashAlgId,
  IN     CHAR16    *VariableName,
  IN     EFI_GUID  *VendorGuid,
  IN     UINT32    Attributes,
  IN     UINT8     *SignerCert,
  IN     UINTN     SignerCertSize,
  IN     UINT8     *TopLevelCert,
  IN     UINTN     TopLevelCertSize
  )
{
  EFI_STATUS         Status;
  UINT8              *Data;
  UINTN              DataSize;
  UINT32             VarAttr;
  UINT8              *NewCertDb;
  UINT32             NewCertDbSize;
  UINT32             CertNodeSize;
  UINT32             NameSize;
  UINT32             CertDataSize;
  AUTH_CERT_DB_DATA  *Ptr;
  CHAR16             *DbName;
  UINT8              ShaDigest[SHA_DIGEST_SIZE_MAX];

  if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
    //
    // Get variable "certdb".
    //
    DbName  = EFI_CERT_DB_NAME;
    VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  } else {
    //
    // Get variable "certdbv".
    //
    DbName  = EFI_CERT_DB_VOLATILE_NAME;
    VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  }

  //
  // Get variable "certdb" or "certdbv".
  //
  Status = AuthServiceInternalFindVariable (
             DbName,
             &gEfiCertDbGuid,
             (VOID **)&Data,
             &DataSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((DataSize == 0) || (Data == NULL)) {
    ASSERT (FALSE);
    return EFI_NOT_FOUND;
  }

  //
  // Find whether matching cert node already exists in "certdb" or "certdbv".
  // If yes return error.
  //
  Status = FindCertsFromDb (
             VariableName,
             VendorGuid,
             Data,
             DataSize,
             NULL,
             NULL,
             NULL,
             NULL
             );

  if (!EFI_ERROR (Status)) {
    ASSERT (FALSE);
    return EFI_ACCESS_DENIED;
  }

  //
  // Construct new data content of variable "certdb" or "certdbv".
  //
  NameSize      = (UINT32)StrLen (VariableName);
  CertDataSize  = mHashInfo[HashAlgId].HashSize;
  CertNodeSize  = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);
  NewCertDbSize = (UINT32)DataSize + CertNodeSize;
  if (NewCertDbSize > mMaxCertDbSize) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = CalculatePrivAuthVarSignChainSHADigest (
             HashAlgId,
             SignerCert,
             SignerCertSize,
             TopLevelCert,
             TopLevelCertSize,
             ShaDigest
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  NewCertDb = (UINT8 *)mCertDbStore;

  //
  // Copy the DB entries before inserting node.
  //
  CopyMem (NewCertDb, Data, DataSize);
  //
  // Update CertDbListSize.
  //
  CopyMem (NewCertDb, &NewCertDbSize, sizeof (UINT32));
  //
  // Construct new cert node.
  //
  Ptr = (AUTH_CERT_DB_DATA *)(NewCertDb + DataSize);
  CopyGuid (&Ptr->VendorGuid, VendorGuid);
  CopyMem (&Ptr->CertNodeSize, &CertNodeSize, sizeof (UINT32));
  CopyMem (&Ptr->NameSize, &NameSize, sizeof (UINT32));
  CopyMem (&Ptr->CertDataSize, &CertDataSize, sizeof (UINT32));

  CopyMem (
    (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA),
    VariableName,
    NameSize * sizeof (CHAR16)
    );

  CopyMem (
    (UINT8 *)Ptr +  sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
    ShaDigest,
    CertDataSize
    );

  //
  // Set "certdb" or "certdbv".
  //
  Status = AuthServiceInternalUpdateVariable (
             DbName,
             &gEfiCertDbGuid,
             NewCertDb,
             NewCertDbSize,
             VarAttr
             );

  return Status;
}

/**
  Clean up signer's certificates for common authenticated variable
  by corresponding VariableName and VendorGuid from "certdb".
  System may break down during Timebased Variable update & certdb update,
  make them inconsistent,  this function is called in AuthVariable Init
  to ensure consistency.

  @retval  EFI_NOT_FOUND         Fail to find variable "certdb".
  @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.
  @retval  EFI_SUCCESS           The operation is completed successfully.

**/
EFI_STATUS
CleanCertsFromDb (
  VOID
  )
{
  UINT32              Offset;
  AUTH_CERT_DB_DATA   *Ptr;
  UINT32              NameSize;
  UINT32              NodeSize;
  CHAR16              *VariableName;
  EFI_STATUS          Status;
  BOOLEAN             CertCleaned;
  UINT8               *Data;
  UINTN               DataSize;
  EFI_GUID            AuthVarGuid;
  AUTH_VARIABLE_INFO  AuthVariableInfo;

  Status = EFI_SUCCESS;

  //
  // Get corresponding certificates by VendorGuid and VariableName.
  //
  do {
    CertCleaned = FALSE;

    //
    // Get latest variable "certdb"
    //
    Status = AuthServiceInternalFindVariable (
               EFI_CERT_DB_NAME,
               &gEfiCertDbGuid,
               (VOID **)&Data,
               &DataSize
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if ((DataSize == 0) || (Data == NULL)) {
      ASSERT (FALSE);
      return EFI_NOT_FOUND;
    }

    Offset = sizeof (UINT32);

    while (Offset < (UINT32)DataSize) {
      Ptr      = (AUTH_CERT_DB_DATA *)(Data + Offset);
      NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);
      NameSize = ReadUnaligned32 (&Ptr->NameSize);

      //
      // Get VarName tailed with '\0'
      //
      VariableName = AllocateZeroPool ((NameSize + 1) * sizeof (CHAR16));
      if (VariableName == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (VariableName, (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof (CHAR16));
      //
      // Keep VarGuid  aligned
      //
      CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof (EFI_GUID));

      //
      // Find corresponding time auth variable
      //
      ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
      Status = mAuthVarLibContextIn->FindVariable (
                                       VariableName,
                                       &AuthVarGuid,
                                       &AuthVariableInfo
                                       );

      if (EFI_ERROR (Status) || ((AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0)) {
        //
        // While cleaning certdb, always delete the variable in certdb regardless of it attributes.
        //
        Status = DeleteCertsFromDb (
                   VariableName,
                   &AuthVarGuid,
                   AuthVariableInfo.Attributes | EFI_VARIABLE_NON_VOLATILE
                   );
        CertCleaned = TRUE;
        DEBUG ((DEBUG_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));
        FreePool (VariableName);
        break;
      }

      FreePool (VariableName);
      Offset = Offset + NodeSize;
    }
  } while (CertCleaned);

  return Status;
}

/**
  Find hash algorithm index.

  @param[in]  SigData      Pointer to the PKCS#7 message.
  @param[in]  SigDataSize  Length of the PKCS#7 message.

  @retval UINT8        Hash Algorithm Index.
**/
UINT8
FindHashAlgorithmIndex (
  IN     UINT8   *SigData,
  IN     UINT32  SigDataSize
  )
{
  UINT8  i;

  for (i = 0; i < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO)); i++) {
    if (  (  (SigDataSize >= (13 + mHashInfo[i].OidLength))
          && (  ((*(SigData + 1) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
             && (CompareMem (SigData + 13, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0)))
       || (  ((SigDataSize >= (32 +  mHashInfo[i].OidLength)))
          && (  ((*(SigData + 20) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
             && (CompareMem (SigData + 32, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0))))
    {
      break;
    }
  }

  return i;
}

/**
  Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set

  Caution: This function may receive untrusted input.
  This function may be invoked in SMM mode, and datasize and data are external input.
  This function will do basic validation, before parse the data.
  This function will parse the authentication carefully to avoid security issues, like
  buffer overflow, integer overflow.

  @param[in]  VariableName                Name of Variable to be found.
  @param[in]  VendorGuid                  Variable vendor GUID.
  @param[in]  Data                        Data pointer.
  @param[in]  DataSize                    Size of Data found. If size is less than the
                                          data, this value contains the required size.
  @param[in]  Attributes                  Attribute value of the variable.
  @param[in]  AuthVarType                 Verify against PK, KEK database, private database or certificate in data payload.
  @param[in]  OrgTimeStamp                Pointer to original time stamp,
                                          original variable is not found if NULL.
  @param[out]  VarPayloadPtr              Pointer to variable payload address.
  @param[out]  VarPayloadSize             Pointer to variable payload size.

  @retval EFI_INVALID_PARAMETER           Invalid parameter.
  @retval EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
                                          check carried out by the firmware.
  @retval EFI_OUT_OF_RESOURCES            Failed to process variable due to lack
                                          of resources.
  @retval EFI_SUCCESS                     Variable pass validation successfully.

**/
EFI_STATUS
VerifyTimeBasedPayload (
  IN     CHAR16        *VariableName,
  IN     EFI_GUID      *VendorGuid,
  IN     VOID          *Data,
  IN     UINTN         DataSize,
  IN     UINT32        Attributes,
  IN     AUTHVAR_TYPE  AuthVarType,
  IN     EFI_TIME      *OrgTimeStamp,
  OUT    UINT8         **VarPayloadPtr,
  OUT    UINTN         *VarPayloadSize
  )
{
  EFI_VARIABLE_AUTHENTICATION_2  *CertData;
  UINT8                          *SigData;
  UINT32                         SigDataSize;
  UINT8                          *PayloadPtr;
  UINTN                          PayloadSize;
  UINT32                         Attr;
  BOOLEAN                        VerifyStatus;
  EFI_STATUS                     Status;
  EFI_SIGNATURE_LIST             *CertList;
  EFI_SIGNATURE_DATA             *Cert;
  UINTN                          Index;
  UINTN                          CertCount;
  UINT32                         KekDataSize;
  UINT8                          *NewData;
  UINTN                          NewDataSize;
  UINT8                          *Buffer;
  UINTN                          Length;
  UINT8                          *TopLevelCert;
  UINTN                          TopLevelCertSize;
  UINT8                          *TrustedCert;
  UINTN                          TrustedCertSize;
  UINT8                          *SignerCerts;
  UINTN                          CertStackSize;
  UINT8                          *CertsInCertDb;
  UINT32                         CertsSizeinDb;
  UINT8                          ShaDigest[SHA_DIGEST_SIZE_MAX];
  EFI_CERT_DATA                  *CertDataPtr;
  UINT8                          HashAlgId;

  //
  // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain
  // 2. TrustedCert is the certificate which firmware trusts. It could be saved in protected
  //     storage or PK payload on PK init
  //
  VerifyStatus  = FALSE;
  CertData      = NULL;
  NewData       = NULL;
  Attr          = Attributes;
  SignerCerts   = NULL;
  TopLevelCert  = NULL;
  CertsInCertDb = NULL;
  CertDataPtr   = NULL;

  //
  // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
  // set, then the Data buffer shall begin with an instance of a complete (and serialized)
  // EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
  // variable value and DataSize shall reflect the combined size of the descriptor and the new
  // variable value. The authentication descriptor is not part of the variable data and is not
  // returned by subsequent calls to GetVariable().
  //
  CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;

  //
  // Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the
  // TimeStamp value are set to zero.
  //
  if ((CertData->TimeStamp.Pad1 != 0) ||
      (CertData->TimeStamp.Nanosecond != 0) ||
      (CertData->TimeStamp.TimeZone != 0) ||
      (CertData->TimeStamp.Daylight != 0) ||
      (CertData->TimeStamp.Pad2 != 0))
  {
    return EFI_SECURITY_VIOLATION;
  }

  if ((OrgTimeStamp != NULL) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {
    if (AuthServiceInternalCompareTimeStamp (&CertData->TimeStamp, OrgTimeStamp)) {
      //
      // TimeStamp check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
      //
      return EFI_SECURITY_VIOLATION;
    }
  }

  //
  // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
  // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.
  //
  if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
      !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid))
  {
    //
    // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
    //
    return EFI_SECURITY_VIOLATION;
  }

  //
  // Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
  // AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.
  //
  SigData     = CertData->AuthInfo.CertData;
  SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32)(OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));

  //
  // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the
  // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is accepted.
  //
  //    According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
  //        SignedData ::= SEQUENCE {
  //            version Version,
  //            digestAlgorithms DigestAlgorithmIdentifiers,
  //            contentInfo ContentInfo,
  //            .... }
  //    The DigestAlgorithmIdentifiers can be used to determine the hash algorithm
  //    in VARIABLE_AUTHENTICATION_2 descriptor.
  //    This field has the fixed offset (+13) or (+32) based on whether the DER-encoded
  //    ContentInfo structure is present or not, and can be calculated based on two
  //    bytes of length encoding.
  //
  //    Both condition can be handled in WrapPkcs7Data() in CryptPkcs7VerifyCommon.c.
  //
  //    See below examples:
  //
  // 1. Without ContentInfo
  //    30 82 0c da // SEQUENCE (5 element) (3294 BYTES) -- SignedData
  //       02 01 01 // INTEGER 1 -- Version
  //       31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers
  //          30 0d // SEQUENCE (2 element) (13 BYTES) -- AlgorithmIdentifier
  //             06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm
  //                60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]
  //             05 00 // NULL (0 BYTES) -- parameters
  //
  // Example from: https://uefi.org/revocationlistfile
  //
  // 2. With ContentInfo
  //    30 82 05 90 // SEQUENCE (1424 BYTES) -- ContentInfo
  //       06 09 // OBJECT-IDENTIFIER (9 BYTES) -- ContentType
  //          2a 86 48 86 f7 0d 01 07 02 // signedData [1.2.840.113549.1.7.2]
  //       a0 82 05 81 // CONTEXT-SPECIFIC CONSTRUCTED TAG 0 (1409 BYTES) -- content
  //          30 82 05 7d // SEQUENCE (1405 BYTES) -- SignedData
  //             02 01 01 // INTEGER 1 -- Version
  //             31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers
  //                30 0d // SEQUENCE (13 BYTES) -- AlgorithmIdentifier
  //                   06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm
  //                      60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]
  //                   05 00 // NULL (0 BYTES) -- parameters
  //
  // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process
  //
  HashAlgId = FindHashAlgorithmIndex (SigData, SigDataSize);
  if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
    if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
      return EFI_SECURITY_VIOLATION;
    }
  }

  //
  // Find out the new data payload which follows Pkcs7 SignedData directly.
  //
  PayloadPtr  = SigData + SigDataSize;
  PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN)SigDataSize;

  // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.
  if ((PayloadSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && !IsVariablePolicyEnabled ()) {
    VerifyStatus = TRUE;
    goto Exit;
  }

  //
  // Construct a serialization buffer of the values of the VariableName, VendorGuid and Attributes
  // parameters of the SetVariable() call and the TimeStamp component of the
  // EFI_VARIABLE_AUTHENTICATION_2 descriptor followed by the variable's new value
  // i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data)
  //
  NewDataSize = PayloadSize + sizeof (EFI_TIME) + sizeof (UINT32) +
                sizeof (EFI_GUID) + StrSize (VariableName) - sizeof (CHAR16);

  //
  // Here is to reuse scratch data area(at the end of volatile variable store)
  // to reduce SMRAM consumption for SMM variable driver.
  // The scratch buffer is enough to hold the serialized data and safe to use,
  // because it is only used at here to do verification temporarily first
  // and then used in UpdateVariable() for a time based auth variable set.
  //
  Status = mAuthVarLibContextIn->GetScratchBuffer (&NewDataSize, (VOID **)&NewData);
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  Buffer = NewData;
  Length = StrLen (VariableName) * sizeof (CHAR16);
  CopyMem (Buffer, VariableName, Length);
  Buffer += Length;

  Length = sizeof (EFI_GUID);
  CopyMem (Buffer, VendorGuid, Length);
  Buffer += Length;

  Length = sizeof (UINT32);
  CopyMem (Buffer, &Attr, Length);
  Buffer += Length;

  Length = sizeof (EFI_TIME);
  CopyMem (Buffer, &CertData->TimeStamp, Length);
  Buffer += Length;

  CopyMem (Buffer, PayloadPtr, PayloadSize);

  if (AuthVarType == AuthVarTypePk) {
    //
    // Verify that the signature has been made with the current Platform Key (no chaining for PK).
    // First, get signer's certificates from SignedData.
    //
    VerifyStatus = Pkcs7GetSigners (
                     SigData,
                     SigDataSize,
                     &SignerCerts,
                     &CertStackSize,
                     &TopLevelCert,
                     &TopLevelCertSize
                     );
    if (!VerifyStatus) {
      goto Exit;
    }

    //
    // Second, get the current platform key from variable. Check whether it's identical with signer's certificates
    // in SignedData. If not, return error immediately.
    //
    Status = AuthServiceInternalFindVariable (
               EFI_PLATFORM_KEY_NAME,
               &gEfiGlobalVariableGuid,
               &Data,
               &DataSize
               );
    if (EFI_ERROR (Status)) {
      VerifyStatus = FALSE;
      goto Exit;
    }

    CertList = (EFI_SIGNATURE_LIST *)Data;
    Cert     = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
    if ((TopLevelCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||
        (CompareMem (Cert->SignatureData, TopLevelCert, TopLevelCertSize) != 0))
    {
      VerifyStatus = FALSE;
      goto Exit;
    }

    //
    // Verify Pkcs7 SignedData via Pkcs7Verify library.
    //
    VerifyStatus = Pkcs7Verify (
                     SigData,
                     SigDataSize,
                     TopLevelCert,
                     TopLevelCertSize,
                     NewData,
                     NewDataSize
                     );
  } else if (AuthVarType == AuthVarTypeKek) {
    //
    // Get KEK database from variable.
    //
    Status = AuthServiceInternalFindVariable (
               EFI_KEY_EXCHANGE_KEY_NAME,
               &gEfiGlobalVariableGuid,
               &Data,
               &DataSize
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.
    //
    KekDataSize = (UINT32)DataSize;
    CertList    = (EFI_SIGNATURE_LIST *)Data;
    while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
      if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
        Cert      = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
        CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
        for (Index = 0; Index < CertCount; Index++) {
          //
          // Iterate each Signature Data Node within this CertList for a verify
          //
          TrustedCert     = Cert->SignatureData;
          TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);

          //
          // Verify Pkcs7 SignedData via Pkcs7Verify library.
          //
          VerifyStatus = Pkcs7Verify (
                           SigData,
                           SigDataSize,
                           TrustedCert,
                           TrustedCertSize,
                           NewData,
                           NewDataSize
                           );
          if (VerifyStatus) {
            goto Exit;
          }

          Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
        }
      }

      KekDataSize -= CertList->SignatureListSize;
      CertList     = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
    }
  } else if (AuthVarType == AuthVarTypePriv) {
    //
    // Process common authenticated variable except PK/KEK/DB/DBX/DBT.
    // Get signer's certificates from SignedData.
    //
    VerifyStatus = Pkcs7GetSigners (
                     SigData,
                     SigDataSize,
                     &SignerCerts,
                     &CertStackSize,
                     &TopLevelCert,
                     &TopLevelCertSize
                     );
    if (!VerifyStatus) {
      goto Exit;
    }

    //
    // Get previously stored signer's certificates from certdb or certdbv for existing
    // variable. Check whether they are identical with signer's certificates
    // in SignedData. If not, return error immediately.
    //
    if (OrgTimeStamp != NULL) {
      VerifyStatus = FALSE;

      Status = GetCertsFromDb (VariableName, VendorGuid, Attributes, &CertsInCertDb, &CertsSizeinDb);
      if (EFI_ERROR (Status)) {
        goto Exit;
      }

      if ((HashAlgId < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) && (CertsSizeinDb == mHashInfo[HashAlgId].HashSize)) {
        //
        // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
        //
        CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
        Status      = CalculatePrivAuthVarSignChainSHADigest (
                        HashAlgId,
                        CertDataPtr->CertDataBuffer,
                        ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
                        TopLevelCert,
                        TopLevelCertSize,
                        ShaDigest
                        );
        if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
          goto Exit;
        }
      } else {
        //
        // Keep backward compatible with previous solution which saves whole signer certs stack in CertDb
        //
        if ((CertStackSize != CertsSizeinDb) ||
            (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0))
        {
          goto Exit;
        }
      }
    }

    VerifyStatus = Pkcs7Verify (
                     SigData,
                     SigDataSize,
                     TopLevelCert,
                     TopLevelCertSize,
                     NewData,
                     NewDataSize
                     );
    if (!VerifyStatus) {
      goto Exit;
    }

    if ((OrgTimeStamp == NULL) && (PayloadSize != 0)) {
      //
      // When adding a new common authenticated variable, always save Hash of cn of signer cert + tbsCertificate of Top-level issuer
      //
      CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
      Status      = InsertCertsToDb (
                      HashAlgId,
                      VariableName,
                      VendorGuid,
                      Attributes,
                      CertDataPtr->CertDataBuffer,
                      ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
                      TopLevelCert,
                      TopLevelCertSize
                      );
      if (EFI_ERROR (Status)) {
        VerifyStatus = FALSE;
        goto Exit;
      }
    }
  } else if (AuthVarType == AuthVarTypePayload) {
    CertList        = (EFI_SIGNATURE_LIST *)PayloadPtr;
    Cert            = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
    TrustedCert     = Cert->SignatureData;
    TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);
    //
    // Verify Pkcs7 SignedData via Pkcs7Verify library.
    //
    VerifyStatus = Pkcs7Verify (
                     SigData,
                     SigDataSize,
                     TrustedCert,
                     TrustedCertSize,
                     NewData,
                     NewDataSize
                     );
  } else {
    return EFI_SECURITY_VIOLATION;
  }

Exit:

  if ((AuthVarType == AuthVarTypePk) || (AuthVarType == AuthVarTypePriv)) {
    if (TopLevelCert != NULL) {
      Pkcs7FreeSigners (TopLevelCert);
    }

    if (SignerCerts != NULL) {
      Pkcs7FreeSigners (SignerCerts);
    }
  }

  if (!VerifyStatus) {
    return EFI_SECURITY_VIOLATION;
  }

  Status = CheckSignatureListFormat (VariableName, VendorGuid, PayloadPtr, PayloadSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *VarPayloadPtr  = PayloadPtr;
  *VarPayloadSize = PayloadSize;

  return EFI_SUCCESS;
}

/**
  Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set

  Caution: This function may receive untrusted input.
  This function may be invoked in SMM mode, and datasize and data are external input.
  This function will do basic validation, before parse the data.
  This function will parse the authentication carefully to avoid security issues, like
  buffer overflow, integer overflow.

  @param[in]  VariableName                Name of Variable to be found.
  @param[in]  VendorGuid                  Variable vendor GUID.
  @param[in]  Data                        Data pointer.
  @param[in]  DataSize                    Size of Data found. If size is less than the
                                          data, this value contains the required size.
  @param[in]  Attributes                  Attribute value of the variable.
  @param[in]  AuthVarType                 Verify against PK, KEK database, private database or certificate in data payload.
  @param[out] VarDel                      Delete the variable or not.

  @retval EFI_INVALID_PARAMETER           Invalid parameter.
  @retval EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
                                          check carried out by the firmware.
  @retval EFI_OUT_OF_RESOURCES            Failed to process variable due to lack
                                          of resources.
  @retval EFI_SUCCESS                     Variable pass validation successfully.

**/
EFI_STATUS
VerifyTimeBasedPayloadAndUpdate (
  IN     CHAR16        *VariableName,
  IN     EFI_GUID      *VendorGuid,
  IN     VOID          *Data,
  IN     UINTN         DataSize,
  IN     UINT32        Attributes,
  IN     AUTHVAR_TYPE  AuthVarType,
  OUT    BOOLEAN       *VarDel
  )
{
  EFI_STATUS                     Status;
  EFI_STATUS                     FindStatus;
  UINT8                          *PayloadPtr;
  UINTN                          PayloadSize;
  EFI_VARIABLE_AUTHENTICATION_2  *CertData;
  AUTH_VARIABLE_INFO             OrgVariableInfo;
  BOOLEAN                        IsDel;

  ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));
  FindStatus = mAuthVarLibContextIn->FindVariable (
                                       VariableName,
                                       VendorGuid,
                                       &OrgVariableInfo
                                       );

  Status = VerifyTimeBasedPayload (
             VariableName,
             VendorGuid,
             Data,
             DataSize,
             Attributes,
             AuthVarType,
             (!EFI_ERROR (FindStatus)) ? OrgVariableInfo.TimeStamp : NULL,
             &PayloadPtr,
             &PayloadSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (  !EFI_ERROR (FindStatus)
     && (PayloadSize == 0)
     && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0))
  {
    IsDel = TRUE;
  } else {
    IsDel = FALSE;
  }

  CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;

  //
  // Final step: Update/Append Variable if it pass Pkcs7Verify
  //
  Status = AuthServiceInternalUpdateVariableWithTimeStamp (
             VariableName,
             VendorGuid,
             PayloadPtr,
             PayloadSize,
             Attributes,
             &CertData->TimeStamp
             );

  //
  // Delete signer's certificates when delete the common authenticated variable.
  //
  if (IsDel && (AuthVarType == AuthVarTypePriv) && !EFI_ERROR (Status)) {
    Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);
  }

  if (VarDel != NULL) {
    if (IsDel && !EFI_ERROR (Status)) {
      *VarDel = TRUE;
    } else {
      *VarDel = FALSE;
    }
  }

  return Status;
}
