/** @file
  Implementation functions and structures for var check uefi library.

Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <Library/VarCheckLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>

#include <Guid/VariableFormat.h>
#include <Guid/GlobalVariable.h>
#include <Guid/HardwareErrorVariable.h>
#include <Guid/ImageAuthentication.h>

typedef
EFI_STATUS
(EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
  IN VAR_CHECK_VARIABLE_PROPERTY    *Propery,
  IN UINTN                          DataSize,
  IN VOID                           *Data
  );

typedef struct {
  CHAR16                        *Name;
  VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
  INTERNAL_VAR_CHECK_FUNCTION   CheckFunction;
} UEFI_DEFINED_VARIABLE_ENTRY;

/**
  Internal check for load option.

  @param[in] VariablePropery    Pointer to variable property.
  @param[in] DataSize           Data size.
  @param[in] Data               Pointer to data buffer.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.

**/
EFI_STATUS
EFIAPI
InternalVarCheckLoadOption (
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
  IN UINTN                          DataSize,
  IN VOID                           *Data
  )
{
  UINT16                    FilePathListLength;
  CHAR16                    *Description;
  EFI_DEVICE_PATH_PROTOCOL  *FilePathList;

  FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));

  //
  // Check Description
  //
  Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));
  while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
    if (*Description == L'\0') {
      break;
    }
    Description++;
  }
  if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
    return EFI_INVALID_PARAMETER;
  }
  Description++;

  //
  // Check FilePathList
  //
  FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
  if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {
    return EFI_INVALID_PARAMETER;
  }
  if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {
    return EFI_INVALID_PARAMETER;
  }
  if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
    return EFI_INVALID_PARAMETER;
  }
  if (!IsDevicePathValid (FilePathList, FilePathListLength)) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Internal check for key option.

  @param[in] VariablePropery    Pointer to variable property.
  @param[in] DataSize           Data size.
  @param[in] Data               Pointer to data buffer.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.

**/
EFI_STATUS
EFIAPI
InternalVarCheckKeyOption (
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
  IN UINTN                          DataSize,
  IN VOID                           *Data
  )
{
  if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Internal check for device path.

  @param[in] VariablePropery    Pointer to variable property.
  @param[in] DataSize           Data size.
  @param[in] Data               Pointer to data buffer.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.

**/
EFI_STATUS
EFIAPI
InternalVarCheckDevicePath (
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
  IN UINTN                          DataSize,
  IN VOID                           *Data
  )
{
  if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
    return EFI_INVALID_PARAMETER;
  }
  return EFI_SUCCESS;
}

/**
  Internal check for ASCII string.

  @param[in] VariablePropery    Pointer to variable property.
  @param[in] DataSize           Data size.
  @param[in] Data               Pointer to data buffer.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.

**/
EFI_STATUS
EFIAPI
InternalVarCheckAsciiString (
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
  IN UINTN                          DataSize,
  IN VOID                           *Data
  )
{
  CHAR8     *String;
  UINTN     Index;

  String = (CHAR8 *) Data;
  if (String[DataSize - 1] == '\0') {
    return EFI_SUCCESS;
  } else {
    for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
    if (Index == DataSize) {
      return EFI_INVALID_PARAMETER;
    }
  }
  return EFI_SUCCESS;
}

/**
  Internal check for size array.

  @param[in] VariablePropery    Pointer to variable property.
  @param[in] DataSize           Data size.
  @param[in] Data               Pointer to data buffer.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER The DataSize is not size array.

**/
EFI_STATUS
EFIAPI
InternalVarCheckSizeArray (
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
  IN UINTN                          DataSize,
  IN VOID                           *Data
  )
{
  if ((DataSize % VariablePropery->MinSize) != 0) {
    return EFI_INVALID_PARAMETER;
  }
  return EFI_SUCCESS;
}

//
// To prevent name collisions with possible future globally defined variables,
// other internal firmware data variables that are not defined here must be
// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
// any other GUID defined by the UEFI Specification. Implementations must
// only permit the creation of variables with a UEFI Specification-defined
// VendorGuid when these variables are documented in the UEFI Specification.
//
UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
  {
    EFI_LANG_CODES_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    InternalVarCheckAsciiString
  },
  {
    EFI_LANG_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      1,
      MAX_UINTN
    },
    InternalVarCheckAsciiString
  },
  {
    EFI_TIME_OUT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT16),
      sizeof (UINT16)
    },
    NULL
  },
  {
    EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    InternalVarCheckAsciiString
  },
  {
    EFI_PLATFORM_LANG_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      1,
      MAX_UINTN
    },
    InternalVarCheckAsciiString
  },
  {
    EFI_CON_IN_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
      MAX_UINTN
    },
    InternalVarCheckDevicePath
  },
  {
    EFI_CON_OUT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
      MAX_UINTN
    },
    InternalVarCheckDevicePath
  },
  {
    EFI_ERR_OUT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
      MAX_UINTN
    },
    InternalVarCheckDevicePath
  },
  {
    EFI_CON_IN_DEV_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
      MAX_UINTN
    },
    InternalVarCheckDevicePath
  },
  {
    EFI_CON_OUT_DEV_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
      MAX_UINTN
    },
    InternalVarCheckDevicePath
  },
  {
    EFI_ERR_OUT_DEV_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
      MAX_UINTN
    },
    InternalVarCheckDevicePath
  },
  {
    EFI_BOOT_ORDER_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckSizeArray
  },
  {
    EFI_BOOT_NEXT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT16),
      sizeof (UINT16)
    },
    NULL
  },
  {
    EFI_BOOT_CURRENT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT16),
      sizeof (UINT16)
    },
    NULL
  },
  {
    EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT32),
      sizeof (UINT32)
    },
    NULL
  },
  {
    EFI_DRIVER_ORDER_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckSizeArray
  },
  {
    EFI_SYS_PREP_ORDER_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckSizeArray
  },
  {
    EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT16),
      sizeof (UINT16)
    },
    NULL
  },
  {
    EFI_SETUP_MODE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT8),
      sizeof (UINT8)
    },
    NULL
  },
  {
    EFI_KEY_EXCHANGE_KEY_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_PLATFORM_KEY_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_SIGNATURE_SUPPORT_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (EFI_GUID),
      MAX_UINTN
    },
    InternalVarCheckSizeArray
  },
  {
    EFI_SECURE_BOOT_MODE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT8),
      sizeof (UINT8)
    },
    NULL
  },
  {
    EFI_KEK_DEFAULT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_PK_DEFAULT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_DB_DEFAULT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_DBX_DEFAULT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_DBT_DEFAULT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT64),
      sizeof (UINT64)
    },
    NULL
  },
  {
    EFI_OS_INDICATIONS_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT64),
      sizeof (UINT64)
    },
    NULL
  },
  {
    EFI_VENDOR_KEYS_VARIABLE_NAME,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT8),
      sizeof (UINT8)
    },
    NULL
  },
};

UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
  {
    L"Boot####",
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT32) + sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckLoadOption
  },
  {
    L"Driver####",
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT32) + sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckLoadOption
  },
  {
    L"SysPrep####",
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (UINT32) + sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckLoadOption
  },
  {
    L"Key####",
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT,
      sizeof (EFI_KEY_OPTION),
      sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
    },
    InternalVarCheckKeyOption
  },
  {
    L"PlatformRecovery####",
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_BS_RT,
      sizeof (UINT32) + sizeof (UINT16),
      MAX_UINTN
    },
    InternalVarCheckLoadOption
  },
};

//
// EFI_IMAGE_SECURITY_DATABASE_GUID
//
UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {
  {
    EFI_IMAGE_SECURITY_DATABASE,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_IMAGE_SECURITY_DATABASE1,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
      1,
      MAX_UINTN
    },
    NULL
  },
  {
    EFI_IMAGE_SECURITY_DATABASE2,
    {
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
      0,
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
      1,
      MAX_UINTN
    },
    NULL
  },
};

//
// EFI_HARDWARE_ERROR_VARIABLE
//
UEFI_DEFINED_VARIABLE_ENTRY mHwErrRecVariable = {
  L"HwErrRec####",
  {
    VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    0,
    VARIABLE_ATTRIBUTE_NV_BS_RT_HR,
    1,
    MAX_UINTN
  },
  NULL
};

EFI_GUID *mUefiDefinedGuid[] = {
  &gEfiGlobalVariableGuid,
  &gEfiImageSecurityDatabaseGuid,
  &gEfiHardwareErrorVariableGuid
};

/**
  Check if a Unicode character is an upper case hexadecimal character.

  This function checks if a Unicode character is an upper case
  hexadecimal character.  The valid upper case hexadecimal character is
  L'0' to L'9', or L'A' to L'F'.


  @param[in] Char       The character to check against.

  @retval TRUE          If the Char is an upper case hexadecmial character.
  @retval FALSE         If the Char is not an upper case hexadecmial character.

**/
BOOLEAN
EFIAPI
VarCheckUefiIsHexaDecimalDigitCharacter (
  IN CHAR16             Char
  )
{
  return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F'));
}

/**

  This code checks if variable is hardware error record variable or not.

  According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid
  and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value.

  @param[in] VariableName   Pointer to variable name.
  @param[in] VendorGuid     Variable Vendor Guid.

  @retval TRUE              Variable is hardware error record variable.
  @retval FALSE             Variable is not hardware error record variable.

**/
BOOLEAN
EFIAPI
IsHwErrRecVariable (
  IN CHAR16             *VariableName,
  IN EFI_GUID           *VendorGuid
  )
{
  if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) ||
      (StrLen (VariableName) != StrLen (L"HwErrRec####")) ||
      (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x8]) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x9]) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xA]) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xB])) {
    return FALSE;
  }

  return TRUE;
}

/**
  Get UEFI defined var check function.

  @param[in]  VariableName      Pointer to variable name.
  @param[in]  VendorGuid        Pointer to variable vendor GUID.
  @param[out] VariableProperty  Pointer to variable property.

  @return Internal var check function, NULL if no specific check function.

**/
INTERNAL_VAR_CHECK_FUNCTION
GetUefiDefinedVarCheckFunction (
  IN CHAR16                         *VariableName,
  IN EFI_GUID                       *VendorGuid,
  OUT VAR_CHECK_VARIABLE_PROPERTY   **VariableProperty
  )
{
  UINTN     Index;
  UINTN     NameLength;

  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
    //
    // Try list 1, exactly match.
    //
    for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
      if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
        *VariableProperty = &(mGlobalVariableList[Index].VariableProperty);
        return mGlobalVariableList[Index].CheckFunction;
      }
    }

    //
    // Try list 2.
    //
    NameLength = StrLen (VariableName) - 4;
    for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
      if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
          (StrnCmp (VariableName, mGlobalVariableList2[Index].Name, NameLength) == 0) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
        *VariableProperty = &(mGlobalVariableList2[Index].VariableProperty);
        return mGlobalVariableList2[Index].CheckFunction;
      }
    }
  }

  return NULL;
}

/**
  SetVariable check handler UEFI defined.

  @param[in] VariableName       Name of Variable to set.
  @param[in] VendorGuid         Variable vendor GUID.
  @param[in] Attributes         Attribute value of the variable.
  @param[in] DataSize           Size of Data to set.
  @param[in] Data               Data pointer.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, GUID,
                                DataSize and Data value was supplied.
  @retval EFI_WRITE_PROTECTED   The variable in question is read-only.

**/
EFI_STATUS
EFIAPI
SetVariableCheckHandlerUefiDefined (
  IN CHAR16     *VariableName,
  IN EFI_GUID   *VendorGuid,
  IN UINT32     Attributes,
  IN UINTN      DataSize,
  IN VOID       *Data
  )
{
  EFI_STATUS                    Status;
  UINTN                         Index;
  VAR_CHECK_VARIABLE_PROPERTY   Property;
  VAR_CHECK_VARIABLE_PROPERTY   *VarCheckProperty;
  INTERNAL_VAR_CHECK_FUNCTION   VarCheckFunction;

  if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
    //
    // Do not check delete variable.
    //
    return EFI_SUCCESS;
  }

  if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
    if (!IsHwErrRecVariable (VariableName, VendorGuid)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  for (Index = 0; Index < sizeof (mUefiDefinedGuid)/sizeof (mUefiDefinedGuid[0]); Index++) {
    if (CompareGuid (VendorGuid, mUefiDefinedGuid[Index])) {
      if (VarCheckLibVariablePropertyGet (VariableName, VendorGuid, &Property) == EFI_NOT_FOUND) {
        //
        // To prevent name collisions with possible future globally defined variables,
        // other internal firmware data variables that are not defined here must be
        // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
        // any other GUID defined by the UEFI Specification. Implementations must
        // only permit the creation of variables with a UEFI Specification-defined
        // VendorGuid when these variables are documented in the UEFI Specification.
        //
        DEBUG ((EFI_D_INFO, "UEFI Variable Check fail %r - %s not in %g namespace\n", EFI_INVALID_PARAMETER, VariableName, VendorGuid));
        return EFI_INVALID_PARAMETER;
      }
    }
  }

  if (DataSize == 0) {
    return EFI_SUCCESS;
  }

  VarCheckProperty = NULL;
  VarCheckFunction = GetUefiDefinedVarCheckFunction (VariableName, VendorGuid, &VarCheckProperty);
  if (VarCheckFunction != NULL) {
    Status = VarCheckFunction (
               VarCheckProperty,
               DataSize,
               Data
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_INFO, "UEFI Variable Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Variable property set for UEFI defined variables.

**/
VOID
VariablePropertySetUefiDefined (
  VOID
  )
{
  UINTN     Index;

  //
  // EFI_GLOBAL_VARIABLE
  //
  for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
    VarCheckLibVariablePropertySet (
      mGlobalVariableList[Index].Name,
      &gEfiGlobalVariableGuid,
      &mGlobalVariableList[Index].VariableProperty
      );
  }
  for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
    VarCheckLibVariablePropertySet (
      mGlobalVariableList2[Index].Name,
      &gEfiGlobalVariableGuid,
      &mGlobalVariableList2[Index].VariableProperty
      );
  }

  //
  // EFI_IMAGE_SECURITY_DATABASE_GUID
  //
  for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {
    VarCheckLibVariablePropertySet (
      mImageSecurityVariableList[Index].Name,
      &gEfiImageSecurityDatabaseGuid,
      &mImageSecurityVariableList[Index].VariableProperty
      );
  }

  //
  // EFI_HARDWARE_ERROR_VARIABLE
  //
  VarCheckLibVariablePropertySet (
    mHwErrRecVariable.Name,
    &gEfiHardwareErrorVariableGuid,
    &mHwErrRecVariable.VariableProperty
    );
}

/**
  Constructor function of VarCheckUefiLib to set property and
  register SetVariable check handler for UEFI defined variables.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The constructor executed correctly.

**/
EFI_STATUS
EFIAPI
VarCheckUefiLibNullClassConstructor (
  IN EFI_HANDLE             ImageHandle,
  IN EFI_SYSTEM_TABLE       *SystemTable
  )
{
  VariablePropertySetUefiDefined ();
  VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerUefiDefined);

  return EFI_SUCCESS;
}
