Adding support for EdDSA with Ed25519 curve.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2023-08-16 14:47:34 +02:00
parent 69d618cc6b
commit e8c8ce4d15
6 changed files with 101 additions and 48 deletions

View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
VERSION_MAJOR="3" VERSION_MAJOR="5"
VERSION_MINOR="0" VERSION_MINOR="4"
rm -rf release/* rm -rf release/*
cd build_release cd build_release

View File

@@ -429,12 +429,12 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) {
flags = flagsx; flags = flagsx;
selcred = &credsx[credentialCounter]; selcred = &credsx[credentialCounter];
} }
mbedtls_ecdsa_context ekey; mbedtls_ecp_keypair ekey;
mbedtls_ecdsa_init(&ekey); mbedtls_ecp_keypair_init(&ekey);
int ret = fido_load_key(selcred->curve, selcred->id.data, &ekey); int ret = fido_load_key(selcred->curve, selcred->id.data, &ekey);
if (ret != 0) { if (ret != 0) {
if (derive_key(rp_id_hash, false, selcred->id.data, MBEDTLS_ECP_DP_SECP256R1, &ekey) != 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); 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) { else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) {
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
ret = mbedtls_md(md, else if (ekey.grp.id == MBEDTLS_ECP_DP_ED25519) {
aut_data, md = NULL;
aut_data_len + clientDataHash.len, }
hash);
size_t olen = 0; size_t olen = 0;
ret = mbedtls_ecdsa_write_signature(&ekey, if (md != NULL) {
mbedtls_md_get_type(md), ret = mbedtls_md(md,
hash, aut_data,
mbedtls_md_get_size(md), aut_data_len + clientDataHash.len,
sig, hash);
sizeof(sig), ret = mbedtls_ecdsa_write_signature(&ekey,
&olen, mbedtls_md_get_type(md),
random_gen, hash,
NULL); mbedtls_md_get_size(md),
mbedtls_ecdsa_free(&ekey); 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; uint8_t lfields = 3;
if (selcred->opts.present == true && selcred->opts.rk == ptrue) { if (selcred->opts.present == true && selcred->opts.rk == ptrue) {

View File

@@ -180,6 +180,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
else if (pubKeyCredParams[i].alg == FIDO2_ALG_ES256K) { else if (pubKeyCredParams[i].alg == FIDO2_ALG_ES256K) {
curve = FIDO2_CURVE_P256K1; curve = FIDO2_CURVE_P256K1;
} }
else if (pubKeyCredParams[i].alg == FIDO2_ALG_EDDSA) {
curve = FIDO2_CURVE_ED25519;
}
else if (pubKeyCredParams[i].alg == 0) { // no present else if (pubKeyCredParams[i].alg == 0) { // no present
curve = -1; curve = -1;
} }
@@ -370,16 +373,16 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
flags |= FIDO2_AUT_FLAG_ED; flags |= FIDO2_AUT_FLAG_ED;
} }
uint8_t pkey[66]; uint8_t pkey[66];
mbedtls_ecdsa_context ekey; mbedtls_ecp_keypair ekey;
mbedtls_ecdsa_init(&ekey); mbedtls_ecp_keypair_init(&ekey);
int ret = fido_load_key(curve, cred_id, &ekey); int ret = fido_load_key(curve, cred_id, &ekey);
if (ret != 0) { if (ret != 0) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecp_keypair_free(&ekey);
CBOR_ERROR(CTAP1_ERR_OTHER); CBOR_ERROR(CTAP1_ERR_OTHER);
} }
const mbedtls_ecp_curve_info *cinfo = mbedtls_ecp_curve_info_from_grp_id(ekey.grp.id); const mbedtls_ecp_curve_info *cinfo = mbedtls_ecp_curve_info_from_grp_id(ekey.grp.id);
if (cinfo == NULL) { if (cinfo == NULL) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecp_keypair_free(&ekey);
CBOR_ERROR(CTAP1_ERR_OTHER); CBOR_ERROR(CTAP1_ERR_OTHER);
} }
size_t olen = 0; 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, cbor_buf, rs); pa += rs;
memcpy(pa, ext, ext_len); pa += ext_len; memcpy(pa, ext, ext_len); pa += ext_len;
if (pa - aut_data != aut_data_len) { if (pa - aut_data != aut_data_len) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecp_keypair_free(&ekey);
CBOR_ERROR(CTAP1_ERR_OTHER); 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) { else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) {
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
ret = mbedtls_md(md, else if (ekey.grp.id == MBEDTLS_ECP_DP_ED25519) {
aut_data, md = NULL;
aut_data_len + clientDataHash.len, }
hash); if (md != NULL) {
ret = mbedtls_md(md,
aut_data,
aut_data_len + clientDataHash.len,
hash);
}
bool self_attestation = true; bool self_attestation = true;
if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) { if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) {
mbedtls_ecdsa_free(&ekey); mbedtls_ecp_keypair_free(&ekey);
mbedtls_ecdsa_init(&ekey); mbedtls_ecp_keypair_init(&ekey);
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, file_get_data(ef_keydev), 32); 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); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
self_attestation = false; self_attestation = false;
} }
ret = mbedtls_ecdsa_write_signature(&ekey, if (md != NULL) {
mbedtls_md_get_type(md), ret = mbedtls_ecdsa_write_signature(&ekey,
hash, mbedtls_md_get_type(md),
mbedtls_md_get_size(md), hash,
sig, mbedtls_md_get_size(md),
sizeof(sig), sig,
&olen, sizeof(sig),
random_gen, &olen,
NULL); random_gen,
mbedtls_ecdsa_free(&ekey); 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]; uint8_t largeBlobKey[32];
if (extensions.largeBlobKey == ptrue && options.rk == ptrue) { if (extensions.largeBlobKey == ptrue && options.rk == ptrue) {

View File

@@ -92,10 +92,16 @@ mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve) {
else if (curve == FIDO2_CURVE_X448) { else if (curve == FIDO2_CURVE_X448) {
return MBEDTLS_ECP_DP_CURVE448; 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; 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); mbedtls_ecp_group_id mbedtls_curve = fido_curve_to_mbedtls(curve);
if (mbedtls_curve == MBEDTLS_ECP_DP_NONE) { if (mbedtls_curve == MBEDTLS_ECP_DP_NONE) {
return CTAP2_ERR_UNSUPPORTED_ALGORITHM; return CTAP2_ERR_UNSUPPORTED_ALGORITHM;
@@ -152,7 +158,7 @@ int load_keydev(uint8_t *key) {
return CCID_OK; 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++) { for (int i = 0; i < KEY_PATH_ENTRIES; i++) {
uint32_t k = *(uint32_t *) &keyHandle[i * sizeof(uint32_t)]; uint32_t k = *(uint32_t *) &keyHandle[i * sizeof(uint32_t)];
if (!(k & 0x80000000)) { if (!(k & 0x80000000)) {
@@ -194,7 +200,7 @@ int derive_key(const uint8_t *app_id,
bool new_key, bool new_key,
uint8_t *key_handle, uint8_t *key_handle,
int curve, int curve,
mbedtls_ecdsa_context *key) { mbedtls_ecp_keypair *key) {
uint8_t outk[64] = { 0 }; uint8_t outk[64] = { 0 };
int r = 0; int r = 0;
memset(outk, 0, sizeof(outk)); memset(outk, 0, sizeof(outk));

View File

@@ -23,6 +23,7 @@
#endif #endif
#include "common.h" #include "common.h"
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
#include "mbedtls/eddsa.h"
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
#include "ctap_hid.h" #include "ctap_hid.h"
#else #else
@@ -40,12 +41,12 @@ extern int derive_key(const uint8_t *app_id,
bool new_key, bool new_key,
uint8_t *key_handle, uint8_t *key_handle,
int, int,
mbedtls_ecdsa_context *key); mbedtls_ecp_keypair *key);
extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *); extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecp_keypair *);
extern bool wait_button_pressed(); extern bool wait_button_pressed();
extern void init_fido(); extern void init_fido();
extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve); 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 load_keydev(uint8_t *key);
extern int encrypt(uint8_t protocol, extern int encrypt(uint8_t protocol,
const uint8_t *key, const uint8_t *key,