diff --git a/pico-hsm-sdk b/pico-hsm-sdk index e5a98ea..c3a7058 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit e5a98ea9bf9fe62fcea6a54b55bd8580f8b73867 +Subproject commit c3a70585c65a82b6b577d174e57b7fae434ee9eb diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 818ddfe..d8ece1d 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -24,6 +24,7 @@ #include "usb.h" #include "apdu.h" #include "management.h" +#include "ctap2_cbor.h" const bool _btrue = true, _bfalse = false; @@ -127,3 +128,108 @@ int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len) { res_APDU_size = 0; return 1; } + +CborError COSE_key_params(int crv, int alg, mbedtls_ecp_group *grp, mbedtls_ecp_point *Q, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) { + CborError error = CborNoError; + int kty = 1; + if (crv == FIDO2_CURVE_P256 || crv == FIDO2_CURVE_P384 || crv == FIDO2_CURVE_P521 || crv == FIDO2_CURVE_P256K1) { + kty = 2; + } + + CBOR_CHECK(cbor_encoder_create_map(mapEncoderParent, mapEncoder, 5)); + + CBOR_CHECK(cbor_encode_uint(mapEncoder, 1)); + CBOR_CHECK(cbor_encode_uint(mapEncoder, kty)); + + CBOR_CHECK(cbor_encode_uint(mapEncoder, 3)); + CBOR_CHECK(cbor_encode_negative_int(mapEncoder, -alg)); + + CBOR_CHECK(cbor_encode_negative_int(mapEncoder, 1)); + CBOR_CHECK(cbor_encode_uint(mapEncoder, crv)); + + + CBOR_CHECK(cbor_encode_negative_int(mapEncoder, 2)); + uint8_t pkey[67]; + if (kty == 2) { + size_t plen = mbedtls_mpi_size(&grp->P); + CBOR_CHECK(mbedtls_mpi_write_binary(&Q->X, pkey, plen)); + CBOR_CHECK(cbor_encode_byte_string(mapEncoder, pkey, plen)); + + CBOR_CHECK(cbor_encode_negative_int(mapEncoder, 3)); + + CBOR_CHECK(mbedtls_mpi_write_binary(&Q->Y, pkey, plen)); + CBOR_CHECK(cbor_encode_byte_string(mapEncoder, pkey, plen)); + } + else { + size_t olen = 0; + CBOR_CHECK(mbedtls_ecp_point_write_binary(grp, Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, pkey, sizeof(pkey))); + CBOR_CHECK(cbor_encode_byte_string(mapEncoder, pkey, olen)); + } + + CBOR_CHECK(cbor_encoder_close_container(mapEncoderParent, mapEncoder)); + err: + return error; +} +CborError COSE_key(mbedtls_ecp_keypair *key, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) { + int crv = mbedtls_curve_to_fido(key->grp.id), alg = 0; + if (key->grp.id == MBEDTLS_ECP_DP_SECP256R1) { + alg = FIDO2_ALG_ES256; + } + else if (key->grp.id == MBEDTLS_ECP_DP_SECP384R1) { + alg = FIDO2_ALG_ES384; + } + else if (key->grp.id == MBEDTLS_ECP_DP_SECP521R1) { + alg = FIDO2_ALG_ES512; + } + else if (key->grp.id == MBEDTLS_ECP_DP_SECP256K1) { + alg = FIDO2_ALG_ES256K; + } + else if (key->grp.id == MBEDTLS_ECP_DP_CURVE25519) { + alg = FIDO2_ALG_ECDH_ES_HKDF_256; + } + return COSE_key_params(crv, alg, &key->grp, &key->Q, mapEncoderParent, mapEncoder); +} +CborError COSE_key_shared(mbedtls_ecdh_context *key, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) { + int crv = mbedtls_curve_to_fido(key->ctx.mbed_ecdh.grp.id), alg = FIDO2_ALG_ECDH_ES_HKDF_256; + return COSE_key_params(crv, alg, &key->ctx.mbed_ecdh.grp, &key->ctx.mbed_ecdh.Q, mapEncoderParent, mapEncoder); +} +CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder) { + CborError error = CborNoError; + CBOR_CHECK(cbor_encoder_create_map(mapEncoderParent, mapEncoder, 2)); + CBOR_CHECK(cbor_encode_text_stringz(mapEncoder, "alg")); + CBOR_CHECK(cbor_encode_negative_int(mapEncoder, -alg)); + CBOR_CHECK(cbor_encode_text_stringz(mapEncoder, "type")); + CBOR_CHECK(cbor_encode_text_stringz(mapEncoder, "public-key")); + CBOR_CHECK(cbor_encoder_close_container(mapEncoderParent, mapEncoder)); + err: + return error; +} +CborError COSE_read_key(CborValue *f, int64_t *kty, int64_t *alg, int64_t *crv, CborByteString *kax, CborByteString *kay) { + int64_t kkey = 0; + CborError error = CborNoError; + CBOR_PARSE_MAP_START(*f, 0) + { + CBOR_FIELD_GET_INT(kkey, 0); + if (kkey == 1) { + CBOR_FIELD_GET_INT(*kty, 0); + } + else if (kkey == 3) { + CBOR_FIELD_GET_INT(*alg, 0); + } + else if (kkey == -1) { + CBOR_FIELD_GET_INT(*crv, 0); + } + else if (kkey == -2) { + CBOR_FIELD_GET_BYTES(*kax, 0); + } + else if (kkey == -3) { + CBOR_FIELD_GET_BYTES(*kay, 0); + } + else { + CBOR_ADVANCE(0); + } + } + CBOR_PARSE_MAP_END(*f, 0); + err: + return error; +} \ No newline at end of file diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index d61133e..f47c09e 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -312,30 +312,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { CBOR_FIELD_GET_UINT(subcommand, 1); } else if (val_u == 0x03) { - int64_t key = 0; - CBOR_PARSE_MAP_START(_f1, 2) - { - CBOR_FIELD_GET_INT(key, 2); - if (key == 1) { - CBOR_FIELD_GET_INT(kty, 2); - } - else if (key == 3) { - CBOR_FIELD_GET_INT(alg, 2); - } - else if (key == -1) { - CBOR_FIELD_GET_INT(crv, 2); - } - else if (key == -2) { - CBOR_FIELD_GET_BYTES(kax, 2); - } - else if (key == -3) { - CBOR_FIELD_GET_BYTES(kay, 2); - } - else { - CBOR_ADVANCE(2); - } - } - CBOR_PARSE_MAP_END(_f1, 2); + CBOR_CHECK(COSE_read_key(&_f1, &kty, &alg, &crv, &kax, &kay)); } else if (val_u == 0x04) { CBOR_FIELD_GET_BYTES(pinUvAuthParam, 1); @@ -374,21 +351,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); - CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, 5)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 3)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_ECDH_ES_HKDF_256)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, FIDO2_CURVE_P256)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 2)); - uint8_t pkey[32]; - mbedtls_mpi_write_binary(&hkey.ctx.mbed_ecdh.Q.X, pkey, 32); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, 32)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 3)); - mbedtls_mpi_write_binary(&hkey.ctx.mbed_ecdh.Q.Y, pkey, 32); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, 32)); - CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_key_shared(&hkey, &mapEncoder, &mapEncoder2)); } else if (pinUvAuthProtocol == 0) { CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); diff --git a/src/fido/cbor_cred_mgmt.c b/src/fido/cbor_cred_mgmt.c index d9705fa..13ee3f6 100644 --- a/src/fido/cbor_cred_mgmt.c +++ b/src/fido/cbor_cred_mgmt.c @@ -309,21 +309,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x08)); - CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, 5)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 3)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -cred.alg)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, cred.curve)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 2)); - uint8_t pkey[66]; - mbedtls_mpi_write_binary(&key.Q.X, pkey, mbedtls_mpi_size(&key.Q.X)); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, mbedtls_mpi_size(&key.Q.X))); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 3)); - mbedtls_mpi_write_binary(&key.Q.Y, pkey, mbedtls_mpi_size(&key.Q.Y)); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, mbedtls_mpi_size(&key.Q.Y))); - CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_key(&key, &mapEncoder, &mapEncoder2)); if (subcommand == 0x04) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x09)); diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index b260be1..c3f51ee 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -150,30 +150,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { { CBOR_FIELD_GET_UINT(ukey, 3); if (ukey == 0x01) { - int64_t kkey = 0; - CBOR_PARSE_MAP_START(_f3, 4) - { - CBOR_FIELD_GET_INT(kkey, 4); - if (kkey == 1) { - CBOR_FIELD_GET_INT(kty, 4); - } - else if (kkey == 3) { - CBOR_FIELD_GET_INT(alg, 4); - } - else if (kkey == -1) { - CBOR_FIELD_GET_INT(crv, 4); - } - else if (kkey == -2) { - CBOR_FIELD_GET_BYTES(kax, 4); - } - else if (kkey == -3) { - CBOR_FIELD_GET_BYTES(kay, 4); - } - else { - CBOR_ADVANCE(4); - } - } - CBOR_PARSE_MAP_END(_f3, 4); + CBOR_CHECK(COSE_read_key(&_f3, &kty, &alg, &crv, &kax, &kay)); } else if (ukey == 0x02) { CBOR_FIELD_GET_BYTES(salt_enc, 3); diff --git a/src/fido/cbor_get_info.c b/src/fido/cbor_get_info.c index 7c10f8d..c5f728e 100644 --- a/src/fido/cbor_get_info.c +++ b/src/fido/cbor_get_info.c @@ -90,37 +90,14 @@ int cbor_get_info() { CBOR_CHECK(cbor_encode_uint(&mapEncoder, MAX_CRED_ID_LENGTH)); // MAX_CRED_ID_MAX_LENGTH CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0A)); + CBOR_CHECK(cbor_encoder_create_array(&mapEncoder, &arrayEncoder, 5)); - CBOR_CHECK(cbor_encoder_create_map(&arrayEncoder, &mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg")); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_ES256)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "type")); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "public-key")); - CBOR_CHECK(cbor_encoder_close_container(&arrayEncoder, &mapEncoder2)); - CBOR_CHECK(cbor_encoder_create_map(&arrayEncoder, &mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg")); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_EDDSA)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "type")); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "public-key")); - CBOR_CHECK(cbor_encoder_close_container(&arrayEncoder, &mapEncoder2)); - CBOR_CHECK(cbor_encoder_create_map(&arrayEncoder, &mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg")); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_ES384)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "type")); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "public-key")); - CBOR_CHECK(cbor_encoder_close_container(&arrayEncoder, &mapEncoder2)); - CBOR_CHECK(cbor_encoder_create_map(&arrayEncoder, &mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg")); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_ES512)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "type")); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "public-key")); - CBOR_CHECK(cbor_encoder_close_container(&arrayEncoder, &mapEncoder2)); - CBOR_CHECK(cbor_encoder_create_map(&arrayEncoder, &mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "alg")); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_ES256K)); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "type")); - CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "public-key")); - CBOR_CHECK(cbor_encoder_close_container(&arrayEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_public_key(FIDO2_ALG_ES256, &arrayEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_public_key(FIDO2_ALG_EDDSA, &arrayEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_public_key(FIDO2_ALG_ES384, &arrayEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_public_key(FIDO2_ALG_ES512, &arrayEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_public_key(FIDO2_ALG_ES256K, &arrayEncoder, &mapEncoder2)); + CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &arrayEncoder)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x0B)); diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 69f5d9e..b60efdf 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -372,7 +372,6 @@ int cbor_make_credential(const uint8_t *data, size_t len) { ext_len = cbor_encoder_get_buffer_size(&encoder, ext); flags |= FIDO2_AUT_FLAG_ED; } - uint8_t pkey[66]; mbedtls_ecp_keypair ekey; mbedtls_ecp_keypair_init(&ekey); int ret = fido_load_key(curve, cred_id, &ekey); @@ -389,21 +388,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { uint32_t ctr = get_sign_counter(); uint8_t cbor_buf[1024]; cbor_encoder_init(&encoder, cbor_buf, sizeof(cbor_buf), 0); - CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 5)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder, 2)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder, 3)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder, -alg)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder, curve)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder, 2)); - mbedtls_mpi_write_binary(&ekey.Q.X, pkey, mbedtls_mpi_size(&ekey.Q.X)); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, pkey, mbedtls_mpi_size(&ekey.Q.X))); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder, 3)); - mbedtls_mpi_write_binary(&ekey.Q.Y, pkey, mbedtls_mpi_size(&ekey.Q.Y)); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, pkey, mbedtls_mpi_size(&ekey.Q.Y))); - - CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); + CBOR_CHECK(COSE_key(&ekey, &encoder, &mapEncoder)); size_t rs = cbor_encoder_get_buffer_size(&encoder, cbor_buf); size_t aut_data_len = 32 + 1 + 4 + (16 + 2 + cred_id_len + rs) + ext_len; diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index 5ec5b28..f76de3c 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -84,30 +84,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { CBOR_FIELD_GET_BYTES(vendorParam, 2); } else if (subpara == 0x02) { - int64_t key = 0; - CBOR_PARSE_MAP_START(_f2, 3) - { - CBOR_FIELD_GET_INT(key, 3); - if (key == 1) { - CBOR_FIELD_GET_INT(kty, 3); - } - else if (key == 3) { - CBOR_FIELD_GET_INT(alg, 3); - } - else if (key == -1) { - CBOR_FIELD_GET_INT(crv, 3); - } - else if (key == -2) { - CBOR_FIELD_GET_BYTES(kax, 3); - } - else if (key == -3) { - CBOR_FIELD_GET_BYTES(kay, 3); - } - else { - CBOR_ADVANCE(3); - } - } - CBOR_PARSE_MAP_END(_f2, 3); + CBOR_CHECK(COSE_read_key(&_f2, &kty, &alg, &crv, &kax, &kay)); } else { CBOR_ADVANCE(2); @@ -223,22 +200,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); - - CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, 5)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 2)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, 3)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, -FIDO2_ALG_ECDH_ES_HKDF_256)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 1)); - CBOR_CHECK(cbor_encode_uint(&mapEncoder2, FIDO2_CURVE_P256)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 2)); - uint8_t pkey[32]; - mbedtls_mpi_write_binary(&hkey.ctx.mbed_ecdh.Q.X, pkey, 32); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, 32)); - CBOR_CHECK(cbor_encode_negative_int(&mapEncoder2, 3)); - mbedtls_mpi_write_binary(&hkey.ctx.mbed_ecdh.Q.Y, pkey, 32); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, 32)); - CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); + CBOR_CHECK(COSE_key_shared(&hkey, &mapEncoder, &mapEncoder2)); mbedtls_ecdh_free(&hkey); } } diff --git a/src/fido/ctap2_cbor.h b/src/fido/ctap2_cbor.h index 65c038d..1706ed8 100644 --- a/src/fido/ctap2_cbor.h +++ b/src/fido/ctap2_cbor.h @@ -19,6 +19,9 @@ #define _CTAP2_CBOR_H_ #include "cbor.h" +#include "common.h" +#include "mbedtls/ecp.h" +#include "mbedtls/ecdh.h" extern uint8_t *driver_prepare_response(); extern void driver_exec_finished(size_t size_next); @@ -237,4 +240,9 @@ typedef struct CborCharString { CBOR_CHECK(cbor_encode_boolean(&(p), v == ptrue ? true : false)); \ } } while (0) +extern CborError COSE_key(mbedtls_ecp_keypair *, CborEncoder *, CborEncoder *); +extern CborError COSE_key_shared(mbedtls_ecdh_context *key, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder); +extern CborError COSE_public_key(int alg, CborEncoder *mapEncoderParent, CborEncoder *mapEncoder); +extern CborError COSE_read_key(CborValue *f, int64_t *kty, int64_t *alg, int64_t *crv, CborByteString *kax, CborByteString *kay); + #endif //_CTAP2_CBOR_H_ diff --git a/src/fido/fido.c b/src/fido/fido.c index 22f1fb7..4ebe8a3 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -32,6 +32,7 @@ #endif #include #include "management.h" +#include "ctap_hid.h" int fido_process_apdu(); int fido_unload(); @@ -100,6 +101,27 @@ mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve) { } return MBEDTLS_ECP_DP_NONE; } +int mbedtls_curve_to_fido(mbedtls_ecp_group_id id) { + if (id == MBEDTLS_ECP_DP_SECP256R1) { + return FIDO2_CURVE_P256; + } + else if (id == MBEDTLS_ECP_DP_SECP384R1) { + return FIDO2_CURVE_P384; + } + else if (id == MBEDTLS_ECP_DP_SECP521R1) { + return FIDO2_CURVE_P521; + } + else if (id == MBEDTLS_ECP_DP_SECP256K1) { + return FIDO2_CURVE_P256K1; + } + else if (id == MBEDTLS_ECP_DP_CURVE25519) { + return MBEDTLS_ECP_DP_CURVE25519; + } + else if (id == MBEDTLS_ECP_DP_CURVE448) { + return FIDO2_CURVE_X448; + } + return 0; +} int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecp_keypair *key) { mbedtls_ecp_group_id mbedtls_curve = fido_curve_to_mbedtls(curve); @@ -409,16 +431,32 @@ void set_opts(uint8_t opts) { extern int cmd_register(); extern int cmd_authenticate(); extern int cmd_version(); +extern int cbor_parse(int, uint8_t *, size_t); + +#define CTAP_CBOR 0x10 + +int cmd_cbor() { + uint8_t *old_buf = res_APDU; + int ret = cbor_parse(0x90, apdu.data, apdu.nc); + if (ret != 0) { + return SW_EXEC_ERROR(); + } + res_APDU = old_buf; + res_APDU_size += 1; + memcpy(res_APDU, ctap_resp->init.data, res_APDU_size); + return SW_OK(); +} static const cmd_t cmds[] = { { CTAP_REGISTER, cmd_register }, { CTAP_AUTHENTICATE, cmd_authenticate }, { CTAP_VERSION, cmd_version }, + { CTAP_CBOR, cmd_cbor }, { 0x00, 0x0 } }; int fido_process_apdu() { - if (CLA(apdu) != 0x00) { + if (CLA(apdu) != 0x00 && CLA(apdu) != 0x80) { return SW_CLA_NOT_SUPPORTED(); } if (cap_supported(CAP_U2F)) { diff --git a/src/fido/fido.h b/src/fido/fido.h index ac951ab..65e164d 100644 --- a/src/fido/fido.h +++ b/src/fido/fido.h @@ -46,6 +46,7 @@ extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ec extern bool wait_button_pressed(); extern void init_fido(); extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve); +extern int mbedtls_curve_to_fido(mbedtls_ecp_group_id id); extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecp_keypair *key); extern int load_keydev(uint8_t *key); extern int encrypt(uint8_t protocol, diff --git a/tests/docker/fido2/__init__.py b/tests/docker/fido2/__init__.py index e172b9d..83359b2 100644 --- a/tests/docker/fido2/__init__.py +++ b/tests/docker/fido2/__init__.py @@ -49,13 +49,14 @@ elif sys.platform.startswith("darwin"): from . import macos as backend elif sys.platform.startswith("freebsd"): from . import freebsd as backend +elif sys.platform.startswith("netbsd"): + from . import netbsd as backend elif sys.platform.startswith("openbsd"): from . import openbsd as backend else: raise Exception("Unsupported platform") from . import emulation as backend - list_descriptors = backend.list_descriptors get_descriptor = backend.get_descriptor open_connection = backend.open_connection