Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/23756
Change subject: security/vboot: Add boot mode selection ......................................................................
security/vboot: Add boot mode selection
* Add Measured Boot mode.
Change-Id: I43d233d5a8766af2dd7f07cc0b64293a80d5d7d2 Signed-off-by: Philipp Deppenwiese zaolin@das-labor.org --- M src/arch/x86/postcar_loader.c M src/include/program_loading.h M src/lib/prog_ops.c M src/mainboard/google/poppy/Kconfig M src/mainboard/google/rotor/Kconfig M src/mainboard/intel/cannonlake_rvp/Kconfig M src/mainboard/intel/kblrvp/Kconfig M src/security/tpm/tspi.h M src/security/vboot/Kconfig M src/security/vboot/antirollback.h M src/security/vboot/secdata_mock.c M src/security/vboot/secdata_tpm.c M src/security/vboot/vboot_common.c M src/security/vboot/vboot_logic.c 14 files changed, 180 insertions(+), 34 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/56/23756/1
diff --git a/src/arch/x86/postcar_loader.c b/src/arch/x86/postcar_loader.c index 5523238..a1c2fc7 100644 --- a/src/arch/x86/postcar_loader.c +++ b/src/arch/x86/postcar_loader.c @@ -160,7 +160,7 @@ void run_postcar_phase(struct postcar_frame *pcf) { struct prog prog = - PROG_INIT(PROG_UNKNOWN, CONFIG_CBFS_PREFIX "/postcar"); + PROG_INIT(PROG_POSTCAR, CONFIG_CBFS_PREFIX "/postcar");
postcar_commit_mtrrs(pcf);
diff --git a/src/include/program_loading.h b/src/include/program_loading.h index 416e2e9..428427b 100644 --- a/src/include/program_loading.h +++ b/src/include/program_loading.h @@ -35,6 +35,7 @@ PROG_PAYLOAD, PROG_BL31, PROG_BL32, + PROG_POSTCAR, };
/* @@ -141,6 +142,10 @@ * 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); +/* + * Measured Boot specific + */ +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 44a32d1..a0f2a54 100644 --- a/src/lib/prog_ops.c +++ b/src/lib/prog_ops.c @@ -37,6 +37,7 @@
void prog_run(struct prog *prog) { + measured_prog_run(prog); platform_prog_run(prog); arch_prog_run(prog); } @@ -45,3 +46,8 @@ { /* do nothing */ } + +void __attribute__((weak)) measured_prog_run(struct prog *prog) +{ + /* do nothing */ +} diff --git a/src/mainboard/google/poppy/Kconfig b/src/mainboard/google/poppy/Kconfig index 9315d96..ee0b25d 100644 --- a/src/mainboard/google/poppy/Kconfig +++ b/src/mainboard/google/poppy/Kconfig @@ -120,7 +120,7 @@ select DRIVERS_I2C_MAX98927 select NO_FADT_8042 select VARIANT_HAS_CAMERA_ACPI - select VARIANT_HAS_I2C_TPM if !VBOOT_MOCK_SECDATA + select VARIANT_HAS_I2C_TPM
config VARIANT_SPECIFIC_OPTIONS_NAMI def_bool n @@ -129,21 +129,21 @@ select DRIVERS_PS2_KEYBOARD select DRIVERS_SPI_ACPI select EXCLUDE_NATIVE_SD_INTERFACE - select VARIANT_HAS_SPI_TPM if !VBOOT_MOCK_SECDATA + select VARIANT_HAS_SPI_TPM
config VARIANT_SPECIFIC_OPTIONS_NAUTILUS def_bool n select DRIVERS_GENERIC_MAX98357A select DRIVERS_I2C_DA7219 select DRIVERS_PS2_KEYBOARD - select VARIANT_HAS_I2C_TPM if !VBOOT_MOCK_SECDATA + select VARIANT_HAS_I2C_TPM
config VARIANT_SPECIFIC_OPTIONS_SORAKA def_bool n select DRIVERS_I2C_MAX98927 select NO_FADT_8042 select VARIANT_HAS_CAMERA_ACPI - select VARIANT_HAS_I2C_TPM if !VBOOT_MOCK_SECDATA + select VARIANT_HAS_I2C_TPM
config VBOOT select EC_GOOGLE_CHROMEEC_SWITCHES diff --git a/src/mainboard/google/rotor/Kconfig b/src/mainboard/google/rotor/Kconfig index 437fa02..6b5319e 100644 --- a/src/mainboard/google/rotor/Kconfig +++ b/src/mainboard/google/rotor/Kconfig @@ -21,9 +21,6 @@ select MAINBOARD_HAS_CHROMEOS select BOARD_ROMSIZE_KB_4096
-config VBOOT - select VBOOT_MOCK_SECDATA - config MAINBOARD_DIR string default google/rotor diff --git a/src/mainboard/intel/cannonlake_rvp/Kconfig b/src/mainboard/intel/cannonlake_rvp/Kconfig index b69a5e9..511603b 100644 --- a/src/mainboard/intel/cannonlake_rvp/Kconfig +++ b/src/mainboard/intel/cannonlake_rvp/Kconfig @@ -61,5 +61,4 @@
config VBOOT select VBOOT_LID_SWITCH - select VBOOT_MOCK_SECDATA endif diff --git a/src/mainboard/intel/kblrvp/Kconfig b/src/mainboard/intel/kblrvp/Kconfig index f483063..e5d4fec 100644 --- a/src/mainboard/intel/kblrvp/Kconfig +++ b/src/mainboard/intel/kblrvp/Kconfig @@ -26,7 +26,6 @@
config KBLRVP_NO_TPM bool "No TPM" - select VBOOT_MOCK_SECDATA if VBOOT
config KBLRVP_TPM1_2 bool "TPM 1.1" diff --git a/src/security/tpm/tspi.h b/src/security/tpm/tspi.h index bf2b7ae..775311e 100644 --- a/src/security/tpm/tspi.h +++ b/src/security/tpm/tspi.h @@ -21,6 +21,34 @@
#define TPM_PCR_MAX_LENGTH 64
+// PCR Registers used by coreboot +#define TPM_BOOTBLOCK_PCR 0 +#define TPM_STAGE_VERSTAGE_PCR 0 +#define TPM_STAGE_ROMSTAGE_PCR 1 +#define TPM_STAGE_POSTCAR_PCR 2 +#define TPM_STAGE_RAMSTAGE_PCR 2 +#define TPM_PAYLOAD_PCR 3 +#define TPM_FW_MAIN 1 + +// Vendor / Platform specific +#define TPM_INTEL_FSP_PCR 1 +#define TPM_INTEL_FSPM_PCR 1 +#define TPM_INTEL_FSPS_PCR 1 +#define TPM_INTEL_NHLT_PCR 1 +#define TPM_ARM_BL31_PCR 2 +#define TPM_ARM_BL32_PCR 2 +#define TPM_VGA_OPTION_ROM_PCR 2 +#define TPM_SPD_DATA_PCR 1 +#define TPM_AMD_PSP_PCR 1 +#define TPM_AMD_AGESA_PCR 1 +#define TPM_NVIDIA_MTC_PCR 1 +#define TPM_VBT_PCR 2 +#define TPM_MICROCODE_PCR 1 + +// special +#define TPM_UNKNOWN_PCR 4 + + /** * TPM measurement with acpi log functionality based on binary data. */ diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index ed613b6..6901ab8 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -26,6 +26,31 @@
if VBOOT
+choice + +prompt "Boot mode" + default VBOOT_MODE_VERIFIED_BOOT + help + Select the boot mode in which VBOOT should run. + +config VBOOT_MODE_VERIFIED_BOOT + bool "Verified Boot" + depends on TPM1 || TPM2 + +config VBOOT_MODE_VERIFIED_BOOT_NO_ROLLBACK_PROTECTION + bool "Verified Boot (no TPM)" + select VBOOT_MOCK_SECDATA + +config VBOOT_MODE_MEASURED_BOOT + bool "Measured Boot" + depends on TPM1 || TPM2 + +config VBOOT_MODE_VERIFIED_AND_MEASURED_BOOT + bool "Verified & Measured Boot" + depends on TPM1 || TPM2 + +endchoice + config VBOOT_VBNV_CMOS bool default n @@ -80,7 +105,7 @@ allocated in CBMEM.
config VBOOT_MOCK_SECDATA - bool "Mock secdata for firmware verification" + bool "Disable antirollback protection" default n help Enabling VBOOT_MOCK_SECDATA will mock secdata for the firmware diff --git a/src/security/vboot/antirollback.h b/src/security/vboot/antirollback.h index ae2d665..a784026 100644 --- a/src/security/vboot/antirollback.h +++ b/src/security/vboot/antirollback.h @@ -66,4 +66,7 @@ uint32_t vboot_extend_pcr(struct vb2_context *ctx, int pcr, enum vb2_pcr_digest which_digest);
+/* Measure boot mode requiredment. Measures bootblock and verstage */ +uint32_t vboot_measure_self(void); + #endif /* ANTIROLLBACK_H_ */ diff --git a/src/security/vboot/secdata_mock.c b/src/security/vboot/secdata_mock.c index 3075d33..184c4ae 100644 --- a/src/security/vboot/secdata_mock.c +++ b/src/security/vboot/secdata_mock.c @@ -79,3 +79,8 @@ { return VB2_SUCCESS; } + +uint32_t vboot_measure_self(void) +{ + return VB2_SUCCESS; +} diff --git a/src/security/vboot/secdata_tpm.c b/src/security/vboot/secdata_tpm.c index 9dff2ff..3d3d590 100644 --- a/src/security/vboot/secdata_tpm.c +++ b/src/security/vboot/secdata_tpm.c @@ -37,6 +37,8 @@ #include <security/tpm/tspi.h> #include <vb2_api.h> #include <console/console.h> +#include <security/tpm/tspi.h> +#include <cbfs.h>
#include "antirollback.h"
@@ -445,10 +447,6 @@ { uint32_t rv;
- rv = vboot_setup_tpm(ctx); - if (rv) - return rv; - /* Read the firmware space. */ rv = read_space_firmware(ctx); if (rv == TPM_E_BADINDEX) { @@ -521,3 +519,30 @@ return VB2_ERROR_EX_TPM_CLEAR_OWNER; return VB2_SUCCESS; } + +uint32_t vboot_measure_self(void) +{ + struct cbfsf file1, file2; + struct prog bootblock = PROG_INIT(PROG_UNKNOWN, "bootblock"); + + struct prog verstage = + PROG_INIT(PROG_VERSTAGE, CONFIG_CBFS_PREFIX "/verstage"); + + /* load verstage from RO */ + if (cbfs_boot_locate(&file1, prog_name(&bootblock), NULL)) + return VB2_ERROR_UNKNOWN; + + cbfs_file_data(prog_rdev(&bootblock), &file1); + + if (cbfs_boot_locate(&file2, prog_name(&verstage), NULL)) + return VB2_ERROR_UNKNOWN; + + cbfs_file_data(prog_rdev(&verstage), &file2); + + tpm_measure_region(TPM_BOOTBLOCK_PCR, prog_rdev(&bootblock), + "bootblock"); + tpm_measure_region(TPM_STAGE_VERSTAGE_PCR, prog_rdev(&verstage), + CONFIG_CBFS_PREFIX "/verstage"); + + return VB2_SUCCESS; +} diff --git a/src/security/vboot/vboot_common.c b/src/security/vboot/vboot_common.c index 3ef9070..5dbf77e 100644 --- a/src/security/vboot/vboot_common.c +++ b/src/security/vboot/vboot_common.c @@ -18,12 +18,14 @@ #include <cbmem.h> #include <console/cbmem_console.h> #include <console/console.h> +#include <program_loading.h> #include <fmap.h> #include <reset.h> #include <rules.h> #include <stddef.h> #include <string.h> #include <security/vboot/vboot_common.h> +#include <security/tpm/tspi.h>
int vboot_named_region_device(const char *name, struct region_device *rdev) { @@ -100,6 +102,55 @@ return sd->recovery_reason; }
+#if !ENV_BOOTBLOCK +void measured_prog_run(struct prog *prog) +{ + switch (prog->type) { + case PROG_VERSTAGE: + tpm_measure_region(TPM_STAGE_VERSTAGE_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_ROMSTAGE: + tpm_measure_region(TPM_STAGE_ROMSTAGE_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_RAMSTAGE: + tpm_measure_region(TPM_STAGE_RAMSTAGE_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_BL32: + tpm_measure_region(TPM_ARM_BL32_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_BL31: + tpm_measure_region(TPM_ARM_BL31_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_PAYLOAD: + tpm_measure_region(TPM_PAYLOAD_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_REFCODE: + tpm_measure_region(TPM_INTEL_FSP_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_POSTCAR: + tpm_measure_region(TPM_STAGE_POSTCAR_PCR, prog_rdev(prog), + prog->name); + break; + case PROG_UNKNOWN: + if (prog->name) { + tpm_measure_region(TPM_UNKNOWN_PCR, prog_rdev(prog), + prog->name); + } else { + die("Can't execute program if measured boot is active " + "and no program name given."); + } + break; + } +} +#endif + /* ============================ VBOOT REBOOT ============================== */ void __attribute__((weak)) vboot_platform_prepare_reboot(void) { diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index 3651a27..6067f6c 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -9,7 +9,7 @@ * * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See themeasure_self * GNU General Public License for more details. */
@@ -19,11 +19,11 @@ #include <console/console.h> #include <console/vtxprintf.h> #include <delay.h> +#include <security/vboot/misc.h> +#include <security/vboot/vbnv.h> #include <string.h> #include <timestamp.h> #include <vb2_api.h> -#include <security/vboot/misc.h> -#include <security/vboot/vbnv.h>
#include "antirollback.h"
@@ -53,11 +53,8 @@ return; }
-int vb2ex_read_resource(struct vb2_context *ctx, - enum vb2_resource_index index, - uint32_t offset, - void *buf, - uint32_t size) +int vb2ex_read_resource(struct vb2_context *ctx, enum vb2_resource_index index, + uint32_t offset, void *buf, uint32_t size) { struct region_device rdev; const char *name; @@ -86,24 +83,21 @@ }
/* No-op stubs that can be overridden by SoCs with hardware crypto support. */ -__attribute__((weak)) -int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, - uint32_t data_size) +__attribute__((weak)) int +vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, uint32_t data_size) { return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; }
-__attribute__((weak)) -int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size) +__attribute__((weak)) int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, + uint32_t size) { - BUG(); /* Should never get called if init() returned an error. */ return VB2_ERROR_UNKNOWN; }
-__attribute__((weak)) -int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size) +__attribute__((weak)) int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, + uint32_t digest_size) { - BUG(); /* Should never get called if init() returned an error. */ return VB2_ERROR_UNKNOWN; }
@@ -249,7 +243,7 @@ }
static int locate_firmware(struct vb2_context *ctx, - struct region_device *fw_main) + struct region_device *fw_main) { const char *name;
@@ -313,6 +307,15 @@ vboot_platform_is_resuming()) ctx.flags |= VB2_CONTEXT_S3_RESUME;
+ /* setup tpm */ + vboot_setup_tpm(&ctx); + + /* Enable measured boot mode */ +#if IS_ENABLED(CONFIG_VBOOT_MODE_MEASURED_BOOT) + if (vboot_measure_self() != VB2_SUCCESS) + die("Initializing measured boot mode failed!"); +#endif + /* Read secdata from TPM. Initialize TPM if secdata not found. We don't * check the return value here because vb2api_fw_phase1 will catch * invalid secdata and tell us what to do (=reboot). */ @@ -351,7 +354,7 @@ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) { printk(BIOS_INFO, "Recovery requested (%x)\n", rv); save_if_needed(&ctx); - extend_pcrs(&ctx); /* ignore failures */ + extend_pcrs(&ctx); /* ignore failures */ timestamp_add_now(TS_END_VBOOT); return; }