Skip to content

Commit 307e3b4

Browse files
committed
otp_keystore_primer: fixed provisioning + readonly
1 parent 8b62697 commit 307e3b4

File tree

6 files changed

+77
-17
lines changed

6 files changed

+77
-17
lines changed

hal/stm32h5.c

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -435,50 +435,93 @@ void hal_prepare_boot(void)
435435

436436
#ifdef FLASH_OTP_KEYSTORE
437437

438+
#define FLASH_OTP_BLOCK_SIZE (64)
439+
438440
/* Public API */
439441

442+
int hal_flash_otp_set_readonly(uint32_t flashAddress, uint16_t length)
443+
{
444+
uint32_t start_block = (flashAddress - FLASH_OTP_BASE) / FLASH_OTP_BLOCK_SIZE;
445+
uint32_t count = length / FLASH_OTP_BLOCK_SIZE;
446+
uint32_t bmap = 0;
447+
unsigned int i;
448+
if (start_block + count > 32)
449+
return -1;
450+
451+
if ((length % FLASH_OTP_BLOCK_SIZE) != 0)
452+
{
453+
count++;
454+
}
455+
456+
/* Turn on the bits */
457+
for (i = start_block; i < (start_block + count); i++) {
458+
bmap |= (1 << i);
459+
}
460+
/* Enable OTP write protection for the selected blocks */
461+
while ((bmap & FLASH_OTPBLR_CUR) != bmap) {
462+
FLASH_OTPBLR_PRG |= bmap;
463+
ISB();
464+
DSB();
465+
}
466+
return 0;
467+
}
468+
440469
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
441470
{
442-
volatile uint16_t tmp;
471+
volatile uint16_t tmp_msw, tmp_lsw;
443472
uint16_t *pdata = (uint16_t *)data;
444473
uint16_t idx = 0, len_align;
445474
uint16_t last_word;
475+
uint32_t blr_bitmap = 0;
446476
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
447477
return -1;
448478
}
449479

480+
/* Reject misaligned destination address */
481+
if ((flashAddress & 0x01) != 0) {
482+
return -1;
483+
}
484+
450485
hal_flash_wait_complete(0);
451486
hal_flash_wait_buffer_empty(0);
452487
hal_flash_unlock();
453488
hal_flash_clear_errors(0);
454489

455-
456490
/* Truncate to 2B alignment */
457491
length = (length / 2 * 2);
458492

459-
while (idx < length && flashAddress <= FLASH_OTP_END-1) {
493+
while ((idx < length) && (flashAddress <= FLASH_OTP_END-1)) {
460494
hal_flash_wait_complete(0);
461495
/* Set PG bit */
462496
FLASH_CR |= FLASH_CR_PG;
463-
/* Program an OTP word (32 bits) */
464-
*(volatile uint16_t*)flashAddress = *pdata;
497+
/* Program an OTP word (16 bits) */
498+
*(volatile uint16_t*)flashAddress = pdata[0];
499+
/* Program a second OTP word (16 bits) */
500+
*(volatile uint16_t*)(flashAddress + sizeof(uint16_t)) = pdata[1];
465501
ISB();
466502
DSB();
503+
504+
/* Wait until not busy */
505+
while ((FLASH_SR & FLASH_SR_BSY) != 0)
506+
;
507+
467508
/* Read it back */
468-
tmp = *(volatile uint16_t*)flashAddress;
469-
if (tmp != *pdata) {
509+
tmp_msw = *(volatile uint16_t*)flashAddress;
510+
tmp_lsw = *(volatile uint16_t*)(flashAddress + sizeof(uint16_t));
511+
if ((tmp_msw != pdata[0]) || (tmp_lsw != pdata[1])) {
470512
/* Provisioning failed. OTP already programmed? */
471513
while(1)
472514
;
473515
}
474516

475517
/* Clear PG bit */
476518
FLASH_CR &= ~FLASH_CR_PG;
477-
flashAddress += sizeof(uint16_t);
478-
pdata++;
479-
idx += sizeof(uint16_t);
480-
}
481519

520+
/* Advance to next two words */
521+
flashAddress += (2 * sizeof(uint16_t));
522+
pdata += 2;
523+
idx += (2 * sizeof(uint16_t));
524+
}
482525
hal_flash_lock();
483526
return 0;
484527
}

hal/stm32h5.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@
207207
#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x24))
208208
#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x2C))
209209

210+
211+
210212
#define FLASH_SECBB1 ((volatile uint32_t *)(FLASH_BASE + 0x0A0)) /* Array */
211213
#define FLASH_SECBB2 ((volatile uint32_t *)(FLASH_BASE + 0x1A0)) /* Array */
212214
#define FLASH_SECBB_NREGS 4 /* Array length for the two above */
@@ -239,6 +241,8 @@
239241
/* Both secure + non secure */
240242
#define FLASH_OPTCR (*(volatile uint32_t *)(FLASH_BASE + 0x1C))
241243
#define FLASH_OPSR (*(volatile uint32_t *)(FLASH_BASE + 0x18))
244+
#define FLASH_OTPBLR_CUR (*(volatile uint32_t *)(FLASH_BASE + 0x90))
245+
#define FLASH_OTPBLR_PRG (*(volatile uint32_t *)(FLASH_BASE + 0x94))
242246

243247
#define FLASH_OPSR_DATA_OP (1 << 21)
244248
#define FLASH_OPSR_BK_OP (1 << 22)

hal/stm32h7.c

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

544544
/* Public API */
545545

546+
int hal_flash_otp_set_readonly(uint32_t flashAddress, uint16_t length)
547+
{
548+
/* TODO: set WP on OTP if needed */
549+
return 0;
550+
}
551+
546552
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
547553
{
548554
volatile uint16_t tmp;

include/hal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ int hal_trng_get_entropy(unsigned char *out, unsigned len);
133133
#ifdef FLASH_OTP_KEYSTORE
134134

135135
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length);
136+
int hal_flash_otp_set_readonly(uint32_t flashAddress, uint16_t length);
136137
int hal_flash_otp_read(uint32_t flashAddress, void* data, uint32_t length);
137138

138139
#endif

tools/keytools/otp/Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ CFLAGS+=-O0 -ggdb
1010
CFLAGS+=-I. -I../../../ -I../../../include
1111
CFLAGS+=-I./wcs
1212
CFLAGS+=-DFLASH_OTP_KEYSTORE -D__FLASH_OTP_PRIMER
13-
OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
13+
PRI_KS_OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
1414
LSCRIPT=target.ld
1515
LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map
1616

1717
ifeq ($(TARGET),stm32h7)
1818
CFLAGS+=-DTARGET_stm32h7
1919
CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
20-
OBJS+=../../../hal/stm32h7.o
20+
PRI_KS_OBJS+=../../../hal/stm32h7.o
2121
endif
2222
ifeq ($(TARGET),stm32h5)
2323
CFLAGS+=-DTARGET_stm32h5
2424
CFLAGS+=-mcpu=cortex-m33 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
25-
OBJS+=../../../hal/stm32h5.o
25+
PRI_KS_OBJS+=../../../hal/stm32h5.o
2626
endif
2727
CC=$(CROSS_COMPILE)gcc
2828
OBJCOPY?=$(CROSS_COMPILE)objcopy
@@ -32,10 +32,10 @@ SIZE?=$(CROSS_COMPILE)size
3232
otp-keystore-primer.bin: otp-keystore-primer.elf
3333
@$(OBJCOPY) -O binary $(^) $(@)
3434

35-
otp-keystore-primer.elf: $(OBJS)
36-
@$(CC) -o otp-keystore-primer.elf $(LDFLAGS) $(CFLAGS) $(OBJS)
35+
otp-keystore-primer.elf: $(PRI_KS_OBJS)
36+
@$(CC) -o otp-keystore-primer.elf $(LDFLAGS) $(CFLAGS) $(PRI_KS_OBJS)
3737
@$(SIZE) $(@)
3838

3939

4040
clean:
41-
@rm -rf $(OBJS) *.bin *.elf
41+
@rm -rf $(PRI_KS_OBJS) *.bin *.elf

tools/keytools/otp/otp-keystore-primer.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ void main(void)
3434
int n_keys = keystore_num_pubkeys();
3535
int i;
3636
struct wolfBoot_otp_hdr hdr;
37+
uint32_t tot_len;
3738

3839
hal_init();
3940

@@ -58,6 +59,11 @@ void main(void)
5859
sizeof(struct keystore_slot));
5960
}
6061

62+
/* Protect the OTP area just written */
63+
tot_len = OTP_HDR_SIZE + n_keys * SIZEOF_KEYSTORE_SLOT;
64+
hal_flash_otp_set_readonly(FLASH_OTP_BASE, tot_len);
65+
66+
6167
/* Done! */
6268
while(1)
6369
;

0 commit comments

Comments
 (0)