From ecfeb632731efc61cb8305600d0a46fa96d956e7 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 20 Feb 2022 20:05:46 +0100 Subject: [PATCH] Storing private keys as only P and Q for RSA. They are converted on the fly upon a request. Signed-off-by: Pol Henarejos --- file.c | 83 ++++++++++++++++++++++++++++++++++++++++---------------- file.h | 25 +++++++++++++++-- sc_hsm.c | 36 ++++++++++++++++++------ 3 files changed, 110 insertions(+), 34 deletions(-) diff --git a/file.c b/file.c index 2826362..3950ec5 100644 --- a/file.c +++ b/file.c @@ -3,6 +3,7 @@ #include "tusb.h" #include "hsm2040.h" #include "sc_hsm.h" +#include "libopensc/card-sc-hsm.h" #include extern const uintptr_t end_data_pool; @@ -95,28 +96,28 @@ const uint8_t token_info[] = { extern const uint8_t sc_hsm_aid[]; file_t file_entries[] = { - /* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, // MF - /* 1 */ { .fid = 0x2f00, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DIR - /* 2 */ { .fid = 0x2f01, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ATR - /* 3 */ { .fid = 0x2f02, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF,.data = (uint8_t *)cvca, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO - /* 4 */ { .fid = 0x2f03, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF,.data = (uint8_t *)token_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo - /* 5 */ { .fid = 0x5015, .parent = 0, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, //DF.PKCS15 - /* 6 */ { .fid = 0x5031, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ODF - /* 7 */ { .fid = 0x5032, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo - /* 8 */ { .fid = 0x5033, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.UnusedSpace - /* 9 */ { .fid = 0x1081, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (PIN1) - /* 10 */ { .fid = 0x1082, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (PIN1) - /* 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 = 0x108A, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN) - /* 15 */ { .fid = 0x108F, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //DKEK - /* 16 */ { .fid = 0x6040, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs - /* 17 */ { .fid = 0x6041, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs - /* 18 */ { .fid = 0x6042, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs - /* 19 */ { .fid = 0x6043, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs - /* 20 */ { .fid = 0x6044, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs - /* 21 */ { .fid = 0x6045, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs + /* 0 */ { .fid = 0x3f00 , .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, // MF + /* 1 */ { .fid = 0x2f00 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DIR + /* 2 */ { .fid = 0x2f01 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ATR + /* 3 */ { .fid = 0x2f02 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF,.data = (uint8_t *)cvca, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO + /* 4 */ { .fid = 0x2f03 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF,.data = (uint8_t *)token_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo + /* 5 */ { .fid = 0x5015 , .parent = 0, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, //DF.PKCS15 + /* 6 */ { .fid = 0x5031 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ODF + /* 7 */ { .fid = 0x5032 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo + /* 8 */ { .fid = 0x5033 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.UnusedSpace + /* 9 */ { .fid = 0x1081 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (PIN1) + /* 10 */ { .fid = 0x1082 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (PIN1) + /* 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 = 0x108A , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF, .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, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //DKEK + /* 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 @@ -131,6 +132,10 @@ file_t *file_retries_pin1 = NULL; file_t *file_sopin = NULL; file_t *file_retries_sopin = NULL; +file_chain_t *ef_prkdf = NULL; +file_chain_t *ef_pukdf = NULL; +file_chain_t *ef_cdf = NULL; + bool card_terminated = false; bool is_parent(const file_t *child, const file_t *parent) { @@ -275,8 +280,14 @@ void scan_flash() { uint16_t fid = flash_read_uint16(base+sizeof(uintptr_t)); file_t *file = (file_t *)search_by_fid(fid, NULL, SPECIFY_EF); if (!file) { - TU_LOG1("SCAN FOUND ORPHAN FILE: %x\r\n",fid); - continue; + if ((fid & 0xff00) == (KEY_PREFIX << 8)) { + file = file_new(fid); + add_file_to_chain(file, &ef_prkdf); + } + else { + TU_LOG1("SCAN FOUND ORPHAN FILE: %x\r\n",fid); + continue; + } } file->data = (uint8_t *)(base+sizeof(uintptr_t)+sizeof(uint16_t)); if (flash_read_uintptr(base) == 0x0) { @@ -362,4 +373,28 @@ uint16_t file_read_uint16(const uint8_t *addr) { } uint8_t file_read_uint8(const uint8_t *addr) { return flash_read_uint8((uintptr_t)addr); +} + +file_t *file_new(uint16_t fid) { + file_t *f = (file_t *)malloc(sizeof(file_t)); + file_t file = { + .fid = fid, + .parent = 5, + .name = NULL, + .type = FILE_TYPE_WORKING_EF, + .ef_structure = FILE_EF_TRANSPARENT, + .data = NULL, + .acl = {0} + }; + memcpy(f, &file, sizeof(file_t)); + memset((uint8_t *)f->acl, 0x90, sizeof(f->acl)); + return f; +} + +file_chain_t *add_file_to_chain(file_t *file, file_chain_t **chain) { + file_chain_t *f_chain = (file_chain_t *)malloc(sizeof(file_chain_t)); + f_chain->file = file; + f_chain->next = *chain; + *chain = f_chain; + return f_chain; } \ No newline at end of file diff --git a/file.h b/file.h index f2e31ee..e918375 100644 --- a/file.h +++ b/file.h @@ -32,6 +32,14 @@ #define SPECIFY_DF 0x2 #define SPECIFY_ANY 0x3 +#define EF_DKEK 0x108F +#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 MAX_DEPTH 4 typedef struct file @@ -40,10 +48,16 @@ typedef struct file const uint8_t parent; //entry number in the whole table!! const uint8_t *name; const uint8_t type; - uint8_t *data; //should include 2 bytes len at begining const uint8_t ef_structure; + uint8_t *data; //should include 2 bytes len at begining const uint8_t acl[7]; -} file_t; +} __attribute__((packed)) file_t; + +typedef struct file_chain +{ + file_t *file; + struct file_chain *next; +} file_chain_t; extern file_t *currentEF; extern file_t *currentDF; @@ -71,6 +85,13 @@ 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); +extern file_t *file_new(uint16_t); + +extern file_chain_t *ef_prkdf; +extern file_chain_t *ef_pukdf; +extern file_chain_t *ef_cdf; + +extern file_chain_t *add_file_to_chain(file_t *file, file_chain_t **chain); #endif diff --git a/sc_hsm.c b/sc_hsm.c index bd43830..461b7ed 100644 --- a/sc_hsm.c +++ b/sc_hsm.c @@ -356,7 +356,7 @@ static int cmd_initialize() { p = random_bytes_get(); memcpy(tmp_dkek, p, 32); encrypt(session_sopin, tmp_dkek, tmp_dkek+IV_SIZE, 32); - file_t *tf = search_by_fid(0x108F, NULL, SPECIFY_EF); + file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF); flash_write_data_to_file(tf, tmp_dkek, sizeof(tmp_dkek)); } return SW_OK(); @@ -395,7 +395,7 @@ static int cmd_import_dkek() { return SW_COMMAND_NOT_ALLOWED(); if (has_session_sopin == false) return SW_CONDITIONS_NOT_SATISFIED(); - file_t *tf = search_by_fid(0x108F, NULL, SPECIFY_EF); + file_t *tf = search_by_fid(EF_DKEK, NULL, SPECIFY_EF); if (apdu.cmd_apdu_data_len > 0) { for (int i = 0; i < apdu.cmd_apdu_data_len; i++) tmp_dkek[IV_SIZE+i] ^= apdu.cmd_apdu_data[i]; @@ -438,16 +438,34 @@ struct ec_curve_mbed_id ec_curves_mbed[] = { { { NULL, 0 }, MBEDTLS_ECP_DP_NONE } }; -static int cmd_keypair_gen() { - uint8_t key_id = P1(apdu); - uint8_t auth_key_id = P2(apdu); +//Stores the private and public keys in flash +int store_key_rsa(mbedtls_rsa_context *rsa, int key_bits, uint8_t key_id) /*in bits*/ { + int key_size = key_bits/8; + uint8_t *pq = (uint8_t *)malloc(key_size); + mbedtls_mpi_write_binary(&rsa->P, pq, key_size/2); + mbedtls_mpi_write_binary(&rsa->Q, pq+key_size/2, key_size/2); + file_t *fpk = file_new((KEY_PREFIX << 8) | key_id); + int r = flash_write_data_to_file(fpk, pq, key_size); + if (r != HSM_OK) + return r; + add_file_to_chain(fpk, &ef_prkdf); +} + +sc_context_t *create_context() { sc_context_t *ctx; - //memset(ctx, 0 , sizeof(sc_context_t)); sc_context_param_t ctx_opts; memset(&ctx_opts, 0, sizeof(sc_context_param_t)); sc_context_create(&ctx, &ctx_opts); ctx->debug = 9; ctx->debug_file = stdout; + return ctx; +} + +static int cmd_keypair_gen() { + uint8_t key_id = P1(apdu); + uint8_t auth_key_id = P2(apdu); + sc_context_t *ctx = create_context(); + size_t tout = 0; sc_asn1_print_tags(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len); const uint8_t *p = sc_asn1_find_tag(ctx, (const uint8_t *)apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, 0x7f49, &tout); @@ -488,8 +506,10 @@ static int cmd_keypair_gen() { cvc.primeOrModuluslen = key_size/8; cvc.primeOrModulus = (uint8_t *)malloc(cvc.primeOrModuluslen); mbedtls_mpi_write_binary(&rsa.N, cvc.primeOrModulus, key_size/8); - cvc.signatureLen = 1; - cvc.signature = (uint8_t *)malloc(1); + cvc.signatureLen = key_size/8; + cvc.signature = (uint8_t *)malloc(key_size/8); + ret = mbedtls_rsa_rsassa_pkcs1_v15_sign(&rsa, NULL, NULL, MBEDTLS_MD_NONE, offsetof(sc_cvc_t, signature), (uint8_t *)&cvc, cvc.signature); + printf("ret %d\r\n"); u8 *cvcbin; size_t cvclen; struct sc_pkcs15_card p15card;