Attention is currently required from: Anjaneya "Reddy" Chagam, Jonathan Zhang, Johnny Lin, Morgan Jang, Patrick Rudolph. Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/54093 )
Change subject: security/intel/cbnt: Add logging ......................................................................
security/intel/cbnt: Add logging
This decodes and logs the CBnT status and error registers.
Change-Id: I8b57132bedbd944b9861ab0e2e0d14723cb61635 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/security/intel/cbnt/Kconfig M src/security/intel/cbnt/Makefile.inc A src/security/intel/cbnt/cbnt.h A src/security/intel/cbnt/logging.c M src/security/intel/txt/ramstage.c M src/soc/intel/xeon_sp/bootblock.c 6 files changed, 221 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/93/54093/1
diff --git a/src/security/intel/cbnt/Kconfig b/src/security/intel/cbnt/Kconfig index a602cca..3d9fb49 100644 --- a/src/security/intel/cbnt/Kconfig +++ b/src/security/intel/cbnt/Kconfig @@ -17,6 +17,12 @@
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 c20a3dd..cdb8fa4 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-$(CONFIG_INTEL_CBNT_LOGGING) += logging.c ramstage-y += cmos.c
# The private key also contains the public key, so use that if a private key is provided. diff --git a/src/security/intel/cbnt/cbnt.h b/src/security/intel/cbnt/cbnt.h new file mode 100644 index 0000000..63433c3 --- /dev/null +++ b/src/security/intel/cbnt/cbnt.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define CBNT_BASE_ADDRESS 0xfed30000 + +#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); diff --git a/src/security/intel/cbnt/logging.c b/src/security/intel/cbnt/logging.c new file mode 100644 index 0000000..f358941 --- /dev/null +++ b/src/security/intel/cbnt/logging.c @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/mmio.h> +#include <console/console.h> +#include <cpu/x86/msr.h> +#include <cpu/intel/msr.h> +#include <stdint.h> +#include <security/intel/txt/txt.h> + +#include "cbnt.h" + +union sacm_info { + struct { + uint64_t nem : 1; + uint64_t tpm_type : 2; + uint64_t tpm_succes : 1; + uint64_t reserved1 : 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; + }; + uint64_t raw; +}; + +_Static_assert(sizeof(union sacm_info) == sizeof(uint64_t), "Wrong size of sacm_info"); + +static const char *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) +{ + static const char *bios_acm = "BIOS ACM Error", *sinit_acm = "SINIT ACM Error", + *btg = "Boot Guard Error", *reserved = "Reserved"; + + switch (type) { + case 0: + return bios_acm; + case 1: + return sinit_acm; + case 3: + return btg; + default: + return reserved; + } +} + +void intel_cbnt_log_registers(void) +{ + const msr_t sacm_info_msr = rdmsr(MSR_BOOT_GUARD_SACM_INFO); + const union sacm_info acm_info = { + .raw = sacm_info_msr.lo | ((uint64_t)sacm_info_msr.hi << 32) + }; + printk(BIOS_DEBUG, "CBNT:\tSACM INFO MSR (0x13A) raw: 0x%016llx\n", acm_info.raw); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tNEM status:\t\t\t%d\n", acm_info.nem); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tTPM type:\t\t\t%s\n", tpm_type[acm_info.tpm_type]); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tTPM succes:\t\t\t%d\n", acm_info.tpm_succes); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tmeasured boot:\t\t\t%d\n", acm_info.measured_boot); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tverified boot:\t\t\t%d\n", acm_info.verified_boot); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\trevoked:\t\t\t%d\n", acm_info.revoked); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tBtG capable:\t\t\t%d\n", acm_info.btg_cap); + printk(BIOS_DEBUG, "CBNT:\tSACM INFO:\tTXT capable:\t\t\t%d\n", acm_info.txt_cap); + + const union cbnt_bootstatus btsts = { .raw = read64((void *)CBNT_BOOTSTATUS), }; + printk(BIOS_DEBUG, "CBNT:\tBOOTSTATUS (0xA0) raw: 0x%016llx\n", btsts.raw); + printk(BIOS_DEBUG, "CBNT:\tBOOTSTATUS:\tBios trusted:\t\t\t%d\n", btsts.bios_trusted); + printk(BIOS_DEBUG, "CBNT:\tBOOTSTATUS:\tTXT disabled by policy:\t\t%d\n", btsts.txt_dis_pol); + printk(BIOS_DEBUG, "CBNT:\tBOOTSTATUS:\tBootguard startup error:\t%d\n", btsts.btg_startup_err); + printk(BIOS_DEBUG, "CBNT:\tBOOTSTATUS:\tTXT ucode or ACM error:\t\t%d\n", btsts.txt_err); + printk(BIOS_DEBUG, "CBNT:\tBOOTSTATUS:\tTXT measurement type 7:\t\t%d\n", btsts.type7); + + const union cbnt_errorcode err = { .raw = read32((void *)CBNT_ERRORCODE), }; + printk(BIOS_DEBUG, "CBNT:\tERRORCODE (0x30) raw: 0x%08x\n", err.raw); + if (btsts.txt_err) { + if (!btsts.txt_dis_pol) { + if (err.microcode.valid && !err.microcode.external) { + printk(BIOS_DEBUG, "CBNT:\tERRORCODE is ucode error\n"); + printk(BIOS_DEBUG, "CBNT:\tERRORCODE: type:\t\t%s\n", + intel_txt_microcode_error_type(err.microcode.type)); + } else if (err.sinit.valid && err.sinit.external) { + printk(BIOS_DEBUG, "CBNT:\tERRORCODE is SINIT error\n"); + const char *type = decode_err_type(err.sinit.ac_type); + printk(BIOS_DEBUG, "CBNT:\tERRORCODE: AC Module Type:\t\t%s\n", + type); + printk(BIOS_DEBUG, "CBNT:\tERRORCODE: class:\t\t0x%x\n", err.sinit.class); + printk(BIOS_DEBUG, "CBNT:\tERRORCODE: major:\t\t0x%x\n", + err.sinit.major); + if (!err.sinit.minor_invalid) + printk(BIOS_DEBUG, + "CBNT:\tERRORCODE: minor:\t\t0x%x\n", + err.sinit.minor); + } + } + } + + const union cbnt_biosacm_errorcode biosacm_err = { .raw = read32((void *)CBNT_BIOSACM_ERRORCODE), }; + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE (0x328) raw: 0x%08x\n", biosacm_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 && biosacm_err.txt.valid) { + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: TXT ucode or ACM error\n"); + const char *type = decode_err_type(biosacm_err.txt.ac_type); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: AC Module Type:\t\t%s\n", type); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: class:\t\t\t0x%x\n", biosacm_err.txt.class); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: major:\t\t\t0x%x\n", biosacm_err.txt.major); + if (!biosacm_err.txt.minor_invalid) + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: minor:\t\t\t0x%x\n", + biosacm_err.txt.minor); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: External:\t\t\t0x%x\n", + biosacm_err.txt.external); + } + + if (btsts.btg_startup_err && biosacm_err.btg.valid) { + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: Bootguard error\n"); + const char *type = decode_err_type(biosacm_err.btg.ac_type); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: AC Module Type:\t\t%s\n", type); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: class:\t\t\t0x%x\n", + biosacm_err.btg.class); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: error:\t\t\t0x%x\n", + biosacm_err.btg.error); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: ACM started:\t\t\t%d\n", biosacm_err.btg.acm_started); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: KMID:\t\t\t0x%x\n", biosacm_err.btg.km_id); + printk(BIOS_DEBUG, "CBNT:\tBIOSACM_ERRORCODE: BootPolicies:\t\t\t0x%x\n", + biosacm_err.btg.bp); + } +} diff --git a/src/security/intel/txt/ramstage.c b/src/security/intel/txt/ramstage.c index c830f97..91d4efd 100644 --- a/src/security/intel/txt/ramstage.c +++ b/src/security/intel/txt/ramstage.c @@ -130,6 +130,9 @@
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 baf5ab5..f4bdd09 100644 --- a/src/soc/intel/xeon_sp/bootblock.c +++ b/src/soc/intel/xeon_sp/bootblock.c @@ -8,6 +8,7 @@ #include <console/console.h> #include <cpu/x86/mtrr.h> #include <intelblocks/lpc_lib.h> +#include <security/intel/cbnt/cbnt.h> #include <soc/pci_devs.h> #include <soc/bootblock.h> #include <fsp/util.h> @@ -70,5 +71,9 @@
if (CONFIG(FSP_CAR)) report_fspt_output(); + + if (CONFIG(INTEL_CBNT_SUPPORT)) + intel_cbnt_log_registers(); + bootblock_pch_init(); }