Skip to content

Commit

Permalink
Added support for key import.
Browse files Browse the repository at this point in the history
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
  • Loading branch information
polhenarejos committed Mar 26, 2024
1 parent 9fe59a5 commit 85b6c90
Showing 1 changed file with 93 additions and 0 deletions.
93 changes: 93 additions & 0 deletions src/openpgp/piv.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#define PIV_ALGO_AES256 0x0c
#define PIV_ALGO_RSA1024 0x06
#define PIV_ALGO_RSA2048 0x07
#define PIV_ALGO_RSA3072 0x05
#define PIV_ALGO_RSA4096 0x16
#define PIV_ALGO_ECCP256 0x11
#define PIV_ALGO_ECCP384 0x14
#define PIV_ALGO_X25519 0xE1
Expand Down Expand Up @@ -1111,6 +1113,95 @@ static int cmd_attestation() {
return SW_OK();
}

static int cmd_import_asym() {
uint8_t algo = P1(apdu), key_ref = P2(apdu);
if (key_ref != EF_PIV_KEY_AUTHENTICATION && key_ref != EF_PIV_KEY_SIGNATURE && key_ref != EF_PIV_KEY_KEYMGM && key_ref != EF_PIV_KEY_CARDAUTH && !(key_ref >= EF_PIV_KEY_RETIRED1 && key_ref <= EF_PIV_KEY_RETIRED20)) {
return SW_INCORRECT_P1P2();
}
asn1_ctx_t ctxi, aaa = {0}, aab = {0};
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
asn1_find_tag(&ctxi, 0xAA, &aaa);
asn1_find_tag(&ctxi, 0xAB, &aab);
if (algo == PIV_ALGO_RSA1024 || algo == PIV_ALGO_RSA2048 || algo == PIV_ALGO_RSA3072 || algo == PIV_ALGO_RSA4096) {
asn1_ctx_t a1 = { 0 }, a2 = { 0 };
asn1_find_tag(&ctxi, 0x01, &a1);
asn1_find_tag(&ctxi, 0x02, &a2);
if (asn1_len(&a1) <= 0 || asn1_len(&a2) <= 0) {
return SW_WRONG_DATA();
}
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa);
int r = mbedtls_mpi_read_binary(&rsa.P, a1.data, a1.len);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return SW_WRONG_DATA();
}
r = mbedtls_mpi_read_binary(&rsa.Q, a2.data, a2.len);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return SW_WRONG_DATA();
}
int exponent = 65537;
mbedtls_mpi_lset(&rsa.E, exponent);
r = mbedtls_rsa_import(&rsa, NULL, &rsa.P, &rsa.Q, NULL, &rsa.E);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
r = mbedtls_rsa_complete(&rsa);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
r = mbedtls_rsa_check_privkey(&rsa);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
r = store_keys(&rsa, ALGO_RSA, key_ref, false);
mbedtls_rsa_free(&rsa);
if (r != 0) {
return SW_EXEC_ERROR();
}
}
else if (algo == PIV_ALGO_ECCP256 || algo == PIV_ALGO_ECCP384) {
asn1_ctx_t a6 = {0};
asn1_find_tag(&ctxi, 0x06, &a6);
if (asn1_len(&a6) <= 0) {
return SW_WRONG_DATA();
}
mbedtls_ecp_group_id gid = algo == PIV_ALGO_ECCP256 ? MBEDTLS_ECP_DP_SECP256R1 : MBEDTLS_ECP_DP_SECP384R1;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
int r = mbedtls_ecp_read_key(gid, &ecdsa, a6.data, a6.len);
if (r != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
r = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL);
if (r != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
r = mbedtls_ecp_check_pub_priv(&ecdsa, &ecdsa, random_gen, NULL);
if (r != 0) {
mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR();
}
r = store_keys(&ecdsa, ALGO_ECDSA, key_ref, false);
mbedtls_ecdsa_free(&ecdsa);
if (r != 0) {
return SW_EXEC_ERROR();
}
}
else {
return SW_WRONG_DATA();
}
uint8_t meta[] = { algo, asn1_len(&aaa) ? aaa.data[0] : PINPOLICY_ALWAYS, asn1_len(&aab) ? aab.data[0] : TOUCHPOLICY_ALWAYS, ORIGIN_IMPORTED };
meta_add(key_ref, meta, sizeof(meta));
return SW_OK();
}

#define INS_VERIFY 0x20
#define INS_VERSION 0xFD
#define INS_SELECT 0xA4
Expand All @@ -1128,6 +1219,7 @@ static int cmd_attestation() {
#define INS_SET_RETRIES 0xFA
#define INS_RESET 0xFB
#define INS_ATTESTATION 0xF9
#define INS_IMPORT_ASYM 0xFE

static const cmd_t cmds[] = {
{ INS_VERSION, cmd_version },
Expand All @@ -1146,6 +1238,7 @@ static const cmd_t cmds[] = {
{ INS_SET_RETRIES, cmd_set_retries },
{ INS_RESET, cmd_reset },
{ INS_ATTESTATION, cmd_attestation },
{ INS_IMPORT_ASYM, cmd_import_asym },
{ 0x00, 0x0 }
};

Expand Down

0 comments on commit 85b6c90

Please sign in to comment.