Merge pull request #212 from danielinux/keystore

Support array of public keys for authentication
pull/220/head
David Garske 2022-07-19 08:56:33 -07:00 committed by GitHub
commit d42820a0c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1240 additions and 672 deletions

View File

@ -24,7 +24,7 @@ jobs:
- name: make clean
run: |
make clean && make -C tools/keytools clean && rm -f include/target.h
make keysclean && make -C tools/keytools clean && rm -f include/target.h
- name: Install wolfSSL
run: |

View File

@ -32,7 +32,7 @@ jobs:
- name: make clean
run: |
make clean && make -C tools/keytools clean && rm -f include/target.h
make keysclean && make -C tools/keytools clean && rm -f include/target.h
- name: Select config
run: |
@ -48,7 +48,7 @@ jobs:
# SIGN=NONE TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -68,7 +68,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -88,7 +88,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -108,7 +108,7 @@ jobs:
# ED25519 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -128,7 +128,7 @@ jobs:
# ED448 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -148,7 +148,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -168,7 +168,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -188,7 +188,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && make clean && rm -f include/target.h
- name: Select config
run: |
@ -216,7 +216,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -236,7 +236,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -256,7 +256,7 @@ jobs:
# ED25519 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -276,7 +276,7 @@ jobs:
# ED448 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -296,7 +296,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -316,7 +316,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -336,7 +336,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -364,7 +364,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -384,7 +384,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -404,7 +404,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -424,7 +424,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -444,7 +444,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -472,7 +472,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -492,7 +492,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -512,7 +512,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -532,7 +532,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -552,7 +552,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -580,7 +580,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -600,7 +600,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -620,7 +620,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -640,7 +640,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -660,7 +660,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |

View File

@ -32,7 +32,7 @@ jobs:
- name: make clean
run: |
make clean && make -C tools/keytools clean && rm -f include/target.h
make keysclean && make -C tools/keytools clean && rm -f include/target.h
- name: Select config
run: |
@ -48,7 +48,7 @@ jobs:
# SIGN=NONE TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -69,7 +69,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -89,7 +89,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -109,7 +109,7 @@ jobs:
# ED25519 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -129,7 +129,7 @@ jobs:
# ED448 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -149,7 +149,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -169,7 +169,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -189,7 +189,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -216,7 +216,7 @@ jobs:
# SIGN=NONE TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -236,7 +236,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -256,7 +256,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -276,7 +276,7 @@ jobs:
# ED25519 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -296,7 +296,7 @@ jobs:
# ED448 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -316,7 +316,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -336,7 +336,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -356,7 +356,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |

View File

@ -32,7 +32,7 @@ jobs:
- name: make clean
run: |
make clean && make -C tools/keytools clean && rm -f include/target.h
make keysclean && make -C tools/keytools clean && rm -f include/target.h
- name: Select config
run: |
@ -45,7 +45,7 @@ jobs:
# SIGN=NONE TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -66,7 +66,7 @@ jobs:
# ECC256 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -86,7 +86,7 @@ jobs:
# ECC384 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -106,7 +106,7 @@ jobs:
# ED25519 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -126,7 +126,7 @@ jobs:
# ED448 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -146,7 +146,7 @@ jobs:
# RSA2048 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -166,7 +166,7 @@ jobs:
# RSA3072 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |
@ -186,7 +186,7 @@ jobs:
# RSA4096 TEST
- name: make clean
run: |
make clean && rm -f include/target.h
make keysclean && rm -f include/target.h
- name: Select config
run: |

1
.gitignore vendored
View File

@ -52,6 +52,7 @@
*.sig
# automatically generated source files
src/keystore.c
src/ed25519_pub_key.c
src/ed448_pub_key.c
src/ecc256_pub_key.c

View File

@ -16,13 +16,27 @@ LDFLAGS:=
LD_START_GROUP:=-Wl,--start-group
LD_END_GROUP:=-Wl,--end-group
V?=0
OBJS:= \
./hal/$(TARGET).o \
./src/string.o \
./src/image.o \
./src/libwolfboot.o
./hal/$(TARGET).o \
./src/string.o \
./src/image.o \
./src/libwolfboot.o
ifeq ($(SIGN),NONE)
PRIVATE_KEY=
else
PRIVATE_KEY=wolfboot_signing_private_key.der
OBJS+=./src/keystore.o
endif
WOLFCRYPT_OBJS:=
PUBLIC_KEY_OBJS:=
ifneq ("$(NO_LOADER)","1")
@ -126,9 +140,10 @@ keytools_check:
"Run 'make keytools' or install wolfcrypt 'pip3 install wolfcrypt'" && false)
%.der:
$(PRIVATE_KEY):
$(Q)$(MAKE) keytools_check
$(Q)$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/$(@:.der=)_pub_key.c
$(Q)(test $(SIGN) = NONE) || ($(KEYGEN_TOOL) $(KEYGEN_OPTIONS) -g $(PRIVATE_KEY)) || true
$(Q)(test $(SIGN) = NONE) && (echo "// SIGN=NONE" > src/keystore.c) || true
keytools:
@make -C tools/keytools clean
@ -136,7 +151,8 @@ keytools:
test-app/image_v1_signed.bin: $(BOOT_IMG)
@echo "\t[SIGN] $(BOOT_IMG)"
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
$(Q)(test $(SIGN) = NONE) || $(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
$(Q)(test $(SIGN) = NONE) && $(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG) 1 || true
test-app/image.elf: wolfboot.elf
$(Q)$(MAKE) -C test-app WOLFBOOT_ROOT=$(WOLFBOOT_ROOT) image.elf
@ -155,6 +171,7 @@ factory.bin: $(BOOT_IMG) wolfboot.bin $(PRIVATE_KEY) test-app/image_v1_signed.bi
$(WOLFBOOT_PARTITION_BOOT_ADDRESS) test-app/image_v1_signed.bin
wolfboot.elf: include/target.h $(OBJS) $(LSCRIPT) FORCE
$(Q)(test $(SIGN) = NONE) || (grep $(SIGN) src/keystore.c) || (echo "Key mismatch: please run 'make distclean' to remove all keys if you want to change algorithm" && false)
@echo "\t[LD] $@"
@echo $(OBJS)
$(Q)$(LD) $(LDFLAGS) $(LD_START_GROUP) $(OBJS) $(LD_END_GROUP) -o $@
@ -171,21 +188,7 @@ hex: wolfboot.hex
@echo "\t[ELF2HEX] $@"
@$(OBJCOPY) -O ihex $^ $@
src/ed25519_pub_key.c: ed25519.der
src/ed448_pub_key.c: ed448.der
src/ecc256_pub_key.c: ecc256.der
src/ecc384_pub_key.c: ecc384.der
src/ecc521_pub_key.c: ecc521.der
src/rsa2048_pub_key.c: rsa2048.der
src/rsa3072_pub_key.c: rsa3072.der
src/rsa4096_pub_key.c: rsa4096.der
src/keystore.c: $(PRIVATE_KEY)
keys: $(PRIVATE_KEY)
@ -195,8 +198,7 @@ clean:
@make -C test-app clean
@make -C tools/check_config clean
distclean: clean
@rm -f *.pem *.der tags ./src/*_pub_key.c include/target.h
utilsclean: clean
$(Q)$(MAKE) -C tools/keytools clean
$(Q)$(MAKE) -C tools/delta clean
$(Q)$(MAKE) -C tools/bin-assemble clean
@ -206,6 +208,14 @@ distclean: clean
$(Q)$(MAKE) -C tools/uart-flash-server clean
$(Q)$(MAKE) -C tools/unit-tests clean
keysclean: clean
@rm -f *.pem *.der tags ./src/*_pub_key.c ./src/keystore.c include/target.h
distclean: clean keysclean utilsclean
include/target.h: include/target.h.in FORCE
@cat include/target.h.in | \
sed -e "s/##WOLFBOOT_PARTITION_SIZE##/$(WOLFBOOT_PARTITION_SIZE)/g" | \

178
docs/keystore.md 100644
View File

@ -0,0 +1,178 @@
# KeyStore structure: support for multiple public keys
## What is wolfBoot KeyStore
KeyStore is the mechanism used by wolfBoot to store all the public keys used for
authenticating the signature of current firmware and updates.
wolfBoot's key generation tool can be used to generate one or more keys. By default,
when running `make` for the first time, a single key `wolfboot_signing_private_key.der`
is created, and added to the keystore module. This key should be used to sign any firmware
running on the target, as well as firmware update binaries.
Additionally, the `keygen` tool creates additional files with different representations
of the keystore
- A .c file (src/keystore.c) which can be used to deploy public keys as part
of the bootloader itself, by linking the keystore in `wolfboot.elf`
- A .bin file (keystore.bin) which contains the keystore that can be hosted
on a custom memory support. In order to access the keystore, a small driver is
required (see section "Interface API" below).
## Default usage (built-in keystore)
By default, the keystore object in `src/keystore.c` is accessed by wolfboot by including
its symbols in the build.
Once generated, this file contains an array of structures describing each public
key that will be available to wolfBoot on the target system. Additionally, there are a few
functions that connect to the wolfBoot keystore API to access the details and the
content of the public key slots.
The public key is described by the following structure:
```
struct keystore_slot {
uint32_t slot_id;
uint32_t key_type;
uint32_t part_id_mask;
uint32_t pubkey_size;
uint8_t pubkey[KEYSTORE_PUBKEY_SIZE];
};
```
- `slot_id` is the incremental identifier for the key slot, starting from 0.
- `key_type` describes the algorithm of the key, e.g. `AUTH_KEY_ECC256` or `AUTH_KEY_RSA3072`
- `mask` describes the permissions for the key. It's a bitmap of the partition ids for which this key can be used for verification
- `pubkey_size` the size of the public key buffer
- `pubkey` the actual buffer containing the public key in its raw format
When booting, wolfBoot will automatically select the public key associated to the signed firmware image, check that it matches the permission mask for the partition id where the verification is running and then attempts to authenticate the signature of the image using the selected public key slot.
### Creating multiple keys
`keygen` accepts multiple filenames for private keys.
Two arguments:
- `-g priv.der` generate new keypair, store the private key in priv.der, add the public key to the keystore
- `-i pub.der` import an existing public key and add it to the keystore
Example of creation of a keystore with two ED25519 keys:
`./tools/keytools/keygen.py --ed25519 -g first.der -g second.der`
will create the following files:
- `first.der` first private key
- `second.der` second private key
- `src/keystore.c` C keystore containing both public keys associated with `first.der`
and `second.der`.
The `keystore.c` generated should look similar to this:
```
#define NUM_PUBKEYS 2
const struct keystore_slot PubKeys[NUM_PUBKEYS] = {
/* Key associated to private key 'first.der' */
{
.slot_id = 0,
.key_type = AUTH_KEY_ED25519,
.part_id_mask = KEY_VERIFY_ALL,
.pubkey_size = KEYSTORE_PUBKEY_SIZE_ED25519,
.pubkey = {
0x21, 0x7B, 0x8E, 0x64, 0x4A, 0xB7, 0xF2, 0x2F,
0x22, 0x5E, 0x9A, 0xC9, 0x86, 0xDF, 0x42, 0x14,
0xA0, 0x40, 0x2C, 0x52, 0x32, 0x2C, 0xF8, 0x9C,
0x6E, 0xB8, 0xC8, 0x74, 0xFA, 0xA5, 0x24, 0x84
},
},
/* Key associated to private key 'second.der' */
{
.slot_id = 1,
.key_type = AUTH_KEY_ED25519,
.part_id_mask = KEY_VERIFY_ALL,
.pubkey_size = KEYSTORE_PUBKEY_SIZE_ED25519,
.pubkey = {
0x41, 0xC8, 0xB6, 0x6C, 0xB5, 0x4C, 0x8E, 0xA4,
0xA7, 0x15, 0x40, 0x99, 0x8E, 0x6F, 0xD9, 0xCF,
0x00, 0xD0, 0x86, 0xB0, 0x0F, 0xF4, 0xA8, 0xAB,
0xA3, 0x35, 0x40, 0x26, 0xAB, 0xA0, 0x2A, 0xD5
},
},
};
```
### Permissions
By default, when a new keystore is created, the permissions mask is set
to `KEY_VERIFY_ALL`, which means that the key can be used to verify a firmware
targeting any partition id.
To restrict the permissions for single keys, it would be sufficient to change the value
of their `part_id_mask` attributes.
The `part_id_mask` value is a bitmask, where each bit represent a different partition.
The bit '0' is reserved for wolfBoot self-update, while typically the main firmware partition
is associated to id 1, so it requires a key with the bit '1' set. In other words, signing a
partition with `--id 3` would require turning on bit '3' in the mask, i.e. adding (1U << 3) to it.
Beside `KEY_VERIFY_ALL`, pre-defined mask values can also be used here:
- `KEY_VERIFY_APP_ONLY` only verifies the main application, with partition id 1
- `KEY_VERIFY_SELF_ONLY` this key can only be used to authenticate wolfBoot self-updates (id = 0)
- `KEY_VERIFY_ONLY_ID(N)` macro that can be used to restrict the usage of the key to a specific partition id `N`
### Importing public keys
Work in progress.
## Using KeyStore with external Key Vaults
It is possible to use an external NVM, a Key Vault or any generic support to
access the KeyStore. In this case, wolfBoot should not link the generated keystore.c directly,
but rather rely on an external interface, that exports the same API which
would be implemented by `keystore.c`.
The API consists of a few functions described below.
### Interface API
#### Number of keys in the keystore
`int keystore_num_pubkeys(void)`
Returns the number of slots in the keystore. At least one slot
should be populated if you want to authenticate your firmware today.
The interface assumes that the slots are numbered sequentially, from zero to
`keystore_num_pubkeys() - 1`. Accessing those slots through this API should always
return a valid public key.
#### Size of the public key in a slot
`int keystore_get_size(int id)`
Returns the size of the public key stored in the slot `id`.
In case of error, return a negative value.
#### Actual public key buffer (mapped/copied in memory)
`uint8_t *keystore_get_buffer(int id)`
Returns a pointer to an accessible area in memory, containing the buffer with the
public key associated to the slot `id`.
#### Permissions mask
`uint32_t keystore_get_mask(int id)`
Returns the permissions mask, as a 32-bit word, for the public key stored in the slot `id`.

View File

@ -452,6 +452,35 @@ static void __attribute__((noinline)) wolfBoot_image_confirm_signature_ok(struct
/* Restore previously saved registry values */ \
asm volatile("pop {r4, r5, r6, r7}")
#define CONFIRM_MASK_VALID(id, mask) \
asm volatile("mov r1, %0" :: "r"(id)); \
/* id &= 0x0F */ \
asm volatile("and.w r1, r1, #15"); \
asm volatile("mov r0, %0" :: "r"(mask)); \
asm volatile("movs r2, #1"); \
asm volatile("lsls r2, r1"); \
asm volatile("ands r2, r0"); \
asm volatile("movs r0, #1"); \
asm volatile("lsls r0, r1"); \
asm volatile("cmp r0, r2"); \
asm volatile("bne ."); \
asm volatile("mov r0, %0" :: "r"(mask)); \
asm volatile("movs r2, #1"); \
asm volatile("lsls r2, r1"); \
asm volatile("ands r2, r0"); \
asm volatile("movs r0, #1"); \
asm volatile("lsls r0, r1"); \
asm volatile("cmp r0, r2"); \
asm volatile("bne ."); \
asm volatile("mov r0, %0" :: "r"(mask)); \
asm volatile("movs r2, #1"); \
asm volatile("lsls r2, r1"); \
asm volatile("ands r2, r0"); \
asm volatile("movs r0, #1"); \
asm volatile("lsls r0, r1"); \
asm volatile("cmp r0, r2"); \
asm volatile("bne ."); \
#else
struct wolfBoot_image {
@ -491,6 +520,10 @@ static void wolfBoot_image_confirm_signature_ok(struct wolfBoot_image *img)
if (((p)->hdr_ok != 1) || ((p)->sha_ok != 1) || ((p)->signature_ok != 1)) \
wolfBoot_panic()
#define CONFIRM_MASK_VALID(id, mask) \
if ((mask & (1UL << id)) != (1UL << id)) \
wolfBoot_panic()
#define VERIFY_VERSION_ALLOWED do{} while(0);
#endif

View File

@ -28,50 +28,34 @@
#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_ED448)
extern const unsigned char ed448_pub_key[];
extern unsigned int ed448_pub_key_len;
# define KEY_BUFFER ed448_pub_key
# define KEY_LEN ed448_pub_key_len
# define IMAGE_SIGNATURE_SIZE (114)
#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)
#elif defined(WOLFBOOT_SIGN_ECC384)
extern const unsigned char ecc384_pub_key[];
extern unsigned int ecc384_pub_key_len;
# define KEY_BUFFER ecc384_pub_key
# define KEY_LEN ecc384_pub_key_len
# define IMAGE_SIGNATURE_SIZE (96)
#elif defined(WOLFBOOT_SIGN_ECC521)
extern const unsigned char ecc521_pub_key[];
extern unsigned int ecc521_pub_key_len;
# define KEY_BUFFER ecc521_pub_key
# define KEY_LEN ecc521_pub_key_len
# define IMAGE_SIGNATURE_SIZE (132)
#elif defined(WOLFBOOT_SIGN_RSA2048)
extern const unsigned char rsa2048_pub_key[];
extern unsigned int rsa2048_pub_key_len;
# define KEY_BUFFER rsa2048_pub_key
# define KEY_LEN rsa2048_pub_key_len
# define IMAGE_SIGNATURE_SIZE (256)
#elif defined(WOLFBOOT_SIGN_RSA3072)
extern const unsigned char rsa3072_pub_key[];
extern unsigned int rsa3072_pub_key_len;
# define KEY_BUFFER rsa3072_pub_key
# define KEY_LEN rsa3072_pub_key_len
# define IMAGE_SIGNATURE_SIZE (384)
#elif defined(WOLFBOOT_SIGN_RSA4096)
extern const unsigned char rsa4096_pub_key[];
extern unsigned int rsa4096_pub_key_len;
# define KEY_BUFFER rsa4096_pub_key
# define KEY_LEN rsa4096_pub_key_len
# define IMAGE_SIGNATURE_SIZE (512)
#elif !defined(WOLFBOOT_NO_SIGN)
# error "No public key available for given signing algorithm."

View File

@ -66,6 +66,18 @@
#define HDR_SIGNATURE 0x20
#define HDR_PADDING 0xFF
/* Auth Key types */
#define AUTH_KEY_ED25519 0x01
#define AUTH_KEY_ECC256 0x02
#define AUTH_KEY_RSA2048 0x03
#define AUTH_KEY_RSA4096 0x04
#define AUTH_KEY_ED448 0x05
#define AUTH_KEY_ECC384 0x06
#define AUTH_KEY_ECC521 0x07
#define AUTH_KEY_RSA3072 0x08
/*
* 8 bits: auth type
* 4 bits: extra features
@ -74,14 +86,14 @@
*/
#define HDR_IMG_TYPE_AUTH_MASK 0xFF00
#define HDR_IMG_TYPE_AUTH_NONE 0xFF00
#define HDR_IMG_TYPE_AUTH_ED25519 0x0100
#define HDR_IMG_TYPE_AUTH_ECC256 0x0200
#define HDR_IMG_TYPE_AUTH_RSA2048 0x0300
#define HDR_IMG_TYPE_AUTH_RSA4096 0x0400
#define HDR_IMG_TYPE_AUTH_ED448 0x0500
#define HDR_IMG_TYPE_AUTH_ECC384 0x0600
#define HDR_IMG_TYPE_AUTH_ECC521 0x0700
#define HDR_IMG_TYPE_AUTH_RSA3072 0x0800
#define HDR_IMG_TYPE_AUTH_ED25519 (AUTH_KEY_ED25519 << 8)
#define HDR_IMG_TYPE_AUTH_ECC256 (AUTH_KEY_ECC256 << 8)
#define HDR_IMG_TYPE_AUTH_RSA2048 (AUTH_KEY_RSA2048 << 8)
#define HDR_IMG_TYPE_AUTH_RSA4096 (AUTH_KEY_RSA4096 << 8)
#define HDR_IMG_TYPE_AUTH_ED448 (AUTH_KEY_ED448 << 8)
#define HDR_IMG_TYPE_AUTH_ECC384 (AUTH_KEY_ECC384 << 8)
#define HDR_IMG_TYPE_AUTH_ECC521 (AUTH_KEY_ECC521 << 8)
#define HDR_IMG_TYPE_AUTH_RSA3072 (AUTH_KEY_RSA3072 << 8)
#define HDR_IMG_TYPE_DIFF 0x00D0
@ -89,30 +101,93 @@
#define HDR_IMG_TYPE_WOLFBOOT 0x0000
#define HDR_IMG_TYPE_APP 0x0001
#define KEYSTORE_PUBKEY_SIZE_NONE 0
#define KEYSTORE_PUBKEY_SIZE_ED25519 32
#define KEYSTORE_PUBKEY_SIZE_ED448 57
#define KEYSTORE_PUBKEY_SIZE_ECC256 64
#define KEYSTORE_PUBKEY_SIZE_ECC384 96
#define KEYSTORE_PUBKEY_SIZE_ECC521 132
#define KEYSTORE_PUBKEY_SIZE_RSA2048 320
#define KEYSTORE_PUBKEY_SIZE_RSA3072 448
#define KEYSTORE_PUBKEY_SIZE_RSA4096 576
/* Mask for key permissions */
#define KEY_VERIFY_ALL (0xFFFFFFFFU)
#define KEY_VERIFY_ONLY_ID(X) (1U << X)
#define KEY_VERIFY_SELF_ONLY KEY_VERIFY_ONLY_ID(0)
#define KEY_VERIFY_APP_ONLY KEY_VERIFY_ONLY_ID(1)
#ifdef __WOLFBOOT
/* Hashing configuration */
#if defined(WOLFBOOT_HASH_SHA256)
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# define WOLFBOOT_SHA_HDR HDR_SHA256
# define WOLFBOOT_SHA_DIGEST_SIZE (32)
# define image_hash image_sha256
# define key_hash key_sha256
#elif defined(WOLFBOOT_HASH_SHA384)
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# define WOLFBOOT_SHA_HDR HDR_SHA384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha384
# define key_hash key_sha384
#elif defined(WOLFBOOT_HASH_SHA3_384)
# define WOLFBOOT_SHA_BLOCK_SIZE (128)
# define WOLFBOOT_SHA_HDR HDR_SHA3_384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha3_384
# define key_hash key_sha3_384
#else
# error "No valid hash algorithm defined!"
#endif
/* Authentication configuration */
#if defined(WOLFBOOT_NO_SIGN)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_NONE
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_NONE
#elif defined(WOLFBOOT_SIGN_ED25519)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ED25519
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ED25519
#elif defined(WOLFBOOT_SIGN_ED448)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ED448
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ED448
#elif defined(WOLFBOOT_SIGN_ECC256)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ECC256
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC256
#elif defined(WOLFBOOT_SIGN_ECC384)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ECC384
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC384
#elif defined(WOLFBOOT_SIGN_ECC521)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ECC521
# error "ECC521 curves not yet supported in this version of wolfBoot. Please select a valid SIGN= option."
#elif defined(WOLFBOOT_SIGN_RSA2048)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_RSA2048
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_RSA2048
#elif defined(WOLFBOOT_SIGN_RSA3072)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_RSA3072
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_RSA3072
#elif defined(WOLFBOOT_SIGN_RSA4096)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_RSA4096
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_RSA4096
#else
# error "no valid authentication mechanism selected. Please select a valid SIGN= option."
#endif /* defined WOLFBOOT_SIGN_ECC256 || WOLFBOOT_SIGN_ED25519 */
struct keystore_slot {
uint32_t slot_id;
uint32_t key_type;
uint32_t part_id_mask;
uint32_t pubkey_size;
uint8_t pubkey[KEYSTORE_PUBKEY_SIZE];
};
/* KeyStore API */
int keystore_num_pubkeys(void);
uint8_t *keystore_get_buffer(int id);
int keystore_get_size(int id);
uint32_t keystore_get_mask(int id);
#endif /* defined WOLFBOOT */
#ifdef WOLFBOOT_FIXED_PARTITIONS
@ -164,30 +239,6 @@ int wolfBoot_dualboot_candidate(void);
int wolfBoot_dualboot_candidate_addr(void**);
/* Hashing function configuration */
#if defined(WOLFBOOT_HASH_SHA256)
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# define WOLFBOOT_SHA_HDR HDR_SHA256
# define WOLFBOOT_SHA_DIGEST_SIZE (32)
# define image_hash image_sha256
# define key_hash key_sha256
#elif defined(WOLFBOOT_HASH_SHA384)
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# define WOLFBOOT_SHA_HDR HDR_SHA384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha384
# define key_hash key_sha384
#elif defined(WOLFBOOT_HASH_SHA3_384)
# define WOLFBOOT_SHA_BLOCK_SIZE (128)
# define WOLFBOOT_SHA_HDR HDR_SHA3_384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha3_384
# define key_hash key_sha3_384
#else
# error "No valid hash algorithm defined!"
#endif
#ifdef EXT_ENCRYPTED
/* Encryption support */
#if defined(ENCRYPT_WITH_CHACHA)
@ -216,4 +267,5 @@ int wolfBoot_set_encrypt_key(const uint8_t *key, const uint8_t *nonce);
int wolfBoot_get_encrypt_key(uint8_t *key, uint8_t *nonce);
int wolfBoot_erase_encrypt_key(void);
#endif /* !WOLFBOOT_H */

View File

@ -9,7 +9,6 @@ endif
ifeq ($(SIGN),NONE)
SIGN_OPTIONS+=--no-sign
PRIVATE_KEY=
STACK_USAGE=1216
CFLAGS+=-DWOLFBOOT_NO_SIGN
endif
@ -27,7 +26,6 @@ endif
ifeq ($(SIGN),ECC256)
KEYGEN_OPTIONS+=--ecc256
SIGN_OPTIONS+=--ecc256
PRIVATE_KEY=ecc256.der
WOLFCRYPT_OBJS+= \
$(MATH_OBJS) \
./lib/wolfssl/wolfcrypt/src/ecc.o \
@ -43,9 +41,8 @@ ifeq ($(SIGN),ECC256)
else ifneq ($(SPMATH),1)
STACK_USAGE=5008
else
STACK_USAGE=3952
STACK_USAGE=3960
endif
PUBLIC_KEY_OBJS=./src/ecc256_pub_key.o
ifeq ($(shell test $(IMAGE_HEADER_SIZE) -lt 256; echo $$?),0)
IMAGE_HEADER_SIZE=256
endif
@ -54,7 +51,6 @@ endif
ifeq ($(SIGN),ECC384)
KEYGEN_OPTIONS+=--ecc384
SIGN_OPTIONS+=--ecc384
PRIVATE_KEY=ecc384.der
WOLFCRYPT_OBJS+= \
$(MATH_OBJS) \
./lib/wolfssl/wolfcrypt/src/ecc.o \
@ -72,7 +68,6 @@ ifeq ($(SIGN),ECC384)
else
STACK_USAGE=5880
endif
PUBLIC_KEY_OBJS=./src/ecc384_pub_key.o
ifeq ($(shell test $(IMAGE_HEADER_SIZE) -lt 512; echo $$?),0)
IMAGE_HEADER_SIZE=512
endif
@ -81,7 +76,6 @@ endif
ifeq ($(SIGN),ECC521)
KEYGEN_OPTIONS+=--ecc521
SIGN_OPTIONS+=--ecc521
PRIVATE_KEY=ecc521.der
WOLFCRYPT_OBJS+= \
$(MATH_OBJS) \
./lib/wolfssl/wolfcrypt/src/ecc.o \
@ -99,7 +93,6 @@ ifeq ($(SIGN),ECC521)
else
STACK_USAGE=3896
endif
PUBLIC_KEY_OBJS=./src/ecc521_pub_key.o
ifeq ($(shell test $(IMAGE_HEADER_SIZE) -lt 512; echo $$?),0)
IMAGE_HEADER_SIZE=512
endif
@ -108,7 +101,6 @@ endif
ifeq ($(SIGN),ED25519)
KEYGEN_OPTIONS+=--ed25519
SIGN_OPTIONS+=--ed25519
PRIVATE_KEY=ed25519.der
WOLFCRYPT_OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
./lib/wolfssl/wolfcrypt/src/ed25519.o \
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
@ -116,9 +108,12 @@ ifeq ($(SIGN),ED25519)
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o
PUBLIC_KEY_OBJS=./src/ed25519_pub_key.o
CFLAGS+=-D"WOLFBOOT_SIGN_ED25519"
STACK_USAGE?=1180
ifeq ($(WOLFTPM),1)
STACK_USAGE=6680
else
STACK_USAGE?=1180
endif
ifeq ($(shell test $(IMAGE_HEADER_SIZE) -lt 256; echo $$?),0)
IMAGE_HEADER_SIZE=256
endif
@ -127,7 +122,6 @@ endif
ifeq ($(SIGN),ED448)
KEYGEN_OPTIONS+=--ed448
SIGN_OPTIONS+=--ed448
PRIVATE_KEY=ed448.der
WOLFCRYPT_OBJS+= ./lib/wolfssl/wolfcrypt/src/ed448.o \
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
./lib/wolfssl/wolfcrypt/src/ge_448.o \
@ -136,16 +130,18 @@ ifeq ($(SIGN),ED448)
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o
ifeq ($(WOLFBOOT_SMALL_STACK),1)
ifeq ($(WOLFTPM),1)
STACK_USAGE=6680
else ifeq ($(WOLFBOOT_SMALL_STACK),1)
STACK_USAGE?=1024
else
STACK_USAGE?=4376
endif
ifneq ($(HASH),SHA3)
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/sha3.o
endif
PUBLIC_KEY_OBJS=./src/ed448_pub_key.o
CFLAGS+=-D"WOLFBOOT_SIGN_ED448"
ifeq ($(shell test $(IMAGE_HEADER_SIZE) -lt 512; echo $$?),0)
IMAGE_HEADER_SIZE=512
@ -155,7 +151,6 @@ endif
ifeq ($(SIGN),RSA2048)
KEYGEN_OPTIONS+=--rsa2048
SIGN_OPTIONS+=--rsa2048
PRIVATE_KEY=rsa2048.der
WOLFCRYPT_OBJS+= \
$(RSA_EXTRA_OBJS) \
$(MATH_OBJS) \
@ -163,7 +158,6 @@ ifeq ($(SIGN),RSA2048)
./lib/wolfssl/wolfcrypt/src/asn.o \
./lib/wolfssl/wolfcrypt/src/hash.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o
PUBLIC_KEY_OBJS=./src/rsa2048_pub_key.o
CFLAGS+=-D"WOLFBOOT_SIGN_RSA2048" $(RSA_EXTRA_CFLAGS)
ifeq ($(WOLFBOOT_SMALL_STACK),1)
ifneq ($(SPMATH),1)
@ -186,7 +180,6 @@ endif
ifeq ($(SIGN),RSA3072)
KEYGEN_OPTIONS+=--rsa3072
SIGN_OPTIONS+=--rsa3072
PRIVATE_KEY=rsa3072.der
WOLFCRYPT_OBJS+= \
$(RSA_EXTRA_OBJS) \
$(MATH_OBJS) \
@ -194,7 +187,6 @@ ifeq ($(SIGN),RSA3072)
./lib/wolfssl/wolfcrypt/src/asn.o \
./lib/wolfssl/wolfcrypt/src/hash.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o
PUBLIC_KEY_OBJS=./src/rsa3072_pub_key.o
CFLAGS+=-D"WOLFBOOT_SIGN_RSA3072" $(RSA_EXTRA_CFLAGS)
ifeq ($(WOLFBOOT_SMALL_STACK),1)
ifneq ($(SPMATH),1)
@ -220,7 +212,6 @@ endif
ifeq ($(SIGN),RSA4096)
KEYGEN_OPTIONS+=--rsa4096
SIGN_OPTIONS+=--rsa4096
PRIVATE_KEY=rsa4096.der
WOLFCRYPT_OBJS+= \
$(RSA_EXTRA_OBJS) \
$(MATH_OBJS) \
@ -228,7 +219,6 @@ ifeq ($(SIGN),RSA4096)
./lib/wolfssl/wolfcrypt/src/asn.o \
./lib/wolfssl/wolfcrypt/src/hash.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o
PUBLIC_KEY_OBJS=./src/rsa4096_pub_key.o
CFLAGS+=-D"WOLFBOOT_SIGN_RSA4096" $(RSA_EXTRA_CFLAGS)
ifeq ($(WOLFBOOT_SMALL_STACK),1)
ifneq ($(SPMATH),1)

View File

@ -26,19 +26,25 @@
#include <stddef.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <string.h>
#include "image.h"
#ifdef WOLFBOOT_TPM
#include <stdlib.h>
#include <string.h>
#include "wolftpm/tpm2.h"
#include "wolftpm/tpm2_wrap.h"
static WOLFTPM2_DEV wolftpm_dev;
#endif /* WOLFBOOT_TPM */
static int keyslot_id_by_sha(const uint8_t *hint);
#ifdef WOLFBOOT_SIGN_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
static void wolfBoot_verify_signature(uint8_t key_slot,
struct wolfBoot_image *img, uint8_t *sig)
{
int ret, res;
ed25519_key ed;
@ -47,7 +53,8 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
/* Failed to initialize key */
return;
}
ret = wc_ed25519_import_public(KEY_BUFFER, KEY_LEN, &ed);
ret = wc_ed25519_import_public(keystore_get_buffer(key_slot),
KEYSTORE_PUBKEY_SIZE, &ed);
if (ret < 0) {
/* Failed to import ed25519 key */
return;
@ -61,7 +68,8 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
#ifdef WOLFBOOT_SIGN_ED448
#include <wolfssl/wolfcrypt/ed448.h>
static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
static void wolfBoot_verify_signature(uint8_t key_slot,
struct wolfBoot_image *img, uint8_t *sig)
{
int ret, res;
ed448_key ed;
@ -70,7 +78,8 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
/* Failed to initialize key */
return;
}
ret = wc_ed448_import_public(KEY_BUFFER, KEY_LEN, &ed);
ret = wc_ed448_import_public(keystore_get_buffer(key_slot),
KEYSTORE_PUBKEY_SIZE, &ed);
if (ret < 0) {
/* Failed to import ed448 key */
return;
@ -89,21 +98,24 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
#include <wolfssl/wolfcrypt/ecc.h>
#ifdef WOLFBOOT_SIGN_ECC256
#define ECC_KEY_SIZE 32
#define ECC_KEY_TYPE ECC_SECP256R1
#endif
#ifdef WOLFBOOT_SIGN_ECC384
#define ECC_KEY_SIZE 48
#define ECC_KEY_TYPE ECC_SECP384R1
#endif
#ifdef WOLFBOOT_SIGN_ECC521
#define ECC_KEY_SIZE 66
#define ECC_KEY_TYPE ECC_SECP521R1
#endif
static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
#define KEYSTORE_ECC_POINT_SIZE (KEYSTORE_PUBKEY_SIZE / 2)
static void wolfBoot_verify_signature(uint8_t key_slot,
struct wolfBoot_image *img, uint8_t *sig)
{
int ret, verify_res = 0;
uint8_t *pubkey = keystore_get_buffer(key_slot);
if (pubkey == NULL)
return;
#ifdef WOLFBOOT_TPM
WOLFTPM2_KEY tpmKey;
#ifdef WOLFBOOT_DEBUG_TPM
@ -113,12 +125,13 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
/* Load public key into TPM */
memset(&tpmKey, 0, sizeof(tpmKey));
ret = wolfTPM2_LoadEccPublicKey(&wolftpm_dev, &tpmKey, TPM_ECC_NIST_P256,
KEY_BUFFER, ECC_KEY_SIZE,
KEY_BUFFER + ECC_KEY_SIZE, ECC_KEY_SIZE);
pubkey, KEYSTORE_ECC_POINT_SIZE, pubkey + KEYSTORE_ECC_POINT_SIZE,
KEYSTORE_ECC_POINT_SIZE);
if (ret < 0)
return;
ret = wolfTPM2_VerifyHashScheme(&wolftpm_dev, &tpmKey, sig, IMAGE_SIGNATURE_SIZE,
img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, TPM_ALG_ECDSA, TPM_ALG_SHA256);
ret = wolfTPM2_VerifyHashScheme(&wolftpm_dev, &tpmKey, sig,
IMAGE_SIGNATURE_SIZE, img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE,
TPM_ALG_ECDSA, TPM_ALG_SHA256);
wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle);
if (ret == 0) {
verify_res = 1; /* TPM does hash verify compare */
@ -146,8 +159,8 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
}
/* Import public key */
ret = wc_ecc_import_unsigned(&ecc, (byte*)KEY_BUFFER,
(byte*)(KEY_BUFFER + ECC_KEY_SIZE), NULL, ECC_KEY_TYPE);
ret = wc_ecc_import_unsigned(&ecc, pubkey,
(byte*)(pubkey + KEYSTORE_ECC_POINT_SIZE), NULL, ECC_KEY_TYPE);
if ((ret < 0) || ecc.type != ECC_PUBLICKEY) {
/* Failed to import ecc key */
return;
@ -156,8 +169,9 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
/* 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);
mp_read_unsigned_bin(&r, sig, KEYSTORE_ECC_POINT_SIZE);
mp_read_unsigned_bin(&s, sig + KEYSTORE_ECC_POINT_SIZE,
KEYSTORE_ECC_POINT_SIZE);
VERIFY_FN(img, &verify_res, wc_ecc_verify_hash_ex, &r, &s, img->sha_hash,
WOLFBOOT_SHA_DIGEST_SIZE, &verify_res, &ecc);
#endif /* WOLFBOOT_TPM */
@ -240,12 +254,19 @@ static int RsaUnPad(const byte *pkcsBlock, int pkcsBlockLen, byte **output)
}
#endif /* WOLFBOOT_TPM */
static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
static void wolfBoot_verify_signature(uint8_t key_slot,
struct wolfBoot_image *img, uint8_t *sig)
{
int ret;
uint8_t output[IMAGE_SIGNATURE_SIZE];
int output_sz = sizeof(output);
uint8_t* digest_out = NULL;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
if ((pubkey_sz < 0) || (pubkey == NULL))
return;
#ifdef WOLFBOOT_TPM
WOLFTPM2_KEY tpmKey;
const byte *n = NULL, *e = NULL;
@ -255,7 +276,7 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
#endif
/* Extract DER RSA key struct */
ret = wc_RsaPublicKeyDecode_ex(KEY_BUFFER, &inOutIdx, KEY_LEN, &n, &nSz, &e,
ret = wc_RsaPublicKeyDecode_ex(pubkey, &inOutIdx, pubkey_sz, &n, &nSz, &e,
&eSz);
if (ret < 0)
return;
@ -305,7 +326,7 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
return;
}
/* Import public key */
ret = wc_RsaPublicKeyDecode((byte*)KEY_BUFFER, &in_out, &rsa, KEY_LEN);
ret = wc_RsaPublicKeyDecode((byte*)pubkey, &in_out, &rsa, pubkey_sz);
if (ret < 0) {
/* Failed to import rsa key */
wc_FreeRsaKey(&rsa);
@ -332,9 +353,11 @@ static void wolfBoot_verify_signature(struct wolfBoot_image *img, uint8_t *sig)
|| WOLFBOOT_SIGN_RSA4096 */
static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr);
static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type,
uint8_t **ptr);
static uint16_t get_header(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr)
static uint16_t get_header(struct wolfBoot_image *img, uint16_t type,
uint8_t **ptr)
{
if (PART_IS_EXT(img))
return get_header_ext(img, type, ptr);
@ -352,7 +375,8 @@ static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset)
return NULL;
#ifdef EXT_FLASH
if (PART_IS_EXT(img)) {
ext_flash_check_read((uintptr_t)(img->fw_base) + offset, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE);
ext_flash_check_read((uintptr_t)(img->fw_base) + offset, ext_hash_block,
WOLFBOOT_SHA_BLOCK_SIZE);
return ext_hash_block;
} else
#endif
@ -372,9 +396,11 @@ static uint8_t *fetch_hdr_cpy(struct wolfBoot_image *img)
return hdr_cpy;
}
static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr)
static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type,
uint8_t **ptr)
{
return wolfBoot_find_header(fetch_hdr_cpy(img) + IMAGE_HEADER_OFFSET, type, ptr);
return wolfBoot_find_header(fetch_hdr_cpy(img) + IMAGE_HEADER_OFFSET, type,
ptr);
}
#else
@ -478,39 +504,46 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
}
#ifndef WOLFBOOT_NO_SIGN
static void key_sha256(uint8_t *hash)
static void key_sha256(uint8_t key_slot, uint8_t *hash)
{
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_HASH_TPM)
int blksz, rc;
unsigned int i = 0;
const char usageAuth[] = "wolfBoot TPM Usage Auth";
uint32_t hashSz = WOLFBOOT_SHA_DIGEST_SIZE;
uint8_t *pubkey = keystore_get_buffer(key_slot);
if (!pubkey)
return;
WOLFTPM2_HASH tpmHash;
memset(&tpmHash, 0, sizeof(tpmHash));
rc = wolfTPM2_HashStart(&wolftpm_dev, &tpmHash, TPM_ALG_SHA256,
(const byte*)usageAuth, sizeof(usageAuth)-1);
if (rc != 0)
return;
while(i < KEY_LEN)
while(i < pubkey_sz)
{
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > KEY_LEN)
blksz = KEY_LEN - i;
wolfTPM2_HashUpdate(&wolftpm_dev, &tpmHash, KEY_BUFFER + i, blksz);
if ((i + blksz) > pubkey_sz)
blksz = pubkey_sz - i;
wolfTPM2_HashUpdate(&wolftpm_dev, &tpmHash, pubkey + i, blksz);
i += blksz;
}
wolfTPM2_HashFinish(&wolftpm_dev, &tpmHash, hash, (word32*)&hashSz);
#else
int blksz;
unsigned int i = 0;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
if (!pubkey || (pubkey_sz < 0))
return;
wc_Sha256 sha256_ctx;
wc_InitSha256(&sha256_ctx);
while(i < KEY_LEN)
while(i < (uint32_t)pubkey_sz)
{
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > KEY_LEN)
blksz = KEY_LEN - i;
wc_Sha256Update(&sha256_ctx, (KEY_BUFFER + i), blksz);
if ((i + blksz) > (uint32_t)pubkey_sz)
blksz = pubkey_sz - i;
wc_Sha256Update(&sha256_ctx, (pubkey + i), blksz);
i += blksz;
}
wc_Sha256Final(&sha256_ctx, hash);
@ -561,18 +594,23 @@ static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
}
#ifndef WOLFBOOT_NO_SIGN
static void key_sha384(uint8_t *hash)
static void key_sha384(uint8_t key_slot, uint8_t *hash)
{
int blksz;
unsigned int i = 0;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
wc_Sha384 sha384_ctx;
if (!pubkey || (pubkey_sz < 0))
return;
wc_InitSha384(&sha384_ctx);
while(i < KEY_LEN)
while(i < (uint32_t)(pubkey_sz))
{
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > KEY_LEN)
blksz = KEY_LEN - i;
wc_Sha384Update(&sha384_ctx, (KEY_BUFFER + i), blksz);
if ((i + blksz) > (uint32_t)pubkey_sz)
blksz = pubkey_sz - i;
wc_Sha384Update(&sha384_ctx, (pubkey + i), blksz);
i += blksz;
}
wc_Sha384Final(&sha384_ctx, hash);
@ -622,18 +660,23 @@ static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
return 0;
}
#ifndef WOLFBOOT_NO_SIGN
static void key_sha3_384(uint8_t *hash)
static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
{
int blksz;
unsigned int i = 0;
wc_Sha3 sha3_ctx;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
if (!pubkey || (pubkey_sz < 0))
return;
wc_InitSha3_384(&sha3_ctx, NULL, INVALID_DEVID);
while(i < KEY_LEN)
while(i < (uint32_t)pubkey_sz)
{
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > KEY_LEN)
blksz = KEY_LEN - i;
wc_Sha3_384_Update(&sha3_ctx, (KEY_BUFFER + i), blksz);
if ((i + blksz) > (uint32_t)pubkey_sz)
blksz = pubkey_sz - i;
wc_Sha3_384_Update(&sha3_ctx, pubkey + i, blksz);
i += blksz;
}
wc_Sha3_384_Final(&sha3_ctx, hash);
@ -868,15 +911,21 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
uint8_t *image_type_buf;
uint16_t image_type;
uint16_t image_type_size;
uint32_t key_mask = 0U;
uint32_t image_part = 1U;
int key_slot;
stored_signature_size = get_header(img, HDR_SIGNATURE, &stored_signature);
if (stored_signature_size != IMAGE_SIGNATURE_SIZE)
return -1;
pubkey_hint_size = get_header(img, HDR_PUBKEY, &pubkey_hint);
if (pubkey_hint_size == WOLFBOOT_SHA_DIGEST_SIZE) {
key_hash(digest);
if (memcmp(digest, pubkey_hint, WOLFBOOT_SHA_DIGEST_SIZE) != 0)
return -1;
key_slot = keyslot_id_by_sha(pubkey_hint);
if (key_slot < 0) {
return -1; /* Key was not found */
}
} else {
return -1; /* Invalid hash size for public key hint */
}
image_type_size = get_header(img, HDR_IMG_TYPE, &image_type_buf);
if (image_type_size != sizeof(uint16_t))
@ -889,6 +938,15 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
return -1;
img->sha_hash = digest;
}
key_mask = keystore_get_mask(key_slot);
image_part = image_type & HDR_IMG_TYPE_PART_MASK;
/* Check if the key permission mask matches the current partition id */
if (((1U << image_part) & key_mask) != (1U << image_part))
return -1; /* Key not allowed to verify this partition id */
CONFIRM_MASK_VALID(image_part, key_mask);
/* wolfBoot_verify_signature() does not return the result directly.
* A call to wolfBoot_image_confirm_signature_ok() is required in order to
* confirm that the signature verification is OK.
@ -897,7 +955,7 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
* img->signature_ok to 1.
*
*/
wolfBoot_verify_signature(img, stored_signature);
wolfBoot_verify_signature(key_slot, img, stored_signature);
if (img->signature_ok == 1)
return 0;
return -2;
@ -914,3 +972,17 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
*sz = WOLFBOOT_SHA_BLOCK_SIZE;
return p;
}
#ifndef WOLFBOOT_NO_SIGN
static int keyslot_id_by_sha(const uint8_t *hint)
{
int id = 0;
for (id = 0; id < keystore_num_pubkeys(); id++)
{
key_hash(id, digest);
if (memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0)
return id;
}
return -1;
}
#endif

View File

@ -27,6 +27,7 @@
//#define DEBUG_SIGNTOOL
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@ -34,6 +35,8 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <wolfssl/wolfcrypt/settings.h>
#ifndef NO_RSA
@ -62,30 +65,88 @@
#define PATH_MAX 256
#endif
#define KEYGEN_ED25519 0
#define KEYGEN_ECC256 1
#define KEYGEN_RSA2048 2
#define KEYGEN_RSA4096 3
#define KEYGEN_ED448 4
#define KEYGEN_ECC384 5
#define KEYGEN_ECC521 6
#define KEYGEN_RSA3072 7
#include "wolfboot/wolfboot.h"
const char Ed25519_pub_key_define[] = "const uint8_t ed25519_pub_key[32] = {";
const char Ed448_pub_key_define[] = "const uint8_t ed448_pub_key[57] = {";
const char Ecc256_pub_key_define[] = "const uint8_t ecc256_pub_key[64] = {";
const char Ecc384_pub_key_define[] = "const uint8_t ecc384_pub_key[96] = {";
const char Ecc521_pub_key_define[] = "const uint8_t ecc521_pub_key[132] = {";
const char Rsa_2048_pub_key_define[] = "const uint8_t rsa2048_pub_key[%d] = {";
const char Rsa_3072_pub_key_define[] = "const uint8_t rsa3072_pub_key[%d] = {";
const char Rsa_4096_pub_key_define[] = "const uint8_t rsa4096_pub_key[%d] = {";
const char Cfile_Banner[] = "/* Public-key file for wolfBoot, automatically generated. Do not edit. */\n" \
"/*\n" \
" * This file has been generated and contains the public key which is\n" \
" * used by wolfBoot to verify the updates.\n" \
" */" \
"\n#include <stdint.h>\n\n";
#define KEYGEN_NONE 0
#define KEYGEN_ED25519 1
#define KEYGEN_ECC256 2
#define KEYGEN_RSA2048 3
#define KEYGEN_RSA4096 4
#define KEYGEN_ED448 5
#define KEYGEN_ECC384 6
#define KEYGEN_ECC521 7
#define KEYGEN_RSA3072 8
/* Globals */
static FILE *fpub, *fpub_image;
static int force = 0;
static WC_RNG rng;
#ifndef KEYSLOT_MAX_PUBKEY_SIZE
#define KEYSLOT_MAX_PUBKEY_SIZE 2048
#endif
struct keystore_slot {
uint32_t slot_id;
uint32_t key_type;
uint32_t part_id_mask;
uint32_t pubkey_size;
uint8_t pubkey[KEYSLOT_MAX_PUBKEY_SIZE];
};
const char pubkeyfile[]= "src/keystore.c";
const char pubkeyimg[] = "keystore.der";
const char Cfile_Banner[]="/* Keystore file for wolfBoot, automatically generated. Do not edit. */\n"
"/*\n"
" * This file has been generated and contains the public keys\n"
" * used by wolfBoot to verify the updates.\n"
" */" \
"\n#include <stdint.h>\n#include \"wolfboot/wolfboot.h\"\n"
"#ifdef WOLFBOOT_NO_SIGN\n\t#define NUM_PUBKEYS 0\n#else\n\n"
"#if (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_%s)\n\t"
"#error Key algorithm mismatch. Remove old keys via 'make distclean'\n"
"#else\n";
const char Store_hdr[] = "#define NUM_PUBKEYS %d\nconst struct keystore_slot PubKeys[NUM_PUBKEYS] = {\n\n";
const char Slot_hdr[] = "\t /* Key associated to file '%s' */\n"
"\t{\n\t\t.slot_id = %d,\n\t\t.key_type = %s,\n"
"\t\t.part_id_mask = KEY_VERIFY_ALL,\n\t\t.pubkey_size = %s,\n"
"\t\t.pubkey = {\n\t\t\t";
const char Slot_hdr_int_size[] = "\t /* Key associated to file '%s' */\n"
"\t{\n\t\t.slot_id = %d,\n\t\t.key_type = %s,\n"
"\t\t.part_id_mask = KEY_VERIFY_ALL,\n\t\t.pubkey_size = %u,\n"
"\t\t.pubkey = {\n\t\t\t";
const char Pubkey_footer[] = "\n\t\t},";
const char Slot_footer[] = "\n\t},\n\n";
const char Store_footer[] = "\n};\n\n";
const char Keystore_API[] =
"int keystore_num_pubkeys(void)\n"
"{\n"
" return NUM_PUBKEYS;\n"
"}\n\n"
"uint8_t *keystore_get_buffer(int id)\n"
"{\n"
" if (id >= keystore_num_pubkeys())\n"
" return (uint8_t *)0;\n"
" return (uint8_t *)PubKeys[id].pubkey;\n"
"}\n\n"
"int keystore_get_size(int id)\n"
"{\n"
" if (id >= keystore_num_pubkeys())\n"
" return -1;\n"
" return (int)PubKeys[id].pubkey_size;\n"
"}\n\n"
"uint32_t keystore_get_mask(int id)\n"
"{\n"
" if (id >= keystore_num_pubkeys())\n"
" return -1;\n"
" return (int)PubKeys[id].part_id_mask;\n"
"}\n\n"
"#endif /* Keystore public key size check */\n"
"#endif /* WOLFBOOT_NO_SIGN */\n";
@ -93,7 +154,7 @@ static void usage(const char *pname) /* implies exit */
{
printf("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 "
"| --ecc521 | --rsa2048 | --rsa3072 "
"| --rsa4096 ] pub_key_file.c\n", pname);
"| --rsa4096 ] [-g privkey] [-i pubkey] \n", pname);
exit(125);
}
@ -105,7 +166,7 @@ static void fwritekey(uint8_t *key, int len, FILE *f)
if ((i % 8) == 0) {
if (i != 0)
fprintf(f, ",");
fprintf(f, "\n\t");
fprintf(f, "\n\t\t\t");
}
else {
fprintf(f, ", ");
@ -114,79 +175,153 @@ static void fwritekey(uint8_t *key, int len, FILE *f)
}
}
const char KType[][17] = {
"AUTH_KEY_NONE",
"AUTH_KEY_ED25519",
"AUTH_KEY_ECC256",
"AUTH_KEY_RSA2048",
"AUTH_KEY_RSA4096",
"AUTH_KEY_ED448",
"AUTH_KEY_ECC384",
"AUTH_KEY_ECC521",
"AUTH_KEY_RSA3072"
};
const char KSize[][29] = {
"KEYSTORE_PUBKEY_SIZE_NONE",
"KEYSTORE_PUBKEY_SIZE_ED25519",
"KEYSTORE_PUBKEY_SIZE_ECC256",
"KEYSTORE_PUBKEY_SIZE_RSA2048",
"KEYSTORE_PUBKEY_SIZE_RSA4096",
"KEYSTORE_PUBKEY_SIZE_ED448",
"KEYSTORE_PUBKEY_SIZE_ECC384",
"KEYSTORE_PUBKEY_SIZE_ECC521",
"KEYSTORE_PUBKEY_SIZE_RSA3072"
};
const char KName[][8] = {
"NONE",
"ED25519",
"ECC256",
"RSA2048",
"RSA4096",
"ED448",
"ECC384",
"ECC521",
"RSA3072"
};
void keystore_add(uint32_t ktype, uint8_t *key, uint32_t sz, const char *keyfile)
{
static int id_slot = 0;
struct keystore_slot sl;
if (ktype == KEYGEN_RSA2048 || ktype == KEYGEN_RSA3072 || ktype == KEYGEN_RSA4096)
fprintf(fpub, Slot_hdr_int_size, keyfile, id_slot, KType[ktype], sz);
else
fprintf(fpub, Slot_hdr, keyfile, id_slot, KType[ktype], KSize[ktype]);
fwritekey(key, sz, fpub);
fprintf(fpub, Pubkey_footer);
fprintf(fpub, Slot_footer);
printf("Associated key file: %s\n", keyfile);
printf("Key type : %s\n", KName[ktype]);
printf("Public key slot: %u\n", id_slot);
memset(&sl, 0, sizeof(sl));
sl.slot_id = id_slot;
sl.key_type = ktype;
sl.part_id_mask = 0xFFFFFFFF;
switch (ktype){
case KEYGEN_ED25519:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_ED25519;
break;
case KEYGEN_ED448:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_ED448;
break;
case KEYGEN_ECC256:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_ECC256;
break;
case KEYGEN_ECC384:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_ECC384;
break;
case KEYGEN_RSA2048:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_RSA2048;
break;
case KEYGEN_RSA3072:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_RSA3072;
break;
case KEYGEN_RSA4096:
sl.pubkey_size = KEYSTORE_PUBKEY_SIZE_RSA4096;
break;
default:
sl.pubkey_size = 0;
}
memcpy(sl.pubkey, key, sz);
fwrite(&sl, sl.pubkey_size, 1, fpub_image);
sl.pubkey_size = sz;
id_slot++;
}
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
static void keygen_rsa(WC_RNG *rng, char *pubkeyfile, int size)
static void keygen_rsa(const char *keyfile, int kbits)
{
RsaKey k;
uint8_t priv_der[4096], pub_der[2048];
int privlen, publen;
FILE *fpub, *fpriv;
char priv_fname[40];
FILE *fpriv;
if (wc_InitRsaKey(&k, NULL) != 0) {
fprintf(stderr, "Unable to initialize RSA%d key\n", size);
fprintf(stderr, "Unable to initialize RSA%d key\n", kbits);
exit(1);
}
if (wc_MakeRsaKey(&k, size, 65537, rng) != 0) {
fprintf(stderr, "Unable to create RSA%d key\n", size);
if (wc_MakeRsaKey(&k, kbits, 65537, &rng) != 0) {
fprintf(stderr, "Unable to create RSA%d key\n", kbits);
exit(1);
}
privlen = wc_RsaKeyToDer(&k, priv_der, size);
privlen = wc_RsaKeyToDer(&k, priv_der, kbits);
if (privlen <= 0) {
fprintf(stderr, "Unable to export private key to DER\n");
exit(2);
}
publen = wc_RsaKeyToPublicDer(&k, pub_der, size);
publen = wc_RsaKeyToPublicDer(&k, pub_der, kbits);
if (publen <= 0) {
fprintf(stderr, "Unable to export public key\n");
exit(3);
}
sprintf(priv_fname, "rsa%d.der", size);
fpriv = fopen(priv_fname, "wb");
printf("RSA public key len: %d bytes\n", publen);
fpriv = fopen(keyfile, "wb");
if (fpriv == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", priv_fname, strerror(errno));
fprintf(stderr, "Unable to open file '%s' for writing: %s", keyfile, strerror(errno));
exit(4);
}
fwrite(priv_der, privlen, 1, fpriv);
fclose(fpriv);
fpub = fopen(pubkeyfile, "w");
if (fpub == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", pubkeyfile, strerror(errno));
exit(4);
}
fprintf(fpub, "%s", Cfile_Banner);
if (size == 2048)
fprintf(fpub, Rsa_2048_pub_key_define, publen);
else if (size == 3072)
fprintf(fpub, Rsa_3072_pub_key_define, publen);
else
fprintf(fpub, Rsa_4096_pub_key_define, publen);
fwritekey(pub_der, publen, fpub);
fprintf(fpub, "\n};\n");
fprintf(fpub, "const uint32_t rsa%d_pub_key_len = %d;\n", size, publen);
fclose(fpub);
if (kbits == 2048)
keystore_add(KEYGEN_RSA2048, pub_der, publen, keyfile);
else if (kbits == 3072)
keystore_add(KEYGEN_RSA3072, pub_der, publen, keyfile);
else if (kbits == 4096)
keystore_add(KEYGEN_RSA4096, pub_der, publen, keyfile);
}
#endif
#ifdef HAVE_ECC
#define MAX_ECC_KEY_SIZE 66
static void keygen_ecc(WC_RNG *rng, char *pubkfile, uint16_t ecc_key_size)
static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size)
{
ecc_key k;
uint8_t Qx[MAX_ECC_KEY_SIZE], Qy[MAX_ECC_KEY_SIZE], d[MAX_ECC_KEY_SIZE];
uint32_t qxsize = ecc_key_size,
qysize = ecc_key_size,
dsize = ecc_key_size;
FILE *fpriv, *fpub;
char priv_fname[20] = "";
uint8_t k_buffer[2 * MAX_ECC_KEY_SIZE];
FILE *fpriv;
if (wc_ecc_make_key(rng, ecc_key_size, &k) != 0) {
if (wc_ecc_make_key(&rng, ecc_key_size, &k) != 0) {
fprintf(stderr, "Unable to create ecc key\n");
exit(1);
}
@ -201,56 +336,38 @@ static void keygen_ecc(WC_RNG *rng, char *pubkfile, uint16_t ecc_key_size)
exit(3);
}
sprintf(priv_fname, "ecc%d.der", (ecc_key_size < 66)?(ecc_key_size << 3):521);
fpriv = fopen(priv_fname, "wb");
if (fpriv == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", priv_fname, strerror(errno));
exit(3);
}
fwrite(Qx, qxsize, 1, fpriv);
fwrite(Qy, qysize, 1, fpriv);
fwrite(d, dsize, 1, fpriv);
fclose(fpriv);
fpub = fopen(pubkfile, "w");
if (fpub == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", pubkfile, strerror(errno));
exit(4);
}
fprintf(fpub, "%s", Cfile_Banner);
if (ecc_key_size == 32)
fprintf(fpub, "%s", Ecc256_pub_key_define);
else if (ecc_key_size == 48)
fprintf(fpub, "%s", Ecc384_pub_key_define);
else if (ecc_key_size == 66)
fprintf(fpub, "%s", Ecc521_pub_key_define);
else
fprintf(fpub, "#error Unknown ecc key size");
memcpy(k_buffer, Qx, ecc_key_size);
memcpy(k_buffer + ecc_key_size, Qy, ecc_key_size);
fwritekey(Qx, qxsize, fpub);
fprintf(fpub, ",");
fwritekey(Qy, qysize, fpub);
fprintf(fpub, "\n};\n");
if (ecc_key_size == 32)
fprintf(fpub, "const uint32_t ecc256_pub_key_len = 64;\n");
keystore_add(KEYGEN_ECC256, k_buffer, 2 * ecc_key_size, priv_fname);
else if (ecc_key_size == 48)
fprintf(fpub, "const uint32_t ecc384_pub_key_len = 96;\n");
keystore_add(KEYGEN_ECC384, k_buffer, 2 * ecc_key_size, priv_fname);
else if (ecc_key_size == 66)
fprintf(fpub, "const uint32_t ecc521_pub_key_len = 132;\n");
fclose(fpub);
keystore_add(KEYGEN_ECC521, k_buffer, 2 * ecc_key_size, priv_fname);
}
#endif
#ifdef HAVE_ED25519
static void keygen_ed25519(WC_RNG *rng, char *pubkfile)
static void keygen_ed25519(const char *privkey)
{
ed25519_key k;
uint8_t priv[32], pub[32];
FILE *fpriv, *fpub;
FILE *fpriv;
uint32_t outlen = ED25519_KEY_SIZE;
if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &k) != 0) {
if (wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &k) != 0) {
fprintf(stderr, "Unable to create ed25519 key\n");
exit(1);
}
@ -262,36 +379,26 @@ static void keygen_ed25519(WC_RNG *rng, char *pubkfile)
fprintf(stderr, "Unable to export ed25519 public key\n");
exit(2);
}
fpriv = fopen("ed25519.der", "wb");
fpriv = fopen(privkey, "wb");
if (fpriv == NULL) {
fprintf(stderr, "Unable to open file 'ed25519.der' for writing: %s", strerror(errno));
fprintf(stderr, "Unable to open file '%s' for writing: %s", privkey, strerror(errno));
exit(3);
}
fwrite(priv, 32, 1, fpriv);
fwrite(pub, 32, 1, fpriv);
fclose(fpriv);
fpub = fopen(pubkfile, "w");
if (fpub == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", pubkfile, strerror(errno));
exit(4);
}
fprintf(fpub, "%s", Cfile_Banner);
fprintf(fpub, "%s", Ed25519_pub_key_define);
fwritekey(pub, 32, fpub);
fprintf(fpub, "\n};\n");
fprintf(fpub, "const uint32_t ed25519_pub_key_len = 32;\n");
fclose(fpub);
keystore_add(KEYGEN_ED25519, pub, ED25519_PUB_KEY_SIZE, privkey);
}
#endif
#ifdef HAVE_ED448
static void keygen_ed448(WC_RNG *rng, char *pubkfile)
static void keygen_ed448(const char *privkey)
{
ed448_key k;
uint8_t priv[ED448_KEY_SIZE], pub[ED448_PUB_KEY_SIZE];
FILE *fpriv, *fpub;
FILE *fpriv;
uint32_t outlen = ED448_KEY_SIZE;
if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &k) != 0) {
if (wc_ed448_make_key(&rng, ED448_KEY_SIZE, &k) != 0) {
fprintf(stderr, "Unable to create ed448 key\n");
exit(1);
}
@ -303,7 +410,7 @@ static void keygen_ed448(WC_RNG *rng, char *pubkfile)
fprintf(stderr, "Unable to export ed448 public key\n");
exit(2);
}
fpriv = fopen("ed448.der", "wb");
fpriv = fopen(privkey, "wb");
if (fpriv == NULL) {
fprintf(stderr, "Unable to open file 'ed448.der' for writing: %s", strerror(errno));
exit(3);
@ -311,158 +418,179 @@ static void keygen_ed448(WC_RNG *rng, char *pubkfile)
fwrite(priv, ED448_KEY_SIZE, 1, fpriv);
fwrite(pub, ED448_PUB_KEY_SIZE, 1, fpriv);
fclose(fpriv);
fpub = fopen(pubkfile, "w");
if (fpub == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", pubkfile, strerror(errno));
exit(4);
}
fprintf(fpub, "%s", Cfile_Banner);
fprintf(fpub, "%s", Ed448_pub_key_define);
fwritekey(pub, ED448_KEY_SIZE, fpub);
fprintf(fpub, "\n};\n");
fprintf(fpub, "const uint32_t ed448_pub_key_len = 57;\n");
fclose(fpub);
keystore_add(KEYGEN_ED448, pub, ED448_PUB_KEY_SIZE, privkey);
}
#endif
static void key_generate(uint32_t ktype, const char *kfilename)
{
FILE *f;
f = fopen(kfilename, "rb");
if (!force && (f != NULL)) {
char reply[40];
int replySz;
printf("** Warning: key file already exist! Are you sure you want to generate a new key and overwrite the existing key? [Type 'Yes']: ");
fflush(stdout);
replySz = scanf("%s", reply);
printf("Reply is [%s]\n", reply);
fclose(f);
if (replySz < 0 || strcmp(reply, "Yes") != 0) {
printf("Operation aborted by user.");
exit(5);
} else {
unlink(kfilename);
}
}
printf("Generating key (type: %s)\n", KName[ktype]);
fflush(stdout);
switch (ktype) {
#ifdef HAVE_ED25519
case KEYGEN_ED25519:
keygen_ed25519(kfilename);
break;
#endif
#ifdef HAVE_ED448
case KEYGEN_ED448:
keygen_ed448(kfilename);
break;
#endif
#ifdef HAVE_ECC
case KEYGEN_ECC256:
keygen_ecc(kfilename, 32);
break;
case KEYGEN_ECC384:
keygen_ecc(kfilename, 48);
break;
case KEYGEN_ECC521:
keygen_ecc(kfilename, 66);
break;
#endif
#ifndef NO_RSA
case KEYGEN_RSA2048:
keygen_rsa(kfilename, 2048);
break;
case KEYGEN_RSA3072:
keygen_rsa(kfilename, 3072);
break;
case KEYGEN_RSA4096:
keygen_rsa(kfilename, 4096);
break;
#endif
} /* end switch */
}
static void key_import(uint32_t ktype, const char *fname)
{
uint8_t buf[KEYSLOT_MAX_PUBKEY_SIZE];
FILE *f;
int r;
f = fopen(fname, "rb");
if (f == NULL) {
fprintf(stderr, "Fatal error: could not open file %s to import public key\n", fname);
exit(6);
}
r = fread(buf, sizeof(buf), 1, f);
keystore_add(ktype, buf, r, fname);
}
int main(int argc, char** argv)
{
int i;
int force = 0;
int keytype = 0;
const char *kfilename = NULL;
char *output_pubkey_file;
WC_RNG rng;
FILE *f;
uint32_t n_pubkeys = 0;
#ifdef DEBUG_SIGNTOOL
wolfSSL_Debugging_ON();
#endif
/* Check arguments and print usage */
if (argc < 2 || argc > 4)
if (argc < 2)
usage(argv[0]);
for (i = 1; i < argc - 1; i++) {
/* Parse Arguments */
for (i = 1; i < argc; i++) {
/* Parse Arguments */
if (strcmp(argv[i], "--ed25519") == 0) {
keytype = KEYGEN_ED25519;
kfilename = strdup("ed25519.der");
}
else if (strcmp(argv[i], "--ed448") == 0) {
keytype = KEYGEN_ED448;
kfilename = strdup("ed448.der");
}
else if (strcmp(argv[i], "--ecc256") == 0) {
keytype = KEYGEN_ECC256;
kfilename = strdup("ecc256.der");
}
else if (strcmp(argv[i], "--ecc384") == 0) {
keytype = KEYGEN_ECC384;
kfilename = strdup("ecc384.der");
}
else if (strcmp(argv[i], "--ecc521") == 0) {
keytype = KEYGEN_ECC521;
kfilename = strdup("ecc521.der");
}
else if (strcmp(argv[i], "--rsa2048") == 0) {
keytype = KEYGEN_RSA2048;
kfilename = strdup("rsa2048.der");
}
else if (strcmp(argv[i], "--rsa3072") == 0) {
keytype = KEYGEN_RSA3072;
kfilename = strdup("rsa3072.der");
}
else if (strcmp(argv[i], "--rsa4096") == 0) {
keytype = KEYGEN_RSA4096;
kfilename = strdup("rsa4096.der");
}
else if (strcmp(argv[i], "--force") == 0) {
force = 1;
}
else if (strcmp(argv[i], "-g") == 0) {
i++;
n_pubkeys++;
continue;
}
else if (strcmp(argv[i], "-i") == 0) {
i++;
n_pubkeys++;
continue;
}
else {
fprintf(stderr, "Invalid argument '%s'.", argv[i]);
usage(argv[0]);
}
}
output_pubkey_file = strdup(argv[argc - 1]);
f = fopen(kfilename, "rb");
if (!force && (f != NULL)) {
char reply[40];
int replySz;
fclose(f);
printf("** Warning: key file already exist! Are you sure you want to generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ");
fflush(stdout);
replySz = scanf("%s", reply);
printf("Reply is [%s]\n", reply);
if (replySz < 0 || strcmp(reply, "Yes, I am sure!") != 0) {
printf("Operation aborted by user.");
exit(5);
printf("Keytype: %s\n", KName[keytype]);
if (keytype == 0)
exit(0);
fpub = fopen(pubkeyfile, "w");
if (fpub == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", pubkeyfile, strerror(errno));
exit(4);
}
fpub_image = fopen(pubkeyimg, "wb");
if (fpub_image == NULL) {
fprintf(stderr, "Unable to open file '%s' for writing: %s", pubkeyimg, strerror(errno));
exit(4);
}
wc_InitRng(&rng);
fprintf(fpub, Cfile_Banner, KName[keytype]);
fprintf(fpub, Store_hdr, n_pubkeys);
for (i = 1; i < argc - 1; i++) {
if (strcmp(argv[i], "-i") == 0) {
printf("Imp %s\n", argv[i + 1]);
key_import(keytype, argv[i + 1]);
i++;
}
else if (strcmp(argv[i], "-g") == 0) {
printf("Gen %s\n", argv[i + 1]);
key_generate(keytype, argv[i + 1]);
i++;
}
}
printf("Private key: %s\n", kfilename);
printf("Generated public key C file: %s\n", output_pubkey_file);
printf("Generating key...\n");
fflush(stdout);
wc_InitRng(&rng);
switch (keytype) {
#ifdef HAVE_ED25519
case KEYGEN_ED25519:
{
keygen_ed25519(&rng, output_pubkey_file);
break;
}
#endif
#ifdef HAVE_ED448
case KEYGEN_ED448:
{
keygen_ed448(&rng, output_pubkey_file);
break;
}
#endif
#ifdef HAVE_ECC
case KEYGEN_ECC256:
{
keygen_ecc(&rng, output_pubkey_file, 32);
break;
}
case KEYGEN_ECC384:
{
keygen_ecc(&rng, output_pubkey_file, 48);
break;
}
case KEYGEN_ECC521:
{
keygen_ecc(&rng, output_pubkey_file, 66);
break;
}
#endif
#ifndef NO_RSA
case KEYGEN_RSA2048:
{
keygen_rsa(&rng, output_pubkey_file, 2048);
break;
}
case KEYGEN_RSA3072:
{
keygen_rsa(&rng, output_pubkey_file, 3072);
break;
}
case KEYGEN_RSA4096:
{
keygen_rsa(&rng, output_pubkey_file, 4096);
break;
}
#endif
} /* end switch */
wc_FreeRng(&rng);
fprintf(fpub, Store_footer);
fprintf(fpub, Keystore_API);
if (fpub)
fclose(fpub);
if (fpub_image)
fclose(fpub_image);
printf("Done.\n");
return 0;
}

View File

@ -21,11 +21,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
'''
import sys,os
import sys,os,struct
from wolfcrypt import ciphers
AUTH_KEY_ED25519 = 0x01
AUTH_KEY_ECC256 = 0x02
AUTH_KEY_RSA2048 = 0x03
AUTH_KEY_RSA4096 = 0x04
AUTH_KEY_ED448 = 0x05
AUTH_KEY_ECC384 = 0x06
AUTH_KEY_ECC521 = 0x07
AUTH_KEY_RSA3072 = 0x08
#default sign algorithm value
sign="ed25519"
def usage():
print("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 | --ecc521 | --rsa2048| --rsa3072 | --rsa4096] [ --force ] pub_key_file.c\n" % sys.argv[0])
print("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 | --ecc521 | --rsa2048| --rsa3072 | --rsa4096] [ --force ] [-i pubkey0.der [-i pubkey1.der -i pubkey2.der ... -i pubkeyN.der]] [-i pubkey0.der [-i pubkey1.der -i pubkey2.der ... -i pubkeyN.der]]n" % sys.argv[0])
parser.print_help()
sys.exit(1)
@ -35,23 +48,115 @@ def dupsign():
print("")
usage()
Cfile_Banner="/* Public-key file for wolfBoot, automatically generated. Do not edit. */\n"+ \
def sign_key_type(name):
if name == 'ed25519':
return 'AUTH_KEY_ED25519'
elif name == 'ed448':
return 'AUTH_KEY_ED448'
elif name == 'ecc256':
return 'AUTH_KEY_ECC256'
elif name == 'ecc384':
return 'AUTH_KEY_ECC384'
elif name == 'ecc521':
return 'AUTH_KEY_ECC521'
elif name == 'rsa2048':
return 'AUTH_KEY_RSA2048'
elif name == 'rsa3072':
return 'AUTH_KEY_RSA3072'
elif name == 'rsa4096':
return 'AUTH_KEY_RSA4096'
else:
return 0
def sign_key_size(name):
if name == 'ed25519':
return 'KEYSTORE_PUBKEY_SIZE_ED25519'
elif name == 'ed448':
return 'KEYSTORE_PUBKEY_SIZE_ED448'
elif name == 'ecc256':
return 'KEYSTORE_PUBKEY_SIZE_ECC256'
elif name == 'ecc384':
return 'KEYSTORE_PUBKEY_SIZE_ECC384'
elif name == 'ecc521':
return 'KEYSTORE_PUBKEY_SIZE_ECC521'
elif name == 'rsa2048':
return 'KEYSTORE_PUBKEY_SIZE_RSA2048'
elif name == 'rsa3072':
return 'KEYSTORE_PUBKEY_SIZE_RSA3072'
elif name == 'rsa4096':
return 'KEYSTORE_PUBKEY_SIZE_RSA4096'
else:
return 0
def keystore_add(slot, pub, sz = 0):
ktype = sign_key_type(sign)
if (sz == 0):
ksize = sign_key_size(sign)
else:
ksize = str(sz)
pfile.write(Slot_hdr % (key_file, slot, ktype, ksize))
i = 0
for c in bytes(pub[0:-1]):
pfile.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
pfile.write('\n\t\t\t')
pfile.write("0x%02X" % pub[-1])
pfile.write(Pubkey_footer)
pfile.write(Slot_footer)
t = 0x8A8A8A8A
m = 0xFFFFFFFF
ks_struct = struct.pack("<LLLL", slot, t, m, len(pub))
ks_struct += pub
ksfile.write(ks_struct)
Cfile_Banner="/* Keystore file for wolfBoot, automatically generated. Do not edit. */\n"+ \
"/*\n" + \
" * This file has been generated and contains the public key which is\n"+ \
" * This file has been generated and contains the public keys\n"+ \
" * used by wolfBoot to verify the updates.\n"+ \
" */" \
"\n#include <stdint.h>\n\n"
"\n#include <stdint.h>\n#include \"wolfboot/wolfboot.h\"\n" \
"#ifdef WOLFBOOT_NO_SIGN\n\t#define NUM_PUBKEYS 0\n#else\n\n" \
"#if (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_%s)\n\t" \
"#error Key algorithm mismatch. Remove old keys via 'make distclean'\n" \
"#else\n"
Ed25519_pub_key_define = "const uint8_t ed25519_pub_key[32] = {\n\t"
Ed448_pub_key_define= "const uint8_t ed448_pub_key[57] = {\n\t"
Ecc256_pub_key_define = "const uint8_t ecc256_pub_key[64] = {\n\t"
Ecc384_pub_key_define = "const uint8_t ecc384_pub_key[96] = {\n\t"
Ecc521_pub_key_define = "const uint8_t ecc521_pub_key[132] = {\n\t"
Rsa_2048_pub_key_define = "const uint8_t rsa2048_pub_key[%d] = {\n\t"
Rsa_3072_pub_key_define = "const uint8_t rsa3072_pub_key[%d] = {\n\t"
Rsa_4096_pub_key_define = "const uint8_t rsa4096_pub_key[%d] = {\n\t"
sign="ed25519"
Store_hdr = "#define NUM_PUBKEYS %d\nconst struct keystore_slot PubKeys[NUM_PUBKEYS] = {\n\n"
Slot_hdr = "\t /* Key associated to file '%s' */\n"
Slot_hdr += "\t{\n\t\t.slot_id = %d,\n\t\t.key_type = %s,\n"
Slot_hdr += "\t\t.part_id_mask = KEY_VERIFY_ALL,\n\t\t.pubkey_size = %s,\n"
Slot_hdr += "\t\t.pubkey = {\n\t\t\t"
Pubkey_footer = "\n\t\t},"
Slot_footer = "\n\t},\n\n"
Store_footer = '\n};\n\n'
Keystore_API = "int keystore_num_pubkeys(void)\n"
Keystore_API += "{\n"
Keystore_API += " return NUM_PUBKEYS;\n"
Keystore_API += "}\n\n"
Keystore_API += "uint8_t *keystore_get_buffer(int id)\n"
Keystore_API += "{\n"
Keystore_API += " if (id >= keystore_num_pubkeys())\n"
Keystore_API += " return (uint8_t *)0;\n"
Keystore_API += " return (uint8_t *)PubKeys[id].pubkey;\n"
Keystore_API += "}\n\n"
Keystore_API += "int keystore_get_size(int id)\n"
Keystore_API += "{\n"
Keystore_API += " if (id >= keystore_num_pubkeys())\n"
Keystore_API += " return -1;\n"
Keystore_API += " return (int)PubKeys[id].pubkey_size;\n"
Keystore_API += "}\n\n"
Keystore_API += "uint32_t keystore_get_mask(int id)\n"
Keystore_API += "{\n"
Keystore_API += " if (id >= keystore_num_pubkeys())\n"
Keystore_API += " return -1;\n"
Keystore_API += " return (int)PubKeys[id].part_id_mask;\n"
Keystore_API += "}\n\n"
Keystore_API += "#endif /* Keystore public key size check */\n"
Keystore_API += "#endif /* WOLFBOOT_NO_SIGN */\n"
import argparse as ap
@ -65,14 +170,24 @@ parser.add_argument('--rsa2048', dest='rsa2048', action='store_true')
parser.add_argument('--rsa3072', dest='rsa3072', action='store_true')
parser.add_argument('--rsa4096', dest='rsa4096', action='store_true')
parser.add_argument('--force', dest='force', action='store_true')
parser.add_argument('cfile')
parser.add_argument('-i', dest='pubfile', nargs='+', action='extend')
parser.add_argument('-g', dest='keyfile', nargs='+', action='extend')
args=parser.parse_args()
#print(args.ecc256)
#sys.exit(0) #test
pubkey_cfile = args.cfile
pubkey_cfile = "src/keystore.c"
keystore_imgfile = "keystore.der"
key_files = args.keyfile
pubkey_files = args.pubfile
print("keys to import:")
print(pubkey_files)
print("keys to generate:")
print(key_files)
sign=None
force=False
if (args.ed25519):
@ -93,6 +208,8 @@ if (args.ecc521):
if sign is not None:
dupsign()
sign='ecc521'
print("ecc521 keys are not yet supported!")
sys.exit(1)
if (args.rsa2048):
if sign is not None:
dupsign()
@ -115,218 +232,123 @@ force = args.force
if pubkey_cfile[-2:] != '.c':
print("** Warning: generated public key cfile does not have a '.c' extension")
key_file=sign+".der"
print ("Selected cipher: " + sign)
print ("Output Private key: " + key_file)
# Create/open public key c file
print ("Output C file: " + pubkey_cfile)
print()
pfile = open(pubkey_cfile, "w")
pfile.write(Cfile_Banner % sign.upper())
pfile.write(Store_hdr % len(key_files))
ksfile = open(keystore_imgfile, "wb")
if (sign == "ed25519"):
ed = ciphers.Ed25519Private.make_key(32)
priv,pub = ed.encode_key()
pub_slot_index = 0
if pubkey_files != None:
for pub_slot_index, key_file in enumerate(pubkey_files):
print ("Public key slot: " + str(pub_slot_index))
print ("Selected cipher: " + sign)
print ("Input public key: " + key_file)
with open(key_file, 'rb') as f:
key = f.read(4096)
keystore_add(pub_slot_index, key)
pub_slot_index = len(pubkey_files)
for slot_index_off, key_file in enumerate(key_files):
slot_index = slot_index_off + pub_slot_index
print ("Public key slot: " + str(slot_index))
print ("Selected cipher: " + sign)
print ("Output Private key: " + key_file)
print()
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
"generate a new key and overwrite the existing key? [Type 'Yes']: ")
if (choice != "Yes"):
print("Operation canceled.")
sys.exit(2)
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.write(pub)
f.close()
print("Creating file " + pubkey_cfile)
with open(pubkey_cfile, "w") as f:
f.write(Cfile_Banner)
f.write(Ed25519_pub_key_define)
i = 0
for c in bytes(pub[0:-1]):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n\t')
f.write("0x%02X" % pub[-1])
f.write("\n};\n")
f.write("const uint32_t ed25519_pub_key_len = 32;\n")
f.close()
if (sign == "ed25519"):
ed = ciphers.Ed25519Private.make_key(32)
priv,pub = ed.encode_key()
if (sign == "ed448"):
ed = ciphers.Ed448Private.make_key(57)
priv,pub = ed.encode_key()
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
print("Operation canceled.")
sys.exit(2)
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.write(pub)
f.close()
keystore_add(slot_index, pub)
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.write(pub)
f.close()
print("Creating file " + pubkey_cfile)
with open(pubkey_cfile, "w") as f:
f.write(Cfile_Banner)
f.write(Ed448_pub_key_define)
i = 0
for c in bytes(pub[0:-1]):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n\t')
f.write("0x%02X" % pub[-1])
f.write("\n};\n")
f.write("const uint32_t ed448_pub_key_len = 57;\n")
f.close()
if (sign[0:3] == 'ecc'):
if (sign == "ecc256"):
ec = ciphers.EccPrivate.make_key(32)
banner = Ecc256_pub_key_define
ecc_pub_key_len = 64
qx,qy,d = ec.encode_key_raw()
if (sign == "ed448"):
ed = ciphers.Ed448Private.make_key(57)
priv,pub = ed.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.write(pub)
f.close()
keystore_add(slot_index, pub)
if (sign[0:3] == 'ecc'):
if (sign == "ecc256"):
ec = ciphers.EccPrivate.make_key(32)
ecc_pub_key_len = 64
qx,qy,d = ec.encode_key_raw()
if (sign == "ecc384"):
ec = ciphers.EccPrivate.make_key(48)
ecc_pub_key_len = 96
qx,qy,d = ec.encode_key_raw()
if (sign == "ecc521"):
ec = ciphers.EccPrivate.make_key(66)
ecc_pub_key_len = 132
qx,qy,d = ec.encode_key_raw()
print()
print("Creating file " + key_file)
keystore_add(slot_index, bytes(qx) + bytes(qy))
with open(key_file, "wb") as f:
f.write(qx)
f.write(qy)
f.write(d)
f.close()
if (sign == "rsa2048"):
rsa = ciphers.RsaPrivate.make_key(2048)
priv,pub = rsa.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.close()
print("Creating file " + pubkey_cfile)
keystore_add(slot_index, pub, len(pub))
if (sign == "rsa3072"):
rsa = ciphers.RsaPrivate.make_key(3072)
priv,pub = rsa.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.close()
keystore_add(slot_index, pub, len(pub))
if (sign == "rsa4096"):
rsa = ciphers.RsaPrivate.make_key(4096)
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
"generate a new key and overwrite the existing key? [Type 'Yes']: ")
if (choice != "Yes"):
print("Operation canceled.")
sys.exit(2)
priv,pub = rsa.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.close()
keystore_add(slot_index, pub, len(pub))
if (sign == "ecc384"):
ec = ciphers.EccPrivate.make_key(48)
banner = Ecc384_pub_key_define
ecc_pub_key_len = 96
qx,qy,d = ec.encode_key_raw()
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
print("Operation canceled.")
sys.exit(2)
if (sign == "ecc521"):
ec = ciphers.EccPrivate.make_key(66)
banner = Ecc521_pub_key_define
ecc_pub_key_len = 132
qx,qy,d = ec.encode_key_raw()
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
print("Operation canceled.")
sys.exit(2)
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(qx)
f.write(qy)
f.write(d)
f.close()
print("Creating file " + pubkey_cfile)
with open(pubkey_cfile, "w") as f:
f.write(Cfile_Banner)
f.write(banner)
i = 0
for c in bytes(qx):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n')
for c in bytes(qy[0:-1]):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n')
f.write("0x%02X" % qy[-1])
f.write("\n};\n")
f.write("const uint32_t %s_pub_key_len = %d;\n" % (sign, ecc_pub_key_len))
f.close()
if (sign == "rsa2048"):
rsa = ciphers.RsaPrivate.make_key(2048)
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
print("Operation canceled.")
sys.exit(2)
priv,pub = rsa.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.close()
print("Creating file " + pubkey_cfile)
with open(pubkey_cfile, "w") as f:
f.write(Cfile_Banner)
f.write(Rsa_2048_pub_key_define % len(pub))
i = 0
for c in bytes(pub):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n')
f.write("\n};\n")
f.write("const uint32_t rsa2048_pub_key_len = %d;\n" % len(pub))
f.close()
if (sign == "rsa3072"):
rsa = ciphers.RsaPrivate.make_key(3072)
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
print("Operation canceled.")
sys.exit(2)
priv,pub = rsa.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.close()
print("Creating file " + pubkey_cfile)
with open(pubkey_cfile, "w") as f:
f.write(Cfile_Banner)
f.write(Rsa_3072_pub_key_define % len(pub))
i = 0
for c in bytes(pub):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n')
f.write("\n};\n")
f.write("const uint32_t rsa3072_pub_key_len = %d;\n" % len(pub))
f.close()
if (sign == "rsa4096"):
rsa = ciphers.RsaPrivate.make_key(4096)
if os.path.exists(key_file) and not force:
choice = input("** Warning: key file already exist! Are you sure you want to "+
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
if (choice != "Yes, I am sure!"):
print("Operation canceled.")
sys.exit(2)
priv,pub = rsa.encode_key()
print()
print("Creating file " + key_file)
with open(key_file, "wb") as f:
f.write(priv)
f.close()
print("Creating file " + pubkey_cfile)
with open(pubkey_cfile, "w") as f:
f.write(Cfile_Banner)
f.write(Rsa_4096_pub_key_define % len(pub))
i = 0
for c in bytes(pub):
f.write("0x%02X, " % c)
i += 1
if (i % 8 == 0):
f.write('\n')
f.write("\n};\n")
f.write("const uint32_t rsa4096_pub_key_len = %d;\n" % len(pub))
f.close()
pfile.write(Store_footer)
pfile.write(Keystore_API)
pfile.close()

View File

@ -399,14 +399,18 @@ if manual_sign:
if not sha_only:
if '.' in image_file:
tokens = image_file.split('.')
output_image_file = image_file.rstrip('.' + tokens[-1])
output_image_file = ''
for x in tokens[0:-1]:
output_image_file+=x
output_image_file += "_v" + str(fw_version) + "_signed.bin"
else:
output_image_file = image_file + "_v" + str(fw_version) + "_signed.bin"
else:
if '.' in image_file:
tokens = image_file.split('.')
output_image_file = image_file.rstrip('.' + tokens[-1])
output_image_file = ''
for x in tokens[0:-1]:
output_image_file+=x
output_image_file += "_v" + str(fw_version) + "_digest.bin"
else:
output_image_file = image_file + "_v" + str(fw_version) + "_digest.bin"
@ -414,7 +418,9 @@ else:
if delta and encrypt:
if '.' in image_file:
tokens = image_file.split('.')
encrypted_output_image_file = image_file.rstrip('.' + tokens[-1])
encrypted_image_file = ''
for x in tokens[0:-1]:
encrypted_image_file += x
encrypted_output_image_file += "_v" + str(fw_version) + "_signed_diff_encrypted.bin"
else:
encrypted_output_image_file = image_file + "_v" + str(fw_version) + "_signed_diff_encrypted.bin"
@ -422,7 +428,9 @@ if delta and encrypt:
elif encrypt:
if '.' in image_file:
tokens = image_file.split('.')
encrypted_output_image_file = image_file.rstrip('.' + tokens[-1])
encrypted_output_file = ''
for x in tokens[0:-1]:
encrypted_output_file += x
encrypted_output_image_file += "_v" + str(fw_version) + "_signed_and_encrypted.bin"
else:
encrypted_output_image_file = image_file + "_v" + str(fw_version) + "_signed_and_encrypted.bin"
@ -430,7 +438,9 @@ elif encrypt:
if delta:
if '.' in image_file:
tokens = image_file.split('.')
delta_output_image_file = image_file.rstrip('.' + tokens[-1])
delta_output_image_file = ''
for x in tokens[0:-1]:
delta_output_image_file += x
delta_output_image_file += "_v" + str(fw_version) + "_signed_diff.bin"
else:
delta_output_image_file = image_file + "_v" + str(fw_version) + "_signed_diff.bin"
@ -443,7 +453,7 @@ else:
print ("Input image: " + image_file)
print ("Selected cipher: " + sign)
print ("Public key: " + key_file)
print ("Private key: " + key_file)
if not sha_only:
print ("Output image: " + output_image_file)

View File

@ -251,26 +251,26 @@ renode-factory-rsa4096: FORCE
make renode-factory SIGN=RSA4096
renode-factory-all: FORCE
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-ed25519
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-ed448 RENODE_PORT=55156
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-ecc256 RENODE_PORT=55157
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-ecc384 RENODE_PORT=55158
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-rsa2048 RENODE_PORT=55160
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-rsa3072 RENODE_PORT=55161
${Q}make clean
${Q}make keysclean
${Q}make renode-factory-rsa4096 RENODE_PORT=55162
${Q}make clean
${Q}make keysclean
${Q}make renode-factory SIGN=NONE RENODE_PORT=55163
${Q}echo All tests in $@ OK!
renode-update-ed25519: FORCE
make renode-update SIGN=ED448
make renode-update SIGN=ED25519
renode-update-ed448: FORCE
make renode-update SIGN=ED448
@ -330,59 +330,59 @@ renode-boot-time-all: FORCE
tools/scripts/renode-test-all.sh 2>/dev/null |grep "BOOT TIME"
renode-update-all: FORCE
${Q}make clean
${Q}make keysclean
${Q}make renode-update-ed25519 RENODE_PORT=55155
${Q}make clean
${Q}make keysclean
${Q}make renode-update-ed448 RENODE_PORT=55156
${Q}make clean
${Q}make keysclean
${Q}make renode-update-ecc256 RENODE_PORT=55157
${Q}make clean
${Q}make keysclean
${Q}make renode-update-ecc384 RENODE_PORT=55158
${Q}make clean
${Q}make keysclean
${Q}make renode-update-rsa2048 RENODE_PORT=55160
${Q}make clean
${Q}make keysclean
${Q}make renode-update-rsa3072 RENODE_PORT=55161
${Q}make clean
${Q}make keysclean
${Q}make renode-update-rsa4096 RENODE_PORT=55162
${Q}make clean
${Q}make keysclean
${Q}make renode-update SIGN=NONE RENODE_PORT=55163
${Q}echo All tests in $@ OK!
renode-no-downgrade-all: FORCE
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-ed25519 RENODE_PORT=55155
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-ed448 RENODE_PORT=55156
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-ecc256 RENODE_PORT=55157
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-ecc384 RENODE_PORT=55158
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-rsa2048 RENODE_PORT=55160
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-rsa3072 RENODE_PORT=55161
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade-rsa4096 RENODE_PORT=55162
${Q}make clean
${Q}make keysclean
${Q}make renode-no-downgrade SIGN=NONE RENODE_PORT=55163
${Q}echo All tests in $@ OK!
renode-corrupted-all: FORCE
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-ed25519 RENODE_PORT=55155
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-ed448 RENODE_PORT=55156
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-ecc256 RENODE_PORT=55157
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-ecc384 RENODE_PORT=55158
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-rsa2048 RENODE_PORT=55160
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-rsa3072 RENODE_PORT=55161
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted-rsa4096 RENODE_PORT=55162
${Q}make clean
${Q}make keysclean
${Q}make renode-corrupted SIGN=NONE RENODE_PORT=55163
${Q}echo All tests in $@ OK!

View File

@ -17,8 +17,6 @@ else
endif
endif
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign)","")
SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign
else
@ -656,20 +654,29 @@ test-base: clean
@echo ==========
@echo
@echo
@make keysclean
make test-01-forward-update-no-downgrade
make test-02-forward-update-allow-downgrade test-03-rollback
@make keysclean
make test-11-forward-update-no-downgrade-ECC test-13-rollback-ECC
@make keysclean
make test-21-forward-update-no-downgrade-SPI test-23-rollback-SPI
make test-34-forward-self-update
@make keysclean
make test-44-forward-self-update-ECC
@make keysclean
make test-51-forward-update-no-downgrade-RSA
make test-53-rollback-RSA
@make keysclean
make test-61-forward-update-no-downgrade-TPM
make test-63-rollback-TPM
@make keysclean
make test-71-forward-update-no-downgrade-RSA-4096
make test-73-rollback-RSA-4096
@make keysclean
make test-74-forward-update-no-downgrade-ED448
make test-75-rollback-ED448
@make keysclean
make test-76-forward-update-no-downgrade-RSA3072
make test-77-rollback-RSA3072
@ -678,11 +685,17 @@ test-sha3: clean
@echo ==========
@echo
@echo
@make keysclean
make test-81-forward-update-no-downgrade-ED25519-SHA3
@make keysclean
make test-91-forward-update-no-downgrade-ECC256-SHA3
@make keysclean
make test-101-forward-update-no-downgrade-RSA2048-SHA3
@make keysclean
make test-111-forward-update-no-downgrade-RSA4096-SHA3
@make keysclean
make test-112-forward-update-no-downgrade-ED448-SHA3
@make keysclean
make test-113-forward-update-no-downgrade-RSA3072-SHA3
test-tpm: clean
@ -690,6 +703,7 @@ test-tpm: clean
@echo ==========
@echo
@echo
@make keysclean
make test-161-forward-update-no-downgrade-TPM-RSA
make test-163-rollback-TPM-RSA
@ -698,6 +712,7 @@ test-nosign: clean
@echo ==========
@echo
@echo
@make keysclean
make test-171-forward-update-no-downgrade-NOSIGN
make test-173-rollback-NOSIGN
@ -706,17 +721,29 @@ test-smallstack: clean
@echo ==========
@echo
@echo
@make keysclean
make test-201-smallstack-forward-update-no-downgrade
@make keysclean
make test-211-smallstack-forward-update-no-downgrade-ECC
@make keysclean
make test-221-smallstack-forward-update-no-downgrade-SPI
@make keysclean
make test-251-smallstack-forward-update-no-downgrade-RSA
@make keysclean
make test-271-smallstack-forward-update-no-downgrade-RSA4096
@make keysclean
make test-274-smallstack-forward-update-no-downgrade-ED448
@make keysclean
make test-281-smallstack-forward-update-no-downgrade-ED25519-SHA3
@make keysclean
make test-291-smallstack-forward-update-no-downgrade-ECC256-SHA3
@make keysclean
make test-301-smallstack-forward-update-no-downgrade-RSA2048-SHA3
@make keysclean
make test-311-smallstack-forward-update-no-downgrade-RSA4096-SHA3
@make keysclean
make test-312-smallstack-forward-update-no-downgrade-ED448-SHA3
@make keysclean
make test-371-smallstack-forward-update-no-downgrade-NOSIGN
test-fastmath: clean
@ -724,17 +751,29 @@ test-fastmath: clean
@echo ==========
@echo
@echo
@make keysclean
make test-401-fastmath-forward-update-no-downgrade
@make keysclean
make test-411-fastmath-forward-update-no-downgrade-ECC
@make keysclean
make test-421-fastmath-forward-update-no-downgrade-SPI
@make keysclean
make test-451-fastmath-forward-update-no-downgrade-RSA
@make keysclean
true || make test-471-fastmath-forward-update-no-downgrade-RSA4096 #Not enough RAM
@make keysclean
make test-474-fastmath-forward-update-no-downgrade-ED448
@make keysclean
make test-481-fastmath-forward-update-no-downgrade-ED25519-SHA3
@make keysclean
make test-491-fastmath-forward-update-no-downgrade-ECC256-SHA3
@make keysclean
make test-501-fastmath-forward-update-no-downgrade-RSA2048-SHA3
@make keysclean
true || make test-511-fastmath-forward-update-no-downgrade-RSA4096-SHA3 #Not enough RAM
@make keysclean
make test-512-fastmath-forward-update-no-downgrade-ED448-SHA3
@make keysclean
make test-571-fastmath-forward-update-no-downgrade-NOSIGN
test-no-asm: clean
@ -742,17 +781,29 @@ test-no-asm: clean
@echo ==========
@echo
@echo
@make keysclean
make test-601-no-asm-forward-update-no-downgrade
@make keysclean
make test-611-no-asm-forward-update-no-downgrade-ECC
@make keysclean
make test-621-no-asm-forward-update-no-downgrade-SPI
@make keysclean
make test-651-no-asm-forward-update-no-downgrade-RSA
@make keysclean
make test-671-no-asm-forward-update-no-downgrade-RSA4096
@make keysclean
make test-674-no-asm-forward-update-no-downgrade-ED448
@make keysclean
make test-681-no-asm-forward-update-no-downgrade-ED25519-SHA3
@make keysclean
make test-691-no-asm-forward-update-no-downgrade-ECC256-SHA3
@make keysclean
make test-701-no-asm-forward-update-no-downgrade-RSA2048-SHA3
@make keysclean
make test-711-no-asm-forward-update-no-downgrade-RSA4096-SHA3
@make keysclean
make test-712-no-asm-forward-update-no-downgrade-ED448-SHA3
@make keysclean
make test-771-no-asm-forward-update-no-downgrade-NOSIGN
test-no-asm-smallstack: clean
@ -760,17 +811,29 @@ test-no-asm-smallstack: clean
@echo ==========
@echo
@echo
@make keysclean
make test-801-no-asm-smallstack-forward-update-no-downgrade
@make keysclean
make test-811-no-asm-smallstack-forward-update-no-downgrade-ECC
@make keysclean
make test-821-no-asm-smallstack-forward-update-no-downgrade-SPI
@make keysclean
make test-851-no-asm-smallstack-forward-update-no-downgrade-RSA
@make keysclean
make test-871-no-asm-smallstack-forward-update-no-downgrade-RSA4096
@make keysclean
make test-874-no-asm-smallstack-forward-update-no-downgrade-ED448
@make keysclean
make test-881-no-asm-smallstack-forward-update-no-downgrade-ED25519-SHA3
@make keysclean
make test-891-no-asm-smallstack-forward-update-no-downgrade-ECC256-SHA3
@make keysclean
make test-901-no-asm-smallstack-forward-update-no-downgrade-RSA2048-SHA3
@make keysclean
make test-911-no-asm-smallstack-forward-update-no-downgrade-RSA4096-SHA3
@make keysclean
make test-912-no-asm-smallstack-forward-update-no-downgrade-ED448-SHA3
@make keysclean
make test-971-no-asm-smallstack-forward-update-no-downgrade-NOSIGN
test-fastmath-smallstack: clean
@ -778,17 +841,29 @@ test-fastmath-smallstack: clean
@echo ==========
@echo
@echo
@make keysclean
make test-1001-fastmath-smallstack-forward-update-no-downgrade
@make keysclean
make test-1011-fastmath-smallstack-forward-update-no-downgrade-ECC
@make keysclean
make test-1021-fastmath-smallstack-forward-update-no-downgrade-SPI
@make keysclean
make test-1051-fastmath-smallstack-forward-update-no-downgrade-RSA
@make keysclean
make test-1071-fastmath-smallstack-forward-update-no-downgrade-RSA4096
@make keysclean
make test-1074-fastmath-smallstack-forward-update-no-downgrade-ED448
@make keysclean
make test-1081-fastmath-smallstack-forward-update-no-downgrade-ED25519-SHA3
@make keysclean
make test-1091-fastmath-smallstack-forward-update-no-downgrade-ECC256-SHA3
@make keysclean
make test-1101-fastmath-smallstack-forward-update-no-downgrade-RSA2048-SHA3
@make keysclean
make test-1111-fastmath-smallstack-forward-update-no-downgrade-RSA4096-SHA3
@make keysclean
make test-1112-fastmath-smallstack-forward-update-no-downgrade-ED448-SHA3
@make keysclean
make test-1171-fastmath-smallstack-forward-update-no-downgrade-NOSIGN
@ -806,15 +881,28 @@ test-all: clean
test-size-all:
make test-size SIGN=NONE LIMIT=4646
make test-size SIGN=ED25519 LIMIT=11214
make test-size SIGN=ECC256 LIMIT=21958
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13718
make test-size SIGN=RSA2048 LIMIT=12906
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=13070
make test-size SIGN=RSA4096 LIMIT=13242
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=13322
make test-size SIGN=ECC384 LIMIT=17562
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15326
make test-size SIGN=ED448 LIMIT=13558
make test-size SIGN=RSA3072 LIMIT=13098
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=13178
make keysclean
make test-size SIGN=ED25519 LIMIT=11366
make keysclean
make test-size SIGN=ECC256 LIMIT=22118
make keysclean
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13878
make keysclean
make test-size SIGN=RSA2048 LIMIT=13110
make keysclean
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=13274
make keysclean
make test-size SIGN=RSA4096 LIMIT=13446
make keysclean
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=13526
make keysclean
make test-size SIGN=ECC384 LIMIT=17722
make keysclean
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15486
make keysclean
make test-size SIGN=ED448 LIMIT=13718
make keysclean
make test-size SIGN=RSA3072 LIMIT=13302
make keysclean
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=13382
make keysclean