Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/test-elf-scattered.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Test for scattered elf validation

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]

jobs:
elf_scattered_test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: make clean
run: |
make keysclean

- name: Select config
run: |
cp config/examples/sim.config .config

- name: Build tools
run: |
make -C tools/keytools && make -C tools/bin-assemble

- name: Build wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update ELF=1 ELF_SCATTERED=1

- name: Run bootloader with no arguments
run: |
./wolfboot.elf
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ project(wolfBoot)
include(cmake/utils.cmake)
include(cmake/functions.cmake)

include_directories(include)
include_directories(lib/wolfssl)

if(NOT DEFINED WOLFBOOT_TARGET)
message(FATAL_ERROR "WOLFBOOT_TARGET must be defined")
else()
Expand Down Expand Up @@ -620,6 +623,8 @@ if(NOT SPMATH AND NOT SPMATHALL)
list(APPEND USER_SETTINGS USE_FAST_MATH)
endif()

list(APPEND WOLFBOOT_DEFS WOLFSSL_USER_SETTINGS)

add_library(user_settings INTERFACE)
target_compile_definitions(user_settings INTERFACE ${USER_SETTINGS} ${SIGN_OPTIONS})

Expand Down Expand Up @@ -699,7 +704,7 @@ configure_file(include/target.h.in ${CMAKE_CURRENT_BINARY_DIR}/target.h @ONLY)

add_library(target INTERFACE)
target_compile_definitions(target INTERFACE ${WOLFBOOT_DEFS})
target_include_directories(target BEFORE INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(target BEFORE INTERFACE ${CMAKE_CURRENT_BINARY_DIR} lib/wolfssl)

set(KEYSTORE ${CMAKE_CURRENT_BINARY_DIR}/keystore.c)

Expand Down
6 changes: 4 additions & 2 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ ifeq ($(ARCH),ARM)
CORTEX_A5=1
UPDATE_OBJS:=src/update_ram.o
CFLAGS+=-DWOLFBOOT_DUALBOOT -DEXT_FLASH -DNAND_FLASH -fno-builtin -ffreestanding
#CFLAGS+=-DWOLFBOOT_USE_STDLIBC
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
endif

## Cortex CPU
Expand Down Expand Up @@ -1125,7 +1125,9 @@ ifeq ($(TARGET),sim)
LD_END_GROUP=
BOOT_IMG=test-app/image.elf
CFLAGS+=-DARCH_SIM
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
ifneq ($(ELF_SCATTERED),1)
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
endif
ifeq ($(FORCE_32BIT),1)
CFLAGS+=-m32
LDFLAGS+=-m32
Expand Down
28 changes: 28 additions & 0 deletions config/examples/sim-elf-scattered.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
ARCH=sim
Comment thread
dgarske marked this conversation as resolved.
TARGET=sim
SIGN?=ED25519
HASH?=SHA256
WOLFBOOT_SMALL_STACK?=0
SPI_FLASH=0
DEBUG=1
ELF_SCATTERED=1
ELF=1


# sizes should be multiple of system page size
WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
# if on external flash, it should be multiple of system page size

# Address from 0x100000 to 0x1FFFFF is reserved for ELF_SCATTERED

WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x200000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x280000


# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1

# For debugging XMALLOC/XFREE
#CFLAGS_EXTRA+=-DWOLFBOOT_DEBUG_MALLOC
24 changes: 24 additions & 0 deletions config/examples/sim32-elf-scattered.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ARCH=sim
TARGET=sim
SIGN?=ECC256
HASH?=SHA256
WOLFBOOT_SMALL_STACK?=0
SPI_FLASH=0
DEBUG=1
FORCE_32BIT=1
ELF=1
ELF_SCATTERED=1

# sizes should be multiple of system page size
WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
# if on external flash, it should be multiple of system page size
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x180000

# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1

# For debugging XMALLOC/XFREE
#CFLAGS_EXTRA+=-DWOLFBOOT_DEBUG_MALLOC
10 changes: 5 additions & 5 deletions hal/sama5d3.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static int division(uint32_t dividend,
return 0;
}

static uint32_t div(uint32_t dividend, uint32_t divisor)
static uint32_t div_u(uint32_t dividend, uint32_t divisor)
{
uint32_t quotient = 0;
uint32_t remainder = 0;
Expand Down Expand Up @@ -504,7 +504,7 @@ static void nand_read_info(void)
nand_flash.bad_block_pos = (*(uint16_t *)(onfi_data + PARAMS_POS_FEATURES)) & 1;
nand_flash.ext_page_len = *(uint16_t *)(onfi_data + PARAMS_POS_EXT_PARAM_PAGE_LEN);
nand_flash.parameter_page = *(uint16_t *)(onfi_data + PARAMS_POS_PARAMETER_PAGE);
nand_flash.pages_per_block = div(nand_flash.block_size, nand_flash.page_size);
nand_flash.pages_per_block = div_u(nand_flash.block_size, nand_flash.page_size);
nand_flash.pages_per_device = nand_flash.pages_per_block * nand_flash.block_count;
nand_flash.oob_size = *(uint16_t *)(onfi_data + PARAMS_POS_OOBSIZE);
nand_flash.revision = *(uint16_t *)(onfi_data + PARAMS_POS_REVISION);
Expand Down Expand Up @@ -605,8 +605,8 @@ static int nand_check_bad_block(uint32_t block)
int ext_flash_read(uintptr_t address, uint8_t *data, int len)
{
uint8_t buffer_page[NAND_FLASH_PAGE_SIZE];
uint32_t block = div(address, nand_flash.block_size); /* The block where the address falls in */
uint32_t page = div(address, nand_flash.page_size); /* The page where the address falls in */
uint32_t block = div_u(address, nand_flash.block_size); /* The block where the address falls in */
uint32_t page = div_u(address, nand_flash.page_size); /* The page where the address falls in */
uint32_t start_page_in_block = mod(page, nand_flash.pages_per_block); /* The start page within this block */
uint32_t in_block_offset = mod(address, nand_flash.block_size); /* The offset of the address within the block */
uint32_t remaining = nand_flash.block_size - in_block_offset; /* How many bytes remaining to read in the first block */
Expand Down Expand Up @@ -637,7 +637,7 @@ int ext_flash_read(uintptr_t address, uint8_t *data, int len)
} while (ret < 0);

/* Amount of pages to be read from this block */
pages_to_read = div((sz + nand_flash.page_size - 1), nand_flash.page_size);
pages_to_read = div_u((sz + nand_flash.page_size - 1), nand_flash.page_size);

if (pages_to_read * nand_flash.page_size > remaining)
pages_to_read--;
Expand Down
26 changes: 24 additions & 2 deletions hal/sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#ifdef __APPLE__
#include <mach-o/loader.h>
Expand All @@ -42,6 +43,10 @@
#include "target.h"
#include "printf.h"

#ifdef WOLFBOOT_ELF_SCATTERED
#include "elf.h"
#endif

#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
#include "wolfhsm/wh_error.h"
#include "wolfhsm/wh_client.h"
Expand Down Expand Up @@ -304,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");
Expand Down Expand Up @@ -348,18 +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 (WOLFBOOT_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);

/* 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\n", app_offset);
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");
Expand Down
35 changes: 34 additions & 1 deletion include/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern "C" {
#define ELF_IDENT_STR "\x7F""ELF"

/* header ident[4] */
#define ELF_CLASS_OFF (4)
#define ELF_CLASS_32 (1)
#define ELF_CLASS_64 (2)

Expand Down Expand Up @@ -111,6 +112,11 @@ typedef struct elf64_header {
uint16_t sh_str_index;
} elf64_header;

union elf_header {
elf32_header *h32;
elf64_header *h64;
};

typedef struct elf64_section_header {
uint32_t name;
uint32_t type;
Expand All @@ -136,9 +142,36 @@ typedef struct elf64_program_header {
} elf64_program_header;


/* support byte swapping if testing/reading an elf with different endianess */
#if defined(ELF_PARSER) || defined(ELF_ENDIAN_SUPPORT)
#ifdef BIG_ENDIAN_ORDER
#define GET16(x) (( is_le) ? __builtin_bswap16(x) : (x))
#define GET32(x) (( is_le) ? __builtin_bswap32(x) : (x))
#define GET64(x) (( is_le) ? __builtin_bswap64(x) : (x))
#else
#define GET16(x) ((!is_le) ? __builtin_bswap16(x) : (x))
#define GET32(x) ((!is_le) ? __builtin_bswap32(x) : (x))
#define GET64(x) ((!is_le) ? __builtin_bswap64(x) : (x))
#endif
#else
#define GET16(x) (x)
#define GET32(x) (x)
#define GET64(x) (x)
#endif

#define GET_H64(name) (is_elf32 ? GET32(h32->name) : GET64(h64->name))
#define GET_H32(name) (is_elf32 ? GET32(h32->name) : GET32(h64->name))
#define GET_H16(name) (is_elf32 ? GET16(h32->name) : GET16(h64->name))
#define GET_E64(name) (is_elf32 ? GET32(e32->name) : GET64(e64->name))
#define GET_E32(name) (is_elf32 ? GET32(e32->name) : GET32(e64->name))

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 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, unsigned long *entry_out);
int elf_hdr_size(const unsigned char *ehdr);
int elf_open(const unsigned char *ehdr, int *is_elf32);


#ifdef __cplusplus
Expand Down
21 changes: 21 additions & 0 deletions include/wolfboot/wolfboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ extern "C" {
#define HDR_SIGNATURE 0x20
#define HDR_POLICY_SIGNATURE 0x21
#define HDR_SECONDARY_SIGNATURE 0x22
#define HDR_ELF_SCATTERED_HASH 0x23
#define HDR_PADDING 0xFF

/* Auth Key types */
Expand Down Expand Up @@ -163,31 +164,49 @@ extern "C" {

/* Hashing configuration */
#if defined(WOLFBOOT_HASH_SHA256)
# include "wolfssl/wolfcrypt/sha256.h"
# ifndef WOLFBOOT_SHA_BLOCK_SIZE
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# endif
# define WOLFBOOT_SHA_HDR HDR_SHA256
# define WOLFBOOT_SHA_DIGEST_SIZE (32)
# define image_hash image_sha256
# define header_hash header_sha256
# define update_hash wc_Sha256Update
# define key_hash key_sha256
# define self_hash self_sha256
# define final_hash wc_Sha256Final
typedef wc_Sha256 wolfBoot_hash_t;
# define HDR_HASH HDR_SHA256
#elif defined(WOLFBOOT_HASH_SHA384)
# include "wolfssl/wolfcrypt/sha512.h"
# ifndef WOLFBOOT_SHA_BLOCK_SIZE
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# endif
# define WOLFBOOT_SHA_HDR HDR_SHA384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha384
# define header_hash header_sha384
# define update_hash wc_Sha384Update
# define key_hash key_sha384
# define self_hash self_sha384
# define final_hash wc_Sha384Final
typedef wc_Sha384 wolfBoot_hash_t;
# define HDR_HASH HDR_SHA384
#elif defined(WOLFBOOT_HASH_SHA3_384)
# include "wolfssl/wolfcrypt/sha3.h"
# ifndef WOLFBOOT_SHA_BLOCK_SIZE
# define WOLFBOOT_SHA_BLOCK_SIZE (128)
# endif
# define WOLFBOOT_SHA_HDR HDR_SHA3_384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha3_384
# define header_hash header_sha3_384
# define update_hash wc_Sha3Update
# define final_hash wc_Sha3Final
# define key_hash key_sha3_384
typedef wc_Sha3 wolfBoot_hash_t;
# define HDR_HASH HDR_SHA3_384
#else
# error "No valid hash algorithm defined!"
#endif
Expand Down Expand Up @@ -291,6 +310,8 @@ extern "C" {
/* now just an intermediary state, update state will always be either new or
* updating before the application boots*/
#define IMG_STATE_FINAL_FLAGS 0x30
/* ELF loading state - only valid on boot partition so doesn't conflict with
* IMAGE_STATE_UPDATING */
#define IMG_STATE_TESTING 0x10
#define IMG_STATE_SUCCESS 0x00
#define FLASH_BYTE_ERASED 0xFF
Expand Down
4 changes: 4 additions & 0 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,10 @@ ifeq ($(ELF),1)
ifneq ($(DEBUG_ELF),)
CFLAGS+=-DDEBUG_ELF=$(DEBUG_ELF)
endif
ifeq ($(ELF_SCATTERED),1)
CFLAGS+=-D"WOLFBOOT_ELF_SCATTERED=1"
endif

endif

ifeq ($(MULTIBOOT2),1)
Expand Down
Loading
Loading