mirror of https://github.com/wolfSSL/wolfBoot.git
C Host key tools rewritten in python (fix for #4)
parent
17f382b995
commit
75fc9cc59a
30
Makefile
30
Makefile
|
@ -49,8 +49,8 @@ include arch.mk
|
|||
## DSA Settings
|
||||
|
||||
ifeq ($(SIGN),ECC256)
|
||||
KEYGEN_TOOL=tools/ecc256/ecc256_keygen
|
||||
SIGN_TOOL=tools/ecc256/ecc256_sign
|
||||
KEYGEN_OPTIONS=--ecc256
|
||||
SIGN_OPTIONS=--ecc256
|
||||
PRIVATE_KEY=ecc256.der
|
||||
OBJS+= \
|
||||
$(ECC_EXTRA_OBJS) \
|
||||
|
@ -63,8 +63,8 @@ ifeq ($(SIGN),ECC256)
|
|||
./src/xmalloc.o
|
||||
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS)
|
||||
else
|
||||
KEYGEN_TOOL=tools/ed25519/ed25519_keygen
|
||||
SIGN_TOOL=tools/ed25519/ed25519_sign
|
||||
KEYGEN_OPTIONS=--ed25519
|
||||
SIGN_OPTIONS=--ed25519
|
||||
PRIVATE_KEY=ed25519.der
|
||||
OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
|
||||
./lib/wolfssl/wolfcrypt/src/ed25519.o \
|
||||
|
@ -150,23 +150,17 @@ test-app/image.bin:
|
|||
|
||||
include tools/test.mk
|
||||
|
||||
tools/ed25519/ed25519_sign:
|
||||
@make -C tools/ed25519
|
||||
ed25519.der:
|
||||
@tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/ed25519_pub_key.c
|
||||
|
||||
tools/ecc256/ecc256_sign:
|
||||
@make -C tools/ecc256
|
||||
ecc256.der:
|
||||
@tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/ecc256_pub_key.c
|
||||
|
||||
ed25519.der: tools/ed25519/ed25519_sign
|
||||
@tools/ed25519/ed25519_keygen src/ed25519_pub_key.c
|
||||
|
||||
ecc256.der: tools/ecc256/ecc256_sign
|
||||
@tools/ecc256/ecc256_keygen src/ecc256_pub_key.c
|
||||
|
||||
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(SIGN_TOOL) $(PRIVATE_KEY)
|
||||
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(PRIVATE_KEY)
|
||||
@echo "\t[SIGN] $(BOOT_IMG)"
|
||||
$(Q)$(SIGN_TOOL) $(BOOT_IMG) $(PRIVATE_KEY) 1 >/dev/null
|
||||
$(Q)tools/keytools/sign.py $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
|
||||
@echo "\t[MERGE] $@"
|
||||
@cat wolfboot-align.bin $(BOOT_IMG).v1.signed > $@
|
||||
@cat wolfboot-align.bin test-app/image_v1_signed.bin > $@
|
||||
|
||||
wolfboot.elf: $(OBJS) $(LSCRIPT)
|
||||
@echo "\t[LD] $@"
|
||||
|
@ -184,8 +178,6 @@ clean:
|
|||
@make -C test-app clean
|
||||
|
||||
distclean: clean
|
||||
@make -C tools/ed25519 clean
|
||||
@make -C tools/ecc256 clean
|
||||
@rm -f *.pem *.der tags ./src/ed25519_pub_key.c ./src/ecc256_pub_key.c
|
||||
|
||||
|
||||
|
|
|
@ -89,4 +89,4 @@ standalone: image.bin
|
|||
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
||||
clean:
|
||||
@rm -f image.bin* image.elf *.o image.map tags
|
||||
@rm -f *.bin *.elf tags *.o
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# Settings
|
||||
#
|
||||
CC=gcc
|
||||
LD=gcc
|
||||
CROSS_COMPILE=
|
||||
WOLFBOOT_ROOT=../../
|
||||
BOOTUTIL_ROOT=$(WOLFBOOT_ROOT)/lib/bootutil
|
||||
CFLAGS:=-lwolfssl -DHAVE_ECC -DHAVE_ASN -DWOLFCRYPT_ONLY -DTFM_TIMING_RESISTANT -DNO_RSA -DECC_TIMING_RESISTANT -DWOLFSSL_DER_TO_PEM -DWOLFSSL_VALIDATE_ECC_IMPORT -DHAVE_ECC_KEY_EXPORT -I$(WOLFBOOT_ROOT)/include
|
||||
LDFLAGS:=-lwolfssl
|
||||
LDFLAGS_EXTRA=
|
||||
EXTRA_LDFLAGS=
|
||||
|
||||
all: ecc256_keygen ecc256_sign
|
||||
|
||||
|
||||
|
||||
ecc256_keygen: ecc256_keygen.o
|
||||
gcc -o $@ $^ $(LDFLAGS)
|
||||
|
||||
ecc256_sign: ecc256_sign.o
|
||||
gcc -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f ecc256_keygen ecc256_sign *.o
|
|
@ -1,151 +0,0 @@
|
|||
/* ecc_keys.h
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define ECC_KEY_SIZE 32
|
||||
|
||||
void create_pubkey_cfile(const char *fname, uint8_t *key_in)
|
||||
{
|
||||
char buf[4192] = { };
|
||||
char keybyte[5] = {};
|
||||
int i;
|
||||
int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0660);
|
||||
if (fd < 0) {
|
||||
perror("creating c file");
|
||||
exit(1);
|
||||
}
|
||||
strcat(buf,"/* This file is automatically generate by ecc256 keygen. DO NOT EDIT. */\n");
|
||||
strcat(buf,"#include <stdint.h>\n");
|
||||
strcat(buf,"const uint8_t ecc256_pub_key[64] = {\n");
|
||||
for (i = 0; i < 2 * ECC_KEY_SIZE; i++) {
|
||||
int p = i % 8;
|
||||
if (p == 0)
|
||||
strcat(buf,"\t");
|
||||
snprintf(keybyte, 5, "0x%02X", key_in[i]);
|
||||
strcat(buf, keybyte);
|
||||
if (i < 2 * ECC_KEY_SIZE - 1)
|
||||
strcat(buf, ",");
|
||||
if (p == 7)
|
||||
strcat(buf, "\n");
|
||||
else
|
||||
strcat(buf," ");
|
||||
}
|
||||
strcat(buf,"};\n");
|
||||
strcat(buf,"const uint32_t ecc256_pub_key_len = 64;\n");
|
||||
write(fd, buf, strlen(buf));
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void print_buf(uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
int p = i % 8;
|
||||
if (p == 0)
|
||||
printf("\t");
|
||||
printf("0x%02X", buf[i]);
|
||||
if (i < len - 1)
|
||||
printf(",");
|
||||
if (p == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_mp(mp_int *m)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
mp_to_unsigned_bin(m, buf);
|
||||
print_buf(buf, 32);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ecc_key key;
|
||||
uint8_t der[3 * ECC_KEY_SIZE];
|
||||
uint8_t buf[2 * ECC_KEY_SIZE];
|
||||
FILE* derFile;
|
||||
size_t sz;
|
||||
uint32_t qxlen = ECC_KEY_SIZE;
|
||||
uint32_t qylen = ECC_KEY_SIZE;
|
||||
uint32_t dlen = ECC_KEY_SIZE;
|
||||
int fd;
|
||||
|
||||
RNG rng;
|
||||
|
||||
wc_InitRng(&rng);
|
||||
wc_ecc_init(&key);
|
||||
|
||||
if (wc_ecc_make_key(&rng, ECC_KEY_SIZE, &key) != 0) {
|
||||
printf("error making ecc key\n");
|
||||
return -1;
|
||||
}
|
||||
print_mp(&key.k);
|
||||
/* write private key */
|
||||
if (wc_ecc_export_private_raw(&key,
|
||||
der, &qxlen,
|
||||
der + ECC_KEY_SIZE, &qylen,
|
||||
der + 2 * ECC_KEY_SIZE, &dlen
|
||||
) == 0) {
|
||||
printf("Created private key: %d bytes\n", qxlen + qylen + dlen);
|
||||
}
|
||||
|
||||
/* Store private key */
|
||||
fd = open("ecc256.der", O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(2);
|
||||
}
|
||||
write(fd, der, qxlen + qylen + dlen);
|
||||
close(fd);
|
||||
|
||||
|
||||
/* Store public key */
|
||||
fd = open("ecc-pub.der", O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(2);
|
||||
}
|
||||
write(fd, der, qxlen + qylen);
|
||||
close(fd);
|
||||
if (argc > 1) {
|
||||
printf("Generating .c code for public key...\n");
|
||||
create_pubkey_cfile(argv[1], der);
|
||||
}
|
||||
|
||||
/* close stuff up */
|
||||
wc_ecc_free(&key);
|
||||
wc_FreeRng(&rng);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,308 +0,0 @@
|
|||
/*
|
||||
* ecc256_sign.c
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define ECC_KEY_SIZE 32
|
||||
#define ECC_SIG_SIZE (2 * ECC_KEY_SIZE)
|
||||
#define WOLFBOOT_SIGN_ECC256
|
||||
#define VERIFY_SIGNATURE_TEST
|
||||
|
||||
#include "target.h"
|
||||
#include "image.h"
|
||||
#include "loader.h"
|
||||
|
||||
static uint8_t key_buffer[2 * sizeof(ecc_key)];
|
||||
|
||||
void print_buf(uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
int p = i % 8;
|
||||
if (p == 0)
|
||||
printf("\t");
|
||||
printf("0x%02X", buf[i]);
|
||||
if (i < len - 1)
|
||||
printf(",");
|
||||
if (p == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_mp(mp_int *m)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
mp_to_unsigned_bin(m, buf);
|
||||
print_buf(buf, 32);
|
||||
}
|
||||
|
||||
void print_key(void *key_in)
|
||||
{
|
||||
uint8_t * key = key_in;
|
||||
print_buf(key, ECC_KEY_SIZE);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint8_t inkey[ECC_KEY_SIZE * 4];
|
||||
int in_fd, key_fd, out_fd, r;
|
||||
int outlen = ECC_SIG_SIZE;
|
||||
char in_name[PATH_MAX];
|
||||
char signed_name[PATH_MAX];
|
||||
char *dot;
|
||||
ecc_key *key = (ecc_key *)key_buffer;
|
||||
Sha256 sha;
|
||||
Sha256 keyhash;
|
||||
uint8_t shabuf[SHA256_DIGEST_SIZE];
|
||||
uint8_t signature[ECC_SIG_SIZE] = { };
|
||||
uint8_t *final;
|
||||
int total_size;
|
||||
uint8_t hdr[IMAGE_HEADER_SIZE];
|
||||
uint8_t *ptr = hdr;
|
||||
struct stat st;
|
||||
int version;
|
||||
int padsize = 0;
|
||||
int i;
|
||||
int sigsize = 0;
|
||||
int res;
|
||||
mp_int mpr, mps;
|
||||
mp_init(&mpr);
|
||||
mp_init(&mps);
|
||||
RNG rng;
|
||||
wc_InitRng(&rng);
|
||||
if (argc != 4 && argc!=5) {
|
||||
fprintf(stderr, "Usage: %s image key.der fw_version [padsize]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
version = atoi(argv[3]);
|
||||
if (version < 0) {
|
||||
fprintf(stderr, "%s: invalid version '%s'.\n", argv[0], argv[3]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc > 4) {
|
||||
padsize = atoi(argv[4]);
|
||||
if (padsize < 1024) {
|
||||
fprintf(stderr, "%s: invalid padding size '%s'.\n", argv[0], argv[4]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(in_name, argv[1]);
|
||||
snprintf(signed_name, PATH_MAX, "%s.v%s.signed", argv[1], argv[3]);
|
||||
|
||||
in_fd = open(in_name, O_RDONLY);
|
||||
if (in_fd < 0) {
|
||||
perror(in_name);
|
||||
exit(2);
|
||||
}
|
||||
out_fd = open(signed_name, O_WRONLY|O_CREAT|O_TRUNC, 0660);
|
||||
if (out_fd < 0) {
|
||||
perror(signed_name);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
key_fd = open(argv[2], O_RDONLY);
|
||||
if (key_fd < 0) {
|
||||
perror(argv[2]);
|
||||
exit(2);
|
||||
}
|
||||
wc_ecc_init(key);
|
||||
r = read(key_fd, inkey, 3 * ECC_KEY_SIZE);
|
||||
if (r < 0) {
|
||||
perror("read");
|
||||
exit(3);
|
||||
}
|
||||
r = wc_ecc_import_unsigned(key, inkey, inkey + ECC_KEY_SIZE, inkey + 2 * ECC_KEY_SIZE, ECC_SECP256R1);
|
||||
if (r < 0) {
|
||||
printf("Errror importing key\n");
|
||||
}
|
||||
printf("key.type = %d\n", key->type);
|
||||
close(key_fd);
|
||||
|
||||
|
||||
/* Create header */
|
||||
r = stat(in_name, &st);
|
||||
if (r < 0) {
|
||||
perror(in_name);
|
||||
exit(2);
|
||||
}
|
||||
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_InitSha256(&sha);
|
||||
wc_Sha256Update(&sha, hdr, ptr - hdr);
|
||||
while(1) {
|
||||
r = read(in_fd, shabuf, SHA256_DIGEST_SIZE);
|
||||
if (r <= 0)
|
||||
break;
|
||||
wc_Sha256Update(&sha, shabuf, r);
|
||||
if (r < 32)
|
||||
break;
|
||||
}
|
||||
wc_Sha256Final(&sha, shabuf);
|
||||
if (wc_ecc_sign_hash_ex(shabuf, SHA256_DIGEST_SIZE, &rng, key, &mpr, &mps) != MP_OKAY) {
|
||||
printf("Error signing hash\n");
|
||||
exit(1);
|
||||
}
|
||||
if (wc_ecc_verify_hash_ex(&mpr, &mps, shabuf, SHA256_DIGEST_SIZE, &res, key) != MP_OKAY) {
|
||||
printf("Error verifying hash\n");
|
||||
exit(1);
|
||||
}
|
||||
if (res == 0) {
|
||||
printf("Bad signature.\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("shabuf\n");
|
||||
print_buf(shabuf, SHA256_DIGEST_SIZE);
|
||||
mp_to_unsigned_bin(&mpr, signature);
|
||||
mp_to_unsigned_bin(&mps, signature + ECC_KEY_SIZE);
|
||||
sigsize = 2 * ECC_KEY_SIZE;
|
||||
printf("signature (%d bytes)\n", sigsize);
|
||||
print_buf(shabuf, sigsize);
|
||||
|
||||
#ifdef VERIFY_SIGNATURE_TEST
|
||||
{
|
||||
ecc_key *pubk = (ecc_key *)key_buffer;
|
||||
int ret;
|
||||
int fd;
|
||||
mp_int r, s;
|
||||
uint8_t pubk_buf[2 * ECC_KEY_SIZE];
|
||||
mp_init(&r);
|
||||
mp_init(&s);
|
||||
|
||||
mp_read_unsigned_bin(&r, signature, ECC_KEY_SIZE);
|
||||
mp_read_unsigned_bin(&s, signature + ECC_KEY_SIZE, ECC_KEY_SIZE);
|
||||
|
||||
ret = wc_ecc_init(pubk);
|
||||
if (ret < 0)
|
||||
{
|
||||
perror ("initializing ecc key");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
fd = open("ecc-pub.der", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror ("cannot verify signature: opening ecc-pub.der");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (read(fd, pubk_buf, 2 * ECC_KEY_SIZE) != (2 * ECC_KEY_SIZE)) {
|
||||
perror ("cannot verify signature: error reading ecc-pub.der");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
ret = wc_ecc_import_unsigned(pubk, pubk_buf, pubk_buf + ECC_KEY_SIZE, NULL, ECC_SECP256R1);
|
||||
if (ret != MP_OKAY) {
|
||||
perror ("importing public key");
|
||||
exit(2);
|
||||
}
|
||||
printf("pubkey.type = %d\n", pubk->type);
|
||||
ret = wc_ecc_verify_hash_ex(&r, &s, shabuf, SHA256_DIGEST_SIZE, &res, pubk);
|
||||
if (ret != MP_OKAY) {
|
||||
printf("Verify operation failed.\n");
|
||||
} else if (res == 0) {
|
||||
printf("Bad signature.\n");
|
||||
} else {
|
||||
printf("Signature verified OK \n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*(ptr++) = HDR_SHA256;
|
||||
*(ptr++) = SHA256_DIGEST_SIZE;
|
||||
memcpy(ptr, shabuf, SHA256_DIGEST_SIZE);
|
||||
ptr += SHA256_DIGEST_SIZE;
|
||||
|
||||
wc_InitSha256(&keyhash);
|
||||
wc_Sha256Update(&keyhash, inkey, 2 * ECC_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++) = ECC_SIG_SIZE;
|
||||
memcpy(ptr, signature, ECC_SIG_SIZE);
|
||||
ptr += ECC_SIG_SIZE;
|
||||
*(ptr++) = HDR_END;
|
||||
|
||||
printf("\n\n");
|
||||
print_buf(hdr, IMAGE_HEADER_SIZE);
|
||||
|
||||
/* Write header */
|
||||
write(out_fd, hdr, IMAGE_HEADER_SIZE);
|
||||
|
||||
/* Write image payload */
|
||||
lseek(in_fd, 0, SEEK_SET);
|
||||
|
||||
while(1) {
|
||||
uint8_t tmpbuf[32];
|
||||
r = read(in_fd, tmpbuf, 32);
|
||||
if (r <= 0)
|
||||
break;
|
||||
write(out_fd, tmpbuf, r);
|
||||
if (r < 32)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pad if needed */
|
||||
r = stat(signed_name, &st);
|
||||
if ((r == 0) && st.st_size < padsize) {
|
||||
size_t fill = padsize - st.st_size;
|
||||
uint8_t padbyte = 0xFF;
|
||||
out_fd = open(signed_name, O_WRONLY|O_APPEND|O_EXCL);
|
||||
if (out_fd > 0) {
|
||||
while(fill--)
|
||||
write(out_fd, &padbyte, 1);
|
||||
}
|
||||
close(out_fd);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
# Settings
|
||||
#
|
||||
CROSS_COMPILE=
|
||||
WOLFBOOT_ROOT=../../
|
||||
CFLAGS:=-lwolfssl -DHAVE_ECC_KEY_EXPORT -DHAVE_ED25519 -DHAVE_ASN -DWOLFCRYPT_ONLY -DTFM_TIMING_RESISTANT -DNO_RSA -DECC_TIMING_RESISTANT -DWOLFSSL_DER_TO_PEM -I$(WOLFBOOT_ROOT)/include -I$(WOLFBOOT_ROOT)/lib/wolfssl
|
||||
LDFLAGS:=-lwolfssl
|
||||
LDFLAGS_EXTRA=
|
||||
EXTRA_LDFLAGS=
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
LD=$(CROSS_COMPILE)gcc
|
||||
|
||||
EXT=
|
||||
|
||||
|
||||
all: binaries
|
||||
|
||||
windows: binaries
|
||||
mv ed25519_keygen ed25519_keygen.exe
|
||||
mv ed25519_sign ed25519_sign.exe
|
||||
|
||||
windows:CROSS_COMPILE=x86_64-w64-mingw32-
|
||||
windows:EXT:=.exe
|
||||
windows:WIN_OBJS+=/usr/x86_64-w64-mingw32/lib/libwolfssl-17.dll
|
||||
windows:LDFLAGS=-Wl,-Bstatic,--whole-archive $(WIN_OBJS) -lgcc -Wl,--no-whole-archive
|
||||
windows: all
|
||||
|
||||
|
||||
binaries: ed25519_keygen$(EXT) ed25519_sign$(EXT)
|
||||
|
||||
ed25519_keygen: ed25519_keygen.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
ed25519_sign: ed25519_sign.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
@rm -f ed25519_keygen ed25519_sign *.o *.exe
|
|
@ -1,167 +0,0 @@
|
|||
/*
|
||||
* ed25519_keygen.c
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
|
||||
#define PEMSIZE 1024
|
||||
#ifndef WIN32
|
||||
# define O_BINARY O_RDONLY
|
||||
#endif
|
||||
|
||||
void print_buf(uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
int p = i % 8;
|
||||
if (p == 0)
|
||||
printf("\t");
|
||||
printf("0x%02X", buf[i]);
|
||||
if (i < len - 1)
|
||||
printf(",");
|
||||
if (p == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void print_key(void *key_in)
|
||||
{
|
||||
uint8_t * key = key_in;
|
||||
print_buf(key, ED25519_KEY_SIZE);
|
||||
}
|
||||
|
||||
void create_pubkey_cfile(const char *fname, uint8_t *key_in)
|
||||
{
|
||||
char buf[4192] = { };
|
||||
char keybyte[5] = {};
|
||||
int i;
|
||||
int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0660);
|
||||
if (fd < 0) {
|
||||
perror("creating c file");
|
||||
exit(1);
|
||||
}
|
||||
strcat(buf,"/* This file is automatically generate by ed25519 keygen. DO NOT EDIT. */\n");
|
||||
strcat(buf,"#include <stdint.h>\n");
|
||||
strcat(buf,"const uint8_t ed25519_pub_key[32] = {\n");
|
||||
for (i = 0; i < ED25519_KEY_SIZE; i++) {
|
||||
int p = i % 8;
|
||||
if (p == 0)
|
||||
strcat(buf,"\t");
|
||||
snprintf(keybyte, 5, "0x%02X", key_in[i]);
|
||||
strcat(buf, keybyte);
|
||||
if (i < ED25519_KEY_SIZE - 1)
|
||||
strcat(buf, ",");
|
||||
if (p == 7)
|
||||
strcat(buf, "\n");
|
||||
else
|
||||
strcat(buf," ");
|
||||
}
|
||||
strcat(buf,"};\n");
|
||||
strcat(buf,"const uint32_t ed25519_pub_key_len = 32;\n");
|
||||
write(fd, buf, strlen(buf));
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void print_sig(void *sig_in)
|
||||
{
|
||||
uint8_t * sig = sig_in;
|
||||
print_buf(sig, ED25519_SIG_SIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint8_t priv[ED25519_KEY_SIZE], pub[ED25519_KEY_SIZE], full[2*ED25519_KEY_SIZE];
|
||||
uint8_t sig[ED25519_SIG_SIZE];
|
||||
uint32_t outlen;
|
||||
char outkey[PEMSIZE];
|
||||
int fd;
|
||||
RNG rng;
|
||||
ed25519_key key;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s cfile\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wc_ed25519_init(&key);
|
||||
wc_InitRng(&rng);
|
||||
if (wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key) != 0) {
|
||||
printf("Failed to create ED25519 key!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
outlen = ED25519_KEY_SIZE;
|
||||
wc_ed25519_export_private_only(&key, priv, &outlen);
|
||||
printf("const uint8_t ed_private_key[ED25519_KEY_SIZE] = {\n");
|
||||
print_key(priv);
|
||||
printf("};\n\n");
|
||||
|
||||
outlen = ED25519_PRV_KEY_SIZE;
|
||||
wc_ed25519_export_private(&key, full, &outlen);
|
||||
print_key(full);
|
||||
print_key(full + 32);
|
||||
|
||||
fd = open("ed25519.der", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
|
||||
if (fd < 0) {
|
||||
perror("exporting key (der)");
|
||||
}
|
||||
write(fd, full, ED25519_PRV_KEY_SIZE);
|
||||
close(fd);
|
||||
memset(outkey, 0, PEMSIZE);
|
||||
wc_DerToPem(priv, outlen, outkey, PEMSIZE, ED25519_TYPE);
|
||||
printf("%s\n", outkey);
|
||||
fd = open("ed25519.pem", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
|
||||
if (fd < 0) {
|
||||
perror("exporting key (pem)");
|
||||
}
|
||||
write(fd, outkey, strlen(outkey));
|
||||
close(fd);
|
||||
|
||||
|
||||
outlen = ED25519_KEY_SIZE;
|
||||
wc_ed25519_export_public(&key, pub, &outlen);
|
||||
printf("const uint8_t ed_public_key[ED25519_KEY_SIZE] = {\n");
|
||||
print_key(pub);
|
||||
printf("};\n\n");
|
||||
memset(outkey, 0, PEMSIZE);
|
||||
wc_DerToPem(pub, 32, outkey, PEMSIZE, PUBLICKEY_TYPE);
|
||||
printf("%s\n", outkey);
|
||||
fd = open("ed25519_pub.pem", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0660);
|
||||
if (fd < 0) {
|
||||
perror("creating key\n");
|
||||
}
|
||||
write(fd, outkey, strlen(outkey));
|
||||
close(fd);
|
||||
if (argc > 1) {
|
||||
printf("Generating .c code for public key...\n");
|
||||
create_pubkey_cfile(argv[1], pub);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
/*
|
||||
* ed25519_sign.c
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#ifndef WIN32
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define WOLFBOOT_SIGN_ED25519
|
||||
|
||||
#include "target.h"
|
||||
#include "image.h"
|
||||
#include "loader.h"
|
||||
|
||||
void print_buf(uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
int p = i % 8;
|
||||
if (p == 0)
|
||||
printf("\t");
|
||||
printf("0x%02X", buf[i]);
|
||||
if (i < len - 1)
|
||||
printf(",");
|
||||
if (p == 7)
|
||||
printf("\n");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void print_key(void *key_in)
|
||||
{
|
||||
uint8_t * key = key_in;
|
||||
print_buf(key, ED25519_KEY_SIZE);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint8_t inkey[ED25519_PRV_KEY_SIZE];
|
||||
int in_fd, key_fd, out_fd, r;
|
||||
int outlen = ED25519_SIG_SIZE;
|
||||
char in_name[PATH_MAX];
|
||||
char signed_name[PATH_MAX];
|
||||
char *dot;
|
||||
ed25519_key key;
|
||||
Sha256 sha;
|
||||
Sha256 keyhash;
|
||||
uint8_t shabuf[32];
|
||||
uint8_t signature[ED25519_SIG_SIZE];
|
||||
uint8_t *final;
|
||||
int total_size;
|
||||
uint8_t hdr[IMAGE_HEADER_SIZE];
|
||||
uint8_t *ptr = hdr;
|
||||
struct stat st;
|
||||
int version;
|
||||
int padsize = 0;
|
||||
int i;
|
||||
|
||||
if (argc != 4 && argc!=5) {
|
||||
fprintf(stderr, "Usage: %s image key.der fw_version [padsize]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
version = atoi(argv[3]);
|
||||
if (version < 0) {
|
||||
fprintf(stderr, "%s: invalid version '%s'.\n", argv[0], argv[3]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc > 4) {
|
||||
padsize = atoi(argv[4]);
|
||||
if (padsize < 1024) {
|
||||
fprintf(stderr, "%s: invalid padding size '%s'.\n", argv[0], argv[4]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(in_name, argv[1]);
|
||||
snprintf(signed_name, PATH_MAX, "%s.v%s.signed", argv[1], argv[3]);
|
||||
|
||||
in_fd = open(in_name, O_RDONLY|O_BINARY);
|
||||
if (in_fd < 0) {
|
||||
perror(in_name);
|
||||
exit(2);
|
||||
}
|
||||
out_fd = open(signed_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0660);
|
||||
if (out_fd < 0) {
|
||||
perror(signed_name);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
key_fd = open(argv[2], O_RDONLY|O_BINARY);
|
||||
if (key_fd < 0) {
|
||||
perror(argv[2]);
|
||||
exit(2);
|
||||
}
|
||||
wc_ed25519_init(&key);
|
||||
wc_InitSha256(&sha);
|
||||
|
||||
r = read(key_fd, inkey, ED25519_PRV_KEY_SIZE);
|
||||
if (r < 0) {
|
||||
perror("read");
|
||||
exit(3);
|
||||
}
|
||||
r = wc_ed25519_import_private_key(inkey, ED25519_KEY_SIZE, inkey + ED25519_KEY_SIZE, ED25519_KEY_SIZE, &key);
|
||||
if (r < 0) {
|
||||
perror("importing private key");
|
||||
}
|
||||
close(key_fd);
|
||||
|
||||
print_key(inkey);
|
||||
print_key(inkey + 32);
|
||||
|
||||
/* Create header */
|
||||
r = stat(in_name, &st);
|
||||
if (r < 0) {
|
||||
perror(in_name);
|
||||
exit(2);
|
||||
}
|
||||
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, hdr, ptr - hdr);
|
||||
while(1) {
|
||||
r = read(in_fd, shabuf, 32);
|
||||
if (r <= 0)
|
||||
break;
|
||||
wc_Sha256Update(&sha, shabuf, r);
|
||||
if (r < 32)
|
||||
break;
|
||||
}
|
||||
wc_Sha256Final(&sha, shabuf);
|
||||
wc_ed25519_sign_msg(shabuf, 32, signature, &outlen, &key);
|
||||
|
||||
|
||||
*(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);
|
||||
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 */
|
||||
if (write(out_fd, hdr, IMAGE_HEADER_SIZE) != IMAGE_HEADER_SIZE) {
|
||||
perror("write");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Write image payload */
|
||||
lseek(in_fd, 0, SEEK_SET);
|
||||
|
||||
while(1) {
|
||||
uint8_t tmpbuf[32];
|
||||
r = read(in_fd, tmpbuf, 32);
|
||||
if (r <= 0)
|
||||
break;
|
||||
write(out_fd, tmpbuf, r);
|
||||
if (r < 32)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pad if needed */
|
||||
r = stat(signed_name, &st);
|
||||
if ((r == 0) && st.st_size < padsize) {
|
||||
size_t fill = padsize - st.st_size;
|
||||
uint8_t padbyte = 0xFF;
|
||||
out_fd = open(signed_name, O_WRONLY|O_APPEND|O_EXCL|O_BINARY);
|
||||
if (out_fd > 0) {
|
||||
while(fill--)
|
||||
write(out_fd, &padbyte, 1);
|
||||
}
|
||||
close(out_fd);
|
||||
}
|
||||
close(in_fd);
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -1,4 +1,25 @@
|
|||
#!/usr/bin/python3
|
||||
'''
|
||||
* keygen.py
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
'''
|
||||
|
||||
import sys,os
|
||||
from wolfcrypt import ciphers
|
||||
|
@ -105,7 +126,7 @@ if (sign == "ecc256"):
|
|||
f.write('\n')
|
||||
f.write("0x%02X" % qy[-1])
|
||||
f.write("\n};\n")
|
||||
f.write("const uint32_t ed25519_pub_key_len = 64;\n")
|
||||
f.write("const uint32_t ecc256_pub_key_len = 64;\n")
|
||||
f.close()
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/python3
|
||||
'''
|
||||
* sign.py
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
'''
|
||||
|
||||
import sys, os, struct, time
|
||||
from wolfcrypt import ciphers, hashes
|
||||
|
||||
|
||||
WOLFBOOT_MAGIC = 0x464C4F57
|
||||
HDR_END = 0x00
|
||||
HDR_VERSION = 0x01
|
||||
HDR_TIMESTAMP = 0x02
|
||||
HDR_SHA256 = 0x03
|
||||
HDR_PUBKEY = 0x10
|
||||
HDR_SIGNATURE = 0x20
|
||||
HDR_PADDING = 0xFF
|
||||
|
||||
HDR_VERSION_LEN = 4
|
||||
HDR_TIMESTAMP_LEN = 8
|
||||
HDR_SHA256_LEN = 32
|
||||
HDR_PUBKEY_LEN = 32
|
||||
HDR_SIGNATURE_LEN = 64
|
||||
|
||||
sign="auto"
|
||||
|
||||
argc = len(sys.argv)
|
||||
argv = sys.argv
|
||||
|
||||
if (argc < 4) or (argc > 5):
|
||||
print("Usage: %s [--ed25519 | --ecc256 ] image key.der fw_version\n" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
if argc == 5:
|
||||
if argv[1] != '--ed25519' and argv[1] != '--ecc256':
|
||||
print("Usage: %s [--ed25519 | --ecc256 ] image key.der fw_version\n" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
sign=argv[1][2:]
|
||||
image_file = argv[2]
|
||||
key_file = argv[3]
|
||||
fw_version = int(argv[4])
|
||||
else:
|
||||
image_file = argv[1]
|
||||
key_file = argv[2]
|
||||
fw_version = int(argv[3])
|
||||
|
||||
if '.' in image_file:
|
||||
tokens = image_file.split('.')
|
||||
output_image_file = image_file.rstrip('.' + tokens[-1])
|
||||
output_image_file += "_v" + str(fw_version) + "_signed.bin"
|
||||
else:
|
||||
output_image_file = image_file + "_v" + str(fw_version) + "_signed.bin"
|
||||
|
||||
print ("Selected cipher: " + sign)
|
||||
print ("Private key: " + key_file)
|
||||
print ("Input image: " + image_file)
|
||||
print ("Output image: " + output_image_file)
|
||||
|
||||
|
||||
''' import (decode) private key for signing '''
|
||||
kf = open(key_file, "rb")
|
||||
wolfboot_private_key = kf.read(96)
|
||||
wolfboot_private_key_len = len(wolfboot_private_key)
|
||||
if wolfboot_private_key_len == 64:
|
||||
if (sign == 'ecc256'):
|
||||
print("Error: key size does not match the cipher selected")
|
||||
sys.exit(1)
|
||||
if sign == 'auto':
|
||||
sign = 'ed25519'
|
||||
print("'ed25519' key autodetected.")
|
||||
elif wolfboot_private_key_len == 96:
|
||||
if (sign == 'ed25519'):
|
||||
print("Error: key size does not match the cipher selected")
|
||||
sys.exit(1)
|
||||
if sign == 'auto':
|
||||
sign = 'ecc256'
|
||||
print("'ecc256' key autodetected.")
|
||||
else:
|
||||
print ("Error: key size does not match any cipher")
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if sign == 'ed25519':
|
||||
ed = ciphers.Ed25519Private(key = wolfboot_private_key)
|
||||
privkey, pubkey = ed.encode_key()
|
||||
|
||||
if sign == 'ecc256':
|
||||
ecc = ciphers.EccPrivate()
|
||||
ecc.decode_key_raw(wolfboot_private_key[0:31], wolfboot_private_key[32:63], wolfboot_private_key[64:])
|
||||
pubkey = wolfboot_private_key[0:64]
|
||||
|
||||
|
||||
img_size = os.path.getsize(image_file)
|
||||
# Magic header (spells 'WOLF')
|
||||
header = struct.pack('<L', WOLFBOOT_MAGIC)
|
||||
# Image size
|
||||
header += struct.pack('<L', img_size)
|
||||
|
||||
# Two pad bytes so version is aligned
|
||||
header += struct.pack('BB', 0xFF, 0xFF)
|
||||
|
||||
# Version field
|
||||
header += struct.pack('BB', HDR_VERSION, HDR_VERSION_LEN)
|
||||
header += struct.pack('<L', fw_version)
|
||||
|
||||
# Six pad bytes so timestamp is aligned
|
||||
header += struct.pack('BB', 0xFF, 0xFF)
|
||||
header += struct.pack('BB', 0xFF, 0xFF)
|
||||
header += struct.pack('BB', 0xFF, 0xFF)
|
||||
|
||||
# Timestamp field
|
||||
header += struct.pack('BB', HDR_TIMESTAMP, HDR_TIMESTAMP_LEN)
|
||||
header += struct.pack('<Q', int(os.path.getmtime(image_file)))
|
||||
|
||||
sha = hashes.Sha256.new()
|
||||
# Sha calculation
|
||||
sha.update(header)
|
||||
img_bin = open(image_file, 'rb')
|
||||
while True:
|
||||
buf = img_bin.read(32)
|
||||
if (len(buf) == 0):
|
||||
img_bin.close()
|
||||
break
|
||||
sha.update(buf)
|
||||
digest = sha.digest()
|
||||
|
||||
# Add SHA to the header
|
||||
header += struct.pack('BB', HDR_SHA256, HDR_SHA256_LEN)
|
||||
header += digest
|
||||
|
||||
# pubkey SHA calculation
|
||||
keysha = hashes.Sha256.new()
|
||||
keysha.update(pubkey)
|
||||
header += struct.pack('BB', HDR_PUBKEY, HDR_PUBKEY_LEN)
|
||||
key_digest = keysha.digest()
|
||||
header += key_digest
|
||||
|
||||
# Sign the digest
|
||||
print("Signing the firmware...")
|
||||
if (sign == 'ed25519'):
|
||||
signature = ed.sign(digest)
|
||||
else:
|
||||
r, s = ecc.sign_raw(digest)
|
||||
signature = r + s
|
||||
header += struct.pack('BB', HDR_SIGNATURE, HDR_SIGNATURE_LEN)
|
||||
header += signature
|
||||
print ("Done.")
|
||||
|
||||
# Create output image. Add padded header in front
|
||||
outfile = open(output_image_file, 'wb')
|
||||
outfile.write(header)
|
||||
sz = len(header)
|
||||
while sz < 256:
|
||||
outfile.write(struct.pack('B',0xFF))
|
||||
sz += 1
|
||||
infile = open(image_file, 'rb')
|
||||
while True:
|
||||
buf = infile.read(1024)
|
||||
if len(buf) == 0:
|
||||
break
|
||||
outfile.write(buf)
|
||||
|
||||
infile.close()
|
||||
outfile.close()
|
||||
print ("Output image successfully created.")
|
||||
sys.exit(0)
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
/* Public-key file for wolfBoot, automatically generated. Do not edit. */
|
||||
/*
|
||||
* This file has been generated and contains the public key which is
|
||||
* used by wolfBoot to verify the updates.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t ed25519_pub_key[32] = {
|
||||
0xB3, 0xAE, 0xD5, 0xEC, 0x20, 0xB0, 0x59, 0x99,
|
||||
0x2C, 0x0D, 0x76, 0x67, 0xA7, 0x29, 0x0A, 0x6D,
|
||||
0x34, 0xD0, 0xDA, 0xBC, 0x7B, 0xDB, 0x2C, 0x6D,
|
||||
0x2F, 0x2A, 0xD5, 0xAE, 0xE1, 0x41, 0x02, 0x46
|
||||
};
|
||||
const uint32_t ed25519_pub_key_len = 32;
|
|
@ -2,6 +2,17 @@ TEST_UPDATE_VERSION?=2
|
|||
EXPVER=tools/test-expect-version/test-expect-version
|
||||
SPI_CHIP=SST25VF080B
|
||||
|
||||
SIGN_TOOL=/bin/false
|
||||
|
||||
ifeq ($(SIGN),ED25519)
|
||||
SIGN_TOOL=tools/keytools/sign.py --ed25519
|
||||
endif
|
||||
|
||||
ifeq ($(SIGN),ECC256)
|
||||
SIGN_TOOL=tools/keytools/sign.py --ecc256
|
||||
endif
|
||||
|
||||
|
||||
$(EXPVER):
|
||||
make -C tools/test-expect-version
|
||||
|
||||
|
@ -31,8 +42,9 @@ test-spi-off: FORCE
|
|||
|
||||
|
||||
test-update: test-app/image.bin FORCE
|
||||
@$(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION) 131072 >/dev/null
|
||||
@dd if=test-app/image.bin.v$(TEST_UPDATE_VERSION).signed of=test-update.bin bs=1 count=131067
|
||||
@dd if=/dev/zero bs=131067 count=1 2>/dev/null | tr "\000" "\377" > test-update.bin
|
||||
@$(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
|
||||
@dd if=test-app/image_v$(TEST_UPDATE_VERSION)_signed.bin of=test-update.bin bs=1 conv=notrunc
|
||||
@printf "pBOOT" >> test-update.bin
|
||||
@make test-reset
|
||||
@sleep 2
|
||||
|
@ -41,9 +53,9 @@ test-update: test-app/image.bin FORCE
|
|||
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000)
|
||||
|
||||
test-update-ext: test-app/image.bin FORCE
|
||||
@$(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION) 524288 >/dev/null
|
||||
@$(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
|
||||
@$$(dd if=/dev/zero bs=1M count=1 | tr '\000' '\377' > test-update.rom)
|
||||
@dd if=test-app/image.bin.v$(TEST_UPDATE_VERSION).signed of=test-update.rom bs=1 count=524283 conv=notrunc
|
||||
@dd if=test-app/image_v$(TEST_UPDATE_VERSION)_signed.bin of=test-update.rom bs=1 count=524283 conv=notrunc
|
||||
@printf "pBOOT" | dd of=test-update.rom obs=1 seek=524283 count=5 conv=notrunc
|
||||
@make test-spi-on
|
||||
flashrom -c $(SPI_CHIP) -p linux_spi:dev=/dev/spidev0.0 -w test-update.rom
|
||||
|
|
Loading…
Reference in New Issue