I can confirm that it works!
The change that I had to do was to write 0x3d3d3d to OTP_DATA_PAGE32_LOCK1 which cannot be done by picotool (permission denied), but by the following firmware:
picotool can however read the firmware after entering BOOTSEL mode again:After this, trying to read the rows 0x800 fails as expected:As required,, the secret can still be read by a secure firmware:This is exactly what is needed for producing a security dongle that can be verified to be present (by an ECC key-pair) but can't (easily!) be copied!
The change that I had to do was to write 0x3d3d3d to OTP_DATA_PAGE32_LOCK1 which cannot be done by picotool (permission denied), but by the following firmware:
Code:
// Lock page 32#include <stdio.h>#include "pico/stdlib.h"#include "pico/bootrom.h"#include "hardware/structs/otp.h"int main(){ stdio_init_all(); // Values to write to the lock registers uint32_t LockMask = 0x3d3d3d; otp_cmd_t Cmd; for (int i=0; i<5; i++) { printf("Sleep %d\n", i); sleep_ms(1000); } printf("Locking page 32\n"); // Lock Page 32 (Row 0x0fc1) Cmd.flags = (0x0fc1 & 0xffff) | 0x00010000; // ROW_NUMBER | IS_WRITE int ret = rom_func_otp_access((uint8_t*)&LockMask, 4, Cmd); printf("Page 32 lock result=%d\n", ret); }Code:
$ sudo picotool otp get --raw OTP_DATA_PAGE32_LOCK1ROW 0x0fc1: OTP_DATA_PAGE32_LOCK1 "Lock configuration MSBs for page 32 (rows 0x800 through 0x83f). Locks are stored with 3-way majority vote encoding, so that bits can be set independently. This OTP location is always readable, and is write-protected by its own permissions." VALUE 0x3d3d3dCode:
$ sudo picotool otp get --raw 0x0800ERROR: The RP2350 device returned an error: permission failureCode:
int get_private_key(uint8_t* buffer_out){ otp_cmd_t cmmd; // Target User Row 0x800 and set IS_ECC bit for hardware error correction cmd.flags = (0x800 & OTP_CMD_ROW_BITS) | OTP_CMD_ECC_BITS; // In ECC mode, 32 bytes of data are retrieved from 16 rows (2 bytes per row) int ret= rom_func_otp_access(buffer_out, 32, cmd); printf("rom_func_otp_access ret=%d!\n", ret); return ret;}Statistics: Posted by dov — Sat Jan 17, 2026 5:22 pm