They will do basic validation for authentication data structure, then call crypto library\r
to verify the signature.\r
\r
-Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "AuthServiceInternal.h"\r
\r
+#include <Protocol/VariablePolicy.h>\r
+#include <Library/VariablePolicyLib.h>\r
+\r
//\r
// Public Exponent of RSA Key.\r
//\r
-CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };\r
+CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };\r
+\r
+CONST UINT8 mSha256OidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };\r
\r
//\r
// Requirement for different signature type which have been defined in UEFI spec.\r
// These data are used to perform SignatureList format check while setting PK/KEK variable.\r
//\r
-EFI_SIGNATURE_ITEM mSupportSigItem[] = {\r
-//{SigType, SigHeaderSize, SigDataSize }\r
- {EFI_CERT_SHA256_GUID, 0, 32 },\r
- {EFI_CERT_RSA2048_GUID, 0, 256 },\r
- {EFI_CERT_RSA2048_SHA256_GUID, 0, 256 },\r
- {EFI_CERT_SHA1_GUID, 0, 20 },\r
- {EFI_CERT_RSA2048_SHA1_GUID, 0, 256 },\r
- {EFI_CERT_X509_GUID, 0, ((UINT32) ~0)},\r
- {EFI_CERT_SHA224_GUID, 0, 28 },\r
- {EFI_CERT_SHA384_GUID, 0, 48 },\r
- {EFI_CERT_SHA512_GUID, 0, 64 },\r
- {EFI_CERT_X509_SHA256_GUID, 0, 48 },\r
- {EFI_CERT_X509_SHA384_GUID, 0, 64 },\r
- {EFI_CERT_X509_SHA512_GUID, 0, 80 }\r
-};\r
-\r
-//\r
-// Secure Boot Mode state machine\r
-//\r
-SECURE_BOOT_MODE mSecureBootState[SecureBootModeTypeMax] = {\r
- // USER MODE\r
- {\r
- AUDIT_MODE_DISABLE, // AuditMode\r
- FALSE, // IsAuditModeRO, AuditMode is RW\r
- DEPLOYED_MODE_DISABLE, // DeployedMode\r
- FALSE, // IsDeployedModeRO, DeployedMode is RW\r
- SETUP_MODE_DISABLE, // SetupMode\r
- // SetupMode is always RO\r
- SECURE_BOOT_MODE_ENABLE // SecureBoot\r
- },\r
- // SETUP MODE\r
- {\r
- AUDIT_MODE_DISABLE, // AuditMode\r
- FALSE, // IsAuditModeRO, AuditMode is RW\r
- DEPLOYED_MODE_DISABLE, // DeployedMode\r
- TRUE, // IsDeployedModeRO, DeployedMode is RO\r
- SETUP_MODE_ENABLE, // SetupMode\r
- // SetupMode is always RO\r
- SECURE_BOOT_MODE_DISABLE // SecureBoot\r
- },\r
- // AUDIT MODE\r
- {\r
- AUDIT_MODE_ENABLE, // AuditMode\r
- TRUE, // AuditModeValAttr RO, AuditMode is RO\r
- DEPLOYED_MODE_DISABLE, // DeployedMode\r
- TRUE, // DeployedModeValAttr RO, DeployedMode is RO\r
- SETUP_MODE_ENABLE, // SetupMode\r
- // SetupMode is always RO\r
- SECURE_BOOT_MODE_DISABLE // SecureBoot\r
- },\r
- // DEPLOYED MODE\r
- {\r
- AUDIT_MODE_DISABLE, // AuditMode, AuditMode is RO\r
- TRUE, // AuditModeValAttr RO\r
- DEPLOYED_MODE_ENABLE, // DeployedMode\r
- TRUE, // DeployedModeValAttr RO, DeployedMode is RO\r
- SETUP_MODE_DISABLE, // SetupMode\r
- // SetupMode is always RO\r
- SECURE_BOOT_MODE_ENABLE // SecureBoot\r
- }\r
+EFI_SIGNATURE_ITEM mSupportSigItem[] = {\r
+ // {SigType, SigHeaderSize, SigDataSize }\r
+ { EFI_CERT_SHA256_GUID, 0, 32 },\r
+ { EFI_CERT_RSA2048_GUID, 0, 256 },\r
+ { EFI_CERT_RSA2048_SHA256_GUID, 0, 256 },\r
+ { EFI_CERT_SHA1_GUID, 0, 20 },\r
+ { EFI_CERT_RSA2048_SHA1_GUID, 0, 256 },\r
+ { EFI_CERT_X509_GUID, 0, ((UINT32) ~0) },\r
+ { EFI_CERT_SHA224_GUID, 0, 28 },\r
+ { EFI_CERT_SHA384_GUID, 0, 48 },\r
+ { EFI_CERT_SHA512_GUID, 0, 64 },\r
+ { EFI_CERT_X509_SHA256_GUID, 0, 48 },\r
+ { EFI_CERT_X509_SHA384_GUID, 0, 64 },\r
+ { EFI_CERT_X509_SHA512_GUID, 0, 80 }\r
};\r
\r
-SECURE_BOOT_MODE_TYPE mSecureBootMode;\r
-\r
/**\r
Finds variable in storage blocks of volatile and non-volatile storage areas.\r
\r
**/\r
EFI_STATUS\r
AuthServiceInternalFindVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT VOID **Data,\r
- OUT UINTN *DataSize\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ OUT VOID **Data,\r
+ OUT UINTN *DataSize\r
)\r
{\r
- EFI_STATUS Status;\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
+ EFI_STATUS Status;\r
+ AUTH_VARIABLE_INFO AuthVariableInfo;\r
\r
ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
Status = mAuthVarLibContextIn->FindVariable (\r
- VariableName,\r
- VendorGuid,\r
- &AuthVariableInfo\r
- );\r
- *Data = AuthVariableInfo.Data;\r
+ VariableName,\r
+ VendorGuid,\r
+ &AuthVariableInfo\r
+ );\r
+ *Data = AuthVariableInfo.Data;\r
*DataSize = AuthVariableInfo.DataSize;\r
return Status;\r
}\r
**/\r
EFI_STATUS\r
AuthServiceInternalUpdateVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes\r
- )\r
-{\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
-\r
- ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
- AuthVariableInfo.VariableName = VariableName;\r
- AuthVariableInfo.VendorGuid = VendorGuid;\r
- AuthVariableInfo.Data = Data;\r
- AuthVariableInfo.DataSize = DataSize;\r
- AuthVariableInfo.Attributes = Attributes;\r
-\r
- return mAuthVarLibContextIn->UpdateVariable (\r
- &AuthVariableInfo\r
- );\r
-}\r
-\r
-/**\r
- Update the variable region with Variable information.\r
-\r
- @param[in] VariableName Name of variable.\r
- @param[in] VendorGuid Guid of variable.\r
- @param[in] Data Data pointer.\r
- @param[in] DataSize Size of Data.\r
- @param[in] Attributes Attribute value of the variable.\r
- @param[in] KeyIndex Index of associated public key.\r
- @param[in] MonotonicCount Value of associated monotonic count.\r
-\r
- @retval EFI_SUCCESS The update operation is success.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_WRITE_PROTECTED Variable is write-protected.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-AuthServiceInternalUpdateVariableWithMonotonicCount (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes,\r
- IN UINT32 KeyIndex,\r
- IN UINT64 MonotonicCount\r
- )\r
-{\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
-\r
- ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
- AuthVariableInfo.VariableName = VariableName;\r
- AuthVariableInfo.VendorGuid = VendorGuid;\r
- AuthVariableInfo.Data = Data;\r
- AuthVariableInfo.DataSize = DataSize;\r
- AuthVariableInfo.Attributes = Attributes;\r
- AuthVariableInfo.PubKeyIndex = KeyIndex;\r
- AuthVariableInfo.MonotonicCount = MonotonicCount;\r
-\r
- return mAuthVarLibContextIn->UpdateVariable (\r
- &AuthVariableInfo\r
- );\r
-}\r
-\r
-/**\r
- Update the variable region with Variable information.\r
-\r
- @param[in] VariableName Name of variable.\r
- @param[in] VendorGuid Guid of variable.\r
- @param[in] Data Data pointer.\r
- @param[in] DataSize Size of Data.\r
- @param[in] Attributes Attribute value of the variable.\r
- @param[in] TimeStamp Value of associated TimeStamp.\r
-\r
- @retval EFI_SUCCESS The update operation is success.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_WRITE_PROTECTED Variable is write-protected.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-AuthServiceInternalUpdateVariableWithTimeStamp (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes,\r
- IN EFI_TIME *TimeStamp\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes\r
)\r
{\r
- EFI_STATUS FindStatus;\r
- VOID *OrgData;\r
- UINTN OrgDataSize;\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
-\r
- FindStatus = AuthServiceInternalFindVariable (\r
- VariableName,\r
- VendorGuid,\r
- &OrgData,\r
- &OrgDataSize\r
- );\r
-\r
- //\r
- // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable\r
- //\r
- if (!EFI_ERROR (FindStatus) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {\r
- if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
- ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
- (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||\r
- (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {\r
- //\r
- // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of\r
- // EFI_SIGNATURE_DATA values that are already part of the existing variable value.\r
- //\r
- FilterSignatureList (\r
- OrgData,\r
- OrgDataSize,\r
- Data,\r
- &DataSize\r
- );\r
- }\r
- }\r
+ AUTH_VARIABLE_INFO AuthVariableInfo;\r
\r
ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
AuthVariableInfo.VariableName = VariableName;\r
- AuthVariableInfo.VendorGuid = VendorGuid;\r
- AuthVariableInfo.Data = Data;\r
- AuthVariableInfo.DataSize = DataSize;\r
- AuthVariableInfo.Attributes = Attributes;\r
- AuthVariableInfo.TimeStamp = TimeStamp;\r
- return mAuthVarLibContextIn->UpdateVariable (\r
- &AuthVariableInfo\r
- );\r
-}\r
-\r
-/**\r
- Initialize Secure Boot variables.\r
-\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-InitSecureBootVariables (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT32 SecureBoot;\r
- UINT8 SecureBootEnable;\r
- SECURE_BOOT_MODE_TYPE SecureBootMode;\r
- BOOLEAN IsPkPresent;\r
-\r
- //\r
- // Find "PK" variable\r
- //\r
- Status = AuthServiceInternalFindVariable (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);\r
- if (EFI_ERROR (Status)) {\r
- IsPkPresent = FALSE;\r
- DEBUG ((EFI_D_INFO, "Variable %s does not exist.\n", EFI_PLATFORM_KEY_NAME));\r
- } else {\r
- IsPkPresent = TRUE;\r
- DEBUG ((EFI_D_INFO, "Variable %s exists.\n", EFI_PLATFORM_KEY_NAME));\r
- }\r
-\r
- //\r
- // Init "SecureBootMode" variable.\r
- // Initial case\r
- // SecureBootMode doesn't exist. Init it with PK state\r
- // 3 inconsistency cases need to sync\r
- // 1.1 Add PK -> system break -> update SecureBootMode Var\r
- // 1.2 Delete PK -> system break -> update SecureBootMode Var\r
- // 1.3 Set AuditMode ->Delete PK -> system break -> Update SecureBootMode Var\r
- //\r
- Status = AuthServiceInternalFindVariable (EDKII_SECURE_BOOT_MODE_NAME, &gEdkiiSecureBootModeGuid, (VOID **)&Data, &DataSize);\r
- if (EFI_ERROR(Status)) {\r
- //\r
- // Variable driver Initial Case\r
- //\r
- if (IsPkPresent) {\r
- SecureBootMode = SecureBootModeTypeUserMode;\r
- } else {\r
- SecureBootMode = SecureBootModeTypeSetupMode;\r
- }\r
- } else {\r
- //\r
- // 3 inconsistency cases need to sync\r
- //\r
- SecureBootMode = (SECURE_BOOT_MODE_TYPE)*Data;\r
- ASSERT(SecureBootMode < SecureBootModeTypeMax);\r
-\r
- if (IsPkPresent) {\r
- //\r
- // 3.1 Add PK -> system break -> update SecureBootMode Var\r
- //\r
- if (SecureBootMode == SecureBootModeTypeSetupMode) {\r
- SecureBootMode = SecureBootModeTypeUserMode;\r
- } else if (SecureBootMode == SecureBootModeTypeAuditMode) {\r
- SecureBootMode = SecureBootModeTypeDeployedMode;\r
- }\r
- } else {\r
- //\r
- // 3.2 Delete PK -> system break -> update SecureBootMode Var\r
- // 3.3 Set AuditMode ->Delete PK -> system break -> Update SecureBootMode Var. Reinit to be SetupMode\r
- //\r
- if ((SecureBootMode == SecureBootModeTypeUserMode) || (SecureBootMode == SecureBootModeTypeDeployedMode)) {\r
- SecureBootMode = SecureBootModeTypeSetupMode;\r
- }\r
- }\r
- }\r
-\r
- if (EFI_ERROR(Status) || (SecureBootMode != (SECURE_BOOT_MODE_TYPE)*Data)) {\r
- //\r
- // Update SecureBootMode Var\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- EDKII_SECURE_BOOT_MODE_NAME,\r
- &gEdkiiSecureBootModeGuid,\r
- &SecureBootMode,\r
- sizeof (UINT8),\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Init "AuditMode"\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_AUDIT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &mSecureBootState[SecureBootMode].AuditMode,\r
- sizeof(UINT8),\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Init "DeployedMode"\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_DEPLOYED_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &mSecureBootState[SecureBootMode].DeployedMode,\r
- sizeof(UINT8),\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Init "SetupMode"\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_SETUP_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &mSecureBootState[SecureBootMode].SetupMode,\r
- sizeof(UINT8),\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // If "SecureBootEnable" variable exists, then update "SecureBoot" variable.\r
- // If "SecureBootEnable" variable is SECURE_BOOT_ENABLE and in User Mode or Deployed Mode, Set "SecureBoot" variable to SECURE_BOOT_MODE_ENABLE.\r
- // If "SecureBootEnable" variable is SECURE_BOOT_DISABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_DISABLE.\r
- //\r
- SecureBootEnable = SECURE_BOOT_DISABLE;\r
- Status = AuthServiceInternalFindVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID **)&Data, &DataSize);\r
- if (!EFI_ERROR(Status)) {\r
- if (!IsPkPresent) {\r
- //\r
- // PK is cleared in runtime. "SecureBootMode" is not updated before reboot\r
- // Delete "SecureBootMode"\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_ENABLE_NAME,\r
- &gEfiSecureBootEnableDisableGuid,\r
- &SecureBootEnable,\r
- 0,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
- } else {\r
- SecureBootEnable = *Data;\r
- }\r
- } else if ((SecureBootMode == SecureBootModeTypeUserMode) || (SecureBootMode == SecureBootModeTypeDeployedMode)) {\r
- //\r
- // "SecureBootEnable" not exist, initialize it in User Mode or Deployed Mode.\r
- //\r
- SecureBootEnable = SECURE_BOOT_ENABLE;\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_ENABLE_NAME,\r
- &gEfiSecureBootEnableDisableGuid,\r
- &SecureBootEnable,\r
- sizeof (UINT8),\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Create "SecureBoot" variable with BS+RT attribute set.\r
- //\r
- if ((SecureBootEnable == SECURE_BOOT_ENABLE) \r
- && ((SecureBootMode == SecureBootModeTypeUserMode) || (SecureBootMode == SecureBootModeTypeDeployedMode))) {\r
- SecureBoot = SECURE_BOOT_MODE_ENABLE;\r
- } else {\r
- SecureBoot = SECURE_BOOT_MODE_DISABLE;\r
- }\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SecureBoot,\r
- sizeof (UINT8),\r
- EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
-\r
- DEBUG ((EFI_D_INFO, "SecureBootMode is %x\n", SecureBootMode));\r
- DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_SECURE_BOOT_MODE_NAME, SecureBoot));\r
- DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_SECURE_BOOT_ENABLE_NAME, SecureBootEnable));\r
-\r
- //\r
- // Save SecureBootMode in global space\r
- //\r
- mSecureBootMode = SecureBootMode;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Update SecureBootMode variable.\r
-\r
- @param[in] NewMode New Secure Boot Mode.\r
-\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateSecureBootMode(\r
- IN SECURE_BOOT_MODE_TYPE NewMode\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Update "SecureBootMode" variable to new Secure Boot Mode\r
- //\r
- Status = AuthServiceInternalUpdateVariable (\r
- EDKII_SECURE_BOOT_MODE_NAME,\r
- &gEdkiiSecureBootModeGuid,\r
- &NewMode,\r
- sizeof (UINT8),\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
- );\r
-\r
- if (!EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_INFO, "SecureBootMode Update to %x\n", NewMode));\r
- mSecureBootMode = NewMode;\r
- } else {\r
- DEBUG((EFI_D_ERROR, "SecureBootMode Update failure %x\n", Status));\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Current secure boot mode is AuditMode. This function performs secure boot mode transition\r
- to a new mode.\r
-\r
- @param[in] NewMode New Secure Boot Mode.\r
-\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromAuditMode(\r
- IN SECURE_BOOT_MODE_TYPE NewMode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *AuditVarData;\r
- UINT8 *DeployedVarData;\r
- UINT8 *SetupVarData;\r
- UINT8 *SecureBootVarData;\r
- UINT8 SecureBootEnable;\r
- UINTN DataSize;\r
-\r
- //\r
- // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
- // they can be RW. but can't be deleted. so they can always be found.\r
- //\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_AUDIT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &AuditVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_DEPLOYED_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &DeployedVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SETUP_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SetupVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SECURE_BOOT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SecureBootVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- //\r
- // Make Secure Boot Mode transition ATOMIC\r
- // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow.\r
- // other tranisition logic are all memory operations.\r
- //\r
- Status = UpdateSecureBootMode(NewMode);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
- }\r
-\r
- if (NewMode == SecureBootModeTypeDeployedMode) {\r
- //\r
- // Since PK is enrolled, can't rollback, always update SecureBootMode in memory\r
- //\r
- mSecureBootMode = NewMode;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // AuditMode ----> DeployedMode\r
- // Side Effects\r
- // AuditMode =: 0 / DeployedMode := 1 / SetupMode := 0\r
- //\r
- // Update the value of AuditMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (AuditVarData, &mSecureBootState[NewMode].AuditMode, sizeof(UINT8));\r
- //\r
- // Update the value of DeployedMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
- //\r
- // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
- if (mAuthVarLibContextIn->AtRuntime ()) {\r
- //\r
- // SecureBoot Variable indicates whether the platform firmware is operating\r
- // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
- // Variable in runtime.\r
- //\r
- return Status;\r
- }\r
-\r
- //\r
- // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
- //\r
- // Create "SecureBootEnable" variable as secure boot is enabled.\r
- //\r
- SecureBootEnable = SECURE_BOOT_ENABLE;\r
- AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_ENABLE_NAME,\r
- &gEfiSecureBootEnableDisableGuid,\r
- &SecureBootEnable,\r
- sizeof (SecureBootEnable),\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
- } else {\r
- DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeAuditMode, NewMode));\r
- ASSERT(FALSE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Current secure boot mode is DeployedMode. This function performs secure boot mode transition\r
- to a new mode.\r
-\r
- @param[in] NewMode New Secure Boot Mode.\r
-\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromDeployedMode(\r
- IN SECURE_BOOT_MODE_TYPE NewMode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *DeployedVarData;\r
- UINT8 *SetupVarData;\r
- UINT8 *SecureBootVarData;\r
- UINT8 SecureBootEnable;\r
- UINTN DataSize;\r
-\r
- //\r
- // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
- // they can be RW. but can't be deleted. so they can always be found.\r
- //\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_DEPLOYED_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &DeployedVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SETUP_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SetupVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SECURE_BOOT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SecureBootVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- //\r
- // Make Secure Boot Mode transition ATOMIC\r
- // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow.\r
- // other tranisition logic are all memory operations.\r
- //\r
- Status = UpdateSecureBootMode(NewMode);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
- }\r
-\r
- switch(NewMode) {\r
- case SecureBootModeTypeUserMode:\r
- //\r
- // DeployedMode ----> UserMode\r
- // Side Effects\r
- // DeployedMode := 0\r
- //\r
- // Platform Specific DeployedMode clear. UpdateSecureBootMode fails and no other variables are updated before. rollback this transition\r
- //\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
-\r
- break;\r
-\r
- case SecureBootModeTypeSetupMode:\r
- //\r
- // Since PK is processed before, can't rollback, still update SecureBootMode in memory\r
- //\r
- mSecureBootMode = NewMode;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // DeployedMode ----> SetupMode\r
- //\r
- // Platform Specific PKpub clear or Delete Pkpub\r
- // Side Effects\r
- // DeployedMode := 0 / SetupMode := 1 / SecureBoot := 0\r
- //\r
- // Update the value of DeployedMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
- //\r
- // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
- if (mAuthVarLibContextIn->AtRuntime ()) {\r
- //\r
- // SecureBoot Variable indicates whether the platform firmware is operating\r
- // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
- // Variable in runtime.\r
- //\r
- return Status;\r
- }\r
-\r
- //\r
- // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
- //\r
- // Delete the "SecureBootEnable" variable as secure boot is Disabled.\r
- //\r
- SecureBootEnable = SECURE_BOOT_DISABLE;\r
- AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_ENABLE_NAME,\r
- &gEfiSecureBootEnableDisableGuid,\r
- &SecureBootEnable,\r
- 0,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
- break;\r
-\r
- default:\r
- DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeDeployedMode, NewMode));\r
- ASSERT(FALSE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Current secure boot mode is UserMode. This function performs secure boot mode transition\r
- to a new mode.\r
-\r
- @param[in] NewMode New Secure Boot Mode.\r
-\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromUserMode(\r
- IN SECURE_BOOT_MODE_TYPE NewMode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *AuditVarData;\r
- UINT8 *DeployedVarData;\r
- UINT8 *SetupVarData;\r
- UINT8 *PkVarData;\r
- UINT8 *SecureBootVarData;\r
- UINT8 SecureBootEnable;\r
- UINTN DataSize;\r
- VARIABLE_ENTRY_CONSISTENCY VariableEntry;\r
-\r
- //\r
- // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
- // they can be RW. but can't be deleted. so they can always be found.\r
- //\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_AUDIT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &AuditVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_DEPLOYED_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &DeployedVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SETUP_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SetupVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SECURE_BOOT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SecureBootVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- //\r
- // Make Secure Boot Mode transition ATOMIC\r
- // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow. \r
- // Other tranisition logic are all memory operations and PK delete is assumed to be always successful.\r
- //\r
- if (NewMode != SecureBootModeTypeAuditMode) {\r
- Status = UpdateSecureBootMode(NewMode);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
- }\r
- } else {\r
- //\r
- // UserMode -----> AuditMode. Check RemainingSpace for SecureBootMode var first.\r
- // Will update SecureBootMode after DeletePK logic\r
- //\r
- VariableEntry.VariableSize = sizeof(UINT8);\r
- VariableEntry.Guid = &gEdkiiSecureBootModeGuid;\r
- VariableEntry.Name = EDKII_SECURE_BOOT_MODE_NAME;\r
- if (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry, NULL)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- switch(NewMode) {\r
- case SecureBootModeTypeDeployedMode:\r
- //\r
- // UpdateSecureBootMode fails and no other variables are updated before. rollback this transition\r
- //\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // UserMode ----> DeployedMode\r
- // Side Effects\r
- // DeployedMode := 1\r
- //\r
- CopyMem (DeployedVarData, &mSecureBootState[NewMode].DeployedMode, sizeof(UINT8));\r
- break;\r
-\r
- case SecureBootModeTypeAuditMode:\r
- //\r
- // UserMode ----> AuditMode\r
- // Side Effects\r
- // Delete PKpub / SetupMode := 1 / SecureBoot := 0\r
- //\r
- // Delete PKpub without verification. Should always succeed.\r
- //\r
- PkVarData = NULL;\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_PLATFORM_KEY_NAME,\r
- &gEfiGlobalVariableGuid,\r
- PkVarData,\r
- 0,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
- );\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "UserMode -> AuditMode. Delete PK fail %x\n", Status));\r
- ASSERT(FALSE);\r
- }\r
-\r
- //\r
- // Update Private NV SecureBootMode Variable\r
- //\r
- Status = UpdateSecureBootMode(NewMode);\r
- if (EFI_ERROR(Status)) {\r
- //\r
- // Since PK is deleted successfully, Doesn't break, continue to update other variable.\r
- //\r
- DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
- }\r
- CopyMem (AuditVarData, &mSecureBootState[NewMode].AuditMode, sizeof(UINT8));\r
-\r
- //\r
- // Fall into SetupMode logic\r
- //\r
- case SecureBootModeTypeSetupMode:\r
- //\r
- // Since PK is deleted before , can't rollback, still update SecureBootMode in memory\r
- //\r
- mSecureBootMode = NewMode;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // UserMode ----> SetupMode\r
- // Side Effects\r
- // DeployedMode :=0 / SetupMode :=1 / SecureBoot :=0\r
- //\r
- // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
- if (mAuthVarLibContextIn->AtRuntime ()) {\r
- //\r
- // SecureBoot Variable indicates whether the platform firmware is operating\r
- // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
- // Variable in runtime.\r
- //\r
- return Status;\r
- }\r
-\r
- //\r
- // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
- //\r
- // Delete the "SecureBootEnable" variable as secure boot is Disabled.\r
- //\r
- SecureBootEnable = SECURE_BOOT_DISABLE;\r
- AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_ENABLE_NAME,\r
- &gEfiSecureBootEnableDisableGuid,\r
- &SecureBootEnable,\r
- 0,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
-\r
- break;\r
-\r
- default:\r
- DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeUserMode, NewMode));\r
- ASSERT(FALSE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Current secure boot mode is SetupMode. This function performs secure boot mode transition\r
- to a new mode.\r
-\r
- @param[in] NewMode New Secure Boot Mode.\r
-\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-\r
-**/\r
-EFI_STATUS\r
-TransitionFromSetupMode(\r
- IN SECURE_BOOT_MODE_TYPE NewMode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *AuditVarData;\r
- UINT8 *SetupVarData;\r
- UINT8 *SecureBootVarData;\r
- UINT8 SecureBootEnable;\r
- UINTN DataSize;\r
-\r
- //\r
- // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
- // they can be RW. but can't be deleted. so they can always be found.\r
- //\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_AUDIT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &AuditVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SETUP_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SetupVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- Status = AuthServiceInternalFindVariable (\r
- EFI_SECURE_BOOT_MODE_NAME,\r
- &gEfiGlobalVariableGuid,\r
- &SecureBootVarData,\r
- &DataSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- //\r
- // Make Secure Boot Mode transition ATOMIC\r
- // Update Private NV SecureBootMode Variable first, because it may fail due to NV range overflow.\r
- // Other tranisition logic are all memory operations and PK delete is assumed to be always successful.\r
- //\r
- Status = UpdateSecureBootMode(NewMode);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "Update SecureBootMode Variable fail %x\n", Status));\r
- }\r
-\r
- switch(NewMode) {\r
- case SecureBootModeTypeAuditMode:\r
- //\r
- // UpdateSecureBootMode fails and no other variables are updated before. rollback this transition\r
- //\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // SetupMode ----> AuditMode\r
- // Side Effects\r
- // AuditMode := 1\r
- //\r
- // Update the value of AuditMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (AuditVarData, &mSecureBootState[NewMode].AuditMode, sizeof(UINT8));\r
- break;\r
-\r
- case SecureBootModeTypeUserMode:\r
- //\r
- // Since PK is enrolled before, can't rollback, still update SecureBootMode in memory\r
- //\r
- mSecureBootMode = NewMode;\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // SetupMode ----> UserMode\r
- // Side Effects\r
- // SetupMode := 0 / SecureBoot := 1\r
- //\r
- // Update the value of AuditMode variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SetupVarData, &mSecureBootState[NewMode].SetupMode, sizeof(UINT8));\r
-\r
- if (mAuthVarLibContextIn->AtRuntime ()) {\r
- //\r
- // SecureBoot Variable indicates whether the platform firmware is operating\r
- // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
- // Variable in runtime.\r
- //\r
- return Status;\r
- }\r
-\r
- //\r
- // Update the value of SecureBoot variable by a simple mem copy, this could avoid possible\r
- // variable storage reclaim at runtime.\r
- //\r
- CopyMem (SecureBootVarData, &mSecureBootState[NewMode].SecureBoot, sizeof(UINT8));\r
-\r
- //\r
- // Create the "SecureBootEnable" variable as secure boot is enabled.\r
- //\r
- SecureBootEnable = SECURE_BOOT_ENABLE;\r
- AuthServiceInternalUpdateVariable (\r
- EFI_SECURE_BOOT_ENABLE_NAME,\r
- &gEfiSecureBootEnableDisableGuid,\r
- &SecureBootEnable,\r
- sizeof (SecureBootEnable),\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
- );\r
- break;\r
-\r
- default:\r
- DEBUG((EFI_D_ERROR, "Invalid state tranition from %x to %x\n", SecureBootModeTypeSetupMode, NewMode));\r
- ASSERT(FALSE);\r
- }\r
+ AuthVariableInfo.VendorGuid = VendorGuid;\r
+ AuthVariableInfo.Data = Data;\r
+ AuthVariableInfo.DataSize = DataSize;\r
+ AuthVariableInfo.Attributes = Attributes;\r
\r
- return Status;\r
+ return mAuthVarLibContextIn->UpdateVariable (\r
+ &AuthVariableInfo\r
+ );\r
}\r
\r
/**\r
- This function performs main secure boot mode transition logic.\r
+ Update the variable region with Variable information.\r
\r
- @param[in] CurMode Current Secure Boot Mode.\r
- @param[in] NewMode New Secure Boot Mode.\r
+ @param[in] VariableName Name of variable.\r
+ @param[in] VendorGuid Guid of variable.\r
+ @param[in] Data Data pointer.\r
+ @param[in] DataSize Size of Data.\r
+ @param[in] Attributes Attribute value of the variable.\r
+ @param[in] TimeStamp Value of associated TimeStamp.\r
\r
- @retval EFI_SUCCESS The initialization operation is successful.\r
+ @retval EFI_SUCCESS The update operation is success.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_WRITE_PROTECTED Variable is write-protected.\r
@retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
- @retval EFI_INVALID_PARAMETER The Current Secure Boot Mode is wrong.\r
\r
**/\r
EFI_STATUS\r
-SecureBootModeTransition(\r
- IN SECURE_BOOT_MODE_TYPE CurMode,\r
- IN SECURE_BOOT_MODE_TYPE NewMode\r
+AuthServiceInternalUpdateVariableWithTimeStamp (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes,\r
+ IN EFI_TIME *TimeStamp\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS FindStatus;\r
+ VOID *OrgData;\r
+ UINTN OrgDataSize;\r
+ AUTH_VARIABLE_INFO AuthVariableInfo;\r
+\r
+ FindStatus = AuthServiceInternalFindVariable (\r
+ VariableName,\r
+ VendorGuid,\r
+ &OrgData,\r
+ &OrgDataSize\r
+ );\r
\r
//\r
- // SecureBootMode transition\r
+ // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable\r
//\r
- switch (CurMode) {\r
- case SecureBootModeTypeUserMode:\r
- Status = TransitionFromUserMode(NewMode);\r
- break;\r
-\r
- case SecureBootModeTypeSetupMode:\r
- Status = TransitionFromSetupMode(NewMode);\r
- break;\r
-\r
- case SecureBootModeTypeAuditMode:\r
- Status = TransitionFromAuditMode(NewMode);\r
- break;\r
-\r
- case SecureBootModeTypeDeployedMode:\r
- Status = TransitionFromDeployedMode(NewMode);\r
- break;\r
-\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
- ASSERT(FALSE);\r
+ if (!EFI_ERROR (FindStatus) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0)) {\r
+ if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
+ ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
+ (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))) ||\r
+ (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)))\r
+ {\r
+ //\r
+ // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of\r
+ // EFI_SIGNATURE_DATA values that are already part of the existing variable value.\r
+ //\r
+ FilterSignatureList (\r
+ OrgData,\r
+ OrgDataSize,\r
+ Data,\r
+ &DataSize\r
+ );\r
+ }\r
}\r
\r
- return Status;\r
-\r
+ ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
+ AuthVariableInfo.VariableName = VariableName;\r
+ AuthVariableInfo.VendorGuid = VendorGuid;\r
+ AuthVariableInfo.Data = Data;\r
+ AuthVariableInfo.DataSize = DataSize;\r
+ AuthVariableInfo.Attributes = Attributes;\r
+ AuthVariableInfo.TimeStamp = TimeStamp;\r
+ return mAuthVarLibContextIn->UpdateVariable (\r
+ &AuthVariableInfo\r
+ );\r
}\r
\r
/**\r
\r
**/\r
BOOLEAN\r
-NeedPhysicallyPresent(\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid\r
+NeedPhysicallyPresent (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid\r
)\r
{\r
- if ((CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))\r
- || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0))) {\r
- return TRUE;\r
+ // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.\r
+ if (IsVariablePolicyEnabled ()) {\r
+ if ( (CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) == 0))\r
+ || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (VariableName, EFI_CUSTOM_MODE_NAME) == 0)))\r
+ {\r
+ return TRUE;\r
+ }\r
}\r
\r
return FALSE;\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
- VOID *Data;\r
- UINTN DataSize;\r
+ EFI_STATUS Status;\r
+ VOID *Data;\r
+ UINTN DataSize;\r
\r
Status = AuthServiceInternalFindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Data, &DataSize);\r
- if (!EFI_ERROR (Status) && (*(UINT8 *) Data == CUSTOM_SECURE_BOOT_MODE)) {\r
+ if (!EFI_ERROR (Status) && (*(UINT8 *)Data == CUSTOM_SECURE_BOOT_MODE)) {\r
return TRUE;\r
}\r
\r
}\r
\r
/**\r
- Get available public key index.\r
+ Update platform mode.\r
\r
- @param[in] PubKey Pointer to Public Key data.\r
+ @param[in] Mode SETUP_MODE or USER_MODE.\r
\r
- @return Public key index, 0 if no any public key index available.\r
+ @return EFI_INVALID_PARAMETER Invalid parameter.\r
+ @return EFI_SUCCESS Update platform mode successfully.\r
\r
**/\r
-UINT32\r
-GetAvailableKeyIndex (\r
- IN UINT8 *PubKey\r
+EFI_STATUS\r
+UpdatePlatformMode (\r
+ IN UINT32 Mode\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT8 *Ptr;\r
- UINT32 Index;\r
- BOOLEAN IsFound;\r
- EFI_GUID VendorGuid;\r
- CHAR16 Name[1];\r
- AUTH_VARIABLE_INFO AuthVariableInfo;\r
- UINT32 KeyIndex;\r
+ EFI_STATUS Status;\r
+ VOID *Data;\r
+ UINTN DataSize;\r
+ UINT8 SecureBootMode;\r
+ UINT8 SecureBootEnable;\r
+ UINTN VariableDataSize;\r
\r
Status = AuthServiceInternalFindVariable (\r
- AUTHVAR_KEYDB_NAME,\r
- &gEfiAuthenticatedVariableGuid,\r
- (VOID **) &Data,\r
+ EFI_SETUP_MODE_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ &Data,\r
&DataSize\r
);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status));\r
- return 0;\r
- }\r
-\r
- if (mPubKeyNumber == mMaxKeyNumber) {\r
- Name[0] = 0;\r
- AuthVariableInfo.VariableName = Name;\r
- ZeroMem (&VendorGuid, sizeof (VendorGuid));\r
- AuthVariableInfo.VendorGuid = &VendorGuid;\r
- mPubKeyNumber = 0;\r
- //\r
- // Collect valid key data.\r
- //\r
- do {\r
- Status = mAuthVarLibContextIn->FindNextVariable (AuthVariableInfo.VariableName, AuthVariableInfo.VendorGuid, &AuthVariableInfo);\r
- if (!EFI_ERROR (Status)) {\r
- if (AuthVariableInfo.PubKeyIndex != 0) {\r
- for (Ptr = Data; Ptr < (Data + DataSize); Ptr += sizeof (AUTHVAR_KEY_DB_DATA)) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) Ptr)->KeyIndex)) == AuthVariableInfo.PubKeyIndex) {\r
- //\r
- // Check if the key data has been collected.\r
- //\r
- for (Index = 0; Index < mPubKeyNumber; Index++) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex)) == AuthVariableInfo.PubKeyIndex) {\r
- break;\r
- }\r
- }\r
- if (Index == mPubKeyNumber) {\r
- //\r
- // New key data.\r
- //\r
- CopyMem ((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber, Ptr, sizeof (AUTHVAR_KEY_DB_DATA));\r
- mPubKeyNumber++;\r
- }\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- } while (Status != EFI_NOT_FOUND);\r
-\r
- //\r
- // No available space to add new public key.\r
- //\r
- if (mPubKeyNumber == mMaxKeyNumber) {\r
- return 0;\r
- }\r
+ return Status;\r
}\r
\r
//\r
- // Find available public key index.\r
+ // Update the value of SetupMode variable by a simple mem copy, this could avoid possible\r
+ // variable storage reclaim at runtime.\r
//\r
- for (KeyIndex = 1; KeyIndex <= mMaxKeyNumber; KeyIndex++) {\r
- IsFound = FALSE;\r
- for (Ptr = mPubKeyStore; Ptr < (mPubKeyStore + mPubKeyNumber * sizeof (AUTHVAR_KEY_DB_DATA)); Ptr += sizeof (AUTHVAR_KEY_DB_DATA)) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) Ptr)->KeyIndex)) == KeyIndex) {\r
- IsFound = TRUE;\r
- break;\r
- }\r
- }\r
- if (!IsFound) {\r
- break;\r
- }\r
- }\r
-\r
- return KeyIndex;\r
-}\r
-\r
-/**\r
- Add public key in store and return its index.\r
-\r
- @param[in] PubKey Input pointer to Public Key data.\r
- @param[in] VariableDataEntry The variable data entry.\r
-\r
- @return Index of new added public key.\r
-\r
-**/\r
-UINT32\r
-AddPubKeyInStore (\r
- IN UINT8 *PubKey,\r
- IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry;\r
- UINT32 Attributes;\r
- UINT32 KeyIndex;\r
+ mPlatformMode = (UINT8)Mode;\r
+ CopyMem (Data, &mPlatformMode, sizeof (UINT8));\r
\r
- if (PubKey == NULL) {\r
- return 0;\r
+ if (mAuthVarLibContextIn->AtRuntime ()) {\r
+ //\r
+ // SecureBoot Variable indicates whether the platform firmware is operating\r
+ // in Secure boot mode (1) or not (0), so we should not change SecureBoot\r
+ // Variable in runtime.\r
+ //\r
+ return Status;\r
}\r
\r
//\r
- // Check whether the public key entry does exist.\r
+ // Check "SecureBoot" variable's existence.\r
+ // If it doesn't exist, firmware has no capability to perform driver signing verification,\r
+ // then set "SecureBoot" to 0.\r
//\r
- for (Index = 0; Index < mPubKeyNumber; Index++) {\r
- if (CompareMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
- return ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex));\r
- }\r
- }\r
-\r
- KeyIndex = GetAvailableKeyIndex (PubKey);\r
- if (KeyIndex == 0) {\r
- return 0;\r
- }\r
-\r
+ Status = AuthServiceInternalFindVariable (\r
+ EFI_SECURE_BOOT_MODE_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ &Data,\r
+ &DataSize\r
+ );\r
//\r
- // Check the variable space for both public key and variable data.\r
+ // If "SecureBoot" variable exists, then check "SetupMode" variable update.\r
+ // If "SetupMode" variable is USER_MODE, "SecureBoot" variable is set to 1.\r
+ // If "SetupMode" variable is SETUP_MODE, "SecureBoot" variable is set to 0.\r
//\r
- PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * sizeof (AUTHVAR_KEY_DB_DATA);\r
- PublicKeyEntry.Guid = &gEfiAuthenticatedVariableGuid;\r
- PublicKeyEntry.Name = AUTHVAR_KEYDB_NAME;\r
- Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;\r
-\r
- if (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {\r
- //\r
- // No enough variable space.\r
- //\r
- return 0;\r
+ if (EFI_ERROR (Status)) {\r
+ SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
+ } else {\r
+ if (mPlatformMode == USER_MODE) {\r
+ SecureBootMode = SECURE_BOOT_MODE_ENABLE;\r
+ } else if (mPlatformMode == SETUP_MODE) {\r
+ SecureBootMode = SECURE_BOOT_MODE_DISABLE;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
}\r
\r
- WriteUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber)->KeyIndex), KeyIndex);\r
- CopyMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + mPubKeyNumber)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
- mPubKeyNumber++;\r
-\r
- //\r
- // Update public key database variable.\r
- //\r
Status = AuthServiceInternalUpdateVariable (\r
- AUTHVAR_KEYDB_NAME,\r
- &gEfiAuthenticatedVariableGuid,\r
- mPubKeyStore,\r
- mPubKeyNumber * sizeof (AUTHVAR_KEY_DB_DATA),\r
- Attributes\r
+ EFI_SECURE_BOOT_MODE_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ &SecureBootMode,\r
+ sizeof (UINT8),\r
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Update public key database variable failure, Status = %r\n", Status));\r
- return 0;\r
- }\r
-\r
- return KeyIndex;\r
-}\r
-\r
-/**\r
- Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256_GUID type.\r
- Follow the steps in UEFI2.2.\r
-\r
- Caution: This function may receive untrusted input.\r
- This function may be invoked in SMM mode, and datasize and data are external input.\r
- This function will do basic validation, before parse the data.\r
- This function will parse the authentication carefully to avoid security issues, like\r
- buffer overflow, integer overflow.\r
-\r
- @param[in] Data Pointer to data with AuthInfo.\r
- @param[in] DataSize Size of Data.\r
- @param[in] PubKey Public key used for verification.\r
-\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_SECURITY_VIOLATION If authentication failed.\r
- @retval EFI_SUCCESS Authentication successful.\r
-\r
-**/\r
-EFI_STATUS\r
-VerifyCounterBasedPayload (\r
- IN UINT8 *Data,\r
- IN UINTN DataSize,\r
- IN UINT8 *PubKey\r
- )\r
-{\r
- BOOLEAN Status;\r
- EFI_VARIABLE_AUTHENTICATION *CertData;\r
- EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;\r
- UINT8 Digest[SHA256_DIGEST_SIZE];\r
- VOID *Rsa;\r
- UINTN PayloadSize;\r
-\r
- PayloadSize = DataSize - AUTHINFO_SIZE;\r
- Rsa = NULL;\r
- CertData = NULL;\r
- CertBlock = NULL;\r
-\r
- if (Data == NULL || PubKey == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
+ return Status;\r
}\r
\r
- CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
- CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
-\r
//\r
- // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.\r
- // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256_GUID.\r
- //\r
- if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
- !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
- //\r
- // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- //\r
- // Hash data payload with SHA256.\r
- //\r
- ZeroMem (Digest, SHA256_DIGEST_SIZE);\r
- Status = Sha256Init (mHashCtx);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = Sha256Update (mHashCtx, Data + AUTHINFO_SIZE, PayloadSize);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Hash Size.\r
- //\r
- Status = Sha256Update (mHashCtx, &PayloadSize, sizeof (UINTN));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Hash Monotonic Count.\r
+ // Check "SecureBootEnable" variable's existence. It can enable/disable secure boot feature.\r
//\r
- Status = Sha256Update (mHashCtx, &CertData->MonotonicCount, sizeof (UINT64));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = Sha256Final (mHashCtx, Digest);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Generate & Initialize RSA Context.\r
- //\r
- Rsa = RsaNew ();\r
- ASSERT (Rsa != NULL);\r
- //\r
- // Set RSA Key Components.\r
- // NOTE: Only N and E are needed to be set as RSA public key for signature verification.\r
- //\r
- Status = RsaSetKey (Rsa, RsaKeyN, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
- if (!Status) {\r
- goto Done;\r
- }\r
- Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));\r
- if (!Status) {\r
- goto Done;\r
- }\r
- //\r
- // Verify the signature.\r
- //\r
- Status = RsaPkcs1Verify (\r
- Rsa,\r
- Digest,\r
- SHA256_DIGEST_SIZE,\r
- CertBlock->Signature,\r
- EFI_CERT_TYPE_RSA2048_SHA256_SIZE\r
+ Status = AuthServiceInternalFindVariable (\r
+ EFI_SECURE_BOOT_ENABLE_NAME,\r
+ &gEfiSecureBootEnableDisableGuid,\r
+ &Data,\r
+ &DataSize\r
);\r
\r
-Done:\r
- if (Rsa != NULL) {\r
- RsaFree (Rsa);\r
- }\r
- if (Status) {\r
- return EFI_SUCCESS;\r
+ if (SecureBootMode == SECURE_BOOT_MODE_ENABLE) {\r
+ //\r
+ // Create the "SecureBootEnable" variable as secure boot is enabled.\r
+ //\r
+ SecureBootEnable = SECURE_BOOT_ENABLE;\r
+ VariableDataSize = sizeof (SecureBootEnable);\r
} else {\r
- return EFI_SECURITY_VIOLATION;\r
+ //\r
+ // Delete the "SecureBootEnable" variable if this variable exist as "SecureBoot"\r
+ // variable is not in secure boot state.\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ SecureBootEnable = SECURE_BOOT_DISABLE;\r
+ VariableDataSize = 0;\r
}\r
-}\r
\r
+ Status = AuthServiceInternalUpdateVariable (\r
+ EFI_SECURE_BOOT_ENABLE_NAME,\r
+ &gEfiSecureBootEnableDisableGuid,\r
+ &SecureBootEnable,\r
+ VariableDataSize,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS\r
+ );\r
+ return Status;\r
+}\r
\r
/**\r
Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK/db/dbx/dbt variable.\r
\r
**/\r
EFI_STATUS\r
-CheckSignatureListFormat(\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize\r
+CheckSignatureListFormat (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize\r
)\r
{\r
- EFI_SIGNATURE_LIST *SigList;\r
- UINTN SigDataSize;\r
- UINT32 Index;\r
- UINT32 SigCount;\r
- BOOLEAN IsPk;\r
- VOID *RsaContext;\r
- EFI_SIGNATURE_DATA *CertData;\r
- UINTN CertLen;\r
+ EFI_SIGNATURE_LIST *SigList;\r
+ UINTN SigDataSize;\r
+ UINT32 Index;\r
+ UINT32 SigCount;\r
+ BOOLEAN IsPk;\r
+ VOID *RsaContext;\r
+ EFI_SIGNATURE_DATA *CertData;\r
+ UINTN CertLen;\r
\r
if (DataSize == 0) {\r
return EFI_SUCCESS;\r
\r
ASSERT (VariableName != NULL && VendorGuid != NULL && Data != NULL);\r
\r
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)){\r
+ if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)) {\r
IsPk = TRUE;\r
} else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) ||\r
(CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&\r
- ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
- (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0)))) {\r
+ ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) ||\r
+ (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0))))\r
+ {\r
IsPk = FALSE;\r
} else {\r
return EFI_SUCCESS;\r
}\r
\r
- SigCount = 0;\r
- SigList = (EFI_SIGNATURE_LIST *) Data;\r
- SigDataSize = DataSize;\r
- RsaContext = NULL;\r
+ SigCount = 0;\r
+ SigList = (EFI_SIGNATURE_LIST *)Data;\r
+ SigDataSize = DataSize;\r
+ RsaContext = NULL;\r
\r
//\r
- // Walk throuth the input signature list and check the data format.\r
+ // Walk through the input signature list and check the data format.\r
// If any signature is incorrectly formed, the whole check will fail.\r
//\r
while ((SigDataSize > 0) && (SigDataSize >= SigList->SignatureListSize)) {\r
// The value of SignatureSize should always be 16 (size of SignatureOwner\r
// component) add the data length according to signature type.\r
//\r
- if (mSupportSigItem[Index].SigDataSize != ((UINT32) ~0) &&\r
- (SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize) {\r
+ if ((mSupportSigItem[Index].SigDataSize != ((UINT32) ~0)) &&\r
+ ((SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (mSupportSigItem[Index].SigHeaderSize != ((UINT32) ~0) &&\r
- SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize) {\r
+\r
+ if ((mSupportSigItem[Index].SigHeaderSize != ((UINT32) ~0)) &&\r
+ (SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
break;\r
}\r
}\r
if (RsaContext == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);\r
- CertLen = SigList->SignatureSize - sizeof (EFI_GUID);\r
+\r
+ CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);\r
+ CertLen = SigList->SignatureSize - sizeof (EFI_GUID);\r
if (!RsaGetPublicKeyFromX509 (CertData->SignatureData, CertLen, &RsaContext)) {\r
RsaFree (RsaContext);\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
RsaFree (RsaContext);\r
}\r
\r
if ((SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) % SigList->SignatureSize != 0) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
SigCount += (SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) / SigList->SignatureSize;\r
\r
SigDataSize -= SigList->SignatureListSize;\r
- SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);\r
+ SigList = (EFI_SIGNATURE_LIST *)((UINT8 *)SigList + SigList->SignatureListSize);\r
}\r
\r
- if (((UINTN) SigList - (UINTN) Data) != DataSize) {\r
+ if (((UINTN)SigList - (UINTN)Data) != DataSize) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (IsPk && SigCount > 1) {\r
+ if (IsPk && (SigCount > 1)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
if (mVendorKeyState == VENDOR_KEYS_MODIFIED) {\r
return EFI_SUCCESS;\r
}\r
+\r
mVendorKeyState = VENDOR_KEYS_MODIFIED;\r
\r
Status = AuthServiceInternalUpdateVariable (\r
);\r
}\r
\r
-/**\r
- Process Secure Boot Mode variable.\r
-\r
- Caution: This function may receive untrusted input.\r
- This function may be invoked in SMM mode, and datasize and data are external input.\r
- This function will do basic validation, before parse the data.\r
- This function will parse the authentication carefully to avoid security issues, like\r
- buffer overflow, integer overflow.\r
- This function will check attribute carefully to avoid authentication bypass.\r
-\r
- @param[in] VariableName Name of Variable to be found.\r
- @param[in] VendorGuid Variable vendor GUID.\r
- @param[in] Data Data pointer.\r
- @param[in] DataSize Size of Data found. If size is less than the\r
- data, this value contains the required size.\r
- @param[in] Attributes Attribute value of the variable\r
-\r
- @return EFI_INVALID_PARAMETER Invalid parameter\r
- @return EFI_SECURITY_VIOLATION The variable does NOT pass the validation\r
- check carried out by the firmware.\r
- @return EFI_WRITE_PROTECTED Variable is Read-Only.\r
- @return EFI_SUCCESS Variable passed validation successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-ProcessSecureBootModeVar (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *VarData;\r
- UINTN VarDataSize;\r
-\r
- //\r
- // Check "AuditMode", "DeployedMode" Variable ReadWrite Attributes\r
- // if in Runtime, Always RO\r
- // if in Boottime, Depends on current Secure Boot Mode\r
- //\r
- if (mAuthVarLibContextIn->AtRuntime()) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
- //\r
- // Delete not OK\r
- //\r
- if ((DataSize != sizeof(UINT8)) || (Attributes == 0)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (StrCmp (VariableName, EFI_AUDIT_MODE_NAME) == 0) {\r
- if(mSecureBootState[mSecureBootMode].IsAuditModeRO) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
- } else {\r
- //\r
- // Platform specific deployedMode clear. Set DeployedMode = RW\r
- //\r
- if (!InCustomMode() || !UserPhysicalPresent() || mSecureBootMode != SecureBootModeTypeDeployedMode) {\r
- if(mSecureBootState[mSecureBootMode].IsDeployedModeRO) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
- }\r
- }\r
-\r
- if (*(UINT8 *)Data != 0 && *(UINT8 *)Data != 1) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // AuditMode/DeployedMode/SetupMode/SecureBoot are all NON_NV variable maintained by Variable driver\r
- // they can be RW. but can't be deleted. so they can always be found.\r
- //\r
- Status = AuthServiceInternalFindVariable (\r
- VariableName,\r
- VendorGuid,\r
- &VarData,\r
- &VarDataSize\r
- );\r
- if (EFI_ERROR(Status)) {\r
- ASSERT(FALSE);\r
- }\r
-\r
- //\r
- // If AuditMode/DeployedMode is assigned same value. Simply return EFI_SUCCESS\r
- //\r
- if (*VarData == *(UINT8 *)Data) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Perform SecureBootMode transition\r
- //\r
- if (StrCmp (VariableName, EFI_AUDIT_MODE_NAME) == 0) {\r
- DEBUG((EFI_D_INFO, "Current SecureBootMode %x Transfer to SecureBootMode %x\n", mSecureBootMode, SecureBootModeTypeAuditMode));\r
- return SecureBootModeTransition(mSecureBootMode, SecureBootModeTypeAuditMode);\r
- } else if (StrCmp (VariableName, EFI_DEPLOYED_MODE_NAME) == 0) {\r
- if (mSecureBootMode == SecureBootModeTypeDeployedMode) {\r
- //\r
- // Platform specific DeployedMode clear. InCustomMode() && UserPhysicalPresent() is checked before\r
- //\r
- DEBUG((EFI_D_INFO, "Current SecureBootMode %x. Transfer to SecureBootMode %x\n", mSecureBootMode, SecureBootModeTypeUserMode));\r
- return SecureBootModeTransition(mSecureBootMode, SecureBootModeTypeUserMode);\r
- } else {\r
- DEBUG((EFI_D_INFO, "Current SecureBootMode %x. Transfer to SecureBootMode %x\n", mSecureBootMode, SecureBootModeTypeDeployedMode));\r
- return SecureBootModeTransition(mSecureBootMode, SecureBootModeTypeDeployedMode);\r
- }\r
- }\r
-\r
- return EFI_INVALID_PARAMETER;\r
-}\r
-\r
/**\r
Process variable with platform key for verification.\r
\r
**/\r
EFI_STATUS\r
ProcessVarWithPk (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes OPTIONAL,\r
- IN BOOLEAN IsPk\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes OPTIONAL,\r
+ IN BOOLEAN IsPk\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN Del;\r
- UINT8 *Payload;\r
- UINTN PayloadSize;\r
- VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];\r
+ EFI_STATUS Status;\r
+ BOOLEAN Del;\r
+ UINT8 *Payload;\r
+ UINTN PayloadSize;\r
\r
- if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||\r
- (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+ if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||\r
+ ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0))\r
+ {\r
//\r
// PK, KEK and db/dbx/dbt should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based\r
// authenticated variable.\r
//\r
// Init state of Del. State may change due to secure check\r
//\r
- Del = FALSE;\r
- Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data);\r
- PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
- if (PayloadSize == 0) {\r
- Del = TRUE;\r
- }\r
-\r
- //\r
- // Check the variable space for both PKpub and SecureBootMode variable.\r
- //\r
- VariableEntry[0].VariableSize = PayloadSize;\r
- VariableEntry[0].Guid = &gEfiGlobalVariableGuid;\r
- VariableEntry[0].Name = EFI_PLATFORM_KEY_NAME;\r
-\r
- VariableEntry[1].VariableSize = sizeof(UINT8);\r
- VariableEntry[1].Guid = &gEdkiiSecureBootModeGuid;\r
- VariableEntry[1].Name = EDKII_SECURE_BOOT_MODE_NAME;\r
-\r
- if ((InCustomMode() && UserPhysicalPresent()) || \r
- (((mSecureBootMode == SecureBootModeTypeSetupMode) || (mSecureBootMode == SecureBootModeTypeAuditMode)) && !IsPk)) {\r
+ Del = FALSE;\r
+ if ((InCustomMode () && UserPhysicalPresent ()) || ((mPlatformMode == SETUP_MODE) && !IsPk)) {\r
+ Payload = (UINT8 *)Data + AUTHINFO2_SIZE (Data);\r
+ PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
+ if (PayloadSize == 0) {\r
+ Del = TRUE;\r
+ }\r
\r
- Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize);\r
+ Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- //\r
- // If delete PKpub, only check for "SecureBootMode" only\r
- // if update / add PKpub, check both NewPKpub & "SecureBootMode"\r
- //\r
- if (IsPk) {\r
- //\r
- // Delete PKpub\r
- //\r
- if (Del && ((mSecureBootMode == SecureBootModeTypeUserMode) || (mSecureBootMode == SecureBootModeTypeDeployedMode)) \r
- && !mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[1], NULL)){\r
- return EFI_OUT_OF_RESOURCES;\r
- //\r
- // Add PKpub\r
- //\r
- } else if (!Del && ((mSecureBootMode == SecureBootModeTypeSetupMode) || (mSecureBootMode == SecureBootModeTypeAuditMode))\r
- && !mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
Status = AuthServiceInternalUpdateVariableWithTimeStamp (\r
VariableName,\r
VendorGuid,\r
Payload,\r
PayloadSize,\r
Attributes,\r
- &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp\r
+ &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp\r
);\r
- if (EFI_ERROR(Status)) {\r
+ if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- if (((mSecureBootMode != SecureBootModeTypeSetupMode) && (mSecureBootMode != SecureBootModeTypeAuditMode)) || IsPk) {\r
+ if ((mPlatformMode != SETUP_MODE) || IsPk) {\r
Status = VendorKeyIsModified ();\r
}\r
- } else if (mSecureBootMode == SecureBootModeTypeUserMode || mSecureBootMode == SecureBootModeTypeDeployedMode) {\r
- //\r
- // If delete PKpub, check "SecureBootMode" only\r
- //\r
- if (IsPk && Del && !mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[1], NULL)){\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
+ } else if (mPlatformMode == USER_MODE) {\r
//\r
// Verify against X509 Cert in PK database.\r
//\r
);\r
} else {\r
//\r
- // SetupMode or AuditMode to add PK\r
// Verify against the certificate in data payload.\r
//\r
- //\r
- // Check PKpub & SecureBootMode variable space consistency\r
- //\r
- if (!mAuthVarLibContextIn->CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {\r
- //\r
- // No enough variable space to set PK successfully.\r
- //\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
Status = VerifyTimeBasedPayloadAndUpdate (\r
VariableName,\r
VendorGuid,\r
);\r
}\r
\r
- if (!EFI_ERROR(Status) && IsPk) {\r
- //\r
- // Delete or Enroll PK causes SecureBootMode change\r
- //\r
- if (!Del) {\r
- if (mSecureBootMode == SecureBootModeTypeSetupMode) {\r
- //\r
- // If enroll PK in setup mode, change to user mode.\r
- //\r
- Status = SecureBootModeTransition (mSecureBootMode, SecureBootModeTypeUserMode);\r
- } else if (mSecureBootMode == SecureBootModeTypeAuditMode) {\r
- //\r
- // If enroll PK in Audit mode, change to Deployed mode.\r
- //\r
- Status = SecureBootModeTransition (mSecureBootMode, SecureBootModeTypeDeployedMode);\r
- } else {\r
- DEBUG((EFI_D_INFO, "PK is updated in %x mode. No SecureBootMode change.\n", mSecureBootMode));\r
- }\r
- } else {\r
- if ((mSecureBootMode == SecureBootModeTypeUserMode) || (mSecureBootMode == SecureBootModeTypeDeployedMode)) {\r
- //\r
- // If delete PK in User Mode or DeployedMode, change to Setup Mode.\r
- //\r
- Status = SecureBootModeTransition (mSecureBootMode, SecureBootModeTypeSetupMode);\r
- }\r
+ if (!EFI_ERROR (Status) && IsPk) {\r
+ if ((mPlatformMode == SETUP_MODE) && !Del) {\r
+ //\r
+ // If enroll PK in setup mode, need change to user mode.\r
+ //\r
+ Status = UpdatePlatformMode (USER_MODE);\r
+ } else if ((mPlatformMode == USER_MODE) && Del) {\r
+ //\r
+ // If delete PK in user mode, need change to setup mode.\r
+ //\r
+ Status = UpdatePlatformMode (SETUP_MODE);\r
}\r
}\r
\r
**/\r
EFI_STATUS\r
ProcessVarWithKek (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes OPTIONAL\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes OPTIONAL\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 *Payload;\r
- UINTN PayloadSize;\r
+ EFI_STATUS Status;\r
+ UINT8 *Payload;\r
+ UINTN PayloadSize;\r
\r
- if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0 ||\r
- (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
+ if (((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) ||\r
+ ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0))\r
+ {\r
//\r
// DB, DBX and DBT should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based\r
// authenticated variable.\r
}\r
\r
Status = EFI_SUCCESS;\r
- if ((mSecureBootMode == SecureBootModeTypeUserMode || mSecureBootMode == SecureBootModeTypeDeployedMode)\r
- && !(InCustomMode() && UserPhysicalPresent())) {\r
+ if ((mPlatformMode == USER_MODE) && !(InCustomMode () && UserPhysicalPresent ())) {\r
//\r
// Time-based, verify against X509 Cert KEK.\r
//\r
//\r
// If in setup mode or custom secure boot mode, no authentication needed.\r
//\r
- Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data);\r
+ Payload = (UINT8 *)Data + AUTHINFO2_SIZE (Data);\r
PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
\r
- Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize);\r
+ Status = CheckSignatureListFormat (VariableName, VendorGuid, Payload, PayloadSize);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
Payload,\r
PayloadSize,\r
Attributes,\r
- &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp\r
+ &((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->TimeStamp\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- if ((mSecureBootMode != SecureBootModeTypeSetupMode) && (mSecureBootMode != SecureBootModeTypeAuditMode)) {\r
+ if (mPlatformMode != SETUP_MODE) {\r
Status = VendorKeyIsModified ();\r
}\r
}\r
**/\r
BOOLEAN\r
IsDeleteAuthVariable (\r
- IN UINT32 OrgAttributes,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes\r
+ IN UINT32 OrgAttributes,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes\r
)\r
{\r
- BOOLEAN Del;\r
- UINTN PayloadSize;\r
+ BOOLEAN Del;\r
+ UINTN PayloadSize;\r
\r
Del = FALSE;\r
\r
// and the DataSize set to the size of the AuthInfo descriptor.\r
//\r
if ((Attributes == OrgAttributes) &&\r
- ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0)) {\r
+ ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0))\r
+ {\r
if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
PayloadSize = DataSize - AUTHINFO2_SIZE (Data);\r
if (PayloadSize == 0) {\r
}\r
\r
/**\r
- Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
+ Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
\r
Caution: This function may receive untrusted input.\r
This function may be invoked in SMM mode, and datasize and data are external input.\r
\r
@return EFI_INVALID_PARAMETER Invalid parameter.\r
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with\r
- EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.\r
@return EFI_OUT_OF_RESOURCES The Database to save the public key is full.\r
- @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+ @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\r
set, but the AuthInfo does NOT pass the validation\r
check carried out by the firmware.\r
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.\r
**/\r
EFI_STATUS\r
ProcessVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes OPTIONAL\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN IsDeletion;\r
- BOOLEAN IsFirstTime;\r
- UINT8 *PubKey;\r
- EFI_VARIABLE_AUTHENTICATION *CertData;\r
- EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;\r
- UINT32 KeyIndex;\r
- UINT64 MonotonicCount;\r
- VARIABLE_ENTRY_CONSISTENCY VariableDataEntry;\r
- UINT32 Index;\r
- AUTH_VARIABLE_INFO OrgVariableInfo;\r
-\r
- KeyIndex = 0;\r
- CertData = NULL;\r
- CertBlock = NULL;\r
- PubKey = NULL;\r
- IsDeletion = FALSE;\r
- Status = EFI_SUCCESS;\r
+ EFI_STATUS Status;\r
+ AUTH_VARIABLE_INFO OrgVariableInfo;\r
+\r
+ Status = EFI_SUCCESS;\r
\r
ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));\r
Status = mAuthVarLibContextIn->FindVariable (\r
- VariableName,\r
- VendorGuid,\r
- &OrgVariableInfo\r
- );\r
+ VariableName,\r
+ VendorGuid,\r
+ &OrgVariableInfo\r
+ );\r
\r
- if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && UserPhysicalPresent()) {\r
+ // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.\r
+ if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attributes, Data, DataSize, Attributes) && (UserPhysicalPresent () || !IsVariablePolicyEnabled ())) {\r
//\r
- // Allow the delete operation of common authenticated variable at user physical presence.\r
+ // Allow the delete operation of common authenticated variable(AT or AW) at user physical presence.\r
//\r
Status = AuthServiceInternalUpdateVariable (\r
- VariableName,\r
- VendorGuid,\r
- NULL,\r
- 0,\r
- 0\r
- );\r
+ VariableName,\r
+ VendorGuid,\r
+ NULL,\r
+ 0,\r
+ 0\r
+ );\r
if (!EFI_ERROR (Status) && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
- Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
+ Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);\r
}\r
\r
return Status;\r
}\r
\r
- if (NeedPhysicallyPresent (VariableName, VendorGuid) && !UserPhysicalPresent()) {\r
+ if (NeedPhysicallyPresent (VariableName, VendorGuid) && !UserPhysicalPresent ()) {\r
//\r
// This variable is protected, only physical present user could modify its value.\r
//\r
}\r
\r
//\r
- // A time-based authenticated variable and a count-based authenticated variable\r
- // can't be updated by each other.\r
- //\r
- if (OrgVariableInfo.Data != NULL) {\r
- if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
- ((OrgVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- if (((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) &&\r
- ((OrgVariableInfo.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
-\r
- //\r
- // Process Time-based Authenticated variable.\r
- //\r
- if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ //\r
+ // Reject Counter Based Auth Variable processing request.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ //\r
+ // Process Time-based Authenticated variable.\r
+ //\r
return VerifyTimeBasedPayloadAndUpdate (\r
VariableName,\r
VendorGuid,\r
);\r
}\r
\r
- //\r
- // Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.\r
- //\r
- if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
- //\r
- // Determine current operation type.\r
- //\r
- if (DataSize == AUTHINFO_SIZE) {\r
- IsDeletion = TRUE;\r
- }\r
- //\r
- // Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.\r
- //\r
- if (OrgVariableInfo.Data == NULL) {\r
- IsFirstTime = TRUE;\r
- } else if ((OrgVariableInfo.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {\r
- IsFirstTime = TRUE;\r
- } else {\r
- KeyIndex = OrgVariableInfo.PubKeyIndex;\r
- IsFirstTime = FALSE;\r
- }\r
- } else if ((OrgVariableInfo.Data != NULL) &&\r
- ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0)\r
- ) {\r
+ if ((OrgVariableInfo.Data != NULL) &&\r
+ ((OrgVariableInfo.Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) != 0))\r
+ {\r
//\r
// If the variable is already write-protected, it always needs authentication before update.\r
//\r
return EFI_WRITE_PROTECTED;\r
- } else {\r
- //\r
- // If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.\r
- // That means it is not authenticated variable, just update variable as usual.\r
- //\r
- Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);\r
- return Status;\r
- }\r
-\r
- //\r
- // Get PubKey and check Monotonic Count value corresponding to the variable.\r
- //\r
- CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;\r
- CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);\r
- PubKey = CertBlock->PublicKey;\r
-\r
- //\r
- // Update Monotonic Count value.\r
- //\r
- MonotonicCount = CertData->MonotonicCount;\r
-\r
- if (!IsFirstTime) {\r
- //\r
- // 2 cases need to check here\r
- // 1. Internal PubKey variable. PubKeyIndex is always 0\r
- // 2. Other counter-based AuthVariable. Check input PubKey.\r
- //\r
- if (KeyIndex == 0) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- for (Index = 0; Index < mPubKeyNumber; Index++) {\r
- if (ReadUnaligned32 (&(((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyIndex)) == KeyIndex) {\r
- if (CompareMem (((AUTHVAR_KEY_DB_DATA *) mPubKeyStore + Index)->KeyData, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
- break;\r
- } else {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
- }\r
- if (Index == mPubKeyNumber) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Compare the current monotonic count and ensure that it is greater than the last SetVariable\r
- // operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.\r
- //\r
- if (MonotonicCount <= OrgVariableInfo.MonotonicCount) {\r
- //\r
- // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.\r
- //\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
- }\r
- //\r
- // Verify the certificate in Data payload.\r
- //\r
- Status = VerifyCounterBasedPayload (Data, DataSize, PubKey);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Now, the signature has been verified!\r
- //\r
- if (IsFirstTime && !IsDeletion) {\r
- VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;\r
- VariableDataEntry.Guid = VendorGuid;\r
- VariableDataEntry.Name = VariableName;\r
-\r
- //\r
- // Update public key database variable if need.\r
- //\r
- KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);\r
- if (KeyIndex == 0) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
}\r
\r
//\r
- // Verification pass.\r
+ // Not authenticated variable, just update variable as usual.\r
//\r
- return AuthServiceInternalUpdateVariableWithMonotonicCount (VariableName, VendorGuid, (UINT8*)Data + AUTHINFO_SIZE, DataSize - AUTHINFO_SIZE, Attributes, KeyIndex, MonotonicCount);\r
+ Status = AuthServiceInternalUpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes);\r
+ return Status;\r
}\r
\r
/**\r
**/\r
EFI_STATUS\r
FilterSignatureList (\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN OUT VOID *NewData,\r
- IN OUT UINTN *NewDataSize\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN OUT VOID *NewData,\r
+ IN OUT UINTN *NewDataSize\r
)\r
{\r
- EFI_SIGNATURE_LIST *CertList;\r
- EFI_SIGNATURE_DATA *Cert;\r
- UINTN CertCount;\r
- EFI_SIGNATURE_LIST *NewCertList;\r
- EFI_SIGNATURE_DATA *NewCert;\r
- UINTN NewCertCount;\r
- UINTN Index;\r
- UINTN Index2;\r
- UINTN Size;\r
- UINT8 *Tail;\r
- UINTN CopiedCount;\r
- UINTN SignatureListSize;\r
- BOOLEAN IsNewCert;\r
- UINT8 *TempData;\r
- UINTN TempDataSize;\r
- EFI_STATUS Status;\r
+ EFI_SIGNATURE_LIST *CertList;\r
+ EFI_SIGNATURE_DATA *Cert;\r
+ UINTN CertCount;\r
+ EFI_SIGNATURE_LIST *NewCertList;\r
+ EFI_SIGNATURE_DATA *NewCert;\r
+ UINTN NewCertCount;\r
+ UINTN Index;\r
+ UINTN Index2;\r
+ UINTN Size;\r
+ UINT8 *Tail;\r
+ UINTN CopiedCount;\r
+ UINTN SignatureListSize;\r
+ BOOLEAN IsNewCert;\r
+ UINT8 *TempData;\r
+ UINTN TempDataSize;\r
+ EFI_STATUS Status;\r
\r
if (*NewDataSize == 0) {\r
return EFI_SUCCESS;\r
}\r
\r
TempDataSize = *NewDataSize;\r
- Status = mAuthVarLibContextIn->GetScratchBuffer (&TempDataSize, (VOID **) &TempData);\r
+ Status = mAuthVarLibContextIn->GetScratchBuffer (&TempDataSize, (VOID **)&TempData);\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
Tail = TempData;\r
\r
- NewCertList = (EFI_SIGNATURE_LIST *) NewData;\r
+ NewCertList = (EFI_SIGNATURE_LIST *)NewData;\r
while ((*NewDataSize > 0) && (*NewDataSize >= NewCertList->SignatureListSize)) {\r
- NewCert = (EFI_SIGNATURE_DATA *) ((UINT8 *) NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
+ NewCert = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCertList + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize);\r
NewCertCount = (NewCertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - NewCertList->SignatureHeaderSize) / NewCertList->SignatureSize;\r
\r
CopiedCount = 0;\r
for (Index = 0; Index < NewCertCount; Index++) {\r
IsNewCert = TRUE;\r
\r
- Size = DataSize;\r
- CertList = (EFI_SIGNATURE_LIST *) Data;\r
+ Size = DataSize;\r
+ CertList = (EFI_SIGNATURE_LIST *)Data;\r
while ((Size > 0) && (Size >= CertList->SignatureListSize)) {\r
if (CompareGuid (&CertList->SignatureType, &NewCertList->SignatureType) &&\r
- (CertList->SignatureSize == NewCertList->SignatureSize)) {\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ (CertList->SignatureSize == NewCertList->SignatureSize))\r
+ {\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
for (Index2 = 0; Index2 < CertCount; Index2++) {\r
//\r
IsNewCert = FALSE;\r
break;\r
}\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
}\r
}\r
\r
if (!IsNewCert) {\r
break;\r
}\r
- Size -= CertList->SignatureListSize;\r
- CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+\r
+ Size -= CertList->SignatureListSize;\r
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
}\r
\r
if (IsNewCert) {\r
CopiedCount++;\r
}\r
\r
- NewCert = (EFI_SIGNATURE_DATA *) ((UINT8 *) NewCert + NewCertList->SignatureSize);\r
+ NewCert = (EFI_SIGNATURE_DATA *)((UINT8 *)NewCert + NewCertList->SignatureSize);\r
}\r
\r
//\r
// Update SignatureListSize in the kept EFI_SIGNATURE_LIST.\r
//\r
if (CopiedCount != 0) {\r
- SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);\r
- CertList = (EFI_SIGNATURE_LIST *) (Tail - SignatureListSize);\r
- CertList->SignatureListSize = (UINT32) SignatureListSize;\r
+ SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize + (CopiedCount * NewCertList->SignatureSize);\r
+ CertList = (EFI_SIGNATURE_LIST *)(Tail - SignatureListSize);\r
+ CertList->SignatureListSize = (UINT32)SignatureListSize;\r
}\r
\r
*NewDataSize -= NewCertList->SignatureListSize;\r
- NewCertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) NewCertList + NewCertList->SignatureListSize);\r
+ NewCertList = (EFI_SIGNATURE_LIST *)((UINT8 *)NewCertList + NewCertList->SignatureListSize);\r
}\r
\r
- TempDataSize = (Tail - (UINT8 *) TempData);\r
+ TempDataSize = (Tail - (UINT8 *)TempData);\r
\r
CopyMem (NewData, TempData, TempDataSize);\r
*NewDataSize = TempDataSize;\r
**/\r
BOOLEAN\r
AuthServiceInternalCompareTimeStamp (\r
- IN EFI_TIME *FirstTime,\r
- IN EFI_TIME *SecondTime\r
+ IN EFI_TIME *FirstTime,\r
+ IN EFI_TIME *SecondTime\r
)\r
{\r
if (FirstTime->Year != SecondTime->Year) {\r
- return (BOOLEAN) (FirstTime->Year < SecondTime->Year);\r
+ return (BOOLEAN)(FirstTime->Year < SecondTime->Year);\r
} else if (FirstTime->Month != SecondTime->Month) {\r
- return (BOOLEAN) (FirstTime->Month < SecondTime->Month);\r
+ return (BOOLEAN)(FirstTime->Month < SecondTime->Month);\r
} else if (FirstTime->Day != SecondTime->Day) {\r
- return (BOOLEAN) (FirstTime->Day < SecondTime->Day);\r
+ return (BOOLEAN)(FirstTime->Day < SecondTime->Day);\r
} else if (FirstTime->Hour != SecondTime->Hour) {\r
- return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);\r
+ return (BOOLEAN)(FirstTime->Hour < SecondTime->Hour);\r
} else if (FirstTime->Minute != SecondTime->Minute) {\r
- return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute);\r
+ return (BOOLEAN)(FirstTime->Minute < SecondTime->Minute);\r
+ }\r
+\r
+ return (BOOLEAN)(FirstTime->Second <= SecondTime->Second);\r
+}\r
+\r
+/**\r
+ Calculate SHA256 digest of SignerCert CommonName + ToplevelCert tbsCertificate\r
+ SignerCert and ToplevelCert are inside the signer certificate chain.\r
+\r
+ @param[in] SignerCert A pointer to SignerCert data.\r
+ @param[in] SignerCertSize Length of SignerCert data.\r
+ @param[in] TopLevelCert A pointer to TopLevelCert data.\r
+ @param[in] TopLevelCertSize Length of TopLevelCert data.\r
+ @param[out] Sha256Digest Sha256 digest calculated.\r
+\r
+ @return EFI_ABORTED Digest process failed.\r
+ @return EFI_SUCCESS SHA256 Digest is successfully calculated.\r
+\r
+**/\r
+EFI_STATUS\r
+CalculatePrivAuthVarSignChainSHA256Digest (\r
+ IN UINT8 *SignerCert,\r
+ IN UINTN SignerCertSize,\r
+ IN UINT8 *TopLevelCert,\r
+ IN UINTN TopLevelCertSize,\r
+ OUT UINT8 *Sha256Digest\r
+ )\r
+{\r
+ UINT8 *TbsCert;\r
+ UINTN TbsCertSize;\r
+ CHAR8 CertCommonName[128];\r
+ UINTN CertCommonNameSize;\r
+ BOOLEAN CryptoStatus;\r
+ EFI_STATUS Status;\r
+\r
+ CertCommonNameSize = sizeof (CertCommonName);\r
+\r
+ //\r
+ // Get SignerCert CommonName\r
+ //\r
+ Status = X509GetCommonName (SignerCert, SignerCertSize, CertCommonName, &CertCommonNameSize);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "%a Get SignerCert CommonName failed with status %x\n", __FUNCTION__, Status));\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ //\r
+ // Get TopLevelCert tbsCertificate\r
+ //\r
+ if (!X509GetTBSCert (TopLevelCert, TopLevelCertSize, &TbsCert, &TbsCertSize)) {\r
+ DEBUG ((DEBUG_INFO, "%a Get Top-level Cert tbsCertificate failed!\n", __FUNCTION__));\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ //\r
+ // Digest SignerCert CN + TopLevelCert tbsCertificate\r
+ //\r
+ ZeroMem (Sha256Digest, SHA256_DIGEST_SIZE);\r
+ CryptoStatus = Sha256Init (mHashCtx);\r
+ if (!CryptoStatus) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ //\r
+ // '\0' is forced in CertCommonName. No overflow issue\r
+ //\r
+ CryptoStatus = Sha256Update (\r
+ mHashCtx,\r
+ CertCommonName,\r
+ AsciiStrLen (CertCommonName)\r
+ );\r
+ if (!CryptoStatus) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ CryptoStatus = Sha256Update (mHashCtx, TbsCert, TbsCertSize);\r
+ if (!CryptoStatus) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ CryptoStatus = Sha256Final (mHashCtx, Sha256Digest);\r
+ if (!CryptoStatus) {\r
+ return EFI_ABORTED;\r
}\r
\r
- return (BOOLEAN) (FirstTime->Second <= SecondTime->Second);\r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
Find matching signer's certificates for common authenticated variable\r
- by corresponding VariableName and VendorGuid from "certdb".\r
+ by corresponding VariableName and VendorGuid from "certdb" or "certdbv".\r
\r
- The data format of "certdb":\r
+ The data format of "certdb" or "certdbv":\r
//\r
// UINT32 CertDbListSize;\r
// /// AUTH_CERT_DB_DATA Certs1[];\r
\r
@param[in] VariableName Name of authenticated Variable.\r
@param[in] VendorGuid Vendor GUID of authenticated Variable.\r
- @param[in] Data Pointer to variable "certdb".\r
- @param[in] DataSize Size of variable "certdb".\r
+ @param[in] Data Pointer to variable "certdb" or "certdbv".\r
+ @param[in] DataSize Size of variable "certdb" or "certdbv".\r
@param[out] CertOffset Offset of matching CertData, from starting of Data.\r
@param[out] CertDataSize Length of CertData in bytes.\r
@param[out] CertNodeOffset Offset of matching AUTH_CERT_DB_DATA , from\r
**/\r
EFI_STATUS\r
FindCertsFromDb (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT8 *Data,\r
- IN UINTN DataSize,\r
- OUT UINT32 *CertOffset, OPTIONAL\r
- OUT UINT32 *CertDataSize, OPTIONAL\r
- OUT UINT32 *CertNodeOffset,OPTIONAL\r
- OUT UINT32 *CertNodeSize OPTIONAL\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT8 *Data,\r
+ IN UINTN DataSize,\r
+ OUT UINT32 *CertOffset OPTIONAL,\r
+ OUT UINT32 *CertDataSize OPTIONAL,\r
+ OUT UINT32 *CertNodeOffset OPTIONAL,\r
+ OUT UINT32 *CertNodeSize OPTIONAL\r
)\r
{\r
- UINT32 Offset;\r
- AUTH_CERT_DB_DATA *Ptr;\r
- UINT32 CertSize;\r
- UINT32 NameSize;\r
- UINT32 NodeSize;\r
- UINT32 CertDbListSize;\r
+ UINT32 Offset;\r
+ AUTH_CERT_DB_DATA *Ptr;\r
+ UINT32 CertSize;\r
+ UINT32 NameSize;\r
+ UINT32 NodeSize;\r
+ UINT32 CertDbListSize;\r
\r
if ((VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- CertDbListSize = ReadUnaligned32 ((UINT32 *) Data);\r
+ CertDbListSize = ReadUnaligned32 ((UINT32 *)Data);\r
\r
- if (CertDbListSize != (UINT32) DataSize) {\r
+ if (CertDbListSize != (UINT32)DataSize) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// Get corresponding certificates by VendorGuid and VariableName.\r
//\r
- while (Offset < (UINT32) DataSize) {\r
- Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
+ while (Offset < (UINT32)DataSize) {\r
+ Ptr = (AUTH_CERT_DB_DATA *)(Data + Offset);\r
//\r
// Check whether VendorGuid matches.\r
//\r
CertSize = ReadUnaligned32 (&Ptr->CertDataSize);\r
\r
if (NodeSize != sizeof (EFI_GUID) + sizeof (UINT32) * 3 + CertSize +\r
- sizeof (CHAR16) * NameSize) {\r
+ sizeof (CHAR16) * NameSize)\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// Check whether VariableName matches.\r
//\r
if ((NameSize == StrLen (VariableName)) &&\r
- (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0)) {\r
+ (CompareMem (Data + Offset, VariableName, NameSize * sizeof (CHAR16)) == 0))\r
+ {\r
Offset = Offset + NameSize * sizeof (CHAR16);\r
\r
if (CertOffset != NULL) {\r
}\r
\r
if (CertNodeOffset != NULL) {\r
- *CertNodeOffset = (UINT32) ((UINT8 *) Ptr - Data);\r
+ *CertNodeOffset = (UINT32)((UINT8 *)Ptr - Data);\r
}\r
\r
if (CertNodeSize != NULL) {\r
\r
/**\r
Retrieve signer's certificates for common authenticated variable\r
- by corresponding VariableName and VendorGuid from "certdb".\r
+ by corresponding VariableName and VendorGuid from "certdb"\r
+ or "certdbv" according to authenticated variable attributes.\r
\r
@param[in] VariableName Name of authenticated Variable.\r
@param[in] VendorGuid Vendor GUID of authenticated Variable.\r
+ @param[in] Attributes Attributes of authenticated variable.\r
@param[out] CertData Pointer to signer's certificates.\r
@param[out] CertDataSize Length of CertData in bytes.\r
\r
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
- @retval EFI_NOT_FOUND Fail to find "certdb" or matching certs.\r
+ @retval EFI_NOT_FOUND Fail to find "certdb"/"certdbv" or matching certs.\r
@retval EFI_SUCCESS Get signer's certificates successfully.\r
\r
**/\r
EFI_STATUS\r
GetCertsFromDb (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINT8 **CertData,\r
- OUT UINT32 *CertDataSize\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ OUT UINT8 **CertData,\r
+ OUT UINT32 *CertDataSize\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT32 CertOffset;\r
+ EFI_STATUS Status;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ UINT32 CertOffset;\r
+ CHAR16 *DbName;\r
\r
if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL) || (CertDataSize == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+ //\r
+ // Get variable "certdb".\r
+ //\r
+ DbName = EFI_CERT_DB_NAME;\r
+ } else {\r
+ //\r
+ // Get variable "certdbv".\r
+ //\r
+ DbName = EFI_CERT_DB_VOLATILE_NAME;\r
+ }\r
+\r
//\r
- // Get variable "certdb".\r
+ // Get variable "certdb" or "certdbv".\r
//\r
Status = AuthServiceInternalFindVariable (\r
- EFI_CERT_DB_NAME,\r
+ DbName,\r
&gEfiCertDbGuid,\r
- (VOID **) &Data,\r
+ (VOID **)&Data,\r
&DataSize\r
);\r
if (EFI_ERROR (Status)) {\r
\r
/**\r
Delete matching signer's certificates when deleting common authenticated\r
- variable by corresponding VariableName and VendorGuid from "certdb".\r
+ variable by corresponding VariableName and VendorGuid from "certdb" or\r
+ "certdbv" according to authenticated variable attributes.\r
\r
@param[in] VariableName Name of authenticated Variable.\r
@param[in] VendorGuid Vendor GUID of authenticated Variable.\r
+ @param[in] Attributes Attributes of authenticated variable.\r
\r
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
- @retval EFI_NOT_FOUND Fail to find "certdb" or matching certs.\r
+ @retval EFI_NOT_FOUND Fail to find "certdb"/"certdbv" or matching certs.\r
@retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.\r
@retval EFI_SUCCESS The operation is completed successfully.\r
\r
**/\r
EFI_STATUS\r
DeleteCertsFromDb (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT32 VarAttr;\r
- UINT32 CertNodeOffset;\r
- UINT32 CertNodeSize;\r
- UINT8 *NewCertDb;\r
- UINT32 NewCertDbSize;\r
+ EFI_STATUS Status;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ UINT32 VarAttr;\r
+ UINT32 CertNodeOffset;\r
+ UINT32 CertNodeSize;\r
+ UINT8 *NewCertDb;\r
+ UINT32 NewCertDbSize;\r
+ CHAR16 *DbName;\r
\r
if ((VariableName == NULL) || (VendorGuid == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- //\r
- // Get variable "certdb".\r
- //\r
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+ //\r
+ // Get variable "certdb".\r
+ //\r
+ DbName = EFI_CERT_DB_NAME;\r
+ VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ } else {\r
+ //\r
+ // Get variable "certdbv".\r
+ //\r
+ DbName = EFI_CERT_DB_VOLATILE_NAME;\r
+ VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ }\r
+\r
Status = AuthServiceInternalFindVariable (\r
- EFI_CERT_DB_NAME,\r
+ DbName,\r
&gEfiCertDbGuid,\r
- (VOID **) &Data,\r
+ (VOID **)&Data,\r
&DataSize\r
);\r
+\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
if (DataSize == sizeof (UINT32)) {\r
//\r
- // There is no certs in certdb.\r
+ // There is no certs in "certdb" or "certdbv".\r
//\r
return EFI_SUCCESS;\r
}\r
\r
//\r
- // Get corresponding cert node from certdb.\r
+ // Get corresponding cert node from "certdb" or "certdbv".\r
//\r
Status = FindCertsFromDb (\r
VariableName,\r
}\r
\r
//\r
- // Construct new data content of variable "certdb".\r
+ // Construct new data content of variable "certdb" or "certdbv".\r
//\r
- NewCertDbSize = (UINT32) DataSize - CertNodeSize;\r
- NewCertDb = (UINT8*) mCertDbStore;\r
+ NewCertDbSize = (UINT32)DataSize - CertNodeSize;\r
+ NewCertDb = (UINT8 *)mCertDbStore;\r
\r
//\r
// Copy the DB entries before deleting node.\r
}\r
\r
//\r
- // Set "certdb".\r
+ // Set "certdb" or "certdbv".\r
//\r
- VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_CERT_DB_NAME,\r
- &gEfiCertDbGuid,\r
- NewCertDb,\r
- NewCertDbSize,\r
- VarAttr\r
- );\r
+ Status = AuthServiceInternalUpdateVariable (\r
+ DbName,\r
+ &gEfiCertDbGuid,\r
+ NewCertDb,\r
+ NewCertDbSize,\r
+ VarAttr\r
+ );\r
\r
return Status;\r
}\r
\r
/**\r
Insert signer's certificates for common authenticated variable with VariableName\r
- and VendorGuid in AUTH_CERT_DB_DATA to "certdb".\r
-\r
- @param[in] VariableName Name of authenticated Variable.\r
- @param[in] VendorGuid Vendor GUID of authenticated Variable.\r
- @param[in] CertData Pointer to signer's certificates.\r
- @param[in] CertDataSize Length of CertData in bytes.\r
+ and VendorGuid in AUTH_CERT_DB_DATA to "certdb" or "certdbv" according to\r
+ time based authenticated variable attributes. CertData is the SHA256 digest of\r
+ SignerCert CommonName + TopLevelCert tbsCertificate.\r
+\r
+ @param[in] VariableName Name of authenticated Variable.\r
+ @param[in] VendorGuid Vendor GUID of authenticated Variable.\r
+ @param[in] Attributes Attributes of authenticated variable.\r
+ @param[in] SignerCert Signer certificate data.\r
+ @param[in] SignerCertSize Length of signer certificate.\r
+ @param[in] TopLevelCert Top-level certificate data.\r
+ @param[in] TopLevelCertSize Length of top-level certificate.\r
\r
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
@retval EFI_ACCESS_DENIED An AUTH_CERT_DB_DATA entry with same VariableName\r
and VendorGuid already exists.\r
@retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.\r
- @retval EFI_SUCCESS Insert an AUTH_CERT_DB_DATA entry to "certdb"\r
+ @retval EFI_SUCCESS Insert an AUTH_CERT_DB_DATA entry to "certdb" or "certdbv"\r
\r
**/\r
EFI_STATUS\r
InsertCertsToDb (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT8 *CertData,\r
- IN UINTN CertDataSize\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ IN UINT8 *SignerCert,\r
+ IN UINTN SignerCertSize,\r
+ IN UINT8 *TopLevelCert,\r
+ IN UINTN TopLevelCertSize\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT32 VarAttr;\r
- UINT8 *NewCertDb;\r
- UINT32 NewCertDbSize;\r
- UINT32 CertNodeSize;\r
- UINT32 NameSize;\r
- AUTH_CERT_DB_DATA *Ptr;\r
-\r
- if ((VariableName == NULL) || (VendorGuid == NULL) || (CertData == NULL)) {\r
+ EFI_STATUS Status;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ UINT32 VarAttr;\r
+ UINT8 *NewCertDb;\r
+ UINT32 NewCertDbSize;\r
+ UINT32 CertNodeSize;\r
+ UINT32 NameSize;\r
+ UINT32 CertDataSize;\r
+ AUTH_CERT_DB_DATA *Ptr;\r
+ CHAR16 *DbName;\r
+ UINT8 Sha256Digest[SHA256_DIGEST_SIZE];\r
+\r
+ if ((VariableName == NULL) || (VendorGuid == NULL) || (SignerCert == NULL) || (TopLevelCert == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+ //\r
+ // Get variable "certdb".\r
+ //\r
+ DbName = EFI_CERT_DB_NAME;\r
+ VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ } else {\r
+ //\r
+ // Get variable "certdbv".\r
+ //\r
+ DbName = EFI_CERT_DB_VOLATILE_NAME;\r
+ VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+ }\r
+\r
//\r
- // Get variable "certdb".\r
+ // Get variable "certdb" or "certdbv".\r
//\r
Status = AuthServiceInternalFindVariable (\r
- EFI_CERT_DB_NAME,\r
+ DbName,\r
&gEfiCertDbGuid,\r
- (VOID **) &Data,\r
+ (VOID **)&Data,\r
&DataSize\r
);\r
if (EFI_ERROR (Status)) {\r
}\r
\r
//\r
- // Find whether matching cert node already exists in "certdb".\r
+ // Find whether matching cert node already exists in "certdb" or "certdbv".\r
// If yes return error.\r
//\r
Status = FindCertsFromDb (\r
}\r
\r
//\r
- // Construct new data content of variable "certdb".\r
+ // Construct new data content of variable "certdb" or "certdbv".\r
//\r
- NameSize = (UINT32) StrLen (VariableName);\r
- CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32) CertDataSize + NameSize * sizeof (CHAR16);\r
- NewCertDbSize = (UINT32) DataSize + CertNodeSize;\r
+ NameSize = (UINT32)StrLen (VariableName);\r
+ CertDataSize = sizeof (Sha256Digest);\r
+ CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32)CertDataSize + NameSize * sizeof (CHAR16);\r
+ NewCertDbSize = (UINT32)DataSize + CertNodeSize;\r
if (NewCertDbSize > mMaxCertDbSize) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- NewCertDb = (UINT8*) mCertDbStore;\r
+\r
+ Status = CalculatePrivAuthVarSignChainSHA256Digest (\r
+ SignerCert,\r
+ SignerCertSize,\r
+ TopLevelCert,\r
+ TopLevelCertSize,\r
+ Sha256Digest\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ NewCertDb = (UINT8 *)mCertDbStore;\r
\r
//\r
// Copy the DB entries before inserting node.\r
//\r
// Construct new cert node.\r
//\r
- Ptr = (AUTH_CERT_DB_DATA *) (NewCertDb + DataSize);\r
+ Ptr = (AUTH_CERT_DB_DATA *)(NewCertDb + DataSize);\r
CopyGuid (&Ptr->VendorGuid, VendorGuid);\r
CopyMem (&Ptr->CertNodeSize, &CertNodeSize, sizeof (UINT32));\r
CopyMem (&Ptr->NameSize, &NameSize, sizeof (UINT32));\r
CopyMem (&Ptr->CertDataSize, &CertDataSize, sizeof (UINT32));\r
\r
CopyMem (\r
- (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA),\r
+ (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA),\r
VariableName,\r
NameSize * sizeof (CHAR16)\r
);\r
\r
CopyMem (\r
- (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),\r
- CertData,\r
+ (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA) + NameSize * sizeof (CHAR16),\r
+ Sha256Digest,\r
CertDataSize\r
);\r
\r
//\r
- // Set "certdb".\r
+ // Set "certdb" or "certdbv".\r
//\r
- VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
- Status = AuthServiceInternalUpdateVariable (\r
- EFI_CERT_DB_NAME,\r
- &gEfiCertDbGuid,\r
- NewCertDb,\r
- NewCertDbSize,\r
- VarAttr\r
- );\r
+ Status = AuthServiceInternalUpdateVariable (\r
+ DbName,\r
+ &gEfiCertDbGuid,\r
+ NewCertDb,\r
+ NewCertDbSize,\r
+ VarAttr\r
+ );\r
\r
return Status;\r
}\r
/**\r
Clean up signer's certificates for common authenticated variable\r
by corresponding VariableName and VendorGuid from "certdb".\r
- Sytem may break down during Timebased Variable update & certdb update,\r
- make them inconsistent, this function is called in AuthVariable Init to ensure \r
- consistency\r
- \r
- @retval EFI_NOT_FOUND Fail to find matching certs.\r
- @retval EFI_SUCCESS Find matching certs and output parameters.\r
+ System may break down during Timebased Variable update & certdb update,\r
+ make them inconsistent, this function is called in AuthVariable Init\r
+ to ensure consistency.\r
+\r
+ @retval EFI_NOT_FOUND Fail to find variable "certdb".\r
+ @retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.\r
+ @retval EFI_SUCCESS The operation is completed successfully.\r
\r
**/\r
EFI_STATUS\r
VOID\r
)\r
{\r
- UINT32 Offset;\r
- AUTH_CERT_DB_DATA *Ptr;\r
- UINT32 NameSize;\r
- UINT32 NodeSize;\r
- CHAR16 *VariableName;\r
- EFI_STATUS Status;\r
- BOOLEAN CertCleaned;\r
- UINT8 *Data;\r
- UINTN DataSize;\r
- UINT8 *AuthVarData;\r
- UINTN AuthVarDataSize;\r
- EFI_GUID AuthVarGuid;\r
+ UINT32 Offset;\r
+ AUTH_CERT_DB_DATA *Ptr;\r
+ UINT32 NameSize;\r
+ UINT32 NodeSize;\r
+ CHAR16 *VariableName;\r
+ EFI_STATUS Status;\r
+ BOOLEAN CertCleaned;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ EFI_GUID AuthVarGuid;\r
+ AUTH_VARIABLE_INFO AuthVariableInfo;\r
\r
Status = EFI_SUCCESS;\r
\r
Status = AuthServiceInternalFindVariable (\r
EFI_CERT_DB_NAME,\r
&gEfiCertDbGuid,\r
- (VOID **) &Data,\r
+ (VOID **)&Data,\r
&DataSize\r
);\r
if (EFI_ERROR (Status)) {\r
\r
Offset = sizeof (UINT32);\r
\r
- while (Offset < (UINT32) DataSize) {\r
- Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
- //\r
- // Check whether VendorGuid matches.\r
- //\r
+ while (Offset < (UINT32)DataSize) {\r
+ Ptr = (AUTH_CERT_DB_DATA *)(Data + Offset);\r
NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);\r
NameSize = ReadUnaligned32 (&Ptr->NameSize);\r
\r
//\r
// Get VarName tailed with '\0'\r
//\r
- VariableName = AllocateZeroPool((NameSize + 1) * sizeof(CHAR16));\r
+ VariableName = AllocateZeroPool ((NameSize + 1) * sizeof (CHAR16));\r
if (VariableName == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- CopyMem (VariableName, (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof(CHAR16));\r
+\r
+ CopyMem (VariableName, (UINT8 *)Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof (CHAR16));\r
//\r
// Keep VarGuid aligned\r
//\r
- CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof(EFI_GUID));\r
+ CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof (EFI_GUID));\r
\r
//\r
// Find corresponding time auth variable\r
//\r
- Status = AuthServiceInternalFindVariable (\r
- VariableName,\r
- &AuthVarGuid,\r
- (VOID **) &AuthVarData,\r
- &AuthVarDataSize\r
- );\r
+ ZeroMem (&AuthVariableInfo, sizeof (AuthVariableInfo));\r
+ Status = mAuthVarLibContextIn->FindVariable (\r
+ VariableName,\r
+ &AuthVarGuid,\r
+ &AuthVariableInfo\r
+ );\r
\r
- if (EFI_ERROR(Status)) {\r
- Status = DeleteCertsFromDb(VariableName, &AuthVarGuid);\r
+ if (EFI_ERROR (Status) || ((AuthVariableInfo.Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0)) {\r
+ //\r
+ // While cleaning certdb, always delete the variable in certdb regardless of it attributes.\r
+ //\r
+ Status = DeleteCertsFromDb (\r
+ VariableName,\r
+ &AuthVarGuid,\r
+ AuthVariableInfo.Attributes | EFI_VARIABLE_NON_VOLATILE\r
+ );\r
CertCleaned = TRUE;\r
- DEBUG((EFI_D_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));\r
- FreePool(VariableName);\r
+ DEBUG ((DEBUG_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));\r
+ FreePool (VariableName);\r
break;\r
}\r
\r
- FreePool(VariableName);\r
+ FreePool (VariableName);\r
Offset = Offset + NodeSize;\r
}\r
} while (CertCleaned);\r
**/\r
EFI_STATUS\r
VerifyTimeBasedPayload (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes,\r
- IN AUTHVAR_TYPE AuthVarType,\r
- IN EFI_TIME *OrgTimeStamp,\r
- OUT UINT8 **VarPayloadPtr,\r
- OUT UINTN *VarPayloadSize\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes,\r
+ IN AUTHVAR_TYPE AuthVarType,\r
+ IN EFI_TIME *OrgTimeStamp,\r
+ OUT UINT8 **VarPayloadPtr,\r
+ OUT UINTN *VarPayloadSize\r
)\r
{\r
- EFI_VARIABLE_AUTHENTICATION_2 *CertData;\r
- UINT8 *SigData;\r
- UINT32 SigDataSize;\r
- UINT8 *PayloadPtr;\r
- UINTN PayloadSize;\r
- UINT32 Attr;\r
- BOOLEAN VerifyStatus;\r
- EFI_STATUS Status;\r
- EFI_SIGNATURE_LIST *CertList;\r
- EFI_SIGNATURE_DATA *Cert;\r
- UINTN Index;\r
- UINTN CertCount;\r
- UINT32 KekDataSize;\r
- UINT8 *NewData;\r
- UINTN NewDataSize;\r
- UINT8 *Buffer;\r
- UINTN Length;\r
- UINT8 *RootCert;\r
- UINTN RootCertSize;\r
- UINT8 *SignerCerts;\r
- UINTN CertStackSize;\r
- UINT8 *CertsInCertDb;\r
- UINT32 CertsSizeinDb;\r
-\r
- VerifyStatus = FALSE;\r
- CertData = NULL;\r
- NewData = NULL;\r
- Attr = Attributes;\r
- SignerCerts = NULL;\r
- RootCert = NULL;\r
- CertsInCertDb = NULL;\r
+ EFI_VARIABLE_AUTHENTICATION_2 *CertData;\r
+ UINT8 *SigData;\r
+ UINT32 SigDataSize;\r
+ UINT8 *PayloadPtr;\r
+ UINTN PayloadSize;\r
+ UINT32 Attr;\r
+ BOOLEAN VerifyStatus;\r
+ EFI_STATUS Status;\r
+ EFI_SIGNATURE_LIST *CertList;\r
+ EFI_SIGNATURE_DATA *Cert;\r
+ UINTN Index;\r
+ UINTN CertCount;\r
+ UINT32 KekDataSize;\r
+ UINT8 *NewData;\r
+ UINTN NewDataSize;\r
+ UINT8 *Buffer;\r
+ UINTN Length;\r
+ UINT8 *TopLevelCert;\r
+ UINTN TopLevelCertSize;\r
+ UINT8 *TrustedCert;\r
+ UINTN TrustedCertSize;\r
+ UINT8 *SignerCerts;\r
+ UINTN CertStackSize;\r
+ UINT8 *CertsInCertDb;\r
+ UINT32 CertsSizeinDb;\r
+ UINT8 Sha256Digest[SHA256_DIGEST_SIZE];\r
+ EFI_CERT_DATA *CertDataPtr;\r
+\r
+ //\r
+ // 1. TopLevelCert is the top-level issuer certificate in signature Signer Cert Chain\r
+ // 2. TrustedCert is the certificate which firmware trusts. It could be saved in protected\r
+ // storage or PK payload on PK init\r
+ //\r
+ VerifyStatus = FALSE;\r
+ CertData = NULL;\r
+ NewData = NULL;\r
+ Attr = Attributes;\r
+ SignerCerts = NULL;\r
+ TopLevelCert = NULL;\r
+ CertsInCertDb = NULL;\r
+ CertDataPtr = NULL;\r
\r
//\r
// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is\r
// variable value. The authentication descriptor is not part of the variable data and is not\r
// returned by subsequent calls to GetVariable().\r
//\r
- CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;\r
+ CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;\r
\r
//\r
// Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components of the\r
(CertData->TimeStamp.Nanosecond != 0) ||\r
(CertData->TimeStamp.TimeZone != 0) ||\r
(CertData->TimeStamp.Daylight != 0) ||\r
- (CertData->TimeStamp.Pad2 != 0)) {\r
+ (CertData->TimeStamp.Pad2 != 0))\r
+ {\r
return EFI_SECURITY_VIOLATION;\r
}\r
\r
// Cert type should be EFI_CERT_TYPE_PKCS7_GUID.\r
//\r
if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||\r
- !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid)) {\r
+ !CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid))\r
+ {\r
//\r
// Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.\r
//\r
// Find out Pkcs7 SignedData which follows the EFI_VARIABLE_AUTHENTICATION_2 descriptor.\r
// AuthInfo.Hdr.dwLength is the length of the entire certificate, including the length of the header.\r
//\r
- SigData = CertData->AuthInfo.CertData;\r
- SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32) (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
+ SigData = CertData->AuthInfo.CertData;\r
+ SigDataSize = CertData->AuthInfo.Hdr.dwLength - (UINT32)(OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));\r
+\r
+ //\r
+ // SignedData.digestAlgorithms shall contain the digest algorithm used when preparing the\r
+ // signature. Only a digest algorithm of SHA-256 is accepted.\r
+ //\r
+ // According to PKCS#7 Definition (https://www.rfc-editor.org/rfc/rfc2315):\r
+ // SignedData ::= SEQUENCE {\r
+ // version Version,\r
+ // digestAlgorithms DigestAlgorithmIdentifiers,\r
+ // contentInfo ContentInfo,\r
+ // .... }\r
+ // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm\r
+ // in VARIABLE_AUTHENTICATION_2 descriptor.\r
+ // This field has the fixed offset (+13) or (+32) based on whether the DER-encoded\r
+ // ContentInfo structure is present or not, and can be calculated based on two\r
+ // bytes of length encoding.\r
+ //\r
+ // Both condition can be handled in WrapPkcs7Data() in CryptPkcs7VerifyCommon.c.\r
+ //\r
+ // See below examples:\r
+ //\r
+ // 1. Without ContentInfo\r
+ // 30 82 0c da // SEQUENCE (5 element) (3294 BYTES) -- SignedData\r
+ // 02 01 01 // INTEGER 1 -- Version\r
+ // 31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers\r
+ // 30 0d // SEQUENCE (2 element) (13 BYTES) -- AlgorithmIdentifier\r
+ // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm\r
+ // 60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]\r
+ // 05 00 // NULL (0 BYTES) -- parameters\r
+ //\r
+ // Example from: https://uefi.org/revocationlistfile\r
+ //\r
+ // 2. With ContentInfo\r
+ // 30 82 05 90 // SEQUENCE (1424 BYTES) -- ContentInfo\r
+ // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- ContentType\r
+ // 2a 86 48 86 f7 0d 01 07 02 // signedData [1.2.840.113549.1.7.2]\r
+ // a0 82 05 81 // CONTEXT-SPECIFIC CONSTRUCTED TAG 0 (1409 BYTES) -- content\r
+ // 30 82 05 7d // SEQUENCE (1405 BYTES) -- SignedData\r
+ // 02 01 01 // INTEGER 1 -- Version\r
+ // 31 0f // SET (1 element) (15 BYTES) -- DigestAlgorithmIdentifiers\r
+ // 30 0d // SEQUENCE (13 BYTES) -- AlgorithmIdentifier\r
+ // 06 09 // OBJECT-IDENTIFIER (9 BYTES) -- algorithm\r
+ // 60 86 48 01 65 03 04 02 01 // sha256 [2.16.840.1.101.3.4.2.1]\r
+ // 05 00 // NULL (0 BYTES) -- parameters\r
+ //\r
+ // Example generated with: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Manual_process\r
+ //\r
+ if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ if ( ( (SigDataSize >= (13 + sizeof (mSha256OidValue)))\r
+ && ( ((*(SigData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)\r
+ || (CompareMem (SigData + 13, &mSha256OidValue, sizeof (mSha256OidValue)) != 0)))\r
+ && ( (SigDataSize >= (32 + sizeof (mSha256OidValue)))\r
+ && ( ((*(SigData + 20) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)\r
+ || (CompareMem (SigData + 32, &mSha256OidValue, sizeof (mSha256OidValue)) != 0))))\r
+ {\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+ }\r
\r
//\r
// Find out the new data payload which follows Pkcs7 SignedData directly.\r
//\r
- PayloadPtr = SigData + SigDataSize;\r
- PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN) SigDataSize;\r
+ PayloadPtr = SigData + SigDataSize;\r
+ PayloadSize = DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN)SigDataSize;\r
+\r
+ // If the VariablePolicy engine is disabled, allow deletion of any authenticated variables.\r
+ if ((PayloadSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && !IsVariablePolicyEnabled ()) {\r
+ VerifyStatus = TRUE;\r
+ goto Exit;\r
+ }\r
\r
//\r
// Construct a serialization buffer of the values of the VariableName, VendorGuid and Attributes\r
// because it is only used at here to do verification temporarily first\r
// and then used in UpdateVariable() for a time based auth variable set.\r
//\r
- Status = mAuthVarLibContextIn->GetScratchBuffer (&NewDataSize, (VOID **) &NewData);\r
+ Status = mAuthVarLibContextIn->GetScratchBuffer (&NewDataSize, (VOID **)&NewData);\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
SigDataSize,\r
&SignerCerts,\r
&CertStackSize,\r
- &RootCert,\r
- &RootCertSize\r
+ &TopLevelCert,\r
+ &TopLevelCertSize\r
);\r
if (!VerifyStatus) {\r
goto Exit;\r
VerifyStatus = FALSE;\r
goto Exit;\r
}\r
- CertList = (EFI_SIGNATURE_LIST *) Data;\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
- if ((RootCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||\r
- (CompareMem (Cert->SignatureData, RootCert, RootCertSize) != 0)) {\r
+\r
+ CertList = (EFI_SIGNATURE_LIST *)Data;\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ if ((TopLevelCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) ||\r
+ (CompareMem (Cert->SignatureData, TopLevelCert, TopLevelCertSize) != 0))\r
+ {\r
VerifyStatus = FALSE;\r
goto Exit;\r
}\r
VerifyStatus = Pkcs7Verify (\r
SigData,\r
SigDataSize,\r
- RootCert,\r
- RootCertSize,\r
+ TopLevelCert,\r
+ TopLevelCertSize,\r
NewData,\r
NewDataSize\r
);\r
-\r
} else if (AuthVarType == AuthVarTypeKek) {\r
-\r
//\r
// Get KEK database from variable.\r
//\r
//\r
// Ready to verify Pkcs7 SignedData. Go through KEK Signature Database to find out X.509 CertList.\r
//\r
- KekDataSize = (UINT32) DataSize;\r
- CertList = (EFI_SIGNATURE_LIST *) Data;\r
+ KekDataSize = (UINT32)DataSize;\r
+ CertList = (EFI_SIGNATURE_LIST *)Data;\r
while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) {\r
if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
- CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
for (Index = 0; Index < CertCount; Index++) {\r
//\r
// Iterate each Signature Data Node within this CertList for a verify\r
//\r
- RootCert = Cert->SignatureData;\r
- RootCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
+ TrustedCert = Cert->SignatureData;\r
+ TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
\r
//\r
// Verify Pkcs7 SignedData via Pkcs7Verify library.\r
VerifyStatus = Pkcs7Verify (\r
SigData,\r
SigDataSize,\r
- RootCert,\r
- RootCertSize,\r
+ TrustedCert,\r
+ TrustedCertSize,\r
NewData,\r
NewDataSize\r
);\r
if (VerifyStatus) {\r
goto Exit;\r
}\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
}\r
}\r
+\r
KekDataSize -= CertList->SignatureListSize;\r
- CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
}\r
} else if (AuthVarType == AuthVarTypePriv) {\r
-\r
//\r
// Process common authenticated variable except PK/KEK/DB/DBX/DBT.\r
// Get signer's certificates from SignedData.\r
SigDataSize,\r
&SignerCerts,\r
&CertStackSize,\r
- &RootCert,\r
- &RootCertSize\r
+ &TopLevelCert,\r
+ &TopLevelCertSize\r
);\r
if (!VerifyStatus) {\r
goto Exit;\r
}\r
\r
//\r
- // Get previously stored signer's certificates from certdb for existing\r
+ // Get previously stored signer's certificates from certdb or certdbv for existing\r
// variable. Check whether they are identical with signer's certificates\r
// in SignedData. If not, return error immediately.\r
//\r
if (OrgTimeStamp != NULL) {\r
VerifyStatus = FALSE;\r
\r
- Status = GetCertsFromDb (VariableName, VendorGuid, &CertsInCertDb, &CertsSizeinDb);\r
+ Status = GetCertsFromDb (VariableName, VendorGuid, Attributes, &CertsInCertDb, &CertsSizeinDb);\r
if (EFI_ERROR (Status)) {\r
goto Exit;\r
}\r
\r
- if ((CertStackSize != CertsSizeinDb) ||\r
- (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0)) {\r
- goto Exit;\r
+ if (CertsSizeinDb == SHA256_DIGEST_SIZE) {\r
+ //\r
+ // Check hash of signer cert CommonName + Top-level issuer tbsCertificate against data in CertDb\r
+ //\r
+ CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);\r
+ Status = CalculatePrivAuthVarSignChainSHA256Digest (\r
+ CertDataPtr->CertDataBuffer,\r
+ ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),\r
+ TopLevelCert,\r
+ TopLevelCertSize,\r
+ Sha256Digest\r
+ );\r
+ if (EFI_ERROR (Status) || (CompareMem (Sha256Digest, CertsInCertDb, CertsSizeinDb) != 0)) {\r
+ goto Exit;\r
+ }\r
+ } else {\r
+ //\r
+ // Keep backward compatible with previous solution which saves whole signer certs stack in CertDb\r
+ //\r
+ if ((CertStackSize != CertsSizeinDb) ||\r
+ (CompareMem (SignerCerts, CertsInCertDb, CertsSizeinDb) != 0))\r
+ {\r
+ goto Exit;\r
+ }\r
}\r
}\r
\r
VerifyStatus = Pkcs7Verify (\r
SigData,\r
SigDataSize,\r
- RootCert,\r
- RootCertSize,\r
+ TopLevelCert,\r
+ TopLevelCertSize,\r
NewData,\r
NewDataSize\r
);\r
\r
if ((OrgTimeStamp == NULL) && (PayloadSize != 0)) {\r
//\r
- // Insert signer's certificates when adding a new common authenticated variable.\r
- //\r
- Status = InsertCertsToDb (VariableName, VendorGuid, SignerCerts, CertStackSize);\r
+ // When adding a new common authenticated variable, always save Hash of cn of signer cert + tbsCertificate of Top-level issuer\r
+ //\r
+ CertDataPtr = (EFI_CERT_DATA *)(SignerCerts + 1);\r
+ Status = InsertCertsToDb (\r
+ VariableName,\r
+ VendorGuid,\r
+ Attributes,\r
+ CertDataPtr->CertDataBuffer,\r
+ ReadUnaligned32 ((UINT32 *)&(CertDataPtr->CertDataLength)),\r
+ TopLevelCert,\r
+ TopLevelCertSize\r
+ );\r
if (EFI_ERROR (Status)) {\r
VerifyStatus = FALSE;\r
goto Exit;\r
}\r
}\r
} else if (AuthVarType == AuthVarTypePayload) {\r
- CertList = (EFI_SIGNATURE_LIST *) PayloadPtr;\r
- Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
- RootCert = Cert->SignatureData;\r
- RootCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
+ CertList = (EFI_SIGNATURE_LIST *)PayloadPtr;\r
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+ TrustedCert = Cert->SignatureData;\r
+ TrustedCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1);\r
//\r
// Verify Pkcs7 SignedData via Pkcs7Verify library.\r
//\r
VerifyStatus = Pkcs7Verify (\r
SigData,\r
SigDataSize,\r
- RootCert,\r
- RootCertSize,\r
+ TrustedCert,\r
+ TrustedCertSize,\r
NewData,\r
NewDataSize\r
);\r
\r
Exit:\r
\r
- if (AuthVarType == AuthVarTypePk || AuthVarType == AuthVarTypePriv) {\r
- Pkcs7FreeSigners (RootCert);\r
- Pkcs7FreeSigners (SignerCerts);\r
+ if ((AuthVarType == AuthVarTypePk) || (AuthVarType == AuthVarTypePriv)) {\r
+ if (TopLevelCert != NULL) {\r
+ Pkcs7FreeSigners (TopLevelCert);\r
+ }\r
+\r
+ if (SignerCerts != NULL) {\r
+ Pkcs7FreeSigners (SignerCerts);\r
+ }\r
}\r
\r
if (!VerifyStatus) {\r
return EFI_SECURITY_VIOLATION;\r
}\r
\r
- Status = CheckSignatureListFormat(VariableName, VendorGuid, PayloadPtr, PayloadSize);\r
+ Status = CheckSignatureListFormat (VariableName, VendorGuid, PayloadPtr, PayloadSize);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- *VarPayloadPtr = PayloadPtr;\r
+ *VarPayloadPtr = PayloadPtr;\r
*VarPayloadSize = PayloadSize;\r
\r
return EFI_SUCCESS;\r
**/\r
EFI_STATUS\r
VerifyTimeBasedPayloadAndUpdate (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes,\r
- IN AUTHVAR_TYPE AuthVarType,\r
- OUT BOOLEAN *VarDel\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes,\r
+ IN AUTHVAR_TYPE AuthVarType,\r
+ OUT BOOLEAN *VarDel\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_STATUS FindStatus;\r
- UINT8 *PayloadPtr;\r
- UINTN PayloadSize;\r
- EFI_VARIABLE_AUTHENTICATION_2 *CertData;\r
- AUTH_VARIABLE_INFO OrgVariableInfo;\r
- BOOLEAN IsDel;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS FindStatus;\r
+ UINT8 *PayloadPtr;\r
+ UINTN PayloadSize;\r
+ EFI_VARIABLE_AUTHENTICATION_2 *CertData;\r
+ AUTH_VARIABLE_INFO OrgVariableInfo;\r
+ BOOLEAN IsDel;\r
\r
ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));\r
FindStatus = mAuthVarLibContextIn->FindVariable (\r
- VariableName,\r
- VendorGuid,\r
- &OrgVariableInfo\r
- );\r
+ VariableName,\r
+ VendorGuid,\r
+ &OrgVariableInfo\r
+ );\r
\r
Status = VerifyTimeBasedPayload (\r
VariableName,\r
return Status;\r
}\r
\r
- if (!EFI_ERROR(FindStatus)\r
- && (PayloadSize == 0)\r
- && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
+ if ( !EFI_ERROR (FindStatus)\r
+ && (PayloadSize == 0)\r
+ && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0))\r
+ {\r
IsDel = TRUE;\r
} else {\r
IsDel = FALSE;\r
}\r
\r
- CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;\r
+ CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;\r
\r
//\r
// Final step: Update/Append Variable if it pass Pkcs7Verify\r
//\r
// Delete signer's certificates when delete the common authenticated variable.\r
//\r
- if (IsDel && AuthVarType == AuthVarTypePriv && !EFI_ERROR(Status) ) {\r
- Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
+ if (IsDel && (AuthVarType == AuthVarTypePriv) && !EFI_ERROR (Status)) {\r
+ Status = DeleteCertsFromDb (VariableName, VendorGuid, Attributes);\r
}\r
\r
if (VarDel != NULL) {\r
- if (IsDel && !EFI_ERROR(Status)) {\r
+ if (IsDel && !EFI_ERROR (Status)) {\r
*VarDel = TRUE;\r
} else {\r
*VarDel = FALSE;\r