From 497ead7111ee8bbe3e64faa16f3825ec3484e06b Mon Sep 17 00:00:00 2001 From: matejcik Date: Thu, 23 Mar 2023 14:52:35 +0100 Subject: [PATCH] feat(core/unix): fill out (non-persistent) OTP functionality --- core/embed/unix/flash.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/core/embed/unix/flash.c b/core/embed/unix/flash.c index c9a400b94e..69a2d7c7e1 100644 --- a/core/embed/unix/flash.c +++ b/core/embed/unix/flash.c @@ -92,6 +92,11 @@ const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT] = { static uint8_t *FLASH_BUFFER = NULL; static uint32_t FLASH_SIZE; +#define OTP_BLOCK_SIZE 32 +#define FLASH_SECTOR_OTP (FLASH_SECTOR_COUNT) + +static uint8_t OTP_BUFFER[OTP_BLOCK_SIZE * 64]; + static void flash_exit(void) { int r = munmap(FLASH_BUFFER, FLASH_SIZE); ensure(sectrue * (r == 0), "munmap failed"); @@ -130,6 +135,9 @@ void flash_init(void) { FLASH_BUFFER = (uint8_t *)map; + // fill OTP buffer with ones + memset(OTP_BUFFER, 0xFF, sizeof(OTP_BUFFER)); + atexit(flash_exit); } @@ -203,12 +211,28 @@ secbool flash_write_word(uint8_t sector, uint32_t offset, uint32_t data) { secbool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data, uint8_t datalen) { - return secfalse; + if (offset + datalen > OTP_BLOCK_SIZE) { + return secfalse; + } + uint32_t offset_in_sector = block * OTP_BLOCK_SIZE + offset; + memcpy(data, OTP_BUFFER + offset_in_sector, datalen); + return sectrue; } secbool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data, uint8_t datalen) { - return secfalse; + if (offset + datalen > OTP_BLOCK_SIZE) { + return secfalse; + } + uint32_t offset_in_sector = block * OTP_BLOCK_SIZE + offset; + uint8_t *flash = OTP_BUFFER + offset_in_sector; + for (int i = 0; i < datalen; i++) { + if ((flash[i] & data[i]) != data[i]) { + return secfalse; // we cannot change zeroes to ones + } + flash[i] = data[i]; + } + return sectrue; } secbool flash_otp_lock(uint8_t block) { return secfalse; }