From dd4bd8e91a7b9021cf2348685a646040e6067820 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 16 Jul 2024 16:06:54 +0200 Subject: [PATCH 1/5] Added new unit tests for NVM_FLASH_WRITEONCE --- tools/unit-tests/Makefile | 6 +- tools/unit-tests/target.h | 8 ++ tools/unit-tests/unit-nvm.c | 223 ++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 tools/unit-tests/unit-nvm.c diff --git a/tools/unit-tests/Makefile b/tools/unit-tests/Makefile index f6902cdd6..50a4aa5dc 100644 --- a/tools/unit-tests/Makefile +++ b/tools/unit-tests/Makefile @@ -17,7 +17,7 @@ WOLFCRYPT=../../lib/wolfssl/ TESTS:=unit-parser unit-extflash unit-aes128 unit-aes256 unit-chacha20 unit-pci \ - unit-mock-state unit-sectorflags unit-image + unit-mock-state unit-sectorflags unit-image unit-nvm all: $(TESTS) @@ -39,6 +39,7 @@ unit-aes128:CFLAGS+=-DEXT_ENCRYPTED -DENCRYPT_WITH_AES128 unit-aes256:CFLAGS+=-DEXT_ENCRYPTED -DENCRYPT_WITH_AES256 unit-chacha20:CFLAGS+=-DEXT_ENCRYPTED -DENCRYPT_WITH_CHACHA unit-parser:CFLAGS+=-DNVM_FLASH_WRITEONCE +unit-nvm:CFLAGS+=-DNVM_FLASH_WRITEONCE -DMOCK_PARTITIONS WOLFCRYPT_SRC:=$(WOLFCRYPT)/wolfcrypt/src/sha.c \ @@ -86,6 +87,9 @@ unit-sectorflags: ../../include/target.h unit-sectorflags.c unit-image: unit-image.c unit-common.c $(WOLFCRYPT_SRC) gcc -o $@ $^ $(CFLAGS) $(WOLFCRYPT_CFLAGS) $(LDFLAGS) +unit-nvm: ../../include/target.h unit-nvm.c + gcc -o $@ unit-nvm.c $(CFLAGS) $(LDFLAGS) + %.o:%.c gcc -c -o $@ $^ $(CFLAGS) diff --git a/tools/unit-tests/target.h b/tools/unit-tests/target.h index bb910d37b..67e92866b 100644 --- a/tools/unit-tests/target.h +++ b/tools/unit-tests/target.h @@ -34,6 +34,13 @@ #define WOLFBOOT_SECTOR_SIZE 0x400 +#ifdef MOCK_PARTITIONS + #define WOLFBOOT_PARTITION_BOOT_ADDRESS 0xCD000000 + #define WOLFBOOT_PARTITION_SIZE 0x8000 + #define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0xCC000000 + #define WOLFBOOT_PARTITION_SWAP_ADDRESS 0xCE000000 +#else + #ifdef WOLFBOOT_FIXED_PARTITIONS #ifdef PULL_LINKER_DEFINES @@ -66,6 +73,7 @@ /* Load address in RAM for staged OS (update_ram only) */ #define WOLFBOOT_LOAD_ADDRESS 0x200000 #define WOLFBOOT_LOAD_DTS_ADDRESS 0x400000 +#endif /* MOCK_PARTITIONS */ #endif /* !H_TARGETS_TARGET_ */ diff --git a/tools/unit-tests/unit-nvm.c b/tools/unit-tests/unit-nvm.c new file mode 100644 index 000000000..99cecf772 --- /dev/null +++ b/tools/unit-tests/unit-nvm.c @@ -0,0 +1,223 @@ +#define WOLFBOOT_HASH_SHA256 +#define IMAGE_HEADER_SIZE 256 +#define UNIT_TEST +#define WC_NO_HARDEN +#define MOCK_ADDRESS 0xCC000000 +#include +#include "libwolfboot.c" +#include +#include +#include +#include + +static int locked = 0; +static int erased_boot = 0; +static int erased_update = 0; +static int erased_nvm_bank0 = 0; +static int erased_nvm_bank1 = 0; + + + + + +/* Mocks */ +void hal_init(void) +{ +} +int hal_flash_write(haladdr_t address, const uint8_t *data, int len) +{ + int i; + uint8_t *a = (uint8_t *)address; + if ((address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) && + (address < WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE)) { + for (i = 0; i < len; i++) { + a[i] = data[i]; + } + } + return 0; +} +int hal_flash_erase(haladdr_t address, int len) +{ + if ((address >= WOLFBOOT_PARTITION_BOOT_ADDRESS) && + (address < WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE)) { + erased_boot++; + } else if ((address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) && + (address < WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE)) { + erased_update++; + if (address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE) { + erased_nvm_bank0++; + } else if (address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - 2 * WOLFBOOT_SECTOR_SIZE) { + erased_nvm_bank1++; + } + } else { + fail("Invalid address\n"); + return -1; + } + return 0; +} +void hal_flash_unlock(void) +{ + fail_unless(locked, "Double unlock detected\n"); + locked--; +} +void hal_flash_lock(void) +{ + fail_if(locked, "Double lock detected\n"); + locked++; +} + +void hal_prepare_boot(void) +{ +} + +/* A simple mock memory */ +static int mmap_file(const char *path, uint8_t *address, uint8_t** ret_address) +{ + struct stat st = { 0 }; + uint8_t *mmaped_addr; + int ret; + int fd; + int i; + + if (path == NULL) + return -1; + + fd = open(path, O_RDWR|O_CREAT|O_TRUNC, 0666); + if (fd == -1) { + fprintf(stderr, "can't open %s\n", path); + return -1; + } + fprintf(stderr, "Open file: %s success.\n", path); + for (i = 0; i < WOLFBOOT_PARTITION_SIZE; i+=4) { + const uint32_t erased_word = 0xFFFFFFFF; + write(fd, &erased_word, 4); + } + lseek(fd, SEEK_SET, 0); + + mmaped_addr = mmap(address, WOLFBOOT_PARTITION_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (mmaped_addr == MAP_FAILED) { + fprintf(stderr, "MMAP failed.\n"); + return -1; + } + + fprintf(stderr, "Simulator assigned %s to base %p\n", path, mmaped_addr); + + if (ret_address) + *ret_address = mmaped_addr; + + close(fd); + return 0; +} + + +/* End Mocks */ + +Suite *wolfboot_suite(void); + + +START_TEST (test_nvm_select_fresh_sector) +{ + int ret; + const char BOOT[] = "BOOT"; + uint8_t st; + ret = mmap_file("/tmp/wolfboot-unit-file.bin", MOCK_ADDRESS, NULL); + + /* Erased flag sectors: select '0' by default */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 0, "Failed to select default fresh sector\n"); + + /* Force a good 'magic' at the end of sector 1 */ + hal_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - + (WOLFBOOT_SECTOR_SIZE + 4), BOOT, 4); + + /* Current selected should now be 1 */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 1, "Failed to select good fresh sector\n"); + + erased_nvm_bank1 = 0; + erased_nvm_bank0 = 0; + + /* Calling 'set_partition_state' should change the current sector */ + wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING); + + /* Current selected should now be 0 */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 0, "Failed to select updating fresh sector\n"); + fail_if(erased_nvm_bank1 == 0, "Did not erase the non-selected bank"); + + erased_nvm_bank1 = 0; + erased_nvm_bank0 = 0; + + /* Check state is read back correctly */ + ret = wolfBoot_get_partition_state(PART_UPDATE, &st); + fail_if(ret != 0, "Failed to read back state\n"); + fail_if(st != IMG_STATE_UPDATING, "Bootloader in the wrong state\n"); + + /* Check that reading did not change the current sector */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 0, "Failed to select right sector after reading\n"); + + /* Update one sector flag, it should change nvm sector */ + wolfBoot_set_update_sector_flag(0, SECT_FLAG_SWAPPING); + + /* Current selected should now be 1 */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 1, "Failed to select updating fresh sector\n"); + fail_if(erased_nvm_bank0 == 0, "Did not erase the non-selected bank"); + + /* Check sector state is read back correctly */ + ret = wolfBoot_get_update_sector_flag(0, &st); + fail_if (ret != 0, "Failed to read sector flag state\n"); + fail_if (st != SECT_FLAG_SWAPPING, "Wrong sector flag state\n"); + + /* Check that reading did not change the current sector (1) */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 1, "Failed to select right sector after reading sector state\n"); + + /* Update sector flag, again. it should change nvm sector */ + erased_nvm_bank1 = 0; + erased_nvm_bank0 = 0; + wolfBoot_set_update_sector_flag(0, SECT_FLAG_UPDATED); + + /* Current selected should now be 0 */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 0, "Failed to select updating fresh sector\n"); + fail_if(erased_nvm_bank1 == 0, "Did not erase the non-selected bank"); + + /* Check sector state is read back correctly */ + ret = wolfBoot_get_update_sector_flag(0, &st); + fail_if (ret != 0, "Failed to read sector flag state\n"); + fail_if (st != SECT_FLAG_UPDATED, "Wrong sector flag state\n"); + + + +} +END_TEST + + +Suite *wolfboot_suite(void) +{ + + /* Suite initialization */ + Suite *s = suite_create("wolfBoot-NVM-workarounds"); + + /* Test cases */ + TCase *nvm_select_fresh_sector = tcase_create("NVM select fresh sector"); + tcase_add_test(nvm_select_fresh_sector, test_nvm_select_fresh_sector); + suite_add_tcase(s, nvm_select_fresh_sector); + + return s; +} + + +int main(void) +{ + int fails; + Suite *s = wolfboot_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + fails = srunner_ntests_failed(sr); + srunner_free(sr); + return fails; +} From 230174e2f7c9dfacd04a1ced81794518c171d27b Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 16 Jul 2024 16:16:46 +0200 Subject: [PATCH 2/5] nvm_select_fresh_sector: fix flag offset The offset for the sector flags position to compare the two redundant blocks with NVM_FLASH_WRITEONCE mode was wrong, resulting in a negative offset, which in turn caused an out-of-bound access outside of the UPDATE partition space. --- src/libwolfboot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 7ff05953e..518703ba3 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -308,8 +308,8 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part) break; } /* Examine previous position one byte ahead */ - byte_0 = get_base_offset(base, (1 - off)); - byte_1 = get_base_offset(base, (1 - (WOLFBOOT_SECTOR_SIZE + off))); + byte_0 = get_base_offset(base, (off - 1)); + byte_1 = get_base_offset(base, ((WOLFBOOT_SECTOR_SIZE + off) - 1)); sel = FLAG_CMP(byte_0, byte_1); break; From 80fa66fe44477900adeb3e19ebfa963662ba508b Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 16 Jul 2024 16:46:03 +0200 Subject: [PATCH 3/5] Added more tests --- tools/unit-tests/unit-nvm.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/tools/unit-tests/unit-nvm.c b/tools/unit-tests/unit-nvm.c index 99cecf772..f3f88a272 100644 --- a/tools/unit-tests/unit-nvm.c +++ b/tools/unit-tests/unit-nvm.c @@ -44,6 +44,7 @@ int hal_flash_erase(haladdr_t address, int len) } else if ((address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) && (address < WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE)) { erased_update++; + memset(address, 0xFF, len); if (address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE) { erased_nvm_bank0++; } else if (address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - 2 * WOLFBOOT_SECTOR_SIZE) { @@ -89,10 +90,10 @@ static int mmap_file(const char *path, uint8_t *address, uint8_t** ret_address) } fprintf(stderr, "Open file: %s success.\n", path); for (i = 0; i < WOLFBOOT_PARTITION_SIZE; i+=4) { - const uint32_t erased_word = 0xFFFFFFFF; - write(fd, &erased_word, 4); + const uint32_t erased_word = 0xBADBADBA; + write(fd, &erased_word, 4); } - lseek(fd, SEEK_SET, 0); + lseek(fd, SEEK_SET, 0); mmaped_addr = mmap(address, WOLFBOOT_PARTITION_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); @@ -120,16 +121,23 @@ START_TEST (test_nvm_select_fresh_sector) { int ret; const char BOOT[] = "BOOT"; + const uint32_t *boot_word = (const uint32_t *)BOOT; uint8_t st; + uint32_t *magic; ret = mmap_file("/tmp/wolfboot-unit-file.bin", MOCK_ADDRESS, NULL); + erased_update = 0; + wolfBoot_erase_partition(PART_UPDATE); + fail_if(erased_update != 1); /* Erased flag sectors: select '0' by default */ ret = nvm_select_fresh_sector(PART_UPDATE); fail_if(ret != 0, "Failed to select default fresh sector\n"); - /* Force a good 'magic' at the end of sector 1 */ - hal_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - - (WOLFBOOT_SECTOR_SIZE + 4), BOOT, 4); + /* Force a good 'magic' at the end of sector 1 by setting the magic word */ + wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_NEW); + magic = get_partition_magic(PART_UPDATE); + fail_if(*magic != *boot_word, + "Failed to read back 'BOOT' trailer at the end of the partition"); /* Current selected should now be 1 */ ret = nvm_select_fresh_sector(PART_UPDATE); @@ -145,7 +153,7 @@ START_TEST (test_nvm_select_fresh_sector) ret = nvm_select_fresh_sector(PART_UPDATE); fail_if(ret != 0, "Failed to select updating fresh sector\n"); fail_if(erased_nvm_bank1 == 0, "Did not erase the non-selected bank"); - + erased_nvm_bank1 = 0; erased_nvm_bank0 = 0; @@ -160,7 +168,7 @@ START_TEST (test_nvm_select_fresh_sector) /* Update one sector flag, it should change nvm sector */ wolfBoot_set_update_sector_flag(0, SECT_FLAG_SWAPPING); - + /* Current selected should now be 1 */ ret = nvm_select_fresh_sector(PART_UPDATE); fail_if(ret != 1, "Failed to select updating fresh sector\n"); @@ -170,16 +178,16 @@ START_TEST (test_nvm_select_fresh_sector) ret = wolfBoot_get_update_sector_flag(0, &st); fail_if (ret != 0, "Failed to read sector flag state\n"); fail_if (st != SECT_FLAG_SWAPPING, "Wrong sector flag state\n"); - + /* Check that reading did not change the current sector (1) */ ret = nvm_select_fresh_sector(PART_UPDATE); fail_if(ret != 1, "Failed to select right sector after reading sector state\n"); - + /* Update sector flag, again. it should change nvm sector */ erased_nvm_bank1 = 0; erased_nvm_bank0 = 0; wolfBoot_set_update_sector_flag(0, SECT_FLAG_UPDATED); - + /* Current selected should now be 0 */ ret = nvm_select_fresh_sector(PART_UPDATE); fail_if(ret != 0, "Failed to select updating fresh sector\n"); @@ -190,7 +198,9 @@ START_TEST (test_nvm_select_fresh_sector) fail_if (ret != 0, "Failed to read sector flag state\n"); fail_if (st != SECT_FLAG_UPDATED, "Wrong sector flag state\n"); - + /* Check that reading did not change the current sector (0) */ + ret = nvm_select_fresh_sector(PART_UPDATE); + fail_if(ret != 0, "Failed to select right sector after reading sector state\n"); } END_TEST From a7668842c77113317af7a20e3a93c1176e623cac Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 16 Jul 2024 17:18:41 +0200 Subject: [PATCH 4/5] Remove silencer for -Warray-bounds --- src/libwolfboot.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 518703ba3..58f335155 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -176,18 +176,10 @@ static const uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL; #include static uint8_t NVM_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(16))); static int nvm_cached_sector = 0; - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Warray-bounds" -#endif static uint8_t get_base_offset(uint8_t *base, uintptr_t off) { return *(base - off); /* ignore array bounds error */ } -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif void WEAKFUNCTION hal_cache_invalidate(void) { From 8f0c090b69b8da3b1d3d01baafd82cbfcb499085 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 16 Jul 2024 17:37:01 +0200 Subject: [PATCH 5/5] Unit tests for memory blob parsers --- tools/unit-tests/unit-parser.c | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/tools/unit-tests/unit-parser.c b/tools/unit-tests/unit-parser.c index 51c6033ca..b275dc144 100644 --- a/tools/unit-tests/unit-parser.c +++ b/tools/unit-tests/unit-parser.c @@ -100,6 +100,81 @@ static uint8_t test_buffer[512] = { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, }; +static uint8_t test_buffer_with_type[512] = { + 'W', 'O', 'L', 'F', 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x0d, 0x0c, 0x0b, 0x0a, + 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x08, 0x00, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x02, 0x00, + 0xEE, 0xDD, 0xFF, 0xFF, 0x03, 0x00, 0x20, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*<-- end of options */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* End HDR */ + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, +}; + +static uint8_t test_buffer_with_diffbase[512] = { + 'W', 'O', 'L', 'F', 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x0d, 0x0c, 0x0b, 0x0a, + 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x08, 0x00, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x02, 0x00, + 0xEE, 0xDD, 0xFF, 0xFF, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x03, 0x02, 0x01, 0x03, 0x00, 0x20, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*<-- end of options */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* End HDR */ + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, +}; + + START_TEST (test_parser_sunny) { uint8_t *p; @@ -167,6 +242,24 @@ START_TEST (test_parser_borders) } END_TEST +START_TEST (test_parser_blobs) +{ + uint32_t ver; + uint16_t type; + ver = wolfBoot_get_blob_version(test_buffer); + fail_unless(ver == 0x0a0b0c0d, "Parser error: version does not match"); + + type = wolfBoot_get_blob_type(test_buffer_with_type); + fail_unless(type == 0xDDEE, "Wrong image type"); + + type = wolfBoot_get_blob_type(test_buffer); + fail_unless(type == 0, "Reading non-existing version: failed to report error"); + ver = wolfBoot_get_blob_diffbase_version(test_buffer_with_diffbase); + fail_unless(ver == 0x01020304, "Wrong delta base version parsed"); + +} +END_TEST + Suite *wolfboot_suite(void) { @@ -176,15 +269,19 @@ Suite *wolfboot_suite(void) /* Test cases */ TCase *parser_sunny = tcase_create("Parser Sunny-day case"); TCase *parser_borders = tcase_create("Parser test buffer borders"); + TCase *parser_blobs = tcase_create("Parser test blobs"); + /* Test function <-> Test case */ tcase_add_test(parser_sunny, test_parser_sunny); tcase_add_test(parser_borders, test_parser_borders); + tcase_add_test(parser_blobs, test_parser_blobs); /* Set parameters + add to suite */ tcase_set_timeout(parser_sunny, 20); suite_add_tcase(s, parser_sunny); suite_add_tcase(s, parser_borders); + suite_add_tcase(s, parser_blobs); return s; }