From 7b7ed4dcae9a417376431e52cfc699795a76be87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Morais?= <118842104+JoaoMorais03@users.noreply.github.com> Date: Sat, 29 Aug 2026 16:26:17 +0000 Subject: [PATCH 1/2] tests: cover the firmware image TLV parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit image_tlv.c is in eboot_core but had no unit tests. Add parse/find/read coverage against simulated flash, and correct the magic-mismatch return in the public header. Signed-off-by: João Morais <118842104+JoaoMorais03@users.noreply.github.com> --- include/eos_image_tlv.h | 3 +- tests/CMakeLists.txt | 213 ++++++++++++------------ tests/unit/test_image_tlv.c | 320 ++++++++++++++++++++++++++++++++++++ 3 files changed, 431 insertions(+), 105 deletions(-) create mode 100644 tests/unit/test_image_tlv.c diff --git a/include/eos_image_tlv.h b/include/eos_image_tlv.h index 2bc858b..4987ca9 100644 --- a/include/eos_image_tlv.h +++ b/include/eos_image_tlv.h @@ -82,7 +82,8 @@ typedef struct { * @brief Parse TLV area from flash at given address. * @param ctx TLV context (caller-allocated). * @param tlv_addr Flash address of the TLV info header. - * @return EOS_OK on success, EOS_ERR_INVALID if magic mismatch. + * @return EOS_OK on success, EOS_ERR_NOT_FOUND if there is no TLV area + * (magic mismatch), EOS_ERR_INVALID if the TLV size is out of range. */ int eos_tlv_parse(eos_tlv_ctx_t *ctx, uint32_t tlv_addr); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c9e95ff..54db2f8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,104 +1,109 @@ -# eBootloader Unit Tests -# All tests link against core libraries and run natively (no board ports needed). - -# --- test_bootctl: Boot control block --- -add_executable(test_bootctl unit/test_bootctl.c) -target_link_libraries(test_bootctl PRIVATE eboot_core) -add_test(NAME test_bootctl COMMAND test_bootctl) - -# --- test_crypto: SHA-256 against known vectors --- -add_executable(test_crypto unit/test_crypto.c) -target_link_libraries(test_crypto PRIVATE eboot_core) -add_test(NAME test_crypto COMMAND test_crypto) - -# --- test_image_verify: Image header parse bounds --- -add_executable(test_image_verify unit/test_image_verify.c) -target_link_libraries(test_image_verify PRIVATE eboot_core) -add_test(NAME test_image_verify COMMAND test_image_verify) - -# --- test_recovery: UART recovery write range --- -add_executable(test_recovery unit/test_recovery.c) -target_link_libraries(test_recovery PRIVATE eboot_core eboot_stage1) -add_test(NAME test_recovery COMMAND test_recovery) - -# --- test_slot_size_bounds: verify_slot() must reject image_size > slot capacity --- -add_executable(test_slot_size_bounds unit/test_slot_size_bounds.c) -target_link_libraries(test_slot_size_bounds PRIVATE eboot_core) -add_test(NAME test_slot_size_bounds COMMAND test_slot_size_bounds) - -# --- test_device_table: UEFI-style device table --- -add_executable(test_device_table unit/test_device_table.c) -target_link_libraries(test_device_table PRIVATE eboot_core) -add_test(NAME test_device_table COMMAND test_device_table) - -# --- test_runtime_svc: Runtime variable store --- -add_executable(test_runtime_svc unit/test_runtime_svc.c) -target_link_libraries(test_runtime_svc PRIVATE eboot_core) -add_test(NAME test_runtime_svc COMMAND test_runtime_svc) - -# --- test_board_config: Declarative hardware config --- -add_executable(test_board_config unit/test_board_config.c) -target_link_libraries(test_board_config PRIVATE eboot_core) -add_test(NAME test_board_config COMMAND test_board_config) - -# --- test_multicore: Multicore boot management --- -add_executable(test_multicore unit/test_multicore.c) -target_link_libraries(test_multicore PRIVATE eboot_core) -add_test(NAME test_multicore COMMAND test_multicore) - -# --- test_board_registry: Runtime board selection --- -add_executable(test_board_registry unit/test_board_registry.c) -target_link_libraries(test_board_registry PRIVATE eboot_core) -add_test(NAME test_board_registry COMMAND test_board_registry) - -# --- test_slot_manager: Firmware slot management --- -add_executable(test_slot_manager unit/test_slot_manager.c) -target_link_libraries(test_slot_manager PRIVATE eboot_core) -add_test(NAME test_slot_manager COMMAND test_slot_manager) - -# --- test_boot_log: Boot log subsystem --- -add_executable(test_boot_log unit/test_boot_log.c) -target_link_libraries(test_boot_log PRIVATE eboot_core) -add_test(NAME test_boot_log COMMAND test_boot_log) - -# --- test_ed25519: Ed25519 signature verification --- -add_executable(test_ed25519 unit/test_ed25519.c) -target_link_libraries(test_ed25519 PRIVATE eboot_core) -add_test(NAME test_ed25519 COMMAND test_ed25519) - -# --- test_keystore: Key management --- -add_executable(test_keystore unit/test_keystore.c) -target_link_libraries(test_keystore PRIVATE eboot_core) -add_test(NAME test_keystore COMMAND test_keystore) - -# --- test_rollback: Anti-rollback security counter --- -add_executable(test_rollback unit/test_rollback.c) -target_link_libraries(test_rollback PRIVATE eboot_core) -add_test(NAME test_rollback COMMAND test_rollback) - -# --- test_storage: Unified storage abstraction --- -add_executable(test_storage unit/test_storage.c) -target_link_libraries(test_storage PRIVATE eboot_core) -add_test(NAME test_storage COMMAND test_storage) - -# --- Valgrind test targets --- -find_program(VALGRIND valgrind) -if(VALGRIND) - set(VALGRIND_OPTS --leak-check=full --error-exitcode=1 --quiet) - foreach(TEST_NAME test_bootctl test_crypto test_ed25519 test_keystore - test_device_table test_runtime_svc test_board_config - test_multicore test_board_registry test_slot_manager - test_boot_log test_image_verify test_recovery - test_slot_size_bounds) - add_test( - NAME valgrind_${TEST_NAME} - COMMAND ${VALGRIND} ${VALGRIND_OPTS} $ - ) - set_tests_properties(valgrind_${TEST_NAME} PROPERTIES LABELS "valgrind") - endforeach() -endif() - -# --- Fuzz targets --- -if(EBLDR_BUILD_FUZZ) - add_subdirectory(fuzz) -endif() +# eBootloader Unit Tests +# All tests link against core libraries and run natively (no board ports needed). + +# --- test_bootctl: Boot control block --- +add_executable(test_bootctl unit/test_bootctl.c) +target_link_libraries(test_bootctl PRIVATE eboot_core) +add_test(NAME test_bootctl COMMAND test_bootctl) + +# --- test_crypto: SHA-256 against known vectors --- +add_executable(test_crypto unit/test_crypto.c) +target_link_libraries(test_crypto PRIVATE eboot_core) +add_test(NAME test_crypto COMMAND test_crypto) + +# --- test_image_verify: Image header parse bounds --- +add_executable(test_image_verify unit/test_image_verify.c) +target_link_libraries(test_image_verify PRIVATE eboot_core) +add_test(NAME test_image_verify COMMAND test_image_verify) + +# --- test_image_tlv: TLV metadata parser --- +add_executable(test_image_tlv unit/test_image_tlv.c) +target_link_libraries(test_image_tlv PRIVATE eboot_core) +add_test(NAME test_image_tlv COMMAND test_image_tlv) + +# --- test_recovery: UART recovery write range --- +add_executable(test_recovery unit/test_recovery.c) +target_link_libraries(test_recovery PRIVATE eboot_core eboot_stage1) +add_test(NAME test_recovery COMMAND test_recovery) + +# --- test_slot_size_bounds: verify_slot() must reject image_size > slot capacity --- +add_executable(test_slot_size_bounds unit/test_slot_size_bounds.c) +target_link_libraries(test_slot_size_bounds PRIVATE eboot_core) +add_test(NAME test_slot_size_bounds COMMAND test_slot_size_bounds) + +# --- test_device_table: UEFI-style device table --- +add_executable(test_device_table unit/test_device_table.c) +target_link_libraries(test_device_table PRIVATE eboot_core) +add_test(NAME test_device_table COMMAND test_device_table) + +# --- test_runtime_svc: Runtime variable store --- +add_executable(test_runtime_svc unit/test_runtime_svc.c) +target_link_libraries(test_runtime_svc PRIVATE eboot_core) +add_test(NAME test_runtime_svc COMMAND test_runtime_svc) + +# --- test_board_config: Declarative hardware config --- +add_executable(test_board_config unit/test_board_config.c) +target_link_libraries(test_board_config PRIVATE eboot_core) +add_test(NAME test_board_config COMMAND test_board_config) + +# --- test_multicore: Multicore boot management --- +add_executable(test_multicore unit/test_multicore.c) +target_link_libraries(test_multicore PRIVATE eboot_core) +add_test(NAME test_multicore COMMAND test_multicore) + +# --- test_board_registry: Runtime board selection --- +add_executable(test_board_registry unit/test_board_registry.c) +target_link_libraries(test_board_registry PRIVATE eboot_core) +add_test(NAME test_board_registry COMMAND test_board_registry) + +# --- test_slot_manager: Firmware slot management --- +add_executable(test_slot_manager unit/test_slot_manager.c) +target_link_libraries(test_slot_manager PRIVATE eboot_core) +add_test(NAME test_slot_manager COMMAND test_slot_manager) + +# --- test_boot_log: Boot log subsystem --- +add_executable(test_boot_log unit/test_boot_log.c) +target_link_libraries(test_boot_log PRIVATE eboot_core) +add_test(NAME test_boot_log COMMAND test_boot_log) + +# --- test_ed25519: Ed25519 signature verification --- +add_executable(test_ed25519 unit/test_ed25519.c) +target_link_libraries(test_ed25519 PRIVATE eboot_core) +add_test(NAME test_ed25519 COMMAND test_ed25519) + +# --- test_keystore: Key management --- +add_executable(test_keystore unit/test_keystore.c) +target_link_libraries(test_keystore PRIVATE eboot_core) +add_test(NAME test_keystore COMMAND test_keystore) + +# --- test_rollback: Anti-rollback security counter --- +add_executable(test_rollback unit/test_rollback.c) +target_link_libraries(test_rollback PRIVATE eboot_core) +add_test(NAME test_rollback COMMAND test_rollback) + +# --- test_storage: Unified storage abstraction --- +add_executable(test_storage unit/test_storage.c) +target_link_libraries(test_storage PRIVATE eboot_core) +add_test(NAME test_storage COMMAND test_storage) + +# --- Valgrind test targets --- +find_program(VALGRIND valgrind) +if(VALGRIND) + set(VALGRIND_OPTS --leak-check=full --error-exitcode=1 --quiet) + foreach(TEST_NAME test_bootctl test_crypto test_ed25519 test_keystore + test_device_table test_runtime_svc test_board_config + test_multicore test_board_registry test_slot_manager + test_boot_log test_image_verify test_image_tlv + test_recovery test_slot_size_bounds) + add_test( + NAME valgrind_${TEST_NAME} + COMMAND ${VALGRIND} ${VALGRIND_OPTS} $ + ) + set_tests_properties(valgrind_${TEST_NAME} PROPERTIES LABELS "valgrind") + endforeach() +endif() + +# --- Fuzz targets --- +if(EBLDR_BUILD_FUZZ) + add_subdirectory(fuzz) +endif() diff --git a/tests/unit/test_image_tlv.c b/tests/unit/test_image_tlv.c new file mode 100644 index 0000000..6f2e370 --- /dev/null +++ b/tests/unit/test_image_tlv.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2026 EoS Project +// ISO/IEC 25000 | ISO/IEC 15288:2023 + +/** + * @file test_image_tlv.c + * @brief Host tests for the firmware image TLV parser + * + * core/image_tlv.c is compiled into eboot_core but had no unit coverage. + * These tests pin parse, find, and read_data against a simulated flash, + * including truncated entries and the documented magic-mismatch code. + */ + +#include "eos_image_tlv.h" +#include "eos_hal.h" +#include +#include +#include + +#define SIM_FLASH_SIZE (64 * 1024) +static uint8_t sim_flash[SIM_FLASH_SIZE]; + +static int sim_flash_read(uint32_t addr, void *buf, size_t len) +{ + if (addr + len > SIM_FLASH_SIZE) return EOS_ERR_FLASH; + memcpy(buf, &sim_flash[addr], len); + return EOS_OK; +} + +static int sim_flash_write(uint32_t addr, const void *buf, size_t len) +{ + if (addr + len > SIM_FLASH_SIZE) return EOS_ERR_FLASH; + memcpy(&sim_flash[addr], buf, len); + return EOS_OK; +} + +static int sim_flash_erase(uint32_t addr, size_t len) +{ + if (addr + len > SIM_FLASH_SIZE) return EOS_ERR_FLASH; + memset(&sim_flash[addr], 0xFF, len); + return EOS_OK; +} + +static uint32_t sim_tick = 0; +static uint32_t sim_get_tick(void) { return sim_tick++; } +static void sim_noop(void) {} +static void sim_noop_u32(uint32_t x) { (void)x; } +static void sim_jump(uint32_t addr) { (void)addr; } +static eos_reset_reason_t sim_reset_reason(void) { return EOS_RESET_POWER_ON; } +static bool sim_recovery_pin(void) { return false; } +static void sim_system_reset(void) {} + +static const eos_board_ops_t sim_ops = { + .flash_base = 0, + .flash_size = SIM_FLASH_SIZE, + .slot_a_addr = 0x4000, + .slot_a_size = 0x8000, + .slot_b_addr = 0xC000, + .slot_b_size = 0x8000, + .recovery_addr = 0, + .recovery_size = 0, + .bootctl_addr = 0, + .bootctl_backup_addr = 0x1000, + .log_addr = 0x2000, + .app_vector_offset = 0, + .flash_read = sim_flash_read, + .flash_write = sim_flash_write, + .flash_erase = sim_flash_erase, + .watchdog_init = sim_noop_u32, + .watchdog_feed = sim_noop, + .get_reset_reason = sim_reset_reason, + .system_reset = sim_system_reset, + .recovery_pin_asserted = sim_recovery_pin, + .jump = sim_jump, + .uart_init = NULL, + .uart_send = NULL, + .uart_recv = NULL, + .get_tick_ms = sim_get_tick, + .disable_interrupts = sim_noop, + .enable_interrupts = sim_noop, + .deinit_peripherals = sim_noop, +}; + +static int tests_run = 0; +static int tests_passed = 0; + +#define TEST(name) \ + static void name(void); \ + static void run_##name(void) { \ + memset(sim_flash, 0xFF, sizeof(sim_flash)); \ + sim_tick = 0; \ + eos_hal_init(&sim_ops); \ + printf(" %-50s ", #name); \ + name(); \ + tests_passed++; \ + printf("[PASS]\n"); \ + } \ + static void name(void) + +#define ASSERT(cond) do { \ + if (!(cond)) { \ + printf("[FAIL] %s:%d: %s\n", __FILE__, __LINE__, #cond); \ + exit(1); \ + } \ +} while(0) + +static uint32_t tlv_align(uint32_t n) +{ + return (n + 3u) & ~3u; +} + +/* Pack one TLV entry at dst; returns bytes consumed including 4-byte pad. */ +static size_t pack_entry(uint8_t *dst, uint16_t type, const void *data, uint16_t len) +{ + eos_tlv_entry_hdr_t hdr; + hdr.type = type; + hdr.len = len; + memcpy(dst, &hdr, sizeof(hdr)); + if (len > 0 && data != NULL) { + memcpy(dst + sizeof(hdr), data, len); + } + size_t n = sizeof(hdr) + len; + size_t aligned = tlv_align((uint32_t)n); + if (aligned > n) { + memset(dst + n, 0, aligned - n); + } + return aligned; +} + +static void write_tlv_area(uint32_t addr, const uint8_t *entries, uint16_t entries_len) +{ + eos_tlv_info_t info; + info.magic = EOS_TLV_INFO_MAGIC; + info.tlv_total_len = (uint16_t)(sizeof(info) + entries_len); + memcpy(&sim_flash[addr], &info, sizeof(info)); + if (entries_len > 0) { + memcpy(&sim_flash[addr + sizeof(info)], entries, entries_len); + } +} + +TEST(test_parse_null_ctx) +{ + ASSERT(eos_tlv_parse(NULL, 0x1000) == EOS_ERR_INVALID); +} + +TEST(test_parse_bad_magic_is_not_found) +{ + eos_tlv_info_t info; + eos_tlv_ctx_t ctx; + + info.magic = 0x0000; + info.tlv_total_len = sizeof(info); + memcpy(&sim_flash[0x1000], &info, sizeof(info)); + + /* No TLV area is a missing optional region, not a malformed header. */ + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_ERR_NOT_FOUND); +} + +TEST(test_parse_oversized_tlv_is_invalid) +{ + eos_tlv_info_t info; + eos_tlv_ctx_t ctx; + + info.magic = EOS_TLV_INFO_MAGIC; + info.tlv_total_len = EOS_TLV_MAX_SIZE + 1; + memcpy(&sim_flash[0x1000], &info, sizeof(info)); + + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_ERR_INVALID); +} + +TEST(test_parse_undersized_tlv_is_invalid) +{ + eos_tlv_info_t info; + eos_tlv_ctx_t ctx; + + info.magic = EOS_TLV_INFO_MAGIC; + info.tlv_total_len = 2; /* smaller than the info header itself */ + memcpy(&sim_flash[0x1000], &info, sizeof(info)); + + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_ERR_INVALID); +} + +TEST(test_parse_and_find_two_entries) +{ + uint8_t sha[32]; + uint8_t keyhash[32]; + uint8_t packed[128]; + size_t n = 0; + eos_tlv_ctx_t ctx; + eos_tlv_parsed_entry_t entry; + uint8_t out[32]; + + memset(sha, 0xA5, sizeof(sha)); + memset(keyhash, 0x5A, sizeof(keyhash)); + + n += pack_entry(packed + n, EOS_TLV_SHA256, sha, sizeof(sha)); + n += pack_entry(packed + n, EOS_TLV_KEYHASH, keyhash, sizeof(keyhash)); + write_tlv_area(0x1000, packed, (uint16_t)n); + + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_OK); + ASSERT(ctx.count == 2); + ASSERT(ctx.total_len == (uint16_t)(sizeof(eos_tlv_info_t) + n)); + + ASSERT(eos_tlv_find(&ctx, EOS_TLV_SHA256, &entry) == EOS_OK); + ASSERT(entry.type == EOS_TLV_SHA256); + ASSERT(entry.len == sizeof(sha)); + ASSERT(eos_tlv_read_data(&ctx, &entry, out, sizeof(out)) == EOS_OK); + ASSERT(memcmp(out, sha, sizeof(sha)) == 0); + + ASSERT(eos_tlv_find(&ctx, EOS_TLV_KEYHASH, &entry) == EOS_OK); + ASSERT(entry.type == EOS_TLV_KEYHASH); + ASSERT(eos_tlv_read_data(&ctx, &entry, out, sizeof(out)) == EOS_OK); + ASSERT(memcmp(out, keyhash, sizeof(keyhash)) == 0); + + ASSERT(eos_tlv_find(&ctx, EOS_TLV_NONCE, &entry) == EOS_ERR_NOT_FOUND); +} + +TEST(test_odd_length_entry_alignment) +{ + /* A 1-byte payload is padded to 4 so the next header is aligned. */ + uint8_t nonce = 0x42; + uint8_t sha[32]; + uint8_t packed[64]; + size_t n = 0; + eos_tlv_ctx_t ctx; + eos_tlv_parsed_entry_t entry; + uint8_t out_nonce = 0; + uint8_t out_sha[32]; + + memset(sha, 0x11, sizeof(sha)); + n += pack_entry(packed + n, EOS_TLV_NONCE, &nonce, 1); + n += pack_entry(packed + n, EOS_TLV_SHA256, sha, sizeof(sha)); + write_tlv_area(0x2000, packed, (uint16_t)n); + + ASSERT(eos_tlv_parse(&ctx, 0x2000) == EOS_OK); + ASSERT(ctx.count == 2); + + ASSERT(eos_tlv_find(&ctx, EOS_TLV_NONCE, &entry) == EOS_OK); + ASSERT(entry.len == 1); + ASSERT(eos_tlv_read_data(&ctx, &entry, &out_nonce, 1) == EOS_OK); + ASSERT(out_nonce == 0x42); + + ASSERT(eos_tlv_find(&ctx, EOS_TLV_SHA256, &entry) == EOS_OK); + ASSERT(eos_tlv_read_data(&ctx, &entry, out_sha, sizeof(out_sha)) == EOS_OK); + ASSERT(memcmp(out_sha, sha, sizeof(sha)) == 0); +} + +TEST(test_truncated_entry_is_skipped) +{ + eos_tlv_info_t info; + eos_tlv_entry_hdr_t hdr; + eos_tlv_ctx_t ctx; + + /* Info claims 20 bytes total; the first entry claims 100 bytes of data. */ + info.magic = EOS_TLV_INFO_MAGIC; + info.tlv_total_len = 20; + hdr.type = EOS_TLV_SHA256; + hdr.len = 100; + memcpy(&sim_flash[0x1000], &info, sizeof(info)); + memcpy(&sim_flash[0x1000 + sizeof(info)], &hdr, sizeof(hdr)); + + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_OK); + ASSERT(ctx.count == 0); +} + +TEST(test_find_and_read_reject_nulls) +{ + uint8_t sha[32]; + uint8_t packed[64]; + size_t n = 0; + eos_tlv_ctx_t ctx; + eos_tlv_parsed_entry_t entry; + uint8_t out[32]; + + memset(sha, 0x22, sizeof(sha)); + n += pack_entry(packed + n, EOS_TLV_SHA256, sha, sizeof(sha)); + write_tlv_area(0x1000, packed, (uint16_t)n); + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_OK); + ASSERT(eos_tlv_find(&ctx, EOS_TLV_SHA256, &entry) == EOS_OK); + + ASSERT(eos_tlv_find(NULL, EOS_TLV_SHA256, &entry) == EOS_ERR_INVALID); + ASSERT(eos_tlv_find(&ctx, EOS_TLV_SHA256, NULL) == EOS_ERR_INVALID); + ASSERT(eos_tlv_read_data(NULL, &entry, out, sizeof(out)) == EOS_ERR_INVALID); + ASSERT(eos_tlv_read_data(&ctx, NULL, out, sizeof(out)) == EOS_ERR_INVALID); + ASSERT(eos_tlv_read_data(&ctx, &entry, NULL, sizeof(out)) == EOS_ERR_INVALID); +} + +TEST(test_read_data_rejects_small_buffer) +{ + uint8_t sha[32]; + uint8_t packed[64]; + size_t n = 0; + eos_tlv_ctx_t ctx; + eos_tlv_parsed_entry_t entry; + uint8_t too_small[8]; + + memset(sha, 0x33, sizeof(sha)); + n += pack_entry(packed + n, EOS_TLV_SHA256, sha, sizeof(sha)); + write_tlv_area(0x1000, packed, (uint16_t)n); + ASSERT(eos_tlv_parse(&ctx, 0x1000) == EOS_OK); + ASSERT(eos_tlv_find(&ctx, EOS_TLV_SHA256, &entry) == EOS_OK); + ASSERT(eos_tlv_read_data(&ctx, &entry, too_small, sizeof(too_small)) == EOS_ERR_FULL); +} + +int main(void) +{ + printf("=== eBootloader: Image TLV Parser Tests ===\n\n"); + run_test_parse_null_ctx(); + run_test_parse_bad_magic_is_not_found(); + run_test_parse_oversized_tlv_is_invalid(); + run_test_parse_undersized_tlv_is_invalid(); + run_test_parse_and_find_two_entries(); + run_test_odd_length_entry_alignment(); + run_test_truncated_entry_is_skipped(); + run_test_find_and_read_reject_nulls(); + run_test_read_data_rejects_small_buffer(); + tests_run = 9; + printf("\n%d/%d tests passed\n", tests_passed, tests_run); + return (tests_passed == tests_run) ? 0 : 1; +} From 70f340a61749e30fdf2dc68d006d25e315cf8385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Morais?= <118842104+JoaoMorais03@users.noreply.github.com> Date: Sat, 29 Aug 2026 16:27:39 +0000 Subject: [PATCH 2/2] tests: keep CRLF in CMakeLists.txt when registering TLV tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit converted the file to LF. Restore the repo's existing line endings so the diff is only the test registration. Signed-off-by: João Morais <118842104+JoaoMorais03@users.noreply.github.com> --- tests/CMakeLists.txt | 218 +++++++++++++++++++++---------------------- 1 file changed, 109 insertions(+), 109 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 54db2f8..a97c898 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,109 +1,109 @@ -# eBootloader Unit Tests -# All tests link against core libraries and run natively (no board ports needed). - -# --- test_bootctl: Boot control block --- -add_executable(test_bootctl unit/test_bootctl.c) -target_link_libraries(test_bootctl PRIVATE eboot_core) -add_test(NAME test_bootctl COMMAND test_bootctl) - -# --- test_crypto: SHA-256 against known vectors --- -add_executable(test_crypto unit/test_crypto.c) -target_link_libraries(test_crypto PRIVATE eboot_core) -add_test(NAME test_crypto COMMAND test_crypto) - -# --- test_image_verify: Image header parse bounds --- -add_executable(test_image_verify unit/test_image_verify.c) -target_link_libraries(test_image_verify PRIVATE eboot_core) -add_test(NAME test_image_verify COMMAND test_image_verify) - -# --- test_image_tlv: TLV metadata parser --- -add_executable(test_image_tlv unit/test_image_tlv.c) -target_link_libraries(test_image_tlv PRIVATE eboot_core) -add_test(NAME test_image_tlv COMMAND test_image_tlv) - -# --- test_recovery: UART recovery write range --- -add_executable(test_recovery unit/test_recovery.c) -target_link_libraries(test_recovery PRIVATE eboot_core eboot_stage1) -add_test(NAME test_recovery COMMAND test_recovery) - -# --- test_slot_size_bounds: verify_slot() must reject image_size > slot capacity --- -add_executable(test_slot_size_bounds unit/test_slot_size_bounds.c) -target_link_libraries(test_slot_size_bounds PRIVATE eboot_core) -add_test(NAME test_slot_size_bounds COMMAND test_slot_size_bounds) - -# --- test_device_table: UEFI-style device table --- -add_executable(test_device_table unit/test_device_table.c) -target_link_libraries(test_device_table PRIVATE eboot_core) -add_test(NAME test_device_table COMMAND test_device_table) - -# --- test_runtime_svc: Runtime variable store --- -add_executable(test_runtime_svc unit/test_runtime_svc.c) -target_link_libraries(test_runtime_svc PRIVATE eboot_core) -add_test(NAME test_runtime_svc COMMAND test_runtime_svc) - -# --- test_board_config: Declarative hardware config --- -add_executable(test_board_config unit/test_board_config.c) -target_link_libraries(test_board_config PRIVATE eboot_core) -add_test(NAME test_board_config COMMAND test_board_config) - -# --- test_multicore: Multicore boot management --- -add_executable(test_multicore unit/test_multicore.c) -target_link_libraries(test_multicore PRIVATE eboot_core) -add_test(NAME test_multicore COMMAND test_multicore) - -# --- test_board_registry: Runtime board selection --- -add_executable(test_board_registry unit/test_board_registry.c) -target_link_libraries(test_board_registry PRIVATE eboot_core) -add_test(NAME test_board_registry COMMAND test_board_registry) - -# --- test_slot_manager: Firmware slot management --- -add_executable(test_slot_manager unit/test_slot_manager.c) -target_link_libraries(test_slot_manager PRIVATE eboot_core) -add_test(NAME test_slot_manager COMMAND test_slot_manager) - -# --- test_boot_log: Boot log subsystem --- -add_executable(test_boot_log unit/test_boot_log.c) -target_link_libraries(test_boot_log PRIVATE eboot_core) -add_test(NAME test_boot_log COMMAND test_boot_log) - -# --- test_ed25519: Ed25519 signature verification --- -add_executable(test_ed25519 unit/test_ed25519.c) -target_link_libraries(test_ed25519 PRIVATE eboot_core) -add_test(NAME test_ed25519 COMMAND test_ed25519) - -# --- test_keystore: Key management --- -add_executable(test_keystore unit/test_keystore.c) -target_link_libraries(test_keystore PRIVATE eboot_core) -add_test(NAME test_keystore COMMAND test_keystore) - -# --- test_rollback: Anti-rollback security counter --- -add_executable(test_rollback unit/test_rollback.c) -target_link_libraries(test_rollback PRIVATE eboot_core) -add_test(NAME test_rollback COMMAND test_rollback) - -# --- test_storage: Unified storage abstraction --- -add_executable(test_storage unit/test_storage.c) -target_link_libraries(test_storage PRIVATE eboot_core) -add_test(NAME test_storage COMMAND test_storage) - -# --- Valgrind test targets --- -find_program(VALGRIND valgrind) -if(VALGRIND) - set(VALGRIND_OPTS --leak-check=full --error-exitcode=1 --quiet) - foreach(TEST_NAME test_bootctl test_crypto test_ed25519 test_keystore - test_device_table test_runtime_svc test_board_config - test_multicore test_board_registry test_slot_manager - test_boot_log test_image_verify test_image_tlv - test_recovery test_slot_size_bounds) - add_test( - NAME valgrind_${TEST_NAME} - COMMAND ${VALGRIND} ${VALGRIND_OPTS} $ - ) - set_tests_properties(valgrind_${TEST_NAME} PROPERTIES LABELS "valgrind") - endforeach() -endif() - -# --- Fuzz targets --- -if(EBLDR_BUILD_FUZZ) - add_subdirectory(fuzz) -endif() +# eBootloader Unit Tests +# All tests link against core libraries and run natively (no board ports needed). + +# --- test_bootctl: Boot control block --- +add_executable(test_bootctl unit/test_bootctl.c) +target_link_libraries(test_bootctl PRIVATE eboot_core) +add_test(NAME test_bootctl COMMAND test_bootctl) + +# --- test_crypto: SHA-256 against known vectors --- +add_executable(test_crypto unit/test_crypto.c) +target_link_libraries(test_crypto PRIVATE eboot_core) +add_test(NAME test_crypto COMMAND test_crypto) + +# --- test_image_verify: Image header parse bounds --- +add_executable(test_image_verify unit/test_image_verify.c) +target_link_libraries(test_image_verify PRIVATE eboot_core) +add_test(NAME test_image_verify COMMAND test_image_verify) + +# --- test_image_tlv: TLV metadata parser --- +add_executable(test_image_tlv unit/test_image_tlv.c) +target_link_libraries(test_image_tlv PRIVATE eboot_core) +add_test(NAME test_image_tlv COMMAND test_image_tlv) + +# --- test_recovery: UART recovery write range --- +add_executable(test_recovery unit/test_recovery.c) +target_link_libraries(test_recovery PRIVATE eboot_core eboot_stage1) +add_test(NAME test_recovery COMMAND test_recovery) + +# --- test_slot_size_bounds: verify_slot() must reject image_size > slot capacity --- +add_executable(test_slot_size_bounds unit/test_slot_size_bounds.c) +target_link_libraries(test_slot_size_bounds PRIVATE eboot_core) +add_test(NAME test_slot_size_bounds COMMAND test_slot_size_bounds) + +# --- test_device_table: UEFI-style device table --- +add_executable(test_device_table unit/test_device_table.c) +target_link_libraries(test_device_table PRIVATE eboot_core) +add_test(NAME test_device_table COMMAND test_device_table) + +# --- test_runtime_svc: Runtime variable store --- +add_executable(test_runtime_svc unit/test_runtime_svc.c) +target_link_libraries(test_runtime_svc PRIVATE eboot_core) +add_test(NAME test_runtime_svc COMMAND test_runtime_svc) + +# --- test_board_config: Declarative hardware config --- +add_executable(test_board_config unit/test_board_config.c) +target_link_libraries(test_board_config PRIVATE eboot_core) +add_test(NAME test_board_config COMMAND test_board_config) + +# --- test_multicore: Multicore boot management --- +add_executable(test_multicore unit/test_multicore.c) +target_link_libraries(test_multicore PRIVATE eboot_core) +add_test(NAME test_multicore COMMAND test_multicore) + +# --- test_board_registry: Runtime board selection --- +add_executable(test_board_registry unit/test_board_registry.c) +target_link_libraries(test_board_registry PRIVATE eboot_core) +add_test(NAME test_board_registry COMMAND test_board_registry) + +# --- test_slot_manager: Firmware slot management --- +add_executable(test_slot_manager unit/test_slot_manager.c) +target_link_libraries(test_slot_manager PRIVATE eboot_core) +add_test(NAME test_slot_manager COMMAND test_slot_manager) + +# --- test_boot_log: Boot log subsystem --- +add_executable(test_boot_log unit/test_boot_log.c) +target_link_libraries(test_boot_log PRIVATE eboot_core) +add_test(NAME test_boot_log COMMAND test_boot_log) + +# --- test_ed25519: Ed25519 signature verification --- +add_executable(test_ed25519 unit/test_ed25519.c) +target_link_libraries(test_ed25519 PRIVATE eboot_core) +add_test(NAME test_ed25519 COMMAND test_ed25519) + +# --- test_keystore: Key management --- +add_executable(test_keystore unit/test_keystore.c) +target_link_libraries(test_keystore PRIVATE eboot_core) +add_test(NAME test_keystore COMMAND test_keystore) + +# --- test_rollback: Anti-rollback security counter --- +add_executable(test_rollback unit/test_rollback.c) +target_link_libraries(test_rollback PRIVATE eboot_core) +add_test(NAME test_rollback COMMAND test_rollback) + +# --- test_storage: Unified storage abstraction --- +add_executable(test_storage unit/test_storage.c) +target_link_libraries(test_storage PRIVATE eboot_core) +add_test(NAME test_storage COMMAND test_storage) + +# --- Valgrind test targets --- +find_program(VALGRIND valgrind) +if(VALGRIND) + set(VALGRIND_OPTS --leak-check=full --error-exitcode=1 --quiet) + foreach(TEST_NAME test_bootctl test_crypto test_ed25519 test_keystore + test_device_table test_runtime_svc test_board_config + test_multicore test_board_registry test_slot_manager + test_boot_log test_image_verify test_image_tlv + test_recovery test_slot_size_bounds) + add_test( + NAME valgrind_${TEST_NAME} + COMMAND ${VALGRIND} ${VALGRIND_OPTS} $ + ) + set_tests_properties(valgrind_${TEST_NAME} PROPERTIES LABELS "valgrind") + endforeach() +endif() + +# --- Fuzz targets --- +if(EBLDR_BUILD_FUZZ) + add_subdirectory(fuzz) +endif()