- 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
- )\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
-\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
- 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
- VOID *AuditVarData;\r
- VOID *DeployedVarData;\r
- VOID *SetupVarData;\r
- VOID *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
- VOID *DeployedVarData;\r
- VOID *SetupVarData;\r
- VOID *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
- VOID *AuditVarData;\r
- VOID *DeployedVarData;\r
- VOID *SetupVarData;\r
- VOID *PkVarData;\r
- VOID *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
- VOID *AuditVarData;\r
- VOID *SetupVarData;\r
- VOID *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
-\r
- return Status;\r