Adding key domain to key generation, wrap, unwrap, export and import.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -149,22 +149,28 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_
|
|||||||
|
|
||||||
uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes 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));
|
memset(kb, 0, sizeof(kb));
|
||||||
int kb_len = 0;
|
int kb_len = 0, r = 0;
|
||||||
uint8_t *algo = NULL;
|
uint8_t *algo = NULL;
|
||||||
uint8_t algo_len = 0;
|
uint8_t algo_len = 0;
|
||||||
uint8_t *allowed = NULL;
|
uint8_t *allowed = NULL;
|
||||||
uint8_t allowed_len = 0;
|
uint8_t allowed_len = 0;
|
||||||
uint8_t kenc[32];
|
uint8_t kenc[32];
|
||||||
memset(kenc, 0, sizeof(kenc));
|
memset(kenc, 0, sizeof(kenc));
|
||||||
dkek_kenc(id, kenc);
|
r = dkek_kenc(id, kenc);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
uint8_t kcv[8];
|
uint8_t kcv[8];
|
||||||
memset(kcv, 0, sizeof(kcv));
|
memset(kcv, 0, sizeof(kcv));
|
||||||
dkek_kcv(id, kcv);
|
r = dkek_kcv(id, kcv);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
uint8_t kmac[32];
|
uint8_t kmac[32];
|
||||||
memset(kmac, 0, sizeof(kmac));
|
memset(kmac, 0, sizeof(kmac));
|
||||||
dkek_kmac(id, kmac);
|
r = dkek_kmac(id, kmac);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (key_type & HSM_KEY_AES) {
|
if (key_type & HSM_KEY_AES) {
|
||||||
if (key_type & HSM_KEY_AES_128)
|
if (key_type & HSM_KEY_AES_128)
|
||||||
@@ -272,7 +278,7 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_
|
|||||||
if (kb_len < kb_len_pad) {
|
if (kb_len < kb_len_pad) {
|
||||||
kb[kb_len] = 0x80;
|
kb[kb_len] = 0x80;
|
||||||
}
|
}
|
||||||
int r = aes_encrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, kb_len_pad);
|
r = aes_encrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, kb_len_pad);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -299,22 +305,29 @@ int dkek_type_key(const uint8_t *in) {
|
|||||||
|
|
||||||
int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out) {
|
int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out) {
|
||||||
uint8_t kcv[8];
|
uint8_t kcv[8];
|
||||||
|
int r = 0;
|
||||||
memset(kcv, 0, sizeof(kcv));
|
memset(kcv, 0, sizeof(kcv));
|
||||||
dkek_kcv(id, kcv);
|
r = dkek_kcv(id, kcv);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
uint8_t kmac[32];
|
uint8_t kmac[32];
|
||||||
memset(kmac, 0, sizeof(kmac));
|
memset(kmac, 0, sizeof(kmac));
|
||||||
dkek_kmac(id, kmac);
|
r = dkek_kmac(id, kmac);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
uint8_t kenc[32];
|
uint8_t kenc[32];
|
||||||
memset(kenc, 0, sizeof(kenc));
|
memset(kenc, 0, sizeof(kenc));
|
||||||
dkek_kenc(id, kenc);
|
r = dkek_kenc(id, kenc);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (memcmp(kcv, in, 8) != 0)
|
if (memcmp(kcv, in, 8) != 0)
|
||||||
return CCID_WRONG_DKEK;
|
return CCID_WRONG_DKEK;
|
||||||
|
|
||||||
uint8_t signature[16];
|
uint8_t signature[16];
|
||||||
int r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, in, in_len-16, signature);
|
r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, in, in_len-16, signature);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return CCID_WRONG_SIGNATURE;
|
return CCID_WRONG_SIGNATURE;
|
||||||
if (memcmp(signature, in+in_len-16, 16) != 0)
|
if (memcmp(signature, in+in_len-16, 16) != 0)
|
||||||
|
|||||||
118
src/hsm/sc_hsm.c
118
src/hsm/sc_hsm.c
@@ -846,8 +846,26 @@ static int cmd_key_domain() {
|
|||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t get_key_domain(file_t *fkey) {
|
||||||
|
if (!fkey)
|
||||||
|
return 0xff;
|
||||||
|
uint8_t *meta_data = NULL;
|
||||||
|
uint8_t meta_size = meta_find(fkey->fid, &meta_data);
|
||||||
|
DEBUG_PAYLOAD(meta_data,meta_size);
|
||||||
|
if (meta_size > 0 && meta_data != NULL) {
|
||||||
|
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL;
|
||||||
|
size_t tag_len = 0;
|
||||||
|
while (walk_tlv(meta_data, meta_size, &p, &tag, &tag_len, &tag_data)) {
|
||||||
|
if (tag == 0x92) { //ofset tag
|
||||||
|
return *tag_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//Stores the private and public keys in flash
|
//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 store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx, uint8_t kdom) {
|
||||||
int r, key_size = 0;
|
int r, key_size = 0;
|
||||||
uint8_t *asn1bin = NULL;
|
uint8_t *asn1bin = NULL;
|
||||||
size_t asn1len = 0;
|
size_t asn1len = 0;
|
||||||
@@ -876,13 +894,13 @@ int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return CCID_WRONG_DATA;
|
return CCID_WRONG_DATA;
|
||||||
r = dkek_encrypt(0, kdata, key_size);
|
|
||||||
if (r != CCID_OK) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
|
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
|
||||||
if (!fpk)
|
if (!fpk)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
|
r = dkek_encrypt(kdom, kdata, key_size);
|
||||||
|
if (r != CCID_OK) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
r = flash_write_data_to_file(fpk, kdata, key_size);
|
r = flash_write_data_to_file(fpk, kdata, key_size);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return r;
|
return r;
|
||||||
@@ -958,7 +976,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id, sc_context_t *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_keypair_gen() {
|
static int cmd_keypair_gen() {
|
||||||
uint8_t key_id = P1(apdu);
|
uint8_t key_id = P1(apdu), kdom = 0;
|
||||||
if (!isUserAuthenticated)
|
if (!isUserAuthenticated)
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
sc_context_t *ctx = create_context();
|
sc_context_t *ctx = create_context();
|
||||||
@@ -976,6 +994,10 @@ static int cmd_keypair_gen() {
|
|||||||
size_t oid_len = 0;
|
size_t oid_len = 0;
|
||||||
const uint8_t *oid = sc_asn1_find_tag(ctx, p, tout, 0x6, &oid_len);
|
const uint8_t *oid = sc_asn1_find_tag(ctx, p, tout, 0x6, &oid_len);
|
||||||
if (oid) {
|
if (oid) {
|
||||||
|
size_t kdom_size = 0;
|
||||||
|
const uint8_t *kdomd = sc_asn1_find_tag(ctx, (const uint8_t *)apdu.data, apdu.nc, 0x92, &kdom_size);
|
||||||
|
if (kdomd && kdom_size > 0)
|
||||||
|
kdom = *kdomd;
|
||||||
if (memcmp(oid, "\x4\x0\x7F\x0\x7\x2\x2\x2\x1\x2",MIN(oid_len,10)) == 0) { //RSA
|
if (memcmp(oid, "\x4\x0\x7F\x0\x7\x2\x2\x2\x1\x2",MIN(oid_len,10)) == 0) { //RSA
|
||||||
size_t ex_len, ks_len;
|
size_t ex_len, ks_len;
|
||||||
const uint8_t *ex = sc_asn1_find_tag(ctx, p, tout, 0x82, &ex_len);
|
const uint8_t *ex = sc_asn1_find_tag(ctx, p, tout, 0x82, &ex_len);
|
||||||
@@ -1035,7 +1057,7 @@ static int cmd_keypair_gen() {
|
|||||||
free(p15card.card);
|
free(p15card.card);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
ret = store_keys(&rsa, SC_PKCS15_TYPE_PRKEY_RSA, key_id, ctx);
|
ret = store_keys(&rsa, SC_PKCS15_TYPE_PRKEY_RSA, key_id, ctx, kdom);
|
||||||
if (ret != CCID_OK) {
|
if (ret != CCID_OK) {
|
||||||
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
||||||
mbedtls_rsa_free(&rsa);
|
mbedtls_rsa_free(&rsa);
|
||||||
@@ -1161,7 +1183,7 @@ static int cmd_keypair_gen() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = store_keys(&ecdsa, SC_PKCS15_TYPE_PRKEY_EC, key_id, ctx);
|
ret = store_keys(&ecdsa, SC_PKCS15_TYPE_PRKEY_EC, key_id, ctx, kdom);
|
||||||
if (ret != CCID_OK) {
|
if (ret != CCID_OK) {
|
||||||
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
|
||||||
mbedtls_ecdsa_free(&ecdsa);
|
mbedtls_ecdsa_free(&ecdsa);
|
||||||
@@ -1337,18 +1359,24 @@ static int cmd_change_pin() {
|
|||||||
}
|
}
|
||||||
uint8_t pin_len = file_read_uint8(file_get_data(file_pin1));
|
uint8_t pin_len = file_read_uint8(file_get_data(file_pin1));
|
||||||
uint16_t r = check_pin(file_pin1, apdu.data, pin_len);
|
uint16_t r = check_pin(file_pin1, apdu.data, pin_len);
|
||||||
uint8_t dkek[DKEK_SIZE];
|
|
||||||
if (r != 0x9000)
|
if (r != 0x9000)
|
||||||
return r;
|
return r;
|
||||||
if (load_dkek(0, dkek) != CCID_OK) //loads the DKEK with old pin
|
uint8_t old_session_pin[32];
|
||||||
return SW_EXEC_ERROR();
|
memcpy(old_session_pin, session_pin, sizeof(old_session_pin));
|
||||||
//encrypt DKEK with new pin
|
for (uint8_t kdom = 0; kdom < MAX_KEY_DOMAINS; kdom++) {
|
||||||
hash_multi(apdu.data+pin_len, apdu.nc-pin_len, session_pin);
|
uint8_t dkek[DKEK_SIZE];
|
||||||
has_session_pin = true;
|
memcpy(session_pin, old_session_pin, sizeof(session_pin));
|
||||||
r = store_dkek_key(0, dkek);
|
if (load_dkek(kdom, dkek) != CCID_OK) //loads the DKEK with old pin
|
||||||
release_dkek(dkek);
|
return SW_EXEC_ERROR();
|
||||||
if (r != CCID_OK)
|
//encrypt DKEK with new pin
|
||||||
return SW_EXEC_ERROR();
|
hash_multi(apdu.data+pin_len, apdu.nc-pin_len, session_pin);
|
||||||
|
has_session_pin = true;
|
||||||
|
r = store_dkek_key(kdom, dkek);
|
||||||
|
release_dkek(dkek);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
|
}
|
||||||
|
memset(old_session_pin, 0, sizeof(old_session_pin));
|
||||||
uint8_t dhash[33];
|
uint8_t dhash[33];
|
||||||
dhash[0] = apdu.nc-pin_len;
|
dhash[0] = apdu.nc-pin_len;
|
||||||
double_hash_pin(apdu.data+pin_len, apdu.nc-pin_len, dhash+1);
|
double_hash_pin(apdu.data+pin_len, apdu.nc-pin_len, dhash+1);
|
||||||
@@ -1384,7 +1412,7 @@ static int cmd_key_gen() {
|
|||||||
else if (key_size == 32)
|
else if (key_size == 32)
|
||||||
aes_type = HSM_KEY_AES_256;
|
aes_type = HSM_KEY_AES_256;
|
||||||
sc_context_t *card_ctx = create_context();
|
sc_context_t *card_ctx = create_context();
|
||||||
r = store_keys(aes_key, aes_type, key_id, card_ctx);
|
r = store_keys(aes_key, aes_type, key_id, card_ctx, 0);
|
||||||
free(card_ctx);
|
free(card_ctx);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
@@ -1397,9 +1425,9 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
|||||||
return CCID_VERIFICATION_FAILED;
|
return CCID_VERIFICATION_FAILED;
|
||||||
|
|
||||||
int key_size = file_get_size(fkey);
|
int key_size = file_get_size(fkey);
|
||||||
uint8_t kdata[4096/8];
|
uint8_t kdata[4096/8], kdom = get_key_domain(fkey);
|
||||||
memcpy(kdata, file_get_data(fkey), key_size);
|
memcpy(kdata, file_get_data(fkey), key_size);
|
||||||
if (dkek_decrypt(0, kdata, key_size) != 0) {
|
if (dkek_decrypt(kdom, kdata, key_size) != 0) {
|
||||||
return CCID_EXEC_ERROR;
|
return CCID_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size/2) != 0) {
|
if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size/2) != 0) {
|
||||||
@@ -1433,10 +1461,10 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
|||||||
if (wait_button() == true) //timeout
|
if (wait_button() == true) //timeout
|
||||||
return CCID_VERIFICATION_FAILED;
|
return CCID_VERIFICATION_FAILED;
|
||||||
|
|
||||||
int key_size = file_get_size(fkey);
|
int key_size = file_get_size(fkey), kdom = get_key_domain(fkey);
|
||||||
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
||||||
memcpy(kdata, file_get_data(fkey), key_size);
|
memcpy(kdata, file_get_data(fkey), key_size);
|
||||||
if (dkek_decrypt(0, kdata, key_size) != 0) {
|
if (dkek_decrypt(kdom, kdata, key_size) != 0) {
|
||||||
return CCID_EXEC_ERROR;
|
return CCID_EXEC_ERROR;
|
||||||
}
|
}
|
||||||
mbedtls_ecp_group_id gid = kdata[0];
|
mbedtls_ecp_group_id gid = kdata[0];
|
||||||
@@ -1604,6 +1632,7 @@ static int cmd_key_wrap() {
|
|||||||
if (!isUserAuthenticated)
|
if (!isUserAuthenticated)
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id);
|
file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id);
|
||||||
|
uint8_t kdom = get_key_domain(ef);
|
||||||
if (!ef)
|
if (!ef)
|
||||||
return SW_FILE_NOT_FOUND();
|
return SW_FILE_NOT_FOUND();
|
||||||
file_t *prkd = search_dynamic_file((PRKD_PREFIX << 8) | key_id);
|
file_t *prkd = search_dynamic_file((PRKD_PREFIX << 8) | key_id);
|
||||||
@@ -1621,7 +1650,7 @@ static int cmd_key_wrap() {
|
|||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
r = dkek_encode_key(0, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len);
|
r = dkek_encode_key(kdom, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len);
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
}
|
}
|
||||||
else if (*dprkd == P15_KEYTYPE_ECC) {
|
else if (*dprkd == P15_KEYTYPE_ECC) {
|
||||||
@@ -1634,7 +1663,7 @@ static int cmd_key_wrap() {
|
|||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
r = dkek_encode_key(0, &ctx, HSM_KEY_EC, res_APDU, &wrap_len);
|
r = dkek_encode_key(kdom, &ctx, HSM_KEY_EC, res_APDU, &wrap_len);
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
}
|
}
|
||||||
else if (*dprkd == P15_KEYTYPE_AES) {
|
else if (*dprkd == P15_KEYTYPE_AES) {
|
||||||
@@ -1644,7 +1673,7 @@ static int cmd_key_wrap() {
|
|||||||
|
|
||||||
int key_size = file_get_size(ef), aes_type = HSM_KEY_AES;
|
int key_size = file_get_size(ef), aes_type = HSM_KEY_AES;
|
||||||
memcpy(kdata, file_get_data(ef), key_size);
|
memcpy(kdata, file_get_data(ef), key_size);
|
||||||
if (dkek_decrypt(0, kdata, key_size) != 0) {
|
if (dkek_decrypt(kdom, kdata, key_size) != 0) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
if (key_size == 32)
|
if (key_size == 32)
|
||||||
@@ -1653,7 +1682,7 @@ static int cmd_key_wrap() {
|
|||||||
aes_type = HSM_KEY_AES_192;
|
aes_type = HSM_KEY_AES_192;
|
||||||
else if (key_size == 16)
|
else if (key_size == 16)
|
||||||
aes_type = HSM_KEY_AES_128;
|
aes_type = HSM_KEY_AES_128;
|
||||||
r = dkek_encode_key(0, kdata, aes_type, res_APDU, &wrap_len);
|
r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len);
|
||||||
}
|
}
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
@@ -1668,18 +1697,21 @@ static int cmd_key_unwrap() {
|
|||||||
if (!isUserAuthenticated)
|
if (!isUserAuthenticated)
|
||||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||||
int key_type = dkek_type_key(apdu.data);
|
int key_type = dkek_type_key(apdu.data);
|
||||||
|
uint8_t kdom = -1;
|
||||||
if (key_type == 0x0)
|
if (key_type == 0x0)
|
||||||
return SW_DATA_INVALID();
|
return SW_DATA_INVALID();
|
||||||
if (key_type == HSM_KEY_RSA) {
|
if (key_type == HSM_KEY_RSA) {
|
||||||
mbedtls_rsa_context ctx;
|
mbedtls_rsa_context ctx;
|
||||||
mbedtls_rsa_init(&ctx);
|
mbedtls_rsa_init(&ctx);
|
||||||
r = dkek_decode_key(0, &ctx, apdu.data, apdu.nc, NULL);
|
do {
|
||||||
|
r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL);
|
||||||
|
} while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
sc_context_t *card_ctx = create_context();
|
sc_context_t *card_ctx = create_context();
|
||||||
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_RSA, key_id, card_ctx);
|
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_RSA, key_id, card_ctx, kdom);
|
||||||
free(card_ctx);
|
free(card_ctx);
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
@@ -1689,13 +1721,15 @@ static int cmd_key_unwrap() {
|
|||||||
else if (key_type == HSM_KEY_EC) {
|
else if (key_type == HSM_KEY_EC) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecdsa_context ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecdsa_init(&ctx);
|
||||||
r = dkek_decode_key(0, &ctx, apdu.data, apdu.nc, NULL);
|
do {
|
||||||
|
r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL);
|
||||||
|
} while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
sc_context_t *card_ctx = create_context();
|
sc_context_t *card_ctx = create_context();
|
||||||
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, key_id, card_ctx);
|
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, key_id, card_ctx, kdom);
|
||||||
free(card_ctx);
|
free(card_ctx);
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
@@ -1705,7 +1739,9 @@ static int cmd_key_unwrap() {
|
|||||||
else if (key_type == HSM_KEY_AES) {
|
else if (key_type == HSM_KEY_AES) {
|
||||||
uint8_t aes_key[32];
|
uint8_t aes_key[32];
|
||||||
int key_size = 0, aes_type = 0;
|
int key_size = 0, aes_type = 0;
|
||||||
r = dkek_decode_key(0, aes_key, apdu.data, apdu.nc, &key_size);
|
do {
|
||||||
|
r = dkek_decode_key(++kdom, aes_key, apdu.data, apdu.nc, &key_size);
|
||||||
|
} while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
@@ -1718,12 +1754,18 @@ static int cmd_key_unwrap() {
|
|||||||
else
|
else
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
sc_context_t *card_ctx = create_context();
|
sc_context_t *card_ctx = create_context();
|
||||||
r = store_keys(aes_key, aes_type, key_id, card_ctx);
|
r = store_keys(aes_key, aes_type, key_id, card_ctx, kdom);
|
||||||
free(card_ctx);
|
free(card_ctx);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (kdom > 0) {
|
||||||
|
uint8_t meta[3] = {0x92,1,kdom};
|
||||||
|
r = meta_add((KEY_PREFIX << 8) | key_id, meta, sizeof(meta));
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1760,9 +1802,9 @@ static int cmd_decrypt_asym() {
|
|||||||
if (wait_button() == true) //timeout
|
if (wait_button() == true) //timeout
|
||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
int key_size = file_get_size(ef);
|
int key_size = file_get_size(ef);
|
||||||
uint8_t *kdata = (uint8_t *)calloc(1,key_size);
|
uint8_t *kdata = (uint8_t *)calloc(1,key_size), kdom = get_key_domain(ef);
|
||||||
memcpy(kdata, file_get_data(ef), key_size);
|
memcpy(kdata, file_get_data(ef), key_size);
|
||||||
if (dkek_decrypt(0, kdata, key_size) != 0) {
|
if (dkek_decrypt(kdom, kdata, key_size) != 0) {
|
||||||
free(kdata);
|
free(kdata);
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
@@ -1817,8 +1859,9 @@ static int cmd_cipher_sym() {
|
|||||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||||
int key_size = file_get_size(ef);
|
int key_size = file_get_size(ef);
|
||||||
uint8_t kdata[32]; //maximum AES key size
|
uint8_t kdata[32]; //maximum AES key size
|
||||||
|
uint8_t kdom = get_key_domain(ef);
|
||||||
memcpy(kdata, file_get_data(ef), key_size);
|
memcpy(kdata, file_get_data(ef), key_size);
|
||||||
if (dkek_decrypt(0, kdata, key_size) != 0) {
|
if (dkek_decrypt(kdom, kdata, key_size) != 0) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
if (algo == ALGO_AES_CBC_ENCRYPT || algo == ALGO_AES_CBC_DECRYPT) {
|
if (algo == ALGO_AES_CBC_ENCRYPT || algo == ALGO_AES_CBC_DECRYPT) {
|
||||||
@@ -1944,7 +1987,8 @@ static int cmd_derive_asym() {
|
|||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
sc_context_t *card_ctx = create_context();
|
sc_context_t *card_ctx = create_context();
|
||||||
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, dest_id, card_ctx);
|
uint8_t kdom = get_key_domain(fkey);
|
||||||
|
r = store_keys(&ctx, SC_PKCS15_TYPE_PRKEY_EC, dest_id, card_ctx, kdom);
|
||||||
free(card_ctx);
|
free(card_ctx);
|
||||||
if (r != CCID_OK) {
|
if (r != CCID_OK) {
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user