diff options
author | Philipp Deppenwiese <zaolin@das-labor.org> | 2017-10-17 17:02:29 +0200 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2017-10-22 02:14:46 +0000 |
commit | fea2429e254c41b192dd0856966d5f80eb15a07a (patch) | |
tree | 40e81b3ca7ee3c1f9985af9a8a24a3a9b21e8700 /src/vboot | |
parent | 9e0d69bf1e0194509108eba23511a12d597ae49e (diff) | |
download | coreboot-fea2429e254c41b192dd0856966d5f80eb15a07a.tar.xz |
security/vboot: Move vboot2 to security kconfig section
This commit just moves the vboot sources into
the security directory and fixes kconfig/makefile paths.
Fix vboot2 headers
Change-Id: Icd87f95640186f7a625242a3937e1dd13347eb60
Signed-off-by: Philipp Deppenwiese <zaolin@das-labor.org>
Reviewed-on: https://review.coreboot.org/22074
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/vboot')
-rw-r--r-- | src/vboot/Kconfig | 334 | ||||
-rw-r--r-- | src/vboot/Makefile.inc | 263 | ||||
-rw-r--r-- | src/vboot/bootmode.c | 171 | ||||
-rw-r--r-- | src/vboot/common.c | 182 | ||||
-rw-r--r-- | src/vboot/misc.h | 40 | ||||
-rw-r--r-- | src/vboot/secdata_mock.c | 85 | ||||
-rw-r--r-- | src/vboot/secdata_tpm.c | 585 | ||||
-rw-r--r-- | src/vboot/symbols.h | 28 | ||||
-rw-r--r-- | src/vboot/vbnv.c | 155 | ||||
-rw-r--r-- | src/vboot/vbnv.h | 51 | ||||
-rw-r--r-- | src/vboot/vbnv_cmos.c | 114 | ||||
-rw-r--r-- | src/vboot/vbnv_ec.c | 30 | ||||
-rw-r--r-- | src/vboot/vbnv_flash.c | 181 | ||||
-rw-r--r-- | src/vboot/vbnv_layout.h | 50 | ||||
-rw-r--r-- | src/vboot/vboot_common.c | 115 | ||||
-rw-r--r-- | src/vboot/vboot_common.h | 118 | ||||
-rw-r--r-- | src/vboot/vboot_handoff.c | 190 | ||||
-rw-r--r-- | src/vboot/vboot_loader.c | 158 | ||||
-rw-r--r-- | src/vboot/vboot_logic.c | 438 | ||||
-rw-r--r-- | src/vboot/verstage.c | 39 |
20 files changed, 0 insertions, 3327 deletions
diff --git a/src/vboot/Kconfig b/src/vboot/Kconfig deleted file mode 100644 index d5b5de291e..0000000000 --- a/src/vboot/Kconfig +++ /dev/null @@ -1,334 +0,0 @@ -## This file is part of the coreboot project. -## -## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved. -## -## 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. -## - -menu "Verified Boot (vboot)" - -config VBOOT - bool "Verify firmware with vboot." - default n - select TPM if !MAINBOARD_HAS_TPM2 && !VBOOT_MOCK_SECDATA - select TPM2 if MAINBOARD_HAS_TPM2 && !VBOOT_MOCK_SECDATA - select TPM_INIT_FAILURE_IS_FATAL if PC80_SYSTEM && LPC_TPM - select SKIP_TPM_STARTUP_ON_NORMAL_BOOT if PC80_SYSTEM && LPC_TPM - depends on HAVE_HARD_RESET - help - Enabling VBOOT will use vboot to verify the components of the firmware - (stages, payload, etc). - -if VBOOT - -config VBOOT_VBNV_CMOS - bool - default n - depends on PC80_SYSTEM - help - VBNV is stored in CMOS - -config VBOOT_VBNV_OFFSET - hex - default 0x26 - depends on VBOOT_VBNV_CMOS - help - CMOS offset for VbNv data. This value must match cmos.layout - in the mainboard directory, minus 14 bytes for the RTC. - -config VBOOT_VBNV_CMOS_BACKUP_TO_FLASH - bool - default n - depends on VBOOT_VBNV_CMOS && BOOT_DEVICE_SUPPORTS_WRITES - help - Vboot non-volatile storage data will be backed up from CMOS to flash - and restored from flash if the CMOS is invalid due to power loss. - -config VBOOT_VBNV_EC - bool - default n - help - VBNV is stored in EC - -config VBOOT_VBNV_FLASH - bool - default n - depends on BOOT_DEVICE_SUPPORTS_WRITES - help - VBNV is stored in flash storage - -config VBOOT_STARTS_IN_BOOTBLOCK - bool - default n - help - Firmware verification happens during the end of or right after the - bootblock. This implies that a static VBOOT2_WORK() buffer must be - allocated in memlayout. - -config VBOOT_STARTS_IN_ROMSTAGE - bool - default n - depends on !VBOOT_STARTS_IN_BOOTBLOCK - help - Firmware verification happens during the end of romstage (after - memory initialization). This implies that vboot working data is - allocated in CBMEM. - -config VBOOT_MOCK_SECDATA - bool "Mock secdata for firmware verification" - default n - help - Enabling VBOOT_MOCK_SECDATA will mock secdata for the firmware - verification to avoid access to a secdata storage (typically TPM). - All operations for a secdata storage will be successful. This option - can be used during development when a TPM is not present or broken. - THIS SHOULD NOT BE LEFT ON FOR PRODUCTION DEVICES. - -config VBOOT_DISABLE_DEV_ON_RECOVERY - bool - default n - help - When this option is enabled, the Chrome OS device leaves the - developer mode as soon as recovery request is detected. This is - handy on embedded devices with limited input capabilities. - -config VBOOT_SEPARATE_VERSTAGE - bool - default n - depends on VBOOT_STARTS_IN_BOOTBLOCK - help - If this option is set, vboot verification runs in a standalone stage - that is loaded from the bootblock and exits into romstage. If it is - not set, the verification code is linked directly into the bootblock - or the romstage and runs as part of that stage (cf. related options - VBOOT_STARTS_IN_BOOTBLOCK/_ROMSTAGE and VBOOT_RETURN_FROM_VERSTAGE). - -config VBOOT_RETURN_FROM_VERSTAGE - bool - default n - depends on VBOOT_SEPARATE_VERSTAGE - help - If this is set, the verstage returns back to the calling stage instead - of exiting to the succeeding stage so that the verstage space can be - reused by the succeeding stage. This is useful if a RAM space is too - small to fit both the verstage and the succeeding stage. - -config VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT - bool - default n - help - This option ensures that the recovery request is not lost because of - reboots caused after vboot verification is run. e.g. reboots caused by - FSP components on Intel platforms. - -config VBOOT_OPROM_MATTERS - bool - default n - help - Set this option to indicate to vboot that this platform will skip its - display initialization on a normal (non-recovery, non-developer) boot. - Vboot calls this "oprom matters" because on x86 devices this - traditionally meant that the video option ROM will not be loaded, but - it works functionally the same for other platforms that can skip their - native display initialization code instead. - -config VBOOT_HAS_REC_HASH_SPACE - bool - default n - help - Set this option to indicate to vboot that recovery data hash space - is present in TPM. - -config VBOOT_SOFT_REBOOT_WORKAROUND - bool - default n - -config VBOOT_EC_SOFTWARE_SYNC - bool "Enable EC software sync" - default y if EC_GOOGLE_CHROMEEC - default n - help - EC software sync is a mechanism where the AP helps the EC verify its - firmware similar to how vboot verifies the main system firmware. This - option selects whether vboot should support EC software sync. - -config VBOOT_EC_SLOW_UPDATE - bool - default n - depends on VBOOT_EC_SOFTWARE_SYNC - help - Whether the EC (or PD) is slow to update and needs to display a - screen that informs the user the update is happening. - -config VBOOT_EC_EFS - bool - default n - depends on VBOOT_EC_SOFTWARE_SYNC - help - CrosEC can support EFS: Early Firmware Selection. If it's enabled, - software sync need to also support it. This setting tells vboot to - perform EFS software sync. - -config VBOOT_PHYSICAL_DEV_SWITCH - bool - default n - help - Whether this platform has a physical developer switch. Note that this - disables virtual dev switch functionality (through secdata). Operation - where both a physical pin and the virtual switch get sampled is not - supported by coreboot. - -config VBOOT_PHYSICAL_REC_SWITCH - bool - default n - help - Whether this platform has a physical recovery switch. - -config VBOOT_LID_SWITCH - bool - default n - help - Whether this platform has a lid switch. If it does, vboot will not - decrement try counters for boot failures if the lid is closed. - -config VBOOT_WIPEOUT_SUPPORTED - bool - default n - help - When this option is enabled, the firmware provides the ability to - signal the application the need for factory reset (a.k.a. wipe - out) of the device - -config VBOOT_FWID_MODEL - string "Firmware ID model" - default "Google_$(CONFIG_MAINBOARD_PART_NUMBER)" if CHROMEOS - default "$(CONFIG_MAINBOARD_VENDOR)_$(CONFIG_MAINBOARD_PART_NUMBER)" - help - This is the first part of the FWID written to various regions of a - vboot firmware image to identify its version. - -config VBOOT_FWID_VERSION - string "Firmware ID version" - default ".$(KERNELVERSION)" - help - This is the second part of the FWID written to various regions of a - vboot firmware image to identify its version. - -config RO_REGION_ONLY - string "Additional files that should not be copied to RW" - default "" - help - Add a space delimited list of filenames that should only be in the - RO section. - -menu "GBB configuration" - -config GBB_HWID - string "Hardware ID" - default "NOCONF HWID" - -config GBB_BMPFV_FILE - string "Path to bmpfv image" - default "" - -config GBB_FLAG_DEV_SCREEN_SHORT_DELAY - bool "Reduce dev screen delay" - default n - -config GBB_FLAG_LOAD_OPTION_ROMS - bool "Load option ROMs" - default n - -config GBB_FLAG_ENABLE_ALTERNATE_OS - bool "Allow booting a non-Chrome OS kernel if dev switch is on" - default n - -config GBB_FLAG_FORCE_DEV_SWITCH_ON - bool "Force dev switch on" - default n - -config GBB_FLAG_FORCE_DEV_BOOT_USB - bool "Allow booting from USB in dev mode even if dev_boot_usb=0" - default y - -config GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK - bool "Disable firmware rollback protection" - default y - -config GBB_FLAG_ENTER_TRIGGERS_TONORM - bool "Return to normal boot with Enter" - default n - -config GBB_FLAG_FORCE_DEV_BOOT_LEGACY - bool "Allow booting to legacy in dev mode even if dev_boot_legacy=0" - default n - -config GBB_FLAG_FAFT_KEY_OVERIDE - bool "Allow booting using alternative keys for FAFT servo testing" - default n - -config GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC - bool "Disable EC software sync" - default n - -config GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY - bool "Default to booting to legacy in dev mode" - default n - -config GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC - bool "Disable PD software sync" - default n - -config GBB_FLAG_DISABLE_LID_SHUTDOWN - bool "Disable shutdown on closed lid" - default n - -config GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP - bool "Allow fastboot even if dev_boot_fastboot_full_cap=0" - default n - -config GBB_FLAG_ENABLE_SERIAL - bool "Tell vboot to enable serial console" - default n - -endmenu # GBB - -menu "Vboot Keys" -config VBOOT_ROOT_KEY - string "Root key (public)" - default "$(VBOOT_SOURCE)/tests/devkeys/root_key.vbpubk" - -config VBOOT_RECOVERY_KEY - string "Recovery key (public)" - default "$(VBOOT_SOURCE)/tests/devkeys/recovery_key.vbpubk" - -config VBOOT_FIRMWARE_PRIVKEY - string "Firmware key (private)" - default "$(VBOOT_SOURCE)/tests/devkeys/firmware_data_key.vbprivk" - -config VBOOT_KERNEL_KEY - string "Kernel subkey (public)" - default "$(VBOOT_SOURCE)/tests/devkeys/kernel_subkey.vbpubk" - -config VBOOT_KEYBLOCK - string "Keyblock to use for the RW regions" - default "$(VBOOT_SOURCE)/tests/devkeys/firmware.keyblock" - -config VBOOT_KEYBLOCK_VERSION - int "Keyblock version number" - default 1 - -config VBOOT_KEYBLOCK_PREAMBLE_FLAGS - hex "Keyblock preamble flags" - default 0x0 - -endmenu # Keys -endif # VBOOT -endmenu # Verified Boot (vboot) diff --git a/src/vboot/Makefile.inc b/src/vboot/Makefile.inc deleted file mode 100644 index 75ecff3b21..0000000000 --- a/src/vboot/Makefile.inc +++ /dev/null @@ -1,263 +0,0 @@ -## -## This file is part of the coreboot project. -## -## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved. -## -## 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. -## - -ifeq ($(CONFIG_VBOOT),y) - -bootblock-y += bootmode.c -romstage-y += bootmode.c -ramstage-y += bootmode.c -verstage-y += bootmode.c -postcar-y += bootmode.c - -verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__ - -bootblock-y += vbnv.c -verstage-y += vbnv.c -romstage-y += vbnv.c -ramstage-y += vbnv.c - -bootblock-$(CONFIG_VBOOT_VBNV_CMOS) += vbnv_cmos.c -verstage-$(CONFIG_VBOOT_VBNV_CMOS) += vbnv_cmos.c -romstage-$(CONFIG_VBOOT_VBNV_CMOS) += vbnv_cmos.c -ramstage-$(CONFIG_VBOOT_VBNV_CMOS) += vbnv_cmos.c - -bootblock-$(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c -verstage-$(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c -romstage-$(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c -ramstage-$(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c - -bootblock-$(CONFIG_VBOOT_VBNV_EC) += vbnv_ec.c -verstage-$(CONFIG_VBOOT_VBNV_EC) += vbnv_ec.c -romstage-$(CONFIG_VBOOT_VBNV_EC) += vbnv_ec.c -ramstage-$(CONFIG_VBOOT_VBNV_EC) += vbnv_ec.c - -bootblock-$(CONFIG_VBOOT_VBNV_FLASH) += vbnv_flash.c -verstage-$(CONFIG_VBOOT_VBNV_FLASH) += vbnv_flash.c -romstage-$(CONFIG_VBOOT_VBNV_FLASH) += vbnv_flash.c -ramstage-$(CONFIG_VBOOT_VBNV_FLASH) += vbnv_flash.c - -bootblock-y += vboot_loader.c -romstage-y += vboot_loader.c -ramstage-y += vboot_loader.c -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 - -bootblock-y += common.c -verstage-y += vboot_logic.c -verstage-y += common.c -verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += verstage.c -ifeq (${CONFIG_VBOOT_MOCK_SECDATA},y) -verstage-y += secdata_mock.c -romstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += secdata_mock.c -else -verstage-y += secdata_tpm.c -romstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += secdata_tpm.c -endif -romstage-y += vboot_handoff.c common.c - -ramstage-y += common.c -postcar-y += common.c - -ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) -VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-verstage-y)) -else -ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y) -VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-bootblock-y)) -else -VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y)) -endif -endif # CONFIG_VBOOT_SEPARATE_VERSTAGE - -VB2_LIB = $(obj)/external/vboot_reference/vboot_fw20.a -VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%, $(filter-out -I$(obj), $(filter-out -include $(src)/include/kconfig.h, $(CPPFLAGS_verstage)))) -VBOOT_CFLAGS += $(CFLAGS_verstage) -VBOOT_CFLAGS += $(verstage-c-ccopts) -VBOOT_CFLAGS += -I$(abspath $(obj)) -include $(top)/src/include/kconfig.h -Wno-missing-prototypes -VBOOT_CFLAGS += -DVBOOT_DEBUG - -$(VB2_LIB): $(obj)/config.h - printf " MAKE $(subst $(obj)/,,$(@))\n" - +FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \ - CC="$(CC_verstage)" \ - CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \ - $(MAKE) -C $(VBOOT_SOURCE) \ - BUILD=$(abspath $(dir $(VB2_LIB))) \ - V=$(V) \ - fwlib20 - -verstage-srcs += $(VB2_LIB) - -ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) - -# This works under the assumption that romstage and verstage use the same -# architecture and thus CC_verstage is the same as CC_romstage. If this is not -# true, VB2_LIB needs to ensure that correct CC is being used. -ifeq ($(CONFIG_VBOOT_HAS_REC_HASH_SPACE),y) -romstage-srcs += $(VB2_LIB) -endif - -cbfs-files-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += $(CONFIG_CBFS_PREFIX)/verstage -$(CONFIG_CBFS_PREFIX)/verstage-file := $(objcbfs)/verstage.elf -$(CONFIG_CBFS_PREFIX)/verstage-type := stage -$(CONFIG_CBFS_PREFIX)/verstage-compression := $(CBFS_PRERAM_COMPRESS_FLAG) - -ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y) -$(CONFIG_CBFS_PREFIX)/verstage-options := -a 64 -S ".car.data" - -# If CAR does not support execution of code, verstage on x86 is expected to be -# xip. -ifneq ($(CONFIG_NO_XIP_EARLY_STAGES),y) -$(CONFIG_CBFS_PREFIX)/verstage-options += --xip -endif - -endif - -else # CONFIG_VBOOT_SEPARATE_VERSTAGE -ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y) -postinclude-hooks += $$(eval bootblock-srcs += $$(verstage-srcs)) -else -postinclude-hooks += $$(eval romstage-srcs += $$(verstage-srcs)) -endif -endif # CONFIG_VBOOT_SEPARATE_VERSTAGE - -# Define a list of files that need to be in RO only. -# All other files will be installed into RO and RW regions -# Use $(sort) to cut down on extra spaces that would be translated to commas -regions-for-file = $(subst $(spc),$(comma),$(sort \ - $(if $(filter \ - $(if $(filter y,$(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)),, \ - %/romstage) \ - mts \ - %/verstage \ - locales \ - locale_%.bin \ - font.bin \ - vbgfx.bin \ - rmu.bin \ - $(call strip_quotes,$(CONFIG_RO_REGION_ONLY)) \ - ,$(1)),COREBOOT,COREBOOT FW_MAIN_A FW_MAIN_B))) - -CONFIG_GBB_HWID := $(call strip_quotes,$(CONFIG_GBB_HWID)) -CONFIG_GBB_BMPFV_FILE := $(call strip_quotes,$(CONFIG_GBB_BMPFV_FILE)) -CONFIG_VBOOT_KEYBLOCK := $(call strip_quotes,$(CONFIG_VBOOT_KEYBLOCK)) -CONFIG_VBOOT_FIRMWARE_PRIVKEY := $(call strip_quotes,$(CONFIG_VBOOT_FIRMWARE_PRIVKEY)) -CONFIG_VBOOT_KERNEL_KEY := $(call strip_quotes,$(CONFIG_VBOOT_KERNEL_KEY)) -CONFIG_VBOOT_FWID_MODEL := $(call strip_quotes,$(CONFIG_VBOOT_FWID_MODEL)) -CONFIG_VBOOT_FWID_VERSION := $(call strip_quotes,$(CONFIG_VBOOT_FWID_VERSION)) - -# bool-to-mask(var, value) -# return "value" if var is "y", 0 otherwise -bool-to-mask = $(if $(filter y,$(1)),$(2),0) - -GBB_FLAGS := $(call int-add, \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_DEV_SCREEN_SHORT_DELAY),0x1) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_LOAD_OPTION_ROMS),0x2) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_ENABLE_ALTERNATE_OS),0x4) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_FORCE_DEV_SWITCH_ON),0x8) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_FORCE_DEV_BOOT_USB),0x10) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK),0x20) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_ENTER_TRIGGERS_TONORM),0x40) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_FORCE_DEV_BOOT_LEGACY),0x80) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_FAFT_KEY_OVERIDE),0x100) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC),0x200) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY),0x400) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC),0x800) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_DISABLE_LID_SHUTDOWN),0x1000) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP),0x2000) \ - $(call bool-to-mask,$(CONFIG_GBB_FLAG_ENABLE_SERIAL),0x4000) \ - ) - -ifneq ($(CONFIG_GBB_BMPFV_FILE),) -$(obj)/gbb.sizetmp: $(obj)/coreboot.rom - $(CBFSTOOL) $< read -r GBB -f $@ - -$(obj)/gbb.stub: $(obj)/coreboot.rom $(FUTILITY) $(obj)/gbb.sizetmp - @printf " CREATE GBB (with BMPFV)\n" - $(FUTILITY) gbb_utility -c 0x100,0x1000,$(call int-subtract,$(call file-size,$(obj)/gbb.sizetmp) 0x2180),0x1000 $@.tmp - mv $@.tmp $@ -else -$(obj)/gbb.stub: $(obj)/coreboot.rom $(FUTILITY) - @printf " CREATE GBB (without BMPFV)\n" - $(FUTILITY) gbb_utility -c 0x100,0x1000,0,0x1000 $@.tmp - mv $@.tmp $@ -endif - -$(obj)/gbb.region: $(obj)/gbb.stub - @printf " SETUP GBB\n" - cp $< $@.tmp - $(FUTILITY) gbb_utility -s \ - --hwid="$(CONFIG_GBB_HWID)" \ - --rootkey="$(CONFIG_VBOOT_ROOT_KEY)" \ - --recoverykey="$(CONFIG_VBOOT_RECOVERY_KEY)" \ - --flags=$(GBB_FLAGS) \ - $@.tmp -ifneq ($(CONFIG_GBB_BMPFV_FILE),) - $(FUTILITY) gbb_utility -s \ - --bmpfv="$(CONFIG_GBB_BMPFV_FILE)" \ - $@.tmp -endif - mv $@.tmp $@ - -$(obj)/fwid.region: - printf "$(CONFIG_VBOOT_FWID_MODEL)$(CONFIG_VBOOT_FWID_VERSION)\0" > $@ - -build_complete:: $(obj)/gbb.region $(obj)/fwid.region - @printf " WRITE GBB\n" - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r GBB -i 0 -f $(obj)/gbb.region - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r RO_FRID -i 0 -f $(obj)/fwid.region - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r RW_FWID_A -i 0 -f $(obj)/fwid.region - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r RW_FWID_B -i 0 -f $(obj)/fwid.region - -ifneq ($(shell grep "SHARED_DATA" "$(CONFIG_FMDFILE)"),) -build_complete:: - printf "\0" > $(obj)/shared_data.region - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r SHARED_DATA -i 0 -f $(obj)/shared_data.region -endif - -# 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), -# improving a lot on hash times due to a smaller amount of data loaded from -# firmware storage. -# When passing the minimized image to vbutil_firmware, its length is recorded -# in the keyblock, and coreboot's vboot code clips the region_device to match, -# which prevents any potential extension attacks. -$(obj)/FW_MAIN_%.bin: $(obj)/coreboot.rom - $(CBFSTOOL) $< truncate -r $(basename $(notdir $@)) > $@.tmp.size - $(CBFSTOOL) $< read -r $(basename $(notdir $@)) -f $@.tmp - head -c $$( printf "%d" $$(cat $@.tmp.size)) $@.tmp > $@.tmp2 - mv $@.tmp2 $@ - rm -f $@.tmp $@.tmp.size - -$(obj)/VBLOCK_%.bin: $(obj)/FW_MAIN_%.bin $(FUTILITY) - $(FUTILITY) vbutil_firmware \ - --vblock $@ \ - --keyblock "$(CONFIG_VBOOT_KEYBLOCK)" \ - --signprivate "$(CONFIG_VBOOT_FIRMWARE_PRIVKEY)" \ - --version $(CONFIG_VBOOT_KEYBLOCK_VERSION) \ - --fv $< \ - --kernelkey "$(CONFIG_VBOOT_KERNEL_KEY)" \ - --flags $(CONFIG_VBOOT_KEYBLOCK_PREAMBLE_FLAGS) - -files_added:: $(obj)/VBLOCK_A.bin $(obj)/VBLOCK_B.bin - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r VBLOCK_A -f $(obj)/VBLOCK_A.bin - $(CBFSTOOL) $(obj)/coreboot.rom write -u -r VBLOCK_B -f $(obj)/VBLOCK_B.bin - -endif # CONFIG_VBOOT diff --git a/src/vboot/bootmode.c b/src/vboot/bootmode.c deleted file mode 100644 index 120744837b..0000000000 --- a/src/vboot/bootmode.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2016 Google 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 <assert.h> -#include <bootmode.h> -#include <bootstate.h> -#include <cbmem.h> -#include <rules.h> -#include <string.h> -#include <vb2_api.h> -#include <vboot/misc.h> -#include <vboot/vbnv.h> -#include <vboot/vboot_common.h> - -static int vb2_get_recovery_reason_shared_data(void) -{ - /* Shared data does not exist for Ramstage and Post-CAR stage. */ - if (ENV_RAMSTAGE || ENV_POSTCAR) - return 0; - - struct vb2_shared_data *sd = vb2_get_shared_data(); - assert(sd); - return sd->recovery_reason; -} - -void vb2_save_recovery_reason_vbnv(void) -{ - if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT)) - return; - - int reason = vb2_get_recovery_reason_shared_data(); - if (!reason) - return; - - set_recovery_mode_into_vbnv(reason); -} - -static void vb2_clear_recovery_reason_vbnv(void *unused) -{ - if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT)) - return; - - set_recovery_mode_into_vbnv(0); -} - -/* - * Recovery reason stored in VBNV needs to be cleared before the state of VBNV - * is backed-up anywhere or jumping to the payload (whichever occurs - * first). Currently, vbnv_cmos.c backs up VBNV on POST_DEVICE. Thus, we need to - * make sure that the stored recovery reason is cleared off before that - * happens. - * IMPORTANT: Any reboot occurring after BS_DEV_INIT state will cause loss of - * recovery reason on reboot. Until now, we have seen reboots occuring on x86 - * only in FSP stages which run before BS_DEV_INIT. - */ -BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, - vb2_clear_recovery_reason_vbnv, NULL); - -/* - * Returns 1 if vboot is being used and currently in a stage which might have - * already executed vboot verification. - */ -static int vboot_possibly_executed(void) -{ - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) { - if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE)) - return 0; - return 1; - } - - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) { - if (ENV_BOOTBLOCK) - return 0; - return 1; - } - - return 0; -} - -/* - * vb2_check_recovery_request looks up different components to identify if there - * is a recovery request and returns appropriate reason code: - * 1. Checks if recovery mode is initiated by EC. If yes, returns - * VB2_RECOVERY_RO_MANUAL. - * 2. Checks if recovery request is present in VBNV and returns the code read - * from it. - * 3. Checks recovery request in handoff for stages post-cbmem. - * 4. For non-CBMEM stages, check if vboot verification is done and look-up - * selected region to identify if vboot_refence library has requested recovery - * path. If yes, return the reason code from shared data. - * 5. If nothing applies, return 0 indicating no recovery request. - */ -int vboot_check_recovery_request(void) -{ - int reason = 0; - - /* EC-initiated recovery. */ - if (get_recovery_mode_switch()) - return VB2_RECOVERY_RO_MANUAL; - - /* Recovery request in VBNV. */ - if ((reason = get_recovery_mode_from_vbnv()) != 0) - return reason; - - /* - * Check recovery flag in vboot_handoff for stages post CBMEM coming - * online. Since for some stages there is no way to know if cbmem has - * already come online, try looking up handoff anyways. If it fails, - * flow will fallback to looking up shared data. - */ - if (cbmem_possibly_online() && - ((reason = vboot_handoff_get_recovery_reason()) != 0)) - return reason; - - /* - * For stages where CBMEM might not be online, identify if vboot - * verification is already complete and no slot was selected - * i.e. recovery path was requested. - */ - if (vboot_possibly_executed() && vb2_logic_executed() && - !vb2_is_slot_selected()) - return vb2_get_recovery_reason_shared_data(); - - return 0; -} - -int vboot_recovery_mode_enabled(void) -{ - return !!vboot_check_recovery_request(); -} - -int __attribute__((weak)) clear_recovery_mode_switch(void) -{ - // Weak implementation. Nothing to do. - return 0; -} - -void __attribute__((weak)) log_recovery_mode_switch(void) -{ - // Weak implementation. Nothing to do. -} - -int __attribute__((weak)) get_recovery_mode_retrain_switch(void) -{ - return 0; -} - -int vboot_recovery_mode_memory_retrain(void) -{ - return get_recovery_mode_retrain_switch(); -} - -int vboot_developer_mode_enabled(void) -{ - if (cbmem_possibly_online() && vboot_handoff_check_developer_flag()) - return 1; - - return 0; -} diff --git a/src/vboot/common.c b/src/vboot/common.c deleted file mode 100644 index 3e480edbf6..0000000000 --- a/src/vboot/common.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved. - * - * 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 <assert.h> -#include <cbfs.h> -#include <cbmem.h> -#include <console/console.h> -#include <reset.h> -#include <string.h> -#include <vb2_api.h> -#include <vboot/misc.h> -#include <vboot/symbols.h> -#include <vboot/vboot_common.h> - -struct selected_region { - uint32_t offset; - uint32_t size; -}; - -/* - * this is placed at the start of the vboot work buffer. selected_region is used - * for the verstage to return the location of the selected slot. buffer is used - * by the vboot2 core. Keep the struct CPU architecture agnostic as it crosses - * stage boundaries. - */ -struct vb2_working_data { - struct selected_region selected_region; - /* offset of the buffer from the start of this struct */ - uint32_t buffer_offset; - uint32_t buffer_size; -}; - -static const size_t vb_work_buf_size = 16 * KiB; - -static struct vb2_working_data * const vboot_get_working_data(void) -{ - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) - /* cbmem_add() does a cbmem_find() first. */ - return cbmem_add(CBMEM_ID_VBOOT_WORKBUF, vb_work_buf_size); - else - return (struct vb2_working_data *)_vboot2_work; -} - -static size_t vb2_working_data_size(void) -{ - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) - return vb_work_buf_size; - else - return _vboot2_work_size; -} - -static struct selected_region *vb2_selected_region(void) -{ - struct selected_region *sel_reg = NULL; - - /* Ramstage and postcar always uses cbmem as a source of truth. */ - if (ENV_RAMSTAGE || ENV_POSTCAR) - sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG); - else if (ENV_ROMSTAGE) { - /* Try cbmem first. Fall back on working data if not found. */ - sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG); - - if (sel_reg == NULL) { - struct vb2_working_data *wd = vboot_get_working_data(); - sel_reg = &wd->selected_region; - } - } else { - /* Stages such as bootblock and verstage use working data. */ - struct vb2_working_data *wd = vboot_get_working_data(); - sel_reg = &wd->selected_region; - } - - return sel_reg; -} - -void vb2_init_work_context(struct vb2_context *ctx) -{ - struct vb2_working_data *wd; - size_t work_size; - - /* First initialize the working data region. */ - work_size = vb2_working_data_size(); - wd = vboot_get_working_data(); - memset(wd, 0, work_size); - - /* - * vboot prefers 16-byte alignment. This takes away 16 bytes - * from the VBOOT2_WORK region, but the vboot devs said that's okay. - */ - wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16); - wd->buffer_size = work_size - wd->buffer_offset; - - /* Initialize the vb2_context. */ - memset(ctx, 0, sizeof(*ctx)); - ctx->workbuf = (void *)vb2_get_shared_data(); - ctx->workbuf_size = wd->buffer_size; - -} - -struct vb2_shared_data *vb2_get_shared_data(void) -{ - struct vb2_working_data *wd = vboot_get_working_data(); - return (void *)((uintptr_t)wd + wd->buffer_offset); -} - -int vb2_get_selected_region(struct region *region) -{ - const struct selected_region *reg = vb2_selected_region(); - - if (reg == NULL) - return -1; - - if (reg->offset == 0 && reg->size == 0) - return -1; - - region->offset = reg->offset; - region->size = reg->size; - - return 0; -} - -void vb2_set_selected_region(const struct region *region) -{ - struct selected_region *reg = vb2_selected_region(); - - assert(reg != NULL); - - reg->offset = region_offset(region); - reg->size = region_sz(region); -} - -int vb2_is_slot_selected(void) -{ - const struct selected_region *reg = vb2_selected_region(); - - assert(reg != NULL); - - return reg->size > 0; -} - -void vb2_store_selected_region(void) -{ - const struct vb2_working_data *wd; - struct selected_region *sel_reg; - - /* Always use the working data in this path since it's the object - * which has the result.. */ - wd = vboot_get_working_data(); - - sel_reg = cbmem_add(CBMEM_ID_VBOOT_SEL_REG, sizeof(*sel_reg)); - - assert(sel_reg != NULL); - - sel_reg->offset = wd->selected_region.offset; - sel_reg->size = wd->selected_region.size; -} - -/* - * For platforms that employ VBOOT_STARTS_IN_ROMSTAGE, the vboot - * verification doesn't happen until after cbmem is brought online. - * Therefore, the selected region contents would not be initialized - * so don't automatically add results when cbmem comes online. - */ -#if !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) -static void vb2_store_selected_region_cbmem(int unused) -{ - vb2_store_selected_region(); -} -ROMSTAGE_CBMEM_INIT_HOOK(vb2_store_selected_region_cbmem) -#endif diff --git a/src/vboot/misc.h b/src/vboot/misc.h deleted file mode 100644 index dc94720ea5..0000000000 --- a/src/vboot/misc.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved. - * - * 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_MISC_H__ -#define __VBOOT_MISC_H__ - -#include <vboot/vboot_common.h> - -struct vb2_context; -struct vb2_shared_data; - -void vboot_fill_handoff(void); - -void vb2_init_work_context(struct vb2_context *ctx); -struct vb2_shared_data *vb2_get_shared_data(void); - -/* Returns 0 on success. < 0 on failure. */ -int vb2_get_selected_region(struct region *region); -void vb2_set_selected_region(const struct region *region); -int vb2_is_slot_selected(void); -int vb2_logic_executed(void); - -/* Store the selected region in cbmem for later use. */ -void vb2_store_selected_region(void); - -void vb2_save_recovery_reason_vbnv(void); - -#endif /* __VBOOT_MISC_H__ */ diff --git a/src/vboot/secdata_mock.c b/src/vboot/secdata_mock.c deleted file mode 100644 index 72ee5b3c11..0000000000 --- a/src/vboot/secdata_mock.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Functions for querying, manipulating and locking rollback indices - * stored in the TPM NVRAM. - */ - -#include <antirollback.h> -#include <stdlib.h> -#include <tpm_lite/tlcl.h> -#include <vb2_api.h> - -uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr, - enum vb2_pcr_digest which_digest) -{ - return TPM_SUCCESS; -} - -uint32_t tpm_clear_and_reenable(void) -{ - return TPM_SUCCESS; -} - -uint32_t antirollback_read_space_firmware(struct vb2_context *ctx) -{ - vb2api_secdata_create(ctx); - return TPM_SUCCESS; -} - -uint32_t antirollback_write_space_firmware(struct vb2_context *ctx) -{ - return TPM_SUCCESS; -} - -uint32_t antirollback_lock_space_firmware() -{ - return TPM_SUCCESS; -} - -uint32_t antirollback_lock_space_rec_hash(void) -{ - return TPM_SUCCESS; -} - -uint32_t antirollback_read_space_rec_hash(uint8_t *data, uint32_t size) -{ - return TPM_SUCCESS; -} - -uint32_t antirollback_write_space_rec_hash(const uint8_t *data, uint32_t size) -{ - return TPM_SUCCESS; -} - -uint32_t tlcl_lib_init(void) -{ - return VB2_SUCCESS; -} diff --git a/src/vboot/secdata_tpm.c b/src/vboot/secdata_tpm.c deleted file mode 100644 index be9d680cc0..0000000000 --- a/src/vboot/secdata_tpm.c +++ /dev/null @@ -1,585 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Functions for querying, manipulating and locking rollback indices - * stored in the TPM NVRAM. - */ - -#include <antirollback.h> -#include <stdlib.h> -#include <string.h> -#include <tpm_lite/tlcl.h> -#include <vb2_api.h> -#include <console/console.h> - -#ifndef offsetof -#define offsetof(A,B) __builtin_offsetof(A,B) -#endif - -#ifdef FOR_TEST -#include <stdio.h> -#define VBDEBUG(format, args...) printf(format, ## args) -#else -#include <console/console.h> -#define VBDEBUG(format, args...) \ - printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args) -#endif - -#define RETURN_ON_FAILURE(tpm_cmd) do { \ - uint32_t result_; \ - if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \ - VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \ - "\n", (int)result_); \ - return result_; \ - } \ - } while (0) - - -static uint32_t safe_write(uint32_t index, const void *data, uint32_t length); - -uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr, - enum vb2_pcr_digest which_digest) -{ - uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE]; - uint32_t size = sizeof(buffer); - int rv; - - rv = vb2api_get_pcr_digest(ctx, which_digest, buffer, &size); - if (rv != VB2_SUCCESS) - return rv; - if (size < TPM_PCR_DIGEST) - return VB2_ERROR_UNKNOWN; - - return tlcl_extend(pcr, buffer, NULL); -} - -static uint32_t read_space_firmware(struct vb2_context *ctx) -{ - int attempts = 3; - - while (attempts--) { - RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata, - VB2_SECDATA_SIZE)); - - if (vb2api_secdata_check(ctx) == VB2_SUCCESS) - return TPM_SUCCESS; - - VBDEBUG("TPM: %s() - bad CRC\n", __func__); - } - - VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__); - return TPM_E_CORRUPTED_STATE; -} - -static uint32_t read_space_rec_hash(uint8_t *data) -{ - RETURN_ON_FAILURE(tlcl_read(REC_HASH_NV_INDEX, data, - REC_HASH_NV_SIZE)); - return TPM_SUCCESS; -} - -static uint32_t write_secdata(uint32_t index, - const uint8_t *secdata, - uint32_t len) -{ - uint8_t sd[32]; - uint32_t rv; - int attempts = 3; - - if (len > sizeof(sd)) { - VBDEBUG("TPM: %s() - data is too large\n", __func__); - return TPM_E_WRITE_FAILURE; - } - - while (attempts--) { - rv = safe_write(index, secdata, len); - /* Can't write, not gonna try again */ - if (rv != TPM_SUCCESS) - return rv; - - /* Read it back to be sure it got the right values. */ - rv = tlcl_read(index, sd, len); - if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0) - return rv; - - VBDEBUG("TPM: %s() failed. trying again\n", __func__); - /* Try writing it again. Maybe it was garbled on the way out. */ - } - - VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__); - - return TPM_E_CORRUPTED_STATE; -} - -/* - * This is derived from rollback_index.h of vboot_reference. see struct - * RollbackSpaceKernel for details. - */ -static const uint8_t secdata_kernel[] = { - 0x02, - 0x4C, 0x57, 0x52, 0x47, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0xE8, -}; - -/* - * This is used to initialize the TPM space for recovery hash after defining - * it. Since there is no data available to calculate hash at the point where TPM - * space is defined, initialize it to all 0s. - */ -static const uint8_t rec_hash_data[REC_HASH_NV_SIZE] = { }; - -#if IS_ENABLED(CONFIG_TPM2) - -/* Nothing special in the TPM2 path yet. */ -static uint32_t safe_write(uint32_t index, const void *data, uint32_t length) -{ - return tlcl_write(index, data, length); -} - -static uint32_t set_firmware_space(const void *firmware_blob) -{ - RETURN_ON_FAILURE(tlcl_define_space(FIRMWARE_NV_INDEX, - VB2_SECDATA_SIZE)); - RETURN_ON_FAILURE(safe_write(FIRMWARE_NV_INDEX, firmware_blob, - VB2_SECDATA_SIZE)); - return TPM_SUCCESS; -} - -static uint32_t set_kernel_space(const void *kernel_blob) -{ - uint32_t rv; - - rv = tlcl_define_space(KERNEL_NV_INDEX, sizeof(secdata_kernel)); - if (rv == TPM_E_NV_DEFINED) { - VBDEBUG("%s: kernel space already exists\n", __func__); - return TPM_SUCCESS; - } - - if (rv != TPM_SUCCESS) - return rv; - - return safe_write(KERNEL_NV_INDEX, kernel_blob, sizeof(secdata_kernel)); -} - -static uint32_t set_rec_hash_space(const uint8_t *data) -{ - uint32_t rv; - - rv = tlcl_define_space(REC_HASH_NV_INDEX, REC_HASH_NV_SIZE); - if (rv == TPM_E_NV_DEFINED) { - VBDEBUG("%s: MRC Hash space already exists\n", __func__); - return TPM_SUCCESS; - } - - if (rv != TPM_SUCCESS) - return rv; - - return safe_write(REC_HASH_NV_INDEX, data, REC_HASH_NV_SIZE); -} - -static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) -{ - RETURN_ON_FAILURE(tlcl_force_clear()); - - /* - * Of all NVRAM spaces defined by this function the firmware space - * must be defined last, because its existence is considered an - * indication that TPM factory initialization was successfully - * completed. - */ - RETURN_ON_FAILURE(set_kernel_space(secdata_kernel)); - - if (IS_ENABLED(CONFIG_VBOOT_HAS_REC_HASH_SPACE)) - RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data)); - - RETURN_ON_FAILURE(set_firmware_space(ctx->secdata)); - - return TPM_SUCCESS; -} - -uint32_t tpm_clear_and_reenable(void) -{ - VBDEBUG("TPM: Clear and re-enable\n"); - RETURN_ON_FAILURE(tlcl_force_clear()); - return TPM_SUCCESS; -} - -uint32_t antirollback_lock_space_firmware(void) -{ - return tlcl_lock_nv_write(FIRMWARE_NV_INDEX); -} - -uint32_t antirollback_lock_space_rec_hash(void) -{ - return tlcl_lock_nv_write(REC_HASH_NV_INDEX); -} - -#else - -uint32_t tpm_clear_and_reenable(void) -{ - VBDEBUG("TPM: Clear and re-enable\n"); - RETURN_ON_FAILURE(tlcl_force_clear()); - RETURN_ON_FAILURE(tlcl_set_enable()); - RETURN_ON_FAILURE(tlcl_set_deactivated(0)); - - return TPM_SUCCESS; -} - -/** - * Like tlcl_write(), but checks for write errors due to hitting the 64-write - * limit and clears the TPM when that happens. This can only happen when the - * TPM is unowned, so it is OK to clear it (and we really have no choice). - * This is not expected to happen frequently, but it could happen. - */ - -static uint32_t safe_write(uint32_t index, const void *data, uint32_t length) -{ - uint32_t result = tlcl_write(index, data, length); - if (result == TPM_E_MAXNVWRITES) { - RETURN_ON_FAILURE(tpm_clear_and_reenable()); - return tlcl_write(index, data, length); - } else { - return result; - } -} - -/** - * Similarly to safe_write(), this ensures we don't fail a DefineSpace because - * we hit the TPM write limit. This is even less likely to happen than with - * writes because we only define spaces once at initialization, but we'd - * rather be paranoid about this. - */ -static uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size) -{ - uint32_t result = tlcl_define_space(index, perm, size); - if (result == TPM_E_MAXNVWRITES) { - RETURN_ON_FAILURE(tpm_clear_and_reenable()); - return tlcl_define_space(index, perm, size); - } else { - return result; - } -} - -static uint32_t set_rec_hash_space(const uint8_t *data) -{ - RETURN_ON_FAILURE(safe_define_space(REC_HASH_NV_INDEX, - TPM_NV_PER_GLOBALLOCK | - TPM_NV_PER_PPWRITE, - REC_HASH_NV_SIZE)); - RETURN_ON_FAILURE(write_secdata(REC_HASH_NV_INDEX, data, - REC_HASH_NV_SIZE)); - - return TPM_SUCCESS; -} - -static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) -{ - TPM_PERMANENT_FLAGS pflags; - uint32_t result; - - result = tlcl_get_permanent_flags(&pflags); - if (result != TPM_SUCCESS) - return result; - - /* - * TPM may come from the factory without physical presence finalized. - * Fix if necessary. - */ - VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n", - pflags.physicalPresenceLifetimeLock); - if (!pflags.physicalPresenceLifetimeLock) { - VBDEBUG("TPM: Finalizing physical presence\n"); - RETURN_ON_FAILURE(tlcl_finalize_physical_presence()); - } - - /* - * The TPM will not enforce the NV authorization restrictions until the - * execution of a TPM_NV_DefineSpace with the handle of - * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already - * exist. */ - VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked); - if (!pflags.nvLocked) { - VBDEBUG("TPM: Enabling NV locking\n"); - RETURN_ON_FAILURE(tlcl_set_nv_locked()); - } - - /* Clear TPM owner, in case the TPM is already owned for some reason. */ - VBDEBUG("TPM: Clearing owner\n"); - RETURN_ON_FAILURE(tpm_clear_and_reenable()); - - /* Define and initialize the kernel space */ - RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX, - TPM_NV_PER_PPWRITE, - sizeof(secdata_kernel))); - RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX, - secdata_kernel, - sizeof(secdata_kernel))); - - /* Defines and sets vb2 secdata space */ - vb2api_secdata_create(ctx); - RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX, - TPM_NV_PER_GLOBALLOCK | - TPM_NV_PER_PPWRITE, - VB2_SECDATA_SIZE)); - RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX, - ctx->secdata, - VB2_SECDATA_SIZE)); - - /* Define and set rec hash space, if available. */ - if (IS_ENABLED(CONFIG_VBOOT_HAS_REC_HASH_SPACE)) - RETURN_ON_FAILURE(set_rec_hash_space(rec_hash_data)); - - return TPM_SUCCESS; -} - -uint32_t antirollback_lock_space_firmware(void) -{ - return tlcl_set_global_lock(); -} - -uint32_t antirollback_lock_space_rec_hash(void) -{ - /* - * Nothing needs to be done here, since global lock is already set while - * locking firmware space. - */ - return TPM_SUCCESS; -} -#endif - -/** - * Perform one-time initializations. - * - * Create the NVRAM spaces, and set their initial values as needed. Sets the - * nvLocked bit and ensures the physical presence command is enabled and - * locked. - */ -static uint32_t factory_initialize_tpm(struct vb2_context *ctx) -{ - uint32_t result; - - /* Defines and sets vb2 secdata space */ - vb2api_secdata_create(ctx); - - VBDEBUG("TPM: factory initialization\n"); - - /* - * Do a full test. This only happens the first time the device is - * turned on in the factory, so performance is not an issue. This is - * almost certainly not necessary, but it gives us more confidence - * about some code paths below that are difficult to - * test---specifically the ones that set lifetime flags, and are only - * executed once per physical TPM. - */ - result = tlcl_self_test_full(); - if (result != TPM_SUCCESS) - return result; - - result = _factory_initialize_tpm(ctx); - if (result != TPM_SUCCESS) - return result; - - VBDEBUG("TPM: factory initialization successful\n"); - - return TPM_SUCCESS; -} - -/* - * SetupTPM starts the TPM and establishes the root of trust for the - * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a - * TPM hardware failure. 3 An unexpected TPM state due to some attack. In - * general we cannot easily distinguish the kind of failure, so our strategy is - * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM - * again, which executes (almost) the same sequence of operations. There is a - * good chance that, if recovery mode was entered because of a TPM failure, the - * failure will repeat itself. (In general this is impossible to guarantee - * because we have no way of creating the exact TPM initial state at the - * previous boot.) In recovery mode, we ignore the failure and continue, thus - * giving the recovery kernel a chance to fix things (that's why we don't set - * bGlobalLock). The choice is between a knowingly insecure device and a - * bricked device. - * - * As a side note, observe that we go through considerable hoops to avoid using - * the STCLEAR permissions for the index spaces. We do this to avoid writing - * to the TPM flashram at every reboot or wake-up, because of concerns about - * the durability of the NVRAM. - */ -uint32_t setup_tpm(struct vb2_context *ctx) -{ - uint8_t disable; - uint8_t deactivated; - uint32_t result; - - RETURN_ON_FAILURE(tlcl_lib_init()); - - /* Handle special init for S3 resume path */ - if (ctx->flags & VB2_CONTEXT_S3_RESUME) { - result = tlcl_resume(); - if (result == TPM_E_INVALID_POSTINIT) - printk(BIOS_DEBUG, "TPM: Already initialized.\n"); - return TPM_SUCCESS; - } - - if (IS_ENABLED(CONFIG_VBOOT_SOFT_REBOOT_WORKAROUND)) { - result = tlcl_startup(); - if (result == TPM_E_INVALID_POSTINIT) { - /* - * Some prototype hardware doesn't reset the TPM on a CPU - * reset. We do a hard reset to get around this. - */ - VBDEBUG("TPM: soft reset detected\n"); - ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT; - return TPM_E_MUST_REBOOT; - } else if (result != TPM_SUCCESS) { - VBDEBUG("TPM: tlcl_startup returned %08x\n", result); - return result; - } - } else - RETURN_ON_FAILURE(tlcl_startup()); - - /* - * Some TPMs start the self test automatically at power on. In that case - * we don't need to call ContinueSelfTest. On some (other) TPMs, - * continue_self_test may block. In that case, we definitely don't want - * to call it here. For TPMs in the intersection of these two sets, we - * are screwed. (In other words: TPMs that require manually starting the - * self-test AND block will have poor performance until we split - * tlcl_send_receive() into send() and receive(), and have a state - * machine to control setup.) - * - * This comment is likely to become obsolete in the near future, so - * don't trust it. It may have not been updated. - */ -#ifdef TPM_MANUAL_SELFTEST -#ifdef TPM_BLOCKING_CONTINUESELFTEST -#warning "lousy TPM!" -#endif - RETURN_ON_FAILURE(tlcl_continue_self_test()); -#endif - result = tlcl_assert_physical_presence(); - if (result != TPM_SUCCESS) { - /* - * It is possible that the TPM was delivered with the physical - * presence command disabled. This tries enabling it, then - * tries asserting PP again. - */ - RETURN_ON_FAILURE(tlcl_physical_presence_cmd_enable()); - RETURN_ON_FAILURE(tlcl_assert_physical_presence()); - } - - /* Check that the TPM is enabled and activated. */ - RETURN_ON_FAILURE(tlcl_get_flags(&disable, &deactivated, NULL)); - if (disable || deactivated) { - VBDEBUG("TPM: disabled (%d) or deactivated (%d). Fixing...\n", - disable, deactivated); - RETURN_ON_FAILURE(tlcl_set_enable()); - RETURN_ON_FAILURE(tlcl_set_deactivated(0)); - VBDEBUG("TPM: Must reboot to re-enable\n"); - ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT; - return TPM_E_MUST_REBOOT; - } - - VBDEBUG("TPM: SetupTPM() succeeded\n"); - return TPM_SUCCESS; -} - -uint32_t antirollback_read_space_firmware(struct vb2_context *ctx) -{ - uint32_t rv; - - rv = setup_tpm(ctx); - if (rv) - return rv; - - /* Read the firmware space. */ - rv = read_space_firmware(ctx); - if (rv == TPM_E_BADINDEX) { - /* - * This seems the first time we've run. Initialize the TPM. - */ - VBDEBUG("TPM: Not initialized yet.\n"); - RETURN_ON_FAILURE(factory_initialize_tpm(ctx)); - } else if (rv != TPM_SUCCESS) { - VBDEBUG("TPM: Firmware space in a bad state; giving up.\n"); - //RETURN_ON_FAILURE(factory_initialize_tpm(ctx)); - return TPM_E_CORRUPTED_STATE; - } - - return TPM_SUCCESS; -} - -uint32_t antirollback_write_space_firmware(struct vb2_context *ctx) -{ - if (IS_ENABLED(CONFIG_CR50_IMMEDIATELY_COMMIT_FW_SECDATA)) - tlcl_cr50_enable_nvcommits(); - return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE); -} - -uint32_t antirollback_read_space_rec_hash(uint8_t *data, uint32_t size) -{ - if (size != REC_HASH_NV_SIZE) { - VBDEBUG("TPM: Incorrect buffer size for rec hash. " - "(Expected=0x%x Actual=0x%x).\n", REC_HASH_NV_SIZE, - size); - return TPM_E_READ_FAILURE; - } - return read_space_rec_hash(data); -} - -uint32_t antirollback_write_space_rec_hash(const uint8_t *data, uint32_t size) -{ - uint8_t spc_data[REC_HASH_NV_SIZE]; - uint32_t rv; - - if (size != REC_HASH_NV_SIZE) { - VBDEBUG("TPM: Incorrect buffer size for rec hash. " - "(Expected=0x%x Actual=0x%x).\n", REC_HASH_NV_SIZE, - size); - return TPM_E_WRITE_FAILURE; - } - - rv = read_space_rec_hash(spc_data); - if (rv == TPM_E_BADINDEX) { - /* - * If space is not defined already for recovery hash, define - * new space. - */ - VBDEBUG("TPM: Initializing recovery hash space.\n"); - return set_rec_hash_space(data); - } - - if (rv != TPM_SUCCESS) - return rv; - - return write_secdata(REC_HASH_NV_INDEX, data, size); -} diff --git a/src/vboot/symbols.h b/src/vboot/symbols.h deleted file mode 100644 index fb3d6545f8..0000000000 --- a/src/vboot/symbols.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2016 Google 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_SYMBOLS_H__ -#define __VBOOT_SYMBOLS_H__ - -extern u8 _vboot2_work[]; -extern u8 _evboot2_work[]; -#define _vboot2_work_size (_evboot2_work - _vboot2_work) - -/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */ -extern u8 _verstage[]; -extern u8 _everstage[]; -#define _verstage_size (_everstage - _verstage) - -#endif /* __VBOOT_SYMBOLS_H__ */ diff --git a/src/vboot/vbnv.c b/src/vboot/vbnv.c deleted file mode 100644 index 79bdc8e5df..0000000000 --- a/src/vboot/vbnv.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2016 Google 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 <arch/early_variables.h> -#include <string.h> -#include <types.h> -#include <vboot/vbnv.h> -#include <vboot/vbnv_layout.h> - -static int vbnv_initialized CAR_GLOBAL; -static uint8_t vbnv[VBOOT_VBNV_BLOCK_SIZE] CAR_GLOBAL; - -/* Wrappers for accessing the variables marked as CAR_GLOBAL. */ -static inline int is_vbnv_initialized(void) -{ - return car_get_var(vbnv_initialized); -} - -static inline uint8_t *vbnv_data_addr(int index) -{ - uint8_t *vbnv_arr = car_get_var_ptr(vbnv); - - return &vbnv_arr[index]; -} - -static inline uint8_t vbnv_data(int index) -{ - return *vbnv_data_addr(index); -} - -/* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. */ -static uint8_t crc8_vbnv(const uint8_t *data, int len) -{ - unsigned crc = 0; - int i, j; - - for (j = len; j; j--, data++) { - crc ^= (*data << 8); - for (i = 8; i; i--) { - if (crc & 0x8000) - crc ^= (0x1070 << 3); - crc <<= 1; - } - } - - return (uint8_t) (crc >> 8); -} - -void vbnv_reset(uint8_t *vbnv_copy) -{ - memset(vbnv_copy, 0, VBOOT_VBNV_BLOCK_SIZE); -} - -/* Read VBNV data into cache. */ -static void vbnv_setup(void) -{ - if (!is_vbnv_initialized()) { - read_vbnv(vbnv_data_addr(0)); - car_set_var(vbnv_initialized, 1); - } -} - -/* Verify VBNV header and checksum. */ -int verify_vbnv(uint8_t *vbnv_copy) -{ - return (HEADER_SIGNATURE == (vbnv_copy[HEADER_OFFSET] & HEADER_MASK)) && - (crc8_vbnv(vbnv_copy, CRC_OFFSET) == vbnv_copy[CRC_OFFSET]); -} - -/* Re-generate VBNV checksum. */ -void regen_vbnv_crc(uint8_t *vbnv_copy) -{ - vbnv_copy[CRC_OFFSET] = crc8_vbnv(vbnv_copy, CRC_OFFSET); -} - -/* - * Read VBNV data from configured storage backend. - * If VBNV verification fails, reset the vbnv copy. - */ -void read_vbnv(uint8_t *vbnv_copy) -{ - if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS)) - read_vbnv_cmos(vbnv_copy); - else if (IS_ENABLED(CONFIG_VBOOT_VBNV_EC)) - read_vbnv_ec(vbnv_copy); - else if (IS_ENABLED(CONFIG_VBOOT_VBNV_FLASH)) - read_vbnv_flash(vbnv_copy); - - /* Check data for consistency */ - if (!verify_vbnv(vbnv_copy)) - vbnv_reset(vbnv_copy); -} - -/* - * Write VBNV data to configured storage backend. - * This assumes that the caller has updated the CRC already. - */ -void save_vbnv(const uint8_t *vbnv_copy) -{ - if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS)) - save_vbnv_cmos(vbnv_copy); - else if (IS_ENABLED(CONFIG_VBOOT_VBNV_EC)) - save_vbnv_ec(vbnv_copy); - else if (IS_ENABLED(CONFIG_VBOOT_VBNV_FLASH)) - save_vbnv_flash(vbnv_copy); - - /* Clear initialized flag to force cached data to be updated */ - car_set_var(vbnv_initialized, 0); -} - -/* Save a recovery reason into VBNV. */ -void set_recovery_mode_into_vbnv(int recovery_reason) -{ - uint8_t vbnv_copy[VBOOT_VBNV_BLOCK_SIZE]; - - read_vbnv(vbnv_copy); - - vbnv_copy[RECOVERY_OFFSET] = recovery_reason; - vbnv_copy[CRC_OFFSET] = crc8_vbnv(vbnv_copy, CRC_OFFSET); - - save_vbnv(vbnv_copy); -} - -/* Read the recovery reason from VBNV. */ -int get_recovery_mode_from_vbnv(void) -{ - vbnv_setup(); - return vbnv_data(RECOVERY_OFFSET); -} - -/* Read the BOOT_OPROM_NEEDED flag from VBNV. */ -int vboot_wants_oprom(void) -{ - vbnv_setup(); - return (vbnv_data(BOOT_OFFSET) & BOOT_OPROM_NEEDED) ? 1 : 0; -} - -void vbnv_init(uint8_t *vbnv_copy) -{ - if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS)) - vbnv_init_cmos(vbnv_copy); - read_vbnv(vbnv_copy); -} diff --git a/src/vboot/vbnv.h b/src/vboot/vbnv.h deleted file mode 100644 index 0288d0df4d..0000000000 --- a/src/vboot/vbnv.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2016 Google 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_VBNV_H__ -#define __VBOOT_VBNV_H__ - -#include <types.h> - -/* Generic functions */ -void read_vbnv(uint8_t *vbnv_copy); -void save_vbnv(const uint8_t *vbnv_copy); -int verify_vbnv(uint8_t *vbnv_copy); -void regen_vbnv_crc(uint8_t *vbnv_copy); -int get_recovery_mode_from_vbnv(void); -void set_recovery_mode_into_vbnv(int recovery_reason); -int vboot_wants_oprom(void); -/* Initialize and read vbnv. This is used in the main vboot logic path. */ -void vbnv_init(uint8_t *vbnv_copy); -/* Reset vbnv snapshot to a known state. */ -void vbnv_reset(uint8_t *vbnv_copy); - -/* CMOS backend */ -/* Initialize the vbnv cmos backing store. The vbnv_copy pointer is used for - optional temporary storage in the init function. */ -void vbnv_init_cmos(uint8_t *vbnv_copy); -/* Return non-zero if cmos power was lost. */ -int vbnv_cmos_failed(void); -void read_vbnv_cmos(uint8_t *vbnv_copy); -void save_vbnv_cmos(const uint8_t *vbnv_copy); - -/* Flash backend */ -void read_vbnv_flash(uint8_t *vbnv_copy); -void save_vbnv_flash(const uint8_t *vbnv_copy); - -/* EC backend */ -void read_vbnv_ec(uint8_t *vbnv_copy); -void save_vbnv_ec(const uint8_t *vbnv_copy); - -#endif /* __VBOOT_VBNV_H__ */ diff --git a/src/vboot/vbnv_cmos.c b/src/vboot/vbnv_cmos.c deleted file mode 100644 index a311fddbb1..0000000000 --- a/src/vboot/vbnv_cmos.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. - * - * 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 <bootstate.h> -#include <console/console.h> -#include <types.h> -#include <pc80/mc146818rtc.h> -#include <vboot/vbnv.h> -#include <vboot/vbnv_layout.h> - -static void clear_vbnv_battery_cutoff_flag(uint8_t *vbnv_copy) -{ - /* - * Currently battery cutoff is done in payload stage, which does not - * update backup VBNV. And doing battery cutoff will invalidate CMOS. - * This means for every reboot after cutoff, read_vbnv_cmos will reload - * backup VBNV and try to cutoff again, causing endless reboot loop. - * So we should always clear battery cutoff flag from loaded backup. - */ - if (vbnv_copy[MISC_FLAGS_OFFSET] & MISC_FLAGS_BATTERY_CUTOFF_MASK) { - printk(BIOS_INFO, "VBNV: Remove battery cut-off request.\n"); - vbnv_copy[MISC_FLAGS_OFFSET] &= ~MISC_FLAGS_BATTERY_CUTOFF_MASK; - regen_vbnv_crc(vbnv_copy); - } -} - -/* Return non-zero if backup was used. */ -static int restore_from_backup(uint8_t *vbnv_copy) -{ - if (!IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH)) - return 0; - - printk(BIOS_INFO, "VBNV: CMOS invalid, restoring from flash\n"); - read_vbnv_flash(vbnv_copy); - - if (verify_vbnv(vbnv_copy)) { - clear_vbnv_battery_cutoff_flag(vbnv_copy); - save_vbnv_cmos(vbnv_copy); - printk(BIOS_INFO, "VBNV: Flash backup restored\n"); - return 1; - } - - printk(BIOS_INFO, "VBNV: Restore from flash failed\n"); - - return 0; -} - -void read_vbnv_cmos(uint8_t *vbnv_copy) -{ - int i; - - for (i = 0; i < VBOOT_VBNV_BLOCK_SIZE; i++) - vbnv_copy[i] = cmos_read(CONFIG_VBOOT_VBNV_OFFSET + 14 + i); - - /* Verify contents before attempting a restore from backup storage. */ - if (verify_vbnv(vbnv_copy)) - return; - - restore_from_backup(vbnv_copy); -} - -void save_vbnv_cmos(const uint8_t *vbnv_copy) -{ - int i; - - for (i = 0; i < VBOOT_VBNV_BLOCK_SIZE; i++) - cmos_write(vbnv_copy[i], CONFIG_VBOOT_VBNV_OFFSET + 14 + i); -} - -void vbnv_init_cmos(uint8_t *vbnv_copy) -{ - /* If no cmos failure just defer to the normal read path for checking - vbnv contents' integrity. */ - if (!vbnv_cmos_failed()) - return; - - /* In the case of cmos failure force the backup. If backup wasn't used - force the vbnv cmos to be reset. */ - if (!restore_from_backup(vbnv_copy)) { - vbnv_reset(vbnv_copy); - /* This parallels the vboot_reference implementation. */ - vbnv_copy[HEADER_OFFSET] = HEADER_SIGNATURE | - HEADER_FIRMWARE_SETTINGS_RESET | - HEADER_KERNEL_SETTINGS_RESET; - regen_vbnv_crc(vbnv_copy); - save_vbnv_cmos(vbnv_copy); - } -} - -#if IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH) -static void back_up_vbnv_cmos(void *unused) -{ - uint8_t vbnv_cmos[VBOOT_VBNV_BLOCK_SIZE]; - - /* Read current VBNV from CMOS. */ - read_vbnv_cmos(vbnv_cmos); - - /* Save to flash, will only be saved if different. */ - save_vbnv_flash(vbnv_cmos); -} -BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, back_up_vbnv_cmos, NULL); -#endif diff --git a/src/vboot/vbnv_ec.c b/src/vboot/vbnv_ec.c deleted file mode 100644 index 99e2b82b1f..0000000000 --- a/src/vboot/vbnv_ec.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. - * - * 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 <types.h> -#include <ec/google/chromeec/ec.h> -#include <vboot/vbnv.h> -#include <vboot/vbnv_layout.h> - -void read_vbnv_ec(uint8_t *vbnv_copy) -{ - google_chromeec_vbnv_context(1, vbnv_copy, VBOOT_VBNV_BLOCK_SIZE); -} - -void save_vbnv_ec(const uint8_t *vbnv_copy) -{ - google_chromeec_vbnv_context(0, (uint8_t *)vbnv_copy, - VBOOT_VBNV_BLOCK_SIZE); -} diff --git a/src/vboot/vbnv_flash.c b/src/vboot/vbnv_flash.c deleted file mode 100644 index dd128a9235..0000000000 --- a/src/vboot/vbnv_flash.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved. - * - * 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 <arch/early_variables.h> -#include <assert.h> -#include <commonlib/region.h> -#include <console/console.h> -#include <string.h> -#include <vb2_api.h> -#include <vboot_nvstorage.h> -#include <vboot/vboot_common.h> -#include <vboot/vbnv.h> -#include <vboot/vbnv_layout.h> - -#define BLOB_SIZE VB2_NVDATA_SIZE - -struct vbnv_flash_ctx { - /* VBNV flash is initialized */ - int initialized; - - /* Offset of the current nvdata in flash */ - int blob_offset; - - /* Offset of the topmost nvdata blob in flash */ - int top_offset; - - /* Region to store and retrieve the VBNV contents. */ - struct region_device vbnv_dev; - - /* Cache of the current nvdata */ - uint8_t cache[BLOB_SIZE]; -}; -static struct vbnv_flash_ctx vbnv_flash CAR_GLOBAL; - -/* - * This code assumes that flash is erased to 1-bits, and write operations can - * only change 1-bits to 0-bits. So if the new contents only change 1-bits to - * 0-bits, we can reuse the current blob. - */ -static inline uint8_t erase_value(void) -{ - return 0xff; -} - -static inline int can_overwrite(uint8_t current, uint8_t new) -{ - return (current & new) == new; -} - -static int init_vbnv(void) -{ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - struct region_device *rdev = &ctx->vbnv_dev; - uint8_t buf[BLOB_SIZE]; - uint8_t empty_blob[BLOB_SIZE]; - int used_below, empty_above; - int offset; - int i; - - if (vboot_named_region_device_rw("RW_NVRAM", rdev) || - region_device_sz(rdev) < BLOB_SIZE) { - printk(BIOS_ERR, "%s: failed to locate NVRAM\n", __func__); - return 1; - } - - /* Prepare an empty blob to compare against. */ - for (i = 0; i < BLOB_SIZE; i++) - empty_blob[i] = erase_value(); - - ctx->top_offset = region_device_sz(rdev) - BLOB_SIZE; - - /* Binary search for the border between used and empty */ - used_below = 0; - empty_above = region_device_sz(rdev) / BLOB_SIZE; - - while (used_below + 1 < empty_above) { - int guess = (used_below + empty_above) / 2; - if (rdev_readat(rdev, buf, guess * BLOB_SIZE, BLOB_SIZE) < 0) { - printk(BIOS_ERR, "failed to read nvdata\n"); - return 1; - } - if (!memcmp(buf, empty_blob, BLOB_SIZE)) - empty_above = guess; - else - used_below = guess; - } - - /* - * Offset points to the last non-empty blob. Or if all blobs are empty - * (nvram is totally erased), point to the first blob. - */ - offset = used_below * BLOB_SIZE; - - /* reread the nvdata and write it to the cache */ - if (rdev_readat(rdev, ctx->cache, offset, BLOB_SIZE) < 0) { - printk(BIOS_ERR, "failed to read nvdata\n"); - return 1; - } - - ctx->blob_offset = offset; - ctx->initialized = 1; - - return 0; -} - -static int erase_nvram(void) -{ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - const struct region_device *rdev = &ctx->vbnv_dev; - - if (rdev_eraseat(rdev, 0, region_device_sz(rdev)) < 0) { - printk(BIOS_ERR, "failed to erase nvram\n"); - return 1; - } - - printk(BIOS_INFO, "nvram is cleared\n"); - return 0; -} - -void read_vbnv_flash(uint8_t *vbnv_copy) -{ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - - if (!ctx->initialized) - if (init_vbnv()) - return; /* error */ - - memcpy(vbnv_copy, ctx->cache, BLOB_SIZE); -} - -void save_vbnv_flash(const uint8_t *vbnv_copy) -{ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - int new_offset; - int i; - const struct region_device *rdev = &ctx->vbnv_dev; - - if (!ctx->initialized) - if (init_vbnv()) - return; /* error */ - - /* Bail out if there have been no changes. */ - if (!memcmp(vbnv_copy, ctx->cache, BLOB_SIZE)) - return; - - new_offset = ctx->blob_offset; - - /* See if we can overwrite the current blob with the new one */ - for (i = 0; i < BLOB_SIZE; i++) { - if (!can_overwrite(ctx->cache[i], vbnv_copy[i])) { - /* unable to overwrite. need to use the next blob */ - new_offset += BLOB_SIZE; - if (new_offset > ctx->top_offset) { - if (erase_nvram()) - return; /* error */ - new_offset = 0; - } - break; - } - } - - if (rdev_writeat(rdev, vbnv_copy, new_offset, BLOB_SIZE) == BLOB_SIZE) { - /* write was successful. safely move pointer forward */ - ctx->blob_offset = new_offset; - memcpy(ctx->cache, vbnv_copy, BLOB_SIZE); - } else { - printk(BIOS_ERR, "failed to save nvdata\n"); - } -} diff --git a/src/vboot/vbnv_layout.h b/src/vboot/vbnv_layout.h deleted file mode 100644 index 1dc01c909a..0000000000 --- a/src/vboot/vbnv_layout.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 The ChromiumOS Authors. All rights reserved. - * - * 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_VBNV_LAYOUT_H__ -#define __VBOOT_VBNV_LAYOUT_H__ - -#define VBOOT_VBNV_BLOCK_SIZE 16 /* Size of NV storage block in bytes */ - -/* Constants for NV storage. We use this rather than structs and - * bitfields so the data format is consistent across platforms and - * compilers. - */ -#define HEADER_OFFSET 0 -#define HEADER_MASK 0xC0 -#define HEADER_SIGNATURE 0x40 -#define HEADER_FIRMWARE_SETTINGS_RESET 0x20 -#define HEADER_KERNEL_SETTINGS_RESET 0x10 - -#define BOOT_OFFSET 1 -#define BOOT_DEBUG_RESET_MODE 0x80 -#define BOOT_DISABLE_DEV_REQUEST 0x40 -#define BOOT_OPROM_NEEDED 0x20 -#define BOOT_TRY_B_COUNT_MASK 0x0F - -#define RECOVERY_OFFSET 2 -#define LOCALIZATION_OFFSET 3 - -#define DEV_FLAGS_OFFSET 4 -#define DEV_BOOT_USB_MASK 0x01 -#define DEV_BOOT_SIGNED_ONLY_MASK 0x02 - -#define MISC_FLAGS_OFFSET 8 -#define MISC_FLAGS_BATTERY_CUTOFF_MASK 0x08 - -#define KERNEL_FIELD_OFFSET 11 -#define CRC_OFFSET 15 - -#endif /* __VBOOT_VBNV_LAYOUT_H__ */ diff --git a/src/vboot/vboot_common.c b/src/vboot/vboot_common.c deleted file mode 100644 index 515b368f91..0000000000 --- a/src/vboot/vboot_common.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved. - * - * 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 <boot/coreboot_tables.h> -#include <boot_device.h> -#include <cbmem.h> -#include <console/cbmem_console.h> -#include <console/console.h> -#include <fmap.h> -#include <reset.h> -#include <rules.h> -#include <stddef.h> -#include <string.h> -#include <vboot/vboot_common.h> - -int vboot_named_region_device(const char *name, struct region_device *rdev) -{ - return fmap_locate_area_as_rdev(name, rdev); -} - -int vboot_named_region_device_rw(const char *name, struct region_device *rdev) -{ - return fmap_locate_area_as_rdev_rw(name, rdev); -} - -/* ========================== VBOOT HANDOFF APIs =========================== */ -int vboot_get_handoff_info(void **addr, uint32_t *size) -{ - /* - * vboot_handoff is present only after cbmem comes online. If we are in - * pre-ram stage, then bail out early. - */ - if (ENV_BOOTBLOCK || - (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))) - return -1; - - struct vboot_handoff *vboot_handoff; - vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - - if (vboot_handoff == NULL) - return -1; - - *addr = vboot_handoff; - - if (size) - *size = sizeof(*vboot_handoff); - return 0; -} - -static int vboot_get_handoff_flag(uint32_t flag) -{ - struct vboot_handoff *vbho; - - /* - * If vboot_handoff cannot be found, return default value of flag as 0. - */ - if (vboot_get_handoff_info((void **)&vbho, NULL)) - return 0; - - return !!(vbho->init_params.out_flags & flag); -} - -int vboot_handoff_skip_display_init(void) -{ - return !vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DISPLAY); -} - -int vboot_handoff_check_developer_flag(void) -{ - return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DEVELOPER); -} - -int vboot_handoff_check_recovery_flag(void) -{ - return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_RECOVERY); -} - -int vboot_handoff_get_recovery_reason(void) -{ - struct vboot_handoff *vbho; - VbSharedDataHeader *sd; - - if (vboot_get_handoff_info((void **)&vbho, NULL)) - return 0; - - sd = (VbSharedDataHeader *)vbho->shared_data; - - return sd->recovery_reason; -} - -/* ============================ VBOOT REBOOT ============================== */ -void __attribute__((weak)) vboot_platform_prepare_reboot(void) -{ -} - -void vboot_reboot(void) -{ - if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART)) - cbmem_dump_console(); - vboot_platform_prepare_reboot(); - hard_reset(); - die("failed to reboot"); -} diff --git a/src/vboot/vboot_common.h b/src/vboot/vboot_common.h deleted file mode 100644 index 8c92f7f131..0000000000 --- a/src/vboot/vboot_common.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google, 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_COMMON_H__ -#define __VBOOT_VBOOT_COMMON_H__ - -#include <commonlib/region.h> -#include <stdint.h> -#include <compiler.h> -#include <vboot_api.h> -#include <vboot_struct.h> - -/* Locate vboot area by name. Returns 0 on success and -1 on error. */ -int vboot_named_region_device(const char *name, struct region_device *rdev); - -/* Like vboot_named_region_device() but provides a RW region device. */ -int vboot_named_region_device_rw(const char *name, struct region_device *rdev); - -/* - * Function to check if there is a request to enter recovery mode. Returns - * reason code if request to enter recovery mode is present, otherwise 0. - */ -int vboot_check_recovery_request(void); - -/* ========================== VBOOT HANDOFF APIs =========================== */ -/* - * The vboot_handoff structure contains the data to be consumed by downstream - * firmware after firmware selection has been completed. Namely it provides - * vboot shared data as well as the flags from VbInit. - */ -struct vboot_handoff { - VbInitParams init_params; - uint32_t selected_firmware; - char shared_data[VB_SHARED_DATA_MIN_SIZE]; -} __packed; - -/* - * vboot_get_handoff_info returns pointer to the vboot_handoff structure if - * available. vboot_handoff is available only after CBMEM comes online. If size - * is not NULL, size of the vboot_handoff structure is returned in it. - * Returns 0 on success and -1 on error. - */ -int vboot_get_handoff_info(void **addr, uint32_t *size); - -/* - * The following functions read vboot_handoff structure to obtain requested - * information. If vboot handoff is not available, 0 is returned by default. - * If vboot handoff is available: - * Returns 1 for flag if true - * Returns 0 for flag if false - * Returns value read for other fields - */ -int vboot_handoff_skip_display_init(void); -int vboot_handoff_check_recovery_flag(void); -int vboot_handoff_check_developer_flag(void); -int vboot_handoff_get_recovery_reason(void); - -/* ============================ VBOOT REBOOT ============================== */ -/* - * vboot_reboot handles the reboot requests made by vboot_reference library. It - * allows the platform to run any preparation steps before the reboot and then - * does a hard reset. - */ -void vboot_reboot(void); - -/* Allow the platform to do any clean up work when vboot requests a reboot. */ -void vboot_platform_prepare_reboot(void); - -/* ============================ VBOOT RESUME ============================== */ -/* - * Save the provided hash digest to a secure location to check against in - * the resume path. Returns 0 on success, < 0 on error. - */ -int vboot_save_hash(void *digest, size_t digest_size); - -/* - * Retrieve the previously saved hash digest. Returns 0 on success, - * < 0 on error. - */ -int vboot_retrieve_hash(void *digest, size_t digest_size); - -/* - * Determine if the platform is resuming from suspend. Returns 0 when - * not resuming, > 0 if resuming, and < 0 on error. - */ -int vboot_platform_is_resuming(void); - -/* ============================= VERSTAGE ================================== */ -/* - * Main logic for verified boot. verstage_main() is just the core vboot logic. - * If the verstage is a separate stage, it should be entered via main(). - */ -void verstage_main(void); -void verstage_mainboard_init(void); - -/* Check boot modes */ -#if IS_ENABLED(CONFIG_VBOOT) -int vboot_developer_mode_enabled(void); -int vboot_recovery_mode_enabled(void); -int vboot_recovery_mode_memory_retrain(void); -#else /* !CONFIG_VBOOT */ -static inline int vboot_developer_mode_enabled(void) { return 0; } -static inline int vboot_recovery_mode_enabled(void) { return 0; } -static inline int vboot_recovery_mode_memory_retrain(void) { return 0; } -#endif - -#endif /* __VBOOT_VBOOT_COMMON_H__ */ diff --git a/src/vboot/vboot_handoff.c b/src/vboot/vboot_handoff.c deleted file mode 100644 index 974fe78ec3..0000000000 --- a/src/vboot/vboot_handoff.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2013 Google, 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. - */ - -/* This needs to be pulled in first so that the handoff code below and - * peek into the vb2 data structures. Additionally, vboot doesn't currently - * include what it uses in its own headers. Provide the types it's after. - * TODO: fix this necessity. */ -#define NEED_VB20_INTERNALS -#include <stddef.h> -#include <stdint.h> -#include <vb2_api.h> - -#include <arch/stages.h> -#include <assert.h> -#include <bootmode.h> -#include <string.h> -#include <cbfs.h> -#include <cbmem.h> -#include <console/console.h> -#include <console/vtxprintf.h> -#include <fmap.h> -#include <stdlib.h> -#include <timestamp.h> -#include <vboot_struct.h> -#include <vboot/vbnv.h> -#include <vboot/misc.h> - -/** - * Sets vboot_handoff based on the information in vb2_shared_data - */ -static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff, - struct vb2_shared_data *vb2_sd) -{ - VbSharedDataHeader *vb_sd = - (VbSharedDataHeader *)vboot_handoff->shared_data; - uint32_t *oflags = &vboot_handoff->init_params.out_flags; - - vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2; - - vboot_handoff->selected_firmware = vb2_sd->fw_slot; - - vb_sd->firmware_index = vb2_sd->fw_slot; - - vb_sd->magic = VB_SHARED_DATA_MAGIC; - vb_sd->struct_version = VB_SHARED_DATA_VERSION; - vb_sd->struct_size = sizeof(VbSharedDataHeader); - vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE; - vb_sd->data_used = sizeof(VbSharedDataHeader); - vb_sd->fw_version_tpm = vb2_sd->fw_version_secdata; - - if (get_write_protect_state()) - vb_sd->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED; - - if (vb2_sd->recovery_reason) { - vb_sd->firmware_index = 0xFF; - if (vb2_sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY) - vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON; - *oflags |= VB_INIT_OUT_ENABLE_RECOVERY; - *oflags |= VB_INIT_OUT_CLEAR_RAM; - *oflags |= VB_INIT_OUT_ENABLE_DISPLAY; - *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE; - } - if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) { - *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER; - *oflags |= VB_INIT_OUT_CLEAR_RAM; - *oflags |= VB_INIT_OUT_ENABLE_DISPLAY; - *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE; - vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON; - vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON; - } - /* TODO: Set these in depthcharge */ - if (!IS_ENABLED(CONFIG_VBOOT_PHYSICAL_DEV_SWITCH)) - vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH; - if (IS_ENABLED(CONFIG_VBOOT_EC_SOFTWARE_SYNC)) { - vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC; - if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE)) - vb_sd->flags |= VBSD_EC_SLOW_UPDATE; - if (IS_ENABLED(CONFIG_VBOOT_EC_EFS)) - vb_sd->flags |= VBSD_EC_EFS; - } - if (!IS_ENABLED(CONFIG_VBOOT_PHYSICAL_REC_SWITCH)) - vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL; - if (IS_ENABLED(CONFIG_VBOOT_OPROM_MATTERS)) { - vb_sd->flags |= VBSD_OPROM_MATTERS; - /* - * Inform vboot if the display was enabled by dev/rec - * mode or was requested by vboot kernel phase. - */ - if ((*oflags & VB_INIT_OUT_ENABLE_DISPLAY) || - vboot_wants_oprom()) { - vb_sd->flags |= VBSD_OPROM_LOADED; - *oflags |= VB_INIT_OUT_ENABLE_DISPLAY; - } - } - - /* In vboot1, VBSD_FWB_TRIED is - * set only if B is booted as explicitly requested. Therefore, if B is - * booted because A was found bad, the flag should not be set. It's - * better not to touch it if we can only ambiguously control it. */ - /* if (vb2_sd->fw_slot) - vb_sd->flags |= VBSD_FWB_TRIED; */ - - /* copy kernel subkey if it's found */ - if (vb2_sd->workbuf_preamble_size) { - struct vb2_fw_preamble *fp; - uintptr_t dst, src; - printk(BIOS_INFO, "Copying FW preamble\n"); - fp = (struct vb2_fw_preamble *)((uintptr_t)vb2_sd + - vb2_sd->workbuf_preamble_offset); - src = (uintptr_t)&fp->kernel_subkey + - fp->kernel_subkey.key_offset; - dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader); - assert(dst + fp->kernel_subkey.key_size <= - (uintptr_t)vboot_handoff + sizeof(*vboot_handoff)); - memcpy((void *)dst, (void *)src, - fp->kernel_subkey.key_size); - vb_sd->data_used += fp->kernel_subkey.key_size; - vb_sd->kernel_subkey.key_offset = - dst - (uintptr_t)&vb_sd->kernel_subkey; - vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size; - vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm; - vb_sd->kernel_subkey.key_version = - fp->kernel_subkey.key_version; - } - - vb_sd->recovery_reason = vb2_sd->recovery_reason; -} - -void vboot_fill_handoff(void) -{ - struct vboot_handoff *vh; - struct vb2_shared_data *sd; - - sd = vb2_get_shared_data(); - sd->workbuf_hash_offset = 0; - sd->workbuf_hash_size = 0; - - printk(BIOS_INFO, "creating vboot_handoff structure\n"); - vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh)); - if (vh == NULL) - /* we don't need to failover gracefully here because this - * shouldn't happen with the image that has passed QA. */ - die("failed to allocate vboot_handoff structure\n"); - - memset(vh, 0, sizeof(*vh)); - - /* needed until we finish transtion to vboot2 for kernel verification */ - fill_vboot_handoff(vh, sd); - - - /* Log the recovery mode switches if required, before clearing them. */ - log_recovery_mode_switch(); - - /* - * The recovery mode switch is cleared (typically backed by EC) here - * to allow multiple queries to get_recovery_mode_switch() and have - * them return consistent results during the verified boot path as well - * as dram initialization. x86 systems ignore the saved dram settings - * in the recovery path in order to start from a clean slate. Therefore - * clear the state here since this function is called when memory - * is known to be up. - */ - clear_recovery_mode_switch(); -} - -/* - * For platforms that employ VBOOT_STARTS_IN_ROMSTAGE, the vboot - * verification doesn't happen until after cbmem is brought online. - * Therefore, the vboot results would not be initialized so don't - * automatically add results when cbmem comes online. - */ -#if !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) -static void vb2_fill_handoff_cbmem(int unused) -{ - vboot_fill_handoff(); -} -ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem) -#endif diff --git a/src/vboot/vboot_loader.c b/src/vboot/vboot_loader.c deleted file mode 100644 index 6a7e284867..0000000000 --- a/src/vboot/vboot_loader.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google, 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 <arch/early_variables.h> -#include <cbfs.h> -#include <cbmem.h> -#include <console/console.h> -#include <ec/google/chromeec/ec.h> -#include <rmodule.h> -#include <rules.h> -#include <string.h> -#include <vboot/misc.h> -#include <vboot/symbols.h> -#include <vboot/vboot_common.h> - -/* Ensure vboot configuration is valid: */ -_Static_assert(IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) + - IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) == 1, - "vboot must either start in bootblock or romstage (not both!)"); -_Static_assert(!IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE) || - IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK), - "stand-alone verstage must start in (i.e. after) bootblock"); -_Static_assert(!IS_ENABLED(CONFIG_VBOOT_RETURN_FROM_VERSTAGE) || - IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE), - "return from verstage only makes sense for separate verstages"); - -/* The stage loading code is compiled and entered from multiple stages. The - * helper functions below attempt to provide more clarity on when certain - * code should be called. */ - -static int verification_should_run(void) -{ - if (IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE)) - return ENV_VERSTAGE; - else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) - return ENV_ROMSTAGE; - else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) - return ENV_BOOTBLOCK; - else - die("impossible!"); -} - -static int verstage_should_load(void) -{ - if (IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE)) - return ENV_BOOTBLOCK; - else - return 0; -} - -static int vboot_executed CAR_GLOBAL; - -int vb2_logic_executed(void) -{ - /* If we are in a stage that would load the verstage or execute the - vboot logic directly, we store the answer in a global. */ - if (verstage_should_load() || verification_should_run()) - return car_get_var(vboot_executed); - - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) { - /* All other stages are "after the bootblock" */ - return !ENV_BOOTBLOCK; - } else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) { - /* Post-RAM stages are "after the romstage" */ -#ifdef __PRE_RAM__ - return 0; -#else - return 1; -#endif - } else { - die("impossible!"); - } -} - -static void vboot_prepare(void) -{ - if (verification_should_run()) { - /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */ - verstage_main(); - car_set_var(vboot_executed, 1); - vb2_save_recovery_reason_vbnv(); - } else if (verstage_should_load()) { - struct cbfsf file; - struct prog verstage = - PROG_INIT(PROG_VERSTAGE, - CONFIG_CBFS_PREFIX "/verstage"); - - printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n"); - - /* load verstage from RO */ - if (cbfs_boot_locate(&file, prog_name(&verstage), NULL)) - die("failed to load verstage"); - - cbfs_file_data(prog_rdev(&verstage), &file); - - if (cbfs_prog_stage_load(&verstage)) - die("failed to load verstage"); - - /* verify and select a slot */ - prog_run(&verstage); - - /* This is not actually possible to hit this condition at - * runtime, but this provides a hint to the compiler for dead - * code elimination below. */ - if (!IS_ENABLED(CONFIG_VBOOT_RETURN_FROM_VERSTAGE)) - return; - - car_set_var(vboot_executed, 1); - } - - /* - * Fill in vboot cbmem objects before moving to ramstage so all - * downstream users have access to vboot results. This path only - * applies to platforms employing VBOOT_STARTS_IN_ROMSTAGE because - * cbmem comes online prior to vboot verification taking place. For - * other platforms the vboot cbmem objects are initialized when - * cbmem comes online. - */ - if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) { - vb2_store_selected_region(); - vboot_fill_handoff(); - } -} - -static int vboot_locate(struct cbfs_props *props) -{ - struct region selected_region; - - /* Don't honor vboot results until the vboot logic has run. */ - if (!vb2_logic_executed()) - return -1; - - if (vb2_get_selected_region(&selected_region)) - return -1; - - props->offset = region_offset(&selected_region); - props->size = region_sz(&selected_region); - - return 0; -} - -const struct cbfs_locator vboot_locator = { - .name = "VBOOT", - .prepare = vboot_prepare, - .locate = vboot_locate, -}; diff --git a/src/vboot/vboot_logic.c b/src/vboot/vboot_logic.c deleted file mode 100644 index d06faa740a..0000000000 --- a/src/vboot/vboot_logic.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2014 Google 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 <antirollback.h> -#include <arch/exception.h> -#include <assert.h> -#include <bootmode.h> -#include <console/console.h> -#include <console/vtxprintf.h> -#include <delay.h> -#include <string.h> -#include <timestamp.h> -#include <vb2_api.h> -#include <vboot/misc.h> -#include <vboot/vbnv.h> - -/* The max hash size to expect is for SHA512. */ -#define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE - -#define TODO_BLOCK_SIZE 1024 - -static int is_slot_a(struct vb2_context *ctx) -{ - return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B); -} - -/* exports */ - -void vb2ex_printf(const char *func, const char *fmt, ...) -{ - va_list args; - - if (func) - printk(BIOS_INFO, "VB2:%s() ", func); - - va_start(args, fmt); - do_printk_va_list(BIOS_INFO, fmt, args); - va_end(args); - - return; -} - -int vb2ex_tpm_clear_owner(struct vb2_context *ctx) -{ - uint32_t rv; - printk(BIOS_INFO, "Clearing TPM owner\n"); - rv = tpm_clear_and_reenable(); - if (rv) - return VB2_ERROR_EX_TPM_CLEAR_OWNER; - return VB2_SUCCESS; -} - -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; - - switch (index) { - case VB2_RES_GBB: - name = "GBB"; - break; - case VB2_RES_FW_VBLOCK: - if (is_slot_a(ctx)) - name = "VBLOCK_A"; - else - name = "VBLOCK_B"; - break; - default: - return VB2_ERROR_EX_READ_RESOURCE_INDEX; - } - - if (vboot_named_region_device(name, &rdev)) - return VB2_ERROR_EX_READ_RESOURCE_SIZE; - - if (rdev_readat(&rdev, buf, offset, size) != size) - return VB2_ERROR_EX_READ_RESOURCE_SIZE; - - return VB2_SUCCESS; -} - -/* 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) -{ - return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; -} - -__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) -{ - BUG(); /* Should never get called if init() returned an error. */ - return VB2_ERROR_UNKNOWN; -} - -static int handle_digest_result(void *slot_hash, size_t slot_hash_sz) -{ - int is_resume; - - /* - * Chrome EC is the only support for vboot_save_hash() & - * vboot_retrieve_hash(), if Chrome EC is not enabled then return. - */ - if (!IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)) - return 0; - - /* - * Nothing to do since resuming on the platform doesn't require - * vboot verification again. - */ - if (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT)) - return 0; - - /* - * Assume that if vboot doesn't start in bootblock verified - * RW memory init code is not employed. i.e. memory init code - * lives in RO CBFS. - */ - if (!IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) - return 0; - - is_resume = vboot_platform_is_resuming(); - - if (is_resume > 0) { - uint8_t saved_hash[VBOOT_MAX_HASH_SIZE]; - const size_t saved_hash_sz = sizeof(saved_hash); - - assert(slot_hash_sz == saved_hash_sz); - - printk(BIOS_DEBUG, "Platform is resuming.\n"); - - if (vboot_retrieve_hash(saved_hash, saved_hash_sz)) { - printk(BIOS_ERR, "Couldn't retrieve saved hash.\n"); - return -1; - } - - if (memcmp(saved_hash, slot_hash, slot_hash_sz)) { - printk(BIOS_ERR, "Hash mismatch on resume.\n"); - return -1; - } - } else if (is_resume < 0) - printk(BIOS_ERR, "Unable to determine if platform resuming.\n"); - - printk(BIOS_DEBUG, "Saving vboot hash.\n"); - - /* Always save the hash for the current boot. */ - if (vboot_save_hash(slot_hash, slot_hash_sz)) { - printk(BIOS_ERR, "Error saving vboot hash.\n"); - /* Though this is an error don't report it up since it could - * lead to a reboot loop. The consequence of this is that - * we will most likely fail resuming because of EC issues or - * the hash digest not matching. */ - return 0; - } - - return 0; -} - -static int hash_body(struct vb2_context *ctx, struct region_device *fw_main) -{ - uint64_t load_ts; - uint32_t expected_size; - uint8_t block[TODO_BLOCK_SIZE]; - uint8_t hash_digest[VBOOT_MAX_HASH_SIZE]; - const size_t hash_digest_sz = sizeof(hash_digest); - size_t block_size = sizeof(block); - size_t offset; - int rv; - - /* Clear the full digest so that any hash digests less than the - * max have trailing zeros. */ - memset(hash_digest, 0, hash_digest_sz); - - /* - * Since loading the firmware and calculating its hash is intertwined, - * we use this little trick to measure them separately and pretend it - * was first loaded and then hashed in one piece with the timestamps. - * (This split won't make sense with memory-mapped media like on x86.) - */ - load_ts = timestamp_get(); - timestamp_add(TS_START_HASH_BODY, load_ts); - - expected_size = region_device_sz(fw_main); - offset = 0; - - /* Start the body hash */ - rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size); - if (rv) - return rv; - - /* - * Honor vboot's RW slot size. The expected size is pulled out of - * the preamble and obtained through vb2api_init_hash() above. By - * creating sub region the RW slot portion of the boot media is - * limited. - */ - if (rdev_chain(fw_main, fw_main, 0, expected_size)) { - printk(BIOS_ERR, "Unable to restrict CBFS size.\n"); - return VB2_ERROR_UNKNOWN; - } - - /* Extend over the body */ - while (expected_size) { - uint64_t temp_ts; - if (block_size > expected_size) - block_size = expected_size; - - temp_ts = timestamp_get(); - if (rdev_readat(fw_main, block, offset, block_size) < 0) - return VB2_ERROR_UNKNOWN; - load_ts += timestamp_get() - temp_ts; - - rv = vb2api_extend_hash(ctx, block, block_size); - if (rv) - return rv; - - expected_size -= block_size; - offset += block_size; - } - - timestamp_add(TS_DONE_LOADING, load_ts); - timestamp_add_now(TS_DONE_HASHING); - - /* Check the result (with RSA signature verification) */ - rv = vb2api_check_hash_get_digest(ctx, hash_digest, hash_digest_sz); - if (rv) - return rv; - - timestamp_add_now(TS_END_HASH_BODY); - - if (handle_digest_result(hash_digest, hash_digest_sz)) - return VB2_ERROR_UNKNOWN; - - return VB2_SUCCESS; -} - -static int locate_firmware(struct vb2_context *ctx, - struct region_device *fw_main) -{ - const char *name; - - if (is_slot_a(ctx)) - name = "FW_MAIN_A"; - else - name = "FW_MAIN_B"; - - return vboot_named_region_device(name, fw_main); -} - -/** - * Save non-volatile and/or secure data if needed. - */ -static void save_if_needed(struct vb2_context *ctx) -{ - if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) { - printk(BIOS_INFO, "Saving nvdata\n"); - save_vbnv(ctx->nvdata); - ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED; - } - if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) { - printk(BIOS_INFO, "Saving secdata\n"); - antirollback_write_space_firmware(ctx); - ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED; - } -} - -static uint32_t extend_pcrs(struct vb2_context *ctx) -{ - return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) || - tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR); -} - -/** - * Verify and select the firmware in the RW image - * - * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage). - * when per-stage verification is ready. - */ -void verstage_main(void) -{ - struct vb2_context ctx; - struct region_device fw_main; - int rv; - - timestamp_add_now(TS_START_VBOOT); - - /* Set up context and work buffer */ - vb2_init_work_context(&ctx); - - /* Initialize and read nvdata from non-volatile storage. */ - vbnv_init(ctx.nvdata); - - /* Set S3 resume flag if vboot should behave differently when selecting - * which slot to boot. This is only relevant to vboot if the platform - * does verification of memory init and thus must ensure it resumes with - * the same slot that it booted from. */ - if (IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) && - IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) && - vboot_platform_is_resuming()) - ctx.flags |= VB2_CONTEXT_S3_RESUME; - - /* 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). */ - timestamp_add_now(TS_START_TPMINIT); - antirollback_read_space_firmware(&ctx); - timestamp_add_now(TS_END_TPMINIT); - - if (IS_ENABLED(CONFIG_VBOOT_PHYSICAL_DEV_SWITCH) && - get_developer_mode_switch()) - ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE; - - if (get_recovery_mode_switch()) { - ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE; - if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY)) - ctx.flags |= VB2_DISABLE_DEVELOPER_MODE; - } - - if (IS_ENABLED(CONFIG_VBOOT_WIPEOUT_SUPPORTED) && - get_wipeout_mode_switch()) - ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE; - - if (IS_ENABLED(CONFIG_VBOOT_LID_SWITCH) && !get_lid_switch()) - ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT; - - /* Do early init (set up secdata and NVRAM, load GBB) */ - printk(BIOS_INFO, "Phase 1\n"); - rv = vb2api_fw_phase1(&ctx); - - if (rv) { - /* - * If vb2api_fw_phase1 fails, check for return value. - * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue - * into recovery mode. - * For any other error code, save context if needed and reboot. - */ - if (rv == VB2_ERROR_API_PHASE1_RECOVERY) { - printk(BIOS_INFO, "Recovery requested (%x)\n", rv); - save_if_needed(&ctx); - extend_pcrs(&ctx); /* ignore failures */ - timestamp_add_now(TS_END_VBOOT); - return; - } - - printk(BIOS_INFO, "Reboot reqested (%x)\n", rv); - save_if_needed(&ctx); - vboot_reboot(); - } - - /* Determine which firmware slot to boot (based on NVRAM) */ - printk(BIOS_INFO, "Phase 2\n"); - rv = vb2api_fw_phase2(&ctx); - if (rv) { - printk(BIOS_INFO, "Reboot requested (%x)\n", rv); - save_if_needed(&ctx); - vboot_reboot(); - } - - /* Try that slot (verify its keyblock and preamble) */ - printk(BIOS_INFO, "Phase 3\n"); - timestamp_add_now(TS_START_VERIFY_SLOT); - rv = vb2api_fw_phase3(&ctx); - timestamp_add_now(TS_END_VERIFY_SLOT); - if (rv) { - printk(BIOS_INFO, "Reboot requested (%x)\n", rv); - save_if_needed(&ctx); - vboot_reboot(); - } - - printk(BIOS_INFO, "Phase 4\n"); - rv = locate_firmware(&ctx, &fw_main); - if (rv) - die("Failed to read FMAP to locate firmware"); - - rv = hash_body(&ctx, &fw_main); - save_if_needed(&ctx); - if (rv) { - printk(BIOS_INFO, "Reboot requested (%x)\n", rv); - vboot_reboot(); - } - - rv = extend_pcrs(&ctx); - if (rv) { - printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv); - vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv); - save_if_needed(&ctx); - vboot_reboot(); - } - - /* Lock TPM */ - rv = antirollback_lock_space_firmware(); - if (rv) { - printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv); - vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0); - save_if_needed(&ctx); - vboot_reboot(); - } - - /* Lock rec hash space if available. */ - if (IS_ENABLED(CONFIG_VBOOT_HAS_REC_HASH_SPACE)) { - rv = antirollback_lock_space_rec_hash(); - if (rv) { - printk(BIOS_INFO, "Failed to lock rec hash space(%x)\n", - rv); - vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR, - 0); - save_if_needed(&ctx); - vboot_reboot(); - } - } - - printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B'); - vb2_set_selected_region(region_device_region(&fw_main)); - timestamp_add_now(TS_END_VBOOT); -} diff --git a/src/vboot/verstage.c b/src/vboot/verstage.c deleted file mode 100644 index aca4ab328d..0000000000 --- a/src/vboot/verstage.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google 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 <arch/exception.h> -#include <arch/hlt.h> -#include <console/console.h> -#include <program_loading.h> -#include <vboot/vboot_common.h> - -void __attribute__((weak)) verstage_mainboard_init(void) -{ - /* Default empty implementation. */ -} - -void main(void) -{ - console_init(); - exception_init(); - verstage_mainboard_init(); - - if (IS_ENABLED(CONFIG_VBOOT_RETURN_FROM_VERSTAGE)) { - verstage_main(); - } else { - run_romstage(); - hlt(); - } -} |