diff --git a/src/hsm/dkek.c b/src/hsm/dkek.c index a70d3aa..f7bc63a 100644 --- a/src/hsm/dkek.c +++ b/src/hsm/dkek.c @@ -296,7 +296,6 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len) { return HSM_WRONG_SIGNATURE; int key_type = in[8]; - if (key_type != 5 && key_type != 6 && key_type != 12 && key_type != 15) return HSM_WRONG_DATA; @@ -331,7 +330,8 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len) { return HSM_WRONG_PADDING; uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding) memset(kb, 0, sizeof(kb)); - r = aes_encrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, in_len-16-ofs); + memcpy(kb, in+ofs, in_len-16-ofs); + r = aes_decrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, in_len-16-ofs); if (r != HSM_OK) return r; @@ -425,6 +425,7 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len) { mbedtls_ecdsa_free(ecdsa); return HSM_WRONG_DATA; } + ofs += len; //N len = get_uint16_t(kb, ofs); ofs += len+2; @@ -433,6 +434,7 @@ int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len) { len = get_uint16_t(kb, ofs); ofs += len+2; //d + len = get_uint16_t(kb, ofs); ofs += 2; r = mbedtls_ecp_read_key(ec_id, ecdsa, kb+ofs, len); if (r != 0) { mbedtls_ecdsa_free(ecdsa); diff --git a/src/hsm/dkek.h b/src/hsm/dkek.h index 12f9248..2219c6d 100644 --- a/src/hsm/dkek.h +++ b/src/hsm/dkek.h @@ -26,5 +26,10 @@ extern void import_dkek_share(const uint8_t *share); extern void dkek_kcv(uint8_t *kcv); extern int dkek_encrypt(uint8_t *data, size_t len); extern int dkek_decrypt(uint8_t *data, size_t len); +extern int dkek_encode_key(void *key_ctx, int key_type, uint8_t *out, size_t *out_len); +extern int dkek_type_key(const uint8_t *in); +extern int dkek_decode_key(void *key_ctx, const uint8_t *in, size_t in_len); + +#define MAX_DKEK_ENCODE_KEY_BUFFER (8+1+12+6+(8+2*4+2*4096/8+3+13)+16) #endif diff --git a/src/hsm/hash_utils.h b/src/hsm/hash_utils.h index 64b9454..c411812 100644 --- a/src/hsm/hash_utils.h +++ b/src/hsm/hash_utils.h @@ -23,6 +23,16 @@ #include "mbedtls/ecp.h" #include "mbedtls/md.h" +#define HSM_KEY_RSA 0x1 +#define HSM_KEY_EC 0x10 +#define HSM_KEY_AES 0x100 +#define HSM_KEY_AES_128 0x300 +#define HSM_KEY_AES_192 0x500 +#define HSM_KEY_AES_256 0x900 + +#define HSM_AES_MODE_CBC 1 +#define HSM_AES_MODE_CFB 2 + extern void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]); extern void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]); extern void hash256(const uint8_t *input, size_t len, uint8_t output[32]); diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index dca3a1c..af8df2b 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -589,31 +589,28 @@ static int cmd_import_dkek() { //Stores the private and public keys in flash int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) { int r, key_size; - uint8_t *asn1bin, *kdata; + uint8_t *asn1bin; size_t asn1len = 0; + uint8_t kdata[4096/8]; //worst case if (type == SC_PKCS15_TYPE_PRKEY_RSA) { mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx; key_size = mbedtls_mpi_size(&rsa->P)+mbedtls_mpi_size(&rsa->Q); - kdata = (uint8_t *)calloc(1, key_size); mbedtls_mpi_write_binary(&rsa->P, kdata, key_size/2); mbedtls_mpi_write_binary(&rsa->Q, kdata+key_size/2, key_size/2); } else { mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx; key_size = mbedtls_mpi_size(&ecdsa->d); - kdata = (uint8_t *)calloc(1, key_size+1); kdata[0] = ecdsa->grp.id & 0xff; mbedtls_mpi_write_binary(&ecdsa->d, kdata+1, key_size); key_size++; } r = dkek_encrypt(kdata, key_size); if (r != HSM_OK) { - free(kdata); return r; } file_t *fpk = file_new((KEY_PREFIX << 8) | key_id); r = flash_write_data_to_file(fpk, kdata, key_size); - free(kdata); if (r != HSM_OK) return r; //add_file_to_chain(fpk, &ef_kf); @@ -1295,7 +1292,7 @@ static int cmd_signature() { } static int cmd_key_wrap() { - int key_id = P1(apdu); + int key_id = P1(apdu), r = 0, key_type = 0x0; if (P2(apdu) != 0x92) return SW_WRONG_P1P2(); if (!isUserAuthenticated) @@ -1303,23 +1300,75 @@ static int cmd_key_wrap() { file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); if (!ef) return SW_FILE_NOT_FOUND(); - int key_len = file_read_uint16(ef->data); - memcpy(res_APDU, file_read(ef->data+2), key_len); - res_APDU_size = key_len; + file_t *prkd = search_dynamic_file((PRKD_PREFIX << 8) | key_id); + if (!prkd) + return SW_FILE_NOT_FOUND(); + const uint8_t *dprkd = file_read(prkd->data+2); + size_t wrap_len = MAX_DKEK_ENCODE_KEY_BUFFER; + if (*dprkd == P15_KEYTYPE_RSA) { + mbedtls_rsa_context ctx; + mbedtls_rsa_init(&ctx); + r = load_private_key_rsa(&ctx, ef); + if (r != HSM_OK) { + mbedtls_rsa_free(&ctx); + return SW_EXEC_ERROR(); + } + r = dkek_encode_key(&ctx, HSM_KEY_RSA, res_APDU, &wrap_len); + mbedtls_rsa_free(&ctx); + } + else if (*dprkd == P15_KEYTYPE_ECC) { + mbedtls_ecdsa_context ctx; + mbedtls_ecdsa_init(&ctx); + r = load_private_key_ecdsa(&ctx, ef); + if (r != HSM_OK) { + mbedtls_ecdsa_free(&ctx); + return SW_EXEC_ERROR(); + } + r = dkek_encode_key(&ctx, HSM_KEY_EC, res_APDU, &wrap_len); + mbedtls_ecdsa_free(&ctx); + } + if (r != HSM_OK) + return SW_EXEC_ERROR(); + res_APDU_size = wrap_len; return SW_OK(); } static int cmd_key_unwrap() { - int key_id = P1(apdu); + int key_id = P1(apdu), r = 0; if (P2(apdu) != 0x93) return SW_WRONG_P1P2(); if (!isUserAuthenticated) return SW_SECURITY_STATUS_NOT_SATISFIED(); - file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); - if (!ef) - ef = file_new((KEY_PREFIX << 8) | key_id); - flash_write_data_to_file(ef, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len); - low_flash_available(); + int key_type = dkek_type_key(apdu.cmd_apdu_data); + if (key_type == 0x0) + return SW_DATA_INVALID(); + if (key_type == HSM_KEY_RSA) { + mbedtls_rsa_context ctx; + mbedtls_rsa_init(&ctx); + r = dkek_decode_key(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len); + printf("r %d\r\n",r); + if (r != HSM_OK) { + mbedtls_rsa_free(&ctx); + return SW_EXEC_ERROR(); + } + sc_context_t *card_ctx = create_context(); + r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_RSA, key_id, card_ctx); + free(card_ctx); + mbedtls_rsa_free(&ctx); + } + else if (key_type == HSM_KEY_EC) { + mbedtls_ecdsa_context ctx; + mbedtls_ecdsa_init(&ctx); + r = dkek_decode_key(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len); + if (r != HSM_OK) { + mbedtls_ecdsa_free(&ctx); + return SW_EXEC_ERROR(); + } + sc_context_t *card_ctx = create_context(); + r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, key_id, card_ctx); + free(card_ctx); + mbedtls_ecdsa_free(&ctx); + } return SW_OK(); } diff --git a/src/hsm/sc_hsm.h b/src/hsm/sc_hsm.h index 7953eda..c2a4f9f 100644 --- a/src/hsm/sc_hsm.h +++ b/src/hsm/sc_hsm.h @@ -97,15 +97,9 @@ extern const uint8_t sc_hsm_aid[]; #define HSM_OPT_COMBINED_AUTH 0x10 #define HSM_OPT_RRC_RESET_ONLY 0x20 -#define HSM_KEY_RSA 0x1 -#define HSM_KEY_EC 0x10 -#define HSM_KEY_AES 0x100 -#define HSM_KEY_AES_128 0x300 -#define HSM_KEY_AES_192 0x500 -#define HSM_KEY_AES_256 0x900 - -#define HSM_AES_MODE_CBC 1 -#define HSM_AES_MODE_CFB 2 +#define P15_KEYTYPE_RSA 0x30 +#define P15_KEYTYPE_ECC 0xA0 +#define P15_KEYTYPE_AES 0xA8 extern int pin_reset_retries(const file_t *pin, bool); extern int pin_wrong_retry(const file_t *pin);