mirror of https://github.com/wolfSSL/wolfBoot.git
Ecc256 signature verification with sp-math support, work in progress
parent
f4f65ae31d
commit
41c60f4bd2
|
@ -49,6 +49,13 @@
|
|||
|
||||
# automatically generated source files
|
||||
src/ed25519_pub_key.c
|
||||
src/ecc256_pub_key.c
|
||||
|
||||
# keygen binaries
|
||||
tools/ed25519/ed25519_sign
|
||||
tools/ed25519/ed25519_keygen
|
||||
tools/ecc256/ecc256_sign
|
||||
tools/ecc256/ecc256_keygen
|
||||
|
||||
# Vim swap files
|
||||
.*.swp
|
||||
|
|
71
Makefile
71
Makefile
|
@ -1,12 +1,13 @@
|
|||
CROSS_COMPILE:=arm-none-eabi-
|
||||
CC:=$(CROSS_COMPILE)gcc
|
||||
LD:=$(CROSS_COMPILE)gcc
|
||||
AS:=$(CROSS_COMPILE)gcc
|
||||
|
||||
|
||||
OBJCOPY:=$(CROSS_COMPILE)objcopy
|
||||
SIZE:=$(CROSS_COMPILE)size
|
||||
BOOT_IMG?=test-app/image.bin
|
||||
BOOT0_OFFSET?=0x20000
|
||||
BOOT0_OFFSET?=0x10000
|
||||
SIGN?=ED25519
|
||||
TARGET?=stm32f4
|
||||
DEBUG?=0
|
||||
|
@ -19,7 +20,7 @@ LSCRIPT:=hal/$(TARGET).ld
|
|||
OBJS:= \
|
||||
./hal/$(TARGET).o \
|
||||
./src/loader.o \
|
||||
./src/mem.o \
|
||||
./src/string.o \
|
||||
./src/crypto.o \
|
||||
./src/wolfboot.o \
|
||||
./src/image.o \
|
||||
|
@ -29,20 +30,42 @@ OBJS:= \
|
|||
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
|
||||
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o
|
||||
|
||||
|
||||
ifeq ($(TARGET),samr21)
|
||||
CORTEX_M0=1
|
||||
endif
|
||||
|
||||
ifeq ($(SIGN),ECC256)
|
||||
KEYGEN_TOOL=tools/ecc256/ecc256_keygen
|
||||
SIGN_TOOL=tools/ecc256/ecc256_sign
|
||||
PRIVATE_KEY=ecc256.der
|
||||
else
|
||||
KEYGEN_TOOL=tools/ed25519/ed25519_keygen
|
||||
SIGN_TOOL=tools/ed25519/ed25519_sign
|
||||
PRIVATE_KEY=ed25519.der
|
||||
endif
|
||||
|
||||
MATH_OBJS:=./lib/wolfssl/wolfcrypt/src/sp_int.o
|
||||
|
||||
|
||||
|
||||
ifeq ($(CORTEX_M0),1)
|
||||
CFLAGS:=-mcpu=cortex-m0
|
||||
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
|
||||
else
|
||||
CFLAGS:=-mcpu=cortex-m3
|
||||
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
|
||||
endif
|
||||
|
||||
ifeq ($(FASTMATH),1)
|
||||
MATH_OBJS:=./lib/wolfssl/wolfcrypt/src/integer.o
|
||||
CFLAGS+=-DUSE_FAST_MATH
|
||||
endif
|
||||
|
||||
CFLAGS+=-mthumb -Wall -Wextra -Wno-main -Wstack-usage=1024 -ffreestanding -Wno-unused \
|
||||
-Ilib/bootutil/include -Iinclude/ -Ilib/wolfssl -nostartfiles \
|
||||
-nostdlib \
|
||||
-DWOLFSSL_USER_SETTINGS \
|
||||
-mthumb -mlittle-endian -mthumb-interwork \
|
||||
-DPLATFORM_$(TARGET)
|
||||
|
||||
ifeq ($(SIGN),ED25519)
|
||||
|
@ -50,12 +73,20 @@ ifeq ($(SIGN),ED25519)
|
|||
./lib/wolfssl/wolfcrypt/src/ed25519.o \
|
||||
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
|
||||
./src/ed25519_pub_key.o
|
||||
CFLAGS+=-DWOLFBOOT_SIGN_ED25519
|
||||
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY
|
||||
LDFLAGS+=-nostdlib
|
||||
endif
|
||||
|
||||
ifeq ($(SIGN),EC256)
|
||||
OBJS+= ./ext/wolfssl/wolfcrypt/src/ecc.o
|
||||
CFLAGS+=-DWOLFBOOT_SIGN_EC256
|
||||
ifeq ($(SIGN),ECC256)
|
||||
OBJS+= \
|
||||
$(MATH_OBJS) \
|
||||
./lib/wolfssl/wolfcrypt/src/ecc.o \
|
||||
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
|
||||
./lib/wolfssl/wolfcrypt/src/memory.o \
|
||||
./lib/wolfssl/wolfcrypt/src/wc_port.o \
|
||||
./src/ecc256_pub_key.o \
|
||||
./src/xmalloc.o
|
||||
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
|
@ -68,7 +99,9 @@ ifeq ($(VTOR),0)
|
|||
CFLAGS+=-DNO_VTOR
|
||||
endif
|
||||
|
||||
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles -mcpu=cortex-m3 -mthumb -nostdlib
|
||||
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles -mcpu=cortex-m3 -mthumb
|
||||
|
||||
ASFLAGS:=$(CFLAGS)
|
||||
|
||||
all: factory.bin
|
||||
|
||||
|
@ -92,16 +125,22 @@ test-app/image.bin:
|
|||
tools/ed25519/ed25519_sign:
|
||||
make -C tools/ed25519
|
||||
|
||||
tools/ecc256/ecc256_sign:
|
||||
make -C tools/ecc256
|
||||
|
||||
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
|
||||
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)
|
||||
$(SIGN_TOOL) $(BOOT_IMG) $(PRIVATE_KEY) 1
|
||||
cat wolfboot-align.bin $(BOOT_IMG).v1.signed > $@
|
||||
|
||||
second.img: $(BOOT_IMG) wolfboot-align.bin tools/ed25519/ed25519_sign ed25519.der
|
||||
tools/ed25519/ed25519_sign $(BOOT_IMG) ed25519.der 1 65536
|
||||
tools/ed25519/ed25519_sign $(BOOT_IMG) ed25519.der 2
|
||||
second.img: $(BOOT_IMG) wolfboot-align.bin $(SIGN_TOOL) $(PRIVATE_KEY)
|
||||
$(SIGN_TOOL) $(BOOT_IMG) $(PRIVATE_KEY) 1 65536
|
||||
$(SIGN_TOOL) $(BOOT_IMG) $(PRIVATE_KEY) 2
|
||||
cat wolfboot-align.bin $(BOOT_IMG).v1.signed $(BOOT_IMG).v2.signed > $@
|
||||
|
||||
wolfboot.elf: $(OBJS) $(LSCRIPT)
|
||||
|
@ -110,8 +149,9 @@ wolfboot.elf: $(OBJS) $(LSCRIPT)
|
|||
|
||||
src/ed25519_pub_key.c: ed25519.der
|
||||
|
||||
keys: ed25519.der
|
||||
src/ecc256_pub_key.c: ecc256.der
|
||||
|
||||
keys: $(PRIVATE_KEY)
|
||||
|
||||
clean:
|
||||
rm -f *.bin *.elf $(OBJS) wolfboot.map *.bin *.hex
|
||||
|
@ -119,5 +159,6 @@ clean:
|
|||
|
||||
distclean: clean
|
||||
make -C tools/ed25519 clean
|
||||
rm -f *.pem *.der tags ./src/ed25519_pub_key.c
|
||||
make -C tools/ecc256 clean
|
||||
rm -f *.pem *.der tags ./src/ed25519_pub_key.c ./src/ecc256_pub_key.c
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#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)
|
||||
#if 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)
|
||||
#elif defined(WOLFBOOT_SIGN_ECC256)
|
||||
extern const unsigned char ecc256_pub_key[];
|
||||
extern unsigned int ecc256_pub_key_len;
|
||||
# define KEY_BUFFER ecc256_pub_key
|
||||
# define KEY_LEN ecc256_pub_key_len
|
||||
# define IMAGE_SIGNATURE_SIZE (64)
|
||||
#else
|
||||
# error "No public key available for given signing algorithm."
|
||||
#endif /* Algorithm selection */
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
* Ensure that your firmware entry point is
|
||||
* at FLASH_AREA_IMAGE_0_OFFSET + 0x100
|
||||
*/
|
||||
#define WOLFBOOT_SECTOR_SIZE 0x20000
|
||||
#define WOLFBOOT_PARTITION_SIZE 0x20000
|
||||
#define WOLFBOOT_SECTOR_SIZE 0x1000
|
||||
#define WOLFBOOT_PARTITION_SIZE 0x10000
|
||||
|
||||
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20000
|
||||
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x40000
|
||||
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x60000
|
||||
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x10000
|
||||
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x20000
|
||||
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x30000
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
#define NO_DEV_RANDOM
|
||||
#define NO_FILESYSTEM
|
||||
#define NO_MAIN_DRIVER
|
||||
#define NO_SIG_WRAPPER
|
||||
#define NO_OLD_RNGNAME
|
||||
#define WOLFSSL_STATIC_MEMORY
|
||||
|
||||
//#define WOLFSSL_SMALL_STACK
|
||||
#define USE_SLOW_SHA512
|
||||
|
||||
|
@ -21,7 +20,6 @@
|
|||
# define NO_CERT
|
||||
# define NO_SESSION_CACHE
|
||||
# define NO_HC128
|
||||
# define NO_ASN
|
||||
# define NO_DES3
|
||||
# define NO_WOLFSSL_DIR
|
||||
# define NO_PWDBASED
|
||||
|
@ -32,24 +30,44 @@
|
|||
|
||||
#define SMALL_SESSION_CACHE
|
||||
#define WOLFSSL_DH_CONST
|
||||
#define WORD64_AVAILABLE
|
||||
#define TFM_TIMING_RESISTANT
|
||||
//#define USE_CERT_BUFFERS_2048
|
||||
#define NO_RC4
|
||||
#define WOLFCRYPT_ONLY
|
||||
#define WOLFSSL_NO_SOCK
|
||||
|
||||
# define WC_NO_RNG
|
||||
|
||||
#ifdef WOLFBOOT_SIGN_ED25519
|
||||
# define HAVE_ED25519
|
||||
# define ED25519_SMALL
|
||||
# define NO_ED25519_SIGN
|
||||
# define NO_ED25519_EXPORT
|
||||
# define USE_FAST_MATH
|
||||
# define WOLFSSL_SHA512
|
||||
# define NO_ASN
|
||||
#endif
|
||||
|
||||
#ifdef WOLFBOOT_SIGN_ECC256
|
||||
# define HAVE_ECC
|
||||
# define FP_ECC
|
||||
# define HAVE_ECC_VERIFY
|
||||
# define ECC_ALT_SIZE
|
||||
# define NO_ECC_SIGN
|
||||
# define NO_ECC_EXPORT
|
||||
# define USE_FAST_MATH
|
||||
# define WOLFSSL_SHA512
|
||||
# define WOLFSSL_SP_SMALL
|
||||
# define SP_WORD_SIZE 32
|
||||
# define WOLFSSL_HAVE_SP_ECC
|
||||
# define WOLFSSL_SP_MATH
|
||||
# define NO_ASN
|
||||
//# define NO_ECC_SIGN
|
||||
# define NO_ECC_DHE
|
||||
# define NO_ECC_KEY_EXPORT
|
||||
#endif
|
||||
|
||||
/* AES */
|
||||
# define NO_AES
|
||||
# define NO_CMAC
|
||||
# define NO_CODING
|
||||
# define WOLFSSL_SHA512
|
||||
# define NO_BIG_INT
|
||||
# define NO_RSA
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 4995051081b65e804594c6e45a54a3b10d6598ac
|
||||
Subproject commit a506c6591dad47036508d55315d09bc13b799a1f
|
34
src/image.c
34
src/image.c
|
@ -48,6 +48,40 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFBOOT_SIGN_ECC256
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#define ECC_KEY_SIZE 32
|
||||
#define ECC_SIG_SIZE 64
|
||||
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
||||
{
|
||||
int ret, res;
|
||||
mp_int r, s;
|
||||
ecc_key ecc;
|
||||
ret = wc_ecc_init(&ecc);
|
||||
if (ret < 0) {
|
||||
/* Failed to initialize key */
|
||||
return -1;
|
||||
}
|
||||
/* Import public key */
|
||||
ret = wc_ecc_import_unsigned(&ecc, KEY_BUFFER, KEY_BUFFER + 32, NULL, ECC_SECP256R1);
|
||||
if ((ret < 0) || ecc.type != ECC_PUBLICKEY) {
|
||||
/* Failed to import ecc key */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Import signature into r,s */
|
||||
mp_init(&r);
|
||||
mp_init(&s);
|
||||
mp_read_unsigned_bin(&r, sig, ECC_KEY_SIZE);
|
||||
mp_read_unsigned_bin(&s, sig + ECC_KEY_SIZE, ECC_KEY_SIZE);
|
||||
ret = wc_ecc_verify_hash_ex(&r, &s, hash, SHA256_DIGEST_SIZE, &res, &ecc);
|
||||
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)
|
||||
{
|
||||
|
|
76
src/mem.c
76
src/mem.c
|
@ -1,76 +0,0 @@
|
|||
/* mem.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 <stddef.h>
|
||||
|
||||
void * memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *d = (unsigned char *)s;
|
||||
|
||||
while (n--) {
|
||||
*d++ = (unsigned char)c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
const char *s = (const char *)src;
|
||||
char *d = (char *)dst;
|
||||
for (i = 0; i < n; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
int memcmp(const void *_s1, const void *_s2, size_t n)
|
||||
{
|
||||
int diff = 0;
|
||||
const unsigned char *s1 = (const unsigned char *)_s1;
|
||||
const unsigned char *s2 = (const unsigned char *)_s2;
|
||||
while(!diff && n)
|
||||
{
|
||||
diff = (int)*s1 - (int)*s2;
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
if (dst == src)
|
||||
return dst;
|
||||
if (src < dst) {
|
||||
const char *s = (const char *)src;
|
||||
char *d = (char *)dst;
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
return dst;
|
||||
} else {
|
||||
return memcpy(dst, src, n);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *d = (unsigned char *)s;
|
||||
|
||||
while (n--) {
|
||||
*d++ = (unsigned char)c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
char *strcat(char *dest, const char *src)
|
||||
{
|
||||
int i = 0;
|
||||
int j = strlen(dest);
|
||||
|
||||
for (i = 0; i < strlen(src); i++) {
|
||||
dest[j++] = src[i];
|
||||
}
|
||||
dest[j] = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
int diff = 0;
|
||||
|
||||
while (!diff && *s1) {
|
||||
diff = (int)*s1 - (int)*s2;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
int strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
int diff = 0;
|
||||
|
||||
while (!diff && *s1) {
|
||||
diff = (int)*s1 - (int)*s2;
|
||||
|
||||
if ((diff == 'A' - 'a') || (diff == 'a' - 'A'))
|
||||
diff = 0;
|
||||
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
int strncasecmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int diff = 0;
|
||||
int i = 0;
|
||||
|
||||
while (!diff && *s1) {
|
||||
diff = (int)*s1 - (int)*s2;
|
||||
|
||||
if ((diff == 'A' - 'a') || (diff == 'a' - 'A'))
|
||||
diff = 0;
|
||||
|
||||
s1++;
|
||||
s2++;
|
||||
if (++i > n)
|
||||
break;
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (s[i] != 0)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
char *strncat(char *dest, const char *src, size_t n)
|
||||
{
|
||||
int i = 0;
|
||||
int j = strlen(dest);
|
||||
|
||||
for (i = 0; i < strlen(src); i++) {
|
||||
if (j >= (n - 1)) {
|
||||
break;
|
||||
}
|
||||
dest[j++] = src[i];
|
||||
}
|
||||
dest[j] = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int diff = 0;
|
||||
|
||||
while (n > 0) {
|
||||
diff = (unsigned char)*s1 - (unsigned char)*s2;
|
||||
if (diff || !*s1)
|
||||
break;
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
const char *s = (const char *)src;
|
||||
char *d = (char *)dst;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *strncpy(char *dst, const char *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
dst[i] = src[i];
|
||||
if (src[i] == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while(1 < 2) {
|
||||
dst[i] = src[i];
|
||||
if (src[i] == '\0')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int memcmp(const void *_s1, const void *_s2, size_t n)
|
||||
{
|
||||
int diff = 0;
|
||||
const unsigned char *s1 = (const unsigned char *)_s1;
|
||||
const unsigned char *s2 = (const unsigned char *)_s2;
|
||||
|
||||
while (!diff && n) {
|
||||
diff = (int)*s1 - (int)*s2;
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
if (dst == src)
|
||||
return dst;
|
||||
if (src < dst) {
|
||||
const char *s = (const char *)src;
|
||||
char *d = (char *)dst;
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
return dst;
|
||||
} else {
|
||||
return memcpy(dst, src, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Allow one single sp_point to be allocated at one time */
|
||||
|
||||
#define SP_POINT_SIZE (244)
|
||||
#define MAX_POINTS 2
|
||||
|
||||
#define SCRATCHBOARD_SIZE (640)
|
||||
static uint8_t sp_scratchboard[SCRATCHBOARD_SIZE];
|
||||
static int sp_scratchboard_in_use = 0;
|
||||
|
||||
static uint8_t sp_point_buffer0[SP_POINT_SIZE];
|
||||
static uint8_t sp_point_buffer1[SP_POINT_SIZE];
|
||||
|
||||
static int point_0_in_use = 0;
|
||||
static int point_1_in_use = 0;
|
||||
|
||||
static void* xmalloc_sp_point(void)
|
||||
{
|
||||
if (point_0_in_use) {
|
||||
if (point_1_in_use)
|
||||
return NULL;
|
||||
point_1_in_use++;
|
||||
return sp_point_buffer1;
|
||||
}
|
||||
point_0_in_use++;
|
||||
return sp_point_buffer0;
|
||||
}
|
||||
|
||||
static void* xmalloc_sp_scratchboard(void)
|
||||
{
|
||||
if (sp_scratchboard_in_use)
|
||||
return NULL;
|
||||
sp_scratchboard_in_use++;
|
||||
return sp_scratchboard;
|
||||
}
|
||||
|
||||
void* XMALLOC(size_t n, void* heap, int type)
|
||||
{
|
||||
if (n == SP_POINT_SIZE)
|
||||
return xmalloc_sp_point();
|
||||
if (n == SCRATCHBOARD_SIZE)
|
||||
return xmalloc_sp_scratchboard();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void XFREE(void *ptr)
|
||||
{
|
||||
if (ptr == sp_point_buffer0)
|
||||
point_0_in_use = 0;
|
||||
if (ptr == sp_point_buffer1)
|
||||
point_1_in_use = 0;
|
||||
if (ptr == sp_scratchboard)
|
||||
sp_scratchboard_in_use = 0;
|
||||
}
|
|
@ -77,3 +77,20 @@ void main(void)
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef PLATFORM_samr21
|
||||
void main(void) {
|
||||
asm volatile ("cpsie i");
|
||||
while(1)
|
||||
WFI();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_lm3s
|
||||
void main(void) {
|
||||
asm volatile ("cpsie i");
|
||||
while(1)
|
||||
WFI();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# 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 -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
|
|
@ -0,0 +1,151 @@
|
|||
/* 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue