TianoCore EDK2 master
Loading...
Searching...
No Matches
AuthService.c
Go to the documentation of this file.
1
27#include "AuthServiceInternal.h"
28
29#include <Protocol/VariablePolicy.h>
30#include <Library/VariablePolicyLib.h>
31
32#define SHA_DIGEST_SIZE_MAX SHA512_DIGEST_SIZE
33
43typedef
46 VOID
47 );
48
63typedef
64BOOLEAN
65(EFIAPI *EFI_HASH_INIT)(
66 OUT VOID *HashContext
67 );
68
89typedef
90BOOLEAN
91(EFIAPI *EFI_HASH_UPDATE)(
92 IN OUT VOID *HashContext,
93 IN CONST VOID *Data,
94 IN UINTN DataSize
95 );
96
119typedef
120BOOLEAN
121(EFIAPI *EFI_HASH_FINAL)(
122 IN OUT VOID *HashContext,
123 OUT UINT8 *HashValue
124 );
125
126typedef struct {
127 UINT32 HashSize;
128 EFI_HASH_GET_CONTEXT_SIZE GetContextSize;
129 EFI_HASH_INIT Init;
130 EFI_HASH_UPDATE Update;
131 EFI_HASH_FINAL Final;
132 VOID **HashShaCtx;
133 UINT8 *OidValue;
134 UINTN OidLength;
136
137//
138// Public Exponent of RSA Key.
139//
140CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
141
142UINT8 mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
143UINT8 mSha384OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 };
144UINT8 mSha512OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 };
145
146EFI_HASH_INFO mHashInfo[] = {
147 { SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final, &mHashSha256Ctx, mSha256OidValue, 9 },
148 { SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final, &mHashSha384Ctx, mSha384OidValue, 9 },
149 { SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final, &mHashSha512Ctx, mSha512OidValue, 9 },
150};
151
152//
153// Requirement for different signature type which have been defined in UEFI spec.
154// These data are used to perform SignatureList format check while setting PK/KEK variable.
155//
156EFI_SIGNATURE_ITEM mSupportSigItem[] = {
157 // {SigType, SigHeaderSize, SigDataSize }
158 { EFI_CERT_SHA256_GUID, 0, 32 },
159 { EFI_CERT_RSA2048_GUID, 0, 256 },
161 { EFI_CERT_SHA1_GUID, 0, 20 },
162 { EFI_CERT_RSA2048_SHA1_GUID, 0, 256 },
163 { EFI_CERT_X509_GUID, 0, ((UINT32) ~0) },
164 { EFI_CERT_SHA224_GUID, 0, 28 },
165 { EFI_CERT_SHA384_GUID, 0, 48 },
166 { EFI_CERT_SHA512_GUID, 0, 64 },
167 { EFI_CERT_X509_SHA256_GUID, 0, 48 },
168 { EFI_CERT_X509_SHA384_GUID, 0, 64 },
170};
171
192 IN CHAR16 *VariableName,
193 IN EFI_GUID *VendorGuid,
194 OUT VOID **Data,
195 OUT UINTN *DataSize
196 )
197{
198 EFI_STATUS Status;
199 AUTH_VARIABLE_INFO AuthVariableInfo;
200
201 ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
202 Status = mAuthVarLibContextIn->FindVariable (
203 VariableName,
204 VendorGuid,
205 &AuthVariableInfo
206 );
207 *Data = AuthVariableInfo.Data;
208 *DataSize = AuthVariableInfo.DataSize;
209 return Status;
210}
211
229 IN CHAR16 *VariableName,
230 IN EFI_GUID *VendorGuid,
231 IN VOID *Data,
232 IN UINTN DataSize,
233 IN UINT32 Attributes
234 )
235{
236 AUTH_VARIABLE_INFO AuthVariableInfo;
237
238 ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
239 AuthVariableInfo.VariableName = VariableName;
240 AuthVariableInfo.VendorGuid = VendorGuid;
241 AuthVariableInfo.Data = Data;
242 AuthVariableInfo.DataSize = DataSize;
243 AuthVariableInfo.Attributes = Attributes;
244
245 return mAuthVarLibContextIn->UpdateVariable (
246 &AuthVariableInfo
247 );
248}
249
268 IN CHAR16 *VariableName,
269 IN EFI_GUID *VendorGuid,
270 IN VOID *Data,
271 IN UINTN DataSize,
272 IN UINT32 Attributes,
273 IN EFI_TIME *TimeStamp
274 )
275{
276 EFI_STATUS FindStatus;
277 VOID *OrgData;
278 UINTN OrgDataSize;
279 AUTH_VARIABLE_INFO AuthVariableInfo;
280
282 VariableName,
283 VendorGuid,
284 &OrgData,
285 &OrgDataSize
286 );
287
288 //
289 // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable
290 //
291 if (!EFI_ERROR (FindStatus) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {
292 if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
293 ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||
294 (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||
295 (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)))
296 {
297 //
298 // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of
299 // EFI_SIGNATURE_DATA values that are already part of the existing variable value.
300 //
302 OrgData,
303 OrgDataSize,
304 Data,
305 &DataSize
306 );
307 }
308 }
309
310 ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
311 AuthVariableInfo.VariableName = VariableName;
312 AuthVariableInfo.VendorGuid = VendorGuid;
313 AuthVariableInfo.Data = Data;
314 AuthVariableInfo.DataSize = DataSize;
315 AuthVariableInfo.Attributes = Attributes;
316 AuthVariableInfo.TimeStamp = TimeStamp;
317 return mAuthVarLibContextIn->UpdateVariable (
318 &AuthVariableInfo
319 );
320}
321
332BOOLEAN
334 IN CHAR16 *VariableName,
335 IN EFI_GUID *VendorGuid
336 )
337{
338 // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.
339 if (IsVariablePolicyEnabled ()) {
340 if ( (CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))
341 || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0)))
342 {
343 return TRUE;
344 }
345 }
346
347 return FALSE;
348}
349
357BOOLEAN
359 VOID
360 )
361{
362 EFI_STATUS Status;
363 VOID *Data;
364 UINTN DataSize;
365
366 Status = AuthServiceInternalFindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Data, &DataSize);
367 if (!EFI_ERROR (Status) && (*(UINT8 *)Data == CUSTOM_SECURE_BOOT_MODE)) {
368 return TRUE;
369 }
370
371 return FALSE;
372}
373
385 IN UINT32 Mode
386 )
387{
388 EFI_STATUS Status;
389 VOID *Data;
390 UINTN DataSize;
391 UINT8 SecureBootMode;
392 UINT8 SecureBootEnable;
393 UINTN VariableDataSize;
394
397 &gEfiGlobalVariableGuid,
398 &Data,
399 &DataSize
400 );
401 if (EFI_ERROR (Status)) {
402 return Status;
403 }
404
405 //
406 // Update the value of SetupMode variable by a simple mem copy, this could avoid possible
407 // variable storage reclaim at runtime.
408 //
409 mPlatformMode = (UINT8)Mode;
410 CopyMem (Data, &mPlatformMode, sizeof (UINT8));
411
412 if (mAuthVarLibContextIn->AtRuntime ()) {
413 //
414 // SecureBoot Variable indicates whether the platform firmware is operating
415 // in Secure boot mode (1) or not (0), so we should not change SecureBoot
416 // Variable in runtime.
417 //
418 return Status;
419 }
420
421 //
422 // Check "SecureBoot" variable's existence.
423 // If it doesn't exist, firmware has no capability to perform driver signing verification,
424 // then set "SecureBoot" to 0.
425 //
428 &gEfiGlobalVariableGuid,
429 &Data,
430 &DataSize
431 );
432 //
433 // If "SecureBoot" variable exists, then check "SetupMode" variable update.
434 // If "SetupMode" variable is USER_MODE, "SecureBoot" variable is set to 1.
435 // If "SetupMode" variable is SETUP_MODE, "SecureBoot" variable is set to 0.
436 //
437 if (EFI_ERROR (Status)) {
438 SecureBootMode = SECURE_BOOT_MODE_DISABLE;
439 } else {
440 if (mPlatformMode == USER_MODE) {
441 SecureBootMode = SECURE_BOOT_MODE_ENABLE;
442 } else if (mPlatformMode == SETUP_MODE) {
443 SecureBootMode = SECURE_BOOT_MODE_DISABLE;
444 } else {
445 return EFI_NOT_FOUND;
446 }
447 }
448
451 &gEfiGlobalVariableGuid,
452 &SecureBootMode,
453 sizeof (UINT8),
454 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
455 );
456 if (EFI_ERROR (Status)) {
457 return Status;
458 }
459
460 //
461 // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.
462 //
465 &gEfiSecureBootEnableDisableGuid,
466 &Data,
467 &DataSize
468 );
469
470 if (SecureBootMode == SECURE_BOOT_MODE_ENABLE) {
471 //
472 // Create the "SecureBootEnable" variable as secure boot is enabled.
473 //
474 SecureBootEnable = SECURE_BOOT_ENABLE;
475 VariableDataSize = sizeof (SecureBootEnable);
476 } else {
477 //
478 // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"
479 // variable is not in secure boot state.
480 //
481 if (EFI_ERROR (Status)) {
482 return EFI_SUCCESS;
483 }
484
485 SecureBootEnable = SECURE_BOOT_DISABLE;
486 VariableDataSize = 0;
487 }
488
491 &gEfiSecureBootEnableDisableGuid,
492 &SecureBootEnable,
493 VariableDataSize,
494 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS
495 );
496 return Status;
497}
498
513 IN CHAR16 *VariableName,
514 IN EFI_GUID *VendorGuid,
515 IN VOID *Data,
516 IN UINTN DataSize
517 )
518{
519 EFI_SIGNATURE_LIST *SigList;
520 UINTN SigDataSize;
521 UINT32 Index;
522 UINT32 SigCount;
523 BOOLEAN IsPk;
524 VOID *RsaContext;
525 EFI_SIGNATURE_DATA *CertData;
526 UINTN CertLen;
527
528 if (DataSize == 0) {
529 return EFI_SUCCESS;
530 }
531
532 ASSERT (VariableName != NULL && VendorGuid != NULL && Data != NULL);
533
534 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)) {
535 IsPk = TRUE;
536 } else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) ||
537 (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
538 ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||
539 (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))))
540 {
541 IsPk = FALSE;
542 } else {
543 return EFI_SUCCESS;
544 }
545
546 SigCount = 0;
547 SigList = (EFI_SIGNATURE_LIST *)Data;
548 SigDataSize = DataSize;
549 RsaContext = NULL;
550
551 //
552 // Walk through the input signature list and check the data format.
553 // If any signature is incorrectly formed, the whole check will fail.
554 //
555 while ((SigDataSize > 0) && (SigDataSize >= SigList->SignatureListSize)) {
556 for (Index = 0; Index < (sizeof (mSupportSigItem) / sizeof (EFI_SIGNATURE_ITEM)); Index++ ) {
557 if (CompareGuid (&SigList->SignatureType, &mSupportSigItem[Index].SigType)) {
558 //
559 // The value of SignatureSize should always be 16 (size of SignatureOwner
560 // component) add the data length according to signature type.
561 //
562 if ((mSupportSigItem[Index].SigDataSize != ((UINT32) ~0)) &&
563 ((SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize))
564 {
565 return EFI_INVALID_PARAMETER;
566 }
567
568 if ((mSupportSigItem[Index].SigHeaderSize != ((UINT32) ~0)) &&
569 (SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize))
570 {
571 return EFI_INVALID_PARAMETER;
572 }
573
574 break;
575 }
576 }
577
578 if (Index == (sizeof (mSupportSigItem) / sizeof (EFI_SIGNATURE_ITEM))) {
579 //
580 // Undefined signature type.
581 //
582 return EFI_INVALID_PARAMETER;
583 }
584
585 if (CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) {
586 //
587 // Try to retrieve the RSA public key from the X.509 certificate.
588 // If this operation fails, it's not a valid certificate.
589 //
590 RsaContext = RsaNew ();
591 if (RsaContext == NULL) {
592 return EFI_INVALID_PARAMETER;
593 }
594
595 CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);
596 CertLen = SigList->SignatureSize - sizeof (EFI_GUID);
597 if (!RsaGetPublicKeyFromX509 (CertData->SignatureData, CertLen, &RsaContext)) {
598 RsaFree (RsaContext);
599 return EFI_INVALID_PARAMETER;
600 }
601
602 RsaFree (RsaContext);
603 }
604
605 if ((SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) % SigList->SignatureSize != 0) {
606 return EFI_INVALID_PARAMETER;
607 }
608
609 SigCount += (SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) / SigList->SignatureSize;
610
611 SigDataSize -= SigList->SignatureListSize;
612 SigList = (EFI_SIGNATURE_LIST *)((UINT8 *)SigList + SigList->SignatureListSize);
613 }
614
615 if (((UINTN)SigList - (UINTN)Data) != DataSize) {
616 return EFI_INVALID_PARAMETER;
617 }
618
619 if (IsPk && (SigCount > 1)) {
620 return EFI_INVALID_PARAMETER;
621 }
622
623 return EFI_SUCCESS;
624}
625
635 VOID
636 )
637{
638 EFI_STATUS Status;
639
640 if (mVendorKeyState == VENDOR_KEYS_MODIFIED) {
641 return EFI_SUCCESS;
642 }
643
644 mVendorKeyState = VENDOR_KEYS_MODIFIED;
645
648 &gEfiVendorKeysNvGuid,
649 &mVendorKeyState,
650 sizeof (UINT8),
652 );
653 if (EFI_ERROR (Status)) {
654 return Status;
655 }
656
659 &gEfiGlobalVariableGuid,
660 &mVendorKeyState,
661 sizeof (UINT8),
662 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
663 );
664}
665
692 IN CHAR16 *VariableName,
693 IN EFI_GUID *VendorGuid,
694 IN VOID *Data,
695 IN UINTN DataSize,
696 IN UINT32 Attributes OPTIONAL,
697 IN BOOLEAN IsPk
698 )
699{
700 EFI_STATUS Status;
701 BOOLEAN Del;
702 UINT8 *Payload;
703 UINTN PayloadSize;
704
705 if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||
707 {
708 //
709 // PK, KEK and db/dbx/dbt should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
710 // authenticated variable.
711 //
712 return EFI_INVALID_PARAMETER;
713 }
714
715 //
716 // Init state of Del. State may change due to secure check
717 //
718 Del = FALSE;
719 if ( (InCustomMode () && UserPhysicalPresent ())
720 || ( (mPlatformMode == SETUP_MODE)
721 && !(FeaturePcdGet (PcdRequireSelfSignedPk) && IsPk)))
722 {
723 Payload = (UINT8 *)Data + AUTHINFO2_SIZE (Data);
724 PayloadSize = DataSize - AUTHINFO2_SIZE (Data);
725 if (PayloadSize == 0) {
726 Del = TRUE;
727 }
728
729 Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);
730 if (EFI_ERROR (Status)) {
731 return Status;
732 }
733
735 VariableName,
736 VendorGuid,
737 Payload,
738 PayloadSize,
739 Attributes,
740 &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp
741 );
742 if (EFI_ERROR (Status)) {
743 return Status;
744 }
745
746 if ( (mPlatformMode != SETUP_MODE)
747 || (FeaturePcdGet (PcdRequireSelfSignedPk) && IsPk))
748 {
749 Status = VendorKeyIsModified ();
750 }
751 } else if (mPlatformMode == USER_MODE) {
752 //
753 // Verify against X509 Cert in PK database.
754 //
756 VariableName,
757 VendorGuid,
758 Data,
759 DataSize,
760 Attributes,
761 AuthVarTypePk,
762 &Del
763 );
764 } else {
765 //
766 // Verify against the certificate in data payload.
767 //
769 VariableName,
770 VendorGuid,
771 Data,
772 DataSize,
773 Attributes,
774 AuthVarTypePayload,
775 &Del
776 );
777 }
778
779 if (!EFI_ERROR (Status) && IsPk) {
780 if ((mPlatformMode == SETUP_MODE) && !Del) {
781 //
782 // If enroll PK in setup mode, need change to user mode.
783 //
784 Status = UpdatePlatformMode (USER_MODE);
785 } else if ((mPlatformMode == USER_MODE) && Del) {
786 //
787 // If delete PK in user mode, need change to setup mode.
788 //
789 Status = UpdatePlatformMode (SETUP_MODE);
790 }
791 }
792
793 return Status;
794}
795
821 IN CHAR16 *VariableName,
822 IN EFI_GUID *VendorGuid,
823 IN VOID *Data,
824 IN UINTN DataSize,
825 IN UINT32 Attributes OPTIONAL
826 )
827{
828 EFI_STATUS Status;
829 UINT8 *Payload;
830 UINTN PayloadSize;
831
832 if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||
834 {
835 //
836 // DB, DBX and DBT should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based
837 // authenticated variable.
838 //
839 return EFI_INVALID_PARAMETER;
840 }
841
842 Status = EFI_SUCCESS;
843 if ((mPlatformMode == USER_MODE) && !(InCustomMode () && UserPhysicalPresent ())) {
844 //
845 // Time-based, verify against X509 Cert KEK.
846 //
848 VariableName,
849 VendorGuid,
850 Data,
851 DataSize,
852 Attributes,
853 AuthVarTypeKek,
854 NULL
855 );
856 } else {
857 //
858 // If in setup mode or custom secure boot mode, no authentication needed.
859 //
860 Payload = (UINT8 *)Data + AUTHINFO2_SIZE (Data);
861 PayloadSize = DataSize - AUTHINFO2_SIZE (Data);
862
863 Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);
864 if (EFI_ERROR (Status)) {
865 return Status;
866 }
867
869 VariableName,
870 VendorGuid,
871 Payload,
872 PayloadSize,
873 Attributes,
874 &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp
875 );
876 if (EFI_ERROR (Status)) {
877 return Status;
878 }
879
880 if (mPlatformMode != SETUP_MODE) {
881 Status = VendorKeyIsModified ();
882 }
883 }
884
885 return Status;
886}
887
900BOOLEAN
902 IN UINT32 OrgAttributes,
903 IN VOID *Data,
904 IN UINTN DataSize,
905 IN UINT32 Attributes
906 )
907{
908 BOOLEAN Del;
909 UINTN PayloadSize;
910
911 Del = FALSE;
912
913 //
914 // To delete a variable created with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
915 // or the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute,
916 // SetVariable must be used with attributes matching the existing variable
917 // and the DataSize set to the size of the AuthInfo descriptor.
918 //
919 if ((Attributes == OrgAttributes) &&
921 {
923 PayloadSize = DataSize - AUTHINFO2_SIZE (Data);
924 if (PayloadSize == 0) {
925 Del = TRUE;
926 }
927 } else {
928 PayloadSize = DataSize - AUTHINFO_SIZE;
929 if (PayloadSize == 0) {
930 Del = TRUE;
931 }
932 }
933 }
934
935 return Del;
936}
937
966 IN CHAR16 *VariableName,
967 IN EFI_GUID *VendorGuid,
968 IN VOID *Data,
969 IN UINTN DataSize,
970 IN UINT32 Attributes
971 )
972{
973 EFI_STATUS Status;
974 AUTH_VARIABLE_INFO OrgVariableInfo;
975
976 Status = EFI_SUCCESS;
977
978 ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));
979 Status = mAuthVarLibContextIn->FindVariable (
980 VariableName,
981 VendorGuid,
982 &OrgVariableInfo
983 );
984
985 // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.
986 if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && (UserPhysicalPresent () || !IsVariablePolicyEnabled ())) {
987 //
988 // Allow the delete operation of common authenticated variable(AT or AW) at user physical presence.
989 //
991 VariableName,
992 VendorGuid,
993 NULL,
994 0,
995 0
996 );
997 if (!EFI_ERROR (Status) && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {
998 Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);
999 }
1000
1001 return Status;
1002 }
1003
1004 if (NeedPhysicallyPresent (VariableName, VendorGuid) && !UserPhysicalPresent ()) {
1005 //
1006 // This variable is protected, only physical present user could modify its value.
1007 //
1008 return EFI_SECURITY_VIOLATION;
1009 }
1010
1011 //
1012 if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
1013 //
1014 // Reject Counter Based Auth Variable processing request.
1015 //
1016 return EFI_UNSUPPORTED;
1017 } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
1018 //
1019 // Process Time-based Authenticated variable.
1020 //
1022 VariableName,
1023 VendorGuid,
1024 Data,
1025 DataSize,
1026 Attributes,
1027 AuthVarTypePriv,
1028 NULL
1029 );
1030 }
1031
1032 if ((OrgVariableInfo.Data != NULL) &&
1034 {
1035 //
1036 // If the variable is already write-protected, it always needs authentication before update.
1037 //
1038 return EFI_WRITE_PROTECTED;
1039 }
1040
1041 //
1042 // Not authenticated variable, just update variable as usual.
1043 //
1044 Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);
1045 return Status;
1046}
1047
1059 IN VOID *Data,
1060 IN UINTN DataSize,
1061 IN OUT VOID *NewData,
1062 IN OUT UINTN *NewDataSize
1063 )
1064{
1065 EFI_SIGNATURE_LIST *CertList;
1066 EFI_SIGNATURE_DATA *Cert;
1067 UINTN CertCount;
1068 EFI_SIGNATURE_LIST *NewCertList;
1069 EFI_SIGNATURE_DATA *NewCert;
1070 UINTN NewCertCount;
1071 UINTN Index;
1072 UINTN Index2;
1073 UINTN Size;
1074 UINT8 *Tail;
1075 UINTN CopiedCount;
1076 UINTN SignatureListSize;
1077 BOOLEAN IsNewCert;
1078 UINT8 *TempData;
1079 UINTN TempDataSize;
1080 EFI_STATUS Status;
1081
1082 if (*NewDataSize == 0) {
1083 return EFI_SUCCESS;
1084 }
1085
1086 TempDataSize = *NewDataSize;
1087 Status = mAuthVarLibContextIn->GetScratchBuffer (&TempDataSize, (VOID **)&TempData);
1088 if (EFI_ERROR (Status)) {
1089 return EFI_OUT_OF_RESOURCES;
1090 }
1091
1092 Tail = TempData;
1093
1094 NewCertList = (EFI_SIGNATURE_LIST *)NewData;
1095 while ((*NewDataSize > 0) && (*NewDataSize >= NewCertList->SignatureListSize)) {
1096 NewCert = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);
1097 NewCertCount = (NewCertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - NewCertList->SignatureHeaderSize) / NewCertList->SignatureSize;
1098
1099 CopiedCount = 0;
1100 for (Index = 0; Index < NewCertCount; Index++) {
1101 IsNewCert = TRUE;
1102
1103 Size = DataSize;
1104 CertList = (EFI_SIGNATURE_LIST *)Data;
1105 while ((Size > 0) && (Size >= CertList->SignatureListSize)) {
1106 if (CompareGuid (&CertList->SignatureType, &NewCertList->SignatureType) &&
1107 (CertList->SignatureSize == NewCertList->SignatureSize))
1108 {
1109 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
1110 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
1111 for (Index2 = 0; Index2 < CertCount; Index2++) {
1112 //
1113 // Iterate each Signature Data in this Signature List.
1114 //
1115 if (CompareMem (NewCert, Cert, CertList->SignatureSize) == 0) {
1116 IsNewCert = FALSE;
1117 break;
1118 }
1119
1120 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
1121 }
1122 }
1123
1124 if (!IsNewCert) {
1125 break;
1126 }
1127
1128 Size -= CertList->SignatureListSize;
1129 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
1130 }
1131
1132 if (IsNewCert) {
1133 //
1134 // New EFI_SIGNATURE_DATA, keep it.
1135 //
1136 if (CopiedCount == 0) {
1137 //
1138 // Copy EFI_SIGNATURE_LIST header for only once.
1139 //
1140 CopyMem (Tail, NewCertList, sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);
1141 Tail = Tail + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize;
1142 }
1143
1144 CopyMem (Tail, NewCert, NewCertList->SignatureSize);
1145 Tail += NewCertList->SignatureSize;
1146 CopiedCount++;
1147 }
1148
1149 NewCert = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCert + NewCertList->SignatureSize);
1150 }
1151
1152 //
1153 // Update SignatureListSize in the kept EFI_SIGNATURE_LIST.
1154 //
1155 if (CopiedCount != 0) {
1156 SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);
1157 CertList = (EFI_SIGNATURE_LIST *)(Tail - SignatureListSize);
1158 CertList->SignatureListSize = (UINT32)SignatureListSize;
1159 }
1160
1161 *NewDataSize -= NewCertList->SignatureListSize;
1162 NewCertList = (EFI_SIGNATURE_LIST *)((UINT8 *)NewCertList + NewCertList->SignatureListSize);
1163 }
1164
1165 TempDataSize = (Tail - (UINT8 *)TempData);
1166
1167 CopyMem (NewData, TempData, TempDataSize);
1168 *NewDataSize = TempDataSize;
1169
1170 return EFI_SUCCESS;
1171}
1172
1184BOOLEAN
1186 IN EFI_TIME *FirstTime,
1187 IN EFI_TIME *SecondTime
1188 )
1189{
1190 if (FirstTime->Year != SecondTime->Year) {
1191 return (BOOLEAN)(FirstTime->Year < SecondTime->Year);
1192 } else if (FirstTime->Month != SecondTime->Month) {
1193 return (BOOLEAN)(FirstTime->Month < SecondTime->Month);
1194 } else if (FirstTime->Day != SecondTime->Day) {
1195 return (BOOLEAN)(FirstTime->Day < SecondTime->Day);
1196 } else if (FirstTime->Hour != SecondTime->Hour) {
1197 return (BOOLEAN)(FirstTime->Hour < SecondTime->Hour);
1198 } else if (FirstTime->Minute != SecondTime->Minute) {
1199 return (BOOLEAN)(FirstTime->Minute < SecondTime->Minute);
1200 }
1201
1202 return (BOOLEAN)(FirstTime->Second <= SecondTime->Second);
1203}
1204
1222 IN UINT8 HashAlgId,
1223 IN UINT8 *SignerCert,
1224 IN UINTN SignerCertSize,
1225 IN UINT8 *TopLevelCert,
1226 IN UINTN TopLevelCertSize,
1227 OUT UINT8 *ShaDigest
1228 )
1229{
1230 UINT8 *TbsCert;
1231 UINTN TbsCertSize;
1232 CHAR8 CertCommonName[128];
1233 UINTN CertCommonNameSize;
1234 BOOLEAN CryptoStatus;
1235 EFI_STATUS Status;
1236
1237 if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
1238 DEBUG ((DEBUG_INFO, "%a Unsupported Hash Algorithm %d\n", __func__, HashAlgId));
1239 return EFI_ABORTED;
1240 }
1241
1242 CertCommonNameSize = sizeof (CertCommonName);
1243
1244 //
1245 // Get SignerCert CommonName
1246 //
1247 Status = X509GetCommonName (SignerCert, SignerCertSize, CertCommonName, &CertCommonNameSize);
1248 if (EFI_ERROR (Status)) {
1249 DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with status %x\n", __func__, Status));
1250 return EFI_ABORTED;
1251 }
1252
1253 //
1254 // Get TopLevelCert tbsCertificate
1255 //
1256 if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert, &TbsCertSize)) {
1257 DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n", __func__));
1258 return EFI_ABORTED;
1259 }
1260
1261 //
1262 // Digest SignerCert CN + TopLevelCert tbsCertificate
1263 //
1264 ZeroMem (ShaDigest, mHashInfo[HashAlgId].HashSize);
1265 CryptoStatus = mHashInfo[HashAlgId].Init (*(mHashInfo[HashAlgId].HashShaCtx));
1266 if (!CryptoStatus) {
1267 return EFI_ABORTED;
1268 }
1269
1270 //
1271 // '\0' is forced in CertCommonName. No overflow issue
1272 //
1273 CryptoStatus = mHashInfo[HashAlgId].Update (
1274 *(mHashInfo[HashAlgId].HashShaCtx),
1275 CertCommonName,
1276 AsciiStrLen (CertCommonName)
1277 );
1278 if (!CryptoStatus) {
1279 return EFI_ABORTED;
1280 }
1281
1282 CryptoStatus = mHashInfo[HashAlgId].Update (*(mHashInfo[HashAlgId].HashShaCtx), TbsCert, TbsCertSize);
1283 if (!CryptoStatus) {
1284 return EFI_ABORTED;
1285 }
1286
1287 CryptoStatus = mHashInfo[HashAlgId].Final (*(mHashInfo[HashAlgId].HashShaCtx), ShaDigest);
1288 if (!CryptoStatus) {
1289 return EFI_ABORTED;
1290 }
1291
1292 return EFI_SUCCESS;
1293}
1294
1325 IN CHAR16 *VariableName,
1326 IN EFI_GUID *VendorGuid,
1327 IN UINT8 *Data,
1328 IN UINTN DataSize,
1329 OUT UINT32 *CertOffset OPTIONAL,
1330 OUT UINT32 *CertDataSize OPTIONAL,
1331 OUT UINT32 *CertNodeOffset OPTIONAL,
1332 OUT UINT32 *CertNodeSize OPTIONAL
1333 )
1334{
1335 UINT32 Offset;
1336 AUTH_CERT_DB_DATA *Ptr;
1337 UINT32 CertSize;
1338 UINT32 NameSize;
1339 UINT32 NodeSize;
1340 UINT32 CertDbListSize;
1341
1342 if ((VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {
1343 return EFI_INVALID_PARAMETER;
1344 }
1345
1346 //
1347 // Check whether DataSize matches recorded CertDbListSize.
1348 //
1349 if (DataSize < sizeof (UINT32)) {
1350 return EFI_INVALID_PARAMETER;
1351 }
1352
1353 CertDbListSize = ReadUnaligned32 ((UINT32 *)Data);
1354
1355 if (CertDbListSize != (UINT32)DataSize) {
1356 return EFI_INVALID_PARAMETER;
1357 }
1358
1359 Offset = sizeof (UINT32);
1360
1361 //
1362 // Get corresponding certificates by VendorGuid and VariableName.
1363 //
1364 while (Offset < (UINT32)DataSize) {
1365 Ptr = (AUTH_CERT_DB_DATA *)(Data + Offset);
1366 //
1367 // Check whether VendorGuid matches.
1368 //
1369 if (CompareGuid (&Ptr->VendorGuid, VendorGuid)) {
1370 NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);
1371 NameSize = ReadUnaligned32 (&Ptr->NameSize);
1372 CertSize = ReadUnaligned32 (&Ptr->CertDataSize);
1373
1374 if (NodeSize != sizeof (EFI_GUID) + sizeof (UINT32) * 3 + CertSize +
1375 sizeof (CHAR16) * NameSize)
1376 {
1377 return EFI_INVALID_PARAMETER;
1378 }
1379
1380 Offset = Offset + sizeof (EFI_GUID) + sizeof (UINT32) * 3;
1381 //
1382 // Check whether VariableName matches.
1383 //
1384 if ((NameSize == StrLen (VariableName)) &&
1385 (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0))
1386 {
1387 Offset = Offset + NameSize * sizeof (CHAR16);
1388
1389 if (CertOffset != NULL) {
1390 *CertOffset = Offset;
1391 }
1392
1393 if (CertDataSize != NULL) {
1394 *CertDataSize = CertSize;
1395 }
1396
1397 if (CertNodeOffset != NULL) {
1398 *CertNodeOffset = (UINT32)((UINT8 *)Ptr - Data);
1399 }
1400
1401 if (CertNodeSize != NULL) {
1402 *CertNodeSize = NodeSize;
1403 }
1404
1405 return EFI_SUCCESS;
1406 } else {
1407 Offset = Offset + NameSize * sizeof (CHAR16) + CertSize;
1408 }
1409 } else {
1410 NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);
1411 Offset = Offset + NodeSize;
1412 }
1413 }
1414
1415 return EFI_NOT_FOUND;
1416}
1417
1436 IN CHAR16 *VariableName,
1437 IN EFI_GUID *VendorGuid,
1438 IN UINT32 Attributes,
1439 OUT UINT8 **CertData,
1440 OUT UINT32 *CertDataSize
1441 )
1442{
1443 EFI_STATUS Status;
1444 UINT8 *Data;
1445 UINTN DataSize;
1446 UINT32 CertOffset;
1447 CHAR16 *DbName;
1448
1449 if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL) || (CertDataSize == NULL)) {
1450 return EFI_INVALID_PARAMETER;
1451 }
1452
1453 if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
1454 //
1455 // Get variable "certdb".
1456 //
1457 DbName = EFI_CERT_DB_NAME;
1458 } else {
1459 //
1460 // Get variable "certdbv".
1461 //
1462 DbName = EFI_CERT_DB_VOLATILE_NAME;
1463 }
1464
1465 //
1466 // Get variable "certdb" or "certdbv".
1467 //
1469 DbName,
1470 &gEfiCertDbGuid,
1471 (VOID **)&Data,
1472 &DataSize
1473 );
1474 if (EFI_ERROR (Status)) {
1475 return Status;
1476 }
1477
1478 if ((DataSize == 0) || (Data == NULL)) {
1479 ASSERT (FALSE);
1480 return EFI_NOT_FOUND;
1481 }
1482
1483 Status = FindCertsFromDb (
1484 VariableName,
1485 VendorGuid,
1486 Data,
1487 DataSize,
1488 &CertOffset,
1489 CertDataSize,
1490 NULL,
1491 NULL
1492 );
1493
1494 if (EFI_ERROR (Status)) {
1495 return Status;
1496 }
1497
1498 *CertData = Data + CertOffset;
1499 return EFI_SUCCESS;
1500}
1501
1519 IN CHAR16 *VariableName,
1520 IN EFI_GUID *VendorGuid,
1521 IN UINT32 Attributes
1522 )
1523{
1524 EFI_STATUS Status;
1525 UINT8 *Data;
1526 UINTN DataSize;
1527 UINT32 VarAttr;
1528 UINT32 CertNodeOffset;
1529 UINT32 CertNodeSize;
1530 UINT8 *NewCertDb;
1531 UINT32 NewCertDbSize;
1532 CHAR16 *DbName;
1533
1534 if ((VariableName == NULL) || (VendorGuid == NULL)) {
1535 return EFI_INVALID_PARAMETER;
1536 }
1537
1538 if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
1539 //
1540 // Get variable "certdb".
1541 //
1542 DbName = EFI_CERT_DB_NAME;
1543 VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
1544 } else {
1545 //
1546 // Get variable "certdbv".
1547 //
1548 DbName = EFI_CERT_DB_VOLATILE_NAME;
1549 VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
1550 }
1551
1553 DbName,
1554 &gEfiCertDbGuid,
1555 (VOID **)&Data,
1556 &DataSize
1557 );
1558
1559 if (EFI_ERROR (Status)) {
1560 return Status;
1561 }
1562
1563 if ((DataSize == 0) || (Data == NULL)) {
1564 ASSERT (FALSE);
1565 return EFI_NOT_FOUND;
1566 }
1567
1568 if (DataSize == sizeof (UINT32)) {
1569 //
1570 // There is no certs in "certdb" or "certdbv".
1571 //
1572 return EFI_SUCCESS;
1573 }
1574
1575 //
1576 // Get corresponding cert node from "certdb" or "certdbv".
1577 //
1578 Status = FindCertsFromDb (
1579 VariableName,
1580 VendorGuid,
1581 Data,
1582 DataSize,
1583 NULL,
1584 NULL,
1585 &CertNodeOffset,
1586 &CertNodeSize
1587 );
1588
1589 if (EFI_ERROR (Status)) {
1590 return Status;
1591 }
1592
1593 if (DataSize < (CertNodeOffset + CertNodeSize)) {
1594 return EFI_NOT_FOUND;
1595 }
1596
1597 //
1598 // Construct new data content of variable "certdb" or "certdbv".
1599 //
1600 NewCertDbSize = (UINT32)DataSize - CertNodeSize;
1601 NewCertDb = (UINT8 *)mCertDbStore;
1602
1603 //
1604 // Copy the DB entries before deleting node.
1605 //
1606 CopyMem (NewCertDb, Data, CertNodeOffset);
1607 //
1608 // Update CertDbListSize.
1609 //
1610 CopyMem (NewCertDb, &NewCertDbSize, sizeof (UINT32));
1611 //
1612 // Copy the DB entries after deleting node.
1613 //
1614 if (DataSize > (CertNodeOffset + CertNodeSize)) {
1615 CopyMem (
1616 NewCertDb + CertNodeOffset,
1617 Data + CertNodeOffset + CertNodeSize,
1618 DataSize - CertNodeOffset - CertNodeSize
1619 );
1620 }
1621
1622 //
1623 // Set "certdb" or "certdbv".
1624 //
1626 DbName,
1627 &gEfiCertDbGuid,
1628 NewCertDb,
1629 NewCertDbSize,
1630 VarAttr
1631 );
1632
1633 return Status;
1634}
1635
1660 IN UINT8 HashAlgId,
1661 IN CHAR16 *VariableName,
1662 IN EFI_GUID *VendorGuid,
1663 IN UINT32 Attributes,
1664 IN UINT8 *SignerCert,
1665 IN UINTN SignerCertSize,
1666 IN UINT8 *TopLevelCert,
1667 IN UINTN TopLevelCertSize
1668 )
1669{
1670 EFI_STATUS Status;
1671 UINT8 *Data;
1672 UINTN DataSize;
1673 UINT32 VarAttr;
1674 UINT8 *NewCertDb;
1675 UINT32 NewCertDbSize;
1676 UINT32 CertNodeSize;
1677 UINT32 NameSize;
1678 UINT32 CertDataSize;
1679 AUTH_CERT_DB_DATA *Ptr;
1680 CHAR16 *DbName;
1681 UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];
1682
1683 if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {
1684 return EFI_INVALID_PARAMETER;
1685 }
1686
1687 if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
1688 return EFI_INVALID_PARAMETER;
1689 }
1690
1691 if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
1692 //
1693 // Get variable "certdb".
1694 //
1695 DbName = EFI_CERT_DB_NAME;
1696 VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
1697 } else {
1698 //
1699 // Get variable "certdbv".
1700 //
1701 DbName = EFI_CERT_DB_VOLATILE_NAME;
1702 VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
1703 }
1704
1705 //
1706 // Get variable "certdb" or "certdbv".
1707 //
1709 DbName,
1710 &gEfiCertDbGuid,
1711 (VOID **)&Data,
1712 &DataSize
1713 );
1714 if (EFI_ERROR (Status)) {
1715 return Status;
1716 }
1717
1718 if ((DataSize == 0) || (Data == NULL)) {
1719 ASSERT (FALSE);
1720 return EFI_NOT_FOUND;
1721 }
1722
1723 //
1724 // Find whether matching cert node already exists in "certdb" or "certdbv".
1725 // If yes return error.
1726 //
1727 Status = FindCertsFromDb (
1728 VariableName,
1729 VendorGuid,
1730 Data,
1731 DataSize,
1732 NULL,
1733 NULL,
1734 NULL,
1735 NULL
1736 );
1737
1738 if (!EFI_ERROR (Status)) {
1739 ASSERT (FALSE);
1740 return EFI_ACCESS_DENIED;
1741 }
1742
1743 //
1744 // Construct new data content of variable "certdb" or "certdbv".
1745 //
1746 NameSize = (UINT32)StrLen (VariableName);
1747 CertDataSize = mHashInfo[HashAlgId].HashSize;
1748 CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);
1749 NewCertDbSize = (UINT32)DataSize + CertNodeSize;
1750 if (NewCertDbSize > mMaxCertDbSize) {
1751 return EFI_OUT_OF_RESOURCES;
1752 }
1753
1755 HashAlgId,
1756 SignerCert,
1757 SignerCertSize,
1758 TopLevelCert,
1759 TopLevelCertSize,
1760 ShaDigest
1761 );
1762
1763 if (EFI_ERROR (Status)) {
1764 return Status;
1765 }
1766
1767 NewCertDb = (UINT8 *)mCertDbStore;
1768
1769 //
1770 // Copy the DB entries before inserting node.
1771 //
1772 CopyMem (NewCertDb, Data, DataSize);
1773 //
1774 // Update CertDbListSize.
1775 //
1776 CopyMem (NewCertDb, &NewCertDbSize, sizeof (UINT32));
1777 //
1778 // Construct new cert node.
1779 //
1780 Ptr = (AUTH_CERT_DB_DATA *)(NewCertDb + DataSize);
1781 CopyGuid (&Ptr->VendorGuid, VendorGuid);
1782 CopyMem (&Ptr->CertNodeSize, &CertNodeSize, sizeof (UINT32));
1783 CopyMem (&Ptr->NameSize, &NameSize, sizeof (UINT32));
1784 CopyMem (&Ptr->CertDataSize, &CertDataSize, sizeof (UINT32));
1785
1786 CopyMem (
1787 (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA),
1788 VariableName,
1789 NameSize * sizeof (CHAR16)
1790 );
1791
1792 CopyMem (
1793 (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),
1794 ShaDigest,
1795 CertDataSize
1796 );
1797
1798 //
1799 // Set "certdb" or "certdbv".
1800 //
1802 DbName,
1803 &gEfiCertDbGuid,
1804 NewCertDb,
1805 NewCertDbSize,
1806 VarAttr
1807 );
1808
1809 return Status;
1810}
1811
1826 VOID
1827 )
1828{
1829 UINT32 Offset;
1830 AUTH_CERT_DB_DATA *Ptr;
1831 UINT32 NameSize;
1832 UINT32 NodeSize;
1833 CHAR16 *VariableName;
1834 EFI_STATUS Status;
1835 BOOLEAN CertCleaned;
1836 UINT8 *Data;
1837 UINTN DataSize;
1838 EFI_GUID AuthVarGuid;
1839 AUTH_VARIABLE_INFO AuthVariableInfo;
1840
1841 Status = EFI_SUCCESS;
1842
1843 //
1844 // Get corresponding certificates by VendorGuid and VariableName.
1845 //
1846 do {
1847 CertCleaned = FALSE;
1848
1849 //
1850 // Get latest variable "certdb"
1851 //
1854 &gEfiCertDbGuid,
1855 (VOID **)&Data,
1856 &DataSize
1857 );
1858 if (EFI_ERROR (Status)) {
1859 return Status;
1860 }
1861
1862 if ((DataSize == 0) || (Data == NULL)) {
1863 ASSERT (FALSE);
1864 return EFI_NOT_FOUND;
1865 }
1866
1867 Offset = sizeof (UINT32);
1868
1869 while (Offset < (UINT32)DataSize) {
1870 Ptr = (AUTH_CERT_DB_DATA *)(Data + Offset);
1871 NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);
1872 NameSize = ReadUnaligned32 (&Ptr->NameSize);
1873
1874 //
1875 // Get VarName tailed with '\0'
1876 //
1877 VariableName = AllocateZeroPool ((NameSize + 1) * sizeof (CHAR16));
1878 if (VariableName == NULL) {
1879 return EFI_OUT_OF_RESOURCES;
1880 }
1881
1882 CopyMem (VariableName, (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof (CHAR16));
1883 //
1884 // Keep VarGuid aligned
1885 //
1886 CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof (EFI_GUID));
1887
1888 //
1889 // Find corresponding time auth variable
1890 //
1891 ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));
1892 Status = mAuthVarLibContextIn->FindVariable (
1893 VariableName,
1894 &AuthVarGuid,
1895 &AuthVariableInfo
1896 );
1897
1898 if (EFI_ERROR (Status) || ((AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0)) {
1899 //
1900 // While cleaning certdb, always delete the variable in certdb regardless of it attributes.
1901 //
1902 Status = DeleteCertsFromDb (
1903 VariableName,
1904 &AuthVarGuid,
1905 AuthVariableInfo.Attributes | EFI_VARIABLE_NON_VOLATILE
1906 );
1907 CertCleaned = TRUE;
1908 DEBUG ((DEBUG_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));
1909 FreePool (VariableName);
1910 break;
1911 }
1912
1913 FreePool (VariableName);
1914 Offset = Offset + NodeSize;
1915 }
1916 } while (CertCleaned);
1917
1918 return Status;
1919}
1920
1929UINT8
1931 IN UINT8 *SigData,
1932 IN UINT32 SigDataSize
1933 )
1934{
1935 UINT8 i;
1936
1937 for (i = 0; i < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO)); i++) {
1938 if ( ( (SigDataSize >= (13 + mHashInfo[i].OidLength))
1939 && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
1940 && (CompareMem (SigData + 13, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0)))
1941 || ( ((SigDataSize >= (32 + mHashInfo[i].OidLength)))
1942 && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) == TWO_BYTE_ENCODE)
1943 && (CompareMem (SigData + 32, mHashInfo[i].OidValue, mHashInfo[i].OidLength) == 0))))
1944 {
1945 break;
1946 }
1947 }
1948
1949 return i;
1950}
1951
1983 IN CHAR16 *VariableName,
1984 IN EFI_GUID *VendorGuid,
1985 IN VOID *Data,
1986 IN UINTN DataSize,
1987 IN UINT32 Attributes,
1988 IN AUTHVAR_TYPE AuthVarType,
1989 IN EFI_TIME *OrgTimeStamp,
1990 OUT UINT8 **VarPayloadPtr,
1991 OUT UINTN *VarPayloadSize
1992 )
1993{
1995 UINT8 *SigData;
1996 UINT32 SigDataSize;
1997 UINT8 *PayloadPtr;
1998 UINTN PayloadSize;
1999 UINT32 Attr;
2000 BOOLEAN VerifyStatus;
2001 EFI_STATUS Status;
2002 EFI_SIGNATURE_LIST *CertList;
2003 EFI_SIGNATURE_DATA *Cert;
2004 UINTN Index;
2005 UINTN CertCount;
2006 UINT32 KekDataSize;
2007 UINT8 *NewData;
2008 UINTN NewDataSize;
2009 UINT8 *Buffer;
2010 UINTN Length;
2011 UINT8 *TopLevelCert;
2012 UINTN TopLevelCertSize;
2013 UINT8 *TrustedCert;
2014 UINTN TrustedCertSize;
2015 UINT8 *SignerCerts;
2016 UINTN CertStackSize;
2017 UINT8 *CertsInCertDb;
2018 UINT32 CertsSizeinDb;
2019 UINT8 ShaDigest[SHA_DIGEST_SIZE_MAX];
2020 EFI_CERT_DATA *CertDataPtr;
2021 UINT8 HashAlgId;
2022
2023 //
2024 // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain
2025 // 2. TrustedCert is the certificate which firmware trusts. It could be saved in protected
2026 // storage or PK payload on PK init
2027 //
2028 VerifyStatus = FALSE;
2029 CertData = NULL;
2030 NewData = NULL;
2031 Attr = Attributes;
2032 SignerCerts = NULL;
2033 TopLevelCert = NULL;
2034 CertsInCertDb = NULL;
2035 CertDataPtr = NULL;
2036
2037 //
2038 // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
2039 // set, then the Data buffer shall begin with an instance of a complete (and serialized)
2040 // EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
2041 // variable value and DataSize shall reflect the combined size of the descriptor and the new
2042 // variable value. The authentication descriptor is not part of the variable data and is not
2043 // returned by subsequent calls to GetVariable().
2044 //
2045 CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;
2046
2047 //
2048 // Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the
2049 // TimeStamp value are set to zero.
2050 //
2051 if ((CertData->TimeStamp.Pad1 != 0) ||
2052 (CertData->TimeStamp.Nanosecond != 0) ||
2053 (CertData->TimeStamp.TimeZone != 0) ||
2054 (CertData->TimeStamp.Daylight != 0) ||
2055 (CertData->TimeStamp.Pad2 != 0))
2056 {
2057 return EFI_SECURITY_VIOLATION;
2058 }
2059
2060 if ((OrgTimeStamp != NULL) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {
2061 if (AuthServiceInternalCompareTimeStamp (&CertData->TimeStamp, OrgTimeStamp)) {
2062 //
2063 // TimeStamp check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
2064 //
2065 return EFI_SECURITY_VIOLATION;
2066 }
2067 }
2068
2069 //
2070 // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
2071 // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.
2072 //
2073 if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
2074 !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid))
2075 {
2076 //
2077 // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
2078 //
2079 return EFI_SECURITY_VIOLATION;
2080 }
2081
2082 //
2083 // Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
2084 // AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.
2085 //
2086 SigData = CertData->AuthInfo.CertData;
2087 SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32)(OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));
2088
2089 //
2090 // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the
2091 // signature. Only a digest algorithm of SHA-256, SHA-384 or SHA-512 is accepted.
2092 //
2093 // According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):
2094 // SignedData ::= SEQUENCE {
2095 // version Version,
2096 // digestAlgorithms DigestAlgorithmIdentifiers,
2097 // contentInfo ContentInfo,
2098 // .... }
2099 // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm
2100 // in VARIABLE_AUTHENTICATION_2 descriptor.
2101 // This field has the fixed offset (+13) or (+32) based on whether the DER-encoded
2102 // ContentInfo structure is present or not, and can be calculated based on two
2103 // bytes of length encoding.
2104 //
2105 // Both condition can be handled in WrapPkcs7Data() in CryptPkcs7VerifyCommon.c.
2106 //
2107 // See below examples:
2108 //
2109 // 1. Without ContentInfo
2110 // 30 82 0c da // SEQUENCE (5 element) (3294 BYTES) -- SignedData
2111 // 02 01 01 // INTEGER 1 -- Version
2112 // 31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers
2113 // 30 0d // SEQUENCE (2 element) (13 BYTES) -- AlgorithmIdentifier
2114 // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm
2115 // 60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]
2116 // 05 00 // NULL (0 BYTES) -- parameters
2117 //
2118 // Example from: https://uefi.org/revocationlistfile
2119 //
2120 // 2. With ContentInfo
2121 // 30 82 05 90 // SEQUENCE (1424 BYTES) -- ContentInfo
2122 // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- ContentType
2123 // 2a 86 48 86 f7 0d 01 07 02 // signedData [1.2.840.113549.1.7.2]
2124 // a0 82 05 81 // CONTEXT-SPECIFIC CONSTRUCTED TAG 0 (1409 BYTES) -- content
2125 // 30 82 05 7d // SEQUENCE (1405 BYTES) -- SignedData
2126 // 02 01 01 // INTEGER 1 -- Version
2127 // 31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers
2128 // 30 0d // SEQUENCE (13 BYTES) -- AlgorithmIdentifier
2129 // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm
2130 // 60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]
2131 // 05 00 // NULL (0 BYTES) -- parameters
2132 //
2133 // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process
2134 //
2135 HashAlgId = FindHashAlgorithmIndex (SigData, SigDataSize);
2137 if (HashAlgId >= (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) {
2138 return EFI_SECURITY_VIOLATION;
2139 }
2140 }
2141
2142 //
2143 // Find out the new data payload which follows Pkcs7 SignedData directly.
2144 //
2145 PayloadPtr = SigData + SigDataSize;
2146 PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN)SigDataSize;
2147
2148 // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.
2149 if ((PayloadSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && !IsVariablePolicyEnabled ()) {
2150 VerifyStatus = TRUE;
2151 goto Exit;
2152 }
2153
2154 //
2155 // Construct a serialization buffer of the values of the VariableName, VendorGuid and Attributes
2156 // parameters of the SetVariable() call and the TimeStamp component of the
2157 // EFI_VARIABLE_AUTHENTICATION_2 descriptor followed by the variable's new value
2158 // i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data)
2159 //
2160 NewDataSize = PayloadSize + sizeof (EFI_TIME) + sizeof (UINT32) +
2161 sizeof (EFI_GUID) + StrSize (VariableName) - sizeof (CHAR16);
2162
2163 //
2164 // Here is to reuse scratch data area(at the end of volatile variable store)
2165 // to reduce SMRAM consumption for SMM variable driver.
2166 // The scratch buffer is enough to hold the serialized data and safe to use,
2167 // because it is only used at here to do verification temporarily first
2168 // and then used in UpdateVariable() for a time based auth variable set.
2169 //
2170 Status = mAuthVarLibContextIn->GetScratchBuffer (&NewDataSize, (VOID **)&NewData);
2171 if (EFI_ERROR (Status)) {
2172 return EFI_OUT_OF_RESOURCES;
2173 }
2174
2175 Buffer = NewData;
2176 Length = StrLen (VariableName) * sizeof (CHAR16);
2177 CopyMem (Buffer, VariableName, Length);
2178 Buffer += Length;
2179
2180 Length = sizeof (EFI_GUID);
2181 CopyMem (Buffer, VendorGuid, Length);
2182 Buffer += Length;
2183
2184 Length = sizeof (UINT32);
2185 CopyMem (Buffer, &Attr, Length);
2186 Buffer += Length;
2187
2188 Length = sizeof (EFI_TIME);
2189 CopyMem (Buffer, &CertData->TimeStamp, Length);
2190 Buffer += Length;
2191
2192 CopyMem (Buffer, PayloadPtr, PayloadSize);
2193
2194 if (AuthVarType == AuthVarTypePk) {
2195 //
2196 // Verify that the signature has been made with the current Platform Key (no chaining for PK).
2197 // First, get signer's certificates from SignedData.
2198 //
2199 VerifyStatus = Pkcs7GetSigners (
2200 SigData,
2201 SigDataSize,
2202 &SignerCerts,
2203 &CertStackSize,
2204 &TopLevelCert,
2205 &TopLevelCertSize
2206 );
2207 if (!VerifyStatus) {
2208 goto Exit;
2209 }
2210
2211 //
2212 // Second, get the current platform key from variable. Check whether it's identical with signer's certificates
2213 // in SignedData. If not, return error immediately.
2214 //
2217 &gEfiGlobalVariableGuid,
2218 &Data,
2219 &DataSize
2220 );
2221 if (EFI_ERROR (Status)) {
2222 VerifyStatus = FALSE;
2223 goto Exit;
2224 }
2225
2226 CertList = (EFI_SIGNATURE_LIST *)Data;
2227 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
2228 if ((TopLevelCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||
2229 (CompareMem (Cert->SignatureData, TopLevelCert, TopLevelCertSize) != 0))
2230 {
2231 VerifyStatus = FALSE;
2232 goto Exit;
2233 }
2234
2235 //
2236 // Verify Pkcs7 SignedData via Pkcs7Verify library.
2237 //
2238 VerifyStatus = Pkcs7Verify (
2239 SigData,
2240 SigDataSize,
2241 TopLevelCert,
2242 TopLevelCertSize,
2243 NewData,
2244 NewDataSize
2245 );
2246 } else if (AuthVarType == AuthVarTypeKek) {
2247 //
2248 // Get KEK database from variable.
2249 //
2252 &gEfiGlobalVariableGuid,
2253 &Data,
2254 &DataSize
2255 );
2256 if (EFI_ERROR (Status)) {
2257 return Status;
2258 }
2259
2260 //
2261 // Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.
2262 //
2263 KekDataSize = (UINT32)DataSize;
2264 CertList = (EFI_SIGNATURE_LIST *)Data;
2265 while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {
2266 if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
2267 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
2268 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
2269 for (Index = 0; Index < CertCount; Index++) {
2270 //
2271 // Iterate each Signature Data Node within this CertList for a verify
2272 //
2273 TrustedCert = Cert->SignatureData;
2274 TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);
2275
2276 //
2277 // Verify Pkcs7 SignedData via Pkcs7Verify library.
2278 //
2279 VerifyStatus = Pkcs7Verify (
2280 SigData,
2281 SigDataSize,
2282 TrustedCert,
2283 TrustedCertSize,
2284 NewData,
2285 NewDataSize
2286 );
2287 if (VerifyStatus) {
2288 goto Exit;
2289 }
2290
2291 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
2292 }
2293 }
2294
2295 KekDataSize -= CertList->SignatureListSize;
2296 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
2297 }
2298 } else if (AuthVarType == AuthVarTypePriv) {
2299 //
2300 // Process common authenticated variable except PK/KEK/DB/DBX/DBT.
2301 // Get signer's certificates from SignedData.
2302 //
2303 VerifyStatus = Pkcs7GetSigners (
2304 SigData,
2305 SigDataSize,
2306 &SignerCerts,
2307 &CertStackSize,
2308 &TopLevelCert,
2309 &TopLevelCertSize
2310 );
2311 if (!VerifyStatus) {
2312 goto Exit;
2313 }
2314
2315 //
2316 // Get previously stored signer's certificates from certdb or certdbv for existing
2317 // variable. Check whether they are identical with signer's certificates
2318 // in SignedData. If not, return error immediately.
2319 //
2320 if (OrgTimeStamp != NULL) {
2321 VerifyStatus = FALSE;
2322
2323 Status = GetCertsFromDb (VariableName, VendorGuid, Attributes, &CertsInCertDb, &CertsSizeinDb);
2324 if (EFI_ERROR (Status)) {
2325 goto Exit;
2326 }
2327
2328 if ((HashAlgId < (sizeof (mHashInfo) / sizeof (EFI_HASH_INFO))) && (CertsSizeinDb == mHashInfo[HashAlgId].HashSize)) {
2329 //
2330 // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb
2331 //
2332 CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
2334 HashAlgId,
2335 CertDataPtr->CertDataBuffer,
2336 ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
2337 TopLevelCert,
2338 TopLevelCertSize,
2339 ShaDigest
2340 );
2341 if (EFI_ERROR (Status) || (CompareMem (ShaDigest, CertsInCertDb, CertsSizeinDb) != 0)) {
2342 goto Exit;
2343 }
2344 } else {
2345 //
2346 // Keep backward compatible with previous solution which saves whole signer certs stack in CertDb
2347 //
2348 if ((CertStackSize != CertsSizeinDb) ||
2349 (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0))
2350 {
2351 goto Exit;
2352 }
2353 }
2354 }
2355
2356 VerifyStatus = Pkcs7Verify (
2357 SigData,
2358 SigDataSize,
2359 TopLevelCert,
2360 TopLevelCertSize,
2361 NewData,
2362 NewDataSize
2363 );
2364 if (!VerifyStatus) {
2365 goto Exit;
2366 }
2367
2368 if ((OrgTimeStamp == NULL) && (PayloadSize != 0)) {
2369 //
2370 // When adding a new common authenticated variable, always save Hash of cn of signer cert + tbsCertificate of Top-level issuer
2371 //
2372 CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);
2373 Status = InsertCertsToDb (
2374 HashAlgId,
2375 VariableName,
2376 VendorGuid,
2377 Attributes,
2378 CertDataPtr->CertDataBuffer,
2379 ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),
2380 TopLevelCert,
2381 TopLevelCertSize
2382 );
2383 if (EFI_ERROR (Status)) {
2384 VerifyStatus = FALSE;
2385 goto Exit;
2386 }
2387 }
2388 } else if (AuthVarType == AuthVarTypePayload) {
2389 CertList = (EFI_SIGNATURE_LIST *)PayloadPtr;
2390 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
2391 TrustedCert = Cert->SignatureData;
2392 TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);
2393 //
2394 // Verify Pkcs7 SignedData via Pkcs7Verify library.
2395 //
2396 VerifyStatus = Pkcs7Verify (
2397 SigData,
2398 SigDataSize,
2399 TrustedCert,
2400 TrustedCertSize,
2401 NewData,
2402 NewDataSize
2403 );
2404 } else {
2405 return EFI_SECURITY_VIOLATION;
2406 }
2407
2408Exit:
2409
2410 if ((AuthVarType == AuthVarTypePk) || (AuthVarType == AuthVarTypePriv)) {
2411 if (TopLevelCert != NULL) {
2412 Pkcs7FreeSigners (TopLevelCert);
2413 }
2414
2415 if (SignerCerts != NULL) {
2416 Pkcs7FreeSigners (SignerCerts);
2417 }
2418 }
2419
2420 if (!VerifyStatus) {
2421 return EFI_SECURITY_VIOLATION;
2422 }
2423
2424 Status = CheckSignatureListFormat (VariableName, VendorGuid, PayloadPtr, PayloadSize);
2425 if (EFI_ERROR (Status)) {
2426 return Status;
2427 }
2428
2429 *VarPayloadPtr = PayloadPtr;
2430 *VarPayloadSize = PayloadSize;
2431
2432 return EFI_SUCCESS;
2433}
2434
2463 IN CHAR16 *VariableName,
2464 IN EFI_GUID *VendorGuid,
2465 IN VOID *Data,
2466 IN UINTN DataSize,
2467 IN UINT32 Attributes,
2468 IN AUTHVAR_TYPE AuthVarType,
2469 OUT BOOLEAN *VarDel
2470 )
2471{
2472 EFI_STATUS Status;
2473 EFI_STATUS FindStatus;
2474 UINT8 *PayloadPtr;
2475 UINTN PayloadSize;
2477 AUTH_VARIABLE_INFO OrgVariableInfo;
2478 BOOLEAN IsDel;
2479
2480 ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));
2481 FindStatus = mAuthVarLibContextIn->FindVariable (
2482 VariableName,
2483 VendorGuid,
2484 &OrgVariableInfo
2485 );
2486
2487 Status = VerifyTimeBasedPayload (
2488 VariableName,
2489 VendorGuid,
2490 Data,
2491 DataSize,
2492 Attributes,
2493 AuthVarType,
2494 (!EFI_ERROR (FindStatus)) ? OrgVariableInfo.TimeStamp : NULL,
2495 &PayloadPtr,
2496 &PayloadSize
2497 );
2498 if (EFI_ERROR (Status)) {
2499 return Status;
2500 }
2501
2502 if ( !EFI_ERROR (FindStatus)
2503 && (PayloadSize == 0)
2504 && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0))
2505 {
2506 IsDel = TRUE;
2507 } else {
2508 IsDel = FALSE;
2509 }
2510
2511 CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;
2512
2513 //
2514 // Final step: Update/Append Variable if it pass Pkcs7Verify
2515 //
2517 VariableName,
2518 VendorGuid,
2519 PayloadPtr,
2520 PayloadSize,
2521 Attributes,
2522 &CertData->TimeStamp
2523 );
2524
2525 //
2526 // Delete signer's certificates when delete the common authenticated variable.
2527 //
2528 if (IsDel && (AuthVarType == AuthVarTypePriv) && !EFI_ERROR (Status)) {
2529 Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);
2530 }
2531
2532 if (VarDel != NULL) {
2533 if (IsDel && !EFI_ERROR (Status)) {
2534 *VarDel = TRUE;
2535 } else {
2536 *VarDel = FALSE;
2537 }
2538 }
2539
2540 return Status;
2541}
UINT64 UINTN
EFI_STATUS AuthServiceInternalUpdateVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes)
Definition: AuthService.c:228
EFI_STATUS CheckSignatureListFormat(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize)
Definition: AuthService.c:512
EFI_STATUS VerifyTimeBasedPayloadAndUpdate(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes, IN AUTHVAR_TYPE AuthVarType, OUT BOOLEAN *VarDel)
Definition: AuthService.c:2462
EFI_STATUS UpdatePlatformMode(IN UINT32 Mode)
Definition: AuthService.c:384
EFI_STATUS ProcessVarWithKek(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes OPTIONAL)
Definition: AuthService.c:820
UINTN(EFIAPI * EFI_HASH_GET_CONTEXT_SIZE)(VOID)
Definition: AuthService.c:45
EFI_STATUS VendorKeyIsModified(VOID)
Definition: AuthService.c:634
EFI_STATUS GetCertsFromDb(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, OUT UINT8 **CertData, OUT UINT32 *CertDataSize)
Definition: AuthService.c:1435
BOOLEAN IsDeleteAuthVariable(IN UINT32 OrgAttributes, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes)
Definition: AuthService.c:901
BOOLEAN(EFIAPI * EFI_HASH_UPDATE)(IN OUT VOID *HashContext, IN CONST VOID *Data, IN UINTN DataSize)
Definition: AuthService.c:91
BOOLEAN InCustomMode(VOID)
Definition: AuthService.c:358
EFI_STATUS AuthServiceInternalUpdateVariableWithTimeStamp(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes, IN EFI_TIME *TimeStamp)
Definition: AuthService.c:267
BOOLEAN AuthServiceInternalCompareTimeStamp(IN EFI_TIME *FirstTime, IN EFI_TIME *SecondTime)
Definition: AuthService.c:1185
BOOLEAN(EFIAPI * EFI_HASH_INIT)(OUT VOID *HashContext)
Definition: AuthService.c:65
EFI_STATUS AuthServiceInternalFindVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT VOID **Data, OUT UINTN *DataSize)
Definition: AuthService.c:191
UINT8 FindHashAlgorithmIndex(IN UINT8 *SigData, IN UINT32 SigDataSize)
Definition: AuthService.c:1930
EFI_STATUS FindCertsFromDb(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT8 *Data, IN UINTN DataSize, OUT UINT32 *CertOffset OPTIONAL, OUT UINT32 *CertDataSize OPTIONAL, OUT UINT32 *CertNodeOffset OPTIONAL, OUT UINT32 *CertNodeSize OPTIONAL)
Definition: AuthService.c:1324
EFI_STATUS ProcessVarWithPk(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes OPTIONAL, IN BOOLEAN IsPk)
Definition: AuthService.c:691
EFI_STATUS InsertCertsToDb(IN UINT8 HashAlgId, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINT8 *SignerCert, IN UINTN SignerCertSize, IN UINT8 *TopLevelCert, IN UINTN TopLevelCertSize)
Definition: AuthService.c:1659
BOOLEAN NeedPhysicallyPresent(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid)
Definition: AuthService.c:333
EFI_STATUS VerifyTimeBasedPayload(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes, IN AUTHVAR_TYPE AuthVarType, IN EFI_TIME *OrgTimeStamp, OUT UINT8 **VarPayloadPtr, OUT UINTN *VarPayloadSize)
Definition: AuthService.c:1982
EFI_STATUS ProcessVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN UINT32 Attributes)
Definition: AuthService.c:965
EFI_STATUS CalculatePrivAuthVarSignChainSHADigest(IN UINT8 HashAlgId, IN UINT8 *SignerCert, IN UINTN SignerCertSize, IN UINT8 *TopLevelCert, IN UINTN TopLevelCertSize, OUT UINT8 *ShaDigest)
Definition: AuthService.c:1221
EFI_STATUS CleanCertsFromDb(VOID)
Definition: AuthService.c:1825
EFI_STATUS FilterSignatureList(IN VOID *Data, IN UINTN DataSize, IN OUT VOID *NewData, IN OUT UINTN *NewDataSize)
Definition: AuthService.c:1058
BOOLEAN(EFIAPI * EFI_HASH_FINAL)(IN OUT VOID *HashContext, OUT UINT8 *HashValue)
Definition: AuthService.c:121
EFI_STATUS DeleteCertsFromDb(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes)
Definition: AuthService.c:1518
#define EFI_CERT_DB_NAME
UINT8 * mCertDbStore
#define AUTHINFO_SIZE
#define EFI_CUSTOM_MODE_NAME
#define EFI_VENDOR_KEYS_NV_VARIABLE_NAME
#define EFI_SECURE_BOOT_ENABLE_NAME
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
VOID *EFIAPI RsaNew(VOID)
Definition: CryptRsaBasic.c:30
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 Pkcs7GetSigners(IN CONST UINT8 *P7Data, IN UINTN P7Length, OUT UINT8 **CertStack, OUT UINTN *StackLength, OUT UINT8 **TrustedCert, OUT UINTN *CertLength)
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 Pkcs7Verify(IN CONST UINT8 *P7Data, IN UINTN P7Length, IN CONST UINT8 *TrustedCert, IN UINTN CertLength, IN CONST UINT8 *InData, IN UINTN DataLength)
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
VOID EFIAPI Pkcs7FreeSigners(IN UINT8 *Certs)
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
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
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 *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define EFI_SETUP_MODE_NAME
#define EFI_KEY_EXCHANGE_KEY_NAME
#define EFI_PLATFORM_KEY_NAME
#define EFI_VENDOR_KEYS_VARIABLE_NAME
#define EFI_SECURE_BOOT_MODE_NAME
#define EFI_CERT_X509_SHA512_GUID
#define EFI_CERT_SHA512_GUID
#define EFI_CERT_SHA224_GUID
#define EFI_CERT_RSA2048_SHA1_GUID
#define EFI_CERT_SHA384_GUID
#define EFI_CERT_RSA2048_GUID
#define EFI_IMAGE_SECURITY_DATABASE2
#define EFI_CERT_SHA256_GUID
#define EFI_CERT_RSA2048_SHA256_GUID
#define EFI_IMAGE_SECURITY_DATABASE1
#define EFI_IMAGE_SECURITY_DATABASE
#define EFI_CERT_X509_SHA256_GUID
#define EFI_CERT_X509_GUID
#define EFI_CERT_SHA1_GUID
#define EFI_CERT_X509_SHA384_GUID
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
BOOLEAN EFIAPI UserPhysicalPresent(VOID)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
#define EFI_VARIABLE_NON_VOLATILE
#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
WIN_CERTIFICATE_UEFI_GUID AuthInfo
Definition: Base.h:213
UINT16 wCertificateType