alder_lake_bios/Insyde/InsydeModulePkg/Universal/Variable/VariableRuntimeDxe/SecureBoot.c

1882 lines
59 KiB
C

/** @file
Provide support functions for Secure Boot.
;******************************************************************************
;* Copyright (c) 2012 - 2021, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "SecureBoot.h"
#include "AuthService.h"
#include "VariableLock.h"
#include "SensitiveVariable.h"
#include "VariableCache.h"
#include "VarCheck.h"
SMI_SUB_FUNCTION_MAP mSecureBootFunctionsTable [] = {
{ ADD_HASH_IMAGE_FUN_NUM, SmmAddFileHashImage , FALSE}, \
{ SECURE_BOOT_ENFORCE_FUN_NUM, SmmUpdateSecureBootEnforce , FALSE}, \
{ CLEAR_ALL_SECURE_SETTINGS_FUN_NUM, SmmClearAllSecureSettings , FALSE}, \
{ RESTORE_FACTORY_DEFAULT_FUN_NUM, SmmRestoreFactoryDefault , FALSE}, \
{ UPDATE_PK_FUN_NUM, SmmUpdatePkVariable , FALSE}, \
{ UPDATE_KEK_FUN_NUM, SmmUpdateKekVariable , FALSE}, \
{ UPDATE_DB_FUN_NUM, SmmUpdateDbVariable , FALSE}, \
{ UPDATE_DBX_FUN_NUM, SmmUpdateDbxVariable , FALSE}, \
{ UPDATE_DBT_FUN_NUM, SmmUpdateDbtVariable , FALSE}, \
{ UPDATE_DBR_FUN_NUM, SmmUpdateDbrVariable , FALSE}, \
{ CLEAR_DEPLOYED_MODE_VALUE_FUN_NUM, SmmClearDeployedMode , FALSE}, \
{ SELECT_SECURE_BOOT_MODE_FUN_NUM, SmmSelectSecureBootMode , FALSE}, \
{ SET_SENSITIVE_VARIABLE_FUN_NUM, SmmSetSensitiveVariable , TRUE}, \
{ SMM_VARIABLE_LOCK_FUN_NUM, SmmCreateVariableLockList , TRUE}, \
{ LEGACY_BOOT_SMI_FUN_NUM, SmmLegacyBootEvent , TRUE}, \
{ SMM_SET_VARIABLE_SMI_FUN_NUM, SmmInternalSetVariable , TRUE}, \
{ DISABLE_VARIABLE_CACHE_SMI_FUN_NUM, SmmDisableVariableCache , TRUE}, \
{ DISABLE_SECURE_BOOT_SMI_FUN_NUM, SmmDisableSecureBootSmi , TRUE}, \
{ UPDATE_VARIABLE_PROPERTY_FUN_NUM, SmmUpdateVariablePropertySmi , TRUE}, \
{ 0, NULL , TRUE}
};
SECURE_BOOT_SUB_FUNCTION_MAP mNonSmiSecureBootFunctionsTable[] = {
{ EFI_ADD_HASH_IMMAGE_NAME, RuntimeDxeAddFileHashImage }, \
{ EFI_SECURE_BOOT_ENFORCE_NAME, RuntimeDxeUpdateSecureBootEnforce }, \
{ EFI_CLEAR_ALL_SECURE_SETTINGS_NAME, RuntimeDxeClearAllSecureSettings }, \
{ EFI_RESTORE_FACTORY_DEFAULT_NAME, RuntimeDxeRestoreFactoryDefault }, \
{ EFI_PLATFORM_KEY_NAME, RuntimeDxeUpdatePkVariable }, \
{ EFI_KEY_EXCHANGE_KEY_NAME, RuntimeDxeUpdateKekVariable }, \
{ EFI_IMAGE_SECURITY_DATABASE, RuntimeDxeUpdateDbVariable }, \
{ EFI_IMAGE_SECURITY_DATABASE1, RuntimeDxeUpdateDbxVariable }, \
{ EFI_IMAGE_SECURITY_DATABASE2, RuntimeDxeUpdateDbtVariable }, \
{ EFI_IMAGE_SECURITY_DATABASE3, RuntimeDxeUpdateDbrVariable }, \
{ EFI_CLEAR_DEPLOYED_MODE_NAME, RuntimeDxeClearDeployedMode }, \
{ NULL, NULL }
};
/**
This function is an internal function which used for update normal
authenticated
@param VariableName Name of Variable to be found
@param VendorGuid Variable vendor GUID
@param DataSize Size of Data found. If size is less than the data, this value contains the required size.
@param Data Data pointer
@param UpdateKey Boolean value to indicate want to update key or not.
Retruns:
@retval EFI_SUCCESS The update operation is success.
@return EFI_OUT_OF_RESOURCES Variable region is full, can not write other data into this region.
**/
STATIC
EFI_STATUS
InternalUpdateAuthVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINTN DataSize,
IN VOID *Data,
IN BOOLEAN UpdateKey
)
{
UINT8 *VariableBuffer;
EFI_VARIABLE_AUTHENTICATION *CertData;
UINTN VariableCount;
VARIABLE_POINTER_TRACK Variable;
UINT32 KeyIndex;
if (UpdateKey) {
if (DataSize < AUTHINFO_SIZE) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *) Data;
CertData = (EFI_VARIABLE_AUTHENTICATION *) VariableBuffer;
FindVariableByLifetime (
VariableName,
VendorGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
KeyIndex = 0;
return UpdateVariable (
VariableName,
VendorGuid,
VariableBuffer + AUTHINFO_SIZE,
DataSize - AUTHINFO_SIZE,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
KeyIndex,
CertData->MonotonicCount,
&Variable,
NULL,
&mVariableModuleGlobal->VariableBase
);
} else {
FindVariableByLifetime (
VariableName,
VendorGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
return UpdateVariable (
VariableName,
VendorGuid,
Data,
DataSize,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
0,
0,
&Variable,
NULL,
&mVariableModuleGlobal->VariableBase
);
}
}
/**
Internal function to update secure boot database variable.
@param[in] VariableName Name of Variable to be found
@param[in] VendorGuid Variable vendor GUID
@param[in] DataSize Size of Data found. If size is less than the data, this value contains the required size.
@param[in] Data Data pointer
@param[in] UpdateType The Input update type. This update type should be UPDATE_AUTHENTICATED_VARIABLE
or APPEND_AUTHENTICATED_VARIABLE.
@retval EFI_SUCCESS update secure boot database variable successfully.
@retval EFI_INVALID_PARAMETER Any input parameter is incorrect.
@retval Other Set variable failed in this function.
**/
STATIC
EFI_STATUS
InternalUpdateSecureDatabaseVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINTN DataSize,
IN VOID *Data,
IN UINT8 UpdateType
)
{
EFI_VARIABLE_AUTHENTICATION_2 *CertData;
UINT8 *VariableBuffer;
EFI_SIGNATURE_LIST *SigList;
UINTN VariableCount;
VARIABLE_POINTER_TRACK Variable;
EFI_STATUS Status;
UINT32 Attribute;
BOOLEAN DelPk;
if (VariableName == NULL || VendorGuid == NULL || Data == NULL) {
return EFI_INVALID_PARAMETER;
}
if (UpdateType != UPDATE_AUTHENTICATED_VARIABLE && UpdateType != APPEND_AUTHENTICATED_VARIABLE) {
return EFI_INVALID_PARAMETER;
}
if (!IsSecureDatabaseVariable (VariableName, VendorGuid)) {
return EFI_INVALID_PARAMETER;
}
if (IsPkVariable (VariableName, VendorGuid) && UpdateType != UPDATE_AUTHENTICATED_VARIABLE) {
return EFI_INVALID_PARAMETER;
}
if (DataSize < AUTHINFO2_SIZE (Data) || DataSize > MAX_VARIABLE_SIZE) {
return EFI_INVALID_PARAMETER;
}
VariableBuffer = (UINT8 *) Data;
CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) VariableBuffer;
if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
!CompareGuid (&CertData->AuthInfo.CertType, &gEfiCertPkcs7Guid)) {
return EFI_INVALID_PARAMETER;;
}
SigList = (EFI_SIGNATURE_LIST *) (VariableBuffer + AUTHINFO2_SIZE (VariableBuffer));
FindVariableByLifetime (
VariableName,
VendorGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
if (UpdateType == APPEND_AUTHENTICATED_VARIABLE) {
Attribute |= EFI_VARIABLE_APPEND_WRITE;
}
DelPk = (DataSize - AUTHINFO2_SIZE (VariableBuffer)) == 0 ? TRUE : FALSE;
Status = UpdateVariable (
VariableName,
VendorGuid,
SigList,
DataSize - AUTHINFO2_SIZE (VariableBuffer),
Attribute,
0,
0,
&Variable,
&CertData->TimeStamp,
&mVariableModuleGlobal->VariableBase
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update secure boot mode if PK present is changed.
//
if (IsPkVariable (VariableName, VendorGuid)) {
if (mPlatformMode == USER_MODE && DelPk && !DoesPkExist ()) {
ChangeSecureBootModeByDeletePk ();
} else if (mPlatformMode == SETUP_MODE && !DelPk) {
ChangeSecureBootModeByInsertPk ();
}
}
//
// Set "CustomSecurity" variable to 1 indicates secure boot database has been modified by user.
//
Status = UpdateCustomSecurityStatus (1);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Append new hash image to EFI_IMAGE_SECURITY_DATABASE (db)
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
CommonAddFileHashImage (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_SIGNATURE_LIST *SigList;
EFI_VARIABLE_AUTHENTICATION_2 *CertData2;
UINTN VariableCount;
VARIABLE_POINTER_TRACK Variable;
EFI_STATUS Status;
if (DataSize != (AUTHINFO2_SIZE (Data) + sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + SHA256_DIGEST_SIZE) &&
DataSize != (AUTHINFO2_SIZE (Data) + sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + SHA1_DIGEST_SIZE)) {
return EFI_UNSUPPORTED;
}
CertData2 = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;
SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) Data + AUTHINFO2_SIZE (Data));
if (!CompareGuid (&SigList->SignatureType, &gEfiCertSha256Guid) &&
!CompareGuid (&SigList->SignatureType, &gEfiCertSha1Guid)) {
return EFI_UNSUPPORTED;
}
FindVariableByLifetime (
EFI_IMAGE_SECURITY_DATABASE,
&gEfiImageSecurityDatabaseGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
Status = UpdateVariable (
VariableName,
VendorGuid,
SigList,
DataSize - AUTHINFO2_SIZE (Data),
Attributes,
0,
0,
&Variable,
&CertData2->TimeStamp,
&mVariableModuleGlobal->VariableBase
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Set "CustomSecurity" variable to 1 indicates secure boot database has been modified by user.
//
Status = UpdateCustomSecurityStatus (1);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
This function uses to check secure boot enforce is enabled or disabled.
@retval TRUE Secure boot enforce is enabled.
@retval FALSE Secure boot enforce is disabled.
**/
BOOLEAN
IsSecureBootEnforceEnabled (
VOID
)
{
UINTN VariableCount;
VARIABLE_POINTER_TRACK Variable;
UINT8 *SecureBootEnforceEnabled;
VariableCount = 0;
FindVariableByLifetime (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
ASSERT (Variable.CurrPtr != NULL && DataSizeOfVariable (Variable.CurrPtr) == sizeof (UINT8));
SecureBootEnforceEnabled = GetVariableDataPtr (Variable.CurrPtr);
return (BOOLEAN) *SecureBootEnforceEnabled;
}
/**
Update EFI_SECURE_BOOT_ENFORCE_NAME variable.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
CommoneUpdateSecureBootEnforce (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize
)
{
EFI_STATUS Status;
if (DataSize != (AUTHINFO_SIZE + sizeof (UINT8))) {
return EFI_UNSUPPORTED;
}
Status = InternalUpdateAuthVariable (
VariableName,
VendorGuid,
DataSize,
Data,
TRUE
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
if (!IsSecureBootEnforceEnabled ()) {
UpdatePlatformBootMode (SECURE_BOOT_MODE_DISABLE, &mVariableModuleGlobal->VariableBase);
}
return Status;
}
/**
This function uses to clear PK, KEK, db and dbx variable
@retval EFI_SUCCESS Clear secure settins successful.
@return Other Any error occurred while clearing secure settins
**/
STATIC
EFI_STATUS
CommonClearAllSecureSettings (
VOID
)
{
EFI_STATUS Status;
Status = ClearSecureSettings (&mVariableModuleGlobal->VariableBase);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Set "CustomSecurity" variable to 1 indicates secure boot database has been modified by user.
//
Status = UpdateCustomSecurityStatus (1);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
This function uses to clear DeployedMode value to 0 and update the related
variables' property.
@retval EFI_SUCCESS Clear DeployedMode value successful.
@return Other Any error occurred while clear DeployedMode value to 0
**/
EFI_STATUS
CommonClearDeployedMode (
VOID
)
{
EFI_STATUS Status;
if (!FeaturePcdGet (PcdH2OCustomizedSecureBootSupported)) {
return EFI_UNSUPPORTED;
}
Status = UpdateDeployedModeValue (0);
if (Status == EFI_SUCCESS) {
UpdateDeployedModeProperty (0);
UpdateAuditModeProperty (0);
}
return Status;
}
/**
UUpdate "RestoreFactoryDefault" EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS variable.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
CommoneRestoreFactoryDefault (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize
)
{
EFI_STATUS Status;
if (DataSize != (AUTHINFO_SIZE + sizeof (UINT8))) {
return EFI_UNSUPPORTED;
}
Status = InternalUpdateAuthVariable (
VariableName,
VendorGuid,
DataSize,
Data,
TRUE
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Set "CustomSecurity" variable to 0 indicates secure boot database has been restored to factory by user.
//
Status = UpdateCustomSecurityStatus (0);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Add selected file hash image to allowed database (db)
@retval EFI_SUCCESS Add image hash to allowed database (db) successful.
@return Other Any error occurred while updating hash to allowed database (db)
**/
EFI_STATUS
SmmAddFileHashImage (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
return CommonAddFileHashImage (
EFI_IMAGE_SECURITY_DATABASE,
&gEfiImageSecurityDatabaseGuid,
VariableBuffer,
BufferSize,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS |
EFI_VARIABLE_APPEND_WRITE
);
}
/**
Update "SecureBootEnforce" EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS variable
@retval EFI_SUCCESS Update "SecureBootEnforce" variable successful.
@return Other Any error occurred while updating "SecureBootEnforce" variable
**/
EFI_STATUS
SmmUpdateSecureBootEnforce (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
return CommoneUpdateSecureBootEnforce (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
VariableBuffer,
BufferSize
);
}
/**
This function uses to clear PK, KEK, db and dbx variable
@retval EFI_SUCCESS Clear secure settins successful.
@return Other Any error occurred while clearing secure settins
**/
EFI_STATUS
SmmClearAllSecureSettings (
VOID
)
{
return CommonClearAllSecureSettings ();
}
/**
Update "RestoreFactoryDefault" EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS variable
@retval EFI_SUCCESS Update "RestoreFactoryDefault" variable successful.
@return Other Any error occurred while updating "RestoreFactoryDefault" variable
**/
EFI_STATUS
SmmRestoreFactoryDefault (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
return CommoneRestoreFactoryDefault (
EFI_RESTORE_FACTORY_DEFAULT_NAME,
&gEfiGenericVariableGuid,
VariableBuffer,
BufferSize
);
}
/**
This function uses to update PK variable.
@retval EFI_SUCCESS Update PK variable successfully.
@retval Other Any error occurred while updating PK variable.
**/
EFI_STATUS
SmmUpdatePkVariable (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
EFI_STATUS Status;
UINT8 Updatetype;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
Updatetype = *(VariableBuffer + AUTHINFO2_SIZE (VariableBuffer) - 1);
Status = InternalUpdateSecureDatabaseVariable (
EFI_PLATFORM_KEY_NAME,
&gEfiGlobalVariableGuid,
BufferSize,
VariableBuffer,
Updatetype
);
return Status;
}
/**
This function uses to update KEK variable.
@retval EFI_SUCCESS Update KEK variable successfully.
@retval Other Any error occurred while updating KEK variable.
**/
EFI_STATUS
SmmUpdateKekVariable (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
EFI_STATUS Status;
UINT8 Updatetype;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
Updatetype = *(VariableBuffer + AUTHINFO2_SIZE (VariableBuffer) - 1);
Status = InternalUpdateSecureDatabaseVariable (
EFI_KEY_EXCHANGE_KEY_NAME,
&gEfiGlobalVariableGuid,
BufferSize,
VariableBuffer,
Updatetype
);
return Status;
}
/**
This function uses to update db variable.
@retval EFI_SUCCESS Update db variable successfully.
@retval Other Any error occurred while updating db variable
**/
EFI_STATUS
SmmUpdateDbVariable (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
EFI_STATUS Status;
UINT8 Updatetype;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
Updatetype = *(VariableBuffer + AUTHINFO2_SIZE (VariableBuffer) - 1);
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE,
&gEfiImageSecurityDatabaseGuid,
BufferSize,
VariableBuffer,
Updatetype
);
return Status;
}
/**
This function uses to update dbx variable.
@retval EFI_SUCCESS Update dbx variable successfully.
@retval Other Any error occurred while updating dbx variable
**/
EFI_STATUS
SmmUpdateDbxVariable (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
EFI_STATUS Status;
UINT8 Updatetype;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
Updatetype = *(VariableBuffer + AUTHINFO2_SIZE (VariableBuffer) - 1);
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE1,
&gEfiImageSecurityDatabaseGuid,
BufferSize,
VariableBuffer,
Updatetype
);
return Status;
}
/**
This function uses to update dbt variable.
@retval EFI_SUCCESS Update dbt variable successfully.
@retval Other Any error occurred while updating dbt variable
**/
EFI_STATUS
SmmUpdateDbtVariable (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
EFI_STATUS Status;
UINT8 Updatetype;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
Updatetype = *(VariableBuffer + AUTHINFO2_SIZE (VariableBuffer) - 1);
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE2,
&gEfiImageSecurityDatabaseGuid,
BufferSize,
VariableBuffer,
Updatetype
);
return Status;
}
/**
This function uses to update dbr variable.
@retval EFI_SUCCESS Update dbr variable successfully.
@retval Other Any error occurred while updating dbr variable
**/
EFI_STATUS
SmmUpdateDbrVariable (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
EFI_STATUS Status;
UINT8 Updatetype;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
Updatetype = *(VariableBuffer + AUTHINFO2_SIZE (VariableBuffer) - 1);
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE3,
&gEfiImageSecurityDatabaseGuid,
BufferSize,
VariableBuffer,
Updatetype
);
return Status;
}
/**
This function uses to clear DeployedMode variable.
@retval EFI_SUCCESS Update PK variable successfully.
@retval Other Any error occurred while updating PK variable.
**/
EFI_STATUS
SmmClearDeployedMode (
VOID
)
{
return CommonClearDeployedMode ();
}
/**
This function uses to get current secur boot mode.
@return SecureBootMode Current secure boot mode.
**/
STATIC
UINT8
GetSecureBootMode (
VOID
)
{
UINTN VariableCount;
VARIABLE_POINTER_TRACK SetupModeVariable;
EFI_STATUS Status;
if (DeployedModeValue () == 1) {
return H2O_DEPLOYED_MODE;
} else if (AuditModeValue () == 1) {
return H2O_AUDIT_MODE;
}
VariableCount = 0;
Status = FindVariableByLifetime (
EFI_SETUP_MODE_NAME,
&gEfiGlobalVariableGuid,
&SetupModeVariable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
if (Status == EFI_SUCCESS && SetupModeVariable.CurrPtr &&
*GetVariableDataPtr (SetupModeVariable.CurrPtr) == 0) {
return H2O_USER_MODE;
}
return H2O_SETUP_MODE;
}
/**
This function uses to delete PK and change secure boot mode to correct mode.
**/
VOID
DeletePkVariable (
VOID
)
{
UINTN VariableCount;
VARIABLE_POINTER_TRACK Variable;
VariableCount = 0;
FindVariableByLifetime (
EFI_PLATFORM_KEY_NAME,
&gEfiGlobalVariableGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
UpdateVariable (
EFI_PLATFORM_KEY_NAME,
&gEfiGlobalVariableGuid,
NULL,
0,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
0,
0,
&Variable,
NULL,
&mVariableModuleGlobal->VariableBase
);
ChangeSecureBootModeByDeletePk ();
}
/**
This function uses to change secure boot mode.
@retval EFI_SUCCESS Change secure boot mode successfully.
@retval Other Any error occurred while changing secure boot mode.
**/
EFI_STATUS
SmmSelectSecureBootMode (
VOID
)
{
UINTN BufferSize;
UINT8 *VariableBuffer;
UINT8 NewSecureBootMode;
UINT8 SecureBootMode;
EFI_STATUS Status;
if (!FeaturePcdGet (PcdH2OCustomizedSecureBootSupported)) {
return EFI_UNSUPPORTED;
}
VariableBuffer = (UINT8 *)(mVariableModuleGlobal->SmmVarBuf + 1);
BufferSize = mVariableModuleGlobal->SmmVarBuf->DataSize;
if (BufferSize != (AUTHINFO_SIZE + sizeof (UINT8))) {
return EFI_UNSUPPORTED;
}
NewSecureBootMode = VariableBuffer[BufferSize - 1];
SecureBootMode = GetSecureBootMode ();
switch (SecureBootMode) {
case H2O_USER_MODE:
if (NewSecureBootMode == H2O_SETUP_MODE) {
DeletePkVariable ();
} else if (NewSecureBootMode == H2O_AUDIT_MODE) {
DeletePkVariable ();
Status = UpdateAuditModeValue (1);
if (!EFI_ERROR (Status)) {
UpdateAuditModeProperty (VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY);
}
} else if (NewSecureBootMode == H2O_DEPLOYED_MODE) {
Status = UpdateDeployedModeValue (1);
if (!EFI_ERROR (Status)) {
UpdateDeployedModeProperty (VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY);
}
}
break;
case H2O_SETUP_MODE:
if (NewSecureBootMode == H2O_AUDIT_MODE) {
Status = UpdateAuditModeValue (1);
if (!EFI_ERROR (Status)) {
UpdateAuditModeProperty (VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY);
}
}
break;
case H2O_AUDIT_MODE:
if (NewSecureBootMode == H2O_SETUP_MODE) {
Status = UpdateAuditModeValue (0);
if (!EFI_ERROR (Status)) {
UpdateAuditModeProperty (0);
}
}
break;
case H2O_DEPLOYED_MODE:
if (NewSecureBootMode == H2O_USER_MODE) {
CommonClearDeployedMode ();
} else if (NewSecureBootMode == H2O_SETUP_MODE) {
DeletePkVariable ();
} else if (NewSecureBootMode == H2O_AUDIT_MODE) {
DeletePkVariable ();
Status = UpdateAuditModeValue (1);
if (!EFI_ERROR (Status)) {
UpdateAuditModeProperty (VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY);
}
}
break;
}
return EFI_SUCCESS;
}
/**
This function uses to disable all of secure boot SMI functions
@retval EFI_SUCCESS Disable all secure boot SMI functions successful.
@return Other Any error occurred while disabling all secure boot SMI functions successful.
**/
EFI_STATUS
SmmDisableSecureBootSmi (
VOID
)
{
mReadyToBootEventSignaled = TRUE;
return EFI_SUCCESS;
}
/**
Use variable name and variable GUID to get relative SMM function index.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param FunctionIndex Pointer to save output function index, if this pointer isn't NULL.
@retval TRUE This variable is a administer secure boot relative variable.
@retval FALSE This variable isn't a administer secure boot relative variable
**/
EFI_STATUS
GetSecureBootFunctionIndex (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINTN *FunctionIndex OPTIONAL
)
{
UINTN Index;
EFI_STATUS Status;
Status = EFI_NOT_FOUND;
if (VariableName == NULL || VendorGuid == NULL) {
return Status;
}
if (!CompareGuid (VendorGuid, &gEfiGenericVariableGuid)) {
return Status;
}
for (Index = 0; mNonSmiSecureBootFunctionsTable[Index].VariableName != NULL; Index++) {
if (!StrCmp (mNonSmiSecureBootFunctionsTable[Index].VariableName, VariableName)) {
Status = EFI_SUCCESS;
break;
}
}
if (Status == EFI_SUCCESS && FunctionIndex != NULL) {
*FunctionIndex = Index;
}
return Status;
}
/**
Use variable name and variable GUID to check this variable is administer secure boot relative variable
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@retval TRUE This variable is a administer secure boot relative variable.
@retval FALSE This variable isn't a administer secure boot relative variable
**/
BOOLEAN
IsAdministerSecureVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
EFI_STATUS Status;
Status = GetSecureBootFunctionIndex (
VariableName,
VendorGuid,
NULL
);
return Status == EFI_SUCCESS ? TRUE : FALSE;
}
/**
Update administer secure boot relative variable
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
UpdateAdministerSecureVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
UINTN FunctionIndex;
if (VariableName == NULL || VendorGuid == NULL || Data == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = GetSecureBootFunctionIndex (VariableName, VendorGuid, &FunctionIndex);
if (!EFI_ERROR (Status)) {
Status = mNonSmiSecureBootFunctionsTable[FunctionIndex].SecureBootSubFunction (
VariableName,
VendorGuid,
Data,
DataSize,
Attributes
);
}
return Status;
}
/**
Append new hash image to EFI_IMAGE_SECURITY_DATABASE (db)
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
RuntimeDxeAddFileHashImage (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
if (Attributes != (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) {
return EFI_INVALID_PARAMETER;
}
return CommonAddFileHashImage (
EFI_IMAGE_SECURITY_DATABASE,
&gEfiImageSecurityDatabaseGuid,
Data,
DataSize,
Attributes
);
}
/**
Update EFI_SECURE_BOOT_ENFORCE_NAME variable.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
RuntimeDxeUpdateSecureBootEnforce (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
if (Attributes != (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)) {
return EFI_INVALID_PARAMETER;
}
return CommoneUpdateSecureBootEnforce (
VariableName,
VendorGuid,
Data,
DataSize
);
}
/**
clear all secure boot settings.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
RuntimeDxeClearAllSecureSettings (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
if (DataSize != (AUTHINFO_SIZE + sizeof (UINT8))) {
return EFI_UNSUPPORTED;
}
//
// Check input is whether want to clear all secure settings
//
if (*((UINT8 *) Data + AUTHINFO_SIZE) != 1) {
return EFI_UNSUPPORTED;
}
return CommonClearAllSecureSettings ();
}
/**
Update EFI_RESTORE_FACTORY_DEFAULT_NAME variable and then system will restore secure boot
database to factory default during next POST.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Data Data pointer.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected or pass validation successfully.
**/
EFI_STATUS
RuntimeDxeRestoreFactoryDefault (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
if (Attributes != (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)) {
return EFI_INVALID_PARAMETER;
}
return CommoneRestoreFactoryDefault (
VariableName,
VendorGuid,
Data,
DataSize
);
}
/**
This function uses to update PK variable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update PK variable successfully.
@retval Other Any error occurred while updating PK variable.
**/
EFI_STATUS
RuntimeDxeUpdatePkVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
if (Attributes != (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
return EFI_INVALID_PARAMETER;
}
Status = InternalUpdateSecureDatabaseVariable (
EFI_PLATFORM_KEY_NAME,
&gEfiGlobalVariableGuid,
DataSize,
Data,
UPDATE_AUTHENTICATED_VARIABLE
);
return Status;
}
/**
This function uses to update KEK variable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update KEK variable successfully.
@retval Other Any error occurred while updating KEK variable.
**/
EFI_STATUS
RuntimeDxeUpdateKekVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
UINT8 UpdateType;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
UpdateType = UPDATE_AUTHENTICATED_VARIABLE;
} else if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) {
UpdateType = APPEND_AUTHENTICATED_VARIABLE;
} else {
return EFI_INVALID_PARAMETER;
}
Status = InternalUpdateSecureDatabaseVariable (
EFI_KEY_EXCHANGE_KEY_NAME,
&gEfiGlobalVariableGuid,
DataSize,
Data,
UpdateType
);
return Status;
}
/**
This function uses to update db variable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update db variable successfully.
@retval Other Any error occurred while updating db variable.
**/
EFI_STATUS
RuntimeDxeUpdateDbVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
UINT8 UpdateType;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
UpdateType = UPDATE_AUTHENTICATED_VARIABLE;
} else if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) {
UpdateType = APPEND_AUTHENTICATED_VARIABLE;
} else {
return EFI_INVALID_PARAMETER;
}
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE,
&gEfiImageSecurityDatabaseGuid,
DataSize,
Data,
UpdateType
);
return Status;
}
/**
This function uses to update dbx variable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update dbx variable successfully.
@retval Other Any error occurred while updating dbx variable.
**/
EFI_STATUS
RuntimeDxeUpdateDbxVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
UINT8 UpdateType;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
UpdateType = UPDATE_AUTHENTICATED_VARIABLE;
} else if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) {
UpdateType = APPEND_AUTHENTICATED_VARIABLE;
} else {
return EFI_INVALID_PARAMETER;
}
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE1,
&gEfiImageSecurityDatabaseGuid,
DataSize,
Data,
UpdateType
);
return Status;
}
/**
This function uses to update dbt variable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update dbt variable successfully.
@retval Other Any error occurred while updating dbt variable.
**/
EFI_STATUS
RuntimeDxeUpdateDbtVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
UINT8 UpdateType;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
UpdateType = UPDATE_AUTHENTICATED_VARIABLE;
} else if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) {
UpdateType = APPEND_AUTHENTICATED_VARIABLE;
} else {
return EFI_INVALID_PARAMETER;
}
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE2,
&gEfiImageSecurityDatabaseGuid,
DataSize,
Data,
UpdateType
);
return Status;
}
/**
This function uses to update dbr variable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update dbr variable successfully.
@retval Other Any error occurred while updating dbr variable.
**/
EFI_STATUS
RuntimeDxeUpdateDbrVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
EFI_STATUS Status;
UINT8 UpdateType;
if (!PcdGetBool(PcdUpdateSecureBootVariablesSupported)) {
return EFI_UNSUPPORTED;
}
if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
UpdateType = UPDATE_AUTHENTICATED_VARIABLE;
} else if (Attributes == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) {
UpdateType = APPEND_AUTHENTICATED_VARIABLE;
} else {
return EFI_INVALID_PARAMETER;
}
Status = InternalUpdateSecureDatabaseVariable (
EFI_IMAGE_SECURITY_DATABASE3,
&gEfiImageSecurityDatabaseGuid,
DataSize,
Data,
UpdateType
);
return Status;
}
/**
This function uses to clear DeployedMode variable value to 0..
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Attributes Attribute value of the variable.
@retval EFI_SUCCESS Update DeployedMode value to 0 successfully.
@retval Other Any error occurred while updating DeployedMode value to 0.
**/
EFI_STATUS
RuntimeDxeClearDeployedMode (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes
)
{
if (DataSize != (AUTHINFO_SIZE + sizeof (UINT8))) {
return EFI_UNSUPPORTED;
}
//
// Check input is whether want to clear all secure settings
//
if (*((UINT8 *) Data + AUTHINFO_SIZE) != 1) {
return EFI_UNSUPPORTED;
}
return CommonClearDeployedMode ();
}
/**
Initialize all of administer secure boot relative authenticated variables.
@retval EFI_SUCCESS Update all of secure boot relative authenticated variables successful
@retval Other The driver failded to start the device
**/
EFI_STATUS
InitializeAdministerSecureBootVariables (
VOID
)
{
UINTN VariableCount;
VARIABLE_POINTER_TRACK Variable;
EFI_STATUS Status;
//
// create all of Administer secure boot variables if they don't exist to prevent from other tool or
// application can set these variables.
//
VariableCount = 0;
FindVariableByLifetime (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
if (Variable.CurrPtr == NULL) {
Status = UpdateSecureBootEnforceVariable (1);
if (EFI_ERROR (Status)) {
return Status;
}
}
VariableCount = 0;
FindVariableByLifetime (
EFI_RESTORE_FACTORY_DEFAULT_NAME,
&gEfiGenericVariableGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
if (Variable.CurrPtr == NULL) {
Status = UpdateRestoreFactoryDefaultVariable (0);
if (EFI_ERROR (Status)) {
return Status;
}
}
VariableCount = 0;
FindVariableByLifetime (
EFI_CUSTOM_SECURITY_NAME,
&gEfiGenericVariableGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
if (Variable.CurrPtr == NULL) {
Status = UpdateCustomSecurityStatus (0);
if (EFI_ERROR (Status)) {
return Status;
}
} else {
Status = UpdateCustomSecurityStatus (*(GetVariableDataPtr (Variable.CurrPtr)));
}
return EFI_SUCCESS;
}
/**
According input data to update L"SecureBootEnforce" variable
@param Data Input data to update "SecureBootEnforce" variable
@retval EFI_SUCCESS update "SecureBootEnforce" successful.
@retval Other The driver failded to start the device
**/
EFI_STATUS
UpdateSecureBootEnforceVariable (
UINT8 Data
)
{
return InternalUpdateAuthVariable (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
sizeof (UINT8),
&Data,
FALSE
);
}
/**
According input data to update L"RestoreFactoryDefault" variable
@param Data Input data to update "RestoreFactoryDefault" variable
@retval EFI_SUCCESS update "RestoreFactoryDefault" successful.
@retval Other The driver failded to start the device
**/
EFI_STATUS
UpdateRestoreFactoryDefaultVariable (
UINT8 Data
)
{
return InternalUpdateAuthVariable (
EFI_RESTORE_FACTORY_DEFAULT_NAME,
&gEfiGenericVariableGuid,
sizeof (UINT8),
&Data,
FALSE
);
}
/**
According to input data to update custom security status.
In this function, it will update "CustomSecurity" variable and "vendorKeys" variable.
If input Data is 0, it will update "CustomSecurity" to 0 and "vendorKeys" to 1.
If input Data is 1, it will update "CustomSecurity" to 1 and "vendorKeys" to 0.
@param[in] Data Input data to update custom security status.
@retval EFI_SUCCESS Update custom security status successful.
@retval EFI_INVALID_PARAMETER The value of Data isn't 0 or 1.
@retval Other Any error occurred while updating variable.
**/
EFI_STATUS
UpdateCustomSecurityStatus (
IN UINT8 Data
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK Variable;
UINTN VariableCount;
UINT8 VendorKeyData;
if (Data != 0 && Data != 1) {
return EFI_INVALID_PARAMETER;
}
//
// Update "CustomSecurity" variable
//
Status = InternalUpdateAuthVariable (
EFI_CUSTOM_SECURITY_NAME,
&gEfiGenericVariableGuid,
sizeof (UINT8),
&Data,
FALSE
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update "VendorKeys" variable
//
VendorKeyData = Data == 0 ? 1 : 0;
VariableCount = 0;
Status = FindVariableByLifetime (
EFI_VENDOR_KEYS_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
Status = UpdateVariable (
EFI_VENDOR_KEYS_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
&VendorKeyData,
sizeof (UINT8),
EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
0,
0,
&Variable,
NULL,
&mVariableModuleGlobal->VariableBase
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
return Status;
}
/**
This function uses to disable all of secure boot relative callbacks
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
STATIC
VOID
EFIAPI
DisableSecureBootCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
STATIC BOOLEAN SmiDisabled = FALSE;
if (!SmiDisabled) {
if (mVariableModuleGlobal->SmmCodeReady) {
InitCommunicationBufferHeader ();
mVariableModuleGlobal->SmmVarBuf->AccessType = DISABLE_SECURE_BOOT_SMI_FUN_NUM;
SendCommunicateBuffer ();
SmiDisabled = TRUE;
}
}
mVariableModuleGlobal->SecureBootCallbackEnabled = FALSE;
gBS->CloseEvent (Event);
return;
}
/**
Register call back function (on ReadytoBoot event and an platform specific event) to disable
all of secure boot functions.
@return EFI_SUCCESS Register callback function successful.
--*/
EFI_STATUS
RegisterEventToDisableSecureBoot (
VOID
)
{
EFI_STATUS Status;
EFI_EVENT Event;
VOID *Registration;
Event = VariableCreateProtocolNotifyEvent (
&gPlatformDisableSecureBootGuid,
TPL_CALLBACK,
DisableSecureBootCallback,
NULL,
&Registration
);
Status = EfiCreateEventReadyToBootEx (
TPL_NOTIFY,
DisableSecureBootCallback,
NULL,
&Event
);
return Status;
}