alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/SecureBootService/SecureBootService.c

483 lines
18 KiB
C

/** @file
Secure Boot Service for L05 feature
;******************************************************************************
;* 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 "SecureBootService.h"
//
// Copy from Insyde\InsydeModulePkg\Universal\UserInterface\SecureBootMgrDxe\SecureBootMgr.c
// The function in SecureBootMgr.c are all unnecessary for L05 feature.
//
UINT8 mDefaultAthenData[] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xdd, 0x26, 0x02, 0x97, 0x9d, 0x44, 0x1f, 0x64, 0x95, 0xf8, 0x88, 0x46, 0xef, 0x9f, 0xb2,
0xa1, 0x6c, 0xbc, 0x89, 0x1c, 0x29, 0xad, 0x4e, 0x5f, 0x67, 0xe0, 0xdb, 0xeb, 0x2f, 0xa4, 0xc0, 0x3f, 0x44, 0x72, 0x5c, 0x93, 0x39, 0x6d, 0xe5, 0x1c, 0xe2, 0x2b, 0xcb, 0x76, 0x11, 0x71, 0x4f,
0xc7, 0xe7, 0xa2, 0xde, 0x1e, 0x07, 0x56, 0x92, 0xfc, 0x63, 0x61, 0xf1, 0x06, 0xbb, 0x77, 0x26, 0xb8, 0x99, 0x7c, 0x0e, 0xb8, 0x81, 0x24, 0x2e, 0x72, 0x78, 0x8c, 0xfa, 0x6a, 0x71, 0x5d, 0x08,
0x42, 0xda, 0xde, 0x86, 0xfe, 0x99, 0x92, 0xf7, 0xf8, 0xa0, 0x3d, 0x1f, 0x52, 0x0b, 0xb8, 0xc6, 0x1b, 0xd5, 0x39, 0xcb, 0x34, 0xdb, 0x2b, 0x25, 0x57, 0x44, 0x72, 0x02, 0x93, 0x67, 0x2a, 0x82,
0x90, 0xa2, 0x5a, 0x76, 0xcb, 0x81, 0x7d, 0x42, 0x39, 0x1a, 0xf8, 0x54, 0xe0, 0x42, 0xbf, 0x49, 0x36, 0x1c, 0x4e, 0x88, 0xda, 0x5c, 0x7b, 0xd4, 0x67, 0xf6, 0x82, 0x30, 0xe4, 0x18, 0xf9, 0xb3,
0xe8, 0xab, 0xa4, 0xca, 0x53, 0x82, 0xcf, 0xf4, 0xac, 0x83, 0x4b, 0xd6, 0xd4, 0xa1, 0xc0, 0x01, 0xfc, 0x16, 0x9d, 0xca, 0xc5, 0x17, 0x2e, 0x70, 0xff, 0xaf, 0x86, 0xc8, 0x43, 0x02, 0xde, 0x52,
0xb1, 0x23, 0xf0, 0x2f, 0xd8, 0x0a, 0x46, 0xd3, 0xaf, 0x6b, 0x7e, 0x77, 0xf6, 0x72, 0x00, 0x66, 0x69, 0x66, 0x37, 0x71, 0x19, 0xc7, 0x7b, 0xf0, 0xd1, 0x41, 0xfd, 0x2b, 0x9b, 0xa1, 0x14, 0xb5,
0xb3, 0x55, 0xb9, 0x96, 0x53, 0x9f, 0x29, 0x63, 0xb2, 0x38, 0x2e, 0x29, 0x10, 0x16, 0x8a, 0xbd, 0x2e, 0xed, 0x3b, 0xdc, 0xb5, 0x40, 0x6f, 0xab, 0x26, 0xea, 0xb5, 0x28, 0x36, 0x6b, 0x4a, 0x68,
0x85, 0xd2, 0xb1, 0xff, 0xbf, 0xe6, 0x0a, 0xd3, 0x8c, 0xe5, 0x01, 0xda, 0xfd, 0x65, 0x75, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
#if (FixedPcdGet32 (PcdH2OCcbVersion) >= H2O_CCB_VERSION_OF_ECR_77485 || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE)
/**
Initial communication buffer header.
@param[in] CommunicationBuffer Input communication buffer.
@param[in] CommunicationBufferSize Size of communication buffer in bytes.
**/
STATIC
VOID
InitCommunicationBufferHeader (
IN VOID *CommunicationBuffer,
IN UINTN CommunicationBufferSize
)
{
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
if (CommunicationBuffer == NULL || CommunicationBufferSize < SMM_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VAR_BUFFER)) {
return;
}
SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) CommunicationBuffer;
ZeroMem (SmmCommunicateHeader, SMM_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VAR_BUFFER));
CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);
SmmCommunicateHeader->MessageLength = SMM_COMMUNICATE_BUFFER_SIZE;
}
/**
Using runtime data type memory to communicate information with variable driver
in SMM. (through SmmCommunication Protocol)
@param[in] InputBuff Buffer to communicate information with variable driver.
@param[in] DataSize Size of the InPutBuff in bytes.
@param[in] SubFunNum sub function number.
@retval EFI_SUCCESS Communicate information with variable driver successfully.
@retval EFI_OUT_OF_RESOURCES There are not enough memory to communicate information.
**/
EFI_STATUS
SmmSecureBootCallWithRuntimeMemoryThroughSmmCommunicate (
IN UINT8 *InputBuff,
IN UINTN DataSize,
IN UINT8 SubFunNum
)
{
NON_VOLATILE_VARIABLE_PROTOCOL *NonVolatileVariableProtocol;
VOID *VariableBuffer;
UINTN VariableBufferSize;
EFI_STATUS Status;
EFI_TPL Tpl;
EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
SMM_VAR_BUFFER *SmmVarBuffer;
Status = gBS->LocateProtocol (
&gEfiNonVolatileVariableProtocolGuid,
NULL,
(VOID **) &NonVolatileVariableProtocol
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = gBS->LocateProtocol (
&gEfiSmmCommunicationProtocolGuid,
NULL,
(VOID **) &SmmCommunication
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = NonVolatileVariableProtocol->GetRuntimeVariableBuffer (&VariableBuffer, &VariableBufferSize);
if (EFI_ERROR (Status) || VariableBufferSize < DataSize) {
return EFI_OUT_OF_RESOURCES;
}
//
// Because the VariableBuffer will be used in many places, raise TPL to prevent from the data in this
// buffer is destroyed in other events.
//
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
InitCommunicationBufferHeader (VariableBuffer, VariableBufferSize);
SmmVarBuffer = (SMM_VAR_BUFFER *)((UINTN) VariableBuffer + SMM_COMMUNICATE_HEADER_SIZE);
SmmVarBuffer->DataSize = DataSize;
SmmVarBuffer->AccessType = SubFunNum;
SmmVarBuffer->Status = EFI_UNSUPPORTED;
CopyMem (SmmVarBuffer + 1, InputBuff, DataSize);
Status = SmmCommunication->Communicate (SmmCommunication, VariableBuffer, &VariableBufferSize);
gBS->RestoreTPL (Tpl);
return EFI_SUCCESS;
}
#endif
/**
Using runtime data type memory to communicate information with variable driver
in SMM.
@param[in] InputBuff Buffer to communicate information with variable driver.
@param[in] DataSize Size of the InPutBuff in bytes.
@param[in] SubFunNum sub function number.
@retval EFI_SUCCESS Communicate information with variable driver successfully.
@retval EFI_OUT_OF_RESOURCES There are not enough memory to communicate information.
**/
EFI_STATUS
SmmSecureBootCallWithRuntimeMemory (
IN UINT8 *InputBuff,
IN UINTN DataSize,
IN UINT8 SubFunNum
)
{
NON_VOLATILE_VARIABLE_PROTOCOL *NonVolatileVariableProtocol;
VOID *VariableBuffer;
UINTN VariableBufferSize;
EFI_STATUS Status;
EFI_TPL Tpl;
BOOLEAN SecureBootCallThroughSmmCommunicate;
SecureBootCallThroughSmmCommunicate = FALSE;
#if (FixedPcdGet32 (PcdH2OCcbVersion) >= H2O_CCB_VERSION_OF_ECR_77485 || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE)
//
// If Kernel version is 05.43.05 later (adopt ECR#77485 IB02961336 solution),
// need to use SmmCommunication Protocol to replace software SMI to trigger SecureBootHandler.
//
SecureBootCallThroughSmmCommunicate = TRUE;
if (SecureBootCallThroughSmmCommunicate) {
return SmmSecureBootCallWithRuntimeMemoryThroughSmmCommunicate (
InputBuff,
DataSize,
SubFunNum
);
}
#endif
Status = gBS->LocateProtocol (
&gEfiNonVolatileVariableProtocolGuid,
NULL,
(VOID **) &NonVolatileVariableProtocol
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = NonVolatileVariableProtocol->GetRuntimeVariableBuffer (&VariableBuffer, &VariableBufferSize);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
if (VariableBufferSize < DataSize) {
return EFI_OUT_OF_RESOURCES;
}
//
// Because the VariableBuffer will be used in many places, raise TPL to prevent from the data in this
// buffer is destroyed in other events.
//
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
CopyMem (VariableBuffer, InputBuff, DataSize);
SmmSecureBootCall (VariableBuffer, DataSize, SubFunNum, SW_SMI_PORT);
gBS->RestoreTPL (Tpl);
return EFI_SUCCESS;
}
/**
This function processes the results of changes in SecureBootData.
@param SecureBootData A pointer to the SecureBootData.
@retval EFI_SUCCESS The operation completed successfully.
**/
EFI_STATUS
L05SecureBootCallback (
IN EFI_L05_SECURE_BOOT_DATA *SecureBootData
)
{
UINTN BufferSize;
switch (SecureBootData->Action) {
case L05_SECURE_BOOT_ENABLE:
//
// Set Enforce Secure Boot to Enable
//
BufferSize = sizeof (mDefaultAthenData);
mDefaultAthenData[BufferSize - 1] = 1;
SmmSecureBootCallWithRuntimeMemory (
mDefaultAthenData,
BufferSize,
SECURE_BOOT_ENFORCE_FUN_NUM
);
break;
case L05_SECURE_BOOT_DISABLE:
//
// Set Enforce Secure Boot to Disable
//
BufferSize = sizeof (mDefaultAthenData);
mDefaultAthenData[BufferSize - 1] = 0;
SmmSecureBootCallWithRuntimeMemory (
mDefaultAthenData,
BufferSize,
SECURE_BOOT_ENFORCE_FUN_NUM
);
break;
default :
break;
}
if (SecureBootData->ResetToSystemMode == L05_SECURE_BOOT_ENABLE) {
//
// Clear Secure Settings option in Secure Boot Manager
//
SmmSecureBootCallWithRuntimeMemory (
NULL,
0,
CLEAR_ALL_SECURE_SETTINGS_FUN_NUM
);
}
if (SecureBootData->RestoreFactoryKeys == L05_SECURE_BOOT_ENABLE) {
//
// Resotre Factory Settings option in Secure Boot Manager
//
BufferSize = sizeof (mDefaultAthenData);
mDefaultAthenData[BufferSize - 1] = 1;
SmmSecureBootCallWithRuntimeMemory (
mDefaultAthenData,
BufferSize,
RESTORE_FACTORY_DEFAULT_FUN_NUM
);
}
return EFI_SUCCESS;
}
/**
Notification function to make sure the Variable EFI_ADMINISTER_SECURE_BOOT_NAME be set and enabled.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
EFI_STATUS
SetAdministerSecureBootName (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN BufferSize;
UINT8 SecureBootEnable;
Status = EFI_SUCCESS;
BufferSize = sizeof (UINT8);
SecureBootEnable = 0;
//
// Make sure EFI_ADMINISTER_SECURE_BOOT_NAME variable to indicate this boot with administer secure boot permission.
//
Status = gRT->GetVariable (
EFI_ADMINISTER_SECURE_BOOT_NAME,
&gEfiGenericVariableGuid,
NULL,
&BufferSize,
&SecureBootEnable
);
if (EFI_ERROR (Status) || SecureBootEnable != 0x01) {
SecureBootEnable = 0x01;
Status = gRT->SetVariable (
EFI_ADMINISTER_SECURE_BOOT_NAME,
&gEfiGenericVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1,
&SecureBootEnable
);
if (EFI_ERROR (Status)) {
return Status;
}
}
gBS->CloseEvent (Event);
return EFI_SUCCESS;
}
/**
Notification function to make sure the Variable EFI_SECURE_BOOT_ENFORCE_NAME be set and enabled.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
EFI_STATUS
SecureBootServiceInit (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN BufferSize;
UINT8 Data;
BOOLEAN IsEfiBoot;
SYSTEM_CONFIGURATION *SystemConfiguration;
IsEfiBoot = FALSE;
SystemConfiguration = NULL;
SystemConfiguration = CommonGetVariableData (SETUP_VARIABLE_NAME, &gSystemConfigurationGuid);
if (SystemConfiguration != NULL) {
if (SystemConfiguration->BootType == EFI_BOOT_TYPE) {
IsEfiBoot = TRUE;
}
}
BufferSize = sizeof (UINT8);
Status = gRT->GetVariable (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
NULL,
&BufferSize,
&Data
);
//
// When Secure Boot Enforce variable does not exist under UEFI mode,
// Set Enforce Secure Boot to Enable.
//
if (EFI_ERROR (Status) && IsEfiBoot) {
mDefaultAthenData[BufferSize - 1] = 1;
SmmSecureBootCallWithRuntimeMemory (
mDefaultAthenData,
BufferSize,
SECURE_BOOT_ENFORCE_FUN_NUM
);
}
gBS->CloseEvent (Event);
return EFI_SUCCESS;
}
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
both device drivers and bus drivers.
@param ImageHandle The firmware allocated handle for the UEFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
EFIAPI
SecureBootServiceDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_L05_SECURE_BOOT_PROTOCOL *L05SecureBootPtr;
EFI_HANDLE Handle;
EFI_EVENT Event;
VOID *Registration;
L05SecureBootPtr = NULL;
Handle = NULL;
//
// Make sure the environment is ready for support L05 Secure Boot Service
// 1. The Variable EFI_ADMINISTER_SECURE_BOOT_NAME be set and enabled
//
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
SetAdministerSecureBootName,
NULL,
&Event
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->RegisterProtocolNotify (
&gEfiVariableArchProtocolGuid,
Event,
&Registration
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Make sure the environment is ready for support L05 Secure Boot Service
// 2. Set Enforce Secure Boot to Enable if Variable EFI_SECURE_BOOT_ENFORCE_NAME does not exist under UEFI mode
//
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
SecureBootServiceInit,
NULL,
&Event
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->RegisterProtocolNotify (
&gEfiSetupUtilityProtocolGuid,
Event,
&Registration
);
if (EFI_ERROR (Status)) {
return Status;
}
L05SecureBootPtr = AllocateZeroPool (sizeof (EFI_L05_SECURE_BOOT_PROTOCOL));
if (L05SecureBootPtr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
L05SecureBootPtr->L05SecureBootCallback = L05SecureBootCallback;
Status = gBS->InstallProtocolInterface (
&Handle,
&gEfiL05SecureBootProtocolGuid,
EFI_NATIVE_INTERFACE,
L05SecureBootPtr
);
return EFI_SUCCESS;
}