2 HII Config Access protocol implementation of SecureBoot configuration module.
4 Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "SecureBootConfigImpl.h"
16 #include <Library/BaseCryptLib.h>
18 CHAR16 mSecureBootStorageName
[] = L
"SECUREBOOT_CONFIGURATION";
20 SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate
= {
21 SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE
,
23 SecureBootExtractConfig
,
24 SecureBootRouteConfig
,
29 HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath
= {
35 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
36 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
39 SECUREBOOT_CONFIG_FORM_SET_GUID
43 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
45 (UINT8
) (END_DEVICE_PATH_LENGTH
),
46 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
52 BOOLEAN mIsEnterSecureBootForm
= FALSE
;
55 // OID ASN.1 Value for Hash Algorithms
57 UINT8 mHashOidValue
[] = {
58 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, // OBJ_md5
59 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJ_sha1
60 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224
61 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256
62 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384
63 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512
66 HASH_TABLE mHash
[] = {
67 { L
"SHA224", 28, &mHashOidValue
[13], 9, NULL
, NULL
, NULL
, NULL
},
68 { L
"SHA256", 32, &mHashOidValue
[22], 9, Sha256GetContextSize
, Sha256Init
, Sha256Update
, Sha256Final
},
69 { L
"SHA384", 48, &mHashOidValue
[31], 9, Sha384GetContextSize
, Sha384Init
, Sha384Update
, Sha384Final
},
70 { L
"SHA512", 64, &mHashOidValue
[40], 9, Sha512GetContextSize
, Sha512Init
, Sha512Update
, Sha512Final
}
74 // Variable Definitions
76 UINT32 mPeCoffHeaderOffset
= 0;
77 WIN_CERTIFICATE
*mCertificate
= NULL
;
78 IMAGE_TYPE mImageType
;
79 UINT8
*mImageBase
= NULL
;
81 UINT8 mImageDigest
[MAX_DIGEST_SIZE
];
82 UINTN mImageDigestSize
;
84 EFI_IMAGE_SECURITY_DATA_DIRECTORY
*mSecDataDir
= NULL
;
85 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader
;
88 // Possible DER-encoded certificate file suffixes, end with NULL pointer.
90 CHAR16
* mDerEncodedSuffix
[] = {
96 CHAR16
* mSupportX509Suffix
= L
"*.cer/der/crt";
98 SECUREBOOT_CONFIG_PRIVATE_DATA
*gSecureBootPrivateData
= NULL
;
101 This code cleans up enrolled file by closing file & free related resources attached to
104 @param[in] FileContext FileContext cached in SecureBootConfig driver
109 IN SECUREBOOT_FILE_CONTEXT
*FileContext
112 if (FileContext
->FHandle
!= NULL
) {
113 CloseFile (FileContext
->FHandle
);
114 FileContext
->FHandle
= NULL
;
117 if (FileContext
->FileName
!= NULL
){
118 FreePool(FileContext
->FileName
);
119 FileContext
->FileName
= NULL
;
121 FileContext
->FileType
= UNKNOWN_FILE_TYPE
;
126 This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.
128 @param[in] FileSuffix The suffix of the input certificate file
130 @retval TRUE It's a DER-encoded certificate.
131 @retval FALSE It's NOT a DER-encoded certificate.
135 IsDerEncodeCertificate (
136 IN CONST CHAR16
*FileSuffix
140 for (Index
= 0; mDerEncodedSuffix
[Index
] != NULL
; Index
++) {
141 if (StrCmp (FileSuffix
, mDerEncodedSuffix
[Index
]) == 0) {
149 This code checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format
150 The function reads file content but won't open/close given FileHandle.
152 @param[in] FileHandle The FileHandle to be checked
154 @retval TRUE The content is EFI_VARIABLE_AUTHENTICATION_2 format.
155 @retval FALSE The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format.
159 IsAuthentication2Format (
160 IN EFI_FILE_HANDLE FileHandle
164 EFI_VARIABLE_AUTHENTICATION_2
*Auth2
;
165 BOOLEAN IsAuth2Format
;
167 IsAuth2Format
= FALSE
;
170 // Read the whole file content
172 Status
= ReadFileContent(
174 (VOID
**) &mImageBase
,
178 if (EFI_ERROR (Status
)) {
182 Auth2
= (EFI_VARIABLE_AUTHENTICATION_2
*)mImageBase
;
183 if (Auth2
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) {
187 if (CompareGuid(&gEfiCertPkcs7Guid
, &Auth2
->AuthInfo
.CertType
)) {
188 IsAuth2Format
= TRUE
;
193 // Do not close File. simply check file content
195 if (mImageBase
!= NULL
) {
196 FreePool (mImageBase
);
200 return IsAuth2Format
;
204 Set Secure Boot option into variable space.
206 @param[in] VarValue The option of Secure Boot.
208 @retval EFI_SUCCESS The operation is finished successfully.
209 @retval Others Other errors as indicated.
213 SaveSecureBootVariable (
219 Status
= gRT
->SetVariable (
220 EFI_SECURE_BOOT_ENABLE_NAME
,
221 &gEfiSecureBootEnableDisableGuid
,
222 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
230 Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
231 descriptor with the input data. NO authentication is required in this function.
233 @param[in, out] DataSize On input, the size of Data buffer in bytes.
234 On output, the size of data returned in Data
236 @param[in, out] Data On input, Pointer to data buffer to be wrapped or
237 pointer to NULL to wrap an empty payload.
238 On output, Pointer to the new payload date buffer allocated from pool,
239 it's caller's responsibility to free the memory when finish using it.
241 @retval EFI_SUCCESS Create time based payload successfully.
242 @retval EFI_OUT_OF_RESOURCES There are not enough memory resourses to create time based payload.
243 @retval EFI_INVALID_PARAMETER The parameter is invalid.
244 @retval Others Unexpected error happens.
248 CreateTimeBasedPayload (
249 IN OUT UINTN
*DataSize
,
257 EFI_VARIABLE_AUTHENTICATION_2
*DescriptorData
;
258 UINTN DescriptorSize
;
261 if (Data
== NULL
|| DataSize
== NULL
) {
262 return EFI_INVALID_PARAMETER
;
266 // In Setup mode or Custom mode, the variable does not need to be signed but the
267 // parameters to the SetVariable() call still need to be prepared as authenticated
268 // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
272 PayloadSize
= *DataSize
;
274 DescriptorSize
= OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2
, AuthInfo
) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID
, CertData
);
275 NewData
= (UINT8
*) AllocateZeroPool (DescriptorSize
+ PayloadSize
);
276 if (NewData
== NULL
) {
277 return EFI_OUT_OF_RESOURCES
;
280 if ((Payload
!= NULL
) && (PayloadSize
!= 0)) {
281 CopyMem (NewData
+ DescriptorSize
, Payload
, PayloadSize
);
284 DescriptorData
= (EFI_VARIABLE_AUTHENTICATION_2
*) (NewData
);
286 ZeroMem (&Time
, sizeof (EFI_TIME
));
287 Status
= gRT
->GetTime (&Time
, NULL
);
288 if (EFI_ERROR (Status
)) {
297 CopyMem (&DescriptorData
->TimeStamp
, &Time
, sizeof (EFI_TIME
));
299 DescriptorData
->AuthInfo
.Hdr
.dwLength
= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID
, CertData
);
300 DescriptorData
->AuthInfo
.Hdr
.wRevision
= 0x0200;
301 DescriptorData
->AuthInfo
.Hdr
.wCertificateType
= WIN_CERT_TYPE_EFI_GUID
;
302 CopyGuid (&DescriptorData
->AuthInfo
.CertType
, &gEfiCertPkcs7Guid
);
304 if (Payload
!= NULL
) {
308 *DataSize
= DescriptorSize
+ PayloadSize
;
314 Internal helper function to delete a Variable given its name and GUID, NO authentication
317 @param[in] VariableName Name of the Variable.
318 @param[in] VendorGuid GUID of the Variable.
320 @retval EFI_SUCCESS Variable deleted successfully.
321 @retval Others The driver failed to start the device.
326 IN CHAR16
*VariableName
,
327 IN EFI_GUID
*VendorGuid
336 GetVariable2 (VariableName
, VendorGuid
, &Variable
, NULL
);
337 if (Variable
== NULL
) {
344 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
345 | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
347 Status
= CreateTimeBasedPayload (&DataSize
, &Data
);
348 if (EFI_ERROR (Status
)) {
349 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
353 Status
= gRT
->SetVariable (
368 Set the platform secure boot mode into "Custom" or "Standard" mode.
370 @param[in] SecureBootMode New secure boot mode: STANDARD_SECURE_BOOT_MODE or
371 CUSTOM_SECURE_BOOT_MODE.
373 @return EFI_SUCCESS The platform has switched to the special mode successfully.
374 @return other Fail to operate the secure boot mode.
379 IN UINT8 SecureBootMode
382 return gRT
->SetVariable (
383 EFI_CUSTOM_MODE_NAME
,
384 &gEfiCustomModeEnableGuid
,
385 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
392 Generate the PK signature list from the X509 Certificate storing file (.cer)
394 @param[in] X509File FileHandle of X509 Certificate storing file.
395 @param[out] PkCert Point to the data buffer to store the signature list.
397 @return EFI_UNSUPPORTED Unsupported Key Length.
398 @return EFI_OUT_OF_RESOURCES There are not enough memory resourses to form the signature list.
402 CreatePkX509SignatureList (
403 IN EFI_FILE_HANDLE X509File
,
404 OUT EFI_SIGNATURE_LIST
**PkCert
410 EFI_SIGNATURE_DATA
*PkCertData
;
416 Status
= ReadFileContent (X509File
, (VOID
**) &X509Data
, &X509DataSize
, 0);
417 if (EFI_ERROR (Status
)) {
420 ASSERT (X509Data
!= NULL
);
423 // Allocate space for PK certificate list and initialize it.
424 // Create PK database entry with SignatureHeaderSize equals 0.
426 *PkCert
= (EFI_SIGNATURE_LIST
*) AllocateZeroPool (
427 sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1
430 if (*PkCert
== NULL
) {
431 Status
= EFI_OUT_OF_RESOURCES
;
435 (*PkCert
)->SignatureListSize
= (UINT32
) (sizeof(EFI_SIGNATURE_LIST
)
436 + sizeof(EFI_SIGNATURE_DATA
) - 1
438 (*PkCert
)->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
439 (*PkCert
)->SignatureHeaderSize
= 0;
440 CopyGuid (&(*PkCert
)->SignatureType
, &gEfiCertX509Guid
);
441 PkCertData
= (EFI_SIGNATURE_DATA
*) ((UINTN
)(*PkCert
)
442 + sizeof(EFI_SIGNATURE_LIST
)
443 + (*PkCert
)->SignatureHeaderSize
);
444 CopyGuid (&PkCertData
->SignatureOwner
, &gEfiGlobalVariableGuid
);
446 // Fill the PK database with PKpub data from X509 certificate file.
448 CopyMem (&(PkCertData
->SignatureData
[0]), X509Data
, X509DataSize
);
452 if (X509Data
!= NULL
) {
456 if (EFI_ERROR(Status
) && *PkCert
!= NULL
) {
465 Enroll new PK into the System without original PK's authentication.
467 The SignatureOwner GUID will be the same with PK's vendorguid.
469 @param[in] PrivateData The module's private data.
471 @retval EFI_SUCCESS New PK enrolled successfully.
472 @retval EFI_INVALID_PARAMETER The parameter is invalid.
473 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
478 IN SECUREBOOT_CONFIG_PRIVATE_DATA
* Private
484 EFI_SIGNATURE_LIST
*PkCert
;
488 if (Private
->FileContext
->FileName
== NULL
) {
489 return EFI_INVALID_PARAMETER
;
494 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
495 if (EFI_ERROR (Status
)) {
500 // Parse the file's postfix. Only support DER encoded X.509 certificate files.
502 NameLength
= StrLen (Private
->FileContext
->FileName
);
503 if (NameLength
<= 4) {
504 return EFI_INVALID_PARAMETER
;
506 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
507 if (!IsDerEncodeCertificate(FilePostFix
)) {
508 DEBUG ((EFI_D_ERROR
, "Unsupported file type, only DER encoded certificate (%s) is supported.", mSupportX509Suffix
));
509 return EFI_INVALID_PARAMETER
;
511 DEBUG ((EFI_D_INFO
, "FileName= %s\n", Private
->FileContext
->FileName
));
512 DEBUG ((EFI_D_INFO
, "FilePostFix = %s\n", FilePostFix
));
515 // Prase the selected PK file and generature PK certificate list.
517 Status
= CreatePkX509SignatureList (
518 Private
->FileContext
->FHandle
,
521 if (EFI_ERROR (Status
)) {
524 ASSERT (PkCert
!= NULL
);
527 // Set Platform Key variable.
529 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
530 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
531 DataSize
= PkCert
->SignatureListSize
;
532 Status
= CreateTimeBasedPayload (&DataSize
, (UINT8
**) &PkCert
);
533 if (EFI_ERROR (Status
)) {
534 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
538 Status
= gRT
->SetVariable(
539 EFI_PLATFORM_KEY_NAME
,
540 &gEfiGlobalVariableGuid
,
545 if (EFI_ERROR (Status
)) {
546 if (Status
== EFI_OUT_OF_RESOURCES
) {
547 DEBUG ((EFI_D_ERROR
, "Enroll PK failed with out of resource.\n"));
554 if (PkCert
!= NULL
) {
558 CloseEnrolledFile(Private
->FileContext
);
564 Remove the PK variable.
566 @retval EFI_SUCCESS Delete PK successfully.
567 @retval Others Could not allow to delete PK.
577 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
578 if (EFI_ERROR (Status
)) {
582 Status
= DeleteVariable (
583 EFI_PLATFORM_KEY_NAME
,
584 &gEfiGlobalVariableGuid
590 Enroll a new KEK item from public key storing file (*.pbk).
592 @param[in] PrivateData The module's private data.
594 @retval EFI_SUCCESS New KEK enrolled successfully.
595 @retval EFI_INVALID_PARAMETER The parameter is invalid.
596 @retval EFI_UNSUPPORTED Unsupported command.
597 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
602 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
608 EFI_SIGNATURE_LIST
*KekSigList
;
611 CPL_KEY_INFO
*KeyInfo
;
612 EFI_SIGNATURE_DATA
*KEKSigData
;
613 UINTN KekSigListSize
;
628 // Form the KeKpub certificate list into EFI_SIGNATURE_LIST type.
629 // First, We have to parse out public key data from the pbk key file.
631 Status
= ReadFileContent (
632 Private
->FileContext
->FHandle
,
637 if (EFI_ERROR (Status
)) {
640 ASSERT (KeyBlob
!= NULL
);
641 KeyInfo
= (CPL_KEY_INFO
*) KeyBlob
;
642 if (KeyInfo
->KeyLengthInBits
/ 8 != WIN_CERT_UEFI_RSA2048_SIZE
) {
643 DEBUG ((DEBUG_ERROR
, "Unsupported key length, Only RSA2048 is supported.\n"));
644 Status
= EFI_UNSUPPORTED
;
649 // Convert the Public key to fix octet string format represented in RSA PKCS#1.
651 KeyLenInBytes
= KeyInfo
->KeyLengthInBits
/ 8;
652 KeyBuffer
= AllocateZeroPool (KeyLenInBytes
);
653 if (KeyBuffer
== NULL
) {
654 Status
= EFI_OUT_OF_RESOURCES
;
658 (UINTN
*) (KeyBlob
+ sizeof (CPL_KEY_INFO
)),
659 KeyLenInBytes
/ sizeof (UINTN
),
663 CopyMem(KeyBlob
+ sizeof(CPL_KEY_INFO
), KeyBuffer
, KeyLenInBytes
);
666 // Form an new EFI_SIGNATURE_LIST.
668 KekSigListSize
= sizeof(EFI_SIGNATURE_LIST
)
669 + sizeof(EFI_SIGNATURE_DATA
) - 1
670 + WIN_CERT_UEFI_RSA2048_SIZE
;
672 KekSigList
= (EFI_SIGNATURE_LIST
*) AllocateZeroPool (KekSigListSize
);
673 if (KekSigList
== NULL
) {
674 Status
= EFI_OUT_OF_RESOURCES
;
678 KekSigList
->SignatureListSize
= sizeof(EFI_SIGNATURE_LIST
)
679 + sizeof(EFI_SIGNATURE_DATA
) - 1
680 + WIN_CERT_UEFI_RSA2048_SIZE
;
681 KekSigList
->SignatureHeaderSize
= 0;
682 KekSigList
->SignatureSize
= sizeof(EFI_SIGNATURE_DATA
) - 1 + WIN_CERT_UEFI_RSA2048_SIZE
;
683 CopyGuid (&KekSigList
->SignatureType
, &gEfiCertRsa2048Guid
);
685 KEKSigData
= (EFI_SIGNATURE_DATA
*)((UINT8
*)KekSigList
+ sizeof(EFI_SIGNATURE_LIST
));
686 CopyGuid (&KEKSigData
->SignatureOwner
, Private
->SignatureGUID
);
688 KEKSigData
->SignatureData
,
689 KeyBlob
+ sizeof(CPL_KEY_INFO
),
690 WIN_CERT_UEFI_RSA2048_SIZE
694 // Check if KEK entry has been already existed.
695 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
696 // new KEK to original variable.
698 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
699 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
700 Status
= CreateTimeBasedPayload (&KekSigListSize
, (UINT8
**) &KekSigList
);
701 if (EFI_ERROR (Status
)) {
702 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
706 Status
= gRT
->GetVariable(
707 EFI_KEY_EXCHANGE_KEY_NAME
,
708 &gEfiGlobalVariableGuid
,
713 if (Status
== EFI_BUFFER_TOO_SMALL
) {
714 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
715 } else if (Status
!= EFI_NOT_FOUND
) {
720 // Done. Now we have formed the correct KEKpub database item, just set it into variable storage,
722 Status
= gRT
->SetVariable(
723 EFI_KEY_EXCHANGE_KEY_NAME
,
724 &gEfiGlobalVariableGuid
,
729 if (EFI_ERROR (Status
)) {
735 CloseEnrolledFile(Private
->FileContext
);
737 if (Private
->SignatureGUID
!= NULL
) {
738 FreePool (Private
->SignatureGUID
);
739 Private
->SignatureGUID
= NULL
;
742 if (KeyBlob
!= NULL
) {
745 if (KeyBuffer
!= NULL
) {
746 FreePool (KeyBuffer
);
748 if (KekSigList
!= NULL
) {
749 FreePool (KekSigList
);
756 Enroll a new KEK item from X509 certificate file.
758 @param[in] PrivateData The module's private data.
760 @retval EFI_SUCCESS New X509 is enrolled successfully.
761 @retval EFI_INVALID_PARAMETER The parameter is invalid.
762 @retval EFI_UNSUPPORTED Unsupported command.
763 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
768 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
774 EFI_SIGNATURE_DATA
*KEKSigData
;
775 EFI_SIGNATURE_LIST
*KekSigList
;
777 UINTN KekSigListSize
;
787 Status
= ReadFileContent (
788 Private
->FileContext
->FHandle
,
793 if (EFI_ERROR (Status
)) {
796 ASSERT (X509Data
!= NULL
);
798 KekSigListSize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
;
799 KekSigList
= (EFI_SIGNATURE_LIST
*) AllocateZeroPool (KekSigListSize
);
800 if (KekSigList
== NULL
) {
801 Status
= EFI_OUT_OF_RESOURCES
;
806 // Fill Certificate Database parameters.
808 KekSigList
->SignatureListSize
= (UINT32
) KekSigListSize
;
809 KekSigList
->SignatureHeaderSize
= 0;
810 KekSigList
->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
811 CopyGuid (&KekSigList
->SignatureType
, &gEfiCertX509Guid
);
813 KEKSigData
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) KekSigList
+ sizeof (EFI_SIGNATURE_LIST
));
814 CopyGuid (&KEKSigData
->SignatureOwner
, Private
->SignatureGUID
);
815 CopyMem (KEKSigData
->SignatureData
, X509Data
, X509DataSize
);
818 // Check if KEK been already existed.
819 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
820 // new kek to original variable
822 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
823 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
824 Status
= CreateTimeBasedPayload (&KekSigListSize
, (UINT8
**) &KekSigList
);
825 if (EFI_ERROR (Status
)) {
826 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
830 Status
= gRT
->GetVariable(
831 EFI_KEY_EXCHANGE_KEY_NAME
,
832 &gEfiGlobalVariableGuid
,
837 if (Status
== EFI_BUFFER_TOO_SMALL
) {
838 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
839 } else if (Status
!= EFI_NOT_FOUND
) {
843 Status
= gRT
->SetVariable(
844 EFI_KEY_EXCHANGE_KEY_NAME
,
845 &gEfiGlobalVariableGuid
,
850 if (EFI_ERROR (Status
)) {
856 CloseEnrolledFile(Private
->FileContext
);
858 if (Private
->SignatureGUID
!= NULL
) {
859 FreePool (Private
->SignatureGUID
);
860 Private
->SignatureGUID
= NULL
;
863 if (KekSigList
!= NULL
) {
864 FreePool (KekSigList
);
871 Enroll new KEK into the System without PK's authentication.
872 The SignatureOwner GUID will be Private->SignatureGUID.
874 @param[in] PrivateData The module's private data.
876 @retval EFI_SUCCESS New KEK enrolled successful.
877 @retval EFI_INVALID_PARAMETER The parameter is invalid.
878 @retval others Fail to enroll KEK data.
882 EnrollKeyExchangeKey (
883 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
890 if ((Private
->FileContext
->FHandle
== NULL
) || (Private
->FileContext
->FileName
== NULL
) || (Private
->SignatureGUID
== NULL
)) {
891 return EFI_INVALID_PARAMETER
;
894 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
895 if (EFI_ERROR (Status
)) {
900 // Parse the file's postfix. Supports DER-encoded X509 certificate,
901 // and .pbk as RSA public key file.
903 NameLength
= StrLen (Private
->FileContext
->FileName
);
904 if (NameLength
<= 4) {
905 return EFI_INVALID_PARAMETER
;
907 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
908 if (IsDerEncodeCertificate(FilePostFix
)) {
909 return EnrollX509ToKek (Private
);
910 } else if (CompareMem (FilePostFix
, L
".pbk",4) == 0) {
911 return EnrollRsa2048ToKek (Private
);
914 // File type is wrong, simply close it
916 CloseEnrolledFile(Private
->FileContext
);
918 return EFI_INVALID_PARAMETER
;
923 Enroll a new X509 certificate into Signature Database (DB or DBX or DBT) without
924 KEK's authentication.
926 @param[in] PrivateData The module's private data.
927 @param[in] VariableName Variable name of signature database, must be
928 EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
930 @retval EFI_SUCCESS New X509 is enrolled successfully.
931 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
936 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
937 IN CHAR16
*VariableName
943 EFI_SIGNATURE_LIST
*SigDBCert
;
944 EFI_SIGNATURE_DATA
*SigDBCertData
;
955 SigDBCertData
= NULL
;
958 Status
= ReadFileContent (
959 Private
->FileContext
->FHandle
,
964 if (EFI_ERROR (Status
)) {
967 ASSERT (X509Data
!= NULL
);
969 SigDBSize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
;
971 Data
= AllocateZeroPool (SigDBSize
);
973 Status
= EFI_OUT_OF_RESOURCES
;
978 // Fill Certificate Database parameters.
980 SigDBCert
= (EFI_SIGNATURE_LIST
*) Data
;
981 SigDBCert
->SignatureListSize
= (UINT32
) SigDBSize
;
982 SigDBCert
->SignatureHeaderSize
= 0;
983 SigDBCert
->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
984 CopyGuid (&SigDBCert
->SignatureType
, &gEfiCertX509Guid
);
986 SigDBCertData
= (EFI_SIGNATURE_DATA
*) ((UINT8
* ) SigDBCert
+ sizeof (EFI_SIGNATURE_LIST
));
987 CopyGuid (&SigDBCertData
->SignatureOwner
, Private
->SignatureGUID
);
988 CopyMem ((UINT8
* ) (SigDBCertData
->SignatureData
), X509Data
, X509DataSize
);
991 // Check if signature database entry has been already existed.
992 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
993 // new signature data to original variable
995 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
996 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
997 Status
= CreateTimeBasedPayload (&SigDBSize
, (UINT8
**) &Data
);
998 if (EFI_ERROR (Status
)) {
999 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
1003 Status
= gRT
->GetVariable(
1005 &gEfiImageSecurityDatabaseGuid
,
1010 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1011 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
1012 } else if (Status
!= EFI_NOT_FOUND
) {
1016 Status
= gRT
->SetVariable(
1018 &gEfiImageSecurityDatabaseGuid
,
1023 if (EFI_ERROR (Status
)) {
1029 CloseEnrolledFile(Private
->FileContext
);
1031 if (Private
->SignatureGUID
!= NULL
) {
1032 FreePool (Private
->SignatureGUID
);
1033 Private
->SignatureGUID
= NULL
;
1040 if (X509Data
!= NULL
) {
1041 FreePool (X509Data
);
1048 Check whether signature is in specified database.
1050 @param[in] VariableName Name of database variable that is searched in.
1051 @param[in] Signature Pointer to signature that is searched for.
1052 @param[in] SignatureSize Size of Signature.
1054 @return TRUE Found the signature in the variable database.
1055 @return FALSE Not found the signature in the variable database.
1059 IsSignatureFoundInDatabase (
1060 IN CHAR16
*VariableName
,
1061 IN UINT8
*Signature
,
1062 IN UINTN SignatureSize
1066 EFI_SIGNATURE_LIST
*CertList
;
1067 EFI_SIGNATURE_DATA
*Cert
;
1075 // Read signature database variable.
1080 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, NULL
);
1081 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1085 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
1090 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, Data
);
1091 if (EFI_ERROR (Status
)) {
1096 // Enumerate all signature data in SigDB to check if executable's signature exists.
1098 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
1099 while ((DataSize
> 0) && (DataSize
>= CertList
->SignatureListSize
)) {
1100 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
1101 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
1102 if ((CertList
->SignatureSize
== sizeof(EFI_SIGNATURE_DATA
) - 1 + SignatureSize
) && (CompareGuid(&CertList
->SignatureType
, &gEfiCertX509Guid
))) {
1103 for (Index
= 0; Index
< CertCount
; Index
++) {
1104 if (CompareMem (Cert
->SignatureData
, Signature
, SignatureSize
) == 0) {
1106 // Find the signature in database.
1111 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
1119 DataSize
-= CertList
->SignatureListSize
;
1120 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
1132 Calculate the hash of a certificate data with the specified hash algorithm.
1134 @param[in] CertData The certificate data to be hashed.
1135 @param[in] CertSize The certificate size in bytes.
1136 @param[in] HashAlg The specified hash algorithm.
1137 @param[out] CertHash The output digest of the certificate
1139 @retval TRUE Successfully got the hash of the CertData.
1140 @retval FALSE Failed to get the hash of CertData.
1160 if (HashAlg
>= HASHALG_MAX
) {
1165 // Retrieve the TBSCertificate for Hash Calculation.
1167 if (!X509GetTBSCert (CertData
, CertSize
, &TBSCert
, &TBSCertSize
)) {
1172 // 1. Initialize context of hash.
1174 CtxSize
= mHash
[HashAlg
].GetContextSize ();
1175 HashCtx
= AllocatePool (CtxSize
);
1176 ASSERT (HashCtx
!= NULL
);
1179 // 2. Initialize a hash context.
1181 Status
= mHash
[HashAlg
].HashInit (HashCtx
);
1187 // 3. Calculate the hash.
1189 Status
= mHash
[HashAlg
].HashUpdate (HashCtx
, TBSCert
, TBSCertSize
);
1195 // 4. Get the hash result.
1197 ZeroMem (CertHash
, mHash
[HashAlg
].DigestLength
);
1198 Status
= mHash
[HashAlg
].HashFinal (HashCtx
, CertHash
);
1201 if (HashCtx
!= NULL
) {
1209 Check whether the hash of an X.509 certificate is in forbidden database (DBX).
1211 @param[in] Certificate Pointer to X.509 Certificate that is searched for.
1212 @param[in] CertSize Size of X.509 Certificate.
1214 @return TRUE Found the certificate hash in the forbidden database.
1215 @return FALSE Certificate hash is Not found in the forbidden database.
1219 IsCertHashFoundInDbx (
1220 IN UINT8
*Certificate
,
1226 EFI_SIGNATURE_LIST
*DbxList
;
1227 EFI_SIGNATURE_DATA
*CertHash
;
1228 UINTN CertHashCount
;
1231 UINT8 CertDigest
[MAX_DIGEST_SIZE
];
1233 UINTN SiglistHeaderSize
;
1238 HashAlg
= HASHALG_MAX
;
1242 // Read signature database variable.
1245 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, NULL
);
1246 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1250 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
1255 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, Data
);
1256 if (EFI_ERROR (Status
)) {
1261 // Check whether the certificate hash exists in the forbidden database.
1263 DbxList
= (EFI_SIGNATURE_LIST
*) Data
;
1264 while ((DataSize
> 0) && (DataSize
>= DbxList
->SignatureListSize
)) {
1266 // Determine Hash Algorithm of Certificate in the forbidden database.
1268 if (CompareGuid (&DbxList
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
1269 HashAlg
= HASHALG_SHA256
;
1270 } else if (CompareGuid (&DbxList
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
1271 HashAlg
= HASHALG_SHA384
;
1272 } else if (CompareGuid (&DbxList
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
1273 HashAlg
= HASHALG_SHA512
;
1275 DataSize
-= DbxList
->SignatureListSize
;
1276 DbxList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) DbxList
+ DbxList
->SignatureListSize
);
1281 // Calculate the hash value of current db certificate for comparision.
1283 if (!CalculateCertHash (Certificate
, CertSize
, HashAlg
, CertDigest
)) {
1287 SiglistHeaderSize
= sizeof (EFI_SIGNATURE_LIST
) + DbxList
->SignatureHeaderSize
;
1288 CertHash
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) DbxList
+ SiglistHeaderSize
);
1289 CertHashCount
= (DbxList
->SignatureListSize
- SiglistHeaderSize
) / DbxList
->SignatureSize
;
1290 for (Index
= 0; Index
< CertHashCount
; Index
++) {
1292 // Iterate each Signature Data Node within this CertList for verify.
1294 DbxCertHash
= CertHash
->SignatureData
;
1295 if (CompareMem (DbxCertHash
, CertDigest
, mHash
[HashAlg
].DigestLength
) == 0) {
1297 // Hash of Certificate is found in forbidden database.
1302 CertHash
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertHash
+ DbxList
->SignatureSize
);
1305 DataSize
-= DbxList
->SignatureListSize
;
1306 DbxList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) DbxList
+ DbxList
->SignatureListSize
);
1318 Check whether the signature list exists in given variable data.
1320 It searches the signature list for the ceritificate hash by CertType.
1321 If the signature list is found, get the offset of Database for the
1322 next hash of a certificate.
1324 @param[in] Database Variable data to save signature list.
1325 @param[in] DatabaseSize Variable size.
1326 @param[in] SignatureType The type of the signature.
1327 @param[out] Offset The offset to save a new hash of certificate.
1329 @return TRUE The signature list is found in the forbidden database.
1330 @return FALSE The signature list is not found in the forbidden database.
1333 GetSignaturelistOffset (
1334 IN EFI_SIGNATURE_LIST
*Database
,
1335 IN UINTN DatabaseSize
,
1336 IN EFI_GUID
*SignatureType
,
1340 EFI_SIGNATURE_LIST
*SigList
;
1343 if ((Database
== NULL
) || (DatabaseSize
== 0)) {
1349 SiglistSize
= DatabaseSize
;
1350 while ((SiglistSize
> 0) && (SiglistSize
>= SigList
->SignatureListSize
)) {
1351 if (CompareGuid (&SigList
->SignatureType
, SignatureType
)) {
1352 *Offset
= DatabaseSize
- SiglistSize
;
1355 SiglistSize
-= SigList
->SignatureListSize
;
1356 SigList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) SigList
+ SigList
->SignatureListSize
);
1363 Enroll a new X509 certificate hash into Signature Database (dbx) without
1364 KEK's authentication.
1366 @param[in] PrivateData The module's private data.
1367 @param[in] HashAlg The hash algorithm to enroll the certificate.
1368 @param[in] RevocationDate The revocation date of the certificate.
1369 @param[in] RevocationTime The revocation time of the certificate.
1370 @param[in] AlwaysRevocation Indicate whether the certificate is always revoked.
1372 @retval EFI_SUCCESS New X509 is enrolled successfully.
1373 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1374 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
1378 EnrollX509HashtoSigDB (
1379 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
1381 IN EFI_HII_DATE
*RevocationDate
,
1382 IN EFI_HII_TIME
*RevocationTime
,
1383 IN BOOLEAN AlwaysRevocation
1389 EFI_SIGNATURE_LIST
*SignatureList
;
1390 UINTN SignatureListSize
;
1396 EFI_SIGNATURE_DATA
*SignatureData
;
1397 UINTN SignatureSize
;
1398 EFI_GUID SignatureType
;
1400 UINT8 CertHash
[MAX_DIGEST_SIZE
];
1401 UINT16
* FilePostFix
;
1408 SignatureData
= NULL
;
1409 SignatureList
= NULL
;
1413 if ((Private
->FileContext
->FileName
== NULL
) || (Private
->FileContext
->FHandle
== NULL
) || (Private
->SignatureGUID
== NULL
)) {
1414 return EFI_INVALID_PARAMETER
;
1417 Status
= SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE
);
1418 if (EFI_ERROR (Status
)) {
1423 // Parse the file's postfix.
1425 NameLength
= StrLen (Private
->FileContext
->FileName
);
1426 if (NameLength
<= 4) {
1427 return EFI_INVALID_PARAMETER
;
1429 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
1430 if (!IsDerEncodeCertificate(FilePostFix
)) {
1432 // Only supports DER-encoded X509 certificate.
1434 return EFI_INVALID_PARAMETER
;
1438 // Get the certificate from file and calculate its hash.
1440 Status
= ReadFileContent (
1441 Private
->FileContext
->FHandle
,
1446 if (EFI_ERROR (Status
)) {
1449 ASSERT (X509Data
!= NULL
);
1451 if (!CalculateCertHash (X509Data
, X509DataSize
, HashAlg
, CertHash
)) {
1456 // Get the variable for enrollment.
1459 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, NULL
);
1460 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1461 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
1463 return EFI_OUT_OF_RESOURCES
;
1466 Status
= gRT
->GetVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, Data
);
1467 if (EFI_ERROR (Status
)) {
1473 // Allocate memory for Signature and fill the Signature
1475 SignatureSize
= sizeof(EFI_SIGNATURE_DATA
) - 1 + sizeof (EFI_TIME
) + mHash
[HashAlg
].DigestLength
;
1476 SignatureData
= (EFI_SIGNATURE_DATA
*) AllocateZeroPool (SignatureSize
);
1477 if (SignatureData
== NULL
) {
1478 return EFI_OUT_OF_RESOURCES
;
1480 CopyGuid (&SignatureData
->SignatureOwner
, Private
->SignatureGUID
);
1481 CopyMem (SignatureData
->SignatureData
, CertHash
, mHash
[HashAlg
].DigestLength
);
1486 if (!AlwaysRevocation
) {
1487 Time
= (EFI_TIME
*)(&SignatureData
->SignatureData
+ mHash
[HashAlg
].DigestLength
);
1488 Time
->Year
= RevocationDate
->Year
;
1489 Time
->Month
= RevocationDate
->Month
;
1490 Time
->Day
= RevocationDate
->Day
;
1491 Time
->Hour
= RevocationTime
->Hour
;
1492 Time
->Minute
= RevocationTime
->Minute
;
1493 Time
->Second
= RevocationTime
->Second
;
1497 // Determine the GUID for certificate hash.
1500 case HASHALG_SHA256
:
1501 SignatureType
= gEfiCertX509Sha256Guid
;
1503 case HASHALG_SHA384
:
1504 SignatureType
= gEfiCertX509Sha384Guid
;
1506 case HASHALG_SHA512
:
1507 SignatureType
= gEfiCertX509Sha512Guid
;
1514 // Add signature into the new variable data buffer
1516 if (GetSignaturelistOffset((EFI_SIGNATURE_LIST
*)Data
, DataSize
, &SignatureType
, &Offset
)) {
1518 // Add the signature to the found signaturelist.
1520 DbSize
= DataSize
+ SignatureSize
;
1521 NewData
= AllocateZeroPool (DbSize
);
1522 if (NewData
== NULL
) {
1523 Status
= EFI_OUT_OF_RESOURCES
;
1527 SignatureList
= (EFI_SIGNATURE_LIST
*)(Data
+ Offset
);
1528 SignatureListSize
= (UINTN
) ReadUnaligned32 ((UINT32
*)&SignatureList
->SignatureListSize
);
1529 CopyMem (NewData
, Data
, Offset
+ SignatureListSize
);
1531 SignatureList
= (EFI_SIGNATURE_LIST
*)(NewData
+ Offset
);
1532 WriteUnaligned32 ((UINT32
*) &SignatureList
->SignatureListSize
, (UINT32
)(SignatureListSize
+ SignatureSize
));
1534 Offset
+= SignatureListSize
;
1535 CopyMem (NewData
+ Offset
, SignatureData
, SignatureSize
);
1536 CopyMem (NewData
+ Offset
+ SignatureSize
, Data
+ Offset
, DataSize
- Offset
);
1543 // Create a new signaturelist, and add the signature into the signaturelist.
1545 DbSize
= DataSize
+ sizeof(EFI_SIGNATURE_LIST
) + SignatureSize
;
1546 NewData
= AllocateZeroPool (DbSize
);
1547 if (NewData
== NULL
) {
1548 Status
= EFI_OUT_OF_RESOURCES
;
1552 // Fill Certificate Database parameters.
1554 SignatureList
= (EFI_SIGNATURE_LIST
*) (NewData
+ DataSize
);
1555 SignatureListSize
= sizeof(EFI_SIGNATURE_LIST
) + SignatureSize
;
1556 WriteUnaligned32 ((UINT32
*) &SignatureList
->SignatureListSize
, (UINT32
) SignatureListSize
);
1557 WriteUnaligned32 ((UINT32
*) &SignatureList
->SignatureSize
, (UINT32
) SignatureSize
);
1558 CopyGuid (&SignatureList
->SignatureType
, &SignatureType
);
1559 CopyMem ((UINT8
* ) SignatureList
+ sizeof (EFI_SIGNATURE_LIST
), SignatureData
, SignatureSize
);
1560 if ((DataSize
!= 0) && (Data
!= NULL
)) {
1561 CopyMem (NewData
, Data
, DataSize
);
1568 Status
= CreateTimeBasedPayload (&DataSize
, (UINT8
**) &Data
);
1569 if (EFI_ERROR (Status
)) {
1573 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
1574 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
1575 Status
= gRT
->SetVariable(
1576 EFI_IMAGE_SECURITY_DATABASE1
,
1577 &gEfiImageSecurityDatabaseGuid
,
1582 if (EFI_ERROR (Status
)) {
1588 CloseEnrolledFile(Private
->FileContext
);
1590 if (Private
->SignatureGUID
!= NULL
) {
1591 FreePool (Private
->SignatureGUID
);
1592 Private
->SignatureGUID
= NULL
;
1599 if (SignatureData
!= NULL
) {
1600 FreePool (SignatureData
);
1603 if (X509Data
!= NULL
) {
1604 FreePool (X509Data
);
1611 Check whether a certificate from a file exists in dbx.
1613 @param[in] PrivateData The module's private data.
1614 @param[in] VariableName Variable name of signature database, must be
1615 EFI_IMAGE_SECURITY_DATABASE1.
1617 @retval TRUE The X509 certificate is found in dbx successfully.
1618 @retval FALSE The X509 certificate is not found in dbx.
1622 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
1623 IN CHAR16
*VariableName
1632 // Read the certificate from file
1636 Status
= ReadFileContent (
1637 Private
->FileContext
->FHandle
,
1642 if (EFI_ERROR (Status
)) {
1647 // Check the raw certificate.
1650 if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1
, X509Data
, X509DataSize
)) {
1656 // Check the hash of certificate.
1658 if (IsCertHashFoundInDbx (X509Data
, X509DataSize
)) {
1664 if (X509Data
!= NULL
) {
1665 FreePool (X509Data
);
1672 Reads contents of a PE/COFF image in memory buffer.
1674 Caution: This function may receive untrusted input.
1675 PE/COFF image is external input, so this function will make sure the PE/COFF image content
1676 read is within the image buffer.
1678 @param FileHandle Pointer to the file handle to read the PE/COFF image.
1679 @param FileOffset Offset into the PE/COFF image to begin the read operation.
1680 @param ReadSize On input, the size in bytes of the requested read operation.
1681 On output, the number of bytes actually read.
1682 @param Buffer Output buffer that contains the data read from the PE/COFF image.
1684 @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
1688 SecureBootConfigImageRead (
1689 IN VOID
*FileHandle
,
1690 IN UINTN FileOffset
,
1691 IN OUT UINTN
*ReadSize
,
1697 if (FileHandle
== NULL
|| ReadSize
== NULL
|| Buffer
== NULL
) {
1698 return EFI_INVALID_PARAMETER
;
1701 if (MAX_ADDRESS
- FileOffset
< *ReadSize
) {
1702 return EFI_INVALID_PARAMETER
;
1705 EndPosition
= FileOffset
+ *ReadSize
;
1706 if (EndPosition
> mImageSize
) {
1707 *ReadSize
= (UINT32
)(mImageSize
- FileOffset
);
1710 if (FileOffset
>= mImageSize
) {
1714 CopyMem (Buffer
, (UINT8
*)((UINTN
) FileHandle
+ FileOffset
), *ReadSize
);
1720 Load PE/COFF image information into internal buffer and check its validity.
1722 @retval EFI_SUCCESS Successful
1723 @retval EFI_UNSUPPORTED Invalid PE/COFF file
1724 @retval EFI_ABORTED Serious error occurs, like file I/O error etc.
1732 EFI_IMAGE_DOS_HEADER
*DosHdr
;
1733 EFI_IMAGE_NT_HEADERS32
*NtHeader32
;
1734 EFI_IMAGE_NT_HEADERS64
*NtHeader64
;
1735 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1741 ZeroMem (&ImageContext
, sizeof (ImageContext
));
1742 ImageContext
.Handle
= (VOID
*) mImageBase
;
1743 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) SecureBootConfigImageRead
;
1746 // Get information about the image being loaded
1748 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1749 if (EFI_ERROR (Status
)) {
1751 // The information can't be got from the invalid PeImage
1753 DEBUG ((DEBUG_INFO
, "SecureBootConfigDxe: PeImage invalid. \n"));
1758 // Read the Dos header
1760 DosHdr
= (EFI_IMAGE_DOS_HEADER
*)(mImageBase
);
1761 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
)
1764 // DOS image header is present,
1765 // So read the PE header after the DOS image header
1767 mPeCoffHeaderOffset
= DosHdr
->e_lfanew
;
1771 mPeCoffHeaderOffset
= 0;
1775 // Read PE header and check the signature validity and machine compatibility
1777 NtHeader32
= (EFI_IMAGE_NT_HEADERS32
*) (mImageBase
+ mPeCoffHeaderOffset
);
1778 if (NtHeader32
->Signature
!= EFI_IMAGE_NT_SIGNATURE
)
1780 return EFI_UNSUPPORTED
;
1783 mNtHeader
.Pe32
= NtHeader32
;
1786 // Check the architecture field of PE header and get the Certificate Data Directory data
1787 // Note the size of FileHeader field is constant for both IA32 and X64 arch
1789 if ((NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA32
)
1790 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_EBC
)
1791 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_ARMTHUMB_MIXED
)) {
1793 // 32-bits Architecture
1795 mImageType
= ImageType_IA32
;
1796 mSecDataDir
= (EFI_IMAGE_SECURITY_DATA_DIRECTORY
*) &(NtHeader32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]);
1798 else if ((NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA64
)
1799 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_X64
)
1800 || (NtHeader32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_AARCH64
)) {
1802 // 64-bits Architecture
1804 mImageType
= ImageType_X64
;
1805 NtHeader64
= (EFI_IMAGE_NT_HEADERS64
*) (mImageBase
+ mPeCoffHeaderOffset
);
1806 mSecDataDir
= (EFI_IMAGE_SECURITY_DATA_DIRECTORY
*) &(NtHeader64
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]);
1808 return EFI_UNSUPPORTED
;
1815 Calculate hash of Pe/Coff image based on the authenticode image hashing in
1816 PE/COFF Specification 8.0 Appendix A
1818 Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in
1819 the function LoadPeImage ().
1821 @param[in] HashAlg Hash algorithm type.
1823 @retval TRUE Successfully hash image.
1824 @retval FALSE Fail in hash image.
1834 EFI_IMAGE_SECTION_HEADER
*Section
;
1839 UINTN SumOfBytesHashed
;
1840 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1845 SectionHeader
= NULL
;
1848 if (HashAlg
!= HASHALG_SHA256
) {
1853 // Initialize context of hash.
1855 ZeroMem (mImageDigest
, MAX_DIGEST_SIZE
);
1857 mImageDigestSize
= SHA256_DIGEST_SIZE
;
1858 mCertType
= gEfiCertSha256Guid
;
1860 CtxSize
= mHash
[HashAlg
].GetContextSize();
1862 HashCtx
= AllocatePool (CtxSize
);
1863 ASSERT (HashCtx
!= NULL
);
1865 // 1. Load the image header into memory.
1867 // 2. Initialize a SHA hash context.
1868 Status
= mHash
[HashAlg
].HashInit(HashCtx
);
1873 // Measuring PE/COFF Image Header;
1874 // But CheckSum field and SECURITY data directory (certificate) are excluded
1876 if (mNtHeader
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& mNtHeader
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1878 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
1879 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
1880 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
1881 // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
1883 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
1886 // Get the magic value from the PE/COFF Optional Header
1888 Magic
= mNtHeader
.Pe32
->OptionalHeader
.Magic
;
1892 // 3. Calculate the distance from the base of the image header to the image checksum address.
1893 // 4. Hash the image header from its base to beginning of the image checksum.
1895 HashBase
= mImageBase
;
1896 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1900 HashSize
= (UINTN
) (&mNtHeader
.Pe32
->OptionalHeader
.CheckSum
) - (UINTN
) HashBase
;
1903 // Use PE32+ offset.
1905 HashSize
= (UINTN
) (&mNtHeader
.Pe32Plus
->OptionalHeader
.CheckSum
) - (UINTN
) HashBase
;
1908 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
1913 // 5. Skip over the image checksum (it occupies a single ULONG).
1914 // 6. Get the address of the beginning of the Cert Directory.
1915 // 7. Hash everything from the end of the checksum to the start of the Cert Directory.
1917 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1921 HashBase
= (UINT8
*) &mNtHeader
.Pe32
->OptionalHeader
.CheckSum
+ sizeof (UINT32
);
1922 HashSize
= (UINTN
) (&mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]) - (UINTN
) HashBase
;
1925 // Use PE32+ offset.
1927 HashBase
= (UINT8
*) &mNtHeader
.Pe32Plus
->OptionalHeader
.CheckSum
+ sizeof (UINT32
);
1928 HashSize
= (UINTN
) (&mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
]) - (UINTN
) HashBase
;
1931 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
1936 // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
1937 // 9. Hash everything from the end of the Cert Directory to the end of image header.
1939 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1943 HashBase
= (UINT8
*) &mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1];
1944 HashSize
= mNtHeader
.Pe32
->OptionalHeader
.SizeOfHeaders
- ((UINTN
) (&mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1]) - (UINTN
) mImageBase
);
1947 // Use PE32+ offset.
1949 HashBase
= (UINT8
*) &mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1];
1950 HashSize
= mNtHeader
.Pe32Plus
->OptionalHeader
.SizeOfHeaders
- ((UINTN
) (&mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
+ 1]) - (UINTN
) mImageBase
);
1953 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
1958 // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.
1960 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1964 SumOfBytesHashed
= mNtHeader
.Pe32
->OptionalHeader
.SizeOfHeaders
;
1969 SumOfBytesHashed
= mNtHeader
.Pe32Plus
->OptionalHeader
.SizeOfHeaders
;
1973 // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
1974 // structures in the image. The 'NumberOfSections' field of the image
1975 // header indicates how big the table should be. Do not include any
1976 // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
1978 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER
) * mNtHeader
.Pe32
->FileHeader
.NumberOfSections
);
1979 ASSERT (SectionHeader
!= NULL
);
1981 // 12. Using the 'PointerToRawData' in the referenced section headers as
1982 // a key, arrange the elements in the table in ascending order. In other
1983 // words, sort the section headers according to the disk-file offset of
1986 Section
= (EFI_IMAGE_SECTION_HEADER
*) (
1988 mPeCoffHeaderOffset
+
1990 sizeof (EFI_IMAGE_FILE_HEADER
) +
1991 mNtHeader
.Pe32
->FileHeader
.SizeOfOptionalHeader
1993 for (Index
= 0; Index
< mNtHeader
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
1995 while ((Pos
> 0) && (Section
->PointerToRawData
< SectionHeader
[Pos
- 1].PointerToRawData
)) {
1996 CopyMem (&SectionHeader
[Pos
], &SectionHeader
[Pos
- 1], sizeof (EFI_IMAGE_SECTION_HEADER
));
1999 CopyMem (&SectionHeader
[Pos
], Section
, sizeof (EFI_IMAGE_SECTION_HEADER
));
2004 // 13. Walk through the sorted table, bring the corresponding section
2005 // into memory, and hash the entire section (using the 'SizeOfRawData'
2006 // field in the section header to determine the amount of data to hash).
2007 // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
2008 // 15. Repeat steps 13 and 14 for all the sections in the sorted table.
2010 for (Index
= 0; Index
< mNtHeader
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
2011 Section
= &SectionHeader
[Index
];
2012 if (Section
->SizeOfRawData
== 0) {
2015 HashBase
= mImageBase
+ Section
->PointerToRawData
;
2016 HashSize
= (UINTN
) Section
->SizeOfRawData
;
2018 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
2023 SumOfBytesHashed
+= HashSize
;
2027 // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
2028 // data in the file that needs to be added to the hash. This data begins
2029 // at file offset SUM_OF_BYTES_HASHED and its length is:
2030 // FileSize - (CertDirectory->Size)
2032 if (mImageSize
> SumOfBytesHashed
) {
2033 HashBase
= mImageBase
+ SumOfBytesHashed
;
2034 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
2040 mNtHeader
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
].Size
-
2044 // Use PE32+ offset.
2048 mNtHeader
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
].Size
-
2052 Status
= mHash
[HashAlg
].HashUpdate(HashCtx
, HashBase
, HashSize
);
2058 Status
= mHash
[HashAlg
].HashFinal(HashCtx
, mImageDigest
);
2061 if (HashCtx
!= NULL
) {
2064 if (SectionHeader
!= NULL
) {
2065 FreePool (SectionHeader
);
2071 Recognize the Hash algorithm in PE/COFF Authenticode and calculate hash of
2072 Pe/Coff image based on the authenticated image hashing in PE/COFF Specification
2075 @retval EFI_UNSUPPORTED Hash algorithm is not supported.
2076 @retval EFI_SUCCESS Hash successfully.
2085 WIN_CERTIFICATE_EFI_PKCS
*PkcsCertData
;
2087 PkcsCertData
= (WIN_CERTIFICATE_EFI_PKCS
*) (mImageBase
+ mSecDataDir
->Offset
);
2089 for (Index
= 0; Index
< HASHALG_MAX
; Index
++) {
2091 // Check the Hash algorithm in PE/COFF Authenticode.
2092 // According to PKCS#7 Definition:
2093 // SignedData ::= SEQUENCE {
2095 // digestAlgorithms DigestAlgorithmIdentifiers,
2096 // contentInfo ContentInfo,
2098 // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
2099 // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
2100 // Fixed offset (+32) is calculated based on two bytes of length encoding.
2102 if ((*(PkcsCertData
->CertData
+ 1) & TWO_BYTE_ENCODE
) != TWO_BYTE_ENCODE
) {
2104 // Only support two bytes of Long Form of Length Encoding.
2110 if (CompareMem (PkcsCertData
->CertData
+ 32, mHash
[Index
].OidValue
, mHash
[Index
].OidLength
) == 0) {
2115 if (Index
== HASHALG_MAX
) {
2116 return EFI_UNSUPPORTED
;
2120 // HASH PE Image based on Hash algorithm in PE/COFF Authenticode.
2122 if (!HashPeImage(Index
)) {
2123 return EFI_UNSUPPORTED
;
2130 Enroll a new executable's signature into Signature Database.
2132 @param[in] PrivateData The module's private data.
2133 @param[in] VariableName Variable name of signature database, must be
2134 EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
2135 or EFI_IMAGE_SECURITY_DATABASE2.
2137 @retval EFI_SUCCESS New signature is enrolled successfully.
2138 @retval EFI_INVALID_PARAMETER The parameter is invalid.
2139 @retval EFI_UNSUPPORTED Unsupported command.
2140 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2144 EnrollAuthentication2Descriptor (
2145 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
2146 IN CHAR16
*VariableName
2157 // DBT only support DER-X509 Cert Enrollment
2159 if (StrCmp (VariableName
, EFI_IMAGE_SECURITY_DATABASE2
) == 0) {
2160 return EFI_UNSUPPORTED
;
2164 // Read the whole file content
2166 Status
= ReadFileContent(
2167 Private
->FileContext
->FHandle
,
2168 (VOID
**) &mImageBase
,
2172 if (EFI_ERROR (Status
)) {
2175 ASSERT (mImageBase
!= NULL
);
2177 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
2178 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
2181 // Check if SigDB variable has been already existed.
2182 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
2183 // new signature data to original variable
2186 Status
= gRT
->GetVariable(
2188 &gEfiImageSecurityDatabaseGuid
,
2193 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2194 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
2195 } else if (Status
!= EFI_NOT_FOUND
) {
2200 // Diretly set AUTHENTICATION_2 data to SetVariable
2202 Status
= gRT
->SetVariable(
2204 &gEfiImageSecurityDatabaseGuid
,
2210 DEBUG((DEBUG_INFO
, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName
, Status
));
2214 CloseEnrolledFile(Private
->FileContext
);
2220 if (mImageBase
!= NULL
) {
2221 FreePool (mImageBase
);
2231 Enroll a new executable's signature into Signature Database.
2233 @param[in] PrivateData The module's private data.
2234 @param[in] VariableName Variable name of signature database, must be
2235 EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
2236 or EFI_IMAGE_SECURITY_DATABASE2.
2238 @retval EFI_SUCCESS New signature is enrolled successfully.
2239 @retval EFI_INVALID_PARAMETER The parameter is invalid.
2240 @retval EFI_UNSUPPORTED Unsupported command.
2241 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2245 EnrollImageSignatureToSigDB (
2246 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
2247 IN CHAR16
*VariableName
2251 EFI_SIGNATURE_LIST
*SigDBCert
;
2252 EFI_SIGNATURE_DATA
*SigDBCertData
;
2257 WIN_CERTIFICATE_UEFI_GUID
*GuidCertData
;
2260 GuidCertData
= NULL
;
2262 if (StrCmp (VariableName
, EFI_IMAGE_SECURITY_DATABASE2
) == 0) {
2263 return EFI_UNSUPPORTED
;
2267 // Form the SigDB certificate list.
2268 // Format the data item into EFI_SIGNATURE_LIST type.
2270 // We need to parse executable's signature data from specified signed executable file.
2271 // In current implementation, we simply trust the pass-in signed executable file.
2272 // In reality, it's OS's responsibility to verify the signed executable file.
2276 // Read the whole file content
2278 Status
= ReadFileContent(
2279 Private
->FileContext
->FHandle
,
2280 (VOID
**) &mImageBase
,
2284 if (EFI_ERROR (Status
)) {
2287 ASSERT (mImageBase
!= NULL
);
2289 Status
= LoadPeImage ();
2290 if (EFI_ERROR (Status
)) {
2294 if (mSecDataDir
->SizeOfCert
== 0) {
2295 if (!HashPeImage (HASHALG_SHA256
)) {
2296 Status
= EFI_SECURITY_VIOLATION
;
2302 // Read the certificate data
2304 mCertificate
= (WIN_CERTIFICATE
*)(mImageBase
+ mSecDataDir
->Offset
);
2306 if (mCertificate
->wCertificateType
== WIN_CERT_TYPE_EFI_GUID
) {
2307 GuidCertData
= (WIN_CERTIFICATE_UEFI_GUID
*) mCertificate
;
2308 if (CompareMem (&GuidCertData
->CertType
, &gEfiCertTypeRsa2048Sha256Guid
, sizeof(EFI_GUID
)) != 0) {
2309 Status
= EFI_ABORTED
;
2313 if (!HashPeImage (HASHALG_SHA256
)) {
2314 Status
= EFI_ABORTED
;
2318 } else if (mCertificate
->wCertificateType
== WIN_CERT_TYPE_PKCS_SIGNED_DATA
) {
2320 Status
= HashPeImageByType ();
2321 if (EFI_ERROR (Status
)) {
2325 Status
= EFI_ABORTED
;
2331 // Create a new SigDB entry.
2333 SigDBSize
= sizeof(EFI_SIGNATURE_LIST
)
2334 + sizeof(EFI_SIGNATURE_DATA
) - 1
2335 + (UINT32
) mImageDigestSize
;
2337 Data
= (UINT8
*) AllocateZeroPool (SigDBSize
);
2339 Status
= EFI_OUT_OF_RESOURCES
;
2344 // Adjust the Certificate Database parameters.
2346 SigDBCert
= (EFI_SIGNATURE_LIST
*) Data
;
2347 SigDBCert
->SignatureListSize
= (UINT32
) SigDBSize
;
2348 SigDBCert
->SignatureHeaderSize
= 0;
2349 SigDBCert
->SignatureSize
= sizeof(EFI_SIGNATURE_DATA
) - 1 + (UINT32
) mImageDigestSize
;
2350 CopyGuid (&SigDBCert
->SignatureType
, &mCertType
);
2352 SigDBCertData
= (EFI_SIGNATURE_DATA
*)((UINT8
*)SigDBCert
+ sizeof(EFI_SIGNATURE_LIST
));
2353 CopyGuid (&SigDBCertData
->SignatureOwner
, Private
->SignatureGUID
);
2354 CopyMem (SigDBCertData
->SignatureData
, mImageDigest
, mImageDigestSize
);
2356 Attr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
2357 | EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
2358 Status
= CreateTimeBasedPayload (&SigDBSize
, (UINT8
**) &Data
);
2359 if (EFI_ERROR (Status
)) {
2360 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
2365 // Check if SigDB variable has been already existed.
2366 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
2367 // new signature data to original variable
2370 Status
= gRT
->GetVariable(
2372 &gEfiImageSecurityDatabaseGuid
,
2377 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2378 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
2379 } else if (Status
!= EFI_NOT_FOUND
) {
2384 // Enroll the variable.
2386 Status
= gRT
->SetVariable(
2388 &gEfiImageSecurityDatabaseGuid
,
2393 if (EFI_ERROR (Status
)) {
2399 CloseEnrolledFile(Private
->FileContext
);
2401 if (Private
->SignatureGUID
!= NULL
) {
2402 FreePool (Private
->SignatureGUID
);
2403 Private
->SignatureGUID
= NULL
;
2410 if (mImageBase
!= NULL
) {
2411 FreePool (mImageBase
);
2419 Enroll signature into DB/DBX/DBT without KEK's authentication.
2420 The SignatureOwner GUID will be Private->SignatureGUID.
2422 @param[in] PrivateData The module's private data.
2423 @param[in] VariableName Variable name of signature database, must be
2424 EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
2426 @retval EFI_SUCCESS New signature enrolled successfully.
2427 @retval EFI_INVALID_PARAMETER The parameter is invalid.
2428 @retval others Fail to enroll signature data.
2432 EnrollSignatureDatabase (
2433 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
2434 IN CHAR16
*VariableName
2437 UINT16
* FilePostFix
;
2441 if ((Private
->FileContext
->FileName
== NULL
) || (Private
->FileContext
->FHandle
== NULL
) || (Private
->SignatureGUID
== NULL
)) {
2442 return EFI_INVALID_PARAMETER
;
2445 Status
= SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE
);
2446 if (EFI_ERROR (Status
)) {
2451 // Parse the file's postfix.
2453 NameLength
= StrLen (Private
->FileContext
->FileName
);
2454 if (NameLength
<= 4) {
2455 return EFI_INVALID_PARAMETER
;
2457 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
2458 if (IsDerEncodeCertificate (FilePostFix
)) {
2460 // Supports DER-encoded X509 certificate.
2462 return EnrollX509toSigDB (Private
, VariableName
);
2463 } else if (IsAuthentication2Format(Private
->FileContext
->FHandle
)){
2464 return EnrollAuthentication2Descriptor(Private
, VariableName
);
2466 return EnrollImageSignatureToSigDB (Private
, VariableName
);
2471 List all signatures in specified signature database (e.g. KEK/DB/DBX/DBT)
2472 by GUID in the page for user to select and delete as needed.
2474 @param[in] PrivateData Module's private data.
2475 @param[in] VariableName The variable name of the vendor's signature database.
2476 @param[in] VendorGuid A unique identifier for the vendor.
2477 @param[in] LabelNumber Label number to insert opcodes.
2478 @param[in] FormId Form ID of current page.
2479 @param[in] QuestionIdBase Base question id of the signature list.
2481 @retval EFI_SUCCESS Success to update the signature list page
2482 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
2487 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
2488 IN CHAR16
*VariableName
,
2489 IN EFI_GUID
*VendorGuid
,
2490 IN UINT16 LabelNumber
,
2491 IN EFI_FORM_ID FormId
,
2492 IN EFI_QUESTION_ID QuestionIdBase
2499 VOID
*StartOpCodeHandle
;
2500 VOID
*EndOpCodeHandle
;
2501 EFI_IFR_GUID_LABEL
*StartLabel
;
2502 EFI_IFR_GUID_LABEL
*EndLabel
;
2505 EFI_SIGNATURE_LIST
*CertList
;
2506 EFI_SIGNATURE_DATA
*Cert
;
2507 UINT32 ItemDataSize
;
2509 EFI_STRING_ID GuidID
;
2516 StartOpCodeHandle
= NULL
;
2517 EndOpCodeHandle
= NULL
;
2520 // Initialize the container for dynamic opcodes.
2522 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
2523 if (StartOpCodeHandle
== NULL
) {
2524 Status
= EFI_OUT_OF_RESOURCES
;
2528 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
2529 if (EndOpCodeHandle
== NULL
) {
2530 Status
= EFI_OUT_OF_RESOURCES
;
2535 // Create Hii Extend Label OpCode.
2537 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2541 sizeof (EFI_IFR_GUID_LABEL
)
2543 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2544 StartLabel
->Number
= LabelNumber
;
2546 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
2550 sizeof (EFI_IFR_GUID_LABEL
)
2552 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
2553 EndLabel
->Number
= LABEL_END
;
2559 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, Data
);
2560 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
2564 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
2566 Status
= EFI_OUT_OF_RESOURCES
;
2570 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, Data
);
2571 if (EFI_ERROR (Status
)) {
2575 GuidStr
= AllocateZeroPool (100);
2576 if (GuidStr
== NULL
) {
2577 Status
= EFI_OUT_OF_RESOURCES
;
2582 // Enumerate all KEK pub data.
2584 ItemDataSize
= (UINT32
) DataSize
;
2585 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
2588 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
2590 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertRsa2048Guid
)) {
2591 Help
= STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID
);
2592 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
2593 Help
= STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID
);
2594 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertSha1Guid
)) {
2595 Help
= STRING_TOKEN (STR_CERT_TYPE_SHA1_GUID
);
2596 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertSha256Guid
)) {
2597 Help
= STRING_TOKEN (STR_CERT_TYPE_SHA256_GUID
);
2598 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
2599 Help
= STRING_TOKEN (STR_CERT_TYPE_X509_SHA256_GUID
);
2600 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
2601 Help
= STRING_TOKEN (STR_CERT_TYPE_X509_SHA384_GUID
);
2602 } else if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
2603 Help
= STRING_TOKEN (STR_CERT_TYPE_X509_SHA512_GUID
);
2606 // The signature type is not supported in current implementation.
2608 ItemDataSize
-= CertList
->SignatureListSize
;
2609 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2613 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2614 for (Index
= 0; Index
< CertCount
; Index
++) {
2615 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
2616 + sizeof (EFI_SIGNATURE_LIST
)
2617 + CertList
->SignatureHeaderSize
2618 + Index
* CertList
->SignatureSize
);
2620 // Display GUID and help
2622 GuidToString (&Cert
->SignatureOwner
, GuidStr
, 100);
2623 GuidID
= HiiSetString (PrivateData
->HiiHandle
, 0, GuidStr
, NULL
);
2624 HiiCreateCheckBoxOpCode (
2626 (EFI_QUESTION_ID
) (QuestionIdBase
+ GuidIndex
++),
2631 EFI_IFR_FLAG_CALLBACK
,
2637 ItemDataSize
-= CertList
->SignatureListSize
;
2638 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2643 PrivateData
->HiiHandle
,
2644 &gSecureBootConfigFormSetGuid
,
2650 if (StartOpCodeHandle
!= NULL
) {
2651 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2654 if (EndOpCodeHandle
!= NULL
) {
2655 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2662 if (GuidStr
!= NULL
) {
2670 Delete a KEK entry from KEK database.
2672 @param[in] PrivateData Module's private data.
2673 @param[in] QuestionId Question id of the KEK item to delete.
2675 @retval EFI_SUCCESS Delete kek item successfully.
2676 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2680 DeleteKeyExchangeKey (
2681 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
2682 IN EFI_QUESTION_ID QuestionId
2691 EFI_SIGNATURE_LIST
*CertList
;
2692 EFI_SIGNATURE_LIST
*NewCertList
;
2693 EFI_SIGNATURE_DATA
*Cert
;
2696 BOOLEAN IsKEKItemFound
;
2698 UINTN DeleteKekIndex
;
2706 DeleteKekIndex
= QuestionId
- OPTION_DEL_KEK_QUESTION_ID
;
2708 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
2709 if (EFI_ERROR (Status
)) {
2714 // Get original KEK variable.
2717 Status
= gRT
->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
, NULL
, &DataSize
, NULL
);
2718 if (EFI_ERROR(Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
2722 OldData
= (UINT8
*)AllocateZeroPool(DataSize
);
2723 if (OldData
== NULL
) {
2724 Status
= EFI_OUT_OF_RESOURCES
;
2728 Status
= gRT
->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
, &Attr
, &DataSize
, OldData
);
2729 if (EFI_ERROR(Status
)) {
2734 // Allocate space for new variable.
2736 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
2738 Status
= EFI_OUT_OF_RESOURCES
;
2743 // Enumerate all KEK pub data and erasing the target item.
2745 IsKEKItemFound
= FALSE
;
2746 KekDataSize
= (UINT32
) DataSize
;
2747 CertList
= (EFI_SIGNATURE_LIST
*) OldData
;
2750 while ((KekDataSize
> 0) && (KekDataSize
>= CertList
->SignatureListSize
)) {
2751 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertRsa2048Guid
) ||
2752 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
2753 CopyMem (Data
+ Offset
, CertList
, (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
));
2754 NewCertList
= (EFI_SIGNATURE_LIST
*)(Data
+ Offset
);
2755 Offset
+= (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2756 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2757 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2758 for (Index
= 0; Index
< CertCount
; Index
++) {
2759 if (GuidIndex
== DeleteKekIndex
) {
2761 // Find it! Skip it!
2763 NewCertList
->SignatureListSize
-= CertList
->SignatureSize
;
2764 IsKEKItemFound
= TRUE
;
2767 // This item doesn't match. Copy it to the Data buffer.
2769 CopyMem (Data
+ Offset
, Cert
, CertList
->SignatureSize
);
2770 Offset
+= CertList
->SignatureSize
;
2773 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
2777 // This List doesn't match. Copy it to the Data buffer.
2779 CopyMem (Data
+ Offset
, CertList
, CertList
->SignatureListSize
);
2780 Offset
+= CertList
->SignatureListSize
;
2783 KekDataSize
-= CertList
->SignatureListSize
;
2784 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2787 if (!IsKEKItemFound
) {
2789 // Doesn't find the Kek Item!
2791 Status
= EFI_NOT_FOUND
;
2796 // Delete the Signature header if there is no signature in the list.
2798 KekDataSize
= Offset
;
2799 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
2801 ZeroMem (OldData
, KekDataSize
);
2802 while ((KekDataSize
> 0) && (KekDataSize
>= CertList
->SignatureListSize
)) {
2803 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2804 DEBUG ((DEBUG_INFO
, " CertCount = %x\n", CertCount
));
2805 if (CertCount
!= 0) {
2806 CopyMem (OldData
+ Offset
, CertList
, CertList
->SignatureListSize
);
2807 Offset
+= CertList
->SignatureListSize
;
2809 KekDataSize
-= CertList
->SignatureListSize
;
2810 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2814 if ((Attr
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
2815 Status
= CreateTimeBasedPayload (&DataSize
, &OldData
);
2816 if (EFI_ERROR (Status
)) {
2817 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
2822 Status
= gRT
->SetVariable(
2823 EFI_KEY_EXCHANGE_KEY_NAME
,
2824 &gEfiGlobalVariableGuid
,
2829 if (EFI_ERROR (Status
)) {
2830 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r\n", Status
));
2839 if (OldData
!= NULL
) {
2843 return UpdateDeletePage (
2845 EFI_KEY_EXCHANGE_KEY_NAME
,
2846 &gEfiGlobalVariableGuid
,
2848 FORMID_DELETE_KEK_FORM
,
2849 OPTION_DEL_KEK_QUESTION_ID
2854 Delete a signature entry from signature database.
2856 @param[in] PrivateData Module's private data.
2857 @param[in] VariableName The variable name of the vendor's signature database.
2858 @param[in] VendorGuid A unique identifier for the vendor.
2859 @param[in] LabelNumber Label number to insert opcodes.
2860 @param[in] FormId Form ID of current page.
2861 @param[in] QuestionIdBase Base question id of the signature list.
2862 @param[in] DeleteIndex Signature index to delete.
2864 @retval EFI_SUCCESS Delete signature successfully.
2865 @retval EFI_NOT_FOUND Can't find the signature item,
2866 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
2870 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
2871 IN CHAR16
*VariableName
,
2872 IN EFI_GUID
*VendorGuid
,
2873 IN UINT16 LabelNumber
,
2874 IN EFI_FORM_ID FormId
,
2875 IN EFI_QUESTION_ID QuestionIdBase
,
2876 IN UINTN DeleteIndex
2885 EFI_SIGNATURE_LIST
*CertList
;
2886 EFI_SIGNATURE_LIST
*NewCertList
;
2887 EFI_SIGNATURE_DATA
*Cert
;
2890 BOOLEAN IsItemFound
;
2891 UINT32 ItemDataSize
;
2900 Status
= SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE
);
2901 if (EFI_ERROR (Status
)) {
2906 // Get original signature list data.
2909 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, NULL
);
2910 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
2914 OldData
= (UINT8
*) AllocateZeroPool (DataSize
);
2915 if (OldData
== NULL
) {
2916 Status
= EFI_OUT_OF_RESOURCES
;
2920 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, &Attr
, &DataSize
, OldData
);
2921 if (EFI_ERROR(Status
)) {
2926 // Allocate space for new variable.
2928 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
2930 Status
= EFI_OUT_OF_RESOURCES
;
2935 // Enumerate all signature data and erasing the target item.
2937 IsItemFound
= FALSE
;
2938 ItemDataSize
= (UINT32
) DataSize
;
2939 CertList
= (EFI_SIGNATURE_LIST
*) OldData
;
2942 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
2943 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertRsa2048Guid
) ||
2944 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
) ||
2945 CompareGuid (&CertList
->SignatureType
, &gEfiCertSha1Guid
) ||
2946 CompareGuid (&CertList
->SignatureType
, &gEfiCertSha256Guid
) ||
2947 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha256Guid
) ||
2948 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha384Guid
) ||
2949 CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Sha512Guid
)
2952 // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
2954 CopyMem (Data
+ Offset
, CertList
, (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
));
2955 NewCertList
= (EFI_SIGNATURE_LIST
*) (Data
+ Offset
);
2956 Offset
+= (sizeof(EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2957 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2958 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2959 for (Index
= 0; Index
< CertCount
; Index
++) {
2960 if (GuidIndex
== DeleteIndex
) {
2962 // Find it! Skip it!
2964 NewCertList
->SignatureListSize
-= CertList
->SignatureSize
;
2968 // This item doesn't match. Copy it to the Data buffer.
2970 CopyMem (Data
+ Offset
, (UINT8
*)(Cert
), CertList
->SignatureSize
);
2971 Offset
+= CertList
->SignatureSize
;
2974 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
2978 // This List doesn't match. Just copy it to the Data buffer.
2980 CopyMem (Data
+ Offset
, (UINT8
*)(CertList
), CertList
->SignatureListSize
);
2981 Offset
+= CertList
->SignatureListSize
;
2984 ItemDataSize
-= CertList
->SignatureListSize
;
2985 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2990 // Doesn't find the signature Item!
2992 Status
= EFI_NOT_FOUND
;
2997 // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
2999 ItemDataSize
= Offset
;
3000 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
3002 ZeroMem (OldData
, ItemDataSize
);
3003 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
3004 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
3005 DEBUG ((DEBUG_INFO
, " CertCount = %x\n", CertCount
));
3006 if (CertCount
!= 0) {
3007 CopyMem (OldData
+ Offset
, (UINT8
*)(CertList
), CertList
->SignatureListSize
);
3008 Offset
+= CertList
->SignatureListSize
;
3010 ItemDataSize
-= CertList
->SignatureListSize
;
3011 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
3015 if ((Attr
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
3016 Status
= CreateTimeBasedPayload (&DataSize
, &OldData
);
3017 if (EFI_ERROR (Status
)) {
3018 DEBUG ((EFI_D_ERROR
, "Fail to create time-based data payload: %r", Status
));
3023 Status
= gRT
->SetVariable(
3030 if (EFI_ERROR (Status
)) {
3031 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r\n", Status
));
3040 if (OldData
!= NULL
) {
3044 return UpdateDeletePage (
3055 This function to delete signature list or data, according by DelType.
3057 @param[in] PrivateData Module's private data.
3058 @param[in] DelType Indicate delete signature list or data.
3059 @param[in] CheckedCount Indicate how many signature data have
3060 been checked in current signature list.
3062 @retval EFI_SUCCESS Success to update the signature list page
3063 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
3067 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
3068 IN SIGNATURE_DELETE_TYPE DelType
,
3069 IN UINT32 CheckedCount
3073 EFI_SIGNATURE_LIST
*ListWalker
;
3074 EFI_SIGNATURE_LIST
*NewCertList
;
3075 EFI_SIGNATURE_DATA
*DataWalker
;
3076 CHAR16 VariableName
[BUFFER_MAX_SIZE
];
3077 UINT32 VariableAttr
;
3078 UINTN VariableDataSize
;
3079 UINTN RemainingSize
;
3083 UINT8
*VariableData
;
3084 UINT8
*NewVariableData
;
3086 Status
= EFI_SUCCESS
;
3088 VariableDataSize
= 0;
3091 VariableData
= NULL
;
3092 NewVariableData
= NULL
;
3094 if (PrivateData
->VariableName
== Variable_DB
) {
3095 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE
);
3096 } else if (PrivateData
->VariableName
== Variable_DBX
) {
3097 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE1
);
3098 } else if (PrivateData
->VariableName
== Variable_DBT
) {
3099 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE2
);
3104 Status
= gRT
->GetVariable (
3106 &gEfiImageSecurityDatabaseGuid
,
3111 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
3115 VariableData
= AllocateZeroPool (VariableDataSize
);
3116 if (VariableData
== NULL
) {
3117 Status
= EFI_OUT_OF_RESOURCES
;
3121 Status
= gRT
->GetVariable (
3123 &gEfiImageSecurityDatabaseGuid
,
3128 if (EFI_ERROR (Status
)) {
3132 Status
= SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE
);
3133 if (EFI_ERROR (Status
)) {
3137 NewVariableData
= AllocateZeroPool (VariableDataSize
);
3138 if (NewVariableData
== NULL
) {
3139 Status
= EFI_OUT_OF_RESOURCES
;
3143 RemainingSize
= VariableDataSize
;
3144 ListWalker
= (EFI_SIGNATURE_LIST
*)(VariableData
);
3145 if (DelType
== Delete_Signature_List_All
) {
3146 VariableDataSize
= 0;
3148 while ((RemainingSize
> 0) && (RemainingSize
>= ListWalker
->SignatureListSize
) && ListIndex
< PrivateData
->ListIndex
) {
3149 CopyMem ((UINT8
*)NewVariableData
+ Offset
, ListWalker
, ListWalker
->SignatureListSize
);
3150 Offset
+= ListWalker
->SignatureListSize
;
3152 RemainingSize
-= ListWalker
->SignatureListSize
;
3153 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
3157 if (CheckedCount
== SIGNATURE_DATA_COUNTS (ListWalker
) || DelType
== Delete_Signature_List_One
) {
3158 RemainingSize
-= ListWalker
->SignatureListSize
;
3159 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
3161 NewCertList
= (EFI_SIGNATURE_LIST
*)(NewVariableData
+ Offset
);
3165 CopyMem ((UINT8
*)NewVariableData
, ListWalker
, sizeof (EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
);
3166 Offset
+= sizeof (EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
;
3168 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)ListWalker
+ sizeof(EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
);
3169 for (Index
= 0; Index
< SIGNATURE_DATA_COUNTS(ListWalker
); Index
= Index
+ 1) {
3170 if (PrivateData
->CheckArray
[Index
]) {
3172 // Delete checked signature data, and update the size of whole signature list.
3174 NewCertList
->SignatureListSize
-= NewCertList
->SignatureSize
;
3177 // Remain the unchecked signature data.
3179 CopyMem ((UINT8
*)NewVariableData
+ Offset
, DataWalker
, ListWalker
->SignatureSize
);
3180 Offset
+= ListWalker
->SignatureSize
;
3182 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)DataWalker
+ ListWalker
->SignatureSize
);
3185 RemainingSize
-= ListWalker
->SignatureListSize
;
3189 // Copy remaining data, maybe 0.
3191 CopyMem((UINT8
*)NewVariableData
+ Offset
, ListWalker
, RemainingSize
);
3192 Offset
+= RemainingSize
;
3194 VariableDataSize
= Offset
;
3197 if ((VariableAttr
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
3198 Status
= CreateTimeBasedPayload (&VariableDataSize
, &NewVariableData
);
3199 if (EFI_ERROR (Status
)) {
3200 DEBUG ((DEBUG_ERROR
, "Fail to create time-based data payload: %r", Status
));
3205 Status
= gRT
->SetVariable (
3207 &gEfiImageSecurityDatabaseGuid
,
3212 if (EFI_ERROR (Status
)) {
3213 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r", Status
));
3218 SECUREBOOT_FREE_NON_NULL (VariableData
);
3219 SECUREBOOT_FREE_NON_NULL (NewVariableData
);
3226 Update SecureBoot strings based on new Secure Boot Mode State. String includes STR_SECURE_BOOT_STATE_CONTENT
3227 and STR_CUR_SECURE_BOOT_MODE_CONTENT.
3229 @param[in] PrivateData Module's private data.
3231 @return EFI_SUCCESS Update secure boot strings successfully.
3232 @return other Fail to update secure boot strings.
3236 UpdateSecureBootString(
3237 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
3245 // Get current secure boot state.
3247 GetVariable2 (EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&SecureBoot
, NULL
);
3248 if (SecureBoot
== NULL
) {
3249 return EFI_NOT_FOUND
;
3252 if (*SecureBoot
== SECURE_BOOT_MODE_ENABLE
) {
3253 HiiSetString (Private
->HiiHandle
, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT
), L
"Enabled", NULL
);
3255 HiiSetString (Private
->HiiHandle
, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT
), L
"Disabled", NULL
);
3258 FreePool(SecureBoot
);
3264 This function extracts configuration from variable.
3266 @param[in] Private Point to SecureBoot configuration driver private data.
3267 @param[in, out] ConfigData Point to SecureBoot configuration private data.
3271 SecureBootExtractConfigFromVariable (
3272 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
,
3273 IN OUT SECUREBOOT_CONFIGURATION
*ConfigData
3276 UINT8
*SecureBootEnable
;
3278 UINT8
*SecureBootMode
;
3281 SecureBootEnable
= NULL
;
3283 SecureBootMode
= NULL
;
3286 // Initilize the Date and Time using system time.
3288 ConfigData
->CertificateFormat
= HASHALG_RAW
;
3289 ConfigData
->AlwaysRevocation
= TRUE
;
3290 gRT
->GetTime (&CurrTime
, NULL
);
3291 ConfigData
->RevocationDate
.Year
= CurrTime
.Year
;
3292 ConfigData
->RevocationDate
.Month
= CurrTime
.Month
;
3293 ConfigData
->RevocationDate
.Day
= CurrTime
.Day
;
3294 ConfigData
->RevocationTime
.Hour
= CurrTime
.Hour
;
3295 ConfigData
->RevocationTime
.Minute
= CurrTime
.Minute
;
3296 ConfigData
->RevocationTime
.Second
= 0;
3297 if (Private
->FileContext
->FHandle
!= NULL
) {
3298 ConfigData
->FileEnrollType
= Private
->FileContext
->FileType
;
3300 ConfigData
->FileEnrollType
= UNKNOWN_FILE_TYPE
;
3304 // If it is Physical Presence User, set the PhysicalPresent to true.
3306 if (UserPhysicalPresent()) {
3307 ConfigData
->PhysicalPresent
= TRUE
;
3309 ConfigData
->PhysicalPresent
= FALSE
;
3313 // If there is no PK then the Delete Pk button will be gray.
3315 GetVariable2 (EFI_SETUP_MODE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&SetupMode
, NULL
);
3316 if (SetupMode
== NULL
|| (*SetupMode
) == SETUP_MODE
) {
3317 ConfigData
->HasPk
= FALSE
;
3319 ConfigData
->HasPk
= TRUE
;
3323 // Check SecureBootEnable & Pk status, fix the inconsistence.
3324 // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable
3327 ConfigData
->AttemptSecureBoot
= FALSE
;
3328 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME
, &gEfiSecureBootEnableDisableGuid
, (VOID
**)&SecureBootEnable
, NULL
);
3331 // Fix Pk, SecureBootEnable inconsistence
3333 if ((SetupMode
!= NULL
) && (*SetupMode
) == USER_MODE
) {
3334 ConfigData
->HideSecureBoot
= FALSE
;
3335 if ((SecureBootEnable
!= NULL
) && (*SecureBootEnable
== SECURE_BOOT_ENABLE
)) {
3336 ConfigData
->AttemptSecureBoot
= TRUE
;
3339 ConfigData
->HideSecureBoot
= TRUE
;
3343 // Get the SecureBootMode from CustomMode variable.
3345 GetVariable2 (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
, (VOID
**)&SecureBootMode
, NULL
);
3346 if (SecureBootMode
== NULL
) {
3347 ConfigData
->SecureBootMode
= STANDARD_SECURE_BOOT_MODE
;
3349 ConfigData
->SecureBootMode
= *(SecureBootMode
);
3352 if (SecureBootEnable
!= NULL
) {
3353 FreePool (SecureBootEnable
);
3355 if (SetupMode
!= NULL
) {
3356 FreePool (SetupMode
);
3358 if (SecureBootMode
!= NULL
) {
3359 FreePool (SecureBootMode
);
3364 This function allows a caller to extract the current configuration for one
3365 or more named elements from the target driver.
3367 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3368 @param[in] Request A null-terminated Unicode string in
3369 <ConfigRequest> format.
3370 @param[out] Progress On return, points to a character in the Request
3371 string. Points to the string's null terminator if
3372 request was successful. Points to the most recent
3373 '&' before the first failing name/value pair (or
3374 the beginning of the string if the failure is in
3375 the first name/value pair) if the request was not
3377 @param[out] Results A null-terminated Unicode string in
3378 <ConfigAltResp> format which has all values filled
3379 in for the names in the Request string. String to
3380 be allocated by the called function.
3382 @retval EFI_SUCCESS The Results is filled with the requested values.
3383 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
3384 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
3385 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
3391 SecureBootExtractConfig (
3392 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3393 IN CONST EFI_STRING Request
,
3394 OUT EFI_STRING
*Progress
,
3395 OUT EFI_STRING
*Results
3401 SECUREBOOT_CONFIGURATION Configuration
;
3402 EFI_STRING ConfigRequest
;
3403 EFI_STRING ConfigRequestHdr
;
3404 SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
;
3405 BOOLEAN AllocatedRequest
;
3407 if (Progress
== NULL
|| Results
== NULL
) {
3408 return EFI_INVALID_PARAMETER
;
3411 AllocatedRequest
= FALSE
;
3412 ConfigRequestHdr
= NULL
;
3413 ConfigRequest
= NULL
;
3416 ZeroMem (&Configuration
, sizeof (Configuration
));
3417 PrivateData
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
3418 *Progress
= Request
;
3420 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gSecureBootConfigFormSetGuid
, mSecureBootStorageName
)) {
3421 return EFI_NOT_FOUND
;
3424 ZeroMem(&Configuration
, sizeof(SECUREBOOT_CONFIGURATION
));
3427 // Get Configuration from Variable.
3429 SecureBootExtractConfigFromVariable (PrivateData
, &Configuration
);
3431 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
3432 ConfigRequest
= Request
;
3433 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
3435 // Request is set to NULL or OFFSET is NULL, construct full request string.
3437 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
3438 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
3440 ConfigRequestHdr
= HiiConstructConfigHdr (&gSecureBootConfigFormSetGuid
, mSecureBootStorageName
, PrivateData
->DriverHandle
);
3441 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
3442 ConfigRequest
= AllocateZeroPool (Size
);
3443 ASSERT (ConfigRequest
!= NULL
);
3444 AllocatedRequest
= TRUE
;
3445 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
3446 FreePool (ConfigRequestHdr
);
3447 ConfigRequestHdr
= NULL
;
3450 Status
= gHiiConfigRouting
->BlockToConfig (
3453 (UINT8
*) &Configuration
,
3460 // Free the allocated config request string.
3462 if (AllocatedRequest
) {
3463 FreePool (ConfigRequest
);
3467 // Set Progress string to the original request string.
3469 if (Request
== NULL
) {
3471 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
3472 *Progress
= Request
+ StrLen (Request
);
3479 This function processes the results of changes in configuration.
3481 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3482 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
3484 @param[out] Progress A pointer to a string filled in with the offset of
3485 the most recent '&' before the first failing
3486 name/value pair (or the beginning of the string if
3487 the failure is in the first name/value pair) or
3488 the terminating NULL if all was successful.
3490 @retval EFI_SUCCESS The Results is processed successfully.
3491 @retval EFI_INVALID_PARAMETER Configuration is NULL.
3492 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
3498 SecureBootRouteConfig (
3499 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3500 IN CONST EFI_STRING Configuration
,
3501 OUT EFI_STRING
*Progress
3504 SECUREBOOT_CONFIGURATION IfrNvData
;
3506 SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
;
3509 if (Configuration
== NULL
|| Progress
== NULL
) {
3510 return EFI_INVALID_PARAMETER
;
3513 *Progress
= Configuration
;
3514 if (!HiiIsConfigHdrMatch (Configuration
, &gSecureBootConfigFormSetGuid
, mSecureBootStorageName
)) {
3515 return EFI_NOT_FOUND
;
3518 PrivateData
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
3521 // Get Configuration from Variable.
3523 SecureBootExtractConfigFromVariable (PrivateData
, &IfrNvData
);
3526 // Map the Configuration to the configuration block.
3528 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
3529 Status
= gHiiConfigRouting
->ConfigToBlock (
3532 (UINT8
*)&IfrNvData
,
3536 if (EFI_ERROR (Status
)) {
3541 // Store Buffer Storage back to EFI variable if needed
3543 if (!IfrNvData
.HideSecureBoot
) {
3544 Status
= SaveSecureBootVariable (IfrNvData
.AttemptSecureBoot
);
3545 if (EFI_ERROR (Status
)) {
3550 *Progress
= Configuration
+ StrLen (Configuration
);
3555 This function to load signature list, the update the menu page.
3557 @param[in] PrivateData Module's private data.
3558 @param[in] LabelId Label number to insert opcodes.
3559 @param[in] FormId Form ID of current page.
3560 @param[in] QuestionIdBase Base question id of the signature list.
3562 @retval EFI_SUCCESS Success to update the signature list page
3563 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
3567 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
3569 IN EFI_FORM_ID FormId
,
3570 IN EFI_QUESTION_ID QuestionIdBase
3574 EFI_STRING_ID ListType
;
3575 EFI_STRING FormatNameString
;
3576 EFI_STRING FormatHelpString
;
3577 EFI_STRING FormatTypeString
;
3578 EFI_SIGNATURE_LIST
*ListWalker
;
3579 EFI_IFR_GUID_LABEL
*StartLabel
;
3580 EFI_IFR_GUID_LABEL
*EndLabel
;
3581 EFI_IFR_GUID_LABEL
*StartGoto
;
3582 EFI_IFR_GUID_LABEL
*EndGoto
;
3583 EFI_FORM_ID DstFormId
;
3584 VOID
*StartOpCodeHandle
;
3585 VOID
*EndOpCodeHandle
;
3586 VOID
*StartGotoHandle
;
3587 VOID
*EndGotoHandle
;
3589 UINTN RemainingSize
;
3591 UINT8
*VariableData
;
3592 CHAR16 VariableName
[BUFFER_MAX_SIZE
];
3593 CHAR16 NameBuffer
[BUFFER_MAX_SIZE
];
3594 CHAR16 HelpBuffer
[BUFFER_MAX_SIZE
];
3596 Status
= EFI_SUCCESS
;
3597 FormatNameString
= NULL
;
3598 FormatHelpString
= NULL
;
3599 StartOpCodeHandle
= NULL
;
3600 EndOpCodeHandle
= NULL
;
3601 StartGotoHandle
= NULL
;
3602 EndGotoHandle
= NULL
;
3604 VariableData
= NULL
;
3607 // Initialize the container for dynamic opcodes.
3609 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
3610 if (StartOpCodeHandle
== NULL
) {
3611 Status
= EFI_OUT_OF_RESOURCES
;
3615 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
3616 if (EndOpCodeHandle
== NULL
) {
3617 Status
= EFI_OUT_OF_RESOURCES
;
3621 StartGotoHandle
= HiiAllocateOpCodeHandle ();
3622 if (StartGotoHandle
== NULL
) {
3623 Status
= EFI_OUT_OF_RESOURCES
;
3627 EndGotoHandle
= HiiAllocateOpCodeHandle ();
3628 if (EndGotoHandle
== NULL
) {
3629 Status
= EFI_OUT_OF_RESOURCES
;
3634 // Create Hii Extend Label OpCode.
3636 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
3640 sizeof (EFI_IFR_GUID_LABEL
)
3642 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3643 StartLabel
->Number
= LabelId
;
3645 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
3649 sizeof (EFI_IFR_GUID_LABEL
)
3651 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3652 EndLabel
->Number
= LABEL_END
;
3654 StartGoto
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode(
3658 sizeof(EFI_IFR_GUID_LABEL
)
3660 StartGoto
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3661 StartGoto
->Number
= LABEL_DELETE_ALL_LIST_BUTTON
;
3663 EndGoto
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode(
3667 sizeof(EFI_IFR_GUID_LABEL
)
3669 EndGoto
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
3670 EndGoto
->Number
= LABEL_END
;
3672 if (PrivateData
->VariableName
== Variable_DB
) {
3673 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE
);
3674 DstFormId
= FORMID_SECURE_BOOT_DB_OPTION_FORM
;
3675 } else if (PrivateData
->VariableName
== Variable_DBX
) {
3676 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE1
);
3677 DstFormId
= FORMID_SECURE_BOOT_DBX_OPTION_FORM
;
3678 } else if (PrivateData
->VariableName
== Variable_DBT
) {
3679 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE2
);
3680 DstFormId
= FORMID_SECURE_BOOT_DBT_OPTION_FORM
;
3685 HiiCreateGotoOpCode (
3688 STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST
),
3689 STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST
),
3690 EFI_IFR_FLAG_CALLBACK
,
3691 KEY_SECURE_BOOT_DELETE_ALL_LIST
3695 // Read Variable, the variable name save in the PrivateData->VariableName.
3698 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
3699 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
3703 VariableData
= AllocateZeroPool (DataSize
);
3704 if (VariableData
== NULL
) {
3705 Status
= EFI_OUT_OF_RESOURCES
;
3708 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
3709 if (EFI_ERROR (Status
)) {
3713 FormatNameString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_LIST_NAME_FORMAT
), NULL
);
3714 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT
), NULL
);
3715 if (FormatNameString
== NULL
|| FormatHelpString
== NULL
) {
3719 RemainingSize
= DataSize
;
3720 ListWalker
= (EFI_SIGNATURE_LIST
*)VariableData
;
3721 while ((RemainingSize
> 0) && (RemainingSize
>= ListWalker
->SignatureListSize
)) {
3722 if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertRsa2048Guid
)) {
3723 ListType
= STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256
);
3724 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Guid
)) {
3725 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509
);
3726 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertSha1Guid
)) {
3727 ListType
= STRING_TOKEN (STR_LIST_TYPE_SHA1
);
3728 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertSha256Guid
)) {
3729 ListType
= STRING_TOKEN (STR_LIST_TYPE_SHA256
);
3730 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
3731 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509_SHA256
);
3732 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
3733 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509_SHA384
);
3734 } else if (CompareGuid (&ListWalker
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
3735 ListType
= STRING_TOKEN (STR_LIST_TYPE_X509_SHA512
);
3737 ListType
= STRING_TOKEN (STR_LIST_TYPE_UNKNOWN
);
3739 FormatTypeString
= HiiGetString (PrivateData
->HiiHandle
, ListType
, NULL
);
3740 if (FormatTypeString
== NULL
) {
3744 ZeroMem (NameBuffer
, sizeof (NameBuffer
));
3745 UnicodeSPrint (NameBuffer
, sizeof (NameBuffer
), FormatNameString
, Index
+ 1);
3747 ZeroMem (HelpBuffer
, sizeof (HelpBuffer
));
3748 UnicodeSPrint (HelpBuffer
,
3749 sizeof (HelpBuffer
),
3752 SIGNATURE_DATA_COUNTS (ListWalker
)
3754 SECUREBOOT_FREE_NON_NULL (FormatTypeString
);
3755 FormatTypeString
= NULL
;
3757 HiiCreateGotoOpCode (
3759 SECUREBOOT_DELETE_SIGNATURE_DATA_FORM
,
3760 HiiSetString (PrivateData
->HiiHandle
, 0, NameBuffer
, NULL
),
3761 HiiSetString (PrivateData
->HiiHandle
, 0, HelpBuffer
, NULL
),
3762 EFI_IFR_FLAG_CALLBACK
,
3763 QuestionIdBase
+ Index
++
3766 RemainingSize
-= ListWalker
->SignatureListSize
;
3767 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
3772 PrivateData
->HiiHandle
,
3773 &gSecureBootConfigFormSetGuid
,
3780 PrivateData
->HiiHandle
,
3781 &gSecureBootConfigFormSetGuid
,
3787 SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle
);
3788 SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle
);
3789 SECUREBOOT_FREE_NON_OPCODE (StartGotoHandle
);
3790 SECUREBOOT_FREE_NON_OPCODE (EndGotoHandle
);
3792 SECUREBOOT_FREE_NON_NULL (VariableData
);
3793 SECUREBOOT_FREE_NON_NULL (FormatNameString
);
3794 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
3796 PrivateData
->ListCount
= Index
;
3802 Parse hash value from EFI_SIGNATURE_DATA, and save in the CHAR16 type array.
3803 The buffer is callee allocated and should be freed by the caller.
3805 @param[in] ListEntry The pointer point to the signature list.
3806 @param[in] DataEntry The signature data we are processing.
3807 @param[out] BufferToReturn Buffer to save the hash value.
3809 @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
3810 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
3811 @retval EFI_SUCCESS Operation success.
3815 IN EFI_SIGNATURE_LIST
*ListEntry
,
3816 IN EFI_SIGNATURE_DATA
*DataEntry
,
3817 OUT CHAR16
**BufferToReturn
3828 // Assume that, display 8 bytes in one line.
3832 if (ListEntry
== NULL
|| DataEntry
== NULL
|| BufferToReturn
== NULL
) {
3833 return EFI_INVALID_PARAMETER
;
3836 DataSize
= ListEntry
->SignatureSize
- sizeof(EFI_GUID
);
3837 Line
= (DataSize
+ OneLineBytes
- 1) / OneLineBytes
;
3840 // Each byte will split two Hex-number, and each line need additional memory to save '\r\n'.
3842 TotalSize
= ((DataSize
+ Line
) * 2 * sizeof(CHAR16
));
3844 *BufferToReturn
= AllocateZeroPool(TotalSize
);
3845 if (*BufferToReturn
== NULL
) {
3846 return EFI_OUT_OF_RESOURCES
;
3849 for (Index
= 0, BufferIndex
= 0; Index
< DataSize
; Index
= Index
+ 1) {
3850 if ((Index
> 0) && (Index
% OneLineBytes
== 0)) {
3851 BufferIndex
+= UnicodeSPrint(&(*BufferToReturn
)[BufferIndex
], TotalSize
- sizeof(CHAR16
) * BufferIndex
, L
"\n");
3853 BufferIndex
+= UnicodeSPrint(&(*BufferToReturn
)[BufferIndex
], TotalSize
- sizeof(CHAR16
) * BufferIndex
, L
"%02x", DataEntry
->SignatureData
[Index
]);
3855 BufferIndex
+= UnicodeSPrint(&(*BufferToReturn
)[BufferIndex
], TotalSize
- sizeof(CHAR16
) * BufferIndex
, L
"\n");
3861 Function to get the common name from the X509 format certificate.
3862 The buffer is callee allocated and should be freed by the caller.
3864 @param[in] ListEntry The pointer point to the signature list.
3865 @param[in] DataEntry The signature data we are processing.
3866 @param[out] BufferToReturn Buffer to save the CN of X509 certificate.
3868 @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
3869 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
3870 @retval EFI_SUCCESS Operation success.
3871 @retval EFI_NOT_FOUND Not found CN field in the X509 certificate.
3874 GetCommonNameFromX509 (
3875 IN EFI_SIGNATURE_LIST
*ListEntry
,
3876 IN EFI_SIGNATURE_DATA
*DataEntry
,
3877 OUT CHAR16
**BufferToReturn
3884 Status
= EFI_SUCCESS
;
3887 CNBuffer
= AllocateZeroPool(256);
3888 if (CNBuffer
== NULL
) {
3889 Status
= EFI_OUT_OF_RESOURCES
;
3895 (UINT8
*)DataEntry
+ sizeof(EFI_GUID
),
3896 ListEntry
->SignatureSize
- sizeof(EFI_GUID
),
3901 *BufferToReturn
= AllocateZeroPool(256 * sizeof(CHAR16
));
3902 if (*BufferToReturn
== NULL
) {
3903 Status
= EFI_OUT_OF_RESOURCES
;
3907 AsciiStrToUnicodeStrS (CNBuffer
, *BufferToReturn
, 256);
3910 SECUREBOOT_FREE_NON_NULL (CNBuffer
);
3916 Format the help info for the signature data, each help info contain 3 parts.
3918 2. Content, depends on the type of the signature list.
3921 @param[in] PrivateData Module's private data.
3922 @param[in] ListEntry Point to the signature list.
3923 @param[in] DataEntry Point to the signature data we are processing.
3924 @param[out] StringId Save the string id of help info.
3926 @retval EFI_SUCCESS Operation success.
3927 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
3931 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
3932 IN EFI_SIGNATURE_LIST
*ListEntry
,
3933 IN EFI_SIGNATURE_DATA
*DataEntry
,
3934 OUT EFI_STRING_ID
*StringId
3939 EFI_STRING_ID ListTypeId
;
3940 EFI_STRING FormatHelpString
;
3941 EFI_STRING FormatTypeString
;
3943 UINTN HelpInfoIndex
;
3945 CHAR16 GuidString
[BUFFER_MAX_SIZE
];
3946 CHAR16 TimeString
[BUFFER_MAX_SIZE
];
3948 CHAR16
*HelpInfoString
;
3951 Status
= EFI_SUCCESS
;
3953 FormatTypeString
= NULL
;
3956 HelpInfoString
= NULL
;
3959 if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertRsa2048Guid
)) {
3960 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_RSA2048_SHA256
);
3961 DataSize
= ListEntry
->SignatureSize
- sizeof(EFI_GUID
);
3963 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Guid
)) {
3964 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509
);
3965 DataSize
= ListEntry
->SignatureSize
- sizeof(EFI_GUID
);
3967 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertSha1Guid
)) {
3968 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_SHA1
);
3970 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertSha256Guid
)) {
3971 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_SHA256
);
3973 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Sha256Guid
)) {
3974 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509_SHA256
);
3976 Time
= (EFI_TIME
*)(DataEntry
->SignatureData
+ DataSize
);
3977 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Sha384Guid
)) {
3978 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509_SHA384
);
3980 Time
= (EFI_TIME
*)(DataEntry
->SignatureData
+ DataSize
);
3981 } else if (CompareGuid(&ListEntry
->SignatureType
, &gEfiCertX509Sha512Guid
)) {
3982 ListTypeId
= STRING_TOKEN(STR_LIST_TYPE_X509_SHA512
);
3984 Time
= (EFI_TIME
*)(DataEntry
->SignatureData
+ DataSize
);
3986 Status
= EFI_UNSUPPORTED
;
3990 FormatTypeString
= HiiGetString (PrivateData
->HiiHandle
, ListTypeId
, NULL
);
3991 if (FormatTypeString
== NULL
) {
3996 HelpInfoString
= AllocateZeroPool (TotalSize
);
3997 if (HelpInfoString
== NULL
) {
3998 Status
= EFI_OUT_OF_RESOURCES
;
4003 // Format GUID part.
4005 ZeroMem (GuidString
, sizeof (GuidString
));
4006 GuidToString(&DataEntry
->SignatureOwner
, GuidString
, BUFFER_MAX_SIZE
);
4007 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID
), NULL
);
4008 if (FormatHelpString
== NULL
) {
4011 HelpInfoIndex
+= UnicodeSPrint (
4012 &HelpInfoString
[HelpInfoIndex
],
4013 TotalSize
- sizeof(CHAR16
) * HelpInfoIndex
,
4017 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
4018 FormatHelpString
= NULL
;
4021 // Format content part, it depends on the type of signature list, hash value or CN.
4024 GetCommonNameFromX509 (ListEntry
, DataEntry
, &DataString
);
4025 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_CN
), NULL
);
4028 // Format hash value for each signature data entry.
4030 ParseHashValue (ListEntry
, DataEntry
, &DataString
);
4031 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH
), NULL
);
4033 if (FormatHelpString
== NULL
) {
4036 HelpInfoIndex
+= UnicodeSPrint (
4037 &HelpInfoString
[HelpInfoIndex
],
4038 TotalSize
- sizeof (CHAR16
) * HelpInfoIndex
,
4044 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
4045 FormatHelpString
= NULL
;
4048 // Format revocation time part.
4051 ZeroMem (TimeString
, sizeof (TimeString
));
4054 sizeof (TimeString
),
4055 L
"%d-%d-%d %d:%d:%d",
4063 FormatHelpString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME
), NULL
);
4064 if (FormatHelpString
== NULL
) {
4068 &HelpInfoString
[HelpInfoIndex
],
4069 TotalSize
- sizeof (CHAR16
) * HelpInfoIndex
,
4073 SECUREBOOT_FREE_NON_NULL (FormatHelpString
);
4074 FormatHelpString
= NULL
;
4077 *StringId
= HiiSetString (PrivateData
->HiiHandle
, 0, HelpInfoString
, NULL
);
4079 SECUREBOOT_FREE_NON_NULL (DataString
);
4080 SECUREBOOT_FREE_NON_NULL (HelpInfoString
);
4082 SECUREBOOT_FREE_NON_NULL (FormatTypeString
);
4088 This functino to load signature data under the signature list.
4090 @param[in] PrivateData Module's private data.
4091 @param[in] LabelId Label number to insert opcodes.
4092 @param[in] FormId Form ID of current page.
4093 @param[in] QuestionIdBase Base question id of the signature list.
4094 @param[in] ListIndex Indicate to load which signature list.
4096 @retval EFI_SUCCESS Success to update the signature list page
4097 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
4101 IN SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
,
4103 IN EFI_FORM_ID FormId
,
4104 IN EFI_QUESTION_ID QuestionIdBase
,
4109 EFI_SIGNATURE_LIST
*ListWalker
;
4110 EFI_SIGNATURE_DATA
*DataWalker
;
4111 EFI_IFR_GUID_LABEL
*StartLabel
;
4112 EFI_IFR_GUID_LABEL
*EndLabel
;
4113 EFI_STRING_ID HelpStringId
;
4114 EFI_STRING FormatNameString
;
4115 VOID
*StartOpCodeHandle
;
4116 VOID
*EndOpCodeHandle
;
4118 UINTN RemainingSize
;
4120 UINT8
*VariableData
;
4121 CHAR16 VariableName
[BUFFER_MAX_SIZE
];
4122 CHAR16 NameBuffer
[BUFFER_MAX_SIZE
];
4124 Status
= EFI_SUCCESS
;
4125 FormatNameString
= NULL
;
4126 StartOpCodeHandle
= NULL
;
4127 EndOpCodeHandle
= NULL
;
4129 VariableData
= NULL
;
4132 // Initialize the container for dynamic opcodes.
4134 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
4135 if (StartOpCodeHandle
== NULL
) {
4136 Status
= EFI_OUT_OF_RESOURCES
;
4140 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
4141 if (EndOpCodeHandle
== NULL
) {
4142 Status
= EFI_OUT_OF_RESOURCES
;
4147 // Create Hii Extend Label OpCode.
4149 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
4153 sizeof (EFI_IFR_GUID_LABEL
)
4155 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4156 StartLabel
->Number
= LabelId
;
4158 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
4162 sizeof (EFI_IFR_GUID_LABEL
)
4164 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4165 EndLabel
->Number
= LABEL_END
;
4167 if (PrivateData
->VariableName
== Variable_DB
) {
4168 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE
);
4169 } else if (PrivateData
->VariableName
== Variable_DBX
) {
4170 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE1
);
4171 } else if (PrivateData
->VariableName
== Variable_DBT
) {
4172 UnicodeSPrint (VariableName
, sizeof (VariableName
), EFI_IMAGE_SECURITY_DATABASE2
);
4178 // Read Variable, the variable name save in the PrivateData->VariableName.
4181 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
4182 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
4186 VariableData
= AllocateZeroPool (DataSize
);
4187 if (VariableData
== NULL
) {
4188 Status
= EFI_OUT_OF_RESOURCES
;
4191 Status
= gRT
->GetVariable (VariableName
, &gEfiImageSecurityDatabaseGuid
, NULL
, &DataSize
, VariableData
);
4192 if (EFI_ERROR (Status
)) {
4196 RemainingSize
= DataSize
;
4197 ListWalker
= (EFI_SIGNATURE_LIST
*)VariableData
;
4200 // Skip signature list.
4202 while ((RemainingSize
> 0) && (RemainingSize
>= ListWalker
->SignatureListSize
) && ListIndex
-- > 0) {
4203 RemainingSize
-= ListWalker
->SignatureListSize
;
4204 ListWalker
= (EFI_SIGNATURE_LIST
*)((UINT8
*)ListWalker
+ ListWalker
->SignatureListSize
);
4207 FormatNameString
= HiiGetString (PrivateData
->HiiHandle
, STRING_TOKEN (STR_SIGNATURE_DATA_NAME_FORMAT
), NULL
);
4208 if (FormatNameString
== NULL
) {
4212 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)ListWalker
+ sizeof(EFI_SIGNATURE_LIST
) + ListWalker
->SignatureHeaderSize
);
4213 for (Index
= 0; Index
< SIGNATURE_DATA_COUNTS(ListWalker
); Index
= Index
+ 1) {
4215 // Format name buffer.
4217 ZeroMem (NameBuffer
, sizeof (NameBuffer
));
4218 UnicodeSPrint (NameBuffer
, sizeof (NameBuffer
), FormatNameString
, Index
+ 1);
4221 // Format help info buffer.
4223 Status
= FormatHelpInfo (PrivateData
, ListWalker
, DataWalker
, &HelpStringId
);
4224 if (EFI_ERROR (Status
)) {
4228 HiiCreateCheckBoxOpCode (
4230 (EFI_QUESTION_ID
)(QuestionIdBase
+ Index
),
4233 HiiSetString (PrivateData
->HiiHandle
, 0, NameBuffer
, NULL
),
4235 EFI_IFR_FLAG_CALLBACK
,
4240 ZeroMem(NameBuffer
, 100);
4241 DataWalker
= (EFI_SIGNATURE_DATA
*)((UINT8
*)DataWalker
+ ListWalker
->SignatureSize
);
4245 // Allocate a buffer to record which signature data will be checked.
4246 // This memory buffer will be freed when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
4248 PrivateData
->CheckArray
= AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker
) * sizeof (BOOLEAN
));
4251 PrivateData
->HiiHandle
,
4252 &gSecureBootConfigFormSetGuid
,
4258 SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle
);
4259 SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle
);
4261 SECUREBOOT_FREE_NON_NULL (VariableData
);
4262 SECUREBOOT_FREE_NON_NULL (FormatNameString
);
4268 This function is called to provide results data to the driver.
4270 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
4271 @param[in] Action Specifies the type of action taken by the browser.
4272 @param[in] QuestionId A unique value which is sent to the original
4273 exporting driver so that it can identify the type
4275 @param[in] Type The type of value for the question.
4276 @param[in] Value A pointer to the data being sent to the original
4278 @param[out] ActionRequest On return, points to the action requested by the
4281 @retval EFI_SUCCESS The callback successfully handled the action.
4282 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
4283 variable and its data.
4284 @retval EFI_DEVICE_ERROR The variable could not be saved.
4285 @retval EFI_UNSUPPORTED The specified Action is not supported by the
4291 SecureBootCallback (
4292 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
4293 IN EFI_BROWSER_ACTION Action
,
4294 IN EFI_QUESTION_ID QuestionId
,
4296 IN EFI_IFR_TYPE_VALUE
*Value
,
4297 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
4302 RETURN_STATUS RStatus
;
4303 SECUREBOOT_CONFIG_PRIVATE_DATA
*Private
;
4305 SECUREBOOT_CONFIGURATION
*IfrNvData
;
4307 UINT8
*SecureBootEnable
;
4309 UINT8
*SecureBootMode
;
4311 CHAR16 PromptString
[100];
4312 EFI_DEVICE_PATH_PROTOCOL
*File
;
4314 UINT16
*FilePostFix
;
4315 SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
;
4317 Status
= EFI_SUCCESS
;
4318 SecureBootEnable
= NULL
;
4319 SecureBootMode
= NULL
;
4323 if ((This
== NULL
) || (Value
== NULL
) || (ActionRequest
== NULL
)) {
4324 return EFI_INVALID_PARAMETER
;
4327 Private
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
4329 gSecureBootPrivateData
= Private
;
4332 // Retrieve uncommitted data from Browser
4334 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
4335 IfrNvData
= AllocateZeroPool (BufferSize
);
4336 if (IfrNvData
== NULL
) {
4337 return EFI_OUT_OF_RESOURCES
;
4340 HiiGetBrowserData (&gSecureBootConfigFormSetGuid
, mSecureBootStorageName
, BufferSize
, (UINT8
*) IfrNvData
);
4342 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
4343 if (QuestionId
== KEY_SECURE_BOOT_MODE
) {
4345 // Update secure boot strings when opening this form
4347 Status
= UpdateSecureBootString(Private
);
4348 SecureBootExtractConfigFromVariable (Private
, IfrNvData
);
4349 mIsEnterSecureBootForm
= TRUE
;
4352 // When entering SecureBoot OPTION Form
4353 // always close opened file & free resource
4355 if ((QuestionId
== KEY_SECURE_BOOT_PK_OPTION
) ||
4356 (QuestionId
== KEY_SECURE_BOOT_KEK_OPTION
) ||
4357 (QuestionId
== KEY_SECURE_BOOT_DB_OPTION
) ||
4358 (QuestionId
== KEY_SECURE_BOOT_DBX_OPTION
) ||
4359 (QuestionId
== KEY_SECURE_BOOT_DBT_OPTION
)) {
4360 CloseEnrolledFile(Private
->FileContext
);
4361 } else if (QuestionId
== KEY_SECURE_BOOT_DELETE_ALL_LIST
) {
4363 // Update ListCount field in varstore
4364 // Button "Delete All Signature List" is
4365 // enable when ListCount is greater than 0.
4367 IfrNvData
->ListCount
= Private
->ListCount
;
4373 if (Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
4374 Status
= EFI_UNSUPPORTED
;
4375 if (QuestionId
== KEY_SECURE_BOOT_MODE
) {
4376 if (mIsEnterSecureBootForm
) {
4377 Value
->u8
= SECURE_BOOT_MODE_STANDARD
;
4378 Status
= EFI_SUCCESS
;
4384 if ((Action
!= EFI_BROWSER_ACTION_CHANGED
) &&
4385 (Action
!= EFI_BROWSER_ACTION_CHANGING
) &&
4386 (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
) &&
4387 (Action
!= EFI_BROWSER_ACTION_DEFAULT_STANDARD
)) {
4388 Status
= EFI_UNSUPPORTED
;
4392 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
4394 switch (QuestionId
) {
4395 case KEY_SECURE_BOOT_ENABLE
:
4396 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME
, &gEfiSecureBootEnableDisableGuid
, (VOID
**)&SecureBootEnable
, NULL
);
4397 if (NULL
!= SecureBootEnable
) {
4398 FreePool (SecureBootEnable
);
4399 if (EFI_ERROR (SaveSecureBootVariable (Value
->u8
))) {
4401 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4403 L
"Only Physical Presence User could disable secure boot!",
4406 Status
= EFI_UNSUPPORTED
;
4409 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4411 L
"Configuration changed, please reset the platform to take effect!",
4418 case KEY_SECURE_BOOT_KEK_OPTION
:
4419 case KEY_SECURE_BOOT_DB_OPTION
:
4420 case KEY_SECURE_BOOT_DBX_OPTION
:
4421 case KEY_SECURE_BOOT_DBT_OPTION
:
4422 PrivateData
= SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This
);
4424 // Clear Signature GUID.
4426 ZeroMem (IfrNvData
->SignatureGuid
, sizeof (IfrNvData
->SignatureGuid
));
4427 if (Private
->SignatureGUID
== NULL
) {
4428 Private
->SignatureGUID
= (EFI_GUID
*) AllocateZeroPool (sizeof (EFI_GUID
));
4429 if (Private
->SignatureGUID
== NULL
) {
4430 return EFI_OUT_OF_RESOURCES
;
4435 // Cleanup VFRData once leaving PK/KEK/DB/DBX/DBT enroll/delete page
4437 SecureBootExtractConfigFromVariable (PrivateData
, IfrNvData
);
4439 if (QuestionId
== KEY_SECURE_BOOT_DB_OPTION
) {
4440 LabelId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DB
;
4441 } else if (QuestionId
== KEY_SECURE_BOOT_DBX_OPTION
) {
4442 LabelId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
;
4443 } else if (QuestionId
== KEY_SECURE_BOOT_DBT_OPTION
) {
4444 LabelId
= SECUREBOOT_ENROLL_SIGNATURE_TO_DBT
;
4446 LabelId
= FORMID_ENROLL_KEK_FORM
;
4450 // Refresh selected file.
4452 CleanUpPage (LabelId
, Private
);
4454 case KEY_SECURE_BOOT_PK_OPTION
:
4455 LabelId
= FORMID_ENROLL_PK_FORM
;
4457 // Refresh selected file.
4459 CleanUpPage (LabelId
, Private
);
4462 case FORMID_ENROLL_PK_FORM
:
4463 ChooseFile (NULL
, NULL
, UpdatePKFromFile
, &File
);
4466 case FORMID_ENROLL_KEK_FORM
:
4467 ChooseFile (NULL
, NULL
, UpdateKEKFromFile
, &File
);
4470 case SECUREBOOT_ENROLL_SIGNATURE_TO_DB
:
4471 ChooseFile (NULL
, NULL
, UpdateDBFromFile
, &File
);
4474 case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX
:
4475 ChooseFile (NULL
, NULL
, UpdateDBXFromFile
, &File
);
4477 if (Private
->FileContext
->FHandle
!= NULL
) {
4479 // Parse the file's postfix.
4481 NameLength
= StrLen (Private
->FileContext
->FileName
);
4482 if (NameLength
<= 4) {
4485 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
4487 if (IsDerEncodeCertificate (FilePostFix
)) {
4489 // Supports DER-encoded X509 certificate.
4491 IfrNvData
->FileEnrollType
= X509_CERT_FILE_TYPE
;
4492 } else if (IsAuthentication2Format(Private
->FileContext
->FHandle
)){
4493 IfrNvData
->FileEnrollType
= AUTHENTICATION_2_FILE_TYPE
;
4495 IfrNvData
->FileEnrollType
= PE_IMAGE_FILE_TYPE
;
4497 Private
->FileContext
->FileType
= IfrNvData
->FileEnrollType
;
4500 // Clean up Certificate Format if File type is not X509 DER
4502 if (IfrNvData
->FileEnrollType
!= X509_CERT_FILE_TYPE
) {
4503 IfrNvData
->CertificateFormat
= HASHALG_RAW
;
4505 DEBUG((DEBUG_ERROR
, "IfrNvData->FileEnrollType %d\n", Private
->FileContext
->FileType
));
4510 case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT
:
4511 ChooseFile (NULL
, NULL
, UpdateDBTFromFile
, &File
);
4514 case KEY_SECURE_BOOT_DELETE_PK
:
4517 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4519 L
"Are you sure you want to delete PK? Secure boot will be disabled!",
4520 L
"Press 'Y' to delete PK and exit, 'N' to discard change and return",
4523 if (Key
.UnicodeChar
== 'y' || Key
.UnicodeChar
== 'Y') {
4524 Status
= DeletePlatformKey ();
4525 if (EFI_ERROR (Status
)) {
4527 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4529 L
"Only Physical Presence User could delete PK in custom mode!",
4537 case KEY_DELETE_KEK
:
4540 EFI_KEY_EXCHANGE_KEY_NAME
,
4541 &gEfiGlobalVariableGuid
,
4543 FORMID_DELETE_KEK_FORM
,
4544 OPTION_DEL_KEK_QUESTION_ID
4548 case SECUREBOOT_DELETE_SIGNATURE_FROM_DB
:
4551 EFI_IMAGE_SECURITY_DATABASE
,
4552 &gEfiImageSecurityDatabaseGuid
,
4554 SECUREBOOT_DELETE_SIGNATURE_FROM_DB
,
4555 OPTION_DEL_DB_QUESTION_ID
4560 // From DBX option to the level-1 form, display signature list.
4562 case KEY_VALUE_FROM_DBX_TO_LIST_FORM
:
4563 Private
->VariableName
= Variable_DBX
;
4566 LABEL_SIGNATURE_LIST_START
,
4567 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4568 OPTION_SIGNATURE_LIST_QUESTION_ID
4573 // Delete all signature list and reload.
4575 case KEY_SECURE_BOOT_DELETE_ALL_LIST
:
4577 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4579 L
"Press 'Y' to delete signature list.",
4580 L
"Press other key to cancel and exit.",
4584 if (Key
.UnicodeChar
== L
'Y' || Key
.UnicodeChar
== L
'y') {
4585 DeleteSignatureEx (Private
, Delete_Signature_List_All
, IfrNvData
->CheckedDataCount
);
4590 LABEL_SIGNATURE_LIST_START
,
4591 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4592 OPTION_SIGNATURE_LIST_QUESTION_ID
4597 // Delete one signature list and reload.
4599 case KEY_SECURE_BOOT_DELETE_ALL_DATA
:
4601 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4603 L
"Press 'Y' to delete signature data.",
4604 L
"Press other key to cancel and exit.",
4608 if (Key
.UnicodeChar
== L
'Y' || Key
.UnicodeChar
== L
'y') {
4609 DeleteSignatureEx (Private
, Delete_Signature_List_One
, IfrNvData
->CheckedDataCount
);
4614 LABEL_SIGNATURE_LIST_START
,
4615 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4616 OPTION_SIGNATURE_LIST_QUESTION_ID
4621 // Delete checked signature data and reload.
4623 case KEY_SECURE_BOOT_DELETE_CHECK_DATA
:
4625 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4627 L
"Press 'Y' to delete signature data.",
4628 L
"Press other key to cancel and exit.",
4632 if (Key
.UnicodeChar
== L
'Y' || Key
.UnicodeChar
== L
'y') {
4633 DeleteSignatureEx (Private
, Delete_Signature_Data
, IfrNvData
->CheckedDataCount
);
4638 LABEL_SIGNATURE_LIST_START
,
4639 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM
,
4640 OPTION_SIGNATURE_LIST_QUESTION_ID
4644 case SECUREBOOT_DELETE_SIGNATURE_FROM_DBT
:
4647 EFI_IMAGE_SECURITY_DATABASE2
,
4648 &gEfiImageSecurityDatabaseGuid
,
4650 SECUREBOOT_DELETE_SIGNATURE_FROM_DBT
,
4651 OPTION_DEL_DBT_QUESTION_ID
4656 case KEY_VALUE_SAVE_AND_EXIT_KEK
:
4657 Status
= EnrollKeyExchangeKey (Private
);
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",
4669 case KEY_VALUE_SAVE_AND_EXIT_DB
:
4670 Status
= EnrollSignatureDatabase (Private
, EFI_IMAGE_SECURITY_DATABASE
);
4671 if (EFI_ERROR (Status
)) {
4673 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4675 L
"ERROR: Unsupported file type!",
4676 L
"Only supports DER-encoded X509 certificate and executable EFI image",
4682 case KEY_VALUE_SAVE_AND_EXIT_DBX
:
4683 if (IsX509CertInDbx (Private
, EFI_IMAGE_SECURITY_DATABASE1
)) {
4685 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4687 L
"Enrollment failed! Same certificate had already been in the dbx!",
4692 // Cert already exists in DBX. Close opened file before exit.
4694 CloseEnrolledFile(Private
->FileContext
);
4698 if ((IfrNvData
!= NULL
) && (IfrNvData
->CertificateFormat
< HASHALG_MAX
)) {
4699 Status
= EnrollX509HashtoSigDB (
4701 IfrNvData
->CertificateFormat
,
4702 &IfrNvData
->RevocationDate
,
4703 &IfrNvData
->RevocationTime
,
4704 IfrNvData
->AlwaysRevocation
4706 IfrNvData
->CertificateFormat
= HASHALG_RAW
;
4708 Status
= EnrollSignatureDatabase (Private
, EFI_IMAGE_SECURITY_DATABASE1
);
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, AUTH_2 format data & executable EFI image",
4721 case KEY_VALUE_SAVE_AND_EXIT_DBT
:
4722 Status
= EnrollSignatureDatabase (Private
, EFI_IMAGE_SECURITY_DATABASE2
);
4723 if (EFI_ERROR (Status
)) {
4725 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4727 L
"ERROR: Unsupported file type!",
4728 L
"Only supports DER-encoded X509 certificate.",
4733 case KEY_VALUE_SAVE_AND_EXIT_PK
:
4734 Status
= EnrollPlatformKey (Private
);
4735 if (EFI_ERROR (Status
)) {
4738 sizeof (PromptString
),
4739 L
"Only DER encoded certificate file (%s) is supported.",
4743 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
4745 L
"ERROR: Unsupported file type!",
4752 if ((QuestionId
>= OPTION_DEL_KEK_QUESTION_ID
) &&
4753 (QuestionId
< (OPTION_DEL_KEK_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4754 DeleteKeyExchangeKey (Private
, QuestionId
);
4755 } else if ((QuestionId
>= OPTION_DEL_DB_QUESTION_ID
) &&
4756 (QuestionId
< (OPTION_DEL_DB_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4759 EFI_IMAGE_SECURITY_DATABASE
,
4760 &gEfiImageSecurityDatabaseGuid
,
4762 SECUREBOOT_DELETE_SIGNATURE_FROM_DB
,
4763 OPTION_DEL_DB_QUESTION_ID
,
4764 QuestionId
- OPTION_DEL_DB_QUESTION_ID
4766 } else if ((QuestionId
>= OPTION_SIGNATURE_LIST_QUESTION_ID
) &&
4767 (QuestionId
< (OPTION_SIGNATURE_LIST_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4770 LABEL_SIGNATURE_DATA_START
,
4771 SECUREBOOT_DELETE_SIGNATURE_DATA_FORM
,
4772 OPTION_SIGNATURE_DATA_QUESTION_ID
,
4773 QuestionId
- OPTION_SIGNATURE_LIST_QUESTION_ID
4775 Private
->ListIndex
= QuestionId
- OPTION_SIGNATURE_LIST_QUESTION_ID
;
4776 } else if ((QuestionId
>= OPTION_SIGNATURE_DATA_QUESTION_ID
) &&
4777 (QuestionId
< (OPTION_SIGNATURE_DATA_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4778 if (Private
->CheckArray
[QuestionId
- OPTION_SIGNATURE_DATA_QUESTION_ID
]) {
4779 IfrNvData
->CheckedDataCount
--;
4780 Private
->CheckArray
[QuestionId
- OPTION_SIGNATURE_DATA_QUESTION_ID
] = FALSE
;
4782 IfrNvData
->CheckedDataCount
++;
4783 Private
->CheckArray
[QuestionId
- OPTION_SIGNATURE_DATA_QUESTION_ID
] = TRUE
;
4785 } else if ((QuestionId
>= OPTION_DEL_DBT_QUESTION_ID
) &&
4786 (QuestionId
< (OPTION_DEL_DBT_QUESTION_ID
+ OPTION_CONFIG_RANGE
))) {
4789 EFI_IMAGE_SECURITY_DATABASE2
,
4790 &gEfiImageSecurityDatabaseGuid
,
4792 SECUREBOOT_DELETE_SIGNATURE_FROM_DBT
,
4793 OPTION_DEL_DBT_QUESTION_ID
,
4794 QuestionId
- OPTION_DEL_DBT_QUESTION_ID
4799 case KEY_VALUE_NO_SAVE_AND_EXIT_PK
:
4800 case KEY_VALUE_NO_SAVE_AND_EXIT_KEK
:
4801 case KEY_VALUE_NO_SAVE_AND_EXIT_DB
:
4802 case KEY_VALUE_NO_SAVE_AND_EXIT_DBX
:
4803 case KEY_VALUE_NO_SAVE_AND_EXIT_DBT
:
4804 CloseEnrolledFile(Private
->FileContext
);
4806 if (Private
->SignatureGUID
!= NULL
) {
4807 FreePool (Private
->SignatureGUID
);
4808 Private
->SignatureGUID
= NULL
;
4812 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
4813 switch (QuestionId
) {
4814 case KEY_SECURE_BOOT_ENABLE
:
4815 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
4817 case KEY_SECURE_BOOT_MODE
:
4818 mIsEnterSecureBootForm
= FALSE
;
4820 case KEY_SECURE_BOOT_KEK_GUID
:
4821 case KEY_SECURE_BOOT_SIGNATURE_GUID_DB
:
4822 case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX
:
4823 case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT
:
4824 ASSERT (Private
->SignatureGUID
!= NULL
);
4825 RStatus
= StrToGuid (IfrNvData
->SignatureGuid
, Private
->SignatureGUID
);
4826 if (RETURN_ERROR (RStatus
) || (IfrNvData
->SignatureGuid
[GUID_STRING_LENGTH
] != L
'\0')) {
4827 Status
= EFI_INVALID_PARAMETER
;
4831 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
4833 case KEY_SECURE_BOOT_DELETE_PK
:
4834 GetVariable2 (EFI_SETUP_MODE_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&SetupMode
, NULL
);
4835 if (SetupMode
== NULL
|| (*SetupMode
) == SETUP_MODE
) {
4836 IfrNvData
->DeletePk
= TRUE
;
4837 IfrNvData
->HasPk
= FALSE
;
4838 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
4840 IfrNvData
->DeletePk
= FALSE
;
4841 IfrNvData
->HasPk
= TRUE
;
4842 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
4844 if (SetupMode
!= NULL
) {
4845 FreePool (SetupMode
);
4851 } else if (Action
== EFI_BROWSER_ACTION_DEFAULT_STANDARD
) {
4852 if (QuestionId
== KEY_HIDE_SECURE_BOOT
) {
4853 GetVariable2 (EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
, (VOID
**)&Pk
, NULL
);
4855 IfrNvData
->HideSecureBoot
= TRUE
;
4858 IfrNvData
->HideSecureBoot
= FALSE
;
4860 Value
->b
= IfrNvData
->HideSecureBoot
;
4862 } else if (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
) {
4864 // Force the platform back to Standard Mode once user leave the setup screen.
4866 GetVariable2 (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
, (VOID
**)&SecureBootMode
, NULL
);
4867 if (NULL
!= SecureBootMode
&& *SecureBootMode
== CUSTOM_SECURE_BOOT_MODE
) {
4868 IfrNvData
->SecureBootMode
= STANDARD_SECURE_BOOT_MODE
;
4869 SetSecureBootMode(STANDARD_SECURE_BOOT_MODE
);
4871 if (SecureBootMode
!= NULL
) {
4872 FreePool (SecureBootMode
);
4875 if (QuestionId
== KEY_SECURE_BOOT_DELETE_ALL_DATA
) {
4877 // Free memory when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
4879 SECUREBOOT_FREE_NON_NULL (Private
->CheckArray
);
4880 IfrNvData
->CheckedDataCount
= 0;
4886 if (!EFI_ERROR (Status
)) {
4887 BufferSize
= sizeof (SECUREBOOT_CONFIGURATION
);
4888 HiiSetBrowserData (&gSecureBootConfigFormSetGuid
, mSecureBootStorageName
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
4891 FreePool (IfrNvData
);
4902 This function publish the SecureBoot configuration Form.
4904 @param[in, out] PrivateData Points to SecureBoot configuration private data.
4906 @retval EFI_SUCCESS HII Form is installed successfully.
4907 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
4908 @retval Others Other errors as indicated.
4912 InstallSecureBootConfigForm (
4913 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
4917 EFI_HII_HANDLE HiiHandle
;
4918 EFI_HANDLE DriverHandle
;
4919 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
4921 DriverHandle
= NULL
;
4922 ConfigAccess
= &PrivateData
->ConfigAccess
;
4923 Status
= gBS
->InstallMultipleProtocolInterfaces (
4925 &gEfiDevicePathProtocolGuid
,
4926 &mSecureBootHiiVendorDevicePath
,
4927 &gEfiHiiConfigAccessProtocolGuid
,
4931 if (EFI_ERROR (Status
)) {
4935 PrivateData
->DriverHandle
= DriverHandle
;
4938 // Publish the HII package list
4940 HiiHandle
= HiiAddPackages (
4941 &gSecureBootConfigFormSetGuid
,
4943 SecureBootConfigDxeStrings
,
4944 SecureBootConfigBin
,
4947 if (HiiHandle
== NULL
) {
4948 gBS
->UninstallMultipleProtocolInterfaces (
4950 &gEfiDevicePathProtocolGuid
,
4951 &mSecureBootHiiVendorDevicePath
,
4952 &gEfiHiiConfigAccessProtocolGuid
,
4956 return EFI_OUT_OF_RESOURCES
;
4959 PrivateData
->HiiHandle
= HiiHandle
;
4961 PrivateData
->FileContext
= AllocateZeroPool (sizeof (SECUREBOOT_FILE_CONTEXT
));
4963 if (PrivateData
->FileContext
== NULL
) {
4964 UninstallSecureBootConfigForm (PrivateData
);
4965 return EFI_OUT_OF_RESOURCES
;
4969 // Init OpCode Handle and Allocate space for creation of Buffer
4971 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
4972 if (mStartOpCodeHandle
== NULL
) {
4973 UninstallSecureBootConfigForm (PrivateData
);
4974 return EFI_OUT_OF_RESOURCES
;
4977 mEndOpCodeHandle
= HiiAllocateOpCodeHandle ();
4978 if (mEndOpCodeHandle
== NULL
) {
4979 UninstallSecureBootConfigForm (PrivateData
);
4980 return EFI_OUT_OF_RESOURCES
;
4984 // Create Hii Extend Label OpCode as the start opcode
4986 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
4990 sizeof (EFI_IFR_GUID_LABEL
)
4992 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
4995 // Create Hii Extend Label OpCode as the end opcode
4997 mEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
5001 sizeof (EFI_IFR_GUID_LABEL
)
5003 mEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
5004 mEndLabel
->Number
= LABEL_END
;
5010 This function removes SecureBoot configuration Form.
5012 @param[in, out] PrivateData Points to SecureBoot configuration private data.
5016 UninstallSecureBootConfigForm (
5017 IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA
*PrivateData
5021 // Uninstall HII package list
5023 if (PrivateData
->HiiHandle
!= NULL
) {
5024 HiiRemovePackages (PrivateData
->HiiHandle
);
5025 PrivateData
->HiiHandle
= NULL
;
5029 // Uninstall HII Config Access Protocol
5031 if (PrivateData
->DriverHandle
!= NULL
) {
5032 gBS
->UninstallMultipleProtocolInterfaces (
5033 PrivateData
->DriverHandle
,
5034 &gEfiDevicePathProtocolGuid
,
5035 &mSecureBootHiiVendorDevicePath
,
5036 &gEfiHiiConfigAccessProtocolGuid
,
5037 &PrivateData
->ConfigAccess
,
5040 PrivateData
->DriverHandle
= NULL
;
5043 if (PrivateData
->SignatureGUID
!= NULL
) {
5044 FreePool (PrivateData
->SignatureGUID
);
5047 if (PrivateData
->FileContext
!= NULL
) {
5048 FreePool (PrivateData
->FileContext
);
5051 FreePool (PrivateData
);
5053 if (mStartOpCodeHandle
!= NULL
) {
5054 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
5057 if (mEndOpCodeHandle
!= NULL
) {
5058 HiiFreeOpCodeHandle (mEndOpCodeHandle
);