security/vboot: Add support for GSCVD (Google "RO verification")

This patch adds a new CONFIG_VBOOT_GSCVD option that will be enabled by
default for TPM_GOOGLE_TI50 devices. It makes the build system run the
`futility gscvd` command to create a GSCVD (GSC verification data) which
signs the CBFS trust anchor (bootblock and GBB). In order for this to
work, boards will need to have an RO_GSCVD section in their FMAP, and
production boards should override the CONFIG_VBOOT_GSC_BOARD_ID option
with the correct ID for each variant.

BUG=b:229015103

Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I1cf86e90b2687e81edadcefa5a8826b02fbc8b24
Reviewed-on: https://review.coreboot.org/c/coreboot/+/64707
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
Julius Werner 2022-05-19 14:37:21 -07:00 committed by Felix Held
parent 600856dec2
commit 5eda52a599
5 changed files with 113 additions and 9 deletions

View File

@ -244,6 +244,10 @@ config VBOOT
select VBOOT_EARLY_EC_SYNC if !BOARD_GOOGLE_BASEBOARD_NISSA select VBOOT_EARLY_EC_SYNC if !BOARD_GOOGLE_BASEBOARD_NISSA
select VBOOT_LID_SWITCH select VBOOT_LID_SWITCH
config VBOOT_GSC_BOARD_ID
string
default "LBTV" if BOARD_GOOGLE_JOXER
config DIMM_SPD_SIZE config DIMM_SPD_SIZE
default 512 default 512

View File

@ -78,6 +78,11 @@ config VBOOT
select VBOOT_SEPARATE_VERSTAGE select VBOOT_SEPARATE_VERSTAGE
select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_STARTS_IN_BOOTBLOCK
# TODO: Remove once CBFS verification on AMD has been fixed.
config VBOOT_GSCVD
bool
default n
if !EM100 # EM100 defaults in soc/amd/common/blocks/spi/Kconfig if !EM100 # EM100 defaults in soc/amd/common/blocks/spi/Kconfig
config EFS_SPI_READ_MODE config EFS_SPI_READ_MODE
default 2 # Dual IO (1-1-2) default 2 # Dual IO (1-1-2)

View File

@ -135,6 +135,10 @@ config CHROMEOS
select VBOOT_EARLY_EC_SYNC select VBOOT_EARLY_EC_SYNC
select VBOOT_LID_SWITCH select VBOOT_LID_SWITCH
config VBOOT_GSCVD
bool
default n
config CHROMEOS_WIFI_SAR config CHROMEOS_WIFI_SAR
bool "Enable SAR options for Chrome OS build" bool "Enable SAR options for Chrome OS build"
depends on CHROMEOS depends on CHROMEOS

View File

@ -290,6 +290,37 @@ config VBOOT_DEFINE_WIDEVINE_COUNTERS
config will only define the counter space. Counters need to be incremented config will only define the counter space. Counters need to be incremented
separately before any read operation is performed on them. separately before any read operation is performed on them.
config VBOOT_HASH_BLOCK_SIZE
hex
default 0x400
help
Set the default hash size. Generally 1k is reasonable, but in some
cases it may improve hashing speed to increase the size.
Note that this buffer is allocated in the stack. Although the
build should fail if the stack size is exceeded, it's something to
be aware of when changing the size.
config VBOOT_GSCVD
bool "Generate GSC verification data"
depends on TPM_GOOGLE
select CBFS_VERIFICATION
default n if TPM_GOOGLE_CR50
default y
help
Generate a Google Security Chip Verification Data (GSCVD) structure on the flash to
allow the GSC to verify the CBFS verification anchor. Used by default with Ti50 GSCs.
Requires an RO_GSCVD FMAP section.
config VBOOT_GSC_BOARD_ID
string
depends on VBOOT_GSCVD
default "ZZCR"
help
GSC board ID to be embedded in the GSCVD. Usually each specific mainboard variant
has its own. Google engineers can find these in the go/cros-dlm database ("Products").
(Note: This is a completely separate thing from coreboot's `board_id()` function.)
menu "GBB configuration" menu "GBB configuration"
config GBB_HWID config GBB_HWID
@ -400,16 +431,21 @@ config VBOOT_KEYBLOCK_PREAMBLE_FLAGS
hex "Keyblock preamble flags" hex "Keyblock preamble flags"
default 0x0 default 0x0
config VBOOT_HASH_BLOCK_SIZE if VBOOT_GSCVD
hex
default 0x400
help
Set the default hash size. Generally 1k is reasonable, but in some
cases it may improve hashing speed to increase the size.
Note that this buffer is allocated in the stack. Although the config VBOOT_GSCVD_ROOT_PUBKEY
build should fail if the stack size is exceeded, it's something to string "GSCVD root key (public)"
be aware of when changing the size. default "\$(VBOOT_SOURCE)/tests/devkeys/arv_root.vbpubk"
config VBOOT_GSCVD_PLATFORM_PRIVKEY
string "GSCVD platform key (private)"
default "\$(VBOOT_SOURCE)/tests/devkeys/arv_platform.vbprivk"
config VBOOT_GSCVD_PLATFORM_KEYBLOCK
string "GSCVD platform keyblock (public)"
default "\$(VBOOT_SOURCE)/tests/devkeys/arv_platform.keyblock"
endif # VBOOT_GSCVD
endmenu # Keys endmenu # Keys
endif # VBOOT endif # VBOOT

View File

@ -294,6 +294,61 @@ build_complete::
$(CBFSTOOL) $(obj)/coreboot.rom write -u -r SHARED_DATA -i 0 -f $(obj)/shared_data.region $(CBFSTOOL) $(obj)/coreboot.rom write -u -r SHARED_DATA -i 0 -f $(obj)/shared_data.region
endif endif
fmap-section-offset-cmd = $(FUTILITY) dump_fmap -p $(obj)/coreboot.rom | \
grep '^$(1) ' | cut '-d ' -f2
ifeq ($(CONFIG_VBOOT_GSCVD),y)
#
# vboot-gscvd-ranges
#
# This variable expands to the list of ranges that will be verified by the GSC
# before releasing the SoC from reset. It needs to cover all security-relevant
# ranges of the flash that CBFS verification cannot cover itself. By default
# this is the `GBB` FMAP section (not handled here but through the special `-G`
# parameter to `futility gscvd` below) and the bootblock. Here we are
# initializing the variable to expansions that produce ranges for both the
# `BOOTBLOCK` FMAP section (filled up to the real size of
# `$(objcbfs)/bootblock.bin`) and the `bootblock` file in the primary CBFS --
# only one of those two should normally exist on a given platform.
#
# Platforms where the bootblock isn't the first and only thing loaded by the
# hardware or which otherwise have special security-relevant flash areas that
# cannot be covered normally by CBFS verification will need to manually add
# ranges to this variable in their own Makefiles, in the format produced by
# printf("%x:%x", start_offset, size). The variable is only expanded once in a
# recipe of the `files_added` target, so $(shell) expansions that depend on
# inspecting $(obj)/coreboot.rom (or any of its dependencies) are valid.
#
vboot-gscvd-ranges += $(shell ( \
offset=$$($(call fmap-section-offset-cmd,BOOTBLOCK)) ;\
if [ -n "$$offset" ]; then \
size=$$(wc -c < $(objcbfs)/bootblock.bin) ;\
printf "%x:%x" $$offset $$size ;\
fi ;\
))
vboot-gscvd-ranges += $(shell ( \
line=$$($(CBFSTOOL) $(obj)/coreboot.rom print -k | grep '^bootblock[[:space:]]') ;\
if [ -n "$$line" ]; then \
cbfs_start=$$($(call fmap-section-offset-cmd,COREBOOT)) ;\
offset=$$(printf "$$line" | cut -f2) ;\
size=$$(printf "$$line" | cut -f6) ;\
printf "%x:%x" $$((cbfs_start + offset)) $$size ;\
fi ;\
))
files_added:: $(FUTILITY)
@printf " WRITE GSCVD\n"
gscvd_range_args="$(foreach range,$(vboot-gscvd-ranges),-R $(range))" ;\
if [ -z "$$gscvd_range_args" ]; then \
echo "ERROR: No valid GSCVD ranges detected in image!" ;\
exit 1 ;\
fi ;\
$(FUTILITY) gscvd -G $$gscvd_range_args -b $(CONFIG_VBOOT_GSC_BOARD_ID) \
-r "$(CONFIG_VBOOT_GSCVD_ROOT_PUBKEY)" \
-p "$(CONFIG_VBOOT_GSCVD_PLATFORM_PRIVKEY)" \
-k "$(CONFIG_VBOOT_GSCVD_PLATFORM_KEYBLOCK)" \
$(obj)/coreboot.rom
endif
# Extract FW_MAIN_? region and minimize it if the last file is empty, so it # Extract FW_MAIN_? region and minimize it if the last file is empty, so it
# doesn't contain this empty file (that can have a significant size), # doesn't contain this empty file (that can have a significant size),
# improving a lot on hash times due to a smaller amount of data loaded from # improving a lot on hash times due to a smaller amount of data loaded from