From 63e15b19bba2c817d2032b2a4da54890487befcb Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 17 Aug 2023 01:19:27 +0200 Subject: [PATCH] Added functions for writing COSE keys. Signed-off-by: Pol Henarejos --- src/fido/cbor.c | 77 +++++++++++++++++++++++++++++++++++++++++++ src/fido/ctap2_cbor.h | 7 ++++ 2 files changed, 84 insertions(+) diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 818ddfe..548a96f 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,79 @@ 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; +} diff --git a/src/fido/ctap2_cbor.h b/src/fido/ctap2_cbor.h index 65c038d..7d03fa8 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,8 @@ 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); + #endif //_CTAP2_CBOR_H_