otp_keystore_primer: fixed provisioning + readonly

pull/449/head
Daniele Lacamera 2024-05-20 10:58:43 +02:00
parent 8b62697f6c
commit 307e3b426c
6 changed files with 77 additions and 17 deletions

View File

@ -435,38 +435,80 @@ void hal_prepare_boot(void)
#ifdef FLASH_OTP_KEYSTORE
#define FLASH_OTP_BLOCK_SIZE (64)
/* Public API */
int hal_flash_otp_set_readonly(uint32_t flashAddress, uint16_t length)
{
uint32_t start_block = (flashAddress - FLASH_OTP_BASE) / FLASH_OTP_BLOCK_SIZE;
uint32_t count = length / FLASH_OTP_BLOCK_SIZE;
uint32_t bmap = 0;
unsigned int i;
if (start_block + count > 32)
return -1;
if ((length % FLASH_OTP_BLOCK_SIZE) != 0)
{
count++;
}
/* Turn on the bits */
for (i = start_block; i < (start_block + count); i++) {
bmap |= (1 << i);
}
/* Enable OTP write protection for the selected blocks */
while ((bmap & FLASH_OTPBLR_CUR) != bmap) {
FLASH_OTPBLR_PRG |= bmap;
ISB();
DSB();
}
return 0;
}
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
{
volatile uint16_t tmp;
volatile uint16_t tmp_msw, tmp_lsw;
uint16_t *pdata = (uint16_t *)data;
uint16_t idx = 0, len_align;
uint16_t last_word;
uint32_t blr_bitmap = 0;
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
return -1;
}
/* Reject misaligned destination address */
if ((flashAddress & 0x01) != 0) {
return -1;
}
hal_flash_wait_complete(0);
hal_flash_wait_buffer_empty(0);
hal_flash_unlock();
hal_flash_clear_errors(0);
/* Truncate to 2B alignment */
length = (length / 2 * 2);
while (idx < length && flashAddress <= FLASH_OTP_END-1) {
while ((idx < length) && (flashAddress <= FLASH_OTP_END-1)) {
hal_flash_wait_complete(0);
/* Set PG bit */
FLASH_CR |= FLASH_CR_PG;
/* Program an OTP word (32 bits) */
*(volatile uint16_t*)flashAddress = *pdata;
/* Program an OTP word (16 bits) */
*(volatile uint16_t*)flashAddress = pdata[0];
/* Program a second OTP word (16 bits) */
*(volatile uint16_t*)(flashAddress + sizeof(uint16_t)) = pdata[1];
ISB();
DSB();
/* Wait until not busy */
while ((FLASH_SR & FLASH_SR_BSY) != 0)
;
/* Read it back */
tmp = *(volatile uint16_t*)flashAddress;
if (tmp != *pdata) {
tmp_msw = *(volatile uint16_t*)flashAddress;
tmp_lsw = *(volatile uint16_t*)(flashAddress + sizeof(uint16_t));
if ((tmp_msw != pdata[0]) || (tmp_lsw != pdata[1])) {
/* Provisioning failed. OTP already programmed? */
while(1)
;
@ -474,11 +516,12 @@ int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length
/* Clear PG bit */
FLASH_CR &= ~FLASH_CR_PG;
flashAddress += sizeof(uint16_t);
pdata++;
idx += sizeof(uint16_t);
}
/* Advance to next two words */
flashAddress += (2 * sizeof(uint16_t));
pdata += 2;
idx += (2 * sizeof(uint16_t));
}
hal_flash_lock();
return 0;
}

View File

@ -207,6 +207,8 @@
#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x24))
#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x2C))
#define FLASH_SECBB1 ((volatile uint32_t *)(FLASH_BASE + 0x0A0)) /* Array */
#define FLASH_SECBB2 ((volatile uint32_t *)(FLASH_BASE + 0x1A0)) /* Array */
#define FLASH_SECBB_NREGS 4 /* Array length for the two above */
@ -239,6 +241,8 @@
/* Both secure + non secure */
#define FLASH_OPTCR (*(volatile uint32_t *)(FLASH_BASE + 0x1C))
#define FLASH_OPSR (*(volatile uint32_t *)(FLASH_BASE + 0x18))
#define FLASH_OTPBLR_CUR (*(volatile uint32_t *)(FLASH_BASE + 0x90))
#define FLASH_OTPBLR_PRG (*(volatile uint32_t *)(FLASH_BASE + 0x94))
#define FLASH_OPSR_DATA_OP (1 << 21)
#define FLASH_OPSR_BK_OP (1 << 22)

View File

@ -543,6 +543,12 @@ static void hal_flash_otp_lock(void)
/* Public API */
int hal_flash_otp_set_readonly(uint32_t flashAddress, uint16_t length)
{
/* TODO: set WP on OTP if needed */
return 0;
}
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
{
volatile uint16_t tmp;

View File

@ -133,6 +133,7 @@ int hal_trng_get_entropy(unsigned char *out, unsigned len);
#ifdef FLASH_OTP_KEYSTORE
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length);
int hal_flash_otp_set_readonly(uint32_t flashAddress, uint16_t length);
int hal_flash_otp_read(uint32_t flashAddress, void* data, uint32_t length);
#endif

View File

@ -10,19 +10,19 @@ CFLAGS+=-O0 -ggdb
CFLAGS+=-I. -I../../../ -I../../../include
CFLAGS+=-I./wcs
CFLAGS+=-DFLASH_OTP_KEYSTORE -D__FLASH_OTP_PRIMER
OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
PRI_KS_OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
LSCRIPT=target.ld
LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map
ifeq ($(TARGET),stm32h7)
CFLAGS+=-DTARGET_stm32h7
CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
OBJS+=../../../hal/stm32h7.o
PRI_KS_OBJS+=../../../hal/stm32h7.o
endif
ifeq ($(TARGET),stm32h5)
CFLAGS+=-DTARGET_stm32h5
CFLAGS+=-mcpu=cortex-m33 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
OBJS+=../../../hal/stm32h5.o
PRI_KS_OBJS+=../../../hal/stm32h5.o
endif
CC=$(CROSS_COMPILE)gcc
OBJCOPY?=$(CROSS_COMPILE)objcopy
@ -32,10 +32,10 @@ SIZE?=$(CROSS_COMPILE)size
otp-keystore-primer.bin: otp-keystore-primer.elf
@$(OBJCOPY) -O binary $(^) $(@)
otp-keystore-primer.elf: $(OBJS)
@$(CC) -o otp-keystore-primer.elf $(LDFLAGS) $(CFLAGS) $(OBJS)
otp-keystore-primer.elf: $(PRI_KS_OBJS)
@$(CC) -o otp-keystore-primer.elf $(LDFLAGS) $(CFLAGS) $(PRI_KS_OBJS)
@$(SIZE) $(@)
clean:
@rm -rf $(OBJS) *.bin *.elf
@rm -rf $(PRI_KS_OBJS) *.bin *.elf

View File

@ -34,6 +34,7 @@ void main(void)
int n_keys = keystore_num_pubkeys();
int i;
struct wolfBoot_otp_hdr hdr;
uint32_t tot_len;
hal_init();
@ -58,6 +59,11 @@ void main(void)
sizeof(struct keystore_slot));
}
/* Protect the OTP area just written */
tot_len = OTP_HDR_SIZE + n_keys * SIZEOF_KEYSTORE_SLOT;
hal_flash_otp_set_readonly(FLASH_OTP_BASE, tot_len);
/* Done! */
while(1)
;