mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-29 01:21:21 +02:00
@@ -21,6 +21,10 @@
|
||||
#include "apdu.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_DEPTH 4
|
||||
|
||||
#define MAX_DYNAMIC_FILES 256
|
||||
|
||||
extern const uintptr_t end_data_pool;
|
||||
extern const uintptr_t start_data_pool;
|
||||
extern const uintptr_t end_rom_pool;
|
||||
@@ -129,7 +133,7 @@ file_t *search_by_name(uint8_t *name, uint16_t namelen) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file_t *search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp) {
|
||||
file_t *file_search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp) {
|
||||
#ifndef ENABLE_EMULATION
|
||||
if (fid == EF_PHY) {
|
||||
return ef_phy;
|
||||
@@ -149,8 +153,17 @@ file_t *search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file_t *search_file(const uint16_t fid) {
|
||||
file_t *ef = search_by_fid(fid, NULL, SPECIFY_EF);
|
||||
static file_t *search_dynamic_file(uint16_t fid) {
|
||||
for (int i = 0; i < dynamic_files; i++) {
|
||||
if (dynamic_file[i].fid == fid) {
|
||||
return &dynamic_file[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file_t *file_search(const uint16_t fid) {
|
||||
file_t *ef = file_search_by_fid(fid, NULL, SPECIFY_EF);
|
||||
if (ef) {
|
||||
return ef;
|
||||
}
|
||||
@@ -218,11 +231,11 @@ bool authenticate_action(const file_t *ef, uint8_t op) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void initialize_flash(bool hard) {
|
||||
void file_initialize_flash(bool hard) {
|
||||
if (hard) {
|
||||
const uint8_t empty[8] = { 0 };
|
||||
flash_program_block(end_data_pool, empty, sizeof(empty));
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
}
|
||||
for (file_t *f = file_entries; f != file_last; f++) {
|
||||
if ((f->type & FILE_DATA_FLASH) == FILE_DATA_FLASH) {
|
||||
@@ -234,8 +247,7 @@ void initialize_flash(bool hard) {
|
||||
|
||||
extern uintptr_t last_base;
|
||||
extern uint32_t num_files;
|
||||
static void scan_region(bool persistent)
|
||||
{
|
||||
static void scan_region(bool persistent) {
|
||||
uintptr_t endp = end_data_pool, startp = start_data_pool;
|
||||
if (persistent) {
|
||||
endp = end_rom_pool;
|
||||
@@ -252,7 +264,7 @@ static void scan_region(bool persistent)
|
||||
|
||||
uint16_t fid = flash_read_uint16(base + sizeof(uintptr_t) + sizeof(uintptr_t));
|
||||
printf("[%x] scan fid %x, len %d\n", (unsigned int) base, fid, flash_read_uint16(base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t)));
|
||||
file_t *file = (file_t *) search_by_fid(fid, NULL, SPECIFY_EF);
|
||||
file_t *file = (file_t *) file_search_by_fid(fid, NULL, SPECIFY_EF);
|
||||
if (!file) {
|
||||
file = file_new(fid);
|
||||
}
|
||||
@@ -270,8 +282,8 @@ static void scan_region(bool persistent)
|
||||
}
|
||||
}
|
||||
}
|
||||
void scan_flash(void) {
|
||||
initialize_flash(false); //soft initialization
|
||||
void file_scan_flash(void) {
|
||||
file_initialize_flash(false); //soft initialization
|
||||
uint32_t r1 = (uint32_t)flash_read_uintptr(end_rom_pool);
|
||||
uint32_t r2 = (uint32_t)flash_read_uintptr(end_rom_pool + sizeof(uintptr_t));
|
||||
if ((r1 == 0xffffffff || r1 == 0xefefefef) && (r2 == 0xffffffff || r2 == 0xefefefef)) {
|
||||
@@ -280,7 +292,7 @@ void scan_flash(void) {
|
||||
memset(empty, 0, sizeof(empty));
|
||||
flash_program_block(end_data_pool, empty, sizeof(empty));
|
||||
flash_program_block(end_rom_pool, empty, sizeof(empty));
|
||||
//low_flash_available();
|
||||
//flash_commit();
|
||||
}
|
||||
printf("SCAN\n");
|
||||
scan_region(true);
|
||||
@@ -318,16 +330,7 @@ int file_put_data(file_t *file, const uint8_t *data, uint16_t len) {
|
||||
return flash_write_data_to_file(file, data, len);
|
||||
}
|
||||
|
||||
file_t *search_dynamic_file(uint16_t fid) {
|
||||
for (int i = 0; i < dynamic_files; i++) {
|
||||
if (dynamic_file[i].fid == fid) {
|
||||
return &dynamic_file[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int delete_dynamic_file(file_t *f) {
|
||||
static int delete_dynamic_file(file_t *f) {
|
||||
if (f == NULL) {
|
||||
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -345,7 +348,7 @@ int delete_dynamic_file(file_t *f) {
|
||||
|
||||
file_t *file_new(uint16_t fid) {
|
||||
file_t *f;
|
||||
if ((f = search_file(fid))) {
|
||||
if ((f = file_search(fid))) {
|
||||
return f;
|
||||
}
|
||||
if (dynamic_files == MAX_DYNAMIC_FILES) {
|
||||
@@ -367,7 +370,7 @@ file_t *file_new(uint16_t fid) {
|
||||
return f;
|
||||
}
|
||||
uint16_t meta_find(uint16_t fid, uint8_t **out) {
|
||||
file_t *ef = search_file(EF_META);
|
||||
file_t *ef = file_search(EF_META);
|
||||
if (!ef) {
|
||||
return 0;
|
||||
}
|
||||
@@ -391,7 +394,7 @@ uint16_t meta_find(uint16_t fid, uint8_t **out) {
|
||||
return 0;
|
||||
}
|
||||
int meta_delete(uint16_t fid) {
|
||||
file_t *ef = search_file(EF_META);
|
||||
file_t *ef = file_search(EF_META);
|
||||
if (!ef) {
|
||||
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -426,7 +429,7 @@ int meta_delete(uint16_t fid) {
|
||||
return PICOKEYS_EXEC_ERROR;
|
||||
}
|
||||
}
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -434,7 +437,7 @@ int meta_delete(uint16_t fid) {
|
||||
}
|
||||
int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||
int r;
|
||||
file_t *ef = search_file(EF_META);
|
||||
file_t *ef = file_search(EF_META);
|
||||
if (!ef) {
|
||||
return PICOKEYS_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -520,6 +523,27 @@ int delete_file(file_t *ef) {
|
||||
if (delete_dynamic_file(ef) != PICOKEYS_OK) {
|
||||
return PICOKEYS_EXEC_ERROR;
|
||||
}
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
|
||||
int flash_clear_file(file_t *file) {
|
||||
if (file == NULL || file->data == NULL) {
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
uintptr_t base_addr = (uintptr_t)(file->data - sizeof(uintptr_t) - sizeof(uint16_t) - sizeof(uintptr_t));
|
||||
uintptr_t prev_addr = flash_read_uintptr(base_addr + sizeof(uintptr_t));
|
||||
uintptr_t next_addr = flash_read_uintptr(base_addr);
|
||||
//printf("nc %lx->%lx %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr),base_addr,next_addr);
|
||||
flash_program_uintptr(prev_addr, next_addr);
|
||||
flash_program_halfword((uintptr_t) file->data, 0);
|
||||
if (next_addr > 0) {
|
||||
flash_program_uintptr(next_addr + sizeof(uintptr_t), prev_addr);
|
||||
}
|
||||
flash_program_uintptr(base_addr, 0);
|
||||
flash_program_uintptr(base_addr + sizeof(uintptr_t), 0);
|
||||
file->data = NULL;
|
||||
num_files--;
|
||||
//printf("na %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr));
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
|
||||
@@ -62,18 +62,8 @@
|
||||
#define SPECIFY_DF 0x2
|
||||
#define SPECIFY_ANY 0x3
|
||||
|
||||
#define EF_PRKDFS 0x6040
|
||||
#define EF_PUKDFS 0x6041
|
||||
#define EF_CDFS 0x6042
|
||||
#define EF_AODFS 0x6043
|
||||
#define EF_DODFS 0x6044
|
||||
#define EF_SKDFS 0x6045
|
||||
#define EF_META 0xE010
|
||||
|
||||
#define MAX_DEPTH 4
|
||||
|
||||
#define MAX_DYNAMIC_FILES 256
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__pragma( pack(push, 1) )
|
||||
#endif
|
||||
@@ -96,30 +86,22 @@ __attribute__ ((packed))
|
||||
#endif
|
||||
file_t;
|
||||
|
||||
extern bool file_has_data(const file_t *);
|
||||
|
||||
extern file_t *currentEF;
|
||||
extern file_t *currentDF;
|
||||
extern const file_t *selected_applet;
|
||||
|
||||
extern const file_t *MF;
|
||||
extern const file_t *file_last;
|
||||
extern const file_t *file_openpgp;
|
||||
extern const file_t *file_sc_hsm;
|
||||
extern bool card_terminated;
|
||||
extern file_t *file_pin1;
|
||||
extern file_t *file_retries_pin1;
|
||||
extern file_t *file_sopin;
|
||||
extern file_t *file_retries_sopin;
|
||||
|
||||
extern file_t *search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp);
|
||||
extern file_t *search_file(const uint16_t fid);
|
||||
extern file_t *search_by_name(uint8_t *name, uint16_t namelen);
|
||||
extern file_t *search_by_path(const uint8_t *pe_path, uint8_t pathlen, const file_t *parent);
|
||||
extern bool authenticate_action(const file_t *ef, uint8_t op);
|
||||
extern void process_fci(const file_t *pe, int fmd);
|
||||
extern void scan_flash(void);
|
||||
extern void initialize_flash(bool);
|
||||
extern file_t *file_search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp);
|
||||
extern file_t *file_search(const uint16_t fid);
|
||||
extern file_t *file_search_by_name(uint8_t *name, uint16_t namelen);
|
||||
extern file_t *file_search_by_path(const uint8_t *pe_path, uint8_t pathlen, const file_t *parent);
|
||||
extern bool file_authenticate_action(const file_t *ef, uint8_t op);
|
||||
extern void file_process_fci(const file_t *pe, int fmd);
|
||||
extern void file_scan_flash(void);
|
||||
extern void file_initialize_flash(bool);
|
||||
|
||||
extern file_t file_entries[];
|
||||
|
||||
@@ -127,17 +109,14 @@ extern uint8_t *file_read(const uint8_t *addr);
|
||||
extern uint16_t file_read_uint16(const uint8_t *addr);
|
||||
extern uint8_t file_read_uint8(const file_t *ef);
|
||||
extern uint8_t file_read_uint8_offset(const file_t *ef, const uint16_t offset);
|
||||
extern bool file_has_data(const file_t *);
|
||||
extern uint8_t *file_get_data(const file_t *tf);
|
||||
extern uint16_t file_get_size(const file_t *tf);
|
||||
extern int file_put_data(file_t *file, const uint8_t *data, uint16_t len);
|
||||
extern file_t *file_new(uint16_t);
|
||||
extern int flash_clear_file(file_t *file);
|
||||
file_t *get_parent(file_t *f);
|
||||
|
||||
extern uint16_t dynamic_files;
|
||||
extern file_t dynamic_file[];
|
||||
extern file_t *search_dynamic_file(uint16_t);
|
||||
extern int delete_dynamic_file(file_t *f);
|
||||
|
||||
extern bool isUserAuthenticated;
|
||||
|
||||
extern uint16_t meta_find(uint16_t, uint8_t **out);
|
||||
@@ -145,27 +124,6 @@ extern int meta_delete(uint16_t fid);
|
||||
extern int meta_add(uint16_t fid, const uint8_t *data, uint16_t len);
|
||||
extern int delete_file(file_t *ef);
|
||||
|
||||
extern uint32_t flash_free_space(void);
|
||||
extern uint32_t flash_used_space(void);
|
||||
extern uint32_t flash_total_space(void);
|
||||
extern uint32_t flash_num_files(void);
|
||||
extern uint32_t flash_size(void);
|
||||
|
||||
extern void flash_set_bounds(uintptr_t start, uintptr_t end);
|
||||
extern int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len);
|
||||
extern int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len);
|
||||
extern int flash_program_halfword(uintptr_t addr, uint16_t data);
|
||||
extern int flash_program_word(uintptr_t addr, uint32_t data);
|
||||
extern int flash_program_uintptr(uintptr_t addr, uintptr_t data);
|
||||
extern uintptr_t flash_read_uintptr(uintptr_t addr);
|
||||
extern uint16_t flash_read_uint16(uintptr_t addr);
|
||||
extern uint8_t flash_read_uint8(uintptr_t addr);
|
||||
extern uint8_t *flash_read(uintptr_t addr);
|
||||
extern int flash_erase_page(uintptr_t addr, size_t page_size);
|
||||
extern bool flash_check_blank(const uint8_t *p_start, size_t size);
|
||||
extern void flash_task(void);
|
||||
extern void low_flash_init(void);
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
extern file_t *ef_phy;
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,7 @@ uint32_t FLASH_SIZE_BYTES = (2 * 1024 * 1024);
|
||||
#include "file.h"
|
||||
|
||||
extern void low_flash_task(void);
|
||||
extern void low_flash_commit(void);
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------
|
||||
@@ -111,27 +112,6 @@ static uintptr_t allocate_free_addr(uint16_t size, bool persistent) {
|
||||
return 0x0; //probably never reached
|
||||
}
|
||||
|
||||
int flash_clear_file(file_t *file) {
|
||||
if (file == NULL || file->data == NULL) {
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
uintptr_t base_addr = (uintptr_t)(file->data - sizeof(uintptr_t) - sizeof(uint16_t) - sizeof(uintptr_t));
|
||||
uintptr_t prev_addr = flash_read_uintptr(base_addr + sizeof(uintptr_t));
|
||||
uintptr_t next_addr = flash_read_uintptr(base_addr);
|
||||
//printf("nc %lx->%lx %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr),base_addr,next_addr);
|
||||
flash_program_uintptr(prev_addr, next_addr);
|
||||
flash_program_halfword((uintptr_t) file->data, 0);
|
||||
if (next_addr > 0) {
|
||||
flash_program_uintptr(next_addr + sizeof(uintptr_t), prev_addr);
|
||||
}
|
||||
flash_program_uintptr(base_addr, 0);
|
||||
flash_program_uintptr(base_addr + sizeof(uintptr_t), 0);
|
||||
file->data = NULL;
|
||||
num_files--;
|
||||
//printf("na %lx->%lx\n",prev_addr,flash_read_uintptr(prev_addr));
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
|
||||
static int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len, uint16_t offset) {
|
||||
if (!file) {
|
||||
return PICOKEYS_ERR_NULL_PARAM;
|
||||
@@ -209,3 +189,7 @@ uint32_t flash_size(void) {
|
||||
void flash_task(void) {
|
||||
low_flash_task();
|
||||
}
|
||||
|
||||
void flash_commit(void) {
|
||||
low_flash_commit();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,29 @@
|
||||
#ifndef _FLASH_H
|
||||
#define _FLASH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern uint32_t flash_free_space(void);
|
||||
extern uint32_t flash_used_space(void);
|
||||
extern uint32_t flash_total_space(void);
|
||||
extern uint32_t flash_num_files(void);
|
||||
extern uint32_t flash_size(void);
|
||||
|
||||
extern void flash_set_bounds(uintptr_t start, uintptr_t end);
|
||||
extern int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len);
|
||||
extern int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len);
|
||||
extern int flash_program_halfword(uintptr_t addr, uint16_t data);
|
||||
extern int flash_program_word(uintptr_t addr, uint32_t data);
|
||||
extern int flash_program_uintptr(uintptr_t addr, uintptr_t data);
|
||||
extern uintptr_t flash_read_uintptr(uintptr_t addr);
|
||||
extern uint16_t flash_read_uint16(uintptr_t addr);
|
||||
extern uint8_t flash_read_uint8(uintptr_t addr);
|
||||
extern uint8_t *flash_read(uintptr_t addr);
|
||||
extern int flash_erase_page(uintptr_t addr, size_t page_size);
|
||||
extern bool flash_check_blank(const uint8_t *p_start, size_t size);
|
||||
extern void flash_task(void);
|
||||
extern void low_flash_init(void);
|
||||
extern void flash_commit(void);
|
||||
|
||||
#endif // _FLASH_H
|
||||
|
||||
@@ -245,7 +245,7 @@ void low_flash_init_core1(void) {
|
||||
mutex_exit(&mtx_flash);
|
||||
}
|
||||
|
||||
void low_flash_available(void) {
|
||||
void low_flash_commit(void) {
|
||||
mutex_enter_blocking(&mtx_flash);
|
||||
flash_available = true;
|
||||
mutex_exit(&mtx_flash);
|
||||
|
||||
@@ -517,7 +517,7 @@ static void otp_migrate_chaff(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_otp_files(void) {
|
||||
void otp_init_files(void) {
|
||||
|
||||
#ifdef PICO_RP2350
|
||||
otp_migrate_chaff();
|
||||
|
||||
@@ -46,7 +46,7 @@ extern int otp_write_data_raw(uint16_t row, const uint8_t *data, uint16_t len);
|
||||
#endif
|
||||
|
||||
extern int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock);
|
||||
extern void init_otp_files(void);
|
||||
extern void otp_init_files(void);
|
||||
|
||||
extern const uint8_t *otp_key_1;
|
||||
extern const uint8_t *otp_key_2;
|
||||
|
||||
@@ -177,7 +177,7 @@ int phy_save(void) {
|
||||
return ret;
|
||||
}
|
||||
file_put_data(ef_phy, tmp, tmp_len);
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,13 +37,12 @@
|
||||
#include "apdu.h"
|
||||
#include "usb.h"
|
||||
#include "flash.h"
|
||||
#include "otp.h"
|
||||
#include "led/led.h"
|
||||
#include "pico_time.h"
|
||||
#include "serial.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
extern void init_otp_files(void);
|
||||
|
||||
app_t apps[16];
|
||||
uint8_t num_apps = 0;
|
||||
|
||||
@@ -159,11 +158,11 @@ int main(void) {
|
||||
|
||||
random_init();
|
||||
|
||||
init_otp_files();
|
||||
otp_init_files();
|
||||
|
||||
low_flash_init();
|
||||
|
||||
scan_flash();
|
||||
file_scan_flash();
|
||||
|
||||
init_rtc();
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "flash.h"
|
||||
#include "debug.h"
|
||||
|
||||
#if !defined(MIN)
|
||||
@@ -142,9 +143,6 @@ static inline uint32_t put_uint64_le(uint64_t n, uint8_t *b) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
extern void low_flash_available(void);
|
||||
extern int flash_clear_file(file_t *file);
|
||||
|
||||
extern int (*button_pressed_cb)(uint8_t);
|
||||
|
||||
extern bool is_req_button_pending(void);
|
||||
|
||||
@@ -76,7 +76,7 @@ static int rescue_select(app_t *a, uint8_t force) {
|
||||
res_APDU_size += sizeof(pico_serial.id);
|
||||
apdu.ne = res_APDU_size;
|
||||
if (force) {
|
||||
scan_flash();
|
||||
file_scan_flash();
|
||||
}
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ static int load_internal_keydev(mbedtls_ecp_keypair *ecp, mbedtls_ecp_group_id e
|
||||
aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICOKEYS_AES_MODE_CBC, pkey, 32);
|
||||
file_put_data(ef_devcert_key, pkey, (uint16_t)olen);
|
||||
mbedtls_platform_zeroize(pkey, sizeof(pkey));
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
}
|
||||
return PICOKEYS_OK;
|
||||
}
|
||||
@@ -222,7 +222,7 @@ static int cmd_keydev_sign(void) {
|
||||
}
|
||||
file_put_data(ef_devcert, apdu.data, (uint16_t)apdu.nc);
|
||||
res_APDU_size = 0;
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
}
|
||||
else {
|
||||
return SW_INCORRECT_P1P2();
|
||||
|
||||
@@ -538,7 +538,7 @@ void rest_check_and_load_credentials(void) {
|
||||
mbedtls_pk_context key;
|
||||
unsigned char cert_pem[2048] = {0};
|
||||
int ret = 0;
|
||||
file_t *ef_key = search_file(EF_TLS_KEY);
|
||||
file_t *ef_key = file_search(EF_TLS_KEY);
|
||||
const uint8_t *file = file_get_data(ef_key);
|
||||
size_t file_len = file_get_size(ef_key);
|
||||
|
||||
@@ -585,7 +585,7 @@ out:
|
||||
tls_credentials.tls_cert_pem = (char *)file_get_data(ef);
|
||||
tls_credentials.tls_cert_pem_len = file_get_size(ef);
|
||||
printf("TLS certificate loaded, length: %u bytes\n", (unsigned)tls_credentials.tls_cert_pem_len);
|
||||
low_flash_available();
|
||||
flash_commit();
|
||||
}
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
|
||||
Reference in New Issue
Block a user