Bill XIE has uploaded this change for review.

View Change

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

To view, visit change 35077. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I1fb376b4a8b98baffaee4d574937797bba1f8aee
Gerrit-Change-Number: 35077
Gerrit-PatchSet: 1
Gerrit-Owner: Bill XIE <persmule@hardenedlinux.org>
Gerrit-MessageType: newchange