Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
228c9d6
F-6407: zeroize static cached_sector after each flash commit in psa_s…
danielinux Jul 2, 2026
60acdc2
F-6402: add negative tests pinning wolfBoot_check_rot digest comparison
danielinux Jul 2, 2026
20f11ae
F-6129: zeroize disk-unlock secret before the state-mismatch panic in…
danielinux Jul 2, 2026
cd4e4be
F-5968: zeroize disk-unlock passphrase from static ATA command buffer
danielinux Jul 2, 2026
9ce750f
F-5965: skip wb_diff match candidates whose offset MSB collides with ESC
danielinux Jul 2, 2026
fea97c5
F-5963: fix over-advance of address/len in unaligned hal_flash_write …
danielinux Jul 2, 2026
8df9689
F-6408: zeroize UDS from OTP keystore generator's heap and stack buffers
danielinux Jul 2, 2026
f20a1e1
F-6403: add successful-boot test coverage for HW-swap wolfBoot_start
danielinux Jul 2, 2026
e09074a
F-6401: emit build-time warning for FPGA_NONFATAL=1
danielinux Jul 2, 2026
32e41f0
F-6399: fix imx_rt DCACHE invalidation to include down-alignment offset
danielinux Jul 2, 2026
e38296c
F-6398: fix OOB write in bmpatch when reconstructed image grows past …
danielinux Jul 2, 2026
dd0712e
F-6130: clear disk_encrypt_key/nonce before panic paths that skip the…
danielinux Jul 2, 2026
9a25fae
F-6127: fix custom-TLV 8-byte value saturation in arg2num
danielinux Jul 2, 2026
72186fa
F-6126: add mutation-pinning test coverage for wolfBoot_check_flash_i…
danielinux Jul 2, 2026
eb5574f
F-6124: emit build-time warning for SIGN=NONE / WOLFBOOT_NO_SIGN
danielinux Jul 2, 2026
102ddc3
F-5964: fix stale in-word offset in hal_flash_write byte-wise path (s…
danielinux Jul 2, 2026
dd16ccb
F-6405: pin partition-fit accept boundary in wolfBoot_open_image_addr…
danielinux Jul 2, 2026
c4e853e
F-6131: enforce full-transfer bounds check in spi_flash_read/spi_flas…
danielinux Jul 2, 2026
0955a42
Added new tests to .gitignore
danielinux Jul 2, 2026
aecf904
hal: advance source index in aligned flash-write fast path
danielinux Jul 2, 2026
d977baa
hal/mcxw: fix truncated empty-word sentinel
danielinux Jul 2, 2026
103eec9
tools/delta: check pwrite result in bmpatch
danielinux Jul 2, 2026
d383fc1
unit-tests: build otp-keystore-gen test without generated keystore.c
danielinux Jul 2, 2026
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
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ tools/unit-tests/unit-linux-loader-e820
tools/unit-tests/unit-linux-loader-syssize
tools/unit-tests/unit-mpusize
tools/unit-tests/unit-otp-keystore
tools/unit-tests/unit-otp-keystore-gen-zeroize
tools/unit-tests/unit-tpm-api-names
tools/unit-tests/unit-elf-bss-guard
tools/unit-tests/unit-fit-fpga
Expand All @@ -210,6 +211,20 @@ tools/unit-tests/unit-flash-erase-u3
tools/unit-tests/unit-flash-erase-wb
tools/unit-tests/unit-fwtpm-nv-oob
tools/unit-tests/unit-x86-paging-oob
tools/unit-tests/unit-ahci-unlock-panic
tools/unit-tests/unit-ata-security-passphrase-zeroize
tools/unit-tests/unit-arm-tee-psa-ipc
tools/unit-tests/unit-flash-write-mcxa
tools/unit-tests/unit-flash-write-same51
tools/unit-tests/unit-flash-write-samr21
tools/unit-tests/unit-image-elf-scatter
tools/unit-tests/unit-image-hybrid
tools/unit-tests/unit-imx-rt-cache-align
tools/unit-tests/unit-update-disk-oob
tools/unit-tests/unit-update-ram-enc
tools/unit-tests/unit-update-ram-enc-nopart
tools/unit-tests/unit-va416x0-fram
tools/unit-tests/unit-wolfhsm_flash_hal



Expand Down
9 changes: 5 additions & 4 deletions hal/imx_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <target.h>
#include "image.h"
#include "printf.h"
#include "imx_rt.h"
#include "fsl_cache.h"
#include "fsl_common.h"
#include "fsl_iomuxc.h"
Expand Down Expand Up @@ -966,8 +967,8 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
* (see definition of DCACHE_InvalidateByRange).
* To ensure all data is included we align the address downwards, and the length upwards.
*/
uint32_t aligned_address = address - (address % 32);
uint32_t aligned_len = len + (32 - (len % 32));
uint32_t aligned_address, aligned_len;
hal_flash_cache_align_range(address, (uint32_t)len, &aligned_address, &aligned_len);
DCACHE_InvalidateByRange(aligned_address, aligned_len);
/* Re-enable interrupts */
asm volatile("cpsie i");
Expand Down Expand Up @@ -1010,8 +1011,8 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
* (see definition of DCACHE_InvalidateByRange).
* To ensure all data is included we align the address downwards, and the length upwards.
*/
uint32_t aligned_address = address - (address % 32);
uint32_t aligned_len = len + (32 - (len % 32));
uint32_t aligned_address, aligned_len;
hal_flash_cache_align_range(address, (uint32_t)len, &aligned_address, &aligned_len);
DCACHE_InvalidateByRange(aligned_address, aligned_len);
/* Re-enable interrupts */
asm volatile("cpsie i");
Expand Down
46 changes: 46 additions & 0 deletions hal/imx_rt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* imx_rt.h
*
* Support routines for the i.MX RT HAL, kept free of NXP MCUXpresso SDK
* dependencies so they can be exercised directly in the host unit tests.
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef IMX_RT_H
#define IMX_RT_H

#include <stdint.h>

/* Flash is memory mapped, so after a program/erase, the affected range must
* be invalidated in the data cache to ensure coherency. The cache line size
* is 32 bytes, so both the address and length passed to
* DCACHE_InvalidateByRange() must be 32-byte aligned: the address is rounded
* down, and the length is rounded up by the same down-alignment offset plus
* "len", so that the invalidated range always fully covers
* [address, address + len). */
static inline void hal_flash_cache_align_range(uint32_t address, uint32_t len,
uint32_t *aligned_address, uint32_t *aligned_len)
{
uint32_t start = address - (address % 32);
uint32_t unaligned_len = len + (address - start);

*aligned_address = start;
*aligned_len = unaligned_len + ((32 - (unaligned_len % 32)) % 32);
}

#endif /* IMX_RT_H */
5 changes: 3 additions & 2 deletions hal/kinetis.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,14 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
if (ret != kStatus_FTFx_Success)
return -1;
}
address += i;
len -= i;
address = address_align + i;
len -= (int)(i - start_off);
} else {
uint32_t len_align = len - (len & 0x07);
ret = FLASH_Program(&pflash, address, (uint8_t*)data + w, len_align);
if (ret != kStatus_FTFx_Success)
return -1;
w += len_align;
len -= len_align;
address += len_align;
}
Expand Down
5 changes: 3 additions & 2 deletions hal/mcxa.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,15 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
if (ret != kStatus_Success)
return -1;
}
address += i;
len -= i;
address = address_align + i;
len -= (int)(i - start_off);
}
else {
uint32_t len_align = len - (len & 0x0F);
ret = FLASH_ProgramPhrase(&pflash, address, (uint8_t*)data + w, len_align);
if (ret != kStatus_Success)
return -1;
w += len_align;
len -= len_align;
address += len_align;
}
Expand Down
7 changes: 4 additions & 3 deletions hal/mcxw.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
int w = 0;
const uint32_t flash_word_size = 16;
const uint32_t empty_qword[4] = {
0xFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
};

while (len > 0) {
Expand All @@ -172,8 +172,8 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
if (memcmp(aligned_qword, empty_qword, flash_word_size) != 0) {
write_flash_qword((uint32_t *)address_align, aligned_qword);
}
address += i;
len -= i;
address = address_align + i;
len -= (int)(i - start_off);
}
else {
uint32_t i;
Expand All @@ -183,6 +183,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
write_flash_qword((uint32_t *)(address + i),
(const uint32_t *)(data + w + i));
}
w += len_align;
len -= len_align;
address += len_align;
}
Expand Down
11 changes: 6 additions & 5 deletions hal/same51.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,9 @@ void hal_init(void)
/* Turn off watchdog */
WDT_CTRL &= (~WDT_EN);
/* Run the bootloader with interrupts off */
#ifndef WOLFBOOT_UNIT_TEST_FLASH_WRITE
__asm__ volatile ("cpsid i");
#endif

/* Initialize clock */
clock_init();
Expand Down Expand Up @@ -357,17 +359,16 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
} else {
uint32_t val;
uint8_t *vbytes = (uint8_t *)(&val);
uint32_t off = (address % 4);
dst = (uint32_t *)(address - off);
uint32_t dst_idx = (i + off) >> 2;
val = dst[dst_idx];
uint32_t off = ((address + i) % 4);
dst = (uint32_t *)(address + i - off);
val = *dst;
while (off < 4) {
if (i < len)
vbytes[off++] = data[i++];
else
off++;
}
dst[dst_idx] = val;
*dst = val;
}
if ((i == len) || ((i % 16)== 0))
NVMCTRLB = (NVMCMD_WQW | NVMCMD_KEY);
Expand Down
11 changes: 6 additions & 5 deletions hal/samr21.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ void hal_init(void)
{

WDT_CTRL &= (~WDT_EN);
#ifndef WOLFBOOT_UNIT_TEST_FLASH_WRITE
__asm__ volatile ("cpsid i");
#endif
uint32_t i, reg;
/* enable clocks for the power, sysctrl and gclk modules */
APBAMASK_REG = APBAMASK_PM_EN | APBAMASK_SYSCTRL_EN | APBAMASK_GCLK_EN;
Expand Down Expand Up @@ -176,17 +178,16 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
} else {
uint32_t val;
uint8_t *vbytes = (uint8_t *)(&val);
uint32_t off = (address % 4);
dst = (uint32_t *)(address - off);
uint32_t dst_idx = (i + off) >> 2;
val = dst[dst_idx];
uint32_t off = ((address + i) % 4);
dst = (uint32_t *)(address + i - off);
val = *dst;
while (off < 4) {
if (i < len)
vbytes[off++] = data[i++];
else
off++;
}
dst[dst_idx] = val;
*dst = val;
}
}
/* Enable write protection */
Expand Down
2 changes: 2 additions & 0 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ endif

## DSA Settings
ifeq ($(SIGN),NONE)
$(warning SIGN=NONE / WOLFBOOT_NO_SIGN=1 disables firmware signature verification; images are NOT authenticated. Do not use in production.)
SIGN_OPTIONS+=--no-sign
ifeq ($(HASH),SHA384)
STACK_USAGE=3760
Expand Down Expand Up @@ -986,6 +987,7 @@ WOLFBOOT_LOAD_FPGA_ADDRESS ?= 0
# logged warning that continues the boot.
FPGA_NONFATAL ?= 0
ifeq ($(FPGA_NONFATAL),1)
$(warning FPGA_NONFATAL=1 continues booting when the FPGA bitstream fails to load; the device may run without security-relevant programmable logic)
CFLAGS+=-DWOLFBOOT_FPGA_NONFATAL
endif
# FIT_CONFIG_SELECT=1 lets the target pick a per-board FIT configuration
Expand Down
16 changes: 16 additions & 0 deletions src/delta.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len)
blk_start = pa - ctx->src_a;
if (blk_start > BLOCK_OFF_MAX)
return -1;
if (((blk_start >> 16) & 0xFF) == ESC) {
/* The most-significant offset byte would collide with
* the escaped-literal marker (ESC ESC), making the
* header indistinguishable from a literal ESC byte on
* decode. Skip this candidate and keep searching.
*/
pa++;
continue;
}
b_start = ctx->off_b;
pa+= BLOCK_HDR_SIZE;
ctx->off_b += BLOCK_HDR_SIZE;
Expand Down Expand Up @@ -367,6 +376,13 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len)
blk_start = pb - ctx->src_b;
if (blk_start > BLOCK_OFF_MAX)
return -1;
if (((blk_start >> 16) & 0xFF) == ESC) {
/* Same ESC-collision hazard as the forward-match
* path: skip this candidate and keep searching.
*/
pb++;
continue;
}
pb+= BLOCK_HDR_SIZE;
ctx->off_b += BLOCK_HDR_SIZE;
while ((pb < pb_limit) &&
Expand Down
5 changes: 5 additions & 0 deletions src/psa_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ static void cache_commit(uint32_t offset)
hal_flash_write((uintptr_t)vault_base + offset, cached_sector, WOLFBOOT_SECTOR_SIZE);

hal_flash_lock();

/* cached_sector may hold key-object plaintext; every caller commits it
* to flash and then either overwrites it before reuse or returns, so
* it is safe to wipe it here right after the last use. */
wc_ForceZero(cached_sector, sizeof(cached_sector));
}

static void restore_backup(uint32_t offset)
Expand Down
16 changes: 13 additions & 3 deletions src/qspi_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,11 @@ int spi_flash_read(uint32_t address, void *data, int len)
uint32_t altMode = QSPI_DATA_MODE_NONE;
#endif

if (address > FLASH_DEVICE_SIZE) {
if ((len < 0) || (address >= FLASH_DEVICE_SIZE) ||
((uint64_t)address + (uint32_t)len > FLASH_DEVICE_SIZE)) {
#ifdef DEBUG_QSPI
wolfBoot_printf("QSPI Flash Read: Invalid address (0x%x > 0x%x max)\n",
address, FLASH_DEVICE_SIZE);
wolfBoot_printf("QSPI Flash Read: Invalid address (0x%x, len %d, max 0x%x)\n",
address, len, FLASH_DEVICE_SIZE);
#endif
return -1;
}
Expand Down Expand Up @@ -427,6 +428,15 @@ int spi_flash_write(uint32_t address, const void *data, int len)
len, data, address);
#endif

if ((len < 0) || (address >= FLASH_DEVICE_SIZE) ||
((uint64_t)address + (uint32_t)len > FLASH_DEVICE_SIZE)) {
#ifdef DEBUG_QSPI
wolfBoot_printf("QSPI Flash Write: Invalid address (0x%x, len %d, max 0x%x)\n",
address, len, FLASH_DEVICE_SIZE);
#endif
return -1;
}

/* write by page */
pages = ((len + (FLASH_PAGE_SIZE-1)) / FLASH_PAGE_SIZE);
for (page = 0; page < pages; page++) {
Expand Down
16 changes: 16 additions & 0 deletions src/update_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ void RAMFUNCTION wolfBoot_start(void)
uint32_t cur_ver = selected ? pB_ver_u : pA_ver_u;
if ((max_ver > 0U) && (cur_ver < max_ver)) {
wolfBoot_printf("Rollback to lower version not allowed\r\n");
#ifdef DISK_ENCRYPT
disk_decrypted_header_clear(dec_hdr);
disk_crypto_clear();
#endif
wolfBoot_panic();
return;
}
Expand Down Expand Up @@ -573,6 +577,10 @@ void RAMFUNCTION wolfBoot_start(void)
if (fpga != NULL) {
if (fit_load_fpga(fit, fpga) != 0) {
wolfBoot_printf("FIT: FPGA load failed\r\n");
#ifdef DISK_ENCRYPT
disk_decrypted_header_clear(dec_hdr);
disk_crypto_clear();
#endif
wolfBoot_panic();
}
}
Expand All @@ -584,6 +592,10 @@ void RAMFUNCTION wolfBoot_start(void)
if (new_load == NULL) {
wolfBoot_printf("FIT: failed to load kernel '%s'\r\n",
kernel);
#ifdef DISK_ENCRYPT
disk_decrypted_header_clear(dec_hdr);
disk_crypto_clear();
#endif
wolfBoot_panic();
}
load_address = new_load;
Expand Down Expand Up @@ -627,6 +639,10 @@ void RAMFUNCTION wolfBoot_start(void)
#ifndef TZEN
if (hal_flash_protect(WOLFBOOT_ORIGIN, BOOTLOADER_PARTITION_SIZE) < 0) {
wolfBoot_printf("Error protecting bootloader flash region\r\n");
#ifdef DISK_ENCRYPT
disk_decrypted_header_clear(dec_hdr);
disk_crypto_clear();
#endif
wolfBoot_panic();
}
#endif
Expand Down
1 change: 1 addition & 0 deletions src/x86/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ int sata_unlock_disk(int drv, int freeze)
if ((freeze && ata_st != ATA_SEC6) || (!freeze && ata_st != ATA_SEC5)) {
AHCI_DEBUG_PRINTF("ATA: Security is not enabled/locked (State SEC%d)\r\n",
ata_st);
ahci_secret_zeroize(secret, sizeof(secret));
panic();
}
AHCI_DEBUG_PRINTF("ATA: Security enabled. State SEC%d\r\n", ata_st);
Expand Down
Loading
Loading