Skip to content

Commit f7ea40f

Browse files
bigbrettdanielinux
authored andcommitted
Add oneshot hash build option
1 parent 1253995 commit f7ea40f

File tree

6 files changed

+164
-64
lines changed

6 files changed

+164
-64
lines changed

.github/workflows/test-elf-scattered.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,11 @@ jobs:
4040
- name: Run bootloader with no arguments
4141
run: |
4242
./wolfboot.elf
43+
44+
- name: Build wolfboot.elf (ELF_SCATTERED, ONESHOT_HASH)
45+
run: |
46+
make clean && make test-sim-internal-flash-with-update ELF=1 ELF_SCATTERED=1 WOLFBOOT_IMG_HASH_ONESHOT=1
47+
48+
- name: Run bootloader with no arguments (ONESHOT_HASH)
49+
run: |
50+
./wolfboot.elf

.github/workflows/test-sunnyday-simulator.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,30 @@ jobs:
336336
run: |
337337
tools/scripts/sim-sunnyday-update.sh
338338
339+
- name: Build wolfboot.elf (ECC256, ONESHOT_HASH, SHA256)
340+
run: |
341+
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 SPMATH=1 WOLFBOOT_IMG_HASH_ONESHOT=1
342+
343+
- name: Run sunny day update test (ONESHOT_HASH, SHA256)
344+
run: |
345+
tools/scripts/sim-sunnyday-update.sh
346+
347+
- name: Build wolfboot.elf (ECC256, ONESHOT_HASH, SHA384)
348+
run: |
349+
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 SPMATH=1 HASH=SHA384 WOLFBOOT_IMG_HASH_ONESHOT=1
350+
351+
- name: Run sunny day update test (ONESHOT_HASH, SHA384)
352+
run: |
353+
tools/scripts/sim-sunnyday-update.sh
354+
355+
- name: Build wolfboot.elf (ECC256, ONESHOT_HASH, SHA3)
356+
run: |
357+
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 SPMATH=1 HASH=SHA3 WOLFBOOT_IMG_HASH_ONESHOT=1
358+
359+
- name: Run sunny day update test (ONESHOT_HASH, SHA3)
360+
run: |
361+
tools/scripts/sim-sunnyday-update.sh
362+
339363
- name: Cleanup to change key type
340364
run: |
341365
make keysclean

docs/compile.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,22 @@ falls in one of these cases, wolfBoot compilation will terminate with an explici
189189
In some cases you might have enough memory available to allow large stack allocations.
190190
To circumvent the compile-time checks on the maximum allowed stack size, use `WOLFBOOT_HUGE_STACK=1`.
191191

192+
### One-shot hash verification
193+
194+
By default, wolfBoot hashes firmware images in blocks of `WOLFBOOT_SHA_BLOCK_SIZE` bytes during
195+
verification. This block-by-block approach is required when firmware resides in external flash or
196+
other non-memory-mapped storage, where data must be read through intermediate buffers.
197+
198+
When firmware images are stored in directly memory-mapped flash (e.g. internal flash with
199+
execute-in-place support), the block-by-block overhead can be eliminated by enabling
200+
`WOLFBOOT_IMG_HASH_ONESHOT=1`. With this option, the entire image buffer is passed to the wolfCrypt
201+
hash function in a single call, which can improve verification performance.
202+
203+
**warning** This option assumes that `fw_base` pointers are directly dereferenceable for the full
204+
firmware size. It is incompatible with `EXT_FLASH=1` configurations where partitions reside on
205+
external SPI or UART flash. Only use `WOLFBOOT_IMG_HASH_ONESHOT=1` when all firmware partitions are
206+
in directly addressable, memory-mapped flash.
207+
192208
### Disable Backup of current running firmware
193209

194210
Optionally, it is possible to disable the backup copy of the current running firmware upon the installation of the

options.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,10 @@ ifeq ($(ARMORED),1)
796796
CFLAGS+=-DWOLFBOOT_ARMORED
797797
endif
798798

799+
ifeq ($(WOLFBOOT_IMG_HASH_ONESHOT),1)
800+
CFLAGS+=-DWOLFBOOT_IMG_HASH_ONESHOT
801+
endif
802+
799803
ifeq ($(WOLFBOOT_HUGE_STACK),1)
800804
CFLAGS+=-DWOLFBOOT_HUGE_STACK
801805
endif

src/image.c

Lines changed: 110 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -974,8 +974,7 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
974974
{
975975
uint8_t *stored_sha, *end_sha;
976976
uint16_t stored_sha_len;
977-
uint8_t *p;
978-
int blksz;
977+
uint8_t* p;
979978
if (!img)
980979
return -1;
981980

@@ -989,13 +988,20 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
989988
wc_InitSha256(sha256_ctx);
990989
#endif
991990
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
992-
while (p < end_sha) {
993-
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
994-
if (end_sha - p < blksz)
995-
blksz = end_sha - p;
996-
wc_Sha256Update(sha256_ctx, p, blksz);
997-
p += blksz;
991+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
992+
wc_Sha256Update(sha256_ctx, p, (word32)(end_sha - p));
993+
#else
994+
{
995+
int blksz;
996+
while (p < end_sha) {
997+
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
998+
if (end_sha - p < blksz)
999+
blksz = end_sha - p;
1000+
wc_Sha256Update(sha256_ctx, p, blksz);
1001+
p += blksz;
1002+
}
9981003
}
1004+
#endif
9991005
return 0;
10001006
}
10011007

@@ -1008,23 +1014,29 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
10081014
*/
10091015
static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
10101016
{
1011-
uint32_t position = 0;
1012-
uint8_t *p;
1013-
int blksz;
10141017
wc_Sha256 sha256_ctx;
10151018

10161019
if (header_sha256(&sha256_ctx, img) != 0)
10171020
return -1;
1018-
do {
1019-
p = get_sha_block(img, position);
1020-
if (p == NULL)
1021-
break;
1022-
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1023-
if (position + blksz > img->fw_size)
1024-
blksz = img->fw_size - position;
1025-
wc_Sha256Update(&sha256_ctx, p, blksz);
1026-
position += blksz;
1027-
} while(position < img->fw_size);
1021+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1022+
wc_Sha256Update(&sha256_ctx, img->fw_base, img->fw_size);
1023+
#else
1024+
{
1025+
uint32_t position = 0;
1026+
uint8_t* p;
1027+
int blksz;
1028+
do {
1029+
p = get_sha_block(img, position);
1030+
if (p == NULL)
1031+
break;
1032+
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1033+
if (position + blksz > img->fw_size)
1034+
blksz = img->fw_size - position;
1035+
wc_Sha256Update(&sha256_ctx, p, blksz);
1036+
position += blksz;
1037+
} while (position < img->fw_size);
1038+
}
1039+
#endif
10281040

10291041
wc_Sha256Final(&sha256_ctx, hash);
10301042
wc_Sha256Free(&sha256_ctx);
@@ -1065,8 +1077,7 @@ static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
10651077
{
10661078
uint16_t stored_sha_len;
10671079
uint8_t *stored_sha, *end_sha;
1068-
uint8_t *p;
1069-
int blksz;
1080+
uint8_t* p;
10701081
if (!img)
10711082
return -1;
10721083

@@ -1080,13 +1091,20 @@ static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
10801091
wc_InitSha384(sha384_ctx);
10811092
#endif
10821093
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
1083-
while (p < end_sha) {
1084-
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1085-
if (end_sha - p < blksz)
1086-
blksz = end_sha - p;
1087-
wc_Sha384Update(sha384_ctx, p, blksz);
1088-
p += blksz;
1094+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1095+
wc_Sha384Update(sha384_ctx, p, (word32)(end_sha - p));
1096+
#else
1097+
{
1098+
int blksz;
1099+
while (p < end_sha) {
1100+
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1101+
if (end_sha - p < blksz)
1102+
blksz = end_sha - p;
1103+
wc_Sha384Update(sha384_ctx, p, blksz);
1104+
p += blksz;
1105+
}
10891106
}
1107+
#endif
10901108
return 0;
10911109
}
10921110

@@ -1102,23 +1120,29 @@ static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
11021120
*/
11031121
static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
11041122
{
1105-
uint32_t position = 0;
1106-
uint8_t *p;
1107-
int blksz;
11081123
wc_Sha384 sha384_ctx;
11091124

11101125
if (header_sha384(&sha384_ctx, img) != 0)
11111126
return -1;
1112-
do {
1113-
p = get_sha_block(img, position);
1114-
if (p == NULL)
1115-
break;
1116-
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1117-
if (position + blksz > img->fw_size)
1118-
blksz = img->fw_size - position;
1119-
wc_Sha384Update(&sha384_ctx, p, blksz);
1120-
position += blksz;
1121-
} while(position < img->fw_size);
1127+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1128+
wc_Sha384Update(&sha384_ctx, img->fw_base, img->fw_size);
1129+
#else
1130+
{
1131+
uint32_t position = 0;
1132+
uint8_t* p;
1133+
int blksz;
1134+
do {
1135+
p = get_sha_block(img, position);
1136+
if (p == NULL)
1137+
break;
1138+
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1139+
if (position + blksz > img->fw_size)
1140+
blksz = img->fw_size - position;
1141+
wc_Sha384Update(&sha384_ctx, p, blksz);
1142+
position += blksz;
1143+
} while (position < img->fw_size);
1144+
}
1145+
#endif
11221146

11231147
wc_Sha384Final(&sha384_ctx, hash);
11241148
wc_Sha384Free(&sha384_ctx);
@@ -1165,8 +1189,7 @@ static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
11651189
{
11661190
uint16_t stored_sha_len;
11671191
uint8_t *stored_sha, *end_sha;
1168-
uint8_t *p;
1169-
int blksz;
1192+
uint8_t* p;
11701193

11711194
if (!img)
11721195
return -1;
@@ -1177,13 +1200,20 @@ static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
11771200
return -1;
11781201
wc_InitSha3_384(sha3_ctx, NULL, INVALID_DEVID);
11791202
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
1180-
while (p < end_sha) {
1181-
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1182-
if (end_sha - p < blksz)
1183-
blksz = end_sha - p;
1184-
wc_Sha3_384_Update(sha3_ctx, p, blksz);
1185-
p += blksz;
1203+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1204+
wc_Sha3_384_Update(sha3_ctx, p, (word32)(end_sha - p));
1205+
#else
1206+
{
1207+
int blksz;
1208+
while (p < end_sha) {
1209+
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1210+
if (end_sha - p < blksz)
1211+
blksz = end_sha - p;
1212+
wc_Sha3_384_Update(sha3_ctx, p, blksz);
1213+
p += blksz;
1214+
}
11861215
}
1216+
#endif
11871217
return 0;
11881218
}
11891219

@@ -1198,23 +1228,29 @@ static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
11981228
*/
11991229
static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
12001230
{
1201-
uint8_t *p;
1202-
int blksz;
1203-
uint32_t position = 0;
12041231
wc_Sha3 sha3_ctx;
12051232

12061233
if (header_sha3_384(&sha3_ctx, img) != 0)
12071234
return -1;
1208-
do {
1209-
p = get_sha_block(img, position);
1210-
if (p == NULL)
1211-
break;
1212-
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1213-
if (position + blksz > img->fw_size)
1214-
blksz = img->fw_size - position;
1215-
wc_Sha3_384_Update(&sha3_ctx, p, blksz);
1216-
position += blksz;
1217-
} while(position < img->fw_size);
1235+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1236+
wc_Sha3_384_Update(&sha3_ctx, img->fw_base, img->fw_size);
1237+
#else
1238+
{
1239+
uint8_t* p;
1240+
int blksz;
1241+
uint32_t position = 0;
1242+
do {
1243+
p = get_sha_block(img, position);
1244+
if (p == NULL)
1245+
break;
1246+
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
1247+
if (position + blksz > img->fw_size)
1248+
blksz = img->fw_size - position;
1249+
wc_Sha3_384_Update(&sha3_ctx, p, blksz);
1250+
position += blksz;
1251+
} while (position < img->fw_size);
1252+
}
1253+
#endif
12181254

12191255
wc_Sha3_384_Final(&sha3_ctx, hash);
12201256
wc_Sha3_384_Free(&sha3_ctx);
@@ -1733,6 +1769,10 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx,
17331769
struct wolfBoot_image* img, uint32_t offset,
17341770
uint32_t size)
17351771
{
1772+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1773+
update_hash(ctx, img->fw_base + offset, size);
1774+
return 0;
1775+
#else
17361776
uint32_t current_offset = offset;
17371777
uint32_t remaining_size = size;
17381778
uint8_t read_buf[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED_STACK(4); /* Use local buffer */
@@ -1755,6 +1795,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx,
17551795
current_offset += read_size;
17561796
}
17571797
return 0;
1798+
#endif
17581799
}
17591800

17601801
/*
@@ -1764,6 +1805,11 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx,
17641805
static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr,
17651806
uint32_t size, int src_ext)
17661807
{
1808+
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
1809+
(void)src_ext;
1810+
update_hash(ctx, (uint8_t*)addr, size);
1811+
return 0;
1812+
#else
17671813
uint8_t buffer[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED_STACK(4);
17681814
uint32_t remaining_size = size;
17691815
uintptr_t current_addr = addr;
@@ -1788,6 +1834,7 @@ static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr,
17881834
}
17891835

17901836
return 0;
1837+
#endif
17911838
}
17921839

17931840
int wolfBoot_check_flash_image_elf(uint8_t part, unsigned long* entry_out)

tools/config.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ ifeq ($(ARCH),)
7878
WOLFBOOT_SMALL_STACK?=0
7979
DELTA_UPDATES?=0
8080
DELTA_BLOCK_SIZE?=256
81+
WOLFBOOT_IMG_HASH_ONESHOT?=0
8182
WOLFBOOT_HUGE_STACK?=0
8283
ARMORED?=0
8384
ELF?=0
@@ -107,7 +108,7 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
107108
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
108109
WOLFBOOT_PARTITION_SWAP_ADDRESS WOLFBOOT_LOAD_ADDRESS \
109110
WOLFBOOT_LOAD_DTS_ADDRESS WOLFBOOT_DTS_BOOT_ADDRESS WOLFBOOT_DTS_UPDATE_ADDRESS \
110-
WOLFBOOT_SMALL_STACK DELTA_UPDATES DELTA_BLOCK_SIZE \
111+
WOLFBOOT_SMALL_STACK DELTA_UPDATES DELTA_BLOCK_SIZE WOLFBOOT_IMG_HASH_ONESHOT \
111112
WOLFBOOT_HUGE_STACK FORCE_32BIT\
112113
ENCRYPT_WITH_CHACHA ENCRYPT_WITH_AES128 ENCRYPT_WITH_AES256 ARMORED \
113114
LMS_LEVELS LMS_HEIGHT LMS_WINTERNITZ \

0 commit comments

Comments
 (0)