mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
Fixed pin reset
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
86cef892ff
commit
c8325babb2
7 changed files with 66 additions and 38 deletions
37
file.c
37
file.c
|
|
@ -14,6 +14,8 @@ extern int flash_program_uintptr (uintptr_t addr, uintptr_t data);
|
|||
extern int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len);
|
||||
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 void low_flash_available();
|
||||
|
||||
//puts FCI in the RAPDU
|
||||
|
|
@ -75,7 +77,7 @@ file_t file_entries[] = {
|
|||
/* 11 */ { .fid = 0x1083, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (PIN1)
|
||||
/* 12 */ { .fid = 0x1088, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (SOPIN)
|
||||
/* 13 */ { .fid = 0x1089, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (SOPIN)
|
||||
/* 14 */ { .fid = 0x1090, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN)
|
||||
/* 14 */ { .fid = 0x108A, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN)
|
||||
/* 15 */ { .fid = 0x6040, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs
|
||||
/* 16 */ { .fid = 0x6041, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs
|
||||
/* 17 */ { .fid = 0x6042, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs
|
||||
|
|
@ -186,27 +188,6 @@ bool authenticate_action(const file_t *ef, uint8_t op) {
|
|||
|
||||
#include "libopensc/pkcs15.h"
|
||||
|
||||
int reset_pin_retries(const file_t *pin) {
|
||||
if (!pin)
|
||||
return HSM_ERR_NULL_PARAM;
|
||||
const file_t *max = search_by_fid(pin->fid+1, NULL, SPECIFY_EF);
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!max || !act)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
return flash_write_data_to_file((file_t *)act, &max->data[2], sizeof(uint8_t));
|
||||
}
|
||||
|
||||
int pin_wrong_retry(const file_t *pin) {
|
||||
if (!pin)
|
||||
return HSM_ERR_NULL_PARAM;
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!act)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
if (act->data[2] > 0)
|
||||
return flash_write_data_to_file((file_t *)act, &act->data[2]-1, sizeof(uint8_t));
|
||||
return HSM_ERR_BLOCKED;
|
||||
}
|
||||
|
||||
void scan_flash() {
|
||||
if (*(uintptr_t *)end_data_pool == 0xffffffff && *(uintptr_t *)(end_data_pool+sizeof(uintptr_t)) == 0xffffffff)
|
||||
{
|
||||
|
|
@ -311,7 +292,7 @@ void scan_flash() {
|
|||
else {
|
||||
TU_LOG1("FATAL ERROR: Retries PIN1 not found in memory!\r\n");
|
||||
}
|
||||
file_retries_sopin = search_by_fid(0x1090, NULL, SPECIFY_EF);
|
||||
file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF);
|
||||
if (file_retries_sopin) {
|
||||
if (!file_retries_sopin->data) {
|
||||
TU_LOG1("Retries SOPIN is empty. Initializing with default retries\r\n");
|
||||
|
|
@ -348,3 +329,13 @@ void scan_flash() {
|
|||
}
|
||||
low_flash_available();
|
||||
}
|
||||
|
||||
uint8_t *file_read(const uint8_t *addr) {
|
||||
return flash_read((uintptr_t)addr);
|
||||
}
|
||||
uint16_t file_read_uint16(const uint8_t *addr) {
|
||||
return flash_read_uint16((uintptr_t)addr);
|
||||
}
|
||||
uint8_t file_read_uint8(const uint8_t *addr) {
|
||||
return flash_read_uint8((uintptr_t)addr);
|
||||
}
|
||||
4
file.h
4
file.h
|
|
@ -68,5 +68,9 @@ extern void scan_flash();
|
|||
|
||||
extern file_t file_entries[];
|
||||
|
||||
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 uint8_t *addr);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
9
flash.c
9
flash.c
|
|
@ -43,6 +43,7 @@
|
|||
#include "hsm2040.h"
|
||||
#include "tusb.h"
|
||||
#include "file.h"
|
||||
#include "sc_hsm.h"
|
||||
|
||||
#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES >> 1) // DATA starts at the mid of flash
|
||||
#define FLASH_DATA_HEADER_SIZE (sizeof(uintptr_t)+sizeof(uint32_t))
|
||||
|
|
@ -130,13 +131,13 @@ int flash_clear_file(file_t *file) {
|
|||
|
||||
int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
|
||||
if (len > FLASH_SECTOR_SIZE)
|
||||
return 1;
|
||||
return HSM_ERR_NO_MEMORY;
|
||||
if (file->data) { //already in flash
|
||||
uint16_t size_file_flash = flash_read_uint16((uintptr_t)file->data);
|
||||
if (len <= size_file_flash) { //it fits, no need to move it
|
||||
flash_program_halfword((uintptr_t)file->data, len);
|
||||
flash_program_block((uintptr_t)file->data+sizeof(uint16_t), data, len);
|
||||
return 0;
|
||||
return HSM_OK;
|
||||
}
|
||||
else { //we clear the old file
|
||||
flash_clear_file(file);
|
||||
|
|
@ -144,10 +145,10 @@ int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
|
|||
}
|
||||
uintptr_t new_addr = allocate_free_addr(len);
|
||||
if (new_addr == 0x0)
|
||||
return 2;
|
||||
return HSM_ERR_NO_MEMORY;
|
||||
file->data = (uint8_t *)new_addr+sizeof(uintptr_t)+sizeof(uint16_t); //next addr+fid
|
||||
flash_program_halfword(new_addr+sizeof(uintptr_t), file->fid);
|
||||
flash_program_halfword((uintptr_t)file->data, len);
|
||||
flash_program_block((uintptr_t)file->data+sizeof(uint16_t), data, len);
|
||||
return 0;
|
||||
return HSM_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,5 @@ void put_binary (const char *s, int len);
|
|||
#endif
|
||||
|
||||
extern int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len);
|
||||
|
||||
|
||||
|
||||
extern void low_flash_available();
|
||||
#endif
|
||||
|
|
@ -199,6 +199,9 @@ uint16_t flash_read_uint16(uintptr_t addr) {
|
|||
}
|
||||
return v;
|
||||
}
|
||||
uint8_t flash_read_uint8(uintptr_t addr) {
|
||||
return *flash_read(addr);
|
||||
}
|
||||
|
||||
int flash_erase_page (uintptr_t addr, size_t page_size)
|
||||
{
|
||||
|
|
|
|||
45
sc_hsm.c
45
sc_hsm.c
|
|
@ -40,7 +40,7 @@ static int cmd_verify() {
|
|||
if (!file_retries_pin1) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
return set_res_sw (0x63, 0xc0 | file_retries_pin1->data[2]);
|
||||
return set_res_sw (0x63, 0xc0 | file_read_uint8(file_retries_pin1->data+2));
|
||||
}
|
||||
else if (p2 == 0x88) { //SOPin
|
||||
}
|
||||
|
|
@ -186,34 +186,64 @@ static int cmd_read_binary()
|
|||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
if (ef->data) {
|
||||
uint16_t data_len = get_uint16_t(ef->data, 0);
|
||||
uint16_t data_len = file_read_uint16(ef->data);
|
||||
if (offset > data_len)
|
||||
return SW_WRONG_P1P2();
|
||||
|
||||
uint16_t maxle = data_len-offset;
|
||||
if (apdu.expected_res_size > maxle)
|
||||
apdu.expected_res_size = maxle;
|
||||
res_APDU = ef->data+2+offset;
|
||||
res_APDU = file_read(ef->data+2+offset);
|
||||
res_APDU_size = data_len-offset;
|
||||
}
|
||||
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
int pin_reset_retries(const file_t *pin) {
|
||||
if (!pin)
|
||||
return HSM_ERR_NULL_PARAM;
|
||||
const file_t *max = search_by_fid(pin->fid+1, NULL, SPECIFY_EF);
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!max || !act)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
uint8_t retries = file_read_uint8(max->data+2);
|
||||
int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries));
|
||||
low_flash_available();
|
||||
return r;
|
||||
}
|
||||
|
||||
int pin_wrong_retry(const file_t *pin) {
|
||||
if (!pin)
|
||||
return HSM_ERR_NULL_PARAM;
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!act)
|
||||
return HSM_ERR_FILE_NOT_FOUND;
|
||||
uint8_t retries = file_read_uint8(act->data+2);
|
||||
if (retries > 0) {
|
||||
retries -= 1;
|
||||
int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries));
|
||||
low_flash_available();
|
||||
return r;
|
||||
}
|
||||
return HSM_ERR_BLOCKED;
|
||||
}
|
||||
|
||||
|
||||
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||
if (!pin)
|
||||
return SW_FILE_NOT_FOUND();
|
||||
if (!pin->data) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
if (len != pin->data[0])
|
||||
if (len != file_read_uint16(pin->data))
|
||||
return SW_CONDITIONS_NOT_SATISFIED();
|
||||
if (memcmp(pin->data+2, data, len) != 0) {
|
||||
if (memcmp(file_read(pin->data+2), data, len) != 0) {
|
||||
if (pin_wrong_retry(pin) != HSM_OK)
|
||||
return SW_PIN_BLOCKED();
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
return reset_pin_retries(pin);
|
||||
return pin_reset_retries(pin);
|
||||
}
|
||||
|
||||
static int cmd_reset_retry() {
|
||||
|
|
@ -229,8 +259,9 @@ static int cmd_reset_retry() {
|
|||
if (r != 0x9000)
|
||||
return r;
|
||||
flash_write_data_to_file(file_pin1, apdu.cmd_apdu_data+8, apdu.cmd_apdu_data_len-8);
|
||||
if (reset_pin_retries(file_pin1) != HSM_OK)
|
||||
if (pin_reset_retries(file_pin1) != HSM_OK)
|
||||
return SW_MEMORY_FAILURE();
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
sc_hsm.h
2
sc_hsm.h
|
|
@ -41,7 +41,7 @@ extern const uint8_t sc_hsm_aid[];
|
|||
#define HSM_ERR_FILE_NOT_FOUND -1003
|
||||
#define HSM_ERR_BLOCKED -1004
|
||||
|
||||
extern int reset_pin_retries(const file_t *pin);
|
||||
extern int pin_reset_retries(const file_t *pin);
|
||||
extern int pin_wrong_retry(const file_t *pin);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue