Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/29547
Change subject: security/vboot: Add measured boot mode ......................................................................
security/vboot: Add measured boot mode
* Introduce a measured boot mode into vboot. * Add hook for stage measurements in prog_ops. * Implement and hook-up CRTM in vboot.
Change-Id: I339a2f1051e44f36aba9f99828f130592a09355e Signed-off-by: Philipp Deppenwiese zaolin.daisuki@gmail.com --- M src/include/program_loading.h M src/lib/prog_ops.c M src/security/vboot/Kconfig M src/security/vboot/Makefile.inc A src/security/vboot/vboot_crtm.c A src/security/vboot/vboot_crtm.h M src/security/vboot/vboot_logic.c 7 files changed, 228 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/47/29547/1
diff --git a/src/include/program_loading.h b/src/include/program_loading.h index 26d0295..c902fcc 100644 --- a/src/include/program_loading.h +++ b/src/include/program_loading.h @@ -146,6 +146,8 @@ * special that needs to be done by the platform similar to the architecture * code it needs to that as well. */ void platform_prog_run(struct prog *prog); +/* VBOOT specific hook */ +void measured_prog_run(struct prog *prog);
struct prog_loader_ops { const char *name; diff --git a/src/lib/prog_ops.c b/src/lib/prog_ops.c index 2641ac6..e7d44d3 100644 --- a/src/lib/prog_ops.c +++ b/src/lib/prog_ops.c @@ -15,6 +15,7 @@ */
#include <program_loading.h> +#include <security/vboot/vboot_crtm.h>
/* For each segment of a program loaded this function is called*/ void prog_segment_loaded(uintptr_t start, size_t size, int flags) @@ -37,6 +38,7 @@
void prog_run(struct prog *prog) { + vboot_prog_run(prog); platform_prog_run(prog); arch_prog_run(prog); } @@ -45,3 +47,8 @@ { /* do nothing */ } + +void __weak vboot_prog_run(struct prog *prog) +{ + /* do nothing */ +} diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index 77483d1..e7cb43a 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -25,6 +25,12 @@
if VBOOT
+config VBOOT_MEASURED_BOOT + bool "Enable Measured Boot mode" + default n + help + Enables measured boot mode in vboot + config VBOOT_VBNV_CMOS bool default n diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc index f51db80..7e16193 100644 --- a/src/security/vboot/Makefile.inc +++ b/src/security/vboot/Makefile.inc @@ -62,6 +62,16 @@ ramstage-y += vboot_common.c postcar-y += vboot_common.c
+ifeq ($(CONFIG_VBOOT_MEASURED_BOOT),y) +ifneq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) +bootblock-$(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) += vboot_crtm.c +endif +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 verstage-y += common.c diff --git a/src/security/vboot/vboot_crtm.c b/src/security/vboot/vboot_crtm.c new file mode 100644 index 0000000..5b76aa8 --- /dev/null +++ b/src/security/vboot/vboot_crtm.c @@ -0,0 +1,154 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Facebook Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cbfs.h> +#include <console/console.h> +#include <fmap.h> +#include <security/tpm/tspi.h> +#include <security/vboot/vboot_crtm.h> +#include <program_loading.h> + +uint32_t vboot_init_crtm(void) +{ + struct prog bootblock = PROG_INIT(PROG_BOOTBLOCK, "bootblock"); + struct prog verstage = + PROG_INIT(PROG_VERSTAGE, CONFIG_CBFS_PREFIX "/verstage"); + struct prog romstage = + PROG_INIT(PROG_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage"); + + /* measure bootblock from RO */ + struct cbfsf bootblock_data; + if (cbfs_boot_locate(&bootblock_data, + prog_name(&bootblock), + NULL) + == 0) { + cbfs_file_data(prog_rdev(&bootblock), &bootblock_data); + + if (tpm_measure_region(prog_rdev(&bootblock), + TPM_BOOTBLOCK_PCR, + "bootblock")) { + return VB2_ERROR_UNKNOWN; + } + } else { + struct region_device fmap; + if (fmap_locate_area_as_rdev("BOOTBLOCK", &fmap) == 0) { + if (tpm_measure_region(&fmap, TPM_BOOTBLOCK_PCR, + "bootblock")) { + return VB2_ERROR_UNKNOWN; + } + } else { + printk(BIOS_INFO, + "VBOOT: Couldn't measure %s into CRTM!", + "bootblock"); + } + } + + if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) { + struct cbfsf romstage_data; + /* measure verstage from RO */ + if (cbfs_boot_locate(&romstage_data, prog_name(&romstage), + NULL) + == 0) { + cbfs_file_data(prog_rdev(&romstage), &romstage_data); + + if (tpm_measure_region(prog_rdev(&romstage), + TPM_STAGE_ROMSTAGE_PCR, + CONFIG_CBFS_PREFIX + "/romstage") + != TPM_SUCCESS) { + return VB2_ERROR_UNKNOWN; + } + } else { + printk(BIOS_INFO, + "VBOOT: Couldn't measure %s into CRTM!", + CONFIG_CBFS_PREFIX "/romstage"); + } + } + + if (IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE)) { + struct cbfsf verstage_data; + /* measure verstage from RO */ + if (cbfs_boot_locate(&verstage_data, prog_name(&verstage), + NULL) + == 0) { + cbfs_file_data(prog_rdev(&verstage), &verstage_data); + + if (tpm_measure_region(prog_rdev(&verstage), + TPM_STAGE_VERSTAGE_PCR, + CONFIG_CBFS_PREFIX + "/verstage") + != TPM_SUCCESS) { + return VB2_ERROR_UNKNOWN; + } + } else { + printk(BIOS_INFO, + "VBOOT: Couldn't measure %s into CRTM!", + CONFIG_CBFS_PREFIX "/verstage"); + } + } + + return VB2_SUCCESS; +} + +void vboot_prog_run(struct prog *prog) +{ + switch (prog->type) { + case PROG_BOOTBLOCK: + tpm_measure_region(prog_rdev(prog), TPM_BOOTBLOCK_PCR, + prog->name); + break; + case PROG_VERSTAGE: + tpm_measure_region(prog_rdev(prog), TPM_STAGE_VERSTAGE_PCR, + prog->name); + break; + case PROG_ROMSTAGE: + tpm_measure_region(prog_rdev(prog), TPM_STAGE_ROMSTAGE_PCR, + prog->name); + break; + case PROG_RAMSTAGE: + tpm_measure_region(prog_rdev(prog), TPM_STAGE_RAMSTAGE_PCR, + prog->name); + break; + case PROG_BL32: + tpm_measure_region(prog_rdev(prog), TPM_ARM_BL32_PCR, + prog->name); + break; + case PROG_BL31: + tpm_measure_region(prog_rdev(prog), TPM_ARM_BL31_PCR, + prog->name); + break; + case PROG_PAYLOAD: + tpm_measure_region(prog_rdev(prog), TPM_PAYLOAD_PCR, + prog->name); + break; + case PROG_REFCODE: + tpm_measure_region(prog_rdev(prog), TPM_INTEL_FSP_PCR, + prog->name); + break; + case PROG_POSTCAR: + tpm_measure_region(prog_rdev(prog), TPM_STAGE_POSTCAR_PCR, + prog->name); + break; + case PROG_UNKNOWN: + if (prog->name) { + tpm_measure_region(prog_rdev(prog), TPM_UNKNOWN_PCR, + prog->name); + } else { + die("Can't execute program if measured boot is active " + "and no program name given."); + } + break; + } +} diff --git a/src/security/vboot/vboot_crtm.h b/src/security/vboot/vboot_crtm.h new file mode 100644 index 0000000..d05fc14 --- /dev/null +++ b/src/security/vboot/vboot_crtm.h @@ -0,0 +1,42 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Facebook Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __VBOOT_VBOOT_CRTM_H__ +#define __VBOOT_VBOOT_CRTM_H__ + +// CRTM +#define TPM_BOOTBLOCK_PCR 0 +#define TPM_STAGE_VERSTAGE_PCR 0 +#define TPM_STAGE_ROMSTAGE_PCR 0 + +// Soc Init +#define TPM_STAGE_POSTCAR_PCR 1 +#define TPM_STAGE_RAMSTAGE_PCR 1 +#define TPM_INTEL_FSP_PCR 1 + +// Payload +#define TPM_PAYLOAD_PCR 3 +#define TPM_ARM_BL31_PCR 3 +#define TPM_ARM_BL32_PCR 3 + +// Unknown +#define TPM_UNKNOWN_PCR 4 + +//PCR for measuring data which might not be part of the TPM sealing +#define TPM_WHITELISTED_PCR 23 + +uint32_t vboot_init_crtm(void); + +#endif /* __VBOOT_VBOOT_CRTM_H__ */ diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index 1b24160..b9ee802 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -24,6 +24,7 @@ #include <vb2_api.h> #include <security/vboot/misc.h> #include <security/vboot/vbnv.h> +#include <security/vboot/vboot_crtm.h>
#include "antirollback.h"
@@ -319,6 +320,12 @@ antirollback_read_space_firmware(&ctx); timestamp_add_now(TS_END_TPMINIT);
+ /* Enable measured boot mode */ + if (IS_ENABLED(CONFIG_VBOOT_MEASURED_BOOT)) { + if (vboot_init_crtm() != VB2_SUCCESS) + die("Initializing measured boot mode failed!"); + } + if (IS_ENABLED(CONFIG_VBOOT_PHYSICAL_DEV_SWITCH) && get_developer_mode_switch()) ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;