mirror of https://github.com/wolfSSL/wolfBoot.git
Add oneshot hash build option
parent
1253995283
commit
f7ea40f7cc
|
|
@ -40,3 +40,11 @@ jobs:
|
|||
- name: Run bootloader with no arguments
|
||||
run: |
|
||||
./wolfboot.elf
|
||||
|
||||
- name: Build wolfboot.elf (ELF_SCATTERED, ONESHOT_HASH)
|
||||
run: |
|
||||
make clean && make test-sim-internal-flash-with-update ELF=1 ELF_SCATTERED=1 WOLFBOOT_IMG_HASH_ONESHOT=1
|
||||
|
||||
- name: Run bootloader with no arguments (ONESHOT_HASH)
|
||||
run: |
|
||||
./wolfboot.elf
|
||||
|
|
|
|||
|
|
@ -336,6 +336,30 @@ jobs:
|
|||
run: |
|
||||
tools/scripts/sim-sunnyday-update.sh
|
||||
|
||||
- name: Build wolfboot.elf (ECC256, ONESHOT_HASH, SHA256)
|
||||
run: |
|
||||
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 SPMATH=1 WOLFBOOT_IMG_HASH_ONESHOT=1
|
||||
|
||||
- name: Run sunny day update test (ONESHOT_HASH, SHA256)
|
||||
run: |
|
||||
tools/scripts/sim-sunnyday-update.sh
|
||||
|
||||
- name: Build wolfboot.elf (ECC256, ONESHOT_HASH, SHA384)
|
||||
run: |
|
||||
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 SPMATH=1 HASH=SHA384 WOLFBOOT_IMG_HASH_ONESHOT=1
|
||||
|
||||
- name: Run sunny day update test (ONESHOT_HASH, SHA384)
|
||||
run: |
|
||||
tools/scripts/sim-sunnyday-update.sh
|
||||
|
||||
- name: Build wolfboot.elf (ECC256, ONESHOT_HASH, SHA3)
|
||||
run: |
|
||||
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 SPMATH=1 HASH=SHA3 WOLFBOOT_IMG_HASH_ONESHOT=1
|
||||
|
||||
- name: Run sunny day update test (ONESHOT_HASH, SHA3)
|
||||
run: |
|
||||
tools/scripts/sim-sunnyday-update.sh
|
||||
|
||||
- name: Cleanup to change key type
|
||||
run: |
|
||||
make keysclean
|
||||
|
|
|
|||
|
|
@ -189,6 +189,22 @@ falls in one of these cases, wolfBoot compilation will terminate with an explici
|
|||
In some cases you might have enough memory available to allow large stack allocations.
|
||||
To circumvent the compile-time checks on the maximum allowed stack size, use `WOLFBOOT_HUGE_STACK=1`.
|
||||
|
||||
### One-shot hash verification
|
||||
|
||||
By default, wolfBoot hashes firmware images in blocks of `WOLFBOOT_SHA_BLOCK_SIZE` bytes during
|
||||
verification. This block-by-block approach is required when firmware resides in external flash or
|
||||
other non-memory-mapped storage, where data must be read through intermediate buffers.
|
||||
|
||||
When firmware images are stored in directly memory-mapped flash (e.g. internal flash with
|
||||
execute-in-place support), the block-by-block overhead can be eliminated by enabling
|
||||
`WOLFBOOT_IMG_HASH_ONESHOT=1`. With this option, the entire image buffer is passed to the wolfCrypt
|
||||
hash function in a single call, which can improve verification performance.
|
||||
|
||||
**warning** This option assumes that `fw_base` pointers are directly dereferenceable for the full
|
||||
firmware size. It is incompatible with `EXT_FLASH=1` configurations where partitions reside on
|
||||
external SPI or UART flash. Only use `WOLFBOOT_IMG_HASH_ONESHOT=1` when all firmware partitions are
|
||||
in directly addressable, memory-mapped flash.
|
||||
|
||||
### Disable Backup of current running firmware
|
||||
|
||||
Optionally, it is possible to disable the backup copy of the current running firmware upon the installation of the
|
||||
|
|
|
|||
|
|
@ -796,6 +796,10 @@ ifeq ($(ARMORED),1)
|
|||
CFLAGS+=-DWOLFBOOT_ARMORED
|
||||
endif
|
||||
|
||||
ifeq ($(WOLFBOOT_IMG_HASH_ONESHOT),1)
|
||||
CFLAGS+=-DWOLFBOOT_IMG_HASH_ONESHOT
|
||||
endif
|
||||
|
||||
ifeq ($(WOLFBOOT_HUGE_STACK),1)
|
||||
CFLAGS+=-DWOLFBOOT_HUGE_STACK
|
||||
endif
|
||||
|
|
|
|||
173
src/image.c
173
src/image.c
|
|
@ -974,8 +974,7 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
|
|||
{
|
||||
uint8_t *stored_sha, *end_sha;
|
||||
uint16_t stored_sha_len;
|
||||
uint8_t *p;
|
||||
int blksz;
|
||||
uint8_t* p;
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
|
|
@ -989,13 +988,20 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
|
|||
wc_InitSha256(sha256_ctx);
|
||||
#endif
|
||||
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
|
||||
while (p < end_sha) {
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (end_sha - p < blksz)
|
||||
blksz = end_sha - p;
|
||||
wc_Sha256Update(sha256_ctx, p, blksz);
|
||||
p += blksz;
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
wc_Sha256Update(sha256_ctx, p, (word32)(end_sha - p));
|
||||
#else
|
||||
{
|
||||
int blksz;
|
||||
while (p < end_sha) {
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (end_sha - p < blksz)
|
||||
blksz = end_sha - p;
|
||||
wc_Sha256Update(sha256_ctx, p, blksz);
|
||||
p += blksz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1008,23 +1014,29 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
|
|||
*/
|
||||
static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
|
||||
{
|
||||
uint32_t position = 0;
|
||||
uint8_t *p;
|
||||
int blksz;
|
||||
wc_Sha256 sha256_ctx;
|
||||
|
||||
if (header_sha256(&sha256_ctx, img) != 0)
|
||||
return -1;
|
||||
do {
|
||||
p = get_sha_block(img, position);
|
||||
if (p == NULL)
|
||||
break;
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (position + blksz > img->fw_size)
|
||||
blksz = img->fw_size - position;
|
||||
wc_Sha256Update(&sha256_ctx, p, blksz);
|
||||
position += blksz;
|
||||
} while(position < img->fw_size);
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
wc_Sha256Update(&sha256_ctx, img->fw_base, img->fw_size);
|
||||
#else
|
||||
{
|
||||
uint32_t position = 0;
|
||||
uint8_t* p;
|
||||
int blksz;
|
||||
do {
|
||||
p = get_sha_block(img, position);
|
||||
if (p == NULL)
|
||||
break;
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (position + blksz > img->fw_size)
|
||||
blksz = img->fw_size - position;
|
||||
wc_Sha256Update(&sha256_ctx, p, blksz);
|
||||
position += blksz;
|
||||
} while (position < img->fw_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
wc_Sha256Final(&sha256_ctx, hash);
|
||||
wc_Sha256Free(&sha256_ctx);
|
||||
|
|
@ -1065,8 +1077,7 @@ static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
|
|||
{
|
||||
uint16_t stored_sha_len;
|
||||
uint8_t *stored_sha, *end_sha;
|
||||
uint8_t *p;
|
||||
int blksz;
|
||||
uint8_t* p;
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
|
|
@ -1080,13 +1091,20 @@ static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
|
|||
wc_InitSha384(sha384_ctx);
|
||||
#endif
|
||||
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
|
||||
while (p < end_sha) {
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (end_sha - p < blksz)
|
||||
blksz = end_sha - p;
|
||||
wc_Sha384Update(sha384_ctx, p, blksz);
|
||||
p += blksz;
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
wc_Sha384Update(sha384_ctx, p, (word32)(end_sha - p));
|
||||
#else
|
||||
{
|
||||
int blksz;
|
||||
while (p < end_sha) {
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (end_sha - p < blksz)
|
||||
blksz = end_sha - p;
|
||||
wc_Sha384Update(sha384_ctx, p, blksz);
|
||||
p += blksz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1102,23 +1120,29 @@ static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
|
|||
*/
|
||||
static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
|
||||
{
|
||||
uint32_t position = 0;
|
||||
uint8_t *p;
|
||||
int blksz;
|
||||
wc_Sha384 sha384_ctx;
|
||||
|
||||
if (header_sha384(&sha384_ctx, img) != 0)
|
||||
return -1;
|
||||
do {
|
||||
p = get_sha_block(img, position);
|
||||
if (p == NULL)
|
||||
break;
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (position + blksz > img->fw_size)
|
||||
blksz = img->fw_size - position;
|
||||
wc_Sha384Update(&sha384_ctx, p, blksz);
|
||||
position += blksz;
|
||||
} while(position < img->fw_size);
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
wc_Sha384Update(&sha384_ctx, img->fw_base, img->fw_size);
|
||||
#else
|
||||
{
|
||||
uint32_t position = 0;
|
||||
uint8_t* p;
|
||||
int blksz;
|
||||
do {
|
||||
p = get_sha_block(img, position);
|
||||
if (p == NULL)
|
||||
break;
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (position + blksz > img->fw_size)
|
||||
blksz = img->fw_size - position;
|
||||
wc_Sha384Update(&sha384_ctx, p, blksz);
|
||||
position += blksz;
|
||||
} while (position < img->fw_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
wc_Sha384Final(&sha384_ctx, hash);
|
||||
wc_Sha384Free(&sha384_ctx);
|
||||
|
|
@ -1165,8 +1189,7 @@ static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
|
|||
{
|
||||
uint16_t stored_sha_len;
|
||||
uint8_t *stored_sha, *end_sha;
|
||||
uint8_t *p;
|
||||
int blksz;
|
||||
uint8_t* p;
|
||||
|
||||
if (!img)
|
||||
return -1;
|
||||
|
|
@ -1177,13 +1200,20 @@ static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
|
|||
return -1;
|
||||
wc_InitSha3_384(sha3_ctx, NULL, INVALID_DEVID);
|
||||
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
|
||||
while (p < end_sha) {
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (end_sha - p < blksz)
|
||||
blksz = end_sha - p;
|
||||
wc_Sha3_384_Update(sha3_ctx, p, blksz);
|
||||
p += blksz;
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
wc_Sha3_384_Update(sha3_ctx, p, (word32)(end_sha - p));
|
||||
#else
|
||||
{
|
||||
int blksz;
|
||||
while (p < end_sha) {
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (end_sha - p < blksz)
|
||||
blksz = end_sha - p;
|
||||
wc_Sha3_384_Update(sha3_ctx, p, blksz);
|
||||
p += blksz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1198,23 +1228,29 @@ static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
|
|||
*/
|
||||
static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
|
||||
{
|
||||
uint8_t *p;
|
||||
int blksz;
|
||||
uint32_t position = 0;
|
||||
wc_Sha3 sha3_ctx;
|
||||
|
||||
if (header_sha3_384(&sha3_ctx, img) != 0)
|
||||
return -1;
|
||||
do {
|
||||
p = get_sha_block(img, position);
|
||||
if (p == NULL)
|
||||
break;
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (position + blksz > img->fw_size)
|
||||
blksz = img->fw_size - position;
|
||||
wc_Sha3_384_Update(&sha3_ctx, p, blksz);
|
||||
position += blksz;
|
||||
} while(position < img->fw_size);
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
wc_Sha3_384_Update(&sha3_ctx, img->fw_base, img->fw_size);
|
||||
#else
|
||||
{
|
||||
uint8_t* p;
|
||||
int blksz;
|
||||
uint32_t position = 0;
|
||||
do {
|
||||
p = get_sha_block(img, position);
|
||||
if (p == NULL)
|
||||
break;
|
||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
||||
if (position + blksz > img->fw_size)
|
||||
blksz = img->fw_size - position;
|
||||
wc_Sha3_384_Update(&sha3_ctx, p, blksz);
|
||||
position += blksz;
|
||||
} while (position < img->fw_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
wc_Sha3_384_Final(&sha3_ctx, hash);
|
||||
wc_Sha3_384_Free(&sha3_ctx);
|
||||
|
|
@ -1733,6 +1769,10 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx,
|
|||
struct wolfBoot_image* img, uint32_t offset,
|
||||
uint32_t size)
|
||||
{
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
update_hash(ctx, img->fw_base + offset, size);
|
||||
return 0;
|
||||
#else
|
||||
uint32_t current_offset = offset;
|
||||
uint32_t remaining_size = size;
|
||||
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,
|
|||
current_offset += read_size;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1764,6 +1805,11 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx,
|
|||
static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr,
|
||||
uint32_t size, int src_ext)
|
||||
{
|
||||
#ifdef WOLFBOOT_IMG_HASH_ONESHOT
|
||||
(void)src_ext;
|
||||
update_hash(ctx, (uint8_t*)addr, size);
|
||||
return 0;
|
||||
#else
|
||||
uint8_t buffer[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED_STACK(4);
|
||||
uint32_t remaining_size = size;
|
||||
uintptr_t current_addr = addr;
|
||||
|
|
@ -1788,6 +1834,7 @@ static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr,
|
|||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int wolfBoot_check_flash_image_elf(uint8_t part, unsigned long* entry_out)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ ifeq ($(ARCH),)
|
|||
WOLFBOOT_SMALL_STACK?=0
|
||||
DELTA_UPDATES?=0
|
||||
DELTA_BLOCK_SIZE?=256
|
||||
WOLFBOOT_IMG_HASH_ONESHOT?=0
|
||||
WOLFBOOT_HUGE_STACK?=0
|
||||
ARMORED?=0
|
||||
ELF?=0
|
||||
|
|
@ -107,7 +108,7 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
|
|||
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS WOLFBOOT_LOAD_ADDRESS \
|
||||
WOLFBOOT_LOAD_DTS_ADDRESS WOLFBOOT_DTS_BOOT_ADDRESS WOLFBOOT_DTS_UPDATE_ADDRESS \
|
||||
WOLFBOOT_SMALL_STACK DELTA_UPDATES DELTA_BLOCK_SIZE \
|
||||
WOLFBOOT_SMALL_STACK DELTA_UPDATES DELTA_BLOCK_SIZE WOLFBOOT_IMG_HASH_ONESHOT \
|
||||
WOLFBOOT_HUGE_STACK FORCE_32BIT\
|
||||
ENCRYPT_WITH_CHACHA ENCRYPT_WITH_AES128 ENCRYPT_WITH_AES256 ARMORED \
|
||||
LMS_LEVELS LMS_HEIGHT LMS_WINTERNITZ \
|
||||
|
|
|
|||
Loading…
Reference in New Issue