diff --git a/pico_keys_sdk_import.cmake b/pico_keys_sdk_import.cmake
index 0ade7d5..2e4ce0d 100644
--- a/pico_keys_sdk_import.cmake
+++ b/pico_keys_sdk_import.cmake
@@ -202,6 +202,7 @@ set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
${CMAKE_CURRENT_LIST_DIR}/src/fs/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/hwrng.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_hash_binary(${CMAKE_PROJECT_NAME})
endif()
+ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE pico_bootrom)
endif()
set(INTERNAL_SOURCES ${SOURCES})
set(SOURCES ${SOURCES} ${EXTERNAL_SOURCES})
diff --git a/src/fs/otp.c b/src/fs/otp.c
new file mode 100644
index 0000000..9b1279a
--- /dev/null
+++ b/src/fs/otp.c
@@ -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 .
+ */
+
+#include "file.h"
+#include "pico_keys.h"
+#include
+#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
+}
diff --git a/src/fs/otp.h b/src/fs/otp.h
new file mode 100644
index 0000000..bac4faa
--- /dev/null
+++ b/src/fs/otp.h
@@ -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 .
+ */
+
+
+#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_
diff --git a/src/main.c b/src/main.c
index 7e4586e..cf7b9fd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -45,6 +45,7 @@
#include "usb.h"
extern void do_flash();
extern void low_flash_init();
+extern void init_otp_files();
app_t apps[4];
uint8_t num_apps = 0;
@@ -296,6 +297,8 @@ int main(void) {
random_init();
+ init_otp_files();
+
low_flash_init();
scan_flash();
@@ -303,6 +306,7 @@ int main(void) {
init_rtc();
usb_init();
+
#ifndef ENABLE_EMULATION
#ifdef ESP_PLATFORM
gpio_pad_select_gpio(BOOT_PIN);