2 This library provides functions to set/clear Secure Boot
5 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
7 Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
8 Copyright (c) 2021, Semihalf All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <UefiSecureBoot.h>
13 #include <Guid/GlobalVariable.h>
14 #include <Guid/AuthenticatedVariableFormat.h>
15 #include <Guid/ImageAuthentication.h>
16 #include <Library/BaseLib.h>
17 #include <Library/BaseCryptLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/UefiLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/UefiRuntimeServicesTableLib.h>
23 #include <Library/SecureBootVariableLib.h>
24 #include <Library/SecureBootVariableProvisionLib.h>
25 #include <Library/DxeServicesLib.h>
28 Create a EFI Signature List with data fetched from section specified as a argument.
29 Found keys are verified using RsaGetPublicKeyFromX509().
31 @param[in] KeyFileGuid A pointer to to the FFS filename GUID
32 @param[out] SigListsSize A pointer to size of signature list
33 @param[out] SigListOut a pointer to a callee-allocated buffer with signature lists
35 @retval EFI_SUCCESS Create time based payload successfully.
36 @retval EFI_NOT_FOUND Section with key has not been found.
37 @retval EFI_INVALID_PARAMETER Embedded key has a wrong format.
38 @retval Others Unexpected error happens.
44 IN EFI_GUID
*KeyFileGuid
,
45 OUT UINTN
*SigListsSize
,
46 OUT EFI_SIGNATURE_LIST
**SigListOut
49 EFI_SIGNATURE_LIST
*EfiSig
;
56 SECURE_BOOT_CERTIFICATE_INFO
*CertInfo
;
57 SECURE_BOOT_CERTIFICATE_INFO
*NewCertInfo
;
63 CertInfo
= AllocatePool (sizeof (SECURE_BOOT_CERTIFICATE_INFO
));
64 NewCertInfo
= CertInfo
;
66 if (NewCertInfo
== NULL
) {
67 Status
= EFI_OUT_OF_RESOURCES
;
70 CertInfo
= NewCertInfo
;
73 Status
= GetSectionFromAnyFv (
81 if (Status
== EFI_SUCCESS
) {
83 if (RsaGetPublicKeyFromX509 (Buffer
, Size
, &RsaPubKey
) == FALSE
) {
84 DEBUG ((DEBUG_ERROR
, "%a: Invalid key format: %d\n", __FUNCTION__
, KeyIndex
));
90 Status
= EFI_INVALID_PARAMETER
;
94 CertInfo
[KeyIndex
].Data
= Buffer
;
95 CertInfo
[KeyIndex
].DataSize
= Size
;
97 NewCertInfo
= ReallocatePool (
98 sizeof (SECURE_BOOT_CERTIFICATE_INFO
) * KeyIndex
,
99 sizeof (SECURE_BOOT_CERTIFICATE_INFO
) * (KeyIndex
+ 1),
104 if (Status
== EFI_NOT_FOUND
) {
105 Status
= EFI_SUCCESS
;
110 if (EFI_ERROR (Status
)) {
115 Status
= EFI_NOT_FOUND
;
119 // Now that we collected all certs from FV, convert it into sig list
120 Status
= SecureBootCreateDataFromInput (SigListsSize
, SigListOut
, KeyIndex
, CertInfo
);
121 if (EFI_ERROR (Status
)) {
127 for (Index
= 0; Index
< KeyIndex
; Index
++) {
128 FreePool ((VOID
*)CertInfo
[Index
].Data
);
138 Enroll a key/certificate based on a default variable.
140 @param[in] VariableName The name of the key/database.
141 @param[in] DefaultName The name of the default variable.
142 @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable
144 @retval EFI_OUT_OF_RESOURCES Out of memory while allocating AuthHeader.
145 @retval EFI_SUCCESS Successful enrollment.
146 @return Error codes from GetTime () and SetVariable ().
151 IN CHAR16
*VariableName
,
152 IN CHAR16
*DefaultName
,
153 IN EFI_GUID
*VendorGuid
160 Status
= EFI_SUCCESS
;
163 Status
= GetVariable2 (DefaultName
, &gEfiGlobalVariableGuid
, &Data
, &DataSize
);
164 if (EFI_ERROR (Status
)) {
165 DEBUG ((DEBUG_ERROR
, "error: GetVariable (\"%s): %r\n", DefaultName
, Status
));
169 Status
= EnrollFromInput (VariableName
, VendorGuid
, DataSize
, Data
);
178 /** Initializes PKDefault variable with data from FFS section.
180 @retval EFI_SUCCESS Variable was initialized successfully.
181 @retval EFI_UNSUPPORTED Variable already exists.
184 SecureBootInitPKDefault (
188 EFI_SIGNATURE_LIST
*EfiSig
;
195 // Check if variable exists, if so do not change it
197 Status
= GetVariable2 (EFI_PK_DEFAULT_VARIABLE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Data
, &DataSize
);
198 if (Status
== EFI_SUCCESS
) {
199 DEBUG ((DEBUG_INFO
, "Variable %s exists. Old value is preserved\n", EFI_PK_DEFAULT_VARIABLE_NAME
));
201 return EFI_UNSUPPORTED
;
204 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
209 // Variable does not exist, can be initialized
211 DEBUG ((DEBUG_INFO
, "Variable %s does not exist.\n", EFI_PK_DEFAULT_VARIABLE_NAME
));
213 Status
= SecureBootFetchData (&gDefaultPKFileGuid
, &SigListsSize
, &EfiSig
);
214 if (EFI_ERROR (Status
)) {
215 DEBUG ((DEBUG_INFO
, "Content for %s not found\n", EFI_PK_DEFAULT_VARIABLE_NAME
));
219 Status
= gRT
->SetVariable (
220 EFI_PK_DEFAULT_VARIABLE_NAME
,
221 &gEfiGlobalVariableGuid
,
222 EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
226 if (EFI_ERROR (Status
)) {
227 DEBUG ((DEBUG_INFO
, "Failed to set %s\n", EFI_PK_DEFAULT_VARIABLE_NAME
));
235 /** Initializes KEKDefault variable with data from FFS section.
237 @retval EFI_SUCCESS Variable was initialized successfully.
238 @retval EFI_UNSUPPORTED Variable already exists.
241 SecureBootInitKEKDefault (
245 EFI_SIGNATURE_LIST
*EfiSig
;
252 // Check if variable exists, if so do not change it
254 Status
= GetVariable2 (EFI_KEK_DEFAULT_VARIABLE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Data
, &DataSize
);
255 if (Status
== EFI_SUCCESS
) {
256 DEBUG ((DEBUG_INFO
, "Variable %s exists. Old value is preserved\n", EFI_KEK_DEFAULT_VARIABLE_NAME
));
258 return EFI_UNSUPPORTED
;
261 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
266 // Variable does not exist, can be initialized
268 DEBUG ((DEBUG_INFO
, "Variable %s does not exist.\n", EFI_KEK_DEFAULT_VARIABLE_NAME
));
270 Status
= SecureBootFetchData (&gDefaultKEKFileGuid
, &SigListsSize
, &EfiSig
);
271 if (EFI_ERROR (Status
)) {
272 DEBUG ((DEBUG_INFO
, "Content for %s not found\n", EFI_KEK_DEFAULT_VARIABLE_NAME
));
276 Status
= gRT
->SetVariable (
277 EFI_KEK_DEFAULT_VARIABLE_NAME
,
278 &gEfiGlobalVariableGuid
,
279 EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
283 if (EFI_ERROR (Status
)) {
284 DEBUG ((DEBUG_INFO
, "Failed to set %s\n", EFI_KEK_DEFAULT_VARIABLE_NAME
));
292 /** Initializes dbDefault variable with data from FFS section.
294 @retval EFI_SUCCESS Variable was initialized successfully.
295 @retval EFI_UNSUPPORTED Variable already exists.
298 SecureBootInitDbDefault (
302 EFI_SIGNATURE_LIST
*EfiSig
;
308 Status
= GetVariable2 (EFI_DB_DEFAULT_VARIABLE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Data
, &DataSize
);
309 if (Status
== EFI_SUCCESS
) {
310 DEBUG ((DEBUG_INFO
, "Variable %s exists. Old value is preserved\n", EFI_DB_DEFAULT_VARIABLE_NAME
));
312 return EFI_UNSUPPORTED
;
315 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
319 DEBUG ((DEBUG_INFO
, "Variable %s does not exist.\n", EFI_DB_DEFAULT_VARIABLE_NAME
));
321 Status
= SecureBootFetchData (&gDefaultdbFileGuid
, &SigListsSize
, &EfiSig
);
322 if (EFI_ERROR (Status
)) {
326 Status
= gRT
->SetVariable (
327 EFI_DB_DEFAULT_VARIABLE_NAME
,
328 &gEfiGlobalVariableGuid
,
329 EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
333 if (EFI_ERROR (Status
)) {
334 DEBUG ((DEBUG_INFO
, "Failed to set %s\n", EFI_DB_DEFAULT_VARIABLE_NAME
));
342 /** Initializes dbxDefault variable with data from FFS section.
344 @retval EFI_SUCCESS Variable was initialized successfully.
345 @retval EFI_UNSUPPORTED Variable already exists.
348 SecureBootInitDbxDefault (
352 EFI_SIGNATURE_LIST
*EfiSig
;
359 // Check if variable exists, if so do not change it
361 Status
= GetVariable2 (EFI_DBX_DEFAULT_VARIABLE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Data
, &DataSize
);
362 if (Status
== EFI_SUCCESS
) {
363 DEBUG ((DEBUG_INFO
, "Variable %s exists. Old value is preserved\n", EFI_DBX_DEFAULT_VARIABLE_NAME
));
365 return EFI_UNSUPPORTED
;
368 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
373 // Variable does not exist, can be initialized
375 DEBUG ((DEBUG_INFO
, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME
));
377 Status
= SecureBootFetchData (&gDefaultdbxFileGuid
, &SigListsSize
, &EfiSig
);
378 if (EFI_ERROR (Status
)) {
379 DEBUG ((DEBUG_INFO
, "Content for %s not found\n", EFI_DBX_DEFAULT_VARIABLE_NAME
));
383 Status
= gRT
->SetVariable (
384 EFI_DBX_DEFAULT_VARIABLE_NAME
,
385 &gEfiGlobalVariableGuid
,
386 EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
390 if (EFI_ERROR (Status
)) {
391 DEBUG ((DEBUG_INFO
, "Failed to set %s\n", EFI_DBX_DEFAULT_VARIABLE_NAME
));
399 /** Initializes dbtDefault variable with data from FFS section.
401 @retval EFI_SUCCESS Variable was initialized successfully.
402 @retval EFI_UNSUPPORTED Variable already exists.
405 SecureBootInitDbtDefault (
409 EFI_SIGNATURE_LIST
*EfiSig
;
416 // Check if variable exists, if so do not change it
418 Status
= GetVariable2 (EFI_DBT_DEFAULT_VARIABLE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Data
, &DataSize
);
419 if (Status
== EFI_SUCCESS
) {
420 DEBUG ((DEBUG_INFO
, "Variable %s exists. Old value is preserved\n", EFI_DBT_DEFAULT_VARIABLE_NAME
));
422 return EFI_UNSUPPORTED
;
425 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
430 // Variable does not exist, can be initialized
432 DEBUG ((DEBUG_INFO
, "Variable %s does not exist.\n", EFI_DBT_DEFAULT_VARIABLE_NAME
));
434 Status
= SecureBootFetchData (&gDefaultdbtFileGuid
, &SigListsSize
, &EfiSig
);
435 if (EFI_ERROR (Status
)) {
439 Status
= gRT
->SetVariable (
440 EFI_DBT_DEFAULT_VARIABLE_NAME
,
441 &gEfiGlobalVariableGuid
,
442 EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
446 if (EFI_ERROR (Status
)) {
447 DEBUG ((DEBUG_INFO
, "Failed to set %s\n", EFI_DBT_DEFAULT_VARIABLE_NAME
));
456 Sets the content of the 'db' variable based on 'dbDefault' variable content.
458 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
459 while VendorGuid is NULL.
460 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
464 EnrollDbFromDefault (
470 Status
= EnrollFromDefault (
471 EFI_IMAGE_SECURITY_DATABASE
,
472 EFI_DB_DEFAULT_VARIABLE_NAME
,
473 &gEfiImageSecurityDatabaseGuid
480 Sets the content of the 'dbx' variable based on 'dbxDefault' variable content.
482 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
483 while VendorGuid is NULL.
484 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
488 EnrollDbxFromDefault (
494 Status
= EnrollFromDefault (
495 EFI_IMAGE_SECURITY_DATABASE1
,
496 EFI_DBX_DEFAULT_VARIABLE_NAME
,
497 &gEfiImageSecurityDatabaseGuid
504 Sets the content of the 'dbt' variable based on 'dbtDefault' variable content.
506 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
507 while VendorGuid is NULL.
508 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
512 EnrollDbtFromDefault (
518 Status
= EnrollFromDefault (
519 EFI_IMAGE_SECURITY_DATABASE2
,
520 EFI_DBT_DEFAULT_VARIABLE_NAME
,
521 &gEfiImageSecurityDatabaseGuid
528 Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
530 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
531 while VendorGuid is NULL.
532 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
536 EnrollKEKFromDefault (
542 Status
= EnrollFromDefault (
543 EFI_KEY_EXCHANGE_KEY_NAME
,
544 EFI_KEK_DEFAULT_VARIABLE_NAME
,
545 &gEfiGlobalVariableGuid
552 Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
554 @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
555 while VendorGuid is NULL.
556 @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
560 EnrollPKFromDefault (
566 Status
= EnrollFromDefault (
567 EFI_PLATFORM_KEY_NAME
,
568 EFI_PK_DEFAULT_VARIABLE_NAME
,
569 &gEfiGlobalVariableGuid