diff --git a/src/security/intel/cbnt/Kconfig b/src/security/intel/cbnt/Kconfig index 9d4849049a..d16e6852a6 100644 --- a/src/security/intel/cbnt/Kconfig +++ b/src/security/intel/cbnt/Kconfig @@ -17,6 +17,12 @@ config INTEL_CBNT_SUPPORT if INTEL_CBNT_SUPPORT +config INTEL_CBNT_LOGGING + bool "Enable verbose CBnT logging" + help + Print more CBnT related debug output. + Use in pre-production environments only! + config INTEL_CBNT_GENERATE_KM bool "Generate Key Manifest (KM)" default y diff --git a/src/security/intel/cbnt/Makefile.inc b/src/security/intel/cbnt/Makefile.inc index 9ade1cdce9..cc18b203d6 100644 --- a/src/security/intel/cbnt/Makefile.inc +++ b/src/security/intel/cbnt/Makefile.inc @@ -1,5 +1,6 @@ ifeq ($(CONFIG_INTEL_CBNT_SUPPORT),y) +all-y += logging.c ramstage-y += cmos.c # As specified in Intel Trusted Execution Technology and Boot Guard Server BIOS diff --git a/src/security/intel/cbnt/cbnt.h b/src/security/intel/cbnt/cbnt.h new file mode 100644 index 0000000000..08011f5965 --- /dev/null +++ b/src/security/intel/cbnt/cbnt.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SECURITY_INTEL_CBNT_H_ +#define SECURITY_INTEL_CBNT_H_ + +#include + +#define CBNT_BASE_ADDRESS TXT_PUBLIC_SPACE + +#define CBNT_ERRORCODE (CBNT_BASE_ADDRESS + 0x30) +#define CBNT_BOOTSTATUS (CBNT_BASE_ADDRESS + 0xa0) +#define CBNT_BIOSACM_ERRORCODE (CBNT_BASE_ADDRESS + 0x328) + +void intel_cbnt_log_registers(void); + +#endif diff --git a/src/security/intel/cbnt/logging.c b/src/security/intel/cbnt/logging.c new file mode 100644 index 0000000000..8e02202550 --- /dev/null +++ b/src/security/intel/cbnt/logging.c @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +#include "cbnt.h" + +#define LOG(...) printk(BIOS_INFO, "CBnT: " __VA_ARGS__) + +union sacm_info { + struct { + uint64_t nem_enabled : 1; + uint64_t tpm_type : 2; + uint64_t tpm_success : 1; + uint64_t facb : 1; + uint64_t measured_boot : 1; + uint64_t verified_boot : 1; + uint64_t revoked : 1; + uint64_t : 24; + uint64_t btg_cap : 1; + uint64_t : 1; + uint64_t txt_cap : 1; + uint64_t : 29; + }; + msr_t msr; + uint64_t raw; +}; + +_Static_assert(sizeof(union sacm_info) == sizeof(uint64_t), "Wrong size of sacm_info"); + +static const char *const tpm_type[] = { + "No TPM", + "TPM 1.2", + "TPM 2.0", + "PTT", +}; + +union cbnt_bootstatus { + struct { + uint64_t : 59; + uint64_t bios_trusted : 1; + uint64_t txt_dis_pol : 1; + uint64_t btg_startup_err : 1; + uint64_t txt_err : 1; + uint64_t type7 : 1; + }; + uint64_t raw; +}; +_Static_assert(sizeof(union cbnt_bootstatus) == sizeof(uint64_t), + "Wrong size of cbnt_bootstatus"); + +union cbnt_errorcode { + struct { + uint32_t type : 15; + uint32_t : 15; + uint32_t external : 1; + uint32_t valid : 1; + } microcode; + struct { + uint32_t ac_type : 4; + uint32_t class : 6; + uint32_t major : 5; + uint32_t minor_invalid : 1; + uint32_t minor : 9; + uint32_t : 5; + uint32_t external : 1; + uint32_t valid : 1; + } sinit; + uint32_t raw; +}; + +_Static_assert(sizeof(union cbnt_errorcode) == sizeof(uint32_t), + "Wrong size of cbnt_errorcode"); + +union cbnt_biosacm_errorcode { + struct { + uint32_t ac_type : 4; + uint32_t class : 6; + uint32_t major : 5; + uint32_t minor_invalid : 1; + uint32_t minor : 12; + uint32_t : 2; + uint32_t external : 1; + uint32_t valid : 1; + } txt; + struct { + uint32_t ac_type : 4; + uint32_t class : 6; + uint32_t error : 5; + uint32_t acm_started : 1; + uint32_t km_id : 4; + uint32_t bp : 5; + uint32_t : 6; + uint32_t valid : 1; + } btg; + uint32_t raw; +}; +_Static_assert(sizeof(union cbnt_biosacm_errorcode) == sizeof(uint32_t), + "Wrong size of cbnt_biosacm_errorcode"); + + +static const char *decode_err_type(uint8_t type) +{ + switch (type) { + case 0: + return "BIOS ACM Error"; + case 1: + return "SINIT ACM Error"; + case 3: + return "Boot Guard Error"; + default: + return "Reserved"; + } +} + +void intel_cbnt_log_registers(void) +{ + const union sacm_info acm_info = { .msr = rdmsr(MSR_BOOT_GUARD_SACM_INFO) }; + LOG("SACM INFO MSR (0x13A) raw: 0x%016llx\n", acm_info.raw); + LOG(" NEM status: %ul\n", acm_info.nem_enabled); + LOG(" TPM type: %s\n", tpm_type[acm_info.tpm_type]); + LOG(" TPM succes: %ul\n", acm_info.tpm_success); + LOG(" FACB: %ul\n", acm_info.facb); + LOG(" measured boot: %ul\n", acm_info.measured_boot); + LOG(" verified boot: %ul\n", acm_info.verified_boot); + LOG(" revoked: %ul\n", acm_info.revoked); + LOG(" BtG capable: %ul\n", acm_info.btg_cap); + LOG(" TXT capable: %ul\n", acm_info.txt_cap); + + const union cbnt_bootstatus btsts = { + .raw = read64p(CBNT_BOOTSTATUS), + }; + LOG("BOOTSTATUS (0xA0) raw: 0x%016llx\n", btsts.raw); + LOG(" Bios trusted: %ul\n", btsts.bios_trusted); + LOG(" TXT disabled by policy: %ul\n", btsts.txt_dis_pol); + LOG(" Bootguard startup error: %ul\n", btsts.btg_startup_err); + LOG(" TXT ucode or ACM error: %ul\n", btsts.txt_err); + LOG(" TXT measurement type 7: %ul\n", btsts.type7); + + const union cbnt_errorcode err = { + .raw = read32p(CBNT_ERRORCODE), + }; + LOG("ERRORCODE (0x30) raw: 0x%08x\n", err.raw); + /* It looks like the hardware does not set the txt error bit properly */ + const bool txt_err_valid = btsts.txt_err || true; + if (txt_err_valid && !btsts.txt_dis_pol) { + if (err.microcode.valid && !err.microcode.external) { + LOG("ERRORCODE is ucode error\n"); + LOG(" type: %s\n", + intel_txt_processor_error_type(err.microcode.type)); + } else if (err.sinit.valid && err.sinit.external) { + LOG("ERRORCODE is SINIT error\n"); + const char *type = decode_err_type(err.sinit.ac_type); + LOG(" AC Module Type: %s\n", type); + LOG(" class: 0x%x\n", err.sinit.class); + LOG(" major: 0x%x\n", err.sinit.major); + if (!err.sinit.minor_invalid) + LOG(" minor: 0x%x\n", err.sinit.minor); + } + } else if (txt_err_valid && btsts.txt_dis_pol) { + LOG("TXT disabled in Policy\n"); + } + + const union cbnt_biosacm_errorcode biosacm_err = { + .raw = read32p(CBNT_BIOSACM_ERRORCODE), + }; + LOG("BIOSACM_ERRORCODE (0x328) raw: 0x%08x\n", biosacm_err.raw); + if (txt_err_valid && biosacm_err.txt.valid) { + LOG("BIOSACM_ERRORCODE: TXT ucode or ACM error\n"); + const char *type = decode_err_type(biosacm_err.txt.ac_type); + LOG(" AC Module Type: %s\n", type); + LOG(" class: 0x%x\n", biosacm_err.txt.class); + LOG(" major: 0x%x\n", biosacm_err.txt.major); + if (!biosacm_err.txt.minor_invalid) + LOG(" minor: 0x%x\n", biosacm_err.txt.minor); + LOG(" External: 0x%x\n", biosacm_err.txt.external); + } + + if (btsts.btg_startup_err && biosacm_err.btg.valid) { + LOG("BIOSACM_ERRORCODE: Bootguard error\n"); + const char *type = decode_err_type(biosacm_err.btg.ac_type); + LOG(" AC Module Type: %s\n", type); + LOG(" class: 0x%x\n", biosacm_err.btg.class); + LOG(" error: 0x%x\n", biosacm_err.btg.error); + LOG(" ACM started: %u\n", biosacm_err.btg.acm_started); + LOG(" KMID: 0x%x\n", biosacm_err.btg.km_id); + LOG(" BootPolicies: 0x%x\n", biosacm_err.btg.bp); + } +} diff --git a/src/security/intel/txt/ramstage.c b/src/security/intel/txt/ramstage.c index 85fa931474..3ca766e51c 100644 --- a/src/security/intel/txt/ramstage.c +++ b/src/security/intel/txt/ramstage.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "txt.h" @@ -130,6 +131,9 @@ static void init_intel_txt(void *unused) intel_txt_log_spad(); + if (CONFIG(INTEL_CBNT_LOGGING)) + intel_cbnt_log_registers(); + if (CONFIG(INTEL_TXT_LOGGING)) { intel_txt_log_bios_acm_error(); txt_dump_chipset_info(); diff --git a/src/soc/intel/xeon_sp/bootblock.c b/src/soc/intel/xeon_sp/bootblock.c index 0b04f03215..1d706fe9c9 100644 --- a/src/soc/intel/xeon_sp/bootblock.c +++ b/src/soc/intel/xeon_sp/bootblock.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -67,5 +68,9 @@ void bootblock_soc_init(void) if (CONFIG(FSP_CAR)) report_fspt_output(); + + if (CONFIG(INTEL_CBNT_LOGGING)) + intel_cbnt_log_registers(); + bootblock_pch_init(); }