Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/test-build-kontron-vx3060-s2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ jobs:
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update -o Acquire::Retries=3
sudo apt-get install --no-install-recommends -y -q -o Acquire::Retries=3 nasm gcc-multilib
- name: setup git
run: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
- name: run test
run: |
cp config/examples/kontron_vx3060_s2.config .config
Expand Down
27 changes: 19 additions & 8 deletions .github/workflows/test-x86-fsp-qemu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ jobs:
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update -o Acquire::Retries=3
sudo apt-get install --no-install-recommends -y -q -o Acquire::Retries=3 nasm gcc-multilib qemu-system-x86 swtpm uuid-dev
- name: setup git
run: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
- name: run test
run: |
./tools/scripts/x86_fsp/qemu/test_qemu.sh
Expand All @@ -70,10 +66,25 @@ jobs:
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update -o Acquire::Retries=3
sudo apt-get install --no-install-recommends -y -q -o Acquire::Retries=3 nasm gcc-multilib qemu-system-x86 uuid-dev dosfstools mtools e2fsprogs
- name: setup git
run: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
- name: run test
run: |
./tools/scripts/x86_fsp/qemu/test_qemu.sh -f

# TPM-NV anti-rollback: the floor anchors on a fresh swtpm, survives a TPM
# restart, and a validly signed downgrade boots and is counted.
fsp_qemu_antirollback_test:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: install req
run: |
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update -o Acquire::Retries=3
sudo apt-get install --no-install-recommends -y -q -o Acquire::Retries=3 nasm gcc-multilib qemu-system-x86 swtpm uuid-dev
- name: run test
run: |
./tools/scripts/x86_fsp/qemu/test_qemu.sh -r
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ tools/unit-tests/unit-update-flash-enc
tools/unit-tests/unit-update-flash-db
tools/unit-tests/unit-update-flash-enc-full
tools/unit-tests/unit-update-ram
tools/unit-tests/unit-boot-state
tools/unit-tests/unit-boot-state-halt
tools/unit-tests/unit-boot-x86-fsp
tools/unit-tests/unit-image-rsa
tools/unit-tests/unit-multiboot
Expand Down
20 changes: 12 additions & 8 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2207,13 +2207,13 @@ ifeq ($(USE_GCC),1)
endif
OUTPUT_FLAG?=-o

ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2),$(TARGET))
ifeq ($(filter $(TARGET),x86_fsp_qemu kontron_vx3060_s2 nai_68int6),$(TARGET))
FSP=1
CFLAGS+=-ffunction-sections -fdata-sections -ffreestanding -nostdlib -static
# some std libc have headers that bring in extra symbols used in
# FORTIFY_SOURCE realated checks. Use -U_FORTIFY_SOURCE to avoid that.
CFLAGS+=-U_FORTIFY_SOURCE
ifeq ($(TARGET), kontron_vx3060_s2)
ifeq ($(filter $(TARGET),kontron_vx3060_s2 nai_68int6),$(TARGET))
FSP_TGL=1
CFLAGS+=-DWOLFBOOT_TGL=1
endif
Expand Down Expand Up @@ -2263,23 +2263,20 @@ ifeq ("${FSP}", "1")
OBJS += src/image.o
OBJS += src/keystore.o
OBJS += src/sig_wolfboot_raw.o
ifeq ($(TARGET), kontron_vx3060_s2)
OBJS += hal/kontron_vx3060_s2_loader.o
endif
OBJS += $(WOLFCRYPT_OBJS)
CFLAGS+=-DSTAGE1_AUTH
endif

# Generic stage1 loader HAL (stubs); shared by all x86 FSP targets.
OBJS += hal/stub_loader.o

CFLAGS += -fno-stack-protector -m32 -fno-PIC -fno-pie -mno-mmx -mno-sse -DDEBUG_UART
CFLAGS += -DFSP_M_BASE=$(FSP_M_BASE)
ifeq ($(FSP_TGL), 1)
OBJS+=src/x86/tgl_fsp.o
OBJS+=src/ucode0.o
CFLAGS += -DUCODE0_ADDRESS=$(UCODE0_BASE)
endif
ifeq ($(TARGET),x86_fsp_qemu)
OBJS += hal/x86_fsp_qemu_loader.o
endif
else
# building wolfBoot
ifeq ($(FSP_TGL), 1)
Expand All @@ -2302,13 +2299,20 @@ ifeq ("${FSP}", "1")
OBJS += src/gpt.o
OBJS += src/disk.o
OBJS += src/x86/mptable.o
ifeq ($(ACPI),1)
OBJS += src/x86/acpi.o
endif
OBJS += src/stage2_params.o
OBJS += src/x86/exceptions.o
OBJS += src/x86/gdt.o
OBJS += src/x86/fsp.o
OBJS += src/x86/fsp_s.o
UPDATE_OBJS := src/update_disk.o
CFLAGS+=-DWOLFBOOT_UPDATE_DISK
ifeq ($(ANTI_ROLLBACK),1)
OBJS += src/boot_state.o
OBJS += src/boot_state_tpm.o
endif
ifeq ($(64BIT),1)
LDFLAGS += -m elf_x86_64 --oformat elf64-x86-64
CFLAGS += -m64
Expand Down
96 changes: 96 additions & 0 deletions config/examples/nai_68int6.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# NAI 68INT6 3U OpenVPX SBC (Tiger Lake UP3); needs the board's own FSP
# (nai_extract_fsp.sh). See the NAI 68INT6 section of docs/Targets.md.

ARCH=x86_64
TARGET=nai_68int6
WOLFBOOT_SMALL_STACK=0

# ECC P-384 signature, SHA-384 digest (measured boot uses SHA-256 on an
# SLB9670). See the integrity-algorithm table in docs/Targets.md.
SIGN=ECC384
HASH=SHA384

DEBUG=1
# FSP-M UPD dump on the console before FspMemInit (bring-up aid).
DUMP_FSP_UPD=0
SPMATH=1
ENCRYPTION=0
WOLFBOOT_NO_PARTITIONS=1
# Disk boot: signed kernels in GPT partitions 3/4, Ubuntu root in partition 2.
# The A/B boot-partition indices are set per target in src/update_disk.c.
WOLFBOOT_BOOT_DISK=0
FORCE_32BIT=1

########## Flash layout (measured from the factory descriptor, 32 MB) ##########
WOLFBOOT_PARTITION_BOOT_ADDRESS=0xff400000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x0
WOLFBOOT_LOAD_BASE=0x58000200
WOLFBOOT_SECTOR_SIZE?=0x1000
WOLFBOOT_DATA_ADDRESS=0x1000000

FSP_CONFIG_BASE=0xffe9f800
FSP_T_BASE=0xfff59000
FSP_M_BASE=0xfff60000

WOLFBOOT_ORIGIN=0xfff00000
BOOTLOADER_PARTITION_SIZE=0x600000
# Inert (the flash descriptor is used); kept for config parity.
BIOS_REGION_SIZE=0xc00000

UCODE0_BASE=0xffd90000
UCODE0_BIN=src/x86/ucode0.bin

FSP_T_BIN=./src/x86/fsp_t.bin
FSP_M_BIN=./src/x86/fsp_m.bin
FSP_S_BIN=./src/x86/fsp_s.bin
FSP_S_UPD_DATA_BIN=./src/x86/fsp_s_upd_data.bin
# Boot Guard is left to the board owner: supply an ACM and key here to build a
# Boot-Guard image. Unset, wolfBoot builds and boots without it.
ACM_BIN=
FSP_S_LOAD_BASE=0x0FED5F00

POLICY_BASE=0xffaa4000
KEYSTORE_OFFSET=0x3FE00
KEYSTORE_STAGE1_OFFSET=0x400

########## Console: LPSS UART2 (PCI 00:19.2), verified on hardware ##########
X86_UART_NUMBER=2
X86_UART_BASE=0xFE032000
X86_UART_REG_WIDTH=4
X86_UART_MMIO=1

########## PCH / PCI ##########
PCH_PCR_BASE=0xFD000000
PCI_ECAM_BASE=0xC0000000
PCI_USE_ECAM=1
PCH_HAS_PCR=1
# Generate ACPI tables so Linux gets the interrupt model and PCI routing.
ACPI=1

########## Payload: signed 64-bit Linux bzImage ##########
64BIT=1
ELF=1
DEBUG_ELF=0
MULTIBOOT2=1
LINUX_PAYLOAD=1

########## Security ##########
STAGE1_AUTH=1
WOLFTPM=1
MEASURED_BOOT=1
MEASURED_PCR_A=0
# Measure the verified OS image into PCR4, alongside the firmware in PCR0.
MEASURED_PCR_OS=4
WOLFBOOT_UNIVERSAL_KEYSTORE=1
WOLFBOOT_SKIP_AUTH_CHECK=0
ENABLE_DEBUG_CONSENT=0

# Deferred: TPM sealing and ATA disk lock/erase.
WOLFBOOT_TPM_SEAL=0
DISK_LOCK=0
DISK_ERASE=0

# Anti-rollback: persistent version floor + audit counters in TPM NV
# (trust-on-first-use; provision before first boot where that matters).
ANTI_ROLLBACK=1
45 changes: 45 additions & 0 deletions config/examples/x86_fsp_qemu_antirollback.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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_NO_PARTITIONS=1

# TPM Keystore options
#WOLFBOOT_TPM_KEYSTORE?=1
#WOLFBOOT_TPM_KEYSTORE_NV_BASE?=0x01800200
#WOLFBOOT_TPM_POLICY_NV_INDEX?=0x01800201

# 4gb - 8mb
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=0xfff80000

BOOTLOADER_PARTITION_SIZE=0xe0000
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
64BIT=1
ELF=1
MULTIBOOT2=1

# TPM-NV anti-rollback (version floor and audit counters), tested by
# tools/scripts/x86_fsp/qemu/test_qemu.sh -r
ANTI_ROLLBACK=1
ANTI_ROLLBACK_HALT_ON_FAILURE=1
69 changes: 69 additions & 0 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This README describes configuration of supported targets.
* [Infineon AURIX TC4xx](#infineon-aurix-tc4xx)
* [Intel x86-64 Intel FSP](#intel-x86_64-with-intel-fsp-support)
* [Kontron VX3060-S2](#kontron-vx3060-s2)
* [NAI 68INT6 (Intel Tiger Lake)](#nai-68int6-intel-tiger-lake)
* [Microchip PIC32CK](#microchip-pic32ck)
* [Microchip PIC32CZ](#microchip-pic32cz)
* [Microchip PolarFire SoC](#microchip-polarfire-soc)
Expand Down Expand Up @@ -9609,6 +9610,74 @@ Attempting boot from partition A
```
At this point, the kernel image in partition "A" is verified and staged and you should be seeing the log messages of your OS booting.

## NAI 68INT6 (Intel Tiger Lake)

wolfBoot target `nai_68int6` for the North Atlantic Industries 68INT6, a 3U OpenVPX SOSA-aligned single board computer (Intel Core i7-1185GRE, Tiger Lake UP3). It uses the Intel FSP support described [above](#intel-x86_64-with-intel-fsp-support) and shares the Tiger Lake path with the Kontron target. wolfBoot boots a signed 64-bit Linux from the SATA disk with A/B update, measured boot and TPM anti-rollback, verified on a Rev D5 bench board. The public Tiger Lake FSP does not train this board's memory, so the FSP is extracted from a 68INT6 BIOS image.

| | |
|---|---|
| CPU | i7-1185GRE (`06-8C-01`), Tiger Lake UP3, PCH-LP |
| Memory | 2 x 32 GB DDR4-3200 SODIMM, non-ECC |
| BIOS flash | Rev C/D5: 2 x W25R256JV (32 MB), selected by JP36. Next revision: one 64 MB device |
| TPM | SLB9670 (SHA-1/256), or SLB9672, which adds a SHA-384 bank |
| Storage | Onboard SATA SSD, AHCI at `00:17.0` |
| Console | LPSS UART2, PCI `00:19.2`, RS-232; `X86_UART_NUMBER=2` |

### Building

```
cp config/examples/nai_68int6.config .config
./tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh # FSP UPD headers, first time only
./tools/scripts/x86_fsp/tgl/nai_extract_fsp.sh <68INT6.bin> # board's own FSP blobs
./tools/scripts/x86_fsp/tgl/assemble_image.sh -k # generate signing keys
make
./tools/scripts/x86_fsp/tgl/assemble_image.sh -n <68INT6.bin>
```

`nai_extract_fsp.sh` takes FSP-T/M/S and the microcode from a 68INT6 BIOS image. Without it the build uses the public FSP, which compiles but does not train memory. The `-n` stitch replaces the top 6 MB (`BOOTLOADER_PARTITION_SIZE`) of the 12 MB BIOS region and keeps the descriptor and CSME byte for byte. The board has no recovery region (recovery is the second flash device), so use `-n`, not `-m`. The result is `final_image.bin`.

### Integrity algorithms

ECC P-384 and SHA-384 match what Intel Boot Guard uses for the Initial Boot Block.

| Layer | Algorithm |
|---|---|
| Image signature | ECC P-384 (`SIGN=ECC384`) |
| Image digest | SHA-384 (`HASH=SHA384`) |
| Measured boot PCR | SHA-256 (the SLB9670 has only SHA-1 and SHA-256 banks) |

`wolfBoot_image_measure()` re-hashes the authenticated digest with the PCR bank's algorithm, so one image serves either TPM. `MEASURED_PCR_ALG=SHA384` needs an SLB9672 with its SHA-384 bank allocated (`TPM2_PCR_Allocate` under platform auth, a provisioning step).

### Configuration

Notable options in [config/examples/nai_68int6.config](../config/examples/nai_68int6.config):

| Option | Meaning |
|---|---|
| `X86_UART_NUMBER=2` | LPSS UART2 for all three FSP phases (Kontron uses 0) |
| `ACPI=1` | Required. Generates ACPI tables (RSDP/XSDT/FADT/MADT/MCFG and a minimal DSDT); the board's PCI interrupt routing is only in the DSDT `_PRT`, since the MP table is the Kontron one |
| `ANTI_ROLLBACK=1` | Persistent version floor and boot audit counters in TPM NV |
| `MEASURED_BOOT=1`, `MEASURED_PCR_OS=4` | Firmware into PCR 0, the verified OS image into PCR 4 |
| `WOLFBOOT_BOOT_DISK=0` | Boot from GPT partitions; the A/B indices (sda3/sda4) are set in `src/update_disk.c` |

### BIOS region lock

Before handoff, `hal_flash_protect()` in the shared Tiger Lake HAL (`hal/x86_fsp_tgl.c`, as on Kontron) sets SPI Flash Protected Range 0 over the BIOS region with read and write protection, then FLOCKDN. Both hold until the next platform reset, so the booted OS cannot read or reprogram the BIOS region; update it with an external programmer.

### Anti-rollback

`ANTI_ROLLBACK=1` keeps a version floor and boot audit counters in a TPM NV index; the backend is `src/boot_state_tpm.c` and the policy is `src/boot_state.c`. The floor is the highest version ever booted, set trust-on-first-use. A validly signed older image still boots and records a rollback event. Only an untrustworthy reference halts the boot; `ANTI_ROLLBACK_HALT_ON_FAILURE=1` also halts when the TPM is unreachable, a write fails or the platform hierarchy cannot be disabled.

TPM NV is used instead of the partition state trailer because the floor must survive a full reimage of the disk or flash. `DISK_BOOT_CONFIRM` still handles per-slot confirmation, and the backend can move to a root-of-trust device later without changing the policy.

`ALLOW_DOWNGRADE` is left unset, the secure default: if the higher-versioned slot fails to verify, wolfBoot halts (`Rollback to lower version not allowed`) rather than boot the lower one. Building with `ALLOW_DOWNGRADE=1` allows that fall-back and leaves the TPM floor as the only rollback guard.

The booted OS cannot lower the floor. The index is platform-created and writable only under platform auth (`TPMA_NV_PPWRITE`), and on every boot wolfBoot disables the platform hierarchy (`TPM2_HierarchyControl`) until the next TPM reset, as in section 10 of the TCG PC Client Platform specification. The OS can then neither write nor undefine the index. An index with any other write attributes is treated as corrupt. Platform-auth provisioning, such as `TPM2_PCR_Allocate`, must be done before wolfBoot is installed.

### Boot, programming and recovery

wolfBoot boots the highest-versioned signed 64-bit `bzImage` that verifies from the two GPT boot partitions. It falls back to the other slot only if that is not a downgrade (see Anti-rollback), and halts if neither boots. Program the flash with a Dediprog SF100 on JP4 while the board is off; the BIOS region lock blocks `flashrom` from the booted OS. JP36 selects which bank boots and which one the programmer sees; move it only with the board off.

## Infineon PSOC Control C3

The [PSOC Control C3](https://www.infineon.com/products/microcontroller/32-bit-psoc-arm-cortex/32-bit-psoc-control-arm-cortex-m33-mcu/psoc-control-c3-main-line) family (PSC3, CAT1B) is an Arm Cortex-M33 motor-control MCU. wolfBoot runs as the first application the BootROM launches, verifies the signed firmware in the BOOT partition and jumps to it.
Expand Down
Loading
Loading