Bill XIE has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35077 )
Change subject: security/vboot: Decouple measured boot from verified boot ......................................................................
security/vboot: Decouple measured boot from verified boot
As said in CB:34977, currently TPM and CRTM are initialized just before romstage loads a file within CBFS, or initialized in vboot_logic() if CONFIG_VBOOT is set.
Change-Id: I1fb376b4a8b98baffaee4d574937797bba1f8aee Signed-off-by: Bill XIE persmule@hardenedlinux.org --- M src/lib/cbfs.c M src/security/tpm/Makefile.inc M src/security/tpm/tspi/tspi.c M src/security/vboot/Kconfig M src/security/vboot/Makefile.inc M src/security/vboot/misc.h M src/security/vboot/vboot_crtm.c M src/security/vboot/vboot_crtm.h 8 files changed, 136 insertions(+), 68 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/35077/1
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 91368fb..246e741 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -327,6 +327,9 @@ * devices. */ const struct cbfs_locator __weak cbfs_master_header_locator = { .name = "Master Header Locator", +#if !CONFIG(VBOOT) && CONFIG(VBOOT_MEASURED_BOOT) + .prepare = measured_boot_init_crtm, +#endif .locate = cbfs_master_header_props, };
diff --git a/src/security/tpm/Makefile.inc b/src/security/tpm/Makefile.inc index a2d32cf..cb936cf 100644 --- a/src/security/tpm/Makefile.inc +++ b/src/security/tpm/Makefile.inc @@ -8,7 +8,10 @@ romstage-y += tss/tcg-1.2/tss.c
verstage-$(CONFIG_VBOOT) += tss/tcg-1.2/tss.c -postcar-$(CONFIG_VBOOT) += tss/tcg-1.2/tss.c + +ifneq ($(CONFIG_VBOOT_MEASURED_BOOT)$(CONFIG_VBOOT),) +postcar-y += tss/tcg-1.2/tss.c +endif
## TSPI
@@ -16,7 +19,10 @@ romstage-y += tspi/tspi.c
verstage-$(CONFIG_VBOOT) += tspi/tspi.c -postcar-$(CONFIG_VBOOT) += tspi/tspi.c + +ifneq ($(CONFIG_VBOOT_MEASURED_BOOT)$(CONFIG_VBOOT),) +postcar-y += tspi/tspi.c +endif
ramstage-$(CONFIG_VBOOT_MEASURED_BOOT) += tspi/log.c romstage-$(CONFIG_VBOOT_MEASURED_BOOT) += tspi/log.c @@ -45,7 +51,10 @@ romstage-y += tspi/tspi.c
verstage-$(CONFIG_VBOOT) += tspi/tspi.c -postcar-$(CONFIG_VBOOT) += tspi/tspi.c + +ifneq ($(CONFIG_VBOOT_MEASURED_BOOT)$(CONFIG_VBOOT),) +postcar-y += tspi/tspi.c +endif
ramstage-$(CONFIG_VBOOT_MEASURED_BOOT) += tspi/log.c romstage-$(CONFIG_VBOOT_MEASURED_BOOT) += tspi/log.c diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 4698a4d..36dd3dd 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -20,7 +20,7 @@ #include <security/tpm/tspi.h> #include <security/tpm/tss.h> #include <stdlib.h> -#if CONFIG(VBOOT) +#if CONFIG(VBOOT) || CONFIG(VBOOT_MEASURED_BOOT) #include <vb2_api.h> #include <vb2_sha.h> #include <assert.h> @@ -220,7 +220,7 @@ return TPM_SUCCESS; }
-#if CONFIG(VBOOT) +#if CONFIG(VBOOT) || CONFIG(VBOOT_MEASURED_BOOT) uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr, const char *rname) { @@ -279,4 +279,4 @@ printk(BIOS_DEBUG, "TPM: Measured %s into PCR %d\n", rname, pcr); return TPM_SUCCESS; } -#endif /* VBOOT */ +#endif /* VBOOT || VBOOT_MEASURED_BOOT */ diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index c5146c6..955e8a6 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -13,7 +13,7 @@ ## GNU General Public License for more details. ##
-menu "Verified Boot (vboot)" +menu "vboot functionalities"
config VBOOT bool "Verify firmware with vboot." @@ -21,21 +21,17 @@ select VBOOT_MOCK_SECDATA if !TPM1 && !TPM2 depends on !MISSING_BOARD_RESET help - Enabling VBOOT will use vboot to verify the components of the firmware + Enabling verified voot will use vboot to verify the components of the firmware (stages, payload, etc).
-if VBOOT - -comment "Anti-Rollback Protection disabled because mocking secdata is enabled." - depends on VBOOT_MOCK_SECDATA - config VBOOT_MEASURED_BOOT - bool "Enable Measured Boot" + bool "Measure firmware components with vboot." default n depends on TPM1 || TPM2 depends on !VBOOT_RETURN_FROM_VERSTAGE help - Enables measured boot mode in vboot (experimental) + Enables measured boot will use vboot to measure the components of the firmware + (stages, payload, etc) to PCRs within TPM. (experimental)
config VBOOT_MEASURED_BOOT_RUNTIME_DATA string "Runtime data whitelist" @@ -45,6 +41,13 @@ Runtime data whitelist of cbfs filenames. Needs to be a comma separated list
+if VBOOT + +comment "Anti-Rollback Protection disabled because mocking secdata is enabled." + depends on VBOOT_MOCK_SECDATA + +comment "A non-trivial fmd file with sections required by vboot is needed." + config VBOOT_SLOTS_RW_A bool "Firmware RO + RW_A" help diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc index d554f10..0729d9f 100644 --- a/src/security/vboot/Makefile.inc +++ b/src/security/vboot/Makefile.inc @@ -14,6 +14,58 @@ ## GNU General Public License for more details. ##
+ifneq ($(CONFIG_VBOOT_MEASURED_BOOT)$(CONFIG_VBOOT),) + +ifneq ($(CONFIG_TPM1)$(CONFIG_TPM2),) +verstage-y += tpm_common.c +endif + + +vboot-fixup-includes = $(patsubst -I%,-I$(top)/%,\ + $(patsubst $(src)/%.h,$(top)/$(src)/%.h,\ + $(filter-out -I$(obj),$(1)))) + +# call with $1 = stage name to create rules for building the library +# for the stage and adding it to the stage's set of object files. +define vboot-for-stage +VB2_LIB_$(1) = $(obj)/external/vboot_reference-$(1)/vboot_fw20.a +VBOOT_CFLAGS_$(1) += $$(call vboot-fixup-includes,$$(CPPFLAGS_$(1))) +VBOOT_CFLAGS_$(1) += $$(CFLAGS_$(1)) +VBOOT_CFLAGS_$(1) += $$(call vboot-fixup-includes,$$($(1)-c-ccopts)) +VBOOT_CFLAGS_$(1) += -I$(abspath $(obj)) -Wno-missing-prototypes +VBOOT_CFLAGS_$(1) += -DVBOOT_DEBUG + +$$(VB2_LIB_$(1)): $(obj)/config.h + printf " MAKE $(subst $(obj)/,,$(@))\n" + +FIRMWARE_ARCH=$$(ARCHDIR-$$(ARCH-$(1)-y)) \ + CC="$$(CC_$(1))" \ + CFLAGS="$$(VBOOT_CFLAGS_$(1))" VBOOT2="y" \ + $(MAKE) -C $(VBOOT_SOURCE) \ + BUILD=$$(abspath $$(dir $$(VB2_LIB_$(1)))) \ + V=$(V) \ + fwlib20 + +$(1)-srcs += $$(VB2_LIB_$(1)) + +endef # vboot-for-stage + +CFLAGS_common += -I3rdparty/vboot/firmware/2lib/include + +$(eval $(call vboot-for-stage,bootblock)) +$(eval $(call vboot-for-stage,romstage)) +$(eval $(call vboot-for-stage,ramstage)) +$(eval $(call vboot-for-stage,postcar)) + +endif # CONFIG_VBOOT_MEASURED_BOOT || CONFIG_VBOOT + +ifeq ($(CONFIG_VBOOT_MEASURED_BOOT),y) +bootblock-y += vboot_crtm.c +verstage-y += vboot_crtm.c +romstage-y += vboot_crtm.c +ramstage-y += vboot_crtm.c +postcar-y += vboot_crtm.c +endif # CONFIG_VBOOT_MEASURED_BOOT + ifeq ($(CONFIG_VBOOT),y)
bootblock-y += bootmode.c @@ -22,6 +74,12 @@ verstage-y += bootmode.c postcar-y += bootmode.c
+bootblock-y += vboot_common.c +verstage-y += vboot_common.c +romstage-y += vboot_common.c +ramstage-y += vboot_common.c +postcar-y += vboot_common.c + # When VBOOT_STARTS_IN_ROMSTAGE is selected, DRAM is already up by # the time verstage runs. ifneq ($(CONFIG_VBOOT_STARTS_IN_ROMSTAGE),y) @@ -63,19 +121,7 @@ verstage-y += vboot_loader.c postcar-y += vboot_loader.c
-bootblock-y += vboot_common.c -verstage-y += vboot_common.c -romstage-y += vboot_common.c -ramstage-y += vboot_common.c -postcar-y += vboot_common.c
-ifeq ($(CONFIG_VBOOT_MEASURED_BOOT),y) -bootblock-y += vboot_crtm.c -verstage-y += vboot_crtm.c -romstage-y += vboot_crtm.c -ramstage-y += vboot_crtm.c -postcar-y += vboot_crtm.c -endif
bootblock-y += common.c verstage-y += vboot_logic.c @@ -89,10 +135,6 @@ romstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += secdata_tpm.c endif
-ifneq ($(CONFIG_TPM1)$(CONFIG_TPM2),) -verstage-y += tpm_common.c -endif - romstage-y += vboot_logic.c romstage-y += common.c
@@ -101,41 +143,6 @@
romstage-$(CONFIG_FSP2_0_USES_TPM_MRC_HASH) += mrc_cache_hash_tpm.c
-vboot-fixup-includes = $(patsubst -I%,-I$(top)/%,\ - $(patsubst $(src)/%.h,$(top)/$(src)/%.h,\ - $(filter-out -I$(obj),$(1)))) - -# call with $1 = stage name to create rules for building the library -# for the stage and adding it to the stage's set of object files. -define vboot-for-stage -VB2_LIB_$(1) = $(obj)/external/vboot_reference-$(1)/vboot_fw20.a -VBOOT_CFLAGS_$(1) += $$(call vboot-fixup-includes,$$(CPPFLAGS_$(1))) -VBOOT_CFLAGS_$(1) += $$(CFLAGS_$(1)) -VBOOT_CFLAGS_$(1) += $$(call vboot-fixup-includes,$$($(1)-c-ccopts)) -VBOOT_CFLAGS_$(1) += -I$(abspath $(obj)) -Wno-missing-prototypes -VBOOT_CFLAGS_$(1) += -DVBOOT_DEBUG - -$$(VB2_LIB_$(1)): $(obj)/config.h - printf " MAKE $(subst $(obj)/,,$(@))\n" - +FIRMWARE_ARCH=$$(ARCHDIR-$$(ARCH-$(1)-y)) \ - CC="$$(CC_$(1))" \ - CFLAGS="$$(VBOOT_CFLAGS_$(1))" VBOOT2="y" \ - $(MAKE) -C $(VBOOT_SOURCE) \ - BUILD=$$(abspath $$(dir $$(VB2_LIB_$(1)))) \ - V=$(V) \ - fwlib20 - -$(1)-srcs += $$(VB2_LIB_$(1)) - -endef # vboot-for-stage - -CFLAGS_common += -I3rdparty/vboot/firmware/2lib/include - -$(eval $(call vboot-for-stage,bootblock)) -$(eval $(call vboot-for-stage,romstage)) -$(eval $(call vboot-for-stage,ramstage)) -$(eval $(call vboot-for-stage,postcar)) - ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y)
$(eval $(call vboot-for-stage,verstage)) diff --git a/src/security/vboot/misc.h b/src/security/vboot/misc.h index 725f5fd..8761b84 100644 --- a/src/security/vboot/misc.h +++ b/src/security/vboot/misc.h @@ -127,5 +127,21 @@ } }
+static inline int vboot_crtm_is_set(void) +{ + extern int crtm_is_set; + if (CONFIG(VBOOT)) { + return vboot_logic_executed(); + } else if(ENV_ROMSTAGE) { + return car_get_var(crtm_is_set); + } else { +#ifdef __PRE_RAM__ + return 0; +#else + return 1; +#endif + } +} +
#endif /* __VBOOT_MISC_H__ */ diff --git a/src/security/vboot/vboot_crtm.c b/src/security/vboot/vboot_crtm.c index e4266b2..92f05e5 100644 --- a/src/security/vboot/vboot_crtm.c +++ b/src/security/vboot/vboot_crtm.c @@ -19,11 +19,13 @@ #include <security/vboot/vboot_crtm.h> #include <security/vboot/misc.h> #include <string.h> +#include <timestamp.h>
/* * This functions sets the TCPA log namespace * for the cbfs file (region) lookup. */ + static int create_tcpa_metadata(const struct region_device *rdev, const char *cbfs_name, char log_string[TCPA_PCR_HASH_NAME]) { @@ -90,7 +92,8 @@ } }
- if (CONFIG(VBOOT_STARTS_IN_ROMSTAGE)) { + if (CONFIG(VBOOT_STARTS_IN_ROMSTAGE) || + CONFIG(VBOOT_MEASURED_BOOT)) { struct cbfsf romstage_data; /* measure romstage from RO */ if (cbfs_boot_locate(&romstage_data, @@ -164,7 +167,7 @@ struct region_device rdev; char tcpa_metadata[TCPA_PCR_HASH_NAME];
- if (!vboot_logic_executed()) + if (!vboot_crtm_is_set()) return 0;
cbfsf_file_type(fh, &cbfs_type); @@ -193,3 +196,26 @@
return tpm_measure_region(&rdev, pcr_index, tcpa_metadata); } + +int crtm_is_set CAR_GLOBAL; + +void measured_boot_init_crtm(void) +{ + if (ENV_ROMSTAGE) { + timestamp_add_now(TS_START_TPMINIT); + int result = tpm_setup(vboot_platform_is_resuming()); + timestamp_add_now(TS_END_TPMINIT); + + if (result == TPM_SUCCESS) { + result = vboot_init_crtm(); + if(result != VB2_SUCCESS) { + printk(BIOS_INFO, + "Initializing CRTM failed!"); + } else { + car_set_var(crtm_is_set, 1); + } + } else { + printk(BIOS_INFO, "TPM setup failed!"); + } + } +} diff --git a/src/security/vboot/vboot_crtm.h b/src/security/vboot/vboot_crtm.h index 64cb4f2..87bfa2d 100644 --- a/src/security/vboot/vboot_crtm.h +++ b/src/security/vboot/vboot_crtm.h @@ -53,6 +53,10 @@ * return 0 if successful, else an error */ uint32_t vboot_measure_cbfs_hook(struct cbfsf *fh, const char *name); +/* + * Initialize crtm without running vboot_logic() + */ +void measured_boot_init_crtm(void);
#else #define vboot_measure_cbfs_hook(fh, name) 0