mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-28 09:01:24 +02:00
Enable OTP to store a permanent secret key.
It can be used by HSM or Fido to protect the keys and use it as MKEK.
This commit is contained in:
@@ -202,6 +202,7 @@ set(SOURCES ${SOURCES}
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/otp.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
|
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/rng/hwrng.c
|
${CMAKE_CURRENT_LIST_DIR}/src/rng/hwrng.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/eac.c
|
${CMAKE_CURRENT_LIST_DIR}/src/eac.c
|
||||||
@@ -362,6 +363,7 @@ if(PICO_RP2350)
|
|||||||
pico_sign_binary(${CMAKE_PROJECT_NAME} ${SECURE_BOOT_PKEY})
|
pico_sign_binary(${CMAKE_PROJECT_NAME} ${SECURE_BOOT_PKEY})
|
||||||
pico_hash_binary(${CMAKE_PROJECT_NAME})
|
pico_hash_binary(${CMAKE_PROJECT_NAME})
|
||||||
endif()
|
endif()
|
||||||
|
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE pico_bootrom)
|
||||||
endif()
|
endif()
|
||||||
set(INTERNAL_SOURCES ${SOURCES})
|
set(INTERNAL_SOURCES ${SOURCES})
|
||||||
set(SOURCES ${SOURCES} ${EXTERNAL_SOURCES})
|
set(SOURCES ${SOURCES} ${EXTERNAL_SOURCES})
|
||||||
|
|||||||
100
src/fs/otp.c
Normal file
100
src/fs/otp.c
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
|
#include "pico_keys.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "otp.h"
|
||||||
|
|
||||||
|
#ifdef PICO_RP2350
|
||||||
|
#include "pico/bootrom.h"
|
||||||
|
#include "hardware/structs/otp.h"
|
||||||
|
#include "hardware/regs/otp_data.h"
|
||||||
|
#endif
|
||||||
|
#include "random.h"
|
||||||
|
|
||||||
|
#ifdef PICO_RP2350
|
||||||
|
|
||||||
|
static bool is_empty_buffer(const uint8_t *buffer, uint16_t buffer_len) {
|
||||||
|
for (int i = 0; i < buffer_len; i++) {
|
||||||
|
if (buffer[i] != 0x00) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int otp_write_data_mode(uint16_t row, uint8_t *data, uint16_t len, bool is_ecc) {
|
||||||
|
otp_cmd_t cmd = { .flags = row | (is_ecc ? OTP_CMD_ECC_BITS : 0) | OTP_CMD_WRITE_BITS };
|
||||||
|
uint32_t ret = rom_func_otp_access(data, len, cmd);
|
||||||
|
if (ret) {
|
||||||
|
printf("OTP Write failed with error: %ld\n", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int otp_write_data(uint16_t row, uint8_t *data, uint16_t len) {
|
||||||
|
return otp_write_data_mode(row, data, len, true);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
static int otp_write_data_raw(uint16_t row, uint8_t *data, uint16_t len) {
|
||||||
|
return otp_write_data_mode(row, data, len, false);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
static uint8_t* otp_buffer(uint16_t row) {
|
||||||
|
volatile uint32_t *p = ((uint32_t *)(OTP_DATA_GUARDED_BASE + (row*2)));
|
||||||
|
return (uint8_t *)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_empty_otp_buffer(uint16_t row, uint16_t len) {
|
||||||
|
return is_empty_buffer(otp_buffer(row), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_otp_locked_page(uint8_t page) {
|
||||||
|
volatile uint32_t *p = ((uint32_t *)(OTP_DATA_BASE + ((OTP_DATA_PAGE0_LOCK0_ROW + page*2)*2)));
|
||||||
|
return ((p[0] & 0xFFFF0000) == 0x3C3C0000 && (p[1] & 0xFF) == 0x3C);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void otp_lock_page(uint8_t page) {
|
||||||
|
if (!is_otp_locked_page(page)) {
|
||||||
|
uint32_t value = 0x3c3c3c;
|
||||||
|
printf("Locking page %d, with row %d and value %lx\n", page, OTP_DATA_PAGE0_LOCK0_ROW + page*2 + 1, value);
|
||||||
|
//otp_write_data_raw(OTP_DATA_PAGE0_LOCK0_ROW + page*2 + 1, (uint8_t *)&value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
otp_hw->sw_lock[page] = 0b1100;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint8_t *otp_key_1 = NULL;
|
||||||
|
void init_otp_files() {
|
||||||
|
#ifdef PICO_RP2350
|
||||||
|
|
||||||
|
uint8_t page = OTP_KEY_1 >> 6;
|
||||||
|
if (is_empty_otp_buffer(OTP_KEY_1, 32)) {
|
||||||
|
uint8_t mkek[32] = {0};
|
||||||
|
random_gen(NULL, mkek, sizeof(mkek));
|
||||||
|
otp_write_data(OTP_KEY_1, mkek, sizeof(mkek));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG_DATA(otp_buffer(OTP_KEY_1), 32);
|
||||||
|
}
|
||||||
|
otp_key_1 = otp_buffer(OTP_KEY_1);
|
||||||
|
|
||||||
|
otp_lock_page(page);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
32
src/fs/otp.h
Normal file
32
src/fs/otp.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||||
|
* Copyright (c) 2022 Pol Henarejos.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _OTP_H_
|
||||||
|
#define _OTP_H_
|
||||||
|
|
||||||
|
#ifdef PICO_RP2350
|
||||||
|
|
||||||
|
#define OTP_TEST_ROW 0xEF0
|
||||||
|
|
||||||
|
#define OTP_KEY_1 OTP_TEST_ROW
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const uint8_t *otp_key_1;
|
||||||
|
|
||||||
|
#endif // _OTP_H_
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
extern void do_flash();
|
extern void do_flash();
|
||||||
extern void low_flash_init();
|
extern void low_flash_init();
|
||||||
|
extern void init_otp_files();
|
||||||
|
|
||||||
app_t apps[4];
|
app_t apps[4];
|
||||||
uint8_t num_apps = 0;
|
uint8_t num_apps = 0;
|
||||||
@@ -296,6 +297,8 @@ int main(void) {
|
|||||||
|
|
||||||
random_init();
|
random_init();
|
||||||
|
|
||||||
|
init_otp_files();
|
||||||
|
|
||||||
low_flash_init();
|
low_flash_init();
|
||||||
|
|
||||||
scan_flash();
|
scan_flash();
|
||||||
@@ -303,6 +306,7 @@ int main(void) {
|
|||||||
init_rtc();
|
init_rtc();
|
||||||
|
|
||||||
usb_init();
|
usb_init();
|
||||||
|
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
gpio_pad_select_gpio(BOOT_PIN);
|
gpio_pad_select_gpio(BOOT_PIN);
|
||||||
|
|||||||
Reference in New Issue
Block a user