Deploy NO_DIRECT_READ_OF_ERASED_SECTOR to protect against hardfault with AHB read of erased sector.

pull/714/head
Thomas Cook 2026-02-27 01:29:51 -05:00 committed by Daniele Lacamera
parent 2af2e795cb
commit dd4312679b
9 changed files with 133 additions and 21 deletions

View File

@ -28,6 +28,7 @@ RAM_CODE?=1
DUALBANK_SWAP?=0
PKA?=1
FLASH_MULTI_SECTOR_ERASE?=1
NO_DIRECT_READ_OF_ERASED_SECTOR?=1
# 512-byte pages erasable/writeable
WOLFBOOT_SECTOR_SIZE?=0x200

View File

@ -1,6 +1,6 @@
/* lpc55s69.c
*
* Copyright (C) 2025 wolfSSL Inc.
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
@ -163,9 +163,15 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
return -1;
}
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
int RAMFUNCTION hal_flash_is_erased_at(uint32_t address)
{
address &= ~(WOLFBOOT_SECTOR_SIZE - 1);
return FLASH_VerifyErase(&pflash, address, WOLFBOOT_SECTOR_SIZE) == kStatus_FLASH_Success;
}
#endif
#ifdef WOLFCRYPT_SECURE_MODE
/* These functions are stubs for now, because the MCUXpresso SDK doesn't
* implement drivers for the MCXN's TRNG. */
void hal_trng_init(void)
{
}

View File

@ -88,6 +88,9 @@ uint64_t hal_get_timer_us(void);
void hal_flash_unlock(void);
void hal_flash_lock(void);
void hal_prepare_boot(void);
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
int hal_flash_is_erased_at(uint32_t address);
#endif
#ifdef DUALBANK_SWAP
void hal_flash_dualbank_swap(void);

View File

@ -489,7 +489,7 @@ extern "C" {
#define IMG_STATE_NEW 0x00
#define IMG_STATE_UPDATING 0x8F
#define IMG_STATE_TESTING 0xEF
#define IMG_STATE_FINAL_FLAGS 0xBF
#define IMG_STATE_FINAL_FLAGS 0xCF
#define IMG_STATE_SUCCESS 0xFF
#define FLASH_BYTE_ERASED 0x00
#define FLASH_WORD_ERASED 0x00000000UL

View File

@ -713,6 +713,10 @@ ifeq ($(NVM_FLASH_WRITEONCE),1)
CFLAGS+= -D"NVM_FLASH_WRITEONCE"
endif
ifeq ($(NO_DIRECT_READ_OF_ERASED_SECTOR),1)
CFLAGS+= -D"NO_DIRECT_READ_OF_ERASED_SECTOR"
endif
ifeq ($(DISABLE_BACKUP),1)
CFLAGS+= -D"DISABLE_BACKUP"
endif

View File

@ -1298,10 +1298,17 @@ uint32_t wolfBoot_image_size(uint8_t *image)
*/
int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image)
{
uint32_t *magic = (uint32_t *)(image);
if (*magic != WOLFBOOT_MAGIC) {
uint32_t *pmagic = (uint32_t *)(image);
uint32_t magic = FLASH_WORD_ERASED;
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)pmagic) ||
#endif
(magic = *pmagic) != WOLFBOOT_MAGIC
)
{
wolfBoot_printf("Partition %d header magic 0x%08x invalid at %p\n",
img->part, (unsigned int)*magic, img->hdr);
img->part, (unsigned int)magic, img->hdr);
return -1;
}
img->fw_size = wolfBoot_image_size(image);

View File

@ -228,6 +228,7 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
uint8_t* addrErase = 0;
uint32_t word_0;
uint32_t word_1;
uint32_t *ptr_word_0, *ptr_word_1;
#if defined(EXT_FLASH) && !defined(FLAGS_HOME)
if ((part == PART_UPDATE) && FLAGS_UPDATE_EXT()) {
@ -254,8 +255,28 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
}
/* check magic in case the sector is corrupt */
word_0 = *((uint32_t*)((uintptr_t)base - sizeof(uint32_t)));
word_1 = *((uint32_t*)((uintptr_t)base - (WOLFBOOT_SECTOR_SIZE + sizeof(uint32_t))));
ptr_word_0 = (uint32_t*)((uintptr_t)base - sizeof(uint32_t));
ptr_word_1 = (uint32_t*)((uintptr_t)base - (WOLFBOOT_SECTOR_SIZE + sizeof(uint32_t)));
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)ptr_word_0))
{
word_0 = FLASH_WORD_ERASED;
}
else
#endif
{
word_0 = *ptr_word_0;
}
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)ptr_word_1))
{
word_1 = FLASH_WORD_ERASED;
}
else
#endif
{
word_1 = *ptr_word_1;
}
if (word_0 == WOLFBOOT_MAGIC_TRAIL && word_1 != WOLFBOOT_MAGIC_TRAIL) {
sel = 0;
@ -301,8 +322,15 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
finish:
/* Erase the non-selected partition, requires unlocked flash */
addrErase -= WOLFBOOT_SECTOR_SIZE * (!sel);
if (*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
!= FLASH_WORD_ERASED) {
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
! hal_flash_is_erased_at((uintptr_t)addrErase)
#else
*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
!= FLASH_WORD_ERASED
#endif
)
{
hal_flash_erase((uintptr_t)addrErase, WOLFBOOT_SECTOR_SIZE);
}
return sel;
@ -626,11 +654,20 @@ int RAMFUNCTION wolfBoot_set_partition_state(uint8_t part, uint8_t newst)
if (part == PART_NONE)
return -1;
magic = get_partition_magic(part);
if (*magic != WOLFBOOT_MAGIC_TRAIL)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC_TRAIL
)
{
set_partition_magic(part);
}
state = get_partition_state(part);
if (*state != newst)
{
set_partition_state(part, newst);
}
return 0;
}
@ -652,8 +689,15 @@ int RAMFUNCTION wolfBoot_set_update_sector_flag(uint16_t sector,
uint8_t pos = sector >> 1;
magic = get_partition_magic(PART_UPDATE);
if (*magic != wolfboot_magic_trail)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != wolfboot_magic_trail
)
{
set_partition_magic(PART_UPDATE);
}
flags = get_update_sector_flags(pos);
if (sector == (pos << 1))
@ -681,8 +725,15 @@ int RAMFUNCTION wolfBoot_get_partition_state(uint8_t part, uint8_t *st)
if (part == PART_NONE)
return -1;
magic = get_partition_magic(part);
if (*magic != WOLFBOOT_MAGIC_TRAIL)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC_TRAIL
)
{
return -1;
}
state = get_partition_state(part);
*st = *state;
return 0;
@ -706,8 +757,15 @@ int wolfBoot_get_update_sector_flag(uint16_t sector, uint8_t *flag)
uint8_t *flags;
uint8_t pos = sector >> 1;
magic = get_partition_magic(PART_UPDATE);
if (*magic != WOLFBOOT_MAGIC_TRAIL)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC_TRAIL
)
{
return -1;
}
flags = get_update_sector_flags(pos);
if (sector == (pos << 1))
*flag = *flags & 0x0F;
@ -1009,8 +1067,15 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset,
/* Don't check image against NULL to allow using address 0x00000000 */
magic = (uint32_t *)image;
if (*magic != WOLFBOOT_MAGIC)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
return -1;
}
if (inverse) {
if (wolfBoot_find_header((uint8_t *)(image + IMAGE_HEADER_OFFSET),
HDR_IMG_DELTA_INVERSE, (uint8_t **)img_offset)
@ -1083,8 +1148,15 @@ uint32_t wolfBoot_get_blob_version(uint8_t *blob)
img_bin = dec_hdr;
#endif
magic = (uint32_t *)img_bin;
if (*magic != WOLFBOOT_MAGIC)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
return 0;
}
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_VERSION,
(void *)&version_field) == 0)
return 0;
@ -1116,8 +1188,15 @@ uint16_t wolfBoot_get_blob_type(uint8_t *blob)
img_bin = dec_hdr;
#endif
magic = (uint32_t *)img_bin;
if (*magic != WOLFBOOT_MAGIC)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
return 0;
}
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE,
(void *)&type_field) == 0)
return 0;
@ -1153,8 +1232,15 @@ uint32_t wolfBoot_get_blob_diffbase_version(uint8_t *blob)
img_bin = dec_hdr;
#endif
magic = (uint32_t *)img_bin;
if (*magic != WOLFBOOT_MAGIC)
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
return 0;
}
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_DELTA_BASE,
(void *)&delta_base) == 0)
return 0;

View File

@ -447,7 +447,12 @@ static int RAMFUNCTION wolfBoot_swap_and_final_erase(int resume)
ext_flash_read((uintptr_t)(boot->hdr + tmpBootPos), (void*)tmpBuffer,
sizeof(tmpBuffer));
#else
memcpy(tmpBuffer, boot->hdr + tmpBootPos, sizeof(tmpBuffer));
# ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)(boot->hdr + tmpBootPos)))
memset(tmpBuffer, 0xFF, sizeof(tmpBuffer));
else
# endif
memcpy(tmpBuffer, boot->hdr + tmpBootPos, sizeof(tmpBuffer));
#endif
/* Check if the magic trailer exists - indicates an interrupted swap

View File

@ -1,6 +1,6 @@
/* app_lpc55s69.c
*
* Copyright (C) 2025 wolfSSL Inc.
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfBoot.
*