| /** @file | |
| The header file of HII Config Access protocol implementation of SecureBoot | |
| configuration module. | |
| Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #ifndef __SECUREBOOT_CONFIG_IMPL_H__ | |
| #define __SECUREBOOT_CONFIG_IMPL_H__ | |
| #include <Uefi.h> | |
| #include <Protocol/HiiConfigAccess.h> | |
| #include <Protocol/HiiConfigRouting.h> | |
| #include <Protocol/SimpleFileSystem.h> | |
| #include <Protocol/BlockIo.h> | |
| #include <Protocol/DevicePath.h> | |
| #include <Protocol/DebugPort.h> | |
| #include <Protocol/LoadFile.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/MemoryAllocationLib.h> | |
| #include <Library/UefiBootServicesTableLib.h> | |
| #include <Library/UefiRuntimeServicesTableLib.h> | |
| #include <Library/UefiHiiServicesLib.h> | |
| #include <Library/UefiLib.h> | |
| #include <Library/HiiLib.h> | |
| #include <Library/DevicePathLib.h> | |
| #include <Library/PrintLib.h> | |
| #include <Library/PlatformSecureLib.h> | |
| #include <Library/BaseCryptLib.h> | |
| #include <Library/FileExplorerLib.h> | |
| #include <Library/PeCoffLib.h> | |
| #include <Guid/MdeModuleHii.h> | |
| #include <Guid/AuthenticatedVariableFormat.h> | |
| #include <Guid/FileSystemVolumeLabelInfo.h> | |
| #include <Guid/ImageAuthentication.h> | |
| #include <Guid/FileInfo.h> | |
| #include <Guid/WinCertificate.h> | |
| #include "SecureBootConfigNvData.h" | |
| // | |
| // Tool generated IFR binary data and String package data | |
| // | |
| extern UINT8 SecureBootConfigBin[]; | |
| extern UINT8 SecureBootConfigDxeStrings[]; | |
| // | |
| // Shared IFR form update data | |
| // | |
| extern VOID *mStartOpCodeHandle; | |
| extern VOID *mEndOpCodeHandle; | |
| extern EFI_IFR_GUID_LABEL *mStartLabel; | |
| extern EFI_IFR_GUID_LABEL *mEndLabel; | |
| #define MAX_CHAR 480 | |
| #define TWO_BYTE_ENCODE 0x82 | |
| #define BUFFER_MAX_SIZE 100 | |
| // | |
| // SHA-256 digest size in bytes | |
| // | |
| #define SHA256_DIGEST_SIZE 32 | |
| // | |
| // SHA-384 digest size in bytes | |
| // | |
| #define SHA384_DIGEST_SIZE 48 | |
| // | |
| // SHA-512 digest size in bytes | |
| // | |
| #define SHA512_DIGEST_SIZE 64 | |
| // | |
| // Set max digest size as SHA512 Output (64 bytes) by far | |
| // | |
| #define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE | |
| #define WIN_CERT_UEFI_RSA2048_SIZE 256 | |
| // | |
| // Support hash types | |
| // | |
| #define HASHALG_SHA224 0x00000000 | |
| #define HASHALG_SHA256 0x00000001 | |
| #define HASHALG_SHA384 0x00000002 | |
| #define HASHALG_SHA512 0x00000003 | |
| #define HASHALG_RAW 0x00000004 | |
| #define HASHALG_MAX 0x00000004 | |
| typedef struct { | |
| UINTN Signature; | |
| LIST_ENTRY Head; | |
| UINTN MenuNumber; | |
| } SECUREBOOT_MENU_OPTION; | |
| typedef struct { | |
| EFI_FILE_HANDLE FHandle; | |
| UINT16 *FileName; | |
| UINT8 FileType; | |
| } SECUREBOOT_FILE_CONTEXT; | |
| #define SECUREBOOT_FREE_NON_NULL(Pointer) \ | |
| do { \ | |
| if ((Pointer) != NULL) { \ | |
| FreePool((Pointer)); \ | |
| (Pointer) = NULL; \ | |
| } \ | |
| } while (FALSE) | |
| #define SECUREBOOT_FREE_NON_OPCODE(Handle) \ | |
| do{ \ | |
| if ((Handle) != NULL) { \ | |
| HiiFreeOpCodeHandle((Handle)); \ | |
| } \ | |
| } while (FALSE) | |
| #define SIGNATURE_DATA_COUNTS(List) \ | |
| (((List)->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - (List)->SignatureHeaderSize) / (List)->SignatureSize) | |
| // | |
| // We define another format of 5th directory entry: security directory | |
| // | |
| typedef struct { | |
| UINT32 Offset; // Offset of certificate | |
| UINT32 SizeOfCert; // size of certificate appended | |
| } EFI_IMAGE_SECURITY_DATA_DIRECTORY; | |
| typedef enum{ | |
| ImageType_IA32, | |
| ImageType_X64 | |
| } IMAGE_TYPE; | |
| /// | |
| /// HII specific Vendor Device Path definition. | |
| /// | |
| typedef struct { | |
| VENDOR_DEVICE_PATH VendorDevicePath; | |
| EFI_DEVICE_PATH_PROTOCOL End; | |
| } HII_VENDOR_DEVICE_PATH; | |
| typedef enum { | |
| Variable_DB, | |
| Variable_DBX, | |
| Variable_DBT, | |
| Variable_MAX | |
| } CURRENT_VARIABLE_NAME; | |
| typedef enum { | |
| Delete_Signature_List_All, | |
| Delete_Signature_List_One, | |
| Delete_Signature_Data | |
| }SIGNATURE_DELETE_TYPE; | |
| typedef struct { | |
| UINTN Signature; | |
| EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; | |
| EFI_HII_HANDLE HiiHandle; | |
| EFI_HANDLE DriverHandle; | |
| SECUREBOOT_FILE_CONTEXT *FileContext; | |
| EFI_GUID *SignatureGUID; | |
| CURRENT_VARIABLE_NAME VariableName; // The variable name we are processing. | |
| UINT32 ListCount; // Record current variable has how many signature list. | |
| UINTN ListIndex; // Record which signature list is processing. | |
| BOOLEAN *CheckArray; // Record whcih siganture data checked. | |
| } SECUREBOOT_CONFIG_PRIVATE_DATA; | |
| extern SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate; | |
| extern SECUREBOOT_CONFIG_PRIVATE_DATA *gSecureBootPrivateData; | |
| #define SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('S', 'E', 'C', 'B') | |
| #define SECUREBOOT_CONFIG_PRIVATE_FROM_THIS(a) CR (a, SECUREBOOT_CONFIG_PRIVATE_DATA, ConfigAccess, SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE) | |
| // | |
| // Cryptograhpic Key Information | |
| // | |
| #pragma pack(1) | |
| typedef struct _CPL_KEY_INFO { | |
| UINT32 KeyLengthInBits; // Key Length In Bits | |
| UINT32 BlockSize; // Operation Block Size in Bytes | |
| UINT32 CipherBlockSize; // Output Cipher Block Size in Bytes | |
| UINT32 KeyType; // Key Type | |
| UINT32 CipherMode; // Cipher Mode for Symmetric Algorithm | |
| UINT32 Flags; // Additional Key Property Flags | |
| } CPL_KEY_INFO; | |
| #pragma pack() | |
| /** | |
| Retrieves the size, in bytes, of the context buffer required for hash operations. | |
| @return The size, in bytes, of the context buffer required for hash operations. | |
| **/ | |
| typedef | |
| EFI_STATUS | |
| (EFIAPI *HASH_GET_CONTEXT_SIZE)( | |
| VOID | |
| ); | |
| /** | |
| Initializes user-supplied memory pointed by HashContext as hash context for | |
| subsequent use. | |
| If HashContext is NULL, then ASSERT(). | |
| @param[in, out] HashContext Pointer to Context being initialized. | |
| @retval TRUE HASH context initialization succeeded. | |
| @retval FALSE HASH context initialization failed. | |
| **/ | |
| typedef | |
| BOOLEAN | |
| (EFIAPI *HASH_INIT)( | |
| IN OUT VOID *HashContext | |
| ); | |
| /** | |
| Performs digest on a data buffer of the specified length. This function can | |
| be called multiple times to compute the digest of long or discontinuous data streams. | |
| If HashContext is NULL, then ASSERT(). | |
| @param[in, out] HashContext Pointer to the MD5 context. | |
| @param[in] Data Pointer to the buffer containing the data to be hashed. | |
| @param[in] DataLength Length of Data buffer in bytes. | |
| @retval TRUE HASH data digest succeeded. | |
| @retval FALSE Invalid HASH context. After HashFinal function has been called, the | |
| HASH context cannot be reused. | |
| **/ | |
| typedef | |
| BOOLEAN | |
| (EFIAPI *HASH_UPDATE)( | |
| IN OUT VOID *HashContext, | |
| IN CONST VOID *Data, | |
| IN UINTN DataLength | |
| ); | |
| /** | |
| Completes hash computation and retrieves the digest value into the specified | |
| memory. After this function has been called, the context cannot be used again. | |
| If HashContext is NULL, then ASSERT(). | |
| If HashValue is NULL, then ASSERT(). | |
| @param[in, out] HashContext Pointer to the MD5 context | |
| @param[out] HashValue Pointer to a buffer that receives the HASH digest | |
| value (16 bytes). | |
| @retval TRUE HASH digest computation succeeded. | |
| @retval FALSE HASH digest computation failed. | |
| **/ | |
| typedef | |
| BOOLEAN | |
| (EFIAPI *HASH_FINAL)( | |
| IN OUT VOID *HashContext, | |
| OUT UINT8 *HashValue | |
| ); | |
| // | |
| // Hash Algorithm Table | |
| // | |
| typedef struct { | |
| CHAR16 *Name; ///< Name for Hash Algorithm | |
| UINTN DigestLength; ///< Digest Length | |
| UINT8 *OidValue; ///< Hash Algorithm OID ASN.1 Value | |
| UINTN OidLength; ///< Length of Hash OID Value | |
| HASH_GET_CONTEXT_SIZE GetContextSize; ///< Pointer to Hash GetContentSize function | |
| HASH_INIT HashInit; ///< Pointer to Hash Init function | |
| HASH_UPDATE HashUpdate; ///< Pointer to Hash Update function | |
| HASH_FINAL HashFinal; ///< Pointer to Hash Final function | |
| } HASH_TABLE; | |
| typedef struct { | |
| WIN_CERTIFICATE Hdr; | |
| UINT8 CertData[1]; | |
| } WIN_CERTIFICATE_EFI_PKCS; | |
| /** | |
| This function publish the SecureBoot configuration Form. | |
| @param[in, out] PrivateData Points to SecureBoot configuration private data. | |
| @retval EFI_SUCCESS HII Form is installed successfully. | |
| @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation. | |
| @retval Others Other errors as indicated. | |
| **/ | |
| EFI_STATUS | |
| InstallSecureBootConfigForm ( | |
| IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData | |
| ); | |
| /** | |
| This function removes SecureBoot configuration Form. | |
| @param[in, out] PrivateData Points to SecureBoot configuration private data. | |
| **/ | |
| VOID | |
| UninstallSecureBootConfigForm ( | |
| IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData | |
| ); | |
| /** | |
| This function allows a caller to extract the current configuration for one | |
| or more named elements from the target driver. | |
| @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
| @param[in] Request A null-terminated Unicode string in | |
| <ConfigRequest> format. | |
| @param[out] Progress On return, points to a character in the Request | |
| string. Points to the string's null terminator if | |
| request was successful. Points to the most recent | |
| '&' before the first failing name/value pair (or | |
| the beginning of the string if the failure is in | |
| the first name/value pair) if the request was not | |
| successful. | |
| @param[out] Results A null-terminated Unicode string in | |
| <ConfigAltResp> format which has all values filled | |
| in for the names in the Request string. String to | |
| be allocated by the called function. | |
| @retval EFI_SUCCESS The Results is filled with the requested values. | |
| @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. | |
| @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. | |
| @retval EFI_NOT_FOUND Routing data doesn't match any storage in this | |
| driver. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| SecureBootExtractConfig ( | |
| IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
| IN CONST EFI_STRING Request, | |
| OUT EFI_STRING *Progress, | |
| OUT EFI_STRING *Results | |
| ); | |
| /** | |
| This function processes the results of changes in configuration. | |
| @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
| @param[in] Configuration A null-terminated Unicode string in <ConfigResp> | |
| format. | |
| @param[out] Progress A pointer to a string filled in with the offset of | |
| the most recent '&' before the first failing | |
| name/value pair (or the beginning of the string if | |
| the failure is in the first name/value pair) or | |
| the terminating NULL if all was successful. | |
| @retval EFI_SUCCESS The Results is processed successfully. | |
| @retval EFI_INVALID_PARAMETER Configuration is NULL. | |
| @retval EFI_NOT_FOUND Routing data doesn't match any storage in this | |
| driver. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| SecureBootRouteConfig ( | |
| IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
| IN CONST EFI_STRING Configuration, | |
| OUT EFI_STRING *Progress | |
| ); | |
| /** | |
| This function processes the results of changes in configuration. | |
| @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
| @param[in] Action Specifies the type of action taken by the browser. | |
| @param[in] QuestionId A unique value which is sent to the original | |
| exporting driver so that it can identify the type | |
| of data to expect. | |
| @param[in] Type The type of value for the question. | |
| @param[in] Value A pointer to the data being sent to the original | |
| exporting driver. | |
| @param[out] ActionRequest On return, points to the action requested by the | |
| callback function. | |
| @retval EFI_SUCCESS The callback successfully handled the action. | |
| @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the | |
| variable and its data. | |
| @retval EFI_DEVICE_ERROR The variable could not be saved. | |
| @retval EFI_UNSUPPORTED The specified Action is not supported by the | |
| callback. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| SecureBootCallback ( | |
| IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
| IN EFI_BROWSER_ACTION Action, | |
| IN EFI_QUESTION_ID QuestionId, | |
| IN UINT8 Type, | |
| IN EFI_IFR_TYPE_VALUE *Value, | |
| OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest | |
| ); | |
| /** | |
| This function converts an input device structure to a Unicode string. | |
| @param[in] DevPath A pointer to the device path structure. | |
| @return A new allocated Unicode string that represents the device path. | |
| **/ | |
| CHAR16 * | |
| EFIAPI | |
| DevicePathToStr ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *DevPath | |
| ); | |
| /** | |
| Clean up the dynamic opcode at label and form specified by both LabelId. | |
| @param[in] LabelId It is both the Form ID and Label ID for opcode deletion. | |
| @param[in] PrivateData Module private data. | |
| **/ | |
| VOID | |
| CleanUpPage ( | |
| IN UINT16 LabelId, | |
| IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData | |
| ); | |
| /** | |
| Read file content into BufferPtr, the size of the allocate buffer | |
| is *FileSize plus AddtionAllocateSize. | |
| @param[in] FileHandle The file to be read. | |
| @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. | |
| @param[out] FileSize Size of input file | |
| @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. | |
| In case the buffer need to contain others besides the file content. | |
| @retval EFI_SUCCESS The file was read into the buffer. | |
| @retval EFI_INVALID_PARAMETER A parameter was invalid. | |
| @retval EFI_OUT_OF_RESOURCES A memory allocation failed. | |
| @retval others Unexpected error. | |
| **/ | |
| EFI_STATUS | |
| ReadFileContent ( | |
| IN EFI_FILE_HANDLE FileHandle, | |
| IN OUT VOID **BufferPtr, | |
| OUT UINTN *FileSize, | |
| IN UINTN AddtionAllocateSize | |
| ); | |
| /** | |
| Close an open file handle. | |
| @param[in] FileHandle The file handle to close. | |
| **/ | |
| VOID | |
| CloseFile ( | |
| IN EFI_FILE_HANDLE FileHandle | |
| ); | |
| /** | |
| Converts a nonnegative integer to an octet string of a specified length. | |
| @param[in] Integer Pointer to the nonnegative integer to be converted | |
| @param[in] IntSizeInWords Length of integer buffer in words | |
| @param[out] OctetString Converted octet string of the specified length | |
| @param[in] OSSizeInBytes Intended length of resulting octet string in bytes | |
| Returns: | |
| @retval EFI_SUCCESS Data conversion successfully | |
| @retval EFI_BUFFER_TOOL_SMALL Buffer is too small for output string | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| Int2OctStr ( | |
| IN CONST UINTN *Integer, | |
| IN UINTN IntSizeInWords, | |
| OUT UINT8 *OctetString, | |
| IN UINTN OSSizeInBytes | |
| ); | |
| /** | |
| Worker function that prints an EFI_GUID into specified Buffer. | |
| @param[in] Guid Pointer to GUID to print. | |
| @param[in] Buffer Buffer to print Guid into. | |
| @param[in] BufferSize Size of Buffer. | |
| @retval Number of characters printed. | |
| **/ | |
| UINTN | |
| GuidToString ( | |
| IN EFI_GUID *Guid, | |
| IN CHAR16 *Buffer, | |
| IN UINTN BufferSize | |
| ); | |
| /** | |
| Update the PK form base on the input file path info. | |
| @param FilePath Point to the file path. | |
| @retval TRUE Exit caller function. | |
| @retval FALSE Not exit caller function. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| UpdatePKFromFile ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath | |
| ); | |
| /** | |
| Update the KEK form base on the input file path info. | |
| @param FilePath Point to the file path. | |
| @retval TRUE Exit caller function. | |
| @retval FALSE Not exit caller function. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| UpdateKEKFromFile ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath | |
| ); | |
| /** | |
| Update the DB form base on the input file path info. | |
| @param FilePath Point to the file path. | |
| @retval TRUE Exit caller function. | |
| @retval FALSE Not exit caller function. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| UpdateDBFromFile ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath | |
| ); | |
| /** | |
| Update the DBX form base on the input file path info. | |
| @param FilePath Point to the file path. | |
| @retval TRUE Exit caller function. | |
| @retval FALSE Not exit caller function. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| UpdateDBXFromFile ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath | |
| ); | |
| /** | |
| Update the DBT form base on the input file path info. | |
| @param FilePath Point to the file path. | |
| @retval TRUE Exit caller function. | |
| @retval FALSE Not exit caller function. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| UpdateDBTFromFile ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath | |
| ); | |
| #endif |