Adding RSA and EC wrap/unwrap, compatible with SC HSM wrap format.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2022-03-30 00:59:37 +02:00
parent 1c272842a7
commit d018e3b9b9
5 changed files with 86 additions and 26 deletions

View File

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

View File

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

View File

@@ -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]);

View File

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

View File

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