2 Implement authentication services for the authenticated variable
5 Copyright (c) 2009 - 2012, 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
[] = {EFI_CERT_SHA1_GUID
, EFI_CERT_SHA256_GUID
, EFI_CERT_RSA2048_GUID
, EFI_CERT_X509_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 // Requirement for different signature type which have been defined in UEFI spec.
53 // These data are used to peform SignatureList format check while setting PK/KEK variable.
55 EFI_SIGNATURE_ITEM mSupportSigItem
[] = {
56 //{SigType, SigHeaderSize, SigDataSize }
57 {EFI_CERT_SHA256_GUID
, 0, 32 },
58 {EFI_CERT_RSA2048_GUID
, 0, 256 },
59 {EFI_CERT_RSA2048_SHA256_GUID
, 0, 256 },
60 {EFI_CERT_SHA1_GUID
, 0, 20 },
61 {EFI_CERT_RSA2048_SHA1_GUID
, 0, 256 },
62 {EFI_CERT_X509_GUID
, 0, ((UINT32
) ~0)},
63 {EFI_CERT_SHA224_GUID
, 0, 28 },
64 {EFI_CERT_SHA384_GUID
, 0, 48 },
65 {EFI_CERT_SHA512_GUID
, 0, 64 }
69 Determine whether this operation needs a physical present user.
71 @param[in] VariableName Name of the Variable.
72 @param[in] VendorGuid GUID of the Variable.
74 @retval TRUE This variable is protected, only a physical present user could set this variable.
75 @retval FALSE This variable is not protected.
79 NeedPhysicallyPresent(
80 IN CHAR16
*VariableName
,
81 IN EFI_GUID
*VendorGuid
84 if ((CompareGuid (VendorGuid
, &gEfiSecureBootEnableDisableGuid
) && (StrCmp (VariableName
, EFI_SECURE_BOOT_ENABLE_NAME
) == 0))
85 || (CompareGuid (VendorGuid
, &gEfiCustomModeEnableGuid
) && (StrCmp (VariableName
, EFI_CUSTOM_MODE_NAME
) == 0))) {
93 Determine whether the platform is operating in Custom Secure Boot mode.
95 @retval TRUE The platform is operating in Custom mode.
96 @retval FALSE The platform is operating in Standard mode.
104 VARIABLE_POINTER_TRACK Variable
;
106 FindVariable (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
, FALSE
);
107 if (Variable
.CurrPtr
!= NULL
&& *(GetVariableDataPtr (Variable
.CurrPtr
)) == CUSTOM_SECURE_BOOT_MODE
) {
116 Internal function to delete a Variable given its name and GUID, no authentication
119 @param[in] VariableName Name of the Variable.
120 @param[in] VendorGuid GUID of the Variable.
122 @retval EFI_SUCCESS Variable deleted successfully.
123 @retval Others The driver failded to start the device.
128 IN CHAR16
*VariableName
,
129 IN EFI_GUID
*VendorGuid
133 VARIABLE_POINTER_TRACK Variable
;
135 Status
= FindVariable (VariableName
, VendorGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
, FALSE
);
136 if (EFI_ERROR (Status
)) {
140 ASSERT (Variable
.CurrPtr
!= NULL
);
141 return UpdateVariable (VariableName
, VendorGuid
, NULL
, 0, 0, 0, 0, &Variable
, NULL
);
145 Initializes for authenticated varibale service.
147 @retval EFI_SUCCESS Function successfully executed.
148 @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resources.
152 AutenticatedVariableServiceInitialize (
157 VARIABLE_POINTER_TRACK Variable
;
158 VARIABLE_POINTER_TRACK PkVariable
;
164 UINT8 SecureBootMode
;
165 UINT8 SecureBootEnable
;
170 // Initialize hash context.
172 CtxSize
= Sha256GetContextSize ();
173 mHashCtx
= AllocateRuntimePool (CtxSize
);
174 if (mHashCtx
== NULL
) {
175 return EFI_OUT_OF_RESOURCES
;
179 // Reserved runtime buffer for "Append" operation in virtual mode.
181 mStorageArea
= AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize
));
182 if (mStorageArea
== NULL
) {
183 return EFI_OUT_OF_RESOURCES
;
187 // Prepare runtime buffer for serialized data of time-based authenticated
188 // Variable, i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data).
190 mSerializationRuntimeBuffer
= AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize
) + sizeof (EFI_GUID
) + sizeof (UINT32
) + sizeof (EFI_TIME
));
191 if (mSerializationRuntimeBuffer
== NULL
) {
192 return EFI_OUT_OF_RESOURCES
;
196 // Check "AuthVarKeyDatabase" variable's existence.
197 // If it doesn't exist, create a new one with initial value of 0 and EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
199 Status
= FindVariable (
201 &gEfiAuthenticatedVariableGuid
,
203 &mVariableModuleGlobal
->VariableGlobal
,
207 if (Variable
.CurrPtr
== NULL
) {
208 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
211 Status
= UpdateVariable (
213 &gEfiAuthenticatedVariableGuid
,
222 if (EFI_ERROR (Status
)) {
227 // Load database in global variable for cache.
229 DataSize
= DataSizeOfVariable (Variable
.CurrPtr
);
230 Data
= GetVariableDataPtr (Variable
.CurrPtr
);
231 ASSERT ((DataSize
!= 0) && (Data
!= NULL
));
232 CopyMem (mPubKeyStore
, (UINT8
*) Data
, DataSize
);
233 mPubKeyNumber
= (UINT32
) (DataSize
/ EFI_CERT_TYPE_RSA2048_SIZE
);
236 FindVariable (EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
, &PkVariable
, &mVariableModuleGlobal
->VariableGlobal
, FALSE
);
237 if (PkVariable
.CurrPtr
== NULL
) {
238 DEBUG ((EFI_D_INFO
, "Variable %s does not exist.\n", EFI_PLATFORM_KEY_NAME
));
240 DEBUG ((EFI_D_INFO
, "Variable %s exists.\n", EFI_PLATFORM_KEY_NAME
));
244 // Check "SetupMode" variable's existence.
245 // If it doesn't exist, check PK database's existence to determine the value.
246 // Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
248 Status
= FindVariable (
250 &gEfiGlobalVariableGuid
,
252 &mVariableModuleGlobal
->VariableGlobal
,
256 if (Variable
.CurrPtr
== NULL
) {
257 if (PkVariable
.CurrPtr
== NULL
) {
258 mPlatformMode
= SETUP_MODE
;
260 mPlatformMode
= USER_MODE
;
263 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
264 Status
= UpdateVariable (
266 &gEfiGlobalVariableGuid
,
275 if (EFI_ERROR (Status
)) {
279 mPlatformMode
= *(GetVariableDataPtr (Variable
.CurrPtr
));
282 // Check "SignatureSupport" variable's existence.
283 // If it doesn't exist, then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
285 Status
= FindVariable (
286 EFI_SIGNATURE_SUPPORT_NAME
,
287 &gEfiGlobalVariableGuid
,
289 &mVariableModuleGlobal
->VariableGlobal
,
293 if (Variable
.CurrPtr
== NULL
) {
294 VarAttr
= EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
295 Status
= UpdateVariable (
296 EFI_SIGNATURE_SUPPORT_NAME
,
297 &gEfiGlobalVariableGuid
,
299 sizeof(mSignatureSupport
),
309 // If "SecureBootEnable" variable exists, then update "SecureBoot" variable.
310 // If "SecureBootEnable" variable is SECURE_BOOT_ENABLE and in USER_MODE, Set "SecureBoot" variable to SECURE_BOOT_MODE_ENABLE.
311 // If "SecureBootEnable" variable is SECURE_BOOT_DISABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_DISABLE.
313 SecureBootEnable
= SECURE_BOOT_MODE_DISABLE
;
314 FindVariable (EFI_SECURE_BOOT_ENABLE_NAME
, &gEfiSecureBootEnableDisableGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
, FALSE
);
315 if (Variable
.CurrPtr
!= NULL
) {
316 SecureBootEnable
= *(GetVariableDataPtr (Variable
.CurrPtr
));
317 } else if (mPlatformMode
== USER_MODE
) {
319 // "SecureBootEnable" not exist, initialize it in USER_MODE.
321 SecureBootEnable
= SECURE_BOOT_MODE_ENABLE
;
322 Status
= UpdateVariable (
323 EFI_SECURE_BOOT_ENABLE_NAME
,
324 &gEfiSecureBootEnableDisableGuid
,
327 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
333 if (EFI_ERROR (Status
)) {
338 if (SecureBootEnable
== SECURE_BOOT_ENABLE
&& mPlatformMode
== USER_MODE
) {
339 SecureBootMode
= SECURE_BOOT_MODE_ENABLE
;
341 SecureBootMode
= SECURE_BOOT_MODE_DISABLE
;
343 FindVariable (EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
, FALSE
);
344 Status
= UpdateVariable (
345 EFI_SECURE_BOOT_MODE_NAME
,
346 &gEfiGlobalVariableGuid
,
349 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
,
355 if (EFI_ERROR (Status
)) {
359 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_SETUP_MODE_NAME
, mPlatformMode
));
360 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_SECURE_BOOT_MODE_NAME
, SecureBootMode
));
361 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_SECURE_BOOT_ENABLE_NAME
, SecureBootEnable
));
364 // Check "CustomMode" variable's existence.
366 FindVariable (EFI_CUSTOM_MODE_NAME
, &gEfiCustomModeEnableGuid
, &Variable
, &mVariableModuleGlobal
->VariableGlobal
, FALSE
);
367 if (Variable
.CurrPtr
!= NULL
) {
368 CustomMode
= *(GetVariableDataPtr (Variable
.CurrPtr
));
371 // "CustomMode" not exist, initialize it in STANDARD_SECURE_BOOT_MODE.
373 CustomMode
= STANDARD_SECURE_BOOT_MODE
;
374 Status
= UpdateVariable (
375 EFI_CUSTOM_MODE_NAME
,
376 &gEfiCustomModeEnableGuid
,
379 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
385 if (EFI_ERROR (Status
)) {
390 DEBUG ((EFI_D_INFO
, "Variable %s is %x\n", EFI_CUSTOM_MODE_NAME
, CustomMode
));
393 // Check "certdb" variable's existence.
394 // If it doesn't exist, then create a new one with
395 // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
397 Status
= FindVariable (
401 &mVariableModuleGlobal
->VariableGlobal
,
405 if (Variable
.CurrPtr
== NULL
) {
406 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
408 Status
= UpdateVariable (
426 Add public key in store and return its index.
428 @param[in] PubKey Input pointer to Public Key data
430 @return Index of new added item
441 VARIABLE_POINTER_TRACK Variable
;
444 if (PubKey
== NULL
) {
448 Status
= FindVariable (
450 &gEfiAuthenticatedVariableGuid
,
452 &mVariableModuleGlobal
->VariableGlobal
,
455 ASSERT_EFI_ERROR (Status
);
457 // Check whether the public key entry does exist.
460 for (Ptr
= mPubKeyStore
, Index
= 1; Index
<= mPubKeyNumber
; Index
++) {
461 if (CompareMem (Ptr
, PubKey
, EFI_CERT_TYPE_RSA2048_SIZE
) == 0) {
465 Ptr
+= EFI_CERT_TYPE_RSA2048_SIZE
;
470 // Add public key in database.
472 if (mPubKeyNumber
== MAX_KEY_NUM
) {
474 // Notes: Database is full, need enhancement here, currently just return 0.
479 CopyMem (mPubKeyStore
+ mPubKeyNumber
* EFI_CERT_TYPE_RSA2048_SIZE
, PubKey
, EFI_CERT_TYPE_RSA2048_SIZE
);
480 Index
= ++mPubKeyNumber
;
482 // Update public key database variable.
484 Status
= UpdateVariable (
486 &gEfiAuthenticatedVariableGuid
,
488 mPubKeyNumber
* EFI_CERT_TYPE_RSA2048_SIZE
,
489 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
,
495 ASSERT_EFI_ERROR (Status
);
502 Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256_GUID type.
503 Follow the steps in UEFI2.2.
505 @param[in] Data Pointer to data with AuthInfo.
506 @param[in] DataSize Size of Data.
507 @param[in] PubKey Public key used for verification.
509 @retval EFI_INVALID_PARAMETER Invalid parameter.
510 @retval EFI_SECURITY_VIOLATION If authentication failed.
511 @retval EFI_SUCCESS Authentication successful.
515 VerifyCounterBasedPayload (
522 EFI_VARIABLE_AUTHENTICATION
*CertData
;
523 EFI_CERT_BLOCK_RSA_2048_SHA256
*CertBlock
;
524 UINT8 Digest
[SHA256_DIGEST_SIZE
];
531 if (Data
== NULL
|| PubKey
== NULL
) {
532 return EFI_INVALID_PARAMETER
;
535 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
536 CertBlock
= (EFI_CERT_BLOCK_RSA_2048_SHA256
*) (CertData
->AuthInfo
.CertData
);
539 // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
540 // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256_GUID.
542 if ((CertData
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) ||
543 !CompareGuid (&CertData
->AuthInfo
.CertType
, &gEfiCertTypeRsa2048Sha256Guid
)
546 // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
548 return EFI_SECURITY_VIOLATION
;
551 // Hash data payload with SHA256.
553 ZeroMem (Digest
, SHA256_DIGEST_SIZE
);
554 Status
= Sha256Init (mHashCtx
);
558 Status
= Sha256Update (mHashCtx
, Data
+ AUTHINFO_SIZE
, (UINTN
) (DataSize
- AUTHINFO_SIZE
));
563 // Hash Monotonic Count.
565 Status
= Sha256Update (mHashCtx
, &CertData
->MonotonicCount
, sizeof (UINT64
));
569 Status
= Sha256Final (mHashCtx
, Digest
);
574 // Generate & Initialize RSA Context.
577 ASSERT (Rsa
!= NULL
);
579 // Set RSA Key Components.
580 // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
582 Status
= RsaSetKey (Rsa
, RsaKeyN
, PubKey
, EFI_CERT_TYPE_RSA2048_SIZE
);
586 Status
= RsaSetKey (Rsa
, RsaKeyE
, mRsaE
, sizeof (mRsaE
));
591 // Verify the signature.
593 Status
= RsaPkcs1Verify (
597 CertBlock
->Signature
,
598 EFI_CERT_TYPE_RSA2048_SHA256_SIZE
608 return EFI_SECURITY_VIOLATION
;
613 Update platform mode.
615 @param[in] Mode SETUP_MODE or USER_MODE.
617 @return EFI_INVALID_PARAMETER Invalid parameter.
618 @return EFI_SUCCESS Update platform mode successfully.
627 VARIABLE_POINTER_TRACK Variable
;
629 UINT8 SecureBootMode
;
630 UINT8 SecureBootEnable
;
631 UINTN VariableDataSize
;
633 Status
= FindVariable (
635 &gEfiGlobalVariableGuid
,
637 &mVariableModuleGlobal
->VariableGlobal
,
640 if (EFI_ERROR (Status
)) {
644 mPlatformMode
= Mode
;
645 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
646 Status
= UpdateVariable (
648 &gEfiGlobalVariableGuid
,
657 if (EFI_ERROR (Status
)) {
663 // SecureBoot Variable indicates whether the platform firmware is operating
664 // in Secure boot mode (1) or not (0), so we should not change SecureBoot
665 // Variable in runtime.
671 // Check "SecureBoot" variable's existence.
672 // If it doesn't exist, firmware has no capability to perform driver signing verification,
673 // then set "SecureBoot" to 0.
675 Status
= FindVariable (
676 EFI_SECURE_BOOT_MODE_NAME
,
677 &gEfiGlobalVariableGuid
,
679 &mVariableModuleGlobal
->VariableGlobal
,
683 // If "SecureBoot" variable exists, then check "SetupMode" variable update.
684 // If "SetupMode" variable is USER_MODE, "SecureBoot" variable is set to 1.
685 // If "SetupMode" variable is SETUP_MODE, "SecureBoot" variable is set to 0.
687 if (Variable
.CurrPtr
== NULL
) {
688 SecureBootMode
= SECURE_BOOT_MODE_DISABLE
;
690 if (mPlatformMode
== USER_MODE
) {
691 SecureBootMode
= SECURE_BOOT_MODE_ENABLE
;
692 } else if (mPlatformMode
== SETUP_MODE
) {
693 SecureBootMode
= SECURE_BOOT_MODE_DISABLE
;
695 return EFI_NOT_FOUND
;
699 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
;
700 Status
= UpdateVariable (
701 EFI_SECURE_BOOT_MODE_NAME
,
702 &gEfiGlobalVariableGuid
,
711 if (EFI_ERROR (Status
)) {
716 // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.
718 Status
= FindVariable (
719 EFI_SECURE_BOOT_ENABLE_NAME
,
720 &gEfiSecureBootEnableDisableGuid
,
722 &mVariableModuleGlobal
->VariableGlobal
,
726 if (SecureBootMode
== SECURE_BOOT_MODE_ENABLE
) {
728 // Create the "SecureBootEnable" variable as secure boot is enabled.
730 SecureBootEnable
= SECURE_BOOT_ENABLE
;
731 VariableDataSize
= sizeof (SecureBootEnable
);
734 // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"
735 // variable is not in secure boot state.
737 if (Variable
.CurrPtr
== NULL
|| EFI_ERROR (Status
)) {
740 SecureBootEnable
= SECURE_BOOT_DISABLE
;
741 VariableDataSize
= 0;
744 Status
= UpdateVariable (
745 EFI_SECURE_BOOT_ENABLE_NAME
,
746 &gEfiSecureBootEnableDisableGuid
,
749 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
759 Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK variable.
761 @param[in] VariableName Name of Variable to be check.
762 @param[in] VendorGuid Variable vendor GUID.
763 @param[in] Data Point to the variable data to be checked.
764 @param[in] DataSize Size of Data.
766 @return EFI_INVALID_PARAMETER Invalid signature list format.
767 @return EFI_SUCCESS Passed signature list format check successfully.
771 CheckSignatureListFormat(
772 IN CHAR16
*VariableName
,
773 IN EFI_GUID
*VendorGuid
,
778 EFI_SIGNATURE_LIST
*SigList
;
788 ASSERT (VariableName
!= NULL
&& VendorGuid
!= NULL
&& Data
!= NULL
);
790 if (CompareGuid (VendorGuid
, &gEfiGlobalVariableGuid
) && (StrCmp (VariableName
, EFI_PLATFORM_KEY_NAME
) == 0)){
792 } else if (CompareGuid (VendorGuid
, &gEfiGlobalVariableGuid
) && (StrCmp (VariableName
, EFI_KEY_EXCHANGE_KEY_NAME
) == 0)) {
799 SigList
= (EFI_SIGNATURE_LIST
*) Data
;
800 SigDataSize
= DataSize
;
803 // Walk throuth the input signature list and check the data format.
804 // If any signature is incorrectly formed, the whole check will fail.
806 while ((SigDataSize
> 0) && (SigDataSize
>= SigList
->SignatureListSize
)) {
807 for (Index
= 0; Index
< (sizeof (mSupportSigItem
) / sizeof (EFI_SIGNATURE_ITEM
)); Index
++ ) {
808 if (CompareGuid (&SigList
->SignatureType
, &mSupportSigItem
[Index
].SigType
)) {
810 // The value of SignatureSize should always be 16 (size of SignatureOwner
811 // component) add the data length according to signature type.
813 if (mSupportSigItem
[Index
].SigDataSize
!= ((UINT32
) ~0) &&
814 (SigList
->SignatureSize
- sizeof (EFI_GUID
)) != mSupportSigItem
[Index
].SigDataSize
) {
815 return EFI_INVALID_PARAMETER
;
817 if (mSupportSigItem
[Index
].SigHeaderSize
!= ((UINTN
) ~0) &&
818 SigList
->SignatureHeaderSize
!= mSupportSigItem
[Index
].SigHeaderSize
) {
819 return EFI_INVALID_PARAMETER
;
825 if (Index
== (sizeof (mSupportSigItem
) / sizeof (EFI_SIGNATURE_ITEM
))) {
827 // Undefined signature type.
829 return EFI_INVALID_PARAMETER
;
832 if ((SigList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - SigList
->SignatureHeaderSize
) % SigList
->SignatureSize
!= 0) {
833 return EFI_INVALID_PARAMETER
;
835 SigCount
+= (SigList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - SigList
->SignatureHeaderSize
) / SigList
->SignatureSize
;
837 SigDataSize
-= SigList
->SignatureListSize
;
838 SigList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) SigList
+ SigList
->SignatureListSize
);
841 if (((UINTN
) SigList
- (UINTN
) Data
) != DataSize
) {
842 return EFI_INVALID_PARAMETER
;
845 if (IsPk
&& SigCount
> 1) {
846 return EFI_INVALID_PARAMETER
;
853 Process variable with platform key for verification.
855 @param[in] VariableName Name of Variable to be found.
856 @param[in] VendorGuid Variable vendor GUID.
857 @param[in] Data Data pointer.
858 @param[in] DataSize Size of Data found. If size is less than the
859 data, this value contains the required size.
860 @param[in] Variable The variable information which is used to keep track of variable usage.
861 @param[in] Attributes Attribute value of the variable
862 @param[in] IsPk Indicate whether it is to process pk.
864 @return EFI_INVALID_PARAMETER Invalid parameter.
865 @return EFI_SECURITY_VIOLATION The variable does NOT pass the validation.
866 check carried out by the firmware.
867 @return EFI_SUCCESS Variable passed validation successfully.
872 IN CHAR16
*VariableName
,
873 IN EFI_GUID
*VendorGuid
,
876 IN VARIABLE_POINTER_TRACK
*Variable
,
877 IN UINT32 Attributes OPTIONAL
,
882 VARIABLE_POINTER_TRACK PkVariable
;
883 EFI_SIGNATURE_LIST
*OldPkList
;
884 EFI_SIGNATURE_DATA
*OldPkData
;
885 EFI_VARIABLE_AUTHENTICATION
*CertData
;
890 UINT64 MonotonicCount
;
893 if ((Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0) {
895 // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute.
897 return EFI_INVALID_PARAMETER
;
900 if (mPlatformMode
== USER_MODE
&& !(InCustomMode() && UserPhysicalPresent())) {
902 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
904 // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute means time-based X509 Cert PK.
907 } else if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
909 // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute means counter-based RSA-2048 Cert PK.
913 return EFI_INVALID_PARAMETER
;
918 // Verify against X509 Cert PK.
921 Status
= VerifyTimeBasedPayload (
931 if (!EFI_ERROR (Status
)) {
933 // If delete PK in user mode, need change to setup mode.
936 Status
= UpdatePlatformMode (SETUP_MODE
);
942 // Verify against RSA2048 Cert PK.
944 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
945 if ((Variable
->CurrPtr
!= NULL
) && (CertData
->MonotonicCount
<= Variable
->CurrPtr
->MonotonicCount
)) {
947 // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
949 return EFI_SECURITY_VIOLATION
;
952 // Get platform key from variable.
954 Status
= FindVariable (
955 EFI_PLATFORM_KEY_NAME
,
956 &gEfiGlobalVariableGuid
,
958 &mVariableModuleGlobal
->VariableGlobal
,
961 ASSERT_EFI_ERROR (Status
);
963 OldPkList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (PkVariable
.CurrPtr
);
964 OldPkData
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) OldPkList
+ sizeof (EFI_SIGNATURE_LIST
) + OldPkList
->SignatureHeaderSize
);
965 Status
= VerifyCounterBasedPayload (Data
, DataSize
, OldPkData
->SignatureData
);
966 if (!EFI_ERROR (Status
)) {
967 Status
= CheckSignatureListFormat(
970 (UINT8
*)Data
+ AUTHINFO_SIZE
,
971 DataSize
- AUTHINFO_SIZE
);
972 if (EFI_ERROR (Status
)) {
976 Status
= UpdateVariable (
979 (UINT8
*)Data
+ AUTHINFO_SIZE
,
980 DataSize
- AUTHINFO_SIZE
,
983 CertData
->MonotonicCount
,
988 if (!EFI_ERROR (Status
)) {
990 // If delete PK in user mode, need change to setup mode.
992 if ((DataSize
== AUTHINFO_SIZE
) && IsPk
) {
993 Status
= UpdatePlatformMode (SETUP_MODE
);
1000 // Process PK or KEK in Setup mode or Custom Secure Boot mode.
1002 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1004 // Time-based Authentication descriptor.
1007 TimeStamp
= &((EFI_VARIABLE_AUTHENTICATION_2
*) Data
)->TimeStamp
;
1008 Payload
= (UINT8
*) Data
+ AUTHINFO2_SIZE (Data
);
1009 PayloadSize
= DataSize
- AUTHINFO2_SIZE (Data
);
1010 } else if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1012 // Counter-based Authentication descriptor.
1014 MonotonicCount
= ((EFI_VARIABLE_AUTHENTICATION
*) Data
)->MonotonicCount
;
1016 Payload
= (UINT8
*) Data
+ AUTHINFO_SIZE
;
1017 PayloadSize
= DataSize
- AUTHINFO_SIZE
;
1020 // No Authentication descriptor.
1025 PayloadSize
= DataSize
;
1028 Status
= CheckSignatureListFormat(VariableName
, VendorGuid
, Payload
, PayloadSize
);
1029 if (EFI_ERROR (Status
)) {
1033 Status
= UpdateVariable (
1046 if (PayloadSize
!= 0) {
1048 // If enroll PK in setup mode, need change to user mode.
1050 Status
= UpdatePlatformMode (USER_MODE
);
1053 // If delete PK in custom mode, need change to setup mode.
1055 UpdatePlatformMode (SETUP_MODE
);
1064 Process variable with key exchange key for verification.
1066 @param[in] VariableName Name of Variable to be found.
1067 @param[in] VendorGuid Variable vendor GUID.
1068 @param[in] Data Data pointer.
1069 @param[in] DataSize Size of Data found. If size is less than the
1070 data, this value contains the required size.
1071 @param[in] Variable The variable information which is used to keep track of variable usage.
1072 @param[in] Attributes Attribute value of the variable.
1074 @return EFI_INVALID_PARAMETER Invalid parameter.
1075 @return EFI_SECURITY_VIOLATION The variable does NOT pass the validation
1076 check carried out by the firmware.
1077 @return EFI_SUCCESS Variable pass validation successfully.
1082 IN CHAR16
*VariableName
,
1083 IN EFI_GUID
*VendorGuid
,
1086 IN VARIABLE_POINTER_TRACK
*Variable
,
1087 IN UINT32 Attributes OPTIONAL
1091 VARIABLE_POINTER_TRACK KekVariable
;
1092 EFI_SIGNATURE_LIST
*KekList
;
1093 EFI_SIGNATURE_DATA
*KekItem
;
1095 EFI_VARIABLE_AUTHENTICATION
*CertData
;
1096 EFI_CERT_BLOCK_RSA_2048_SHA256
*CertBlock
;
1102 UINT64 MonotonicCount
;
1103 EFI_TIME
*TimeStamp
;
1105 if ((Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0) {
1107 // DB and DBX should set EFI_VARIABLE_NON_VOLATILE attribute.
1109 return EFI_INVALID_PARAMETER
;
1112 Status
= EFI_SUCCESS
;
1113 if (mPlatformMode
== USER_MODE
&& !(InCustomMode() && UserPhysicalPresent())) {
1114 if (((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) == 0) &&
1115 ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) == 0)){
1117 // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or
1118 // EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute.
1120 return EFI_INVALID_PARAMETER
;
1123 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1125 // Time-based, verify against X509 Cert KEK.
1127 return VerifyTimeBasedPayload (
1137 } else if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1139 // Counter-based, verify against RSA2048 Cert KEK.
1141 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
1142 CertBlock
= (EFI_CERT_BLOCK_RSA_2048_SHA256
*) (CertData
->AuthInfo
.CertData
);
1143 if ((Variable
->CurrPtr
!= NULL
) && (CertData
->MonotonicCount
<= Variable
->CurrPtr
->MonotonicCount
)) {
1145 // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
1147 return EFI_SECURITY_VIOLATION
;
1150 // Get KEK database from variable.
1152 Status
= FindVariable (
1153 EFI_KEY_EXCHANGE_KEY_NAME
,
1154 &gEfiGlobalVariableGuid
,
1156 &mVariableModuleGlobal
->VariableGlobal
,
1159 ASSERT_EFI_ERROR (Status
);
1161 KekDataSize
= KekVariable
.CurrPtr
->DataSize
;
1162 KekList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (KekVariable
.CurrPtr
);
1165 // Enumerate all Kek items in this list to verify the variable certificate data.
1166 // If anyone is authenticated successfully, it means the variable is correct!
1169 while ((KekDataSize
> 0) && (KekDataSize
>= KekList
->SignatureListSize
)) {
1170 if (CompareGuid (&KekList
->SignatureType
, &gEfiCertRsa2048Guid
)) {
1171 KekItem
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) KekList
+ sizeof (EFI_SIGNATURE_LIST
) + KekList
->SignatureHeaderSize
);
1172 KekCount
= (KekList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - KekList
->SignatureHeaderSize
) / KekList
->SignatureSize
;
1173 for (Index
= 0; Index
< KekCount
; Index
++) {
1174 if (CompareMem (KekItem
->SignatureData
, CertBlock
->PublicKey
, EFI_CERT_TYPE_RSA2048_SIZE
) == 0) {
1178 KekItem
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) KekItem
+ KekList
->SignatureSize
);
1181 KekDataSize
-= KekList
->SignatureListSize
;
1182 KekList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) KekList
+ KekList
->SignatureListSize
);
1186 return EFI_SECURITY_VIOLATION
;
1189 Status
= VerifyCounterBasedPayload (Data
, DataSize
, CertBlock
->PublicKey
);
1190 if (!EFI_ERROR (Status
)) {
1191 Status
= UpdateVariable (
1194 (UINT8
*)Data
+ AUTHINFO_SIZE
,
1195 DataSize
- AUTHINFO_SIZE
,
1198 CertData
->MonotonicCount
,
1206 // If in setup mode or custom secure boot mode, no authentication needed.
1208 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1210 // Time-based Authentication descriptor.
1213 TimeStamp
= &((EFI_VARIABLE_AUTHENTICATION_2
*) Data
)->TimeStamp
;
1214 Payload
= (UINT8
*) Data
+ AUTHINFO2_SIZE (Data
);
1215 PayloadSize
= DataSize
- AUTHINFO2_SIZE (Data
);
1216 } else if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1218 // Counter-based Authentication descriptor.
1220 MonotonicCount
= ((EFI_VARIABLE_AUTHENTICATION
*) Data
)->MonotonicCount
;
1222 Payload
= (UINT8
*) Data
+ AUTHINFO_SIZE
;
1223 PayloadSize
= DataSize
- AUTHINFO_SIZE
;
1226 // No Authentication descriptor.
1231 PayloadSize
= DataSize
;
1234 Status
= UpdateVariable (
1251 Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
1253 @param[in] VariableName Name of Variable to be found.
1254 @param[in] VendorGuid Variable vendor GUID.
1256 @param[in] Data Data pointer.
1257 @param[in] DataSize Size of Data found. If size is less than the
1258 data, this value contains the required size.
1259 @param[in] Variable The variable information which is used to keep track of variable usage.
1260 @param[in] Attributes Attribute value of the variable.
1262 @return EFI_INVALID_PARAMETER Invalid parameter.
1263 @return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
1264 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
1265 @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
1266 set, but the AuthInfo does NOT pass the validation
1267 check carried out by the firmware.
1268 @return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
1273 IN CHAR16
*VariableName
,
1274 IN EFI_GUID
*VendorGuid
,
1277 IN VARIABLE_POINTER_TRACK
*Variable
,
1278 IN UINT32 Attributes
1283 BOOLEAN IsFirstTime
;
1285 EFI_VARIABLE_AUTHENTICATION
*CertData
;
1286 EFI_CERT_BLOCK_RSA_2048_SHA256
*CertBlock
;
1288 UINT64 MonotonicCount
;
1296 if (NeedPhysicallyPresent(VariableName
, VendorGuid
) && !UserPhysicalPresent()) {
1298 // This variable is protected, only physical present user could modify its value.
1300 return EFI_SECURITY_VIOLATION
;
1304 // Process Time-based Authenticated variable.
1306 if ((Attributes
& EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1307 return VerifyTimeBasedPayload (
1320 // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.
1322 if ((Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0) {
1324 // Determine current operation type.
1326 if (DataSize
== AUTHINFO_SIZE
) {
1330 // Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
1332 if (Variable
->CurrPtr
== NULL
) {
1334 } else if ((Variable
->CurrPtr
->Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) == 0) {
1337 KeyIndex
= Variable
->CurrPtr
->PubKeyIndex
;
1338 IsFirstTime
= FALSE
;
1340 } else if ((Variable
->CurrPtr
!= NULL
) &&
1341 (Variable
->CurrPtr
->Attributes
& EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
) != 0
1344 // If the variable is already write-protected, it always needs authentication before update.
1346 return EFI_WRITE_PROTECTED
;
1349 // If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.
1350 // That means it is not authenticated variable, just update variable as usual.
1352 Status
= UpdateVariable (VariableName
, VendorGuid
, Data
, DataSize
, Attributes
, 0, 0, Variable
, NULL
);
1357 // Get PubKey and check Monotonic Count value corresponding to the variable.
1359 CertData
= (EFI_VARIABLE_AUTHENTICATION
*) Data
;
1360 CertBlock
= (EFI_CERT_BLOCK_RSA_2048_SHA256
*) (CertData
->AuthInfo
.CertData
);
1361 PubKey
= CertBlock
->PublicKey
;
1364 // Update Monotonic Count value.
1366 MonotonicCount
= CertData
->MonotonicCount
;
1370 // Check input PubKey.
1372 if (CompareMem (PubKey
, mPubKeyStore
+ (KeyIndex
- 1) * EFI_CERT_TYPE_RSA2048_SIZE
, EFI_CERT_TYPE_RSA2048_SIZE
) != 0) {
1373 return EFI_SECURITY_VIOLATION
;
1376 // Compare the current monotonic count and ensure that it is greater than the last SetVariable
1377 // operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.
1379 if (CertData
->MonotonicCount
<= Variable
->CurrPtr
->MonotonicCount
) {
1381 // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
1383 return EFI_SECURITY_VIOLATION
;
1387 // Verify the certificate in Data payload.
1389 Status
= VerifyCounterBasedPayload (Data
, DataSize
, PubKey
);
1390 if (EFI_ERROR (Status
)) {
1395 // Now, the signature has been verified!
1397 if (IsFirstTime
&& !IsDeletion
) {
1399 // Update public key database variable if need.
1401 KeyIndex
= AddPubKeyInStore (PubKey
);
1405 // Verification pass.
1407 return UpdateVariable (VariableName
, VendorGuid
, (UINT8
*)Data
+ AUTHINFO_SIZE
, DataSize
- AUTHINFO_SIZE
, Attributes
, KeyIndex
, MonotonicCount
, Variable
, NULL
);
1411 Merge two buffers which formatted as EFI_SIGNATURE_LIST. Only the new EFI_SIGNATURE_DATA
1412 will be appended to the original EFI_SIGNATURE_LIST, duplicate EFI_SIGNATURE_DATA
1415 @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST.
1416 @param[in] DataSize Size of Data buffer.
1417 @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended.
1418 @param[in] NewDataSize Size of NewData buffer.
1420 @return Size of the merged buffer.
1424 AppendSignatureList (
1428 IN UINTN NewDataSize
1431 EFI_SIGNATURE_LIST
*CertList
;
1432 EFI_SIGNATURE_DATA
*Cert
;
1434 EFI_SIGNATURE_LIST
*NewCertList
;
1435 EFI_SIGNATURE_DATA
*NewCert
;
1442 UINTN SignatureListSize
;
1445 Tail
= (UINT8
*) Data
+ DataSize
;
1447 NewCertList
= (EFI_SIGNATURE_LIST
*) NewData
;
1448 while ((NewDataSize
> 0) && (NewDataSize
>= NewCertList
->SignatureListSize
)) {
1449 NewCert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) NewCertList
+ sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
);
1450 NewCertCount
= (NewCertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - NewCertList
->SignatureHeaderSize
) / NewCertList
->SignatureSize
;
1453 for (Index
= 0; Index
< NewCertCount
; Index
++) {
1457 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
1458 while ((Size
> 0) && (Size
>= CertList
->SignatureListSize
)) {
1459 if (CompareGuid (&CertList
->SignatureType
, &NewCertList
->SignatureType
) &&
1460 (CertList
->SignatureSize
== NewCertList
->SignatureSize
)) {
1461 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
1462 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
1463 for (Index2
= 0; Index2
< CertCount
; Index2
++) {
1465 // Iterate each Signature Data in this Signature List.
1467 if (CompareMem (NewCert
, Cert
, CertList
->SignatureSize
) == 0) {
1471 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
1478 Size
-= CertList
->SignatureListSize
;
1479 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
1484 // New EFI_SIGNATURE_DATA, append it.
1486 if (CopiedCount
== 0) {
1488 // Copy EFI_SIGNATURE_LIST header for only once.
1490 CopyMem (Tail
, NewCertList
, sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
);
1491 Tail
= Tail
+ sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
;
1494 CopyMem (Tail
, NewCert
, NewCertList
->SignatureSize
);
1495 Tail
+= NewCertList
->SignatureSize
;
1499 NewCert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) NewCert
+ NewCertList
->SignatureSize
);
1503 // Update SignatureListSize in newly appended EFI_SIGNATURE_LIST.
1505 if (CopiedCount
!= 0) {
1506 SignatureListSize
= sizeof (EFI_SIGNATURE_LIST
) + NewCertList
->SignatureHeaderSize
+ (CopiedCount
* NewCertList
->SignatureSize
);
1507 CertList
= (EFI_SIGNATURE_LIST
*) (Tail
- SignatureListSize
);
1508 CertList
->SignatureListSize
= (UINT32
) SignatureListSize
;
1511 NewDataSize
-= NewCertList
->SignatureListSize
;
1512 NewCertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) NewCertList
+ NewCertList
->SignatureListSize
);
1515 return (Tail
- (UINT8
*) Data
);
1519 Compare two EFI_TIME data.
1522 @param FirstTime A pointer to the first EFI_TIME data.
1523 @param SecondTime A pointer to the second EFI_TIME data.
1525 @retval TRUE The FirstTime is not later than the SecondTime.
1526 @retval FALSE The FirstTime is later than the SecondTime.
1531 IN EFI_TIME
*FirstTime
,
1532 IN EFI_TIME
*SecondTime
1535 if (FirstTime
->Year
!= SecondTime
->Year
) {
1536 return (BOOLEAN
) (FirstTime
->Year
< SecondTime
->Year
);
1537 } else if (FirstTime
->Month
!= SecondTime
->Month
) {
1538 return (BOOLEAN
) (FirstTime
->Month
< SecondTime
->Month
);
1539 } else if (FirstTime
->Day
!= SecondTime
->Day
) {
1540 return (BOOLEAN
) (FirstTime
->Day
< SecondTime
->Day
);
1541 } else if (FirstTime
->Hour
!= SecondTime
->Hour
) {
1542 return (BOOLEAN
) (FirstTime
->Hour
< SecondTime
->Hour
);
1543 } else if (FirstTime
->Minute
!= SecondTime
->Minute
) {
1544 return (BOOLEAN
) (FirstTime
->Minute
< FirstTime
->Minute
);
1547 return (BOOLEAN
) (FirstTime
->Second
<= SecondTime
->Second
);
1551 Find matching signer's certificates for common authenticated variable
1552 by corresponding VariableName and VendorGuid from "certdb".
1554 The data format of "certdb":
1556 // UINT32 CertDbListSize;
1557 // /// AUTH_CERT_DB_DATA Certs1[];
1558 // /// AUTH_CERT_DB_DATA Certs2[];
1560 // /// AUTH_CERT_DB_DATA Certsn[];
1563 @param[in] VariableName Name of authenticated Variable.
1564 @param[in] VendorGuid Vendor GUID of authenticated Variable.
1565 @param[in] Data Pointer to variable "certdb".
1566 @param[in] DataSize Size of variable "certdb".
1567 @param[out] CertOffset Offset of matching CertData, from starting of Data.
1568 @param[out] CertDataSize Length of CertData in bytes.
1569 @param[out] CertNodeOffset Offset of matching AUTH_CERT_DB_DATA , from
1571 @param[out] CertNodeSize Length of AUTH_CERT_DB_DATA in bytes.
1573 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1574 @retval EFI_NOT_FOUND Fail to find matching certs.
1575 @retval EFI_SUCCESS Find matching certs and output parameters.
1580 IN CHAR16
*VariableName
,
1581 IN EFI_GUID
*VendorGuid
,
1584 OUT UINT32
*CertOffset
, OPTIONAL
1585 OUT UINT32
*CertDataSize
, OPTIONAL
1586 OUT UINT32
*CertNodeOffset
,OPTIONAL
1587 OUT UINT32
*CertNodeSize OPTIONAL
1591 AUTH_CERT_DB_DATA
*Ptr
;
1595 UINT32 CertDbListSize
;
1597 if ((VariableName
== NULL
) || (VendorGuid
== NULL
) || (Data
== NULL
)) {
1598 return EFI_INVALID_PARAMETER
;
1602 // Check whether DataSize matches recorded CertDbListSize.
1604 if (DataSize
< sizeof (UINT32
)) {
1605 return EFI_INVALID_PARAMETER
;
1608 CertDbListSize
= ReadUnaligned32 ((UINT32
*) Data
);
1610 if (CertDbListSize
!= (UINT32
) DataSize
) {
1611 return EFI_INVALID_PARAMETER
;
1614 Offset
= sizeof (UINT32
);
1617 // Get corresponding certificates by VendorGuid and VariableName.
1619 while (Offset
< (UINT32
) DataSize
) {
1620 Ptr
= (AUTH_CERT_DB_DATA
*) (Data
+ Offset
);
1622 // Check whether VendorGuid matches.
1624 if (CompareGuid (&Ptr
->VendorGuid
, VendorGuid
)) {
1625 NodeSize
= ReadUnaligned32 (&Ptr
->CertNodeSize
);
1626 NameSize
= ReadUnaligned32 (&Ptr
->NameSize
);
1627 CertSize
= ReadUnaligned32 (&Ptr
->CertDataSize
);
1629 if (NodeSize
!= sizeof (EFI_GUID
) + sizeof (UINT32
) * 3 + CertSize
+
1630 sizeof (CHAR16
) * NameSize
) {
1631 return EFI_INVALID_PARAMETER
;
1634 Offset
= Offset
+ sizeof (EFI_GUID
) + sizeof (UINT32
) * 3;
1636 // Check whether VariableName matches.
1638 if ((NameSize
== StrLen (VariableName
)) &&
1639 (CompareMem (Data
+ Offset
, VariableName
, NameSize
* sizeof (CHAR16
)) == 0)) {
1640 Offset
= Offset
+ NameSize
* sizeof (CHAR16
);
1642 if (CertOffset
!= NULL
) {
1643 *CertOffset
= Offset
;
1646 if (CertDataSize
!= NULL
) {
1647 *CertDataSize
= CertSize
;
1650 if (CertNodeOffset
!= NULL
) {
1651 *CertNodeOffset
= (UINT32
) ((UINT8
*) Ptr
- Data
);
1654 if (CertNodeSize
!= NULL
) {
1655 *CertNodeSize
= NodeSize
;
1660 Offset
= Offset
+ NameSize
* sizeof (CHAR16
) + CertSize
;
1663 NodeSize
= ReadUnaligned32 (&Ptr
->CertNodeSize
);
1664 Offset
= Offset
+ NodeSize
;
1668 return EFI_NOT_FOUND
;
1672 Retrieve signer's certificates for common authenticated variable
1673 by corresponding VariableName and VendorGuid from "certdb".
1675 @param[in] VariableName Name of authenticated Variable.
1676 @param[in] VendorGuid Vendor GUID of authenticated Variable.
1677 @param[out] CertData Pointer to signer's certificates.
1678 @param[out] CertDataSize Length of CertData in bytes.
1680 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1681 @retval EFI_NOT_FOUND Fail to find "certdb" or matching certs.
1682 @retval EFI_SUCCESS Get signer's certificates successfully.
1687 IN CHAR16
*VariableName
,
1688 IN EFI_GUID
*VendorGuid
,
1689 OUT UINT8
**CertData
,
1690 OUT UINT32
*CertDataSize
1693 VARIABLE_POINTER_TRACK CertDbVariable
;
1699 if ((VariableName
== NULL
) || (VendorGuid
== NULL
) || (CertData
== NULL
) || (CertDataSize
== NULL
)) {
1700 return EFI_INVALID_PARAMETER
;
1704 // Get variable "certdb".
1706 Status
= FindVariable (
1710 &mVariableModuleGlobal
->VariableGlobal
,
1713 if (EFI_ERROR (Status
)) {
1717 DataSize
= DataSizeOfVariable (CertDbVariable
.CurrPtr
);
1718 Data
= GetVariableDataPtr (CertDbVariable
.CurrPtr
);
1719 if ((DataSize
== 0) || (Data
== NULL
)) {
1721 return EFI_NOT_FOUND
;
1724 Status
= FindCertsFromDb (
1735 if (EFI_ERROR (Status
)) {
1739 *CertData
= Data
+ CertOffset
;
1744 Delete matching signer's certificates when deleting common authenticated
1745 variable by corresponding VariableName and VendorGuid from "certdb".
1747 @param[in] VariableName Name of authenticated Variable.
1748 @param[in] VendorGuid Vendor GUID of authenticated Variable.
1750 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1751 @retval EFI_NOT_FOUND Fail to find "certdb" or matching certs.
1752 @retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.
1753 @retval EFI_SUCCESS The operation is completed successfully.
1758 IN CHAR16
*VariableName
,
1759 IN EFI_GUID
*VendorGuid
1762 VARIABLE_POINTER_TRACK CertDbVariable
;
1767 UINT32 CertNodeOffset
;
1768 UINT32 CertNodeSize
;
1770 UINT32 NewCertDbSize
;
1772 if ((VariableName
== NULL
) || (VendorGuid
== NULL
)) {
1773 return EFI_INVALID_PARAMETER
;
1777 // Get variable "certdb".
1779 Status
= FindVariable (
1783 &mVariableModuleGlobal
->VariableGlobal
,
1786 if (EFI_ERROR (Status
)) {
1790 DataSize
= DataSizeOfVariable (CertDbVariable
.CurrPtr
);
1791 Data
= GetVariableDataPtr (CertDbVariable
.CurrPtr
);
1792 if ((DataSize
== 0) || (Data
== NULL
)) {
1794 return EFI_NOT_FOUND
;
1797 if (DataSize
== sizeof (UINT32
)) {
1799 // There is no certs in certdb.
1805 // Get corresponding cert node from certdb.
1807 Status
= FindCertsFromDb (
1818 if (EFI_ERROR (Status
)) {
1822 if (DataSize
< (CertNodeOffset
+ CertNodeSize
)) {
1823 return EFI_NOT_FOUND
;
1827 // Construct new data content of variable "certdb".
1829 NewCertDbSize
= (UINT32
) DataSize
- CertNodeSize
;
1830 NewCertDb
= AllocateZeroPool (NewCertDbSize
);
1831 if (NewCertDb
== NULL
) {
1832 return EFI_OUT_OF_RESOURCES
;
1836 // Copy the DB entries before deleting node.
1838 CopyMem (NewCertDb
, Data
, CertNodeOffset
);
1840 // Update CertDbListSize.
1842 CopyMem (NewCertDb
, &NewCertDbSize
, sizeof (UINT32
));
1844 // Copy the DB entries after deleting node.
1846 if (DataSize
> (CertNodeOffset
+ CertNodeSize
)) {
1848 NewCertDb
+ CertNodeOffset
,
1849 Data
+ CertNodeOffset
+ CertNodeSize
,
1850 DataSize
- CertNodeOffset
- CertNodeSize
1857 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
1858 Status
= UpdateVariable (
1870 FreePool (NewCertDb
);
1875 Insert signer's certificates for common authenticated variable with VariableName
1876 and VendorGuid in AUTH_CERT_DB_DATA to "certdb".
1878 @param[in] VariableName Name of authenticated Variable.
1879 @param[in] VendorGuid Vendor GUID of authenticated Variable.
1880 @param[in] CertData Pointer to signer's certificates.
1881 @param[in] CertDataSize Length of CertData in bytes.
1883 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1884 @retval EFI_ACCESS_DENIED An AUTH_CERT_DB_DATA entry with same VariableName
1885 and VendorGuid already exists.
1886 @retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.
1887 @retval EFI_SUCCESS Insert an AUTH_CERT_DB_DATA entry to "certdb"
1892 IN CHAR16
*VariableName
,
1893 IN EFI_GUID
*VendorGuid
,
1895 IN UINTN CertDataSize
1898 VARIABLE_POINTER_TRACK CertDbVariable
;
1904 UINT32 NewCertDbSize
;
1905 UINT32 CertNodeSize
;
1907 AUTH_CERT_DB_DATA
*Ptr
;
1909 if ((VariableName
== NULL
) || (VendorGuid
== NULL
) || (CertData
== NULL
)) {
1910 return EFI_INVALID_PARAMETER
;
1914 // Get variable "certdb".
1916 Status
= FindVariable (
1920 &mVariableModuleGlobal
->VariableGlobal
,
1923 if (EFI_ERROR (Status
)) {
1927 DataSize
= DataSizeOfVariable (CertDbVariable
.CurrPtr
);
1928 Data
= GetVariableDataPtr (CertDbVariable
.CurrPtr
);
1929 if ((DataSize
== 0) || (Data
== NULL
)) {
1931 return EFI_NOT_FOUND
;
1935 // Find whether matching cert node already exists in "certdb".
1936 // If yes return error.
1938 Status
= FindCertsFromDb (
1949 if (!EFI_ERROR (Status
)) {
1951 return EFI_ACCESS_DENIED
;
1955 // Construct new data content of variable "certdb".
1957 NameSize
= (UINT32
) StrLen (VariableName
);
1958 CertNodeSize
= sizeof (AUTH_CERT_DB_DATA
) + (UINT32
) CertDataSize
+ NameSize
* sizeof (CHAR16
);
1959 NewCertDbSize
= (UINT32
) DataSize
+ CertNodeSize
;
1960 NewCertDb
= AllocateZeroPool (NewCertDbSize
);
1961 if (NewCertDb
== NULL
) {
1962 return EFI_OUT_OF_RESOURCES
;
1966 // Copy the DB entries before deleting node.
1968 CopyMem (NewCertDb
, Data
, DataSize
);
1970 // Update CertDbListSize.
1972 CopyMem (NewCertDb
, &NewCertDbSize
, sizeof (UINT32
));
1974 // Construct new cert node.
1976 Ptr
= (AUTH_CERT_DB_DATA
*) (NewCertDb
+ DataSize
);
1977 CopyGuid (&Ptr
->VendorGuid
, VendorGuid
);
1978 CopyMem (&Ptr
->CertNodeSize
, &CertNodeSize
, sizeof (UINT32
));
1979 CopyMem (&Ptr
->NameSize
, &NameSize
, sizeof (UINT32
));
1980 CopyMem (&Ptr
->CertDataSize
, &CertDataSize
, sizeof (UINT32
));
1983 (UINT8
*) Ptr
+ sizeof (AUTH_CERT_DB_DATA
),
1985 NameSize
* sizeof (CHAR16
)
1989 (UINT8
*) Ptr
+ sizeof (AUTH_CERT_DB_DATA
) + NameSize
* sizeof (CHAR16
),
1997 VarAttr
= EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
;
1998 Status
= UpdateVariable (
2010 FreePool (NewCertDb
);
2015 Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
2017 @param[in] VariableName Name of Variable to be found.
2018 @param[in] VendorGuid Variable vendor GUID.
2019 @param[in] Data Data pointer.
2020 @param[in] DataSize Size of Data found. If size is less than the
2021 data, this value contains the required size.
2022 @param[in] Variable The variable information which is used to keep track of variable usage.
2023 @param[in] Attributes Attribute value of the variable.
2024 @param[in] AuthVarType Verify against PK or KEK database or private database.
2025 @param[out] VarDel Delete the variable or not.
2027 @retval EFI_INVALID_PARAMETER Invalid parameter.
2028 @retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
2029 check carried out by the firmware.
2030 @retval EFI_OUT_OF_RESOURCES Failed to process variable due to lack
2032 @retval EFI_SUCCESS Variable pass validation successfully.
2036 VerifyTimeBasedPayload (
2037 IN CHAR16
*VariableName
,
2038 IN EFI_GUID
*VendorGuid
,
2041 IN VARIABLE_POINTER_TRACK
*Variable
,
2042 IN UINT32 Attributes
,
2043 IN AUTHVAR_TYPE AuthVarType
,
2057 BOOLEAN VerifyStatus
;
2059 EFI_SIGNATURE_LIST
*CertList
;
2060 EFI_SIGNATURE_DATA
*Cert
;
2061 VARIABLE_POINTER_TRACK KekVariable
;
2062 EFI_VARIABLE_AUTHENTICATION_2
*CertData
;
2065 VARIABLE_POINTER_TRACK PkVariable
;
2070 UINTN CertStackSize
;
2071 UINT8
*CertsInCertDb
;
2072 UINT32 CertsSizeinDb
;
2074 VerifyStatus
= FALSE
;
2083 // When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
2084 // set, then the Data buffer shall begin with an instance of a complete (and serialized)
2085 // EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
2086 // variable value and DataSize shall reflect the combined size of the descriptor and the new
2087 // variable value. The authentication descriptor is not part of the variable data and is not
2088 // returned by subsequent calls to GetVariable().
2090 CertData
= (EFI_VARIABLE_AUTHENTICATION_2
*) Data
;
2093 // Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the
2094 // TimeStamp value are set to zero.
2096 if ((CertData
->TimeStamp
.Pad1
!= 0) ||
2097 (CertData
->TimeStamp
.Nanosecond
!= 0) ||
2098 (CertData
->TimeStamp
.TimeZone
!= 0) ||
2099 (CertData
->TimeStamp
.Daylight
!= 0) ||
2100 (CertData
->TimeStamp
.Pad2
!= 0)) {
2101 return EFI_SECURITY_VIOLATION
;
2104 if ((Variable
->CurrPtr
!= NULL
) && ((Attributes
& EFI_VARIABLE_APPEND_WRITE
) == 0)) {
2105 if (CompareTimeStamp (&CertData
->TimeStamp
, &Variable
->CurrPtr
->TimeStamp
)) {
2107 // TimeStamp check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
2109 return EFI_SECURITY_VIOLATION
;
2114 // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
2115 // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.
2117 if ((CertData
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) ||
2118 !CompareGuid (&CertData
->AuthInfo
.CertType
, &gEfiCertPkcs7Guid
)) {
2120 // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
2122 return EFI_SECURITY_VIOLATION
;
2126 // Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.
2127 // AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.
2129 SigData
= CertData
->AuthInfo
.CertData
;
2130 SigDataSize
= CertData
->AuthInfo
.Hdr
.dwLength
- (UINT32
) (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID
, CertData
));
2133 // Find out the new data payload which follows Pkcs7 SignedData directly.
2135 PayloadPtr
= SigData
+ SigDataSize
;
2136 PayloadSize
= DataSize
- OFFSET_OF_AUTHINFO2_CERT_DATA
- (UINTN
) SigDataSize
;
2139 // Construct a buffer to fill with (VariableName, VendorGuid, Attributes, TimeStamp, Data).
2141 NewDataSize
= PayloadSize
+ sizeof (EFI_TIME
) + sizeof (UINT32
) +
2142 sizeof (EFI_GUID
) + StrSize (VariableName
) - sizeof (CHAR16
);
2143 NewData
= mSerializationRuntimeBuffer
;
2146 Length
= StrLen (VariableName
) * sizeof (CHAR16
);
2147 CopyMem (Buffer
, VariableName
, Length
);
2150 Length
= sizeof (EFI_GUID
);
2151 CopyMem (Buffer
, VendorGuid
, Length
);
2154 Length
= sizeof (UINT32
);
2155 CopyMem (Buffer
, &Attr
, Length
);
2158 Length
= sizeof (EFI_TIME
);
2159 CopyMem (Buffer
, &CertData
->TimeStamp
, Length
);
2162 CopyMem (Buffer
, PayloadPtr
, PayloadSize
);
2164 if (AuthVarType
== AuthVarTypePk
) {
2166 // Get platform key from variable.
2168 Status
= FindVariable (
2169 EFI_PLATFORM_KEY_NAME
,
2170 &gEfiGlobalVariableGuid
,
2172 &mVariableModuleGlobal
->VariableGlobal
,
2175 if (EFI_ERROR (Status
)) {
2179 CertList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (PkVariable
.CurrPtr
);
2180 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2181 RootCert
= Cert
->SignatureData
;
2182 RootCertSize
= CertList
->SignatureSize
;
2186 // Verify Pkcs7 SignedData via Pkcs7Verify library.
2188 VerifyStatus
= Pkcs7Verify (
2197 } else if (AuthVarType
== AuthVarTypeKek
) {
2200 // Get KEK database from variable.
2202 Status
= FindVariable (
2203 EFI_KEY_EXCHANGE_KEY_NAME
,
2204 &gEfiGlobalVariableGuid
,
2206 &mVariableModuleGlobal
->VariableGlobal
,
2209 if (EFI_ERROR (Status
)) {
2214 // Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.
2216 KekDataSize
= KekVariable
.CurrPtr
->DataSize
;
2217 CertList
= (EFI_SIGNATURE_LIST
*) GetVariableDataPtr (KekVariable
.CurrPtr
);
2218 while ((KekDataSize
> 0) && (KekDataSize
>= CertList
->SignatureListSize
)) {
2219 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
2220 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
2221 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
2222 for (Index
= 0; Index
< CertCount
; Index
++) {
2224 // Iterate each Signature Data Node within this CertList for a verify
2226 RootCert
= Cert
->SignatureData
;
2227 RootCertSize
= CertList
->SignatureSize
;
2230 // Verify Pkcs7 SignedData via Pkcs7Verify library.
2232 VerifyStatus
= Pkcs7Verify (
2243 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
2246 KekDataSize
-= CertList
->SignatureListSize
;
2247 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
2249 } else if (AuthVarType
== AuthVarTypePriv
) {
2252 // Process common authenticated variable except PK/KEK/DB/DBX.
2253 // Get signer's certificates from SignedData.
2255 VerifyStatus
= Pkcs7GetSigners (
2263 if (!VerifyStatus
) {
2268 // Get previously stored signer's certificates from certdb for existing
2269 // variable. Check whether they are identical with signer's certificates
2270 // in SignedData. If not, return error immediately.
2272 if ((Variable
->CurrPtr
!= NULL
)) {
2273 VerifyStatus
= FALSE
;
2275 Status
= GetCertsFromDb (VariableName
, VendorGuid
, &CertsInCertDb
, &CertsSizeinDb
);
2276 if (EFI_ERROR (Status
)) {
2280 if ((CertStackSize
!= CertsSizeinDb
) ||
2281 (CompareMem (SignerCerts
, CertsInCertDb
, CertsSizeinDb
) != 0)) {
2286 VerifyStatus
= Pkcs7Verify (
2294 if (!VerifyStatus
) {
2299 // Delete signer's certificates when delete the common authenticated variable.
2301 if ((PayloadSize
== 0) && (Variable
->CurrPtr
!= NULL
)) {
2302 Status
= DeleteCertsFromDb (VariableName
, VendorGuid
);
2303 if (EFI_ERROR (Status
)) {
2304 VerifyStatus
= FALSE
;
2307 } else if (Variable
->CurrPtr
== NULL
) {
2309 // Insert signer's certificates when adding a new common authenticated variable.
2311 Status
= InsertCertsToDb (VariableName
, VendorGuid
, SignerCerts
, CertStackSize
);
2312 if (EFI_ERROR (Status
)) {
2313 VerifyStatus
= FALSE
;
2318 return EFI_SECURITY_VIOLATION
;
2323 if (AuthVarType
== AuthVarTypePriv
) {
2324 Pkcs7FreeSigners (RootCert
);
2325 Pkcs7FreeSigners (SignerCerts
);
2328 if (!VerifyStatus
) {
2329 return EFI_SECURITY_VIOLATION
;
2332 Status
= CheckSignatureListFormat(VariableName
, VendorGuid
, PayloadPtr
, PayloadSize
);
2333 if (EFI_ERROR (Status
)) {
2337 if ((PayloadSize
== 0) && (VarDel
!= NULL
)) {
2342 // Final step: Update/Append Variable if it pass Pkcs7Verify
2344 return UpdateVariable (
2353 &CertData
->TimeStamp