From a3c60f762d7237b43ed06e1022359f0087155d56 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 20 Sep 2022 14:39:59 +0200 Subject: [PATCH] Reorganizing core0/core1 split. Now CBOR and APDU (i.e., intensive processing) areas are executed on core1, while core0 is dedicated for hardware tasks (usb, button, led, etc.). --- src/fido/cbor.c | 38 +++++++++++++++++++++++++++++---- src/fido/cbor_client_pin.c | 20 ++++++++--------- src/fido/cbor_get_info.c | 4 ++-- src/fido/cbor_make_credential.c | 26 +++++++++++----------- src/fido/cbor_reset.c | 2 +- src/fido/fido.c | 3 ++- src/fido/fido.h | 2 ++ 7 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 8ac6380..696868d 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -22,14 +22,17 @@ #include "ctap_hid.h" #include "fido.h" #include "hsm.h" +#include "usb.h" +#include "apdu.h" const bool _btrue = true, _bfalse = false; const uint8_t aaguid[16] = {0x89, 0xFB, 0x94, 0xB7, 0x06, 0xC9, 0x36, 0x73, 0x9B, 0x7E, 0x30, 0x52, 0x6D, 0x96, 0x81, 0x45}; // First 16 bytes of SHA256("Pico FIDO2") -int cbor_process(const uint8_t *data, size_t len) { - if (scan_files() != CCID_OK) - return -CTAP1_ERR_OTHER; +const uint8_t *cbor_data = NULL; +size_t cbor_len = 0; + +int cbor_parse(const uint8_t *data, size_t len) { if (len == 0) return -CTAP1_ERR_INVALID_LEN; driver_prepare_response(); @@ -40,6 +43,33 @@ int cbor_process(const uint8_t *data, size_t len) { else if (data[0] == CTAP_RESET) return cbor_reset(); else if (data[0] == CTAP_CLIENT_PIN) - return cbor_client_pin(data+1, len-1); + return cbor_client_pin(data + 1, len - 1); return -CTAP2_ERR_INVALID_CBOR; } + +void cbor_thread() { + + while (1) { + uint32_t m; + queue_remove_blocking(&usb_to_card_q, &m); + + if (m == EV_EXIT) { + + break; + } + + apdu.sw = cbor_parse(cbor_data, cbor_len); + + finished_data_size = res_APDU_size+1; + uint32_t flag = EV_EXEC_FINISHED; + queue_add_blocking(&card_to_usb_q, &flag); + } +} + +int cbor_process(const uint8_t *data, size_t len) { + cbor_data = data; + cbor_len = len; + res_APDU = ctap_resp->init.data + 1; + res_APDU_size = 0; + return 1; +} diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index 4016462..9581f34 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -92,7 +92,7 @@ int regenerate() { mbedtls_ecdh_init(&hkey); hkey_init = true; mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1); - int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen_core0, NULL); + int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen, NULL); mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1); if (ret != 0) return ret; @@ -121,7 +121,7 @@ int kdf(uint8_t protocol, const mbedtls_mpi *z, uint8_t *sharedSecret) { int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret) { mbedtls_mpi z; mbedtls_mpi_init(&z); - int ret = mbedtls_ecdh_compute_shared(&hkey.ctx.mbed_ecdh.grp, &z, Q, &hkey.ctx.mbed_ecdh.d, random_gen_core0, NULL); + int ret = mbedtls_ecdh_compute_shared(&hkey.ctx.mbed_ecdh.grp, &z, Q, &hkey.ctx.mbed_ecdh.d, random_gen, NULL); ret = kdf(protocol, &z, sharedSecret); mbedtls_mpi_free(&z); return ret; @@ -129,7 +129,7 @@ int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret) { int resetPinUvAuthToken() { uint8_t t[32]; - random_gen_core0(NULL, t, sizeof(t)); + random_gen(NULL, t, sizeof(t)); flash_write_data_to_file(ef_authtoken, t, sizeof(t)); paut.permissions = 0; paut.data = file_get_data(ef_authtoken); @@ -145,7 +145,7 @@ int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_l return aes_encrypt(key, NULL, 32*8, HSM_AES_MODE_CBC, out, in_len); } else if (protocol == 2) { - random_gen_core0(NULL, out, IV_SIZE); + random_gen(NULL, out, IV_SIZE); memcpy(out + IV_SIZE, in, in_len); return aes_encrypt(key+32, out, 32*8, HSM_AES_MODE_CBC, out+IV_SIZE, in_len); } @@ -315,7 +315,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { 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_ES256)); + 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)); @@ -338,7 +338,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { if (pinUvAuthProtocol != 1 && pinUvAuthProtocol != 2) CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); if (file_has_data(ef_pin)) - CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); + CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); if (newPinEnc.len != 64) CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); if (mbedtls_mpi_read_binary(&hkey.ctx.mbed_ecdh.Qp.X, kax.data, kax.len) != 0) { @@ -438,7 +438,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { if (paddedNewPin[63] != 0) CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); uint8_t pin_len = 0; - while (paddedNewPin[pin_len] != 0 && pin_len < sizeof(pin_len)) + while (paddedNewPin[pin_len] != 0 && pin_len < sizeof(paddedNewPin)) pin_len++; if (pin_len < 4) CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION); @@ -520,9 +520,9 @@ err: CBOR_FREE_BYTE_STRING(rpId); if (error != CborNoError) { if (error == CborErrorImproperValue) - return -CTAP2_ERR_CBOR_UNEXPECTED_TYPE; - return -error; + return CTAP2_ERR_CBOR_UNEXPECTED_TYPE; + return error; } - driver_exec_finished(1+resp_size); + res_APDU_size = resp_size; return 0; } diff --git a/src/fido/cbor_get_info.c b/src/fido/cbor_get_info.c index 55895eb..5538fb9 100644 --- a/src/fido/cbor_get_info.c +++ b/src/fido/cbor_get_info.c @@ -19,6 +19,7 @@ #include "fido.h" #include "ctap.h" #include "files.h" +#include "apdu.h" int cbor_get_info() { CborEncoder encoder, mapEncoder, arrayEncoder; @@ -78,7 +79,6 @@ int cbor_get_info() { err: if (error != CborNoError) return -CTAP2_ERR_INVALID_CBOR; - size_t rs = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); - driver_exec_finished(rs + 1); + res_APDU_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); return 0; } diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 2abb967..80fd0a2 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -161,7 +161,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { uint8_t rp_id_hash[32]; mbedtls_sha256((uint8_t *)rp.id.data, rp.id.len, rp_id_hash, 0); - + printf("IEEEEEE 1\n"); int curve = -1, alg = 0; if (pubKeyCredParams_len == 0) CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); @@ -191,7 +191,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { if (pinUvAuthParam.present == true) { if (pinUvAuthParam.len == 0 || pinUvAuthParam.data == NULL) { - if (wait_button() == true) + if (check_user_presence() == false) CBOR_ERROR(CTAP2_ERR_OPERATION_DENIED); if (!file_has_data(ef_pin)) CBOR_ERROR(CTAP2_ERR_PIN_NOT_SET); @@ -230,7 +230,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); //Check pinUvAuthToken permissions. See 6.1.2.11 } - + printf("IEEEEEE 2\n"); for (int e = 0; e < excludeList_len; e++) { //12.1 if (excludeList[e].type.present == false || excludeList[e].id.present == false) CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); @@ -241,7 +241,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { } if (pinUvAuthParam.present && options.up == ptrue) { //14.1 - if (wait_button_pressed() == true) + if (check_user_presence() == false) CBOR_ERROR(CTAP2_ERR_OPERATION_DENIED); //rup = ptrue; } @@ -272,7 +272,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { uint8_t key[32]; memset(key, 0, sizeof(key)); uint8_t iv[12]; - random_gen_core0(NULL, iv, sizeof(12)); + random_gen(NULL, iv, sizeof(12)); mbedtls_chachapoly_context chatx; mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_setkey(&chatx, key); @@ -298,7 +298,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { mbedtls_curve = MBEDTLS_ECP_DP_CURVE448; else CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_ALGORITHM); - + printf("IEEEEEE 3\n"); mbedtls_ecdsa_context ekey; mbedtls_ecdsa_init(&ekey); uint8_t key_path[KEY_PATH_LEN]; @@ -362,7 +362,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); rs = cbor_encoder_get_buffer_size(&encoder, cbor_buf); - + printf("IEEEEEE 4\n"); size_t aut_data_len = 32 + 1 + 4 + (16 + 2 + cred_id_len + rs) + ext_len; aut_data = (uint8_t *)calloc(1, aut_data_len + clientDataHash.len); uint8_t *pa = aut_data; @@ -393,9 +393,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) { ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, file_get_data(ef_keydev), 32); self_attestation = false; } - ret = mbedtls_ecdsa_write_signature(&ekey, MBEDTLS_MD_SHA256, hash, 32, sig, sizeof(sig), &olen, random_gen_core0, NULL); + ret = mbedtls_ecdsa_write_signature(&ekey, MBEDTLS_MD_SHA256, hash, 32, sig, sizeof(sig), &olen, random_gen, NULL); mbedtls_ecdsa_free(&ekey); - + printf("IEEEEEE 5\n"); cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 3)); @@ -421,7 +421,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); - + printf("IEEEEEE 6\n"); err: CBOR_FREE_BYTE_STRING(clientDataHash); CBOR_FREE_BYTE_STRING(pinUvAuthParam); @@ -447,10 +447,10 @@ int cbor_make_credential(const uint8_t *data, size_t len) { free(cred_id); if (error != CborNoError) { if (error == CborErrorImproperValue) - return -CTAP2_ERR_CBOR_UNEXPECTED_TYPE; - return -error; + return CTAP2_ERR_CBOR_UNEXPECTED_TYPE; + return error; } - driver_exec_finished(1+resp_size); + res_APDU_size = resp_size; return 0; } diff --git a/src/fido/cbor_reset.c b/src/fido/cbor_reset.c index 6225239..9723c4c 100644 --- a/src/fido/cbor_reset.c +++ b/src/fido/cbor_reset.c @@ -19,12 +19,12 @@ #include "ctap2_cbor.h" #include "file.h" #include "fido.h" +#include "apdu.h" extern void scan_all(); int cbor_reset() { initialize_flash(true); scan_all(); - driver_exec_finished(1); return 0; } diff --git a/src/fido/fido.c b/src/fido/fido.c index 9d275f9..e762afc 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -221,6 +221,7 @@ int scan_files() { void scan_all() { scan_flash(); + scan_files(); } void init_fido() { @@ -240,7 +241,7 @@ uint32_t user_present_time_limit = 0; bool check_user_presence() { if (user_present_time_limit == 0 || user_present_time_limit+TRANSPORT_TIME_LIMIT < board_millis()) { - if (wait_button() == true) //timeout + if (wait_button_pressed() == true) //timeout return false; user_present_time_limit = board_millis(); } diff --git a/src/fido/fido.h b/src/fido/fido.h index 8f524c3..396e4a1 100644 --- a/src/fido/fido.h +++ b/src/fido/fido.h @@ -34,11 +34,13 @@ extern int scan_files(); extern int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int, mbedtls_ecdsa_context *key); extern bool wait_button_pressed(); extern CTAPHID_FRAME *ctap_req, *ctap_resp; +extern void init_fido(); #define FIDO2_ALG_ES256 -7 //ECDSA-SHA256 P256 #define FIDO2_ALG_EDDSA -8 //EdDSA #define FIDO2_ALG_ES384 -35 //ECDSA-SHA384 P384 #define FIDO2_ALG_ES512 -36 //ECDSA-SHA512 P521 +#define FIDO2_ALG_ECDH_ES_HKDF_256 -25 //ECDH-ES + HKDF-256 #define FIDO2_CURVE_P256 1 #define FIDO2_CURVE_P384 2