mirror of https://github.com/wolfSSL/wolfBoot.git
ELF_SCATTERED: added sha check (WIP)
parent
e7cd340ebf
commit
11091944d7
11
hal/sim.c
11
hal/sim.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
206
src/elf.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
393
src/image.c
393
src/image.c
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue