2 Implement authentication services for the authenticated variable
5 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "AuthService.h"
20 /// Global database array for scratch
22 UINT8 mPubKeyStore
[MAX_KEYDB_SIZE
];
25 EFI_GUID mSignatureSupport
[SIGSUPPORT_NUM
] = {EFI_CERT_RSA2048_SHA256_GUID
, EFI_CERT_RSA2048_SHA1_GUID
};
27 // Public Exponent of RSA Key.
29 CONST UINT8 mRsaE
[] = { 0x01, 0x00, 0x01 };
31 // Hash context pointer
33 VOID
*mHashCtx
= NULL
;
36 // Pointer to runtime buffer.
37 // For "Append" operation to an existing variable, a read/modify/write operation
38 // is supported by firmware internally. Reserve runtime buffer to cache previous
39 // variable data in runtime phase because memory allocation is forbidden in virtual mode.
41 VOID
*mStorageArea
= NULL
;
44 // The serialization of the values of the VariableName, VendorGuid and Attributes
45 // parameters of the SetVariable() call and the TimeStamp component of the
46 // EFI_VARIABLE_AUTHENTICATION_2 descriptor followed by the variable's new value
47 // i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data)
49 UINT8
*mSerializationRuntimeBuffer
= NULL
;
52 Internal function to delete a Variable given its name and GUID, no authentication
55 @param[in] VariableName Name of the Variable.
56 @param[in] VendorGuid GUID of the Variable.
58 @retval EFI_SUCCESS Variable deleted successfully.
59 @retval Others The driver failded to start the device.
64 IN CHAR16
*VariableName
,
65 IN EFI_GUID
*VendorGuid
69 VARIABLE_POINTER_TRACK Variable
;
71 Status
= FindVariable (VariableName
, VendorGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
);
72 if (EFI_ERROR (Status
)) {
76 ASSERT (Variable
.CurrPtr
!= NULL
);
77 return UpdateVariable (VariableName
, VendorGuid
, NULL
, 0, 0, 0, 0, &Variable
, NULL
);
81 Initializes for authenticated varibale service.
83 @retval EFI_SUCCESS Function successfully executed.
84 @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resources.
88 AutenticatedVariableServiceInitialize (
93 VARIABLE_POINTER_TRACK Variable
;
94 VARIABLE_POINTER_TRACK PkVariable
;
100 UINT8 SecureBootMode
;
101 UINT8 SecureBootEnable
;
104 // Initialize hash context.
106 CtxSize
= Sha256GetContextSize ();
107 mHashCtx
= AllocateRuntimePool (CtxSize
);
108 if (mHashCtx
== NULL
) {
109 return EFI_OUT_OF_RESOURCES
;
113 // Reserved runtime buffer for "Append" operation in virtual mode.
115 mStorageArea
= AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize
));
116 if (mStorageArea
== NULL
) {
117 return EFI_OUT_OF_RESOURCES
;
121 // Prepare runtime buffer for serialized data of time-based authenticated
122 // Variable, i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data).
124 mSerializationRuntimeBuffer
= AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize
) + sizeof (EFI_GUID
) + sizeof (UINT32
) + sizeof (EFI_TIME
));
125 if (mSerializationRuntimeBuffer
== NULL
) {
126 return EFI_OUT_OF_RESOURCES
;
130 // Check "AuthVarKeyDatabase" variable's existence.
131 // If it doesn't exist, create a new one with initial value of 0 and EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
133 Status
= FindVariable (
135 &gEfiAuthenticatedVariableGuid
,
137 &mVariableModuleGlobal
->VariableGlobal
140 if (Variable
.CurrPtr
== NULL
) {
141 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
144 Status
= UpdateVariable (
146 &gEfiAuthenticatedVariableGuid
,
155 if (EFI_ERROR (Status
)) {
160 // Load database in global variable for cache.
162 DataSize
= DataSizeOfVariable (Variable
.CurrPtr
);
163 Data
= GetVariableDataPtr (Variable
.CurrPtr
);
164 ASSERT ((DataSize
!= 0) && (Data
!= NULL
));
165 CopyMem (mPubKeyStore
, (UINT8
*) Data
, DataSize
);
166 mPubKeyNumber
= (UINT32
) (DataSize
/ EFI_CERT_TYPE_RSA2048_SIZE
);
169 FindVariable (EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
, &PkVariable
, &mVariableModuleGlobal
->VariableGlobal
);
170 if (PkVariable
.CurrPtr
== NULL
) {
171 DEBUG ((EFI_D_INFO
, "Variable %s does not exist.\n", EFI_PLATFORM_KEY_NAME
));
173 DEBUG ((EFI_D_INFO
, "Variable %s exists.\n", EFI_PLATFORM_KEY_NAME
));
177 // Check "SetupMode" variable's existence.
178 // If it doesn't exist, check PK database's existence to determine the value.
179 // Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
181 Status
= FindVariable (
183 &gEfiGlobalVariableGuid
,
185 &mVariableModuleGlobal
->VariableGlobal
188 if (Variable
.CurrPtr
== NULL
) {
189 if (PkVariable
.CurrPtr
== NULL
) {
190 mPlatformMode
= SETUP_MODE
;
192 mPlatformMode
= USER_MODE
;
195 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
196 Status
= UpdateVariable (
198 &gEfiGlobalVariableGuid
,
207 if (EFI_ERROR (Status
)) {
211 mPlatformMode
= *(GetVariableDataPtr (Variable
.CurrPtr
));
214 // Check "SignatureSupport" variable's existence.
215 // If it doesn't exist, then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
217 Status
= FindVariable (
218 EFI_SIGNATURE_SUPPORT_NAME
,
219 &gEfiGlobalVariableGuid
,
221 &mVariableModuleGlobal
->VariableGlobal
224 if (Variable
.CurrPtr
== NULL
) {
225 VarAttr
= EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
226 Status
= UpdateVariable (
227 EFI_SIGNATURE_SUPPORT_NAME
,
228 &gEfiGlobalVariableGuid
,
230 SIGSUPPORT_NUM
* sizeof(EFI_GUID
),
240 // If "SecureBootEnable" variable exists, then update "SecureBoot" variable.
241 // If "SecureBootEnable" variable is SECURE_BOOT_ENABLE and in USER_MODE, Set "SecureBoot" variable to SECURE_BOOT_MODE_ENABLE.
242 // If "SecureBootEnable" variable is SECURE_BOOT_DISABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_DISABLE.
244 SecureBootEnable
= SECURE_BOOT_MODE_DISABLE
;
245 FindVariable (EFI_SECURE_BOOT_ENABLE_NAME
, &gEfiSecureBootEnableDisableGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
);
246 if (Variable
.CurrPtr
!= NULL
) {
247 SecureBootEnable
= *(GetVariableDataPtr (Variable
.CurrPtr
));
248 } else if (mPlatformMode
== USER_MODE
) {
250 // "SecureBootEnable" not exist, initialize it in USER_MODE.
252 SecureBootEnable
= SECURE_BOOT_MODE_ENABLE
;
253 Status
= UpdateVariable (
254 EFI_SECURE_BOOT_ENABLE_NAME
,
255 &gEfiSecureBootEnableDisableGuid
,
258 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
264 if (EFI_ERROR (Status
)) {
269 if (SecureBootEnable
== SECURE_BOOT_ENABLE
&& mPlatformMode
== USER_MODE
) {
270 SecureBootMode
= SECURE_BOOT_MODE_ENABLE
;
272 SecureBootMode
= SECURE_BOOT_MODE_DISABLE
;
274 FindVariable (EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
);
275 Status
= UpdateVariable (
276 EFI_SECURE_BOOT_MODE_NAME
,
277 &gEfiGlobalVariableGuid
,
280 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
,
286 if (EFI_ERROR (Status
)) {
290 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_SETUP_MODE_NAME
, mPlatformMode
));
291 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_SECURE_BOOT_MODE_NAME
, SecureBootMode
));
292 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_SECURE_BOOT_ENABLE_NAME
, SecureBootEnable
));
295 // Detect whether a secure platform-specific method to clear PK(Platform Key)
296 // is configured by platform owner. This method is provided for users force to clear PK
297 // in case incorrect enrollment mis-haps.
299 if (ForceClearPK ()) {
300 DEBUG ((EFI_D_INFO
, "Variable PK/KEK/DB/DBX will be cleared in clear PK mode.\n"));
305 Status
= DeleteVariable (EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
);
306 if (EFI_ERROR (Status
)) {
311 // 2. Update "SetupMode" variable to SETUP_MODE.
313 UpdatePlatformMode (SETUP_MODE
);
316 // 3. Clear KEK, DB and DBX.
318 DeleteVariable (EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
);
319 DeleteVariable (EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
);
320 DeleteVariable (EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
);
327 Add public key in store and return its index.
329 @param[in] PubKey Input pointer to Public Key data
331 @return Index of new added item
342 VARIABLE_POINTER_TRACK Variable
;
345 if (PubKey
== NULL
) {
349 Status
= FindVariable (
351 &gEfiAuthenticatedVariableGuid
,
353 &mVariableModuleGlobal
->VariableGlobal
355 ASSERT_EFI_ERROR (Status
);
357 // Check whether the public key entry does exist.
360 for (Ptr
= mPubKeyStore
, Index
= 1; Index
<= mPubKeyNumber
; Index
++) {
361 if (CompareMem (Ptr
, PubKey
, EFI_CERT_TYPE_RSA2048_SIZE
) == 0) {
365 Ptr
+= EFI_CERT_TYPE_RSA2048_SIZE
;
370 // Add public key in database.
372 if (mPubKeyNumber
== MAX_KEY_NUM
) {
374 // Notes: Database is full, need enhancement here, currently just return 0.
379 CopyMem (mPubKeyStore
+ mPubKeyNumber
* EFI_CERT_TYPE_RSA2048_SIZE
, PubKey
, EFI_CERT_TYPE_RSA2048_SIZE
);
380 Index
= ++mPubKeyNumber
;
382 // Update public key database variable.
384 Status
= UpdateVariable (
386 &gEfiAuthenticatedVariableGuid
,
388 mPubKeyNumber
* EFI_CERT_TYPE_RSA2048_SIZE
,
389 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
,
395 ASSERT_EFI_ERROR (Status
);
402 Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type.
403 Follow the steps in UEFI2.2.
405 @param[in] Data Pointer to data with AuthInfo.
406 @param[in] DataSize Size of Data.
407 @param[in] PubKey Public key used for verification.
409 @retval EFI_INVALID_PARAMETER Invalid parameter.
410 @retval EFI_SECURITY_VIOLATION If authentication failed.
411 @retval EFI_SUCCESS Authentication successful.
415 VerifyCounterBasedPayload (
422 EFI_VARIABLE_AUTHENTICATION
*CertData
;
423 EFI_CERT_BLOCK_RSA_2048_SHA256
*CertBlock
;
424 UINT8 Digest
[SHA256_DIGEST_SIZE
];
431 if (Data
== NULL
|| PubKey
== NULL
) {
432 return EFI_INVALID_PARAMETER
;
435 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
436 CertBlock
= (EFI_CERT_BLOCK_RSA_2048_SHA256
*) (CertData
->AuthInfo
.CertData
);
439 // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
440 // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256.
442 if ((CertData
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) ||
443 !CompareGuid (&CertData
->AuthInfo
.CertType
, &gEfiCertRsa2048Sha256Guid
)
446 // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
448 return EFI_SECURITY_VIOLATION
;
451 // Hash data payload with SHA256.
453 ZeroMem (Digest
, SHA256_DIGEST_SIZE
);
454 Status
= Sha256Init (mHashCtx
);
458 Status
= Sha256Update (mHashCtx
, Data
+ AUTHINFO_SIZE
, (UINTN
) (DataSize
- AUTHINFO_SIZE
));
463 // Hash Monotonic Count.
465 Status
= Sha256Update (mHashCtx
, &CertData
->MonotonicCount
, sizeof (UINT64
));
469 Status
= Sha256Final (mHashCtx
, Digest
);
474 // Generate & Initialize RSA Context.
477 ASSERT (Rsa
!= NULL
);
479 // Set RSA Key Components.
480 // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
482 Status
= RsaSetKey (Rsa
, RsaKeyN
, PubKey
, EFI_CERT_TYPE_RSA2048_SIZE
);
486 Status
= RsaSetKey (Rsa
, RsaKeyE
, mRsaE
, sizeof (mRsaE
));
491 // Verify the signature.
493 Status
= RsaPkcs1Verify (
497 CertBlock
->Signature
,
498 EFI_CERT_TYPE_RSA2048_SHA256_SIZE
508 return EFI_SECURITY_VIOLATION
;
513 Update platform mode.
515 @param[in] Mode SETUP_MODE or USER_MODE.
517 @return EFI_INVALID_PARAMETER Invalid parameter.
518 @return EFI_SUCCESS Update platform mode successfully.
527 VARIABLE_POINTER_TRACK Variable
;
529 UINT8 SecureBootMode
;
530 UINT8 SecureBootEnable
;
531 UINTN VariableDataSize
;
533 Status
= FindVariable (
535 &gEfiGlobalVariableGuid
,
537 &mVariableModuleGlobal
->VariableGlobal
539 if (EFI_ERROR (Status
)) {
543 mPlatformMode
= Mode
;
544 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
545 Status
= UpdateVariable (
547 &gEfiGlobalVariableGuid
,
556 if (EFI_ERROR (Status
)) {
562 // SecureBoot Variable indicates whether the platform firmware is operating
563 // in Secure boot mode (1) or not (0), so we should not change SecureBoot
564 // Variable in runtime.
570 // Check "SecureBoot" variable's existence.
571 // If it doesn't exist, firmware has no capability to perform driver signing verification,
572 // then set "SecureBoot" to 0.
574 Status
= FindVariable (
575 EFI_SECURE_BOOT_MODE_NAME
,
576 &gEfiGlobalVariableGuid
,
578 &mVariableModuleGlobal
->VariableGlobal
581 // If "SecureBoot" variable exists, then check "SetupMode" variable update.
582 // If "SetupMode" variable is USER_MODE, "SecureBoot" variable is set to 1.
583 // If "SetupMode" variable is SETUP_MODE, "SecureBoot" variable is set to 0.
585 if (Variable
.CurrPtr
== NULL
) {
586 SecureBootMode
= SECURE_BOOT_MODE_DISABLE
;
588 if (mPlatformMode
== USER_MODE
) {
589 SecureBootMode
= SECURE_BOOT_MODE_ENABLE
;
590 } else if (mPlatformMode
== SETUP_MODE
) {
591 SecureBootMode
= SECURE_BOOT_MODE_DISABLE
;
593 return EFI_NOT_FOUND
;
597 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
598 Status
= UpdateVariable (
599 EFI_SECURE_BOOT_MODE_NAME
,
600 &gEfiGlobalVariableGuid
,
609 if (EFI_ERROR (Status
)) {
614 // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.
616 Status
= FindVariable (
617 EFI_SECURE_BOOT_ENABLE_NAME
,
618 &gEfiSecureBootEnableDisableGuid
,
620 &mVariableModuleGlobal
->VariableGlobal
623 if (SecureBootMode
== SECURE_BOOT_MODE_ENABLE
) {
625 // Create the "SecureBootEnable" variable as secure boot is enabled.
627 SecureBootEnable
= SECURE_BOOT_ENABLE
;
628 VariableDataSize
= sizeof (SecureBootEnable
);
631 // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"
632 // variable is not in secure boot state.
634 if (Variable
.CurrPtr
== NULL
|| EFI_ERROR (Status
)) {
637 SecureBootEnable
= SECURE_BOOT_DISABLE
;
638 VariableDataSize
= 0;
641 Status
= UpdateVariable (
642 EFI_SECURE_BOOT_ENABLE_NAME
,
643 &gEfiSecureBootEnableDisableGuid
,
646 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
656 Process variable with platform key for verification.
658 @param[in] VariableName Name of Variable to be found.
659 @param[in] VendorGuid Variable vendor GUID.
660 @param[in] Data Data pointer.
661 @param[in] DataSize Size of Data found. If size is less than the
662 data, this value contains the required size.
663 @param[in] Variable The variable information which is used to keep track of variable usage.
664 @param[in] Attributes Attribute value of the variable
665 @param[in] IsPk Indicate whether it is to process pk.
667 @return EFI_INVALID_PARAMETER Invalid parameter.
668 @return EFI_SECURITY_VIOLATION The variable does NOT pass the validation.
669 check carried out by the firmware.
670 @return EFI_SUCCESS Variable passed validation successfully.
675 IN CHAR16
*VariableName
,
676 IN EFI_GUID
*VendorGuid
,
679 IN VARIABLE_POINTER_TRACK
*Variable
,
680 IN UINT32 Attributes OPTIONAL
,
685 VARIABLE_POINTER_TRACK PkVariable
;
686 EFI_SIGNATURE_LIST
*OldPkList
;
687 EFI_SIGNATURE_DATA
*OldPkData
;
688 EFI_VARIABLE_AUTHENTICATION
*CertData
;
693 UINT64 MonotonicCount
;
696 if ((Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0) {
698 // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute.
700 return EFI_INVALID_PARAMETER
;
703 if (mPlatformMode
== USER_MODE
) {
705 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
707 // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute means time-based X509 Cert PK.
710 } else if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
712 // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute means counter-based RSA-2048 Cert PK.
716 return EFI_INVALID_PARAMETER
;
721 // Verify against X509 Cert PK.
724 Status
= VerifyTimeBasedPayload (VariableName
, VendorGuid
, Data
, DataSize
, Variable
, Attributes
, TRUE
, &Del
);
725 if (!EFI_ERROR (Status
)) {
727 // If delete PK in user mode, need change to setup mode.
730 Status
= UpdatePlatformMode (SETUP_MODE
);
736 // Verify against RSA2048 Cert PK.
738 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
739 if ((Variable
->CurrPtr
!= NULL
) && (CertData
->MonotonicCount
<= Variable
->CurrPtr
->MonotonicCount
)) {
741 // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
743 return EFI_SECURITY_VIOLATION
;
746 // Get platform key from variable.
748 Status
= FindVariable (
749 EFI_PLATFORM_KEY_NAME
,
750 &gEfiGlobalVariableGuid
,
752 &mVariableModuleGlobal
->VariableGlobal
754 ASSERT_EFI_ERROR (Status
);
756 OldPkList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (PkVariable
.CurrPtr
);
757 OldPkData
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) OldPkList
+ sizeof (EFI_SIGNATURE_LIST
) + OldPkList
->SignatureHeaderSize
);
758 Status
= VerifyCounterBasedPayload (Data
, DataSize
, OldPkData
->SignatureData
);
759 if (!EFI_ERROR (Status
)) {
760 Status
= UpdateVariable (
763 (UINT8
*)Data
+ AUTHINFO_SIZE
,
764 DataSize
- AUTHINFO_SIZE
,
767 CertData
->MonotonicCount
,
772 if (!EFI_ERROR (Status
)) {
774 // If delete PK in user mode, need change to setup mode.
776 if ((DataSize
== AUTHINFO_SIZE
) && IsPk
) {
777 Status
= UpdatePlatformMode (SETUP_MODE
);
784 // Process PK or KEK in Setup mode.
786 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
788 // Time-based Authentication descriptor.
791 TimeStamp
= &((EFI_VARIABLE_AUTHENTICATION_2
*) Data
)->TimeStamp
;
792 Payload
= (UINT8
*) Data
+ AUTHINFO2_SIZE (Data
);
793 PayloadSize
= DataSize
- AUTHINFO2_SIZE (Data
);
794 } else if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
796 // Counter-based Authentication descriptor.
798 MonotonicCount
= ((EFI_VARIABLE_AUTHENTICATION
*) Data
)->MonotonicCount
;
800 Payload
= (UINT8
*) Data
+ AUTHINFO_SIZE
;
801 PayloadSize
= DataSize
- AUTHINFO_SIZE
;
804 // No Authentication descriptor.
809 PayloadSize
= DataSize
;
812 Status
= UpdateVariable (
824 // If enroll PK in setup mode, need change to user mode.
826 if ((DataSize
!= 0) && IsPk
) {
827 Status
= UpdatePlatformMode (USER_MODE
);
835 Process variable with key exchange key for verification.
837 @param[in] VariableName Name of Variable to be found.
838 @param[in] VendorGuid Variable vendor GUID.
839 @param[in] Data Data pointer.
840 @param[in] DataSize Size of Data found. If size is less than the
841 data, this value contains the required size.
842 @param[in] Variable The variable information which is used to keep track of variable usage.
843 @param[in] Attributes Attribute value of the variable.
845 @return EFI_INVALID_PARAMETER Invalid parameter.
846 @return EFI_SECURITY_VIOLATION The variable does NOT pass the validation
847 check carried out by the firmware.
848 @return EFI_SUCCESS Variable pass validation successfully.
853 IN CHAR16
*VariableName
,
854 IN EFI_GUID
*VendorGuid
,
857 IN VARIABLE_POINTER_TRACK
*Variable
,
858 IN UINT32 Attributes OPTIONAL
862 VARIABLE_POINTER_TRACK KekVariable
;
863 EFI_SIGNATURE_LIST
*KekList
;
864 EFI_SIGNATURE_DATA
*KekItem
;
866 EFI_VARIABLE_AUTHENTICATION
*CertData
;
867 EFI_CERT_BLOCK_RSA_2048_SHA256
*CertBlock
;
873 UINT64 MonotonicCount
;
875 if (mPlatformMode
== USER_MODE
) {
876 if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) == 0) {
878 // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute.
880 return EFI_INVALID_PARAMETER
;
883 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
884 CertBlock
= (EFI_CERT_BLOCK_RSA_2048_SHA256
*) (CertData
->AuthInfo
.CertData
);
885 if ((Variable
->CurrPtr
!= NULL
) && (CertData
->MonotonicCount
<= Variable
->CurrPtr
->MonotonicCount
)) {
887 // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
889 return EFI_SECURITY_VIOLATION
;
892 // Get KEK database from variable.
894 Status
= FindVariable (
895 EFI_KEY_EXCHANGE_KEY_NAME
,
896 &gEfiGlobalVariableGuid
,
898 &mVariableModuleGlobal
->VariableGlobal
900 ASSERT_EFI_ERROR (Status
);
902 KekDataSize
= KekVariable
.CurrPtr
->DataSize
;
903 KekList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (KekVariable
.CurrPtr
);
906 // Enumerate all Kek items in this list to verify the variable certificate data.
907 // If anyone is authenticated successfully, it means the variable is correct!
910 while ((KekDataSize
> 0) && (KekDataSize
>= KekList
->SignatureListSize
)) {
911 if (CompareGuid (&KekList
->SignatureType
, &gEfiCertRsa2048Guid
)) {
912 KekItem
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) KekList
+ sizeof (EFI_SIGNATURE_LIST
) + KekList
->SignatureHeaderSize
);
913 KekCount
= (KekList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - KekList
->SignatureHeaderSize
) / KekList
->SignatureSize
;
914 for (Index
= 0; Index
< KekCount
; Index
++) {
915 if (CompareMem (KekItem
->SignatureData
, CertBlock
->PublicKey
, EFI_CERT_TYPE_RSA2048_SIZE
) == 0) {
919 KekItem
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) KekItem
+ KekList
->SignatureSize
);
922 KekDataSize
-= KekList
->SignatureListSize
;
923 KekList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) KekList
+ KekList
->SignatureListSize
);
927 return EFI_SECURITY_VIOLATION
;
930 Status
= VerifyCounterBasedPayload (Data
, DataSize
, CertBlock
->PublicKey
);
931 if (!EFI_ERROR (Status
)) {
932 Status
= UpdateVariable (
935 (UINT8
*)Data
+ AUTHINFO_SIZE
,
936 DataSize
- AUTHINFO_SIZE
,
939 CertData
->MonotonicCount
,
946 // If in setup mode, no authentication needed.
948 if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
950 // Counter-based Authentication descriptor.
952 MonotonicCount
= ((EFI_VARIABLE_AUTHENTICATION
*) Data
)->MonotonicCount
;
953 Payload
= (UINT8
*) Data
+ AUTHINFO_SIZE
;
954 PayloadSize
= DataSize
- AUTHINFO_SIZE
;
957 // No Authentication descriptor.
961 PayloadSize
= DataSize
;
964 Status
= UpdateVariable (
981 Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
983 @param[in] VariableName Name of Variable to be found.
984 @param[in] VendorGuid Variable vendor GUID.
986 @param[in] Data Data pointer.
987 @param[in] DataSize Size of Data found. If size is less than the
988 data, this value contains the required size.
989 @param[in] Variable The variable information which is used to keep track of variable usage.
990 @param[in] Attributes Attribute value of the variable.
992 @return EFI_INVALID_PARAMETER Invalid parameter.
993 @return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
994 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
995 @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
996 set, but the AuthInfo does NOT pass the validation
997 check carried out by the firmware.
998 @return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
1003 IN CHAR16
*VariableName
,
1004 IN EFI_GUID
*VendorGuid
,
1007 IN VARIABLE_POINTER_TRACK
*Variable
,
1008 IN UINT32 Attributes
1013 BOOLEAN IsFirstTime
;
1015 EFI_VARIABLE_AUTHENTICATION
*CertData
;
1016 EFI_CERT_BLOCK_RSA_2048_SHA256
*CertBlock
;
1018 UINT64 MonotonicCount
;
1027 // Process Time-based Authenticated variable.
1029 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1030 return VerifyTimeBasedPayload (VariableName
, VendorGuid
, Data
, DataSize
, Variable
, Attributes
, FALSE
, NULL
);
1034 // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.
1036 if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1038 // Determine current operation type.
1040 if (DataSize
== AUTHINFO_SIZE
) {
1044 // Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
1046 if (Variable
->CurrPtr
== NULL
) {
1048 } else if ((Variable
->CurrPtr
->Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) == 0) {
1051 KeyIndex
= Variable
->CurrPtr
->PubKeyIndex
;
1052 IsFirstTime
= FALSE
;
1054 } else if ((Variable
->CurrPtr
!= NULL
) &&
1055 (Variable
->CurrPtr
->Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0
1058 // If the variable is already write-protected, it always needs authentication before update.
1060 return EFI_WRITE_PROTECTED
;
1063 // If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.
1064 // That means it is not authenticated variable, just update variable as usual.
1066 Status
= UpdateVariable (VariableName
, VendorGuid
, Data
, DataSize
, Attributes
, 0, 0, Variable
, NULL
);
1071 // Get PubKey and check Monotonic Count value corresponding to the variable.
1073 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
1074 CertBlock
= (EFI_CERT_BLOCK_RSA_2048_SHA256
*) (CertData
->AuthInfo
.CertData
);
1075 PubKey
= CertBlock
->PublicKey
;
1078 // Update Monotonic Count value.
1080 MonotonicCount
= CertData
->MonotonicCount
;
1084 // Check input PubKey.
1086 if (CompareMem (PubKey
, mPubKeyStore
+ (KeyIndex
- 1) * EFI_CERT_TYPE_RSA2048_SIZE
, EFI_CERT_TYPE_RSA2048_SIZE
) != 0) {
1087 return EFI_SECURITY_VIOLATION
;
1090 // Compare the current monotonic count and ensure that it is greater than the last SetVariable
1091 // operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.
1093 if (CertData
->MonotonicCount
<= Variable
->CurrPtr
->MonotonicCount
) {
1095 // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
1097 return EFI_SECURITY_VIOLATION
;
1101 // Verify the certificate in Data payload.
1103 Status
= VerifyCounterBasedPayload (Data
, DataSize
, PubKey
);
1104 if (EFI_ERROR (Status
)) {
1109 // Now, the signature has been verified!
1111 if (IsFirstTime
&& !IsDeletion
) {
1113 // Update public key database variable if need.
1115 KeyIndex
= AddPubKeyInStore (PubKey
);
1119 // Verification pass.
1121 return UpdateVariable (VariableName
, VendorGuid
, (UINT8
*)Data
+ AUTHINFO_SIZE
, DataSize
- AUTHINFO_SIZE
, Attributes
, KeyIndex
, MonotonicCount
, Variable
, NULL
);
1125 Merge two buffers which formatted as EFI_SIGNATURE_LIST. Only the new EFI_SIGNATURE_DATA
1126 will be appended to the original EFI_SIGNATURE_LIST, duplicate EFI_SIGNATURE_DATA
1129 @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST.
1130 @param[in] DataSize Size of Data buffer.
1131 @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended.
1132 @param[in] NewDataSize Size of NewData buffer.
1134 @return Size of the merged buffer.
1138 AppendSignatureList (
1142 IN UINTN NewDataSize
1145 EFI_SIGNATURE_LIST
*CertList
;
1146 EFI_SIGNATURE_DATA
*Cert
;
1148 EFI_SIGNATURE_LIST
*NewCertList
;
1149 EFI_SIGNATURE_DATA
*NewCert
;
1156 UINTN SignatureListSize
;
1159 Tail
= (UINT8
*) Data
+ DataSize
;
1161 NewCertList
= (EFI_SIGNATURE_LIST
*) NewData
;
1162 while ((NewDataSize
> 0) && (NewDataSize
>= NewCertList
->SignatureListSize
)) {
1163 NewCert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) NewCertList
+ sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
);
1164 NewCertCount
= (NewCertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - NewCertList
->SignatureHeaderSize
) / NewCertList
->SignatureSize
;
1167 for (Index
= 0; Index
< NewCertCount
; Index
++) {
1171 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
1172 while ((Size
> 0) && (Size
>= CertList
->SignatureListSize
)) {
1173 if (CompareGuid (&CertList
->SignatureType
, &NewCertList
->SignatureType
) &&
1174 (CertList
->SignatureSize
== NewCertList
->SignatureSize
)) {
1175 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
1176 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
1177 for (Index2
= 0; Index2
< CertCount
; Index2
++) {
1179 // Iterate each Signature Data in this Signature List.
1181 if (CompareMem (NewCert
, Cert
, CertList
->SignatureSize
) == 0) {
1185 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
1192 Size
-= CertList
->SignatureListSize
;
1193 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
1198 // New EFI_SIGNATURE_DATA, append it.
1200 if (CopiedCount
== 0) {
1202 // Copy EFI_SIGNATURE_LIST header for only once.
1204 CopyMem (Tail
, NewCertList
, sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
);
1205 Tail
= Tail
+ sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
;
1208 CopyMem (Tail
, NewCert
, NewCertList
->SignatureSize
);
1209 Tail
+= NewCertList
->SignatureSize
;
1213 NewCert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) NewCert
+ NewCertList
->SignatureSize
);
1217 // Update SignatureListSize in newly appended EFI_SIGNATURE_LIST.
1219 if (CopiedCount
!= 0) {
1220 SignatureListSize
= sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
+ (CopiedCount
* NewCertList
->SignatureSize
);
1221 CertList
= (EFI_SIGNATURE_LIST
*) (Tail
- SignatureListSize
);
1222 CertList
->SignatureListSize
= (UINT32
) SignatureListSize
;
1225 NewDataSize
-= NewCertList
->SignatureListSize
;
1226 NewCertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) NewCertList
+ NewCertList
->SignatureListSize
);
1229 return (Tail
- (UINT8
*) Data
);
1233 Compare two EFI_TIME data.
1236 @param FirstTime A pointer to the first EFI_TIME data.
1237 @param SecondTime A pointer to the second EFI_TIME data.
1239 @retval TRUE The FirstTime is not later than the SecondTime.
1240 @retval FALSE The FirstTime is later than the SecondTime.
1245 IN EFI_TIME
*FirstTime
,
1246 IN EFI_TIME
*SecondTime
1249 if (FirstTime
->Year
!= SecondTime
->Year
) {
1250 return (BOOLEAN
) (FirstTime
->Year
< SecondTime
->Year
);
1251 } else if (FirstTime
->Month
!= SecondTime
->Month
) {
1252 return (BOOLEAN
) (FirstTime
->Month
< SecondTime
->Month
);
1253 } else if (FirstTime
->Day
!= SecondTime
->Day
) {
1254 return (BOOLEAN
) (FirstTime
->Day
< SecondTime
->Day
);
1255 } else if (FirstTime
->Hour
!= SecondTime
->Hour
) {
1256 return (BOOLEAN
) (FirstTime
->Hour
< SecondTime
->Hour
);
1257 } else if (FirstTime
->Minute
!= SecondTime
->Minute
) {
1258 return (BOOLEAN
) (FirstTime
->Minute
< FirstTime
->Minute
);
1261 return (BOOLEAN
) (FirstTime
->Second
<= SecondTime
->Second
);
1265 Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
1267 @param[in] VariableName Name of Variable to be found.
1268 @param[in] VendorGuid Variable vendor GUID.
1269 @param[in] Data Data pointer.
1270 @param[in] DataSize Size of Data found. If size is less than the
1271 data, this value contains the required size.
1272 @param[in] Variable The variable information which is used to keep track of variable usage.
1273 @param[in] Attributes Attribute value of the variable.
1274 @param[in] Pk Verify against PK or KEK database.
1275 @param[out] VarDel Delete the variable or not.
1277 @retval EFI_INVALID_PARAMETER Invalid parameter.
1278 @retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
1279 check carried out by the firmware.
1280 @retval EFI_OUT_OF_RESOURCES Failed to process variable due to lack
1282 @retval EFI_SUCCESS Variable pass validation successfully.
1286 VerifyTimeBasedPayload (
1287 IN CHAR16
*VariableName
,
1288 IN EFI_GUID
*VendorGuid
,
1291 IN VARIABLE_POINTER_TRACK
*Variable
,
1292 IN UINT32 Attributes
,
1308 BOOLEAN VerifyStatus
;
1310 EFI_SIGNATURE_LIST
*CertList
;
1311 EFI_SIGNATURE_DATA
*Cert
;
1312 VARIABLE_POINTER_TRACK KekVariable
;
1313 EFI_VARIABLE_AUTHENTICATION_2
*CertData
;
1316 VARIABLE_POINTER_TRACK PkVariable
;
1321 VerifyStatus
= FALSE
;
1327 // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
1328 // set, then the Data buffer shall begin with an instance of a complete (and serialized)
1329 // EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
1330 // variable value and DataSize shall reflect the combined size of the descriptor and the new
1331 // variable value. The authentication descriptor is not part of the variable data and is not
1332 // returned by subsequent calls to GetVariable().
1334 CertData
= (EFI_VARIABLE_AUTHENTICATION_2
*) Data
;
1337 // Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the
1338 // TimeStamp value are set to zero.
1340 if ((CertData
->TimeStamp
.Pad1
!= 0) ||
1341 (CertData
->TimeStamp
.Nanosecond
!= 0) ||
1342 (CertData
->TimeStamp
.TimeZone
!= 0) ||
1343 (CertData
->TimeStamp
.Daylight
!= 0) ||
1344 (CertData
->TimeStamp
.Pad2
!= 0)) {
1345 return EFI_INVALID_PARAMETER
;
1348 if ((Variable
->CurrPtr
!= NULL
) && ((Attributes
& EFI_VARIABLE_APPEND_WRITE
) == 0)) {
1349 if (CompareTimeStamp (&CertData
->TimeStamp
, &Variable
->CurrPtr
->TimeStamp
)) {
1351 // TimeStamp check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
1353 return EFI_SECURITY_VIOLATION
;
1358 // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
1359 // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.
1361 if ((CertData
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) ||
1362 !CompareGuid (&CertData
->AuthInfo
.CertType
, &gEfiCertPkcs7Guid
)) {
1364 // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
1366 return EFI_SECURITY_VIOLATION
;
1370 // Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
1371 // AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.
1373 SigData
= CertData
->AuthInfo
.CertData
;
1374 SigDataSize
= CertData
->AuthInfo
.Hdr
.dwLength
- (UINT32
) (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID
, CertData
));
1377 // Find out the new data payload which follows Pkcs7 SignedData directly.
1379 PayloadPtr
= SigData
+ SigDataSize
;
1380 PayloadSize
= DataSize
- OFFSET_OF_AUTHINFO2_CERT_DATA
- (UINTN
) SigDataSize
;
1383 // Construct a buffer to fill with (VariableName, VendorGuid, Attributes, TimeStamp, Data).
1385 NewDataSize
= PayloadSize
+ sizeof (EFI_TIME
) + sizeof (UINT32
) +
1386 sizeof (EFI_GUID
) + StrSize (VariableName
) - sizeof (CHAR16
);
1387 NewData
= mSerializationRuntimeBuffer
;
1390 Length
= StrLen (VariableName
) * sizeof (CHAR16
);
1391 CopyMem (Buffer
, VariableName
, Length
);
1394 Length
= sizeof (EFI_GUID
);
1395 CopyMem (Buffer
, VendorGuid
, Length
);
1398 Length
= sizeof (UINT32
);
1399 CopyMem (Buffer
, &Attr
, Length
);
1402 Length
= sizeof (EFI_TIME
);
1403 CopyMem (Buffer
, &CertData
->TimeStamp
, Length
);
1406 CopyMem (Buffer
, PayloadPtr
, PayloadSize
);
1410 // Get platform key from variable.
1412 Status
= FindVariable (
1413 EFI_PLATFORM_KEY_NAME
,
1414 &gEfiGlobalVariableGuid
,
1416 &mVariableModuleGlobal
->VariableGlobal
1418 if (EFI_ERROR (Status
)) {
1422 CertList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (PkVariable
.CurrPtr
);
1423 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
1424 RootCert
= Cert
->SignatureData
;
1425 RootCertSize
= CertList
->SignatureSize
;
1429 // Verify Pkcs7 SignedData via Pkcs7Verify library.
1431 VerifyStatus
= Pkcs7Verify (
1443 // Get KEK database from variable.
1445 Status
= FindVariable (
1446 EFI_KEY_EXCHANGE_KEY_NAME
,
1447 &gEfiGlobalVariableGuid
,
1449 &mVariableModuleGlobal
->VariableGlobal
1451 if (EFI_ERROR (Status
)) {
1456 // Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.
1458 KekDataSize
= KekVariable
.CurrPtr
->DataSize
;
1459 CertList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (KekVariable
.CurrPtr
);
1460 while ((KekDataSize
> 0) && (KekDataSize
>= CertList
->SignatureListSize
)) {
1461 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
1462 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
1463 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
1464 for (Index
= 0; Index
< CertCount
; Index
++) {
1466 // Iterate each Signature Data Node within this CertList for a verify
1468 RootCert
= Cert
->SignatureData
;
1469 RootCertSize
= CertList
->SignatureSize
;
1472 // Verify Pkcs7 SignedData via Pkcs7Verify library.
1474 VerifyStatus
= Pkcs7Verify (
1485 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
1488 KekDataSize
-= CertList
->SignatureListSize
;
1489 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
1495 if (!VerifyStatus
) {
1496 return EFI_SECURITY_VIOLATION
;
1499 if ((PayloadSize
== 0) && (VarDel
!= NULL
)) {
1504 // Final step: Update/Append Variable if it pass Pkcs7Verify
1506 return UpdateVariable (
1515 &CertData
->TimeStamp