diff --git a/Makefile b/Makefile index 7d329a42..52178ee2 100644 --- a/Makefile +++ b/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 diff --git a/test-app/Makefile b/test-app/Makefile index de93724e..27c8ef14 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -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 diff --git a/tools/ecc256/Makefile b/tools/ecc256/Makefile deleted file mode 100644 index b9e6f8ac..00000000 --- a/tools/ecc256/Makefile +++ /dev/null @@ -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 diff --git a/tools/ecc256/ecc256_keygen.c b/tools/ecc256/ecc256_keygen.c deleted file mode 100644 index ff91f804..00000000 --- a/tools/ecc256/ecc256_keygen.c +++ /dev/null @@ -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 -#include -#include -#include - -#include -#include -#include -#include - -#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 \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; -} - diff --git a/tools/ecc256/ecc256_sign.c b/tools/ecc256/ecc256_sign.c deleted file mode 100644 index 075e115f..00000000 --- a/tools/ecc256/ecc256_sign.c +++ /dev/null @@ -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 -#include - -#include -#include -#include -#include -#include -#include - -#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); -} - diff --git a/tools/ed25519/Makefile b/tools/ed25519/Makefile deleted file mode 100644 index 54804f05..00000000 --- a/tools/ed25519/Makefile +++ /dev/null @@ -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 diff --git a/tools/ed25519/ed25519_keygen.c b/tools/ed25519/ed25519_keygen.c deleted file mode 100644 index 3f69f8b6..00000000 --- a/tools/ed25519/ed25519_keygen.c +++ /dev/null @@ -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 -#include - -#include -#include -#include - -#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 \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); -} - diff --git a/tools/ed25519/ed25519_sign.c b/tools/ed25519/ed25519_sign.c deleted file mode 100644 index d3680ec5..00000000 --- a/tools/ed25519/ed25519_sign.c +++ /dev/null @@ -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 -#include -#include -#ifndef WIN32 -# define O_BINARY 0 -#endif - -#include -#include -#include -#include -#include - -#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); -} - diff --git a/tools/keytools/keygen.py b/tools/keytools/keygen.py index 9d6596f5..f143b9e6 100755 --- a/tools/keytools/keygen.py +++ b/tools/keytools/keygen.py @@ -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() diff --git a/tools/keytools/sign.py b/tools/keytools/sign.py new file mode 100755 index 00000000..71d83ba7 --- /dev/null +++ b/tools/keytools/sign.py @@ -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(' - -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; diff --git a/tools/test.mk b/tools/test.mk index e2c72281..794bacff 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -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