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