2 HII Config Access protocol implementation of SecureBoot configuration module.
4 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "SecureBootConfigImpl.h"
11 #include <Library/BaseCryptLib.h>
13 CHAR16 mSecureBootStorageName
[] = L
"SECUREBOOT_CONFIGURATION";
15 SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate
= {
16 SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE
,
18 SecureBootExtractConfig
,
19 SecureBootRouteConfig
,
24 HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath
= {
30 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
31 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
34 SECUREBOOT_CONFIG_FORM_SET_GUID
38 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
40 (UINT8
) (END_DEVICE_PATH_LENGTH
),
41 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
47 BOOLEAN mIsEnterSecureBootForm
= FALSE
;
50 // OID ASN.1 Value for Hash Algorithms
52 UINT8 mHashOidValue
[] = {
53 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, // OBJ_md5
54 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJ_sha1
55 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224
56 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256
57 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384
58 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512
61 HASH_TABLE mHash
[] = {
62 { L
"SHA224", 28, &mHashOidValue
[13], 9, NULL
, NULL
, NULL
, NULL
},
63 { L
"SHA256", 32, &mHashOidValue
[22], 9, Sha256GetContextSize
, Sha256Init
, Sha256Update
, Sha256Final
},
64 { L
"SHA384", 48, &mHashOidValue
[31], 9, Sha384GetContextSize
, Sha384Init
, Sha384Update
, Sha384Final
},
65 { L
"SHA512", 64, &mHashOidValue
[40], 9, Sha512GetContextSize
, Sha512Init
, Sha512Update
, Sha512Final
}
69 // Variable Definitions
71 UINT32 mPeCoffHeaderOffset
= 0;
72 WIN_CERTIFICATE
*mCertificate
= NULL
;
73 IMAGE_TYPE mImageType
;
74 UINT8
*mImageBase
= NULL
;
76 UINT8 mImageDigest
[MAX_DIGEST_SIZE
];
77 UINTN mImageDigestSize
;
79 EFI_IMAGE_SECURITY_DATA_DIRECTORY
*mSecDataDir
= NULL
;
80 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader
;
83 // Possible DER-encoded certificate file suffixes, end with NULL pointer.
85 CHAR16
* mDerEncodedSuffix
[] = {
91 CHAR16
* mSupportX509Suffix
= L
"*.cer/der/crt";
93 SECUREBOOT_CONFIG_PRIVATE_DATA
*gSecureBootPrivateData
= NULL
;
96 This code cleans up enrolled file by closing file & free related resources attached to
99 @param[in] FileContext FileContext cached in SecureBootConfig driver
104 IN SECUREBOOT_FILE_CONTEXT
*FileContext
107 if (FileContext
->FHandle
!= NULL
) {
108 CloseFile (FileContext
->FHandle
);
109 FileContext
->FHandle
= NULL
;
112 if (FileContext
->FileName
!= NULL
){
113 FreePool(FileContext
->FileName
);
114 FileContext
->FileName
= NULL
;
116 FileContext
->FileType
= UNKNOWN_FILE_TYPE
;
121 This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.
123 @param[in] FileSuffix The suffix of the input certificate file
125 @retval TRUE It's a DER-encoded certificate.
126 @retval FALSE It's NOT a DER-encoded certificate.
130 IsDerEncodeCertificate (
131 IN CONST CHAR16
*FileSuffix
135 for (Index
= 0; mDerEncodedSuffix
[Index
] != NULL
; Index
++) {
136 if (StrCmp (FileSuffix
, mDerEncodedSuffix
[Index
]) == 0) {
144 This code checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format
145 The function reads file content but won't open/close given FileHandle.
147 @param[in] FileHandle The FileHandle to be checked
149 @retval TRUE The content is EFI_VARIABLE_AUTHENTICATION_2 format.
150 @retval FALSE The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format.
154 IsAuthentication2Format (
155 IN EFI_FILE_HANDLE FileHandle
159 EFI_VARIABLE_AUTHENTICATION_2
*Auth2
;
160 BOOLEAN IsAuth2Format
;
162 IsAuth2Format
= FALSE
;
165 // Read the whole file content
167 Status
= ReadFileContent(
169 (VOID
**) &mImageBase
,
173 if (EFI_ERROR (Status
)) {
177 Auth2
= (EFI_VARIABLE_AUTHENTICATION_2
*)mImageBase
;
178 if (Auth2
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) {
182 if (CompareGuid(&gEfiCertPkcs7Guid
, &Auth2
->AuthInfo
.CertType
)) {
183 IsAuth2Format
= TRUE
;
188 // Do not close File. simply check file content
190 if (mImageBase
!= NULL
) {
191 FreePool (mImageBase
);
195 return IsAuth2Format
;
199 Set Secure Boot option into variable space.
201 @param[in] VarValue The option of Secure Boot.
203 @retval EFI_SUCCESS The operation is finished successfully.
204 @retval Others Other errors as indicated.
208 SaveSecureBootVariable (
214 Status
= gRT
->SetVariable (
215 EFI_SECURE_BOOT_ENABLE_NAME
,
216 &gEfiSecureBootEnableDisableGuid
,
217 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
225 Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
226 descriptor with the input data. NO authentication is required in this function.
228 @param[in, out] DataSize On input, the size of Data buffer in bytes.
229 On output, the size of data returned in Data
231 @param[in, out] Data On input, Pointer to data buffer to be wrapped or
232 pointer to NULL to wrap an empty payload.
233 On output, Pointer to the new payload date buffer allocated from pool,
234 it's caller's responsibility to free the memory when finish using it.
236 @retval EFI_SUCCESS Create time based payload successfully.
237 @retval EFI_OUT_OF_RESOURCES There are not enough memory resources to create time based payload.
238 @retval EFI_INVALID_PARAMETER The parameter is invalid.
239 @retval Others Unexpected error happens.
243 CreateTimeBasedPayload (
244 IN OUT UINTN
*DataSize
,
252 EFI_VARIABLE_AUTHENTICATION_2
*DescriptorData
;
253 UINTN DescriptorSize
;
256 if (Data
== NULL
|| DataSize
== NULL
) {
257 return EFI_INVALID_PARAMETER
;
261 // In Setup mode or Custom mode, the variable does not need to be signed but the
262 // parameters to the SetVariable() call still need to be prepared as authenticated
263 // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
267 PayloadSize
= *DataSize
;
269 DescriptorSize
= OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2
, AuthInfo
) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID
, CertData
);
270 NewData
= (UINT8
*) AllocateZeroPool (DescriptorSize
+ PayloadSize
);
271 if (NewData
== NULL
) {
272 return EFI_OUT_OF_RESOURCES
;
275 if ((Payload
!= NULL
) && (PayloadSize
!= 0)) {
276 CopyMem (NewData
+ DescriptorSize
, Payload
, PayloadSize
);
279 DescriptorData
= (EFI_VARIABLE_AUTHENTICATION_2
*) (NewData
);
281 ZeroMem (&Time
, sizeof (EFI_TIME
));
282 Status
= gRT
->GetTime (&Time
, NULL
);
283 if (EFI_ERROR (Status
)) {
292 CopyMem (&DescriptorData
->TimeStamp
, &Time
, sizeof (EFI_TIME
));
294 DescriptorData
->AuthInfo
.Hdr
.dwLength
= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID
, CertData
);
295 DescriptorData
->AuthInfo
.Hdr
.wRevision
= 0x0200;
296 DescriptorData
->AuthInfo
.Hdr
.wCertificateType
= WIN_CERT_TYPE_EFI_GUID
;
297 CopyGuid (&DescriptorData
->AuthInfo
.CertType
, &gEfiCertPkcs7Guid
);
299 if (Payload
!= NULL
) {
303 *DataSize
= DescriptorSize
+ PayloadSize
;
309 Internal helper function to delete a Variable given its name and GUID, NO authentication
312 @param[in] VariableName Name of the Variable.
313 @param[in] VendorGuid GUID of the Variable.
315 @retval EFI_SUCCESS Variable deleted successfully.
316 @retval Others The driver failed to start the device.
321 IN CHAR16
*VariableName
,
322 IN EFI_GUID
*VendorGuid
331 GetVariable2 (VariableName
, VendorGuid
, &Variable
, NULL
);
332 if (Variable
== NULL
) {
339 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
340 | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
342 Status
= CreateTimeBasedPayload (&DataSize
, &Data
);
343 if (EFI_ERROR (Status
)) {
344 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
348 Status
= gRT
->SetVariable (
363 Set the platform secure boot mode into "Custom" or "Standard" mode.
365 @param[in] SecureBootMode New secure boot mode: STANDARD_SECURE_BOOT_MODE or
366 CUSTOM_SECURE_BOOT_MODE.
368 @return EFI_SUCCESS The platform has switched to the special mode successfully.
369 @return other Fail to operate the secure boot mode.
374 IN UINT8 SecureBootMode
377 return gRT
->SetVariable (
378 EFI_CUSTOM_MODE_NAME
,
379 &gEfiCustomModeEnableGuid
,
380 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
387 Generate the PK signature list from the X509 Certificate storing file (.cer)
389 @param[in] X509File FileHandle of X509 Certificate storing file.
390 @param[out] PkCert Point to the data buffer to store the signature list.
392 @return EFI_UNSUPPORTED Unsupported Key Length.
393 @return EFI_OUT_OF_RESOURCES There are not enough memory resources to form the signature list.
397 CreatePkX509SignatureList (
398 IN EFI_FILE_HANDLE X509File
,
399 OUT EFI_SIGNATURE_LIST
**PkCert
405 EFI_SIGNATURE_DATA
*PkCertData
;
411 Status
= ReadFileContent (X509File
, (VOID
**) &X509Data
, &X509DataSize
, 0);
412 if (EFI_ERROR (Status
)) {
415 ASSERT (X509Data
!= NULL
);
418 // Allocate space for PK certificate list and initialize it.
419 // Create PK database entry with SignatureHeaderSize equals 0.
421 *PkCert
= (EFI_SIGNATURE_LIST
*) AllocateZeroPool (
422 sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1
425 if (*PkCert
== NULL
) {
426 Status
= EFI_OUT_OF_RESOURCES
;
430 (*PkCert
)->SignatureListSize
= (UINT32
) (sizeof(EFI_SIGNATURE_LIST
)
431 + sizeof(EFI_SIGNATURE_DATA
) - 1
433 (*PkCert
)->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
434 (*PkCert
)->SignatureHeaderSize
= 0;
435 CopyGuid (&(*PkCert
)->SignatureType
, &gEfiCertX509Guid
);
436 PkCertData
= (EFI_SIGNATURE_DATA
*) ((UINTN
)(*PkCert
)
437 + sizeof(EFI_SIGNATURE_LIST
)
438 + (*PkCert
)->SignatureHeaderSize
);
439 CopyGuid (&PkCertData
->SignatureOwner
, &gEfiGlobalVariableGuid
);
441 // Fill the PK database with PKpub data from X509 certificate file.
443 CopyMem (&(PkCertData
->SignatureData
[0]), X509Data
, X509DataSize
);
447 if (X509Data
!= NULL
) {
451 if (EFI_ERROR(Status
) && *PkCert
!= NULL
) {
460 Enroll new PK into the System without original PK's authentication.
462 The SignatureOwner GUID will be the same with PK's vendorguid.
464 @param[in] PrivateData The module's private data.
466 @retval EFI_SUCCESS New PK enrolled successfully.
467 @retval EFI_INVALID_PARAMETER The parameter is invalid.
468 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
473 IN SECUREBOOT_CONFIG_PRIVATE_DATA
* Private
479 EFI_SIGNATURE_LIST
*PkCert
;
483 if (Private
->FileContext
->FileName
== NULL
) {
484 return EFI_INVALID_PARAMETER
;
489 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
490 if (EFI_ERROR (Status
)) {
495 // Parse the file's postfix. Only support DER encoded X.509 certificate files.
497 NameLength
= StrLen (Private
->FileContext
->FileName
);
498 if (NameLength
<= 4) {
499 return EFI_INVALID_PARAMETER
;
501 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
502 if (!IsDerEncodeCertificate(FilePostFix
)) {
503 DEBUG ((EFI_D_ERROR
, "Unsupported file type, only DER encoded certificate (%s) is supported.", mSupportX509Suffix
));
504 return EFI_INVALID_PARAMETER
;
506 DEBUG ((EFI_D_INFO
, "FileName= %s\n", Private
->FileContext
->FileName
));
507 DEBUG ((EFI_D_INFO
, "FilePostFix = %s\n", FilePostFix
));
510 // Prase the selected PK file and generate PK certificate list.
512 Status
= CreatePkX509SignatureList (
513 Private
->FileContext
->FHandle
,
516 if (EFI_ERROR (Status
)) {
519 ASSERT (PkCert
!= NULL
);
522 // Set Platform Key variable.
524 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
525 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
526 DataSize
= PkCert
->SignatureListSize
;
527 Status
= CreateTimeBasedPayload (&DataSize
, (UINT8
**) &PkCert
);
528 if (EFI_ERROR (Status
)) {
529 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
533 Status
= gRT
->SetVariable(
534 EFI_PLATFORM_KEY_NAME
,
535 &gEfiGlobalVariableGuid
,
540 if (EFI_ERROR (Status
)) {
541 if (Status
== EFI_OUT_OF_RESOURCES
) {
542 DEBUG ((EFI_D_ERROR
, "Enroll PK failed with out of resource.\n"));
549 if (PkCert
!= NULL
) {
553 CloseEnrolledFile(Private
->FileContext
);
559 Remove the PK variable.
561 @retval EFI_SUCCESS Delete PK successfully.
562 @retval Others Could not allow to delete PK.
572 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
573 if (EFI_ERROR (Status
)) {
577 Status
= DeleteVariable (
578 EFI_PLATFORM_KEY_NAME
,
579 &gEfiGlobalVariableGuid
585 Enroll a new KEK item from public key storing file (*.pbk).
587 @param[in] PrivateData The module's private data.
589 @retval EFI_SUCCESS New KEK enrolled successfully.
590 @retval EFI_INVALID_PARAMETER The parameter is invalid.
591 @retval EFI_UNSUPPORTED Unsupported command.
592 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
597 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
603 EFI_SIGNATURE_LIST
*KekSigList
;
606 CPL_KEY_INFO
*KeyInfo
;
607 EFI_SIGNATURE_DATA
*KEKSigData
;
608 UINTN KekSigListSize
;
623 // Form the KeKpub certificate list into EFI_SIGNATURE_LIST type.
624 // First, We have to parse out public key data from the pbk key file.
626 Status
= ReadFileContent (
627 Private
->FileContext
->FHandle
,
632 if (EFI_ERROR (Status
)) {
635 ASSERT (KeyBlob
!= NULL
);
636 KeyInfo
= (CPL_KEY_INFO
*) KeyBlob
;
637 if (KeyInfo
->KeyLengthInBits
/ 8 != WIN_CERT_UEFI_RSA2048_SIZE
) {
638 DEBUG ((DEBUG_ERROR
, "Unsupported key length, Only RSA2048 is supported.\n"));
639 Status
= EFI_UNSUPPORTED
;
644 // Convert the Public key to fix octet string format represented in RSA PKCS#1.
646 KeyLenInBytes
= KeyInfo
->KeyLengthInBits
/ 8;
647 KeyBuffer
= AllocateZeroPool (KeyLenInBytes
);
648 if (KeyBuffer
== NULL
) {
649 Status
= EFI_OUT_OF_RESOURCES
;
653 (UINTN
*) (KeyBlob
+ sizeof (CPL_KEY_INFO
)),
654 KeyLenInBytes
/ sizeof (UINTN
),
658 CopyMem(KeyBlob
+ sizeof(CPL_KEY_INFO
), KeyBuffer
, KeyLenInBytes
);
661 // Form an new EFI_SIGNATURE_LIST.
663 KekSigListSize
= sizeof(EFI_SIGNATURE_LIST
)
664 + sizeof(EFI_SIGNATURE_DATA
) - 1
665 + WIN_CERT_UEFI_RSA2048_SIZE
;
667 KekSigList
= (EFI_SIGNATURE_LIST
*) AllocateZeroPool (KekSigListSize
);
668 if (KekSigList
== NULL
) {
669 Status
= EFI_OUT_OF_RESOURCES
;
673 KekSigList
->SignatureListSize
= sizeof(EFI_SIGNATURE_LIST
)
674 + sizeof(EFI_SIGNATURE_DATA
) - 1
675 + WIN_CERT_UEFI_RSA2048_SIZE
;
676 KekSigList
->SignatureHeaderSize
= 0;
677 KekSigList
->SignatureSize
= sizeof(EFI_SIGNATURE_DATA
) - 1 + WIN_CERT_UEFI_RSA2048_SIZE
;
678 CopyGuid (&KekSigList
->SignatureType
, &gEfiCertRsa2048Guid
);
680 KEKSigData
= (EFI_SIGNATURE_DATA
*)((UINT8
*)KekSigList
+ sizeof(EFI_SIGNATURE_LIST
));
681 CopyGuid (&KEKSigData
->SignatureOwner
, Private
->SignatureGUID
);
683 KEKSigData
->SignatureData
,
684 KeyBlob
+ sizeof(CPL_KEY_INFO
),
685 WIN_CERT_UEFI_RSA2048_SIZE
689 // Check if KEK entry has been already existed.
690 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
691 // new KEK to original variable.
693 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
694 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
695 Status
= CreateTimeBasedPayload (&KekSigListSize
, (UINT8
**) &KekSigList
);
696 if (EFI_ERROR (Status
)) {
697 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
701 Status
= gRT
->GetVariable(
702 EFI_KEY_EXCHANGE_KEY_NAME
,
703 &gEfiGlobalVariableGuid
,
708 if (Status
== EFI_BUFFER_TOO_SMALL
) {
709 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
710 } else if (Status
!= EFI_NOT_FOUND
) {
715 // Done. Now we have formed the correct KEKpub database item, just set it into variable storage,
717 Status
= gRT
->SetVariable(
718 EFI_KEY_EXCHANGE_KEY_NAME
,
719 &gEfiGlobalVariableGuid
,
724 if (EFI_ERROR (Status
)) {
730 CloseEnrolledFile(Private
->FileContext
);
732 if (Private
->SignatureGUID
!= NULL
) {
733 FreePool (Private
->SignatureGUID
);
734 Private
->SignatureGUID
= NULL
;
737 if (KeyBlob
!= NULL
) {
740 if (KeyBuffer
!= NULL
) {
741 FreePool (KeyBuffer
);
743 if (KekSigList
!= NULL
) {
744 FreePool (KekSigList
);
751 Enroll a new KEK item from X509 certificate file.
753 @param[in] PrivateData The module's private data.
755 @retval EFI_SUCCESS New X509 is enrolled successfully.
756 @retval EFI_INVALID_PARAMETER The parameter is invalid.
757 @retval EFI_UNSUPPORTED Unsupported command.
758 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
763 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
769 EFI_SIGNATURE_DATA
*KEKSigData
;
770 EFI_SIGNATURE_LIST
*KekSigList
;
772 UINTN KekSigListSize
;
782 Status
= ReadFileContent (
783 Private
->FileContext
->FHandle
,
788 if (EFI_ERROR (Status
)) {
791 ASSERT (X509Data
!= NULL
);
793 KekSigListSize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
;
794 KekSigList
= (EFI_SIGNATURE_LIST
*) AllocateZeroPool (KekSigListSize
);
795 if (KekSigList
== NULL
) {
796 Status
= EFI_OUT_OF_RESOURCES
;
801 // Fill Certificate Database parameters.
803 KekSigList
->SignatureListSize
= (UINT32
) KekSigListSize
;
804 KekSigList
->SignatureHeaderSize
= 0;
805 KekSigList
->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
806 CopyGuid (&KekSigList
->SignatureType
, &gEfiCertX509Guid
);
808 KEKSigData
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) KekSigList
+ sizeof (EFI_SIGNATURE_LIST
));
809 CopyGuid (&KEKSigData
->SignatureOwner
, Private
->SignatureGUID
);
810 CopyMem (KEKSigData
->SignatureData
, X509Data
, X509DataSize
);
813 // Check if KEK been already existed.
814 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
815 // new kek to original variable
817 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
818 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
819 Status
= CreateTimeBasedPayload (&KekSigListSize
, (UINT8
**) &KekSigList
);
820 if (EFI_ERROR (Status
)) {
821 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
825 Status
= gRT
->GetVariable(
826 EFI_KEY_EXCHANGE_KEY_NAME
,
827 &gEfiGlobalVariableGuid
,
832 if (Status
== EFI_BUFFER_TOO_SMALL
) {
833 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
834 } else if (Status
!= EFI_NOT_FOUND
) {
838 Status
= gRT
->SetVariable(
839 EFI_KEY_EXCHANGE_KEY_NAME
,
840 &gEfiGlobalVariableGuid
,
845 if (EFI_ERROR (Status
)) {
851 CloseEnrolledFile(Private
->FileContext
);
853 if (Private
->SignatureGUID
!= NULL
) {
854 FreePool (Private
->SignatureGUID
);
855 Private
->SignatureGUID
= NULL
;
858 if (KekSigList
!= NULL
) {
859 FreePool (KekSigList
);
866 Enroll new KEK into the System without PK's authentication.
867 The SignatureOwner GUID will be Private->SignatureGUID.
869 @param[in] PrivateData The module's private data.
871 @retval EFI_SUCCESS New KEK enrolled successful.
872 @retval EFI_INVALID_PARAMETER The parameter is invalid.
873 @retval others Fail to enroll KEK data.
877 EnrollKeyExchangeKey (
878 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
885 if ((Private
->FileContext
->FHandle
== NULL
) || (Private
->FileContext
->FileName
== NULL
) || (Private
->SignatureGUID
== NULL
)) {
886 return EFI_INVALID_PARAMETER
;
889 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
890 if (EFI_ERROR (Status
)) {
895 // Parse the file's postfix. Supports DER-encoded X509 certificate,
896 // and .pbk as RSA public key file.
898 NameLength
= StrLen (Private
->FileContext
->FileName
);
899 if (NameLength
<= 4) {
900 return EFI_INVALID_PARAMETER
;
902 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
903 if (IsDerEncodeCertificate(FilePostFix
)) {
904 return EnrollX509ToKek (Private
);
905 } else if (CompareMem (FilePostFix
, L
".pbk",4) == 0) {
906 return EnrollRsa2048ToKek (Private
);
909 // File type is wrong, simply close it
911 CloseEnrolledFile(Private
->FileContext
);
913 return EFI_INVALID_PARAMETER
;
918 Enroll a new X509 certificate into Signature Database (DB or DBX or DBT) without
919 KEK's authentication.
921 @param[in] PrivateData The module's private data.
922 @param[in] VariableName Variable name of signature database, must be
923 EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
925 @retval EFI_SUCCESS New X509 is enrolled successfully.
926 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
931 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
932 IN CHAR16
*VariableName
938 EFI_SIGNATURE_LIST
*SigDBCert
;
939 EFI_SIGNATURE_DATA
*SigDBCertData
;
950 SigDBCertData
= NULL
;
953 Status
= ReadFileContent (
954 Private
->FileContext
->FHandle
,
959 if (EFI_ERROR (Status
)) {
962 ASSERT (X509Data
!= NULL
);
964 SigDBSize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
;
966 Data
= AllocateZeroPool (SigDBSize
);
968 Status
= EFI_OUT_OF_RESOURCES
;
973 // Fill Certificate Database parameters.
975 SigDBCert
= (EFI_SIGNATURE_LIST
*) Data
;
976 SigDBCert
->SignatureListSize
= (UINT32
) SigDBSize
;
977 SigDBCert
->SignatureHeaderSize
= 0;
978 SigDBCert
->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
979 CopyGuid (&SigDBCert
->SignatureType
, &gEfiCertX509Guid
);
981 SigDBCertData
= (EFI_SIGNATURE_DATA
*) ((UINT8
* ) SigDBCert
+ sizeof (EFI_SIGNATURE_LIST
));
982 CopyGuid (&SigDBCertData
->SignatureOwner
, Private
->SignatureGUID
);
983 CopyMem ((UINT8
* ) (SigDBCertData
->SignatureData
), X509Data
, X509DataSize
);
986 // Check if signature database entry has been already existed.
987 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
988 // new signature data to original variable
990 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
991 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
992 Status
= CreateTimeBasedPayload (&SigDBSize
, (UINT8
**) &Data
);
993 if (EFI_ERROR (Status
)) {
994 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
998 Status
= gRT
->GetVariable(
1000 &gEfiImageSecurityDatabaseGuid
,
1005 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1006 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
1007 } else if (Status
!= EFI_NOT_FOUND
) {
1011 Status
= gRT
->SetVariable(
1013 &gEfiImageSecurityDatabaseGuid
,
1018 if (EFI_ERROR (Status
)) {
1024 CloseEnrolledFile(Private
->FileContext
);
1026 if (Private
->SignatureGUID
!= NULL
) {
1027 FreePool (Private
->SignatureGUID
);
1028 Private
->SignatureGUID
= NULL
;
1035 if (X509Data
!= NULL
) {
1036 FreePool (X509Data
);
1043 Check whether signature is in specified database.
1045 @param[in] VariableName Name of database variable that is searched in.
1046 @param[in] Signature Pointer to signature that is searched for.
1047 @param[in] SignatureSize Size of Signature.
1049 @return TRUE Found the signature in the variable database.
1050 @return FALSE Not found the signature in the variable database.
1054 IsSignatureFoundInDatabase (
1055 IN CHAR16
*VariableName
,
1056 IN UINT8
*Signature
,
1057 IN UINTN SignatureSize
1061 EFI_SIGNATURE_LIST
*CertList
;
1062 EFI_SIGNATURE_DATA
*Cert
;
1070 // Read signature database variable.
1075 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, NULL
);
1076 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1080 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
1085 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, Data
);
1086 if (EFI_ERROR (Status
)) {
1091 // Enumerate all signature data in SigDB to check if signature exists for executable.
1093 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
1094 while ((DataSize
> 0) && (DataSize
>= CertList
->SignatureListSize
)) {
1095 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
1096 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
1097 if ((CertList
->SignatureSize
== sizeof(EFI_SIGNATURE_DATA
) - 1 + SignatureSize
) && (CompareGuid(&CertList
->SignatureType
, &gEfiCertX509Guid
))) {
1098 for (Index
= 0; Index
< CertCount
; Index
++) {
1099 if (CompareMem (Cert
->SignatureData
, Signature
, SignatureSize
) == 0) {
1101 // Find the signature in database.
1106 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
1114 DataSize
-= CertList
->SignatureListSize
;
1115 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
1127 Calculate the hash of a certificate data with the specified hash algorithm.
1129 @param[in] CertData The certificate data to be hashed.
1130 @param[in] CertSize The certificate size in bytes.
1131 @param[in] HashAlg The specified hash algorithm.
1132 @param[out] CertHash The output digest of the certificate
1134 @retval TRUE Successfully got the hash of the CertData.
1135 @retval FALSE Failed to get the hash of CertData.
1155 if (HashAlg
>= HASHALG_MAX
) {
1160 // Retrieve the TBSCertificate for Hash Calculation.
1162 if (!X509GetTBSCert (CertData
, CertSize
, &TBSCert
, &TBSCertSize
)) {
1167 // 1. Initialize context of hash.
1169 CtxSize
= mHash
[HashAlg
].GetContextSize ();
1170 HashCtx
= AllocatePool (CtxSize
);
1171 ASSERT (HashCtx
!= NULL
);
1174 // 2. Initialize a hash context.
1176 Status
= mHash
[HashAlg
].HashInit (HashCtx
);
1182 // 3. Calculate the hash.
1184 Status
= mHash
[HashAlg
].HashUpdate (HashCtx
, TBSCert
, TBSCertSize
);
1190 // 4. Get the hash result.
1192 ZeroMem (CertHash
, mHash
[HashAlg
].DigestLength
);
1193 Status
= mHash
[HashAlg
].HashFinal (HashCtx
, CertHash
);
1196 if (HashCtx
!= NULL
) {
1204 Check whether the hash of an X.509 certificate is in forbidden database (DBX).
1206 @param[in] Certificate Pointer to X.509 Certificate that is searched for.
1207 @param[in] CertSize Size of X.509 Certificate.
1209 @return TRUE Found the certificate hash in the forbidden database.
1210 @return FALSE Certificate hash is Not found in the forbidden database.
1214 IsCertHashFoundInDbx (
1215 IN UINT8
*Certificate
,
1221 EFI_SIGNATURE_LIST
*DbxList
;
1222 EFI_SIGNATURE_DATA
*CertHash
;
1223 UINTN CertHashCount
;
1226 UINT8 CertDigest
[MAX_DIGEST_SIZE
];
1228 UINTN SiglistHeaderSize
;
1233 HashAlg
= HASHALG_MAX
;
1237 // Read signature database variable.
1240 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, NULL
);
1241 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1245 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
1250 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, Data
);
1251 if (EFI_ERROR (Status
)) {
1256 // Check whether the certificate hash exists in the forbidden database.
1258 DbxList
= (EFI_SIGNATURE_LIST
*) Data
;
1259 while ((DataSize
> 0) && (DataSize
>= DbxList
->SignatureListSize
)) {
1261 // Determine Hash Algorithm of Certificate in the forbidden database.
1263 if (CompareGuid (&DbxList
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
1264 HashAlg
= HASHALG_SHA256
;
1265 } else if (CompareGuid (&DbxList
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
1266 HashAlg
= HASHALG_SHA384
;
1267 } else if (CompareGuid (&DbxList
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
1268 HashAlg
= HASHALG_SHA512
;
1270 DataSize
-= DbxList
->SignatureListSize
;
1271 DbxList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) DbxList
+ DbxList
->SignatureListSize
);
1276 // Calculate the hash value of current db certificate for comparision.
1278 if (!CalculateCertHash (Certificate
, CertSize
, HashAlg
, CertDigest
)) {
1282 SiglistHeaderSize
= sizeof (EFI_SIGNATURE_LIST
) + DbxList
->SignatureHeaderSize
;
1283 CertHash
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) DbxList
+ SiglistHeaderSize
);
1284 CertHashCount
= (DbxList
->SignatureListSize
- SiglistHeaderSize
) / DbxList
->SignatureSize
;
1285 for (Index
= 0; Index
< CertHashCount
; Index
++) {
1287 // Iterate each Signature Data Node within this CertList for verify.
1289 DbxCertHash
= CertHash
->SignatureData
;
1290 if (CompareMem (DbxCertHash
, CertDigest
, mHash
[HashAlg
].DigestLength
) == 0) {
1292 // Hash of Certificate is found in forbidden database.
1297 CertHash
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertHash
+ DbxList
->SignatureSize
);
1300 DataSize
-= DbxList
->SignatureListSize
;
1301 DbxList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) DbxList
+ DbxList
->SignatureListSize
);
1313 Check whether the signature list exists in given variable data.
1315 It searches the signature list for the certificate hash by CertType.
1316 If the signature list is found, get the offset of Database for the
1317 next hash of a certificate.
1319 @param[in] Database Variable data to save signature list.
1320 @param[in] DatabaseSize Variable size.
1321 @param[in] SignatureType The type of the signature.
1322 @param[out] Offset The offset to save a new hash of certificate.
1324 @return TRUE The signature list is found in the forbidden database.
1325 @return FALSE The signature list is not found in the forbidden database.
1328 GetSignaturelistOffset (
1329 IN EFI_SIGNATURE_LIST
*Database
,
1330 IN UINTN DatabaseSize
,
1331 IN EFI_GUID
*SignatureType
,
1335 EFI_SIGNATURE_LIST
*SigList
;
1338 if ((Database
== NULL
) || (DatabaseSize
== 0)) {
1344 SiglistSize
= DatabaseSize
;
1345 while ((SiglistSize
> 0) && (SiglistSize
>= SigList
->SignatureListSize
)) {
1346 if (CompareGuid (&SigList
->SignatureType
, SignatureType
)) {
1347 *Offset
= DatabaseSize
- SiglistSize
;
1350 SiglistSize
-= SigList
->SignatureListSize
;
1351 SigList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) SigList
+ SigList
->SignatureListSize
);
1358 Enroll a new X509 certificate hash into Signature Database (dbx) without
1359 KEK's authentication.
1361 @param[in] PrivateData The module's private data.
1362 @param[in] HashAlg The hash algorithm to enroll the certificate.
1363 @param[in] RevocationDate The revocation date of the certificate.
1364 @param[in] RevocationTime The revocation time of the certificate.
1365 @param[in] AlwaysRevocation Indicate whether the certificate is always revoked.
1367 @retval EFI_SUCCESS New X509 is enrolled successfully.
1368 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1369 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
1373 EnrollX509HashtoSigDB (
1374 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
1376 IN EFI_HII_DATE
*RevocationDate
,
1377 IN EFI_HII_TIME
*RevocationTime
,
1378 IN BOOLEAN AlwaysRevocation
1384 EFI_SIGNATURE_LIST
*SignatureList
;
1385 UINTN SignatureListSize
;
1391 EFI_SIGNATURE_DATA
*SignatureData
;
1392 UINTN SignatureSize
;
1393 EFI_GUID SignatureType
;
1395 UINT8 CertHash
[MAX_DIGEST_SIZE
];
1396 UINT16
* FilePostFix
;
1403 SignatureData
= NULL
;
1404 SignatureList
= NULL
;
1408 if ((Private
->FileContext
->FileName
== NULL
) || (Private
->FileContext
->FHandle
== NULL
) || (Private
->SignatureGUID
== NULL
)) {
1409 return EFI_INVALID_PARAMETER
;
1412 Status
= SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE
);
1413 if (EFI_ERROR (Status
)) {
1418 // Parse the file's postfix.
1420 NameLength
= StrLen (Private
->FileContext
->FileName
);
1421 if (NameLength
<= 4) {
1422 return EFI_INVALID_PARAMETER
;
1424 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
1425 if (!IsDerEncodeCertificate(FilePostFix
)) {
1427 // Only supports DER-encoded X509 certificate.
1429 return EFI_INVALID_PARAMETER
;
1433 // Get the certificate from file and calculate its hash.
1435 Status
= ReadFileContent (
1436 Private
->FileContext
->FHandle
,
1441 if (EFI_ERROR (Status
)) {
1444 ASSERT (X509Data
!= NULL
);
1446 if (!CalculateCertHash (X509Data
, X509DataSize
, HashAlg
, CertHash
)) {
1451 // Get the variable for enrollment.
1454 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, NULL
);
1455 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1456 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
1458 return EFI_OUT_OF_RESOURCES
;
1461 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, Data
);
1462 if (EFI_ERROR (Status
)) {
1468 // Allocate memory for Signature and fill the Signature
1470 SignatureSize
= sizeof(EFI_SIGNATURE_DATA
) - 1 + sizeof (EFI_TIME
) + mHash
[HashAlg
].DigestLength
;
1471 SignatureData
= (EFI_SIGNATURE_DATA
*) AllocateZeroPool (SignatureSize
);
1472 if (SignatureData
== NULL
) {
1473 return EFI_OUT_OF_RESOURCES
;
1475 CopyGuid (&SignatureData
->SignatureOwner
, Private
->SignatureGUID
);
1476 CopyMem (SignatureData
->SignatureData
, CertHash
, mHash
[HashAlg
].DigestLength
);
1481 if (!AlwaysRevocation
) {
1482 Time
= (EFI_TIME
*)(&SignatureData
->SignatureData
+ mHash
[HashAlg
].DigestLength
);
1483 Time
->Year
= RevocationDate
->Year
;
1484 Time
->Month
= RevocationDate
->Month
;
1485 Time
->Day
= RevocationDate
->Day
;
1486 Time
->Hour
= RevocationTime
->Hour
;
1487 Time
->Minute
= RevocationTime
->Minute
;
1488 Time
->Second
= RevocationTime
->Second
;
1492 // Determine the GUID for certificate hash.
1495 case HASHALG_SHA256
:
1496 SignatureType
= gEfiCertX509Sha256Guid
;
1498 case HASHALG_SHA384
:
1499 SignatureType
= gEfiCertX509Sha384Guid
;
1501 case HASHALG_SHA512
:
1502 SignatureType
= gEfiCertX509Sha512Guid
;
1509 // Add signature into the new variable data buffer
1511 if (GetSignaturelistOffset((EFI_SIGNATURE_LIST
*)Data
, DataSize
, &SignatureType
, &Offset
)) {
1513 // Add the signature to the found signaturelist.
1515 DbSize
= DataSize
+ SignatureSize
;
1516 NewData
= AllocateZeroPool (DbSize
);
1517 if (NewData
== NULL
) {
1518 Status
= EFI_OUT_OF_RESOURCES
;
1522 SignatureList
= (EFI_SIGNATURE_LIST
*)(Data
+ Offset
);
1523 SignatureListSize
= (UINTN
) ReadUnaligned32 ((UINT32
*)&SignatureList
->SignatureListSize
);
1524 CopyMem (NewData
, Data
, Offset
+ SignatureListSize
);
1526 SignatureList
= (EFI_SIGNATURE_LIST
*)(NewData
+ Offset
);
1527 WriteUnaligned32 ((UINT32
*) &SignatureList
->SignatureListSize
, (UINT32
)(SignatureListSize
+ SignatureSize
));
1529 Offset
+= SignatureListSize
;
1530 CopyMem (NewData
+ Offset
, SignatureData
, SignatureSize
);
1531 CopyMem (NewData
+ Offset
+ SignatureSize
, Data
+ Offset
, DataSize
- Offset
);
1538 // Create a new signaturelist, and add the signature into the signaturelist.
1540 DbSize
= DataSize
+ sizeof(EFI_SIGNATURE_LIST
) + SignatureSize
;
1541 NewData
= AllocateZeroPool (DbSize
);
1542 if (NewData
== NULL
) {
1543 Status
= EFI_OUT_OF_RESOURCES
;
1547 // Fill Certificate Database parameters.
1549 SignatureList
= (EFI_SIGNATURE_LIST
*) (NewData
+ DataSize
);
1550 SignatureListSize
= sizeof(EFI_SIGNATURE_LIST
) + SignatureSize
;
1551 WriteUnaligned32 ((UINT32
*) &SignatureList
->SignatureListSize
, (UINT32
) SignatureListSize
);
1552 WriteUnaligned32 ((UINT32
*) &SignatureList
->SignatureSize
, (UINT32
) SignatureSize
);
1553 CopyGuid (&SignatureList
->SignatureType
, &SignatureType
);
1554 CopyMem ((UINT8
* ) SignatureList
+ sizeof (EFI_SIGNATURE_LIST
), SignatureData
, SignatureSize
);
1555 if ((DataSize
!= 0) && (Data
!= NULL
)) {
1556 CopyMem (NewData
, Data
, DataSize
);
1563 Status
= CreateTimeBasedPayload (&DataSize
, (UINT8
**) &Data
);
1564 if (EFI_ERROR (Status
)) {
1568 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
1569 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
1570 Status
= gRT
->SetVariable(
1571 EFI_IMAGE_SECURITY_DATABASE1
,
1572 &gEfiImageSecurityDatabaseGuid
,
1577 if (EFI_ERROR (Status
)) {
1583 CloseEnrolledFile(Private
->FileContext
);
1585 if (Private
->SignatureGUID
!= NULL
) {
1586 FreePool (Private
->SignatureGUID
);
1587 Private
->SignatureGUID
= NULL
;
1594 if (SignatureData
!= NULL
) {
1595 FreePool (SignatureData
);
1598 if (X509Data
!= NULL
) {
1599 FreePool (X509Data
);
1606 Check whether a certificate from a file exists in dbx.
1608 @param[in] PrivateData The module's private data.
1609 @param[in] VariableName Variable name of signature database, must be
1610 EFI_IMAGE_SECURITY_DATABASE1.
1612 @retval TRUE The X509 certificate is found in dbx successfully.
1613 @retval FALSE The X509 certificate is not found in dbx.
1617 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
1618 IN CHAR16
*VariableName
1627 // Read the certificate from file
1631 Status
= ReadFileContent (
1632 Private
->FileContext
->FHandle
,
1637 if (EFI_ERROR (Status
)) {
1642 // Check the raw certificate.
1645 if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1
, X509Data
, X509DataSize
)) {
1651 // Check the hash of certificate.
1653 if (IsCertHashFoundInDbx (X509Data
, X509DataSize
)) {
1659 if (X509Data
!= NULL
) {
1660 FreePool (X509Data
);
1667 Reads contents of a PE/COFF image in memory buffer.
1669 Caution: This function may receive untrusted input.
1670 PE/COFF image is external input, so this function will make sure the PE/COFF image content
1671 read is within the image buffer.
1673 @param FileHandle Pointer to the file handle to read the PE/COFF image.
1674 @param FileOffset Offset into the PE/COFF image to begin the read operation.
1675 @param ReadSize On input, the size in bytes of the requested read operation.
1676 On output, the number of bytes actually read.
1677 @param Buffer Output buffer that contains the data read from the PE/COFF image.
1679 @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
1683 SecureBootConfigImageRead (
1684 IN VOID
*FileHandle
,
1685 IN UINTN FileOffset
,
1686 IN OUT UINTN
*ReadSize
,
1692 if (FileHandle
== NULL
|| ReadSize
== NULL
|| Buffer
== NULL
) {
1693 return EFI_INVALID_PARAMETER
;
1696 if (MAX_ADDRESS
- FileOffset
< *ReadSize
) {
1697 return EFI_INVALID_PARAMETER
;
1700 EndPosition
= FileOffset
+ *ReadSize
;
1701 if (EndPosition
> mImageSize
) {
1702 *ReadSize
= (UINT32
)(mImageSize
- FileOffset
);
1705 if (FileOffset
>= mImageSize
) {
1709 CopyMem (Buffer
, (UINT8
*)((UINTN
) FileHandle
+ FileOffset
), *ReadSize
);
1715 Load PE/COFF image information into internal buffer and check its validity.
1717 @retval EFI_SUCCESS Successful
1718 @retval EFI_UNSUPPORTED Invalid PE/COFF file
1719 @retval EFI_ABORTED Serious error occurs, like file I/O error etc.
1727 EFI_IMAGE_DOS_HEADER
*DosHdr
;
1728 EFI_IMAGE_NT_HEADERS32
*NtHeader32
;
1729 EFI_IMAGE_NT_HEADERS64
*NtHeader64
;
1730 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1736 ZeroMem (&ImageContext
, sizeof (ImageContext
));
1737 ImageContext
.Handle
= (VOID
*) mImageBase
;
1738 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) SecureBootConfigImageRead
;
1741 // Get information about the image being loaded
1743 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1744 if (EFI_ERROR (Status
)) {
1746 // The information can't be got from the invalid PeImage
1748 DEBUG ((DEBUG_INFO
, "SecureBootConfigDxe: PeImage invalid. \n"));
1753 // Read the Dos header
1755 DosHdr
= (EFI_IMAGE_DOS_HEADER
*)(mImageBase
);
1756 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
)
1759 // DOS image header is present,
1760 // So read the PE header after the DOS image header
1762 mPeCoffHeaderOffset
= DosHdr
->e_lfanew
;
1766 mPeCoffHeaderOffset
= 0;
1770 // Read PE header and check the signature validity and machine compatibility
1772 NtHeader32
= (EFI_IMAGE_NT_HEADERS32
*) (mImageBase
+ mPeCoffHeaderOffset
);
1773 if (NtHeader32
->Signature
!= EFI_IMAGE_NT_SIGNATURE
)
1775 return EFI_UNSUPPORTED
;
1778 mNtHeader
.Pe32
= NtHeader32
;
1781 // Check the architecture field of PE header and get the Certificate Data Directory data
1782 // Note the size of FileHeader field is constant for both IA32 and X64 arch
1784 if ((NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA32
)
1785 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_EBC
)
1786 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_ARMTHUMB_MIXED
)) {
1788 // 32-bits Architecture
1790 mImageType
= ImageType_IA32
;
1791 mSecDataDir
= (EFI_IMAGE_SECURITY_DATA_DIRECTORY
*) &(NtHeader32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]);
1793 else if ((NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA64
)
1794 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_X64
)
1795 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_AARCH64
)) {
1797 // 64-bits Architecture
1799 mImageType
= ImageType_X64
;
1800 NtHeader64
= (EFI_IMAGE_NT_HEADERS64
*) (mImageBase
+ mPeCoffHeaderOffset
);
1801 mSecDataDir
= (EFI_IMAGE_SECURITY_DATA_DIRECTORY
*) &(NtHeader64
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]);
1803 return EFI_UNSUPPORTED
;
1810 Calculate hash of Pe/Coff image based on the authenticode image hashing in
1811 PE/COFF Specification 8.0 Appendix A
1813 Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in
1814 the function LoadPeImage ().
1816 @param[in] HashAlg Hash algorithm type.
1818 @retval TRUE Successfully hash image.
1819 @retval FALSE Fail in hash image.
1828 EFI_IMAGE_SECTION_HEADER
*Section
;
1833 UINTN SumOfBytesHashed
;
1834 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1839 SectionHeader
= NULL
;
1842 if (HashAlg
!= HASHALG_SHA256
) {
1847 // Initialize context of hash.
1849 ZeroMem (mImageDigest
, MAX_DIGEST_SIZE
);
1851 mImageDigestSize
= SHA256_DIGEST_SIZE
;
1852 mCertType
= gEfiCertSha256Guid
;
1854 CtxSize
= mHash
[HashAlg
].GetContextSize();
1856 HashCtx
= AllocatePool (CtxSize
);
1857 ASSERT (HashCtx
!= NULL
);
1859 // 1. Load the image header into memory.
1861 // 2. Initialize a SHA hash context.
1862 Status
= mHash
[HashAlg
].HashInit(HashCtx
);
1867 // Measuring PE/COFF Image Header;
1868 // But CheckSum field and SECURITY data directory (certificate) are excluded
1872 // 3. Calculate the distance from the base of the image header to the image checksum address.
1873 // 4. Hash the image header from its base to beginning of the image checksum.
1875 HashBase
= mImageBase
;
1876 if (mNtHeader
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1880 HashSize
= (UINTN
) (&mNtHeader
.Pe32
->OptionalHeader
.CheckSum
) - (UINTN
) HashBase
;
1883 // Use PE32+ offset.
1885 HashSize
= (UINTN
) (&mNtHeader
.Pe32Plus
->OptionalHeader
.CheckSum
) - (UINTN
) HashBase
;
1888 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
1893 // 5. Skip over the image checksum (it occupies a single ULONG).
1894 // 6. Get the address of the beginning of the Cert Directory.
1895 // 7. Hash everything from the end of the checksum to the start of the Cert Directory.
1897 if (mNtHeader
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1901 HashBase
= (UINT8
*) &mNtHeader
.Pe32
->OptionalHeader
.CheckSum
+ sizeof (UINT32
);
1902 HashSize
= (UINTN
) (&mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]) - (UINTN
) HashBase
;
1905 // Use PE32+ offset.
1907 HashBase
= (UINT8
*) &mNtHeader
.Pe32Plus
->OptionalHeader
.CheckSum
+ sizeof (UINT32
);
1908 HashSize
= (UINTN
) (&mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]) - (UINTN
) HashBase
;
1911 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
1916 // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
1917 // 9. Hash everything from the end of the Cert Directory to the end of image header.
1919 if (mNtHeader
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1923 HashBase
= (UINT8
*) &mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1];
1924 HashSize
= mNtHeader
.Pe32
->OptionalHeader
.SizeOfHeaders
- ((UINTN
) (&mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1]) - (UINTN
) mImageBase
);
1927 // Use PE32+ offset.
1929 HashBase
= (UINT8
*) &mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1];
1930 HashSize
= mNtHeader
.Pe32Plus
->OptionalHeader
.SizeOfHeaders
- ((UINTN
) (&mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1]) - (UINTN
) mImageBase
);
1933 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
1938 // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.
1940 if (mNtHeader
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1944 SumOfBytesHashed
= mNtHeader
.Pe32
->OptionalHeader
.SizeOfHeaders
;
1949 SumOfBytesHashed
= mNtHeader
.Pe32Plus
->OptionalHeader
.SizeOfHeaders
;
1953 // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
1954 // structures in the image. The 'NumberOfSections' field of the image
1955 // header indicates how big the table should be. Do not include any
1956 // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
1958 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER
) * mNtHeader
.Pe32
->FileHeader
.NumberOfSections
);
1959 ASSERT (SectionHeader
!= NULL
);
1961 // 12. Using the 'PointerToRawData' in the referenced section headers as
1962 // a key, arrange the elements in the table in ascending order. In other
1963 // words, sort the section headers according to the disk-file offset of
1966 Section
= (EFI_IMAGE_SECTION_HEADER
*) (
1968 mPeCoffHeaderOffset
+
1970 sizeof (EFI_IMAGE_FILE_HEADER
) +
1971 mNtHeader
.Pe32
->FileHeader
.SizeOfOptionalHeader
1973 for (Index
= 0; Index
< mNtHeader
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
1975 while ((Pos
> 0) && (Section
->PointerToRawData
< SectionHeader
[Pos
- 1].PointerToRawData
)) {
1976 CopyMem (&SectionHeader
[Pos
], &SectionHeader
[Pos
- 1], sizeof (EFI_IMAGE_SECTION_HEADER
));
1979 CopyMem (&SectionHeader
[Pos
], Section
, sizeof (EFI_IMAGE_SECTION_HEADER
));
1984 // 13. Walk through the sorted table, bring the corresponding section
1985 // into memory, and hash the entire section (using the 'SizeOfRawData'
1986 // field in the section header to determine the amount of data to hash).
1987 // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
1988 // 15. Repeat steps 13 and 14 for all the sections in the sorted table.
1990 for (Index
= 0; Index
< mNtHeader
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
1991 Section
= &SectionHeader
[Index
];
1992 if (Section
->SizeOfRawData
== 0) {
1995 HashBase
= mImageBase
+ Section
->PointerToRawData
;
1996 HashSize
= (UINTN
) Section
->SizeOfRawData
;
1998 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
2003 SumOfBytesHashed
+= HashSize
;
2007 // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
2008 // data in the file that needs to be added to the hash. This data begins
2009 // at file offset SUM_OF_BYTES_HASHED and its length is:
2010 // FileSize - (CertDirectory->Size)
2012 if (mImageSize
> SumOfBytesHashed
) {
2013 HashBase
= mImageBase
+ SumOfBytesHashed
;
2014 if (mNtHeader
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
2020 mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
].Size
-
2024 // Use PE32+ offset.
2028 mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
].Size
-
2032 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
2038 Status
= mHash
[HashAlg
].HashFinal(HashCtx
, mImageDigest
);
2041 if (HashCtx
!= NULL
) {
2044 if (SectionHeader
!= NULL
) {
2045 FreePool (SectionHeader
);
2051 Recognize the Hash algorithm in PE/COFF Authenticode and calculate hash of
2052 Pe/Coff image based on the authenticated image hashing in PE/COFF Specification
2055 @retval EFI_UNSUPPORTED Hash algorithm is not supported.
2056 @retval EFI_SUCCESS Hash successfully.
2065 WIN_CERTIFICATE_EFI_PKCS
*PkcsCertData
;
2067 PkcsCertData
= (WIN_CERTIFICATE_EFI_PKCS
*) (mImageBase
+ mSecDataDir
->Offset
);
2069 for (Index
= 0; Index
< HASHALG_MAX
; Index
++) {
2071 // Check the Hash algorithm in PE/COFF Authenticode.
2072 // According to PKCS#7 Definition:
2073 // SignedData ::= SEQUENCE {
2075 // digestAlgorithms DigestAlgorithmIdentifiers,
2076 // contentInfo ContentInfo,
2078 // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
2079 // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
2080 // Fixed offset (+32) is calculated based on two bytes of length encoding.
2082 if ((*(PkcsCertData
->CertData
+ 1) & TWO_BYTE_ENCODE
) != TWO_BYTE_ENCODE
) {
2084 // Only support two bytes of Long Form of Length Encoding.
2090 if (CompareMem (PkcsCertData
->CertData
+ 32, mHash
[Index
].OidValue
, mHash
[Index
].OidLength
) == 0) {
2095 if (Index
== HASHALG_MAX
) {
2096 return EFI_UNSUPPORTED
;
2100 // HASH PE Image based on Hash algorithm in PE/COFF Authenticode.
2102 if (!HashPeImage(Index
)) {
2103 return EFI_UNSUPPORTED
;
2110 Enroll a new signature of executable into Signature Database.
2112 @param[in] PrivateData The module's private data.
2113 @param[in] VariableName Variable name of signature database, must be
2114 EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
2115 or EFI_IMAGE_SECURITY_DATABASE2.
2117 @retval EFI_SUCCESS New signature is enrolled successfully.
2118 @retval EFI_INVALID_PARAMETER The parameter is invalid.
2119 @retval EFI_UNSUPPORTED Unsupported command.
2120 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2124 EnrollAuthentication2Descriptor (
2125 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
2126 IN CHAR16
*VariableName
2137 // DBT only support DER-X509 Cert Enrollment
2139 if (StrCmp (VariableName
, EFI_IMAGE_SECURITY_DATABASE2
) == 0) {
2140 return EFI_UNSUPPORTED
;
2144 // Read the whole file content
2146 Status
= ReadFileContent(
2147 Private
->FileContext
->FHandle
,
2148 (VOID
**) &mImageBase
,
2152 if (EFI_ERROR (Status
)) {
2155 ASSERT (mImageBase
!= NULL
);
2157 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
2158 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
2161 // Check if SigDB variable has been already existed.
2162 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
2163 // new signature data to original variable
2166 Status
= gRT
->GetVariable(
2168 &gEfiImageSecurityDatabaseGuid
,
2173 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2174 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
2175 } else if (Status
!= EFI_NOT_FOUND
) {
2180 // Directly set AUTHENTICATION_2 data to SetVariable
2182 Status
= gRT
->SetVariable(
2184 &gEfiImageSecurityDatabaseGuid
,
2190 DEBUG((DEBUG_INFO
, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName
, Status
));
2194 CloseEnrolledFile(Private
->FileContext
);
2200 if (mImageBase
!= NULL
) {
2201 FreePool (mImageBase
);
2211 Enroll a new signature of executable into Signature Database.
2213 @param[in] PrivateData The module's private data.
2214 @param[in] VariableName Variable name of signature database, must be
2215 EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
2216 or EFI_IMAGE_SECURITY_DATABASE2.
2218 @retval EFI_SUCCESS New signature is enrolled successfully.
2219 @retval EFI_INVALID_PARAMETER The parameter is invalid.
2220 @retval EFI_UNSUPPORTED Unsupported command.
2221 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2225 EnrollImageSignatureToSigDB (
2226 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
2227 IN CHAR16
*VariableName
2231 EFI_SIGNATURE_LIST
*SigDBCert
;
2232 EFI_SIGNATURE_DATA
*SigDBCertData
;
2237 WIN_CERTIFICATE_UEFI_GUID
*GuidCertData
;
2240 GuidCertData
= NULL
;
2242 if (StrCmp (VariableName
, EFI_IMAGE_SECURITY_DATABASE2
) == 0) {
2243 return EFI_UNSUPPORTED
;
2247 // Form the SigDB certificate list.
2248 // Format the data item into EFI_SIGNATURE_LIST type.
2250 // We need to parse signature data of executable from specified signed executable file.
2251 // In current implementation, we simply trust the pass-in signed executable file.
2252 // In reality, it's OS's responsibility to verify the signed executable file.
2256 // Read the whole file content
2258 Status
= ReadFileContent(
2259 Private
->FileContext
->FHandle
,
2260 (VOID
**) &mImageBase
,
2264 if (EFI_ERROR (Status
)) {
2267 ASSERT (mImageBase
!= NULL
);
2269 Status
= LoadPeImage ();
2270 if (EFI_ERROR (Status
)) {
2274 if (mSecDataDir
->SizeOfCert
== 0) {
2275 if (!HashPeImage (HASHALG_SHA256
)) {
2276 Status
= EFI_SECURITY_VIOLATION
;
2282 // Read the certificate data
2284 mCertificate
= (WIN_CERTIFICATE
*)(mImageBase
+ mSecDataDir
->Offset
);
2286 if (mCertificate
->wCertificateType
== WIN_CERT_TYPE_EFI_GUID
) {
2287 GuidCertData
= (WIN_CERTIFICATE_UEFI_GUID
*) mCertificate
;
2288 if (CompareMem (&GuidCertData
->CertType
, &gEfiCertTypeRsa2048Sha256Guid
, sizeof(EFI_GUID
)) != 0) {
2289 Status
= EFI_ABORTED
;
2293 if (!HashPeImage (HASHALG_SHA256
)) {
2294 Status
= EFI_ABORTED
;
2298 } else if (mCertificate
->wCertificateType
== WIN_CERT_TYPE_PKCS_SIGNED_DATA
) {
2300 Status
= HashPeImageByType ();
2301 if (EFI_ERROR (Status
)) {
2305 Status
= EFI_ABORTED
;
2311 // Create a new SigDB entry.
2313 SigDBSize
= sizeof(EFI_SIGNATURE_LIST
)
2314 + sizeof(EFI_SIGNATURE_DATA
) - 1
2315 + (UINT32
) mImageDigestSize
;
2317 Data
= (UINT8
*) AllocateZeroPool (SigDBSize
);
2319 Status
= EFI_OUT_OF_RESOURCES
;
2324 // Adjust the Certificate Database parameters.
2326 SigDBCert
= (EFI_SIGNATURE_LIST
*) Data
;
2327 SigDBCert
->SignatureListSize
= (UINT32
) SigDBSize
;
2328 SigDBCert
->SignatureHeaderSize
= 0;
2329 SigDBCert
->SignatureSize
= sizeof(EFI_SIGNATURE_DATA
) - 1 + (UINT32
) mImageDigestSize
;
2330 CopyGuid (&SigDBCert
->SignatureType
, &mCertType
);
2332 SigDBCertData
= (EFI_SIGNATURE_DATA
*)((UINT8
*)SigDBCert
+ sizeof(EFI_SIGNATURE_LIST
));
2333 CopyGuid (&SigDBCertData
->SignatureOwner
, Private
->SignatureGUID
);
2334 CopyMem (SigDBCertData
->SignatureData
, mImageDigest
, mImageDigestSize
);
2336 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
2337 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
2338 Status
= CreateTimeBasedPayload (&SigDBSize
, (UINT8
**) &Data
);
2339 if (EFI_ERROR (Status
)) {
2340 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
2345 // Check if SigDB variable has been already existed.
2346 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
2347 // new signature data to original variable
2350 Status
= gRT
->GetVariable(
2352 &gEfiImageSecurityDatabaseGuid
,
2357 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2358 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
2359 } else if (Status
!= EFI_NOT_FOUND
) {
2364 // Enroll the variable.
2366 Status
= gRT
->SetVariable(
2368 &gEfiImageSecurityDatabaseGuid
,
2373 if (EFI_ERROR (Status
)) {
2379 CloseEnrolledFile(Private
->FileContext
);
2381 if (Private
->SignatureGUID
!= NULL
) {
2382 FreePool (Private
->SignatureGUID
);
2383 Private
->SignatureGUID
= NULL
;
2390 if (mImageBase
!= NULL
) {
2391 FreePool (mImageBase
);
2399 Enroll signature into DB/DBX/DBT without KEK's authentication.
2400 The SignatureOwner GUID will be Private->SignatureGUID.
2402 @param[in] PrivateData The module's private data.
2403 @param[in] VariableName Variable name of signature database, must be
2404 EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
2406 @retval EFI_SUCCESS New signature enrolled successfully.
2407 @retval EFI_INVALID_PARAMETER The parameter is invalid.
2408 @retval others Fail to enroll signature data.
2412 EnrollSignatureDatabase (
2413 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
2414 IN CHAR16
*VariableName
2417 UINT16
* FilePostFix
;
2421 if ((Private
->FileContext
->FileName
== NULL
) || (Private
->FileContext
->FHandle
== NULL
) || (Private
->SignatureGUID
== NULL
)) {
2422 return EFI_INVALID_PARAMETER
;
2425 Status
= SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE
);
2426 if (EFI_ERROR (Status
)) {
2431 // Parse the file's postfix.
2433 NameLength
= StrLen (Private
->FileContext
->FileName
);
2434 if (NameLength
<= 4) {
2435 return EFI_INVALID_PARAMETER
;
2437 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
2438 if (IsDerEncodeCertificate (FilePostFix
)) {
2440 // Supports DER-encoded X509 certificate.
2442 return EnrollX509toSigDB (Private
, VariableName
);
2443 } else if (IsAuthentication2Format(Private
->FileContext
->FHandle
)){
2444 return EnrollAuthentication2Descriptor(Private
, VariableName
);
2446 return EnrollImageSignatureToSigDB (Private
, VariableName
);
2451 List all signatures in specified signature database (e.g. KEK/DB/DBX/DBT)
2452 by GUID in the page for user to select and delete as needed.
2454 @param[in] PrivateData Module's private data.
2455 @param[in] VariableName The variable name of the vendor's signature database.
2456 @param[in] VendorGuid A unique identifier for the vendor.
2457 @param[in] LabelNumber Label number to insert opcodes.
2458 @param[in] FormId Form ID of current page.
2459 @param[in] QuestionIdBase Base question id of the signature list.
2461 @retval EFI_SUCCESS Success to update the signature list page
2462 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
2467 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
2468 IN CHAR16
*VariableName
,
2469 IN EFI_GUID
*VendorGuid
,
2470 IN UINT16 LabelNumber
,
2471 IN EFI_FORM_ID FormId
,
2472 IN EFI_QUESTION_ID QuestionIdBase
2479 VOID
*StartOpCodeHandle
;
2480 VOID
*EndOpCodeHandle
;
2481 EFI_IFR_GUID_LABEL
*StartLabel
;
2482 EFI_IFR_GUID_LABEL
*EndLabel
;
2485 EFI_SIGNATURE_LIST
*CertList
;
2486 EFI_SIGNATURE_DATA
*Cert
;
2487 UINT32 ItemDataSize
;
2489 EFI_STRING_ID GuidID
;
2496 StartOpCodeHandle
= NULL
;
2497 EndOpCodeHandle
= NULL
;
2500 // Initialize the container for dynamic opcodes.
2502 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
2503 if (StartOpCodeHandle
== NULL
) {
2504 Status
= EFI_OUT_OF_RESOURCES
;
2508 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
2509 if (EndOpCodeHandle
== NULL
) {
2510 Status
= EFI_OUT_OF_RESOURCES
;
2515 // Create Hii Extend Label OpCode.
2517 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2521 sizeof (EFI_IFR_GUID_LABEL
)
2523 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2524 StartLabel
->Number
= LabelNumber
;
2526 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2530 sizeof (EFI_IFR_GUID_LABEL
)
2532 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2533 EndLabel
->Number
= LABEL_END
;
2539 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, Data
);
2540 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
2544 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
2546 Status
= EFI_OUT_OF_RESOURCES
;
2550 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, Data
);
2551 if (EFI_ERROR (Status
)) {
2555 GuidStr
= AllocateZeroPool (100);
2556 if (GuidStr
== NULL
) {
2557 Status
= EFI_OUT_OF_RESOURCES
;
2562 // Enumerate all KEK pub data.
2564 ItemDataSize
= (UINT32
) DataSize
;
2565 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
2568 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
2570 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertRsa2048Guid
)) {
2571 Help
= STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID
);
2572 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
2573 Help
= STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID
);
2574 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertSha1Guid
)) {
2575 Help
= STRING_TOKEN (STR_CERT_TYPE_SHA1_GUID
);
2576 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertSha256Guid
)) {
2577 Help
= STRING_TOKEN (STR_CERT_TYPE_SHA256_GUID
);
2578 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
2579 Help
= STRING_TOKEN (STR_CERT_TYPE_X509_SHA256_GUID
);
2580 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
2581 Help
= STRING_TOKEN (STR_CERT_TYPE_X509_SHA384_GUID
);
2582 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
2583 Help
= STRING_TOKEN (STR_CERT_TYPE_X509_SHA512_GUID
);
2586 // The signature type is not supported in current implementation.
2588 ItemDataSize
-= CertList
->SignatureListSize
;
2589 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2593 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2594 for (Index
= 0; Index
< CertCount
; Index
++) {
2595 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
2596 + sizeof (EFI_SIGNATURE_LIST
)
2597 + CertList
->SignatureHeaderSize
2598 + Index
* CertList
->SignatureSize
);
2600 // Display GUID and help
2602 GuidToString (&Cert
->SignatureOwner
, GuidStr
, 100);
2603 GuidID
= HiiSetString (PrivateData
->HiiHandle
, 0, GuidStr
, NULL
);
2604 HiiCreateCheckBoxOpCode (
2606 (EFI_QUESTION_ID
) (QuestionIdBase
+ GuidIndex
++),
2611 EFI_IFR_FLAG_CALLBACK
,
2617 ItemDataSize
-= CertList
->SignatureListSize
;
2618 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2623 PrivateData
->HiiHandle
,
2624 &gSecureBootConfigFormSetGuid
,
2630 if (StartOpCodeHandle
!= NULL
) {
2631 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2634 if (EndOpCodeHandle
!= NULL
) {
2635 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2642 if (GuidStr
!= NULL
) {
2650 Delete a KEK entry from KEK database.
2652 @param[in] PrivateData Module's private data.
2653 @param[in] QuestionId Question id of the KEK item to delete.
2655 @retval EFI_SUCCESS Delete kek item successfully.
2656 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2660 DeleteKeyExchangeKey (
2661 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
2662 IN EFI_QUESTION_ID QuestionId
2671 EFI_SIGNATURE_LIST
*CertList
;
2672 EFI_SIGNATURE_LIST
*NewCertList
;
2673 EFI_SIGNATURE_DATA
*Cert
;
2676 BOOLEAN IsKEKItemFound
;
2678 UINTN DeleteKekIndex
;
2686 DeleteKekIndex
= QuestionId
- OPTION_DEL_KEK_QUESTION_ID
;
2688 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
2689 if (EFI_ERROR (Status
)) {
2694 // Get original KEK variable.
2697 Status
= gRT
->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
, NULL
, &DataSize
, NULL
);
2698 if (EFI_ERROR(Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
2702 OldData
= (UINT8
*)AllocateZeroPool(DataSize
);
2703 if (OldData
== NULL
) {
2704 Status
= EFI_OUT_OF_RESOURCES
;
2708 Status
= gRT
->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
, &Attr
, &DataSize
, OldData
);
2709 if (EFI_ERROR(Status
)) {
2714 // Allocate space for new variable.
2716 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
2718 Status
= EFI_OUT_OF_RESOURCES
;
2723 // Enumerate all KEK pub data and erasing the target item.
2725 IsKEKItemFound
= FALSE
;
2726 KekDataSize
= (UINT32
) DataSize
;
2727 CertList
= (EFI_SIGNATURE_LIST
*) OldData
;
2730 while ((KekDataSize
> 0) && (KekDataSize
>= CertList
->SignatureListSize
)) {
2731 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertRsa2048Guid
) ||
2732 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
2733 CopyMem (Data
+ Offset
, CertList
, (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
));
2734 NewCertList
= (EFI_SIGNATURE_LIST
*)(Data
+ Offset
);
2735 Offset
+= (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2736 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2737 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2738 for (Index
= 0; Index
< CertCount
; Index
++) {
2739 if (GuidIndex
== DeleteKekIndex
) {
2741 // Find it! Skip it!
2743 NewCertList
->SignatureListSize
-= CertList
->SignatureSize
;
2744 IsKEKItemFound
= TRUE
;
2747 // This item doesn't match. Copy it to the Data buffer.
2749 CopyMem (Data
+ Offset
, Cert
, CertList
->SignatureSize
);
2750 Offset
+= CertList
->SignatureSize
;
2753 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
2757 // This List doesn't match. Copy it to the Data buffer.
2759 CopyMem (Data
+ Offset
, CertList
, CertList
->SignatureListSize
);
2760 Offset
+= CertList
->SignatureListSize
;
2763 KekDataSize
-= CertList
->SignatureListSize
;
2764 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2767 if (!IsKEKItemFound
) {
2769 // Doesn't find the Kek Item!
2771 Status
= EFI_NOT_FOUND
;
2776 // Delete the Signature header if there is no signature in the list.
2778 KekDataSize
= Offset
;
2779 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
2781 ZeroMem (OldData
, KekDataSize
);
2782 while ((KekDataSize
> 0) && (KekDataSize
>= CertList
->SignatureListSize
)) {
2783 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2784 DEBUG ((DEBUG_INFO
, " CertCount = %x\n", CertCount
));
2785 if (CertCount
!= 0) {
2786 CopyMem (OldData
+ Offset
, CertList
, CertList
->SignatureListSize
);
2787 Offset
+= CertList
->SignatureListSize
;
2789 KekDataSize
-= CertList
->SignatureListSize
;
2790 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2794 if ((Attr
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
2795 Status
= CreateTimeBasedPayload (&DataSize
, &OldData
);
2796 if (EFI_ERROR (Status
)) {
2797 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
2802 Status
= gRT
->SetVariable(
2803 EFI_KEY_EXCHANGE_KEY_NAME
,
2804 &gEfiGlobalVariableGuid
,
2809 if (EFI_ERROR (Status
)) {
2810 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r\n", Status
));
2819 if (OldData
!= NULL
) {
2823 return UpdateDeletePage (
2825 EFI_KEY_EXCHANGE_KEY_NAME
,
2826 &gEfiGlobalVariableGuid
,
2828 FORMID_DELETE_KEK_FORM
,
2829 OPTION_DEL_KEK_QUESTION_ID
2834 Delete a signature entry from signature database.
2836 @param[in] PrivateData Module's private data.
2837 @param[in] VariableName The variable name of the vendor's signature database.
2838 @param[in] VendorGuid A unique identifier for the vendor.
2839 @param[in] LabelNumber Label number to insert opcodes.
2840 @param[in] FormId Form ID of current page.
2841 @param[in] QuestionIdBase Base question id of the signature list.
2842 @param[in] DeleteIndex Signature index to delete.
2844 @retval EFI_SUCCESS Delete signature successfully.
2845 @retval EFI_NOT_FOUND Can't find the signature item,
2846 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2850 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
2851 IN CHAR16
*VariableName
,
2852 IN EFI_GUID
*VendorGuid
,
2853 IN UINT16 LabelNumber
,
2854 IN EFI_FORM_ID FormId
,
2855 IN EFI_QUESTION_ID QuestionIdBase
,
2856 IN UINTN DeleteIndex
2865 EFI_SIGNATURE_LIST
*CertList
;
2866 EFI_SIGNATURE_LIST
*NewCertList
;
2867 EFI_SIGNATURE_DATA
*Cert
;
2870 BOOLEAN IsItemFound
;
2871 UINT32 ItemDataSize
;
2880 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
2881 if (EFI_ERROR (Status
)) {
2886 // Get original signature list data.
2889 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, NULL
);
2890 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
2894 OldData
= (UINT8
*) AllocateZeroPool (DataSize
);
2895 if (OldData
== NULL
) {
2896 Status
= EFI_OUT_OF_RESOURCES
;
2900 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, &Attr
, &DataSize
, OldData
);
2901 if (EFI_ERROR(Status
)) {
2906 // Allocate space for new variable.
2908 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
2910 Status
= EFI_OUT_OF_RESOURCES
;
2915 // Enumerate all signature data and erasing the target item.
2917 IsItemFound
= FALSE
;
2918 ItemDataSize
= (UINT32
) DataSize
;
2919 CertList
= (EFI_SIGNATURE_LIST
*) OldData
;
2922 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
2923 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertRsa2048Guid
) ||
2924 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
) ||
2925 CompareGuid (&CertList
->SignatureType
, &gEfiCertSha1Guid
) ||
2926 CompareGuid (&CertList
->SignatureType
, &gEfiCertSha256Guid
) ||
2927 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha256Guid
) ||
2928 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha384Guid
) ||
2929 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha512Guid
)
2932 // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
2934 CopyMem (Data
+ Offset
, CertList
, (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
));
2935 NewCertList
= (EFI_SIGNATURE_LIST
*) (Data
+ Offset
);
2936 Offset
+= (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2937 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2938 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2939 for (Index
= 0; Index
< CertCount
; Index
++) {
2940 if (GuidIndex
== DeleteIndex
) {
2942 // Find it! Skip it!
2944 NewCertList
->SignatureListSize
-= CertList
->SignatureSize
;
2948 // This item doesn't match. Copy it to the Data buffer.
2950 CopyMem (Data
+ Offset
, (UINT8
*)(Cert
), CertList
->SignatureSize
);
2951 Offset
+= CertList
->SignatureSize
;
2954 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
2958 // This List doesn't match. Just copy it to the Data buffer.
2960 CopyMem (Data
+ Offset
, (UINT8
*)(CertList
), CertList
->SignatureListSize
);
2961 Offset
+= CertList
->SignatureListSize
;
2964 ItemDataSize
-= CertList
->SignatureListSize
;
2965 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2970 // Doesn't find the signature Item!
2972 Status
= EFI_NOT_FOUND
;
2977 // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
2979 ItemDataSize
= Offset
;
2980 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
2982 ZeroMem (OldData
, ItemDataSize
);
2983 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
2984 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2985 DEBUG ((DEBUG_INFO
, " CertCount = %x\n", CertCount
));
2986 if (CertCount
!= 0) {
2987 CopyMem (OldData
+ Offset
, (UINT8
*)(CertList
), CertList
->SignatureListSize
);
2988 Offset
+= CertList
->SignatureListSize
;
2990 ItemDataSize
-= CertList
->SignatureListSize
;
2991 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2995 if ((Attr
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
2996 Status
= CreateTimeBasedPayload (&DataSize
, &OldData
);
2997 if (EFI_ERROR (Status
)) {
2998 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
3003 Status
= gRT
->SetVariable(
3010 if (EFI_ERROR (Status
)) {
3011 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r\n", Status
));
3020 if (OldData
!= NULL
) {
3024 return UpdateDeletePage (
3035 This function to delete signature list or data, according by DelType.
3037 @param[in] PrivateData Module's private data.
3038 @param[in] DelType Indicate delete signature list or data.
3039 @param[in] CheckedCount Indicate how many signature data have
3040 been checked in current signature list.
3042 @retval EFI_SUCCESS Success to update the signature list page
3043 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
3047 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
3048 IN SIGNATURE_DELETE_TYPE DelType
,
3049 IN UINT32 CheckedCount
3053 EFI_SIGNATURE_LIST
*ListWalker
;
3054 EFI_SIGNATURE_LIST
*NewCertList
;
3055 EFI_SIGNATURE_DATA
*DataWalker
;
3056 CHAR16 VariableName
[BUFFER_MAX_SIZE
];
3057 UINT32 VariableAttr
;
3058 UINTN VariableDataSize
;
3059 UINTN RemainingSize
;
3063 UINT8
*VariableData
;
3064 UINT8
*NewVariableData
;
3066 Status
= EFI_SUCCESS
;
3068 VariableDataSize
= 0;
3071 VariableData
= NULL
;
3072 NewVariableData
= NULL
;
3074 if (PrivateData
->VariableName
== Variable_DB
) {
3075 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE
);
3076 } else if (PrivateData
->VariableName
== Variable_DBX
) {
3077 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE1
);
3078 } else if (PrivateData
->VariableName
== Variable_DBT
) {
3079 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE2
);
3084 Status
= gRT
->GetVariable (
3086 &gEfiImageSecurityDatabaseGuid
,
3091 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
3095 VariableData
= AllocateZeroPool (VariableDataSize
);
3096 if (VariableData
== NULL
) {
3097 Status
= EFI_OUT_OF_RESOURCES
;
3101 Status
= gRT
->GetVariable (
3103 &gEfiImageSecurityDatabaseGuid
,
3108 if (EFI_ERROR (Status
)) {
3112 Status
= SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE
);
3113 if (EFI_ERROR (Status
)) {
3117 NewVariableData
= AllocateZeroPool (VariableDataSize
);
3118 if (NewVariableData
== NULL
) {
3119 Status
= EFI_OUT_OF_RESOURCES
;
3123 RemainingSize
= VariableDataSize
;
3124 ListWalker
= (EFI_SIGNATURE_LIST
*)(VariableData
);
3125 if (DelType
== Delete_Signature_List_All
) {
3126 VariableDataSize
= 0;
3129 // Traverse to target EFI_SIGNATURE_LIST but others will be skipped.
3131 while ((RemainingSize
> 0) && (RemainingSize
>= ListWalker
->SignatureListSize
) && ListIndex
< PrivateData
->ListIndex
) {
3132 CopyMem ((UINT8
*)NewVariableData
+ Offset
, ListWalker
, ListWalker
->SignatureListSize
);
3133 Offset
+= ListWalker
->SignatureListSize
;
3135 RemainingSize
-= ListWalker
->SignatureListSize
;
3136 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
3141 // Handle the target EFI_SIGNATURE_LIST.
3142 // If CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) or DelType == Delete_Signature_List_One
3143 // it means delete the whole EFI_SIGNATURE_LIST, So we just skip this EFI_SIGNATURE_LIST.
3145 if (CheckedCount
< SIGNATURE_DATA_COUNTS (ListWalker
) && DelType
== Delete_Signature_Data
) {
3146 NewCertList
= (EFI_SIGNATURE_LIST
*)(NewVariableData
+ Offset
);
3150 CopyMem ((UINT8
*)NewVariableData
+ Offset
, ListWalker
, sizeof (EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
);
3151 Offset
+= sizeof (EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
;
3153 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)ListWalker
+ sizeof(EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
);
3154 for (Index
= 0; Index
< SIGNATURE_DATA_COUNTS(ListWalker
); Index
= Index
+ 1) {
3155 if (PrivateData
->CheckArray
[Index
]) {
3157 // Delete checked signature data, and update the size of whole signature list.
3159 NewCertList
->SignatureListSize
-= NewCertList
->SignatureSize
;
3162 // Remain the unchecked signature data.
3164 CopyMem ((UINT8
*)NewVariableData
+ Offset
, DataWalker
, ListWalker
->SignatureSize
);
3165 Offset
+= ListWalker
->SignatureSize
;
3167 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)DataWalker
+ ListWalker
->SignatureSize
);
3171 RemainingSize
-= ListWalker
->SignatureListSize
;
3172 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
3175 // Copy remaining data, maybe 0.
3177 CopyMem((UINT8
*)NewVariableData
+ Offset
, ListWalker
, RemainingSize
);
3178 Offset
+= RemainingSize
;
3180 VariableDataSize
= Offset
;
3183 if ((VariableAttr
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
3184 Status
= CreateTimeBasedPayload (&VariableDataSize
, &NewVariableData
);
3185 if (EFI_ERROR (Status
)) {
3186 DEBUG ((DEBUG_ERROR
, "Fail to create time-based data payload: %r", Status
));
3191 Status
= gRT
->SetVariable (
3193 &gEfiImageSecurityDatabaseGuid
,
3198 if (EFI_ERROR (Status
)) {
3199 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r", Status
));
3204 SECUREBOOT_FREE_NON_NULL (VariableData
);
3205 SECUREBOOT_FREE_NON_NULL (NewVariableData
);
3212 Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT
3213 and STR_CUR_SECURE_BOOT_MODE_CONTENT.
3215 @param[in] PrivateData Module's private data.
3217 @return EFI_SUCCESS Update secure boot strings successfully.
3218 @return other Fail to update secure boot strings.
3222 UpdateSecureBootString(
3223 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
3231 // Get current secure boot state.
3233 GetVariable2 (EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&SecureBoot
, NULL
);
3234 if (SecureBoot
== NULL
) {
3235 return EFI_NOT_FOUND
;
3238 if (*SecureBoot
== SECURE_BOOT_MODE_ENABLE
) {
3239 HiiSetString (Private
->HiiHandle
, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT
), L
"Enabled", NULL
);
3241 HiiSetString (Private
->HiiHandle
, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT
), L
"Disabled", NULL
);
3244 FreePool(SecureBoot
);
3250 This function extracts configuration from variable.
3252 @param[in] Private Point to SecureBoot configuration driver private data.
3253 @param[in, out] ConfigData Point to SecureBoot configuration private data.
3257 SecureBootExtractConfigFromVariable (
3258 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
3259 IN OUT SECUREBOOT_CONFIGURATION
*ConfigData
3262 UINT8
*SecureBootEnable
;
3264 UINT8
*SecureBootMode
;
3267 SecureBootEnable
= NULL
;
3269 SecureBootMode
= NULL
;
3272 // Initialize the Date and Time using system time.
3274 ConfigData
->CertificateFormat
= HASHALG_RAW
;
3275 ConfigData
->AlwaysRevocation
= TRUE
;
3276 gRT
->GetTime (&CurrTime
, NULL
);
3277 ConfigData
->RevocationDate
.Year
= CurrTime
.Year
;
3278 ConfigData
->RevocationDate
.Month
= CurrTime
.Month
;
3279 ConfigData
->RevocationDate
.Day
= CurrTime
.Day
;
3280 ConfigData
->RevocationTime
.Hour
= CurrTime
.Hour
;
3281 ConfigData
->RevocationTime
.Minute
= CurrTime
.Minute
;
3282 ConfigData
->RevocationTime
.Second
= 0;
3283 if (Private
->FileContext
->FHandle
!= NULL
) {
3284 ConfigData
->FileEnrollType
= Private
->FileContext
->FileType
;
3286 ConfigData
->FileEnrollType
= UNKNOWN_FILE_TYPE
;
3290 // If it is Physical Presence User, set the PhysicalPresent to true.
3292 if (UserPhysicalPresent()) {
3293 ConfigData
->PhysicalPresent
= TRUE
;
3295 ConfigData
->PhysicalPresent
= FALSE
;
3299 // If there is no PK then the Delete Pk button will be gray.
3301 GetVariable2 (EFI_SETUP_MODE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&SetupMode
, NULL
);
3302 if (SetupMode
== NULL
|| (*SetupMode
) == SETUP_MODE
) {
3303 ConfigData
->HasPk
= FALSE
;
3305 ConfigData
->HasPk
= TRUE
;
3309 // Check SecureBootEnable & Pk status, fix the inconsistency.
3310 // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable
3313 ConfigData
->AttemptSecureBoot
= FALSE
;
3314 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME
, &gEfiSecureBootEnableDisableGuid
, (VOID
**)&SecureBootEnable
, NULL
);
3317 // Fix Pk and SecureBootEnable inconsistency
3319 if ((SetupMode
!= NULL
) && (*SetupMode
) == USER_MODE
) {
3320 ConfigData
->HideSecureBoot
= FALSE
;
3321 if ((SecureBootEnable
!= NULL
) && (*SecureBootEnable
== SECURE_BOOT_ENABLE
)) {
3322 ConfigData
->AttemptSecureBoot
= TRUE
;
3325 ConfigData
->HideSecureBoot
= TRUE
;
3329 // Get the SecureBootMode from CustomMode variable.
3331 GetVariable2 (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
, (VOID
**)&SecureBootMode
, NULL
);
3332 if (SecureBootMode
== NULL
) {
3333 ConfigData
->SecureBootMode
= STANDARD_SECURE_BOOT_MODE
;
3335 ConfigData
->SecureBootMode
= *(SecureBootMode
);
3338 if (SecureBootEnable
!= NULL
) {
3339 FreePool (SecureBootEnable
);
3341 if (SetupMode
!= NULL
) {
3342 FreePool (SetupMode
);
3344 if (SecureBootMode
!= NULL
) {
3345 FreePool (SecureBootMode
);
3350 This function allows a caller to extract the current configuration for one
3351 or more named elements from the target driver.
3353 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3354 @param[in] Request A null-terminated Unicode string in
3355 <ConfigRequest> format.
3356 @param[out] Progress On return, points to a character in the Request
3357 string. Points to the string's null terminator if
3358 request was successful. Points to the most recent
3359 '&' before the first failing name/value pair (or
3360 the beginning of the string if the failure is in
3361 the first name/value pair) if the request was not
3363 @param[out] Results A null-terminated Unicode string in
3364 <ConfigAltResp> format which has all values filled
3365 in for the names in the Request string. String to
3366 be allocated by the called function.
3368 @retval EFI_SUCCESS The Results is filled with the requested values.
3369 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
3370 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
3371 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
3377 SecureBootExtractConfig (
3378 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3379 IN CONST EFI_STRING Request
,
3380 OUT EFI_STRING
*Progress
,
3381 OUT EFI_STRING
*Results
3387 SECUREBOOT_CONFIGURATION Configuration
;
3388 EFI_STRING ConfigRequest
;
3389 EFI_STRING ConfigRequestHdr
;
3390 SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
;
3391 BOOLEAN AllocatedRequest
;
3393 if (Progress
== NULL
|| Results
== NULL
) {
3394 return EFI_INVALID_PARAMETER
;
3397 AllocatedRequest
= FALSE
;
3398 ConfigRequestHdr
= NULL
;
3399 ConfigRequest
= NULL
;
3402 ZeroMem (&Configuration
, sizeof (Configuration
));
3403 PrivateData
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
3404 *Progress
= Request
;
3406 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gSecureBootConfigFormSetGuid
, mSecureBootStorageName
)) {
3407 return EFI_NOT_FOUND
;
3410 ZeroMem(&Configuration
, sizeof(SECUREBOOT_CONFIGURATION
));
3413 // Get Configuration from Variable.
3415 SecureBootExtractConfigFromVariable (PrivateData
, &Configuration
);
3417 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
3418 ConfigRequest
= Request
;
3419 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
3421 // Request is set to NULL or OFFSET is NULL, construct full request string.
3423 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
3424 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
3426 ConfigRequestHdr
= HiiConstructConfigHdr (&gSecureBootConfigFormSetGuid
, mSecureBootStorageName
, PrivateData
->DriverHandle
);
3427 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
3428 ConfigRequest
= AllocateZeroPool (Size
);
3429 ASSERT (ConfigRequest
!= NULL
);
3430 AllocatedRequest
= TRUE
;
3431 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
3432 FreePool (ConfigRequestHdr
);
3433 ConfigRequestHdr
= NULL
;
3436 Status
= gHiiConfigRouting
->BlockToConfig (
3439 (UINT8
*) &Configuration
,
3446 // Free the allocated config request string.
3448 if (AllocatedRequest
) {
3449 FreePool (ConfigRequest
);
3453 // Set Progress string to the original request string.
3455 if (Request
== NULL
) {
3457 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
3458 *Progress
= Request
+ StrLen (Request
);
3465 This function processes the results of changes in configuration.
3467 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3468 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
3470 @param[out] Progress A pointer to a string filled in with the offset of
3471 the most recent '&' before the first failing
3472 name/value pair (or the beginning of the string if
3473 the failure is in the first name/value pair) or
3474 the terminating NULL if all was successful.
3476 @retval EFI_SUCCESS The Results is processed successfully.
3477 @retval EFI_INVALID_PARAMETER Configuration is NULL.
3478 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
3484 SecureBootRouteConfig (
3485 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3486 IN CONST EFI_STRING Configuration
,
3487 OUT EFI_STRING
*Progress
3490 SECUREBOOT_CONFIGURATION IfrNvData
;
3492 SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
;
3495 if (Configuration
== NULL
|| Progress
== NULL
) {
3496 return EFI_INVALID_PARAMETER
;
3499 *Progress
= Configuration
;
3500 if (!HiiIsConfigHdrMatch (Configuration
, &gSecureBootConfigFormSetGuid
, mSecureBootStorageName
)) {
3501 return EFI_NOT_FOUND
;
3504 PrivateData
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
3507 // Get Configuration from Variable.
3509 SecureBootExtractConfigFromVariable (PrivateData
, &IfrNvData
);
3512 // Map the Configuration to the configuration block.
3514 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
3515 Status
= gHiiConfigRouting
->ConfigToBlock (
3518 (UINT8
*)&IfrNvData
,
3522 if (EFI_ERROR (Status
)) {
3527 // Store Buffer Storage back to EFI variable if needed
3529 if (!IfrNvData
.HideSecureBoot
) {
3530 Status
= SaveSecureBootVariable (IfrNvData
.AttemptSecureBoot
);
3531 if (EFI_ERROR (Status
)) {
3536 *Progress
= Configuration
+ StrLen (Configuration
);
3541 This function to load signature list, the update the menu page.
3543 @param[in] PrivateData Module's private data.
3544 @param[in] LabelId Label number to insert opcodes.
3545 @param[in] FormId Form ID of current page.
3546 @param[in] QuestionIdBase Base question id of the signature list.
3548 @retval EFI_SUCCESS Success to update the signature list page
3549 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
3553 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
3555 IN EFI_FORM_ID FormId
,
3556 IN EFI_QUESTION_ID QuestionIdBase
3560 EFI_STRING_ID ListType
;
3561 EFI_STRING FormatNameString
;
3562 EFI_STRING FormatHelpString
;
3563 EFI_STRING FormatTypeString
;
3564 EFI_SIGNATURE_LIST
*ListWalker
;
3565 EFI_IFR_GUID_LABEL
*StartLabel
;
3566 EFI_IFR_GUID_LABEL
*EndLabel
;
3567 EFI_IFR_GUID_LABEL
*StartGoto
;
3568 EFI_IFR_GUID_LABEL
*EndGoto
;
3569 EFI_FORM_ID DstFormId
;
3570 VOID
*StartOpCodeHandle
;
3571 VOID
*EndOpCodeHandle
;
3572 VOID
*StartGotoHandle
;
3573 VOID
*EndGotoHandle
;
3575 UINTN RemainingSize
;
3577 UINT8
*VariableData
;
3578 CHAR16 VariableName
[BUFFER_MAX_SIZE
];
3579 CHAR16 NameBuffer
[BUFFER_MAX_SIZE
];
3580 CHAR16 HelpBuffer
[BUFFER_MAX_SIZE
];
3582 Status
= EFI_SUCCESS
;
3583 FormatNameString
= NULL
;
3584 FormatHelpString
= NULL
;
3585 StartOpCodeHandle
= NULL
;
3586 EndOpCodeHandle
= NULL
;
3587 StartGotoHandle
= NULL
;
3588 EndGotoHandle
= NULL
;
3590 VariableData
= NULL
;
3593 // Initialize the container for dynamic opcodes.
3595 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
3596 if (StartOpCodeHandle
== NULL
) {
3597 Status
= EFI_OUT_OF_RESOURCES
;
3601 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
3602 if (EndOpCodeHandle
== NULL
) {
3603 Status
= EFI_OUT_OF_RESOURCES
;
3607 StartGotoHandle
= HiiAllocateOpCodeHandle ();
3608 if (StartGotoHandle
== NULL
) {
3609 Status
= EFI_OUT_OF_RESOURCES
;
3613 EndGotoHandle
= HiiAllocateOpCodeHandle ();
3614 if (EndGotoHandle
== NULL
) {
3615 Status
= EFI_OUT_OF_RESOURCES
;
3620 // Create Hii Extend Label OpCode.
3622 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
3626 sizeof (EFI_IFR_GUID_LABEL
)
3628 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3629 StartLabel
->Number
= LabelId
;
3631 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
3635 sizeof (EFI_IFR_GUID_LABEL
)
3637 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3638 EndLabel
->Number
= LABEL_END
;
3640 StartGoto
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode(
3644 sizeof(EFI_IFR_GUID_LABEL
)
3646 StartGoto
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3647 StartGoto
->Number
= LABEL_DELETE_ALL_LIST_BUTTON
;
3649 EndGoto
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode(
3653 sizeof(EFI_IFR_GUID_LABEL
)
3655 EndGoto
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3656 EndGoto
->Number
= LABEL_END
;
3658 if (PrivateData
->VariableName
== Variable_DB
) {
3659 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE
);
3660 DstFormId
= FORMID_SECURE_BOOT_DB_OPTION_FORM
;
3661 } else if (PrivateData
->VariableName
== Variable_DBX
) {
3662 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE1
);
3663 DstFormId
= FORMID_SECURE_BOOT_DBX_OPTION_FORM
;
3664 } else if (PrivateData
->VariableName
== Variable_DBT
) {
3665 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE2
);
3666 DstFormId
= FORMID_SECURE_BOOT_DBT_OPTION_FORM
;
3671 HiiCreateGotoOpCode (
3674 STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST
),
3675 STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST
),
3676 EFI_IFR_FLAG_CALLBACK
,
3677 KEY_SECURE_BOOT_DELETE_ALL_LIST
3681 // Read Variable, the variable name save in the PrivateData->VariableName.
3684 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
3685 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
3689 VariableData
= AllocateZeroPool (DataSize
);
3690 if (VariableData
== NULL
) {
3691 Status
= EFI_OUT_OF_RESOURCES
;
3694 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
3695 if (EFI_ERROR (Status
)) {
3699 FormatNameString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_LIST_NAME_FORMAT
), NULL
);
3700 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT
), NULL
);
3701 if (FormatNameString
== NULL
|| FormatHelpString
== NULL
) {
3705 RemainingSize
= DataSize
;
3706 ListWalker
= (EFI_SIGNATURE_LIST
*)VariableData
;
3707 while ((RemainingSize
> 0) && (RemainingSize
>= ListWalker
->SignatureListSize
)) {
3708 if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertRsa2048Guid
)) {
3709 ListType
= STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256
);
3710 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Guid
)) {
3711 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509
);
3712 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertSha1Guid
)) {
3713 ListType
= STRING_TOKEN (STR_LIST_TYPE_SHA1
);
3714 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertSha256Guid
)) {
3715 ListType
= STRING_TOKEN (STR_LIST_TYPE_SHA256
);
3716 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
3717 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509_SHA256
);
3718 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
3719 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509_SHA384
);
3720 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
3721 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509_SHA512
);
3723 ListType
= STRING_TOKEN (STR_LIST_TYPE_UNKNOWN
);
3725 FormatTypeString
= HiiGetString (PrivateData
->HiiHandle
, ListType
, NULL
);
3726 if (FormatTypeString
== NULL
) {
3730 ZeroMem (NameBuffer
, sizeof (NameBuffer
));
3731 UnicodeSPrint (NameBuffer
, sizeof (NameBuffer
), FormatNameString
, Index
+ 1);
3733 ZeroMem (HelpBuffer
, sizeof (HelpBuffer
));
3734 UnicodeSPrint (HelpBuffer
,
3735 sizeof (HelpBuffer
),
3738 SIGNATURE_DATA_COUNTS (ListWalker
)
3740 SECUREBOOT_FREE_NON_NULL (FormatTypeString
);
3741 FormatTypeString
= NULL
;
3743 HiiCreateGotoOpCode (
3745 SECUREBOOT_DELETE_SIGNATURE_DATA_FORM
,
3746 HiiSetString (PrivateData
->HiiHandle
, 0, NameBuffer
, NULL
),
3747 HiiSetString (PrivateData
->HiiHandle
, 0, HelpBuffer
, NULL
),
3748 EFI_IFR_FLAG_CALLBACK
,
3749 QuestionIdBase
+ Index
++
3752 RemainingSize
-= ListWalker
->SignatureListSize
;
3753 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
3758 PrivateData
->HiiHandle
,
3759 &gSecureBootConfigFormSetGuid
,
3766 PrivateData
->HiiHandle
,
3767 &gSecureBootConfigFormSetGuid
,
3773 SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle
);
3774 SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle
);
3775 SECUREBOOT_FREE_NON_OPCODE (StartGotoHandle
);
3776 SECUREBOOT_FREE_NON_OPCODE (EndGotoHandle
);
3778 SECUREBOOT_FREE_NON_NULL (VariableData
);
3779 SECUREBOOT_FREE_NON_NULL (FormatNameString
);
3780 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
3782 PrivateData
->ListCount
= Index
;
3788 Parse hash value from EFI_SIGNATURE_DATA, and save in the CHAR16 type array.
3789 The buffer is callee allocated and should be freed by the caller.
3791 @param[in] ListEntry The pointer point to the signature list.
3792 @param[in] DataEntry The signature data we are processing.
3793 @param[out] BufferToReturn Buffer to save the hash value.
3795 @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
3796 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
3797 @retval EFI_SUCCESS Operation success.
3801 IN EFI_SIGNATURE_LIST
*ListEntry
,
3802 IN EFI_SIGNATURE_DATA
*DataEntry
,
3803 OUT CHAR16
**BufferToReturn
3814 // Assume that, display 8 bytes in one line.
3818 if (ListEntry
== NULL
|| DataEntry
== NULL
|| BufferToReturn
== NULL
) {
3819 return EFI_INVALID_PARAMETER
;
3822 DataSize
= ListEntry
->SignatureSize
- sizeof(EFI_GUID
);
3823 Line
= (DataSize
+ OneLineBytes
- 1) / OneLineBytes
;
3826 // Each byte will split two Hex-number, and each line need additional memory to save '\r\n'.
3828 TotalSize
= ((DataSize
+ Line
) * 2 * sizeof(CHAR16
));
3830 *BufferToReturn
= AllocateZeroPool(TotalSize
);
3831 if (*BufferToReturn
== NULL
) {
3832 return EFI_OUT_OF_RESOURCES
;
3835 for (Index
= 0, BufferIndex
= 0; Index
< DataSize
; Index
= Index
+ 1) {
3836 if ((Index
> 0) && (Index
% OneLineBytes
== 0)) {
3837 BufferIndex
+= UnicodeSPrint(&(*BufferToReturn
)[BufferIndex
], TotalSize
- sizeof(CHAR16
) * BufferIndex
, L
"\n");
3839 BufferIndex
+= UnicodeSPrint(&(*BufferToReturn
)[BufferIndex
], TotalSize
- sizeof(CHAR16
) * BufferIndex
, L
"%02x", DataEntry
->SignatureData
[Index
]);
3841 BufferIndex
+= UnicodeSPrint(&(*BufferToReturn
)[BufferIndex
], TotalSize
- sizeof(CHAR16
) * BufferIndex
, L
"\n");
3847 Function to get the common name from the X509 format certificate.
3848 The buffer is callee allocated and should be freed by the caller.
3850 @param[in] ListEntry The pointer point to the signature list.
3851 @param[in] DataEntry The signature data we are processing.
3852 @param[out] BufferToReturn Buffer to save the CN of X509 certificate.
3854 @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
3855 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
3856 @retval EFI_SUCCESS Operation success.
3857 @retval EFI_NOT_FOUND Not found CN field in the X509 certificate.
3860 GetCommonNameFromX509 (
3861 IN EFI_SIGNATURE_LIST
*ListEntry
,
3862 IN EFI_SIGNATURE_DATA
*DataEntry
,
3863 OUT CHAR16
**BufferToReturn
3870 Status
= EFI_SUCCESS
;
3873 CNBuffer
= AllocateZeroPool(256);
3874 if (CNBuffer
== NULL
) {
3875 Status
= EFI_OUT_OF_RESOURCES
;
3881 (UINT8
*)DataEntry
+ sizeof(EFI_GUID
),
3882 ListEntry
->SignatureSize
- sizeof(EFI_GUID
),
3887 *BufferToReturn
= AllocateZeroPool(256 * sizeof(CHAR16
));
3888 if (*BufferToReturn
== NULL
) {
3889 Status
= EFI_OUT_OF_RESOURCES
;
3893 AsciiStrToUnicodeStrS (CNBuffer
, *BufferToReturn
, 256);
3896 SECUREBOOT_FREE_NON_NULL (CNBuffer
);
3902 Format the help info for the signature data, each help info contain 3 parts.
3904 2. Content, depends on the type of the signature list.
3907 @param[in] PrivateData Module's private data.
3908 @param[in] ListEntry Point to the signature list.
3909 @param[in] DataEntry Point to the signature data we are processing.
3910 @param[out] StringId Save the string id of help info.
3912 @retval EFI_SUCCESS Operation success.
3913 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
3917 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
3918 IN EFI_SIGNATURE_LIST
*ListEntry
,
3919 IN EFI_SIGNATURE_DATA
*DataEntry
,
3920 OUT EFI_STRING_ID
*StringId
3925 EFI_STRING_ID ListTypeId
;
3926 EFI_STRING FormatHelpString
;
3927 EFI_STRING FormatTypeString
;
3929 UINTN HelpInfoIndex
;
3931 CHAR16 GuidString
[BUFFER_MAX_SIZE
];
3932 CHAR16 TimeString
[BUFFER_MAX_SIZE
];
3934 CHAR16
*HelpInfoString
;
3937 Status
= EFI_SUCCESS
;
3939 FormatTypeString
= NULL
;
3942 HelpInfoString
= NULL
;
3945 if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertRsa2048Guid
)) {
3946 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_RSA2048_SHA256
);
3947 DataSize
= ListEntry
->SignatureSize
- sizeof(EFI_GUID
);
3949 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Guid
)) {
3950 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509
);
3951 DataSize
= ListEntry
->SignatureSize
- sizeof(EFI_GUID
);
3953 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertSha1Guid
)) {
3954 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_SHA1
);
3956 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertSha256Guid
)) {
3957 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_SHA256
);
3959 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
3960 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509_SHA256
);
3962 Time
= (EFI_TIME
*)(DataEntry
->SignatureData
+ DataSize
);
3963 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
3964 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509_SHA384
);
3966 Time
= (EFI_TIME
*)(DataEntry
->SignatureData
+ DataSize
);
3967 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
3968 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509_SHA512
);
3970 Time
= (EFI_TIME
*)(DataEntry
->SignatureData
+ DataSize
);
3972 Status
= EFI_UNSUPPORTED
;
3976 FormatTypeString
= HiiGetString (PrivateData
->HiiHandle
, ListTypeId
, NULL
);
3977 if (FormatTypeString
== NULL
) {
3982 HelpInfoString
= AllocateZeroPool (TotalSize
);
3983 if (HelpInfoString
== NULL
) {
3984 Status
= EFI_OUT_OF_RESOURCES
;
3989 // Format GUID part.
3991 ZeroMem (GuidString
, sizeof (GuidString
));
3992 GuidToString(&DataEntry
->SignatureOwner
, GuidString
, BUFFER_MAX_SIZE
);
3993 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID
), NULL
);
3994 if (FormatHelpString
== NULL
) {
3997 HelpInfoIndex
+= UnicodeSPrint (
3998 &HelpInfoString
[HelpInfoIndex
],
3999 TotalSize
- sizeof(CHAR16
) * HelpInfoIndex
,
4003 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
4004 FormatHelpString
= NULL
;
4007 // Format content part, it depends on the type of signature list, hash value or CN.
4010 GetCommonNameFromX509 (ListEntry
, DataEntry
, &DataString
);
4011 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_CN
), NULL
);
4014 // Format hash value for each signature data entry.
4016 ParseHashValue (ListEntry
, DataEntry
, &DataString
);
4017 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH
), NULL
);
4019 if (FormatHelpString
== NULL
) {
4022 HelpInfoIndex
+= UnicodeSPrint (
4023 &HelpInfoString
[HelpInfoIndex
],
4024 TotalSize
- sizeof (CHAR16
) * HelpInfoIndex
,
4030 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
4031 FormatHelpString
= NULL
;
4034 // Format revocation time part.
4037 ZeroMem (TimeString
, sizeof (TimeString
));
4040 sizeof (TimeString
),
4041 L
"%d-%d-%d %d:%d:%d",
4049 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME
), NULL
);
4050 if (FormatHelpString
== NULL
) {
4054 &HelpInfoString
[HelpInfoIndex
],
4055 TotalSize
- sizeof (CHAR16
) * HelpInfoIndex
,
4059 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
4060 FormatHelpString
= NULL
;
4063 *StringId
= HiiSetString (PrivateData
->HiiHandle
, 0, HelpInfoString
, NULL
);
4065 SECUREBOOT_FREE_NON_NULL (DataString
);
4066 SECUREBOOT_FREE_NON_NULL (HelpInfoString
);
4068 SECUREBOOT_FREE_NON_NULL (FormatTypeString
);
4074 This function to load signature data under the signature list.
4076 @param[in] PrivateData Module's private data.
4077 @param[in] LabelId Label number to insert opcodes.
4078 @param[in] FormId Form ID of current page.
4079 @param[in] QuestionIdBase Base question id of the signature list.
4080 @param[in] ListIndex Indicate to load which signature list.
4082 @retval EFI_SUCCESS Success to update the signature list page
4083 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
4087 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
4089 IN EFI_FORM_ID FormId
,
4090 IN EFI_QUESTION_ID QuestionIdBase
,
4095 EFI_SIGNATURE_LIST
*ListWalker
;
4096 EFI_SIGNATURE_DATA
*DataWalker
;
4097 EFI_IFR_GUID_LABEL
*StartLabel
;
4098 EFI_IFR_GUID_LABEL
*EndLabel
;
4099 EFI_STRING_ID HelpStringId
;
4100 EFI_STRING FormatNameString
;
4101 VOID
*StartOpCodeHandle
;
4102 VOID
*EndOpCodeHandle
;
4104 UINTN RemainingSize
;
4106 UINT8
*VariableData
;
4107 CHAR16 VariableName
[BUFFER_MAX_SIZE
];
4108 CHAR16 NameBuffer
[BUFFER_MAX_SIZE
];
4110 Status
= EFI_SUCCESS
;
4111 FormatNameString
= NULL
;
4112 StartOpCodeHandle
= NULL
;
4113 EndOpCodeHandle
= NULL
;
4115 VariableData
= NULL
;
4118 // Initialize the container for dynamic opcodes.
4120 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
4121 if (StartOpCodeHandle
== NULL
) {
4122 Status
= EFI_OUT_OF_RESOURCES
;
4126 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
4127 if (EndOpCodeHandle
== NULL
) {
4128 Status
= EFI_OUT_OF_RESOURCES
;
4133 // Create Hii Extend Label OpCode.
4135 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
4139 sizeof (EFI_IFR_GUID_LABEL
)
4141 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4142 StartLabel
->Number
= LabelId
;
4144 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
4148 sizeof (EFI_IFR_GUID_LABEL
)
4150 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4151 EndLabel
->Number
= LABEL_END
;
4153 if (PrivateData
->VariableName
== Variable_DB
) {
4154 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE
);
4155 } else if (PrivateData
->VariableName
== Variable_DBX
) {
4156 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE1
);
4157 } else if (PrivateData
->VariableName
== Variable_DBT
) {
4158 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE2
);
4164 // Read Variable, the variable name save in the PrivateData->VariableName.
4167 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
4168 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
4172 VariableData
= AllocateZeroPool (DataSize
);
4173 if (VariableData
== NULL
) {
4174 Status
= EFI_OUT_OF_RESOURCES
;
4177 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
4178 if (EFI_ERROR (Status
)) {
4182 RemainingSize
= DataSize
;
4183 ListWalker
= (EFI_SIGNATURE_LIST
*)VariableData
;
4186 // Skip signature list.
4188 while ((RemainingSize
> 0) && (RemainingSize
>= ListWalker
->SignatureListSize
) && ListIndex
-- > 0) {
4189 RemainingSize
-= ListWalker
->SignatureListSize
;
4190 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
4193 FormatNameString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_NAME_FORMAT
), NULL
);
4194 if (FormatNameString
== NULL
) {
4198 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)ListWalker
+ sizeof(EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
);
4199 for (Index
= 0; Index
< SIGNATURE_DATA_COUNTS(ListWalker
); Index
= Index
+ 1) {
4201 // Format name buffer.
4203 ZeroMem (NameBuffer
, sizeof (NameBuffer
));
4204 UnicodeSPrint (NameBuffer
, sizeof (NameBuffer
), FormatNameString
, Index
+ 1);
4207 // Format help info buffer.
4209 Status
= FormatHelpInfo (PrivateData
, ListWalker
, DataWalker
, &HelpStringId
);
4210 if (EFI_ERROR (Status
)) {
4214 HiiCreateCheckBoxOpCode (
4216 (EFI_QUESTION_ID
)(QuestionIdBase
+ Index
),
4219 HiiSetString (PrivateData
->HiiHandle
, 0, NameBuffer
, NULL
),
4221 EFI_IFR_FLAG_CALLBACK
,
4226 ZeroMem(NameBuffer
, 100);
4227 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)DataWalker
+ ListWalker
->SignatureSize
);
4231 // Allocate a buffer to record which signature data will be checked.
4232 // This memory buffer will be freed when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
4234 PrivateData
->CheckArray
= AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker
) * sizeof (BOOLEAN
));
4237 PrivateData
->HiiHandle
,
4238 &gSecureBootConfigFormSetGuid
,
4244 SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle
);
4245 SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle
);
4247 SECUREBOOT_FREE_NON_NULL (VariableData
);
4248 SECUREBOOT_FREE_NON_NULL (FormatNameString
);
4254 This function is called to provide results data to the driver.
4256 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
4257 @param[in] Action Specifies the type of action taken by the browser.
4258 @param[in] QuestionId A unique value which is sent to the original
4259 exporting driver so that it can identify the type
4261 @param[in] Type The type of value for the question.
4262 @param[in] Value A pointer to the data being sent to the original
4264 @param[out] ActionRequest On return, points to the action requested by the
4267 @retval EFI_SUCCESS The callback successfully handled the action.
4268 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
4269 variable and its data.
4270 @retval EFI_DEVICE_ERROR The variable could not be saved.
4271 @retval EFI_UNSUPPORTED The specified Action is not supported by the
4277 SecureBootCallback (
4278 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
4279 IN EFI_BROWSER_ACTION Action
,
4280 IN EFI_QUESTION_ID QuestionId
,
4282 IN EFI_IFR_TYPE_VALUE
*Value
,
4283 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
4288 RETURN_STATUS RStatus
;
4289 SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
;
4291 SECUREBOOT_CONFIGURATION
*IfrNvData
;
4293 UINT8
*SecureBootEnable
;
4295 UINT8
*SecureBootMode
;
4297 CHAR16 PromptString
[100];
4298 EFI_DEVICE_PATH_PROTOCOL
*File
;
4300 UINT16
*FilePostFix
;
4301 SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
;
4302 BOOLEAN GetBrowserDataResult
;
4304 Status
= EFI_SUCCESS
;
4305 SecureBootEnable
= NULL
;
4306 SecureBootMode
= NULL
;
4310 if ((This
== NULL
) || (Value
== NULL
) || (ActionRequest
== NULL
)) {
4311 return EFI_INVALID_PARAMETER
;
4314 Private
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
4316 gSecureBootPrivateData
= Private
;
4319 // Retrieve uncommitted data from Browser
4321 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
4322 IfrNvData
= AllocateZeroPool (BufferSize
);
4323 if (IfrNvData
== NULL
) {
4324 return EFI_OUT_OF_RESOURCES
;
4327 GetBrowserDataResult
= HiiGetBrowserData (&gSecureBootConfigFormSetGuid
, mSecureBootStorageName
, BufferSize
, (UINT8
*) IfrNvData
);
4329 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
4330 if (QuestionId
== KEY_SECURE_BOOT_MODE
) {
4332 // Update secure boot strings when opening this form
4334 Status
= UpdateSecureBootString(Private
);
4335 SecureBootExtractConfigFromVariable (Private
, IfrNvData
);
4336 mIsEnterSecureBootForm
= TRUE
;
4339 // When entering SecureBoot OPTION Form
4340 // always close opened file & free resource
4342 if ((QuestionId
== KEY_SECURE_BOOT_PK_OPTION
) ||
4343 (QuestionId
== KEY_SECURE_BOOT_KEK_OPTION
) ||
4344 (QuestionId
== KEY_SECURE_BOOT_DB_OPTION
) ||
4345 (QuestionId
== KEY_SECURE_BOOT_DBX_OPTION
) ||
4346 (QuestionId
== KEY_SECURE_BOOT_DBT_OPTION
)) {
4347 CloseEnrolledFile(Private
->FileContext
);
4348 } else if (QuestionId
== KEY_SECURE_BOOT_DELETE_ALL_LIST
) {
4350 // Update ListCount field in varstore
4351 // Button "Delete All Signature List" is
4352 // enable when ListCount is greater than 0.
4354 IfrNvData
->ListCount
= Private
->ListCount
;
4360 if (Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
4361 Status
= EFI_UNSUPPORTED
;
4362 if (QuestionId
== KEY_SECURE_BOOT_MODE
) {
4363 if (mIsEnterSecureBootForm
) {
4364 Value
->u8
= SECURE_BOOT_MODE_STANDARD
;
4365 Status
= EFI_SUCCESS
;
4371 if ((Action
!= EFI_BROWSER_ACTION_CHANGED
) &&
4372 (Action
!= EFI_BROWSER_ACTION_CHANGING
) &&
4373 (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
) &&
4374 (Action
!= EFI_BROWSER_ACTION_DEFAULT_STANDARD
)) {
4375 Status
= EFI_UNSUPPORTED
;
4379 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
4381 switch (QuestionId
) {
4382 case KEY_SECURE_BOOT_ENABLE
:
4383 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME
, &gEfiSecureBootEnableDisableGuid
, (VOID
**)&SecureBootEnable
, NULL
);
4384 if (NULL
!= SecureBootEnable
) {
4385 FreePool (SecureBootEnable
);
4386 if (EFI_ERROR (SaveSecureBootVariable (Value
->u8
))) {
4388 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4390 L
"Only Physical Presence User could disable secure boot!",
4393 Status
= EFI_UNSUPPORTED
;
4396 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4398 L
"Configuration changed, please reset the platform to take effect!",
4405 case KEY_SECURE_BOOT_KEK_OPTION
:
4406 case KEY_SECURE_BOOT_DB_OPTION
:
4407 case KEY_SECURE_BOOT_DBX_OPTION
:
4408 case KEY_SECURE_BOOT_DBT_OPTION
:
4409 PrivateData
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
4411 // Clear Signature GUID.
4413 ZeroMem (IfrNvData
->SignatureGuid
, sizeof (IfrNvData
->SignatureGuid
));
4414 if (Private
->SignatureGUID
== NULL
) {
4415 Private
->SignatureGUID
= (EFI_GUID
*) AllocateZeroPool (sizeof (EFI_GUID
));
4416 if (Private
->SignatureGUID
== NULL
) {
4417 return EFI_OUT_OF_RESOURCES
;
4422 // Cleanup VFRData once leaving PK/KEK/DB/DBX/DBT enroll/delete page
4424 SecureBootExtractConfigFromVariable (PrivateData
, IfrNvData
);
4426 if (QuestionId
== KEY_SECURE_BOOT_DB_OPTION
) {
4427 LabelId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
4428 } else if (QuestionId
== KEY_SECURE_BOOT_DBX_OPTION
) {
4429 LabelId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
4430 } else if (QuestionId
== KEY_SECURE_BOOT_DBT_OPTION
) {
4431 LabelId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBT
;
4433 LabelId
= FORMID_ENROLL_KEK_FORM
;
4437 // Refresh selected file.
4439 CleanUpPage (LabelId
, Private
);
4441 case KEY_SECURE_BOOT_PK_OPTION
:
4442 LabelId
= FORMID_ENROLL_PK_FORM
;
4444 // Refresh selected file.
4446 CleanUpPage (LabelId
, Private
);
4449 case FORMID_ENROLL_PK_FORM
:
4450 ChooseFile (NULL
, NULL
, UpdatePKFromFile
, &File
);
4453 case FORMID_ENROLL_KEK_FORM
:
4454 ChooseFile (NULL
, NULL
, UpdateKEKFromFile
, &File
);
4457 case SECUREBOOT_ENROLL_SIGNATURE_TO_DB
:
4458 ChooseFile (NULL
, NULL
, UpdateDBFromFile
, &File
);
4461 case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
:
4462 ChooseFile (NULL
, NULL
, UpdateDBXFromFile
, &File
);
4464 if (Private
->FileContext
->FHandle
!= NULL
) {
4466 // Parse the file's postfix.
4468 NameLength
= StrLen (Private
->FileContext
->FileName
);
4469 if (NameLength
<= 4) {
4472 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
4474 if (IsDerEncodeCertificate (FilePostFix
)) {
4476 // Supports DER-encoded X509 certificate.
4478 IfrNvData
->FileEnrollType
= X509_CERT_FILE_TYPE
;
4479 } else if (IsAuthentication2Format(Private
->FileContext
->FHandle
)){
4480 IfrNvData
->FileEnrollType
= AUTHENTICATION_2_FILE_TYPE
;
4482 IfrNvData
->FileEnrollType
= PE_IMAGE_FILE_TYPE
;
4484 Private
->FileContext
->FileType
= IfrNvData
->FileEnrollType
;
4487 // Clean up Certificate Format if File type is not X509 DER
4489 if (IfrNvData
->FileEnrollType
!= X509_CERT_FILE_TYPE
) {
4490 IfrNvData
->CertificateFormat
= HASHALG_RAW
;
4492 DEBUG((DEBUG_ERROR
, "IfrNvData->FileEnrollType %d\n", Private
->FileContext
->FileType
));
4497 case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT
:
4498 ChooseFile (NULL
, NULL
, UpdateDBTFromFile
, &File
);
4501 case KEY_SECURE_BOOT_DELETE_PK
:
4504 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4506 L
"Are you sure you want to delete PK? Secure boot will be disabled!",
4507 L
"Press 'Y' to delete PK and exit, 'N' to discard change and return",
4510 if (Key
.UnicodeChar
== 'y' || Key
.UnicodeChar
== 'Y') {
4511 Status
= DeletePlatformKey ();
4512 if (EFI_ERROR (Status
)) {
4514 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4516 L
"Only Physical Presence User could delete PK in custom mode!",
4524 case KEY_DELETE_KEK
:
4527 EFI_KEY_EXCHANGE_KEY_NAME
,
4528 &gEfiGlobalVariableGuid
,
4530 FORMID_DELETE_KEK_FORM
,
4531 OPTION_DEL_KEK_QUESTION_ID
4535 case SECUREBOOT_DELETE_SIGNATURE_FROM_DB
:
4538 EFI_IMAGE_SECURITY_DATABASE
,
4539 &gEfiImageSecurityDatabaseGuid
,
4541 SECUREBOOT_DELETE_SIGNATURE_FROM_DB
,
4542 OPTION_DEL_DB_QUESTION_ID
4547 // From DBX option to the level-1 form, display signature list.
4549 case KEY_VALUE_FROM_DBX_TO_LIST_FORM
:
4550 Private
->VariableName
= Variable_DBX
;
4553 LABEL_SIGNATURE_LIST_START
,
4554 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4555 OPTION_SIGNATURE_LIST_QUESTION_ID
4560 // Delete all signature list and reload.
4562 case KEY_SECURE_BOOT_DELETE_ALL_LIST
:
4564 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4566 L
"Press 'Y' to delete signature list.",
4567 L
"Press other key to cancel and exit.",
4571 if (Key
.UnicodeChar
== L
'Y' || Key
.UnicodeChar
== L
'y') {
4572 DeleteSignatureEx (Private
, Delete_Signature_List_All
, IfrNvData
->CheckedDataCount
);
4577 LABEL_SIGNATURE_LIST_START
,
4578 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4579 OPTION_SIGNATURE_LIST_QUESTION_ID
4584 // Delete one signature list and reload.
4586 case KEY_SECURE_BOOT_DELETE_ALL_DATA
:
4588 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4590 L
"Press 'Y' to delete signature data.",
4591 L
"Press other key to cancel and exit.",
4595 if (Key
.UnicodeChar
== L
'Y' || Key
.UnicodeChar
== L
'y') {
4596 DeleteSignatureEx (Private
, Delete_Signature_List_One
, IfrNvData
->CheckedDataCount
);
4601 LABEL_SIGNATURE_LIST_START
,
4602 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4603 OPTION_SIGNATURE_LIST_QUESTION_ID
4608 // Delete checked signature data and reload.
4610 case KEY_SECURE_BOOT_DELETE_CHECK_DATA
:
4612 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4614 L
"Press 'Y' to delete signature data.",
4615 L
"Press other key to cancel and exit.",
4619 if (Key
.UnicodeChar
== L
'Y' || Key
.UnicodeChar
== L
'y') {
4620 DeleteSignatureEx (Private
, Delete_Signature_Data
, IfrNvData
->CheckedDataCount
);
4625 LABEL_SIGNATURE_LIST_START
,
4626 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4627 OPTION_SIGNATURE_LIST_QUESTION_ID
4631 case SECUREBOOT_DELETE_SIGNATURE_FROM_DBT
:
4634 EFI_IMAGE_SECURITY_DATABASE2
,
4635 &gEfiImageSecurityDatabaseGuid
,
4637 SECUREBOOT_DELETE_SIGNATURE_FROM_DBT
,
4638 OPTION_DEL_DBT_QUESTION_ID
4643 case KEY_VALUE_SAVE_AND_EXIT_KEK
:
4644 Status
= EnrollKeyExchangeKey (Private
);
4645 if (EFI_ERROR (Status
)) {
4647 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4649 L
"ERROR: Unsupported file type!",
4650 L
"Only supports DER-encoded X509 certificate",
4656 case KEY_VALUE_SAVE_AND_EXIT_DB
:
4657 Status
= EnrollSignatureDatabase (Private
, EFI_IMAGE_SECURITY_DATABASE
);
4658 if (EFI_ERROR (Status
)) {
4660 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4662 L
"ERROR: Unsupported file type!",
4663 L
"Only supports DER-encoded X509 certificate and executable EFI image",
4669 case KEY_VALUE_SAVE_AND_EXIT_DBX
:
4670 if (IsX509CertInDbx (Private
, EFI_IMAGE_SECURITY_DATABASE1
)) {
4672 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4674 L
"Enrollment failed! Same certificate had already been in the dbx!",
4679 // Cert already exists in DBX. Close opened file before exit.
4681 CloseEnrolledFile(Private
->FileContext
);
4685 if ((IfrNvData
!= NULL
) && (IfrNvData
->CertificateFormat
< HASHALG_MAX
)) {
4686 Status
= EnrollX509HashtoSigDB (
4688 IfrNvData
->CertificateFormat
,
4689 &IfrNvData
->RevocationDate
,
4690 &IfrNvData
->RevocationTime
,
4691 IfrNvData
->AlwaysRevocation
4693 IfrNvData
->CertificateFormat
= HASHALG_RAW
;
4695 Status
= EnrollSignatureDatabase (Private
, EFI_IMAGE_SECURITY_DATABASE1
);
4697 if (EFI_ERROR (Status
)) {
4699 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4701 L
"ERROR: Unsupported file type!",
4702 L
"Only supports DER-encoded X509 certificate, AUTH_2 format data & executable EFI image",
4708 case KEY_VALUE_SAVE_AND_EXIT_DBT
:
4709 Status
= EnrollSignatureDatabase (Private
, EFI_IMAGE_SECURITY_DATABASE2
);
4710 if (EFI_ERROR (Status
)) {
4712 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4714 L
"ERROR: Unsupported file type!",
4715 L
"Only supports DER-encoded X509 certificate.",
4720 case KEY_VALUE_SAVE_AND_EXIT_PK
:
4721 Status
= EnrollPlatformKey (Private
);
4722 if (EFI_ERROR (Status
)) {
4725 sizeof (PromptString
),
4726 L
"Only DER encoded certificate file (%s) is supported.",
4730 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4732 L
"ERROR: Unsupported file type!",
4739 if ((QuestionId
>= OPTION_DEL_KEK_QUESTION_ID
) &&
4740 (QuestionId
< (OPTION_DEL_KEK_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4741 DeleteKeyExchangeKey (Private
, QuestionId
);
4742 } else if ((QuestionId
>= OPTION_DEL_DB_QUESTION_ID
) &&
4743 (QuestionId
< (OPTION_DEL_DB_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4746 EFI_IMAGE_SECURITY_DATABASE
,
4747 &gEfiImageSecurityDatabaseGuid
,
4749 SECUREBOOT_DELETE_SIGNATURE_FROM_DB
,
4750 OPTION_DEL_DB_QUESTION_ID
,
4751 QuestionId
- OPTION_DEL_DB_QUESTION_ID
4753 } else if ((QuestionId
>= OPTION_SIGNATURE_LIST_QUESTION_ID
) &&
4754 (QuestionId
< (OPTION_SIGNATURE_LIST_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4757 LABEL_SIGNATURE_DATA_START
,
4758 SECUREBOOT_DELETE_SIGNATURE_DATA_FORM
,
4759 OPTION_SIGNATURE_DATA_QUESTION_ID
,
4760 QuestionId
- OPTION_SIGNATURE_LIST_QUESTION_ID
4762 Private
->ListIndex
= QuestionId
- OPTION_SIGNATURE_LIST_QUESTION_ID
;
4763 } else if ((QuestionId
>= OPTION_SIGNATURE_DATA_QUESTION_ID
) &&
4764 (QuestionId
< (OPTION_SIGNATURE_DATA_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4765 if (Private
->CheckArray
[QuestionId
- OPTION_SIGNATURE_DATA_QUESTION_ID
]) {
4766 IfrNvData
->CheckedDataCount
--;
4767 Private
->CheckArray
[QuestionId
- OPTION_SIGNATURE_DATA_QUESTION_ID
] = FALSE
;
4769 IfrNvData
->CheckedDataCount
++;
4770 Private
->CheckArray
[QuestionId
- OPTION_SIGNATURE_DATA_QUESTION_ID
] = TRUE
;
4772 } else if ((QuestionId
>= OPTION_DEL_DBT_QUESTION_ID
) &&
4773 (QuestionId
< (OPTION_DEL_DBT_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4776 EFI_IMAGE_SECURITY_DATABASE2
,
4777 &gEfiImageSecurityDatabaseGuid
,
4779 SECUREBOOT_DELETE_SIGNATURE_FROM_DBT
,
4780 OPTION_DEL_DBT_QUESTION_ID
,
4781 QuestionId
- OPTION_DEL_DBT_QUESTION_ID
4786 case KEY_VALUE_NO_SAVE_AND_EXIT_PK
:
4787 case KEY_VALUE_NO_SAVE_AND_EXIT_KEK
:
4788 case KEY_VALUE_NO_SAVE_AND_EXIT_DB
:
4789 case KEY_VALUE_NO_SAVE_AND_EXIT_DBX
:
4790 case KEY_VALUE_NO_SAVE_AND_EXIT_DBT
:
4791 CloseEnrolledFile(Private
->FileContext
);
4793 if (Private
->SignatureGUID
!= NULL
) {
4794 FreePool (Private
->SignatureGUID
);
4795 Private
->SignatureGUID
= NULL
;
4799 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
4800 switch (QuestionId
) {
4801 case KEY_SECURE_BOOT_ENABLE
:
4802 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
4804 case KEY_SECURE_BOOT_MODE
:
4805 mIsEnterSecureBootForm
= FALSE
;
4807 case KEY_SECURE_BOOT_KEK_GUID
:
4808 case KEY_SECURE_BOOT_SIGNATURE_GUID_DB
:
4809 case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX
:
4810 case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT
:
4811 ASSERT (Private
->SignatureGUID
!= NULL
);
4812 RStatus
= StrToGuid (IfrNvData
->SignatureGuid
, Private
->SignatureGUID
);
4813 if (RETURN_ERROR (RStatus
) || (IfrNvData
->SignatureGuid
[GUID_STRING_LENGTH
] != L
'\0')) {
4814 Status
= EFI_INVALID_PARAMETER
;
4818 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
4820 case KEY_SECURE_BOOT_DELETE_PK
:
4821 GetVariable2 (EFI_SETUP_MODE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&SetupMode
, NULL
);
4822 if (SetupMode
== NULL
|| (*SetupMode
) == SETUP_MODE
) {
4823 IfrNvData
->DeletePk
= TRUE
;
4824 IfrNvData
->HasPk
= FALSE
;
4825 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
4827 IfrNvData
->DeletePk
= FALSE
;
4828 IfrNvData
->HasPk
= TRUE
;
4829 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
4831 if (SetupMode
!= NULL
) {
4832 FreePool (SetupMode
);
4838 } else if (Action
== EFI_BROWSER_ACTION_DEFAULT_STANDARD
) {
4839 if (QuestionId
== KEY_HIDE_SECURE_BOOT
) {
4840 GetVariable2 (EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Pk
, NULL
);
4842 IfrNvData
->HideSecureBoot
= TRUE
;
4845 IfrNvData
->HideSecureBoot
= FALSE
;
4847 Value
->b
= IfrNvData
->HideSecureBoot
;
4849 } else if (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
) {
4851 // Force the platform back to Standard Mode once user leave the setup screen.
4853 GetVariable2 (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
, (VOID
**)&SecureBootMode
, NULL
);
4854 if (NULL
!= SecureBootMode
&& *SecureBootMode
== CUSTOM_SECURE_BOOT_MODE
) {
4855 IfrNvData
->SecureBootMode
= STANDARD_SECURE_BOOT_MODE
;
4856 SetSecureBootMode(STANDARD_SECURE_BOOT_MODE
);
4858 if (SecureBootMode
!= NULL
) {
4859 FreePool (SecureBootMode
);
4862 if (QuestionId
== KEY_SECURE_BOOT_DELETE_ALL_DATA
) {
4864 // Free memory when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
4866 SECUREBOOT_FREE_NON_NULL (Private
->CheckArray
);
4867 IfrNvData
->CheckedDataCount
= 0;
4873 if (!EFI_ERROR (Status
) && GetBrowserDataResult
) {
4874 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
4875 HiiSetBrowserData (&gSecureBootConfigFormSetGuid
, mSecureBootStorageName
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
4878 FreePool (IfrNvData
);
4889 This function publish the SecureBoot configuration Form.
4891 @param[in, out] PrivateData Points to SecureBoot configuration private data.
4893 @retval EFI_SUCCESS HII Form is installed successfully.
4894 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
4895 @retval Others Other errors as indicated.
4899 InstallSecureBootConfigForm (
4900 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
4904 EFI_HII_HANDLE HiiHandle
;
4905 EFI_HANDLE DriverHandle
;
4906 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
4908 DriverHandle
= NULL
;
4909 ConfigAccess
= &PrivateData
->ConfigAccess
;
4910 Status
= gBS
->InstallMultipleProtocolInterfaces (
4912 &gEfiDevicePathProtocolGuid
,
4913 &mSecureBootHiiVendorDevicePath
,
4914 &gEfiHiiConfigAccessProtocolGuid
,
4918 if (EFI_ERROR (Status
)) {
4922 PrivateData
->DriverHandle
= DriverHandle
;
4925 // Publish the HII package list
4927 HiiHandle
= HiiAddPackages (
4928 &gSecureBootConfigFormSetGuid
,
4930 SecureBootConfigDxeStrings
,
4931 SecureBootConfigBin
,
4934 if (HiiHandle
== NULL
) {
4935 gBS
->UninstallMultipleProtocolInterfaces (
4937 &gEfiDevicePathProtocolGuid
,
4938 &mSecureBootHiiVendorDevicePath
,
4939 &gEfiHiiConfigAccessProtocolGuid
,
4943 return EFI_OUT_OF_RESOURCES
;
4946 PrivateData
->HiiHandle
= HiiHandle
;
4948 PrivateData
->FileContext
= AllocateZeroPool (sizeof (SECUREBOOT_FILE_CONTEXT
));
4950 if (PrivateData
->FileContext
== NULL
) {
4951 UninstallSecureBootConfigForm (PrivateData
);
4952 return EFI_OUT_OF_RESOURCES
;
4956 // Init OpCode Handle and Allocate space for creation of Buffer
4958 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
4959 if (mStartOpCodeHandle
== NULL
) {
4960 UninstallSecureBootConfigForm (PrivateData
);
4961 return EFI_OUT_OF_RESOURCES
;
4964 mEndOpCodeHandle
= HiiAllocateOpCodeHandle ();
4965 if (mEndOpCodeHandle
== NULL
) {
4966 UninstallSecureBootConfigForm (PrivateData
);
4967 return EFI_OUT_OF_RESOURCES
;
4971 // Create Hii Extend Label OpCode as the start opcode
4973 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
4977 sizeof (EFI_IFR_GUID_LABEL
)
4979 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4982 // Create Hii Extend Label OpCode as the end opcode
4984 mEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
4988 sizeof (EFI_IFR_GUID_LABEL
)
4990 mEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4991 mEndLabel
->Number
= LABEL_END
;
4997 This function removes SecureBoot configuration Form.
4999 @param[in, out] PrivateData Points to SecureBoot configuration private data.
5003 UninstallSecureBootConfigForm (
5004 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
5008 // Uninstall HII package list
5010 if (PrivateData
->HiiHandle
!= NULL
) {
5011 HiiRemovePackages (PrivateData
->HiiHandle
);
5012 PrivateData
->HiiHandle
= NULL
;
5016 // Uninstall HII Config Access Protocol
5018 if (PrivateData
->DriverHandle
!= NULL
) {
5019 gBS
->UninstallMultipleProtocolInterfaces (
5020 PrivateData
->DriverHandle
,
5021 &gEfiDevicePathProtocolGuid
,
5022 &mSecureBootHiiVendorDevicePath
,
5023 &gEfiHiiConfigAccessProtocolGuid
,
5024 &PrivateData
->ConfigAccess
,
5027 PrivateData
->DriverHandle
= NULL
;
5030 if (PrivateData
->SignatureGUID
!= NULL
) {
5031 FreePool (PrivateData
->SignatureGUID
);
5034 if (PrivateData
->FileContext
!= NULL
) {
5035 FreePool (PrivateData
->FileContext
);
5038 FreePool (PrivateData
);
5040 if (mStartOpCodeHandle
!= NULL
) {
5041 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
5044 if (mEndOpCodeHandle
!= NULL
) {
5045 HiiFreeOpCodeHandle (mEndOpCodeHandle
);