From 9ac91d220f18377825aac8889e99b2cf078e4afc Mon Sep 17 00:00:00 2001 From: Pablo Stebler Date: Fri, 18 Sep 2020 10:32:22 +0200 Subject: [PATCH] util/intelmetool: Fix the BootGuard dump feature Read the correct bits for measured and verified boot, print information about some other bits. Signed-off-by: Pablo Stebler Change-Id: Ie79d6da33032aee94d716bf0698b5501bbc424fa Reviewed-on: https://review.coreboot.org/c/coreboot/+/45516 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- util/intelmetool/intelmetool.c | 107 +++++++++++++++++++-------------- util/intelmetool/intelmetool.h | 15 ----- util/intelmetool/me.c | 6 ++ util/intelmetool/msr.c | 5 +- util/intelmetool/msr.h | 2 +- 5 files changed, 71 insertions(+), 64 deletions(-) diff --git a/util/intelmetool/intelmetool.c b/util/intelmetool/intelmetool.c index 482fd5b183..9105d3b82b 100644 --- a/util/intelmetool/intelmetool.c +++ b/util/intelmetool/intelmetool.c @@ -314,12 +314,16 @@ out: rehide_me(); } +static void print_btg_bool_param(const char *name, u8 state) +{ + printf("%-20s : %s\n", name, state ? "ON" : "OFF"); +} + static void dump_bootguard_info(void) { struct pci_dev *dev; char namebuf[1024]; const char *name = NULL; - uint64_t bootguard = 0; if (pci_platform_scan()) return; @@ -342,59 +346,74 @@ static void dump_bootguard_info(void) if (ME_major_ver && (ME_major_ver < 9 || (ME_major_ver == 9 && ME_minor_ver < 5))) { - print_cap("BootGuard ", 0); - printf(CGRN "\nYour system isn't bootguard ready. You can " - "flash other firmware!\n" RESET); + printf(CGRN "Your system isn't BootGuard ready.\n" + "You can flash other firmware!\n" RESET); rehide_me(); return; } - if (msr_bootguard(&bootguard, debug) < 0) { - printf("ME Capability: %-43s: " CCYN "%s\n" RESET, - "BootGuard Mode", "Unknown"); - rehide_me(); - return; - } - - if (debug) { - printf("BootGuard MSR Output: 0x%" PRIx64 "\n", bootguard); - bootguard &= ~0xff; - } - - print_cap("BootGuard ", 1); if (pci_read_long(dev, 0x40) & 0x10) - printf(CYEL "Your southbridge configuration is insecure!! " + printf(CYEL "Your southbridge configuration is insecure!!\n" "BootGuard keys can be overwritten or wiped, or you are " "in developer mode.\n" RESET); rehide_me(); - switch (bootguard) { - case BOOTGUARD_DISABLED: - printf("ME Capability: %-43s: " CGRN "%s\n" RESET, - "BootGuard Mode", "Disabled"); - printf(CGRN "\nYour system is bootguard ready but your vendor " - "disabled it. You can flash other firmware!\n" RESET); - break; - case BOOTGUARD_ENABLED_COMBI_MODE: - printf("ME Capability: %-43s: " CGRN "%s\n" RESET, - "BootGuard Mode", "Verified & Measured Boot"); - printf(CRED "\nVerified boot is enabled. You can't flash other " - "firmware. !\n" RESET); - break; - case BOOTGUARD_ENABLED_MEASUREMENT_MODE: - printf("ME Capability: %-43s: " CGRN "%s\n" RESET, - "BootGuard Mode", "Measured Boot"); - printf(CGRN "\nYour system is bootguard ready but only running " - "the measured boot mode. You can flash other firmware!\n" - RESET); - break; - case BOOTGUARD_ENABLED_VERIFIED_MODE: - printf("ME Capability: %-43s: " CGRN "%s\n" RESET, - "BootGuard Mode", "Verified Boot"); - printf(CRED "\nVerified boot is enabled! You can't flash other " - "firmware.\n" RESET); - break; + union { + struct { + u8 nem_enabled : 1; /* [ 0.. 0] */ + u8 tpm_type : 2; /* [ 2.. 1] */ + u8 tpm_success : 1; /* [ 3.. 3] */ + u8 facb_fpf : 1; /* [ 4.. 4] */ + u8 measured_boot : 1; /* [ 5.. 5] */ + u8 verified_boot : 1; /* [ 6.. 6] */ + u8 module_revoked : 1; /* [ 7.. 7] */ + u32 : 24; + u8 btg_capability : 1; /* [32..32] */ + u32 : 31; + }; + u64 raw; + } btg; + + if (msr_bootguard(&btg.raw) < 0) { + printf("Could not read the BOOTGUARD_SACM_INFO MSR.\n"); + return; + } + + printf("BootGuard MSR Output : 0x%" PRIx64 "\n", btg.raw); + + if (!btg.btg_capability) { + printf(CGRN "Your system isn't BootGuard ready.\n" + "You can flash other firmware!\n" RESET); + return; + } + + print_btg_bool_param("Measured boot", btg.measured_boot); + print_btg_bool_param("Verified boot", btg.verified_boot); + print_btg_bool_param("FACB in FPFs", btg.facb_fpf); + print_btg_bool_param("Module revoked", btg.module_revoked); + if (btg.measured_boot) { + const char *const tpm_type_strs[] = { + "None", + "TPM 1.2", + "TPM 2.0", + "PTT", + }; + printf("%-20s : %s\n", "TPM type", tpm_type_strs[btg.tpm_type]); + print_btg_bool_param("TPM success", btg.tpm_success); + } + if (btg.verified_boot) { + print_btg_bool_param("NEM enabled", btg.nem_enabled); + if (btg.nem_enabled) + printf(CRED "Verified boot is enabled and ACM has enabled " + "Cache-As-RAM.\nYou can't flash other firmware!\n" RESET); + else + printf(CYEL "Verified boot is enabled, but ACM did not enable " + "Cache-As-RAM.\nIt might be possible to flash other firmware.\n" + RESET); + } else { + printf(CGRN "Your system is BootGuard ready but verified boot is disabled.\n" + "You can flash other firmware!\n" RESET); } } diff --git a/util/intelmetool/intelmetool.h b/util/intelmetool/intelmetool.h index 47b892ed25..bab661f9ae 100644 --- a/util/intelmetool/intelmetool.h +++ b/util/intelmetool/intelmetool.h @@ -48,11 +48,6 @@ #define ME_MESSAGE_LEN 256 extern int debug; -static inline void print_cap(const char *name, int state) -{ - printf("ME Capability: %-30s : %s\n", - name, state ? CRED "ON" RESET : CGRN "OFF" RESET); -} #define PCI_VENDOR_ID_INTEL 0x8086 @@ -495,13 +490,3 @@ static inline void print_cap(const char *name, int state) ((x) == PCI_DEVICE_ID_INTEL_LEWISBURG_IE3) || \ ((x) == PCI_DEVICE_ID_INTEL_CANNONLAKE) || \ 0) - -#define BOOTGUARD_DISABLED 0x400000000 -#define BOOTGUARD_ENABLED_VERIFIED_MODE 0x100000000 -#define BOOTGUARD_ENABLED_MEASUREMENT_MODE 0x200000000 -#define BOOTGUARD_ENABLED_COMBI_MODE 0x300000000 -#define BOOTGUARD_CAPABILITY(x) ( \ - ((x) == BOOTGUARD_DISABLED) || \ - ((x) == BOOTGUARD_ENABLED_VERIFIED_MODE) || \ - ((x) == BOOTGUARD_ENABLED_MEASUREMENT_MODE) || \ - ((x) == BOOTGUARD_ENABLED_COMBI_MODE)) diff --git a/util/intelmetool/me.c b/util/intelmetool/me.c index 694d733464..72430afc90 100644 --- a/util/intelmetool/me.c +++ b/util/intelmetool/me.c @@ -413,6 +413,12 @@ int mkhi_get_fw_version(int *major, int *minor) return 0; } +static void print_cap(const char *name, int state) +{ + printf("ME Capability: %-30s : %s\n", + name, state ? CRED "ON" RESET : CGRN "OFF" RESET); +} + /* Get ME Firmware Capabilities */ int mkhi_get_fwcaps(void) { diff --git a/util/intelmetool/msr.c b/util/intelmetool/msr.c index 263a8202bb..1a5ead9737 100644 --- a/util/intelmetool/msr.c +++ b/util/intelmetool/msr.c @@ -39,7 +39,7 @@ static int rdmsr(int addr, uint64_t *msr) } #endif -int msr_bootguard(uint64_t *msr, int debug) +int msr_bootguard(uint64_t *msr) { #ifndef __DARWIN__ @@ -54,8 +54,5 @@ int msr_bootguard(uint64_t *msr, int debug) return -1; #endif - if (!debug) - *msr &= ~0xff; - return 0; } diff --git a/util/intelmetool/msr.h b/util/intelmetool/msr.h index 44008d50c6..952b0c0a24 100644 --- a/util/intelmetool/msr.h +++ b/util/intelmetool/msr.h @@ -13,5 +13,5 @@ typedef struct { unsigned int ecx; } regs_t; -extern int msr_bootguard(uint64_t *msr, int debug); +extern int msr_bootguard(uint64_t *msr); #endif