diff --git a/hal/sim.c b/hal/sim.c index 615c0d26..b576b7a8 100644 --- a/hal/sim.c +++ b/hal/sim.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef __APPLE__ #include @@ -308,6 +309,7 @@ void do_boot(const uint32_t *app_offset) { int ret; size_t app_size = WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE; + wolfBoot_printf("Simulator do_boot app_offset = %p\n", app_offset); if (flashLocked == 0) { wolfBoot_printf("WARNING FLASH IS UNLOCKED AT BOOT"); @@ -352,26 +354,34 @@ void do_boot(const uint32_t *app_offset) main = (main_entry)((uint8_t*)pSymbolAddress + epc->entryoff); main(main_argc, main_argv, NULL, NULL); -#elif defined ELF_SCATTERED - uint8_t *entry_point = (sim_ram_base + 0x100000); + +#elif defined (ELF_SCATTERED) + uint8_t *entry_point = (sim_ram_base + (unsigned long)app_offset); printf("entry point: %p\n", entry_point); printf("app offset: %p\n", app_offset); typedef int (*main_entry)(int, char**); main_entry main; main = (main_entry)(entry_point); - main(main_argc, main_argv); + + /* TODO: call main ! */ + /* main(main_argc, main_argv); */ + wolfBoot_printf("Simulator for ELF_SCATTERED image not implemented yet. Exiting...\n"); + exit(0); #else char *envp[1] = {NULL}; int fd = memfd_create("test_app", 0); + size_t wret; if (fd == -1) { wolfBoot_printf( "memfd error\n"); exit(-1); } - if ((size_t)write(fd, app_offset, app_size) != app_size) { - wolfBoot_printf( "can't write test-app to memfd\n"); + wret = write(fd, app_offset, app_size); + if (wret != app_size) { + wolfBoot_printf( "can't write test-app to memfd, address %p: fd %d rval %d errno %d\n", app_offset, fd, wret, errno); exit(-1); } + wolfBoot_printf("Stored test-app to memfd, address %p (%zu bytes)\n", app_offset, wret); ret = fexecve(fd, main_argv, envp); wolfBoot_printf( "fexecve error\n"); diff --git a/include/elf.h b/include/elf.h index c0a24071..d459ec89 100644 --- a/include/elf.h +++ b/include/elf.h @@ -169,7 +169,7 @@ typedef int (*elf_mmu_map_cb)(uint64_t, uint64_t, uint32_t); int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb); int elf_load_image(uint8_t *image, uintptr_t *entry, int is_ext); int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_out, int ext_flash); -int elf_check_image_scattered(uint8_t part); +int elf_check_image_scattered(uint8_t part, unsigned long *entry_out); int elf_hdr_size(const unsigned char *ehdr); int elf_open(const unsigned char *ehdr, int *is_elf32); diff --git a/src/elf.c b/src/elf.c index ba3d288d..26594ce3 100644 --- a/src/elf.c +++ b/src/elf.c @@ -212,10 +212,10 @@ int elf_store_image_scattered(const unsigned char *hdr, unsigned long *entry_out if (ph[i].type != ELF_PT_LOAD) continue; - paddr = (unsigned long)ph[i].paddr; offset = (unsigned long)ph[i].offset; filesz = (unsigned long)ph[i].file_size; + printf("Writing section at address %lx offset %lx\n", paddr, offset); #ifdef EXT_FLASH if (ext_flash) { ext_flash_unlock(); @@ -227,12 +227,12 @@ int elf_store_image_scattered(const unsigned char *hdr, unsigned long *entry_out #endif { hal_flash_unlock(); - hal_flash_erase(paddr, filesz); - hal_flash_write(paddr, image + offset, filesz); + hal_flash_erase(paddr + ARCH_FLASH_OFFSET, filesz); + hal_flash_write(paddr + ARCH_FLASH_OFFSET, image + offset, filesz); hal_flash_lock(); } } - } else { /* 64 bit ELF */ + } else { /* 32 bit ELF */ const elf64_header *eh; const elf64_program_header *ph; wolfBoot_printf("ELF image is 64 bit\n"); @@ -281,7 +281,7 @@ int elf_load_image(uint8_t *image, uintptr_t *entry, int ext_flash) #ifdef MMU return elf_load_image_mmu(image, entry, NULL); #else - return elf_store_image_scattered(image, entry, ext_flash); + return elf_store_image_scattered(image, (unsigned long *)entry, ext_flash); #endif } diff --git a/src/image.c b/src/image.c index cd17515f..eb01bb8c 100644 --- a/src/image.c +++ b/src/image.c @@ -1332,7 +1332,7 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img) #define PADDING_BLOCK_SIZE 64 -int elf_check_image_scattered(uint8_t part) +int elf_check_image_scattered(uint8_t part, unsigned long *entry_out) { /* Open the partition containing the image */ struct wolfBoot_image boot; @@ -1349,6 +1349,8 @@ int elf_check_image_scattered(uint8_t part) int stored_sha_len; int i; uint8_t padding_block[PADDING_BLOCK_SIZE]; + int entry_out_set = 0; + wolfBoot_hash_t ctx; if (wolfBoot_open_image(&boot, part) < 0) @@ -1389,8 +1391,6 @@ int elf_check_image_scattered(uint8_t part) } wolfBoot_printf("Hashed ELF header.\n"); - - /* Feed the program headers to the hash function */ if (is_elf32) { elf32_header *eh = (elf32_header *)elf_h; @@ -1398,9 +1398,15 @@ int elf_check_image_scattered(uint8_t part) entry_count = eh->ph_entry_count; entry_size = eh->ph_entry_size; entry_off = eh->ph_offset; + if (!entry_out_set) { + *entry_out = eh->entry; + entry_out_set = 1; + } + wolfBoot_printf("EH entry offset: %d\n", entry_off); + ph = (elf32_program_header *)(elf_h + entry_off); /* Add padding until the first program header into hash function */ - len = entry_off - elf_hdr_sz; + len = ph[0].offset - elf_hdr_sz; wolfBoot_printf("Adding %d bytes padding\n", len); while (len > 0) { if (len > PADDING_BLOCK_SIZE) { @@ -1411,24 +1417,26 @@ int elf_check_image_scattered(uint8_t part) break; } } - - ph = (elf32_program_header *)(elf_h + entry_off); - for (i = 0; i < entry_count; ++i) { + for (i = 0; i < entry_count; i++) { unsigned long paddr; unsigned long filesz; unsigned long offset; paddr = (unsigned long)ph[i].paddr; offset = (unsigned long)ph[i].offset; filesz = (unsigned long)ph[i].file_size; + wolfBoot_printf("Paddr: 0x%lx offset: %lu, size: %lu\n", paddr, + offset, filesz); /* Feed any non-loaded parts to the hash function */ if (ph[i].type != ELF_PT_LOAD) { len = filesz; + //wolfBoot_printf("Feeding ghost segment, len %d\n", len); + continue; while (len > 0) { if (len > WOLFBOOT_SHA_BLOCK_SIZE) { update_hash(&ctx, elf_h + offset, WOLFBOOT_SHA_BLOCK_SIZE); len -= WOLFBOOT_SHA_BLOCK_SIZE; - offset += WOLFBOOT_SHA_BLOCK_SIZE; + paddr += WOLFBOOT_SHA_BLOCK_SIZE; } else { update_hash(&ctx, elf_h + offset, len); break; @@ -1437,23 +1445,24 @@ int elf_check_image_scattered(uint8_t part) } else { /* Feed the loaded parts to the hash function */ len = filesz; + wolfBoot_printf("Feeding stored segment, len %d\n", len); while (len > 0) { if (len > WOLFBOOT_SHA_BLOCK_SIZE) { update_hash(&ctx, (void *)(paddr + ARCH_FLASH_OFFSET), WOLFBOOT_SHA_BLOCK_SIZE); len -= WOLFBOOT_SHA_BLOCK_SIZE; - offset += WOLFBOOT_SHA_BLOCK_SIZE; + paddr += WOLFBOOT_SHA_BLOCK_SIZE; } else { - update_hash(&ctx, (void *)(paddr + ARCH_FLASH_OFFSET), - len); + update_hash(&ctx, (void *)(paddr + ARCH_FLASH_OFFSET), + len); break; } } } /* Add padding until next program header, if any. */ - if ((i < entry_count - 1) && (ph[i+1].offset > offset)) { + if ((i < entry_count - 1) && (ph[i+1].offset > (offset + filesz))) { unsigned long padding = ph[i+1].offset - (offset + filesz); - wolfBoot_printf("Adding padding: %lu\n", padding); + wolfBoot_printf("Adding padding: %lu (from %p to %p)\n", padding, offset + filesz, ph[i+1].offset); while (padding > 0) { if (padding > PADDING_BLOCK_SIZE) { update_hash(&ctx, padding_block, PADDING_BLOCK_SIZE); @@ -1467,12 +1476,16 @@ int elf_check_image_scattered(uint8_t part) final_offset = offset + filesz; } } - }else { /* 64-bit ELF */ + } else { /* 64-bit ELF */ elf64_header *eh = (elf64_header *)elf_h; elf64_program_header *ph; entry_count = eh->ph_entry_count; entry_size = eh->ph_entry_size; entry_off = eh->ph_offset; + if (!entry_out_set) { + *entry_out = eh->entry; + entry_out_set = 1; + } wolfBoot_printf("EH entry offset: %d\n", entry_off); ph = (elf64_program_header *)(elf_h + entry_off); @@ -1507,7 +1520,7 @@ int elf_check_image_scattered(uint8_t part) if (len > WOLFBOOT_SHA_BLOCK_SIZE) { update_hash(&ctx, elf_h + offset, WOLFBOOT_SHA_BLOCK_SIZE); len -= WOLFBOOT_SHA_BLOCK_SIZE; - offset += WOLFBOOT_SHA_BLOCK_SIZE; + paddr += WOLFBOOT_SHA_BLOCK_SIZE; } else { update_hash(&ctx, elf_h + offset, len); break; @@ -1522,7 +1535,7 @@ int elf_check_image_scattered(uint8_t part) update_hash(&ctx, (void *)(paddr + ARCH_FLASH_OFFSET), WOLFBOOT_SHA_BLOCK_SIZE); len -= WOLFBOOT_SHA_BLOCK_SIZE; - offset += WOLFBOOT_SHA_BLOCK_SIZE; + paddr += WOLFBOOT_SHA_BLOCK_SIZE; } else { update_hash(&ctx, (void *)(paddr + ARCH_FLASH_OFFSET), len); @@ -1531,7 +1544,7 @@ int elf_check_image_scattered(uint8_t part) } } /* Add padding until next program header, if any. */ - if ((i < entry_count - 1) && (ph[i+1].offset > offset)) { + if ((i < entry_count - 1) && (ph[i+1].offset > (offset + filesz))) { unsigned long padding = ph[i+1].offset - (offset + filesz); wolfBoot_printf("Adding padding: %lu\n", padding); while (padding > 0) { @@ -1550,7 +1563,7 @@ int elf_check_image_scattered(uint8_t part) } if (final_offset < 0) return -1; - if (final_offset + IMAGE_HEADER_SIZE > boot.fw_size) + if (final_offset + IMAGE_HEADER_SIZE > (long)boot.fw_size) return -1; len = boot.fw_size - final_offset; diff --git a/src/update_flash.c b/src/update_flash.c index 17f0becc..24b36e69 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -1069,13 +1069,13 @@ void RAMFUNCTION wolfBoot_start(void) PART_SANITY_CHECK(&boot); #ifdef ELF_SCATTERED - uintptr_t entry; + unsigned long entry; void *base = (void *)WOLFBOOT_PARTITION_BOOT_ADDRESS; wolfBoot_printf("ELF Scattered image digest check\n"); - if (elf_check_image_scattered(PART_BOOT) <0) { + if (elf_check_image_scattered(PART_BOOT, &entry) < 0) { wolfBoot_printf("ELF Scattered image digest check: failed. Restoring scattered image...\n"); elf_store_image_scattered(base, &entry, PART_IS_EXT(boot)); - if (elf_check_image_scattered(PART_BOOT) < 0) { + if (elf_check_image_scattered(PART_BOOT, &entry) < 0) { wolfBoot_printf("Fatal: Could not verify digest after scattering. Panic().\n"); wolfBoot_panic(); }