From 7b5cb48dcc693cd476754a5b17ae11b4bd2b70b6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 23 May 2022 20:06:06 +0200 Subject: [PATCH] Added key domains for device initialization and dkek import. Signed-off-by: Pol Henarejos --- pico-ccid | 2 +- src/hsm/dkek.c | 4 ++-- src/hsm/files.c | 21 +++++++++--------- src/hsm/files.h | 4 ++-- src/hsm/sc_hsm.c | 58 ++++++++++++++++++++++++++++++++---------------- 5 files changed, 54 insertions(+), 35 deletions(-) diff --git a/pico-ccid b/pico-ccid index de04dd6..d19429c 160000 --- a/pico-ccid +++ b/pico-ccid @@ -1 +1 @@ -Subproject commit de04dd612102bd9f82a51006d631ff0b9198d82a +Subproject commit d19429cb84dd388c90594b32aa2557ea631249f9 diff --git a/src/hsm/dkek.c b/src/hsm/dkek.c index d40d437..6ad03ce 100644 --- a/src/hsm/dkek.c +++ b/src/hsm/dkek.c @@ -37,7 +37,7 @@ extern uint8_t session_pin[32]; int load_dkek() { if (has_session_pin == false) return CCID_NO_LOGIN; - file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF); + file_t *tf = search_dynamic_file(EF_DKEK); if (!tf) return CCID_ERR_FILE_NOT_FOUND; memcpy(dkek, file_read(tf->data+sizeof(uint16_t)), IV_SIZE+32); @@ -58,7 +58,7 @@ void init_dkek() { int store_dkek_key() { aes_encrypt_cfb_256(session_pin, dkek, dkek+IV_SIZE, 32); - file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF); + file_t *tf = search_dynamic_file(EF_DKEK); if (!tf) return CCID_ERR_FILE_NOT_FOUND; flash_write_data_to_file(tf, dkek, sizeof(dkek)); diff --git a/src/hsm/files.c b/src/hsm/files.c index 12e30fc..7f65045 100644 --- a/src/hsm/files.c +++ b/src/hsm/files.c @@ -37,17 +37,16 @@ file_t file_entries[] = { /* 12 */ { .fid = 0x1088 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (SOPIN) /* 13 */ { .fid = 0x1089 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (SOPIN) /* 14 */ { .fid = 0x108A , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN) - /* 15 */ { .fid = EF_DKEK , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //DKEK - /* 16 */ { .fid = EF_DEVOPS , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Device options - /* 17 */ { .fid = EF_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs - /* 18 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs - /* 19 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs - /* 20 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs - /* 21 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs - /* 22 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs - ///* 23 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, - /* 24 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, - /* 25 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end + /* 15 */ { .fid = EF_DEVOPS , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Device options + /* 16 */ { .fid = EF_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs + /* 17 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs + /* 18 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs + /* 19 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs + /* 20 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs + /* 21 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs + ///* 22 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, + /* 23 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, + /* 24 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end }; const file_t *MF = &file_entries[0]; diff --git a/src/hsm/files.h b/src/hsm/files.h index a1a51bd..4474cfa 100644 --- a/src/hsm/files.h +++ b/src/hsm/files.h @@ -21,14 +21,14 @@ #include "file.h" -#define EF_DKEK 0x108F +#define EF_DEVOPS 0x100E +#define EF_DKEK 0x1090 #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_DEVOPS 0x100E extern file_t *file_pin1; extern file_t *file_retries_pin1; diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 0357544..7b56e26 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -720,6 +720,19 @@ static int cmd_initialize() { } else if (tag == 0x92) { dkeks = *tag_data; + file_t *tf = file_new(EF_DKEK); + if (!tf) + return SW_MEMORY_FAILURE(); + low_flash_available(); + } + else if (tag == 0x97) { + for (int i = 0; i < MIN(*tag_data,16); i++) { + file_t *tf = file_new(EF_DKEK+i); + if (!tf) + return SW_MEMORY_FAILURE(); + flash_write_data_to_file(tf, NULL, 0); + } + low_flash_available(); } } if (dkeks == 0) { @@ -747,29 +760,36 @@ static int cmd_initialize() { static int cmd_key_domain() { //if (dkeks == 0) // return SW_COMMAND_NOT_ALLOWED(); - if (P1(apdu) != 0x0 || P2(apdu) != 0x0) - return SW_INCORRECT_P1P2(); + uint8_t p1 = P1(apdu), p2 = P2(apdu); if (has_session_pin == false && apdu.cmd_apdu_data_len > 0) return SW_CONDITIONS_NOT_SATISFIED(); - file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF); - if (!authenticate_action(get_parent(tf), ACL_OP_CREATE_EF)) { - return SW_SECURITY_STATUS_NOT_SATISFIED(); - } - if (apdu.cmd_apdu_data_len > 0) { - if (apdu.cmd_apdu_data_len < 32) - return SW_WRONG_LENGTH(); - import_dkek_share(apdu.cmd_apdu_data); - if (++current_dkeks == dkeks) { - if (save_dkek_key(NULL) != CCID_OK) - return SW_FILE_NOT_FOUND(); - + if (p1 == 0x0) { //dkek import + if (p2 > 0xF) + return SW_WRONG_P1P2(); + if (apdu.cmd_apdu_data_len > 0) { + file_t *tf = file_new(EF_DKEK+p2); + if (!tf) + return SW_MEMORY_FAILURE(); + if (apdu.cmd_apdu_data_len < 32) + return SW_WRONG_LENGTH(); + import_dkek_share(apdu.cmd_apdu_data); + if (++current_dkeks == dkeks) { + if (save_dkek_key(NULL) != CCID_OK) + return SW_FILE_NOT_FOUND(); + } + low_flash_available(); } + else { + file_t *tf = search_dynamic_file(EF_DKEK+p2); + if (!tf) + return SW_INCORRECT_P1P2(); + } + memset(res_APDU,0,10); + res_APDU[0] = dkeks; + res_APDU[1] = dkeks-current_dkeks; + dkek_kcv(res_APDU+2); + res_APDU_size = 2+8; } - memset(res_APDU,0,10); - res_APDU[0] = dkeks; - res_APDU[1] = dkeks-current_dkeks; - dkek_kcv(res_APDU+2); - res_APDU_size = 2+8; return SW_OK(); }