TianoCore EDK2 master
Loading...
Searching...
No Matches
SecureBootConfigImpl.c
Go to the documentation of this file.
1
11#include <UefiSecureBoot.h>
12#include <Protocol/HiiPopup.h>
17
18CHAR16 mSecureBootStorageName[] = L"SECUREBOOT_CONFIGURATION";
19
20SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate = {
21 SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE,
22 {
26 }
27};
28
29HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath = {
30 {
31 {
34 {
35 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
36 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
37 }
38 },
39 SECUREBOOT_CONFIG_FORM_SET_GUID
40 },
41 {
42 END_DEVICE_PATH_TYPE,
43 END_ENTIRE_DEVICE_PATH_SUBTYPE,
44 {
45 (UINT8)(END_DEVICE_PATH_LENGTH),
46 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
47 }
48 }
49};
50
51BOOLEAN mIsEnterSecureBootForm = FALSE;
52
53//
54// OID ASN.1 Value for Hash Algorithms
55//
56UINT8 mHashOidValue[] = {
57 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, // OBJ_md5
58 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJ_sha1
59 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224
60 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256
61 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384
62 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512
63};
64
65HASH_TABLE mHash[] = {
66 { L"SHA224", 28, &mHashOidValue[13], 9, NULL, NULL, NULL, NULL },
67 { L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final },
68 { L"SHA384", 48, &mHashOidValue[31], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final },
69 { L"SHA512", 64, &mHashOidValue[40], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final }
70};
71
72//
73// Variable Definitions
74//
75UINT32 mPeCoffHeaderOffset = 0;
76WIN_CERTIFICATE *mCertificate = NULL;
77IMAGE_TYPE mImageType;
78UINT8 *mImageBase = NULL;
79UINTN mImageSize = 0;
80UINT8 mImageDigest[MAX_DIGEST_SIZE];
81UINTN mImageDigestSize;
82EFI_GUID mCertType;
85
86//
87// Possible DER-encoded certificate file suffixes, end with NULL pointer.
88//
89CHAR16 *mDerEncodedSuffix[] = {
90 L".cer",
91 L".der",
92 L".crt",
93 NULL
94};
95CHAR16 *mSupportX509Suffix = L"*.cer/der/crt";
96
97//
98// Prompt strings during certificate enrollment.
99//
100CHAR16 *mX509EnrollPromptTitle[] = {
101 L"",
102 L"ERROR: Unsupported file type!",
103 L"ERROR: Unsupported certificate!",
104 NULL
105};
106CHAR16 *mX509EnrollPromptString[] = {
107 L"",
108 L"Only DER encoded certificate file (*.cer/der/crt) is supported.",
109 L"Public key length should be equal to or greater than 2048 bits.",
110 NULL
111};
112
113SECUREBOOT_CONFIG_PRIVATE_DATA *gSecureBootPrivateData = NULL;
114
122VOID
124 IN SECUREBOOT_FILE_CONTEXT *FileContext
125 )
126{
127 if (FileContext->FHandle != NULL) {
128 CloseFile (FileContext->FHandle);
129 FileContext->FHandle = NULL;
130 }
131
132 if (FileContext->FileName != NULL) {
133 FreePool (FileContext->FileName);
134 FileContext->FileName = NULL;
135 }
136
137 FileContext->FileType = UNKNOWN_FILE_TYPE;
138}
139
146STATIC
149 IN EFI_TIME *Time
150 )
151{
152 EFI_STATUS Status;
153 VOID *TestPointer;
154
155 if (Time == NULL) {
156 return EFI_INVALID_PARAMETER;
157 }
158
159 Status = gBS->LocateProtocol (&gEfiRealTimeClockArchProtocolGuid, NULL, &TestPointer);
160 if (EFI_ERROR (Status)) {
161 return Status;
162 }
163
164 ZeroMem (Time, sizeof (EFI_TIME));
165 Status = gRT->GetTime (Time, NULL);
166 if (EFI_ERROR (Status)) {
167 DEBUG ((
168 DEBUG_ERROR,
169 "%a(), GetTime() failed, status = '%r'\n",
170 __func__,
171 Status
172 ));
173 return Status;
174 }
175
176 Time->Pad1 = 0;
177 Time->Nanosecond = 0;
178 Time->TimeZone = 0;
179 Time->Daylight = 0;
180 Time->Pad2 = 0;
181
182 return EFI_SUCCESS;
183}
184
194BOOLEAN
196 IN CONST CHAR16 *FileSuffix
197 )
198{
199 UINTN Index;
200
201 for (Index = 0; mDerEncodedSuffix[Index] != NULL; Index++) {
202 if (StrCmp (FileSuffix, mDerEncodedSuffix[Index]) == 0) {
203 return TRUE;
204 }
205 }
206
207 return FALSE;
208}
209
220BOOLEAN
222 IN EFI_FILE_HANDLE FileHandle
223 )
224{
225 EFI_STATUS Status;
227 BOOLEAN IsAuth2Format;
228
229 IsAuth2Format = FALSE;
230
231 //
232 // Read the whole file content
233 //
234 Status = ReadFileContent (
235 FileHandle,
236 (VOID **)&mImageBase,
237 &mImageSize,
238 0
239 );
240 if (EFI_ERROR (Status)) {
241 goto ON_EXIT;
242 }
243
244 Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)mImageBase;
245 if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {
246 goto ON_EXIT;
247 }
248
249 if (CompareGuid (&gEfiCertPkcs7Guid, &Auth2->AuthInfo.CertType)) {
250 IsAuth2Format = TRUE;
251 }
252
253ON_EXIT:
254 //
255 // Do not close File. simply check file content
256 //
257 if (mImageBase != NULL) {
258 FreePool (mImageBase);
259 mImageBase = NULL;
260 }
261
262 return IsAuth2Format;
263}
264
276 IN UINT8 VarValue
277 )
278{
279 EFI_STATUS Status;
280
281 Status = gRT->SetVariable (
283 &gEfiSecureBootEnableDisableGuid,
284 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
285 sizeof (UINT8),
286 &VarValue
287 );
288 return Status;
289}
290
306 IN SECUREBOOT_FILE_CONTEXT *X509FileContext,
307 OUT ENROLL_KEY_ERROR *Error
308 )
309{
310 EFI_STATUS Status;
311 UINT16 *FilePostFix;
312 UINTN NameLength;
313 UINT8 *X509Data;
314 UINTN X509DataSize;
315 void *X509PubKey;
316 UINTN PubKeyModSize;
317
318 if (X509FileContext->FileName == NULL) {
319 *Error = Unsupported_Type;
320 return EFI_INVALID_PARAMETER;
321 }
322
323 X509Data = NULL;
324 X509DataSize = 0;
325 X509PubKey = NULL;
326 PubKeyModSize = 0;
327
328 //
329 // Parse the file's postfix. Only support DER encoded X.509 certificate files.
330 //
331 NameLength = StrLen (X509FileContext->FileName);
332 if (NameLength <= 4) {
333 DEBUG ((DEBUG_ERROR, "Wrong X509 NameLength\n"));
334 *Error = Unsupported_Type;
335 return EFI_INVALID_PARAMETER;
336 }
337
338 FilePostFix = X509FileContext->FileName + NameLength - 4;
339 if (!IsDerEncodeCertificate (FilePostFix)) {
340 DEBUG ((DEBUG_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.\n", mSupportX509Suffix));
341 *Error = Unsupported_Type;
342 return EFI_INVALID_PARAMETER;
343 }
344
345 DEBUG ((DEBUG_INFO, "FileName= %s\n", X509FileContext->FileName));
346 DEBUG ((DEBUG_INFO, "FilePostFix = %s\n", FilePostFix));
347
348 //
349 // Read the certificate file content
350 //
351 Status = ReadFileContent (X509FileContext->FHandle, (VOID **)&X509Data, &X509DataSize, 0);
352 if (EFI_ERROR (Status)) {
353 DEBUG ((DEBUG_ERROR, "Error occured while reading the file.\n"));
354 goto ON_EXIT;
355 }
356
357 //
358 // Parse the public key context.
359 //
360 if (RsaGetPublicKeyFromX509 (X509Data, X509DataSize, &X509PubKey) == FALSE) {
361 DEBUG ((DEBUG_ERROR, "Error occured while parsing the pubkey from certificate.\n"));
362 Status = EFI_INVALID_PARAMETER;
363 *Error = Unsupported_Type;
364 goto ON_EXIT;
365 }
366
367 //
368 // Parse Module size of public key using interface provided by CryptoPkg, which is
369 // actually the size of public key.
370 //
371 if (X509PubKey != NULL) {
372 RsaGetKey (X509PubKey, RsaKeyN, NULL, &PubKeyModSize);
373 if (PubKeyModSize < CER_PUBKEY_MIN_SIZE) {
374 DEBUG ((DEBUG_ERROR, "Unqualified PK size, key size should be equal to or greater than 2048 bits.\n"));
375 Status = EFI_INVALID_PARAMETER;
376 *Error = Unqualified_Key;
377 }
378
379 RsaFree (X509PubKey);
380 }
381
382ON_EXIT:
383 if (X509Data != NULL) {
384 FreePool (X509Data);
385 }
386
387 return Status;
388}
389
402 IN EFI_FILE_HANDLE X509File,
403 OUT EFI_SIGNATURE_LIST **PkCert
404 )
405{
406 EFI_STATUS Status;
407 UINT8 *X509Data;
408 UINTN X509DataSize;
409 EFI_SIGNATURE_DATA *PkCertData;
410
411 X509Data = NULL;
412 PkCertData = NULL;
413 X509DataSize = 0;
414
415 Status = ReadFileContent (X509File, (VOID **)&X509Data, &X509DataSize, 0);
416 if (EFI_ERROR (Status)) {
417 goto ON_EXIT;
418 }
419
420 ASSERT (X509Data != NULL);
421
422 //
423 // Allocate space for PK certificate list and initialize it.
424 // Create PK database entry with SignatureHeaderSize equals 0.
425 //
427 sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1
428 + X509DataSize
429 );
430 if (*PkCert == NULL) {
431 Status = EFI_OUT_OF_RESOURCES;
432 goto ON_EXIT;
433 }
434
435 (*PkCert)->SignatureListSize = (UINT32)(sizeof (EFI_SIGNATURE_LIST)
436 + sizeof (EFI_SIGNATURE_DATA) - 1
437 + X509DataSize);
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);
445 //
446 // Fill the PK database with PKpub data from X509 certificate file.
447 //
448 CopyMem (&(PkCertData->SignatureData[0]), X509Data, X509DataSize);
449
450ON_EXIT:
451
452 if (X509Data != NULL) {
453 FreePool (X509Data);
454 }
455
456 if (EFI_ERROR (Status) && (*PkCert != NULL)) {
457 FreePool (*PkCert);
458 *PkCert = NULL;
459 }
460
461 return Status;
462}
463
479 )
480{
481 EFI_STATUS Status;
482 UINT32 Attr;
483 UINTN DataSize;
484 EFI_SIGNATURE_LIST *PkCert;
485 EFI_TIME Time;
486
487 PkCert = NULL;
488
489 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
490 if (EFI_ERROR (Status)) {
491 return Status;
492 }
493
494 //
495 // Prase the selected PK file and generate PK certificate list.
496 //
498 Private->FileContext->FHandle,
499 &PkCert
500 );
501 if (EFI_ERROR (Status)) {
502 goto ON_EXIT;
503 }
504
505 ASSERT (PkCert != NULL);
506
507 //
508 // Set Platform Key variable.
509 //
510 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
511 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
512 DataSize = PkCert->SignatureListSize;
513 Status = GetCurrentTime (&Time);
514 if (EFI_ERROR (Status)) {
515 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
516 goto ON_EXIT;
517 }
518
519 Status = CreateTimeBasedPayload (&DataSize, (UINT8 **)&PkCert, &Time);
520 if (EFI_ERROR (Status)) {
521 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
522 goto ON_EXIT;
523 }
524
525 Status = gRT->SetVariable (
527 &gEfiGlobalVariableGuid,
528 Attr,
529 DataSize,
530 PkCert
531 );
532 if (EFI_ERROR (Status)) {
533 if (Status == EFI_OUT_OF_RESOURCES) {
534 DEBUG ((DEBUG_ERROR, "Enroll PK failed with out of resource.\n"));
535 }
536
537 goto ON_EXIT;
538 }
539
540ON_EXIT:
541
542 if (PkCert != NULL) {
543 FreePool (PkCert);
544 }
545
546 CloseEnrolledFile (Private->FileContext);
547
548 return Status;
549}
550
565 )
566{
567 EFI_STATUS Status;
568 UINT32 Attr;
569 UINTN DataSize;
570 EFI_SIGNATURE_LIST *KekSigList;
571 UINTN KeyBlobSize;
572 UINT8 *KeyBlob;
573 CPL_KEY_INFO *KeyInfo;
574 EFI_SIGNATURE_DATA *KEKSigData;
575 UINTN KekSigListSize;
576 UINT8 *KeyBuffer;
577 UINTN KeyLenInBytes;
578 EFI_TIME Time;
579
580 Attr = 0;
581 DataSize = 0;
582 KeyBuffer = NULL;
583 KeyBlobSize = 0;
584 KeyBlob = NULL;
585 KeyInfo = NULL;
586 KEKSigData = NULL;
587 KekSigList = NULL;
588 KekSigListSize = 0;
589
590 //
591 // Form the KeKpub certificate list into EFI_SIGNATURE_LIST type.
592 // First, We have to parse out public key data from the pbk key file.
593 //
594 Status = ReadFileContent (
595 Private->FileContext->FHandle,
596 (VOID **)&KeyBlob,
597 &KeyBlobSize,
598 0
599 );
600 if (EFI_ERROR (Status)) {
601 goto ON_EXIT;
602 }
603
604 ASSERT (KeyBlob != NULL);
605 KeyInfo = (CPL_KEY_INFO *)KeyBlob;
606 if (KeyInfo->KeyLengthInBits / 8 != WIN_CERT_UEFI_RSA2048_SIZE) {
607 DEBUG ((DEBUG_ERROR, "Unsupported key length, Only RSA2048 is supported.\n"));
608 Status = EFI_UNSUPPORTED;
609 goto ON_EXIT;
610 }
611
612 //
613 // Convert the Public key to fix octet string format represented in RSA PKCS#1.
614 //
615 KeyLenInBytes = KeyInfo->KeyLengthInBits / 8;
616 KeyBuffer = AllocateZeroPool (KeyLenInBytes);
617 if (KeyBuffer == NULL) {
618 Status = EFI_OUT_OF_RESOURCES;
619 goto ON_EXIT;
620 }
621
622 Int2OctStr (
623 (UINTN *)(KeyBlob + sizeof (CPL_KEY_INFO)),
624 KeyLenInBytes / sizeof (UINTN),
625 KeyBuffer,
626 KeyLenInBytes
627 );
628 CopyMem (KeyBlob + sizeof (CPL_KEY_INFO), KeyBuffer, KeyLenInBytes);
629
630 //
631 // Form an new EFI_SIGNATURE_LIST.
632 //
633 KekSigListSize = sizeof (EFI_SIGNATURE_LIST)
634 + sizeof (EFI_SIGNATURE_DATA) - 1
635 + WIN_CERT_UEFI_RSA2048_SIZE;
636
637 KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
638 if (KekSigList == NULL) {
639 Status = EFI_OUT_OF_RESOURCES;
640 goto ON_EXIT;
641 }
642
643 KekSigList->SignatureListSize = sizeof (EFI_SIGNATURE_LIST)
644 + sizeof (EFI_SIGNATURE_DATA) - 1
645 + WIN_CERT_UEFI_RSA2048_SIZE;
646 KekSigList->SignatureHeaderSize = 0;
647 KekSigList->SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + WIN_CERT_UEFI_RSA2048_SIZE;
648 CopyGuid (&KekSigList->SignatureType, &gEfiCertRsa2048Guid);
649
650 KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
651 CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
652 CopyMem (
653 KEKSigData->SignatureData,
654 KeyBlob + sizeof (CPL_KEY_INFO),
655 WIN_CERT_UEFI_RSA2048_SIZE
656 );
657
658 //
659 // Check if KEK entry has been already existed.
660 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
661 // new KEK to original variable.
662 //
663 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
664 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
665 Status = GetCurrentTime (&Time);
666 if (EFI_ERROR (Status)) {
667 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
668 goto ON_EXIT;
669 }
670
671 Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **)&KekSigList, &Time);
672 if (EFI_ERROR (Status)) {
673 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
674 goto ON_EXIT;
675 }
676
677 Status = gRT->GetVariable (
679 &gEfiGlobalVariableGuid,
680 NULL,
681 &DataSize,
682 NULL
683 );
684 if (Status == EFI_BUFFER_TOO_SMALL) {
685 Attr |= EFI_VARIABLE_APPEND_WRITE;
686 } else if (Status != EFI_NOT_FOUND) {
687 goto ON_EXIT;
688 }
689
690 //
691 // Done. Now we have formed the correct KEKpub database item, just set it into variable storage,
692 //
693 Status = gRT->SetVariable (
695 &gEfiGlobalVariableGuid,
696 Attr,
697 KekSigListSize,
698 KekSigList
699 );
700 if (EFI_ERROR (Status)) {
701 goto ON_EXIT;
702 }
703
704ON_EXIT:
705
706 CloseEnrolledFile (Private->FileContext);
707
708 if (Private->SignatureGUID != NULL) {
709 FreePool (Private->SignatureGUID);
710 Private->SignatureGUID = NULL;
711 }
712
713 if (KeyBlob != NULL) {
714 FreePool (KeyBlob);
715 }
716
717 if (KeyBuffer != NULL) {
718 FreePool (KeyBuffer);
719 }
720
721 if (KekSigList != NULL) {
722 FreePool (KekSigList);
723 }
724
725 return Status;
726}
727
742 )
743{
744 EFI_STATUS Status;
745 UINTN X509DataSize;
746 VOID *X509Data;
747 EFI_SIGNATURE_DATA *KEKSigData;
748 EFI_SIGNATURE_LIST *KekSigList;
749 UINTN DataSize;
750 UINTN KekSigListSize;
751 UINT32 Attr;
752 EFI_TIME Time;
753
754 X509Data = NULL;
755 X509DataSize = 0;
756 KekSigList = NULL;
757 KekSigListSize = 0;
758 DataSize = 0;
759 KEKSigData = NULL;
760
761 Status = ReadFileContent (
762 Private->FileContext->FHandle,
763 &X509Data,
764 &X509DataSize,
765 0
766 );
767 if (EFI_ERROR (Status)) {
768 goto ON_EXIT;
769 }
770
771 ASSERT (X509Data != NULL);
772
773 KekSigListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
774 KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
775 if (KekSigList == NULL) {
776 Status = EFI_OUT_OF_RESOURCES;
777 goto ON_EXIT;
778 }
779
780 //
781 // Fill Certificate Database parameters.
782 //
783 KekSigList->SignatureListSize = (UINT32)KekSigListSize;
784 KekSigList->SignatureHeaderSize = 0;
785 KekSigList->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
786 CopyGuid (&KekSigList->SignatureType, &gEfiCertX509Guid);
787
788 KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
789 CopyGuid (&KEKSigData->SignatureOwner, Private->SignatureGUID);
790 CopyMem (KEKSigData->SignatureData, X509Data, X509DataSize);
791
792 //
793 // Check if KEK been already existed.
794 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
795 // new kek to original variable
796 //
797 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
798 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
799 Status = GetCurrentTime (&Time);
800 if (EFI_ERROR (Status)) {
801 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
802 goto ON_EXIT;
803 }
804
805 Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **)&KekSigList, &Time);
806 if (EFI_ERROR (Status)) {
807 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
808 goto ON_EXIT;
809 }
810
811 Status = gRT->GetVariable (
813 &gEfiGlobalVariableGuid,
814 NULL,
815 &DataSize,
816 NULL
817 );
818 if (Status == EFI_BUFFER_TOO_SMALL) {
819 Attr |= EFI_VARIABLE_APPEND_WRITE;
820 } else if (Status != EFI_NOT_FOUND) {
821 goto ON_EXIT;
822 }
823
824 Status = gRT->SetVariable (
826 &gEfiGlobalVariableGuid,
827 Attr,
828 KekSigListSize,
829 KekSigList
830 );
831 if (EFI_ERROR (Status)) {
832 goto ON_EXIT;
833 }
834
835ON_EXIT:
836
837 CloseEnrolledFile (Private->FileContext);
838
839 if (Private->SignatureGUID != NULL) {
840 FreePool (Private->SignatureGUID);
841 Private->SignatureGUID = NULL;
842 }
843
844 if (KekSigList != NULL) {
845 FreePool (KekSigList);
846 }
847
848 return Status;
849}
850
865 )
866{
867 UINT16 *FilePostFix;
868 EFI_STATUS Status;
869 UINTN NameLength;
870
871 if ((Private->FileContext->FHandle == NULL) || (Private->FileContext->FileName == NULL) || (Private->SignatureGUID == NULL)) {
872 return EFI_INVALID_PARAMETER;
873 }
874
875 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
876 if (EFI_ERROR (Status)) {
877 return Status;
878 }
879
880 //
881 // Parse the file's postfix. Supports DER-encoded X509 certificate,
882 // and .pbk as RSA public key file.
883 //
884 NameLength = StrLen (Private->FileContext->FileName);
885 if (NameLength <= 4) {
886 return EFI_INVALID_PARAMETER;
887 }
888
889 FilePostFix = Private->FileContext->FileName + NameLength - 4;
890 if (IsDerEncodeCertificate (FilePostFix)) {
891 return EnrollX509ToKek (Private);
892 } else if (CompareMem (FilePostFix, L".pbk", 4) == 0) {
893 return EnrollRsa2048ToKek (Private);
894 } else {
895 //
896 // File type is wrong, simply close it
897 //
898 CloseEnrolledFile (Private->FileContext);
899
900 return EFI_INVALID_PARAMETER;
901 }
902}
903
919 IN CHAR16 *VariableName
920 )
921{
922 EFI_STATUS Status;
923 UINTN X509DataSize;
924 VOID *X509Data;
925 EFI_SIGNATURE_LIST *SigDBCert;
926 EFI_SIGNATURE_DATA *SigDBCertData;
927 VOID *Data;
928 UINTN DataSize;
929 UINTN SigDBSize;
930 UINT32 Attr;
931 EFI_TIME Time;
932
933 X509DataSize = 0;
934 SigDBSize = 0;
935 DataSize = 0;
936 X509Data = NULL;
937 SigDBCert = NULL;
938 SigDBCertData = NULL;
939 Data = NULL;
940
941 Status = ReadFileContent (
942 Private->FileContext->FHandle,
943 &X509Data,
944 &X509DataSize,
945 0
946 );
947 if (EFI_ERROR (Status)) {
948 goto ON_EXIT;
949 }
950
951 ASSERT (X509Data != NULL);
952
953 SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
954
955 Data = AllocateZeroPool (SigDBSize);
956 if (Data == NULL) {
957 Status = EFI_OUT_OF_RESOURCES;
958 goto ON_EXIT;
959 }
960
961 //
962 // Fill Certificate Database parameters.
963 //
964 SigDBCert = (EFI_SIGNATURE_LIST *)Data;
965 SigDBCert->SignatureListSize = (UINT32)SigDBSize;
966 SigDBCert->SignatureHeaderSize = 0;
967 SigDBCert->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
968 CopyGuid (&SigDBCert->SignatureType, &gEfiCertX509Guid);
969
970 SigDBCertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigDBCert + sizeof (EFI_SIGNATURE_LIST));
971 CopyGuid (&SigDBCertData->SignatureOwner, Private->SignatureGUID);
972 CopyMem ((UINT8 *)(SigDBCertData->SignatureData), X509Data, X509DataSize);
973
974 //
975 // Check if signature database entry has been already existed.
976 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
977 // new signature data to original variable
978 //
979 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
980 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
981 Status = GetCurrentTime (&Time);
982 if (EFI_ERROR (Status)) {
983 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
984 goto ON_EXIT;
985 }
986
987 Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data, &Time);
988 if (EFI_ERROR (Status)) {
989 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
990 goto ON_EXIT;
991 }
992
993 Status = gRT->GetVariable (
994 VariableName,
995 &gEfiImageSecurityDatabaseGuid,
996 NULL,
997 &DataSize,
998 NULL
999 );
1000 if (Status == EFI_BUFFER_TOO_SMALL) {
1001 Attr |= EFI_VARIABLE_APPEND_WRITE;
1002 } else if (Status != EFI_NOT_FOUND) {
1003 goto ON_EXIT;
1004 }
1005
1006 Status = gRT->SetVariable (
1007 VariableName,
1008 &gEfiImageSecurityDatabaseGuid,
1009 Attr,
1010 SigDBSize,
1011 Data
1012 );
1013 if (EFI_ERROR (Status)) {
1014 goto ON_EXIT;
1015 }
1016
1017ON_EXIT:
1018
1019 CloseEnrolledFile (Private->FileContext);
1020
1021 if (Private->SignatureGUID != NULL) {
1022 FreePool (Private->SignatureGUID);
1023 Private->SignatureGUID = NULL;
1024 }
1025
1026 if (Data != NULL) {
1027 FreePool (Data);
1028 }
1029
1030 if (X509Data != NULL) {
1031 FreePool (X509Data);
1032 }
1033
1034 return Status;
1035}
1036
1048BOOLEAN
1050 IN CHAR16 *VariableName,
1051 IN UINT8 *Signature,
1052 IN UINTN SignatureSize
1053 )
1054{
1055 EFI_STATUS Status;
1056 EFI_SIGNATURE_LIST *CertList;
1057 EFI_SIGNATURE_DATA *Cert;
1058 UINTN DataSize;
1059 UINT8 *Data;
1060 UINTN Index;
1061 UINTN CertCount;
1062 BOOLEAN IsFound;
1063
1064 //
1065 // Read signature database variable.
1066 //
1067 IsFound = FALSE;
1068 Data = NULL;
1069 DataSize = 0;
1070 Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
1071 if (Status != EFI_BUFFER_TOO_SMALL) {
1072 return FALSE;
1073 }
1074
1075 Data = (UINT8 *)AllocateZeroPool (DataSize);
1076 if (Data == NULL) {
1077 return FALSE;
1078 }
1079
1080 Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
1081 if (EFI_ERROR (Status)) {
1082 goto Done;
1083 }
1084
1085 //
1086 // Enumerate all signature data in SigDB to check if signature exists for executable.
1087 //
1088 CertList = (EFI_SIGNATURE_LIST *)Data;
1089 while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {
1090 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
1091 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
1092 if ((CertList->SignatureSize == sizeof (EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))) {
1093 for (Index = 0; Index < CertCount; Index++) {
1094 if (CompareMem (Cert->SignatureData, Signature, SignatureSize) == 0) {
1095 //
1096 // Find the signature in database.
1097 //
1098 IsFound = TRUE;
1099 break;
1100 }
1101
1102 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
1103 }
1104
1105 if (IsFound) {
1106 break;
1107 }
1108 }
1109
1110 DataSize -= CertList->SignatureListSize;
1111 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
1112 }
1113
1114Done:
1115 if (Data != NULL) {
1116 FreePool (Data);
1117 }
1118
1119 return IsFound;
1120}
1121
1134BOOLEAN
1136 IN UINT8 *CertData,
1137 IN UINTN CertSize,
1138 IN UINT32 HashAlg,
1139 OUT UINT8 *CertHash
1140 )
1141{
1142 BOOLEAN Status;
1143 VOID *HashCtx;
1144 UINTN CtxSize;
1145 UINT8 *TBSCert;
1146 UINTN TBSCertSize;
1147
1148 HashCtx = NULL;
1149 Status = FALSE;
1150
1151 if (HashAlg >= HASHALG_MAX) {
1152 return FALSE;
1153 }
1154
1155 //
1156 // Retrieve the TBSCertificate for Hash Calculation.
1157 //
1158 if (!X509GetTBSCert (CertData, CertSize, &TBSCert, &TBSCertSize)) {
1159 return FALSE;
1160 }
1161
1162 //
1163 // 1. Initialize context of hash.
1164 //
1165 CtxSize = mHash[HashAlg].GetContextSize ();
1166 HashCtx = AllocatePool (CtxSize);
1167 ASSERT (HashCtx != NULL);
1168
1169 //
1170 // 2. Initialize a hash context.
1171 //
1172 Status = mHash[HashAlg].HashInit (HashCtx);
1173 if (!Status) {
1174 goto Done;
1175 }
1176
1177 //
1178 // 3. Calculate the hash.
1179 //
1180 Status = mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize);
1181 if (!Status) {
1182 goto Done;
1183 }
1184
1185 //
1186 // 4. Get the hash result.
1187 //
1188 ZeroMem (CertHash, mHash[HashAlg].DigestLength);
1189 Status = mHash[HashAlg].HashFinal (HashCtx, CertHash);
1190
1191Done:
1192 if (HashCtx != NULL) {
1193 FreePool (HashCtx);
1194 }
1195
1196 return Status;
1197}
1198
1209BOOLEAN
1211 IN UINT8 *Certificate,
1212 IN UINTN CertSize
1213 )
1214{
1215 BOOLEAN IsFound;
1216 EFI_STATUS Status;
1217 EFI_SIGNATURE_LIST *DbxList;
1218 EFI_SIGNATURE_DATA *CertHash;
1219 UINTN CertHashCount;
1220 UINTN Index;
1221 UINT32 HashAlg;
1222 UINT8 CertDigest[MAX_DIGEST_SIZE];
1223 UINT8 *DbxCertHash;
1224 UINTN SiglistHeaderSize;
1225 UINT8 *Data;
1226 UINTN DataSize;
1227
1228 IsFound = FALSE;
1229 HashAlg = HASHALG_MAX;
1230 Data = NULL;
1231
1232 //
1233 // Read signature database variable.
1234 //
1235 DataSize = 0;
1236 Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
1237 if (Status != EFI_BUFFER_TOO_SMALL) {
1238 return FALSE;
1239 }
1240
1241 Data = (UINT8 *)AllocateZeroPool (DataSize);
1242 if (Data == NULL) {
1243 return FALSE;
1244 }
1245
1246 Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
1247 if (EFI_ERROR (Status)) {
1248 goto Done;
1249 }
1250
1251 //
1252 // Check whether the certificate hash exists in the forbidden database.
1253 //
1254 DbxList = (EFI_SIGNATURE_LIST *)Data;
1255 while ((DataSize > 0) && (DataSize >= DbxList->SignatureListSize)) {
1256 //
1257 // Determine Hash Algorithm of Certificate in the forbidden database.
1258 //
1259 if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha256Guid)) {
1260 HashAlg = HASHALG_SHA256;
1261 } else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha384Guid)) {
1262 HashAlg = HASHALG_SHA384;
1263 } else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha512Guid)) {
1264 HashAlg = HASHALG_SHA512;
1265 } else {
1266 DataSize -= DbxList->SignatureListSize;
1267 DbxList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);
1268 continue;
1269 }
1270
1271 //
1272 // Calculate the hash value of current db certificate for comparision.
1273 //
1274 if (!CalculateCertHash (Certificate, CertSize, HashAlg, CertDigest)) {
1275 goto Done;
1276 }
1277
1278 SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;
1279 CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)DbxList + SiglistHeaderSize);
1280 CertHashCount = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;
1281 for (Index = 0; Index < CertHashCount; Index++) {
1282 //
1283 // Iterate each Signature Data Node within this CertList for verify.
1284 //
1285 DbxCertHash = CertHash->SignatureData;
1286 if (CompareMem (DbxCertHash, CertDigest, mHash[HashAlg].DigestLength) == 0) {
1287 //
1288 // Hash of Certificate is found in forbidden database.
1289 //
1290 IsFound = TRUE;
1291 goto Done;
1292 }
1293
1294 CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)CertHash + DbxList->SignatureSize);
1295 }
1296
1297 DataSize -= DbxList->SignatureListSize;
1298 DbxList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);
1299 }
1300
1301Done:
1302 if (Data != NULL) {
1303 FreePool (Data);
1304 }
1305
1306 return IsFound;
1307}
1308
1324BOOLEAN
1326 IN EFI_SIGNATURE_LIST *Database,
1327 IN UINTN DatabaseSize,
1328 IN EFI_GUID *SignatureType,
1329 OUT UINTN *Offset
1330 )
1331{
1332 EFI_SIGNATURE_LIST *SigList;
1333 UINTN SiglistSize;
1334
1335 if ((Database == NULL) || (DatabaseSize == 0)) {
1336 *Offset = 0;
1337 return FALSE;
1338 }
1339
1340 SigList = Database;
1341 SiglistSize = DatabaseSize;
1342 while ((SiglistSize > 0) && (SiglistSize >= SigList->SignatureListSize)) {
1343 if (CompareGuid (&SigList->SignatureType, SignatureType)) {
1344 *Offset = DatabaseSize - SiglistSize;
1345 return TRUE;
1346 }
1347
1348 SiglistSize -= SigList->SignatureListSize;
1349 SigList = (EFI_SIGNATURE_LIST *)((UINT8 *)SigList + SigList->SignatureListSize);
1350 }
1351
1352 *Offset = 0;
1353 return FALSE;
1354}
1355
1374 IN UINT32 HashAlg,
1375 IN EFI_HII_DATE *RevocationDate,
1376 IN EFI_HII_TIME *RevocationTime,
1377 IN BOOLEAN AlwaysRevocation
1378 )
1379{
1380 EFI_STATUS Status;
1381 UINTN X509DataSize;
1382 VOID *X509Data;
1383 EFI_SIGNATURE_LIST *SignatureList;
1384 UINTN SignatureListSize;
1385 UINT8 *Data;
1386 UINT8 *NewData;
1387 UINTN DataSize;
1388 UINTN DbSize;
1389 UINT32 Attr;
1390 EFI_SIGNATURE_DATA *SignatureData;
1391 UINTN SignatureSize;
1392 EFI_GUID SignatureType;
1393 UINTN Offset;
1394 UINT8 CertHash[MAX_DIGEST_SIZE];
1395 UINT16 *FilePostFix;
1396 UINTN NameLength;
1397 EFI_TIME *Time;
1398 EFI_TIME NewTime;
1399
1400 X509DataSize = 0;
1401 DbSize = 0;
1402 X509Data = NULL;
1403 SignatureData = NULL;
1404 SignatureList = NULL;
1405 Data = NULL;
1406 NewData = NULL;
1407
1408 if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->SignatureGUID == NULL)) {
1409 return EFI_INVALID_PARAMETER;
1410 }
1411
1412 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
1413 if (EFI_ERROR (Status)) {
1414 return Status;
1415 }
1416
1417 //
1418 // Parse the file's postfix.
1419 //
1420 NameLength = StrLen (Private->FileContext->FileName);
1421 if (NameLength <= 4) {
1422 return EFI_INVALID_PARAMETER;
1423 }
1424
1425 FilePostFix = Private->FileContext->FileName + NameLength - 4;
1426 if (!IsDerEncodeCertificate (FilePostFix)) {
1427 //
1428 // Only supports DER-encoded X509 certificate.
1429 //
1430 return EFI_INVALID_PARAMETER;
1431 }
1432
1433 //
1434 // Get the certificate from file and calculate its hash.
1435 //
1436 Status = ReadFileContent (
1437 Private->FileContext->FHandle,
1438 &X509Data,
1439 &X509DataSize,
1440 0
1441 );
1442 if (EFI_ERROR (Status)) {
1443 goto ON_EXIT;
1444 }
1445
1446 ASSERT (X509Data != NULL);
1447
1448 if (!CalculateCertHash (X509Data, X509DataSize, HashAlg, CertHash)) {
1449 goto ON_EXIT;
1450 }
1451
1452 //
1453 // Get the variable for enrollment.
1454 //
1455 DataSize = 0;
1456 Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
1457 if (Status == EFI_BUFFER_TOO_SMALL) {
1458 Data = (UINT8 *)AllocateZeroPool (DataSize);
1459 if (Data == NULL) {
1460 return EFI_OUT_OF_RESOURCES;
1461 }
1462
1463 Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
1464 if (EFI_ERROR (Status)) {
1465 goto ON_EXIT;
1466 }
1467 }
1468
1469 //
1470 // Allocate memory for Signature and fill the Signature
1471 //
1472 SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + sizeof (EFI_TIME) + mHash[HashAlg].DigestLength;
1473 SignatureData = (EFI_SIGNATURE_DATA *)AllocateZeroPool (SignatureSize);
1474 if (SignatureData == NULL) {
1475 return EFI_OUT_OF_RESOURCES;
1476 }
1477
1478 CopyGuid (&SignatureData->SignatureOwner, Private->SignatureGUID);
1479 CopyMem (SignatureData->SignatureData, CertHash, mHash[HashAlg].DigestLength);
1480
1481 //
1482 // Fill the time.
1483 //
1484 if (!AlwaysRevocation) {
1485 Time = (EFI_TIME *)(&SignatureData->SignatureData + mHash[HashAlg].DigestLength);
1486 Time->Year = RevocationDate->Year;
1487 Time->Month = RevocationDate->Month;
1488 Time->Day = RevocationDate->Day;
1489 Time->Hour = RevocationTime->Hour;
1490 Time->Minute = RevocationTime->Minute;
1491 Time->Second = RevocationTime->Second;
1492 }
1493
1494 //
1495 // Determine the GUID for certificate hash.
1496 //
1497 switch (HashAlg) {
1498 case HASHALG_SHA256:
1499 SignatureType = gEfiCertX509Sha256Guid;
1500 break;
1501 case HASHALG_SHA384:
1502 SignatureType = gEfiCertX509Sha384Guid;
1503 break;
1504 case HASHALG_SHA512:
1505 SignatureType = gEfiCertX509Sha512Guid;
1506 break;
1507 default:
1508 return FALSE;
1509 }
1510
1511 //
1512 // Add signature into the new variable data buffer
1513 //
1514 if (GetSignaturelistOffset ((EFI_SIGNATURE_LIST *)Data, DataSize, &SignatureType, &Offset)) {
1515 //
1516 // Add the signature to the found signaturelist.
1517 //
1518 DbSize = DataSize + SignatureSize;
1519 NewData = AllocateZeroPool (DbSize);
1520 if (NewData == NULL) {
1521 Status = EFI_OUT_OF_RESOURCES;
1522 goto ON_EXIT;
1523 }
1524
1525 SignatureList = (EFI_SIGNATURE_LIST *)(Data + Offset);
1526 SignatureListSize = (UINTN)ReadUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize);
1527 CopyMem (NewData, Data, Offset + SignatureListSize);
1528
1529 SignatureList = (EFI_SIGNATURE_LIST *)(NewData + Offset);
1530 WriteUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize, (UINT32)(SignatureListSize + SignatureSize));
1531
1532 Offset += SignatureListSize;
1533 CopyMem (NewData + Offset, SignatureData, SignatureSize);
1534 CopyMem (NewData + Offset + SignatureSize, Data + Offset, DataSize - Offset);
1535
1536 FreePool (Data);
1537 Data = NewData;
1538 DataSize = DbSize;
1539 } else {
1540 //
1541 // Create a new signaturelist, and add the signature into the signaturelist.
1542 //
1543 DbSize = DataSize + sizeof (EFI_SIGNATURE_LIST) + SignatureSize;
1544 NewData = AllocateZeroPool (DbSize);
1545 if (NewData == NULL) {
1546 Status = EFI_OUT_OF_RESOURCES;
1547 goto ON_EXIT;
1548 }
1549
1550 //
1551 // Fill Certificate Database parameters.
1552 //
1553 SignatureList = (EFI_SIGNATURE_LIST *)(NewData + DataSize);
1554 SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + SignatureSize;
1555 WriteUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize, (UINT32)SignatureListSize);
1556 WriteUnaligned32 ((UINT32 *)&SignatureList->SignatureSize, (UINT32)SignatureSize);
1557 CopyGuid (&SignatureList->SignatureType, &SignatureType);
1558 CopyMem ((UINT8 *)SignatureList + sizeof (EFI_SIGNATURE_LIST), SignatureData, SignatureSize);
1559 if ((DataSize != 0) && (Data != NULL)) {
1560 CopyMem (NewData, Data, DataSize);
1561 FreePool (Data);
1562 }
1563
1564 Data = NewData;
1565 DataSize = DbSize;
1566 }
1567
1568 Status = GetCurrentTime (&NewTime);
1569 if (EFI_ERROR (Status)) {
1570 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
1571 goto ON_EXIT;
1572 }
1573
1574 Status = CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data, &NewTime);
1575 if (EFI_ERROR (Status)) {
1576 goto ON_EXIT;
1577 }
1578
1579 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
1580 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
1581 Status = gRT->SetVariable (
1583 &gEfiImageSecurityDatabaseGuid,
1584 Attr,
1585 DataSize,
1586 Data
1587 );
1588 if (EFI_ERROR (Status)) {
1589 goto ON_EXIT;
1590 }
1591
1592ON_EXIT:
1593
1594 CloseEnrolledFile (Private->FileContext);
1595
1596 if (Private->SignatureGUID != NULL) {
1597 FreePool (Private->SignatureGUID);
1598 Private->SignatureGUID = NULL;
1599 }
1600
1601 if (Data != NULL) {
1602 FreePool (Data);
1603 }
1604
1605 if (SignatureData != NULL) {
1606 FreePool (SignatureData);
1607 }
1608
1609 if (X509Data != NULL) {
1610 FreePool (X509Data);
1611 }
1612
1613 return Status;
1614}
1615
1626BOOLEAN
1629 IN CHAR16 *VariableName
1630 )
1631{
1632 EFI_STATUS Status;
1633 UINTN X509DataSize;
1634 VOID *X509Data;
1635 BOOLEAN IsFound;
1636
1637 //
1638 // Read the certificate from file
1639 //
1640 X509DataSize = 0;
1641 X509Data = NULL;
1642 Status = ReadFileContent (
1643 Private->FileContext->FHandle,
1644 &X509Data,
1645 &X509DataSize,
1646 0
1647 );
1648 if (EFI_ERROR (Status)) {
1649 return FALSE;
1650 }
1651
1652 //
1653 // Check the raw certificate.
1654 //
1655 IsFound = FALSE;
1656 if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, X509Data, X509DataSize)) {
1657 IsFound = TRUE;
1658 goto ON_EXIT;
1659 }
1660
1661 //
1662 // Check the hash of certificate.
1663 //
1664 if (IsCertHashFoundInDbx (X509Data, X509DataSize)) {
1665 IsFound = TRUE;
1666 goto ON_EXIT;
1667 }
1668
1669ON_EXIT:
1670 if (X509Data != NULL) {
1671 FreePool (X509Data);
1672 }
1673
1674 return IsFound;
1675}
1676
1693EFIAPI
1695 IN VOID *FileHandle,
1696 IN UINTN FileOffset,
1697 IN OUT UINTN *ReadSize,
1698 OUT VOID *Buffer
1699 )
1700{
1701 UINTN EndPosition;
1702
1703 if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) {
1704 return EFI_INVALID_PARAMETER;
1705 }
1706
1707 if (MAX_ADDRESS - FileOffset < *ReadSize) {
1708 return EFI_INVALID_PARAMETER;
1709 }
1710
1711 EndPosition = FileOffset + *ReadSize;
1712 if (EndPosition > mImageSize) {
1713 *ReadSize = (UINT32)(mImageSize - FileOffset);
1714 }
1715
1716 if (FileOffset >= mImageSize) {
1717 *ReadSize = 0;
1718 }
1719
1720 CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize);
1721
1722 return EFI_SUCCESS;
1723}
1724
1735 VOID
1736 )
1737{
1738 EFI_IMAGE_DOS_HEADER *DosHdr;
1739 EFI_IMAGE_NT_HEADERS32 *NtHeader32;
1740 EFI_IMAGE_NT_HEADERS64 *NtHeader64;
1741 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
1742 EFI_STATUS Status;
1743
1744 NtHeader32 = NULL;
1745 NtHeader64 = NULL;
1746
1747 ZeroMem (&ImageContext, sizeof (ImageContext));
1748 ImageContext.Handle = (VOID *)mImageBase;
1750
1751 //
1752 // Get information about the image being loaded
1753 //
1754 Status = PeCoffLoaderGetImageInfo (&ImageContext);
1755 if (EFI_ERROR (Status)) {
1756 //
1757 // The information can't be got from the invalid PeImage
1758 //
1759 DEBUG ((DEBUG_INFO, "SecureBootConfigDxe: PeImage invalid. \n"));
1760 return Status;
1761 }
1762
1763 //
1764 // Read the Dos header
1765 //
1766 DosHdr = (EFI_IMAGE_DOS_HEADER *)(mImageBase);
1767 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
1768 //
1769 // DOS image header is present,
1770 // So read the PE header after the DOS image header
1771 //
1772 mPeCoffHeaderOffset = DosHdr->e_lfanew;
1773 } else {
1774 mPeCoffHeaderOffset = 0;
1775 }
1776
1777 //
1778 // Read PE header and check the signature validity and machine compatibility
1779 //
1780 NtHeader32 = (EFI_IMAGE_NT_HEADERS32 *)(mImageBase + mPeCoffHeaderOffset);
1781 if (NtHeader32->Signature != EFI_IMAGE_NT_SIGNATURE) {
1782 return EFI_UNSUPPORTED;
1783 }
1784
1785 mNtHeader.Pe32 = NtHeader32;
1786
1787 //
1788 // Check the architecture field of PE header and get the Certificate Data Directory data
1789 // Note the size of FileHeader field is constant for both IA32 and X64 arch
1790 //
1791 if ( (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32)
1792 || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_EBC)
1793 || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED))
1794 {
1795 //
1796 // 32-bits Architecture
1797 //
1798 mImageType = ImageType_IA32;
1799 mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY *)&(NtHeader32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]);
1800 } else if ( (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64)
1801 || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64)
1802 || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_AARCH64))
1803 {
1804 //
1805 // 64-bits Architecture
1806 //
1807 mImageType = ImageType_X64;
1808 NtHeader64 = (EFI_IMAGE_NT_HEADERS64 *)(mImageBase + mPeCoffHeaderOffset);
1809 mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY *)&(NtHeader64->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]);
1810 } else {
1811 return EFI_UNSUPPORTED;
1812 }
1813
1814 return EFI_SUCCESS;
1815}
1816
1830BOOLEAN
1832 IN UINT32 HashAlg
1833 )
1834{
1835 BOOLEAN Status;
1836 EFI_IMAGE_SECTION_HEADER *Section;
1837 VOID *HashCtx;
1838 UINTN CtxSize;
1839 UINT8 *HashBase;
1840 UINTN HashSize;
1841 UINTN SumOfBytesHashed;
1842 EFI_IMAGE_SECTION_HEADER *SectionHeader;
1843 UINTN Index;
1844 UINTN Pos;
1845
1846 HashCtx = NULL;
1847 SectionHeader = NULL;
1848 Status = FALSE;
1849
1850 if ((HashAlg >= HASHALG_MAX)) {
1851 return FALSE;
1852 }
1853
1854 //
1855 // Initialize context of hash.
1856 //
1857 ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
1858
1859 switch (HashAlg) {
1860 case HASHALG_SHA256:
1861 mImageDigestSize = SHA256_DIGEST_SIZE;
1862 mCertType = gEfiCertSha256Guid;
1863 break;
1864
1865 case HASHALG_SHA384:
1866 mImageDigestSize = SHA384_DIGEST_SIZE;
1867 mCertType = gEfiCertSha384Guid;
1868 break;
1869
1870 case HASHALG_SHA512:
1871 mImageDigestSize = SHA512_DIGEST_SIZE;
1872 mCertType = gEfiCertSha512Guid;
1873 break;
1874
1875 default:
1876 return FALSE;
1877 }
1878
1879 CtxSize = mHash[HashAlg].GetContextSize ();
1880
1881 HashCtx = AllocatePool (CtxSize);
1882 ASSERT (HashCtx != NULL);
1883
1884 // 1. Load the image header into memory.
1885
1886 // 2. Initialize a SHA hash context.
1887 Status = mHash[HashAlg].HashInit (HashCtx);
1888 if (!Status) {
1889 goto Done;
1890 }
1891
1892 //
1893 // Measuring PE/COFF Image Header;
1894 // But CheckSum field and SECURITY data directory (certificate) are excluded
1895 //
1896
1897 //
1898 // 3. Calculate the distance from the base of the image header to the image checksum address.
1899 // 4. Hash the image header from its base to beginning of the image checksum.
1900 //
1901 HashBase = mImageBase;
1902 if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
1903 //
1904 // Use PE32 offset.
1905 //
1906 HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase;
1907 } else {
1908 //
1909 // Use PE32+ offset.
1910 //
1911 HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase;
1912 }
1913
1914 Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
1915 if (!Status) {
1916 goto Done;
1917 }
1918
1919 //
1920 // 5. Skip over the image checksum (it occupies a single ULONG).
1921 // 6. Get the address of the beginning of the Cert Directory.
1922 // 7. Hash everything from the end of the checksum to the start of the Cert Directory.
1923 //
1924 if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
1925 //
1926 // Use PE32 offset.
1927 //
1928 HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
1929 HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase;
1930 } else {
1931 //
1932 // Use PE32+ offset.
1933 //
1934 HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
1935 HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase;
1936 }
1937
1938 Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
1939 if (!Status) {
1940 goto Done;
1941 }
1942
1943 //
1944 // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
1945 // 9. Hash everything from the end of the Cert Directory to the end of image header.
1946 //
1947 if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
1948 //
1949 // Use PE32 offset
1950 //
1951 HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
1952 HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN)mImageBase);
1953 } else {
1954 //
1955 // Use PE32+ offset.
1956 //
1957 HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
1958 HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN)mImageBase);
1959 }
1960
1961 Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
1962 if (!Status) {
1963 goto Done;
1964 }
1965
1966 //
1967 // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.
1968 //
1969 if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
1970 //
1971 // Use PE32 offset.
1972 //
1973 SumOfBytesHashed = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders;
1974 } else {
1975 //
1976 // Use PE32+ offset
1977 //
1978 SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders;
1979 }
1980
1981 //
1982 // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
1983 // structures in the image. The 'NumberOfSections' field of the image
1984 // header indicates how big the table should be. Do not include any
1985 // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
1986 //
1987 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections);
1988 ASSERT (SectionHeader != NULL);
1989 //
1990 // 12. Using the 'PointerToRawData' in the referenced section headers as
1991 // a key, arrange the elements in the table in ascending order. In other
1992 // words, sort the section headers according to the disk-file offset of
1993 // the section.
1994 //
1995 Section = (EFI_IMAGE_SECTION_HEADER *)(
1996 mImageBase +
1997 mPeCoffHeaderOffset +
1998 sizeof (UINT32) +
1999 sizeof (EFI_IMAGE_FILE_HEADER) +
2000 mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader
2001 );
2002 for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {
2003 Pos = Index;
2004 while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {
2005 CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER));
2006 Pos--;
2007 }
2008
2009 CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER));
2010 Section += 1;
2011 }
2012
2013 //
2014 // 13. Walk through the sorted table, bring the corresponding section
2015 // into memory, and hash the entire section (using the 'SizeOfRawData'
2016 // field in the section header to determine the amount of data to hash).
2017 // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
2018 // 15. Repeat steps 13 and 14 for all the sections in the sorted table.
2019 //
2020 for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {
2021 Section = &SectionHeader[Index];
2022 if (Section->SizeOfRawData == 0) {
2023 continue;
2024 }
2025
2026 HashBase = mImageBase + Section->PointerToRawData;
2027 HashSize = (UINTN)Section->SizeOfRawData;
2028
2029 Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
2030 if (!Status) {
2031 goto Done;
2032 }
2033
2034 SumOfBytesHashed += HashSize;
2035 }
2036
2037 //
2038 // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
2039 // data in the file that needs to be added to the hash. This data begins
2040 // at file offset SUM_OF_BYTES_HASHED and its length is:
2041 // FileSize - (CertDirectory->Size)
2042 //
2043 if (mImageSize > SumOfBytesHashed) {
2044 HashBase = mImageBase + SumOfBytesHashed;
2045 if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
2046 //
2047 // Use PE32 offset.
2048 //
2049 HashSize = (UINTN)(
2050 mImageSize -
2051 mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
2052 SumOfBytesHashed);
2053 } else {
2054 //
2055 // Use PE32+ offset.
2056 //
2057 HashSize = (UINTN)(
2058 mImageSize -
2059 mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
2060 SumOfBytesHashed);
2061 }
2062
2063 Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
2064 if (!Status) {
2065 goto Done;
2066 }
2067 }
2068
2069 Status = mHash[HashAlg].HashFinal (HashCtx, mImageDigest);
2070
2071Done:
2072 if (HashCtx != NULL) {
2073 FreePool (HashCtx);
2074 }
2075
2076 if (SectionHeader != NULL) {
2077 FreePool (SectionHeader);
2078 }
2079
2080 return Status;
2081}
2082
2094 VOID
2095 )
2096{
2097 UINT8 Index;
2098 WIN_CERTIFICATE_EFI_PKCS *PkcsCertData;
2099
2100 PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)(mImageBase + mSecDataDir->Offset);
2101
2102 for (Index = 0; Index < HASHALG_MAX; Index++) {
2103 //
2104 // Check the Hash algorithm in PE/COFF Authenticode.
2105 // According to PKCS#7 Definition:
2106 // SignedData ::= SEQUENCE {
2107 // version Version,
2108 // digestAlgorithms DigestAlgorithmIdentifiers,
2109 // contentInfo ContentInfo,
2110 // .... }
2111 // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
2112 // This field has the fixed offset (+32) in final Authenticode ASN.1 data.
2113 // Fixed offset (+32) is calculated based on two bytes of length encoding.
2114 //
2115 if ((*(PkcsCertData->CertData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) {
2116 //
2117 // Only support two bytes of Long Form of Length Encoding.
2118 //
2119 continue;
2120 }
2121
2122 //
2123 if (CompareMem (PkcsCertData->CertData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) {
2124 break;
2125 }
2126 }
2127
2128 if (Index == HASHALG_MAX) {
2129 return EFI_UNSUPPORTED;
2130 }
2131
2132 //
2133 // HASH PE Image based on Hash algorithm in PE/COFF Authenticode.
2134 //
2135 if (!HashPeImage (Index)) {
2136 return EFI_UNSUPPORTED;
2137 }
2138
2139 return EFI_SUCCESS;
2140}
2141
2159 IN CHAR16 *VariableName
2160 )
2161{
2162 EFI_STATUS Status;
2163 VOID *Data;
2164 UINTN DataSize;
2165 UINT32 Attr;
2166
2167 Data = NULL;
2168
2169 //
2170 // DBT only support DER-X509 Cert Enrollment
2171 //
2172 if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {
2173 return EFI_UNSUPPORTED;
2174 }
2175
2176 //
2177 // Read the whole file content
2178 //
2179 Status = ReadFileContent (
2180 Private->FileContext->FHandle,
2181 (VOID **)&mImageBase,
2182 &mImageSize,
2183 0
2184 );
2185 if (EFI_ERROR (Status)) {
2186 goto ON_EXIT;
2187 }
2188
2189 ASSERT (mImageBase != NULL);
2190
2191 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
2192 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
2193
2194 //
2195 // Check if SigDB variable has been already existed.
2196 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
2197 // new signature data to original variable
2198 //
2199 DataSize = 0;
2200 Status = gRT->GetVariable (
2201 VariableName,
2202 &gEfiImageSecurityDatabaseGuid,
2203 NULL,
2204 &DataSize,
2205 NULL
2206 );
2207 if (Status == EFI_BUFFER_TOO_SMALL) {
2208 Attr |= EFI_VARIABLE_APPEND_WRITE;
2209 } else if (Status != EFI_NOT_FOUND) {
2210 goto ON_EXIT;
2211 }
2212
2213 //
2214 // Directly set AUTHENTICATION_2 data to SetVariable
2215 //
2216 Status = gRT->SetVariable (
2217 VariableName,
2218 &gEfiImageSecurityDatabaseGuid,
2219 Attr,
2220 mImageSize,
2221 mImageBase
2222 );
2223
2224 DEBUG ((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status));
2225
2226ON_EXIT:
2227
2228 CloseEnrolledFile (Private->FileContext);
2229
2230 if (Data != NULL) {
2231 FreePool (Data);
2232 }
2233
2234 if (mImageBase != NULL) {
2235 FreePool (mImageBase);
2236 mImageBase = NULL;
2237 }
2238
2239 return Status;
2240}
2241
2259 IN CHAR16 *VariableName
2260 )
2261{
2262 EFI_STATUS Status;
2263 EFI_SIGNATURE_LIST *SigDBCert;
2264 EFI_SIGNATURE_DATA *SigDBCertData;
2265 VOID *Data;
2266 UINTN DataSize;
2267 UINTN SigDBSize;
2268 UINT32 Attr;
2269 WIN_CERTIFICATE_UEFI_GUID *GuidCertData;
2270 EFI_TIME Time;
2271 UINT32 HashAlg;
2272
2273 Data = NULL;
2274 GuidCertData = NULL;
2275
2276 if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {
2277 return EFI_UNSUPPORTED;
2278 }
2279
2280 //
2281 // Form the SigDB certificate list.
2282 // Format the data item into EFI_SIGNATURE_LIST type.
2283 //
2284 // We need to parse signature data of executable from specified signed executable file.
2285 // In current implementation, we simply trust the pass-in signed executable file.
2286 // In reality, it's OS's responsibility to verify the signed executable file.
2287 //
2288
2289 //
2290 // Read the whole file content
2291 //
2292 Status = ReadFileContent (
2293 Private->FileContext->FHandle,
2294 (VOID **)&mImageBase,
2295 &mImageSize,
2296 0
2297 );
2298 if (EFI_ERROR (Status)) {
2299 goto ON_EXIT;
2300 }
2301
2302 ASSERT (mImageBase != NULL);
2303
2304 Status = LoadPeImage ();
2305 if (EFI_ERROR (Status)) {
2306 goto ON_EXIT;
2307 }
2308
2309 if (mSecDataDir->SizeOfCert == 0) {
2310 Status = EFI_SECURITY_VIOLATION;
2311 HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
2312 while (HashAlg > 0) {
2313 HashAlg--;
2314 if ((mHash[HashAlg].GetContextSize == NULL) || (mHash[HashAlg].HashInit == NULL) || (mHash[HashAlg].HashUpdate == NULL) || (mHash[HashAlg].HashFinal == NULL)) {
2315 continue;
2316 }
2317
2318 if (HashPeImage (HashAlg)) {
2319 Status = EFI_SUCCESS;
2320 break;
2321 }
2322 }
2323
2324 if (EFI_ERROR (Status)) {
2325 DEBUG ((DEBUG_ERROR, "Fail to get hash digest: %r", Status));
2326 goto ON_EXIT;
2327 }
2328 } else {
2329 //
2330 // Read the certificate data
2331 //
2332 mCertificate = (WIN_CERTIFICATE *)(mImageBase + mSecDataDir->Offset);
2333
2334 if (mCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {
2335 GuidCertData = (WIN_CERTIFICATE_UEFI_GUID *)mCertificate;
2336 if (CompareMem (&GuidCertData->CertType, &gEfiCertTypeRsa2048Sha256Guid, sizeof (EFI_GUID)) != 0) {
2337 Status = EFI_ABORTED;
2338 goto ON_EXIT;
2339 }
2340
2341 if (!HashPeImage (HASHALG_SHA256)) {
2342 Status = EFI_ABORTED;
2343 goto ON_EXIT;
2344 }
2345 } else if (mCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
2346 Status = HashPeImageByType ();
2347 if (EFI_ERROR (Status)) {
2348 goto ON_EXIT;
2349 }
2350 } else {
2351 Status = EFI_ABORTED;
2352 goto ON_EXIT;
2353 }
2354 }
2355
2356 //
2357 // Create a new SigDB entry.
2358 //
2359 SigDBSize = sizeof (EFI_SIGNATURE_LIST)
2360 + sizeof (EFI_SIGNATURE_DATA) - 1
2361 + (UINT32)mImageDigestSize;
2362
2363 Data = (UINT8 *)AllocateZeroPool (SigDBSize);
2364 if (Data == NULL) {
2365 Status = EFI_OUT_OF_RESOURCES;
2366 goto ON_EXIT;
2367 }
2368
2369 //
2370 // Adjust the Certificate Database parameters.
2371 //
2372 SigDBCert = (EFI_SIGNATURE_LIST *)Data;
2373 SigDBCert->SignatureListSize = (UINT32)SigDBSize;
2374 SigDBCert->SignatureHeaderSize = 0;
2375 SigDBCert->SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32)mImageDigestSize;
2376 CopyGuid (&SigDBCert->SignatureType, &mCertType);
2377
2378 SigDBCertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigDBCert + sizeof (EFI_SIGNATURE_LIST));
2379 CopyGuid (&SigDBCertData->SignatureOwner, Private->SignatureGUID);
2380 CopyMem (SigDBCertData->SignatureData, mImageDigest, mImageDigestSize);
2381
2382 Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
2383 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
2384 Status = GetCurrentTime (&Time);
2385 if (EFI_ERROR (Status)) {
2386 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
2387 goto ON_EXIT;
2388 }
2389
2390 Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data, &Time);
2391 if (EFI_ERROR (Status)) {
2392 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
2393 goto ON_EXIT;
2394 }
2395
2396 //
2397 // Check if SigDB variable has been already existed.
2398 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
2399 // new signature data to original variable
2400 //
2401 DataSize = 0;
2402 Status = gRT->GetVariable (
2403 VariableName,
2404 &gEfiImageSecurityDatabaseGuid,
2405 NULL,
2406 &DataSize,
2407 NULL
2408 );
2409 if (Status == EFI_BUFFER_TOO_SMALL) {
2410 Attr |= EFI_VARIABLE_APPEND_WRITE;
2411 } else if (Status != EFI_NOT_FOUND) {
2412 goto ON_EXIT;
2413 }
2414
2415 //
2416 // Enroll the variable.
2417 //
2418 Status = gRT->SetVariable (
2419 VariableName,
2420 &gEfiImageSecurityDatabaseGuid,
2421 Attr,
2422 SigDBSize,
2423 Data
2424 );
2425 if (EFI_ERROR (Status)) {
2426 goto ON_EXIT;
2427 }
2428
2429ON_EXIT:
2430
2431 CloseEnrolledFile (Private->FileContext);
2432
2433 if (Private->SignatureGUID != NULL) {
2434 FreePool (Private->SignatureGUID);
2435 Private->SignatureGUID = NULL;
2436 }
2437
2438 if (Data != NULL) {
2439 FreePool (Data);
2440 }
2441
2442 if (mImageBase != NULL) {
2443 FreePool (mImageBase);
2444 mImageBase = NULL;
2445 }
2446
2447 return Status;
2448}
2449
2466 IN CHAR16 *VariableName
2467 )
2468{
2469 UINT16 *FilePostFix;
2470 EFI_STATUS Status;
2471 UINTN NameLength;
2472
2473 if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->SignatureGUID == NULL)) {
2474 return EFI_INVALID_PARAMETER;
2475 }
2476
2477 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
2478 if (EFI_ERROR (Status)) {
2479 return Status;
2480 }
2481
2482 //
2483 // Parse the file's postfix.
2484 //
2485 NameLength = StrLen (Private->FileContext->FileName);
2486 if (NameLength <= 4) {
2487 return EFI_INVALID_PARAMETER;
2488 }
2489
2490 FilePostFix = Private->FileContext->FileName + NameLength - 4;
2491 if (IsDerEncodeCertificate (FilePostFix)) {
2492 //
2493 // Supports DER-encoded X509 certificate.
2494 //
2495 return EnrollX509toSigDB (Private, VariableName);
2496 } else if (IsAuthentication2Format (Private->FileContext->FHandle)) {
2497 return EnrollAuthentication2Descriptor (Private, VariableName);
2498 } else {
2499 return EnrollImageSignatureToSigDB (Private, VariableName);
2500 }
2501}
2502
2521 IN CHAR16 *VariableName,
2522 IN EFI_GUID *VendorGuid,
2523 IN UINT16 LabelNumber,
2524 IN EFI_FORM_ID FormId,
2525 IN EFI_QUESTION_ID QuestionIdBase
2526 )
2527{
2528 EFI_STATUS Status;
2529 UINT32 Index;
2530 UINTN CertCount;
2531 UINTN GuidIndex;
2532 VOID *StartOpCodeHandle;
2533 VOID *EndOpCodeHandle;
2534 EFI_IFR_GUID_LABEL *StartLabel;
2535 EFI_IFR_GUID_LABEL *EndLabel;
2536 UINTN DataSize;
2537 UINT8 *Data;
2538 EFI_SIGNATURE_LIST *CertList;
2539 EFI_SIGNATURE_DATA *Cert;
2540 UINT32 ItemDataSize;
2541 CHAR16 *GuidStr;
2542 EFI_STRING_ID GuidID;
2543 EFI_STRING_ID Help;
2544
2545 Data = NULL;
2546 CertList = NULL;
2547 Cert = NULL;
2548 GuidStr = NULL;
2549 StartOpCodeHandle = NULL;
2550 EndOpCodeHandle = NULL;
2551
2552 //
2553 // Initialize the container for dynamic opcodes.
2554 //
2555 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
2556 if (StartOpCodeHandle == NULL) {
2557 Status = EFI_OUT_OF_RESOURCES;
2558 goto ON_EXIT;
2559 }
2560
2561 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
2562 if (EndOpCodeHandle == NULL) {
2563 Status = EFI_OUT_OF_RESOURCES;
2564 goto ON_EXIT;
2565 }
2566
2567 //
2568 // Create Hii Extend Label OpCode.
2569 //
2570 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
2571 StartOpCodeHandle,
2572 &gEfiIfrTianoGuid,
2573 NULL,
2574 sizeof (EFI_IFR_GUID_LABEL)
2575 );
2577 StartLabel->Number = LabelNumber;
2578
2580 EndOpCodeHandle,
2581 &gEfiIfrTianoGuid,
2582 NULL,
2583 sizeof (EFI_IFR_GUID_LABEL)
2584 );
2586 EndLabel->Number = LABEL_END;
2587
2588 //
2589 // Read Variable.
2590 //
2591 DataSize = 0;
2592 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
2593 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
2594 goto ON_EXIT;
2595 }
2596
2597 Data = (UINT8 *)AllocateZeroPool (DataSize);
2598 if (Data == NULL) {
2599 Status = EFI_OUT_OF_RESOURCES;
2600 goto ON_EXIT;
2601 }
2602
2603 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
2604 if (EFI_ERROR (Status)) {
2605 goto ON_EXIT;
2606 }
2607
2608 GuidStr = AllocateZeroPool (100);
2609 if (GuidStr == NULL) {
2610 Status = EFI_OUT_OF_RESOURCES;
2611 goto ON_EXIT;
2612 }
2613
2614 //
2615 // Enumerate all KEK pub data.
2616 //
2617 ItemDataSize = (UINT32)DataSize;
2618 CertList = (EFI_SIGNATURE_LIST *)Data;
2619 GuidIndex = 0;
2620
2621 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
2622 if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid)) {
2623 Help = STRING_TOKEN (STR_CERT_TYPE_RSA2048_SHA256_GUID);
2624 } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
2625 Help = STRING_TOKEN (STR_CERT_TYPE_PCKS7_GUID);
2626 } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid)) {
2627 Help = STRING_TOKEN (STR_CERT_TYPE_SHA1_GUID);
2628 } else if (CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid)) {
2629 Help = STRING_TOKEN (STR_CERT_TYPE_SHA256_GUID);
2630 } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha256Guid)) {
2631 Help = STRING_TOKEN (STR_CERT_TYPE_X509_SHA256_GUID);
2632 } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha384Guid)) {
2633 Help = STRING_TOKEN (STR_CERT_TYPE_X509_SHA384_GUID);
2634 } else if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha512Guid)) {
2635 Help = STRING_TOKEN (STR_CERT_TYPE_X509_SHA512_GUID);
2636 } else {
2637 //
2638 // The signature type is not supported in current implementation.
2639 //
2640 ItemDataSize -= CertList->SignatureListSize;
2641 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
2642 continue;
2643 }
2644
2645 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
2646 for (Index = 0; Index < CertCount; Index++) {
2647 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList
2648 + sizeof (EFI_SIGNATURE_LIST)
2649 + CertList->SignatureHeaderSize
2650 + Index * CertList->SignatureSize);
2651 //
2652 // Display GUID and help
2653 //
2654 GuidToString (&Cert->SignatureOwner, GuidStr, 100);
2655 GuidID = HiiSetString (PrivateData->HiiHandle, 0, GuidStr, NULL);
2657 StartOpCodeHandle,
2658 (EFI_QUESTION_ID)(QuestionIdBase + GuidIndex++),
2659 0,
2660 0,
2661 GuidID,
2662 Help,
2663 EFI_IFR_FLAG_CALLBACK,
2664 0,
2665 NULL
2666 );
2667 }
2668
2669 ItemDataSize -= CertList->SignatureListSize;
2670 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
2671 }
2672
2673ON_EXIT:
2675 PrivateData->HiiHandle,
2676 &gSecureBootConfigFormSetGuid,
2677 FormId,
2678 StartOpCodeHandle,
2679 EndOpCodeHandle
2680 );
2681
2682 if (StartOpCodeHandle != NULL) {
2683 HiiFreeOpCodeHandle (StartOpCodeHandle);
2684 }
2685
2686 if (EndOpCodeHandle != NULL) {
2687 HiiFreeOpCodeHandle (EndOpCodeHandle);
2688 }
2689
2690 if (Data != NULL) {
2691 FreePool (Data);
2692 }
2693
2694 if (GuidStr != NULL) {
2695 FreePool (GuidStr);
2696 }
2697
2698 return EFI_SUCCESS;
2699}
2700
2714 IN EFI_QUESTION_ID QuestionId
2715 )
2716{
2717 EFI_STATUS Status;
2718 UINTN DataSize;
2719 UINT8 *Data;
2720 UINT8 *OldData;
2721 UINT32 Attr;
2722 UINT32 Index;
2723 EFI_SIGNATURE_LIST *CertList;
2724 EFI_SIGNATURE_LIST *NewCertList;
2725 EFI_SIGNATURE_DATA *Cert;
2726 UINTN CertCount;
2727 UINT32 Offset;
2728 BOOLEAN IsKEKItemFound;
2729 UINT32 KekDataSize;
2730 UINTN DeleteKekIndex;
2731 UINTN GuidIndex;
2732 EFI_TIME Time;
2733
2734 Data = NULL;
2735 OldData = NULL;
2736 CertList = NULL;
2737 Cert = NULL;
2738 Attr = 0;
2739 DeleteKekIndex = QuestionId - OPTION_DEL_KEK_QUESTION_ID;
2740
2741 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
2742 if (EFI_ERROR (Status)) {
2743 return Status;
2744 }
2745
2746 //
2747 // Get original KEK variable.
2748 //
2749 DataSize = 0;
2750 Status = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, NULL, &DataSize, NULL);
2751 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
2752 goto ON_EXIT;
2753 }
2754
2755 OldData = (UINT8 *)AllocateZeroPool (DataSize);
2756 if (OldData == NULL) {
2757 Status = EFI_OUT_OF_RESOURCES;
2758 goto ON_EXIT;
2759 }
2760
2761 Status = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, &Attr, &DataSize, OldData);
2762 if (EFI_ERROR (Status)) {
2763 goto ON_EXIT;
2764 }
2765
2766 //
2767 // Allocate space for new variable.
2768 //
2769 Data = (UINT8 *)AllocateZeroPool (DataSize);
2770 if (Data == NULL) {
2771 Status = EFI_OUT_OF_RESOURCES;
2772 goto ON_EXIT;
2773 }
2774
2775 //
2776 // Enumerate all KEK pub data and erasing the target item.
2777 //
2778 IsKEKItemFound = FALSE;
2779 KekDataSize = (UINT32)DataSize;
2780 CertList = (EFI_SIGNATURE_LIST *)OldData;
2781 Offset = 0;
2782 GuidIndex = 0;
2783 while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
2784 if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
2785 CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid))
2786 {
2787 CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
2788 NewCertList = (EFI_SIGNATURE_LIST *)(Data + Offset);
2789 Offset += (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
2790 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
2791 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
2792 for (Index = 0; Index < CertCount; Index++) {
2793 if (GuidIndex == DeleteKekIndex ) {
2794 //
2795 // Find it! Skip it!
2796 //
2797 NewCertList->SignatureListSize -= CertList->SignatureSize;
2798 IsKEKItemFound = TRUE;
2799 } else {
2800 //
2801 // This item doesn't match. Copy it to the Data buffer.
2802 //
2803 CopyMem (Data + Offset, Cert, CertList->SignatureSize);
2804 Offset += CertList->SignatureSize;
2805 }
2806
2807 GuidIndex++;
2808 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
2809 }
2810 } else {
2811 //
2812 // This List doesn't match. Copy it to the Data buffer.
2813 //
2814 CopyMem (Data + Offset, CertList, CertList->SignatureListSize);
2815 Offset += CertList->SignatureListSize;
2816 }
2817
2818 KekDataSize -= CertList->SignatureListSize;
2819 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
2820 }
2821
2822 if (!IsKEKItemFound) {
2823 //
2824 // Doesn't find the Kek Item!
2825 //
2826 Status = EFI_NOT_FOUND;
2827 goto ON_EXIT;
2828 }
2829
2830 //
2831 // Delete the Signature header if there is no signature in the list.
2832 //
2833 KekDataSize = Offset;
2834 CertList = (EFI_SIGNATURE_LIST *)Data;
2835 Offset = 0;
2836 ZeroMem (OldData, KekDataSize);
2837 while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
2838 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
2839 DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
2840 if (CertCount != 0) {
2841 CopyMem (OldData + Offset, CertList, CertList->SignatureListSize);
2842 Offset += CertList->SignatureListSize;
2843 }
2844
2845 KekDataSize -= CertList->SignatureListSize;
2846 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
2847 }
2848
2849 DataSize = Offset;
2851 Status = GetCurrentTime (&Time);
2852 if (EFI_ERROR (Status)) {
2853 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
2854 goto ON_EXIT;
2855 }
2856
2857 Status = CreateTimeBasedPayload (&DataSize, &OldData, &Time);
2858 if (EFI_ERROR (Status)) {
2859 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
2860 goto ON_EXIT;
2861 }
2862 }
2863
2864 Status = gRT->SetVariable (
2866 &gEfiGlobalVariableGuid,
2867 Attr,
2868 DataSize,
2869 OldData
2870 );
2871 if (EFI_ERROR (Status)) {
2872 DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
2873 goto ON_EXIT;
2874 }
2875
2876ON_EXIT:
2877 if (Data != NULL) {
2878 FreePool (Data);
2879 }
2880
2881 if (OldData != NULL) {
2882 FreePool (OldData);
2883 }
2884
2885 return UpdateDeletePage (
2886 PrivateData,
2888 &gEfiGlobalVariableGuid,
2889 LABEL_KEK_DELETE,
2890 FORMID_DELETE_KEK_FORM,
2891 OPTION_DEL_KEK_QUESTION_ID
2892 );
2893}
2894
2913 IN CHAR16 *VariableName,
2914 IN EFI_GUID *VendorGuid,
2915 IN UINT16 LabelNumber,
2916 IN EFI_FORM_ID FormId,
2917 IN EFI_QUESTION_ID QuestionIdBase,
2918 IN UINTN DeleteIndex
2919 )
2920{
2921 EFI_STATUS Status;
2922 UINTN DataSize;
2923 UINT8 *Data;
2924 UINT8 *OldData;
2925 UINT32 Attr;
2926 UINT32 Index;
2927 EFI_SIGNATURE_LIST *CertList;
2928 EFI_SIGNATURE_LIST *NewCertList;
2929 EFI_SIGNATURE_DATA *Cert;
2930 UINTN CertCount;
2931 UINT32 Offset;
2932 BOOLEAN IsItemFound;
2933 UINT32 ItemDataSize;
2934 UINTN GuidIndex;
2935 EFI_TIME Time;
2936
2937 Data = NULL;
2938 OldData = NULL;
2939 CertList = NULL;
2940 Cert = NULL;
2941 Attr = 0;
2942
2943 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
2944 if (EFI_ERROR (Status)) {
2945 return Status;
2946 }
2947
2948 //
2949 // Get original signature list data.
2950 //
2951 DataSize = 0;
2952 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
2953 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
2954 goto ON_EXIT;
2955 }
2956
2957 OldData = (UINT8 *)AllocateZeroPool (DataSize);
2958 if (OldData == NULL) {
2959 Status = EFI_OUT_OF_RESOURCES;
2960 goto ON_EXIT;
2961 }
2962
2963 Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
2964 if (EFI_ERROR (Status)) {
2965 goto ON_EXIT;
2966 }
2967
2968 //
2969 // Allocate space for new variable.
2970 //
2971 Data = (UINT8 *)AllocateZeroPool (DataSize);
2972 if (Data == NULL) {
2973 Status = EFI_OUT_OF_RESOURCES;
2974 goto ON_EXIT;
2975 }
2976
2977 //
2978 // Enumerate all signature data and erasing the target item.
2979 //
2980 IsItemFound = FALSE;
2981 ItemDataSize = (UINT32)DataSize;
2982 CertList = (EFI_SIGNATURE_LIST *)OldData;
2983 Offset = 0;
2984 GuidIndex = 0;
2985 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
2986 if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
2987 CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
2988 CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
2989 CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
2990 CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha256Guid) ||
2991 CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha384Guid) ||
2992 CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha512Guid)
2993 )
2994 {
2995 //
2996 // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
2997 //
2998 CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
2999 NewCertList = (EFI_SIGNATURE_LIST *)(Data + Offset);
3000 Offset += (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
3001 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
3002 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
3003 for (Index = 0; Index < CertCount; Index++) {
3004 if (GuidIndex == DeleteIndex) {
3005 //
3006 // Find it! Skip it!
3007 //
3008 NewCertList->SignatureListSize -= CertList->SignatureSize;
3009 IsItemFound = TRUE;
3010 } else {
3011 //
3012 // This item doesn't match. Copy it to the Data buffer.
3013 //
3014 CopyMem (Data + Offset, (UINT8 *)(Cert), CertList->SignatureSize);
3015 Offset += CertList->SignatureSize;
3016 }
3017
3018 GuidIndex++;
3019 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
3020 }
3021 } else {
3022 //
3023 // This List doesn't match. Just copy it to the Data buffer.
3024 //
3025 CopyMem (Data + Offset, (UINT8 *)(CertList), CertList->SignatureListSize);
3026 Offset += CertList->SignatureListSize;
3027 }
3028
3029 ItemDataSize -= CertList->SignatureListSize;
3030 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
3031 }
3032
3033 if (!IsItemFound) {
3034 //
3035 // Doesn't find the signature Item!
3036 //
3037 Status = EFI_NOT_FOUND;
3038 goto ON_EXIT;
3039 }
3040
3041 //
3042 // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
3043 //
3044 ItemDataSize = Offset;
3045 CertList = (EFI_SIGNATURE_LIST *)Data;
3046 Offset = 0;
3047 ZeroMem (OldData, ItemDataSize);
3048 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
3049 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
3050 DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
3051 if (CertCount != 0) {
3052 CopyMem (OldData + Offset, (UINT8 *)(CertList), CertList->SignatureListSize);
3053 Offset += CertList->SignatureListSize;
3054 }
3055
3056 ItemDataSize -= CertList->SignatureListSize;
3057 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
3058 }
3059
3060 DataSize = Offset;
3062 Status = GetCurrentTime (&Time);
3063 if (EFI_ERROR (Status)) {
3064 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
3065 goto ON_EXIT;
3066 }
3067
3068 Status = CreateTimeBasedPayload (&DataSize, &OldData, &Time);
3069 if (EFI_ERROR (Status)) {
3070 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
3071 goto ON_EXIT;
3072 }
3073 }
3074
3075 Status = gRT->SetVariable (
3076 VariableName,
3077 VendorGuid,
3078 Attr,
3079 DataSize,
3080 OldData
3081 );
3082 if (EFI_ERROR (Status)) {
3083 DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
3084 goto ON_EXIT;
3085 }
3086
3087ON_EXIT:
3088 if (Data != NULL) {
3089 FreePool (Data);
3090 }
3091
3092 if (OldData != NULL) {
3093 FreePool (OldData);
3094 }
3095
3096 return UpdateDeletePage (
3097 PrivateData,
3098 VariableName,
3099 VendorGuid,
3100 LabelNumber,
3101 FormId,
3102 QuestionIdBase
3103 );
3104}
3105
3120 IN SIGNATURE_DELETE_TYPE DelType,
3121 IN UINT32 CheckedCount
3122 )
3123{
3124 EFI_STATUS Status;
3125 EFI_SIGNATURE_LIST *ListWalker;
3126 EFI_SIGNATURE_LIST *NewCertList;
3127 EFI_SIGNATURE_DATA *DataWalker;
3128 CHAR16 VariableName[BUFFER_MAX_SIZE];
3129 UINT32 VariableAttr;
3130 UINTN VariableDataSize;
3131 UINTN RemainingSize;
3132 UINTN ListIndex;
3133 UINTN Index;
3134 UINTN Offset;
3135 UINT8 *VariableData;
3136 UINT8 *NewVariableData;
3137 EFI_TIME Time;
3138
3139 Status = EFI_SUCCESS;
3140 VariableAttr = 0;
3141 VariableDataSize = 0;
3142 ListIndex = 0;
3143 Offset = 0;
3144 VariableData = NULL;
3145 NewVariableData = NULL;
3146
3147 if (PrivateData->VariableName == Variable_DB) {
3148 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
3149 } else if (PrivateData->VariableName == Variable_DBX) {
3150 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
3151 } else if (PrivateData->VariableName == Variable_DBT) {
3152 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE2);
3153 } else {
3154 goto ON_EXIT;
3155 }
3156
3157 Status = gRT->GetVariable (
3158 VariableName,
3159 &gEfiImageSecurityDatabaseGuid,
3160 &VariableAttr,
3161 &VariableDataSize,
3162 VariableData
3163 );
3164 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
3165 goto ON_EXIT;
3166 }
3167
3168 VariableData = AllocateZeroPool (VariableDataSize);
3169 if (VariableData == NULL) {
3170 Status = EFI_OUT_OF_RESOURCES;
3171 goto ON_EXIT;
3172 }
3173
3174 Status = gRT->GetVariable (
3175 VariableName,
3176 &gEfiImageSecurityDatabaseGuid,
3177 &VariableAttr,
3178 &VariableDataSize,
3179 VariableData
3180 );
3181 if (EFI_ERROR (Status)) {
3182 goto ON_EXIT;
3183 }
3184
3185 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
3186 if (EFI_ERROR (Status)) {
3187 goto ON_EXIT;
3188 }
3189
3190 NewVariableData = AllocateZeroPool (VariableDataSize);
3191 if (NewVariableData == NULL) {
3192 Status = EFI_OUT_OF_RESOURCES;
3193 goto ON_EXIT;
3194 }
3195
3196 RemainingSize = VariableDataSize;
3197 ListWalker = (EFI_SIGNATURE_LIST *)(VariableData);
3198 if (DelType == Delete_Signature_List_All) {
3199 VariableDataSize = 0;
3200 } else {
3201 //
3202 // Traverse to target EFI_SIGNATURE_LIST but others will be skipped.
3203 //
3204 while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex < PrivateData->ListIndex) {
3205 CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, ListWalker->SignatureListSize);
3206 Offset += ListWalker->SignatureListSize;
3207
3208 RemainingSize -= ListWalker->SignatureListSize;
3209 ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
3210 ListIndex++;
3211 }
3212
3213 //
3214 // Handle the target EFI_SIGNATURE_LIST.
3215 // If CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) or DelType == Delete_Signature_List_One
3216 // it means delete the whole EFI_SIGNATURE_LIST, So we just skip this EFI_SIGNATURE_LIST.
3217 //
3218 if ((CheckedCount < SIGNATURE_DATA_COUNTS (ListWalker)) && (DelType == Delete_Signature_Data)) {
3219 NewCertList = (EFI_SIGNATURE_LIST *)(NewVariableData + Offset);
3220 //
3221 // Copy header.
3222 //
3223 CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
3224 Offset += sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize;
3225
3226 DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
3227 for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
3228 if (PrivateData->CheckArray[Index]) {
3229 //
3230 // Delete checked signature data, and update the size of whole signature list.
3231 //
3232 NewCertList->SignatureListSize -= NewCertList->SignatureSize;
3233 } else {
3234 //
3235 // Remain the unchecked signature data.
3236 //
3237 CopyMem ((UINT8 *)NewVariableData + Offset, DataWalker, ListWalker->SignatureSize);
3238 Offset += ListWalker->SignatureSize;
3239 }
3240
3241 DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
3242 }
3243 }
3244
3245 RemainingSize -= ListWalker->SignatureListSize;
3246 ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
3247
3248 //
3249 // Copy remaining data, maybe 0.
3250 //
3251 CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, RemainingSize);
3252 Offset += RemainingSize;
3253
3254 VariableDataSize = Offset;
3255 }
3256
3257 if ((VariableAttr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
3258 Status = GetCurrentTime (&Time);
3259 if (EFI_ERROR (Status)) {
3260 DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
3261 goto ON_EXIT;
3262 }
3263
3264 Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData, &Time);
3265 if (EFI_ERROR (Status)) {
3266 DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
3267 goto ON_EXIT;
3268 }
3269 }
3270
3271 Status = gRT->SetVariable (
3272 VariableName,
3273 &gEfiImageSecurityDatabaseGuid,
3274 VariableAttr,
3275 VariableDataSize,
3276 NewVariableData
3277 );
3278 if (EFI_ERROR (Status)) {
3279 DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r", Status));
3280 goto ON_EXIT;
3281 }
3282
3283ON_EXIT:
3284 SECUREBOOT_FREE_NON_NULL (VariableData);
3285 SECUREBOOT_FREE_NON_NULL (NewVariableData);
3286
3287 return Status;
3288}
3289
3304 )
3305{
3306 UINT8 *SecureBoot;
3307
3308 SecureBoot = NULL;
3309
3310 //
3311 // Get current secure boot state.
3312 //
3313 GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID **)&SecureBoot, NULL);
3314 if (SecureBoot == NULL) {
3315 return EFI_NOT_FOUND;
3316 }
3317
3318 if (*SecureBoot == SECURE_BOOT_MODE_ENABLE) {
3319 HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Enabled", NULL);
3320 } else {
3321 HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL);
3322 }
3323
3324 FreePool (SecureBoot);
3325
3326 return EFI_SUCCESS;
3327}
3328
3336VOID
3339 IN OUT SECUREBOOT_CONFIGURATION *ConfigData
3340 )
3341{
3342 UINT8 *SecureBootEnable;
3343 UINT8 *SetupMode;
3344 UINT8 *SecureBootMode;
3345 EFI_TIME CurrTime;
3346
3347 SecureBootEnable = NULL;
3348 SetupMode = NULL;
3349 SecureBootMode = NULL;
3350
3351 //
3352 // Initialize the Date and Time using system time.
3353 //
3354 ConfigData->CertificateFormat = HASHALG_RAW;
3355 ConfigData->AlwaysRevocation = TRUE;
3356 gRT->GetTime (&CurrTime, NULL);
3357 ConfigData->RevocationDate.Year = CurrTime.Year;
3358 ConfigData->RevocationDate.Month = CurrTime.Month;
3359 ConfigData->RevocationDate.Day = CurrTime.Day;
3360 ConfigData->RevocationTime.Hour = CurrTime.Hour;
3361 ConfigData->RevocationTime.Minute = CurrTime.Minute;
3362 ConfigData->RevocationTime.Second = 0;
3363 if (Private->FileContext->FHandle != NULL) {
3364 ConfigData->FileEnrollType = Private->FileContext->FileType;
3365 } else {
3366 ConfigData->FileEnrollType = UNKNOWN_FILE_TYPE;
3367 }
3368
3369 ConfigData->ListCount = Private->ListCount;
3370
3371 //
3372 // If it is Physical Presence User, set the PhysicalPresent to true.
3373 //
3374 if (UserPhysicalPresent ()) {
3375 ConfigData->PhysicalPresent = TRUE;
3376 } else {
3377 ConfigData->PhysicalPresent = FALSE;
3378 }
3379
3380 //
3381 // If there is no PK then the Delete Pk button will be gray.
3382 //
3383 GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID **)&SetupMode, NULL);
3384 if ((SetupMode == NULL) || ((*SetupMode) == SETUP_MODE)) {
3385 ConfigData->HasPk = FALSE;
3386 } else {
3387 ConfigData->HasPk = TRUE;
3388 }
3389
3390 //
3391 // Check SecureBootEnable & Pk status, fix the inconsistency.
3392 // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable
3393 // Checkbox.
3394 //
3395 ConfigData->AttemptSecureBoot = FALSE;
3396 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID **)&SecureBootEnable, NULL);
3397
3398 //
3399 // Fix Pk and SecureBootEnable inconsistency
3400 //
3401 if ((SetupMode != NULL) && ((*SetupMode) == USER_MODE)) {
3402 ConfigData->HideSecureBoot = FALSE;
3403 if ((SecureBootEnable != NULL) && (*SecureBootEnable == SECURE_BOOT_ENABLE)) {
3404 ConfigData->AttemptSecureBoot = TRUE;
3405 }
3406 } else {
3407 ConfigData->HideSecureBoot = TRUE;
3408 }
3409
3410 //
3411 // Get the SecureBootMode from CustomMode variable.
3412 //
3413 GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID **)&SecureBootMode, NULL);
3414 if (SecureBootMode == NULL) {
3415 ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;
3416 } else {
3417 ConfigData->SecureBootMode = *(SecureBootMode);
3418 }
3419
3420 if (SecureBootEnable != NULL) {
3421 FreePool (SecureBootEnable);
3422 }
3423
3424 if (SetupMode != NULL) {
3425 FreePool (SetupMode);
3426 }
3427
3428 if (SecureBootMode != NULL) {
3429 FreePool (SecureBootMode);
3430 }
3431}
3432
3460EFIAPI
3463 IN CONST EFI_STRING Request,
3464 OUT EFI_STRING *Progress,
3465 OUT EFI_STRING *Results
3466 )
3467{
3468 EFI_STATUS Status;
3469 UINTN BufferSize;
3470 UINTN Size;
3471 SECUREBOOT_CONFIGURATION Configuration;
3472 EFI_STRING ConfigRequest;
3473 EFI_STRING ConfigRequestHdr;
3474 SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData;
3475 BOOLEAN AllocatedRequest;
3476
3477 if ((Progress == NULL) || (Results == NULL)) {
3478 return EFI_INVALID_PARAMETER;
3479 }
3480
3481 AllocatedRequest = FALSE;
3482 ConfigRequestHdr = NULL;
3483 ConfigRequest = NULL;
3484 Size = 0;
3485
3486 ZeroMem (&Configuration, sizeof (Configuration));
3487 PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
3488 *Progress = Request;
3489
3490 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {
3491 return EFI_NOT_FOUND;
3492 }
3493
3494 ZeroMem (&Configuration, sizeof (SECUREBOOT_CONFIGURATION));
3495
3496 //
3497 // Get Configuration from Variable.
3498 //
3499 SecureBootExtractConfigFromVariable (PrivateData, &Configuration);
3500
3501 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
3502 ConfigRequest = Request;
3503 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
3504 //
3505 // Request is set to NULL or OFFSET is NULL, construct full request string.
3506 //
3507 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
3508 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
3509 //
3510 ConfigRequestHdr = HiiConstructConfigHdr (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, PrivateData->DriverHandle);
3511 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
3512 ConfigRequest = AllocateZeroPool (Size);
3513 ASSERT (ConfigRequest != NULL);
3514 AllocatedRequest = TRUE;
3515 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
3516 FreePool (ConfigRequestHdr);
3517 ConfigRequestHdr = NULL;
3518 }
3519
3520 Status = gHiiConfigRouting->BlockToConfig (
3522 ConfigRequest,
3523 (UINT8 *)&Configuration,
3524 BufferSize,
3525 Results,
3526 Progress
3527 );
3528
3529 //
3530 // Free the allocated config request string.
3531 //
3532 if (AllocatedRequest) {
3533 FreePool (ConfigRequest);
3534 }
3535
3536 //
3537 // Set Progress string to the original request string.
3538 //
3539 if (Request == NULL) {
3540 *Progress = NULL;
3541 } else if (StrStr (Request, L"OFFSET") == NULL) {
3542 *Progress = Request + StrLen (Request);
3543 }
3544
3545 return Status;
3546}
3547
3567EFIAPI
3570 IN CONST EFI_STRING Configuration,
3571 OUT EFI_STRING *Progress
3572 )
3573{
3574 SECUREBOOT_CONFIGURATION IfrNvData;
3575 UINTN BufferSize;
3576 SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData;
3577 EFI_STATUS Status;
3578
3579 if ((Configuration == NULL) || (Progress == NULL)) {
3580 return EFI_INVALID_PARAMETER;
3581 }
3582
3583 *Progress = Configuration;
3584 if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) {
3585 return EFI_NOT_FOUND;
3586 }
3587
3588 PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
3589
3590 //
3591 // Get Configuration from Variable.
3592 //
3593 SecureBootExtractConfigFromVariable (PrivateData, &IfrNvData);
3594
3595 //
3596 // Map the Configuration to the configuration block.
3597 //
3598 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
3599 Status = gHiiConfigRouting->ConfigToBlock (
3601 Configuration,
3602 (UINT8 *)&IfrNvData,
3603 &BufferSize,
3604 Progress
3605 );
3606 if (EFI_ERROR (Status)) {
3607 return Status;
3608 }
3609
3610 //
3611 // Store Buffer Storage back to EFI variable if needed
3612 //
3613 if (!IfrNvData.HideSecureBoot) {
3614 Status = SaveSecureBootVariable (IfrNvData.AttemptSecureBoot);
3615 if (EFI_ERROR (Status)) {
3616 return Status;
3617 }
3618 }
3619
3620 *Progress = Configuration + StrLen (Configuration);
3621 return EFI_SUCCESS;
3622}
3623
3638 IN UINT16 LabelId,
3639 IN EFI_FORM_ID FormId,
3640 IN EFI_QUESTION_ID QuestionIdBase
3641 )
3642{
3643 EFI_STATUS Status;
3644 EFI_STRING_ID ListType;
3645 EFI_STRING FormatNameString;
3646 EFI_STRING FormatHelpString;
3647 EFI_STRING FormatTypeString;
3648 EFI_SIGNATURE_LIST *ListWalker;
3649 EFI_IFR_GUID_LABEL *StartLabel;
3650 EFI_IFR_GUID_LABEL *EndLabel;
3651 EFI_IFR_GUID_LABEL *StartGoto;
3652 EFI_IFR_GUID_LABEL *EndGoto;
3653 EFI_FORM_ID DstFormId;
3654 VOID *StartOpCodeHandle;
3655 VOID *EndOpCodeHandle;
3656 VOID *StartGotoHandle;
3657 VOID *EndGotoHandle;
3658 UINTN DataSize;
3659 UINTN RemainingSize;
3660 UINT16 Index;
3661 UINT8 *VariableData;
3662 CHAR16 VariableName[BUFFER_MAX_SIZE];
3663 CHAR16 NameBuffer[BUFFER_MAX_SIZE];
3664 CHAR16 HelpBuffer[BUFFER_MAX_SIZE];
3665
3666 Status = EFI_SUCCESS;
3667 FormatNameString = NULL;
3668 FormatHelpString = NULL;
3669 StartOpCodeHandle = NULL;
3670 EndOpCodeHandle = NULL;
3671 StartGotoHandle = NULL;
3672 EndGotoHandle = NULL;
3673 Index = 0;
3674 VariableData = NULL;
3675
3676 //
3677 // Initialize the container for dynamic opcodes.
3678 //
3679 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
3680 if (StartOpCodeHandle == NULL) {
3681 Status = EFI_OUT_OF_RESOURCES;
3682 goto ON_EXIT;
3683 }
3684
3685 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
3686 if (EndOpCodeHandle == NULL) {
3687 Status = EFI_OUT_OF_RESOURCES;
3688 goto ON_EXIT;
3689 }
3690
3691 StartGotoHandle = HiiAllocateOpCodeHandle ();
3692 if (StartGotoHandle == NULL) {
3693 Status = EFI_OUT_OF_RESOURCES;
3694 goto ON_EXIT;
3695 }
3696
3697 EndGotoHandle = HiiAllocateOpCodeHandle ();
3698 if (EndGotoHandle == NULL) {
3699 Status = EFI_OUT_OF_RESOURCES;
3700 goto ON_EXIT;
3701 }
3702
3703 //
3704 // Create Hii Extend Label OpCode.
3705 //
3706 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
3707 StartOpCodeHandle,
3708 &gEfiIfrTianoGuid,
3709 NULL,
3710 sizeof (EFI_IFR_GUID_LABEL)
3711 );
3713 StartLabel->Number = LabelId;
3714
3716 EndOpCodeHandle,
3717 &gEfiIfrTianoGuid,
3718 NULL,
3719 sizeof (EFI_IFR_GUID_LABEL)
3720 );
3722 EndLabel->Number = LABEL_END;
3723
3725 StartGotoHandle,
3726 &gEfiIfrTianoGuid,
3727 NULL,
3728 sizeof (EFI_IFR_GUID_LABEL)
3729 );
3731 StartGoto->Number = LABEL_DELETE_ALL_LIST_BUTTON;
3732
3734 EndGotoHandle,
3735 &gEfiIfrTianoGuid,
3736 NULL,
3737 sizeof (EFI_IFR_GUID_LABEL)
3738 );
3740 EndGoto->Number = LABEL_END;
3741
3742 if (PrivateData->VariableName == Variable_DB) {
3743 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
3744 DstFormId = FORMID_SECURE_BOOT_DB_OPTION_FORM;
3745 } else if (PrivateData->VariableName == Variable_DBX) {
3746 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
3747 DstFormId = FORMID_SECURE_BOOT_DBX_OPTION_FORM;
3748 } else if (PrivateData->VariableName == Variable_DBT) {
3749 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE2);
3750 DstFormId = FORMID_SECURE_BOOT_DBT_OPTION_FORM;
3751 } else {
3752 goto ON_EXIT;
3753 }
3754
3756 StartGotoHandle,
3757 DstFormId,
3758 STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST),
3759 STRING_TOKEN (STR_SECURE_BOOT_DELETE_ALL_LIST),
3760 EFI_IFR_FLAG_CALLBACK,
3761 KEY_SECURE_BOOT_DELETE_ALL_LIST
3762 );
3763
3764 //
3765 // Read Variable, the variable name save in the PrivateData->VariableName.
3766 //
3767 DataSize = 0;
3768 Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
3769 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
3770 goto ON_EXIT;
3771 }
3772
3773 VariableData = AllocateZeroPool (DataSize);
3774 if (VariableData == NULL) {
3775 Status = EFI_OUT_OF_RESOURCES;
3776 goto ON_EXIT;
3777 }
3778
3779 Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
3780 if (EFI_ERROR (Status)) {
3781 goto ON_EXIT;
3782 }
3783
3784 FormatNameString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_NAME_FORMAT), NULL);
3785 FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT), NULL);
3786 if ((FormatNameString == NULL) || (FormatHelpString == NULL)) {
3787 goto ON_EXIT;
3788 }
3789
3790 RemainingSize = DataSize;
3791 ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
3792 while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
3793 if (CompareGuid (&ListWalker->SignatureType, &gEfiCertRsa2048Guid)) {
3794 ListType = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
3795 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
3796 ListType = STRING_TOKEN (STR_LIST_TYPE_X509);
3797 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha1Guid)) {
3798 ListType = STRING_TOKEN (STR_LIST_TYPE_SHA1);
3799 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
3800 ListType = STRING_TOKEN (STR_LIST_TYPE_SHA256);
3801 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Guid)) {
3802 ListType = STRING_TOKEN (STR_LIST_TYPE_SHA384);
3803 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Guid)) {
3804 ListType = STRING_TOKEN (STR_LIST_TYPE_SHA512);
3805 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
3806 ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
3807 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
3808 ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA384);
3809 } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha512Guid)) {
3810 ListType = STRING_TOKEN (STR_LIST_TYPE_X509_SHA512);
3811 } else {
3812 ListType = STRING_TOKEN (STR_LIST_TYPE_UNKNOWN);
3813 }
3814
3815 FormatTypeString = HiiGetString (PrivateData->HiiHandle, ListType, NULL);
3816 if (FormatTypeString == NULL) {
3817 goto ON_EXIT;
3818 }
3819
3820 ZeroMem (NameBuffer, sizeof (NameBuffer));
3821 UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1);
3822
3823 ZeroMem (HelpBuffer, sizeof (HelpBuffer));
3825 HelpBuffer,
3826 sizeof (HelpBuffer),
3827 FormatHelpString,
3828 FormatTypeString,
3829 SIGNATURE_DATA_COUNTS (ListWalker)
3830 );
3831 SECUREBOOT_FREE_NON_NULL (FormatTypeString);
3832 FormatTypeString = NULL;
3833
3835 StartOpCodeHandle,
3836 SECUREBOOT_DELETE_SIGNATURE_DATA_FORM,
3837 HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
3838 HiiSetString (PrivateData->HiiHandle, 0, HelpBuffer, NULL),
3839 EFI_IFR_FLAG_CALLBACK,
3840 QuestionIdBase + Index++
3841 );
3842
3843 RemainingSize -= ListWalker->SignatureListSize;
3844 ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
3845 }
3846
3847ON_EXIT:
3849 PrivateData->HiiHandle,
3850 &gSecureBootConfigFormSetGuid,
3851 FormId,
3852 StartOpCodeHandle,
3853 EndOpCodeHandle
3854 );
3855
3857 PrivateData->HiiHandle,
3858 &gSecureBootConfigFormSetGuid,
3859 FormId,
3860 StartGotoHandle,
3861 EndGotoHandle
3862 );
3863
3864 SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle);
3865 SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle);
3866 SECUREBOOT_FREE_NON_OPCODE (StartGotoHandle);
3867 SECUREBOOT_FREE_NON_OPCODE (EndGotoHandle);
3868
3869 SECUREBOOT_FREE_NON_NULL (VariableData);
3870 SECUREBOOT_FREE_NON_NULL (FormatNameString);
3871 SECUREBOOT_FREE_NON_NULL (FormatHelpString);
3872
3873 PrivateData->ListCount = Index;
3874
3875 return Status;
3876}
3877
3892 IN EFI_SIGNATURE_LIST *ListEntry,
3893 IN EFI_SIGNATURE_DATA *DataEntry,
3894 OUT CHAR16 **BufferToReturn
3895 )
3896{
3897 UINTN Index;
3898 UINTN BufferIndex;
3899 UINTN TotalSize;
3900 UINTN DataSize;
3901 UINTN Line;
3902 UINTN OneLineBytes;
3903
3904 //
3905 // Assume that, display 8 bytes in one line.
3906 //
3907 OneLineBytes = 8;
3908
3909 if ((ListEntry == NULL) || (DataEntry == NULL) || (BufferToReturn == NULL)) {
3910 return EFI_INVALID_PARAMETER;
3911 }
3912
3913 DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
3914 Line = (DataSize + OneLineBytes - 1) / OneLineBytes;
3915
3916 //
3917 // Each byte will split two Hex-number, and each line need additional memory to save '\r\n'.
3918 //
3919 TotalSize = ((DataSize + Line) * 2 * sizeof (CHAR16));
3920
3921 *BufferToReturn = AllocateZeroPool (TotalSize);
3922 if (*BufferToReturn == NULL) {
3923 return EFI_OUT_OF_RESOURCES;
3924 }
3925
3926 for (Index = 0, BufferIndex = 0; Index < DataSize; Index = Index + 1) {
3927 if ((Index > 0) && (Index % OneLineBytes == 0)) {
3928 BufferIndex += UnicodeSPrint (&(*BufferToReturn)[BufferIndex], TotalSize - sizeof (CHAR16) * BufferIndex, L"\n");
3929 }
3930
3931 BufferIndex += UnicodeSPrint (&(*BufferToReturn)[BufferIndex], TotalSize - sizeof (CHAR16) * BufferIndex, L"%02x", DataEntry->SignatureData[Index]);
3932 }
3933
3934 BufferIndex += UnicodeSPrint (&(*BufferToReturn)[BufferIndex], TotalSize - sizeof (CHAR16) * BufferIndex, L"\n");
3935
3936 return EFI_SUCCESS;
3937}
3938
3954 IN EFI_SIGNATURE_LIST *ListEntry,
3955 IN EFI_SIGNATURE_DATA *DataEntry,
3956 OUT CHAR16 **BufferToReturn
3957 )
3958{
3959 EFI_STATUS Status;
3960 CHAR8 *CNBuffer;
3961 UINTN CNBufferSize;
3962
3963 Status = EFI_SUCCESS;
3964 CNBuffer = NULL;
3965
3966 CNBuffer = AllocateZeroPool (256);
3967 if (CNBuffer == NULL) {
3968 Status = EFI_OUT_OF_RESOURCES;
3969 goto ON_EXIT;
3970 }
3971
3972 CNBufferSize = 256;
3974 (UINT8 *)DataEntry + sizeof (EFI_GUID),
3975 ListEntry->SignatureSize - sizeof (EFI_GUID),
3976 CNBuffer,
3977 &CNBufferSize
3978 );
3979
3980 *BufferToReturn = AllocateZeroPool (256 * sizeof (CHAR16));
3981 if (*BufferToReturn == NULL) {
3982 Status = EFI_OUT_OF_RESOURCES;
3983 goto ON_EXIT;
3984 }
3985
3986 AsciiStrToUnicodeStrS (CNBuffer, *BufferToReturn, 256);
3987
3988ON_EXIT:
3989 SECUREBOOT_FREE_NON_NULL (CNBuffer);
3990
3991 return Status;
3992}
3993
4011 IN EFI_SIGNATURE_LIST *ListEntry,
4012 IN EFI_SIGNATURE_DATA *DataEntry,
4013 OUT EFI_STRING_ID *StringId
4014 )
4015{
4016 EFI_STATUS Status;
4017 EFI_TIME *Time;
4018 EFI_STRING_ID ListTypeId;
4019 EFI_STRING FormatHelpString;
4020 EFI_STRING FormatTypeString;
4021 UINTN DataSize;
4022 UINTN HelpInfoIndex;
4023 UINTN TotalSize;
4024 CHAR16 GuidString[BUFFER_MAX_SIZE];
4025 CHAR16 TimeString[BUFFER_MAX_SIZE];
4026 CHAR16 *DataString;
4027 CHAR16 *HelpInfoString;
4028 BOOLEAN IsCert;
4029
4030 Status = EFI_SUCCESS;
4031 Time = NULL;
4032 FormatTypeString = NULL;
4033 HelpInfoIndex = 0;
4034 DataString = NULL;
4035 HelpInfoString = NULL;
4036 IsCert = FALSE;
4037
4038 if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa2048Guid)) {
4039 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
4040 DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
4041 IsCert = TRUE;
4042 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
4043 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
4044 DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
4045 IsCert = TRUE;
4046 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha1Guid)) {
4047 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA1);
4048 DataSize = 20;
4049 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
4050 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
4051 DataSize = 32;
4052 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
4053 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
4054 DataSize = 48;
4055 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
4056 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
4057 DataSize = 64;
4058 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
4059 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
4060 DataSize = 32;
4061 Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
4062 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha384Guid)) {
4063 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA384);
4064 DataSize = 48;
4065 Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
4066 } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha512Guid)) {
4067 ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA512);
4068 DataSize = 64;
4069 Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
4070 } else {
4071 Status = EFI_UNSUPPORTED;
4072 goto ON_EXIT;
4073 }
4074
4075 FormatTypeString = HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL);
4076 if (FormatTypeString == NULL) {
4077 goto ON_EXIT;
4078 }
4079
4080 TotalSize = 1024;
4081 HelpInfoString = AllocateZeroPool (TotalSize);
4082 if (HelpInfoString == NULL) {
4083 Status = EFI_OUT_OF_RESOURCES;
4084 goto ON_EXIT;
4085 }
4086
4087 //
4088 // Format GUID part.
4089 //
4090 ZeroMem (GuidString, sizeof (GuidString));
4091 GuidToString (&DataEntry->SignatureOwner, GuidString, BUFFER_MAX_SIZE);
4092 FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID), NULL);
4093 if (FormatHelpString == NULL) {
4094 goto ON_EXIT;
4095 }
4096
4097 HelpInfoIndex += UnicodeSPrint (
4098 &HelpInfoString[HelpInfoIndex],
4099 TotalSize - sizeof (CHAR16) * HelpInfoIndex,
4100 FormatHelpString,
4101 GuidString
4102 );
4103 SECUREBOOT_FREE_NON_NULL (FormatHelpString);
4104 FormatHelpString = NULL;
4105
4106 //
4107 // Format content part, it depends on the type of signature list, hash value or CN.
4108 //
4109 if (IsCert) {
4110 GetCommonNameFromX509 (ListEntry, DataEntry, &DataString);
4111 FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_CN), NULL);
4112 } else {
4113 //
4114 // Format hash value for each signature data entry.
4115 //
4116 ParseHashValue (ListEntry, DataEntry, &DataString);
4117 FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH), NULL);
4118 }
4119
4120 if (FormatHelpString == NULL) {
4121 goto ON_EXIT;
4122 }
4123
4124 HelpInfoIndex += UnicodeSPrint (
4125 &HelpInfoString[HelpInfoIndex],
4126 TotalSize - sizeof (CHAR16) * HelpInfoIndex,
4127 FormatHelpString,
4128 FormatTypeString,
4129 DataSize,
4130 DataString
4131 );
4132 SECUREBOOT_FREE_NON_NULL (FormatHelpString);
4133 FormatHelpString = NULL;
4134
4135 //
4136 // Format revocation time part.
4137 //
4138 if (Time != NULL) {
4139 ZeroMem (TimeString, sizeof (TimeString));
4141 TimeString,
4142 sizeof (TimeString),
4143 L"%d-%d-%d %d:%d:%d",
4144 Time->Year,
4145 Time->Month,
4146 Time->Day,
4147 Time->Hour,
4148 Time->Minute,
4149 Time->Second
4150 );
4151 FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME), NULL);
4152 if (FormatHelpString == NULL) {
4153 goto ON_EXIT;
4154 }
4155
4157 &HelpInfoString[HelpInfoIndex],
4158 TotalSize - sizeof (CHAR16) * HelpInfoIndex,
4159 FormatHelpString,
4160 TimeString
4161 );
4162 SECUREBOOT_FREE_NON_NULL (FormatHelpString);
4163 FormatHelpString = NULL;
4164 }
4165
4166 *StringId = HiiSetString (PrivateData->HiiHandle, 0, HelpInfoString, NULL);
4167ON_EXIT:
4168 SECUREBOOT_FREE_NON_NULL (DataString);
4169 SECUREBOOT_FREE_NON_NULL (HelpInfoString);
4170
4171 SECUREBOOT_FREE_NON_NULL (FormatTypeString);
4172
4173 return Status;
4174}
4175
4191 IN UINT16 LabelId,
4192 IN EFI_FORM_ID FormId,
4193 IN EFI_QUESTION_ID QuestionIdBase,
4194 IN UINT16 ListIndex
4195 )
4196{
4197 EFI_STATUS Status;
4198 EFI_SIGNATURE_LIST *ListWalker;
4199 EFI_SIGNATURE_DATA *DataWalker;
4200 EFI_IFR_GUID_LABEL *StartLabel;
4201 EFI_IFR_GUID_LABEL *EndLabel;
4202 EFI_STRING_ID HelpStringId;
4203 EFI_STRING FormatNameString;
4204 VOID *StartOpCodeHandle;
4205 VOID *EndOpCodeHandle;
4206 UINTN DataSize;
4207 UINTN RemainingSize;
4208 UINT16 Index;
4209 UINT8 *VariableData;
4210 CHAR16 VariableName[BUFFER_MAX_SIZE];
4211 CHAR16 NameBuffer[BUFFER_MAX_SIZE];
4212
4213 Status = EFI_SUCCESS;
4214 FormatNameString = NULL;
4215 StartOpCodeHandle = NULL;
4216 EndOpCodeHandle = NULL;
4217 Index = 0;
4218 VariableData = NULL;
4219
4220 //
4221 // Initialize the container for dynamic opcodes.
4222 //
4223 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
4224 if (StartOpCodeHandle == NULL) {
4225 Status = EFI_OUT_OF_RESOURCES;
4226 goto ON_EXIT;
4227 }
4228
4229 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
4230 if (EndOpCodeHandle == NULL) {
4231 Status = EFI_OUT_OF_RESOURCES;
4232 goto ON_EXIT;
4233 }
4234
4235 //
4236 // Create Hii Extend Label OpCode.
4237 //
4238 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
4239 StartOpCodeHandle,
4240 &gEfiIfrTianoGuid,
4241 NULL,
4242 sizeof (EFI_IFR_GUID_LABEL)
4243 );
4245 StartLabel->Number = LabelId;
4246
4248 EndOpCodeHandle,
4249 &gEfiIfrTianoGuid,
4250 NULL,
4251 sizeof (EFI_IFR_GUID_LABEL)
4252 );
4254 EndLabel->Number = LABEL_END;
4255
4256 if (PrivateData->VariableName == Variable_DB) {
4257 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
4258 } else if (PrivateData->VariableName == Variable_DBX) {
4259 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
4260 } else if (PrivateData->VariableName == Variable_DBT) {
4261 UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE2);
4262 } else {
4263 goto ON_EXIT;
4264 }
4265
4266 //
4267 // Read Variable, the variable name save in the PrivateData->VariableName.
4268 //
4269 DataSize = 0;
4270 Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
4271 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
4272 goto ON_EXIT;
4273 }
4274
4275 VariableData = AllocateZeroPool (DataSize);
4276 if (VariableData == NULL) {
4277 Status = EFI_OUT_OF_RESOURCES;
4278 goto ON_EXIT;
4279 }
4280
4281 Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
4282 if (EFI_ERROR (Status)) {
4283 goto ON_EXIT;
4284 }
4285
4286 RemainingSize = DataSize;
4287 ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
4288
4289 //
4290 // Skip signature list.
4291 //
4292 while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex-- > 0) {
4293 RemainingSize -= ListWalker->SignatureListSize;
4294 ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
4295 }
4296
4297 FormatNameString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_NAME_FORMAT), NULL);
4298 if (FormatNameString == NULL) {
4299 goto ON_EXIT;
4300 }
4301
4302 DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
4303 for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
4304 //
4305 // Format name buffer.
4306 //
4307 ZeroMem (NameBuffer, sizeof (NameBuffer));
4308 UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1);
4309
4310 //
4311 // Format help info buffer.
4312 //
4313 Status = FormatHelpInfo (PrivateData, ListWalker, DataWalker, &HelpStringId);
4314 if (EFI_ERROR (Status)) {
4315 goto ON_EXIT;
4316 }
4317
4319 StartOpCodeHandle,
4320 (EFI_QUESTION_ID)(QuestionIdBase + Index),
4321 0,
4322 0,
4323 HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
4324 HelpStringId,
4325 EFI_IFR_FLAG_CALLBACK,
4326 0,
4327 NULL
4328 );
4329
4330 ZeroMem (NameBuffer, 100);
4331 DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
4332 }
4333
4334 //
4335 // Allocate a buffer to record which signature data will be checked.
4336 // This memory buffer will be freed when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
4337 //
4338 PrivateData->CheckArray = AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker) * sizeof (BOOLEAN));
4339ON_EXIT:
4341 PrivateData->HiiHandle,
4342 &gSecureBootConfigFormSetGuid,
4343 FormId,
4344 StartOpCodeHandle,
4345 EndOpCodeHandle
4346 );
4347
4348 SECUREBOOT_FREE_NON_OPCODE (StartOpCodeHandle);
4349 SECUREBOOT_FREE_NON_OPCODE (EndOpCodeHandle);
4350
4351 SECUREBOOT_FREE_NON_NULL (VariableData);
4352 SECUREBOOT_FREE_NON_NULL (FormatNameString);
4353
4354 return Status;
4355}
4356
4364EFIAPI
4366 VOID
4367 )
4368{
4369 EFI_STATUS Status;
4370 UINT8 SetupMode;
4371
4372 Status = EFI_SUCCESS;
4373
4374 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
4375 if (EFI_ERROR (Status)) {
4376 return Status;
4377 }
4378
4379 // Clear all the keys and databases
4380 Status = DeleteDb ();
4381 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
4382 DEBUG ((DEBUG_ERROR, "Fail to clear DB: %r\n", Status));
4383 return Status;
4384 }
4385
4386 Status = DeleteDbx ();
4387 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
4388 DEBUG ((DEBUG_ERROR, "Fail to clear DBX: %r\n", Status));
4389 return Status;
4390 }
4391
4392 Status = DeleteDbt ();
4393 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
4394 DEBUG ((DEBUG_ERROR, "Fail to clear DBT: %r\n", Status));
4395 return Status;
4396 }
4397
4398 Status = DeleteKEK ();
4399 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
4400 DEBUG ((DEBUG_ERROR, "Fail to clear KEK: %r\n", Status));
4401 return Status;
4402 }
4403
4404 Status = DeletePlatformKey ();
4405 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
4406 DEBUG ((DEBUG_ERROR, "Fail to clear PK: %r\n", Status));
4407 return Status;
4408 }
4409
4410 // After PK clear, Setup Mode shall be enabled
4411 Status = GetSetupMode (&SetupMode);
4412 if (EFI_ERROR (Status)) {
4413 DEBUG ((
4414 DEBUG_ERROR,
4415 "Cannot get SetupMode variable: %r\n",
4416 Status
4417 ));
4418 return Status;
4419 }
4420
4421 if (SetupMode == USER_MODE) {
4422 DEBUG ((DEBUG_INFO, "Skipped - USER_MODE\n"));
4423 return EFI_SUCCESS;
4424 }
4425
4426 Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
4427 if (EFI_ERROR (Status)) {
4428 DEBUG ((
4429 DEBUG_ERROR,
4430 "Cannot set CUSTOM_SECURE_BOOT_MODE: %r\n",
4431 Status
4432 ));
4433 return EFI_SUCCESS;
4434 }
4435
4436 // Enroll all the keys from default variables
4437 Status = EnrollDbFromDefault ();
4438 if (EFI_ERROR (Status)) {
4439 DEBUG ((DEBUG_ERROR, "Cannot enroll db: %r\n", Status));
4440 goto error;
4441 }
4442
4443 Status = EnrollDbxFromDefault ();
4444 if (EFI_ERROR (Status)) {
4445 DEBUG ((DEBUG_ERROR, "Cannot enroll dbx: %r\n", Status));
4446 }
4447
4448 Status = EnrollDbtFromDefault ();
4449 if (EFI_ERROR (Status)) {
4450 DEBUG ((DEBUG_ERROR, "Cannot enroll dbt: %r\n", Status));
4451 }
4452
4453 Status = EnrollKEKFromDefault ();
4454 if (EFI_ERROR (Status)) {
4455 DEBUG ((DEBUG_ERROR, "Cannot enroll KEK: %r\n", Status));
4456 goto cleardbs;
4457 }
4458
4459 Status = EnrollPKFromDefault ();
4460 if (EFI_ERROR (Status)) {
4461 DEBUG ((DEBUG_ERROR, "Cannot enroll PK: %r\n", Status));
4462 goto clearKEK;
4463 }
4464
4465 Status = SetSecureBootMode (STANDARD_SECURE_BOOT_MODE);
4466 if (EFI_ERROR (Status)) {
4467 DEBUG ((
4468 DEBUG_ERROR,
4469 "Cannot set CustomMode to STANDARD_SECURE_BOOT_MODE\n"
4470 "Please do it manually, otherwise system can be easily compromised\n"
4471 ));
4472 }
4473
4474 return Status;
4475
4476clearKEK:
4477 DeleteKEK ();
4478
4479cleardbs:
4480 DeleteDbt ();
4481 DeleteDbx ();
4482 DeleteDb ();
4483
4484error:
4485 if (SetSecureBootMode (STANDARD_SECURE_BOOT_MODE) != EFI_SUCCESS) {
4486 DEBUG ((DEBUG_ERROR, "Cannot set mode to Secure: %r\n", Status));
4487 }
4488
4489 return Status;
4490}
4491
4515EFIAPI
4518 IN EFI_BROWSER_ACTION Action,
4519 IN EFI_QUESTION_ID QuestionId,
4520 IN UINT8 Type,
4521 IN EFI_IFR_TYPE_VALUE *Value,
4522 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
4523 )
4524{
4525 EFI_INPUT_KEY Key;
4526 EFI_STATUS Status;
4527 RETURN_STATUS RStatus;
4529 UINTN BufferSize;
4530 SECUREBOOT_CONFIGURATION *IfrNvData;
4531 UINT16 LabelId;
4532 UINT8 *SecureBootEnable;
4533 UINT8 *Pk;
4534 UINT8 *SecureBootMode;
4535 UINT8 *SetupMode;
4536 CHAR16 PromptString[100];
4538 UINTN NameLength;
4539 UINT16 *FilePostFix;
4540 SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData;
4541 BOOLEAN GetBrowserDataResult;
4542 ENROLL_KEY_ERROR EnrollKeyErrorCode;
4543 EFI_HII_POPUP_PROTOCOL *HiiPopup;
4544 EFI_HII_POPUP_SELECTION UserSelection;
4545
4546 Status = EFI_SUCCESS;
4547 SecureBootEnable = NULL;
4548 SecureBootMode = NULL;
4549 SetupMode = NULL;
4550 File = NULL;
4551 EnrollKeyErrorCode = None_Error;
4552 GetBrowserDataResult = FALSE;
4553
4554 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
4555 return EFI_INVALID_PARAMETER;
4556 }
4557
4558 Private = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
4559
4560 gSecureBootPrivateData = Private;
4561
4562 //
4563 // Retrieve uncommitted data from Browser
4564 //
4565 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
4566 IfrNvData = AllocateZeroPool (BufferSize);
4567 if (IfrNvData == NULL) {
4568 return EFI_OUT_OF_RESOURCES;
4569 }
4570
4571 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
4572 if (QuestionId == KEY_SECURE_BOOT_MODE) {
4573 //
4574 // Update secure boot strings when opening this form
4575 //
4576 Status = UpdateSecureBootString (Private);
4577 mIsEnterSecureBootForm = TRUE;
4578 } else {
4579 //
4580 // When entering SecureBoot OPTION Form
4581 // always close opened file & free resource
4582 //
4583 if ((QuestionId == KEY_SECURE_BOOT_PK_OPTION) ||
4584 (QuestionId == KEY_SECURE_BOOT_KEK_OPTION) ||
4585 (QuestionId == KEY_SECURE_BOOT_DB_OPTION) ||
4586 (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) ||
4587 (QuestionId == KEY_SECURE_BOOT_DBT_OPTION))
4588 {
4589 CloseEnrolledFile (Private->FileContext);
4590 }
4591 }
4592
4593 goto EXIT;
4594 }
4595
4596 GetBrowserDataResult = HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *)IfrNvData);
4597
4598 if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
4599 Status = EFI_UNSUPPORTED;
4600 if (QuestionId == KEY_SECURE_BOOT_MODE) {
4601 if (mIsEnterSecureBootForm) {
4602 if (GetBrowserDataResult) {
4603 SecureBootExtractConfigFromVariable (Private, IfrNvData);
4604 }
4605
4606 Value->u8 = SECURE_BOOT_MODE_STANDARD;
4607 Status = EFI_SUCCESS;
4608 }
4609 }
4610
4611 goto EXIT;
4612 }
4613
4614 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
4615 (Action != EFI_BROWSER_ACTION_CHANGING) &&
4616 (Action != EFI_BROWSER_ACTION_FORM_CLOSE) &&
4617 (Action != EFI_BROWSER_ACTION_DEFAULT_STANDARD))
4618 {
4619 Status = EFI_UNSUPPORTED;
4620 goto EXIT;
4621 }
4622
4623 if (Action == EFI_BROWSER_ACTION_CHANGING) {
4624 switch (QuestionId) {
4625 case KEY_SECURE_BOOT_ENABLE:
4626 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID **)&SecureBootEnable, NULL);
4627 if (NULL != SecureBootEnable) {
4628 FreePool (SecureBootEnable);
4629 if (EFI_ERROR (SaveSecureBootVariable (Value->u8))) {
4630 CreatePopUp (
4631 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4632 &Key,
4633 L"Only Physical Presence User could disable secure boot!",
4634 NULL
4635 );
4636 Status = EFI_UNSUPPORTED;
4637 } else {
4638 CreatePopUp (
4639 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4640 &Key,
4641 L"Configuration changed, please reset the platform to take effect!",
4642 NULL
4643 );
4644 }
4645 }
4646
4647 break;
4648
4649 case KEY_SECURE_BOOT_KEK_OPTION:
4650 case KEY_SECURE_BOOT_DB_OPTION:
4651 case KEY_SECURE_BOOT_DBX_OPTION:
4652 case KEY_SECURE_BOOT_DBT_OPTION:
4653 PrivateData = SECUREBOOT_CONFIG_PRIVATE_FROM_THIS (This);
4654 //
4655 // Clear Signature GUID.
4656 //
4657 ZeroMem (IfrNvData->SignatureGuid, sizeof (IfrNvData->SignatureGuid));
4658 if (Private->SignatureGUID == NULL) {
4659 Private->SignatureGUID = (EFI_GUID *)AllocateZeroPool (sizeof (EFI_GUID));
4660 if (Private->SignatureGUID == NULL) {
4661 return EFI_OUT_OF_RESOURCES;
4662 }
4663 }
4664
4665 //
4666 // Cleanup VFRData once leaving PK/KEK/DB/DBX/DBT enroll/delete page
4667 //
4668 SecureBootExtractConfigFromVariable (PrivateData, IfrNvData);
4669
4670 if (QuestionId == KEY_SECURE_BOOT_DB_OPTION) {
4671 LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
4672 } else if (QuestionId == KEY_SECURE_BOOT_DBX_OPTION) {
4673 LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
4674 } else if (QuestionId == KEY_SECURE_BOOT_DBT_OPTION) {
4675 LabelId = SECUREBOOT_ENROLL_SIGNATURE_TO_DBT;
4676 } else {
4677 LabelId = FORMID_ENROLL_KEK_FORM;
4678 }
4679
4680 //
4681 // Refresh selected file.
4682 //
4683 CleanUpPage (LabelId, Private);
4684 break;
4685 case KEY_SECURE_BOOT_PK_OPTION:
4686 LabelId = FORMID_ENROLL_PK_FORM;
4687 //
4688 // Refresh selected file.
4689 //
4690 CleanUpPage (LabelId, Private);
4691 break;
4692
4693 case FORMID_ENROLL_PK_FORM:
4695 break;
4696
4697 case FORMID_ENROLL_KEK_FORM:
4699 break;
4700
4701 case SECUREBOOT_ENROLL_SIGNATURE_TO_DB:
4703 break;
4704
4705 case SECUREBOOT_ENROLL_SIGNATURE_TO_DBX:
4707
4708 if (Private->FileContext->FHandle != NULL) {
4709 //
4710 // Parse the file's postfix.
4711 //
4712 NameLength = StrLen (Private->FileContext->FileName);
4713 if (NameLength <= 4) {
4714 return FALSE;
4715 }
4716
4717 FilePostFix = Private->FileContext->FileName + NameLength - 4;
4718
4719 if (IsDerEncodeCertificate (FilePostFix)) {
4720 //
4721 // Supports DER-encoded X509 certificate.
4722 //
4723 IfrNvData->FileEnrollType = X509_CERT_FILE_TYPE;
4724 } else if (IsAuthentication2Format (Private->FileContext->FHandle)) {
4725 IfrNvData->FileEnrollType = AUTHENTICATION_2_FILE_TYPE;
4726 } else {
4727 IfrNvData->FileEnrollType = PE_IMAGE_FILE_TYPE;
4728 }
4729
4730 Private->FileContext->FileType = IfrNvData->FileEnrollType;
4731
4732 //
4733 // Clean up Certificate Format if File type is not X509 DER
4734 //
4735 if (IfrNvData->FileEnrollType != X509_CERT_FILE_TYPE) {
4736 IfrNvData->CertificateFormat = HASHALG_RAW;
4737 }
4738
4739 DEBUG ((DEBUG_ERROR, "IfrNvData->FileEnrollType %d\n", Private->FileContext->FileType));
4740 }
4741
4742 break;
4743
4744 case SECUREBOOT_ENROLL_SIGNATURE_TO_DBT:
4746 break;
4747
4748 case KEY_SECURE_BOOT_DELETE_PK:
4749 if (Value->u8) {
4750 CreatePopUp (
4751 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4752 &Key,
4753 L"Are you sure you want to delete PK? Secure boot will be disabled!",
4754 L"Press 'Y' to delete PK and exit, 'N' to discard change and return",
4755 NULL
4756 );
4757 if ((Key.UnicodeChar == 'y') || (Key.UnicodeChar == 'Y')) {
4758 Status = DeletePlatformKey ();
4759 if (EFI_ERROR (Status)) {
4760 CreatePopUp (
4761 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4762 &Key,
4763 L"Only Physical Presence User could delete PK in custom mode!",
4764 NULL
4765 );
4766 } else {
4767 SecureBootExtractConfigFromVariable (Private, IfrNvData);
4768 }
4769 }
4770 }
4771
4772 break;
4773
4774 case KEY_DELETE_KEK:
4776 Private,
4778 &gEfiGlobalVariableGuid,
4779 LABEL_KEK_DELETE,
4780 FORMID_DELETE_KEK_FORM,
4781 OPTION_DEL_KEK_QUESTION_ID
4782 );
4783 break;
4784
4785 case SECUREBOOT_DELETE_SIGNATURE_FROM_DB:
4787 Private,
4789 &gEfiImageSecurityDatabaseGuid,
4790 LABEL_DB_DELETE,
4791 SECUREBOOT_DELETE_SIGNATURE_FROM_DB,
4792 OPTION_DEL_DB_QUESTION_ID
4793 );
4794 break;
4795
4796 //
4797 // From DBX option to the level-1 form, display signature list.
4798 //
4799 case KEY_VALUE_FROM_DBX_TO_LIST_FORM:
4800 Private->VariableName = Variable_DBX;
4802 Private,
4803 LABEL_SIGNATURE_LIST_START,
4804 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
4805 OPTION_SIGNATURE_LIST_QUESTION_ID
4806 );
4807 break;
4808
4809 //
4810 // Delete all signature list and reload.
4811 //
4812 case KEY_SECURE_BOOT_DELETE_ALL_LIST:
4813 CreatePopUp (
4814 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4815 &Key,
4816 L"Press 'Y' to delete signature list.",
4817 L"Press other key to cancel and exit.",
4818 NULL
4819 );
4820
4821 if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
4822 DeleteSignatureEx (Private, Delete_Signature_List_All, IfrNvData->CheckedDataCount);
4823 }
4824
4826 Private,
4827 LABEL_SIGNATURE_LIST_START,
4828 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
4829 OPTION_SIGNATURE_LIST_QUESTION_ID
4830 );
4831 IfrNvData->ListCount = Private->ListCount;
4832 break;
4833
4834 //
4835 // Delete one signature list and reload.
4836 //
4837 case KEY_SECURE_BOOT_DELETE_ALL_DATA:
4838 CreatePopUp (
4839 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4840 &Key,
4841 L"Press 'Y' to delete signature data.",
4842 L"Press other key to cancel and exit.",
4843 NULL
4844 );
4845
4846 if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
4847 DeleteSignatureEx (Private, Delete_Signature_List_One, IfrNvData->CheckedDataCount);
4848 }
4849
4851 Private,
4852 LABEL_SIGNATURE_LIST_START,
4853 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
4854 OPTION_SIGNATURE_LIST_QUESTION_ID
4855 );
4856 IfrNvData->ListCount = Private->ListCount;
4857 break;
4858
4859 //
4860 // Delete checked signature data and reload.
4861 //
4862 case KEY_SECURE_BOOT_DELETE_CHECK_DATA:
4863 CreatePopUp (
4864 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4865 &Key,
4866 L"Press 'Y' to delete signature data.",
4867 L"Press other key to cancel and exit.",
4868 NULL
4869 );
4870
4871 if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
4872 DeleteSignatureEx (Private, Delete_Signature_Data, IfrNvData->CheckedDataCount);
4873 }
4874
4876 Private,
4877 LABEL_SIGNATURE_LIST_START,
4878 SECUREBOOT_DELETE_SIGNATURE_LIST_FORM,
4879 OPTION_SIGNATURE_LIST_QUESTION_ID
4880 );
4881 IfrNvData->ListCount = Private->ListCount;
4882 break;
4883
4884 case SECUREBOOT_DELETE_SIGNATURE_FROM_DBT:
4886 Private,
4888 &gEfiImageSecurityDatabaseGuid,
4889 LABEL_DBT_DELETE,
4890 SECUREBOOT_DELETE_SIGNATURE_FROM_DBT,
4891 OPTION_DEL_DBT_QUESTION_ID
4892 );
4893
4894 break;
4895
4896 case KEY_VALUE_SAVE_AND_EXIT_KEK:
4897 Status = EnrollKeyExchangeKey (Private);
4898 if (EFI_ERROR (Status)) {
4899 CreatePopUp (
4900 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4901 &Key,
4902 L"ERROR: Unsupported file type!",
4903 L"Only supports DER-encoded X509 certificate",
4904 NULL
4905 );
4906 }
4907
4908 break;
4909
4910 case KEY_VALUE_SAVE_AND_EXIT_DB:
4912 if (EFI_ERROR (Status)) {
4913 CreatePopUp (
4914 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4915 &Key,
4916 L"ERROR: Unsupported file type!",
4917 L"Only supports DER-encoded X509 certificate and executable EFI image",
4918 NULL
4919 );
4920 }
4921
4922 break;
4923
4924 case KEY_VALUE_SAVE_AND_EXIT_DBX:
4926 CreatePopUp (
4927 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4928 &Key,
4929 L"Enrollment failed! Same certificate had already been in the dbx!",
4930 NULL
4931 );
4932
4933 //
4934 // Cert already exists in DBX. Close opened file before exit.
4935 //
4936 CloseEnrolledFile (Private->FileContext);
4937 break;
4938 }
4939
4940 if ((IfrNvData != NULL) && (IfrNvData->CertificateFormat < HASHALG_MAX)) {
4941 Status = EnrollX509HashtoSigDB (
4942 Private,
4943 IfrNvData->CertificateFormat,
4944 &IfrNvData->RevocationDate,
4945 &IfrNvData->RevocationTime,
4946 IfrNvData->AlwaysRevocation
4947 );
4948 IfrNvData->CertificateFormat = HASHALG_RAW;
4949 } else {
4951 }
4952
4953 if (EFI_ERROR (Status)) {
4954 CreatePopUp (
4955 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4956 &Key,
4957 L"ERROR: Unsupported file type!",
4958 L"Only supports DER-encoded X509 certificate, AUTH_2 format data & executable EFI image",
4959 NULL
4960 );
4961 } else {
4962 IfrNvData->ListCount = Private->ListCount;
4963 }
4964
4965 break;
4966
4967 case KEY_VALUE_SAVE_AND_EXIT_DBT:
4969 if (EFI_ERROR (Status)) {
4970 CreatePopUp (
4971 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4972 &Key,
4973 L"ERROR: Unsupported file type!",
4974 L"Only supports DER-encoded X509 certificate.",
4975 NULL
4976 );
4977 }
4978
4979 break;
4980 case KEY_VALUE_SAVE_AND_EXIT_PK:
4981 //
4982 // Check the suffix, encode type and the key strength of PK certificate.
4983 //
4984 Status = CheckX509Certificate (Private->FileContext, &EnrollKeyErrorCode);
4985 if (EFI_ERROR (Status)) {
4986 if ((EnrollKeyErrorCode != None_Error) && (EnrollKeyErrorCode < Enroll_Error_Max)) {
4987 CreatePopUp (
4988 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
4989 &Key,
4990 mX509EnrollPromptTitle[EnrollKeyErrorCode],
4991 mX509EnrollPromptString[EnrollKeyErrorCode],
4992 NULL
4993 );
4994 break;
4995 }
4996 } else {
4997 Status = EnrollPlatformKey (Private);
4998 }
4999
5000 if (EFI_ERROR (Status)) {
5002 PromptString,
5003 sizeof (PromptString),
5004 L"Error status: %x.",
5005 Status
5006 );
5007 CreatePopUp (
5008 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
5009 &Key,
5010 L"ERROR: Enrollment failed!",
5011 PromptString,
5012 NULL
5013 );
5014 } else {
5015 SecureBootExtractConfigFromVariable (Private, IfrNvData);
5016 }
5017
5018 break;
5019 default:
5020 if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) &&
5021 (QuestionId < (OPTION_DEL_KEK_QUESTION_ID + OPTION_CONFIG_RANGE)))
5022 {
5023 DeleteKeyExchangeKey (Private, QuestionId);
5024 } else if ((QuestionId >= OPTION_DEL_DB_QUESTION_ID) &&
5025 (QuestionId < (OPTION_DEL_DB_QUESTION_ID + OPTION_CONFIG_RANGE)))
5026 {
5028 Private,
5030 &gEfiImageSecurityDatabaseGuid,
5031 LABEL_DB_DELETE,
5032 SECUREBOOT_DELETE_SIGNATURE_FROM_DB,
5033 OPTION_DEL_DB_QUESTION_ID,
5034 QuestionId - OPTION_DEL_DB_QUESTION_ID
5035 );
5036 } else if ((QuestionId >= OPTION_SIGNATURE_LIST_QUESTION_ID) &&
5037 (QuestionId < (OPTION_SIGNATURE_LIST_QUESTION_ID + OPTION_CONFIG_RANGE)))
5038 {
5040 Private,
5041 LABEL_SIGNATURE_DATA_START,
5042 SECUREBOOT_DELETE_SIGNATURE_DATA_FORM,
5043 OPTION_SIGNATURE_DATA_QUESTION_ID,
5044 QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID
5045 );
5046 Private->ListIndex = QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID;
5047 } else if ((QuestionId >= OPTION_SIGNATURE_DATA_QUESTION_ID) &&
5048 (QuestionId < (OPTION_SIGNATURE_DATA_QUESTION_ID + OPTION_CONFIG_RANGE)))
5049 {
5050 if (Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID]) {
5051 IfrNvData->CheckedDataCount--;
5052 Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = FALSE;
5053 } else {
5054 IfrNvData->CheckedDataCount++;
5055 Private->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = TRUE;
5056 }
5057 } else if ((QuestionId >= OPTION_DEL_DBT_QUESTION_ID) &&
5058 (QuestionId < (OPTION_DEL_DBT_QUESTION_ID + OPTION_CONFIG_RANGE)))
5059 {
5061 Private,
5063 &gEfiImageSecurityDatabaseGuid,
5064 LABEL_DBT_DELETE,
5065 SECUREBOOT_DELETE_SIGNATURE_FROM_DBT,
5066 OPTION_DEL_DBT_QUESTION_ID,
5067 QuestionId - OPTION_DEL_DBT_QUESTION_ID
5068 );
5069 }
5070
5071 break;
5072
5073 case KEY_VALUE_NO_SAVE_AND_EXIT_PK:
5074 case KEY_VALUE_NO_SAVE_AND_EXIT_KEK:
5075 case KEY_VALUE_NO_SAVE_AND_EXIT_DB:
5076 case KEY_VALUE_NO_SAVE_AND_EXIT_DBX:
5077 case KEY_VALUE_NO_SAVE_AND_EXIT_DBT:
5078 CloseEnrolledFile (Private->FileContext);
5079
5080 if (Private->SignatureGUID != NULL) {
5081 FreePool (Private->SignatureGUID);
5082 Private->SignatureGUID = NULL;
5083 }
5084
5085 break;
5086 }
5087 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
5088 switch (QuestionId) {
5089 case KEY_SECURE_BOOT_ENABLE:
5090 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
5091 break;
5092 case KEY_SECURE_BOOT_MODE:
5093 mIsEnterSecureBootForm = FALSE;
5094 break;
5095 case KEY_SECURE_BOOT_KEK_GUID:
5096 case KEY_SECURE_BOOT_SIGNATURE_GUID_DB:
5097 case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:
5098 case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT:
5099 ASSERT (Private->SignatureGUID != NULL);
5100 RStatus = StrToGuid (IfrNvData->SignatureGuid, Private->SignatureGUID);
5101 if (RETURN_ERROR (RStatus) || (IfrNvData->SignatureGuid[GUID_STRING_LENGTH] != L'\0')) {
5102 Status = EFI_INVALID_PARAMETER;
5103 break;
5104 }
5105
5106 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
5107 break;
5108 case KEY_SECURE_BOOT_DELETE_PK:
5109 GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID **)&SetupMode, NULL);
5110 if ((SetupMode == NULL) || ((*SetupMode) == SETUP_MODE)) {
5111 IfrNvData->DeletePk = TRUE;
5112 IfrNvData->HasPk = FALSE;
5113 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
5114 } else {
5115 IfrNvData->DeletePk = FALSE;
5116 IfrNvData->HasPk = TRUE;
5117 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
5118 }
5119
5120 if (SetupMode != NULL) {
5121 FreePool (SetupMode);
5122 }
5123
5124 break;
5125 case KEY_SECURE_BOOT_RESET_TO_DEFAULT:
5126 {
5127 Status = gBS->LocateProtocol (&gEfiHiiPopupProtocolGuid, NULL, (VOID **)&HiiPopup);
5128 if (EFI_ERROR (Status)) {
5129 return Status;
5130 }
5131
5132 Status = HiiPopup->CreatePopup (
5133 HiiPopup,
5134 EfiHiiPopupStyleInfo,
5135 EfiHiiPopupTypeYesNo,
5136 Private->HiiHandle,
5137 STRING_TOKEN (STR_RESET_TO_DEFAULTS_POPUP),
5138 &UserSelection
5139 );
5140 if (UserSelection == EfiHiiPopupSelectionYes) {
5141 Status = KeyEnrollReset ();
5142 }
5143
5144 //
5145 // Update secure boot strings after key reset
5146 //
5147 if (Status == EFI_SUCCESS) {
5148 Status = UpdateSecureBootString (Private);
5149 SecureBootExtractConfigFromVariable (Private, IfrNvData);
5150 }
5151 }
5152 default:
5153 break;
5154 }
5155 } else if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
5156 if (QuestionId == KEY_HIDE_SECURE_BOOT) {
5157 GetVariable2 (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, (VOID **)&Pk, NULL);
5158 if (Pk == NULL) {
5159 IfrNvData->HideSecureBoot = TRUE;
5160 } else {
5161 FreePool (Pk);
5162 IfrNvData->HideSecureBoot = FALSE;
5163 }
5164
5165 Value->b = IfrNvData->HideSecureBoot;
5166 }
5167 } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
5168 //
5169 // Force the platform back to Standard Mode once user leave the setup screen.
5170 //
5171 GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID **)&SecureBootMode, NULL);
5172 if ((NULL != SecureBootMode) && (*SecureBootMode == CUSTOM_SECURE_BOOT_MODE)) {
5173 IfrNvData->SecureBootMode = STANDARD_SECURE_BOOT_MODE;
5174 SetSecureBootMode (STANDARD_SECURE_BOOT_MODE);
5175 }
5176
5177 if (SecureBootMode != NULL) {
5178 FreePool (SecureBootMode);
5179 }
5180
5181 if (QuestionId == KEY_SECURE_BOOT_DELETE_ALL_DATA) {
5182 //
5183 // Free memory when exit from the SECUREBOOT_DELETE_SIGNATURE_DATA_FORM form.
5184 //
5185 SECUREBOOT_FREE_NON_NULL (Private->CheckArray);
5186 IfrNvData->CheckedDataCount = 0;
5187 }
5188 }
5189
5190EXIT:
5191
5192 if (!EFI_ERROR (Status) && GetBrowserDataResult) {
5193 BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
5194 HiiSetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *)IfrNvData, NULL);
5195 }
5196
5197 FreePool (IfrNvData);
5198
5199 if (File != NULL) {
5200 FreePool (File);
5201 File = NULL;
5202 }
5203
5204 return EFI_SUCCESS;
5205}
5206
5220 )
5221{
5222 EFI_STATUS Status;
5223 EFI_HII_HANDLE HiiHandle;
5224 EFI_HANDLE DriverHandle;
5225 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
5226
5227 DriverHandle = NULL;
5228 ConfigAccess = &PrivateData->ConfigAccess;
5229 Status = gBS->InstallMultipleProtocolInterfaces (
5230 &DriverHandle,
5231 &gEfiDevicePathProtocolGuid,
5232 &mSecureBootHiiVendorDevicePath,
5233 &gEfiHiiConfigAccessProtocolGuid,
5234 ConfigAccess,
5235 NULL
5236 );
5237 if (EFI_ERROR (Status)) {
5238 return Status;
5239 }
5240
5241 PrivateData->DriverHandle = DriverHandle;
5242
5243 //
5244 // Publish the HII package list
5245 //
5246 HiiHandle = HiiAddPackages (
5247 &gSecureBootConfigFormSetGuid,
5248 DriverHandle,
5249 SecureBootConfigDxeStrings,
5250 SecureBootConfigBin,
5251 NULL
5252 );
5253 if (HiiHandle == NULL) {
5254 gBS->UninstallMultipleProtocolInterfaces (
5255 DriverHandle,
5256 &gEfiDevicePathProtocolGuid,
5257 &mSecureBootHiiVendorDevicePath,
5258 &gEfiHiiConfigAccessProtocolGuid,
5259 ConfigAccess,
5260 NULL
5261 );
5262 return EFI_OUT_OF_RESOURCES;
5263 }
5264
5265 PrivateData->HiiHandle = HiiHandle;
5266
5267 PrivateData->FileContext = AllocateZeroPool (sizeof (SECUREBOOT_FILE_CONTEXT));
5268
5269 if (PrivateData->FileContext == NULL) {
5270 UninstallSecureBootConfigForm (PrivateData);
5271 return EFI_OUT_OF_RESOURCES;
5272 }
5273
5274 //
5275 // Init OpCode Handle and Allocate space for creation of Buffer
5276 //
5277 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
5278 if (mStartOpCodeHandle == NULL) {
5279 UninstallSecureBootConfigForm (PrivateData);
5280 return EFI_OUT_OF_RESOURCES;
5281 }
5282
5283 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
5284 if (mEndOpCodeHandle == NULL) {
5285 UninstallSecureBootConfigForm (PrivateData);
5286 return EFI_OUT_OF_RESOURCES;
5287 }
5288
5289 //
5290 // Create Hii Extend Label OpCode as the start opcode
5291 //
5292 mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
5293 mStartOpCodeHandle,
5294 &gEfiIfrTianoGuid,
5295 NULL,
5296 sizeof (EFI_IFR_GUID_LABEL)
5297 );
5299
5300 //
5301 // Create Hii Extend Label OpCode as the end opcode
5302 //
5304 mEndOpCodeHandle,
5305 &gEfiIfrTianoGuid,
5306 NULL,
5307 sizeof (EFI_IFR_GUID_LABEL)
5308 );
5310 mEndLabel->Number = LABEL_END;
5311
5312 return EFI_SUCCESS;
5313}
5314
5321VOID
5324 )
5325{
5326 //
5327 // Uninstall HII package list
5328 //
5329 if (PrivateData->HiiHandle != NULL) {
5330 HiiRemovePackages (PrivateData->HiiHandle);
5331 PrivateData->HiiHandle = NULL;
5332 }
5333
5334 //
5335 // Uninstall HII Config Access Protocol
5336 //
5337 if (PrivateData->DriverHandle != NULL) {
5338 gBS->UninstallMultipleProtocolInterfaces (
5339 PrivateData->DriverHandle,
5340 &gEfiDevicePathProtocolGuid,
5341 &mSecureBootHiiVendorDevicePath,
5342 &gEfiHiiConfigAccessProtocolGuid,
5343 &PrivateData->ConfigAccess,
5344 NULL
5345 );
5346 PrivateData->DriverHandle = NULL;
5347 }
5348
5349 if (PrivateData->SignatureGUID != NULL) {
5350 FreePool (PrivateData->SignatureGUID);
5351 }
5352
5353 if (PrivateData->FileContext != NULL) {
5354 FreePool (PrivateData->FileContext);
5355 }
5356
5357 FreePool (PrivateData);
5358
5359 if (mStartOpCodeHandle != NULL) {
5360 HiiFreeOpCodeHandle (mStartOpCodeHandle);
5361 }
5362
5363 if (mEndOpCodeHandle != NULL) {
5364 HiiFreeOpCodeHandle (mEndOpCodeHandle);
5365 }
5366}
UINT64 UINTN
#define MAX_ADDRESS
#define EFI_CUSTOM_MODE_NAME
#define EFI_SECURE_BOOT_ENABLE_NAME
@ RsaKeyN
RSA public Modulus (N)
Definition: BaseCryptLib.h:75
UINTN EFIAPI Sha256GetContextSize(VOID)
Definition: CryptSha256.c:20
UINTN EFIAPI Sha384GetContextSize(VOID)
Definition: CryptSha512.c:20
BOOLEAN EFIAPI Sha512Final(IN OUT VOID *Sha512Context, OUT UINT8 *HashValue)
Definition: CryptSha512.c:389
UINTN EFIAPI Sha512GetContextSize(VOID)
Definition: CryptSha512.c:246
BOOLEAN EFIAPI Sha512Init(OUT VOID *Sha512Context)
Definition: CryptSha512.c:270
#define SHA512_DIGEST_SIZE
Definition: BaseCryptLib.h:54
BOOLEAN EFIAPI Sha256Init(OUT VOID *Sha256Context)
Definition: CryptSha256.c:44
BOOLEAN EFIAPI RsaGetPublicKeyFromX509(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT VOID **RsaContext)
Definition: CryptX509.c:580
BOOLEAN EFIAPI Sha256Final(IN OUT VOID *Sha256Context, OUT UINT8 *HashValue)
Definition: CryptSha256.c:161
#define SHA256_DIGEST_SIZE
Definition: BaseCryptLib.h:44
BOOLEAN EFIAPI Sha384Update(IN OUT VOID *Sha384Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha512.c:115
BOOLEAN EFIAPI RsaGetKey(IN OUT VOID *RsaContext, IN RSA_KEY_TAG KeyTag, OUT UINT8 *BigNumber, IN OUT UINTN *BnSize)
Definition: CryptRsaExt.c:50
BOOLEAN EFIAPI Sha256Update(IN OUT VOID *Sha256Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha256.c:113
VOID EFIAPI RsaFree(IN VOID *RsaContext)
Definition: CryptRsaBasic.c:48
BOOLEAN EFIAPI Sha384Final(IN OUT VOID *Sha384Context, OUT UINT8 *HashValue)
Definition: CryptSha512.c:163
BOOLEAN EFIAPI Sha384Init(OUT VOID *Sha384Context)
Definition: CryptSha512.c:44
BOOLEAN EFIAPI X509GetTBSCert(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 **TBSCert, OUT UINTN *TBSCertSize)
Definition: CryptX509.c:798
BOOLEAN EFIAPI Sha512Update(IN OUT VOID *Sha512Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha512.c:341
RETURN_STATUS EFIAPI X509GetCommonName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT CHAR8 *CommonName OPTIONAL, IN OUT UINTN *CommonNameSize)
Definition: CryptX509.c:514
#define SHA384_DIGEST_SIZE
Definition: BaseCryptLib.h:49
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
RETURN_STATUS EFIAPI StrToGuid(IN CONST CHAR16 *String, OUT GUID *Guid)
Definition: SafeString.c:1500
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
Definition: Unaligned.c:177
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2873
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID CleanUpPage(IN UINT16 LabelId, IN BMM_CALLBACK_DATA *CallbackData)
Definition: UpdatePage.c:165
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI ChooseFile(IN EFI_DEVICE_PATH_PROTOCOL *RootDirectory, IN CHAR16 *FileType OPTIONAL, IN CHOOSE_HANDLER ChooseHandler OPTIONAL, OUT EFI_DEVICE_PATH_PROTOCOL **File OPTIONAL)
#define EFI_SETUP_MODE_NAME
#define EFI_KEY_EXCHANGE_KEY_NAME
#define EFI_PLATFORM_KEY_NAME
#define EFI_SECURE_BOOT_MODE_NAME
EFI_STATUS EFIAPI HashUpdate(IN HASH_HANDLE HashHandle, IN VOID *DataToHash, IN UINTN DataToHashLen)
Definition: HashLibTdx.c:69
EFI_STRING EFIAPI HiiConstructConfigHdr(IN CONST EFI_GUID *Guid OPTIONAL, IN CONST CHAR16 *Name OPTIONAL, IN EFI_HANDLE DriverHandle)
Definition: HiiLib.c:723
BOOLEAN EFIAPI HiiGetBrowserData(IN CONST EFI_GUID *VariableGuid OPTIONAL, IN CONST CHAR16 *VariableName OPTIONAL, IN UINTN BufferSize, OUT UINT8 *Buffer)
Definition: HiiLib.c:2872
UINT8 *EFIAPI HiiCreateGotoOpCode(IN VOID *OpCodeHandle, IN EFI_FORM_ID FormId, IN EFI_STRING_ID Prompt, IN EFI_STRING_ID Help, IN UINT8 QuestionFlags, IN EFI_QUESTION_ID QuestionId)
Definition: HiiLib.c:3551
VOID *EFIAPI HiiAllocateOpCodeHandle(VOID)
Definition: HiiLib.c:3051
VOID EFIAPI HiiFreeOpCodeHandle(VOID *OpCodeHandle)
Definition: HiiLib.c:3085
EFI_HII_HANDLE EFIAPI HiiAddPackages(IN CONST EFI_GUID *PackageListGuid, IN EFI_HANDLE DeviceHandle OPTIONAL,...)
Definition: HiiLib.c:141
UINT8 *EFIAPI HiiCreateGuidOpCode(IN VOID *OpCodeHandle, IN CONST EFI_GUID *Guid, IN CONST VOID *GuidOpCode OPTIONAL, IN UINTN OpCodeSize)
Definition: HiiLib.c:3411
UINT8 *EFIAPI HiiCreateCheckBoxOpCode(IN VOID *OpCodeHandle, IN EFI_QUESTION_ID QuestionId, IN EFI_VARSTORE_ID VarStoreId, IN UINT16 VarOffset, IN EFI_STRING_ID Prompt, IN EFI_STRING_ID Help, IN UINT8 QuestionFlags, IN UINT8 CheckBoxFlags, IN VOID *DefaultsOpCodeHandle OPTIONAL)
Definition: HiiLib.c:3675
BOOLEAN EFIAPI HiiSetBrowserData(IN CONST EFI_GUID *VariableGuid OPTIONAL, IN CONST CHAR16 *VariableName OPTIONAL, IN UINTN BufferSize, IN CONST UINT8 *Buffer, IN CONST CHAR16 *RequestElement OPTIONAL)
Definition: HiiLib.c:2954
EFI_STRING EFIAPI HiiGetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language OPTIONAL)
Definition: HiiString.c:211
EFI_STATUS EFIAPI HiiUpdateForm(IN EFI_HII_HANDLE HiiHandle, IN EFI_GUID *FormSetGuid OPTIONAL, IN EFI_FORM_ID FormId, IN VOID *StartOpCodeHandle, IN VOID *EndOpCodeHandle OPTIONAL)
Definition: HiiLib.c:4410
BOOLEAN EFIAPI HiiIsConfigHdrMatch(IN CONST EFI_STRING ConfigHdr, IN CONST EFI_GUID *Guid OPTIONAL, IN CONST CHAR16 *Name OPTIONAL)
Definition: HiiLib.c:2813
EFI_STRING_ID EFIAPI HiiSetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId OPTIONAL, IN CONST EFI_STRING String, IN CONST CHAR8 *SupportedLanguages OPTIONAL)
Definition: HiiString.c:52
VOID EFIAPI HiiRemovePackages(IN EFI_HII_HANDLE HiiHandle)
Definition: HiiLib.c:253
#define EFI_IMAGE_SECURITY_DATABASE2
#define EFI_IMAGE_SECURITY_DATABASE1
#define EFI_IMAGE_SECURITY_DATABASE
#define EFI_IFR_EXTEND_OP_LABEL
Definition: MdeModuleHii.h:33
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
RETURN_STATUS(EFIAPI * PE_COFF_LOADER_READ_FILE)(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: PeCoffLib.h:65
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:577
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: PeImage.h:143
EFI_STATUS CreateTimeBasedPayload(IN OUT UINTN *DataSize, IN OUT UINT8 **Data)
BOOLEAN EFIAPI UserPhysicalPresent(VOID)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
BOOLEAN EFIAPI UpdatePKFromFile(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
BOOLEAN EFIAPI UpdateDBTFromFile(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
BOOLEAN EFIAPI UpdateDBXFromFile(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
BOOLEAN EFIAPI UpdateKEKFromFile(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
BOOLEAN EFIAPI UpdateDBFromFile(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
EFI_STATUS LoadSignatureList(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN UINT16 LabelId, IN EFI_FORM_ID FormId, IN EFI_QUESTION_ID QuestionIdBase)
BOOLEAN HashPeImage(IN UINT32 HashAlg)
EFI_STATUS EFIAPI SecureBootExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Request, OUT EFI_STRING *Progress, OUT EFI_STRING *Results)
BOOLEAN IsDerEncodeCertificate(IN CONST CHAR16 *FileSuffix)
EFI_STATUS FormatHelpInfo(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN EFI_SIGNATURE_LIST *ListEntry, IN EFI_SIGNATURE_DATA *DataEntry, OUT EFI_STRING_ID *StringId)
EFI_STATUS ParseHashValue(IN EFI_SIGNATURE_LIST *ListEntry, IN EFI_SIGNATURE_DATA *DataEntry, OUT CHAR16 **BufferToReturn)
BOOLEAN GetSignaturelistOffset(IN EFI_SIGNATURE_LIST *Database, IN UINTN DatabaseSize, IN EFI_GUID *SignatureType, OUT UINTN *Offset)
EFI_STATUS EFIAPI SecureBootConfigImageRead(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
EFI_STATUS DeleteKeyExchangeKey(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN EFI_QUESTION_ID QuestionId)
EFI_STATUS EnrollKeyExchangeKey(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private)
STATIC EFI_STATUS GetCurrentTime(IN EFI_TIME *Time)
EFI_STATUS EnrollAuthentication2Descriptor(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN CHAR16 *VariableName)
EFI_STATUS CreatePkX509SignatureList(IN EFI_FILE_HANDLE X509File, OUT EFI_SIGNATURE_LIST **PkCert)
EFI_STATUS EFIAPI SecureBootRouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Configuration, OUT EFI_STRING *Progress)
EFI_STATUS GetCommonNameFromX509(IN EFI_SIGNATURE_LIST *ListEntry, IN EFI_SIGNATURE_DATA *DataEntry, OUT CHAR16 **BufferToReturn)
BOOLEAN CalculateCertHash(IN UINT8 *CertData, IN UINTN CertSize, IN UINT32 HashAlg, OUT UINT8 *CertHash)
EFI_STATUS HashPeImageByType(VOID)
BOOLEAN IsCertHashFoundInDbx(IN UINT8 *Certificate, IN UINTN CertSize)
EFI_STATUS EnrollRsa2048ToKek(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private)
EFI_STATUS UpdateSecureBootString(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private)
EFI_STATUS LoadSignatureData(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN UINT16 LabelId, IN EFI_FORM_ID FormId, IN EFI_QUESTION_ID QuestionIdBase, IN UINT16 ListIndex)
EFI_STATUS EnrollX509ToKek(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private)
EFI_STATUS CheckX509Certificate(IN SECUREBOOT_FILE_CONTEXT *X509FileContext, OUT ENROLL_KEY_ERROR *Error)
VOID CloseEnrolledFile(IN SECUREBOOT_FILE_CONTEXT *FileContext)
EFI_STATUS InstallSecureBootConfigForm(IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData)
BOOLEAN IsSignatureFoundInDatabase(IN CHAR16 *VariableName, IN UINT8 *Signature, IN UINTN SignatureSize)
BOOLEAN IsX509CertInDbx(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN CHAR16 *VariableName)
EFI_STATUS UpdateDeletePage(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT16 LabelNumber, IN EFI_FORM_ID FormId, IN EFI_QUESTION_ID QuestionIdBase)
EFI_STATUS SaveSecureBootVariable(IN UINT8 VarValue)
EFI_STATUS EnrollPlatformKey(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private)
EFI_STATUS EnrollX509HashtoSigDB(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN UINT32 HashAlg, IN EFI_HII_DATE *RevocationDate, IN EFI_HII_TIME *RevocationTime, IN BOOLEAN AlwaysRevocation)
EFI_STATUS LoadPeImage(VOID)
EFI_STATUS EnrollSignatureDatabase(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN CHAR16 *VariableName)
EFI_STATUS EnrollX509toSigDB(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN CHAR16 *VariableName)
EFI_STATUS DeleteSignatureEx(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN SIGNATURE_DELETE_TYPE DelType, IN UINT32 CheckedCount)
BOOLEAN IsAuthentication2Format(IN EFI_FILE_HANDLE FileHandle)
VOID SecureBootExtractConfigFromVariable(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN OUT SECUREBOOT_CONFIGURATION *ConfigData)
STATIC EFI_STATUS EFIAPI KeyEnrollReset(VOID)
EFI_STATUS EFIAPI SecureBootCallback(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest)
EFI_STATUS EnrollImageSignatureToSigDB(IN SECUREBOOT_CONFIG_PRIVATE_DATA *Private, IN CHAR16 *VariableName)
EFI_STATUS DeleteSignature(IN SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT16 LabelNumber, IN EFI_FORM_ID FormId, IN EFI_QUESTION_ID QuestionIdBase, IN UINTN DeleteIndex)
VOID UninstallSecureBootConfigForm(IN OUT SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData)
EFI_STATUS EFIAPI Int2OctStr(IN CONST UINTN *Integer, IN UINTN IntSizeInWords, OUT UINT8 *OctetString, IN UINTN OSSizeInBytes)
VOID CloseFile(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI SetSecureBootMode(IN UINT8 SecureBootMode)
EFI_STATUS EFIAPI GetSetupMode(OUT UINT8 *SetupMode)
EFI_STATUS EFIAPI DeleteDbx(VOID)
EFI_STATUS EFIAPI DeletePlatformKey(VOID)
EFI_STATUS EFIAPI DeleteDb(VOID)
EFI_STATUS EFIAPI DeleteKEK(VOID)
EFI_STATUS EFIAPI DeleteDbt(VOID)
EFI_STATUS EFIAPI EnrollPKFromDefault(VOID)
EFI_STATUS EFIAPI EnrollKEKFromDefault(VOID)
EFI_STATUS EFIAPI EnrollDbFromDefault(VOID)
EFI_STATUS EFIAPI EnrollDbtFromDefault(VOID)
EFI_STATUS EFIAPI EnrollDbxFromDefault(VOID)
UINTN GuidToString(IN EFI_GUID *Guid, IN CHAR16 *Buffer, IN UINTN BufferSize)
EFI_STATUS ReadFileContent(IN EFI_FILE_HANDLE FileHandle, IN OUT VOID **BufferPtr, OUT UINTN *FileSize, IN UINTN AddtionAllocateSize)
#define EFI_IMAGE_MACHINE_AARCH64
Definition: UefiBaseType.h:243
#define EFI_IMAGE_MACHINE_EBC
Definition: UefiBaseType.h:228
#define EFI_IMAGE_MACHINE_IA32
Definition: UefiBaseType.h:218
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_IMAGE_MACHINE_IA64
Definition: UefiBaseType.h:223
#define EFI_IMAGE_MACHINE_X64
Definition: UefiBaseType.h:233
#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED
Definition: UefiBaseType.h:238
GUID EFI_GUID
Definition: UefiBaseType.h:25
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_HII_CONFIG_ROUTING_PROTOCOL * gHiiConfigRouting
#define STRING_TOKEN(t)
VOID * EFI_HII_HANDLE
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
VOID EFIAPI CreatePopUp(IN UINTN Attribute, OUT EFI_INPUT_KEY *Key OPTIONAL,...)
Definition: Console.c:393
#define EFI_VARIABLE_NON_VOLATILE
#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
UINT32 e_lfanew
File address of new exe header.
Definition: PeImage.h:76
UINT16 e_magic
Magic number.
Definition: PeImage.h:58
WIN_CERTIFICATE_UEFI_GUID AuthInfo
Definition: Base.h:213
HASH_FINAL HashFinal
Pointer to Hash Final function.
UINTN DigestLength
Digest Length.
UINTN OidLength
Length of Hash OID Value.
HASH_UPDATE HashUpdate
Pointer to Hash Update function.
UINT8 * OidValue
Hash Algorithm OID ASN.1 Value.
HASH_GET_CONTEXT_SIZE GetContextSize
Pointer to Hash GetContentSize function.
HASH_INIT HashInit
Pointer to Hash Init function.
PE_COFF_LOADER_READ_FILE ImageRead
Definition: PeCoffLib.h:100
UINT16 wCertificateType