/** @file This file contains the tests for the SecureCPUConfiguration bit Copyright (c) 2017, Intel Corporation. All rights reserved.
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; }