Skip to content

Commit 572e115

Browse files
committed
Added "otp-keystore-primer" tool
1 parent 3257880 commit 572e115

File tree

11 files changed

+580
-37
lines changed

11 files changed

+580
-37
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ tools/keytools/keygen.exe
6969
tools/keytools/x64
7070
tools/keytools/Debug
7171
tools/keytools/Release
72+
tools/keytools/otp/otp-keystore-primer
7273

7374
# delta binaries
7475
tools/delta/bmdiff

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ ifeq ($(TARGET),nxp_t1024)
127127
MAIN_TARGET:=factory_wstage1.bin
128128
endif
129129

130+
ifeq ($(FLASH_OTP_ROT),1)
131+
MAIN_TARGET:=include/target.h tools/keytools/otp/otp-keystore-primer factory.bin
132+
endif
133+
130134
ASFLAGS:=$(CFLAGS)
131135
BOOTLOADER_PARTITION_SIZE?=$$(( $(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET)))
132136

@@ -184,6 +188,7 @@ $(PRIVATE_KEY):
184188
$(Q)$(MAKE) keytools_check
185189
$(Q)(test $(SIGN) = NONE) || ("$(KEYGEN_TOOL)" $(KEYGEN_OPTIONS) -g $(PRIVATE_KEY)) || true
186190
$(Q)(test $(SIGN) = NONE) && (echo "// SIGN=NONE" > src/keystore.c) || true
191+
$(Q)(test $(FLASH_OTP_ROT) = 0) || (make -C tools/keytools/otp) || true
187192

188193
keytools: include/target.h
189194
@echo "Building key tools"
@@ -239,7 +244,7 @@ wolfboot_stage1.bin: wolfboot.elf stage1/loader_stage1.bin
239244
$(Q) cp stage1/loader_stage1.bin wolfboot_stage1.bin
240245

241246
wolfboot.elf: include/target.h $(LSCRIPT) $(OBJS) $(LIBS) $(BINASSEMBLE) FORCE
242-
$(Q)(test $(SIGN) = NONE) || (grep -q $(SIGN_ALG) src/keystore.c) || \
247+
$(Q)(test $(SIGN) = NONE) || (test $(FLASH_OTP_ROT) = 1) || (grep -q $(SIGN_ALG) src/keystore.c) || \
243248
(echo "Key mismatch: please run 'make distclean' to remove all keys if you want to change algorithm" && false)
244249
@echo "\t[LD] $@"
245250
@echo $(OBJS)
@@ -279,6 +284,8 @@ hex: wolfboot.hex
279284

280285
src/keystore.c: $(PRIVATE_KEY)
281286

287+
flash_keystore: $(PRIVATE_KEY) src/flash_otp_keystore.o
288+
282289
keys: $(PRIVATE_KEY)
283290

284291
clean:
@@ -302,6 +309,7 @@ utilsclean: clean
302309
$(Q)$(MAKE) -C tools/test-update-server -s clean
303310
$(Q)$(MAKE) -C tools/uart-flash-server -s clean
304311
$(Q)$(MAKE) -C tools/unit-tests -s clean
312+
$(Q)$(MAKE) -C tools/keytools/otp -s clean
305313

306314
keysclean: clean
307315
$(Q)rm -f *.pem *.der tags ./src/*_pub_key.c ./src/keystore.c include/target.h
@@ -359,6 +367,12 @@ cppcheck:
359367
--suppress="objectIndex" --suppress="comparePointers" \
360368
--error-exitcode=89 --std=c89 src/*.c hal/*.c hal/spi/*.c hal/uart/*.c
361369

370+
otp: tools/keytools/otp/otp-keystore-primer.bin
371+
372+
tools/keytools/otp/otp-keystore-primer.bin: FORCE
373+
make -C tools/keytools/otp clean
374+
make -C tools/keytools/otp
375+
362376
%.o:%.c
363377
@echo "\t[CC-$(ARCH)] $@"
364378
$(Q)$(CC) $(CFLAGS) -c $(OUTPUT_FLAG) $@ $^

hal/stm32h7.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ static void hal_flash_otp_lock(void)
543543

544544
/* Public API */
545545

546-
int hal_flash_otp_write(uint32_t flashAddress, uint16_t* data, uint16_t length)
546+
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
547547
{
548548
volatile uint16_t tmp;
549549
uint16_t idx = 0;
@@ -569,28 +569,31 @@ int hal_flash_otp_write(uint32_t flashAddress, uint16_t* data, uint16_t length)
569569
DSB();
570570

571571
/* Program an OTP word (16 bits) */
572-
*(volatile uint16_t*)flashAddress = *(volatile uint16_t*)data;
572+
*(volatile uint16_t*)flashAddress = *(const uint16_t*)data;
573573

574+
#if 0
574575
/* Read it back */
575576
tmp = *(volatile uint16_t*)flashAddress;
576577
(void)tmp; /* avoid unused warnings */
577-
flashAddress += sizeof(uint16_t);
578-
data++;
579-
idx += sizeof(uint16_t);
578+
#endif
580579

581580
/* Wait for last operation to be completed */
582581
flash_otp_wait();
583582

584583
/* clear OTP_PG bit */
585584
FLASH_OPTCR &= ~FLASH_OPTCR_PG_OTP;
585+
586+
flashAddress += sizeof(uint16_t);
587+
data++;
588+
idx += sizeof(uint16_t);
586589
}
587590

588591
hal_flash_otp_lock();
589592
hal_flash_lock();
590593
return 0;
591594
}
592595

593-
int hal_flash_otp_read(uint32_t flashAddress, uint16_t* data, uint32_t length)
596+
int hal_flash_otp_read(uint32_t flashAddress, void* data, uint32_t length)
594597
{
595598
uint32_t i;
596599
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
@@ -600,7 +603,7 @@ int hal_flash_otp_read(uint32_t flashAddress, uint16_t* data, uint32_t length)
600603
(i < length) && (flashAddress <= (FLASH_OTP_END-1));
601604
i += sizeof(uint16_t))
602605
{
603-
*data = *(volatile uint16_t*)flashAddress;
606+
*(uint16_t *)data = *(volatile uint16_t*)flashAddress;
604607
flashAddress += sizeof(uint16_t);
605608
data++;
606609
}

include/hal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ int hal_trng_get_entropy(unsigned char *out, unsigned len);
132132

133133
#ifdef FLASH_OTP_ROT
134134

135-
int hal_flash_otp_write(uint32_t flashAddress, uint16_t* data, uint16_t length);
136-
int hal_flash_otp_read(uint32_t flashAddress, uint16_t* data, uint32_t length);
135+
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length);
136+
int hal_flash_otp_read(uint32_t flashAddress, void* data, uint32_t length);
137137

138138
#endif
139139

include/otp_keystore.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* otp_keystore.h
2+
*
3+
* Helper for storing/retrieving Trust Anchor to/from OTP flash
4+
*
5+
*
6+
* Copyright (C) 2024 wolfSSL Inc.
7+
*
8+
* This file is part of wolfBoot.
9+
*
10+
* wolfBoot is free software; you can redistribute it and/or modify
11+
* it under the terms of the GNU General Public License as published by
12+
* the Free Software Foundation; either version 3 of the License, or
13+
* (at your option) any later version.
14+
*
15+
* wolfBoot is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU General Public License
21+
* along with this program; if not, write to the Free Software
22+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
23+
*/
24+
25+
26+
#ifndef OTP_KEYSTORE_H
27+
#define OTP_KEYSTORE_H
28+
29+
#if defined(FLASH_OTP_ROT) && !defined(WOLFBOOT_NO_SIGN)
30+
/* Specific includes for supported targets
31+
* (needed for OTP_SIZE)
32+
*/
33+
#ifdef TARGET_stm32h7
34+
#include "hal/stm32h7.h"
35+
#else
36+
#error "Unsupported target for OTP"
37+
#endif
38+
39+
#include "keystore.h"
40+
41+
#define OTP_HDR_SIZE 16
42+
43+
struct __attribute__((packed)) wolfBoot_otp_hdr {
44+
char keystore_hdr_magic[8];
45+
uint16_t item_count;
46+
uint16_t flags;
47+
uint32_t version;
48+
};
49+
50+
static const char KEYSTORE_HDR_MAGIC[8] = "WOLFBOOT";
51+
52+
#if !defined(KEYSTORE_ANY) && (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_ECC256)
53+
#error Key algorithm mismatch. Remove old keys via 'make keysclean'
54+
#else
55+
56+
#define KEYSTORE_MAX_PUBKEYS ((OTP_SIZE - OTP_HDR_SIZE) / SIZEOF_KEYSTORE_SLOT)
57+
58+
#if (OTP_SIZE == 0)
59+
#error WRONG OTP SIZE
60+
#endif
61+
62+
#if (KEYSTORE_MAX_PUBKEYS < 1)
63+
#error "No space for any keystores in OTP with current algorithm"
64+
#endif
65+
66+
#endif /* KEYSTORE_ANY */
67+
68+
#endif /* FLASH_OTP_ROT */
69+
70+
#endif /* OTP_KEYSTORE_H */

include/wolfboot/wolfboot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ int wolfBoot_set_encrypt_key(const uint8_t *key, const uint8_t *nonce);
330330
int wolfBoot_get_encrypt_key(uint8_t *key, uint8_t *nonce);
331331
int wolfBoot_erase_encrypt_key(void);
332332

333+
333334
#ifdef __cplusplus
334335
}
335336
#endif

src/flash_otp_keystore.c

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,38 +27,14 @@
2727
#include "wolfboot/wolfboot.h"
2828
#include "keystore.h"
2929
#include "hal.h"
30+
#include "otp_keystore.h"
3031

3132
#if defined(FLASH_OTP_ROT) && !defined(WOLFBOOT_NO_SIGN)
3233

33-
#ifdef TARGET_stm32h7
34-
#include "hal/stm32h7.h"
35-
#endif
36-
37-
#define OTP_HDR_SIZE 16
38-
39-
struct wolfBoot_otp_hdr_size {
40-
char keystore_hdr_magic[8];
41-
uint16_t item_count;
42-
uint16_t flags;
43-
uint32_t version;
44-
};
45-
46-
static const char KEYSTORE_HDR_MAGIC[8] = "WOLFBOOT";
47-
48-
#if !defined(KEYSTORE_ANY) && (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_ECC256)
49-
#error Key algorithm mismatch. Remove old keys via 'make keysclean'
50-
#else
51-
52-
#define KEYSTORE_MAX_PUBKEYS ((OTP_SIZE - OTP_HDR_SIZE) / SIZEOF_KEYSTORE_SLOT)
53-
54-
#if (KEYSTORE_MAX_PUBKEYS < 1)
55-
#error "No space for keystore in OTP with current algorithm"
56-
#endif
57-
5834
int keystore_num_pubkeys(void)
5935
{
6036
uint8_t otp_header[OTP_HDR_SIZE];
61-
struct wolfBoot_otp_hdr_size *hdr = (struct wolfBoot_otp_hdr_size *)otp_header;
37+
struct wolfBoot_otp_hdr *hdr = (struct wolfBoot_otp_hdr *)otp_header;
6238
if (hal_flash_otp_read(FLASH_OTP_BASE, (void *)otp_header, OTP_HDR_SIZE) != 0)
6339
return 0;
6440
if (memcmp(hdr->keystore_hdr_magic, KEYSTORE_HDR_MAGIC, 8) != 0) {
@@ -123,6 +99,5 @@ uint32_t keystore_get_key_type(int id)
12399
return slot->key_type;
124100
}
125101

126-
#endif /* Keystore public key size check */
127102

128103
#endif /* FLASH_OTP_ROT && !WOLFBOOT_NO_SIGN */

tools/keytools/otp/Makefile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-include ../../../.config
2+
-include ../../../tools/config.mk
3+
-include ../../../options.mk
4+
-include ../../../wcs/pkcs11.mk
5+
6+
TARGET?=none
7+
ARCH?=ARM
8+
CROSS_COMPILE?=arm-none-eabi-
9+
CFLAGS+=-O0 -ggdb
10+
CFLAGS+=-I. -I../../../ -I../../../include
11+
CFLAGS+=-I./wcs
12+
CFLAGS+=-DFLASH_OTP_ROT
13+
OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
14+
LSCRIPT=target.ld
15+
LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map
16+
17+
ifeq ($(TARGET),stm32h7)
18+
CFLAGS+=-DTARGET_stm32h7
19+
CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
20+
OBJS+=../../../hal/stm32h7.o
21+
endif
22+
CC=$(CROSS_COMPILE)gcc
23+
OBJCOPY?=$(CROSS_COMPILE)objcopy
24+
SIZE?=$(CROSS_COMPILE)size
25+
26+
27+
otp-keystore-primer.bin: otp-keystore-primer.elf
28+
@$(OBJCOPY) -O binary $(^) $(@)
29+
30+
otp-keystore-primer.elf: $(OBJS)
31+
@$(CC) -o otp-keystore-primer.elf $(LDFLAGS) $(CFLAGS) $(OBJS)
32+
@$(SIZE) $(@)
33+
34+
35+
clean:
36+
@rm -rf $(OBJS) *.bin *.elf
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* otp-keystore-primer.c
2+
*
3+
* Primer app to provision public keys into OTP flash
4+
*
5+
*
6+
* Copyright (C) 2024 wolfSSL Inc.
7+
*
8+
* This file is part of wolfBoot.
9+
*
10+
* wolfBoot is free software; you can redistribute it and/or modify
11+
* it under the terms of the GNU General Public License as published by
12+
* the Free Software Foundation; either version 3 of the License, or
13+
* (at your option) any later version.
14+
*
15+
* wolfBoot is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU General Public License
21+
* along with this program; if not, write to the Free Software
22+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
23+
*/
24+
#include <stdint.h>
25+
#include <string.h>
26+
#include "hal.h"
27+
#include "otp_keystore.h"
28+
29+
extern struct keystore_slot PubKeys[];
30+
31+
void main(void)
32+
{
33+
int n_keys = keystore_num_pubkeys();
34+
int i;
35+
struct wolfBoot_otp_hdr hdr;
36+
memcpy(hdr.keystore_hdr_magic, KEYSTORE_HDR_MAGIC, 8);
37+
hdr.item_count = n_keys;
38+
hdr.flags = 0;
39+
hdr.version = WOLFBOOT_VERSION;
40+
41+
/* Sanity check to avoid writing an empty keystore */
42+
if (n_keys < 1) {
43+
while(1)
44+
;
45+
}
46+
47+
/* Write the header to the beginning of the OTP memory */
48+
hal_flash_otp_write(FLASH_OTP_BASE, (uint16_t *)&hdr, sizeof(hdr));
49+
50+
for (i = 0; i < n_keys; i++) {
51+
/* Write each public key to its slot in OTP */
52+
hal_flash_otp_write(FLASH_OTP_BASE +
53+
OTP_HDR_SIZE + i * SIZEOF_KEYSTORE_SLOT, (uint16_t *)&PubKeys[i],
54+
sizeof(struct keystore_slot));
55+
}
56+
57+
/* Done! */
58+
while(1)
59+
;
60+
61+
}

0 commit comments

Comments
 (0)