Home | History | Annotate | Download | only in VarCheckUefiLib
      1 /** @file
      2   Implementation functions and structures for var check uefi library.
      3 
      4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Library/VarCheckLib.h>
     16 #include <Library/BaseLib.h>
     17 #include <Library/BaseMemoryLib.h>
     18 #include <Library/DebugLib.h>
     19 #include <Library/DevicePathLib.h>
     20 
     21 #include <Guid/VariableFormat.h>
     22 #include <Guid/GlobalVariable.h>
     23 #include <Guid/HardwareErrorVariable.h>
     24 #include <Guid/ImageAuthentication.h>
     25 
     26 typedef
     27 EFI_STATUS
     28 (EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
     29   IN VAR_CHECK_VARIABLE_PROPERTY    *Propery,
     30   IN UINTN                          DataSize,
     31   IN VOID                           *Data
     32   );
     33 
     34 typedef struct {
     35   CHAR16                        *Name;
     36   VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
     37   INTERNAL_VAR_CHECK_FUNCTION   CheckFunction;
     38 } UEFI_DEFINED_VARIABLE_ENTRY;
     39 
     40 /**
     41   Internal check for load option.
     42 
     43   @param[in] VariablePropery    Pointer to variable property.
     44   @param[in] DataSize           Data size.
     45   @param[in] Data               Pointer to data buffer.
     46 
     47   @retval EFI_SUCCESS           The SetVariable check result was success.
     48   @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
     49 
     50 **/
     51 EFI_STATUS
     52 EFIAPI
     53 InternalVarCheckLoadOption (
     54   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
     55   IN UINTN                          DataSize,
     56   IN VOID                           *Data
     57   )
     58 {
     59   UINT16                    FilePathListLength;
     60   CHAR16                    *Description;
     61   EFI_DEVICE_PATH_PROTOCOL  *FilePathList;
     62 
     63   FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));
     64 
     65   //
     66   // Check Description
     67   //
     68   Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));
     69   while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
     70     if (*Description == L'\0') {
     71       break;
     72     }
     73     Description++;
     74   }
     75   if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
     76     return EFI_INVALID_PARAMETER;
     77   }
     78   Description++;
     79 
     80   //
     81   // Check FilePathList
     82   //
     83   FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
     84   if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {
     85     return EFI_INVALID_PARAMETER;
     86   }
     87   if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {
     88     return EFI_INVALID_PARAMETER;
     89   }
     90   if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
     91     return EFI_INVALID_PARAMETER;
     92   }
     93   if (!IsDevicePathValid (FilePathList, FilePathListLength)) {
     94     return EFI_INVALID_PARAMETER;
     95   }
     96 
     97   return EFI_SUCCESS;
     98 }
     99 
    100 /**
    101   Internal check for key option.
    102 
    103   @param[in] VariablePropery    Pointer to variable property.
    104   @param[in] DataSize           Data size.
    105   @param[in] Data               Pointer to data buffer.
    106 
    107   @retval EFI_SUCCESS           The SetVariable check result was success.
    108   @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
    109 
    110 **/
    111 EFI_STATUS
    112 EFIAPI
    113 InternalVarCheckKeyOption (
    114   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
    115   IN UINTN                          DataSize,
    116   IN VOID                           *Data
    117   )
    118 {
    119   if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
    120     return EFI_INVALID_PARAMETER;
    121   }
    122 
    123   return EFI_SUCCESS;
    124 }
    125 
    126 /**
    127   Internal check for device path.
    128 
    129   @param[in] VariablePropery    Pointer to variable property.
    130   @param[in] DataSize           Data size.
    131   @param[in] Data               Pointer to data buffer.
    132 
    133   @retval EFI_SUCCESS           The SetVariable check result was success.
    134   @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
    135 
    136 **/
    137 EFI_STATUS
    138 EFIAPI
    139 InternalVarCheckDevicePath (
    140   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
    141   IN UINTN                          DataSize,
    142   IN VOID                           *Data
    143   )
    144 {
    145   if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
    146     return EFI_INVALID_PARAMETER;
    147   }
    148   return EFI_SUCCESS;
    149 }
    150 
    151 /**
    152   Internal check for ASCII string.
    153 
    154   @param[in] VariablePropery    Pointer to variable property.
    155   @param[in] DataSize           Data size.
    156   @param[in] Data               Pointer to data buffer.
    157 
    158   @retval EFI_SUCCESS           The SetVariable check result was success.
    159   @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.
    160 
    161 **/
    162 EFI_STATUS
    163 EFIAPI
    164 InternalVarCheckAsciiString (
    165   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
    166   IN UINTN                          DataSize,
    167   IN VOID                           *Data
    168   )
    169 {
    170   CHAR8     *String;
    171   UINTN     Index;
    172 
    173   String = (CHAR8 *) Data;
    174   if (String[DataSize - 1] == '\0') {
    175     return EFI_SUCCESS;
    176   } else {
    177     for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
    178     if (Index == DataSize) {
    179       return EFI_INVALID_PARAMETER;
    180     }
    181   }
    182   return EFI_SUCCESS;
    183 }
    184 
    185 /**
    186   Internal check for size array.
    187 
    188   @param[in] VariablePropery    Pointer to variable property.
    189   @param[in] DataSize           Data size.
    190   @param[in] Data               Pointer to data buffer.
    191 
    192   @retval EFI_SUCCESS           The SetVariable check result was success.
    193   @retval EFI_INVALID_PARAMETER The DataSize is not size array.
    194 
    195 **/
    196 EFI_STATUS
    197 EFIAPI
    198 InternalVarCheckSizeArray (
    199   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
    200   IN UINTN                          DataSize,
    201   IN VOID                           *Data
    202   )
    203 {
    204   if ((DataSize % VariablePropery->MinSize) != 0) {
    205     return EFI_INVALID_PARAMETER;
    206   }
    207   return EFI_SUCCESS;
    208 }
    209 
    210 //
    211 // To prevent name collisions with possible future globally defined variables,
    212 // other internal firmware data variables that are not defined here must be
    213 // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
    214 // any other GUID defined by the UEFI Specification. Implementations must
    215 // only permit the creation of variables with a UEFI Specification-defined
    216 // VendorGuid when these variables are documented in the UEFI Specification.
    217 //
    218 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
    219   {
    220     EFI_LANG_CODES_VARIABLE_NAME,
    221     {
    222       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    223       0,
    224       VARIABLE_ATTRIBUTE_BS_RT,
    225       1,
    226       MAX_UINTN
    227     },
    228     InternalVarCheckAsciiString
    229   },
    230   {
    231     EFI_LANG_VARIABLE_NAME,
    232     {
    233       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    234       0,
    235       VARIABLE_ATTRIBUTE_NV_BS_RT,
    236       1,
    237       MAX_UINTN
    238     },
    239     InternalVarCheckAsciiString
    240   },
    241   {
    242     EFI_TIME_OUT_VARIABLE_NAME,
    243     {
    244       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    245       0,
    246       VARIABLE_ATTRIBUTE_NV_BS_RT,
    247       sizeof (UINT16),
    248       sizeof (UINT16)
    249     },
    250     NULL
    251   },
    252   {
    253     EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
    254     {
    255       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    256       0,
    257       VARIABLE_ATTRIBUTE_BS_RT,
    258       1,
    259       MAX_UINTN
    260     },
    261     InternalVarCheckAsciiString
    262   },
    263   {
    264     EFI_PLATFORM_LANG_VARIABLE_NAME,
    265     {
    266       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    267       0,
    268       VARIABLE_ATTRIBUTE_NV_BS_RT,
    269       1,
    270       MAX_UINTN
    271     },
    272     InternalVarCheckAsciiString
    273   },
    274   {
    275     EFI_CON_IN_VARIABLE_NAME,
    276     {
    277       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    278       0,
    279       VARIABLE_ATTRIBUTE_NV_BS_RT,
    280       sizeof (EFI_DEVICE_PATH_PROTOCOL),
    281       MAX_UINTN
    282     },
    283     InternalVarCheckDevicePath
    284   },
    285   {
    286     EFI_CON_OUT_VARIABLE_NAME,
    287     {
    288       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    289       0,
    290       VARIABLE_ATTRIBUTE_NV_BS_RT,
    291       sizeof (EFI_DEVICE_PATH_PROTOCOL),
    292       MAX_UINTN
    293     },
    294     InternalVarCheckDevicePath
    295   },
    296   {
    297     EFI_ERR_OUT_VARIABLE_NAME,
    298     {
    299       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    300       0,
    301       VARIABLE_ATTRIBUTE_NV_BS_RT,
    302       sizeof (EFI_DEVICE_PATH_PROTOCOL),
    303       MAX_UINTN
    304     },
    305     InternalVarCheckDevicePath
    306   },
    307   {
    308     EFI_CON_IN_DEV_VARIABLE_NAME,
    309     {
    310       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    311       0,
    312       VARIABLE_ATTRIBUTE_BS_RT,
    313       sizeof (EFI_DEVICE_PATH_PROTOCOL),
    314       MAX_UINTN
    315     },
    316     InternalVarCheckDevicePath
    317   },
    318   {
    319     EFI_CON_OUT_DEV_VARIABLE_NAME,
    320     {
    321       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    322       0,
    323       VARIABLE_ATTRIBUTE_BS_RT,
    324       sizeof (EFI_DEVICE_PATH_PROTOCOL),
    325       MAX_UINTN
    326     },
    327     InternalVarCheckDevicePath
    328   },
    329   {
    330     EFI_ERR_OUT_DEV_VARIABLE_NAME,
    331     {
    332       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    333       0,
    334       VARIABLE_ATTRIBUTE_BS_RT,
    335       sizeof (EFI_DEVICE_PATH_PROTOCOL),
    336       MAX_UINTN
    337     },
    338     InternalVarCheckDevicePath
    339   },
    340   {
    341     EFI_BOOT_ORDER_VARIABLE_NAME,
    342     {
    343       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    344       0,
    345       VARIABLE_ATTRIBUTE_NV_BS_RT,
    346       sizeof (UINT16),
    347       MAX_UINTN
    348     },
    349     InternalVarCheckSizeArray
    350   },
    351   {
    352     EFI_BOOT_NEXT_VARIABLE_NAME,
    353     {
    354       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    355       0,
    356       VARIABLE_ATTRIBUTE_NV_BS_RT,
    357       sizeof (UINT16),
    358       sizeof (UINT16)
    359     },
    360     NULL
    361   },
    362   {
    363     EFI_BOOT_CURRENT_VARIABLE_NAME,
    364     {
    365       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    366       0,
    367       VARIABLE_ATTRIBUTE_BS_RT,
    368       sizeof (UINT16),
    369       sizeof (UINT16)
    370     },
    371     NULL
    372   },
    373   {
    374     EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
    375     {
    376       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    377       0,
    378       VARIABLE_ATTRIBUTE_BS_RT,
    379       sizeof (UINT32),
    380       sizeof (UINT32)
    381     },
    382     NULL
    383   },
    384   {
    385     EFI_DRIVER_ORDER_VARIABLE_NAME,
    386     {
    387       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    388       0,
    389       VARIABLE_ATTRIBUTE_NV_BS_RT,
    390       sizeof (UINT16),
    391       MAX_UINTN
    392     },
    393     InternalVarCheckSizeArray
    394   },
    395   {
    396     EFI_SYS_PREP_ORDER_VARIABLE_NAME,
    397     {
    398       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    399       0,
    400       VARIABLE_ATTRIBUTE_NV_BS_RT,
    401       sizeof (UINT16),
    402       MAX_UINTN
    403     },
    404     InternalVarCheckSizeArray
    405   },
    406   {
    407     EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
    408     {
    409       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    410       0,
    411       VARIABLE_ATTRIBUTE_NV_BS_RT,
    412       sizeof (UINT16),
    413       sizeof (UINT16)
    414     },
    415     NULL
    416   },
    417   {
    418     EFI_SETUP_MODE_NAME,
    419     {
    420       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    421       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    422       VARIABLE_ATTRIBUTE_BS_RT,
    423       sizeof (UINT8),
    424       sizeof (UINT8)
    425     },
    426     NULL
    427   },
    428   {
    429     EFI_KEY_EXCHANGE_KEY_NAME,
    430     {
    431       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    432       0,
    433       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
    434       1,
    435       MAX_UINTN
    436     },
    437     NULL
    438   },
    439   {
    440     EFI_PLATFORM_KEY_NAME,
    441     {
    442       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    443       0,
    444       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
    445       1,
    446       MAX_UINTN
    447     },
    448     NULL
    449   },
    450   {
    451     EFI_SIGNATURE_SUPPORT_NAME,
    452     {
    453       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    454       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    455       VARIABLE_ATTRIBUTE_BS_RT,
    456       sizeof (EFI_GUID),
    457       MAX_UINTN
    458     },
    459     InternalVarCheckSizeArray
    460   },
    461   {
    462     EFI_SECURE_BOOT_MODE_NAME,
    463     {
    464       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    465       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    466       VARIABLE_ATTRIBUTE_BS_RT,
    467       sizeof (UINT8),
    468       sizeof (UINT8)
    469     },
    470     NULL
    471   },
    472   {
    473     EFI_KEK_DEFAULT_VARIABLE_NAME,
    474     {
    475       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    476       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    477       VARIABLE_ATTRIBUTE_BS_RT,
    478       1,
    479       MAX_UINTN
    480     },
    481     NULL
    482   },
    483   {
    484     EFI_PK_DEFAULT_VARIABLE_NAME,
    485     {
    486       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    487       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    488       VARIABLE_ATTRIBUTE_BS_RT,
    489       1,
    490       MAX_UINTN
    491     },
    492     NULL
    493   },
    494   {
    495     EFI_DB_DEFAULT_VARIABLE_NAME,
    496     {
    497       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    498       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    499       VARIABLE_ATTRIBUTE_BS_RT,
    500       1,
    501       MAX_UINTN
    502     },
    503     NULL
    504   },
    505   {
    506     EFI_DBX_DEFAULT_VARIABLE_NAME,
    507     {
    508       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    509       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    510       VARIABLE_ATTRIBUTE_BS_RT,
    511       1,
    512       MAX_UINTN
    513     },
    514     NULL
    515   },
    516   {
    517     EFI_DBT_DEFAULT_VARIABLE_NAME,
    518     {
    519       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    520       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    521       VARIABLE_ATTRIBUTE_BS_RT,
    522       1,
    523       MAX_UINTN
    524     },
    525     NULL
    526   },
    527   {
    528     EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
    529     {
    530       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    531       0,
    532       VARIABLE_ATTRIBUTE_BS_RT,
    533       sizeof (UINT64),
    534       sizeof (UINT64)
    535     },
    536     NULL
    537   },
    538   {
    539     EFI_OS_INDICATIONS_VARIABLE_NAME,
    540     {
    541       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    542       0,
    543       VARIABLE_ATTRIBUTE_NV_BS_RT,
    544       sizeof (UINT64),
    545       sizeof (UINT64)
    546     },
    547     NULL
    548   },
    549   {
    550     EFI_VENDOR_KEYS_VARIABLE_NAME,
    551     {
    552       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    553       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
    554       VARIABLE_ATTRIBUTE_BS_RT,
    555       sizeof (UINT8),
    556       sizeof (UINT8)
    557     },
    558     NULL
    559   },
    560 };
    561 
    562 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
    563   {
    564     L"Boot####",
    565     {
    566       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    567       0,
    568       VARIABLE_ATTRIBUTE_NV_BS_RT,
    569       sizeof (UINT32) + sizeof (UINT16),
    570       MAX_UINTN
    571     },
    572     InternalVarCheckLoadOption
    573   },
    574   {
    575     L"Driver####",
    576     {
    577       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    578       0,
    579       VARIABLE_ATTRIBUTE_NV_BS_RT,
    580       sizeof (UINT32) + sizeof (UINT16),
    581       MAX_UINTN
    582     },
    583     InternalVarCheckLoadOption
    584   },
    585   {
    586     L"SysPrep####",
    587     {
    588       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    589       0,
    590       VARIABLE_ATTRIBUTE_NV_BS_RT,
    591       sizeof (UINT32) + sizeof (UINT16),
    592       MAX_UINTN
    593     },
    594     InternalVarCheckLoadOption
    595   },
    596   {
    597     L"Key####",
    598     {
    599       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    600       0,
    601       VARIABLE_ATTRIBUTE_NV_BS_RT,
    602       sizeof (EFI_KEY_OPTION),
    603       sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
    604     },
    605     InternalVarCheckKeyOption
    606   },
    607   {
    608     L"PlatformRecovery####",
    609     {
    610       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    611       0,
    612       VARIABLE_ATTRIBUTE_BS_RT,
    613       sizeof (UINT32) + sizeof (UINT16),
    614       MAX_UINTN
    615     },
    616     InternalVarCheckLoadOption
    617   },
    618 };
    619 
    620 //
    621 // EFI_IMAGE_SECURITY_DATABASE_GUID
    622 //
    623 UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {
    624   {
    625     EFI_IMAGE_SECURITY_DATABASE,
    626     {
    627       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    628       0,
    629       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
    630       1,
    631       MAX_UINTN
    632     },
    633     NULL
    634   },
    635   {
    636     EFI_IMAGE_SECURITY_DATABASE1,
    637     {
    638       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    639       0,
    640       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
    641       1,
    642       MAX_UINTN
    643     },
    644     NULL
    645   },
    646   {
    647     EFI_IMAGE_SECURITY_DATABASE2,
    648     {
    649       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    650       0,
    651       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
    652       1,
    653       MAX_UINTN
    654     },
    655     NULL
    656   },
    657 };
    658 
    659 //
    660 // EFI_HARDWARE_ERROR_VARIABLE
    661 //
    662 UEFI_DEFINED_VARIABLE_ENTRY mHwErrRecVariable = {
    663   L"HwErrRec####",
    664   {
    665     VAR_CHECK_VARIABLE_PROPERTY_REVISION,
    666     0,
    667     VARIABLE_ATTRIBUTE_NV_BS_RT_HR,
    668     1,
    669     MAX_UINTN
    670   },
    671   NULL
    672 };
    673 
    674 EFI_GUID *mUefiDefinedGuid[] = {
    675   &gEfiGlobalVariableGuid,
    676   &gEfiImageSecurityDatabaseGuid,
    677   &gEfiHardwareErrorVariableGuid
    678 };
    679 
    680 /**
    681   Check if a Unicode character is an upper case hexadecimal character.
    682 
    683   This function checks if a Unicode character is an upper case
    684   hexadecimal character.  The valid upper case hexadecimal character is
    685   L'0' to L'9', or L'A' to L'F'.
    686 
    687 
    688   @param[in] Char       The character to check against.
    689 
    690   @retval TRUE          If the Char is an upper case hexadecmial character.
    691   @retval FALSE         If the Char is not an upper case hexadecmial character.
    692 
    693 **/
    694 BOOLEAN
    695 EFIAPI
    696 VarCheckUefiIsHexaDecimalDigitCharacter (
    697   IN CHAR16             Char
    698   )
    699 {
    700   return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F'));
    701 }
    702 
    703 /**
    704 
    705   This code checks if variable is hardware error record variable or not.
    706 
    707   According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid
    708   and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value.
    709 
    710   @param[in] VariableName   Pointer to variable name.
    711   @param[in] VendorGuid     Variable Vendor Guid.
    712 
    713   @retval TRUE              Variable is hardware error record variable.
    714   @retval FALSE             Variable is not hardware error record variable.
    715 
    716 **/
    717 BOOLEAN
    718 EFIAPI
    719 IsHwErrRecVariable (
    720   IN CHAR16             *VariableName,
    721   IN EFI_GUID           *VendorGuid
    722   )
    723 {
    724   if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) ||
    725       (StrLen (VariableName) != StrLen (L"HwErrRec####")) ||
    726       (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) ||
    727       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x8]) ||
    728       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x9]) ||
    729       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xA]) ||
    730       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xB])) {
    731     return FALSE;
    732   }
    733 
    734   return TRUE;
    735 }
    736 
    737 /**
    738   Get UEFI defined var check function.
    739 
    740   @param[in]  VariableName      Pointer to variable name.
    741   @param[in]  VendorGuid        Pointer to variable vendor GUID.
    742   @param[out] VariableProperty  Pointer to variable property.
    743 
    744   @return Internal var check function, NULL if no specific check function.
    745 
    746 **/
    747 INTERNAL_VAR_CHECK_FUNCTION
    748 GetUefiDefinedVarCheckFunction (
    749   IN CHAR16                         *VariableName,
    750   IN EFI_GUID                       *VendorGuid,
    751   OUT VAR_CHECK_VARIABLE_PROPERTY   **VariableProperty
    752   )
    753 {
    754   UINTN     Index;
    755   UINTN     NameLength;
    756 
    757   if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
    758     //
    759     // Try list 1, exactly match.
    760     //
    761     for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
    762       if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
    763         *VariableProperty = &(mGlobalVariableList[Index].VariableProperty);
    764         return mGlobalVariableList[Index].CheckFunction;
    765       }
    766     }
    767 
    768     //
    769     // Try list 2.
    770     //
    771     NameLength = StrLen (VariableName) - 4;
    772     for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
    773       if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
    774           (StrnCmp (VariableName, mGlobalVariableList2[Index].Name, NameLength) == 0) &&
    775           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
    776           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
    777           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
    778           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
    779         *VariableProperty = &(mGlobalVariableList2[Index].VariableProperty);
    780         return mGlobalVariableList2[Index].CheckFunction;
    781       }
    782     }
    783   }
    784 
    785   return NULL;
    786 }
    787 
    788 /**
    789   SetVariable check handler UEFI defined.
    790 
    791   @param[in] VariableName       Name of Variable to set.
    792   @param[in] VendorGuid         Variable vendor GUID.
    793   @param[in] Attributes         Attribute value of the variable.
    794   @param[in] DataSize           Size of Data to set.
    795   @param[in] Data               Data pointer.
    796 
    797   @retval EFI_SUCCESS           The SetVariable check result was success.
    798   @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, GUID,
    799                                 DataSize and Data value was supplied.
    800   @retval EFI_WRITE_PROTECTED   The variable in question is read-only.
    801 
    802 **/
    803 EFI_STATUS
    804 EFIAPI
    805 SetVariableCheckHandlerUefiDefined (
    806   IN CHAR16     *VariableName,
    807   IN EFI_GUID   *VendorGuid,
    808   IN UINT32     Attributes,
    809   IN UINTN      DataSize,
    810   IN VOID       *Data
    811   )
    812 {
    813   EFI_STATUS                    Status;
    814   UINTN                         Index;
    815   VAR_CHECK_VARIABLE_PROPERTY   Property;
    816   VAR_CHECK_VARIABLE_PROPERTY   *VarCheckProperty;
    817   INTERNAL_VAR_CHECK_FUNCTION   VarCheckFunction;
    818 
    819   if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
    820     //
    821     // Do not check delete variable.
    822     //
    823     return EFI_SUCCESS;
    824   }
    825 
    826   if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
    827     if (!IsHwErrRecVariable (VariableName, VendorGuid)) {
    828       return EFI_INVALID_PARAMETER;
    829     }
    830   }
    831 
    832   for (Index = 0; Index < sizeof (mUefiDefinedGuid)/sizeof (mUefiDefinedGuid[0]); Index++) {
    833     if (CompareGuid (VendorGuid, mUefiDefinedGuid[Index])) {
    834       if (VarCheckLibVariablePropertyGet (VariableName, VendorGuid, &Property) == EFI_NOT_FOUND) {
    835         //
    836         // To prevent name collisions with possible future globally defined variables,
    837         // other internal firmware data variables that are not defined here must be
    838         // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
    839         // any other GUID defined by the UEFI Specification. Implementations must
    840         // only permit the creation of variables with a UEFI Specification-defined
    841         // VendorGuid when these variables are documented in the UEFI Specification.
    842         //
    843         DEBUG ((EFI_D_INFO, "UEFI Variable Check fail %r - %s not in %g namespace\n", EFI_INVALID_PARAMETER, VariableName, VendorGuid));
    844         return EFI_INVALID_PARAMETER;
    845       }
    846     }
    847   }
    848 
    849   if (DataSize == 0) {
    850     return EFI_SUCCESS;
    851   }
    852 
    853   VarCheckProperty = NULL;
    854   VarCheckFunction = GetUefiDefinedVarCheckFunction (VariableName, VendorGuid, &VarCheckProperty);
    855   if (VarCheckFunction != NULL) {
    856     Status = VarCheckFunction (
    857                VarCheckProperty,
    858                DataSize,
    859                Data
    860                );
    861     if (EFI_ERROR (Status)) {
    862       DEBUG ((EFI_D_INFO, "UEFI Variable Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
    863       return Status;
    864     }
    865   }
    866 
    867   return EFI_SUCCESS;
    868 }
    869 
    870 /**
    871   Variable property set for UEFI defined variables.
    872 
    873 **/
    874 VOID
    875 VariablePropertySetUefiDefined (
    876   VOID
    877   )
    878 {
    879   UINTN     Index;
    880 
    881   //
    882   // EFI_GLOBAL_VARIABLE
    883   //
    884   for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
    885     VarCheckLibVariablePropertySet (
    886       mGlobalVariableList[Index].Name,
    887       &gEfiGlobalVariableGuid,
    888       &mGlobalVariableList[Index].VariableProperty
    889       );
    890   }
    891   for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
    892     VarCheckLibVariablePropertySet (
    893       mGlobalVariableList2[Index].Name,
    894       &gEfiGlobalVariableGuid,
    895       &mGlobalVariableList2[Index].VariableProperty
    896       );
    897   }
    898 
    899   //
    900   // EFI_IMAGE_SECURITY_DATABASE_GUID
    901   //
    902   for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {
    903     VarCheckLibVariablePropertySet (
    904       mImageSecurityVariableList[Index].Name,
    905       &gEfiImageSecurityDatabaseGuid,
    906       &mImageSecurityVariableList[Index].VariableProperty
    907       );
    908   }
    909 
    910   //
    911   // EFI_HARDWARE_ERROR_VARIABLE
    912   //
    913   VarCheckLibVariablePropertySet (
    914     mHwErrRecVariable.Name,
    915     &gEfiHardwareErrorVariableGuid,
    916     &mHwErrRecVariable.VariableProperty
    917     );
    918 }
    919 
    920 /**
    921   Constructor function of VarCheckUefiLib to set property and
    922   register SetVariable check handler for UEFI defined variables.
    923 
    924   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
    925   @param[in] SystemTable    A pointer to the EFI System Table.
    926 
    927   @retval EFI_SUCCESS       The constructor executed correctly.
    928 
    929 **/
    930 EFI_STATUS
    931 EFIAPI
    932 VarCheckUefiLibNullClassConstructor (
    933   IN EFI_HANDLE             ImageHandle,
    934   IN EFI_SYSTEM_TABLE       *SystemTable
    935   )
    936 {
    937   VariablePropertySetUefiDefined ();
    938   VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerUefiDefined);
    939 
    940   return EFI_SUCCESS;
    941 }
    942