The region count truncated (n = len / SPU_FLASH_BLOCK_SIZE), so a len
smaller than one 16 KiB SPU block locked nothing and a non-multiple len
left the tail block writable, while the function returned 0 either way.
Round the block count up so the locked range covers [start, start+len)
whole (partial blocks at both ends locked whole, which only ever widens
protection), and reject len < 0. Add unit-nrf5340-flash-protect, which
sed-extracts the real function and runs it against a mock SPU region
array; mutation (revert to the truncating count) fails 3 of 6 tests.
After emitting CRLF the buffer advanced to the newline, not the byte
after it, so multiline input reprocessed the newline (stray CRLFs) and
lost the following text. Extract the CRLF conversion to
hal/nrf5340_uart.c (no nrfx) for host unit testing; add a regression
test.
- hal/nxp_p1021.c: fix ONFI status polarity (bit 0 set = fail, bit 7
clear = protected; was checking bits 0+1 set = success)
- src/libwolfboot.c: move partition state APIs under HAVE_PARTITION_TRAILERS
so CUSTOM_PARTITION_TRAILER without WOLFBOOT_FIXED_PARTITIONS links
- src/x86/ata.c: do not zeroize DMA buffer when another async op is
in progress (buffer still owned by first command's transfer)
- unit-p1021-fcm-bytes/erase-advance: update mocks to ONFI status bytes
- unit-update-ram-custom-trailer: add BOOT selection assertion via
mock_max_read_addr, PID-suffixed temp files, unlink in cleanup
- unit-update-ram-nofixed-noramboot: unlink PID-specific temp files
The reliability gate is WRCALIB, not PHY_TRAINING_STATUS. MTC is a
secondary gate skipped when TIP completes full training, and the
retry budget is 3 inner x 6 outer (up to 18 attempts), not 5.
buffer_is_all_value() early-exited on the first byte differing from
the target, so the loop trip count leaked the length of the leading
0xFF/0x00 run of the UDS, the DICE root secret read in
hal_uds_derive_key().
Replace the early exit with a volatile |= accumulator over the full
buffer, matching the constant-time compare pattern already used by
image_CT_compare() and the other secret comparisons in the tree.
Verified: gcc -S -O2 shows a straight-line loop body with only the
data-independent i < len branch; arm-none-eabi-gcc (stm32h5 preset)
compiles the file clean.
Reported by Fenrir.
The F-12879 fix publishes SHM status with plain C stores before
IPC_TASKS_SEND; without a compiler memory barrier an optimized
build can reorder the stores past the dsb asm. Matches the
existing clobber in imx95_m7.h and stm32g4.h.
hal_shm_status_set() triggered the IPC event before storing the
magic/status fields, so the peer core could wake on the event, read
stale fields, and wait for a second event that never comes. Store
the fields first, order them with a DSB, then signal; the receiver
pairs it with a DSB after clearing the event, before re-reading the
fields. Not verified on real nRF5340 hardware.
The write/erase loops discarded the JEDEC status byte from MDR and
hal_flash_command ignored the PAR (uncorrectable ECC) and FCT (FCM
timeout) bits, so failed programs, erases and uncorrectable reads
all reported success. Check P/WPS in the status byte and stop the
loop, and fail the command on PAR/FCT. The small-page FCM sequence
now ends with the status command (CM3+RSW) so MDR holds a valid
status like the large-page path; not verified on real P1021
hardware. config_io_pin now uses a single masked store for CPDIR/
CPPAR (F-12880): the clear-then-set pair could drop a concurrent
update to another pin in the same register.
F-12880, F-12881, F-12882
vault_obj_read() now separates "object absent" from a failed read, so the
power-fail test rejects a corrupted vault instead of accepting any negative.
hal_cache_invalidate() shrank 120 -> 44 bytes; the 48 it still costs every
STM32F407 build is folded into the test-size-all limits.
The weak no-op sat inside NVM_FLASH_WRITEONCE, so pkcs11_store.c failed to
link on the nrf5340/nrf54l TrustZone configs. STM32F4 and STM32G4 enable the
flash instruction/data caches and never reset them, so give them a real one.
The store commits sectors with hal_flash_erase()/hal_flash_write() and
then reads them back through the memory map - sector_ptr(),
cache_get_sector()'s refill, and the raw magic reads in check_vault().
On a part that caches flash reads (STM32 ICACHE) those reads can return
pre-erase bytes. check_vault() is the worst case: a stale magic there
does not merely read wrong, it triggers restore_backup() or a full vault
re-initialisation, losing the token.
hal/stm32wb.c: dedicated RCC_CFGR_SWS_{MSI,MASK} macros for the
clock-switch confirmation wait; SW/SWS encodings verified identical
in RM0434 6.4.3 and the STM32WB55 SVD.
unit-stm32u5-write.c: START_TEST brace on the next line, matching
the file and the unit-suite convention.
An unaligned starting address split the four word stores across two
16-byte program units, leaving partial quad-words that set
FLASH_SR_WDW and hang the wait for completion. Align the destination
down to the unit, read-modify-write the whole unit, and store through
the aligned pointer. The unit test gains unaligned-start cases.
hal_flash_write() stored both words of the 64-bit program unit
relative to the caller's address, so a write starting inside a unit
split the two stores across two units: the flash has no 32-bit
program mode, so nothing is programmed and the second store faults
on alignment. Align the destination down to the unit, take the bytes
outside the requested span from the unit itself, and store through
the aligned pointer, as hal/stm32h5.c does. The TrustZone claim is
unchanged: it is page-granular and already covers every non-secure
byte the aligned program touches.
Extend unit-stm32l5-write with unaligned-start cases. The host data
model cannot observe the program-unit split (pre-fix the bytes land
identically), so these pin the fixed layout: bytes before the
request preserved, nothing past it touched.
The HAL contract is absolute (0x08000000-based) addresses, as the
erase path and every NVM caller use, but the double-word fast path
added the flash base on top and targeted an address space past the
flash. The read-modify-write path located its unit from the request
base indexed by i/4, landing in the wrong 8-byte unit once a request
started inside one. Both paths now program the 8-byte unit at
(address + i), and the now-dead FLASHMEM_ADDRESS_SPACE define is
gone.
Add unit-stm32c0-write: runs the extracted hal_flash_write() against
a host register/flash model with a second mapping standing in for
the wrong address space (4/5 checks fail pre-fix, 5/5 pass post-fix).
The CM4 firmware DTB is unverified (unsigned FAT partition) and this
path never attaches an authenticated ramdisk, so a non-zero
linux,initrd-start/end in it would direct the signed kernel to an
unauthenticated initramfs in RAM. Zero both properties on the
relocated DTB (fail closed on fixup error) and update the SECURITY
comment to state the new behavior.
Sector 11 was at 0x818C000, inside sector 10's 256 KB range
(0x8180000-0x81C0000), so hal_flash_erase mapped the upper part of
sector 10 to sector 11 and erased the wrong sector. Sector 11 is
0x81C0000, contiguous after sector 10 and ending at FLASH_TOP.
The MSIRDY wait read RCC_CFGR (bit 1 is SW status) instead of RCC_CR,
so it never gated, and the MSI selection was cleared only in a local
variable, never written back to RCC_CFGR. The PLL was disabled while
still the SYSCLK source, dropping the system clock. Now: wait MSIRDY,
commit the MSI selection, wait for SWS to confirm, then turn off PLL.
do_boot() already returned after its panic() calls, but GetVolume() and
efi_main() did not: under UNIT_TEST panic() returns, so GetVolume() hit a
NULL deref / uninitialized return and efi_main() ran wolfBoot_start().
Return NULL / EFI_LOAD_ERROR at each site (unreachable on target).
Cap the library fw_size clamp at UINT32_MAX (a > 4 GiB file would
otherwise truncate to a small value), say 'restore' not 'store' in the
scatter-restore error message, and print stdout as well as stderr in
the compile-check scripts on failure.
panic() returns under UNIT_TEST, so the LoadImage-failure site fell
through to StartImage on a failed load. Add the return to match the
zero-size guard; on target panic() never returns, so behavior is
unchanged.
The H7 OTP memory is one-time programmable, so the keystore and UDS
are permanent once written; the H7 has no OTP block-lock register
(unlike the H5), so there is no write-protection step to perform.
Replace the misleading TODO with the reason the no-op is correct.
boot_x86_64.c declared x86_64_efi_do_boot(uint8_t *) while the HAL
defines (uint32_t *, uint8_t *): the linker connected the incompatible
pair and the call was undefined behavior, mostly latent because the
second parameter was discarded. Match the AArch64 sibling: single
const uint32_t *boot_addr in the declaration, definition and call,
and remove the unused dts_address parameter.