Secure Configuration
For security features, it is not a good idea to use variables to control the behavior because they can be altered by an attacker to bypass protection. The general configuration also includes the system state, memory configuration, different boot mode, etc.
Previous Vulnerabilities:
UEFI Secure Boot
In CanSecWest 2014, MITRE disclosed the vulnerability that the OEM used setup a variable to control the image verification policy. That meant the UEFI secure boot could be easily bypassed. See lines below assigning values to policy
within each case
statement.
DxeImageVerificationHandler(EFI_EXECUTABLE Image) {
switch (getImageOrigin(image)) {
case IMAGE_FROM_OPTION_ROM:
policy = Setup.LOAD_FROM_OROM;
case IMAGE_FROM_FIXED_DRIVE:
policy = Setup.LOAD_FROM_FIXED;
case IMAGE_FROM_REMOVABLE:
policy = Setup.LOAD_FROM_REMOVABLE;
...
if (policy == ALWAYS_EXECUTE)
return EFI_SUCCESS;
else
return IsImageAllowed(image);
}
For any security feature, there should be no way to bypass it in the production. No variable should be used to control it. If a Platform Configuration Database (PCD) is used, the PCD must be statically configured.
Intel® Boot Guard
In 2016 and DefCon 2017, Ermolov disclosed how to bypass Intel® Boot Guard.
In BlackHat 2017 and BlackHat 2019, Mastrov disclosed how to bypass Intel® Boot Guard. See lines below assigning values to BootGuardVerifyTransitionPEItoDXEFlag
followed by a check.
EFI_STATUS BootGuardPei (EFI_PEI_SERVICES **PeiServices, VOID *Ppt)
{
...
if (!((BootGuardHashKeySegment1 == 0) {
CalculateSha256 (BootGuardHashKeySegment1);
CalculateSha256 (CurrentBootGuardHashKey1);
if (!MemCmp (BootGuardHashKeySegment1, CurrentBootGuardHashKey1, 32)) {
BootGuardVerifyTransitionPEItoDXEFlag = 1;
} else {
BootGuardVerifyTransitionPEItoDXEFlag = 0;
return EFI_SUCCESS;
}
}
return Status;
}
EFI_STATUS BootGuardDxe (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
...
if (BootGuardVerifyTransitionPEItoDXEFlag == 0) {
BootGuardRegisterCallback();
}
return EFI_SUCCESS;
}
The summary of the issue is below:
- The Intel® Boot Guard configuration is not set properly.
- The verification does not always happen in all boot modes. For example, the verification is done only once every 12 times a device is powered up.
- The software logic issue in Intel Boot Guard PEI or DXE that the verification may be bypassed in some cases.
The mitigation is:
- Fuse configuration – always verify the fuses are configured for security.
- Verification – ensure that verification occurs in all boot modes and boot paths.
TCG Trusted Boot
In BlackHat 2018, Han disclosed an issue about TPM measurements in a DRTM environment. This issue was related to the S3 resume path, where TBOOT only measured code and read-only data for the Measured Launch Environment (MLE). However, TBOOT did not measure the required initialized data. This created a condition where an attacker could hijack the control flow and exploit TBOOT. See lines below with statements _mle_end
and .data
.
_mle_start = .; /* beginning of MLE pages */
*(.text)
*(.fixup)
*(.gnu.warning)
} :text = 0x9090
.rodata : { *(.rodata) *(.rodata.*) }
. = ALIGN(4096);
_mle_end = .; /* end of MLE pages */
.data : { /* Data */
*(.data)
*(.tboot_shared)
CONSTRUCTORS
}
Mitigation occurs when MLE sets up the environment, ensuring that all critical data (code, read-only data, and initialized data) is measured, including the function pointers. This demonstrates the importance of a complete measurement.
In BlackHat 2019, Han disclosed an issue using TPM in a static root-of-trust for measurement (SRTM) environment. During the S3 resume path, if the OS does not send Shutdown(STATE) the firmware Startup(STATE) will fail. Some platform firmware only sent Startup(CLEAR) which left all Platform Configuration Registers (PCR) open. See lines below with if statement BootMode == BOOT_ON_S3_RESUME
and then Status = Tpm2Startup (TPM_SU_CLEAR);
statement.
PeimEntryMA ()
{
if (BootMode == BOOT_ON_S3_RESUME) {
Status = Tpm2Startup (TPM_SU_STATE);
if (EFI_ERROR (Status) ) {
Status = Tpm2Startup (TPM_SU_CLEAR);
The mitigation extends the PCR with an EV_SEPARATOR error, which takes advantage of proper error handling.