From eeacd8349c1bf208acf393e10e72a6da413a67ef Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 19 Feb 2021 17:14:23 +0100 Subject: [PATCH] cpu/intel/fit: Add the FIT table as a separate CBFS file With CBnT a digest needs to be made of the IBB, Initial BootBlock, in this case the bootblock. After that a pointer to the BPM, Boot Policy Manifest, containing the IBB digest needs to be added to the FIT table. If the fit table is inside the IBB, updating it with a pointer to the BPM, would make the digest invalid. The proper solution is to move the FIT table out of the bootblock. The FIT table itself does not need to be covered by the digest as it just contains pointers to structures that can by verified by the hardware itself, such as microcode and ACMs (Authenticated Code Modules). Change-Id: I352e11d5f7717147a877be16a87e9ae35ae14856 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/50926 Reviewed-by: Patrick Rudolph Reviewed-by: Christian Walter Tested-by: build bot (Jenkins) --- src/cpu/intel/fit/Makefile.inc | 27 ++++++++++++++++++++++++++- src/cpu/intel/fit/fit.S | 25 ++----------------------- src/cpu/intel/fit/fit_table.c | 21 +++++++++++++++++++++ src/security/intel/cbnt/Makefile.inc | 4 ++-- src/security/intel/txt/Makefile.inc | 4 ++-- src/security/vboot/Makefile.inc | 2 ++ 6 files changed, 55 insertions(+), 28 deletions(-) create mode 100644 src/cpu/intel/fit/fit_table.c diff --git a/src/cpu/intel/fit/Makefile.inc b/src/cpu/intel/fit/Makefile.inc index 3b18e0b6aa..ee6d55885d 100644 --- a/src/cpu/intel/fit/Makefile.inc +++ b/src/cpu/intel/fit/Makefile.inc @@ -1,5 +1,20 @@ bootblock-y += fit.S +# The FIT table is generated as a separate CBFS file. +# The FIT pointer is reserved in fit.c and updated to point to the 'intel_fit' +# CBFS file using 'ifittool -F'. +# With a TOP_SWAP enabled bootblock the FIT pointer at the top swap offset +# will point to the 'intel_fit_ts' CBFS file. + +cbfs-files-y += intel_fit +intel_fit-file := fit_table.c:struct +intel_fit-type := raw +intel_fit-align := 16 + +$(call add_intermediate, set_fit_ptr, $(IFITTOOL)) + @printf " UPDATE-FIT set FIT pointer to table\n" + $(IFITTOOL) -f $< -F -n intel_fit -r COREBOOT + FIT_ENTRY=$(call strip_quotes, $(CONFIG_INTEL_TOP_SWAP_FIT_ENTRY_FMAP_REG)) ifneq ($(CONFIG_UPDATE_IMAGE),y) # never update the bootblock @@ -13,13 +28,23 @@ $(call add_intermediate, add_mcu_fit, $(IFITTOOL)) # Second FIT in TOP_SWAP bootblock ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y) -$(call add_intermediate, add_ts_mcu_fit, $(IFITTOOL)) +$(call add_intermediate, add_ts_mcu_fit, $(IFITTOOL) set_fit_ptr_ts) @printf " UPDATE-FIT Top Swap: Microcode\n" ifneq ($(FIT_ENTRY),) $(IFITTOOL) -f $< -A -n $(FIT_ENTRY) -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r COREBOOT endif # FIT_ENTRY $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r COREBOOT +cbfs-files-y += intel_fit_ts +intel_fit_ts-file := fit_table.c:struct +intel_fit_ts-type := raw +intel_fit_ts-align := 16 + +PHONY += set_ts_fit_ptr +set_ts_fit_ptr: $(obj)/coreboot.pre $(IFITTOOL) + @printf " UPDATE-FIT Top Swap: set FIT pointer to table\n" + $(IFITTOOL) -f $< -F -n intel_fit_ts -r COREBOOT -t $(TS_OPTIONS) + endif # CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK endif # CONFIG_CPU_MICROCODE_CBFS_NONE diff --git a/src/cpu/intel/fit/fit.S b/src/cpu/intel/fit/fit.S index afecacdcd8..ca95a90c2f 100644 --- a/src/cpu/intel/fit/fit.S +++ b/src/cpu/intel/fit/fit.S @@ -2,29 +2,8 @@ .section ".fit_pointer", "a", @progbits .code32 +/* This will get updated by ifittool later on to point to the cbfs 'intel_fit' file. */ .global fit_pointer fit_pointer: -.long fit_table .long 0 - -.section .text -.align 16 -.global fit_table -.global fit_table_end -fit_table: -/* Address for type 0 is '_FIT_ ' */ -.long 0x5449465f -.long 0x2020205f -/* - * There is 1 entry in the table. Other tools will have to update the size - * and checksum when adding entries. - */ -.long 0x00000001 -/* Version */ -.word 0x0100 -/* Type 0 with checksum valid. */ -.byte 0x80 -/* Checksum byte - must add to zero. */ -.byte 0x7d -.fill CONFIG_CPU_INTEL_NUM_FIT_ENTRIES*16 -fit_table_end: +.long 0 diff --git a/src/cpu/intel/fit/fit_table.c b/src/cpu/intel/fit/fit_table.c new file mode 100644 index 0000000000..62d624f5b0 --- /dev/null +++ b/src/cpu/intel/fit/fit_table.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +struct fit_entry { + uint8_t address[sizeof(uint64_t)]; + uint32_t size_reserved; + uint16_t version; + uint8_t type_checksum_valid; + uint8_t checksum; +} __packed; + +__attribute((used)) static struct fit_entry fit_table[CONFIG_CPU_INTEL_NUM_FIT_ENTRIES + 1] = { + [0] = { + .address = {'_', 'F', 'I', 'T', '_', ' ', ' ', ' '}, + .size_reserved = 1, + .version = 0x100, + .type_checksum_valid = 0x80, + .checksum = 0x7d, + } +}; diff --git a/src/security/intel/cbnt/Makefile.inc b/src/security/intel/cbnt/Makefile.inc index b612a81655..b8ea702df2 100644 --- a/src/security/intel/cbnt/Makefile.inc +++ b/src/security/intel/cbnt/Makefile.inc @@ -6,7 +6,7 @@ boot_policy_manifest.bin-file := $(CONFIG_INTEL_CBNT_BOOT_POLICY_MANIFEST_BINARY boot_policy_manifest.bin-type := raw boot_policy_manifest.bin-align := 0x10 -$(call add_intermediate, add_bpm_fit, $(IFITTOOL)) +$(call add_intermediate, add_bpm_fit, $(IFITTOOL) set_fit_ptr) $(IFITTOOL) -r COREBOOT -a -n boot_policy_manifest.bin -t 12 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -f $< endif @@ -16,7 +16,7 @@ key_manifest.bin-file := $(CONFIG_INTEL_CBNT_KEY_MANIFEST_BINARY) key_manifest.bin-type := raw key_manifest.bin-align := 0x10 -$(call add_intermediate, add_km_fit, $(IFITTOOL)) +$(call add_intermediate, add_km_fit, $(IFITTOOL) set_fit_ptr) $(IFITTOOL) -r COREBOOT -a -n key_manifest.bin -t 11 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -f $< endif diff --git a/src/security/intel/txt/Makefile.inc b/src/security/intel/txt/Makefile.inc index cdcbd40660..d3323417c0 100644 --- a/src/security/intel/txt/Makefile.inc +++ b/src/security/intel/txt/Makefile.inc @@ -28,7 +28,7 @@ endif ifeq ($(CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE),y) -$(call add_intermediate, add_acm_fit, $(IFITTOOL)) +$(call add_intermediate, add_acm_fit, $(IFITTOOL) set_fit_ptr) $(IFITTOOL) -r COREBOOT -a -n $(CONFIG_INTEL_TXT_CBFS_BIOS_ACM) -t 2 \ -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -f $< @@ -41,7 +41,7 @@ ibb-files := $(foreach file,$(cbfs-files), \ ibb-files += bootblock -$(call add_intermediate, add_ibb_fit, $(IFITTOOL)) +$(call add_intermediate, add_ibb_fit, $(IFITTOOL) set_fit_ptr) $(foreach file, $(ibb-files), $(shell $(IFITTOOL) -f $< -a -n $(file) -t 7 \ -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT)) true diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc index 74b397c76c..cecaa2d6e7 100644 --- a/src/security/vboot/Makefile.inc +++ b/src/security/vboot/Makefile.inc @@ -185,6 +185,8 @@ regions-for-file = $(subst $(spc),$(comma),$(sort \ rmu.bin \ cmos_layout.bin \ cmos.default \ + intel_fit \ + intel_fit_ts \ $(call strip_quotes,$(CONFIG_RO_REGION_ONLY)) \ ,$(1)),COREBOOT,\ $(if $(filter \