Skip to content

Commit 3659d21

Browse files
committed
Add RAM_CODE self-update unit coverage
F/2261
1 parent ff60286 commit 3659d21

2 files changed

Lines changed: 199 additions & 6 deletions

File tree

tools/unit-tests/Makefile

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ TESTS:=unit-parser unit-fdt unit-extflash unit-string unit-spi-flash unit-aes128
4646
unit-aes256 unit-chacha20 unit-pci unit-mock-state unit-sectorflags \
4747
unit-image unit-image-rsa unit-nvm unit-nvm-flagshome unit-enc-nvm \
4848
unit-enc-nvm-flagshome unit-delta unit-update-flash \
49+
unit-update-flash-self-update \
4950
unit-update-flash-enc unit-update-ram unit-pkcs11_store unit-psa_store unit-disk \
5051
unit-update-disk unit-multiboot unit-boot-x86-fsp unit-qspi-flash unit-tpm-rsa-exp \
5152
unit-image-nopart unit-image-sha384 unit-image-sha3-384 unit-store-sbrk \
@@ -95,7 +96,13 @@ unit-delta:CFLAGS+=-DNVM_FLASH_WRITEONCE -DMOCK_PARTITIONS -DDELTA_UPDATES -DDEL
9596
unit-pkcs11_store:CFLAGS+=-I$(WOLFBOOT_LIB_WOLFPKCS11) -DMOCK_PARTITIONS -DMOCK_KEYVAULT -DSECURE_PKCS11 -DWOLFPKCS11_USER_SETTINGS
9697
unit-psa_store:CFLAGS+=-I$(WOLFBOOT_LIB_WOLFPSA) -DMOCK_PARTITIONS -DMOCK_KEYVAULT -DWOLFCRYPT_TZ_PSA
9798
unit-update-flash:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
98-
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT
99+
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
100+
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
101+
unit-update-flash-self-update:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
102+
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
103+
-DRAM_CODE -DARCH_SIM -DUNIT_TEST_SELF_UPDATE_ONLY \
104+
-DARCH_FLASH_OFFSET=MOCK_ADDRESS_BOOT -DWOLFBOOT_VERSION=7 \
105+
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
99106
unit-update-ram:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
100107
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
101108
-DPART_SWAP_EXT -DPART_BOOT_EXT -DWOLFBOOT_DUALBOOT -DNO_XIP
@@ -183,6 +190,11 @@ unit-store-sbrk: unit-store-sbrk.c ../../src/store_sbrk.c
183190
unit-string: ../../include/target.h unit-string.c
184191
gcc -o $@ $^ $(CFLAGS) -DDEBUG_UART -DPRINTF_ENABLED $(LDFLAGS)
185192

193+
unit-update-flash-self-update: ../../include/target.h unit-update-flash.c
194+
gcc -o $@ unit-update-flash.c ../../src/image.c \
195+
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c \
196+
$(CFLAGS) $(LDFLAGS)
197+
186198
unit-sdhci-response-bits: ../../include/target.h unit-sdhci-response-bits.c
187199
gcc -o $@ $^ $(CFLAGS) -ffunction-sections -fdata-sections $(LDFLAGS) \
188200
-Wl,--gc-sections
@@ -256,7 +268,8 @@ unit-update-flash: ../../include/target.h unit-update-flash.c
256268
unit-update-flash-enc:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
257269
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
258270
-DPART_SWAP_EXT -DEXT_ENCRYPTED -DENCRYPT_WITH_CHACHA -DHAVE_CHACHA \
259-
-DCUSTOM_ENCRYPT_KEY -DUNIT_TEST_FALLBACK_ONLY
271+
-DCUSTOM_ENCRYPT_KEY -DUNIT_TEST_FALLBACK_ONLY \
272+
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
260273
unit-update-flash-enc: ../../include/target.h unit-update-flash.c
261274
gcc -o $@ unit-update-flash.c ../../src/image.c \
262275
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c \

tools/unit-tests/unit-update-flash.c

Lines changed: 184 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ const char *argv0;
5151
static void reset_mock_stats(void);
5252
static void prepare_flash(void);
5353
static void cleanup_flash(void);
54+
static int add_payload_type(uint8_t part, uint32_t version, uint32_t size,
55+
uint16_t img_type);
5456

5557
#ifdef CUSTOM_ENCRYPT_KEY
5658
int wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce)
@@ -78,6 +80,7 @@ int wolfBoot_erase_encrypt_key(void)
7880
}
7981
#endif
8082

83+
#ifndef UNIT_TEST_SELF_UPDATE_ONLY
8184
START_TEST (test_boot_success_sets_state)
8285
{
8386
uint8_t state = 0;
@@ -96,27 +99,62 @@ START_TEST (test_boot_success_sets_state)
9699
cleanup_flash();
97100
}
98101
END_TEST
102+
#endif
99103

100104
Suite *wolfboot_suite(void);
101105

102106
int wolfBoot_staged_ok = 0;
103107
const uint32_t *wolfBoot_stage_address = (uint32_t *) 0xFFFFFFFF;
108+
#ifdef RAM_CODE
109+
static int arch_reboot_called = 0;
110+
unsigned int _start_text = MOCK_ADDRESS_BOOT;
111+
#endif
104112

105113
void do_boot(const uint32_t *address)
106114
{
107115
/* Mock of do_boot */
116+
#ifndef ARCH_SIM
108117
if (wolfBoot_panicked)
109118
return;
119+
#endif
110120
wolfBoot_staged_ok++;
111121
wolfBoot_stage_address = address;
112122
printf("Called do_boot with address %p\n", address);
113123
}
114124

125+
int hal_flash_protect(haladdr_t address, int len)
126+
{
127+
(void)address;
128+
(void)len;
129+
return 0;
130+
}
131+
115132
static void reset_mock_stats(void)
116133
{
117134
wolfBoot_staged_ok = 0;
135+
#ifndef ARCH_SIM
118136
wolfBoot_panicked = 0;
137+
#endif
138+
erased_boot = 0;
139+
erased_update = 0;
140+
erased_swap = 0;
141+
erased_nvm_bank0 = 0;
142+
erased_nvm_bank1 = 0;
143+
erased_vault = 0;
119144
ext_flash_reset_lock();
145+
#ifdef RAM_CODE
146+
arch_reboot_called = 0;
147+
#endif
148+
}
149+
150+
static void clear_erase_stats(void)
151+
{
152+
erased_boot = 0;
153+
erased_update = 0;
154+
erased_swap = 0;
155+
erased_nvm_bank0 = 0;
156+
erased_nvm_bank1 = 0;
157+
erased_vault = 0;
120158
}
121159

122160

@@ -148,9 +186,15 @@ static void cleanup_flash(void)
148186

149187
#define DIGEST_TLV_OFF_IN_HDR 28
150188
static int add_payload(uint8_t part, uint32_t version, uint32_t size)
189+
{
190+
return add_payload_type(part, version, size,
191+
HDR_IMG_TYPE_AUTH_NONE | HDR_IMG_TYPE_APP);
192+
}
193+
194+
static int add_payload_type(uint8_t part, uint32_t version, uint32_t size,
195+
uint16_t img_type)
151196
{
152197
uint32_t word;
153-
uint16_t word16;
154198
int i;
155199
uint8_t *base = (uint8_t *)(uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
156200
int ret;
@@ -182,9 +226,8 @@ static int add_payload(uint8_t part, uint32_t version, uint32_t size)
182226

183227
word = 2 << 16 | HDR_IMG_TYPE;
184228
hal_flash_write((uintptr_t)base + 16, (void *)&word, 4);
185-
word16 = HDR_IMG_TYPE_AUTH_NONE | HDR_IMG_TYPE_APP;
186-
hal_flash_write((uintptr_t)base + 20, (void *)&word16, 2);
187-
printf("Written img_type: %04X\n", word16);
229+
hal_flash_write((uintptr_t)base + 20, (void *)&img_type, 2);
230+
printf("Written img_type: %04X\n", img_type);
188231

189232
/* Add 28B header to sha calculation */
190233
ret = wc_Sha256Update(&sha, base, DIGEST_TLV_OFF_IN_HDR);
@@ -225,6 +268,104 @@ static int add_payload(uint8_t part, uint32_t version, uint32_t size)
225268

226269
}
227270

271+
#ifdef RAM_CODE
272+
void arch_reboot(void)
273+
{
274+
arch_reboot_called++;
275+
}
276+
277+
START_TEST (test_self_update_sameversion_erased)
278+
{
279+
reset_mock_stats();
280+
prepare_flash();
281+
clear_erase_stats();
282+
add_payload_type(PART_UPDATE, WOLFBOOT_VERSION, TEST_SIZE_SMALL,
283+
HDR_IMG_TYPE_WOLFBOOT | HDR_IMG_TYPE_AUTH);
284+
ext_flash_unlock();
285+
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
286+
ext_flash_lock();
287+
288+
wolfBoot_check_self_update();
289+
290+
ck_assert_int_eq(arch_reboot_called, 0);
291+
ck_assert_int_ge(erased_update, 1);
292+
ck_assert_uint_eq(*(uint32_t *)(uintptr_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS,
293+
0xFFFFFFFFu);
294+
cleanup_flash();
295+
}
296+
END_TEST
297+
298+
START_TEST (test_self_update_oldversion_erased)
299+
{
300+
reset_mock_stats();
301+
prepare_flash();
302+
clear_erase_stats();
303+
add_payload_type(PART_UPDATE, WOLFBOOT_VERSION - 1, TEST_SIZE_SMALL,
304+
HDR_IMG_TYPE_WOLFBOOT | HDR_IMG_TYPE_AUTH);
305+
ext_flash_unlock();
306+
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
307+
ext_flash_lock();
308+
309+
wolfBoot_check_self_update();
310+
311+
ck_assert_int_eq(arch_reboot_called, 0);
312+
ck_assert_int_ge(erased_update, 1);
313+
ck_assert_uint_eq(*(uint32_t *)(uintptr_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS,
314+
0xFFFFFFFFu);
315+
cleanup_flash();
316+
}
317+
END_TEST
318+
319+
START_TEST (test_self_update_newversion_invalid_integrity_denied)
320+
{
321+
uint8_t bad_digest[SHA256_DIGEST_SIZE];
322+
323+
reset_mock_stats();
324+
prepare_flash();
325+
clear_erase_stats();
326+
add_payload_type(PART_UPDATE, WOLFBOOT_VERSION + 1, TEST_SIZE_SMALL,
327+
HDR_IMG_TYPE_WOLFBOOT | HDR_IMG_TYPE_AUTH);
328+
memset(bad_digest, 0xBA, sizeof(bad_digest));
329+
ext_flash_unlock();
330+
ext_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + DIGEST_TLV_OFF_IN_HDR + 4,
331+
bad_digest, sizeof(bad_digest));
332+
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
333+
ext_flash_lock();
334+
335+
wolfBoot_check_self_update();
336+
337+
ck_assert_int_eq(arch_reboot_called, 0);
338+
ck_assert_int_eq(erased_update, 0);
339+
ck_assert_uint_eq(*(uint32_t *)(uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS,
340+
0xFFFFFFFFu);
341+
cleanup_flash();
342+
}
343+
END_TEST
344+
345+
START_TEST (test_self_update_newversion_copies_and_reboots)
346+
{
347+
reset_mock_stats();
348+
prepare_flash();
349+
clear_erase_stats();
350+
add_payload_type(PART_UPDATE, WOLFBOOT_VERSION + 1, TEST_SIZE_SMALL,
351+
HDR_IMG_TYPE_WOLFBOOT | HDR_IMG_TYPE_AUTH);
352+
ext_flash_unlock();
353+
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
354+
ext_flash_lock();
355+
356+
wolfBoot_check_self_update();
357+
358+
ck_assert_int_eq(arch_reboot_called, 1);
359+
ck_assert_int_ge(erased_boot, 1);
360+
ck_assert_mem_eq((const void *)(uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS,
361+
(const void *)(uintptr_t)(WOLFBOOT_PARTITION_UPDATE_ADDRESS + IMAGE_HEADER_SIZE),
362+
FLASHBUFFER_SIZE);
363+
cleanup_flash();
364+
}
365+
END_TEST
366+
#endif
367+
368+
#ifndef UNIT_TEST_SELF_UPDATE_ONLY
228369
#ifdef EXT_ENCRYPTED
229370
static int build_image_buffer(uint8_t part, uint32_t version, uint32_t size,
230371
uint8_t *buf, uint32_t buf_sz)
@@ -676,6 +817,7 @@ START_TEST (test_diffbase_version_reads)
676817
cleanup_flash();
677818
}
678819
END_TEST
820+
#endif
679821

680822

681823
Suite *wolfboot_suite(void)
@@ -684,6 +826,25 @@ Suite *wolfboot_suite(void)
684826
Suite *s = suite_create("wolfboot");
685827

686828
/* Test cases */
829+
#ifdef UNIT_TEST_SELF_UPDATE_ONLY
830+
#ifdef RAM_CODE
831+
TCase *self_update_sameversion = tcase_create("Self update same version erased");
832+
TCase *self_update_oldversion = tcase_create("Self update older version erased");
833+
TCase *self_update_invalid_integrity = tcase_create("Self update invalid integrity denied");
834+
TCase *self_update_success = tcase_create("Self update success");
835+
836+
tcase_add_test(self_update_sameversion, test_self_update_sameversion_erased);
837+
tcase_add_test(self_update_oldversion, test_self_update_oldversion_erased);
838+
tcase_add_test(self_update_invalid_integrity, test_self_update_newversion_invalid_integrity_denied);
839+
tcase_add_test(self_update_success, test_self_update_newversion_copies_and_reboots);
840+
841+
suite_add_tcase(s, self_update_sameversion);
842+
suite_add_tcase(s, self_update_oldversion);
843+
suite_add_tcase(s, self_update_invalid_integrity);
844+
suite_add_tcase(s, self_update_success);
845+
#endif
846+
return s;
847+
#else
687848
#ifdef UNIT_TEST_FALLBACK_ONLY
688849
TCase *fallback_verify = tcase_create("Fallback verify");
689850
#else
@@ -712,6 +873,12 @@ Suite *wolfboot_suite(void)
712873
TCase *swap_resume = tcase_create("Swap resume noop");
713874
TCase *diffbase_version = tcase_create("Diffbase version lookup");
714875
TCase *boot_success = tcase_create("Boot success state");
876+
#ifdef RAM_CODE
877+
TCase *self_update_sameversion = tcase_create("Self update same version erased");
878+
TCase *self_update_oldversion = tcase_create("Self update older version erased");
879+
TCase *self_update_invalid_integrity = tcase_create("Self update invalid integrity denied");
880+
TCase *self_update_success = tcase_create("Self update success");
881+
#endif
715882
#ifdef EXT_ENCRYPTED
716883
TCase *fallback_verify = tcase_create("Fallback verify");
717884
#endif
@@ -743,6 +910,12 @@ Suite *wolfboot_suite(void)
743910
tcase_add_test(swap_resume, test_swap_resume_noop);
744911
tcase_add_test(diffbase_version, test_diffbase_version_reads);
745912
tcase_add_test(boot_success, test_boot_success_sets_state);
913+
#ifdef RAM_CODE
914+
tcase_add_test(self_update_sameversion, test_self_update_sameversion_erased);
915+
tcase_add_test(self_update_oldversion, test_self_update_oldversion_erased);
916+
tcase_add_test(self_update_invalid_integrity, test_self_update_newversion_invalid_integrity_denied);
917+
tcase_add_test(self_update_success, test_self_update_newversion_copies_and_reboots);
918+
#endif
746919
#ifdef EXT_ENCRYPTED
747920
tcase_add_test(fallback_verify, test_fallback_image_verification_rejects_corruption);
748921
#endif
@@ -765,6 +938,12 @@ Suite *wolfboot_suite(void)
765938
suite_add_tcase(s, swap_resume);
766939
suite_add_tcase(s, diffbase_version);
767940
suite_add_tcase(s, boot_success);
941+
#ifdef RAM_CODE
942+
suite_add_tcase(s, self_update_sameversion);
943+
suite_add_tcase(s, self_update_oldversion);
944+
suite_add_tcase(s, self_update_invalid_integrity);
945+
suite_add_tcase(s, self_update_success);
946+
#endif
768947
#ifdef EXT_ENCRYPTED
769948
suite_add_tcase(s, fallback_verify);
770949
#endif
@@ -773,6 +952,7 @@ Suite *wolfboot_suite(void)
773952

774953

775954
return s;
955+
#endif
776956
}
777957

778958

0 commit comments

Comments
 (0)