Fixed pin reset

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2022-02-14 00:29:04 +01:00
parent 86cef892ff
commit c8325babb2
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
7 changed files with 66 additions and 38 deletions

37
file.c
View file

@ -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
View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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)
{

View file

@ -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();
}
}

View file

@ -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