From e8c8ce4d1502dec2aca4e0e9d769ae82bde2bc76 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 16 Aug 2023 14:47:34 +0200 Subject: [PATCH] Adding support for EdDSA with Ed25519 curve. Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 4 +- pico-hsm-sdk | 2 +- src/fido/cbor_get_assertion.c | 55 ++++++++++++++++++-------- src/fido/cbor_make_credential.c | 69 ++++++++++++++++++++++----------- src/fido/fido.c | 12 ++++-- src/fido/fido.h | 7 ++-- 6 files changed, 101 insertions(+), 48 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index fc7e24a..aa1db41 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -1,7 +1,7 @@ #!/bin/bash -VERSION_MAJOR="3" -VERSION_MINOR="0" +VERSION_MAJOR="5" +VERSION_MINOR="4" rm -rf release/* cd build_release diff --git a/pico-hsm-sdk b/pico-hsm-sdk index cb453d3..e5a98ea 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit cb453d3ee70016787bdb904fa8e1c4805576f418 +Subproject commit e5a98ea9bf9fe62fcea6a54b55bd8580f8b73867 diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index 7967c28..b260be1 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -429,12 +429,12 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { flags = flagsx; selcred = &credsx[credentialCounter]; } - mbedtls_ecdsa_context ekey; - mbedtls_ecdsa_init(&ekey); + mbedtls_ecp_keypair ekey; + mbedtls_ecp_keypair_init(&ekey); int ret = fido_load_key(selcred->curve, selcred->id.data, &ekey); if (ret != 0) { if (derive_key(rp_id_hash, false, selcred->id.data, MBEDTLS_ECP_DP_SECP256R1, &ekey) != 0) { - mbedtls_ecdsa_free(&ekey); + mbedtls_ecp_keypair_free(&ekey); CBOR_ERROR(CTAP1_ERR_OTHER); } } @@ -582,21 +582,42 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) { md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } - ret = mbedtls_md(md, - aut_data, - aut_data_len + clientDataHash.len, - hash); + else if (ekey.grp.id == MBEDTLS_ECP_DP_ED25519) { + md = NULL; + } size_t olen = 0; - ret = mbedtls_ecdsa_write_signature(&ekey, - mbedtls_md_get_type(md), - hash, - mbedtls_md_get_size(md), - sig, - sizeof(sig), - &olen, - random_gen, - NULL); - mbedtls_ecdsa_free(&ekey); + if (md != NULL) { + ret = mbedtls_md(md, + aut_data, + aut_data_len + clientDataHash.len, + hash); + ret = mbedtls_ecdsa_write_signature(&ekey, + mbedtls_md_get_type(md), + hash, + mbedtls_md_get_size(md), + sig, + sizeof(sig), + &olen, + random_gen, + NULL); + } + else { + ret = mbedtls_eddsa_write_signature(&ekey, + aut_data, + aut_data_len + clientDataHash.len, + sig, + sizeof(sig), + &olen, + MBEDTLS_EDDSA_PURE, + NULL, + 0, + random_gen, + NULL); + } + if (ret != 0) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } + mbedtls_ecp_keypair_free(&ekey); uint8_t lfields = 3; if (selcred->opts.present == true && selcred->opts.rk == ptrue) { diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index c176408..69f5d9e 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -180,6 +180,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) { else if (pubKeyCredParams[i].alg == FIDO2_ALG_ES256K) { curve = FIDO2_CURVE_P256K1; } + else if (pubKeyCredParams[i].alg == FIDO2_ALG_EDDSA) { + curve = FIDO2_CURVE_ED25519; + } else if (pubKeyCredParams[i].alg == 0) { // no present curve = -1; } @@ -370,16 +373,16 @@ int cbor_make_credential(const uint8_t *data, size_t len) { flags |= FIDO2_AUT_FLAG_ED; } uint8_t pkey[66]; - mbedtls_ecdsa_context ekey; - mbedtls_ecdsa_init(&ekey); + mbedtls_ecp_keypair ekey; + mbedtls_ecp_keypair_init(&ekey); int ret = fido_load_key(curve, cred_id, &ekey); if (ret != 0) { - mbedtls_ecdsa_free(&ekey); + mbedtls_ecp_keypair_free(&ekey); CBOR_ERROR(CTAP1_ERR_OTHER); } const mbedtls_ecp_curve_info *cinfo = mbedtls_ecp_curve_info_from_grp_id(ekey.grp.id); if (cinfo == NULL) { - mbedtls_ecdsa_free(&ekey); + mbedtls_ecp_keypair_free(&ekey); CBOR_ERROR(CTAP1_ERR_OTHER); } size_t olen = 0; @@ -419,7 +422,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { memcpy(pa, cbor_buf, rs); pa += rs; memcpy(pa, ext, ext_len); pa += ext_len; if (pa - aut_data != aut_data_len) { - mbedtls_ecdsa_free(&ekey); + mbedtls_ecp_keypair_free(&ekey); CBOR_ERROR(CTAP1_ERR_OTHER); } @@ -432,29 +435,51 @@ int cbor_make_credential(const uint8_t *data, size_t len) { else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) { md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } - ret = mbedtls_md(md, - aut_data, - aut_data_len + clientDataHash.len, - hash); - + else if (ekey.grp.id == MBEDTLS_ECP_DP_ED25519) { + md = NULL; + } + if (md != NULL) { + ret = mbedtls_md(md, + aut_data, + aut_data_len + clientDataHash.len, + hash); + } bool self_attestation = true; if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) { - mbedtls_ecdsa_free(&ekey); - mbedtls_ecdsa_init(&ekey); + mbedtls_ecp_keypair_free(&ekey); + mbedtls_ecp_keypair_init(&ekey); ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, file_get_data(ef_keydev), 32); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); self_attestation = false; } - ret = mbedtls_ecdsa_write_signature(&ekey, - mbedtls_md_get_type(md), - hash, - mbedtls_md_get_size(md), - sig, - sizeof(sig), - &olen, - random_gen, - NULL); - mbedtls_ecdsa_free(&ekey); + if (md != NULL) { + ret = mbedtls_ecdsa_write_signature(&ekey, + mbedtls_md_get_type(md), + hash, + mbedtls_md_get_size(md), + sig, + sizeof(sig), + &olen, + random_gen, + NULL); + } + else { + ret = mbedtls_eddsa_write_signature(&ekey, + aut_data, + aut_data_len + clientDataHash.len, + sig, + sizeof(sig), + &olen, + MBEDTLS_EDDSA_PURE, + NULL, + 0, + random_gen, + NULL); + } + if (ret != 0) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } + mbedtls_ecp_keypair_free(&ekey); uint8_t largeBlobKey[32]; if (extensions.largeBlobKey == ptrue && options.rk == ptrue) { diff --git a/src/fido/fido.c b/src/fido/fido.c index e86d7c6..22f1fb7 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -92,10 +92,16 @@ mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve) { else if (curve == FIDO2_CURVE_X448) { return MBEDTLS_ECP_DP_CURVE448; } + else if (curve == FIDO2_CURVE_ED25519) { + return MBEDTLS_ECP_DP_ED25519; + } + else if (curve == FIDO2_CURVE_ED448) { + return MBEDTLS_ECP_DP_ED448; + } return MBEDTLS_ECP_DP_NONE; } -int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecdsa_context *key) { +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); if (mbedtls_curve == MBEDTLS_ECP_DP_NONE) { return CTAP2_ERR_UNSUPPORTED_ALGORITHM; @@ -152,7 +158,7 @@ int load_keydev(uint8_t *key) { return CCID_OK; } -int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *key) { +int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecp_keypair *key) { for (int i = 0; i < KEY_PATH_ENTRIES; i++) { uint32_t k = *(uint32_t *) &keyHandle[i * sizeof(uint32_t)]; if (!(k & 0x80000000)) { @@ -194,7 +200,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int curve, - mbedtls_ecdsa_context *key) { + mbedtls_ecp_keypair *key) { uint8_t outk[64] = { 0 }; int r = 0; memset(outk, 0, sizeof(outk)); diff --git a/src/fido/fido.h b/src/fido/fido.h index 06d547b..ac951ab 100644 --- a/src/fido/fido.h +++ b/src/fido/fido.h @@ -23,6 +23,7 @@ #endif #include "common.h" #include "mbedtls/ecdsa.h" +#include "mbedtls/eddsa.h" #ifndef ENABLE_EMULATION #include "ctap_hid.h" #else @@ -40,12 +41,12 @@ extern int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int, - mbedtls_ecdsa_context *key); -extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *); + mbedtls_ecp_keypair *key); +extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecp_keypair *); extern bool wait_button_pressed(); extern void init_fido(); extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve); -extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecdsa_context *key); +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, const uint8_t *key,