- Check diag_erase() return value in wolfBoot_record_failure()
- Dedicated WOLFBOOT_FAILURE_PHASE_SELF_UPDATE
- Mark the diagnostics flash write buffers XALIGNED_STACK(4) for HALs
that access the source word by word
- Ensure diagnostics, update, or swap partitions don't overlap the
bootloader
When boot/update partition verification fails during boot or update,
with this option the event is logged to flash in an ad-hoc partition.
Information about logged failures is made available to the application
through an API.
Allow to either use a master different that the sample one or to
directly use the pre-computed per-device auth values for EH and AIK.
Using the per-device value is preferred as it doesn't expose the auth
value of the sibling devices in the same fleet.
Add wolfBoot support for booting VxWorks 7 SMP 64-bit (and signed ELF
images) on the NXP T2080 (e6500) / Curtiss-Wright VPX3-152.
Key fix: bring up the e6500 cluster L2 cache in the correct order -- set
L2PE (ECC) in its own polled write BEFORE enabling L2E, with L2FI|L2LFC --
matching CW U-Boot (SDK2.0). The previous bare-L2E init left the L2 ECC
array uninitialized for the kernel's 0x1E0000 set, machine-checking VxWorks
(MCSR[IF], L2ERRDET MBECC).
Also: ePAPR spin-table SMP bring-up of all four cores, ELF in-place loader
staging-overlap fix, DPAA/LIODN + QMan/BMan init, 64-bit OS handoff
(LAW/TLB/IVOR), and NAII 68PPC2 + CW VPX3-152 board configs.
security_command_passphrase used strlen(passphrase) on a 32-byte binary
buffer from TPM unsealing that carries no null-terminator guarantee,
causing an OOB stack read whenever none of the 32 key bytes is zero.
Replace strlen with strnlen(passphrase, ATA_SECURITY_PASSWORD_LEN) using
a new constant (32, matching the ATA-8 ACS password field size) defined
in ata.h. Also add a size check in sata_unlock_disk after
sata_get_unlock_secret so a short or malformed unseal result is rejected
before reaching the ATA command path.
Three related defects:
- panic() halted with a single hlt instruction (no loop), so any
resumable interrupt (LAPIC timer via iretq) caused it to return,
allowing callers to continue executing. Add while(1) and declare
__attribute__((noreturn)) in both definition and header.
- x86_paging_setup_ptp guarded with == WOLFBOOT_PTP_NUM instead of >=,
so if the counter ever exceeded that value (after a panic() return)
the guard was permanently bypassed.
- The ptp pointer was computed before the bounds check, creating an
out-of-bounds pointer for one-past-end indices; move the assignment
to after the guard so no invalid pointer is ever formed.
Add unit-x86-paging-oob test that sets page_table_page_used to
WOLFBOOT_PTP_NUM and verifies that every subsequent call to
x86_paging_setup_ptp triggers panic (via longjmp stub) rather than
silently proceeding with an out-of-bounds memset.
disk_open() computed bytes_left = n_part * array_sz from the GPT header and
scanned the whole declared partition-entry array (one disk_read per 512-byte
chunk) to compute its CRC32 *before* comparing against ptable.part_crc. Both
n_part and array_sz are taken verbatim from the GPT header, whose only gate is
a header CRC32 the attacker can freely recompute. A crafted header with e.g.
n_part=0xFFFFFFFF forces ~10^9 disk reads before the mismatch is detected: a
pre-auth denial of service that can trip a watchdog and block boot.
Reject the header when n_part * array_sz exceeds GPT_MAX_PART_ENTRIES (128, the
UEFI default) * GPT_PART_ENTRY_SIZE before entering the scan loop. The bound is
generous enough for any standard table (128 * 128 = 16 KiB) and for the
existing oversized-array test cases, but caps the scan at 64 sectors.
Add a regression test that crafts a header with a valid header CRC and an 8 MB
declared array and asserts disk_open performs no partition-array reads.
* file level rename for ML-DSA
* Add missing source file to build system
* Update some macros
* Other minor fixes
* Update size limitations for some slight increases
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.
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.
New src/gzip.c implements DEFLATE (RFC 1951) plus the gzip wrapper
(RFC 1952) from the RFC text only. Single-pass inflate, no allocations:
the output buffer doubles as the LZ77 sliding window, so back-references
read from out[out_pos - distance]. Canonical Huffman decode using
counts[] / symbols[] tables, ~10x smaller code than fast lookup tables
which matters in the bootloader. CRC32 + ISIZE verified against the
gzip trailer. Gated by WOLFBOOT_GZIP.
include/gzip.h carries the public entry point plus the RFC-canonical
constants (magic bytes, CM=DEFLATE, fixed Huffman boundaries, EOB
symbol, dynamic block field widths, run-length repeat metadata, CRC32
init/final-XOR, header/trailer sizes, alphabet sizes) so future
maintainers can cross-reference the RFC sections by name instead of
chasing literal numbers.
Tests in tools/unit-tests/unit-gzip.c round-trip 6 corpora through host
gzip(1) and back through wolfBoot_gunzip (empty, short text, all-zeros,
structured text, pseudo-random, ~2 MB kernel-sized). 9 negative cases
cover bad magic, bad CM, reserved FLG bits, truncated header,
truncated DEFLATE body, CRC32 mismatch, ISIZE mismatch, output overflow,
and NULL parameters. All 15 pass under libcheck.
hal/zynq.c:
- Route IOU_TAPDLY_BYPASS writes through pmu_request at EL<=2 in the
<=40 MHz and <=100 MHz branches (previously only done at <=150 MHz);
the register is equally unwritable from EL2/EL1 at lower clocks.
- Add qspi_flash_reset() (RESET_ENABLE 0x66 + RESET_MEMORY 0x99),
called per chip in qspi_init so the flash starts from a known state
regardless of what FSBL/BootROM left behind (XIP, 4-byte addr,
auto-boot).
- Drop unused 'reg' in csu_aes and 'ms' in csu_init so
-Werror=unused-variable builds (OPTIMIZATION_LEVEL=0 / DEBUG=1) pass.
hal/zynq.ld:
- Move wolfBoot ORIGIN from 0x08000000 to 0x10000000. Large FIT images
(kernel load=0x00200000, payload >~126 MB) would sweep across
0x08000000 at handoff and overwrite wolfBoot's own code.
tools/scripts/zcu102/zcu102-ca53-qspi.cmm:
- Rewrite against the Lauterbach TRACE32 ZCU102 QSPI demo: PREPAREONLY
entry mode, single/dual toggle, READ_ID_TEST, separate flash dialogs
for BOOT.BIN (offset 0) and test-app/image_v1_signed.bin.
- Document the ~128 MB TRACE32 temp-memory ceiling on FLASHFILE.Create:
larger files must be split externally and loaded in chunks.