mirror of https://github.com/wolfSSL/wolfBoot.git
Update mechanism implemented, ed25519 signing tool changed
parent
6b3dfe2e69
commit
9403c711ad
1
Makefile
1
Makefile
|
@ -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 > $@
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue