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