1 Commits
v8.5 ... v8.4

Author SHA1 Message Date
Pol Henarejos
12b4940662 Pico Keys SDK 8.4
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2026-01-26 23:23:50 +01:00
8 changed files with 28 additions and 155 deletions

View File

@@ -10,7 +10,7 @@
}, },
"partitions": [ "partitions": [
{ {
"name": "PicoKeys Firmware", "name": "Pico Keys Firmware",
"id": 0, "id": 0,
"start": 0, "start": 0,
"size": "1024K", "size": "1024K",
@@ -22,10 +22,10 @@
} }
}, },
{ {
"name": "PicoKeys Data", "name": "Pico Keys Data",
"id": 1, "id": 1,
"start": "1032K", "start": "1024K",
"size": "3064K", "size": "3072K",
"families": ["data"], "families": ["data"],
"permissions": { "permissions": {
"secure": "rw", "secure": "rw",
@@ -35,21 +35,6 @@
"link": ["owner", 0], "link": ["owner", 0],
"ignored_during_arm_boot": true, "ignored_during_arm_boot": true,
"ignored_during_riscv_boot": true "ignored_during_riscv_boot": true
},
{
"name": "PicoKeys Binding",
"id": 2,
"start": "1024K",
"size": "8K",
"families": ["data"],
"permissions": {
"secure": "r",
"nonsecure": "",
"bootloader": "w"
},
"link": ["owner", 0],
"ignored_during_arm_boot": true,
"ignored_during_riscv_boot": true
} }
] ]
} }

View File

@@ -278,16 +278,3 @@ mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_
} }
return MBEDTLS_ECP_DP_NONE; return MBEDTLS_ECP_DP_NONE;
} }
#define POLY 0xedb88320
uint32_t crc32c(const uint8_t *buf, size_t len) {
uint32_t crc = 0xffffffff;
while (len--) {
crc ^= *buf++;
for (int k = 0; k < 8; k++) {
crc = (crc >> 1) ^ (POLY & (0 - (crc & 1)));
}
}
return ~crc;
}

View File

@@ -56,6 +56,5 @@ extern int aes_decrypt(const uint8_t *key, const uint8_t *iv, uint16_t key_size,
extern int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len); extern int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len);
extern int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len); extern int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len);
extern mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len); extern mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len);
extern uint32_t crc32c(const uint8_t *buf, size_t len);
#endif #endif

View File

@@ -22,7 +22,6 @@
#include "pico_keys.h" #include "pico_keys.h"
#include <string.h> #include <string.h>
#include "crypto_utils.h"
#ifdef PICO_PLATFORM #ifdef PICO_PLATFORM
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "hardware/flash.h" #include "hardware/flash.h"
@@ -159,14 +158,8 @@ void do_flash() {
sem_release(&sem_flash); sem_release(&sem_flash);
} }
#ifdef PICO_RP2040
void phymarker_write();
#endif
//this function has to be called from the core 0 //this function has to be called from the core 0
void low_flash_init() { void low_flash_init() {
#ifdef PICO_RP2040
phymarker_write();
#endif
memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES); memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES);
mutex_init(&mtx_flash); mutex_init(&mtx_flash);
sem_init(&sem_flash, 0, 1); sem_init(&sem_flash, 0, 1);
@@ -378,40 +371,3 @@ bool flash_check_blank(const uint8_t *p_start, size_t size) {
} }
return true; return true;
} }
#ifdef PICO_RP2040
typedef struct {
uint64_t magic;
uint16_t version;
uint16_t flags;
uint8_t uid[PICO_UNIQUE_BOARD_ID_SIZE_BYTES];
uint32_t crc32;
} __attribute__ ((packed)) phymarker_t;
uintptr_t __phymarker_start = (uintptr_t)0x10100000;
const uint64_t PHYSICAL_MARKER_MAGIC = 0x5049434F4B455953ULL; // "PICOKEYS"
void phymarker_write() {
const uint64_t magic = *(uint64_t *)__phymarker_start;
if (magic == PHYSICAL_MARKER_MAGIC) {
return;
}
phymarker_t pm = {
.magic = PHYSICAL_MARKER_MAGIC, // "PICOKEYS"
.version = 0x0001,
.flags = 0x0000,
.crc32 = 0x00000000
};
memcpy(pm.uid, pico_serial.id, PICO_UNIQUE_BOARD_ID_SIZE_BYTES);
pm.crc32 = crc32c((const uint8_t *)&pm, sizeof(phymarker_t) - sizeof(uint32_t));
uint32_t ints = save_and_disable_interrupts();
flash_range_erase((uint32_t)__phymarker_start - XIP_BASE, FLASH_SECTOR_SIZE);
flash_range_program((uint32_t)__phymarker_start - XIP_BASE, (const uint8_t *)&pm, sizeof(phymarker_t));
restore_interrupts(ints);
}
#endif

View File

@@ -235,11 +235,6 @@ bool wait_button() {
req_button_pending = false; req_button_pending = false;
return timeout || cancel_button; return timeout || cancel_button;
} }
__attribute__((weak)) int picokey_init() {
return 0;
}
#endif #endif
bool set_rtc = false; bool set_rtc = false;
@@ -398,10 +393,6 @@ int main(void) {
#endif #endif
#endif #endif
#ifndef ENABLE_EMULATION
picokey_init();
#endif
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
xTaskCreatePinnedToCore(core0_loop, "core0", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, ESP32_CORE0); xTaskCreatePinnedToCore(core0_loop, "core0", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, ESP32_CORE0);
#else #else

View File

@@ -18,7 +18,7 @@
#ifndef __VERSION_H_ #ifndef __VERSION_H_
#define __VERSION_H_ #define __VERSION_H_
#define PICO_KEYS_SDK_VERSION 0x0805 #define PICO_KEYS_SDK_VERSION 0x0804
#define PICO_KEYS_SDK_VERSION_MAJOR ((PICO_KEYS_SDK_VERSION >> 8) & 0xff) #define PICO_KEYS_SDK_VERSION_MAJOR ((PICO_KEYS_SDK_VERSION >> 8) & 0xff)
#define PICO_KEYS_SDK_VERSION_MINOR (PICO_KEYS_SDK_VERSION & 0xff) #define PICO_KEYS_SDK_VERSION_MINOR (PICO_KEYS_SDK_VERSION & 0xff)

View File

@@ -22,7 +22,6 @@
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
#include "random.h" #include "random.h"
#include "crypto_utils.h"
#ifdef PICO_PLATFORM #ifdef PICO_PLATFORM
extern char __flash_binary_start; extern char __flash_binary_start;
@@ -47,8 +46,6 @@ const uint8_t rescue_aid[] = {
#define PICO_MCU 0 #define PICO_MCU 0
#endif #endif
#define EF_DEVCERT_KEY 0xE0C1
extern uint8_t PICO_PRODUCT; extern uint8_t PICO_PRODUCT;
extern uint8_t PICO_VERSION_MAJOR; extern uint8_t PICO_VERSION_MAJOR;
extern uint8_t PICO_VERSION_MINOR; extern uint8_t PICO_VERSION_MINOR;
@@ -78,69 +75,30 @@ int rescue_unload() {
return PICOKEY_OK; return PICOKEY_OK;
} }
static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id ec_id) {
file_t *ef_devcert_key = file_new(EF_DEVCERT_KEY);
if (!ef_devcert_key) {
return SW_FILE_NOT_FOUND();
}
uint8_t kbase[32] = {0};
derive_kbase(kbase);
if (file_has_data(ef_devcert_key)) {
uint8_t pkey[32] = {0};
memcpy(pkey, file_get_data(ef_devcert_key), 32);
aes_decrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32);
int ret = mbedtls_ecp_read_key(ec_id, ecp, pkey, 32);
mbedtls_platform_zeroize(pkey, sizeof(pkey));
if (ret != 0) {
return SW_EXEC_ERROR();
}
}
else {
// Generate new key
uint8_t pkey[MBEDTLS_ECP_MAX_BYTES] = {0};
size_t olen = 0;
mbedtls_ecp_gen_key(ec_id, ecp, random_gen, NULL);
mbedtls_ecp_write_key_ext(ecp, &olen, pkey, sizeof(pkey));
aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, pkey, 32);
file_put_data(ef_devcert_key, pkey, (uint16_t)olen);
mbedtls_platform_zeroize(pkey, sizeof(pkey));
low_flash_available();
}
return PICOKEY_OK;
}
int cmd_keydev_sign() { int cmd_keydev_sign() {
uint8_t p1 = P1(apdu); uint8_t p1 = P1(apdu);
if (p1 == 0x01) { if (p1 == 0x01) {
if (apdu.nc != 32) { if (apdu.nc != 32) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
mbedtls_ecp_keypair ecp;
mbedtls_ecp_keypair_init(&ecp);
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1;
if (!otp_key_2) { if (!otp_key_2) {
int ret = load_internal_keydev(&ecp, ec_id); return SW_INS_NOT_SUPPORTED();
if (ret != PICOKEY_OK) {
mbedtls_ecp_keypair_free(&ecp);
return ret;
}
} }
else { mbedtls_ecdsa_context ecdsa;
int ret = mbedtls_ecp_read_key(ec_id, &ecp, otp_key_2, 32); mbedtls_ecdsa_init(&ecdsa);
if (ret != 0) { int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecdsa, otp_key_2, 32);
mbedtls_ecp_keypair_free(&ecp); if (ret != 0) {
return SW_EXEC_ERROR(); mbedtls_ecdsa_free(&ecdsa);
} return SW_EXEC_ERROR();
} }
uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(ec_id)->bit_size + 7) / 8); uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(MBEDTLS_ECP_DP_SECP256K1)->bit_size + 7) / 8);
mbedtls_mpi r, s; mbedtls_mpi r, s;
mbedtls_mpi_init(&r); mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s); mbedtls_mpi_init(&s);
int ret = mbedtls_ecdsa_sign(&ecp.MBEDTLS_PRIVATE(grp), &r, &s, &ecp.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL); ret = mbedtls_ecdsa_sign(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL);
if (ret != 0) { if (ret != 0) {
mbedtls_ecp_keypair_free(&ecp); mbedtls_ecdsa_free(&ecdsa);
mbedtls_mpi_free(&r); mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s); mbedtls_mpi_free(&s);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
@@ -148,33 +106,26 @@ int cmd_keydev_sign() {
mbedtls_mpi_write_binary(&r, res_APDU, key_size / 2); res_APDU_size = key_size / 2; mbedtls_mpi_write_binary(&r, res_APDU, key_size / 2); res_APDU_size = key_size / 2;
mbedtls_mpi_write_binary(&s, res_APDU + res_APDU_size, key_size / 2); res_APDU_size += key_size / 2; mbedtls_mpi_write_binary(&s, res_APDU + res_APDU_size, key_size / 2); res_APDU_size += key_size / 2;
mbedtls_ecp_keypair_free(&ecp); mbedtls_ecdsa_free(&ecdsa);
mbedtls_mpi_free(&r); mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s); mbedtls_mpi_free(&s);
} }
else if (p1 == 0x02) { else if (p1 == 0x02) {
// Return public key // Return public key
if (!otp_key_2) {
return SW_INS_NOT_SUPPORTED();
}
if (apdu.nc != 0) { if (apdu.nc != 0) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
mbedtls_ecp_keypair ecp; mbedtls_ecp_keypair ecp;
mbedtls_ecp_keypair_init(&ecp); mbedtls_ecp_keypair_init(&ecp);
mbedtls_ecp_group_id ec_id = MBEDTLS_ECP_DP_SECP256K1; int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecp, otp_key_2, 32);
if (!otp_key_2) { if (ret != 0) {
int ret = load_internal_keydev(&ecp, ec_id); mbedtls_ecp_keypair_free(&ecp);
if (ret != PICOKEY_OK) { return SW_EXEC_ERROR();
mbedtls_ecp_keypair_free(&ecp);
return ret;
}
} }
else { ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL);
int ret = mbedtls_ecp_read_key(ec_id, &ecp, otp_key_2, 32);
if (ret != 0) {
mbedtls_ecp_keypair_free(&ecp);
return SW_EXEC_ERROR();
}
}
int ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL);
if (ret != 0) { if (ret != 0) {
mbedtls_ecp_keypair_free(&ecp); mbedtls_ecp_keypair_free(&ecp);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();

View File

@@ -323,10 +323,14 @@ char const *string_desc_arr [] = {
"Pico Key", // 2: Product "Pico Key", // 2: Product
"11223344", // 3: Serials, should use chip ID "11223344", // 3: Serials, should use chip ID
"Config" // 4: Vendor Interface "Config" // 4: Vendor Interface
#ifdef USB_ITF_HID
, "HID Interface" , "HID Interface"
, "HID Keyboard Interface" , "HID Keyboard Interface"
#endif
#ifdef USB_ITF_CCID
, "CCID OTP FIDO Interface" , "CCID OTP FIDO Interface"
, "WebCCID Interface" , "WebCCID Interface"
#endif
}; };
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM