Home | History | Annotate | Download | only in SecureBootConfigDxe
      1 /** @file
      2   The header file of HII Config Access protocol implementation of SecureBoot
      3   configuration module.
      4 
      5 Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #ifndef __SECUREBOOT_CONFIG_IMPL_H__
     17 #define __SECUREBOOT_CONFIG_IMPL_H__
     18 
     19 #include <Uefi.h>
     20 
     21 #include <Protocol/HiiConfigAccess.h>
     22 #include <Protocol/HiiConfigRouting.h>
     23 #include <Protocol/SimpleFileSystem.h>
     24 #include <Protocol/BlockIo.h>
     25 #include <Protocol/DevicePath.h>
     26 #include <Protocol/DebugPort.h>
     27 #include <Protocol/LoadFile.h>
     28 
     29 #include <Library/BaseLib.h>
     30 #include <Library/BaseMemoryLib.h>
     31 #include <Library/DebugLib.h>
     32 #include <Library/MemoryAllocationLib.h>
     33 #include <Library/UefiBootServicesTableLib.h>
     34 #include <Library/UefiRuntimeServicesTableLib.h>
     35 #include <Library/UefiHiiServicesLib.h>
     36 #include <Library/UefiLib.h>
     37 #include <Library/HiiLib.h>
     38 #include <Library/DevicePathLib.h>
     39 #include <Library/PrintLib.h>
     40 #include <Library/PlatformSecureLib.h>
     41 #include <Library/BaseCryptLib.h>
     42 #include <Library/FileExplorerLib.h>
     43 #include <Library/PeCoffLib.h>
     44 
     45 #include <Guid/MdeModuleHii.h>
     46 #include <Guid/AuthenticatedVariableFormat.h>
     47 #include <Guid/FileSystemVolumeLabelInfo.h>
     48 #include <Guid/ImageAuthentication.h>
     49 #include <Guid/FileInfo.h>
     50 
     51 #include "SecureBootConfigNvData.h"
     52 
     53 //
     54 // Tool generated IFR binary data and String package data
     55 //
     56 extern  UINT8                      SecureBootConfigBin[];
     57 extern  UINT8                      SecureBootConfigDxeStrings[];
     58 
     59 //
     60 // Shared IFR form update data
     61 //
     62 extern  VOID                       *mStartOpCodeHandle;
     63 extern  VOID                       *mEndOpCodeHandle;
     64 extern  EFI_IFR_GUID_LABEL         *mStartLabel;
     65 extern  EFI_IFR_GUID_LABEL         *mEndLabel;
     66 
     67 #define MAX_CHAR              480
     68 #define TWO_BYTE_ENCODE       0x82
     69 
     70 //
     71 // SHA-1 digest size in bytes.
     72 //
     73 #define SHA1_DIGEST_SIZE    20
     74 //
     75 // SHA-256 digest size in bytes
     76 //
     77 #define SHA256_DIGEST_SIZE  32
     78 //
     79 // SHA-384 digest size in bytes
     80 //
     81 #define SHA384_DIGEST_SIZE  48
     82 //
     83 // SHA-512 digest size in bytes
     84 //
     85 #define SHA512_DIGEST_SIZE  64
     86 
     87 //
     88 // Set max digest size as SHA512 Output (64 bytes) by far
     89 //
     90 #define MAX_DIGEST_SIZE    SHA512_DIGEST_SIZE
     91 
     92 #define WIN_CERT_UEFI_RSA2048_SIZE               256
     93 
     94 //
     95 // Support hash types
     96 //
     97 #define HASHALG_SHA1                           0x00000000
     98 #define HASHALG_SHA224                         0x00000001
     99 #define HASHALG_SHA256                         0x00000002
    100 #define HASHALG_SHA384                         0x00000003
    101 #define HASHALG_SHA512                         0x00000004
    102 #define HASHALG_RAW                            0x00000005
    103 #define HASHALG_MAX                            0x00000005
    104 
    105 
    106 typedef struct {
    107   UINTN             Signature;
    108   LIST_ENTRY        Head;
    109   UINTN             MenuNumber;
    110 } SECUREBOOT_MENU_OPTION;
    111 
    112 typedef struct {
    113   EFI_FILE_HANDLE                   FHandle;
    114   UINT16                            *FileName;
    115 } SECUREBOOT_FILE_CONTEXT;
    116 
    117 
    118 //
    119 // We define another format of 5th directory entry: security directory
    120 //
    121 typedef struct {
    122   UINT32               Offset;      // Offset of certificate
    123   UINT32               SizeOfCert;  // size of certificate appended
    124 } EFI_IMAGE_SECURITY_DATA_DIRECTORY;
    125 
    126 typedef enum{
    127   ImageType_IA32,
    128   ImageType_X64
    129 } IMAGE_TYPE;
    130 
    131 ///
    132 /// HII specific Vendor Device Path definition.
    133 ///
    134 typedef struct {
    135   VENDOR_DEVICE_PATH                VendorDevicePath;
    136   EFI_DEVICE_PATH_PROTOCOL          End;
    137 } HII_VENDOR_DEVICE_PATH;
    138 
    139 typedef struct {
    140   UINTN                             Signature;
    141 
    142   EFI_HII_CONFIG_ACCESS_PROTOCOL    ConfigAccess;
    143   EFI_HII_HANDLE                    HiiHandle;
    144   EFI_HANDLE                        DriverHandle;
    145 
    146   SECUREBOOT_FILE_CONTEXT           *FileContext;
    147 
    148   EFI_GUID                          *SignatureGUID;
    149 } SECUREBOOT_CONFIG_PRIVATE_DATA;
    150 
    151 extern SECUREBOOT_CONFIG_PRIVATE_DATA      mSecureBootConfigPrivateDateTemplate;
    152 extern SECUREBOOT_CONFIG_PRIVATE_DATA      *gSecureBootPrivateData;
    153 
    154 #define SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE     SIGNATURE_32 ('S', 'E', 'C', 'B')
    155 #define SECUREBOOT_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, SECUREBOOT_CONFIG_PRIVATE_DATA, ConfigAccess, SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE)
    156 
    157 //
    158 // Cryptograhpic Key Information
    159 //
    160 #pragma pack(1)
    161 typedef struct _CPL_KEY_INFO {
    162   UINT32        KeyLengthInBits;    // Key Length In Bits
    163   UINT32        BlockSize;          // Operation Block Size in Bytes
    164   UINT32        CipherBlockSize;    // Output Cipher Block Size in Bytes
    165   UINT32        KeyType;            // Key Type
    166   UINT32        CipherMode;         // Cipher Mode for Symmetric Algorithm
    167   UINT32        Flags;              // Additional Key Property Flags
    168 } CPL_KEY_INFO;
    169 #pragma pack()
    170 
    171 
    172 /**
    173   Retrieves the size, in bytes, of the context buffer required for hash operations.
    174 
    175   @return  The size, in bytes, of the context buffer required for hash operations.
    176 
    177 **/
    178 typedef
    179 EFI_STATUS
    180 (EFIAPI *HASH_GET_CONTEXT_SIZE)(
    181   VOID
    182   );
    183 
    184 /**
    185   Initializes user-supplied memory pointed by HashContext as hash context for
    186   subsequent use.
    187 
    188   If HashContext is NULL, then ASSERT().
    189 
    190   @param[in, out]  HashContext  Pointer to  Context being initialized.
    191 
    192   @retval TRUE   HASH context initialization succeeded.
    193   @retval FALSE  HASH context initialization failed.
    194 
    195 **/
    196 typedef
    197 BOOLEAN
    198 (EFIAPI *HASH_INIT)(
    199   IN OUT  VOID  *HashContext
    200   );
    201 
    202 
    203 /**
    204   Performs digest on a data buffer of the specified length. This function can
    205   be called multiple times to compute the digest of long or discontinuous data streams.
    206 
    207   If HashContext is NULL, then ASSERT().
    208 
    209   @param[in, out]  HashContext  Pointer to the MD5 context.
    210   @param[in]       Data        Pointer to the buffer containing the data to be hashed.
    211   @param[in]       DataLength  Length of Data buffer in bytes.
    212 
    213   @retval TRUE   HASH data digest succeeded.
    214   @retval FALSE  Invalid HASH context. After HashFinal function has been called, the
    215                  HASH context cannot be reused.
    216 
    217 **/
    218 typedef
    219 BOOLEAN
    220 (EFIAPI *HASH_UPDATE)(
    221   IN OUT  VOID        *HashContext,
    222   IN      CONST VOID  *Data,
    223   IN      UINTN       DataLength
    224   );
    225 
    226 /**
    227   Completes hash computation and retrieves the digest value into the specified
    228   memory. After this function has been called, the context cannot be used again.
    229 
    230   If HashContext is NULL, then ASSERT().
    231   If HashValue is NULL, then ASSERT().
    232 
    233   @param[in, out]  HashContext  Pointer to the MD5 context
    234   @param[out]      HashValue   Pointer to a buffer that receives the HASH digest
    235                                value (16 bytes).
    236 
    237   @retval TRUE   HASH digest computation succeeded.
    238   @retval FALSE  HASH digest computation failed.
    239 
    240 **/
    241 typedef
    242 BOOLEAN
    243 (EFIAPI *HASH_FINAL)(
    244   IN OUT  VOID   *HashContext,
    245   OUT     UINT8  *HashValue
    246   );
    247 
    248 //
    249 // Hash Algorithm Table
    250 //
    251 typedef struct {
    252   CHAR16                   *Name;           ///< Name for Hash Algorithm
    253   UINTN                    DigestLength;    ///< Digest Length
    254   UINT8                    *OidValue;       ///< Hash Algorithm OID ASN.1 Value
    255   UINTN                    OidLength;       ///< Length of Hash OID Value
    256   HASH_GET_CONTEXT_SIZE    GetContextSize;  ///< Pointer to Hash GetContentSize function
    257   HASH_INIT                HashInit;        ///< Pointer to Hash Init function
    258   HASH_UPDATE              HashUpdate;      ///< Pointer to Hash Update function
    259   HASH_FINAL               HashFinal;       ///< Pointer to Hash Final function
    260 } HASH_TABLE;
    261 
    262 typedef struct {
    263   WIN_CERTIFICATE Hdr;
    264   UINT8           CertData[1];
    265 } WIN_CERTIFICATE_EFI_PKCS;
    266 
    267 
    268 /**
    269   This function publish the SecureBoot configuration Form.
    270 
    271   @param[in, out]  PrivateData   Points to SecureBoot configuration private data.
    272 
    273   @retval EFI_SUCCESS            HII Form is installed successfully.
    274   @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.
    275   @retval Others                 Other errors as indicated.
    276 
    277 **/
    278 EFI_STATUS
    279 InstallSecureBootConfigForm (
    280   IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA  *PrivateData
    281   );
    282 
    283 
    284 /**
    285   This function removes SecureBoot configuration Form.
    286 
    287   @param[in, out]  PrivateData   Points to SecureBoot configuration private data.
    288 
    289 **/
    290 VOID
    291 UninstallSecureBootConfigForm (
    292   IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA    *PrivateData
    293   );
    294 
    295 
    296 /**
    297   This function allows a caller to extract the current configuration for one
    298   or more named elements from the target driver.
    299 
    300   @param[in]   This              Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    301   @param[in]   Request           A null-terminated Unicode string in
    302                                  <ConfigRequest> format.
    303   @param[out]  Progress          On return, points to a character in the Request
    304                                  string. Points to the string's null terminator if
    305                                  request was successful. Points to the most recent
    306                                  '&' before the first failing name/value pair (or
    307                                  the beginning of the string if the failure is in
    308                                  the first name/value pair) if the request was not
    309                                  successful.
    310   @param[out]  Results           A null-terminated Unicode string in
    311                                  <ConfigAltResp> format which has all values filled
    312                                  in for the names in the Request string. String to
    313                                  be allocated by the called function.
    314 
    315   @retval EFI_SUCCESS            The Results is filled with the requested values.
    316   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
    317   @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
    318   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
    319                                  driver.
    320 
    321 **/
    322 EFI_STATUS
    323 EFIAPI
    324 SecureBootExtractConfig (
    325   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL        *This,
    326   IN CONST EFI_STRING                            Request,
    327        OUT EFI_STRING                            *Progress,
    328        OUT EFI_STRING                            *Results
    329   );
    330 
    331 
    332 /**
    333   This function processes the results of changes in configuration.
    334 
    335   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    336   @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>
    337                                  format.
    338   @param[out] Progress           A pointer to a string filled in with the offset of
    339                                  the most recent '&' before the first failing
    340                                  name/value pair (or the beginning of the string if
    341                                  the failure is in the first name/value pair) or
    342                                  the terminating NULL if all was successful.
    343 
    344   @retval EFI_SUCCESS            The Results is processed successfully.
    345   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
    346   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
    347                                  driver.
    348 
    349 **/
    350 EFI_STATUS
    351 EFIAPI
    352 SecureBootRouteConfig (
    353   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
    354   IN CONST EFI_STRING                          Configuration,
    355        OUT EFI_STRING                          *Progress
    356   );
    357 
    358 
    359 /**
    360   This function processes the results of changes in configuration.
    361 
    362   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    363   @param[in]  Action             Specifies the type of action taken by the browser.
    364   @param[in]  QuestionId         A unique value which is sent to the original
    365                                  exporting driver so that it can identify the type
    366                                  of data to expect.
    367   @param[in]  Type               The type of value for the question.
    368   @param[in]  Value              A pointer to the data being sent to the original
    369                                  exporting driver.
    370   @param[out] ActionRequest      On return, points to the action requested by the
    371                                  callback function.
    372 
    373   @retval EFI_SUCCESS            The callback successfully handled the action.
    374   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
    375                                  variable and its data.
    376   @retval EFI_DEVICE_ERROR       The variable could not be saved.
    377   @retval EFI_UNSUPPORTED        The specified Action is not supported by the
    378                                  callback.
    379 
    380 **/
    381 EFI_STATUS
    382 EFIAPI
    383 SecureBootCallback (
    384   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
    385   IN     EFI_BROWSER_ACTION                    Action,
    386   IN     EFI_QUESTION_ID                       QuestionId,
    387   IN     UINT8                                 Type,
    388   IN     EFI_IFR_TYPE_VALUE                    *Value,
    389      OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
    390   );
    391 
    392 
    393 /**
    394   This function converts an input device structure to a Unicode string.
    395 
    396   @param[in] DevPath                  A pointer to the device path structure.
    397 
    398   @return A new allocated Unicode string that represents the device path.
    399 
    400 **/
    401 CHAR16 *
    402 EFIAPI
    403 DevicePathToStr (
    404   IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
    405   );
    406 
    407 
    408 /**
    409   Clean up the dynamic opcode at label and form specified by both LabelId.
    410 
    411   @param[in] LabelId         It is both the Form ID and Label ID for opcode deletion.
    412   @param[in] PrivateData     Module private data.
    413 
    414 **/
    415 VOID
    416 CleanUpPage (
    417   IN UINT16                           LabelId,
    418   IN SECUREBOOT_CONFIG_PRIVATE_DATA   *PrivateData
    419   );
    420 
    421 
    422 /**
    423   Read file content into BufferPtr, the size of the allocate buffer
    424   is *FileSize plus AddtionAllocateSize.
    425 
    426   @param[in]       FileHandle            The file to be read.
    427   @param[in, out]  BufferPtr             Pointers to the pointer of allocated buffer.
    428   @param[out]      FileSize              Size of input file
    429   @param[in]       AddtionAllocateSize   Addtion size the buffer need to be allocated.
    430                                          In case the buffer need to contain others besides the file content.
    431 
    432   @retval   EFI_SUCCESS                  The file was read into the buffer.
    433   @retval   EFI_INVALID_PARAMETER        A parameter was invalid.
    434   @retval   EFI_OUT_OF_RESOURCES         A memory allocation failed.
    435   @retval   others                       Unexpected error.
    436 
    437 **/
    438 EFI_STATUS
    439 ReadFileContent (
    440   IN      EFI_FILE_HANDLE           FileHandle,
    441   IN OUT  VOID                      **BufferPtr,
    442      OUT  UINTN                     *FileSize,
    443   IN      UINTN                     AddtionAllocateSize
    444   );
    445 
    446 
    447 /**
    448   Close an open file handle.
    449 
    450   @param[in] FileHandle           The file handle to close.
    451 
    452 **/
    453 VOID
    454 CloseFile (
    455   IN EFI_FILE_HANDLE   FileHandle
    456   );
    457 
    458 
    459 /**
    460   Converts a nonnegative integer to an octet string of a specified length.
    461 
    462   @param[in]   Integer          Pointer to the nonnegative integer to be converted
    463   @param[in]   IntSizeInWords   Length of integer buffer in words
    464   @param[out]  OctetString      Converted octet string of the specified length
    465   @param[in]   OSSizeInBytes    Intended length of resulting octet string in bytes
    466 
    467 Returns:
    468 
    469   @retval   EFI_SUCCESS            Data conversion successfully
    470   @retval   EFI_BUFFER_TOOL_SMALL  Buffer is too small for output string
    471 
    472 **/
    473 EFI_STATUS
    474 EFIAPI
    475 Int2OctStr (
    476   IN     CONST UINTN       *Integer,
    477   IN     UINTN             IntSizeInWords,
    478      OUT UINT8             *OctetString,
    479   IN     UINTN             OSSizeInBytes
    480   );
    481 
    482 
    483 /**
    484   Convert a String to Guid Value.
    485 
    486   @param[in]   Str        Specifies the String to be converted.
    487   @param[in]   StrLen     Number of Unicode Characters of String (exclusive \0)
    488   @param[out]  Guid       Return the result Guid value.
    489 
    490   @retval    EFI_SUCCESS           The operation is finished successfully.
    491   @retval    EFI_NOT_FOUND         Invalid string.
    492 
    493 **/
    494 EFI_STATUS
    495 StringToGuid (
    496   IN   CHAR16           *Str,
    497   IN   UINTN            StrLen,
    498   OUT  EFI_GUID         *Guid
    499   );
    500 
    501 
    502 /**
    503   Worker function that prints an EFI_GUID into specified Buffer.
    504 
    505   @param[in]     Guid          Pointer to GUID to print.
    506   @param[in]     Buffer        Buffer to print Guid into.
    507   @param[in]     BufferSize    Size of Buffer.
    508 
    509   @retval    Number of characters printed.
    510 
    511 **/
    512 UINTN
    513 GuidToString (
    514   IN  EFI_GUID  *Guid,
    515   IN  CHAR16    *Buffer,
    516   IN  UINTN     BufferSize
    517   );
    518 
    519 /**
    520   Update the PK form base on the input file path info.
    521 
    522   @param FilePath    Point to the file path.
    523 
    524   @retval TRUE   Exit caller function.
    525   @retval FALSE  Not exit caller function.
    526 **/
    527 BOOLEAN
    528 EFIAPI
    529 UpdatePKFromFile (
    530   IN EFI_DEVICE_PATH_PROTOCOL    *FilePath
    531   );
    532 
    533 /**
    534   Update the KEK form base on the input file path info.
    535 
    536   @param FilePath    Point to the file path.
    537 
    538   @retval TRUE   Exit caller function.
    539   @retval FALSE  Not exit caller function.
    540 **/
    541 BOOLEAN
    542 EFIAPI
    543 UpdateKEKFromFile (
    544   IN EFI_DEVICE_PATH_PROTOCOL    *FilePath
    545   );
    546 
    547 /**
    548   Update the DB form base on the input file path info.
    549 
    550   @param FilePath    Point to the file path.
    551 
    552   @retval TRUE   Exit caller function.
    553   @retval FALSE  Not exit caller function.
    554 **/
    555 BOOLEAN
    556 EFIAPI
    557 UpdateDBFromFile (
    558   IN EFI_DEVICE_PATH_PROTOCOL    *FilePath
    559   );
    560 
    561 /**
    562   Update the DBX form base on the input file path info.
    563 
    564   @param FilePath    Point to the file path.
    565 
    566   @retval TRUE   Exit caller function.
    567   @retval FALSE  Not exit caller function.
    568 **/
    569 BOOLEAN
    570 EFIAPI
    571 UpdateDBXFromFile (
    572   IN EFI_DEVICE_PATH_PROTOCOL    *FilePath
    573   );
    574 
    575 /**
    576   Update the DBT form base on the input file path info.
    577 
    578   @param FilePath    Point to the file path.
    579 
    580   @retval TRUE   Exit caller function.
    581   @retval FALSE  Not exit caller function.
    582 **/
    583 BOOLEAN
    584 EFIAPI
    585 UpdateDBTFromFile (
    586   IN EFI_DEVICE_PATH_PROTOCOL    *FilePath
    587   );
    588 
    589 #endif
    590