Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions hal/nxp_ls1028a.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ void xspi_flash_write(uintptr_t address, const uint8_t *data, uint32_t len)
for(j = 0; j < XSPI_IP_WM_SIZE; j+=4) {
memcpy(&tx_data, data, 4);
data += 4;
xspi_writereg((uint32_t*)XSPI_TFD_BASE + j, tx_data);
xspi_writereg((uint32_t*)XSPI_TFD_BASE + (j / 4), tx_data);
}

/* Reset fifo */
Expand All @@ -574,7 +574,7 @@ void xspi_flash_write(uintptr_t address, const uint8_t *data, uint32_t len)
rem_size = ((remaining - j) < 4) ? (remaining - j) : 4;
memcpy(&tx_data, data, rem_size);
data += rem_size;
xspi_writereg((uint32_t*)XSPI_TFD_BASE + j, tx_data);
xspi_writereg((uint32_t*)XSPI_TFD_BASE + (j / 4), tx_data);
}

/* Reset fifo */
Expand Down
2 changes: 1 addition & 1 deletion hal/pic32c.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static void pic32_fcw_pfswap_set(int sw)
uint32_t reg;

reg = FCW_SWAP;
reg &= FCW_SWAP_PFSWAP;
reg &= ~FCW_SWAP_PFSWAP;
if (sw)
reg |= FCW_SWAP_PFSWAP;
FCW_KEY = FCW_UNLOCK_SWAPKEY;
Expand Down
16 changes: 13 additions & 3 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1910,6 +1910,17 @@ void RAMFUNCTION wolfBoot_crypto_set_iv(const uint8_t *nonce, uint32_t iv_counte
}
#endif /* EXT_ENCRYPTED && (__WOLFBOOT || UNIT_TEST || MMU) */

#if !defined(NVM_FLASH_WRITEONCE) && !defined(WOLFBOOT_ENCRYPT_CACHE) && \
!defined(MMU) && !defined(WOLFBOOT_RENESAS_TSIP)
static void wolfBoot_secure_zero(void *ptr, size_t len)
{
volatile uint8_t *p = (volatile uint8_t *)ptr;

while (len-- > 0)
*p++ = 0;
}
#endif

static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce)
{
#ifdef WOLFBOOT_RENESAS_TSIP
Expand Down Expand Up @@ -1988,9 +1999,8 @@ static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce)
ret = hal_flash_erase(addr_align, WOLFBOOT_SECTOR_SIZE);
#endif
exit_lock:
#if !defined(WOLFBOOT_SMALL_STACK) && !defined(NVM_FLASH_WRITEONCE) && \
!defined(WOLFBOOT_ENCRYPT_CACHE)
ForceZero(ENCRYPT_CACHE, NVM_CACHE_SIZE);
#if !defined(NVM_FLASH_WRITEONCE) && !defined(WOLFBOOT_ENCRYPT_CACHE)
wolfBoot_secure_zero(ENCRYPT_CACHE, NVM_CACHE_SIZE);
#endif
hal_flash_lock();
return ret;
Expand Down
15 changes: 15 additions & 0 deletions tools/unit-tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ TESTS+=unit-flash-write-mcxa
TESTS+=unit-flash-write-samr21
TESTS+=unit-flash-write-same51
TESTS+=unit-imx-rt-cache-align
TESTS+=unit-xspi-tfd-index
TESTS+=unit-pic32-pfswap
TESTS+=unit-enc-key-zeroize

# linux_loader.c is x86 32-bit only, so its unit tests need a working 32-bit
# (multilib) toolchain. Probe whether "gcc -m32" can link, and only add the
Expand Down Expand Up @@ -332,6 +335,12 @@ unit-arm-tee-psa-ipc: ../../include/target.h unit-arm-tee-psa-ipc.c ../../src/ar
unit-va416x0-fram: unit-va416x0-fram.c ../../hal/va416x0.c
gcc -o $@ unit-va416x0-fram.c $(CFLAGS) $(LDFLAGS)

unit-xspi-tfd-index: unit-xspi-tfd-index.c
gcc -o $@ unit-xspi-tfd-index.c $(CFLAGS) -I../../hal $(LDFLAGS)

unit-pic32-pfswap: unit-pic32-pfswap.c
gcc -o $@ unit-pic32-pfswap.c $(CFLAGS) $(LDFLAGS)

unit-max-space: ../../include/target.h unit-max-space.c
gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)

Expand Down Expand Up @@ -487,6 +496,12 @@ unit-diagnostics-256: ../../include/target.h unit-diagnostics.c
unit-enc-nvm: ../../include/target.h unit-enc-nvm.c
gcc -o $@ $(WOLFCRYPT_SRC) unit-enc-nvm.c $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS)

unit-enc-key-zeroize:CFLAGS+=-DWOLFBOOT_SMALL_STACK -DMOCK_PARTITIONS -DEXT_ENCRYPTED \
-DENCRYPT_WITH_CHACHA -DEXT_FLASH -DHAVE_CHACHA
unit-enc-key-zeroize:WOLFCRYPT_SRC+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/chacha.c
unit-enc-key-zeroize: ../../include/target.h unit-enc-key-zeroize.c
gcc -o $@ $(WOLFCRYPT_SRC) unit-enc-key-zeroize.c $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS)

unit-enc-nvm-flagshome: ../../include/target.h unit-enc-nvm.c
gcc -o $@ $(WOLFCRYPT_SRC) unit-enc-nvm.c $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS)

Expand Down
93 changes: 93 additions & 0 deletions tools/unit-tests/unit-enc-key-zeroize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* unit-enc-key-zeroize.c
*
* Unit test that hal_set_key zeroizes the static ENCRYPT_CACHE on the
* WOLFBOOT_SMALL_STACK path.
*
* 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
*/
#define WOLFBOOT_HASH_SHA256
#define IMAGE_HEADER_SIZE 256
#define MOCK_ADDRESS 0xCC000000
#define MOCK_ADDRESS_BOOT 0xCD000000
#define MOCK_ADDRESS_SWAP 0xCE000000
const char ENCRYPT_KEY[] = "0123456789abcdef0123456789abcdef0123456789abcdef";
#include <stdio.h>
#include <string.h>
#include "image.h"
#include "encrypt.h"
#include "libwolfboot.c"
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <check.h>

const char *argv0;

#include "unit-mock-flash.c"

START_TEST(test_hal_set_key_zeroizes_static_cache)
{
uint8_t key[ENCRYPT_KEY_SIZE];
uint8_t nonce[ENCRYPT_NONCE_SIZE];
int ret, i;

ret = mmap_file("/tmp/wolfboot-unit-boot.bin", (void *)MOCK_ADDRESS_BOOT,
WOLFBOOT_PARTITION_SIZE, NULL);
ck_assert(ret >= 0);
ret = mmap_file("/tmp/wolfboot-unit-file.bin", (void *)MOCK_ADDRESS,
WOLFBOOT_PARTITION_SIZE, NULL);
ck_assert(ret >= 0);
ret = mmap_file("/tmp/wolfboot-unit-swap.bin", (void *)MOCK_ADDRESS_SWAP,
WOLFBOOT_SECTOR_SIZE, NULL);
ck_assert(ret >= 0);

memset(key, 0x5A, sizeof(key));
memset(nonce, 0xA5, sizeof(nonce));

ret = hal_set_key(key, nonce);
ck_assert_int_eq(ret, 0);

for (i = 0; i < (int)NVM_CACHE_SIZE; i++)
ck_assert_uint_eq(ENCRYPT_CACHE[i], 0);
}
END_TEST

Suite *enc_key_zeroize_suite(void)
{
Suite *s = suite_create("enc-key-zeroize");
TCase *tc = tcase_create("hal_set_key");

tcase_add_test(tc, test_hal_set_key_zeroizes_static_cache);
suite_add_tcase(s, tc);

return s;
}

int main(void)
{
int fails;
Suite *s = enc_key_zeroize_suite();
SRunner *sr = srunner_create(s);

srunner_run_all(sr, CK_NORMAL);
fails = srunner_ntests_failed(sr);
srunner_free(sr);

return fails;
}
114 changes: 114 additions & 0 deletions tools/unit-tests/unit-pic32-pfswap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* unit-pic32-pfswap.c
*
* Unit tests for the PIC32 FCW dual-bank PFSWAP read-modify-write.
*
*
* 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
*/

#include <check.h>
#include <stdint.h>

#define FCW_SWAP_PFSWAP (1u << 8)
#define FCW_UNLOCK_SWAPKEY 0x91C32C02u
#define FCW_OTHER_BITS 0x000000A5u

static uint32_t g_fcw_swap;
static uint32_t g_fcw_key;

static int pfswap_get(void)
{
return !!(g_fcw_swap & FCW_SWAP_PFSWAP);
}

static void pfswap_set_bytemask(int sw)
{
uint32_t reg;

reg = g_fcw_swap;
reg &= FCW_SWAP_PFSWAP;
if (sw)
reg |= FCW_SWAP_PFSWAP;
g_fcw_key = FCW_UNLOCK_SWAPKEY;
g_fcw_swap = reg;
}

static void pfswap_set_clearbit(int sw)
{
uint32_t reg;

reg = g_fcw_swap;
reg &= ~FCW_SWAP_PFSWAP;
if (sw)
reg |= FCW_SWAP_PFSWAP;
g_fcw_key = FCW_UNLOCK_SWAPKEY;
g_fcw_swap = reg;
}

START_TEST(test_masked_set_cannot_clear_bit)
{
g_fcw_swap = FCW_OTHER_BITS;

pfswap_set_bytemask(!pfswap_get());
ck_assert_int_eq(pfswap_get(), 1);

pfswap_set_bytemask(!pfswap_get());
ck_assert_int_eq(pfswap_get(), 1);
ck_assert_uint_eq(g_fcw_swap & FCW_OTHER_BITS, 0u);
}
END_TEST

START_TEST(test_cleared_set_toggles_and_preserves)
{
g_fcw_swap = FCW_OTHER_BITS;

pfswap_set_clearbit(!pfswap_get());
ck_assert_int_eq(pfswap_get(), 1);
ck_assert_uint_eq(g_fcw_swap & FCW_OTHER_BITS, FCW_OTHER_BITS);

pfswap_set_clearbit(!pfswap_get());
ck_assert_int_eq(pfswap_get(), 0);
ck_assert_uint_eq(g_fcw_swap & FCW_OTHER_BITS, FCW_OTHER_BITS);
}
END_TEST

Suite *pic32_pfswap_suite(void)
{
Suite *s = suite_create("pic32-pfswap");
TCase *tc = tcase_create("dualbank-swap");

tcase_add_test(tc, test_masked_set_cannot_clear_bit);
tcase_add_test(tc, test_cleared_set_toggles_and_preserves);
suite_add_tcase(s, tc);

return s;
}

int main(void)
{
int fails;
Suite *s = pic32_pfswap_suite();
SRunner *sr = srunner_create(s);

srunner_run_all(sr, CK_NORMAL);
fails = srunner_ntests_failed(sr);
srunner_free(sr);

return fails;
}
Loading
Loading