Furquan Shaikh (furquan@google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15867
-gerrit
commit 2b6ac782c383530c05f2132f46b3b815265ba288 Author: Furquan Shaikh furquan@google.com Date: Mon Jul 25 11:48:03 2016 -0700
vboot: Separate vboot from chromeos
VBOOT_VERIFY_FIRMWARE should be independent of CHROMEOS. This allows use of verified boot library without having to stick to CHROMEOS.
BUG=chrome-os-partner:55639
Change-Id: Ia2c328712caedd230ab295b8a613e3c1ed1532d9 Signed-off-by: Furquan Shaikh furquan@google.com --- Makefile.inc | 1 + src/Kconfig | 1 + src/device/pci_device.c | 2 +- src/ec/google/chromeec/Makefile.inc | 8 +- src/lib/bootmode.c | 2 +- src/lib/cbfs.c | 2 +- src/lib/coreboot_table.c | 10 +- src/mainboard/google/auron/Kconfig | 4 +- src/mainboard/google/auron_paine/Kconfig | 6 +- src/mainboard/google/butterfly/Kconfig | 2 +- src/mainboard/google/cosmos/Kconfig | 2 +- src/mainboard/google/cyan/Kconfig | 4 +- src/mainboard/google/daisy/Kconfig | 2 +- src/mainboard/google/falco/Kconfig | 4 +- src/mainboard/google/foster/Kconfig | 2 +- src/mainboard/google/gru/Kconfig | 2 +- src/mainboard/google/guado/Kconfig | 4 +- src/mainboard/google/jecht/Kconfig | 4 +- src/mainboard/google/link/Kconfig | 2 +- src/mainboard/google/ninja/Kconfig | 2 + src/mainboard/google/nyan/Kconfig | 2 +- src/mainboard/google/nyan/romstage.c | 2 +- src/mainboard/google/nyan_big/Kconfig | 2 +- src/mainboard/google/nyan_big/romstage.c | 2 +- src/mainboard/google/nyan_blaze/Kconfig | 2 +- src/mainboard/google/nyan_blaze/romstage.c | 6 +- src/mainboard/google/oak/Kconfig | 2 +- src/mainboard/google/panther/Kconfig | 2 +- src/mainboard/google/parrot/Kconfig | 2 +- src/mainboard/google/peach_pit/Kconfig | 2 +- src/mainboard/google/peppy/Kconfig | 6 +- src/mainboard/google/purin/Kconfig | 2 +- src/mainboard/google/rambi/Kconfig | 4 +- src/mainboard/google/rikku/Kconfig | 4 +- src/mainboard/google/rush/Kconfig | 2 +- src/mainboard/google/rush_ryu/Kconfig | 2 +- src/mainboard/google/rush_ryu/mainboard.c | 4 +- src/mainboard/google/samus/Kconfig | 6 +- src/mainboard/google/smaug/Kconfig | 2 +- src/mainboard/google/stout/Kconfig | 2 +- src/mainboard/google/tidus/Kconfig | 4 +- src/mainboard/google/veyron/Kconfig | 2 +- src/mainboard/google/veyron_brain/Kconfig | 2 +- src/mainboard/google/veyron_danger/Kconfig | 2 +- src/mainboard/google/veyron_emile/Kconfig | 2 +- src/mainboard/google/veyron_mickey/Kconfig | 2 +- src/mainboard/google/veyron_rialto/Kconfig | 2 +- src/mainboard/google/veyron_romy/Kconfig | 2 +- src/mainboard/intel/baskingridge/Kconfig | 2 +- src/mainboard/intel/emeraldlake2/Kconfig | 2 +- src/mainboard/intel/strago/Kconfig | 4 +- src/mainboard/intel/wtm2/Kconfig | 2 +- src/mainboard/samsung/lumpy/Kconfig | 2 +- src/mainboard/samsung/stumpy/Kconfig | 2 +- src/soc/intel/apollolake/Kconfig | 4 +- src/soc/intel/apollolake/lpc.c | 4 +- src/soc/intel/apollolake/pmutil.c | 2 +- src/soc/intel/broadwell/igd.c | 2 +- src/soc/intel/broadwell/lpc.c | 13 +- src/soc/intel/skylake/Kconfig | 4 +- src/soc/intel/skylake/igd.c | 3 +- src/soc/intel/skylake/pmc.c | 12 +- src/soc/intel/skylake/romstage/power_state.c | 2 +- src/soc/marvell/bg4cd/Kconfig | 2 +- src/soc/marvell/bg4cd/Makefile.inc | 4 +- src/soc/qualcomm/ipq40xx/Kconfig | 4 +- src/soc/qualcomm/ipq806x/Kconfig | 2 +- src/vboot/Kconfig | 143 +++++++ src/vboot/Makefile.inc | 143 +++++++ src/vboot/common.c | 182 +++++++++ src/vboot/misc.h | 40 ++ src/vboot/recovery.c | 152 +++++++ src/vboot/secdata_mock.c | 38 ++ src/vboot/secdata_tpm.c | 436 +++++++++++++++++++++ src/vboot/symbols.h | 28 ++ src/vboot/vbnv.c | 142 +++++++ src/vboot/vbnv.h | 42 ++ src/vboot/vbnv_cmos.c | 79 ++++ src/vboot/vbnv_ec.c | 30 ++ src/vboot/vbnv_flash.c | 228 +++++++++++ src/vboot/vbnv_layout.h | 47 +++ src/vboot/vboot_common.c | 110 ++++++ src/vboot/vboot_common.h | 104 +++++ src/vboot/vboot_handoff.c | 180 +++++++++ src/vboot/vboot_loader.c | 159 ++++++++ src/vboot/vboot_logic.c | 415 ++++++++++++++++++++ src/vboot/verstage.c | 44 +++ src/vendorcode/google/Kconfig | 1 - src/vendorcode/google/chromeos/Kconfig | 61 +-- src/vendorcode/google/chromeos/Makefile.inc | 27 -- src/vendorcode/google/chromeos/acpi/chromeos.asl | 6 +- src/vendorcode/google/chromeos/chromeos.h | 5 +- src/vendorcode/google/chromeos/elog.c | 7 +- src/vendorcode/google/chromeos/gnvs.c | 9 +- src/vendorcode/google/chromeos/symbols.h | 9 - src/vendorcode/google/chromeos/vbnv.c | 143 ------- src/vendorcode/google/chromeos/vbnv.h | 42 -- src/vendorcode/google/chromeos/vbnv_cmos.c | 79 ---- src/vendorcode/google/chromeos/vbnv_ec.c | 29 -- src/vendorcode/google/chromeos/vbnv_flash.c | 227 ----------- src/vendorcode/google/chromeos/vbnv_layout.h | 47 --- src/vendorcode/google/chromeos/vboot2/Kconfig | 89 ----- src/vendorcode/google/chromeos/vboot2/Makefile.inc | 118 ------ .../google/chromeos/vboot2/antirollback.c | 436 --------------------- src/vendorcode/google/chromeos/vboot2/common.c | 183 --------- src/vendorcode/google/chromeos/vboot2/misc.h | 40 -- src/vendorcode/google/chromeos/vboot2/recovery.c | 154 -------- .../google/chromeos/vboot2/secdata_mock.c | 38 -- .../google/chromeos/vboot2/vboot_handoff.c | 179 --------- .../google/chromeos/vboot2/vboot_loader.c | 159 -------- .../google/chromeos/vboot2/vboot_logic.c | 415 -------------------- src/vendorcode/google/chromeos/vboot2/verstage.c | 44 --- src/vendorcode/google/chromeos/vboot_common.c | 112 ------ src/vendorcode/google/chromeos/vboot_common.h | 106 ----- 114 files changed, 2866 insertions(+), 2855 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc index 5e564d6..e3f6d0e 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -82,6 +82,7 @@ subdirs-y += util/cbfstool util/sconfig util/nvramtool util/broadcom subdirs-y += util/futility util/marvell subdirs-y += $(wildcard src/arch/*) subdirs-y += src/mainboard/$(MAINBOARDDIR) +subdirs-$(CONFIG_VBOOT) += src/vboot subdirs-y += payloads payloads/external
subdirs-y += site-local diff --git a/src/Kconfig b/src/Kconfig index 1cc0bfa..1694805 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -453,6 +453,7 @@ source "src/ec/*/*/Kconfig" source "src/drivers/intel/fsp1_0/Kconfig"
source "src/southbridge/intel/common/firmware/Kconfig" +source "src/vboot/Kconfig" source "src/vendorcode/*/Kconfig"
source "src/arch/*/Kconfig" diff --git a/src/device/pci_device.c b/src/device/pci_device.c index 5cd0053..73558db 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -48,7 +48,7 @@ #include <device/hypertransport.h> #include <pc80/i8259.h> #include <kconfig.h> -#include <vendorcode/google/chromeos/chromeos.h> +#include <vboot/vbnv.h>
u8 pci_moving_config8(struct device *dev, unsigned int reg) { diff --git a/src/ec/google/chromeec/Makefile.inc b/src/ec/google/chromeec/Makefile.inc index 4f310c8..c4b9c1a 100644 --- a/src/ec/google/chromeec/Makefile.inc +++ b/src/ec/google/chromeec/Makefile.inc @@ -22,10 +22,10 @@ verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_LPC) += ec_lpc.c verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_MEC) += ec_mec.c verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_SPI) += ec_spi.c
-ramstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c -smm-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c -romstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c -verstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c +ramstage-$(CONFIG_VBOOT) += vboot_storage.c +smm-$(CONFIG_VBOOT) += vboot_storage.c +romstage-$(CONFIG_VBOOT) += vboot_storage.c +verstage-$(CONFIG_VBOOT) += vboot_storage.c
# These are Chrome EC firmware images that a payload (such as depthcharge) can # use to update the EC. ecrw is the main embedded controller's firmware, diff --git a/src/lib/bootmode.c b/src/lib/bootmode.c index c6c29ac..824edfb 100644 --- a/src/lib/bootmode.c +++ b/src/lib/bootmode.c @@ -22,7 +22,7 @@ int developer_mode_enabled(void) { if (get_developer_mode_switch()) return 1; -#if CONFIG_VBOOT_VERIFY_FIRMWARE +#if CONFIG_VBOOT if (vboot_handoff_check_developer_flag()) return 1; #endif diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index b8575f3..7a0f187 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -269,7 +269,7 @@ const struct cbfs_locator __attribute__((weak)) cbfs_master_header_locator = { extern const struct cbfs_locator vboot_locator;
static const struct cbfs_locator *locators[] = { -#if CONFIG_VBOOT_VERIFY_FIRMWARE +#if CONFIG_VBOOT &vboot_locator, #endif &cbfs_master_header_locator, diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 3af2be6..44ae733 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -32,6 +32,7 @@ #include <cbmem.h> #include <bootmem.h> #include <spi_flash.h> +#include <vboot/vbnv_layout.h> #if CONFIG_USE_OPTION_TABLE #include <option_table.h> #endif @@ -41,7 +42,6 @@ #endif #include <vendorcode/google/chromeos/chromeos.h> #include <vendorcode/google/chromeos/gnvs.h> -#include <vendorcode/google/chromeos/vbnv_layout.h> #endif #if CONFIG_ARCH_X86 #include <cpu/x86/mtrr.h> @@ -221,12 +221,12 @@ static void lb_vbnv(struct lb_header *header) vbnv = (struct lb_range *)lb_new_record(header); vbnv->tag = LB_TAG_VBNV; vbnv->size = sizeof(*vbnv); - vbnv->range_start = CONFIG_VBNV_OFFSET + 14; - vbnv->range_size = VBNV_BLOCK_SIZE; + vbnv->range_start = CONFIG_VBOOT_VBNV_OFFSET + 14; + vbnv->range_size = VBOOT_VBNV_BLOCK_SIZE; #endif }
-#if CONFIG_VBOOT_VERIFY_FIRMWARE +#if CONFIG_VBOOT static void lb_vboot_handoff(struct lb_header *header) { void *addr; @@ -244,7 +244,7 @@ static void lb_vboot_handoff(struct lb_header *header) } #else static inline void lb_vboot_handoff(struct lb_header *header) {} -#endif /* CONFIG_VBOOT_VERIFY_FIRMWARE */ +#endif /* CONFIG_VBOOT */ #endif /* CONFIG_CHROMEOS */
static void lb_board_id(struct lb_header *header) diff --git a/src/mainboard/google/auron/Kconfig b/src/mainboard/google/auron/Kconfig index e897d11..f1b1719 100644 --- a/src/mainboard/google/auron/Kconfig +++ b/src/mainboard/google/auron/Kconfig @@ -15,10 +15,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS - select LID_SWITCH select CHROMEOS_RAMOOPS_DYNAMIC select EC_SOFTWARE_SYNC + select LID_SWITCH + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/auron_paine/Kconfig b/src/mainboard/google/auron_paine/Kconfig index 0b945ee..533c3da 100644 --- a/src/mainboard/google/auron_paine/Kconfig +++ b/src/mainboard/google/auron_paine/Kconfig @@ -15,10 +15,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS - select LID_SWITCH - select CHROMEOS_RAMOOPS_DYNAMIC select EC_SOFTWARE_SYNC + select CHROMEOS_RAMOOPS_DYNAMIC + select LID_SWITCH + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config VBOOT_RAMSTAGE_INDEX diff --git a/src/mainboard/google/butterfly/Kconfig b/src/mainboard/google/butterfly/Kconfig index 4240076..09d2157 100644 --- a/src/mainboard/google/butterfly/Kconfig +++ b/src/mainboard/google/butterfly/Kconfig @@ -18,7 +18,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SERIRQ_CONTINUOUS_MODE # Workaround for EC/KBC IRQ1.
config CHROMEOS - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/google/cosmos/Kconfig b/src/mainboard/google/cosmos/Kconfig index 7588125..19d5955 100644 --- a/src/mainboard/google/cosmos/Kconfig +++ b/src/mainboard/google/cosmos/Kconfig @@ -27,7 +27,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_SPANSION
config CHROMEOS - select CHROMEOS_VBNV_FLASH + select VBOOT_VBNV_FLASH
config MAINBOARD_DIR string diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index a863c55..782a460 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -16,10 +16,10 @@ config BOARD_SPECIFIC_OPTIONS select PCIEXP_L1_SUB_STATE
config CHROMEOS - select LID_SWITCH - select CHROMEOS_VBNV_CMOS select EC_SOFTWARE_SYNC + select LID_SWITCH select VBOOT_DYNAMIC_WORK_BUFFER + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config DISPLAY_SPD_DATA diff --git a/src/mainboard/google/daisy/Kconfig b/src/mainboard/google/daisy/Kconfig index d02a852..9f6a615 100644 --- a/src/mainboard/google/daisy/Kconfig +++ b/src/mainboard/google/daisy/Kconfig @@ -28,7 +28,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_DO_NATIVE_VGA_INIT
config CHROMEOS - select CHROMEOS_VBNV_EC + select VBOOT_VBNV_EC
config MAINBOARD_DIR string diff --git a/src/mainboard/google/falco/Kconfig b/src/mainboard/google/falco/Kconfig index 5afecaa..d0b911a 100644 --- a/src/mainboard/google/falco/Kconfig +++ b/src/mainboard/google/falco/Kconfig @@ -21,9 +21,9 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS - select LID_SWITCH select EC_SOFTWARE_SYNC + select LID_SWITCH + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/foster/Kconfig b/src/mainboard/google/foster/Kconfig index fa7353d..dfe79a5 100644 --- a/src/mainboard/google/foster/Kconfig +++ b/src/mainboard/google/foster/Kconfig @@ -27,7 +27,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_FLASH + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/gru/Kconfig b/src/mainboard/google/gru/Kconfig index 0b061af..1b657d9 100644 --- a/src/mainboard/google/gru/Kconfig +++ b/src/mainboard/google/gru/Kconfig @@ -39,9 +39,9 @@ config BOARD_SPECIFIC_OPTIONS select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_FLASH select EC_SOFTWARE_SYNC select SPI_TPM + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/guado/Kconfig b/src/mainboard/google/guado/Kconfig index 4ca573e..09a75b7 100644 --- a/src/mainboard/google/guado/Kconfig +++ b/src/mainboard/google/guado/Kconfig @@ -14,10 +14,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_LPC_TPM
config CHROMEOS - select CHROMEOS_VBNV_CMOS select CHROMEOS_RAMOOPS_DYNAMIC - select VIRTUAL_DEV_SWITCH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_CMOS + select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR string diff --git a/src/mainboard/google/jecht/Kconfig b/src/mainboard/google/jecht/Kconfig index 471e8fd..0c3d3db 100644 --- a/src/mainboard/google/jecht/Kconfig +++ b/src/mainboard/google/jecht/Kconfig @@ -15,9 +15,9 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS - select PHYSICAL_REC_SWITCH select CHROMEOS_RAMOOPS_DYNAMIC + select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/link/Kconfig b/src/mainboard/google/link/Kconfig index 8fe3a87..d1e1140 100644 --- a/src/mainboard/google/link/Kconfig +++ b/src/mainboard/google/link/Kconfig @@ -17,8 +17,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_NATIVE_VGA_INIT
config CHROMEOS - select CHROMEOS_VBNV_CMOS select LID_SWITCH + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/google/ninja/Kconfig b/src/mainboard/google/ninja/Kconfig index 232b75d..ce32d3d 100644 --- a/src/mainboard/google/ninja/Kconfig +++ b/src/mainboard/google/ninja/Kconfig @@ -15,6 +15,8 @@ config BOARD_SPECIFIC_OPTIONS
config CHROMEOS select EC_SOFTWARE_SYNC + select LID_SWITCH + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH select PHYSICAL_REC_SWITCH
diff --git a/src/mainboard/google/nyan/Kconfig b/src/mainboard/google/nyan/Kconfig index 21f42da..2c39a1a 100644 --- a/src/mainboard/google/nyan/Kconfig +++ b/src/mainboard/google/nyan/Kconfig @@ -32,8 +32,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B
config CHROMEOS - select CHROMEOS_VBNV_EC select EC_SOFTWARE_SYNC + select VBOOT_VBNV_EC select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/nyan/romstage.c b/src/mainboard/google/nyan/romstage.c index 2388f95..4ec0164 100644 --- a/src/mainboard/google/nyan/romstage.c +++ b/src/mainboard/google/nyan/romstage.c @@ -83,7 +83,7 @@ static void __attribute__((noinline)) romstage(void) cbmem_initialize_empty();
/* This was already called from verstage in vboot context. */ - if (!IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)) + if (!IS_ENABLED(CONFIG_VBOOT)) early_mainboard_init();
run_ramstage(); diff --git a/src/mainboard/google/nyan_big/Kconfig b/src/mainboard/google/nyan_big/Kconfig index 7af9657..c9b8aed 100644 --- a/src/mainboard/google/nyan_big/Kconfig +++ b/src/mainboard/google/nyan_big/Kconfig @@ -34,7 +34,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
config CHROMEOS select EC_SOFTWARE_SYNC - select CHROMEOS_VBNV_EC + select VBOOT_VBNV_EC select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/nyan_big/romstage.c b/src/mainboard/google/nyan_big/romstage.c index 2388f95..4ec0164 100644 --- a/src/mainboard/google/nyan_big/romstage.c +++ b/src/mainboard/google/nyan_big/romstage.c @@ -83,7 +83,7 @@ static void __attribute__((noinline)) romstage(void) cbmem_initialize_empty();
/* This was already called from verstage in vboot context. */ - if (!IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)) + if (!IS_ENABLED(CONFIG_VBOOT)) early_mainboard_init();
run_ramstage(); diff --git a/src/mainboard/google/nyan_blaze/Kconfig b/src/mainboard/google/nyan_blaze/Kconfig index 9fa99d8..3541da1 100644 --- a/src/mainboard/google/nyan_blaze/Kconfig +++ b/src/mainboard/google/nyan_blaze/Kconfig @@ -35,7 +35,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
config CHROMEOS select EC_SOFTWARE_SYNC - select CHROMEOS_VBNV_EC + select VBOOT_VBNV_EC select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/nyan_blaze/romstage.c b/src/mainboard/google/nyan_blaze/romstage.c index e91fa33..e3d7116 100644 --- a/src/mainboard/google/nyan_blaze/romstage.c +++ b/src/mainboard/google/nyan_blaze/romstage.c @@ -53,7 +53,7 @@ static void __attribute__((noinline)) romstage(void) u32 dram_end_mb = sdram_max_addressable_mb(); u32 dram_size_mb = dram_end_mb - dram_start_mb;
-#if !CONFIG_VBOOT_VERIFY_FIRMWARE +#if !CONFIG_VBOOT configure_l2_cache(); mmu_init(); /* Device memory below DRAM is uncached. */ @@ -87,7 +87,7 @@ static void __attribute__((noinline)) romstage(void) cbmem_initialize_empty();
/* This was already called from verstage in vboot context. */ - if (!IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)) + if (!IS_ENABLED(CONFIG_VBOOT)) early_mainboard_init();
run_ramstage(); @@ -96,7 +96,7 @@ static void __attribute__((noinline)) romstage(void) /* Stub to force arm_init_caches to the top, before any stack/memory accesses */ void main(void) { -#if !CONFIG_VBOOT_VERIFY_FIRMWARE +#if !CONFIG_VBOOT asm volatile ("bl arm_init_caches" ::: "r0","r1","r2","r3","r4","r5","ip"); #endif diff --git a/src/mainboard/google/oak/Kconfig b/src/mainboard/google/oak/Kconfig index 5ab6f2d..975cdab 100644 --- a/src/mainboard/google/oak/Kconfig +++ b/src/mainboard/google/oak/Kconfig @@ -34,10 +34,10 @@ config BOARD_SPECIFIC_OPTIONS select SPI_FLASH
config CHROMEOS - select CHROMEOS_VBNV_FLASH select EC_SOFTWARE_SYNC select VBOOT_EC_SLOW_UPDATE select VBOOT_OPROM_MATTERS + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/panther/Kconfig b/src/mainboard/google/panther/Kconfig index b70b6cb..0aa8927 100644 --- a/src/mainboard/google/panther/Kconfig +++ b/src/mainboard/google/panther/Kconfig @@ -19,7 +19,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
config CHROMEOS select PHYSICAL_REC_SWITCH - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/parrot/Kconfig b/src/mainboard/google/parrot/Kconfig index fa94ab6..974c58f 100644 --- a/src/mainboard/google/parrot/Kconfig +++ b/src/mainboard/google/parrot/Kconfig @@ -16,7 +16,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
# Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE diff --git a/src/mainboard/google/peach_pit/Kconfig b/src/mainboard/google/peach_pit/Kconfig index 69ac1ae..125333c 100644 --- a/src/mainboard/google/peach_pit/Kconfig +++ b/src/mainboard/google/peach_pit/Kconfig @@ -26,7 +26,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select DRIVER_PARADE_PS8625
config CHROMEOS - select CHROMEOS_VBNV_EC + select VBOOT_VBNV_EC
config MAINBOARD_DIR string diff --git a/src/mainboard/google/peppy/Kconfig b/src/mainboard/google/peppy/Kconfig index 47e715e..8829371 100644 --- a/src/mainboard/google/peppy/Kconfig +++ b/src/mainboard/google/peppy/Kconfig @@ -22,10 +22,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select MAINBOARD_DO_NATIVE_VGA_INIT - select CHROMEOS_VBNV_CMOS - select LID_SWITCH select EC_SOFTWARE_SYNC + select LID_SWITCH + select MAINBOARD_DO_NATIVE_VGA_INIT + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/purin/Kconfig b/src/mainboard/google/purin/Kconfig index aca20e3..d415211 100644 --- a/src/mainboard/google/purin/Kconfig +++ b/src/mainboard/google/purin/Kconfig @@ -29,7 +29,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_ATOMIC_SEQUENCING
config CHROMEOS - select CHROMEOS_VBNV_FLASH + select VBOOT_VBNV_FLASH
config MAINBOARD_DIR string diff --git a/src/mainboard/google/rambi/Kconfig b/src/mainboard/google/rambi/Kconfig index 3539f0e..48af3b3 100644 --- a/src/mainboard/google/rambi/Kconfig +++ b/src/mainboard/google/rambi/Kconfig @@ -13,9 +13,9 @@ config BOARD_SPECIFIC_OPTIONS select MAINBOARD_HAS_LPC_TPM
config CHROMEOS - select CHROMEOS_VBNV_CMOS - select LID_SWITCH select EC_SOFTWARE_SYNC + select LID_SWITCH + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/rikku/Kconfig b/src/mainboard/google/rikku/Kconfig index 83a99bd..a421e77 100644 --- a/src/mainboard/google/rikku/Kconfig +++ b/src/mainboard/google/rikku/Kconfig @@ -14,10 +14,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_LPC_TPM
config CHROMEOS - select CHROMEOS_VBNV_CMOS select CHROMEOS_RAMOOPS_DYNAMIC - select VIRTUAL_DEV_SWITCH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_CMOS + select VIRTUAL_DEV_SWITCH
config VBOOT_RAMSTAGE_INDEX hex diff --git a/src/mainboard/google/rush/Kconfig b/src/mainboard/google/rush/Kconfig index cb00ba7..09d9ebf 100644 --- a/src/mainboard/google/rush/Kconfig +++ b/src/mainboard/google/rush/Kconfig @@ -29,8 +29,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select BOARD_ROMSIZE_KB_4096
config CHROMEOS - select CHROMEOS_VBNV_EC select EC_SOFTWARE_SYNC + select VBOOT_VBNV_EC select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/rush_ryu/Kconfig b/src/mainboard/google/rush_ryu/Kconfig index efcb2d9..7b559a9 100644 --- a/src/mainboard/google/rush_ryu/Kconfig +++ b/src/mainboard/google/rush_ryu/Kconfig @@ -30,8 +30,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select BOARD_ROMSIZE_KB_8192
config CHROMEOS - select CHROMEOS_VBNV_EC select EC_SOFTWARE_SYNC + select VBOOT_VBNV_EC select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/rush_ryu/mainboard.c b/src/mainboard/google/rush_ryu/mainboard.c index 85034b3..b53b0ff 100644 --- a/src/mainboard/google/rush_ryu/mainboard.c +++ b/src/mainboard/google/rush_ryu/mainboard.c @@ -35,8 +35,8 @@ #include <vendorcode/google/chromeos/cros_vpd.h> #if IS_ENABLED(CONFIG_CHROMEOS) #include <vboot_struct.h> -#include <vendorcode/google/chromeos/vboot2/misc.h> -#include <vendorcode/google/chromeos/vboot_common.h> +#include <vboot/misc.h> +#include <vboot/vboot_common.h> #endif
#include "gpio.h" diff --git a/src/mainboard/google/samus/Kconfig b/src/mainboard/google/samus/Kconfig index 329fa1f..0275189 100644 --- a/src/mainboard/google/samus/Kconfig +++ b/src/mainboard/google/samus/Kconfig @@ -16,12 +16,12 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS - select LID_SWITCH + select CHROMEOS_RAMOOPS_DYNAMIC select EC_SOFTWARE_SYNC + select LID_SWITCH select VBOOT_EC_SLOW_UPDATE select VBOOT_OPROM_MATTERS - select CHROMEOS_RAMOOPS_DYNAMIC + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/smaug/Kconfig b/src/mainboard/google/smaug/Kconfig index a2d47a4..03e8bd4 100644 --- a/src/mainboard/google/smaug/Kconfig +++ b/src/mainboard/google/smaug/Kconfig @@ -33,8 +33,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select RAM_CODE_SUPPORT
config CHROMEOS - select CHROMEOS_VBNV_FLASH select EC_SOFTWARE_SYNC + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/stout/Kconfig b/src/mainboard/google/stout/Kconfig index 3a2250d..571cbce 100644 --- a/src/mainboard/google/stout/Kconfig +++ b/src/mainboard/google/stout/Kconfig @@ -18,7 +18,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SANDYBRIDGE_IVYBRIDGE_LVDS
config CHROMEOS - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/google/tidus/Kconfig b/src/mainboard/google/tidus/Kconfig index 196bd76..fd841a9 100644 --- a/src/mainboard/google/tidus/Kconfig +++ b/src/mainboard/google/tidus/Kconfig @@ -14,10 +14,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_LPC_TPM
config CHROMEOS - select CHROMEOS_VBNV_CMOS select CHROMEOS_RAMOOPS_DYNAMIC - select VIRTUAL_DEV_SWITCH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_CMOS + select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR string diff --git a/src/mainboard/google/veyron/Kconfig b/src/mainboard/google/veyron/Kconfig index 27b3fee..c21cd3f 100644 --- a/src/mainboard/google/veyron/Kconfig +++ b/src/mainboard/google/veyron/Kconfig @@ -36,8 +36,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_EC select EC_SOFTWARE_SYNC + select VBOOT_VBNV_EC select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/veyron_brain/Kconfig b/src/mainboard/google/veyron_brain/Kconfig index e16d9d5..41a7456 100644 --- a/src/mainboard/google/veyron_brain/Kconfig +++ b/src/mainboard/google/veyron_brain/Kconfig @@ -31,8 +31,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_FLASH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/veyron_danger/Kconfig b/src/mainboard/google/veyron_danger/Kconfig index 2544205..cb1dc71 100644 --- a/src/mainboard/google/veyron_danger/Kconfig +++ b/src/mainboard/google/veyron_danger/Kconfig @@ -33,8 +33,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_CHROMEOS
config CHROMEOS - select CHROMEOS_VBNV_FLASH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_FLASH
config MAINBOARD_DIR string diff --git a/src/mainboard/google/veyron_emile/Kconfig b/src/mainboard/google/veyron_emile/Kconfig index 895953c..059dd1f 100644 --- a/src/mainboard/google/veyron_emile/Kconfig +++ b/src/mainboard/google/veyron_emile/Kconfig @@ -31,8 +31,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_NATIVE_VGA_INIT
config CHROMEOS - select CHROMEOS_VBNV_FLASH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/veyron_mickey/Kconfig b/src/mainboard/google/veyron_mickey/Kconfig index 3bf59f2..6f489ff 100644 --- a/src/mainboard/google/veyron_mickey/Kconfig +++ b/src/mainboard/google/veyron_mickey/Kconfig @@ -31,8 +31,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_FLASH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/veyron_rialto/Kconfig b/src/mainboard/google/veyron_rialto/Kconfig index 7b15310..9321812 100644 --- a/src/mainboard/google/veyron_rialto/Kconfig +++ b/src/mainboard/google/veyron_rialto/Kconfig @@ -31,8 +31,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_FLASH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/google/veyron_romy/Kconfig b/src/mainboard/google/veyron_romy/Kconfig index ec15026..c151727 100644 --- a/src/mainboard/google/veyron_romy/Kconfig +++ b/src/mainboard/google/veyron_romy/Kconfig @@ -31,8 +31,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH_WINBOND
config CHROMEOS - select CHROMEOS_VBNV_FLASH select PHYSICAL_REC_SWITCH + select VBOOT_VBNV_FLASH select VIRTUAL_DEV_SWITCH
config MAINBOARD_DIR diff --git a/src/mainboard/intel/baskingridge/Kconfig b/src/mainboard/intel/baskingridge/Kconfig index 47aca1a..df5d312 100644 --- a/src/mainboard/intel/baskingridge/Kconfig +++ b/src/mainboard/intel/baskingridge/Kconfig @@ -15,7 +15,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/intel/emeraldlake2/Kconfig b/src/mainboard/intel/emeraldlake2/Kconfig index dd9a7c7..9ee41e8 100644 --- a/src/mainboard/intel/emeraldlake2/Kconfig +++ b/src/mainboard/intel/emeraldlake2/Kconfig @@ -14,7 +14,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy #select MAINBOARD_HAS_CHROMEOS
config CHROMEOS - #select CHROMEOS_VBNV_CMOS + #select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/intel/strago/Kconfig b/src/mainboard/intel/strago/Kconfig index 3faa1bf..42118f9 100644 --- a/src/mainboard/intel/strago/Kconfig +++ b/src/mainboard/intel/strago/Kconfig @@ -16,10 +16,10 @@ config BOARD_SPECIFIC_OPTIONS select PCIEXP_L1_SUB_STATE
config CHROMEOS - select LID_SWITCH - select CHROMEOS_VBNV_CMOS select EC_SOFTWARE_SYNC + select LID_SWITCH select VBOOT_DYNAMIC_WORK_BUFFER + select VBOOT_VBNV_CMOS select VIRTUAL_DEV_SWITCH
config DYNAMIC_VNN_SUPPORT diff --git a/src/mainboard/intel/wtm2/Kconfig b/src/mainboard/intel/wtm2/Kconfig index e739efa..f57cb23 100644 --- a/src/mainboard/intel/wtm2/Kconfig +++ b/src/mainboard/intel/wtm2/Kconfig @@ -15,7 +15,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
config CHROMEOS select CHROMEOS_RAMOOPS_DYNAMIC - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/samsung/lumpy/Kconfig b/src/mainboard/samsung/lumpy/Kconfig index adeb9fb..7cb00e5 100644 --- a/src/mainboard/samsung/lumpy/Kconfig +++ b/src/mainboard/samsung/lumpy/Kconfig @@ -21,7 +21,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15
config CHROMEOS - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/mainboard/samsung/stumpy/Kconfig b/src/mainboard/samsung/stumpy/Kconfig index 699e58e..3777f69 100644 --- a/src/mainboard/samsung/stumpy/Kconfig +++ b/src/mainboard/samsung/stumpy/Kconfig @@ -19,7 +19,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
config CHROMEOS select PHYSICAL_REC_SWITCH - select CHROMEOS_VBNV_CMOS + select VBOOT_VBNV_CMOS
config MAINBOARD_DIR string diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 3f14880..0745679 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -59,13 +59,13 @@ config CPU_SPECIFIC_OPTIONS
config CHROMEOS select CHROMEOS_RAMOOPS_DYNAMIC - select CHROMEOS_VBNV_CMOS - select CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH select EC_SOFTWARE_SYNC if EC_GOOGLE_CHROMEEC select SEPARATE_VERSTAGE select VBOOT_OPROM_MATTERS select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_VBNV_CMOS + select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH select VIRTUAL_DEV_SWITCH
config TPM_ON_FAST_SPI diff --git a/src/soc/intel/apollolake/lpc.c b/src/soc/intel/apollolake/lpc.c index cc4de88..5455ded 100644 --- a/src/soc/intel/apollolake/lpc.c +++ b/src/soc/intel/apollolake/lpc.c @@ -25,7 +25,7 @@ #include <soc/lpc.h> #include <soc/pci_ids.h> #include <soc/pm.h> -#include <vendorcode/google/chromeos/chromeos.h> +#include <vboot/vbnv.h>
#include "chip.h"
@@ -60,7 +60,7 @@ static void rtc_init(void) rtc_fail = !!(ps->gen_pmcon1 & RPS); /* Ensure the date is set including century byte. */ cmos_check_update_date(); - if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS)) + if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS)) init_vbnv_cmos(rtc_fail); else cmos_init(rtc_fail); diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c index e23feb2..61aa637 100644 --- a/src/soc/intel/apollolake/pmutil.c +++ b/src/soc/intel/apollolake/pmutil.c @@ -27,7 +27,7 @@ #include <soc/pm.h> #include <device/device.h> #include <device/pci.h> -#include <vendorcode/google/chromeos/vboot_common.h> +#include <vboot/vboot_common.h>
static uintptr_t read_pmc_mmio_bar(void) { diff --git a/src/soc/intel/broadwell/igd.c b/src/soc/intel/broadwell/igd.c index 599a95c..d25ddcc 100644 --- a/src/soc/intel/broadwell/igd.c +++ b/src/soc/intel/broadwell/igd.c @@ -30,7 +30,7 @@ #include <soc/ramstage.h> #include <soc/systemagent.h> #include <soc/intel/broadwell/chip.h> -#include <vendorcode/google/chromeos/chromeos.h> +#include <vboot/vbnv.h>
#define GT_RETRY 1000 #define GT_CDCLK_337 0 diff --git a/src/soc/intel/broadwell/lpc.c b/src/soc/intel/broadwell/lpc.c index 7e57b23..20fa345 100644 --- a/src/soc/intel/broadwell/lpc.c +++ b/src/soc/intel/broadwell/lpc.c @@ -44,11 +44,8 @@ #include <arch/acpi.h> #include <arch/acpigen.h> #include <cpu/cpu.h> - -#if IS_ENABLED(CONFIG_CHROMEOS) -#include <vendorcode/google/chromeos/chromeos.h> -#include <vendorcode/google/chromeos/vbnv_layout.h> -#endif +#include <vboot/vbnv.h> +#include <vboot/vbnv_layout.h>
static void pch_enable_ioapic(struct device *dev) { @@ -175,14 +172,14 @@ static void pch_power_options(device_t dev) enable_alt_smi(config->alt_gp_smi_en); }
-#if IS_ENABLED(CONFIG_CHROMEOS) && IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) +#if IS_ENABLED(CONFIG_CHROMEOS) && IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS) /* * Preserve Vboot NV data when clearing CMOS as it will * have been re-initialized already by Vboot firmware init. */ static void pch_cmos_init_preserve(int reset) { - uint8_t vbnv[VBNV_BLOCK_SIZE]; + uint8_t vbnv[VBOOT_VBNV_BLOCK_SIZE];
if (reset) read_vbnv(vbnv); @@ -207,7 +204,7 @@ static void pch_rtc_init(struct device *dev) printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed); }
-#if IS_ENABLED(CONFIG_CHROMEOS) && IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) +#if IS_ENABLED(CONFIG_CHROMEOS) && IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS) pch_cmos_init_preserve(rtc_failed); #else cmos_init(rtc_failed); diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 4c055ea..b86d002 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -53,12 +53,12 @@ config CPU_SPECIFIC_OPTIONS
config CHROMEOS select CHROMEOS_RAMOOPS_DYNAMIC - select CHROMEOS_VBNV_CMOS - select CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH select EC_SOFTWARE_SYNC if EC_GOOGLE_CHROMEEC select VBOOT_EC_SLOW_UPDATE select VBOOT_OPROM_MATTERS select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT + select VBOOT_VBNV_CMOS + select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH select VIRTUAL_DEV_SWITCH
config BOOTBLOCK_CPU_INIT diff --git a/src/soc/intel/skylake/igd.c b/src/soc/intel/skylake/igd.c index 4bb597c..209d22c 100644 --- a/src/soc/intel/skylake/igd.c +++ b/src/soc/intel/skylake/igd.c @@ -16,6 +16,7 @@
#include <arch/acpi.h> #include <arch/io.h> +#include <bootmode.h> #include <chip.h> #include <console/console.h> #include <delay.h> @@ -31,7 +32,7 @@ #include <soc/systemagent.h> #include <stdlib.h> #include <string.h> -#include <vendorcode/google/chromeos/chromeos.h> +#include <vboot/vbnv.h>
u32 map_oprom_vendev(u32 vendev) { diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c index 6b7a17b..a8ec7b6 100644 --- a/src/soc/intel/skylake/pmc.c +++ b/src/soc/intel/skylake/pmc.c @@ -35,10 +35,8 @@ #include <cpu/x86/smm.h> #include <soc/pcr.h> #include <soc/ramstage.h> -#if IS_ENABLED(CONFIG_CHROMEOS) -#include <vendorcode/google/chromeos/chromeos.h> -#include <vendorcode/google/chromeos/vbnv_layout.h> -#endif +#include <vboot/vbnv.h> +#include <vboot/vbnv_layout.h>
static const struct reg_script pch_pmc_misc_init_script[] = { /* SLP_S4=4s, SLP_S3=50ms, disable SLP_X stretching after SUS loss. */ @@ -108,14 +106,14 @@ static void pch_set_acpi_mode(void) } }
-#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) +#if IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS) /* * Preserve Vboot NV data when clearing CMOS as it will * have been re-initialized already by Vboot firmware init. */ static void pch_cmos_init_preserve(int reset) { - uint8_t vbnv[VBNV_BLOCK_SIZE]; + uint8_t vbnv[VBOOT_VBNV_BLOCK_SIZE]; if (reset) read_vbnv(vbnv);
@@ -143,7 +141,7 @@ static void pch_rtc_init(void) /* Ensure the date is set including century byte. */ cmos_check_update_date();
-#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) +#if IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS) pch_cmos_init_preserve(rtc_failed); #else cmos_init(rtc_failed); diff --git a/src/soc/intel/skylake/romstage/power_state.c b/src/soc/intel/skylake/romstage/power_state.c index 209beeb..cf75ccb 100644 --- a/src/soc/intel/skylake/romstage/power_state.c +++ b/src/soc/intel/skylake/romstage/power_state.c @@ -30,7 +30,7 @@ #include <soc/pci_devs.h> #include <soc/pm.h> #include <soc/romstage.h> -#include <vendorcode/google/chromeos/vboot_common.h> +#include <vboot/vboot_common.h>
static struct chipset_power_state power_state CAR_GLOBAL;
diff --git a/src/soc/marvell/bg4cd/Kconfig b/src/soc/marvell/bg4cd/Kconfig index 2e5b15c..cdd8597 100644 --- a/src/soc/marvell/bg4cd/Kconfig +++ b/src/soc/marvell/bg4cd/Kconfig @@ -17,7 +17,7 @@ config SOC_MARVELL_BG4CD bool default n select ARCH_BOOTBLOCK_ARMV7_M - select BOOTBLOCK_CUSTOM if VBOOT_VERIFY_FIRMWARE + select BOOTBLOCK_CUSTOM if VBOOT select ARCH_RAMSTAGE_ARMV7 select ARCH_ROMSTAGE_ARMV7 select ARCH_VERSTAGE_ARMV7_M diff --git a/src/soc/marvell/bg4cd/Makefile.inc b/src/soc/marvell/bg4cd/Makefile.inc index 717cb3b..86aa764 100644 --- a/src/soc/marvell/bg4cd/Makefile.inc +++ b/src/soc/marvell/bg4cd/Makefile.inc @@ -15,8 +15,8 @@
ifeq ($(CONFIG_SOC_MARVELL_BG4CD),y)
-bootblock-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += bootblock_asm.S -bootblock-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += bootblock.c +bootblock-$(CONFIG_VBOOT) += bootblock_asm.S +bootblock-$(CONFIG_VBOOT) += bootblock.c
bootblock-y += cbmem.c bootblock-y += i2c.c diff --git a/src/soc/qualcomm/ipq40xx/Kconfig b/src/soc/qualcomm/ipq40xx/Kconfig index 605cea2..f738622 100644 --- a/src/soc/qualcomm/ipq40xx/Kconfig +++ b/src/soc/qualcomm/ipq40xx/Kconfig @@ -14,9 +14,9 @@ config SOC_QC_IPQ40XX if SOC_QC_IPQ40XX
config CHROMEOS - select CHROMEOS_VBNV_FLASH - select SEPARATE_VERSTAGE select RETURN_FROM_VERSTAGE + select SEPARATE_VERSTAGE + select VBOOT_VBNV_FLASH
config IPQ_QFN_PART bool diff --git a/src/soc/qualcomm/ipq806x/Kconfig b/src/soc/qualcomm/ipq806x/Kconfig index aeb59ff..7ba5df5 100644 --- a/src/soc/qualcomm/ipq806x/Kconfig +++ b/src/soc/qualcomm/ipq806x/Kconfig @@ -13,7 +13,7 @@ config SOC_QC_IPQ806X if SOC_QC_IPQ806X
config CHROMEOS - select CHROMEOS_VBNV_FLASH + select VBOOT_VBNV_FLASH select SEPARATE_VERSTAGE select RETURN_FROM_VERSTAGE
diff --git a/src/vboot/Kconfig b/src/vboot/Kconfig new file mode 100644 index 0000000..6f9e3b9 --- /dev/null +++ b/src/vboot/Kconfig @@ -0,0 +1,143 @@ +## 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. +## + +config VBOOT_VBNV_OFFSET + hex + default 0x26 + depends on PC80_SYSTEM + 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 + bool "Vboot non-volatile storage in CMOS." + default n + help + VBNV is stored in CMOS + +config VBOOT_VBNV_CMOS_BACKUP_TO_FLASH + bool "Back up Vboot non-volatile storage from CMOS to flash." + default n + depends on VBOOT_VBNV_CMOS + 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 "Vboot non-volatile storage in EC." + default n + help + VBNV is stored in EC + +config VBOOT_VBNV_FLASH + def_bool n + help + VBNV is stored in flash storage + +config VBOOT_STARTS_IN_BOOTBLOCK + bool "Vboot starts verifying in bootblock" + default n + depends on VBOOT + help + Firmware verification happens during or at the end of bootblock. + +config VBOOT_STARTS_IN_ROMSTAGE + bool "Vboot starts verifying in romstage" + default n + depends on VBOOT && !VBOOT_STARTS_IN_BOOTBLOCK + help + Firmware verification happens during or at the end of romstage. + +config VBOOT_MOCK_SECDATA + bool "Mock secdata for firmware verification" + default n + depends on VBOOT + 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 "Disable dev mode on recovery requests" + default n + depends on VBOOT + 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 SEPARATE_VERSTAGE + bool "Vboot verification is built into a separate stage" + default n + depends on VBOOT + +config RETURN_FROM_VERSTAGE + bool "The separate verification stage returns to its caller" + default n + depends on 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 CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL + bool "The chipset provides the main() entry point for verstage" + default n + depends on SEPARATE_VERSTAGE + help + The chipset code provides their own main() entry point. + +config VBOOT_DYNAMIC_WORK_BUFFER + bool "Vboot's work buffer is dynamically allocated." + default y if ARCH_ROMSTAGE_X86_32 && !SEPARATE_VERSTAGE + default n + depends on VBOOT + help + This option is used when there isn't enough pre-main memory + ram to allocate the vboot work buffer. That means vboot verification + is after memory init and requires main memory to back the work + buffer. + +config VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT + bool + default n + depends on VBOOT + 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 "Video option ROM matters (= can skip display init)" + default n + depends on VBOOT + 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 + bool "Verify firmware with vboot." + default n + depends on HAVE_HARD_RESET + help + Enabling VBOOT will use vboot to verify the components of the firmware + (stages, payload, etc). + diff --git a/src/vboot/Makefile.inc b/src/vboot/Makefile.inc new file mode 100644 index 0000000..c43af72 --- /dev/null +++ b/src/vboot/Makefile.inc @@ -0,0 +1,143 @@ +## +## 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. +## + +libverstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__ +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 += recovery.c +romstage-y += recovery.c +ramstage-y += recovery.c +verstage-y += recovery.c +postcar-y += recovery.c + +bootblock-y += common.c +libverstage-y += vboot_logic.c +verstage-y += common.c +verstage-y += verstage.c +ifeq (${CONFIG_VBOOT_MOCK_SECDATA},y) +libverstage-y += secdata_mock.c +else +libverstage-y += secdata_tpm.c +endif +romstage-y += vboot_handoff.c common.c + +ramstage-y += common.c +postcar-y += common.c + +ifeq ($(CONFIG_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_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_libverstage)))) +VBOOT_CFLAGS += $(CFLAGS_libverstage) +VBOOT_CFLAGS += $(libverstage-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" + $(Q)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 + +libverstage-srcs += $(VB2_LIB) + +ifeq ($(CONFIG_SEPARATE_VERSTAGE),y) +cbfs-files-$(CONFIG_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 +ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y) +bootblock-srcs += $(objgenerated)/libverstage.a +else +romstage-srcs += $(objgenerated)/libverstage.a +endif +endif # CONFIG_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 \ + ,$(1)),COREBOOT,COREBOOT FW_MAIN_A FW_MAIN_B))) diff --git a/src/vboot/common.c b/src/vboot/common.c new file mode 100644 index 0000000..3fa9657 --- /dev/null +++ b/src/vboot/common.c @@ -0,0 +1,182 @@ +/* + * 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_DYNAMIC_WORK_BUFFER)) + /* 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_DYNAMIC_WORK_BUFFER)) + 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_DYNAMIC_WORK_BUFFER, 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_DYNAMIC_WORK_BUFFER) +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 new file mode 100644 index 0000000..dc94720 --- /dev/null +++ b/src/vboot/misc.h @@ -0,0 +1,40 @@ +/* + * 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/recovery.c b/src/vboot/recovery.c new file mode 100644 index 0000000..6e6eb0e --- /dev/null +++ b/src/vboot/recovery.c @@ -0,0 +1,152 @@ +/* + * 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 <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 0 for the stages where we know that cbmem does not come online. + * Even if this function returns 1 for romstage, depending upon the point in + * bootup, cbmem might not actually be online. + */ +static int cbmem_possibly_online(void) +{ + if (ENV_BOOTBLOCK) + return 0; + + if (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) + return 0; + + return 1; +} + +/* + * 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_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; +} diff --git a/src/vboot/secdata_mock.c b/src/vboot/secdata_mock.c new file mode 100644 index 0000000..03616c1 --- /dev/null +++ b/src/vboot/secdata_mock.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Functions for querying, manipulating and locking rollback indices + * stored in the TPM NVRAM. + */ + +#include <antirollback.h> +#include <stdlib.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; +} diff --git a/src/vboot/secdata_tpm.c b/src/vboot/secdata_tpm.c new file mode 100644 index 0000000..a51e5d6 --- /dev/null +++ b/src/vboot/secdata_tpm.c @@ -0,0 +1,436 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * 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 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, +}; + +#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) +{ + RETURN_ON_FAILURE(tlcl_define_space(KERNEL_NV_INDEX, + sizeof(secdata_kernel))); + RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX, kernel_blob, + sizeof(secdata_kernel))); + return TPM_SUCCESS; +} + +static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) +{ + RETURN_ON_FAILURE(tlcl_force_clear()); + RETURN_ON_FAILURE(set_firmware_space(ctx->secdata)); + RETURN_ON_FAILURE(set_kernel_space(secdata_kernel)); + return TPM_SUCCESS; +} + +uint32_t tpm_clear_and_reenable(void) +{ + VBDEBUG("TPM: Clear and re-enable\n"); + return TPM_SUCCESS; +} + +uint32_t antirollback_lock_space_firmware(void) +{ + return tlcl_lock_nv_write(FIRMWARE_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 _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 the backup space. No need to initialize it, though. */ + RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX, + TPM_NV_PER_PPWRITE, + VB2_NVDATA_SIZE)); + + /* 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)); + return TPM_SUCCESS; +} + +uint32_t antirollback_lock_space_firmware(void) +{ + return tlcl_set_global_lock(); +} +#endif + +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; + } + +#ifdef TEGRA_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", result); + 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()); +#endif + + /* + * 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) +{ + return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE); +} diff --git a/src/vboot/symbols.h b/src/vboot/symbols.h new file mode 100644 index 0000000..fb3d654 --- /dev/null +++ b/src/vboot/symbols.h @@ -0,0 +1,28 @@ +/* + * 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 new file mode 100644 index 0000000..ce64928 --- /dev/null +++ b/src/vboot/vbnv.c @@ -0,0 +1,142 @@ +/* + * 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); +} + +static void reset_vbnv(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]); +} + +/* + * 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)) + reset_vbnv(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; +} diff --git a/src/vboot/vbnv.h b/src/vboot/vbnv.h new file mode 100644 index 0000000..78ca8f6 --- /dev/null +++ b/src/vboot/vbnv.h @@ -0,0 +1,42 @@ +/* + * 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); +int get_recovery_mode_from_vbnv(void); +void set_recovery_mode_into_vbnv(int recovery_reason); +int vboot_wants_oprom(void); + +/* CMOS backend */ +void read_vbnv_cmos(uint8_t *vbnv_copy); +void save_vbnv_cmos(const uint8_t *vbnv_copy); +void init_vbnv_cmos(int rtc_fail); + +/* 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 new file mode 100644 index 0000000..5eda8e6 --- /dev/null +++ b/src/vboot/vbnv_cmos.c @@ -0,0 +1,79 @@ +/* + * 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> + +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); + + if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH)) { + if (verify_vbnv(vbnv_copy)) + return; + + printk(BIOS_INFO, "VBNV: CMOS invalid, restoring from flash\n"); + read_vbnv_flash(vbnv_copy); + + if (verify_vbnv(vbnv_copy)) { + save_vbnv_cmos(vbnv_copy); + printk(BIOS_INFO, "VBNV: Flash backup restored\n"); + } else { + printk(BIOS_INFO, "VBNV: Restore from flash failed\n"); + } + } +} + +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 init_vbnv_cmos(int rtc_fail) +{ + uint8_t vbnv[VBOOT_VBNV_BLOCK_SIZE]; + + if (rtc_fail) + read_vbnv_cmos(vbnv); + + cmos_init(rtc_fail); + + if (rtc_fail) + save_vbnv_cmos(vbnv); +} + +#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 new file mode 100644 index 0000000..99e2b82 --- /dev/null +++ b/src/vboot/vbnv_ec.c @@ -0,0 +1,30 @@ +/* + * 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 new file mode 100644 index 0000000..8b60be2 --- /dev/null +++ b/src/vboot/vbnv_flash.c @@ -0,0 +1,228 @@ +/* + * 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 <spi_flash.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 SPI flash */ + int blob_offset; + + /* Offset of the topmost nvdata blob in SPI flash */ + int top_offset; + + /* SPI flash handler used when saving data */ + struct spi_flash *flash; + + /* FMAP descriptor of the NVRAM area */ + struct region_device region; + + /* 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); + uint8_t buf[BLOB_SIZE]; + uint8_t empty_blob[BLOB_SIZE]; + int offset; + int i; + + if (vboot_named_region_device("RW_NVRAM", &ctx->region) || + region_device_sz(&ctx->region) < 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(); + + offset = 0; + ctx->top_offset = region_device_sz(&ctx->region) - BLOB_SIZE; + + /* + * after the loop, offset is supposed to point the blob right before + * the first empty blob, the last blob in the nvram if there is no + * empty blob, or the base of the region if the nvram has never been + * used. + */ + for (i = 0; i <= ctx->top_offset; i += BLOB_SIZE) { + if (rdev_readat(&ctx->region, buf, i, BLOB_SIZE) < 0) { + printk(BIOS_ERR, "failed to read nvdata\n"); + return 1; + } + if (!memcmp(buf, empty_blob, BLOB_SIZE)) + break; + offset = i; + } + + /* reread the nvdata and write it to the cache */ + if (rdev_readat(&ctx->region, 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 void vbnv_is_erasable(void) +{ + /* + * We check whether the region is aligned or not in advance to ensure + * we can erase the region when it's all used up. + * + * The region offset & size are determined by fmap.dts yet the check can + * be confidently done only by the spi flash driver. We use the same + * check as the one used by spi_flash_cmd_erase, which happens to be + * common to all the spi flash parts we support. + * + * TODO: Check by calling can_erase implemented by each spi flash driver + */ + struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); + + assert(!(region_device_offset(&ctx->region) % ctx->flash->sector_size)); + assert(!(region_device_sz(&ctx->region) % ctx->flash->sector_size)); +} + +static int vbnv_flash_probe(void) +{ + struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); + + if (!ctx->flash) { + ctx->flash = spi_flash_probe(CONFIG_BOOT_MEDIA_SPI_BUS, 0); + if (!ctx->flash) { + printk(BIOS_ERR, "failed to probe spi flash\n"); + return 1; + } + /* + * Called here instead of init_vbnv to reduce impact on boot + * speed. + */ + vbnv_is_erasable(); + } + + /* + * Handle the case where spi_flash_probe returns a CAR_GLOBAL + * in early execution on x86 but then later is moved to RAM. + */ + ctx->flash = car_get_var_ptr(ctx->flash); + + return 0; +} + +static int erase_nvram(void) +{ + struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); + + if (vbnv_flash_probe()) + return 1; + + if (ctx->flash->erase(ctx->flash, region_device_offset(&ctx->region), + region_device_sz(&ctx->region))) { + 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; + + 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 (!vbnv_flash_probe() && + !ctx->flash->write(ctx->flash, + region_device_offset(&ctx->region) + new_offset, + BLOB_SIZE, vbnv_copy)) { + /* 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 new file mode 100644 index 0000000..59acd0c --- /dev/null +++ b/src/vboot/vbnv_layout.h @@ -0,0 +1,47 @@ +/* + * 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 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 new file mode 100644 index 0000000..319e0de --- /dev/null +++ b/src/vboot/vboot_common.c @@ -0,0 +1,110 @@ +/* + * 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); +} + +/* ========================== 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 new file mode 100644 index 0000000..684a66b --- /dev/null +++ b/src/vboot/vboot_common.h @@ -0,0 +1,104 @@ +/* + * 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 <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); + +/* + * 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]; +} __attribute__((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() is the stage entry point + * while the verstage_main() is just the core logic. + */ +void verstage_main(void); +void verstage(void); +void verstage_mainboard_init(void); + +#endif /* __VBOOT_VBOOT_COMMON_H__ */ diff --git a/src/vboot/vboot_handoff.c b/src/vboot/vboot_handoff.c new file mode 100644 index 0000000..b0bd04c --- /dev/null +++ b/src/vboot/vboot_handoff.c @@ -0,0 +1,180 @@ +/* + * 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. + */ + +#include <arch/stages.h> +#include <assert.h> +#include <bootmode.h> +#include <stdint.h> +#include <stddef.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> +#define NEED_VB20_INTERNALS /* TODO: remove me! */ +#include <vb2_api.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 (get_sw_write_protect_state()) + vb_sd->flags |= VBSD_BOOT_FIRMWARE_SW_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_VIRTUAL_DEV_SWITCH)) + vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH; + if (IS_ENABLED(CONFIG_EC_SOFTWARE_SYNC)) + vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC; + if (!IS_ENABLED(CONFIG_PHYSICAL_REC_SWITCH)) + vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL; + if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE)) + vb_sd->flags |= VBSD_EC_SLOW_UPDATE; + 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); + + /* + * 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_DYNAMIC_WORK_BUFFER, 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_DYNAMIC_WORK_BUFFER) +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 new file mode 100644 index 0000000..7395fd7 --- /dev/null +++ b/src/vboot/vboot_loader.c @@ -0,0 +1,159 @@ +/* + * 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 <rmodule.h> +#include <rules.h> +#include <string.h> +#include <vboot/misc.h> +#include <vboot/symbols.h> +#include <vboot/vboot_common.h> + +/* 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 (ENV_VERSTAGE && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) + return 1; + + if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) { + if (ENV_ROMSTAGE && + IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) + return 1; + if (ENV_BOOTBLOCK && + IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) + return 1; + } + + return 0; +} + +static int verstage_should_load(void) +{ + if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) + return 0; + + if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) + return 1; + + if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) + return 1; + + return 0; +} + +static int vboot_executed CAR_GLOBAL; + +int vb2_logic_executed(void) +{ + /* If this stage is supposed to run the vboot logic ensure it has been + * executed. */ + if (verification_should_run() && car_get_var(vboot_executed)) + return 1; + + /* If this stage is supposed to load verstage and verstage is returning + * back to the calling stage check that it has been executed. */ + if (verstage_should_load() && IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) + if (car_get_var(vboot_executed)) + return 1; + + /* Handle all other stages post vboot execution. */ + if (!ENV_BOOTBLOCK) { + if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) + return 1; + if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) && + !ENV_ROMSTAGE) + return 1; + } + + return 0; +} + +static void vboot_prepare(void) +{ + if (verification_should_run()) { + 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_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_DYNAMIC_WORK_BUFFER 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_DYNAMIC_WORK_BUFFER)) { + 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 new file mode 100644 index 0000000..bc6ab48 --- /dev/null +++ b/src/vboot/vboot_logic.c @@ -0,0 +1,415 @@ +/* + * 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; + + 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; + + /* + * 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); + + /* Read nvdata from a non-volatile storage. */ + read_vbnv(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_VIRTUAL_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_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch()) + ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE; + + if (IS_ENABLED(CONFIG_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(); + } + + 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 new file mode 100644 index 0000000..0ec9ca6 --- /dev/null +++ b/src/vboot/verstage.c @@ -0,0 +1,44 @@ +/* + * 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 verstage(void) +{ + console_init(); + exception_init(); + verstage_mainboard_init(); + + if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) { + verstage_main(); + } else { + run_romstage(); + hlt(); + } +} + +#if !IS_ENABLED(CONFIG_CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL) +/* This is for boards that rely on main() for an entry point of a stage. */ +void main(void) __attribute__((alias ("verstage"))); +#endif diff --git a/src/vendorcode/google/Kconfig b/src/vendorcode/google/Kconfig index 74c573a..f275e6c 100644 --- a/src/vendorcode/google/Kconfig +++ b/src/vendorcode/google/Kconfig @@ -13,4 +13,3 @@ ##
source src/vendorcode/google/chromeos/Kconfig - diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig index f97a4e1..944a706 100644 --- a/src/vendorcode/google/chromeos/Kconfig +++ b/src/vendorcode/google/chromeos/Kconfig @@ -28,7 +28,7 @@ config CHROMEOS select BOOTMODE_STRAPS select ELOG if SPI_FLASH select COLLECT_TIMESTAMPS - select VBOOT_VERIFY_FIRMWARE + select VBOOT select MULTIPLE_CBFS_INSTANCES help Enable ChromeOS specific features like the GPIO sub table in @@ -37,39 +37,6 @@ config CHROMEOS
if CHROMEOS
-config VBNV_OFFSET - hex - default 0x26 - depends on PC80_SYSTEM - help - CMOS offset for VbNv data. This value must match cmos.layout - in the mainboard directory, minus 14 bytes for the RTC. - -config CHROMEOS_VBNV_CMOS - bool "Vboot non-volatile storage in CMOS." - default n - help - VBNV is stored in CMOS - -config CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH - bool "Back up Vboot non-volatile storage from CMOS to flash." - default n - depends on CHROMEOS_VBNV_CMOS - 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 CHROMEOS_VBNV_EC - bool "Vboot non-volatile storage in EC." - default n - help - VBNV is stored in EC - -config CHROMEOS_VBNV_FLASH - def_bool n - help - VBNV is stored in flash storage - config CHROMEOS_RAMOOPS bool "Reserve space for Chrome OS ramoops" default y @@ -97,7 +64,7 @@ config CHROMEOS_RAMOOPS_RAM_SIZE config EC_SOFTWARE_SYNC bool "Enable EC software sync" default n - depends on VBOOT_VERIFY_FIRMWARE + depends on VBOOT 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 @@ -111,33 +78,13 @@ config VBOOT_EC_SLOW_UPDATE 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_OPROM_MATTERS - bool "Video option ROM matters (= can skip display init)" - default n - depends on VBOOT_VERIFY_FIRMWARE - 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 VIRTUAL_DEV_SWITCH bool "Virtual developer switch support" default n - depends on VBOOT_VERIFY_FIRMWARE + depends on VBOOT help Whether this platform has a virtual developer switch.
-config VBOOT_VERIFY_FIRMWARE - bool "Verify firmware with vboot." - default n - depends on HAVE_HARD_RESET - help - Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the components - of the firmware (stages, payload, etc). - config NO_TPM_RESUME bool default n @@ -172,8 +119,6 @@ config HAVE_REGULATORY_DOMAIN help This option is needed to add ACPI regulatory domain methods
-source src/vendorcode/google/chromeos/vboot2/Kconfig - menu "GBB configuration"
config GBB_HWID diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc index 18ce13e..253c30e 100644 --- a/src/vendorcode/google/chromeos/Makefile.inc +++ b/src/vendorcode/google/chromeos/Makefile.inc @@ -18,31 +18,6 @@ verstage-y += chromeos.c romstage-y += chromeos.c ramstage-y += chromeos.c
-bootblock-y += vbnv.c -verstage-y += vbnv.c -romstage-y += vbnv.c -ramstage-y += vbnv.c - -bootblock-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c -verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c -romstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c -ramstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c - -bootblock-$(CONFIG_CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c -verstage-$(CONFIG_CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c -romstage-$(CONFIG_CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c -ramstage-$(CONFIG_CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH) += vbnv_flash.c - -bootblock-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c -verstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c -romstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c -ramstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c - -bootblock-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c -verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c -romstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c -ramstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c - ramstage-$(CONFIG_ELOG) += elog.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += gnvs.c ramstage-$(CONFIG_CHROMEOS_RAMOOPS) += ramoops.c @@ -60,8 +35,6 @@ else CFLAGS_common += -DMOCK_TPM=0 endif
-subdirs-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot2 - 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)) diff --git a/src/vendorcode/google/chromeos/acpi/chromeos.asl b/src/vendorcode/google/chromeos/acpi/chromeos.asl index 66ebbc1..7d62f4a 100644 --- a/src/vendorcode/google/chromeos/acpi/chromeos.asl +++ b/src/vendorcode/google/chromeos/acpi/chromeos.asl @@ -13,7 +13,7 @@ * GNU General Public License for more details. */
-#include <vendorcode/google/chromeos/vbnv_layout.h> +#include <vboot/vbnv_layout.h>
Device (CRHW) { @@ -71,8 +71,8 @@ Device (CRHW) Name(VNBV, Package() { // See src/vendorcode/google/chromeos/Kconfig // for the definition of these: - CONFIG_VBNV_OFFSET, - VBNV_BLOCK_SIZE + CONFIG_VBOOT_VBNV_OFFSET, + VBOOT_VBNV_BLOCK_SIZE }) Return(VNBV) } diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h index ad9ef2f..92c943c 100644 --- a/src/vendorcode/google/chromeos/chromeos.h +++ b/src/vendorcode/google/chromeos/chromeos.h @@ -20,9 +20,8 @@ #include <stdint.h> #include <bootmode.h> #include <rules.h> -#include "vbnv.h" -#include "vboot_common.h" -#include "vboot2/misc.h" +#include <vboot/misc.h> +#include <vboot/vboot_common.h>
void save_chromeos_gpios(void);
diff --git a/src/vendorcode/google/chromeos/elog.c b/src/vendorcode/google/chromeos/elog.c index 710d6f6..0d835b8 100644 --- a/src/vendorcode/google/chromeos/elog.c +++ b/src/vendorcode/google/chromeos/elog.c @@ -17,8 +17,9 @@ #include <console/console.h> #include <elog.h> #include <vendorcode/google/chromeos/chromeos.h> -#if CONFIG_VBOOT_VERIFY_FIRMWARE -#include "vboot_common.h" +#if CONFIG_VBOOT +#include <vboot/vbnv.h> +#include <vboot/vboot_common.h> #include <vboot_struct.h> #endif
@@ -29,7 +30,7 @@ void elog_add_boot_reason(void) printk(BIOS_DEBUG, "%s: Logged dev mode boot\n", __func__); } else if (recovery_mode_enabled()) { u8 reason = 0; -#if CONFIG_VBOOT_VERIFY_FIRMWARE +#if CONFIG_VBOOT struct vboot_handoff *vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
reason = get_recovery_mode_from_vbnv(); diff --git a/src/vendorcode/google/chromeos/gnvs.c b/src/vendorcode/google/chromeos/gnvs.c index 48668e8..f5ccd65 100644 --- a/src/vendorcode/google/chromeos/gnvs.c +++ b/src/vendorcode/google/chromeos/gnvs.c @@ -23,8 +23,9 @@
#include "chromeos.h" #include "gnvs.h" -#if CONFIG_VBOOT_VERIFY_FIRMWARE -#include "vboot_common.h" +#if CONFIG_VBOOT +#include <vboot/vbnv.h> +#include <vboot/vboot_common.h> #include <vboot_struct.h> #endif
@@ -38,7 +39,7 @@ void chromeos_init_vboot(chromeos_acpi_t *chromeos) /* Copy saved ME hash into NVS */ memcpy(vboot_data->mehh, me_hash_saved, sizeof(vboot_data->mehh));
-#if CONFIG_VBOOT_VERIFY_FIRMWARE +#if CONFIG_VBOOT /* Save the vdat from the vboot handoff structure. Downstream software * consumes the data located in the ACPI table. Ensure it reflects * the shared data from VbInit() and VbSelectFirmware(). */ @@ -57,7 +58,7 @@ void chromeos_init_vboot(chromeos_acpi_t *chromeos) elog_add_event(ELOG_TYPE_CROS_DEVELOPER_MODE); if (recovery_mode_enabled()) { int reason = get_recovery_mode_from_vbnv(); -#if CONFIG_VBOOT_VERIFY_FIRMWARE +#if CONFIG_VBOOT if (vboot_handoff && !reason) { VbSharedDataHeader *sd = (VbSharedDataHeader *) vboot_handoff->shared_data; diff --git a/src/vendorcode/google/chromeos/symbols.h b/src/vendorcode/google/chromeos/symbols.h index 78b28e2..d8e1ead 100644 --- a/src/vendorcode/google/chromeos/symbols.h +++ b/src/vendorcode/google/chromeos/symbols.h @@ -16,15 +16,6 @@ #ifndef __CHROMEOS_SYMBOLS_H #define __CHROMEOS_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) - extern u8 _watchdog_tombstone[]; extern u8 _ewatchdog_tombstone[]; #define _watchdog_tombstone_size (_ewatchdog_tombstone - _watchdog_tombstone) diff --git a/src/vendorcode/google/chromeos/vbnv.c b/src/vendorcode/google/chromeos/vbnv.c deleted file mode 100644 index 9fd97a0..0000000 --- a/src/vendorcode/google/chromeos/vbnv.c +++ /dev/null @@ -1,143 +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 "chromeos.h" -#include "vbnv.h" -#include "vbnv_layout.h" - -static int vbnv_initialized CAR_GLOBAL; -static uint8_t vbnv[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); -} - -static void reset_vbnv(uint8_t *vbnv_copy) -{ - memset(vbnv_copy, 0, 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]); -} - -/* - * 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_CHROMEOS_VBNV_CMOS)) - read_vbnv_cmos(vbnv_copy); - else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_EC)) - read_vbnv_ec(vbnv_copy); - else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_FLASH)) - read_vbnv_flash(vbnv_copy); - - /* Check data for consistency */ - if (!verify_vbnv(vbnv_copy)) - reset_vbnv(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_CHROMEOS_VBNV_CMOS)) - save_vbnv_cmos(vbnv_copy); - else if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_EC)) - save_vbnv_ec(vbnv_copy); - else if (IS_ENABLED(CONFIG_CHROMEOS_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[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; -} diff --git a/src/vendorcode/google/chromeos/vbnv.h b/src/vendorcode/google/chromeos/vbnv.h deleted file mode 100644 index 5d21cc8..0000000 --- a/src/vendorcode/google/chromeos/vbnv.h +++ /dev/null @@ -1,42 +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 __CHROMEOS_VBNV_H__ -#define __CHROMEOS_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); -int get_recovery_mode_from_vbnv(void); -void set_recovery_mode_into_vbnv(int recovery_reason); -int vboot_wants_oprom(void); - -/* CMOS backend */ -void read_vbnv_cmos(uint8_t *vbnv_copy); -void save_vbnv_cmos(const uint8_t *vbnv_copy); -void init_vbnv_cmos(int rtc_fail); - -/* 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 diff --git a/src/vendorcode/google/chromeos/vbnv_cmos.c b/src/vendorcode/google/chromeos/vbnv_cmos.c deleted file mode 100644 index da0d300..0000000 --- a/src/vendorcode/google/chromeos/vbnv_cmos.c +++ /dev/null @@ -1,79 +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 "vbnv.h" -#include "vbnv_layout.h" - -void read_vbnv_cmos(uint8_t *vbnv_copy) -{ - int i; - - for (i = 0; i < VBNV_BLOCK_SIZE; i++) - vbnv_copy[i] = cmos_read(CONFIG_VBNV_OFFSET + 14 + i); - - if (IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH)) { - if (verify_vbnv(vbnv_copy)) - return; - - printk(BIOS_INFO, "VBNV: CMOS invalid, restoring from flash\n"); - read_vbnv_flash(vbnv_copy); - - if (verify_vbnv(vbnv_copy)) { - save_vbnv_cmos(vbnv_copy); - printk(BIOS_INFO, "VBNV: Flash backup restored\n"); - } else { - printk(BIOS_INFO, "VBNV: Restore from flash failed\n"); - } - } -} - -void save_vbnv_cmos(const uint8_t *vbnv_copy) -{ - int i; - - for (i = 0; i < VBNV_BLOCK_SIZE; i++) - cmos_write(vbnv_copy[i], CONFIG_VBNV_OFFSET + 14 + i); -} - -void init_vbnv_cmos(int rtc_fail) -{ - uint8_t vbnv[VBNV_BLOCK_SIZE]; - - if (rtc_fail) - read_vbnv_cmos(vbnv); - - cmos_init(rtc_fail); - - if (rtc_fail) - save_vbnv_cmos(vbnv); -} - -#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS_BACKUP_TO_FLASH) -static void back_up_vbnv_cmos(void *unused) -{ - uint8_t vbnv_cmos[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/vendorcode/google/chromeos/vbnv_ec.c b/src/vendorcode/google/chromeos/vbnv_ec.c deleted file mode 100644 index 0b7b7b5..0000000 --- a/src/vendorcode/google/chromeos/vbnv_ec.c +++ /dev/null @@ -1,29 +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 "vbnv.h" -#include "vbnv_layout.h" - -void read_vbnv_ec(uint8_t *vbnv_copy) -{ - google_chromeec_vbnv_context(1, vbnv_copy, VBNV_BLOCK_SIZE); -} - -void save_vbnv_ec(const uint8_t *vbnv_copy) -{ - google_chromeec_vbnv_context(0, (uint8_t *)vbnv_copy, VBNV_BLOCK_SIZE); -} diff --git a/src/vendorcode/google/chromeos/vbnv_flash.c b/src/vendorcode/google/chromeos/vbnv_flash.c deleted file mode 100644 index 88f39b0..0000000 --- a/src/vendorcode/google/chromeos/vbnv_flash.c +++ /dev/null @@ -1,227 +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 <console/console.h> -#include <spi_flash.h> -#include <string.h> -#include <vb2_api.h> -#include <vboot_nvstorage.h> -#include "chromeos.h" -#include "vbnv.h" -#include "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 SPI flash */ - int blob_offset; - - /* Offset of the topmost nvdata blob in SPI flash */ - int top_offset; - - /* SPI flash handler used when saving data */ - struct spi_flash *flash; - - /* FMAP descriptor of the NVRAM area */ - struct region_device region; - - /* 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); - uint8_t buf[BLOB_SIZE]; - uint8_t empty_blob[BLOB_SIZE]; - int offset; - int i; - - if (vboot_named_region_device("RW_NVRAM", &ctx->region) || - region_device_sz(&ctx->region) < 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(); - - offset = 0; - ctx->top_offset = region_device_sz(&ctx->region) - BLOB_SIZE; - - /* - * after the loop, offset is supposed to point the blob right before - * the first empty blob, the last blob in the nvram if there is no - * empty blob, or the base of the region if the nvram has never been - * used. - */ - for (i = 0; i <= ctx->top_offset; i += BLOB_SIZE) { - if (rdev_readat(&ctx->region, buf, i, BLOB_SIZE) < 0) { - printk(BIOS_ERR, "failed to read nvdata\n"); - return 1; - } - if (!memcmp(buf, empty_blob, BLOB_SIZE)) - break; - offset = i; - } - - /* reread the nvdata and write it to the cache */ - if (rdev_readat(&ctx->region, 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 void vbnv_is_erasable(void) -{ - /* - * We check whether the region is aligned or not in advance to ensure - * we can erase the region when it's all used up. - * - * The region offset & size are determined by fmap.dts yet the check can - * be confidently done only by the spi flash driver. We use the same - * check as the one used by spi_flash_cmd_erase, which happens to be - * common to all the spi flash parts we support. - * - * TODO: Check by calling can_erase implemented by each spi flash driver - */ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - - assert(!(region_device_offset(&ctx->region) % ctx->flash->sector_size)); - assert(!(region_device_sz(&ctx->region) % ctx->flash->sector_size)); -} - -static int vbnv_flash_probe(void) -{ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - - if (!ctx->flash) { - ctx->flash = spi_flash_probe(CONFIG_BOOT_MEDIA_SPI_BUS, 0); - if (!ctx->flash) { - printk(BIOS_ERR, "failed to probe spi flash\n"); - return 1; - } - /* - * Called here instead of init_vbnv to reduce impact on boot - * speed. - */ - vbnv_is_erasable(); - } - - /* - * Handle the case where spi_flash_probe returns a CAR_GLOBAL - * in early execution on x86 but then later is moved to RAM. - */ - ctx->flash = car_get_var_ptr(ctx->flash); - - return 0; -} - -static int erase_nvram(void) -{ - struct vbnv_flash_ctx *ctx = car_get_var_ptr(&vbnv_flash); - - if (vbnv_flash_probe()) - return 1; - - if (ctx->flash->erase(ctx->flash, region_device_offset(&ctx->region), - region_device_sz(&ctx->region))) { - 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; - - 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 (!vbnv_flash_probe() && - !ctx->flash->write(ctx->flash, - region_device_offset(&ctx->region) + new_offset, - BLOB_SIZE, vbnv_copy)) { - /* 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/vendorcode/google/chromeos/vbnv_layout.h b/src/vendorcode/google/chromeos/vbnv_layout.h deleted file mode 100644 index d7e7845..0000000 --- a/src/vendorcode/google/chromeos/vbnv_layout.h +++ /dev/null @@ -1,47 +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 VBNV_LAYOUT_H -#define VBNV_LAYOUT_H - -#define 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 KERNEL_FIELD_OFFSET 11 -#define CRC_OFFSET 15 - -#endif /* VBNV_LAYOUT_H */ diff --git a/src/vendorcode/google/chromeos/vboot2/Kconfig b/src/vendorcode/google/chromeos/vboot2/Kconfig deleted file mode 100644 index 5aaf932..0000000 --- a/src/vendorcode/google/chromeos/vboot2/Kconfig +++ /dev/null @@ -1,89 +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. -## - -config VBOOT_STARTS_IN_BOOTBLOCK - bool "Vboot starts verifying in bootblock" - default n - depends on VBOOT_VERIFY_FIRMWARE - help - Firmware verification happens during or at the end of bootblock. - -config VBOOT_STARTS_IN_ROMSTAGE - bool "Vboot starts verifying in romstage" - default n - depends on VBOOT_VERIFY_FIRMWARE && !VBOOT_STARTS_IN_BOOTBLOCK - help - Firmware verification happens during or at the end of romstage. - -config VBOOT2_MOCK_SECDATA - bool "Mock secdata for firmware verification" - default n - depends on VBOOT_VERIFY_FIRMWARE - help - Enabling VBOOT2_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 "Disable dev mode on recovery requests" - default n - depends on VBOOT_VERIFY_FIRMWARE - 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 SEPARATE_VERSTAGE - bool "Vboot verification is built into a separate stage" - default n - depends on VBOOT_VERIFY_FIRMWARE - -config RETURN_FROM_VERSTAGE - bool "The separate verification stage returns to its caller" - default n - depends on 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 CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL - bool "The chipset provides the main() entry point for verstage" - default n - depends on SEPARATE_VERSTAGE - help - The chipset code provides their own main() entry point. - -config VBOOT_DYNAMIC_WORK_BUFFER - bool "Vboot's work buffer is dynamically allocated." - default y if ARCH_ROMSTAGE_X86_32 && !SEPARATE_VERSTAGE - default n - depends on VBOOT_VERIFY_FIRMWARE - help - This option is used when there isn't enough pre-main memory - ram to allocate the vboot work buffer. That means vboot verification - is after memory init and requires main memory to back the work - buffer. - -config VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT - bool - default n - depends on VBOOT_VERIFY_FIRMWARE - 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. diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc deleted file mode 100644 index bf13fd6..0000000 --- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc +++ /dev/null @@ -1,118 +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. -## - -libverstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__ -verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__ - -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 += recovery.c -romstage-y += recovery.c -ramstage-y += recovery.c -verstage-y += recovery.c -postcar-y += recovery.c - -bootblock-y += common.c -libverstage-y += vboot_logic.c -verstage-y += common.c -verstage-y += verstage.c -ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y) -libverstage-y += secdata_mock.c -else -libverstage-y += antirollback.c -endif -romstage-y += vboot_handoff.c common.c - -ramstage-y += common.c -postcar-y += common.c - -ifeq ($(CONFIG_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_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_libverstage)))) -VBOOT_CFLAGS += $(CFLAGS_libverstage) -VBOOT_CFLAGS += $(libverstage-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" - $(Q)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 - -libverstage-srcs += $(VB2_LIB) - -ifeq ($(CONFIG_SEPARATE_VERSTAGE),y) -cbfs-files-$(CONFIG_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 -ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y) -bootblock-srcs += $(objgenerated)/libverstage.a -else -romstage-srcs += $(objgenerated)/libverstage.a -endif -endif # CONFIG_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 \ - ,$(1)),COREBOOT,COREBOOT FW_MAIN_A FW_MAIN_B))) diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c deleted file mode 100644 index a51e5d6..0000000 --- a/src/vendorcode/google/chromeos/vboot2/antirollback.c +++ /dev/null @@ -1,436 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * 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 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, -}; - -#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) -{ - RETURN_ON_FAILURE(tlcl_define_space(KERNEL_NV_INDEX, - sizeof(secdata_kernel))); - RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX, kernel_blob, - sizeof(secdata_kernel))); - return TPM_SUCCESS; -} - -static uint32_t _factory_initialize_tpm(struct vb2_context *ctx) -{ - RETURN_ON_FAILURE(tlcl_force_clear()); - RETURN_ON_FAILURE(set_firmware_space(ctx->secdata)); - RETURN_ON_FAILURE(set_kernel_space(secdata_kernel)); - return TPM_SUCCESS; -} - -uint32_t tpm_clear_and_reenable(void) -{ - VBDEBUG("TPM: Clear and re-enable\n"); - return TPM_SUCCESS; -} - -uint32_t antirollback_lock_space_firmware(void) -{ - return tlcl_lock_nv_write(FIRMWARE_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 _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 the backup space. No need to initialize it, though. */ - RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX, - TPM_NV_PER_PPWRITE, - VB2_NVDATA_SIZE)); - - /* 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)); - return TPM_SUCCESS; -} - -uint32_t antirollback_lock_space_firmware(void) -{ - return tlcl_set_global_lock(); -} -#endif - -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; - } - -#ifdef TEGRA_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", result); - 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()); -#endif - - /* - * 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) -{ - return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE); -} diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c deleted file mode 100644 index 58ea95d..0000000 --- a/src/vendorcode/google/chromeos/vboot2/common.c +++ /dev/null @@ -1,183 +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 "../chromeos.h" -#include "../symbols.h" -#include "../vboot_common.h" -#include "misc.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_DYNAMIC_WORK_BUFFER)) - /* 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_DYNAMIC_WORK_BUFFER)) - 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_DYNAMIC_WORK_BUFFER, 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_DYNAMIC_WORK_BUFFER) -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/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h deleted file mode 100644 index 9b771a2..0000000 --- a/src/vendorcode/google/chromeos/vboot2/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 __CHROMEOS_VBOOT2_MISC_H__ -#define __CHROMEOS_VBOOT2_MISC_H__ - -#include "../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 /* __CHROMEOS_VBOOT2_MISC_H__ */ diff --git a/src/vendorcode/google/chromeos/vboot2/recovery.c b/src/vendorcode/google/chromeos/vboot2/recovery.c deleted file mode 100644 index 94a8cc3..0000000 --- a/src/vendorcode/google/chromeos/vboot2/recovery.c +++ /dev/null @@ -1,154 +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 <bootstate.h> -#include <rules.h> -#include <string.h> -#include <vb2_api.h> - -#include "misc.h" -#include "../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 0 for the stages where we know that cbmem does not come online. - * Even if this function returns 1 for romstage, depending upon the point in - * bootup, cbmem might not actually be online. - */ -static int cbmem_possibly_online(void) -{ - if (ENV_BOOTBLOCK) - return 0; - - if (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) - return 0; - - return 1; -} - -/* - * 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_VERIFY_FIRMWARE)) - return 0; - - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) { - if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_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; -} diff --git a/src/vendorcode/google/chromeos/vboot2/secdata_mock.c b/src/vendorcode/google/chromeos/vboot2/secdata_mock.c deleted file mode 100644 index 03616c1..0000000 --- a/src/vendorcode/google/chromeos/vboot2/secdata_mock.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Functions for querying, manipulating and locking rollback indices - * stored in the TPM NVRAM. - */ - -#include <antirollback.h> -#include <stdlib.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; -} diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c deleted file mode 100644 index 0e2cb84..0000000 --- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c +++ /dev/null @@ -1,179 +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. - */ - -#include <arch/stages.h> -#include <assert.h> -#include <stdint.h> -#include <stddef.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> -#define NEED_VB20_INTERNALS /* TODO: remove me! */ -#include <vb2_api.h> -#include <vboot_struct.h> -#include "../chromeos.h" -#include "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 (get_sw_write_protect_state()) - vb_sd->flags |= VBSD_BOOT_FIRMWARE_SW_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_VIRTUAL_DEV_SWITCH)) - vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH; - if (IS_ENABLED(CONFIG_EC_SOFTWARE_SYNC)) - vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC; - if (!IS_ENABLED(CONFIG_PHYSICAL_REC_SWITCH)) - vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL; - if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE)) - vb_sd->flags |= VBSD_EC_SLOW_UPDATE; - 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); - - /* - * 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_DYNAMIC_WORK_BUFFER, 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_DYNAMIC_WORK_BUFFER) -static void vb2_fill_handoff_cbmem(int unused) -{ - vboot_fill_handoff(); -} -ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem) -#endif diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c deleted file mode 100644 index b76d20b..0000000 --- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c +++ /dev/null @@ -1,159 +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 <rmodule.h> -#include <rules.h> -#include <string.h> -#include "misc.h" -#include "../vboot_common.h" -#include "../symbols.h" - -/* 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 (ENV_VERSTAGE && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) - return 1; - - if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) { - if (ENV_ROMSTAGE && - IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) - return 1; - if (ENV_BOOTBLOCK && - IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) - return 1; - } - - return 0; -} - -static int verstage_should_load(void) -{ - if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) - return 0; - - if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) - return 1; - - if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) - return 1; - - return 0; -} - -static int vboot_executed CAR_GLOBAL; - -int vb2_logic_executed(void) -{ - /* If this stage is supposed to run the vboot logic ensure it has been - * executed. */ - if (verification_should_run() && car_get_var(vboot_executed)) - return 1; - - /* If this stage is supposed to load verstage and verstage is returning - * back to the calling stage check that it has been executed. */ - if (verstage_should_load() && IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) - if (car_get_var(vboot_executed)) - return 1; - - /* Handle all other stages post vboot execution. */ - if (!ENV_BOOTBLOCK) { - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) - return 1; - if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) && - !ENV_ROMSTAGE) - return 1; - } - - return 0; -} - -static void vboot_prepare(void) -{ - if (verification_should_run()) { - 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_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_DYNAMIC_WORK_BUFFER 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_DYNAMIC_WORK_BUFFER)) { - 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/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c deleted file mode 100644 index 4c799c9..0000000 --- a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c +++ /dev/null @@ -1,415 +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 <console/console.h> -#include <console/vtxprintf.h> -#include <delay.h> -#include <string.h> -#include <timestamp.h> -#include <vb2_api.h> - -#include "../chromeos.h" -#include "misc.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; - - 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; - - /* - * 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); - - /* Read nvdata from a non-volatile storage. */ - read_vbnv(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_VIRTUAL_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_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch()) - ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE; - - if (IS_ENABLED(CONFIG_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(); - } - - 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/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c deleted file mode 100644 index 99bc28d..0000000 --- a/src/vendorcode/google/chromeos/vboot2/verstage.c +++ /dev/null @@ -1,44 +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_common.h" - -void __attribute__((weak)) verstage_mainboard_init(void) -{ - /* Default empty implementation. */ -} - -void verstage(void) -{ - console_init(); - exception_init(); - verstage_mainboard_init(); - - if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) { - verstage_main(); - } else { - run_romstage(); - hlt(); - } -} - -#if !IS_ENABLED(CONFIG_CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL) -/* This is for boards that rely on main() for an entry point of a stage. */ -void main(void) __attribute__((alias ("verstage"))); -#endif diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c deleted file mode 100644 index 66800ed..0000000 --- a/src/vendorcode/google/chromeos/vboot_common.c +++ /dev/null @@ -1,112 +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 "chromeos.h" -#include "vboot_common.h" - -int vboot_named_region_device(const char *name, struct region_device *rdev) -{ - return fmap_locate_area_as_rdev(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/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h deleted file mode 100644 index 266ce4f..0000000 --- a/src/vendorcode/google/chromeos/vboot_common.h +++ /dev/null @@ -1,106 +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_COMMON_H -#define VBOOT_COMMON_H - -#include <commonlib/region.h> -#include <stdint.h> -#include <vboot_api.h> -#include <vboot_struct.h> - -#include "chromeos.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); - -/* - * 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]; -} __attribute__((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() is the stage entry point - * while the verstage_main() is just the core logic. - */ -void verstage_main(void); -void verstage(void); -void verstage_mainboard_init(void); - -#endif /* VBOOT_COMMON_H */