Commit Graph

81 Commits (80dbb6da15ab5eb348f5d76049dabd03be5bdd67)

Author SHA1 Message Date
David Garske 80dbb6da15 update_disk: golden slot tried after the A/B attempts, exempt from anti-rollback and never written 2026-10-07 20:07:38 -07:00
David Garske 5ecce1a6c9 disk: fix the DEBUG_UART=0 build for every disk boot target 2026-10-06 20:11:29 -07:00
David Garske bd1bc31ed1 x86 FSP: address review - shared fsp_handle_reset, UART number/mode, always re-hash OS digest 2026-09-30 09:25:16 +02:00
David Garske 3d197cb8c7 x86 FSP: load an optional initrd alongside the Linux bzImage payload 2026-09-30 09:25:16 +02:00
David Garske d51df7819b x86 FSP: measure the disk OS image into a configurable PCR 2026-09-30 09:25:16 +02:00
David Garske 8f4578c84e Add optional boot confirmation and rollback for the disk boot path 2026-09-29 07:41:43 +02:00
David Garske 490a3791f9 Fix to keep the FIT DTB's own bootargs unless LINUX_BOOTARGS is explicitly configured 2026-09-24 16:03:12 +02:00
Daniele Lacamera 6b505817ed F-13660: zeroize the nonce-derived IV copy in disk_crypto_set_iv
The CTR counter block built on the stack is a full copy of the secret
disk-encryption nonce plus counter; both in-tree sibling IV helpers
already scrub their stack copy, this was the only one that did not.
2026-09-23 03:26:31 +02:00
David Garske fae9e53653 hooks: add pre-boot hook, DTB accessor and FDT alias/reg helpers 2026-09-21 18:10:09 +02:00
David Garske 4093fa0e17 Add NXP i.MX 8QuadMax MEK port including BL33 support 2026-09-21 18:07:44 +02:00
Daniele Lacamera 394f160a83 F-12873: update_disk: FSP low-mem check reuses validated slot_max
The final image-size check re-derived the low-memory limit with a
uint32 subtraction and no ordering check, so an inverted tolum
wrapped into a near-2^32 limit and accepted any image. Compare the
tolum/load_address ordering in 32-bit (low-memory) form when
computing slot_max, and reuse that validated value in the check.
Add a unit test for the inverted-tolum case (fails closed, both
slots rejected).
2026-09-07 14:40:35 +02:00
Daniele Lacamera a2d5543ebb F-9740: update_disk: FSP low-mem rejection falls back to other slot
The WOLFBOOT_FSP low-memory size check was the only per-slot rejection
in the boot retry loop that used a bare break, so an image whose
header-declared fw_size exceeded the tolum window aborted the boot
instead of trying the other slot. Every other rejection in the same
loop switches partitions and retries; match that.
2026-09-04 10:32:13 +02:00
Daniele Lacamera b548341e9b F-12114: pkcs11: wipe the login PIN on all pre-handoff paths
pkcs11_crypto_deinit() - the only caller of pkcs11_pin_wipe() - was
invoked from the update_flash path alone (src/update_flash.c:1715).
On the RAMBOOT, hwswap and disk pre-handoff paths the PKCS#11 login
credential stayed in retained bootloader memory after handoff.

Add the same #ifdef ENCRYPT_PKCS11 deinit block after the WOLFHSM
cleanup in src/update_ram.c, src/update_flash_hwswap.c and
src/update_disk.c, in the same position as the existing update_flash
call (before hal_flash_protect/hal_prepare_boot). update_ram.c and
update_flash_hwswap.c did not include encrypt.h, where
pkcs11_crypto_deinit() is declared - add the include (update_flash.c
and update_disk.c already had it). The deinit is a no-op when crypto
was never initialized, so the calls are safe on every build.

Verification: full build with PKCS11 enabled (sim config +
CFLAGS_EXTRA: ENCRYPT_PKCS11, EXT_ENCRYPTED, EXT_FLASH,
WOLFCRYPT_SECURE_MODE, SECURE_PKCS11, WOLFPKCS11_USER_SETTINGS +
mechanism/sizes/PIN) compiles all sources cleanly; the link stops on
pre-existing externals (token library + secure-mode wolfssl objects
that a real target's link config supplies) - a control build of the
unpatched tree fails identically with the same undefined-symbol set.
sim and kontron_vx3060_s2 builds green (PKCS11 disabled, hunks
inactive). cstyle clean on the changed hunks.
2026-09-02 12:15:51 +02:00
David Garske 95227f823c fdt: rewrite device tree parser with capacity bound and full validation 2026-09-02 10:48:52 +02:00
David Garske 664b09a075 update_disk: load signed image from a file when a filesystem is present 2026-09-02 10:47:33 +02:00
David Garske a5c94502d4
Merge pull request #868 from danielinux/fenrir-fixes-2026-08-21
Fenrir fixes 2026 08 21
2026-08-24 13:34:37 -04:00
David Garske 88984858d5 Peer review fixes (thanks Jack) 2026-08-24 12:47:34 +02:00
David Garske 2df97e448e cm4: define weak hal_get_boot_dts in update_disk.c so ARM32/RISC-V disk targets link 2026-08-24 12:47:34 +02:00
David Garske 56651bde95 cm4: add Linux kernel FIT boot via firmware-provided DTB with injected bootargs 2026-08-24 12:47:34 +02:00
Daniele Lacamera 9b1a48554a share the DTS size bounds in fdt.h and state the window assumption
The WOLFBOOT_DTS_MAX_SIZE/WOLFBOOT_DTS_MIN_SIZE pair was defined
separately in update_disk.c (F-7066) and update_ram.c (pre-existing), so
the two copies could drift. Move it to include/fdt.h, the FDT dialect
header both translation units already pull in via image.h; the hal
override (nxp_ppc.h, included before fdt.h in boot_ppc.c) keeps its
precedence. Also replace the 'bounded by the staging region' comment,
which claimed more than the code guarantees: the copy is clamped to
WOLFBOOT_DTS_MAX_SIZE, so the staging window at
WOLFBOOT_LOAD_DTS_ADDRESS must be at least that large (or the bound
overridden for the target), and the header comment now says so.

Skoll review finding 3, 2026-08-21 wolfboot review.
2026-08-21 09:08:26 +02:00
Daniele Lacamera d554bbb98b F-7066: bound the FIT DTS relocation copy to the staging size
The FIT boot path relocated the flat-dt sub-image with a copy whose
length came from the FIT-declared data property length, never bounded
against the WOLFBOOT_LOAD_DTS_ADDRESS staging region - unlike the
sibling DTB paths, which all validate the parsed size against
WOLFBOOT_DTS_MIN_SIZE/WOLFBOOT_DTS_MAX_SIZE first. The length was also
harvested through a (int*)&dts_size cast of a uint32_t.

Relocate the parsed DTB size instead: validate it against the same
MIN/MAX bounds as the other DTB sources and copy that many bytes. An
out-of-range DTB is rejected (dts_addr stays NULL and the existing
fallback chain applies) rather than partially or oversize copied.
Applied to both call sites of the pattern: update_ram.c (memcpy) and
update_disk.c (wolfBoot_fit_memcpy), which also gains the DTS bounds
macros it was missing.

unit-update-disk-fit (drives the real update_disk.c wolfBoot_start)
gains two cases: a parsed size above WOLFBOOT_DTS_MAX_SIZE and one
below WOLFBOOT_DTS_MIN_SIZE are both rejected without a copy, while
the existing success/failure-copy cases keep passing. The staging
stand-in is grown so the pre-fix unbounded copy is observable as a
copy instead of a crash.
2026-08-21 08:52:59 +02:00
Alex Lanzano 4fb9e81b44
Merge pull request #853 from dgarske/zynqmp_sdhci_reset
SDHCI: fix silent read failures and unbootable warm reset with UHS-I cards
2026-08-14 12:51:20 -04:00
David Garske 38ec1e1bed sdhci: fix silent read failures and unbootable warm reset with UHS-I cards 2026-08-11 15:37:56 -07:00
Daniele Lacamera 4726dce42b update_disk: use wc_ForceZero() in the DISK_ENCRYPT helpers
ForceZero() is only visible in libwolfboot.c, which pulls in misc.c
inline; update_disk.c called it without a declaration, so any config with
disk encryption failed to build. Use the exported wc_ForceZero() from
memory.o instead, which is always linked.

Add a zynqmp_sdcard ENCRYPT build job to CI, the only one that compiles
these paths.
2026-08-11 13:59:06 +02:00
Daniele Lacamera f9fe1386ac F-6130: clear disk_encrypt_key/nonce on the FIT DTS load failure path
dd0712ec added the disk_decrypted_header_clear()/disk_crypto_clear() pair
to the wolfBoot_start() panic paths that were missing it, but the FIT
flat-device-tree load failure was one more: when wolfBoot_fit_memcpy()
fails to relocate the DTS, wolfBoot_panic() is entered with
disk_encrypt_key/disk_encrypt_nonce still live in BSS, and that call never
returns on a real target.

Add unit-update-disk-fit, which drives wolfBoot_start() through the FIT
branch with DISK_ENCRYPT enabled and snapshots the module statics from the
WOLFBOOT_HOOK_PANIC hook.
2026-08-11 13:59:06 +02:00
David Garske 5f40400e57 PolarFire SoC: address PR review
- wolfBoot_fit_memcpy: return int so a failed PDMA copy propagates instead
  of being swallowed. The weak default (memcpy) returns 0; the MPFS250 PDMA
  override returns -1 if any chunk's mpfs_pdma_memcpy() fails. Callers now
  fail closed: fit_load_image_inner returns NULL (kernel load then panics
  via update_disk.c), the update_disk DTS copy panics, and hal_dts_fixup
  returns an error on a failed L2->DDR copy-back.
- options.mk: gate -DSTACK_SIZE_PER_HART behind RISC-V arch (RISCV/RISCV64).
  The macro is only consumed by the RISC-V startup asm and the mpfs250-m.ld
  sed token, so it is no longer emitted for PPC/ARM/other targets. The
  unconditional default (?= 0) is kept because the linker sed always needs
  a value to substitute.
2026-08-03 12:27:22 +02:00
David Garske e718eed709 PolarFire SoC: LPDDR4 DDR init for MPFS250T Video Kit (M-Mode) 2026-08-03 12:27:22 +02:00
David Garske 1ceaef3eee zynqmp: wolfBoot ZynqMP FSBL with signed FIT Linux boot and EL3 security (eFuse/PUF/AES-CSU) 2026-07-22 11:56:40 +02:00
Daniele Lacamera dd0712ec52 F-6130: clear disk_encrypt_key/nonce before panic paths that skip the final cleanup
update_disk.c wolfBoot_start() already zeroizes disk_encrypt_key/nonce and
the decrypted header before most wolfBoot_panic() halts, but four paths
were missed: anti-rollback rejection, FIT FPGA load failure, FIT kernel
load failure, and flash-protect failure. Since wolfBoot_panic() halts
forever on real targets, these paths left the key live in BSS on a halted
device. Add the same disk_decrypted_header_clear()/disk_crypto_clear()
pair used on the other panic paths immediately before each.
2026-07-02 15:23:43 +02:00
Marco Oliverio 6e117a5b50 update_disk.c: enforce bound over memcpy 2026-06-23 17:28:25 +02:00
Daniele Lacamera 2365e452c3 F-3736: fix pA_ver/pB_ver int/uint32_t mismatch in update_disk wolfBoot_start
Versions with the high bit set (>= 0x80000000) were stored as negative
int, causing the `> 0` guards to fail silently and leaving pA_ver_u /
pB_ver_u at 0. This broke partition selection and disabled the rollback
check for any image with a version number above INT_MAX.

Declare pA_ver and pB_ver as uint32_t (matching the return type of
wolfBoot_get_blob_version and get_decrypted_blob_version), update the
guards to != 0U, and drop the now-redundant (uint32_t) casts.

Add a unit test that places 0x80000001 in A and 0x80000002 in B and
asserts B is selected; before the fix the test failed with A chosen.
2026-06-11 18:32:50 +02:00
David Garske 14f6e4a298 Add wolfBoot FIT support for loading bitstream 2026-06-09 15:30:27 +02:00
David Garske 9ca1d435b9 Peer review fixes (copilot)
src/fdt.c, include/fdt.h
  - Propagate fdt_fixup_initrd error in fit_load_ramdisk so a /chosen
    patch failure no longer silently boots a kernel with no initrd.
  - Add fit_load_image_to(): decompress (or memcpy) directly to a
    caller-supplied destination buffer instead of going through the
    FIT-declared `load` address. fit_load_ramdisk now uses this when
    WOLFBOOT_LOAD_RAMDISK_ADDRESS is set, so the override is a real
    safety bound for compressed ramdisks (previously the gzip stream
    was still inflated to the FIT `load` and only memcpy'd afterward).
  - Refactor fit_load_image_ex into a shared inner helper.
  - Reword the WOLFBOOT_FIT_MAX_DECOMP comment: the cap is a sanity
    ceiling, not a per-destination memory-safety bound. Authenticity
    is provided by the outer wolfBoot signature; tighter bounds need
    fit_load_image_ex / _to with an explicit out_max / dst_max.
  - Add WOLFBOOT_FIT_MAX_RAMDISK (defaults to WOLFBOOT_FIT_MAX_DECOMP)
    so targets can pin a tighter ramdisk decompression bound.

src/update_ram.c, src/update_disk.c
  - Panic when fit_load_image() returns NULL for the kernel subimage
    instead of letting load_address=NULL propagate into do_boot().

tools/unit-tests/unit-gzip.c
  - Add deterministic stored / fixed-Huffman / dynamic-Huffman gzip
    fixtures so the inflater's BTYPE 00/01/10 paths are exercised
    independent of host gzip(1) heuristics.
  - Add FEXTRA / FNAME / FCOMMENT / FHCRC and combined-flag fixtures
    plus a truncated-FEXTRA negative case to cover the optional gzip
    header parser.

tools/unit-tests/unit-fit-gzip.c (new), tools/unit-tests/Makefile
  - New libcheck binary covering the FIT loader's compression
    branches: gzip success, gzip stream corruption, unknown
    compression, compression="none" baseline, and the no-load
    fail-closed path. Built twice from the same source - once with
    WOLFBOOT_GZIP for the success / runtime-failure paths, and once
    without it so the compile-time fail-closed branch is also tested.
2026-05-05 10:16:16 +02:00
David Garske d92053037c Fixes from peer review (Thank you Daniele and Marco) 2026-05-05 10:16:16 +02:00
David Garske c643215c5e fit: gzip-compressed kernel + ramdisk (initramfs) support
Wires the new wolfBoot_gunzip inflater into the FIT image-loading path
and adds initramfs (ramdisk) extraction with DTB /chosen fixup so a
single signed FIT can carry kernel, DTB, and rootfs.

GZIP path
---------
* fit_load_image_ex(out_max) added; fit_load_image kept as a wrapper.
* When a subimage carries compression="gzip", inflate straight to the
  FIT-declared load address, then verify the FIT hash-1 subnode
  (sha256 / sha384 if available) for defense in depth on top of the
  outer wolfBoot signature. The compression property is now read
  unconditionally so a build without WOLFBOOT_GZIP can warn and fail
  closed instead of silently memcpy-ing compressed bytes as if they
  were raw.
* fit_verify_hash propagates wc_InitSha256 / wc_Sha256Update /
  wc_Sha256Final return codes (and the SHA-384 equivalents) - any
  non-zero return is treated as a verification failure so a misbehaving
  backend cannot silently degrade to a no-op.
* GZIP=1 is the new default in the FIT-using example configs (zynqmp,
  zynqmp_sdcard, polarfire_mpfs250, polarfire_mpfs250_qspi,
  versal_vmk180, versal_vmk180_sdcard); set GZIP=0 to opt out.

Ramdisk path
------------
* fit_find_images() gains a ramdisk out-arg and fdt_fixup_initrd()
  writes /chosen/linux,initrd-{start,end} as 64-bit big-endian cells.
* update_disk.c and update_ram.c load the FIT ramdisk node (under
  WOLFBOOT_FIT_RAMDISK) and patch the loaded DTB. Compressed (gzip)
  ramdisks reuse the same fit_load_image_ex() decompress path.
* RAMDISK=1 build switch defines WOLFBOOT_FIT_RAMDISK;
  WOLFBOOT_LOAD_RAMDISK_ADDRESS is plumbed through tools/config.mk ->
  Makefile sed -> include/target.h.in. Defaults to 0; when 0 the
  ramdisk stays at whatever fit_load_image returned.
* hal/zynq.c and hal/versal.c bump fdt_totalsize headroom from 512 to
  768 bytes to fit the new linux,initrd-{start,end} entries.
* config/examples/zynqmp_sdcard.config gains a commented-out opt-in
  block (RAMDISK=1, WOLFBOOT_LOAD_RAMDISK_ADDRESS=0x40000000, alt
  LINUX_BOOTARGS) so a single config file covers both rootfs-on-disk
  and FIT-bundled-initramfs flows.

Builds against the existing master configs are byte-identical when
GZIP=0 and RAMDISK is unset.
2026-05-05 10:16:16 +02:00
Daniele Lacamera 26cae311d2 Fix decrypted blob TLV parsing
F/3301
2026-04-29 12:18:04 +02:00
David Garske f2fe1f42fa ZynqMP ZCU102 SD-card boot fixes 2026-04-28 14:55:06 +02:00
Daniele Lacamera 776378ca78 Preparing release v2.8.0 + update copyright 2026-04-16 13:11:56 +02:00
Daniele Lacamera 8d9e912fb8 Addressed another round of copilot comments 2026-04-15 20:37:07 +02:00
Daniele Lacamera 0a4f8281a2 Addressed Fenrir's comments 2026-04-15 18:57:13 +02:00
Daniele Lacamera 1359aac80d Block rollback fallback in non-flash update paths
F/2254
2026-04-15 17:31:29 +02:00
Daniele Lacamera f8cbad0bdf Add final sanity checks to boot paths
F/2570
2026-04-14 07:51:21 +02:00
Daniele Lacamera 4c704a9440 boot: fail closed on flash protect errors 2026-04-09 16:36:38 +02:00
Daniele Lacamera 44c5b4ab0a Protect bootloader before application boot
F/2255
2026-04-08 19:53:50 +02:00
Daniele Lacamera 7e64e91c09 zero decrypted disk header on exit
F/1104
2026-03-22 10:08:58 +01:00
Daniele Lacamera 87a4ffc1e2 Addressed reviewers comments 2026-03-12 11:52:19 +01:00
Daniele Lacamera 2239c6e163 Added bound check to get_decrypted_blob_version
F/374
2026-03-12 09:28:51 +01:00
Daniele Lacamera ae1e9dfc06 Force-zero secrets in update_disk.c
F/97
2026-03-12 09:28:51 +01:00
David Garske d23943a5af PolarFire SoC M-Mode, QSPI and L2-LIM support
Adds support for running wolfBoot in **Machine Mode (M-mode)** on the PolarFire SoC MPFS250T, booting from eNVM and loading a signed application from **SC QSPI flash** into on-chip LIM (Loosely Integrated Memory). No HSS (Hart Software Services) or DDR is required. It also extends the existing PolarFire HAL with multi-hart support, L2 cache configuration, per-hart UART, and refactors shared code (SDHCI, SCB mailbox, linker/test-app) for both S-mode and M-mode builds.
2026-03-09 07:29:27 +01:00
Brett Nicholas 3f18028e13 add build option to skip verification of boot image 2026-03-06 17:05:45 +01:00