Update mechanism implemented, ed25519 signing tool changed

pull/1/head
Daniele Lacamera 2018-11-22 15:47:41 +01:00
parent 6b3dfe2e69
commit 9403c711ad
7 changed files with 580 additions and 54 deletions

View File

@ -88,7 +88,6 @@ tools/ed25519/ed25519_sign:
ed25519.der: tools/ed25519/ed25519_sign
tools/ed25519/ed25519_keygen src/ed25519_pub_key.c
factory.bin: $(BOOT_IMG) wolfboot-align.bin tools/ed25519/ed25519_sign ed25519.der
tools/ed25519/ed25519_sign $(BOOT_IMG) ed25519.der 1
cat wolfboot-align.bin $(BOOT_IMG).v1.signed > $@

59
include/image.h 100644
View File

@ -0,0 +1,59 @@
#ifndef IMAGE_H
#define IMAGE_H
#include <stdint.h>
#include <target.h>
#define IMAGE_HEADER_SIZE 256
#define IMAGE_HEADER_OFFSET (2 * sizeof(uint32_t))
#define WOLFBOOT_MAGIC 0x464C4F57 /* WOLF */
#define WOLFBOOT_MAGIC_TRAIL 0x544F4F42 /* BOOT */
#define HDR_END 0x00
#define HDR_VERSION 0x01
#define HDR_TIMESTAMP 0x02
#define HDR_SHA256 0x03
#define HDR_PUBKEY 0x10
#define HDR_SIGNATURE 0x20
#define HDR_PADDING 0xFF
#define PART_BOOT 0
#define PART_UPDATE 1
#define PART_SWAP 2
#define IMG_STATE_NEW 0xFF
#define IMG_STATE_UPDATING 0x70
#define IMG_STATE_TESTING 0x10
#define IMG_STATE_SUCCESS 0x00
#define SECT_FLAG_NEW 0x0F
#define SECT_FLAG_SWAPPING 0x07
#define SECT_FLAG_BACKUP 0x03
#define SECT_FLAG_UPDATED 0x00
struct wolfBoot_image {
uint8_t *hdr;
uint8_t *trailer;
int hdr_ok;
int signature_ok;
int sha_ok;
uint8_t *fw_base;
uint32_t fw_size;
uint8_t part;
};
int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part);
int wolfBoot_verify_integrity(struct wolfBoot_image *img);
int wolfBoot_verify_authenticity(struct wolfBoot_image *img);
int wolfBoot_set_partition_state(uint8_t part, uint8_t newst);
int wolfBoot_set_sector_flag(uint8_t part, uint8_t sector, uint8_t newflag);
int wolfBoot_get_partition_state(uint8_t part, uint8_t *st);
int wolfBoot_get_sector_flag(uint8_t part, uint8_t sector, uint8_t *flag);
int wolfBoot_copy(uint32_t src, uint32_t dst, uint32_t size);
void wolfBoot_erase_partition(uint8_t part);
void wolfBoot_update_trigger(void);
void wolfBoot_success(void);
#endif /* IMAGE_H */

21
include/loader.h 100644
View File

@ -0,0 +1,21 @@
#ifndef LOADER_H
#define LOADER_H
#if defined(WOLFBOOT_SIGN_EC256)
extern const unsigned char ecdsa_pub_key[];
extern unsigned int ecdsa_pub_key_len;
# define KEY_BUFFER ecdsa_pub_key
# define KEY_LEN ecdsa_pub_key_len
# define IMAGE_SIGNATURE_SIZE (72)
#elif defined(WOLFBOOT_SIGN_ED25519)
extern const unsigned char ed25519_pub_key[];
extern unsigned int ed25519_pub_key_len;
# define KEY_BUFFER ed25519_pub_key
# define KEY_LEN ed25519_pub_key_len
# define IMAGE_SIGNATURE_SIZE (64)
#else
# error "No public key available for given signing algorithm."
#endif /* Algorithm selection */
#endif /* LOADER_H */

323
src/image.c 100644
View File

@ -0,0 +1,323 @@
/* image.c
*
* Copyright (C) 2018 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <image.h>
#include <hal.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/ssl.h>
#include <loader.h>
#ifdef WOLFBOOT_SIGN_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
{
int ret, res;
ed25519_key ed;
ret = wc_ed25519_init(&ed);
if (ret < 0) {
/* Failed to initialize key */
return -1;
}
ret = wc_ed25519_import_public(KEY_BUFFER, KEY_LEN, &ed);
if (ret < 0) {
/* Failed to import ed25519 key */
return -1;
}
ret = wc_ed25519_verify_msg(sig, IMAGE_SIGNATURE_SIZE, hash, SHA256_DIGEST_SIZE, &res, &ed);
if ((ret < 0) || (res == 0)) {
return -1;
}
return 0;
}
#endif
static uint8_t get_header(struct wolfBoot_image *img, uint8_t type, uint8_t **ptr)
{
uint8_t *p = img->hdr + IMAGE_HEADER_OFFSET;
while (*p != 0) {
if (*p == HDR_PADDING) {
p++;
continue;
}
if (*p == type) {
p++;
*ptr = (p + 1);
return *p;
}
p++;
p += (*p + 1);
}
*ptr = NULL;
return 0;
}
int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)
{
uint32_t *magic;
uint32_t *size;
if (!img)
return -1;
memset(img, 0, sizeof(struct wolfBoot_image));
if (part == PART_BOOT)
img->hdr = (void *)WOLFBOOT_PARTITION_BOOT_ADDRESS;
else if (part == PART_UPDATE)
img->hdr = (void *)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
else
return -1;
magic = (uint32_t *)(img->hdr);
if (*magic != WOLFBOOT_MAGIC)
return -1;
size = (uint32_t *)(img->hdr + sizeof (uint32_t));
if (*size >= WOLFBOOT_PARTITION_SIZE)
return -1;
img->part = part;
img->hdr_ok = 1;
img->fw_size = *size;
img->fw_base = img->hdr + IMAGE_HEADER_SIZE;
img->trailer = img->hdr + WOLFBOOT_PARTITION_SIZE;
return 0;
}
static int image_hash(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
uint8_t stored_sha_len;
uint8_t *p = img->hdr;
uint8_t *fw_end = img->fw_base + img->fw_size;
int blksz;
wc_Sha256 sha256_ctx;
if (!img || !img->hdr)
return -1;
stored_sha_len = get_header(img, HDR_SHA256, &stored_sha);
if (stored_sha_len != SHA256_DIGEST_SIZE)
return -1;
wc_InitSha256(&sha256_ctx);
end_sha = stored_sha - 2;
while (p < end_sha) {
blksz = SHA256_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha256Update(&sha256_ctx, p, blksz);
p += blksz;
}
p = img->fw_base;
while(p < fw_end) {
blksz = SHA256_BLOCK_SIZE;
if (fw_end - p < blksz)
blksz = fw_end - p;
wc_Sha256Update(&sha256_ctx, p, blksz);
p += blksz;
}
wc_Sha256Final(&sha256_ctx, hash);
return 0;
}
static void key_hash(uint8_t *hash)
{
int blksz;
unsigned int i = 0;
wc_Sha256 sha256_ctx;
wc_InitSha256(&sha256_ctx);
while(i < KEY_LEN)
{
blksz = SHA256_BLOCK_SIZE;
if ((i + blksz) > KEY_LEN)
blksz = KEY_LEN - i;
wc_Sha256Update(&sha256_ctx, (KEY_BUFFER + i), blksz);
i += blksz;
}
wc_Sha256Final(&sha256_ctx, hash);
}
static uint8_t digest[SHA256_DIGEST_SIZE];
int wolfBoot_verify_integrity(struct wolfBoot_image *img)
{
uint8_t *stored_sha;
uint8_t stored_sha_len;
stored_sha_len = get_header(img, HDR_SHA256, &stored_sha);
if (stored_sha_len != SHA256_DIGEST_SIZE)
return -1;
if (image_hash(img, digest) != 0)
return -1;
if (memcmp(digest, stored_sha, stored_sha_len) != 0)
return -1;
img->sha_ok = 1;
return 0;
}
static uint8_t verification[IMAGE_SIGNATURE_SIZE];
int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
{
uint8_t *stored_signature;
uint8_t stored_signature_size;
uint8_t *pubkey_hint;
uint8_t pubkey_hint_size;
stored_signature_size = get_header(img, HDR_SIGNATURE, &stored_signature);
if (stored_signature_size != IMAGE_SIGNATURE_SIZE)
return -1;
pubkey_hint_size = get_header(img, HDR_PUBKEY, &pubkey_hint);
if (pubkey_hint_size == SHA256_DIGEST_SIZE) {
key_hash(digest);
if (memcmp(digest, pubkey_hint, SHA256_DIGEST_SIZE) != 0)
return -1;
}
if (image_hash(img, digest) != 0)
return -1;
if (wolfBoot_verify_signature(digest, stored_signature) != 0)
return -1;
img->signature_ok = 1;
return 0;
}
static uint8_t *get_trailer(uint8_t part)
{
if (part == PART_BOOT)
return (void *)(WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE);
else if (part == PART_UPDATE)
return (void *)(WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE);
else
return NULL;
}
int wolfBoot_set_partition_state(uint8_t part, uint8_t newst)
{
uint8_t *trailer_end = get_trailer(part);
uint32_t *magic;
uint8_t *state;
uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL;
if (!trailer_end)
return -1;
magic = (uint32_t *)(trailer_end - sizeof(uint32_t));
if (*magic != WOLFBOOT_MAGIC_TRAIL)
hal_flash_write((uint32_t)magic, (void *)&wolfboot_magic_trail, sizeof(uint32_t));
state = (trailer_end - sizeof(uint32_t)) - 1;
if (*state != newst)
hal_flash_write((uint32_t)state, (void *)&newst, 1);
return 0;
}
int wolfBoot_set_sector_flag(uint8_t part, uint8_t sector, uint8_t newflag)
{
uint8_t *trailer_end = get_trailer(part);
uint32_t *magic;
uint8_t *flags;
uint8_t fl_value;
uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL;
uint8_t pos = sector >> 1;
if (!trailer_end)
return -1;
magic = (uint32_t *)(trailer_end - sizeof(uint32_t));
if (*magic != WOLFBOOT_MAGIC_TRAIL)
hal_flash_write((uint32_t)magic, (void *)&wolfboot_magic_trail, sizeof(uint32_t));
flags = (trailer_end - sizeof(uint32_t)) - pos;
if (sector == (pos << 1))
fl_value = (*flags & 0xF0) | (newflag & 0x0F);
else
fl_value = ((newflag & 0x0F) << 4) | (*flags & 0x0F);
if (fl_value != *flags)
hal_flash_write((uint32_t)flags, &fl_value, 1);
return 0;
}
int wolfBoot_get_partition_state(uint8_t part, uint8_t *st)
{
uint8_t *trailer_end = get_trailer(part);
uint32_t *magic;
uint8_t *state;
if (trailer_end)
return -1;
magic = (uint32_t *)(trailer_end - sizeof(uint32_t));
if (*magic != WOLFBOOT_MAGIC_TRAIL)
return -1;
state = (trailer_end - sizeof(uint32_t)) - 1;
*st = *state;
return 0;
}
int wolfBoot_get_sector_flag(uint8_t part, uint8_t sector, uint8_t *flag)
{
uint8_t *trailer_end = get_trailer(part);
uint32_t *magic;
uint8_t *flags;
uint8_t fl_value;
uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL;
uint8_t pos = sector >> 1;
if (!trailer_end)
return -1;
magic = (uint32_t *)(trailer_end - sizeof(uint32_t));
if (*magic != WOLFBOOT_MAGIC_TRAIL)
return -1;
flags = (trailer_end - sizeof(uint32_t)) - pos;
if (sector == (pos << 1))
*flag = *flags & 0x0F;
else
*flag = (*flags & 0xF0) >> 4;
return 0;
}
int wolfBoot_copy(uint32_t src, uint32_t dst, uint32_t size)
{
uint32_t *content;
uint32_t pos = 0;
if (src == dst)
return 0;
if ((src & 0x03) || (dst & 0x03))
return -1;
while (pos < size) {
content = (uint32_t *)(src + pos);
hal_flash_write(dst + pos, (void *)content, sizeof(uint32_t));
pos += sizeof(uint32_t);
}
return pos;
}
void wolfBoot_erase_partition(uint8_t part)
{
if (part == PART_BOOT)
hal_flash_erase(WOLFBOOT_PARTITION_BOOT_ADDRESS, WOLFBOOT_PARTITION_SIZE);
if (part == PART_UPDATE)
hal_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS, WOLFBOOT_PARTITION_SIZE);
#ifdef WOLFBOOT_PARTITION_SWAP_ADDRESS
if (part == PART_SWAP)
hal_flash_erase(WOLFBOOT_PARTITION_SWAP_ADDRESS, WOLFBOOT_SECTOR_SIZE);
#endif
}
void wolfBoot_update_trigger(void)
{
uint8_t st = IMG_STATE_UPDATING;
hal_flash_unlock();
wolfBoot_set_partition_state(PART_UPDATE, st);
hal_flash_lock();
}
void wolfBoot_success(void)
{
uint8_t st = IMG_STATE_SUCCESS;
hal_flash_unlock();
wolfBoot_set_partition_state(PART_BOOT, st);
hal_flash_lock();
}

122
src/loader.c 100644
View File

@ -0,0 +1,122 @@
/* loader.c
*
* Copyright (C) 2018 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <loader.h>
#include <image.h>
#include <hal.h>
extern void do_boot(const uint32_t *app_offset);
static int wolfBoot_update(void)
{
uint32_t total_size;
uint32_t sector_size = WOLFBOOT_SECTOR_SIZE;
uint32_t sector = 0;
uint8_t flag, st;
struct wolfBoot_image update;
if ((wolfBoot_open_image(&update, PART_BOOT) < 0) ||
(wolfBoot_verify_integrity(&update) < 0) ||
(wolfBoot_verify_authenticity(&update) < 0)) {
return -1;
}
total_size = update.fw_size + IMAGE_HEADER_SIZE;
hal_flash_unlock();
while ((sector * sector_size) < total_size) {
if ((wolfBoot_get_sector_flag(PART_UPDATE, sector, &flag) != 0) || (flag == SECT_FLAG_NEW)) {
flag = SECT_FLAG_SWAPPING;
hal_flash_erase(WOLFBOOT_PARTITION_SWAP_ADDRESS, WOLFBOOT_SECTOR_SIZE);
wolfBoot_copy(WOLFBOOT_PARTITION_UPDATE_ADDRESS + sector * sector_size,
WOLFBOOT_PARTITION_SWAP_ADDRESS,
WOLFBOOT_SECTOR_SIZE);
wolfBoot_set_sector_flag(PART_UPDATE, sector, flag);
}
if (flag == SECT_FLAG_SWAPPING) {
uint32_t size = total_size - (sector * sector_size);
if (size > sector_size)
size = sector_size;
flag = SECT_FLAG_BACKUP;
hal_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS + sector * sector_size,
WOLFBOOT_SECTOR_SIZE);
wolfBoot_copy(WOLFBOOT_PARTITION_BOOT_ADDRESS + sector * sector_size,
WOLFBOOT_PARTITION_UPDATE_ADDRESS + sector * sector_size,
WOLFBOOT_SECTOR_SIZE);
wolfBoot_set_sector_flag(PART_UPDATE, sector, flag);
}
if (flag == SECT_FLAG_BACKUP) {
uint32_t size = total_size - (sector * sector_size);
if (size > sector_size)
size = sector_size;
flag = SECT_FLAG_UPDATED;
hal_flash_erase(WOLFBOOT_PARTITION_BOOT_ADDRESS + sector * sector_size,
sector_size);
wolfBoot_copy(WOLFBOOT_PARTITION_SWAP_ADDRESS,
WOLFBOOT_PARTITION_BOOT_ADDRESS + sector * sector_size,
size);
wolfBoot_set_sector_flag(PART_UPDATE, sector, flag);
}
sector++;
}
while((sector * sector_size) < WOLFBOOT_PARTITION_SIZE) {
hal_flash_erase(WOLFBOOT_PARTITION_BOOT_ADDRESS + sector * sector_size,
sector_size);
hal_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS + sector * sector_size,
sector_size);
sector++;
}
hal_flash_erase(WOLFBOOT_PARTITION_SWAP_ADDRESS, WOLFBOOT_SECTOR_SIZE);
st = IMG_STATE_TESTING;
wolfBoot_set_partition_state(PART_BOOT, st);
hal_flash_lock();
return 0;
}
static void wolfBoot_start(void)
{
uint8_t st;
struct wolfBoot_image boot;
if ((wolfBoot_open_image(&boot, PART_BOOT) < 0) ||
(wolfBoot_verify_integrity(&boot) < 0) ||
(wolfBoot_verify_authenticity(&boot) < 0)) {
if (wolfBoot_update() < 0) {
while(1)
/* panic */;
}
}
if ((wolfBoot_get_partition_state(PART_UPDATE, &st) == 0) && (st == IMG_STATE_UPDATING)) {
wolfBoot_update();
} else if ((wolfBoot_get_partition_state(PART_BOOT, &st) == 0) && (st == IMG_STATE_TESTING)) {
wolfBoot_update_trigger();
wolfBoot_update();
}
do_boot((void *)boot.fw_base);
}
int main(void)
{
hal_init();
wolfBoot_start();
while(1)
;
return 0;
}

View File

@ -1,4 +1,4 @@
/* startup_bl.c
/* wolfboot.c
*
* Copyright (C) 2018 wolfSSL Inc.
*
@ -28,7 +28,8 @@ extern unsigned int _end_bss;
extern uint32_t *END_STACK;
void main(void);
extern void main(void);
void isr_reset(void) {
unsigned int *src, *dst;

View File

@ -25,12 +25,13 @@
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#include <bootutil/image.h>
#include <sys/stat.h>
#define WOLFBOOT_SIGN_ED25519
#include "target.h"
#define IMAGE_FIRMWARE_OFFSET 256
#include "image.h"
#include "loader.h"
void print_buf(uint8_t *buf, int len)
{
@ -70,17 +71,13 @@ int main(int argc, char *argv[])
uint8_t signature[ED25519_SIG_SIZE];
uint8_t *final;
int total_size;
struct image_header *hdr;
uint8_t header_buffer[IMAGE_FIRMWARE_OFFSET];
struct image_tlv_info info;
struct image_tlv tlv;
uint8_t hdr[IMAGE_HEADER_SIZE];
uint8_t *ptr = hdr;
struct stat st;
int version;
int padsize = 0;
int i;
hdr = (struct image_header *)header_buffer;
if (argc != 4 && argc!=5) {
fprintf(stderr, "Usage: %s image key.der fw_version [padsize]\n", argv[0]);
exit(1);
@ -111,6 +108,7 @@ int main(int argc, char *argv[])
perror(signed_name);
exit(2);
}
key_fd = open(argv[2], O_RDONLY);
if (key_fd < 0) {
perror(argv[2]);
@ -139,16 +137,27 @@ int main(int argc, char *argv[])
perror(in_name);
exit(2);
}
memset(hdr, 0x00, IMAGE_FIRMWARE_OFFSET);
hdr->ih_magic = IMAGE_MAGIC;
hdr->ih_load_addr = FLASH_AREA_IMAGE_0_OFFSET + IMAGE_FIRMWARE_OFFSET;
hdr->ih_hdr_size = IMAGE_FIRMWARE_OFFSET;
hdr->ih_img_size = st.st_size;
hdr->ih_ver.iv_major = version;
hdr->ih_ver.iv_build_num = (uint32_t)(st.st_mtime);
memset(hdr, 0xFF, IMAGE_HEADER_SIZE);
*((uint32_t *)ptr) = WOLFBOOT_MAGIC;
ptr += (sizeof(uint32_t));
*((uint32_t *)(ptr)) = st.st_size;
ptr += (sizeof(uint32_t));
ptr += (sizeof(uint16_t));
*(ptr++) = HDR_VERSION;
*(ptr++) = 4;
*((uint32_t *)(ptr)) = version;
ptr += (sizeof(uint32_t));
ptr += (sizeof(uint16_t) + sizeof(uint32_t));
*(ptr++) = HDR_TIMESTAMP;
*(ptr++) = 8;
*((uint64_t *)(ptr)) = st.st_mtime;
ptr += sizeof(uint64_t);
/* Sha256 */
wc_Sha256Update(&sha, (uint8_t *)hdr, IMAGE_FIRMWARE_OFFSET);
wc_Sha256Update(&sha, hdr, ptr - hdr);
while(1) {
r = read(in_fd, shabuf, 32);
if (r <= 0)
@ -161,8 +170,32 @@ int main(int argc, char *argv[])
wc_ed25519_sign_msg(shabuf, 32, signature, &outlen, &key);
wc_Sha256Free(&sha);
*(ptr++) = HDR_SHA256;
*(ptr++) = SHA256_DIGEST_SIZE;
memcpy(ptr, shabuf, SHA256_DIGEST_SIZE);
ptr += SHA256_DIGEST_SIZE;
wc_InitSha256(&keyhash);
wc_Sha256Update(&keyhash, inkey + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
wc_Sha256Final(&keyhash, shabuf);
*(ptr++) = HDR_PUBKEY;
*(ptr++) = SHA256_DIGEST_SIZE;
memcpy(ptr, shabuf, SHA256_DIGEST_SIZE);
wc_Sha256Free(&keyhash);
ptr += SHA256_DIGEST_SIZE;
*(ptr++) = HDR_SIGNATURE;
*(ptr++) = ED25519_SIG_SIZE;
memcpy(ptr, signature, ED25519_SIG_SIZE);
ptr += ED25519_SIG_SIZE;
*(ptr++) = HDR_END;
printf("\n\n");
print_buf(hdr, IMAGE_HEADER_SIZE);
/* Write header */
write(out_fd, hdr, IMAGE_FIRMWARE_OFFSET);
write(out_fd, hdr, IMAGE_HEADER_SIZE);
/* Write image payload */
lseek(in_fd, 0, SEEK_SET);
@ -177,38 +210,6 @@ int main(int argc, char *argv[])
break;
}
/* TLV INFO hdr */
memset(&info, 0, sizeof(info));
info.it_magic = IMAGE_TLV_INFO_MAGIC;
info.it_tlv_tot = sizeof(info) + 3 * sizeof(tlv) + 2 * SHA256_DIGEST_SIZE + ED25519_SIG_SIZE;
write(out_fd, &info, sizeof(info));
/* TLV 0: SHA DIGEST */
memset(&tlv, 0, sizeof(tlv));
tlv.it_type = IMAGE_TLV_SHA256;
tlv.it_len = SHA256_DIGEST_SIZE;
write(out_fd, &tlv, sizeof(tlv));
write(out_fd, shabuf, SHA256_DIGEST_SIZE);
/* TLV 1: KEYHASH */
wc_InitSha256(&keyhash);
wc_Sha256Update(&keyhash, inkey + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
wc_Sha256Final(&keyhash, shabuf);
memset(&tlv, 0, sizeof(tlv));
tlv.it_type = IMAGE_TLV_KEYHASH;
tlv.it_len = SHA256_DIGEST_SIZE;
write(out_fd, &tlv, sizeof(tlv));
write(out_fd, shabuf, SHA256_DIGEST_SIZE);
wc_Sha256Free(&keyhash);
/* TLV 2: SIGNATURE */
memset(&tlv, 0, sizeof(tlv));
tlv.it_type = IMAGE_TLV_ED25519;
tlv.it_len = ED25519_SIG_SIZE;
write(out_fd, &tlv, sizeof(tlv));
write(out_fd, signature, ED25519_SIG_SIZE);
close(out_fd);
/* Pad if needed */
r = stat(signed_name, &st);
if ((r == 0) && st.st_size < padsize) {