Skip to content

Commit dd43126

Browse files
twcook86danielinux
authored andcommitted
Deploy NO_DIRECT_READ_OF_ERASED_SECTOR to protect against hardfault with AHB read of erased sector.
1 parent 2af2e79 commit dd43126

9 files changed

Lines changed: 133 additions & 21 deletions

File tree

config/examples/lpc55s69.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ RAM_CODE?=1
2828
DUALBANK_SWAP?=0
2929
PKA?=1
3030
FLASH_MULTI_SECTOR_ERASE?=1
31+
NO_DIRECT_READ_OF_ERASED_SECTOR?=1
3132

3233
# 512-byte pages erasable/writeable
3334
WOLFBOOT_SECTOR_SIZE?=0x200

hal/lpc55s69.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* lpc55s69.c
22
*
3-
* Copyright (C) 2025 wolfSSL Inc.
3+
* Copyright (C) 2026 wolfSSL Inc.
44
*
55
* This file is part of wolfBoot.
66
*
@@ -163,9 +163,15 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
163163
return -1;
164164
}
165165

166+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
167+
int RAMFUNCTION hal_flash_is_erased_at(uint32_t address)
168+
{
169+
address &= ~(WOLFBOOT_SECTOR_SIZE - 1);
170+
return FLASH_VerifyErase(&pflash, address, WOLFBOOT_SECTOR_SIZE) == kStatus_FLASH_Success;
171+
}
172+
#endif
173+
166174
#ifdef WOLFCRYPT_SECURE_MODE
167-
/* These functions are stubs for now, because the MCUXpresso SDK doesn't
168-
* implement drivers for the MCXN's TRNG. */
169175
void hal_trng_init(void)
170176
{
171177
}

include/hal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ uint64_t hal_get_timer_us(void);
8888
void hal_flash_unlock(void);
8989
void hal_flash_lock(void);
9090
void hal_prepare_boot(void);
91+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
92+
int hal_flash_is_erased_at(uint32_t address);
93+
#endif
9194

9295
#ifdef DUALBANK_SWAP
9396
void hal_flash_dualbank_swap(void);

include/wolfboot/wolfboot.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ extern "C" {
489489
#define IMG_STATE_NEW 0x00
490490
#define IMG_STATE_UPDATING 0x8F
491491
#define IMG_STATE_TESTING 0xEF
492-
#define IMG_STATE_FINAL_FLAGS 0xBF
492+
#define IMG_STATE_FINAL_FLAGS 0xCF
493493
#define IMG_STATE_SUCCESS 0xFF
494494
#define FLASH_BYTE_ERASED 0x00
495495
#define FLASH_WORD_ERASED 0x00000000UL

options.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,10 @@ ifeq ($(NVM_FLASH_WRITEONCE),1)
713713
CFLAGS+= -D"NVM_FLASH_WRITEONCE"
714714
endif
715715

716+
ifeq ($(NO_DIRECT_READ_OF_ERASED_SECTOR),1)
717+
CFLAGS+= -D"NO_DIRECT_READ_OF_ERASED_SECTOR"
718+
endif
719+
716720
ifeq ($(DISABLE_BACKUP),1)
717721
CFLAGS+= -D"DISABLE_BACKUP"
718722
endif

src/image.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,10 +1298,17 @@ uint32_t wolfBoot_image_size(uint8_t *image)
12981298
*/
12991299
int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image)
13001300
{
1301-
uint32_t *magic = (uint32_t *)(image);
1302-
if (*magic != WOLFBOOT_MAGIC) {
1301+
uint32_t *pmagic = (uint32_t *)(image);
1302+
uint32_t magic = FLASH_WORD_ERASED;
1303+
if (
1304+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
1305+
hal_flash_is_erased_at((uintptr_t)pmagic) ||
1306+
#endif
1307+
(magic = *pmagic) != WOLFBOOT_MAGIC
1308+
)
1309+
{
13031310
wolfBoot_printf("Partition %d header magic 0x%08x invalid at %p\n",
1304-
img->part, (unsigned int)*magic, img->hdr);
1311+
img->part, (unsigned int)magic, img->hdr);
13051312
return -1;
13061313
}
13071314
img->fw_size = wolfBoot_image_size(image);

src/libwolfboot.c

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
228228
uint8_t* addrErase = 0;
229229
uint32_t word_0;
230230
uint32_t word_1;
231+
uint32_t *ptr_word_0, *ptr_word_1;
231232

232233
#if defined(EXT_FLASH) && !defined(FLAGS_HOME)
233234
if ((part == PART_UPDATE) && FLAGS_UPDATE_EXT()) {
@@ -254,8 +255,28 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
254255
}
255256

256257
/* check magic in case the sector is corrupt */
257-
word_0 = *((uint32_t*)((uintptr_t)base - sizeof(uint32_t)));
258-
word_1 = *((uint32_t*)((uintptr_t)base - (WOLFBOOT_SECTOR_SIZE + sizeof(uint32_t))));
258+
ptr_word_0 = (uint32_t*)((uintptr_t)base - sizeof(uint32_t));
259+
ptr_word_1 = (uint32_t*)((uintptr_t)base - (WOLFBOOT_SECTOR_SIZE + sizeof(uint32_t)));
260+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
261+
if (hal_flash_is_erased_at((uintptr_t)ptr_word_0))
262+
{
263+
word_0 = FLASH_WORD_ERASED;
264+
}
265+
else
266+
#endif
267+
{
268+
word_0 = *ptr_word_0;
269+
}
270+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
271+
if (hal_flash_is_erased_at((uintptr_t)ptr_word_1))
272+
{
273+
word_1 = FLASH_WORD_ERASED;
274+
}
275+
else
276+
#endif
277+
{
278+
word_1 = *ptr_word_1;
279+
}
259280

260281
if (word_0 == WOLFBOOT_MAGIC_TRAIL && word_1 != WOLFBOOT_MAGIC_TRAIL) {
261282
sel = 0;
@@ -301,8 +322,15 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
301322
finish:
302323
/* Erase the non-selected partition, requires unlocked flash */
303324
addrErase -= WOLFBOOT_SECTOR_SIZE * (!sel);
304-
if (*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
305-
!= FLASH_WORD_ERASED) {
325+
if (
326+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
327+
! hal_flash_is_erased_at((uintptr_t)addrErase)
328+
#else
329+
*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
330+
!= FLASH_WORD_ERASED
331+
#endif
332+
)
333+
{
306334
hal_flash_erase((uintptr_t)addrErase, WOLFBOOT_SECTOR_SIZE);
307335
}
308336
return sel;
@@ -626,11 +654,20 @@ int RAMFUNCTION wolfBoot_set_partition_state(uint8_t part, uint8_t newst)
626654
if (part == PART_NONE)
627655
return -1;
628656
magic = get_partition_magic(part);
629-
if (*magic != WOLFBOOT_MAGIC_TRAIL)
657+
if (
658+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
659+
hal_flash_is_erased_at((uintptr_t)magic) ||
660+
#endif
661+
*magic != WOLFBOOT_MAGIC_TRAIL
662+
)
663+
{
630664
set_partition_magic(part);
665+
}
631666
state = get_partition_state(part);
632667
if (*state != newst)
668+
{
633669
set_partition_state(part, newst);
670+
}
634671
return 0;
635672
}
636673

@@ -652,8 +689,15 @@ int RAMFUNCTION wolfBoot_set_update_sector_flag(uint16_t sector,
652689
uint8_t pos = sector >> 1;
653690

654691
magic = get_partition_magic(PART_UPDATE);
655-
if (*magic != wolfboot_magic_trail)
692+
if (
693+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
694+
hal_flash_is_erased_at((uintptr_t)magic) ||
695+
#endif
696+
*magic != wolfboot_magic_trail
697+
)
698+
{
656699
set_partition_magic(PART_UPDATE);
700+
}
657701

658702
flags = get_update_sector_flags(pos);
659703
if (sector == (pos << 1))
@@ -681,8 +725,15 @@ int RAMFUNCTION wolfBoot_get_partition_state(uint8_t part, uint8_t *st)
681725
if (part == PART_NONE)
682726
return -1;
683727
magic = get_partition_magic(part);
684-
if (*magic != WOLFBOOT_MAGIC_TRAIL)
728+
if (
729+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
730+
hal_flash_is_erased_at((uintptr_t)magic) ||
731+
#endif
732+
*magic != WOLFBOOT_MAGIC_TRAIL
733+
)
734+
{
685735
return -1;
736+
}
686737
state = get_partition_state(part);
687738
*st = *state;
688739
return 0;
@@ -706,8 +757,15 @@ int wolfBoot_get_update_sector_flag(uint16_t sector, uint8_t *flag)
706757
uint8_t *flags;
707758
uint8_t pos = sector >> 1;
708759
magic = get_partition_magic(PART_UPDATE);
709-
if (*magic != WOLFBOOT_MAGIC_TRAIL)
760+
if (
761+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
762+
hal_flash_is_erased_at((uintptr_t)magic) ||
763+
#endif
764+
*magic != WOLFBOOT_MAGIC_TRAIL
765+
)
766+
{
710767
return -1;
768+
}
711769
flags = get_update_sector_flags(pos);
712770
if (sector == (pos << 1))
713771
*flag = *flags & 0x0F;
@@ -1009,8 +1067,15 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset,
10091067

10101068
/* Don't check image against NULL to allow using address 0x00000000 */
10111069
magic = (uint32_t *)image;
1012-
if (*magic != WOLFBOOT_MAGIC)
1070+
if (
1071+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
1072+
hal_flash_is_erased_at((uintptr_t)magic) ||
1073+
#endif
1074+
*magic != WOLFBOOT_MAGIC
1075+
)
1076+
{
10131077
return -1;
1078+
}
10141079
if (inverse) {
10151080
if (wolfBoot_find_header((uint8_t *)(image + IMAGE_HEADER_OFFSET),
10161081
HDR_IMG_DELTA_INVERSE, (uint8_t **)img_offset)
@@ -1083,8 +1148,15 @@ uint32_t wolfBoot_get_blob_version(uint8_t *blob)
10831148
img_bin = dec_hdr;
10841149
#endif
10851150
magic = (uint32_t *)img_bin;
1086-
if (*magic != WOLFBOOT_MAGIC)
1151+
if (
1152+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
1153+
hal_flash_is_erased_at((uintptr_t)magic) ||
1154+
#endif
1155+
*magic != WOLFBOOT_MAGIC
1156+
)
1157+
{
10871158
return 0;
1159+
}
10881160
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_VERSION,
10891161
(void *)&version_field) == 0)
10901162
return 0;
@@ -1116,8 +1188,15 @@ uint16_t wolfBoot_get_blob_type(uint8_t *blob)
11161188
img_bin = dec_hdr;
11171189
#endif
11181190
magic = (uint32_t *)img_bin;
1119-
if (*magic != WOLFBOOT_MAGIC)
1191+
if (
1192+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
1193+
hal_flash_is_erased_at((uintptr_t)magic) ||
1194+
#endif
1195+
*magic != WOLFBOOT_MAGIC
1196+
)
1197+
{
11201198
return 0;
1199+
}
11211200
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE,
11221201
(void *)&type_field) == 0)
11231202
return 0;
@@ -1153,8 +1232,15 @@ uint32_t wolfBoot_get_blob_diffbase_version(uint8_t *blob)
11531232
img_bin = dec_hdr;
11541233
#endif
11551234
magic = (uint32_t *)img_bin;
1156-
if (*magic != WOLFBOOT_MAGIC)
1235+
if (
1236+
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
1237+
hal_flash_is_erased_at((uintptr_t)magic) ||
1238+
#endif
1239+
*magic != WOLFBOOT_MAGIC
1240+
)
1241+
{
11571242
return 0;
1243+
}
11581244
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_DELTA_BASE,
11591245
(void *)&delta_base) == 0)
11601246
return 0;

src/update_flash.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,12 @@ static int RAMFUNCTION wolfBoot_swap_and_final_erase(int resume)
447447
ext_flash_read((uintptr_t)(boot->hdr + tmpBootPos), (void*)tmpBuffer,
448448
sizeof(tmpBuffer));
449449
#else
450-
memcpy(tmpBuffer, boot->hdr + tmpBootPos, sizeof(tmpBuffer));
450+
# ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
451+
if (hal_flash_is_erased_at((uintptr_t)(boot->hdr + tmpBootPos)))
452+
memset(tmpBuffer, 0xFF, sizeof(tmpBuffer));
453+
else
454+
# endif
455+
memcpy(tmpBuffer, boot->hdr + tmpBootPos, sizeof(tmpBuffer));
451456
#endif
452457

453458
/* Check if the magic trailer exists - indicates an interrupted swap

test-app/app_lpc55s69.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* app_lpc55s69.c
22
*
3-
* Copyright (C) 2025 wolfSSL Inc.
3+
* Copyright (C) 2026 wolfSSL Inc.
44
*
55
* This file is part of wolfBoot.
66
*

0 commit comments

Comments
 (0)