Home | History | Annotate | Download | only in EsalVariableDxeSal
      1 /** @file
      2   Internal header file for Extended SAL variable service module.
      3 
      4 Copyright (c) 2009 - 2015, 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 #ifndef _VARIABLE_H_
     16 #define _VARIABLE_H_
     17 
     18 #include <PiDxe.h>
     19 
     20 #include <Protocol/VariableWrite.h>
     21 #include <Protocol/FaultTolerantWrite.h>
     22 #include <Protocol/FirmwareVolumeBlock.h>
     23 #include <Protocol/Variable.h>
     24 #include <Protocol/ExtendedSalBootService.h>
     25 #include <Protocol/ExtendedSalServiceClasses.h>
     26 
     27 #include <Guid/GlobalVariable.h>
     28 #include <Guid/AuthenticatedVariableFormat.h>
     29 #include <Guid/ImageAuthentication.h>
     30 #include <Guid/EventGroup.h>
     31 
     32 #include <Library/PcdLib.h>
     33 #include <Library/HobLib.h>
     34 #include <Library/UefiDriverEntryPoint.h>
     35 #include <Library/DxeServicesTableLib.h>
     36 #include <Library/UefiRuntimeLib.h>
     37 #include <Library/DebugLib.h>
     38 #include <Library/BaseMemoryLib.h>
     39 #include <Library/UefiBootServicesTableLib.h>
     40 #include <Library/UefiLib.h>
     41 #include <Library/BaseLib.h>
     42 #include <Library/SynchronizationLib.h>
     43 #include <Library/MemoryAllocationLib.h>
     44 #include <Library/ExtendedSalLib.h>
     45 #include <Library/BaseCryptLib.h>
     46 
     47 #define MAX_NAME_SIZE            0x100
     48 #define NUM_VAR_NAME             9  // Number of pre-defined variable name to be referenced
     49 #define VAR_PLATFORM_LANG_CODES  0  // Index of "PlatformLangCodes" variable
     50 #define VAR_LANG_CODES           1  // Index of "LangCodes" variable
     51 #define VAR_PLATFORM_LANG        2  // Index of "PlatformLang" variable
     52 #define VAR_LANG                 3  // Index of "Lang" variable
     53 #define VAR_HW_ERR_REC           4  // Index of "HwErrRecXXXX" variable
     54 #define VAR_AUTH_KEY_DB          5  // Index of "AuthVarKeyDatabase" variable
     55 #define VAR_SETUP_MODE           6  // Index of "SetupMode" variable
     56 #define VAR_PLATFORM_KEY         7  // Index of "PK" variable
     57 #define VAR_KEY_EXCHANGE_KEY     8  // Index of "KEK" variable
     58 
     59 ///
     60 /// "AuthVarKeyDatabase" variable for the Public Key store.
     61 ///
     62 #define AUTHVAR_KEYDB_NAME      L"AuthVarKeyDatabase"
     63 #define AUTHVAR_KEYDB_NAME_SIZE 38
     64 
     65 ///
     66 /// The maximum size of the public key database, restricted by maximum individal EFI
     67 /// varible size, and excluding the variable header and name size.
     68 ///
     69 #define MAX_KEYDB_SIZE  (FixedPcdGet32 (PcdMaxVariableSize) - sizeof (AUTHENTICATED_VARIABLE_HEADER) - AUTHVAR_KEYDB_NAME_SIZE)
     70 #define MAX_KEY_NUM     (MAX_KEYDB_SIZE / EFI_CERT_TYPE_RSA2048_SIZE)
     71 
     72 ///
     73 /// The size of a 3 character ISO639 language code.
     74 ///
     75 #define ISO_639_2_ENTRY_SIZE    3
     76 
     77 typedef enum {
     78   Physical,
     79   Virtual
     80 } VARIABLE_POINTER_TYPE;
     81 
     82 typedef struct {
     83   EFI_PHYSICAL_ADDRESS CurrPtr;
     84   EFI_PHYSICAL_ADDRESS EndPtr;
     85   EFI_PHYSICAL_ADDRESS StartPtr;
     86   BOOLEAN              Volatile;
     87 } VARIABLE_POINTER_TRACK;
     88 
     89 typedef struct {
     90   EFI_PHYSICAL_ADDRESS  VolatileVariableBase;
     91   EFI_PHYSICAL_ADDRESS  NonVolatileVariableBase;
     92   EFI_LOCK              VariableServicesLock;
     93 } VARIABLE_GLOBAL;
     94 
     95 typedef struct {
     96   VARIABLE_GLOBAL VariableGlobal[2];
     97   CHAR16          *VariableName[2][NUM_VAR_NAME];
     98   EFI_GUID        *GlobalVariableGuid[2];
     99   UINTN           VolatileLastVariableOffset;
    100   UINTN           NonVolatileLastVariableOffset;
    101   UINTN           CommonVariableTotalSize;
    102   UINTN           HwErrVariableTotalSize;
    103   CHAR8           *PlatformLangCodes[2];
    104   CHAR8           *LangCodes[2];
    105   CHAR8           *PlatformLang[2];
    106   CHAR8           Lang[ISO_639_2_ENTRY_SIZE + 1];
    107   UINT32          FvbInstance;
    108   UINT32          ReentrantState;
    109   EFI_GUID        *AuthenticatedVariableGuid[2];
    110   EFI_GUID        *CertRsa2048Sha256Guid[2];
    111   EFI_GUID        *ImageSecurityDatabaseGuid[2];
    112   VOID            *HashContext[2];             // Hash context pointer
    113   UINT8           KeyList[MAX_KEYDB_SIZE];     // Cached Platform Key list
    114   UINT8           PubKeyStore[MAX_KEYDB_SIZE]; // Cached Public Key list
    115 } ESAL_VARIABLE_GLOBAL;
    116 
    117 typedef struct {
    118   EFI_GUID    *Guid;
    119   CHAR16      *Name;
    120   UINT32      Attributes;
    121   UINTN       DataSize;
    122   VOID        *Data;
    123 } VARIABLE_CACHE_ENTRY;
    124 
    125 
    126 extern ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;
    127 
    128 //
    129 // Functions
    130 //
    131 
    132 /**
    133   Initializes variable store area for non-volatile and volatile variable.
    134 
    135   This function allocates and initializes memory space for global context of ESAL
    136   variable service and variable store area for non-volatile and volatile variable.
    137 
    138   @param[in]  ImageHandle       The Image handle of this driver.
    139   @param[in]  SystemTable       The pointer of EFI_SYSTEM_TABLE.
    140 
    141   @retval EFI_SUCCESS           Function successfully executed.
    142   @retval EFI_OUT_OF_RESOURCES  Failed to allocate enough memory resource.
    143 
    144 **/
    145 EFI_STATUS
    146 VariableCommonInitialize (
    147   IN EFI_HANDLE         ImageHandle,
    148   IN EFI_SYSTEM_TABLE   *SystemTable
    149   );
    150 
    151 /**
    152   Entry point of Extended SAL Variable service module.
    153 
    154   This function is the entry point of Extended SAL Variable service module.
    155   It registers all functions of Extended SAL Variable class, initializes
    156   variable store for non-volatile and volatile variables, and registers
    157   notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
    158 
    159   @param[in]  ImageHandle   The Image handle of this driver.
    160   @param[in]  SystemTable   The pointer of EFI_SYSTEM_TABLE.
    161 
    162   @retval     EFI_SUCCESS   Extended SAL Variable Services Class successfully registered.
    163 
    164 **/
    165 EFI_STATUS
    166 EFIAPI
    167 VariableServiceInitialize (
    168   IN EFI_HANDLE         ImageHandle,
    169   IN EFI_SYSTEM_TABLE   *SystemTable
    170   );
    171 
    172 /**
    173   Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
    174 
    175   This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
    176   It convers pointer to new virtual address.
    177 
    178   @param[in]  Event        The event whose notification function is being invoked.
    179   @param[in]  Context      The pointer to the notification function's context.
    180 
    181 **/
    182 VOID
    183 EFIAPI
    184 VariableClassAddressChangeEvent (
    185   IN EFI_EVENT        Event,
    186   IN VOID             *Context
    187   );
    188 
    189 /**
    190   Implements EsalGetVariable function of Extended SAL Variable Services Class.
    191 
    192   This function implements EsalGetVariable function of Extended SAL Variable Services Class.
    193   It is equivalent in functionality to the EFI Runtime Service GetVariable().
    194 
    195   @param[in]      VariableName    A Null-terminated Unicode string that is the name of
    196                                   the vendor's variable.
    197   @param[in]      VendorGuid      A unique identifier for the vendor.
    198   @param[out]     Attributes      If not NULL, a pointer to the memory location to return the
    199                                   attributes bitmask for the variable.
    200   @param[in, out] DataSize        Size of Data found. If size is less than the
    201                                   data, this value contains the required size.
    202   @param[out]     Data            On input, the size in bytes of the return Data buffer.
    203                                   On output, the size of data returned in Data.
    204   @param[in]      VirtualMode     Current calling mode for this function.
    205   @param[in]      Global          Context of this Extended SAL Variable Services Class call.
    206 
    207   @retval EFI_SUCCESS            The function completed successfully.
    208   @retval EFI_NOT_FOUND          The variable was not found.
    209   @retval EFI_BUFFER_TOO_SMALL   DataSize is too small for the result.  DataSize has
    210                                  been updated with the size needed to complete the request.
    211   @retval EFI_INVALID_PARAMETER  VariableName is NULL.
    212   @retval EFI_INVALID_PARAMETER  VendorGuid is NULL.
    213   @retval EFI_INVALID_PARAMETER  DataSize is NULL.
    214   @retval EFI_INVALID_PARAMETER  DataSize is not too small and Data is NULL.
    215   @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
    216   @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
    217 
    218 **/
    219 EFI_STATUS
    220 EFIAPI
    221 EsalGetVariable (
    222   IN      CHAR16                *VariableName,
    223   IN      EFI_GUID              *VendorGuid,
    224   OUT     UINT32                *Attributes OPTIONAL,
    225   IN OUT  UINTN                 *DataSize,
    226   OUT     VOID                  *Data,
    227   IN      BOOLEAN               VirtualMode,
    228   IN      ESAL_VARIABLE_GLOBAL  *Global
    229   );
    230 
    231 /**
    232   Implements EsalGetNextVariableName function of Extended SAL Variable Services Class.
    233 
    234   This function implements EsalGetNextVariableName function of Extended SAL Variable Services Class.
    235   It is equivalent in functionality to the EFI Runtime Service GetNextVariableName().
    236 
    237   @param[in, out] VariableNameSize Size of the variable
    238   @param[in, out] VariableName     On input, supplies the last VariableName that was returned by GetNextVariableName().
    239                                    On output, returns the Null-terminated Unicode string of the current variable.
    240   @param[in, out] VendorGuid       On input, supplies the last VendorGuid that was returned by GetNextVariableName().
    241                                    On output, returns the VendorGuid of the current variable.
    242   @param[in]      VirtualMode      Current calling mode for this function.
    243   @param[in]      Global           Context of this Extended SAL Variable Services Class call.
    244 
    245   @retval EFI_SUCCESS             The function completed successfully.
    246   @retval EFI_NOT_FOUND           The next variable was not found.
    247   @retval EFI_BUFFER_TOO_SMALL    VariableNameSize is too small for the result.
    248                                   VariableNameSize has been updated with the size needed to complete the request.
    249   @retval EFI_INVALID_PARAMETER   VariableNameSize is NULL.
    250   @retval EFI_INVALID_PARAMETER   VariableName is NULL.
    251   @retval EFI_INVALID_PARAMETER   VendorGuid is NULL.
    252   @retval EFI_DEVICE_ERROR        The variable name could not be retrieved due to a hardware error.
    253 
    254 **/
    255 EFI_STATUS
    256 EFIAPI
    257 EsalGetNextVariableName (
    258   IN OUT  UINTN                 *VariableNameSize,
    259   IN OUT  CHAR16                *VariableName,
    260   IN OUT  EFI_GUID              *VendorGuid,
    261   IN      BOOLEAN               VirtualMode,
    262   IN      ESAL_VARIABLE_GLOBAL  *Global
    263   );
    264 
    265 /**
    266   Implements EsalSetVariable function of Extended SAL Variable Services Class.
    267 
    268   This function implements EsalSetVariable function of Extended SAL Variable Services Class.
    269   It is equivalent in functionality to the EFI Runtime Service SetVariable().
    270 
    271   @param[in]  VariableName       A Null-terminated Unicode string that is the name of the vendor's
    272                                  variable.  Each VariableName is unique for each
    273                                  VendorGuid.  VariableName must contain 1 or more
    274                                  Unicode characters.  If VariableName is an empty Unicode
    275                                  string, then EFI_INVALID_PARAMETER is returned.
    276   @param[in]  VendorGuid         A unique identifier for the vendor.
    277   @param[in]  Attributes         Attributes bitmask to set for the variable.
    278   @param[in]  DataSize           The size in bytes of the Data buffer.  A size of zero causes the
    279                                  variable to be deleted.
    280   @param[in]  Data               The contents for the variable.
    281   @param[in]  VirtualMode        Current calling mode for this function.
    282   @param[in]  Global             Context of this Extended SAL Variable Services Class call.
    283 
    284   @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
    285                                  defined by the Attributes.
    286   @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the
    287                                  DataSize exceeds the maximum allowed.
    288   @retval EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.
    289   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
    290   @retval EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.
    291   @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
    292   @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
    293   @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
    294   @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
    295 
    296 **/
    297 EFI_STATUS
    298 EFIAPI
    299 EsalSetVariable (
    300   IN CHAR16                  *VariableName,
    301   IN EFI_GUID                *VendorGuid,
    302   IN UINT32                  Attributes,
    303   IN UINTN                   DataSize,
    304   IN VOID                    *Data,
    305   IN BOOLEAN                 VirtualMode,
    306   IN ESAL_VARIABLE_GLOBAL    *Global
    307   );
    308 
    309 /**
    310   Implements EsalQueryVariableInfo function of Extended SAL Variable Services Class.
    311 
    312   This function implements EsalQueryVariableInfo function of Extended SAL Variable Services Class.
    313   It is equivalent in functionality to the EFI Runtime Service QueryVariableInfo().
    314 
    315   @param[in]  Attributes                   Attributes bitmask to specify the type of variables
    316                                            on which to return information.
    317   @param[out] MaximumVariableStorageSize   On output the maximum size of the storage space available for
    318                                            the EFI variables associated with the attributes specified.
    319   @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space available for EFI
    320                                            variables associated with the attributes specified.
    321   @param[out] MaximumVariableSize          Returns the maximum size of an individual EFI variable
    322                                            associated with the attributes specified.
    323   @param[in]  VirtualMode                  Current calling mode for this function
    324   @param[in]  Global                       Context of this Extended SAL Variable Services Class call
    325 
    326   @retval EFI_SUCCESS                      Valid answer returned.
    327   @retval EFI_INVALID_PARAMETER            An invalid combination of attribute bits was supplied.
    328   @retval EFI_UNSUPPORTED                  The attribute is not supported on this platform, and the
    329                                            MaximumVariableStorageSize, RemainingVariableStorageSize,
    330                                            MaximumVariableSize are undefined.
    331 **/
    332 EFI_STATUS
    333 EFIAPI
    334 EsalQueryVariableInfo (
    335   IN  UINT32                 Attributes,
    336   OUT UINT64                 *MaximumVariableStorageSize,
    337   OUT UINT64                 *RemainingVariableStorageSize,
    338   OUT UINT64                 *MaximumVariableSize,
    339   IN  BOOLEAN                VirtualMode,
    340   IN  ESAL_VARIABLE_GLOBAL   *Global
    341   );
    342 
    343 /**
    344   Writes a buffer to variable storage space.
    345 
    346   This function writes a buffer to variable storage space into firmware
    347   volume block device. The destination is specified by parameter
    348   VariableBase. Fault Tolerant Write protocol is used for writing.
    349 
    350   @param[in] VariableBase The base address of the variable to write.
    351   @param[in] Buffer       Points to the data buffer.
    352   @param[in] BufferSize   The number of bytes of the data Buffer.
    353 
    354   @retval EFI_SUCCESS     The function completed successfully.
    355   @retval EFI_NOT_FOUND   Fail to locate Fault Tolerant Write protocol.
    356   @retval Other           The function could not complete successfully.
    357 
    358 **/
    359 EFI_STATUS
    360 FtwVariableSpace (
    361   IN EFI_PHYSICAL_ADDRESS   VariableBase,
    362   IN UINT8                  *Buffer,
    363   IN UINTN                  BufferSize
    364   );
    365 
    366 /**
    367   Finds variable in volatile and non-volatile storage areas.
    368 
    369   This code finds variable in volatile and non-volatile storage areas.
    370   If VariableName is an empty string, then we just return the first
    371   qualified variable without comparing VariableName and VendorGuid.
    372   Otherwise, VariableName and VendorGuid are compared.
    373 
    374   @param[in]  VariableName            Name of the variable to be found.
    375   @param[in]  VendorGuid              Vendor GUID to be found.
    376   @param[out] PtrTrack                VARIABLE_POINTER_TRACK structure for output,
    377                                       including the range searched and the target position.
    378   @param[in]  Global                  Pointer to VARIABLE_GLOBAL structure, including
    379                                       base of volatile variable storage area, base of
    380                                       NV variable storage area, and a lock.
    381   @param[in]  Instance                Instance of FV Block services.
    382 
    383   @retval EFI_INVALID_PARAMETER       If VariableName is not an empty string, while
    384                                       VendorGuid is NULL.
    385   @retval EFI_SUCCESS                 Variable successfully found.
    386   @retval EFI_INVALID_PARAMETER       Variable not found.
    387 
    388 **/
    389 EFI_STATUS
    390 FindVariable (
    391   IN  CHAR16                  *VariableName,
    392   IN  EFI_GUID                *VendorGuid,
    393   OUT VARIABLE_POINTER_TRACK  *PtrTrack,
    394   IN  VARIABLE_GLOBAL         *Global,
    395   IN  UINTN                   Instance
    396   );
    397 
    398 /**
    399   Gets the pointer to variable data area.
    400 
    401   This function gets the pointer to variable data area.
    402   The variable is specified by its variable header.
    403 
    404   @param[in]  VariableAddress    Start address of variable header.
    405   @param[in]  Volatile           TRUE  - Variable is volatile.
    406                                  FALSE - Variable is non-volatile.
    407   @param[in]  Global             Pointer to VARAIBLE_GLOBAL structure.
    408   @param[in]  Instance           Instance of FV Block services.
    409   @param[out] VariableData       Buffer to hold variable data for output.
    410 
    411 **/
    412 VOID
    413 GetVariableDataPtr (
    414   IN  EFI_PHYSICAL_ADDRESS   VariableAddress,
    415   IN  BOOLEAN                Volatile,
    416   IN  VARIABLE_GLOBAL        *Global,
    417   IN  UINTN                  Instance,
    418   OUT CHAR16                 *VariableData
    419   );
    420 
    421 /**
    422   Gets the size of variable data area.
    423 
    424   This function gets the size of variable data area.
    425   The variable is specified by its variable header.
    426   If variable header contains raw data, just return 0.
    427 
    428   @param[in]  Variable  Pointer to the variable header.
    429 
    430   @return               Size of variable data area in bytes.
    431 
    432 **/
    433 UINTN
    434 DataSizeOfVariable (
    435   IN  AUTHENTICATED_VARIABLE_HEADER     *Variable
    436   );
    437 
    438 /**
    439   Update the variable region with Variable information. These are the same
    440   arguments as the EFI Variable services.
    441 
    442   @param[in] VariableName       Name of variable.
    443   @param[in] VendorGuid         Guid of variable.
    444   @param[in] Data               Variable data.
    445   @param[in] DataSize           Size of data. 0 means delete.
    446   @param[in] Attributes         Attributes of the variable.
    447   @param[in] KeyIndex           Index of associated public key.
    448   @param[in] MonotonicCount     Value of associated monotonic count.
    449   @param[in] VirtualMode        Current calling mode for this function.
    450   @param[in] Global             Context of this Extended SAL Variable Services Class call.
    451   @param[in] Variable           The variable information which is used to keep track of variable usage.
    452 
    453   @retval EFI_SUCCESS           The update operation is success.
    454   @retval EFI_OUT_OF_RESOURCES  Variable region is full, can not write other data into this region.
    455 
    456 **/
    457 EFI_STATUS
    458 EFIAPI
    459 UpdateVariable (
    460   IN      CHAR16                  *VariableName,
    461   IN      EFI_GUID                *VendorGuid,
    462   IN      VOID                    *Data,
    463   IN      UINTN                   DataSize,
    464   IN      UINT32                  Attributes OPTIONAL,
    465   IN      UINT32                  KeyIndex  OPTIONAL,
    466   IN      UINT64                  MonotonicCount  OPTIONAL,
    467   IN      BOOLEAN                 VirtualMode,
    468   IN      ESAL_VARIABLE_GLOBAL    *Global,
    469   IN      VARIABLE_POINTER_TRACK  *Variable
    470   );
    471 
    472 /**
    473   Checks variable header.
    474 
    475   This function checks if variable header is valid or not.
    476 
    477   @param[in]  VariableAddress    Start address of variable header.
    478   @param[in]  Volatile           TRUE  - Variable is volatile.
    479                                  FALSE - Variable is non-volatile.
    480   @param[in]  Global             Pointer to VARAIBLE_GLOBAL structure.
    481   @param[in]  Instance           Instance of FV Block services.
    482   @param[out] VariableHeader     Pointer to AUTHENTICATED_VARIABLE_HEADER for output.
    483 
    484   @retval TRUE                   Variable header is valid.
    485   @retval FALSE                  Variable header is not valid.
    486 
    487 **/
    488 BOOLEAN
    489 IsValidVariableHeader (
    490   IN  EFI_PHYSICAL_ADDRESS              VariableAddress,
    491   IN  BOOLEAN                           Volatile,
    492   IN  VARIABLE_GLOBAL                   *Global,
    493   IN  UINTN                             Instance,
    494   OUT AUTHENTICATED_VARIABLE_HEADER     *VariableHeader  OPTIONAL
    495   );
    496 
    497 /**
    498   Flush the HOB variable to NV variable storage.
    499 **/
    500 VOID
    501 FlushHob2Nv (
    502   VOID
    503   );
    504 
    505 #endif
    506