diff --git a/Makefile b/Makefile index e556a7e64..d70fe6c4a 100644 --- a/Makefile +++ b/Makefile @@ -231,7 +231,8 @@ $(LSCRIPT): $(LSCRIPT_IN) FORCE sed -e "s/@WOLFBOOT_STAGE1_FLASH_ADDR@/$(WOLFBOOT_STAGE1_FLASH_ADDR)/g" | \ sed -e "s/@WOLFBOOT_STAGE1_BASE_ADDR@/$(WOLFBOOT_STAGE1_BASE_ADDR)/g" | \ sed -e "s/@WOLFBOOT_LOAD_BASE@/$(WOLFBOOT_LOAD_BASE)/g" | \ - sed -e "s/@BOOTLOADER_START@/$(BOOTLOADER_START)/g" \ + sed -e "s/@BOOTLOADER_START@/$(BOOTLOADER_START)/g" | \ + sed -e "s/@IMAGE_HEADER_SIZE@/$(IMAGE_HEADER_SIZE)/g" \ > $@ hex: wolfboot.hex diff --git a/arch.mk b/arch.mk index c75d8bad0..917d79214 100644 --- a/arch.mk +++ b/arch.mk @@ -489,7 +489,9 @@ ifeq ("${FSP}", "1") --defsym wb_start_bss=`grep _start_bss ../wolfboot.map | awk '{print $$1}'` \ --defsym wb_end_bss=`grep _end_bss ../wolfboot.map | awk '{print $$1}'` \ --defsym _stage2_params=`grep _stage2_params ../wolfboot.map | awk '{print $$1}'` - LDFLAGS += --no-gc-sections --print-gc-sections -T $(LSCRIPT) -m elf_i386 -Map=loader.map + LDFLAGS += --no-gc-sections --print-gc-sections -T $(LSCRIPT) -m elf_i386 -Map=loader_stage1.map + CFLAGS+=-DFSP_M_LOAD_BASE=$(FSP_M_LOAD_BASE) + CFLAGS+=-DFSP_S_LOAD_BASE=$(FSP_S_LOAD_BASE) OBJS += src/boot_x86_fsp.o OBJS += src/boot_x86_fsp_start.o OBJS += src/fsp_m.o @@ -501,12 +503,24 @@ ifeq ("${FSP}", "1") OBJS += src/pci.o OBJS += hal/x86_uart.o OBJS += src/string.o + ifeq ($(filter-out $(STAGE1_AUTH),1),) + OBJS += src/libwolfboot.o + OBJS += src/image.o + OBJS += src/keystore.o + OBJS += src/sig_wolfboot_raw.o + OBJS += src/sig_fsp_s.o + ifeq ($(TARGET), kontron_vx3060_s2) + OBJS += hal/kontron_vx3060_s2_loader.o + endif + OBJS += $(WOLFCRYPT_OBJS) + CFLAGS+=-DSTAGE1_AUTH + endif + CFLAGS += -fno-stack-protector -m32 -fno-PIC -fno-pie -mno-mmx -mno-sse -DDEBUG_UART ifeq ($(FSP_TGL), 1) OBJS+=src/x86/tgl_fsp.o OBJS+=src/fsp_tgl_s_upd.o OBJS+=src/ucode0.o - OBJS+=$(MATH_OBJS) CFLAGS += -DUCODE0_ADDRESS=$(UCODE0_BASE) endif ifeq ($(TARGET),x86_fsp_qemu) diff --git a/config/examples/kontron_vx3060_s2.config b/config/examples/kontron_vx3060_s2.config index d86e93527..40fdfdfd4 100644 --- a/config/examples/kontron_vx3060_s2.config +++ b/config/examples/kontron_vx3060_s2.config @@ -21,11 +21,11 @@ WOLFBOOT_LOAD_ADDRESS=0x1000000 WOLFBOOT_SECTOR_SIZE?=0x1000 WOLFBOOT_DATA_ADDRESS=0x1000000 -FSP_M_BASE=0xffe37000 +FSP_M_BASE=0xffc33000 FSP_S_BASE=0xffed6000 FSP_T_BASE=0xfffe0000 -WOLFBOOT_ORIGIN=0xffff0000 +WOLFBOOT_ORIGIN=0xfffa0000 # 4 MB BOOTLOADER_PARTITION_SIZE=0x400000 # 12 MB @@ -57,3 +57,7 @@ ELF=1 DEBUG_ELF=0 MULTIBOOT2=1 64BIT=1 + +STAGE1_AUTH=1 +FSP_S_LOAD_BASE=0x0FED5F00 + diff --git a/config/examples/x86_fsp_qemu.config b/config/examples/x86_fsp_qemu.config index 1833b423e..48b64c3b8 100644 --- a/config/examples/x86_fsp_qemu.config +++ b/config/examples/x86_fsp_qemu.config @@ -30,7 +30,7 @@ WOLFBOOT_DATA_ADDRESS=0x1000000 FSP_M_BASE=0xffe30000 FSP_S_BASE=0xffed6000 FSP_T_BASE=0xfffe0000 -WOLFBOOT_ORIGIN=0xffff0000 +WOLFBOOT_ORIGIN=0xfffa0000 LINUX_PAYLOAD=1 BOOTLOADER_PARTITION_SIZE=0xa0000 @@ -39,3 +39,4 @@ MACHINE_OBJ=src/x86/qemu_fsp.o FSP_T_BIN=./src/x86/fsp_t.bin FSP_M_BIN=./src/x86/fsp_m.bin FSP_S_BIN=./src/x86/fsp_s.bin +STAGE1_AUTH=1 diff --git a/config/examples/x86_fsp_qemu_stage1_auth.config b/config/examples/x86_fsp_qemu_stage1_auth.config new file mode 100644 index 000000000..18aab291f --- /dev/null +++ b/config/examples/x86_fsp_qemu_stage1_auth.config @@ -0,0 +1,43 @@ +ARCH=x86_64 +TARGET=x86_fsp_qemu +WOLFBOOT_SMALL_STACK=1 +SIGN?=ECC256 +HASH?=SHA256 +DEBUG=1 +SPMATH=1 +FORCE_32BIT=1 +ENCRYPTION=0 +WOLFBOOT_FIXED_PARTITIONS=1 +WOLFBOOT_PARTITION_SIZE=0x8000000 +WOLFTPM=0 + +# TPM Keystore options +#WOLFBOOT_TPM_KEYSTORE?=1 +#WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=0x01800200 +#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201 + +# 4gb - 8mb +WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff800000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0 +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0 +WOLFBOOT_LOAD_BASE=0x2000000 +WOLFBOOT_LOAD_ADDRESS=0x1000000 + +# required for keytools +WOLFBOOT_SECTOR_SIZE?=0x1000 +WOLFBOOT_DATA_ADDRESS=0x1000000 + +FSP_M_BASE=0xffe30000 +FSP_S_BASE=0xffed6000 +FSP_T_BASE=0xfffe0000 +FSP_S_LOAD_BASE=0x0FED5F00 +WOLFBOOT_ORIGIN=0xfffa0000 +LINUX_PAYLOAD=1 + +BOOTLOADER_PARTITION_SIZE=0xa0000 +BIOS_REGION_SIZE=0x800000 +MACHINE_OBJ=src/x86/qemu_fsp.o +FSP_T_BIN=./src/x86/fsp_t.bin +FSP_M_BIN=./src/x86/fsp_m.bin +FSP_S_BIN=./src/x86/fsp_s.bin +STAGE1_AUTH=1 diff --git a/hal/kontron_vx3060_s2_loader.c b/hal/kontron_vx3060_s2_loader.c new file mode 100644 index 000000000..a5f0f8588 --- /dev/null +++ b/hal/kontron_vx3060_s2_loader.c @@ -0,0 +1,95 @@ +/* kontron_vx3060_s2_loader.c + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot 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; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include +#include +#include + +#ifdef __WOLFBOOT +#include + +extern uint8_t* _stage2_params[]; + +static void panic(void); + +void hal_init(void) +{ +} + +void hal_prepare_boot(void) +{ +} +#endif + +int hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + return 0; +} + +void hal_flash_unlock(void) +{ +} + +void hal_flash_lock(void) +{ +} + +int hal_flash_erase(uint32_t address, int len) +{ + return 0; +} + +int wolfBoot_fallback_is_possible(void) +{ + return 0; + +} + +int wolfBoot_dualboot_candidate(void) +{ + return PART_BOOT; +} + +void* hal_get_primary_address(void) +{ + return (void*)0; +} + +void* hal_get_update_address(void) +{ + return (void*)0; +} + +void *hal_get_dts_address(void) +{ + return 0; +} + +void *hal_get_dts_update_address(void) +{ + return 0; +} + +static void panic(void) +{ + while(1) {} +} diff --git a/hal/x86_fsp_qemu_stage1.ld.in b/hal/x86_fsp_qemu_stage1.ld.in index 1b73ba728..c65268d3e 100644 --- a/hal/x86_fsp_qemu_stage1.ld.in +++ b/hal/x86_fsp_qemu_stage1.ld.in @@ -1,10 +1,10 @@ FLASH_SIZE = @BOOTLOADER_PARTITION_SIZE@; FLASH_START = 0x100000000 - @BOOTLOADER_PARTITION_SIZE@; +BOOTLOADER_JUMP32_START = 0xfffff000; RESETVECTOR_START = 0xffffffec; -FSP_T_BASE = @FSP_T_BASE@; /* default base:size 0xFFFFF000:0x3000 [0xfffff000:0x100002000] */ -FSP_M_BASE = @FSP_M_BASE@; /* default base:size 0xfffdd000:0x22000 [0xfffdd000:0xfffff000] */ -FSP_S_BASE = @FSP_S_BASE@; /* default base:size 0xfffc8000:0x15000 [0xfffdd000:0xfffdd000] */ -WOLFBOOT_LOAD_BASE = @WOLFBOOT_LOAD_BASE@; +FSP_T_ORIGIN = @FSP_T_BASE@; /* default base:size 0xFFFFF000:0x3000 [0xfffff000:0x100002000] */ +FSP_M_ORIGIN = @FSP_M_BASE@; /* default base:size 0xfffdd000:0x22000 [0xfffdd000:0xfffff000] */ +FSP_S_ORIGIN = @FSP_S_BASE@; /* default base:size 0xfffc8000:0x15000 [0xfffdd000:0xfffdd000] */ WOLFBOOT_ORIGIN = @WOLFBOOT_ORIGIN@; OUTPUT_FORMAT(elf32-i386) @@ -16,6 +16,11 @@ MEMORY SECTIONS { + .jmpto32 BOOTLOADER_JUMP32_START : + { + _off_boot = ABSOLUTE(.) & 0xffff; + KEEP(*(.jmpto32)) + } .reset_vector RESETVECTOR_START : { KEEP(*(.reset_vector)) @@ -23,39 +28,43 @@ SECTIONS .bootloader WOLFBOOT_ORIGIN : { - _off_boot = ABSOLUTE(.) & 0xffff; KEEP(*(.boot*)) *(.text*) *(.rodata*) *(.eh_frame*) *(.data*) - . = ALIGN(4); + . = ALIGN(256); } .wolfboot FLASH_START : { _wolfboot_flash_start = .; + KEEP(*(.sig_wolfboot_raw*)) *(.wolfboot) _wolfboot_flash_end = .; } - .fsp_t FSP_T_BASE : - AT(FSP_T_BASE) + .fsp_t FSP_T_ORIGIN : + AT(FSP_T_ORIGIN) { _start_fsp_t = .; *(.fsp_t) } - .fsp_s FSP_S_BASE : + .fsp_s FSP_S_ORIGIN : { + _fsp_s_hdr = .; + KEEP(*(.sig_fsp_s*)) _start_fsp_s = .; *(.fsp_s) + _end_fsp_s = .; } - .fsp_m FSP_M_BASE : + .fsp_m FSP_M_ORIGIN : { _start_fsp_m = .; *(.fsp_m) + _end_fsp_m = .; } } diff --git a/hal/x86_fsp_tgl.c b/hal/x86_fsp_tgl.c index 1be61effb..b79d0973e 100644 --- a/hal/x86_fsp_tgl.c +++ b/hal/x86_fsp_tgl.c @@ -47,3 +47,4 @@ void x86_fsp_tgl_init_sata(void) } #endif + diff --git a/hal/x86_fsp_tgl_stage1.ld.in b/hal/x86_fsp_tgl_stage1.ld.in index c11ebe421..67d2f47ce 100644 --- a/hal/x86_fsp_tgl_stage1.ld.in +++ b/hal/x86_fsp_tgl_stage1.ld.in @@ -1,15 +1,14 @@ FLASH_SIZE = @BOOTLOADER_PARTITION_SIZE@; FLASH_START = 0x100000000 - @BOOTLOADER_PARTITION_SIZE@; +BOOTLOADER_JUMP32_START = 0xfffff000; RESETVECTOR_START = 0xffffffec; -FSP_T_BASE = @FSP_T_BASE@; /* default base:size 0xFFFFF000:0x3000 [0xfffff000:0x100002000] */ -FSP_M_BASE = @FSP_M_BASE@; /* default base:size 0xfffdd000:0x22000 [0xfffdd000:0xfffff000] */ -FSP_S_BASE = @FSP_S_BASE@; /* default base:size 0xfffc8000:0x15000 [0xfffdd000:0xfffdd000] */ -WOLFBOOT_LOAD_BASE = @WOLFBOOT_LOAD_BASE@; +FSP_T_ORIGIN = @FSP_T_BASE@; /* default base:size 0xFFFFF000:0x3000 [0xfffff000:0x100002000] */ +FSP_M_ORIGIN = @FSP_M_BASE@; /* default base:size 0xfffdd000:0x22000 [0xfffdd000:0xfffff000] */ +FSP_S_ORIGIN = @FSP_S_BASE@; /* default base:size 0xfffc8000:0x15000 [0xfffdd000:0xfffdd000] */ FIT_TABLE_PTR = 0xffffffc0; UCODE0_BASE = @UCODE0_BASE@; FSP_S_UPD_DATA_BASE = @FSP_S_UPD_DATA_BASE@; WOLFBOOT_ORIGIN = @WOLFBOOT_ORIGIN@; - OUTPUT_FORMAT(elf32-i386) MEMORY @@ -20,6 +19,12 @@ MEMORY SECTIONS { + .jmpto32 BOOTLOADER_JUMP32_START : + { + _off_boot = ABSOLUTE(.) & 0xffff; + KEEP(*(.jmpto32)) + } + .fit_table_tr FIT_TABLE_PTR : { QUAD(fit_table); @@ -37,7 +42,6 @@ SECTIONS .bootloader WOLFBOOT_ORIGIN : { - _off_boot = ABSOLUTE(.) & 0xffff; KEEP(./boot_x86_fsp_start.o(.boot*)) KEEP(./tgl_fsp.o(.boot)) *(.boot*) @@ -55,28 +59,34 @@ SECTIONS .text FLASH_START : { - _wolfboot_flash_start = ABSOLUTE(FLASH_START); - *(.wolfboot) - _wolfboot_flash_end = .; + _wolfboot_flash_start = .; + KEEP(*(.sig_wolfboot_raw*)) + *(.wolfboot) + _wolfboot_flash_end = .; } - .fsp_t FSP_T_BASE : - AT(FSP_T_BASE) + .fsp_t FSP_T_ORIGIN : + AT(FSP_T_ORIGIN) { _start_fsp_t = .; *(.fsp_t) } - .fsp_s FSP_S_BASE : + .fsp_s FSP_S_ORIGIN : { + _fsp_s_hdr = .; + KEEP(*(.sig_fsp_s*)) _start_fsp_s = .; *(.fsp_s) + _end_fsp_s = .; } - .fsp_m FSP_M_BASE : + .fsp_m FSP_M_ORIGIN : { + _fsp_m_hdr = .; _start_fsp_m = .; *(.fsp_m) + _end_fsp_m = .; } } diff --git a/lib/wolfTPM b/lib/wolfTPM index 50bf4beb0..7c9391ebf 160000 --- a/lib/wolfTPM +++ b/lib/wolfTPM @@ -1 +1 @@ -Subproject commit 50bf4beb08a0483d0bdaf181fd294a15d2e4ce4a +Subproject commit 7c9391ebf3341ac10c8357adedd96ff42d59c845 diff --git a/src/boot_x86_fsp.c b/src/boot_x86_fsp.c index b7689812b..49a219e34 100644 --- a/src/boot_x86_fsp.c +++ b/src/boot_x86_fsp.c @@ -35,8 +35,23 @@ #include #include +#include "wolfboot/wolfboot.h" +#include "image.h" + #define WOLFBOOT_X86_STACK_SIZE 0x10000 + +#ifndef STAGE1_AUTH +/* When STAGE1_AUTH is disabled, create dummy images to fill + * the space used by wolfBoot manifest headers to authenticate FSPs + */ +#define HEADER_SIZE IMAGE_HEADER_SIZE +const uint8_t __attribute__((section(".sig_fsp_s"))) + empty_sig_fsp_s[HEADER_SIZE] = {}; +const uint8_t __attribute__((section(".sig_wolfboot_raw"))) + empty_sig_wolfboot_raw[HEADER_SIZE] = {}; +#endif + /* info can be retrieved from the CfgRegionSize of FSP info header. we need to * know this at compile time because to make things simpler we want to use the * stack to store the parameters and we don't want to include machine specific @@ -77,9 +92,10 @@ int fsp_machine_update_s_parameters(uint8_t *default_s_params); int post_temp_ram_init_cb(void); /* from the linker */ -extern uint8_t _start_fsp_t[]; extern uint8_t _start_fsp_m[]; -extern uint8_t _start_fsp_s[]; +extern uint8_t _fsp_s_hdr[]; +extern uint8_t _end_fsp_m[]; +extern uint8_t _end_fsp_s[]; extern uint8_t _wolfboot_flash_start[]; extern uint8_t _wolfboot_flash_end[]; extern uint8_t wb_end_bss[], wb_start_bss[]; @@ -112,20 +128,29 @@ static void change_stack_and_invoke(uint32_t new_stack, : "%eax"); } -static void load_wolfboot() +static void load_wolfboot(void) { size_t wolfboot_size, bss_size; - wolfBoot_printf("loading wolfboot at %x..." ENDLINE, - (uint32_t)WOLFBOOT_LOAD_BASE); + (uint32_t)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE); wolfboot_size = _wolfboot_flash_end - _wolfboot_flash_start; - memcpy((uint8_t*)WOLFBOOT_LOAD_BASE, + memcpy((uint8_t*)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE, _wolfboot_flash_start, wolfboot_size); bss_size = wb_end_bss - wb_start_bss; memset(wb_start_bss, 0, bss_size); wolfBoot_printf("load wolfboot end" ENDLINE); } +static void load_fsp_s_to_ram(void) +{ + size_t fsp_s_size; + wolfBoot_printf("loading FSP_S at %x..." ENDLINE, + (uint32_t)(FSP_S_LOAD_BASE - IMAGE_HEADER_SIZE)); + fsp_s_size = _end_fsp_s - _fsp_s_hdr; + memcpy((uint8_t*)FSP_S_LOAD_BASE - IMAGE_HEADER_SIZE, + _fsp_s_hdr, fsp_s_size); +} + extern uint8_t _stage2_params[]; static void set_stage2_parameter(struct stage2_parameter *p) @@ -134,7 +159,7 @@ static void set_stage2_parameter(struct stage2_parameter *p) } #ifdef WOLFBOOT_64BIT -static void jump_into_wolfboot() +static void jump_into_wolfboot(void) { struct stage2_parameter *params = (struct stage2_parameter*)_stage2_params; uint32_t cr3; @@ -159,6 +184,31 @@ static void jump_into_wolfboot() } #endif /* WOLFBOOT_64BIT */ +static inline int verify_payload(uint8_t *base_addr) +{ + int ret = -1; + struct wolfBoot_image wb_img; + memset(&wb_img, 0, sizeof(struct wolfBoot_image)); + ret = wolfBoot_open_image_address(&wb_img, base_addr); + if (ret < 0) { + wolfBoot_printf("verify_payload: Failed to open image" ENDLINE); + panic(); + } + wolfBoot_printf("verify_payload: image open successfully." ENDLINE); + ret = wolfBoot_verify_integrity(&wb_img); + if (ret < 0) { + wolfBoot_printf("verify_payload: Failed integrity check" ENDLINE); + panic(); + } + wolfBoot_printf("verify_payload: integrity OK. Checking signature." ENDLINE); + ret = wolfBoot_verify_authenticity(&wb_img); + if (ret < 0) { + wolfBoot_printf("verify_payload: Failed signature check" ENDLINE); + panic(); + } + return ret; +} + static void memory_ready_entry(void *ptr) { struct stage2_parameter *stage2_params = (struct stage2_parameter *)ptr; @@ -168,13 +218,19 @@ static void memory_ready_entry(void *ptr) silicon_init_cb SiliconInit; notify_phase_cb notifyPhase; NOTIFY_PHASE_PARAMS param; + uint32_t info[4]; uint32_t status; unsigned int i; int ret; + uint8_t *fsp_s_base; + uint8_t *fsp_m_base; + + fsp_m_base = _start_fsp_m; + fsp_s_base = (uint8_t *)(FSP_S_LOAD_BASE); fsp_info_header = - (struct fsp_info_header *)(_start_fsp_m + FSP_INFO_HEADER_OFFSET); - TempRamExit = (temp_ram_exit_cb)(_start_fsp_m + + (struct fsp_info_header *)(fsp_m_base + FSP_INFO_HEADER_OFFSET); + TempRamExit = (temp_ram_exit_cb)(fsp_m_base + fsp_info_header->TempRamExitEntryOffset); status = TempRamExit(NULL); if (status != EFI_SUCCESS) { @@ -182,13 +238,28 @@ static void memory_ready_entry(void *ptr) panic(); } - memcpy(silicon_init_parameter, _start_fsp_s + fsp_info_header->CfgRegionOffset, + /* Load FSP_S to RAM */ + load_fsp_s_to_ram(); + +#ifdef STAGE1_AUTH + /* Verify FSP_S */ + wolfBoot_printf("Authenticating FSP_S at %x..." ENDLINE, + fsp_s_base - IMAGE_HEADER_SIZE); + + if (verify_payload(fsp_s_base - IMAGE_HEADER_SIZE) == 0) + wolfBoot_printf("FSP_S: verified OK." ENDLINE); + else { + panic(); + } +#endif + + memcpy(silicon_init_parameter, fsp_s_base + fsp_info_header->CfgRegionOffset, FSP_S_PARAM_SIZE); status = fsp_machine_update_s_parameters(silicon_init_parameter); fsp_info_header = - (struct fsp_info_header *)(_start_fsp_s + FSP_INFO_HEADER_OFFSET); - SiliconInit = (silicon_init_cb)(_start_fsp_s + + (struct fsp_info_header *)(fsp_s_base + FSP_INFO_HEADER_OFFSET); + SiliconInit = (silicon_init_cb)(fsp_s_base + fsp_info_header->FspSiliconInitEntryOffset); wolfBoot_printf("call silicon..." ENDLINE); @@ -199,7 +270,7 @@ static void memory_ready_entry(void *ptr) } wolfBoot_printf("success" ENDLINE); pci_enum_do(); - notifyPhase = (notify_phase_cb)(_start_fsp_s + + notifyPhase = (notify_phase_cb)(fsp_s_base + fsp_info_header->NotifyPhaseEntryOffset); param.Phase = EnumInitPhaseAfterPciEnumeration; status = notifyPhase(¶m); @@ -219,10 +290,20 @@ static void memory_ready_entry(void *ptr) wolfBoot_printf("failed %d: %x\n", __LINE__, status); panic(); } - uint32_t info[4]; cpuid(0, &info[0], &info[1], &info[2], NULL); wolfBoot_printf("CPUID(0):%x %x %x\r\n", info[0], info[1], info[2]); load_wolfboot(); + +#ifdef STAGE1_AUTH + /* Verify wolfBoot */ + wolfBoot_printf("Authenticating wolfboot at %x..." ENDLINE, + WOLFBOOT_LOAD_BASE); + if (verify_payload((uint8_t *)WOLFBOOT_LOAD_BASE - IMAGE_HEADER_SIZE) == 0) + wolfBoot_printf("wolfBoot: verified OK." ENDLINE); + else { + panic(); + } +#endif set_stage2_parameter(stage2_params); jump_into_wolfboot(); } @@ -245,7 +326,7 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, uint8_t udp_m_parameter[FSP_M_UDP_MAX_SIZE], *udp_m_default; struct fsp_info_header *fsp_m_info_header; struct stage2_parameter *stage2_params; - uint8_t *_fsp_m_base, done = 0; + uint8_t *fsp_m_base, done = 0; struct efi_hob *hobList, *it; memory_init_cb MemoryInit; uint64_t top_address; @@ -254,20 +335,27 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, uint16_t type; uint32_t esp; +#ifdef STAGE1_AUTH + int ret; + struct wolfBoot_image fsp_m; +#endif + (void)stack_top; (void)timestamp; (void)bist; + fsp_m_base = (uint8_t *)(_start_fsp_m); + status = post_temp_ram_init_cb(); if (status != 0) { wolfBoot_printf("post temp ram init cb failed" ENDLINE); panic(); } - wolfBoot_printf("Cache-as-RAM initialized" ENDLINE); + fsp_m_info_header = - (struct fsp_info_header *)(_start_fsp_m + FSP_INFO_HEADER_OFFSET); - udp_m_default = _start_fsp_m + fsp_m_info_header->CfgRegionOffset; + (struct fsp_info_header *)(fsp_m_base + FSP_INFO_HEADER_OFFSET); + udp_m_default = fsp_m_base + fsp_m_info_header->CfgRegionOffset; if (!fsp_info_header_is_ok(fsp_m_info_header)) { wolfBoot_printf("invalid FSP_INFO_HEADER" ENDLINE); panic(); @@ -286,8 +374,7 @@ void start(uint32_t stack_base, uint32_t stack_top, uint64_t timestamp, } wolfBoot_printf("calling FspMemInit..." ENDLINE); - /* enable_dram_scratch_bit(); */ - MemoryInit = (memory_init_cb)(_start_fsp_m + + MemoryInit = (memory_init_cb)(fsp_m_base + fsp_m_info_header->FspMemoryInitEntryOffset); status = MemoryInit((void *)udp_m_parameter, &hobList); if (status == FSP_STATUS_RESET_REQUIRED_WARM) { diff --git a/src/boot_x86_fsp_start.S b/src/boot_x86_fsp_start.S index 4e1beb5df..5e829a398 100644 --- a/src/boot_x86_fsp_start.S +++ b/src/boot_x86_fsp_start.S @@ -50,7 +50,7 @@ extern _off_boot extern _start_fsp_t extern TempRamInitParams extern start -[section .boot] +[section .jmpto32] ;; If the offset to the segment selector code_sel_long is changed, make sure to ;; update the corresponding code in src/x86/common.c accordingly. gdt: diff --git a/src/image.c b/src/image.c index 70749a5bc..4fda57c56 100644 --- a/src/image.c +++ b/src/image.c @@ -959,6 +959,10 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img) { uint8_t *stored_sha; uint16_t stored_sha_len; +#ifdef STAGE1_AUTH + /* Override global */ + uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE]; +#endif stored_sha_len = get_header(img, WOLFBOOT_SHA_HDR, &stored_sha); if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE) return -1; @@ -999,6 +1003,10 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img) uint32_t key_mask = 0U; uint32_t image_part = 1U; int key_slot; +#ifdef STAGE1_AUTH + /* Override global */ + uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE]; +#endif stored_signature_size = get_header(img, HDR_SIGNATURE, &stored_signature); if (stored_signature_size != IMAGE_SIGNATURE_SIZE) @@ -1068,6 +1076,10 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset, #ifndef WOLFBOOT_NO_SIGN static int keyslot_id_by_sha(const uint8_t *hint) { +#ifdef STAGE1_AUTH + /* Override global */ + uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE]; +#endif int id = 0; for (id = 0; id < keystore_num_pubkeys(); id++) { diff --git a/src/x86/tgl_fsp.c b/src/x86/tgl_fsp.c index c7c6d4ede..ffbbee619 100644 --- a/src/x86/tgl_fsp.c +++ b/src/x86/tgl_fsp.c @@ -110,7 +110,7 @@ __attribute__((__section__(".boot"))) const struct fit_table_entry fit_table[FIT }, }; -__attribute__((__section__(".boot"))) const +__attribute__((__section__(".jmpto32"))) const FSPT_UPD TempRamInitParams = { .FspUpdHeader = { .Signature = FSPT_UPD_SIGNATURE, diff --git a/stage1/Makefile b/stage1/Makefile index c95d0af38..54af56b7c 100644 --- a/stage1/Makefile +++ b/stage1/Makefile @@ -135,7 +135,8 @@ $(LSCRIPT): $(LSCRIPT_IN) FORCE sed -e "s/@WOLFBOOT_STAGE1_SIZE@/$(WOLFBOOT_STAGE1_SIZE)/g" | \ sed -e "s/@WOLFBOOT_STAGE1_LOAD_ADDR@/$(WOLFBOOT_STAGE1_LOAD_ADDR)/g" | \ sed -e "s/@WOLFBOOT_STAGE1_FLASH_ADDR@/$(WOLFBOOT_STAGE1_FLASH_ADDR)/g" | \ - sed -e "s/@WOLFBOOT_STAGE1_BASE_ADDR@/$(WOLFBOOT_STAGE1_BASE_ADDR)/g" \ + sed -e "s/@WOLFBOOT_STAGE1_BASE_ADDR@/$(WOLFBOOT_STAGE1_BASE_ADDR)/g" | \ + sed -e "s/@IMAGE_HEADER_SIZE@/$(IMAGE_HEADER_SIZE)/g" \ > $@ %.hex:%.elf @@ -180,7 +181,8 @@ $(BUILD_DIR)/%.o: ../hal/%.S clean: $(Q)rm -f *.o - $(Q)rm -f loader_stage1.bin loader_stage1.elf loader_stage1.map $(LSCRIPT) + $(Q)rm -f *.bin + $(Q)rm -f loader_stage1.bin loader_stage1.elf *.map $(LSCRIPT) FORCE: diff --git a/stage1/x86_fsp.mk b/stage1/x86_fsp.mk index b6cfc9596..ea48facb9 100644 --- a/stage1/x86_fsp.mk +++ b/stage1/x86_fsp.mk @@ -1,3 +1,9 @@ +SIGN_TOOL?=../tools/keytools/sign +SIGN_OPTIONS?=--ecc256 --sha256 +SIGN_KEY?=../wolfboot_signing_private_key.der +X86FSP_PATH?=../`dirname $(FSP_M_BIN)` + + $(LSCRIPT_IN): $(WOLFBOOT_ROOT)/hal/$(LSCRIPT_IN).in FORCE @cat $(WOLFBOOT_ROOT)/hal/$(LSCRIPT_IN).in | \ sed -e "s/@FSP_T_BASE@/$(FSP_T_BASE)/g" | \ @@ -28,6 +34,24 @@ wolfboot_raw.bin: ../wolfboot.elf wolfboot_raw.o: wolfboot_raw.bin $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.wolfboot $^ $@ +sig_fsp_m.o: fsp_m.o $(SIGN_KEY) ../$(FSP_M_BIN) + $(SIGN_TOOL) $(SIGN_OPTIONS) ../$(FSP_M_BIN) $(SIGN_KEY) 1 + @dd if=$(X86FSP_PATH)/fsp_m_v1_signed.bin of=$(X86FSP_PATH)/fsp_m_signature.bin bs=256 count=1 + $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.sig_fsp_m $(X86FSP_PATH)/fsp_m_signature.bin sig_fsp_m.o + @rm -f $(X86FSP_PATH)/fsp_m_v1_signed.bin $(X86FSP_PATH)/fsp_m_signature.bin + +sig_fsp_s.o: fsp_s.o $(SIGN_KEY) ../$(FSP_S_BIN) + $(SIGN_TOOL) $(SIGN_OPTIONS) ../$(FSP_S_BIN) $(SIGN_KEY) 1 + @dd if=$(X86FSP_PATH)/fsp_s_v1_signed.bin of=$(X86FSP_PATH)/fsp_s_signature.bin bs=256 count=1 + $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.sig_fsp_s $(X86FSP_PATH)/fsp_s_signature.bin sig_fsp_s.o + @rm -f $(X86FSP_PATH)/fsp_s_v1_signed.bin $(X86FSP_PATH)/fsp_s_signature.bin + +sig_wolfboot_raw.o: wolfboot_raw.bin $(SIGN_KEY) + $(SIGN_TOOL) $(SIGN_OPTIONS) wolfboot_raw.bin $(SIGN_KEY) 1 + @dd if=wolfboot_raw_v1_signed.bin of=wolfboot_raw_signature.bin bs=256 count=1 + $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.sig_wolfboot_raw wolfboot_raw_signature.bin sig_wolfboot_raw.o + + fsp_tgl_s_upd.o: ../$(FSP_S_UPD_DATA_BIN) $(OBJCOPY) -I binary -O elf32-i386 -B i386 --rename-section .data=.fsps_upd $^ $@ diff --git a/tools/scripts/qemu64/qemudbg.sh b/tools/scripts/qemu64/qemudbg.sh index e7ab6863b..17f8b0de4 100755 --- a/tools/scripts/qemu64/qemudbg.sh +++ b/tools/scripts/qemu64/qemudbg.sh @@ -1,6 +1,6 @@ #!/bin/bash qemu-system-i386 -m 1G -machine q35 -serial mon:stdio -nographic \ - -pflash stage1/loader_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \g + -pflash stage1/loader_stage1.bin -drive id=mydisk,format=raw,file=app.bin,if=none \ -device ide-hd,drive=mydisk \ -S -s diff --git a/tools/x86_fsp/qemu/qemu_build_fsp.sh b/tools/x86_fsp/qemu/qemu_build_fsp.sh index 5f980af3c..0be29f9d4 100755 --- a/tools/x86_fsp/qemu/qemu_build_fsp.sh +++ b/tools/x86_fsp/qemu/qemu_build_fsp.sh @@ -20,7 +20,7 @@ if [ -f "${CONFIG_FILE}" ] then FSP_T_BASE=$(grep -Eo '^FSP_T_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) FSP_M_BASE=$(grep -Eo '^FSP_M_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) - FSP_S_BASE=$(grep -Eo '^FSP_S_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) + FSP_S_LOAD_BASE=$(grep -Eo '^FSP_S_LOAD_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) else echo "Error: ${CONFIG_FILE} file not found in current directory" exit @@ -88,8 +88,8 @@ download_sbl_patch_and_patch_edkii build_qemu_fsp rebase_fsp_component "T" ${FSP_T_BASE} rebase_fsp_component "M" ${FSP_M_BASE} -rebase_fsp_component "S" ${FSP_S_BASE} +rebase_fsp_component "S" ${FSP_S_LOAD_BASE} copy_fsp_component "T" ${FSP_T_BASE} copy_fsp_component "M" ${FSP_M_BASE} -copy_fsp_component "S" ${FSP_S_BASE} +copy_fsp_component "S" ${FSP_S_LOAD_BASE} copy_fsp_headers diff --git a/tools/x86_fsp/tgl/tgl_download_fsp.sh b/tools/x86_fsp/tgl/tgl_download_fsp.sh index 3d33a1848..321dbb137 100755 --- a/tools/x86_fsp/tgl/tgl_download_fsp.sh +++ b/tools/x86_fsp/tgl/tgl_download_fsp.sh @@ -23,7 +23,7 @@ if [ -f "${CONFIG_FILE}" ] then FSP_T_BASE=$(grep -Eo '^FSP_T_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) FSP_M_BASE=$(grep -Eo '^FSP_M_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) - FSP_S_BASE=$(grep -Eo '^FSP_S_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) + FSP_S_LOAD_BASE=$(grep -Eo '^FSP_S_LOAD_BASE=.*' ${CONFIG_FILE} | cut -d "=" -f 2) else echo "Error: ${CONFIG_FILE} file not found in current directory" exit @@ -95,10 +95,10 @@ download_split_tool split_fsp rebase_fsp_component "T" ${FSP_T_BASE} rebase_fsp_component "M" ${FSP_M_BASE} -rebase_fsp_component "S" ${FSP_S_BASE} +rebase_fsp_component "S" ${FSP_S_LOAD_BASE} copy_fsp_component "T" ${FSP_T_BASE} copy_fsp_component "M" ${FSP_M_BASE} -copy_fsp_component "S" ${FSP_S_BASE} +copy_fsp_component "S" ${FSP_S_LOAD_BASE} patch_tgl_fsp copy_fsp_headers download_ucode