Home | History | Annotate | Download | only in AuthVariableLib
      1 /** @file
      2   The internal header file includes the common header files, defines
      3   internal structure and functions used by AuthService module.
      4 
      5   Caution: This module requires additional review when modified.
      6   This driver will have external input - variable data. It may be input in SMM mode.
      7   This external input must be validated carefully to avoid security issue like
      8   buffer overflow, integer overflow.
      9   Variable attribute should also be checked to avoid authentication bypass.
     10      The whole SMM authentication variable design relies on the integrity of flash part and SMM.
     11   which is assumed to be protected by platform.  All variable code and metadata in flash/SMM Memory
     12   may not be modified without authorization. If platform fails to protect these resources,
     13   the authentication service provided in this driver will be broken, and the behavior is undefined.
     14 
     15 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
     16 This program and the accompanying materials
     17 are licensed and made available under the terms and conditions of the BSD License
     18 which accompanies this distribution.  The full text of the license may be found at
     19 http://opensource.org/licenses/bsd-license.php
     20 
     21 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     22 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     23 
     24 **/
     25 
     26 #ifndef _AUTHSERVICE_INTERNAL_H_
     27 #define _AUTHSERVICE_INTERNAL_H_
     28 
     29 #include <Library/AuthVariableLib.h>
     30 #include <Library/BaseLib.h>
     31 #include <Library/BaseMemoryLib.h>
     32 #include <Library/DebugLib.h>
     33 #include <Library/MemoryAllocationLib.h>
     34 #include <Library/BaseCryptLib.h>
     35 #include <Library/PlatformSecureLib.h>
     36 
     37 #include <Guid/AuthenticatedVariableFormat.h>
     38 #include <Guid/ImageAuthentication.h>
     39 
     40 ///
     41 /// Struct to record signature requirement defined by UEFI spec.
     42 /// For SigHeaderSize and SigDataSize, ((UINT32) ~0) means NO exact length requirement for this field.
     43 ///
     44 typedef struct {
     45   EFI_GUID    SigType;
     46   // Expected SignatureHeader size in Bytes.
     47   UINT32      SigHeaderSize;
     48   // Expected SignatureData size in Bytes.
     49   UINT32      SigDataSize;
     50 } EFI_SIGNATURE_ITEM;
     51 
     52 typedef enum {
     53   AuthVarTypePk,
     54   AuthVarTypeKek,
     55   AuthVarTypePriv,
     56   AuthVarTypePayload
     57 } AUTHVAR_TYPE;
     58 
     59 ///
     60 /// "AuthVarKeyDatabase" variable for the Public Key store
     61 /// of variables with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
     62 ///
     63 /// GUID: gEfiAuthenticatedVariableGuid
     64 ///
     65 /// We need maintain atomicity.
     66 ///
     67 /// Format:
     68 /// +----------------------------+
     69 /// | AUTHVAR_KEY_DB_DATA        | <-- First AuthVarKey
     70 /// +----------------------------+
     71 /// | ......                     |
     72 /// +----------------------------+
     73 /// | AUTHVAR_KEY_DB_DATA        | <-- Last AuthKey
     74 /// +----------------------------+
     75 ///
     76 #define AUTHVAR_KEYDB_NAME      L"AuthVarKeyDatabase"
     77 
     78 #define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256
     79 #define EFI_CERT_TYPE_RSA2048_SIZE        256
     80 
     81 #pragma pack(1)
     82 typedef struct {
     83   UINT32    KeyIndex;
     84   UINT8     KeyData[EFI_CERT_TYPE_RSA2048_SIZE];
     85 } AUTHVAR_KEY_DB_DATA;
     86 #pragma pack()
     87 
     88 ///
     89 /// "certdb" variable stores the signer's certificates for non PK/KEK/DB/DBX
     90 /// variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
     91 ///
     92 /// GUID: gEfiCertDbGuid
     93 ///
     94 /// We need maintain atomicity.
     95 ///
     96 /// Format:
     97 /// +----------------------------+
     98 /// | UINT32                     | <-- CertDbListSize, including this UINT32
     99 /// +----------------------------+
    100 /// | AUTH_CERT_DB_DATA          | <-- First CERT
    101 /// +----------------------------+
    102 /// | ........                   |
    103 /// +----------------------------+
    104 /// | AUTH_CERT_DB_DATA          | <-- Last CERT
    105 /// +----------------------------+
    106 ///
    107 #define EFI_CERT_DB_NAME        L"certdb"
    108 
    109 #pragma pack(1)
    110 typedef struct {
    111   EFI_GUID    VendorGuid;
    112   UINT32      CertNodeSize;
    113   UINT32      NameSize;
    114   UINT32      CertDataSize;
    115   /// CHAR16  VariableName[NameSize];
    116   /// UINT8   CertData[CertDataSize];
    117 } AUTH_CERT_DB_DATA;
    118 #pragma pack()
    119 
    120 ///
    121 /// "SecureBootMode" variable stores current secure boot mode.
    122 /// The value type is SECURE_BOOT_MODE_TYPE.
    123 ///
    124 #define EDKII_SECURE_BOOT_MODE_NAME    L"SecureBootMode"
    125 
    126 typedef enum {
    127   SecureBootModeTypeUserMode,
    128   SecureBootModeTypeSetupMode,
    129   SecureBootModeTypeAuditMode,
    130   SecureBootModeTypeDeployedMode,
    131   SecureBootModeTypeMax
    132 } SECURE_BOOT_MODE_TYPE;
    133 
    134 //
    135 // Record status info of Customized Secure Boot Mode.
    136 //
    137 typedef struct {
    138   ///
    139   /// AuditMode variable value
    140   ///
    141   UINT8   AuditMode;
    142   ///
    143   /// AuditMode variable RW
    144   ///
    145   BOOLEAN IsAuditModeRO;
    146   ///
    147   /// DeployedMode variable value
    148   ///
    149   UINT8   DeployedMode;
    150   ///
    151   /// AuditMode variable RW
    152   ///
    153   BOOLEAN IsDeployedModeRO;
    154   ///
    155   /// SetupMode variable value
    156   ///
    157   UINT8   SetupMode;
    158   ///
    159   /// SetupMode is always RO. Skip IsSetupModeRO;
    160   ///
    161 
    162   ///
    163   /// SecureBoot variable value
    164   ///
    165   UINT8   SecureBoot;
    166 } SECURE_BOOT_MODE;
    167 
    168 extern UINT8    *mPubKeyStore;
    169 extern UINT32   mPubKeyNumber;
    170 extern UINT32   mMaxKeyNumber;
    171 extern UINT32   mMaxKeyDbSize;
    172 extern UINT8    *mCertDbStore;
    173 extern UINT32   mMaxCertDbSize;
    174 extern UINT32   mPlatformMode;
    175 extern UINT8    mVendorKeyState;
    176 
    177 extern VOID     *mHashCtx;
    178 
    179 extern AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn;
    180 
    181 /**
    182   Initialize Secure Boot variables.
    183 
    184   @retval EFI_SUCCESS               The initialization operation is successful.
    185   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
    186 
    187 **/
    188 EFI_STATUS
    189 InitSecureBootVariables (
    190   VOID
    191   );
    192 
    193 /**
    194   Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
    195 
    196   Caution: This function may receive untrusted input.
    197   This function may be invoked in SMM mode, and datasize and data are external input.
    198   This function will do basic validation, before parse the data.
    199   This function will parse the authentication carefully to avoid security issues, like
    200   buffer overflow, integer overflow.
    201 
    202   @param[in]  VariableName                Name of Variable to be found.
    203   @param[in]  VendorGuid                  Variable vendor GUID.
    204   @param[in]  Data                        Data pointer.
    205   @param[in]  DataSize                    Size of Data found. If size is less than the
    206                                           data, this value contains the required size.
    207   @param[in]  Attributes                  Attribute value of the variable.
    208   @param[in]  AuthVarType                 Verify against PK, KEK database, private database or certificate in data payload.
    209   @param[out] VarDel                      Delete the variable or not.
    210 
    211   @retval EFI_INVALID_PARAMETER           Invalid parameter.
    212   @retval EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
    213                                           check carried out by the firmware.
    214   @retval EFI_OUT_OF_RESOURCES            Failed to process variable due to lack
    215                                           of resources.
    216   @retval EFI_SUCCESS                     Variable pass validation successfully.
    217 
    218 **/
    219 EFI_STATUS
    220 VerifyTimeBasedPayloadAndUpdate (
    221   IN     CHAR16                             *VariableName,
    222   IN     EFI_GUID                           *VendorGuid,
    223   IN     VOID                               *Data,
    224   IN     UINTN                              DataSize,
    225   IN     UINT32                             Attributes,
    226   IN     AUTHVAR_TYPE                       AuthVarType,
    227   OUT    BOOLEAN                            *VarDel
    228   );
    229 
    230 /**
    231   Delete matching signer's certificates when deleting common authenticated
    232   variable by corresponding VariableName and VendorGuid from "certdb".
    233 
    234   @param[in]  VariableName   Name of authenticated Variable.
    235   @param[in]  VendorGuid     Vendor GUID of authenticated Variable.
    236 
    237   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
    238   @retval  EFI_NOT_FOUND         Fail to find "certdb" or matching certs.
    239   @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.
    240   @retval  EFI_SUCCESS           The operation is completed successfully.
    241 
    242 **/
    243 EFI_STATUS
    244 DeleteCertsFromDb (
    245   IN     CHAR16           *VariableName,
    246   IN     EFI_GUID         *VendorGuid
    247   );
    248 
    249 /**
    250   Clean up signer's certificates for common authenticated variable
    251   by corresponding VariableName and VendorGuid from "certdb".
    252   Sytem may break down during Timebased Variable update & certdb update,
    253   make them inconsistent,  this function is called in AuthVariable Init to ensure
    254   consistency
    255 
    256   @retval  EFI_NOT_FOUND         Fail to find matching certs.
    257   @retval  EFI_SUCCESS           Find matching certs and output parameters.
    258 
    259 **/
    260 EFI_STATUS
    261 CleanCertsFromDb (
    262   VOID
    263   );
    264 
    265 /**
    266   Filter out the duplicated EFI_SIGNATURE_DATA from the new data by comparing to the original data.
    267 
    268   @param[in]        Data          Pointer to original EFI_SIGNATURE_LIST.
    269   @param[in]        DataSize      Size of Data buffer.
    270   @param[in, out]   NewData       Pointer to new EFI_SIGNATURE_LIST.
    271   @param[in, out]   NewDataSize   Size of NewData buffer.
    272 
    273 **/
    274 EFI_STATUS
    275 FilterSignatureList (
    276   IN     VOID       *Data,
    277   IN     UINTN      DataSize,
    278   IN OUT VOID       *NewData,
    279   IN OUT UINTN      *NewDataSize
    280   );
    281 
    282 /**
    283   Process Secure Boot Mode variable.
    284 
    285   Caution: This function may receive untrusted input.
    286   This function may be invoked in SMM mode, and datasize and data are external input.
    287   This function will do basic validation, before parse the data.
    288   This function will parse the authentication carefully to avoid security issues, like
    289   buffer overflow, integer overflow.
    290   This function will check attribute carefully to avoid authentication bypass.
    291 
    292   @param[in]  VariableName                Name of Variable to be found.
    293   @param[in]  VendorGuid                  Variable vendor GUID.
    294   @param[in]  Data                        Data pointer.
    295   @param[in]  DataSize                    Size of Data found. If size is less than the
    296                                           data, this value contains the required size.
    297   @param[in]  Attributes                  Attribute value of the variable
    298 
    299   @return EFI_INVALID_PARAMETER           Invalid parameter
    300   @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
    301                                           check carried out by the firmware.
    302   @return EFI_WRITE_PROTECTED             Variable is Read-Only.
    303   @return EFI_SUCCESS                     Variable passed validation successfully.
    304 
    305 **/
    306 EFI_STATUS
    307 ProcessSecureBootModeVar (
    308   IN  CHAR16         *VariableName,
    309   IN  EFI_GUID       *VendorGuid,
    310   IN  VOID           *Data,
    311   IN  UINTN          DataSize,
    312   IN  UINT32         Attributes OPTIONAL
    313   );
    314 
    315 /**
    316   Process variable with platform key for verification.
    317 
    318   Caution: This function may receive untrusted input.
    319   This function may be invoked in SMM mode, and datasize and data are external input.
    320   This function will do basic validation, before parse the data.
    321   This function will parse the authentication carefully to avoid security issues, like
    322   buffer overflow, integer overflow.
    323   This function will check attribute carefully to avoid authentication bypass.
    324 
    325   @param[in]  VariableName                Name of Variable to be found.
    326   @param[in]  VendorGuid                  Variable vendor GUID.
    327   @param[in]  Data                        Data pointer.
    328   @param[in]  DataSize                    Size of Data found. If size is less than the
    329                                           data, this value contains the required size.
    330   @param[in]  Attributes                  Attribute value of the variable
    331   @param[in]  IsPk                        Indicate whether it is to process pk.
    332 
    333   @return EFI_INVALID_PARAMETER           Invalid parameter.
    334   @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation.
    335                                           check carried out by the firmware.
    336   @return EFI_SUCCESS                     Variable passed validation successfully.
    337 
    338 **/
    339 EFI_STATUS
    340 ProcessVarWithPk (
    341   IN  CHAR16                    *VariableName,
    342   IN  EFI_GUID                  *VendorGuid,
    343   IN  VOID                      *Data,
    344   IN  UINTN                     DataSize,
    345   IN  UINT32                    Attributes OPTIONAL,
    346   IN  BOOLEAN                   IsPk
    347   );
    348 
    349 /**
    350   Process variable with key exchange key for verification.
    351 
    352   Caution: This function may receive untrusted input.
    353   This function may be invoked in SMM mode, and datasize and data are external input.
    354   This function will do basic validation, before parse the data.
    355   This function will parse the authentication carefully to avoid security issues, like
    356   buffer overflow, integer overflow.
    357   This function will check attribute carefully to avoid authentication bypass.
    358 
    359   @param[in]  VariableName                Name of Variable to be found.
    360   @param[in]  VendorGuid                  Variable vendor GUID.
    361   @param[in]  Data                        Data pointer.
    362   @param[in]  DataSize                    Size of Data found. If size is less than the
    363                                           data, this value contains the required size.
    364   @param[in]  Attributes                  Attribute value of the variable.
    365 
    366   @return EFI_INVALID_PARAMETER           Invalid parameter.
    367   @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
    368                                           check carried out by the firmware.
    369   @return EFI_SUCCESS                     Variable pass validation successfully.
    370 
    371 **/
    372 EFI_STATUS
    373 ProcessVarWithKek (
    374   IN  CHAR16                               *VariableName,
    375   IN  EFI_GUID                             *VendorGuid,
    376   IN  VOID                                 *Data,
    377   IN  UINTN                                DataSize,
    378   IN  UINT32                               Attributes OPTIONAL
    379   );
    380 
    381 /**
    382   Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
    383 
    384   Caution: This function may receive untrusted input.
    385   This function may be invoked in SMM mode, and datasize and data are external input.
    386   This function will do basic validation, before parse the data.
    387   This function will parse the authentication carefully to avoid security issues, like
    388   buffer overflow, integer overflow.
    389   This function will check attribute carefully to avoid authentication bypass.
    390 
    391   @param[in]  VariableName                Name of the variable.
    392   @param[in]  VendorGuid                  Variable vendor GUID.
    393   @param[in]  Data                        Data pointer.
    394   @param[in]  DataSize                    Size of Data.
    395   @param[in]  Attributes                  Attribute value of the variable.
    396 
    397   @return EFI_INVALID_PARAMETER           Invalid parameter.
    398   @return EFI_WRITE_PROTECTED             Variable is write-protected and needs authentication with
    399                                           EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
    400   @return EFI_OUT_OF_RESOURCES            The Database to save the public key is full.
    401   @return EFI_SECURITY_VIOLATION          The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
    402                                           set, but the AuthInfo does NOT pass the validation
    403                                           check carried out by the firmware.
    404   @return EFI_SUCCESS                     Variable is not write-protected or pass validation successfully.
    405 
    406 **/
    407 EFI_STATUS
    408 ProcessVariable (
    409   IN     CHAR16                             *VariableName,
    410   IN     EFI_GUID                           *VendorGuid,
    411   IN     VOID                               *Data,
    412   IN     UINTN                              DataSize,
    413   IN     UINT32                             Attributes OPTIONAL
    414   );
    415 
    416 /**
    417   Finds variable in storage blocks of volatile and non-volatile storage areas.
    418 
    419   This code finds variable in storage blocks of volatile and non-volatile storage areas.
    420   If VariableName is an empty string, then we just return the first
    421   qualified variable without comparing VariableName and VendorGuid.
    422 
    423   @param[in]  VariableName          Name of the variable to be found.
    424   @param[in]  VendorGuid            Variable vendor GUID to be found.
    425   @param[out] Data                  Pointer to data address.
    426   @param[out] DataSize              Pointer to data size.
    427 
    428   @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
    429                                     while VendorGuid is NULL.
    430   @retval EFI_SUCCESS               Variable successfully found.
    431   @retval EFI_NOT_FOUND             Variable not found
    432 
    433 **/
    434 EFI_STATUS
    435 AuthServiceInternalFindVariable (
    436   IN  CHAR16        *VariableName,
    437   IN  EFI_GUID      *VendorGuid,
    438   OUT VOID          **Data,
    439   OUT UINTN         *DataSize
    440   );
    441 
    442 /**
    443   Update the variable region with Variable information.
    444 
    445   @param[in] VariableName           Name of variable.
    446   @param[in] VendorGuid             Guid of variable.
    447   @param[in] Data                   Data pointer.
    448   @param[in] DataSize               Size of Data.
    449   @param[in] Attributes             Attribute value of the variable.
    450 
    451   @retval EFI_SUCCESS               The update operation is success.
    452   @retval EFI_INVALID_PARAMETER     Invalid parameter.
    453   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
    454   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
    455 
    456 **/
    457 EFI_STATUS
    458 AuthServiceInternalUpdateVariable (
    459   IN CHAR16         *VariableName,
    460   IN EFI_GUID       *VendorGuid,
    461   IN VOID           *Data,
    462   IN UINTN          DataSize,
    463   IN UINT32         Attributes
    464   );
    465 
    466 /**
    467   Update the variable region with Variable information.
    468 
    469   @param[in] VariableName           Name of variable.
    470   @param[in] VendorGuid             Guid of variable.
    471   @param[in] Data                   Data pointer.
    472   @param[in] DataSize               Size of Data.
    473   @param[in] Attributes             Attribute value of the variable.
    474   @param[in] KeyIndex               Index of associated public key.
    475   @param[in] MonotonicCount         Value of associated monotonic count.
    476 
    477   @retval EFI_SUCCESS               The update operation is success.
    478   @retval EFI_INVALID_PARAMETER     Invalid parameter.
    479   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
    480   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
    481 
    482 **/
    483 EFI_STATUS
    484 AuthServiceInternalUpdateVariableWithMonotonicCount (
    485   IN CHAR16         *VariableName,
    486   IN EFI_GUID       *VendorGuid,
    487   IN VOID           *Data,
    488   IN UINTN          DataSize,
    489   IN UINT32         Attributes,
    490   IN UINT32         KeyIndex,
    491   IN UINT64         MonotonicCount
    492   );
    493 
    494 /**
    495   Update the variable region with Variable information.
    496 
    497   @param[in] VariableName           Name of variable.
    498   @param[in] VendorGuid             Guid of variable.
    499   @param[in] Data                   Data pointer.
    500   @param[in] DataSize               Size of Data.
    501   @param[in] Attributes             Attribute value of the variable.
    502   @param[in] TimeStamp              Value of associated TimeStamp.
    503 
    504   @retval EFI_SUCCESS               The update operation is success.
    505   @retval EFI_INVALID_PARAMETER     Invalid parameter.
    506   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
    507   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
    508 
    509 **/
    510 EFI_STATUS
    511 AuthServiceInternalUpdateVariableWithTimeStamp (
    512   IN CHAR16         *VariableName,
    513   IN EFI_GUID       *VendorGuid,
    514   IN VOID           *Data,
    515   IN UINTN          DataSize,
    516   IN UINT32         Attributes,
    517   IN EFI_TIME       *TimeStamp
    518   );
    519 
    520 #endif
    521