ELF_SCATTERED: added sha check (WIP)

pull/562/head
Daniele Lacamera 2025-04-04 19:15:04 +02:00
parent e7cd340ebf
commit 11091944d7
7 changed files with 443 additions and 220 deletions

View File

@ -353,16 +353,11 @@ 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
unsigned long *entry_point = (unsigned long *)sim_ram_base;
uint8_t *entry_point = (sim_ram_base + 0x100000);
printf("entry point: %p\n", entry_point);
printf("app offset: %p\n", app_offset);
typedef int (*main_entry)(int, char**);
main_entry main;
wolfBoot_printf("Loading ELF image with scattered segments...\n");
ret = elf_store_image_scattered((void*)app_offset, entry_point, 0);
if (ret != 0) {
wolfBoot_printf( "Error loading ELF image!\n");
exit(-1);
}
main = (main_entry)(entry_point);
main(main_argc, main_argv);
#else

View File

@ -112,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;
@ -164,6 +169,9 @@ 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_hdr_size(const unsigned char *ehdr);
int elf_open(const unsigned char *ehdr, int *is_elf32);
#ifdef __cplusplus

View File

@ -164,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_384 wolfBoot_hash_t;
# define HDR_HASH HDR_SHA3_384
#else
# error "No valid hash algorithm defined!"
#endif

206
src/elf.c
View File

@ -33,6 +33,10 @@
#include "hal/nxp_ppc.h"
#endif
#ifdef ELF_SCATTERED
#include "image.h"
#endif
/* support for elf parsing debug printf */
#if defined(DEBUG) || defined(ELF_PARSER)
#if defined(DEBUG_ELF) && DEBUG_ELF == 0
@ -147,167 +151,52 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb)
}
#endif /* MMU */
#if 0
/**
* @brief Compute the scattered hash by hashing PT_LOAD segments at their XIP
* addresses. Note: This function assumes that the destination addresses for elf
* loading have the same access patterns as the memory represented by img.
* (e.g. if BOOT partition is external, then reads/writes to the load address
* will use ext_flash_read/ext_flash_write.
*
* @param img Pointer to the wolfBoot image
* @param hash Buffer to store the computed hash (must be at least
* WOLFBOOT_SHA_DIGEST_SIZE bytes)
* @return 0 on success, negative value on error
*/
static int wolfBoot_compute_scattered_hash(struct wolfBoot_image *img, uint8_t *hash)
int elf_open(const unsigned char *ehdr, int *is_elf32)
{
uint8_t elf_header_buf[sizeof(elf64_header)];
uint8_t program_header_buf[sizeof(elf64_program_header)];
elf32_header* h32;
elf64_header* h64;
uint16_t entry_count, entry_size;
uint32_t ph_offset;
int is_elf32, is_le, i;
#if defined(WOLFBOOT_HASH_SHA256)
wc_Sha256 sha256_ctx;
#elif defined(WOLFBOOT_HASH_SHA384)
wc_Sha384 sha384_ctx;
#elif defined(WOLFBOOT_HASH_SHA3_384)
wc_Sha3 sha3_384_ctx;
#endif
#ifdef EXT_FLASH
if (PART_IS_EXT(img)) {
/* Read ELF header from external flash */
ext_flash_check_read((uintptr_t)(img->fw_base), elf_header_buf, sizeof(elf64_header));
} else
#endif
{
memcpy(elf_header_buf, (void*)(img->fw_base), sizeof(elf64_header));
}
h32 = (elf32_header*)elf_header_buf;
h64 = (elf64_header*)elf_header_buf;
const unsigned char *ident = ehdr;
/* Verify ELF header */
if (memcmp(h32->ident, ELF_IDENT_STR, 4) != 0) {
if (memcmp(ident, ELF_IDENT_STR, 4) != 0) {
return -1; /* not valid header identifier */
}
/* Load class and endianess */
is_elf32 = (h32->ident[4] == ELF_CLASS_32);
is_le = (h32->ident[5] == ELF_ENDIAN_LITTLE);
(void)is_le;
/* Initialize hash context */
#if defined(WOLFBOOT_HASH_SHA256)
wc_InitSha256(&sha256_ctx);
#elif defined(WOLFBOOT_HASH_SHA384)
wc_InitSha384(&sha384_ctx);
#elif defined(WOLFBOOT_HASH_SHA3_384)
wc_Sha3_384_Init(&sha3_384_ctx, NULL, INVALID_DEVID);
#endif
/* Get program headers info */
ph_offset = is_elf32 ? GET32(h32->ph_offset) : GET32(h64->ph_offset);
entry_size = is_elf32 ? GET16(h32->ph_entry_size) : GET16(h64->ph_entry_size);
entry_count = is_elf32 ? GET16(h32->ph_entry_count) : GET16(h64->ph_entry_count);
/* Hash each loadable segment directly from its physical address */
for (i = 0; i < entry_count; i++) {
elf32_program_header* phdr32;
elf64_program_header* phdr64;
uint32_t type;
uintptr_t paddr;
uintptr_t file_size;
/* Read program header into buffer */
#ifdef EXT_FLASH
if (PART_IS_EXT(img)) {
ext_flash_check_read((uintptr_t)(img->fw_base) + ph_offset + (i * entry_size),
program_header_buf, entry_size);
} else
#endif
{
memcpy(program_header_buf,
(uint8_t*)(img->fw_base) + ph_offset + (i * entry_size),
entry_size);
}
phdr32 = (elf32_program_header*)program_header_buf;
phdr64 = (elf64_program_header*)program_header_buf;
type = (is_elf32 ? GET32(phdr32->type) : GET32(phdr64->type));
paddr = (is_elf32 ? GET32(phdr32->paddr) : GET64(phdr64->paddr));
file_size = (is_elf32 ? GET32(phdr32->file_size) : GET64(phdr64->file_size));
/* Only hash PT_LOAD segments with non-zero size */
if (type == ELF_PT_LOAD && file_size > 0) {
#ifdef DEBUG_ELF
wolfBoot_printf("Hashing segment at %p (%d bytes)\r\n", (void*)paddr, (uint32_t)file_size);
#endif
/* Hash the segment data from physical address in blocks */
uint32_t pos = 0;
while (pos < file_size) {
uint8_t *block;
uint32_t blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (pos + blksz > file_size) {
blksz = file_size - pos;
}
block = get_sha_block_ptr(img, (const uint8_t *)(paddr + pos));
if (block == NULL) {
return -1;
}
#if defined(WOLFBOOT_HASH_SHA256)
wc_Sha256Update(&sha256_ctx, block, blksz);
#elif defined(WOLFBOOT_HASH_SHA384)
wc_Sha384Update(&sha384_ctx, block, blksz);
#elif defined(WOLFBOOT_HASH_SHA3_384)
wc_Sha3_384_Update(&sha3_384_ctx, block, blksz);
#endif
pos += blksz;
}
}
}
/* Finalize hash */
#if defined(WOLFBOOT_HASH_SHA256)
wc_Sha256Final(&sha256_ctx, hash);
#elif defined(WOLFBOOT_HASH_SHA384)
wc_Sha384Final(&sha384_ctx, hash);
#elif defined(WOLFBOOT_HASH_SHA3_384)
wc_Sha3_384_Final(&sha3_384_ctx, hash);
#endif
wolfBoot_printf("ELF image found\n");
*is_elf32 = !!(ident[ELF_CLASS_OFF] == ELF_CLASS_32);
return 0;
}
#endif
int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_out, int ext_flash) {
const unsigned char *ident;
}
int elf_hdr_size(const unsigned char *ehdr)
{
int sz = 0;
int is_elf32;
if (elf_open(ehdr, &is_elf32) != 0)
return -1;
if (is_elf32) {
const elf32_header *elf32_hdr = (const elf32_header *)ehdr;
sz = sizeof(elf32_header);
sz += elf32_hdr->ph_entry_count * sizeof(elf32_program_header);
} else {
const elf64_header *elf64_hdr = (const elf64_header *)ehdr;
sz = sizeof(elf64_header);
sz += elf64_hdr->ph_entry_count * sizeof(elf64_program_header);
}
return sz;
}
int elf_store_image_scattered(const unsigned char *hdr, unsigned long *entry_out, int ext_flash) {
const unsigned char *image;
int is_elf32;
unsigned short entry_count;
unsigned short entry_size;
unsigned long entry_off;
int i;
ident = image;
/* Verify ELF header */
if (memcmp(ident, ELF_IDENT_STR, 4) != 0) {
return -1; /* not valid header identifier */
image = hdr + IMAGE_HEADER_SIZE;
if (elf_open(image, &is_elf32) != 0) {
return -1;
}
is_elf32 = (ident[ELF_CLASS_OFF] == ELF_CLASS_32);
if (is_elf32) {
const elf32_header *eh;
const elf32_program_header *ph;
wolfBoot_printf("ELF image is 32 bit\n");
eh = (const elf32_header *)image;
entry_count = eh->ph_entry_count;
@ -327,12 +216,11 @@ int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_o
paddr = (unsigned long)ph[i].paddr;
offset = (unsigned long)ph[i].offset;
filesz = (unsigned long)ph[i].file_size;
#if 0
#ifdef EXT_FLASH
if (ext_flash) {
ext_flash_unlock();
ext_flash_erase(paddr, filesz);
ext_flash_write(paddr, image + offset, filesz);
ext_flash_erase(paddr + ARCH_FLASH_OFFSET, filesz);
ext_flash_write(paddr + ARCH_FLASH_OFFSET, image + offset, filesz);
ext_flash_lock();
}
else
@ -343,11 +231,11 @@ int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_o
hal_flash_write(paddr, image + offset, filesz);
hal_flash_lock();
}
#endif
}
} else if (ident[ELF_CLASS_OFF] == ELF_CLASS_64) {
} else { /* 64 bit ELF */
const elf64_header *eh;
const elf64_program_header *ph;
wolfBoot_printf("ELF image is 64 bit\n");
eh = (const elf64_header *)image;
entry_count = eh->ph_entry_count;
@ -363,33 +251,27 @@ int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_o
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;
#if 0
printf("Writing section at address %lx offset %lx\n", paddr, offset);
#ifdef EXT_FLASH
if (ext_flash) {
ext_flash_unlock();
ext_flash_erase(paddr, filesz);
ext_flash_write(paddr, image + offset, filesz);
ext_flash_erase(paddr + ARCH_FLASH_OFFSET, filesz);
ext_flash_write(paddr + ARCH_FLASH_OFFSET, image + offset, filesz);
ext_flash_lock();
}
else
#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();
}
#endif
}
} else {
/* Invalid elf header. */
return -1;
}
return 0;
}

View File

@ -818,22 +818,13 @@ static uint8_t *get_img_hdr(struct wolfBoot_image *img)
#if defined(WOLFBOOT_HASH_SHA256)
#include <wolfssl/wolfcrypt/sha256.h>
/**
* @brief Calculate the SHA256 hash of the image.
*
* @param img The image to calculate the hash for.
* @param hash A pointer to store the resulting SHA256 hash.
* @return 0 on success, -1 on failure.
*/
static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
/* Initialize and hash the header part */
static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
{
uint8_t *stored_sha, *end_sha;
uint16_t stored_sha_len;
uint8_t *p;
int blksz;
uint32_t position = 0;
wc_Sha256 sha256_ctx;
if (!img)
return -1;
@ -844,16 +835,35 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
(void)wc_InitSha256_ex(&sha256_ctx, NULL, hsmClientDevIdHash);
#else
wc_InitSha256(&sha256_ctx);
wc_InitSha256(sha256_ctx);
#endif
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
while (p < end_sha) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha256Update(&sha256_ctx, p, blksz);
wc_Sha256Update(sha256_ctx, p, blksz);
p += blksz;
}
return 0;
}
/**
* @brief Calculate the SHA256 hash of the image.
*
* @param img The image to calculate the hash for.
* @param hash A pointer to store the resulting SHA256 hash.
* @return 0 on success, -1 on failure.
*/
static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
{
uint32_t position = 0;
uint8_t *p;
int blksz;
wc_Sha256 sha256_ctx;
if (header_sha256(&sha256_ctx, img) != 0)
return -1;
do {
p = get_sha_block(img, position);
if (p == NULL)
@ -899,6 +909,37 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash)
#if defined(WOLFBOOT_HASH_SHA384)
#include <wolfssl/wolfcrypt/sha512.h>
/* Initialize and hash the header part */
static int header_sha384(wc_Sha384 *sha384_ctx, struct wolfBoot_image *img)
{
uint16_t stored_sha_len;
uint8_t *stored_sha, *end_sha;
uint8_t *p;
int blksz;
if (!img)
return -1;
p = get_img_hdr(img);
stored_sha_len = get_header(img, HDR_SHA384, &stored_sha);
if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE)
return -1;
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
(void)wc_InitSha384_ex(&sha384_ctx, NULL, hsmClientDevIdHash);
#else
wc_InitSha384(sha384_ctx);
#endif
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
while (p < end_sha) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha384Update(sha384_ctx, p, blksz);
p += blksz;
}
return 0;
}
/**
* @brief Calculate SHA-384 hash of the image.
*
@ -910,29 +951,13 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash)
*/
static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
uint16_t stored_sha_len;
uint32_t position = 0;
uint8_t *p;
int blksz;
uint32_t position = 0;
wc_Sha384 sha384_ctx;
if (!img)
if (header_sha384(&sha384_ctx, img) != 0)
return -1;
p = get_img_hdr(img);
stored_sha_len = get_header(img, HDR_SHA384, &stored_sha);
if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE)
return -1;
wc_InitSha384(&sha384_ctx);
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
while (p < end_sha) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha384Update(&sha384_ctx, p, blksz);
p += blksz;
}
do {
p = get_sha_block(img, position);
if (p == NULL)
@ -983,6 +1008,33 @@ static void key_sha384(uint8_t key_slot, uint8_t *hash)
#include <wolfssl/wolfcrypt/sha3.h>
/* Initialize and hash the header part */
static int header_sha3_384(wc_Sha3 *sha3_ctx, struct wolfBoot_image *img)
{
uint16_t stored_sha_len;
uint8_t *stored_sha, *end_sha;
uint8_t *p;
int blksz;
if (!img)
return -1;
p = get_img_hdr(img);
stored_sha_len = get_header(img, HDR_SHA3_384, &stored_sha);
if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE)
return -1;
wc_InitSha3_384(sha3_ctx, NULL, INVALID_DEVID);
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
while (p < end_sha) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha3_384_Update(sha3_ctx, p, blksz);
p += blksz;
}
return 0;
}
/**
* @brief Calculate SHA3-384 hash of the image.
*
@ -994,29 +1046,13 @@ static void key_sha384(uint8_t key_slot, uint8_t *hash)
*/
static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
uint16_t stored_sha_len;
uint8_t *p;
int blksz;
uint32_t position = 0;
wc_Sha3 sha3_ctx;
if (!img)
if (header_sha3_384(&sha3_ctx, img) != 0)
return -1;
p = get_img_hdr(img);
stored_sha_len = get_header(img, HDR_SHA3_384, &stored_sha);
if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE)
return -1;
wc_InitSha3_384(&sha3_ctx, NULL, INVALID_DEVID);
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
while (p < end_sha) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha3_384_Update(&sha3_ctx, p, blksz);
p += blksz;
}
do {
p = get_sha_block(img, position);
if (p == NULL)
@ -1291,6 +1327,267 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img)
return 0;
}
#ifdef ELF_SCATTERED
#include "elf.h"
#define PADDING_BLOCK_SIZE 64
int elf_check_image_scattered(uint8_t part)
{
/* Open the partition containing the image */
struct wolfBoot_image boot;
uint8_t *elf_h, *p;
int elf_hdr_sz = 0;
int len;
int is_elf32;
unsigned short entry_count;
unsigned short entry_size;
unsigned long entry_off;
long final_offset = -1;
uint8_t calc_digest[WOLFBOOT_SHA_DIGEST_SIZE];
uint8_t *exp_digest;
int stored_sha_len;
int i;
uint8_t padding_block[PADDING_BLOCK_SIZE];
wolfBoot_hash_t ctx;
if (wolfBoot_open_image(&boot, part) < 0)
return -1;
p = get_img_hdr(&boot);
/* Initialize hash, feed the manifest header to it */
if (header_hash(&ctx, &boot) < 0)
return -1;
stored_sha_len = get_header(&boot, HDR_HASH, &exp_digest);
if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE)
return -1;
/* Get the elf header size */
elf_h = p + IMAGE_HEADER_SIZE;
if (elf_open(elf_h, &is_elf32) < 0)
return -1;
elf_hdr_sz = elf_hdr_size(elf_h);
wolfBoot_printf("Elf header size: %d\n", elf_hdr_sz);
memset(padding_block, 0, PADDING_BLOCK_SIZE);
/* Feed the elf header to the hash function */
len = elf_hdr_sz;
p = elf_h;
while (len > 0) {
if (len > WOLFBOOT_SHA_BLOCK_SIZE) {
update_hash(&ctx, p, WOLFBOOT_SHA_BLOCK_SIZE);
len -= WOLFBOOT_SHA_BLOCK_SIZE;
} else {
update_hash(&ctx, p, len);
break;
}
p += WOLFBOOT_SHA_BLOCK_SIZE;
}
wolfBoot_printf("Hashed ELF header.\n");
/* Feed the program headers to the hash function */
if (is_elf32) {
elf32_header *eh = (elf32_header *)elf_h;
elf32_program_header *ph;
entry_count = eh->ph_entry_count;
entry_size = eh->ph_entry_size;
entry_off = eh->ph_offset;
/* Add padding until the first program header into hash function */
len = entry_off - elf_hdr_sz;
wolfBoot_printf("Adding %d bytes padding\n", len);
while (len > 0) {
if (len > PADDING_BLOCK_SIZE) {
update_hash(&ctx, padding_block, PADDING_BLOCK_SIZE);
len -= PADDING_BLOCK_SIZE;
} else {
update_hash(&ctx, padding_block, len);
break;
}
}
ph = (elf32_program_header *)(elf_h + entry_off);
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;
/* Feed any non-loaded parts to the hash function */
if (ph[i].type != ELF_PT_LOAD) {
len = filesz;
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;
} else {
update_hash(&ctx, elf_h + offset, len);
break;
}
}
} else {
/* Feed the loaded parts to the hash function */
len = filesz;
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;
} else {
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)) {
unsigned long padding = ph[i+1].offset - (offset + filesz);
wolfBoot_printf("Adding padding: %lu\n", padding);
while (padding > 0) {
if (padding > PADDING_BLOCK_SIZE) {
update_hash(&ctx, padding_block, PADDING_BLOCK_SIZE);
padding -= PADDING_BLOCK_SIZE;
} else {
update_hash(&ctx, padding_block, padding);
break;
}
}
} else {
final_offset = offset + filesz;
}
}
}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;
wolfBoot_printf("EH entry offset: %d\n", entry_off);
ph = (elf64_program_header *)(elf_h + entry_off);
/* Add padding until the first program header into hash function */
len = ph[0].offset - elf_hdr_sz;
wolfBoot_printf("Adding %d bytes padding\n", len);
while (len > 0) {
if (len > PADDING_BLOCK_SIZE) {
update_hash(&ctx, padding_block, PADDING_BLOCK_SIZE);
len -= PADDING_BLOCK_SIZE;
} else {
update_hash(&ctx, padding_block, len);
break;
}
}
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;
} else {
update_hash(&ctx, elf_h + offset, len);
break;
}
}
} 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;
} else {
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)) {
unsigned long padding = ph[i+1].offset - (offset + filesz);
wolfBoot_printf("Adding padding: %lu\n", padding);
while (padding > 0) {
if (padding > PADDING_BLOCK_SIZE) {
update_hash(&ctx, padding_block, PADDING_BLOCK_SIZE);
padding -= PADDING_BLOCK_SIZE;
} else {
update_hash(&ctx, padding_block, padding);
break;
}
}
} else {
final_offset = offset + filesz;
}
}
}
if (final_offset < 0)
return -1;
if (final_offset + IMAGE_HEADER_SIZE > boot.fw_size)
return -1;
len = boot.fw_size - final_offset;
p = boot.hdr + IMAGE_HEADER_SIZE + final_offset;
p = get_img_hdr(&boot) + IMAGE_HEADER_SIZE + final_offset;
wolfBoot_printf("Appending %d bytes of data from image, from position %lu...(0x%p)\n", len, IMAGE_HEADER_SIZE + final_offset, p);
while (len > 0) {
if (len > WOLFBOOT_SHA_BLOCK_SIZE) {
update_hash(&ctx, p, WOLFBOOT_SHA_BLOCK_SIZE);
len -= WOLFBOOT_SHA_BLOCK_SIZE;
p += WOLFBOOT_SHA_BLOCK_SIZE;
} else {
update_hash(&ctx, p, len);
break;
}
}
/* Finalize SHA calculation */
final_hash(&ctx, calc_digest);
if (memcmp(calc_digest, exp_digest, WOLFBOOT_SHA_DIGEST_SIZE) != 0) {
wolfBoot_printf("SHA failed for scattered ELF!\n");
wolfBoot_printf("Expected %02x%02x%02x%02x%02x%02x%02x%02x\n",
exp_digest[0], exp_digest[1], exp_digest[2], exp_digest[3],
exp_digest[4], exp_digest[5], exp_digest[6], exp_digest[7]);
wolfBoot_printf("Calculated %02x%02x%02x%02x%02x%02x%02x%02x\n",
calc_digest[0], calc_digest[1], calc_digest[2], calc_digest[3],
calc_digest[4], calc_digest[5], calc_digest[6], calc_digest[7]);
return -2;
}
wolfBoot_printf("Scattered ELF verified.\n");
return 0;
}
#endif
#ifdef WOLFBOOT_NO_SIGN
/**
* @brief Verify the authenticity of the image using a digital signature.

View File

@ -38,6 +38,11 @@
int WP11_Library_Init(void);
#endif
/* Support for ELF scatter/gather format */
#ifdef ELF_SCATTERED
#include "elf.h"
#endif
#ifdef RAM_CODE
#ifndef TARGET_rp2350
extern unsigned int _start_text;
@ -1062,6 +1067,24 @@ void RAMFUNCTION wolfBoot_start(void)
}
}
PART_SANITY_CHECK(&boot);
#ifdef ELF_SCATTERED
uintptr_t entry;
void *base = (void *)WOLFBOOT_PARTITION_BOOT_ADDRESS;
wolfBoot_printf("ELF Scattered image digest check\n");
if (elf_check_image_scattered(PART_BOOT) <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) {
wolfBoot_printf("Fatal: Could not verify digest after scattering. Panic().\n");
wolfBoot_panic();
}
}
wolfBoot_printf("Scattered image correctly verified. Setting entry point to %p\n", entry);
boot.fw_base = (void *)entry;
#endif
#ifdef WOLFBOOT_TPM
wolfBoot_tpm2_deinit();
#endif

View File

@ -227,7 +227,6 @@ ifeq ($(TARGET),ti_hercules)
endif
ifeq ($(TARGET),sim)
APP_OBJS+=../test-app/libwolfboot.o ../hal/$(TARGET).o
# LD on MacOS does not support "-Map="
LDMAPSUPPORTED=$(shell $(CC) -Wl,-Map=image.map 2>&1 | grep 'unknown option')
LDFLAGS=
@ -241,11 +240,12 @@ ifeq ($(TARGET),sim)
endif
ifeq ($(ELF_SCATTERED),1)
LSCRIPT_TEMPLATE=sim_scattered.ld
APP_OBJS=app_sim_scattered.o ../src/elf.o ../src/string.o
APP_OBJS=app_sim_scattered.o ../src/string.o
CFLAGS+=-D"ELF_SCATTERED=1" -nostartfiles -ffreestanding -static -nostdlib
LDFLAGS+=-ffreestanding -nostartfiles -static -T$(LSCRIPT) -nostdlib
else
APP_OBJS=app_sim.o
APP_OBJS+=../test-app/libwolfboot.o ../hal/$(TARGET).o
endif
endif