/** @file
|
This file contains the tests for the SecureCPUConfiguration bit
|
|
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include "HstiSiliconDxe.h"
|
|
/**
|
Run tests for SecureCPUConfiguration bit
|
**/
|
VOID
|
CheckSecureCpuConfiguration (
|
VOID
|
)
|
{
|
EFI_STATUS Status;
|
BOOLEAN Result;
|
UINTN CpuNumber;
|
UINTN CpuIndex;
|
CPUID_VERSION_INFO_ECX Ecx;
|
UINT8 SramC;
|
UINT32 TsegMB;
|
UINT32 Bgsm;
|
UINT64 SmrrBase;
|
UINT64 SmrrMask;
|
UINT64 MasterSmrrBase;
|
UINT64 MasterSmrrMask;
|
CHAR16 *HstiErrorString;
|
UINT64 SmmFeatureControl;
|
MSR_IA32_FEATURE_CONTROL_REGISTER Ia32FeatureControlMsr;
|
MSR_IA32_MTRRCAP_REGISTER MtrrCapMsr;
|
|
if ((mFeatureImplemented[0] & HSTI_BYTE0_SECURE_CPU_CONFIGURATION) == 0) {
|
return;
|
}
|
|
Result = TRUE;
|
|
DEBUG ((DEBUG_INFO, " Table 3-1. CPU Security Configuration\n"));
|
|
CpuNumber = GetCpuNumber ();
|
for (CpuIndex = 0; CpuIndex < CpuNumber; CpuIndex++) {
|
DEBUG ((DEBUG_INFO, " [CPU - 0x%x]\n", CpuIndex));
|
|
DEBUG ((DEBUG_INFO, " 1. Microcode Update Revision\n"));
|
if ((ProcessorReadMsr64 (CpuIndex, MSR_IA32_BIOS_SIGN_ID) & 0xFFFFFFFF00000000) == 0) {
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_1 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_1);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 2. Sample Part \n"));
|
|
if ((ProcessorReadMsr64 (CpuIndex, MSR_PLATFORM_INFO) & BIT27) != 0) {
|
DEBUG ((DEBUG_INFO, "Fail: This is a sample part\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_2 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_2);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 3. IA32_FEATURE_CONTROL MSR Lock\n"));
|
|
Ia32FeatureControlMsr.Uint64 = ProcessorReadMsr64 (CpuIndex, MSR_IA32_FEATURE_CONTROL);
|
if (Ia32FeatureControlMsr.Bits.Lock == 0) {
|
DEBUG ((DEBUG_INFO, "Fail: This is a sample part\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_3 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_3);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 4. SMM_FEATURE_CONTROL MSR Lock\n"));
|
|
SmmFeatureControl = ProcessorReadMsr64 (CpuIndex, MSR_SMM_FEATURE_CONTROL);
|
|
DEBUG ((DEBUG_INFO, " 4. SMM_CODE_CHK_EN TEST\n"));
|
|
if ((SmmFeatureControl & B_SMM_CODE_CHK_EN) == 0) {
|
|
DEBUG ((DEBUG_INFO, "Fail: SMM Code Fetch outside SMRAM dectect feature disabled\n"));
|
|
HstiErrorString = BuildHstiErrorString(HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_4 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_B);
|
Status = HstiLibAppendErrorString(
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool(HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " SMM_FEATURE_CONTROL MSR Lock\n"));
|
|
if ((SmmFeatureControl & B_SMM_FEATURE_CONTROL_LOCK) == 0) {
|
|
DEBUG ((DEBUG_INFO, "Fail: Smm feature control msr not locked\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_4 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_4);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 5. FEATURE_CONFIG MSR Lock\n"));
|
|
ProcessorCpuid (CpuIndex, CPUID_VERSION_INFO, NULL, NULL, &Ecx.Uint32, NULL);
|
if (Ecx.Bits.AESNI == 1) {
|
if ((ProcessorReadMsr64 (CpuIndex, MSR_IA32_FEATURE_CONFIG) & B_IA32_FEATURE_CONFIG_LOCK) == 0) {
|
DEBUG ((DEBUG_INFO, "Fail: Feature control msr not locked\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_5 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_5);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
}
|
}
|
|
DEBUG ((DEBUG_INFO, " Table 7-4. SMM Security Configuration\n"));
|
|
DEBUG ((DEBUG_INFO, " 1. SMRAMC\n"));
|
|
SramC = MmioRead8 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_MC_DEV,SA_MC_FUN) + R_SA_SMRAMC);
|
if ((SramC & B_SA_SMRAMC_D_LCK_MASK) == 0) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRAMC not locked\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_8 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_8);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 2. TSEGMB\n"));
|
|
TsegMB = MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_MC_DEV,SA_MC_FUN) + R_SA_TSEGMB);
|
if ((TsegMB & B_SA_TSEGMB_LOCK_MASK) == 0) {
|
DEBUG ((DEBUG_INFO, "Fail: TSEGMB not locked\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_8 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_8);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 3. TSEGMB Alignment\n"));
|
|
if (((TsegMB & B_SA_TSEGMB_TSEGMB_MASK) & (LShiftU64 (1,20) - 1)) != 0) {
|
DEBUG ((DEBUG_INFO, "Fail: TSEGMB not size aligned, TSEG size: 0x%x\n",(LShiftU64 (1,20) - 1)));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_9 ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_9);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
MasterSmrrBase = 0;
|
MasterSmrrMask = 0;
|
for (CpuIndex = 0; CpuIndex < CpuNumber; CpuIndex++) {
|
DEBUG ((DEBUG_INFO, " [CPU - 0x%x]\n", CpuIndex));
|
|
DEBUG ((DEBUG_INFO, " 4. SMRR1 are supported\n"));
|
|
MtrrCapMsr.Uint64 = ProcessorReadMsr64 (CpuIndex, MSR_IA32_MTRRCAP);
|
if (MtrrCapMsr.Bits.SMRR == 0) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRR1 not supported\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_A ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_A);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
} else {
|
DEBUG ((DEBUG_INFO, " 5. SMRR1 programmed consistently on all cores\n"));
|
|
SmrrBase = ProcessorReadMsr64 (CpuIndex, MSR_IA32_SMRR_PHYSBASE);
|
SmrrMask = ProcessorReadMsr64 (CpuIndex, MSR_IA32_SMRR_PHYSMASK);
|
|
if (CpuIndex == 0) {
|
MasterSmrrBase = SmrrBase;
|
MasterSmrrMask = SmrrMask;
|
} else {
|
if ((SmrrBase != MasterSmrrBase) || (SmrrMask != MasterSmrrMask)) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRR1 not programmed consistently across all cores\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_A ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_A);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
}
|
|
DEBUG ((DEBUG_INFO, " 6. SMRR1 enabled/correct\n"));
|
|
if (((SmrrMask & BIT11) == 0x0) ||
|
((SmrrMask & BIT9) != 0x0) ||
|
((SmrrBase & 0x7) != 0x6)) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRR1 not enabled/correct\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_A ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_A);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 7. SMRR1 and TSEGMB match\n"));
|
|
DEBUG ((DEBUG_INFO, "SMRR: 0x%08x - 0x%08x\n", SmrrBase & (SmrrMask & 0xFFFFF000), (UINT32) (~(SmrrMask & 0xFFFFF000) + 1)));
|
DEBUG ((DEBUG_INFO, "TSEGMB: 0x%08x\n", TsegMB & B_SA_TSEGMB_TSEGMB_MASK));
|
|
if ((SmrrBase & (SmrrMask & 0xFFFFF000)) != (TsegMB & B_SA_TSEGMB_TSEGMB_MASK)) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRR1 != TSEGMB\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_A ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_A);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 8. SMRR1 size\n"));
|
Bgsm = MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_MC_DEV,SA_MC_FUN) + R_SA_BGSM);
|
|
if ((UINT32) (~(SmrrMask & 0xFFFFF000) + 1) !=
|
((Bgsm & B_SA_BGSM_BGSM_MASK) - (TsegMB & B_SA_TSEGMB_TSEGMB_MASK))) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRR1 size != BGSM-TSEGMB\n"));
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_A ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_A);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
|
DEBUG ((DEBUG_INFO, " 9. SMRR1 work\n"));
|
|
if (MmioRead32 (SmrrBase & SmrrMask) != 0xFFFFFFFF) {
|
DEBUG ((DEBUG_INFO, "Fail: SMRR1 not working, read succeeded\n"));
|
|
|
HstiErrorString = BuildHstiErrorString (HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_CODE_A ,HSTI_CPU_SECURITY_CONFIGURATION, HSTI_BYTE0_SECURE_CPU_CONFIGURATION_ERROR_STRING_A);
|
Status = HstiLibAppendErrorString (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
HstiErrorString
|
);
|
ASSERT_EFI_ERROR (Status);
|
Result = FALSE;
|
FreePool (HstiErrorString);
|
}
|
}
|
}
|
|
//
|
// ALL PASS
|
//
|
if (Result) {
|
Status = HstiLibSetFeaturesVerified (
|
PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
|
NULL,
|
0,
|
HSTI_BYTE0_SECURE_CPU_CONFIGURATION
|
);
|
ASSERT_EFI_ERROR (Status);
|
}
|
|
return;
|
}
|