Commit Graph

3131 Commits (f193b9c239fdd5fcd73fda9f0cdbbe48092e2830)

Author SHA1 Message Date
Daniele Lacamera f193b9c239 F-4789: fix uint64_t overflow in squashelf range filter segment end
In the PT_LOAD range filter, segmentEnd was computed as
p_paddr + p_memsz - 1 in uint64_t with no overflow check. Both fields
come straight from the (possibly crafted) ELF64 program header. When
p_paddr + p_memsz exceeds 2^64 the result wraps below p_paddr: the
wrapped end can land back inside the requested range, so a segment whose
true span lies entirely outside the range is spuriously included (and the
converse can silently drop a valid segment). squashelf would then emit a
squashed image that wolfBoot signs and boots.

Detect the overflow before computing segmentEnd and treat such a segment
as out-of-range. ELF32 cannot overflow a uint64 sum and is unaffected.

Adds tools/squashelf/test-range-overflow.py (run via `make test`) which
fails before the fix and passes after.
2026-06-09 15:52:07 +02:00
Daniele Lacamera 740383a3f5 F-4790: clamp OTP pubkey_size in keystore_get_size to prevent OOB read
keystore_get_size() returned slot->pubkey_size verbatim from the OTP
keystore slot with no upper bound. A corrupted or mis-provisioned slot
with pubkey_size > KEYSTORE_PUBKEY_SIZE produces a positive value that
passes every caller guard (pubkey_sz < 0 / <= 0). The callers in image.c
(key_sha256/key_sha384/key_sha3_384 and the ECC verify y-coordinate
offset) then read past otp_slot_item_cache, which only holds
KEYSTORE_PUBKEY_SIZE pubkey bytes.

Reject an out-of-range pubkey_size by returning -1, matching the existing
defensive validation of item_count in keystore_num_pubkeys() and the -1
error convention the callers already handle.

Add unit-otp-keystore, which compiles flash_otp_keystore.c in isolation
and verifies keystore_get_size() rejects oversized slots.
2026-06-09 15:52:07 +02:00
Daniele Lacamera eaa6e4201a F-4973: clamp TPM-supplied nvPublic.dataSize before NV read-back in rot.c
The TPM-bus-supplied UINT16 nvPublic.dataSize was assigned to digestSz and
forwarded to wolfTPM2_NVReadAuth as the read byte count with no bound check.
wolfTPM2_NVReadAuthPolicy uses that count as the XMEMCPY length into the
caller's buffer with no separate capacity argument, so a malicious/emulated
TPM (or a pre-existing NV index larger than the hash) reporting dataSize > 64
overflows the 64-byte digest[WC_MAX_DIGEST_SIZE] stack buffer.

Clamp digestSz to sizeof(digest) before the read. Stored values are key-hash
digests (<= WC_MAX_DIGEST_SIZE), so the clamp never truncates valid data.

Add a unit-rot-auth case driving nvPublic.dataSize=1000 through the existing
mocked harness, asserting the requested read count is clamped to the buffer.
2026-06-09 15:52:07 +02:00
Daniele Lacamera 03f5193dc2 F-5129: fix stm32h7 hal_flash_erase Bank 2 sector underflow
The Bank 2 branch of hal_flash_erase() subtracted the absolute base
FLASH_BANK2_BASE (0x08100000) from the bank-relative loop offset p,
instead of the relative FLASH_BANK2_BASE_REL (0x00100000) used by every
other comparison in the function. For a Bank 2 offset (p >= 0x00100000)
this underflowed uint32_t to ~0xF8000000, with two effects:

  1. the SNB sector index programmed into FLASH_CR2 came from the
     underflowed value (always sector 0, with stray high bits leaking
     into other CR2 fields), and
  2. the subtraction mutated the loop variable p itself, so after
     p += FLASH_PAGE_SIZE the offset jumped past any end_address and the
     loop exited after a single iteration.

The combined result: any multi-sector Bank 2 erase touched only one
sector with the wrong index, silently leaving the remaining requested
sectors (e.g. the SWAP partition at 0x081C0000) unerased.

Compute the sector index in a temporary from FLASH_BANK2_BASE_REL so the
loop variable is preserved, and mask it with FLASH_CR_SNB_MASK before
shifting into FLASH_CR2.

Adds unit-flash-erase-h7, which compiles hal_flash_erase() in isolation
(guarded by WOLFBOOT_UNIT_TEST_FLASH_ERASE, mirroring the unit-mpusize
approach for boot_arm.c) against mocked flash registers and asserts that
a two-sector Bank 2 erase programs sectors 6 and 7 across two iterations.
2026-06-09 15:52:07 +02:00
Daniele Lacamera 74b8fc0664 F-5131: fix stale delta inverse-patch offset when cert chain expands header
base_diff() captured patch_inv_off = len3 + CMD.header_sz before calling
make_header_delta(), which signs the delta image via make_header_ex(is_diff=1).
When a certificate chain is present, the delta (is_diff=1) header needs ~72
more bytes than the non-delta header for the four delta TLVs plus the base-hash
TLV. For a window of cert-chain sizes, header_required_size(is_diff=0) still fit
the current CMD.header_sz while header_required_size(is_diff=1) did not, so
make_header_ex(is_diff=1) grew CMD.header_sz to the next power of two *after*
patch_inv_off was captured. The HDR_IMG_DELTA_INVERSE TLV then encoded a stale,
too-small offset; the bootloader (update_flash.c) uses it as a raw byte offset
into the update partition to locate the inverse patch, so rollback read from the
wrong offset and failed.

Resolve the is_diff=1 header-size expansion (same logic as make_header_ex)
before computing patch_inv_off. Add unit-sign-delta-cert-inv-off.py, which signs
an ed25519 delta with a 300-byte chain (inside the triggering window) and
asserts the inverse patch is the trailing HDR_IMG_DELTA_INVERSE_SIZE bytes of
the file; it fails before this fix.
2026-06-09 15:52:07 +02:00
Daniele Lacamera 8d235cf215 F-5132: complete mpusize() table so MPU stays enabled for >64KB wolfBoot
The mpusize() lookup in boot_arm.c only covered sizes up to 64KB and
returned MPUSIZE_ERR for anything larger. mpu_init() passes the wolfBoot
.text+.rodata span (_stored_data - _start_text) to mpusize() and bails
out at the MPUSIZE_ERR guard before reaching mpu_on(). Any build whose
bootloader image exceeds 64KB (TrustZone, PQC, delta-update, or several
crypto algorithms) therefore left MPU_CTRL clear, silently disabling all
five MPU regions for the lifetime of the bootloader.

Fill in the missing power-of-two entries from 128KB through 128MB
(ARMv7-M SIZE field = log2(bytes)-1, shifted into the RASR layout) so
the flash region size is resolved and mpu_on() is reached.

Add tools/unit-tests/unit-mpusize.c, which includes the real mpusize()
from boot_arm.c (guarded to its host-portable MPU helpers via
WOLFBOOT_UNIT_TEST_MPU) and checks that sizes above 64KB no longer map
to MPUSIZE_ERR. The test fails before this fix and passes after.
2026-06-09 15:52:07 +02:00
Daniele Lacamera 84d5bd3dde F-5352: emit 4-byte delta size TLVs from Python signer
sign.py encoded HDR_IMG_DELTA_SIZE and HDR_IMG_DELTA_INVERSE_SIZE with a
2-byte length via struct.pack("<H", ...), but wolfBoot_get_delta_info()
accepts those tags only when wolfBoot_find_header() returns
sizeof(uint32_t). Delta images produced by sign.py were therefore signed
with parseable TLVs yet rejected by the bootloader before the patch was
applied. Encode both size TLVs as 4-byte little-endian values, matching
sign.c (header_append_tag_u32) and the bootloader parser.

Add a regression test that signs a real delta image with sign.py and
asserts the bootloader-side parse recovers each delta TLV with the
required 4-byte length.
2026-06-09 15:50:48 +02:00
Daniele Lacamera d280262028 F-5356: bound i.MX RT flash write copy to caller buffer length
hal_flash_write() programs one full CONFIG_FLASH_PAGE_SIZE (256/512 byte)
page per loop iteration but unconditionally memcpy'd a whole page out of
the caller's buffer regardless of len. Sub-page writes - notably the
1-byte trailer updates from set_trailer_at()/trailer_write() on the
non-NVM_FLASH_WRITEONCE i.MX RT configs - therefore overread the source
buffer (e.g. 255 bytes past a 1-byte stack value) and could program
adjacent stack/RAM contents into flash.

Bound the copy to min(page, len - i) and pad the rest of the page buffer
with the erased value (0xFF). 0xFF is a no-op for NOR programming, so the
existing flash contents of the rest of the page are preserved.
2026-06-09 15:50:48 +02:00
Daniele Lacamera 3bfd7de34d F-5674: cap PCI IO BAR allocator at the 16-bit IO ceiling
A device advertising a 64KB IO BAR pushed the IO allocator cursor
(info->io) past 0x10000 because pci_program_bar used 0xffffffff as the
IO BAR limit. The PCI-to-PCI bridge IO base/limit registers are 8-bit
and only carry address bits [15:8], so io_start >> 8 silently narrows a
0x20000 cursor to 0x00, programming a bogus bridge IO window
0x0000-0x0FFF that forwards legacy IO (8259A PIC, 8254 PIT, MC146818
RTC) to the secondary bus.

x86 IO space is 16-bit, so IO BARs must never be allocated above 0xFFFF.
Cap the IO BAR allocator limit at PCI_IO32_LIMIT (0x10000): oversized IO
BARs are now skipped at allocation time and the bridge IO window is
programmed from the real cursor, never narrowing onto legacy IO.

Add test_program_bridge_io_64k_no_narrow proving the bridge IO window is
no longer mis-programmed. The post-enum IO OOM case is removed as the
cap makes that wrap unreachable.
2026-06-09 15:50:48 +02:00
Mattia Moffa 9a68ef15dd arm_tee_psa_ipc: copy NS buffers into S before use
(Copilot suggestion)
2026-06-09 15:50:14 +02:00
Mattia Moffa ceb959cf70 PKCS#11 NSC veneers: sanitize non-secure pointers
Fixes F#4259

cmse_nonsecure_entry doesn't intrinsically validate NS-supplied
pointers, so the veneers let a hostile NS caller aim them into Secure
SRAM and make wolfPKCS11 read/write secure memory. Validate every NS
pointer with cmse_check_address_range() (recursing into nested pointers)
and pass wolfPKCS11 only secure copies, so it never dereferences NS
memory -- deep and TOCTOU-safe. Also stop leaking the secure function
table via C_GetFunctionList.
2026-06-09 15:50:14 +02:00
Mattia Moffa fdec7a1fe8 Add explicit integrity/authenticity failure tests in update-disk suite
Fixes F#5350
2026-06-09 15:50:14 +02:00
Mattia Moffa 4830817bef Layerscape 1028a flash erase: reset status to 0 at each iteration
Fixes F#5347
2026-06-09 15:50:14 +02:00
Mattia Moffa b193bfbf68 Layerscape 1028a: add missing semicolon in while loop
Fixes F#5346
2026-06-09 15:50:14 +02:00
Mattia Moffa 6ac1fc1d07 Layerscape 1028a: fix pointer arithmetic errors
Fixes F#5345
2026-06-09 15:50:14 +02:00
Mattia Moffa 833373f57c Polarfire: prevent integer overflow in address bounds check
Fixes F#5128
2026-06-09 15:50:14 +02:00
Mattia Moffa 6221144fa1 Prevent integer underflowing out-of-bounds ELF segments
Fixes F#4257
2026-06-09 15:50:14 +02:00
Mattia Moffa 88bb215736 Validate NS inputs to TrustZone flash veneers
Fixes F#4333-4335
2026-06-09 15:50:14 +02:00
Mattia Moffa 74c92014c8 arm_tee_psa_ipc: validate NS pointers via cmse_check_address_range
Fixes F#4332, F#4336, F#4709
2026-06-09 15:50:14 +02:00
David Garske b60bd311a3 Peer review feedback (thanks Daniele) 2026-06-09 15:30:27 +02:00
David Garske 14f6e4a298 Add wolfBoot FIT support for loading bitstream 2026-06-09 15:30:27 +02:00
David Garske a296902049
Merge pull request #789 from bigbrett/wolfhsm-remove-pem-to-der
wolfHSM quickfix
2026-06-08 10:54:31 -07:00
Mattia Moffa d915c60f39
Merge pull request #788 from danielinux/fenrir-fixes-2026-06-05
Fenrir fixes 2026 06 05
2026-06-06 03:37:44 +02:00
Daniele Lacamera 3a8404b5e2 Fix test regression, addressed copilot comments 2026-06-05 20:55:52 +02:00
Daniele Lacamera f9d7b79967 Updated .gitignore with new unit tests 2026-06-05 20:00:11 +02:00
Daniele Lacamera 3bf9a76462 F-4337: validate NS pointer in wolfBoot_nsc_get_partition_state CMSE veneer
wolfBoot_nsc_get_partition_state is a cmse_nonsecure_entry secure-gateway
veneer (compiled with CSME_NSE_API under __WOLFBOOT && TZEN). The output
pointer st arrives directly from the non-secure caller and was forwarded
unchecked to wolfBoot_get_partition_state, which performs *st = *state
unconditionally once the partition magic check passes (libwolfboot.c:735).
Because the veneer runs in Secure state with full write access to Secure
SRAM, a malicious NS caller could aim st at Secure memory and turn the
veneer into a confused-deputy 1-byte write primitive (the partition-state
byte, e.g. 0x00/0xFF) against Secure SRAM (magic fields, key-store flags,
version counters).

Validate the st range with cmse_check_address_range
(CMSE_NONSECURE | CMSE_MPU_READWRITE) before forwarding, returning -1 when
the range is not accessible from the non-secure world. The check is wrapped
in WOLFBOOT_NSC_NS_RW, guarded by __ARM_FEATURE_CMSE == 3U so non-CMSE
builds (no security boundary) collapse to a plain non-NULL pass-through.
Same fix pattern as F-4416/F-4417/F-4644 (wc_callable.c, fwtpm_callable.c,
tpm.c).

Verified by compiling the veneer with cortex-m33 -mcmse: the expected
bl cmse_check_address_range is emitted before the callee. The bug is a
TrustZone Secure/Non-secure partitioning issue that cannot be exercised on
the host unit-test build (the TZEN veneer block is not compiled there).
2026-06-05 19:51:13 +02:00
Daniele Lacamera 53601308aa F-4338: skip MMIO BAR with zero alignment to prevent length-wrap cursor stall
A hostile or malformed PCIe endpoint can return a BAR size-probe readback
whose address bits (31:4) are all zero but is itself non-zero (e.g. 0x8,
only the prefetch indicator). This passes the bar_value == 0 guard, yields
bar_align == 0, and makes length = (~bar_align) + 1 wrap to 0 in uint32_t.
With length == 0 the allocator cursor *base = bar_value + length is left
unchanged, so the next BAR is programmed onto the same MMIO address,
colliding the windows of all following devices.

Treat a BAR with no writable address bits as unimplemented and skip it via
restore_bar before computing length. Legitimate MMIO BARs always have at
least one writable address bit; IO BARs already force the high bits, so
bar_align is never 0 for them.

Add a unit test that simulates the malformed probe readback and verifies the
BAR is restored (not programmed) and does not collide with the next BAR.
2026-06-05 19:49:13 +02:00
Daniele Lacamera 2ebc304cae F-4416: validate NS pointers in wcs_fwtpm_transmit CMSE veneer
wcs_fwtpm_transmit is a cmse_nonsecure_entry veneer that receives the
command buffer (cmd), response buffer (rsp) and response-size pointer
(rspSz) directly from the non-secure caller. It only checked for NULL and
size bounds, then passed the pointers to FWTPM_ProcessCommand (reading cmd,
writing rsp) and dereferenced rspSz. A non-secure caller could aim rsp at
Secure SRAM (confused-deputy write, forging TPM responses) or cmd at Secure
memory (leak through the command path).

Validate each NS-supplied range with cmse_check_address_range before first
use: cmd as read-only (cmdSz), rspSz as read-write (sizeof) before
dereferencing it, and rsp as read-write (rspCapacity). The checks are
wrapped in WCS_FWTPM_NS_R/WCS_FWTPM_NS_RW, guarded by __ARM_FEATURE_CMSE ==
3U so non-CMSE builds collapse to a non-NULL pass-through. Matches the
existing guards in wc_callable.c and tpm.c.

Verified by building wolfboot.elf with the stm32h5-tz-fwtpm config (-mcmse);
the bug is a TrustZone Secure/Non-secure partitioning issue that cannot be
exercised on the host unit-test build.
2026-06-05 19:45:41 +02:00
Daniele Lacamera e1dd13e4da F-4417: validate NS pointer in wcs_get_random CMSE veneer with cmse_check_address_range
wcs_get_random is a cmse_nonsecure_entry secure gateway (wc_callable.o is in
SECURE_OBJS, built with -mcmse when WOLFCRYPT_TZ=1, e.g.
config/examples/stm32l5-wolfcrypt-tz.config). The rand pointer and size arrive
directly from the non-secure caller and were passed unchecked to
wc_RNG_GenerateBlock, which writes size bytes through rand. Because Secure code
can write Secure SRAM, a malicious NS caller could pass a Secure pointer and
turn the veneer into a confused-deputy write primitive against Secure memory
(RNG output aimed at key buffers, RNG state, or a Secure stack return address).

Validate the full rand/size range with cmse_check_address_range
(CMSE_NONSECURE | CMSE_MPU_READWRITE) before the write, returning BAD_FUNC_ARG
when the range is not accessible from the non-secure world. The check is wrapped
in WOLFBOOT_WCS_NS_RW, guarded by __ARM_FEATURE_CMSE == 3U so non-CMSE builds
(no security boundary) collapse to a plain non-NULL pass-through. The range
check already rejects oversized lengths that overrun NS-accessible memory, so no
separate size cap is needed. Same fix pattern as F-4644 (TPM veneers in tpm.c).

Verified by compiling src/wc_callable.c with cortex-m33 -mcmse
-DWOLFCRYPT_SECURE_MODE; the bug is a TrustZone partitioning issue that cannot
be exercised on the host unit-test build.
2026-06-05 19:44:07 +02:00
Daniele Lacamera 091b4eabbe F-4644: validate NS pointers in TPM CSME_NSE_API veneers with cmse_check_address_range
The eleven CSME_NSE_API TPM veneers in src/tpm.c are cmse_nonsecure_entry
gateways when built with TZEN=1 (e.g. config/examples/stm32h5-tz-tpm.config,
which exposes them to the non-secure STM32H5 test app). Each accepted a typed
pointer from the non-secure caller and immediately used it as a dereference or
memset/XMEMSET target on the Secure side -- memset(caps), memset(handles),
memset(getTime), XMEMSET(quoteResult), and the in/out forwards to
TPM2_GetCapability / TPM2_ParseAttest. Because Secure code can write Secure
SRAM, a malicious non-secure caller could pass a Secure pointer and turn any of
these veneers into a confused-deputy write primitive against Secure memory.

Validate every non-secure-supplied pointer with cmse_check_address_range
(CMSE_NONSECURE, plus CMSE_MPU_READWRITE for write targets) before the first
use, returning BAD_FUNC_ARG (or NULL for the string helpers) when the range is
not accessible from the non-secure world. The check is wrapped in
WOLFBOOT_TPM_NS_RW/WOLFBOOT_TPM_NS_R, guarded by __ARM_FEATURE_CMSE == 3U so
non-CMSE builds (where there is no security boundary) collapse to a plain
non-NULL pass-through. Buffer sizes use the caller-provided/known capacities
(name_sz, error_sz, *certSz, PCR digest size).

Verified by building wolfboot.elf with the stm32h5-tz-tpm config (-mcmse);
the bug itself is a TrustZone Secure/Non-secure partitioning issue that cannot
be exercised on the host unit-test build.
2026-06-05 19:41:59 +02:00
Daniele Lacamera d175c819cd F-4645: bound load_linux kernel size to prevent syssize*16 overflow
load_linux() computed the protected-mode kernel size as the uint32_t
product param.hdr.syssize * 16 (src/x86/linux_loader.c), where syssize
is copied verbatim from the (authenticated) bzImage at offset 0x1f4.
The multiplication wraps for any syssize > 0x0FFFFFFF: syssize=0x10000000
yields kernel_size=0 (DoS), and syssize=0x1FFFFFFF/0xFFFFFFFF yields
kernel_size=0xFFFFFFF0 (~4 GiB). That value fed straight into
memcpy((uint8_t*)KERNEL_LOAD_ADDRESS, linux_image + param_size,
kernel_size) with no cap, overwriting wolfBoot stage2, FSP data, and the
heap (CWE-190 -> CWE-680).

Fix at the root: linux_kernel_size() computes syssize * 16 in 64-bit and
rejects the image (panic) when the result is zero or does not fit in the
destination window [KERNEL_LOAD_ADDRESS, tolum). tolum is the top of low
usable memory the FSP already reports and that the ELF boot path uses as
its load upper bound (src/boot_x86_fsp_payload.c). The kernel load only
runs under WOLFBOOT_FSP (the non-FSP path panics earlier at the memory
map step), so tolum is always available there.

Add unit-linux-loader-syssize regression test (x86 32bit, standalone)
that feeds the PoC overflow values and asserts they are rejected while a
legitimate kernel and the exact-fit boundary are accepted.
2026-06-05 19:33:51 +02:00
Daniele Lacamera 2766450123 F-4710: reject oversized FDT property length to prevent ~4GB FIT memcpy
fdt_next_tag() advanced its struct cursor with
  offset += sizeof(struct fdt_property) - FDT_TAGSIZE + fdt32_to_cpu(*lenp);
using unsigned arithmetic. A property whose len field is 0xFFFFFFFF
wrapped this to a +7 advance, so the malformed node slipped past the
fdt_offset_ptr() bounds check at the end of fdt_next_tag(). The bogus
length then propagated up through fdt_get_property_by_offset() /
fdt_getprop() and was returned by fit_load_image() as *lenp = -1.

In the MMU FIT boot path, wolfBoot_start() (src/update_ram.c:465) aliases
that out-parameter through (int*)&dts_size, turning -1 into a uint32_t
0xFFFFFFFF, and the only guard before the relocation is dts_ptr != NULL,
so memcpy(WOLFBOOT_LOAD_DTS_ADDRESS, dts_ptr, 0xFFFFFFFF) ran (CWE-680).
A FIT subimage with no "load" property reaches this with the inner copy
skipped, so the giant size hits the outer DTS relocation directly.

Fix at the root: a property value can never exceed the blob, so reject
any FDT_PROP whose declared length is greater than fdt_totalsize()
before the cursor arithmetic. This closes the wrap for every caller of
fdt_next_tag() (including the other fit_load_image() sinks), not just the
DTS path. Legitimate properties (len <= size_dt_struct < totalsize) are
unaffected.

Add a regression test to unit-fdt: a hand-built FIT whose /images/kernel-1
"data" property declares len=0xFFFFFFFF must make fit_load_image_ex()
fail closed (return NULL) instead of handing back a live pointer with a
negative length. The test fails before this change and passes after.
2026-06-05 19:26:28 +02:00
Daniele Lacamera a8a9eec96b F-4711: bound e820 entries to prevent boot_params stack overflow
e820_add_entry_cb() appended every FSP-supplied resource descriptor into
boot_params->e820_table[] with no check against E820_MAX_ENTRIES_ZEROPAGE
(128). A HOB list with more than 128 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
entries therefore wrote FSP-controlled addr/size/type triples past the
fixed-size table into the stack-allocated boot_params in load_linux(),
corrupting adjacent fields and the saved return address.

Reject any entry once the table is full (return non-zero, which aborts the
HOB iteration). e820_entries stays uint8_t since it is a fixed-offset field
in the Linux zero-page layout and the cap makes the 256 wrap unreachable.

Add unit-linux-loader-e820 regression test (x86 32bit, standalone) that
feeds 200 descriptors and asserts the table never overflows.
2026-06-05 19:19:05 +02:00
Daniele Lacamera 277e8013cc F-4965: bound hdr->pos in bitmap_put to prevent OOB write from corrupted vault
A power fault during cache_commit(0) can leave a node header in the
keyvault with valid magic/tok/obj/type but pos left as erased flash
(0xFFFFFFFF). On the next boot find_object_buffer() detects the
data-sector mismatch and calls delete_object(), which reaches
bitmap_put(0xFFFFFFFF, 0). bitmap_put computed octet = pos/8 and indexed
cached_sector[4 + octet] with no bounds check, writing ~512 MB past the
static sector buffer. Reject pos >= KEYVAULT_MAX_ITEMS so a corrupted
header can no longer turn into an out-of-bounds write.

Adds a unit test that seeds a node with pos=PKCS11_INVALID_ID and
confirms delete_object() no longer faults.
2026-06-05 19:13:36 +02:00
Daniele Lacamera 8cff2e8792 F-5672: cache NS in_vec[1].len in ARM_TEE_PS_SET to close TOCTOU double-fetch
The ARM_TEE_PS_SET branch of arm_tee_psa_call() read in_vec[1].len
directly from non-secure memory four times: the WOLFBOOT_PS_MAX_DATA
bounds check, the null-data guard, the copy gate, the XMEMCPY length,
and the entry->size assignment. in_vec lives in NS RAM, and on ARMv8-M
with AIRCR.PRIS=0 a higher-priority NS interrupt can preempt Secure
thread-mode execution (and an NS-accessible DMA engine can mutate NS RAM
independently) between the bounds check and the copy. An NS attacker
racing either mechanism could grow the length past WOLFBOOT_PS_MAX_DATA
after it was validated, overflowing the fixed entry->data[512] buffer in
Secure SRAM into adjacent Secure globals.

Snapshot the length once into a Secure-stack local (data_len) right
after capturing the in_vec bases and use only that local for every
subsequent check, the XMEMCPY operand, and entry->size. This follows the
standard PSA/CMSE practice of copying NS-supplied scalars to the Secure
stack before validating and using them.
2026-06-05 18:50:47 +02:00
Brett Nicholas 9b8629e626 remove pem to der define to reduce image size 2026-06-05 10:44:30 -06:00
David Garske e27e81f659 Improve SRAM partitioning for Ethernet DMA 2026-06-03 10:54:20 +02:00
David Garske 1e4fbc49b2 Peer review fixes (thanks Copilot) 2026-06-03 10:54:20 +02:00
David Garske bbb4d66479 stm32h5: clear MPCBB SRAM2/3 PRIVCFGR so NS ETH DMA can access them 2026-06-03 10:54:20 +02:00
David Garske 5b51344421 stm32h5: cede SRAM2 + clear GPIO SECCFGR for NS apps (TZEN=1) 2026-06-03 10:54:20 +02:00
David Garske 8fe46bb40f Peer review fixes (thanks Copilot)
hal/stm32g4.c:
- hal_flash_write unaligned path: rebase the aligned doubleword on
  (address + i), not the initial address; index as dst[0]/dst[1].
  The old form skipped to the wrong DW once i advanced past 8 with
  an unaligned starting address.
- hal_flash_erase: end_address was address + len - 1 paired with a
  strict less-than, which dropped the last page when len straddled a
  page boundary by one byte. Use address + len.
- flash_clear_errors / EOP clear at end of hal_flash_write: FLASH_SR
  bits are W1C. Read-modify-write via |= can clear unrelated W1C
  bits that happen to be set. Write the mask directly.
- uart_write: cast through uint8_t before promoting to uint32_t so
  high-bit chars do not sign-extend into TDR.

hal/stm32g4.h:
- DMB/ISB/DSB: add the "memory" clobber so the compiler also treats
  them as scheduling barriers, not just hardware-level fences.

hal/stm32g4.ld:
- Rename the output section .edidx to .ARM.exidx to match the
  input-section pattern and standard Cortex-M linker scripts.
2026-05-29 13:10:15 +02:00
David Garske c075549ea2 Add wolfBoot support for STM32G4 2026-05-29 13:10:15 +02:00
David Garske 0cb6bd42ac Vorago VA416x0: simplify iram_write/iram_fill (single RMW path) 2026-05-29 13:09:19 +02:00
David Garske 9786f5608b Add wolfBoot port for STM32N6 (NUCLEO-N657X0-Q)
Co-authored-by: Aidan Garske <aidan@wolfssl.com>
2026-05-28 16:49:57 +02:00
Brett Nicholas a1f86fa1c2 expose root CA list as makefile var 2026-05-26 17:37:50 +02:00
Brett Nicholas b8bc0a75e5 Add support for wolfHSM multi-root certificate verification 2026-05-26 17:37:50 +02:00
Alex Lanzano a41a98551b Fix mcxn build by providing the RNG for TZ_PSA builds 2026-05-26 17:13:17 +02:00
Yosuke Shimizu f4d5340641 Add hardware-based DICE on mcxn 2026-05-21 20:49:20 +02:00
David Garske b983fa7717
Merge pull request #783 from Frauschi/mldsa_rename
Continue the ML-DSA renaming
2026-05-19 12:03:28 -07:00
Tobias Frauenschläger 6e60abd034 Continue the ML-DSA renaming 2026-05-19 11:21:20 -07:00