From 6c85d57412749de0aa3b78dab9f821370822775f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 18 Sep 2023 10:13:06 +0200 Subject: [PATCH 01/39] Added support for LED in Pico W. Fixed #17. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index a36a89c..10a9511 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit a36a89cc9555b9a9959218f011488c542aefc0b8 +Subproject commit 10a951135888c976369d101e36b771faab3dd469 From b1c4ff877e2402fcedc6e034b8a0d6382c02b19b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 18 Sep 2023 10:39:21 +0200 Subject: [PATCH 02/39] Fix pico_w build. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index 10a9511..a35ba06 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit 10a951135888c976369d101e36b771faab3dd469 +Subproject commit a35ba063c4c8d04d81e794577029df8603cb5dcc From c1fd5736f90dd9bbc999a192ce1d89bee8584ee5 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:51:36 +0200 Subject: [PATCH 03/39] Update to latest HSM SDK changes. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index a35ba06..4f09254 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit a35ba063c4c8d04d81e794577029df8603cb5dcc +Subproject commit 4f0925420b896c247718471da39eb9ae1f86b145 From 46ce9390bf4816b3d4132973273611ac1e77cba4 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:52:07 +0200 Subject: [PATCH 04/39] Added backfall compatibility. Signed-off-by: Pol Henarejos --- src/fido/cbor.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/fido/cbor.c b/src/fido/cbor.c index f9e9269..9483d44 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -25,6 +25,7 @@ #include "apdu.h" #include "management.h" #include "ctap2_cbor.h" +#include "version.h" const bool _btrue = true, _bfalse = false; @@ -40,6 +41,8 @@ int cbor_config(const uint8_t *data, size_t len); int cbor_vendor(const uint8_t *data, size_t len); int cbor_large_blobs(const uint8_t *data, size_t len); +extern int cmd_read_config(); + 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") @@ -91,6 +94,12 @@ int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) { else if (cmd == CTAP_VENDOR_CBOR) { return cbor_vendor(data, len); } + else if (cmd == 0xC2) { + if (cmd_read_config() == 0x9000) { + res_APDU_size -= 1; + return 0; + } + } } return CTAP1_ERR_INVALID_CMD; } From c24be5a6319c98cc95ed410807d5c7679782cecf Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:53:06 +0200 Subject: [PATCH 05/39] Adapted to new selection AID method. Signed-off-by: Pol Henarejos --- src/fido/cmd_register.c | 14 +++------ src/fido/fido.c | 22 +++++++------ src/fido/management.c | 22 ++++++------- src/fido/oath.c | 70 +++++++++++++++++++---------------------- src/fido/otp.c | 34 +++++++++----------- 5 files changed, 75 insertions(+), 87 deletions(-) diff --git a/src/fido/cmd_register.c b/src/fido/cmd_register.c index 837cb90..877f5b0 100644 --- a/src/fido/cmd_register.c +++ b/src/fido/cmd_register.c @@ -32,18 +32,14 @@ const uint8_t u2f_aid[] = { int u2f_unload(); int u2f_process_apdu(); -app_t *u2f_select(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, u2f_aid + 1, MIN(aid_len, u2f_aid[0])) && cap_supported(CAP_U2F)) { - a->aid = u2f_aid; - a->process_apdu = u2f_process_apdu; - a->unload = u2f_unload; - return a; - } - return NULL; +int u2f_select(app_t *a) { + a->process_apdu = u2f_process_apdu; + a->unload = u2f_unload; + return CCID_OK; } void __attribute__((constructor)) u2f_ctor() { - register_app(u2f_select); + register_app(u2f_select, u2f_aid); } int u2f_unload() { diff --git a/src/fido/fido.c b/src/fido/fido.c index dc70e86..32db925 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -33,6 +33,7 @@ #include #include "management.h" #include "ctap_hid.h" +#include "version.h" int fido_process_apdu(); int fido_unload(); @@ -53,27 +54,30 @@ const uint8_t atr_fido[] = { 0x75, 0x62, 0x69, 0x4b, 0x65, 0x79, 0x40 }; -app_t *fido_select(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, fido_aid + 1, MIN(aid_len, fido_aid[0])) && cap_supported(CAP_FIDO2)) { - a->aid = fido_aid; - a->process_apdu = fido_process_apdu; - a->unload = fido_unload; - return a; - } - return NULL; +int fido_select(app_t *a) { + a->process_apdu = fido_process_apdu; + a->unload = fido_unload; + return CCID_OK; } void __attribute__((constructor)) fido_ctor() { #if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION) ccid_atr = atr_fido; #endif - register_app(fido_select); + register_app(fido_select, fido_aid); } int fido_unload() { return CCID_OK; } +uint8_t get_version_major() { + return PICO_FIDO_VERSION_MAJOR; +} +uint8_t get_version_minor() { + return PICO_FIDO_VERSION_MINOR; +} + mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve) { if (curve == FIDO2_CURVE_P256) { return MBEDTLS_ECP_DP_SECP256R1; diff --git a/src/fido/management.c b/src/fido/management.c index f2f8df7..5d4eefb 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -31,22 +31,18 @@ const uint8_t man_aid[] = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 }; extern void scan_all(); -app_t *man_select(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, man_aid + 1, MIN(aid_len, man_aid[0]))) { - a->aid = man_aid; - a->process_apdu = man_process_apdu; - a->unload = man_unload; - sprintf((char *) res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR); - res_APDU_size = strlen((char *) res_APDU); - apdu.ne = res_APDU_size; - scan_all(); - return a; - } - return NULL; +int man_select(app_t *a) { + a->process_apdu = man_process_apdu; + a->unload = man_unload; + sprintf((char *) res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR); + res_APDU_size = strlen((char *) res_APDU); + apdu.ne = res_APDU_size; + scan_all(); + return CCID_OK; } void __attribute__((constructor)) man_ctor() { - register_app(man_select); + register_app(man_select, man_aid); } int man_unload() { diff --git a/src/fido/oath.c b/src/fido/oath.c index e3d25bc..a0713c9 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -68,50 +68,46 @@ const uint8_t oath_aid[] = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x21, 0x01 }; -app_t *oath_select(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, oath_aid + 1, MIN(aid_len, oath_aid[0])) && cap_supported(CAP_OATH)) { - a->aid = oath_aid; - a->process_apdu = oath_process_apdu; - a->unload = oath_unload; - res_APDU_size = 0; - res_APDU[res_APDU_size++] = TAG_T_VERSION; - res_APDU[res_APDU_size++] = 3; - res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR; - res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR; - res_APDU[res_APDU_size++] = 0; - res_APDU[res_APDU_size++] = TAG_NAME; - res_APDU[res_APDU_size++] = 8; +int oath_select(app_t *a) { + a->process_apdu = oath_process_apdu; + a->unload = oath_unload; + res_APDU_size = 0; + res_APDU[res_APDU_size++] = TAG_T_VERSION; + res_APDU[res_APDU_size++] = 3; + res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR; + res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR; + res_APDU[res_APDU_size++] = 0; + res_APDU[res_APDU_size++] = TAG_NAME; + res_APDU[res_APDU_size++] = 8; #ifndef ENABLE_EMULATION - pico_get_unique_board_id((pico_unique_board_id_t *) (res_APDU + res_APDU_size)); - res_APDU_size += 8; + pico_get_unique_board_id((pico_unique_board_id_t *) (res_APDU + res_APDU_size)); + res_APDU_size += 8; #else - memset(res_APDU + res_APDU_size, 0, 8); res_APDU_size += 8; + memset(res_APDU + res_APDU_size, 0, 8); res_APDU_size += 8; #endif - if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) { - random_gen(NULL, challenge, sizeof(challenge)); - res_APDU[res_APDU_size++] = TAG_CHALLENGE; - res_APDU[res_APDU_size++] = sizeof(challenge); - memcpy(res_APDU + res_APDU_size, challenge, sizeof(challenge)); - res_APDU_size += sizeof(challenge); - } - file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); - if (file_has_data(ef_otp_pin)) { - const uint8_t *pin_data = file_get_data(ef_otp_pin); - res_APDU[res_APDU_size++] = TAG_PIN_COUNTER; - res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = *pin_data; - } - res_APDU[res_APDU_size++] = TAG_ALGO; - res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = ALG_HMAC_SHA1; - apdu.ne = res_APDU_size; - return a; + if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) { + random_gen(NULL, challenge, sizeof(challenge)); + res_APDU[res_APDU_size++] = TAG_CHALLENGE; + res_APDU[res_APDU_size++] = sizeof(challenge); + memcpy(res_APDU + res_APDU_size, challenge, sizeof(challenge)); + res_APDU_size += sizeof(challenge); } - return NULL; + file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); + if (file_has_data(ef_otp_pin)) { + const uint8_t *pin_data = file_get_data(ef_otp_pin); + res_APDU[res_APDU_size++] = TAG_PIN_COUNTER; + res_APDU[res_APDU_size++] = 1; + res_APDU[res_APDU_size++] = *pin_data; + } + res_APDU[res_APDU_size++] = TAG_ALGO; + res_APDU[res_APDU_size++] = 1; + res_APDU[res_APDU_size++] = ALG_HMAC_SHA1; + apdu.ne = res_APDU_size; + return CCID_OK; } void __attribute__((constructor)) oath_ctor() { - register_app(oath_select); + register_app(oath_select, oath_aid); } int oath_unload() { diff --git a/src/fido/otp.c b/src/fido/otp.c index a38c287..3bfce0d 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -116,25 +116,21 @@ const uint8_t otp_aid[] = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01 }; -app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, otp_aid + 1, MIN(aid_len, otp_aid[0])) && cap_supported(CAP_OTP)) { - a->aid = otp_aid; - a->process_apdu = otp_process_apdu; - a->unload = otp_unload; - if (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) || - file_has_data(search_dynamic_file(EF_OTP_SLOT2))) { - config_seq = 1; - } - else { - config_seq = 0; - } - otp_status(); - memmove(res_APDU, res_APDU + 1, 6); - res_APDU_size = 6; - apdu.ne = res_APDU_size; - return a; +int otp_select(app_t *a) { + a->process_apdu = otp_process_apdu; + a->unload = otp_unload; + if (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) || + file_has_data(search_dynamic_file(EF_OTP_SLOT2))) { + config_seq = 1; } - return NULL; + else { + config_seq = 0; + } + otp_status(); + memmove(res_APDU, res_APDU + 1, 6); + res_APDU_size = 6; + apdu.ne = res_APDU_size; + return CCID_OK; } uint8_t modhex_tab[] = @@ -308,7 +304,7 @@ int otp_button_pressed(uint8_t slot) { } void __attribute__((constructor)) otp_ctor() { - register_app(otp_select); + register_app(otp_select, otp_aid); button_pressed_cb = otp_button_pressed; } From da94a824877b46c2e4cc5c63a9375269a156075b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:57:53 +0200 Subject: [PATCH 06/39] Fix AID selection. Signed-off-by: Pol Henarejos --- src/fido/cmd_register.c | 9 ++++-- src/fido/fido.c | 9 ++++-- src/fido/oath.c | 63 +++++++++++++++++++++-------------------- src/fido/otp.c | 29 ++++++++++--------- 4 files changed, 61 insertions(+), 49 deletions(-) diff --git a/src/fido/cmd_register.c b/src/fido/cmd_register.c index 877f5b0..1be7e55 100644 --- a/src/fido/cmd_register.c +++ b/src/fido/cmd_register.c @@ -33,9 +33,12 @@ int u2f_unload(); int u2f_process_apdu(); int u2f_select(app_t *a) { - a->process_apdu = u2f_process_apdu; - a->unload = u2f_unload; - return CCID_OK; + if (cap_supported(CAP_U2F)) { + a->process_apdu = u2f_process_apdu; + a->unload = u2f_unload; + return CCID_OK; + } + return CCID_ERR_FILE_NOT_FOUND; } void __attribute__((constructor)) u2f_ctor() { diff --git a/src/fido/fido.c b/src/fido/fido.c index 32db925..4431136 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -55,9 +55,12 @@ const uint8_t atr_fido[] = { }; int fido_select(app_t *a) { - a->process_apdu = fido_process_apdu; - a->unload = fido_unload; - return CCID_OK; + if (cap_supported(CAP_FIDO2)) { + a->process_apdu = fido_process_apdu; + a->unload = fido_unload; + return CCID_OK; + } + return CCID_ERR_FILE_NOT_FOUND; } void __attribute__((constructor)) fido_ctor() { diff --git a/src/fido/oath.c b/src/fido/oath.c index a0713c9..0a9b9a3 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -69,41 +69,44 @@ const uint8_t oath_aid[] = { }; int oath_select(app_t *a) { - a->process_apdu = oath_process_apdu; - a->unload = oath_unload; - res_APDU_size = 0; - res_APDU[res_APDU_size++] = TAG_T_VERSION; - res_APDU[res_APDU_size++] = 3; - res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR; - res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR; - res_APDU[res_APDU_size++] = 0; - res_APDU[res_APDU_size++] = TAG_NAME; - res_APDU[res_APDU_size++] = 8; + if (cap_supported(CAP_OATH)) { + a->process_apdu = oath_process_apdu; + a->unload = oath_unload; + res_APDU_size = 0; + res_APDU[res_APDU_size++] = TAG_T_VERSION; + res_APDU[res_APDU_size++] = 3; + res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR; + res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR; + res_APDU[res_APDU_size++] = 0; + res_APDU[res_APDU_size++] = TAG_NAME; + res_APDU[res_APDU_size++] = 8; #ifndef ENABLE_EMULATION - pico_get_unique_board_id((pico_unique_board_id_t *) (res_APDU + res_APDU_size)); - res_APDU_size += 8; + pico_get_unique_board_id((pico_unique_board_id_t *) (res_APDU + res_APDU_size)); + res_APDU_size += 8; #else - memset(res_APDU + res_APDU_size, 0, 8); res_APDU_size += 8; + memset(res_APDU + res_APDU_size, 0, 8); res_APDU_size += 8; #endif - if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) { - random_gen(NULL, challenge, sizeof(challenge)); - res_APDU[res_APDU_size++] = TAG_CHALLENGE; - res_APDU[res_APDU_size++] = sizeof(challenge); - memcpy(res_APDU + res_APDU_size, challenge, sizeof(challenge)); - res_APDU_size += sizeof(challenge); - } - file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); - if (file_has_data(ef_otp_pin)) { - const uint8_t *pin_data = file_get_data(ef_otp_pin); - res_APDU[res_APDU_size++] = TAG_PIN_COUNTER; + if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) { + random_gen(NULL, challenge, sizeof(challenge)); + res_APDU[res_APDU_size++] = TAG_CHALLENGE; + res_APDU[res_APDU_size++] = sizeof(challenge); + memcpy(res_APDU + res_APDU_size, challenge, sizeof(challenge)); + res_APDU_size += sizeof(challenge); + } + file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); + if (file_has_data(ef_otp_pin)) { + const uint8_t *pin_data = file_get_data(ef_otp_pin); + res_APDU[res_APDU_size++] = TAG_PIN_COUNTER; + res_APDU[res_APDU_size++] = 1; + res_APDU[res_APDU_size++] = *pin_data; + } + res_APDU[res_APDU_size++] = TAG_ALGO; res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = *pin_data; + res_APDU[res_APDU_size++] = ALG_HMAC_SHA1; + apdu.ne = res_APDU_size; + return CCID_OK; } - res_APDU[res_APDU_size++] = TAG_ALGO; - res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = ALG_HMAC_SHA1; - apdu.ne = res_APDU_size; - return CCID_OK; + return CCID_ERR_FILE_NOT_FOUND; } void __attribute__((constructor)) oath_ctor() { diff --git a/src/fido/otp.c b/src/fido/otp.c index 3bfce0d..7a8bfd3 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -117,20 +117,23 @@ const uint8_t otp_aid[] = { }; int otp_select(app_t *a) { - a->process_apdu = otp_process_apdu; - a->unload = otp_unload; - if (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) || - file_has_data(search_dynamic_file(EF_OTP_SLOT2))) { - config_seq = 1; + if (cap_supported(CAP_OTP)) { + a->process_apdu = otp_process_apdu; + a->unload = otp_unload; + if (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) || + file_has_data(search_dynamic_file(EF_OTP_SLOT2))) { + config_seq = 1; + } + else { + config_seq = 0; + } + otp_status(); + memmove(res_APDU, res_APDU + 1, 6); + res_APDU_size = 6; + apdu.ne = res_APDU_size; + return CCID_OK; } - else { - config_seq = 0; - } - otp_status(); - memmove(res_APDU, res_APDU + 1, 6); - res_APDU_size = 6; - apdu.ne = res_APDU_size; - return CCID_OK; + return CCID_ERR_FILE_NOT_FOUND; } uint8_t modhex_tab[] = From 7bf26b28fcf14621f1613fb53734eadc10b4b89f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 30 Oct 2023 16:51:56 +0100 Subject: [PATCH 07/39] Fixed potential memory leak. Signed-off-by: Pol Henarejos --- src/fido/oath.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fido/oath.c b/src/fido/oath.c index 0a9b9a3..d2615c7 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -454,6 +454,7 @@ int cmd_calculate_all() { if (asn1_find_tag(apdu.data, apdu.nc, TAG_CHALLENGE, &chal_len, &chal) == false) { return SW_INCORRECT_PARAMS(); } + res_APDU_size = 0; for (int i = 0; i < MAX_OATH_CRED; i++) { file_t *ef = search_dynamic_file(EF_OATH_CRED + i); if (file_has_data(ef)) { From 0fd36806cced45b11c1ed36c14fc505cd8d3d171 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 31 Oct 2023 00:40:56 +0100 Subject: [PATCH 08/39] Fixed potential crash. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index 4f09254..3182d1e 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit 4f0925420b896c247718471da39eb9ae1f86b145 +Subproject commit 3182d1e2e66f860f3b8f50fc2d86b4903b4f3784 From e5d1ef29a4335cd3fd483216772527cd16f32a8a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 31 Oct 2023 17:35:59 +0100 Subject: [PATCH 09/39] Fixed OTP read packet through HID interfaces. Fixes #19. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index 3182d1e..d580194 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit 3182d1e2e66f860f3b8f50fc2d86b4903b4f3784 +Subproject commit d58019403007d18ba10c0f490f0338747d577500 From 365236854223394933dc213e011888be595bbe14 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 09:32:19 +0100 Subject: [PATCH 10/39] Added Windows & Linux backend for backup/restore. Fixes #21 Signed-off-by: Pol Henarejos --- tools/pico-fido-tool.py | 32 +++++++++++++++++++-------- tools/secure_key/windows.py | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 tools/secure_key/windows.py diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 9971387..4123233 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -23,7 +23,6 @@ import sys import argparse import platform from binascii import hexlify -from words import words from threading import Event from typing import Mapping, Any, Optional, Callable import struct @@ -58,14 +57,6 @@ except: from enum import IntEnum from binascii import hexlify -if (platform.system() == 'Windows' or platform.system() == 'Linux'): - from secure_key import windows as skey -elif (platform.system() == 'Darwin'): - from secure_key import macos as skey -else: - print('ERROR: platform not supported') - sys.exit(-1) - def get_pki_data(url, data=None, method='GET'): user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; ' 'rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7' @@ -252,6 +243,14 @@ class Vendor: return self.ctap.vendor(cmd, sub_cmd, params, pin_uv_protocol, pin_uv_param) def backup_save(self, filename): + if (platform.system() == 'Windows' or platform.system() == 'Linux'): + from secure_key import windows as skey + elif (platform.system() == 'Darwin'): + from secure_key import macos as skey + else: + print('ERROR: platform not supported') + sys.exit(-1) + from words import words ret = self._call( Vendor.CMD.VENDOR_BACKUP, Vendor.SUBCMD.ENABLE, @@ -270,6 +269,14 @@ class Vendor: print(f'{(c+1):02d} - {words[coef]}') def backup_load(self, filename): + if (platform.system() == 'Windows' or platform.system() == 'Linux'): + from secure_key import windows as skey + elif (platform.system() == 'Darwin'): + from secure_key import macos as skey + else: + print('ERROR: platform not supported') + sys.exit(-1) + from words import words d = 0 if (d == 0): for c in range(24): @@ -349,6 +356,13 @@ class Vendor: ) def _get_key_device(self): + if (platform.system() == 'Windows' or platform.system() == 'Linux'): + from secure_key import windows as skey + elif (platform.system() == 'Darwin'): + from secure_key import macos as skey + else: + print('ERROR: platform not supported') + sys.exit(-1) return skey.get_secure_key() def get_skey(self): diff --git a/tools/secure_key/windows.py b/tools/secure_key/windows.py new file mode 100644 index 0000000..d1c5845 --- /dev/null +++ b/tools/secure_key/windows.py @@ -0,0 +1,44 @@ +import sys +import os +import base64 + +DOMAIN = "PicoKeys.com" +USERNAME = "Pico-Fido" + +try: + import keyring +except: + print('ERROR: keyring module not found! Install keyring package.\nTry with `pip install keyring`') + sys.exit(-1) + +try: + from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, load_pem_private_key + from cryptography.hazmat.primitives.asymmetric import ec +except: + print('ERROR: cryptography module not found! Install cryptography package.\nTry with `pip install cryptography`') + sys.exit(-1) + + + +def generate_secure_key(): + pkey = ec.generate_private_key(ec.SECP256R1()) + set_secure_key(pkey) + return keyring.get_password(DOMAIN, USERNAME) + +def get_d(key): + return load_pem_private_key(key, password=None).private_numbers().private_value.to_bytes(32, 'big') + +def set_secure_key(pk): + try: + keyring.delete_password(DOMAIN, USERNAME) + except: + pass + keyring.set_password(DOMAIN, USERNAME, pk.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()).decode()) + +def get_secure_key(): + key = None + try: + key = keyring.get_password(DOMAIN, USERNAME) + except keyring.errors.KeyringError: + key = generate_secure_key() + return get_d(key.encode()) From 8e36b4c379eebbbe25014855f9006c487fec99ec Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 22:08:49 +0100 Subject: [PATCH 11/39] Added support for --pin flag. It loads Vendor/Ctap2Vendor with uv_token based on provided --pin. Signed-off-by: Pol Henarejos --- tools/pico-fido-tool.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 4123233..38336d0 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -32,7 +32,7 @@ from enum import IntEnum, unique try: from fido2.ctap2.config import Config - from fido2.ctap2 import Ctap2 + from fido2.ctap2 import Ctap2, ClientPin, PinProtocolV2 from fido2.hid import CtapHidDevice, CTAPHID from fido2.utils import bytes2int, int2bytes from fido2 import cbor @@ -221,7 +221,7 @@ class Vendor: self.__key_enc = None self.__iv = None - self.vcfg = VendorConfig(ctap) + self.vcfg = VendorConfig(ctap, pin_uv_protocol=pin_uv_protocol, pin_uv_token=pin_uv_token) def _call(self, cmd, sub_cmd, params=None): if params: @@ -395,6 +395,7 @@ class Vendor: def parse_args(): parser = argparse.ArgumentParser() subparser = parser.add_subparsers(title="commands", dest="command") + parser.add_argument('-p','--pin', help='Specify the PIN of the device.', required=True) parser_secure = subparser.add_parser('secure', help='Manages security of Pico Fido.') parser_secure.add_argument('subcommand', choices=['enable', 'disable', 'unlock'], help='Enables, disables or unlocks the security.') @@ -440,15 +441,17 @@ def attestation(vdr, args): vdr.upload_ea(cert.public_bytes(Encoding.DER)) def main(args): - print('Pico Fido Tool v1.4') + print('Pico Fido Tool v1.5') print('Author: Pol Henarejos') print('Report bugs to https://github.com/polhenarejos/pico-fido/issues') print('') print('') dev = next(CtapHidDevice.list_devices(), None) - - vdr = Vendor(Ctap2Vendor(dev)) + ctap = Ctap2Vendor(dev) + client_pin = ClientPin(ctap) + token = client_pin.get_pin_token(args.pin) + vdr = Vendor(ctap, pin_uv_protocol=PinProtocolV2(), pin_uv_token=token) if (args.command == 'secure'): secure(vdr, args) From 65039c0959fd13b7d4e22f4fba89f553b64bbbbc Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 22:13:45 +0100 Subject: [PATCH 12/39] Fixed AUT permission. Signed-off-by: Pol Henarejos --- tools/pico-fido-tool.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 38336d0..5b58911 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -90,7 +90,7 @@ class VendorConfig(Config): def enable_device_aut(self, ct): self._call( - Config.CMD.VENDOR_PROTOTYPE, + Config.CMD.CONFIG_VENDOR_PROTOTYPE, { VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT_ENABLE, VendorConfig.PARAM.VENDOR_AUT_CT: ct @@ -99,7 +99,7 @@ class VendorConfig(Config): def disable_device_aut(self): self._call( - Config.CMD.VENDOR_PROTOTYPE, + Config.CMD.CONFIG_VENDOR_PROTOTYPE, { VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT_DISABLE }, @@ -450,7 +450,7 @@ def main(args): dev = next(CtapHidDevice.list_devices(), None) ctap = Ctap2Vendor(dev) client_pin = ClientPin(ctap) - token = client_pin.get_pin_token(args.pin) + token = client_pin.get_pin_token(args.pin, permissions=ClientPin.PERMISSION.AUTHENTICATOR_CFG) vdr = Vendor(ctap, pin_uv_protocol=PinProtocolV2(), pin_uv_token=token) if (args.command == 'secure'): From 421bea642167b16ee09e6efd3ab18820eeee2504 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 22:14:42 +0100 Subject: [PATCH 13/39] python-fido2 has a bug which does not allow to use 0xff as ConfigVendorPrototype. It encodes an uint8_t to int8_t and thus, the command must be <= 0x7f. Fixes #22. Signed-off-by: Pol Henarejos --- src/fido/cbor_config.c | 4 ++-- tools/pico-fido-tool.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index 88562d8..0d6aeb8 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -64,7 +64,7 @@ int cbor_config(const uint8_t *data, size_t len) { raw_subpara = (uint8_t *) cbor_value_get_next_byte(&_f1); CBOR_PARSE_MAP_START(_f1, 2) { - if (subcommand == 0xff) { + if (subcommand == 0x7f) { CBOR_FIELD_GET_UINT(subpara, 2); if (subpara == 0x01) { CBOR_FIELD_GET_UINT(vendorCommandId, 2); @@ -134,7 +134,7 @@ int cbor_config(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); } - if (subcommand == 0xff) { + if (subcommand == 0x7f) { if (vendorCommandId == CTAP_CONFIG_AUT_DISABLE) { if (!file_has_data(ef_keydev_enc)) { CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED); diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 5b58911..a12bce1 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -81,6 +81,7 @@ class VendorConfig(Config): class CMD(IntEnum): CONFIG_AUT_ENABLE = 0x03e43f56b34285e2 CONFIG_AUT_DISABLE = 0x1831a40f04a25ed9 + CONFIG_VENDOR_PROTOTYPE = 0x7f class RESP(IntEnum): KEY_AGREEMENT = 0x01 @@ -90,7 +91,7 @@ class VendorConfig(Config): def enable_device_aut(self, ct): self._call( - Config.CMD.CONFIG_VENDOR_PROTOTYPE, + VendorConfig.CMD.CONFIG_VENDOR_PROTOTYPE, { VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT_ENABLE, VendorConfig.PARAM.VENDOR_AUT_CT: ct @@ -99,7 +100,7 @@ class VendorConfig(Config): def disable_device_aut(self): self._call( - Config.CMD.CONFIG_VENDOR_PROTOTYPE, + VendorConfig.CMD.CONFIG_VENDOR_PROTOTYPE, { VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT_DISABLE }, From 5db1014850aa60921db489117eba8ccfcba43aac Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:48:32 +0100 Subject: [PATCH 14/39] Generate a secure key if it is not found. Should fix #23. Signed-off-by: Pol Henarejos --- tools/pico-fido-tool.py | 2 +- tools/secure_key/macos.py | 4 +++- tools/secure_key/windows.py | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index a12bce1..89d1615 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -442,7 +442,7 @@ def attestation(vdr, args): vdr.upload_ea(cert.public_bytes(Encoding.DER)) def main(args): - print('Pico Fido Tool v1.5') + print('Pico Fido Tool v1.6') print('Author: Pol Henarejos') print('Report bugs to https://github.com/polhenarejos/pico-fido/issues') print('') diff --git a/tools/secure_key/macos.py b/tools/secure_key/macos.py index 381ee21..1ccc1a4 100644 --- a/tools/secure_key/macos.py +++ b/tools/secure_key/macos.py @@ -51,7 +51,9 @@ def get_secure_key(): try: backend = get_backend(False) key = backend.get_password(DOMAIN, USERNAME)[0] - except keyring.errors.KeyringError: + if (key is None): + raise TypeError + except (keyring.errors.KeyringError, TypeError): try: key = generate_secure_key(False)[0] # It should be True, but secure enclave causes python segfault except keyring.errors.PasswordSetError: diff --git a/tools/secure_key/windows.py b/tools/secure_key/windows.py index d1c5845..844190a 100644 --- a/tools/secure_key/windows.py +++ b/tools/secure_key/windows.py @@ -1,6 +1,4 @@ import sys -import os -import base64 DOMAIN = "PicoKeys.com" USERNAME = "Pico-Fido" @@ -39,6 +37,8 @@ def get_secure_key(): key = None try: key = keyring.get_password(DOMAIN, USERNAME) - except keyring.errors.KeyringError: + if (key is None): + raise TypeError + except (keyring.errors.KeyringError, TypeError): key = generate_secure_key() return get_d(key.encode()) From cb2744cab37bc845de9333434b6fcb618ba521e1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:49:18 +0100 Subject: [PATCH 15/39] Move some OTP functions from HID to OTP. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/src/fido/otp.c b/src/fido/otp.c index 7a8bfd3..65f4bdb 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -111,6 +111,13 @@ uint16_t otp_status(); int otp_process_apdu(); int otp_unload(); +#ifndef ENABLE_EMULATION +extern int (*hid_set_report_cb)(uint8_t, uint8_t, hid_report_type_t, uint8_t const *, uint16_t); +extern uint16_t (*hid_get_report_cb)(uint8_t, uint8_t, hid_report_type_t, uint8_t *, uint16_t); +int otp_hid_set_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t const *, uint16_t); +uint16_t otp_hid_get_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t *, uint16_t); +#endif + const uint8_t otp_aid[] = { 7, 0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01 @@ -168,6 +175,10 @@ void init_otp() { } scanned = true; low_flash_available(); +#ifndef ENABLE_EMULATION + hid_set_report_cb = otp_hid_set_report_cb; + hid_get_report_cb = otp_hid_get_report_cb; +#endif } } extern int calculate_oath(uint8_t truncate, @@ -175,6 +186,22 @@ extern int calculate_oath(uint8_t truncate, size_t key_len, const uint8_t *chal, size_t chal_len); + +uint16_t calculate_crc(const uint8_t *data, size_t data_len) { + uint16_t crc = 0xFFFF; + for (size_t idx = 0; idx < data_len; idx++) { + crc ^= data[idx]; + for (uint8_t i = 0; i < 8; i++) { + uint16_t j = crc & 0x1; + crc >>= 1; + if (j == 1) { + crc ^= 0x8408; + } + } + } + return crc & 0xFFFF; +} + #ifndef ENABLE_EMULATION static uint8_t session_counter[2] = { 0 }; #endif @@ -488,3 +515,112 @@ int otp_process_apdu() { } return SW_INS_NOT_SUPPORTED(); } + +#ifndef ENABLE_EMULATION + +uint8_t otp_frame_rx[70] = {0}; +uint8_t otp_frame_tx[70] = {0}; +uint8_t otp_exp_seq = 0, otp_curr_seq = 0; +uint8_t otp_header[4] = {0}; + +extern uint16_t *get_send_buffer_size(uint8_t itf); + +int otp_send_frame(uint8_t *frame, size_t frame_len) { + uint16_t crc = calculate_crc(frame, frame_len); + frame[frame_len] = ~crc & 0xff; + frame[frame_len + 1] = ~crc >> 8; + frame_len += 2; + *get_send_buffer_size(ITF_KEYBOARD) = frame_len; + otp_exp_seq = (frame_len / 7); + if (frame_len % 7) { + otp_exp_seq++; + } + otp_curr_seq = 0; + return 0; +} + +int otp_hid_set_report_cb(uint8_t itf, + uint8_t report_id, + hid_report_type_t report_type, + uint8_t const *buffer, + uint16_t bufsize) +{ + if (report_type == 3) { + DEBUG_PAYLOAD(buffer, bufsize); + if (itf == ITF_KEYBOARD && buffer[7] == 0xFF) { // reset + *get_send_buffer_size(ITF_KEYBOARD) = 0; + otp_curr_seq = otp_exp_seq = 0; + memset(otp_frame_tx, 0, sizeof(otp_frame_tx)); + } + else if (buffer[7] & 0x80) { // a frame + uint8_t rseq = buffer[7] & 0x1F; + if (rseq < 10) { + if (rseq == 0) { + memset(otp_frame_rx, 0, sizeof(otp_frame_rx)); + } + memcpy(otp_frame_rx + rseq * 7, buffer, 7); + if (rseq == 9) { + DEBUG_DATA(otp_frame_rx, sizeof(otp_frame_rx)); + uint16_t residual_crc = calculate_crc(otp_frame_rx, 64), rcrc = (otp_frame_rx[66] << 8 | otp_frame_rx[65]); + uint8_t slot_id = otp_frame_rx[64]; + if (residual_crc == rcrc) { + apdu.data = otp_frame_rx; + apdu.nc = 64; + apdu.rdata = otp_frame_tx; + apdu.header[0] = 0; + apdu.header[1] = 0x01; + apdu.header[2] = slot_id; + apdu.header[3] = 0; + int ret = otp_process_apdu(); + if (ret == 0x9000 && res_APDU_size > 0) { + otp_send_frame(apdu.rdata, apdu.rlen); + } + } + else { + printf("[OTP] Bad CRC!\n"); + } + } + } + } + return 1; + } + return 0; +} + +uint16_t otp_hid_get_report_cb(uint8_t itf, + uint8_t report_id, + hid_report_type_t report_type, + uint8_t *buffer, + uint16_t reqlen) { + // TODO not Implemented + (void) itf; + (void) report_id; + (void) report_type; + (void) buffer; + (void) reqlen; + printf("get_report %d %d %d\n", itf, report_id, report_type); + DEBUG_PAYLOAD(buffer, reqlen); + uint16_t send_buffer_size = *get_send_buffer_size(ITF_KEYBOARD); + if (send_buffer_size > 0) { + uint8_t seq = otp_curr_seq++; + memset(buffer, 0, 8); + memcpy(buffer, otp_frame_tx + 7 * seq, MIN(7, send_buffer_size)); + buffer[7] = 0x40 | seq; + DEBUG_DATA(buffer, 8); + *get_send_buffer_size(ITF_KEYBOARD) -= MIN(7, send_buffer_size); + } + else if (otp_curr_seq == otp_exp_seq && otp_exp_seq > 0) { + memset(buffer, 0, 7); + buffer[7] = 0x40; + DEBUG_DATA(buffer,8); + otp_curr_seq = otp_exp_seq = 0; + } + else { + otp_status(); + memcpy(buffer, res_APDU, 7); + } + + return reqlen; +} + +#endif From 440ec5c85420ea56e3c42ac927f66b3ff2378301 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:49:42 +0100 Subject: [PATCH 16/39] Update SDK to new otp. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index d580194..c9cb330 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit d58019403007d18ba10c0f490f0338747d577500 +Subproject commit c9cb330a07fa2bcd33a354d903aec86b0e08b145 From 27b9e3954aa70237e5bfa55477ace0bd5b6b3e83 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:57:08 +0100 Subject: [PATCH 17/39] Use get_version_major and get_version_minor as pointers. Signed-off-by: Pol Henarejos --- src/fido/fido.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/fido/fido.c b/src/fido/fido.c index 4431136..be9c685 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -54,6 +54,13 @@ const uint8_t atr_fido[] = { 0x75, 0x62, 0x69, 0x4b, 0x65, 0x79, 0x40 }; +uint8_t fido_get_version_major() { + return PICO_FIDO_VERSION_MAJOR; +} +uint8_t fido_get_version_minor() { + return PICO_FIDO_VERSION_MINOR; +} + int fido_select(app_t *a) { if (cap_supported(CAP_FIDO2)) { a->process_apdu = fido_process_apdu; @@ -63,24 +70,22 @@ int fido_select(app_t *a) { return CCID_ERR_FILE_NOT_FOUND; } +extern uint8_t (*get_version_major)(); +extern uint8_t (*get_version_minor)(); + void __attribute__((constructor)) fido_ctor() { #if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION) ccid_atr = atr_fido; #endif register_app(fido_select, fido_aid); + get_version_major = fido_get_version_major; + get_version_minor = fido_get_version_minor; } int fido_unload() { return CCID_OK; } -uint8_t get_version_major() { - return PICO_FIDO_VERSION_MAJOR; -} -uint8_t get_version_minor() { - return PICO_FIDO_VERSION_MINOR; -} - mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve) { if (curve == FIDO2_CURVE_P256) { return MBEDTLS_ECP_DP_SECP256R1; From 5c20909b03144153c00c8e0bea5860b7b2a405b6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 13:01:10 +0100 Subject: [PATCH 18/39] Move some functions from HID to fido callbacks. Signed-off-by: Pol Henarejos --- src/fido/fido.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/fido/fido.c b/src/fido/fido.c index be9c685..b990b14 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -43,7 +43,7 @@ pinUvAuthToken_t paut = { 0 }; uint8_t keydev_dec[32]; bool has_keydev_dec = false; -const uint8_t fido_aid[] = { +const uint8_t _fido_aid[] = { 8, 0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01 }; @@ -72,14 +72,24 @@ int fido_select(app_t *a) { extern uint8_t (*get_version_major)(); extern uint8_t (*get_version_minor)(); +extern const uint8_t *fido_aid; +extern void (*init_fido_cb)(); +extern void (*cbor_thread_func)(); +extern int (*cbor_process_cb)(uint8_t, const uint8_t *, size_t); +extern void cbor_thread(); +extern int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len); void __attribute__((constructor)) fido_ctor() { #if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION) ccid_atr = atr_fido; #endif - register_app(fido_select, fido_aid); get_version_major = fido_get_version_major; get_version_minor = fido_get_version_minor; + fido_aid = _fido_aid; + init_fido_cb = init_fido; + cbor_thread_func = cbor_thread; + cbor_process_cb = cbor_process; + register_app(fido_select, fido_aid); } int fido_unload() { From b493a81ddce0911165f529990440938f25c68287 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 14:27:57 +0100 Subject: [PATCH 19/39] Rename old pico-hsm-sdk to the new pico-keys-sdk. Signed-off-by: Pol Henarejos --- .gitmodules | 2 +- pico-hsm-sdk => pico-keys-sdk | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename pico-hsm-sdk => pico-keys-sdk (100%) diff --git a/.gitmodules b/.gitmodules index 6e06e69..5609c7f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "pico-hsm-sdk"] - path = pico-hsm-sdk + path = pico-keys-sdk url = ../pico-hsm-sdk diff --git a/pico-hsm-sdk b/pico-keys-sdk similarity index 100% rename from pico-hsm-sdk rename to pico-keys-sdk From f8d4f1d02e860cc5dd77def8ad88505a22096200 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 14:28:09 +0100 Subject: [PATCH 20/39] Use new pico-keys-sdk submodule name. Signed-off-by: Pol Henarejos --- .gitmodules | 4 ++-- pico-keys-sdk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5609c7f..852c02c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "pico-hsm-sdk"] +[submodule "pico-keys-sdk"] path = pico-keys-sdk - url = ../pico-hsm-sdk + url = https://github.com/polhenarejos/pico-keys-sdk diff --git a/pico-keys-sdk b/pico-keys-sdk index c9cb330..09276f7 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit c9cb330a07fa2bcd33a354d903aec86b0e08b145 +Subproject commit 09276f7117beb7a2f52e65cc601b9153e7b59ca1 From d78d9d10aaf8fe2f0d29b54c05cf28005930a431 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 15:22:28 +0100 Subject: [PATCH 21/39] Use new names and defines. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 4 ++-- src/fido/cbor_client_pin.c | 10 +++++----- src/fido/cbor_config.c | 2 +- src/fido/cbor_cred_mgmt.c | 2 +- src/fido/cbor_get_assertion.c | 2 +- src/fido/cbor_large_blobs.c | 2 +- src/fido/cbor_make_credential.c | 2 +- src/fido/cbor_vendor.c | 2 +- src/fido/cmd_authenticate.c | 2 +- src/fido/cmd_register.c | 2 +- src/fido/cmd_version.c | 2 +- src/fido/credential.c | 2 +- src/fido/fido.c | 2 +- src/fido/management.c | 2 +- src/fido/oath.c | 2 +- src/fido/otp.c | 2 +- 16 files changed, 21 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8eee727..a5f60bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ set(SOURCES ${SOURCES} endif() set(USB_ITF_HID 1) -include(pico-hsm-sdk/pico_hsm_sdk_import.cmake) +include(pico-keys-sdk/pico_keys_sdk_import.cmake) set(INCLUDES ${INCLUDES} ${CMAKE_CURRENT_LIST_DIR}/src/fido @@ -147,5 +147,5 @@ target_compile_options(pico_fido PUBLIC endif (APPLE) else() pico_add_extra_outputs(pico_fido) -target_link_libraries(pico_fido PRIVATE pico_hsm_sdk pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc tinyusb_device tinyusb_board) +target_link_libraries(pico_fido PRIVATE pico_keys_sdk pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc tinyusb_device tinyusb_board) endif() diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index f47c09e..c7c13d8 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -31,7 +31,7 @@ #include "files.h" #include "random.h" #include "crypto_utils.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" uint32_t usage_timer = 0, initial_usage_time_limit = 0; @@ -181,12 +181,12 @@ int resetPinUvAuthToken() { int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out) { if (protocol == 1) { memcpy(out, in, in_len); - return aes_encrypt(key, NULL, 32 * 8, HSM_AES_MODE_CBC, out, in_len); + return aes_encrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len); } else if (protocol == 2) { 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); + return aes_encrypt(key + 32, out, 32 * 8, PICO_KEYS_AES_MODE_CBC, out + IV_SIZE, in_len); } return -1; @@ -195,11 +195,11 @@ int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_l int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out) { if (protocol == 1) { memcpy(out, in, in_len); - return aes_decrypt(key, NULL, 32 * 8, HSM_AES_MODE_CBC, out, in_len); + return aes_decrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len); } else if (protocol == 2) { memcpy(out, in + IV_SIZE, in_len); - return aes_decrypt(key + 32, in, 32 * 8, HSM_AES_MODE_CBC, out, in_len - IV_SIZE); + return aes_decrypt(key + 32, in, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len - IV_SIZE); } return -1; diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index 0d6aeb8..4026cc7 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -22,7 +22,7 @@ #include "files.h" #include "apdu.h" #include "credential.h" -#include "hsm.h" +#include "pico_keys.h" #include "random.h" #include "mbedtls/ecdh.h" #include "mbedtls/chachapoly.h" diff --git a/src/fido/cbor_cred_mgmt.c b/src/fido/cbor_cred_mgmt.c index 7f5bf3f..68e95a8 100644 --- a/src/fido/cbor_cred_mgmt.c +++ b/src/fido/cbor_cred_mgmt.c @@ -22,7 +22,7 @@ #include "files.h" #include "apdu.h" #include "credential.h" -#include "hsm.h" +#include "pico_keys.h" uint8_t rp_counter = 1; uint8_t rp_total = 0; diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index 8dfb206..f3a2516 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -24,7 +24,7 @@ #include "fido.h" #include "files.h" #include "crypto_utils.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "cbor_make_credential.h" #include "credential.h" diff --git a/src/fido/cbor_large_blobs.c b/src/fido/cbor_large_blobs.c index 4948457..c3ebd70 100644 --- a/src/fido/cbor_large_blobs.c +++ b/src/fido/cbor_large_blobs.c @@ -21,7 +21,7 @@ #include "hid/ctap_hid.h" #include "files.h" #include "apdu.h" -#include "hsm.h" +#include "pico_keys.h" #include "mbedtls/sha256.h" static uint64_t expectedLength = 0, expectedNextOffset = 0; diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 832ee35..44a488f 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -25,7 +25,7 @@ #include "credential.h" #include "mbedtls/sha256.h" #include "random.h" -#include "hsm.h" +#include "pico_keys.h" int cbor_make_credential(const uint8_t *data, size_t len) { CborParser parser; diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index f76de3c..afe939b 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -21,7 +21,7 @@ #include "hid/ctap_hid.h" #include "files.h" #include "apdu.h" -#include "hsm.h" +#include "pico_keys.h" #include "random.h" #include "mbedtls/ecdh.h" #include "mbedtls/chachapoly.h" diff --git a/src/fido/cmd_authenticate.c b/src/fido/cmd_authenticate.c index 3bea9e6..6f458d6 100644 --- a/src/fido/cmd_authenticate.c +++ b/src/fido/cmd_authenticate.c @@ -16,7 +16,7 @@ */ #include "fido.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "ctap.h" #include "random.h" diff --git a/src/fido/cmd_register.c b/src/fido/cmd_register.c index 1be7e55..7962719 100644 --- a/src/fido/cmd_register.c +++ b/src/fido/cmd_register.c @@ -16,7 +16,7 @@ */ #include "fido.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "ctap.h" #include "random.h" diff --git a/src/fido/cmd_version.c b/src/fido/cmd_version.c index 6a3b132..7b0ff74 100644 --- a/src/fido/cmd_version.c +++ b/src/fido/cmd_version.c @@ -16,7 +16,7 @@ */ #include "apdu.h" -#include "hsm.h" +#include "pico_keys.h" int cmd_version() { memcpy(res_APDU, "U2F_V2", strlen("U2F_V2")); diff --git a/src/fido/credential.c b/src/fido/credential.c index 7e766c6..b43388b 100644 --- a/src/fido/credential.c +++ b/src/fido/credential.c @@ -26,7 +26,7 @@ #include "ctap.h" #include "random.h" #include "files.h" -#include "hsm.h" +#include "pico_keys.h" int credential_derive_chacha_key(uint8_t *outk); diff --git a/src/fido/fido.c b/src/fido/fido.c index b990b14..ab0cc1b 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -16,7 +16,7 @@ */ #include "fido.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "ctap.h" #include "files.h" diff --git a/src/fido/management.c b/src/fido/management.c index 5d4eefb..f835b73 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -16,7 +16,7 @@ */ #include "fido.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "version.h" #include "files.h" diff --git a/src/fido/oath.c b/src/fido/oath.c index d2615c7..cfeb390 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -16,7 +16,7 @@ */ #include "fido.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "files.h" #include "random.h" diff --git a/src/fido/otp.c b/src/fido/otp.c index 65f4bdb..9b31027 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -16,7 +16,7 @@ */ #include "fido.h" -#include "hsm.h" +#include "pico_keys.h" #include "apdu.h" #include "files.h" #include "random.h" From ffb3beb84ab1cd1d8986c4d5f254de0e7c49d545 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 15:32:25 +0100 Subject: [PATCH 22/39] Fix build in emulation mode. Signed-off-by: Pol Henarejos --- src/fido/fido.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fido/fido.c b/src/fido/fido.c index ab0cc1b..d340f33 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -87,7 +87,9 @@ void __attribute__((constructor)) fido_ctor() { get_version_minor = fido_get_version_minor; fido_aid = _fido_aid; init_fido_cb = init_fido; +#ifndef ENABLE_EMULATION cbor_thread_func = cbor_thread; +#endif cbor_process_cb = cbor_process; register_app(fido_select, fido_aid); } From 1ee86f8634a8f919f8e882e25eaadab071a767a3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 16 Nov 2023 20:12:01 +0100 Subject: [PATCH 23/39] Moving Pico Keys SDK pointer. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 09276f7..f0687c1 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 09276f7117beb7a2f52e65cc601b9153e7b59ca1 +Subproject commit f0687c1ef392c2bcb293ea554f1dd8b784484922 From 195096ad5205c28c4877e3cb52bd468235ef049a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 16 Nov 2023 20:12:48 +0100 Subject: [PATCH 24/39] otp must be initialized when selection fido or management applets. Signed-off-by: Pol Henarejos --- src/fido/fido.c | 2 ++ src/fido/management.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/fido/fido.c b/src/fido/fido.c index d340f33..79a935d 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -398,8 +398,10 @@ void scan_all() { scan_files(); } +extern void init_otp(); void init_fido() { scan_all(); + init_otp(); } bool wait_button_pressed() { diff --git a/src/fido/management.c b/src/fido/management.c index f835b73..83cbd43 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -31,6 +31,7 @@ const uint8_t man_aid[] = { 0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 }; extern void scan_all(); +extern void init_otp(); int man_select(app_t *a) { a->process_apdu = man_process_apdu; a->unload = man_unload; @@ -38,6 +39,7 @@ int man_select(app_t *a) { res_APDU_size = strlen((char *) res_APDU); apdu.ne = res_APDU_size; scan_all(); + init_otp(); return CCID_OK; } From 96de6efed6f981ade100a895d0ffc8325fa447e8 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 16 Nov 2023 20:16:23 +0100 Subject: [PATCH 25/39] OTP static passwords are 38 bytes length. A static password uses fixed, uid and key fields (sum 38). However, Yubikey sets short_ticket flag which implies the half of the password is sent. Fixes #29. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fido/otp.c b/src/fido/otp.c index 9b31027..52f1f8b 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -270,10 +270,11 @@ int otp_button_pressed(uint8_t slot) { } } else if (otp_config->cfg_flags & SHORT_TICKET || otp_config->cfg_flags & STATIC_TICKET) { + uint8_t fixed_size = FIXED_SIZE + UID_SIZE + KEY_SIZE; if (otp_config->cfg_flags & SHORT_TICKET) { - otp_config->fixed_size /= 2; + fixed_size /= 2; } - add_keyboard_buffer(otp_config->fixed_data, otp_config->fixed_size, false); + add_keyboard_buffer(otp_config->fixed_data, fixed_size, false); if (otp_config->tkt_flags & APPEND_CR) { append_keyboard_buffer((const uint8_t *) "\x28", 1); } From 1ce0d98c3497360f1acaefa83a0c0308f8e1c91f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 21 Nov 2023 11:42:27 +0100 Subject: [PATCH 26/39] OTP callbacks must be initialized on ctor. Fixes #30. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/fido/otp.c b/src/fido/otp.c index 52f1f8b..58b7e34 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -175,10 +175,6 @@ void init_otp() { } scanned = true; low_flash_available(); -#ifndef ENABLE_EMULATION - hid_set_report_cb = otp_hid_set_report_cb; - hid_get_report_cb = otp_hid_get_report_cb; -#endif } } extern int calculate_oath(uint8_t truncate, @@ -337,6 +333,10 @@ int otp_button_pressed(uint8_t slot) { void __attribute__((constructor)) otp_ctor() { register_app(otp_select, otp_aid); button_pressed_cb = otp_button_pressed; +#ifndef ENABLE_EMULATION + hid_set_report_cb = otp_hid_set_report_cb; + hid_get_report_cb = otp_hid_get_report_cb; +#endif } int otp_unload() { @@ -599,8 +599,6 @@ uint16_t otp_hid_get_report_cb(uint8_t itf, (void) report_type; (void) buffer; (void) reqlen; - printf("get_report %d %d %d\n", itf, report_id, report_type); - DEBUG_PAYLOAD(buffer, reqlen); uint16_t send_buffer_size = *get_send_buffer_size(ITF_KEYBOARD); if (send_buffer_size > 0) { uint8_t seq = otp_curr_seq++; From e757ad294577e2688a53425f2c433b3175cd2322 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 21 Nov 2023 11:53:47 +0100 Subject: [PATCH 27/39] Removing SHORT_TICKET limitation. It is not used to return the half of ticket, but to combine with static to produce hex scancodes. Fixes #29. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fido/otp.c b/src/fido/otp.c index 58b7e34..e37e779 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -267,8 +267,8 @@ int otp_button_pressed(uint8_t slot) { } else if (otp_config->cfg_flags & SHORT_TICKET || otp_config->cfg_flags & STATIC_TICKET) { uint8_t fixed_size = FIXED_SIZE + UID_SIZE + KEY_SIZE; - if (otp_config->cfg_flags & SHORT_TICKET) { - fixed_size /= 2; + if (otp_config->cfg_flags & SHORT_TICKET) { // Not clear which is the purpose of SHORT_TICKET + //fixed_size /= 2; } add_keyboard_buffer(otp_config->fixed_data, fixed_size, false); if (otp_config->tkt_flags & APPEND_CR) { From 20a8ef08f06f067d816e8d5530538ebf72ade953 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 21 Nov 2023 12:01:47 +0100 Subject: [PATCH 28/39] Upgrade to version 5.8 Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 2 +- src/fido/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index 1e51c67..04945c3 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -1,7 +1,7 @@ #!/bin/bash VERSION_MAJOR="5" -VERSION_MINOR="6" +VERSION_MINOR="8" rm -rf release/* cd build_release diff --git a/src/fido/version.h b/src/fido/version.h index 721a0bf..789f039 100644 --- a/src/fido/version.h +++ b/src/fido/version.h @@ -18,7 +18,7 @@ #ifndef __VERSION_H_ #define __VERSION_H_ -#define PICO_FIDO_VERSION 0x0506 +#define PICO_FIDO_VERSION 0x0508 #define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff) #define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff) From 7a71bf48fc7680c243ff53b9e206cf5d453ffa73 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 11 Dec 2023 18:13:32 +0100 Subject: [PATCH 29/39] Add -DVIDPID= to build a project with a known VID/PID. Supported values: NitroHSM, NitroFIDO2, NitroStart, NitroPro, Nitro3, Yubikey5, YubikeyNeo, YubiHSM, Gnuk, GnuPG Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index f0687c1..4d77ca7 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit f0687c1ef392c2bcb293ea554f1dd8b784484922 +Subproject commit 4d77ca7b75eff04bd401208054a83857844ecca4 From 92d04f913198d7801625c927c0602b1952f18232 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 18:34:14 +0100 Subject: [PATCH 30/39] Use new asn1 structs. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/files.c | 2 +- src/fido/management.c | 10 +- src/fido/oath.c | 236 +++++++++++++++++++++--------------------- 4 files changed, 125 insertions(+), 125 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 4d77ca7..e055d4c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 4d77ca7b75eff04bd401208054a83857844ecca4 +Subproject commit e055d4cfc9df1a41585ac83d484b903088f3db13 diff --git a/src/fido/files.c b/src/fido/files.c index 121f76d..11573c5 100644 --- a/src/fido/files.c +++ b/src/fido/files.c @@ -49,7 +49,7 @@ file_t file_entries[] = { { .fid = EF_OTP_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, - { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, + { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_NOT_KNOWN, .data = NULL, .ef_structure = 0, .acl = { 0 } } //end }; diff --git a/src/fido/management.c b/src/fido/management.c index 83cbd43..fb305c8 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -54,10 +54,12 @@ int man_unload() { bool cap_supported(uint16_t cap) { file_t *ef = search_dynamic_file(EF_DEV_CONF); if (file_has_data(ef)) { - uint16_t tag = 0x0, data_len = file_get_size(ef); - uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef); - size_t tag_len = 0; - while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) { + uint16_t tag = 0x0; + uint8_t *tag_data = NULL, *p = NULL; + uint16_t tag_len = 0; + asn1_ctx_t ctxi; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == TAG_USB_ENABLED) { uint16_t ecaps = tag_data[0]; if (tag_len == 2) { diff --git a/src/fido/oath.c b/src/fido/oath.c index cfeb390..c2e942a 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -118,14 +118,11 @@ int oath_unload() { } file_t *find_oath_cred(const uint8_t *name, size_t name_len) { - size_t ef_tag_len = 0; - uint8_t *ef_tag_data = NULL; for (int i = 0; i < MAX_OATH_CRED; i++) { file_t *ef = search_dynamic_file(EF_OATH_CRED + i); - if (file_has_data(ef) && - asn1_find_tag(file_get_data(ef), file_get_size(ef), TAG_NAME, &ef_tag_len, - &ef_tag_data) == true && ef_tag_len == name_len && - memcmp(ef_tag_data, name, name_len) == 0) { + asn1_ctx_t ctxi, ef_tag = { 0 }; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + if (file_has_data(ef) && asn1_find_tag(&ctxi, TAG_NAME, &ef_tag) == true && ef_tag.len == name_len && memcmp(ef_tag.data, name, name_len) == 0) { return ef; } } @@ -136,30 +133,30 @@ int cmd_put() { if (validated == false) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - size_t key_len = 0, imf_len = 0, name_len = 0; - uint8_t *key = NULL, *imf = NULL, *name = NULL; - if (asn1_find_tag(apdu.data, apdu.nc, TAG_KEY, &key_len, &key) == false) { + asn1_ctx_t ctxi, key = { 0 }, name = { 0 }, imf = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) { return SW_INCORRECT_PARAMS(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_NAME, &name_len, &name) == false) { + if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) { return SW_INCORRECT_PARAMS(); } - if ((key[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { - if (asn1_find_tag(apdu.data, apdu.nc, TAG_IMF, &imf_len, &imf) == false) { + if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { + if (asn1_find_tag(&ctxi, TAG_IMF, &imf) == false) { memcpy(apdu.data + apdu.nc, "\x7a\x08\x00\x00\x00\x00\x00\x00\x00\x00", 10); apdu.nc += 10; } else { //prepend zero-valued bytes - if (imf_len < 8) { - memmove(imf + (8 - imf_len), imf, imf_len); - memset(imf, 0, 8 - imf_len); - *(imf - 1) = 8; - apdu.nc += (8 - imf_len); + if (imf.len < 8) { + memmove(imf.data + (8 - imf.len), imf.data, imf.len); + memset(imf.data, 0, 8 - imf.len); + *(imf.data - 1) = 8; + apdu.nc += (8 - imf.len); } } } - file_t *ef = find_oath_cred(name, name_len); + file_t *ef = find_oath_cred(name.data, name.len); if (file_has_data(ef)) { flash_write_data_to_file(ef, apdu.data, apdu.nc); low_flash_available(); @@ -181,13 +178,13 @@ int cmd_put() { int cmd_delete() { - size_t tag_len = 0; - uint8_t *tag_data = NULL; if (validated == false) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_NAME, &tag_len, &tag_data) == true) { - file_t *ef = find_oath_cred(tag_data, tag_len); + asn1_ctx_t ctxi, ctxo = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_NAME, &ctxo) == true) { + file_t *ef = find_oath_cred(ctxo.data, ctxo.len); if (ef) { delete_file(ef); return SW_OK(); @@ -219,38 +216,38 @@ int cmd_set_code() { validated = true; return SW_OK(); } - size_t key_len = 0, chal_len = 0, resp_len = 0; - uint8_t *key = NULL, *chal = NULL, *resp = NULL; - if (asn1_find_tag(apdu.data, apdu.nc, TAG_KEY, &key_len, &key) == false) { + asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_KEY, &key) == false) { return SW_INCORRECT_PARAMS(); } - if (key_len == 0) { + if (key.len == 0) { delete_file(search_dynamic_file(EF_OATH_CODE)); validated = true; return SW_OK(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_CHALLENGE, &chal_len, &chal) == false) { + if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) { return SW_INCORRECT_PARAMS(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_RESPONSE, &resp_len, &resp) == false) { + if (asn1_find_tag(&ctxi, TAG_RESPONSE, &resp) == false) { return SW_INCORRECT_PARAMS(); } - const mbedtls_md_info_t *md_info = get_oath_md_info(key[0]); + const mbedtls_md_info_t *md_info = get_oath_md_info(key.data[0]); if (md_info == NULL) { return SW_INCORRECT_PARAMS(); } uint8_t hmac[64]; - int r = mbedtls_md_hmac(md_info, key + 1, key_len - 1, chal, chal_len, hmac); + int r = mbedtls_md_hmac(md_info, key.data + 1, key.len - 1, chal.data, chal.len, hmac); if (r != 0) { return SW_EXEC_ERROR(); } - if (memcmp(hmac, resp, resp_len) != 0) { + if (memcmp(hmac, resp.data, resp.len) != 0) { return SW_DATA_INVALID(); } random_gen(NULL, challenge, sizeof(challenge)); file_t *ef = file_new(EF_OATH_CODE); - flash_write_data_to_file(ef, key, key_len); + flash_write_data_to_file(ef, key.data, key.len); low_flash_available(); validated = false; return SW_OK(); @@ -274,23 +271,19 @@ int cmd_reset() { } int cmd_list() { - size_t name_len = 0, key_len = 0; - uint8_t *name = NULL, *key = NULL; if (validated == false) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } for (int i = 0; i < MAX_OATH_CRED; i++) { file_t *ef = search_dynamic_file(EF_OATH_CRED + i); if (file_has_data(ef)) { - uint8_t *data = file_get_data(ef); - size_t data_len = file_get_size(ef); - if (asn1_find_tag(data, data_len, TAG_NAME, &name_len, - &name) == true && - asn1_find_tag(data, data_len, TAG_KEY, &key_len, &key) == true) { + asn1_ctx_t ctxi, key = { 0 }, name = { 0 }; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + if (asn1_find_tag(&ctxi, TAG_NAME, &name) == true && asn1_find_tag(&ctxi, TAG_KEY, &key) == true) { res_APDU[res_APDU_size++] = TAG_NAME_LIST; - res_APDU[res_APDU_size++] = name_len + 1; - res_APDU[res_APDU_size++] = key[0]; - memcpy(res_APDU + res_APDU_size, name, name_len); res_APDU_size += name_len; + res_APDU[res_APDU_size++] = name.len + 1; + res_APDU[res_APDU_size++] = key.data[0]; + memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len; } } } @@ -299,12 +292,12 @@ int cmd_list() { } int cmd_validate() { - size_t chal_len = 0, resp_len = 0, key_len = 0; - uint8_t *chal = NULL, *resp = NULL, *key = NULL; - if (asn1_find_tag(apdu.data, apdu.nc, TAG_CHALLENGE, &chal_len, &chal) == false) { + asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, resp = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) { return SW_INCORRECT_PARAMS(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_RESPONSE, &resp_len, &resp) == false) { + if (asn1_find_tag(&ctxi, TAG_RESPONSE, &resp) == false) { return SW_INCORRECT_PARAMS(); } file_t *ef = search_dynamic_file(EF_OATH_CODE); @@ -312,21 +305,21 @@ int cmd_validate() { validated = true; return SW_DATA_INVALID(); } - key = file_get_data(ef); - key_len = file_get_size(ef); - const mbedtls_md_info_t *md_info = get_oath_md_info(key[0]); + key.data = file_get_data(ef); + key.len = file_get_size(ef); + const mbedtls_md_info_t *md_info = get_oath_md_info(key.data[0]); if (md_info == NULL) { return SW_INCORRECT_PARAMS(); } uint8_t hmac[64]; - int ret = mbedtls_md_hmac(md_info, key + 1, key_len - 1, challenge, sizeof(challenge), hmac); + int ret = mbedtls_md_hmac(md_info, key.data + 1, key.len - 1, challenge, sizeof(challenge), hmac); if (ret != 0) { return SW_EXEC_ERROR(); } - if (memcmp(hmac, resp, resp_len) != 0) { + if (memcmp(hmac, resp.data, resp.len) != 0) { return SW_DATA_INVALID(); } - ret = mbedtls_md_hmac(md_info, key + 1, key_len - 1, chal, chal_len, hmac); + ret = mbedtls_md_hmac(md_info, key.data + 1, key.len - 1, chal.data, chal.len, hmac); if (ret != 0) { return SW_EXEC_ERROR(); } @@ -373,67 +366,69 @@ int calculate_oath(uint8_t truncate, } int cmd_calculate() { - size_t chal_len = 0, name_len = 0, key_len = 0; - uint8_t *chal = NULL, *name = NULL, *key = NULL; if (P2(apdu) != 0x0 && P2(apdu) != 0x1) { return SW_INCORRECT_P1P2(); } if (validated == false) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_CHALLENGE, &chal_len, &chal) == false) { + asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) { return SW_INCORRECT_PARAMS(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_NAME, &name_len, &name) == false) { + if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) { return SW_INCORRECT_PARAMS(); } - file_t *ef = find_oath_cred(name, name_len); + file_t *ef = find_oath_cred(name.data, name.len); if (file_has_data(ef) == false) { return SW_DATA_INVALID(); } - - if (asn1_find_tag(file_get_data(ef), file_get_size(ef), TAG_KEY, &key_len, &key) == false) { + asn1_ctx_t ctxe; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + if (asn1_find_tag(&ctxe, TAG_KEY, &key) == false) { return SW_INCORRECT_PARAMS(); } - if ((key[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { - if (asn1_find_tag(file_get_data(ef), file_get_size(ef), TAG_IMF, &chal_len, - &chal) == false) { + if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { + if (asn1_find_tag(&ctxe, TAG_IMF, &chal) == false) { return SW_INCORRECT_PARAMS(); } } res_APDU[res_APDU_size++] = TAG_RESPONSE + P2(apdu); - int ret = calculate_oath(P2(apdu), key, key_len, chal, chal_len); + int ret = calculate_oath(P2(apdu), key.data, key.len, chal.data, chal.len); if (ret != CCID_OK) { return SW_EXEC_ERROR(); } - if ((key[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { + if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { uint64_t v = - ((uint64_t) chal[0] << + ((uint64_t) chal.data[0] << 56) | - ((uint64_t) chal[1] << + ((uint64_t) chal.data[1] << 48) | - ((uint64_t) chal[2] << + ((uint64_t) chal.data[2] << 40) | - ((uint64_t) chal[3] << + ((uint64_t) chal.data[3] << 32) | - ((uint64_t) chal[4] << - 24) | ((uint64_t) chal[5] << 16) | ((uint64_t) chal[6] << 8) | (uint64_t) chal[7]; + ((uint64_t) chal.data[4] << + 24) | ((uint64_t) chal.data[5] << 16) | ((uint64_t) chal.data[6] << 8) | (uint64_t) chal.data[7]; size_t ef_size = file_get_size(ef); v++; uint8_t *tmp = (uint8_t *) calloc(1, ef_size); memcpy(tmp, file_get_data(ef), ef_size); - asn1_find_tag(tmp, ef_size, TAG_IMF, &chal_len, &chal); - chal[0] = v >> 56; - chal[1] = v >> 48; - chal[2] = v >> 40; - chal[3] = v >> 32; - chal[4] = v >> 24; - chal[5] = v >> 16; - chal[6] = v >> 8; - chal[7] = v & 0xff; + asn1_ctx_t ctxt; + asn1_ctx_init(tmp, ef_size, &ctxt); + asn1_find_tag(&ctxt, TAG_IMF, &chal); + chal.data[0] = v >> 56; + chal.data[1] = v >> 48; + chal.data[2] = v >> 40; + chal.data[3] = v >> 32; + chal.data[4] = v >> 24; + chal.data[5] = v >> 16; + chal.data[6] = v >> 8; + chal.data[7] = v & 0xff; flash_write_data_to_file(ef, tmp, ef_size); low_flash_available(); free(tmp); @@ -443,15 +438,15 @@ int cmd_calculate() { } int cmd_calculate_all() { - size_t chal_len = 0, name_len = 0, key_len = 0, prop_len = 0; - uint8_t *chal = NULL, *name = NULL, *key = NULL, *prop = NULL; + asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, prop = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); if (P2(apdu) != 0x0 && P2(apdu) != 0x1) { return SW_INCORRECT_P1P2(); } if (validated == false) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_CHALLENGE, &chal_len, &chal) == false) { + if (asn1_find_tag(&ctxi, TAG_CHALLENGE, &chal) == false) { return SW_INCORRECT_PARAMS(); } res_APDU_size = 0; @@ -460,31 +455,30 @@ int cmd_calculate_all() { if (file_has_data(ef)) { const uint8_t *ef_data = file_get_data(ef); size_t ef_len = file_get_size(ef); - if (asn1_find_tag(ef_data, ef_len, TAG_NAME, &name_len, - &name) == false || - asn1_find_tag(ef_data, ef_len, TAG_KEY, &key_len, &key) == false) { + asn1_ctx_t ctxe; + asn1_ctx_init((uint8_t *)ef_data, ef_len, &ctxe); + if (asn1_find_tag(&ctxe, TAG_NAME, &name) == false || asn1_find_tag(&ctxe, TAG_KEY, &key) == false) { continue; } res_APDU[res_APDU_size++] = TAG_NAME; - res_APDU[res_APDU_size++] = name_len; - memcpy(res_APDU + res_APDU_size, name, name_len); res_APDU_size += name_len; - if ((key[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { + res_APDU[res_APDU_size++] = name.len; + memcpy(res_APDU + res_APDU_size, name.data, name.len); res_APDU_size += name.len; + if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { res_APDU[res_APDU_size++] = TAG_NO_RESPONSE; res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = key[1]; + res_APDU[res_APDU_size++] = key.data[1]; } - else if (asn1_find_tag(ef_data, ef_len, TAG_PROPERTY, &prop_len, - &prop) == true && (prop[0] & PROP_TOUCH)) { + else if (asn1_find_tag(&ctxe, TAG_PROPERTY, &prop) == true && (prop.data[0] & PROP_TOUCH)) { res_APDU[res_APDU_size++] = TAG_TOUCH_RESPONSE; res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = key[1]; + res_APDU[res_APDU_size++] = key.data[1]; } else { res_APDU[res_APDU_size++] = TAG_RESPONSE + P2(apdu); - int ret = calculate_oath(P2(apdu), key, key_len, chal, chal_len); + int ret = calculate_oath(P2(apdu), key.data, key.len, chal.data, chal.len); if (ret != CCID_OK) { res_APDU[res_APDU_size++] = 1; - res_APDU[res_APDU_size++] = key[1]; + res_APDU[res_APDU_size++] = key.data[1]; } } } @@ -498,57 +492,60 @@ int cmd_send_remaining() { } int cmd_set_otp_pin() { - size_t pw_len = 0; - uint8_t *pw = NULL, hsh[33] = { 0 }; + uint8_t hsh[33] = { 0 }; file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); if (file_has_data(ef_otp_pin)) { return SW_CONDITIONS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_PASSWORD, &pw_len, &pw) == false) { + asn1_ctx_t ctxi, pw = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) { return SW_INCORRECT_PARAMS(); } hsh[0] = MAX_OTP_COUNTER; - double_hash_pin(pw, pw_len, hsh + 1); + double_hash_pin(pw.data, pw.len, hsh + 1); flash_write_data_to_file(ef_otp_pin, hsh, sizeof(hsh)); low_flash_available(); return SW_OK(); } int cmd_change_otp_pin() { - size_t pw_len = 0, new_pw_len = 0; - uint8_t *pw = NULL, *new_pw = NULL, hsh[33] = { 0 }; + uint8_t hsh[33] = { 0 }; file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); if (!file_has_data(ef_otp_pin)) { return SW_CONDITIONS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_PASSWORD, &pw_len, &pw) == false) { + asn1_ctx_t ctxi, pw = { 0 }, new_pw = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) { return SW_INCORRECT_PARAMS(); } - double_hash_pin(pw, pw_len, hsh + 1); + double_hash_pin(pw.data, pw.len, hsh + 1); if (memcmp(file_get_data(ef_otp_pin) + 1, hsh + 1, 32) != 0) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_NEW_PASSWORD, &new_pw_len, &new_pw) == false) { + if (asn1_find_tag(&ctxi, TAG_NEW_PASSWORD, &new_pw) == false) { return SW_INCORRECT_PARAMS(); } hsh[0] = MAX_OTP_COUNTER; - double_hash_pin(new_pw, new_pw_len, hsh + 1); + double_hash_pin(new_pw.data, new_pw.len, hsh + 1); flash_write_data_to_file(ef_otp_pin, hsh, sizeof(hsh)); low_flash_available(); return SW_OK(); } int cmd_verify_otp_pin() { - size_t pw_len = 0; - uint8_t *pw = NULL, hsh[33] = { 0 }, data_hsh[33]; + uint8_t hsh[33] = { 0 }, data_hsh[33]; file_t *ef_otp_pin = search_by_fid(EF_OTP_PIN, NULL, SPECIFY_EF); if (!file_has_data(ef_otp_pin)) { return SW_CONDITIONS_NOT_SATISFIED(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_PASSWORD, &pw_len, &pw) == false) { + asn1_ctx_t ctxi, pw = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_PASSWORD, &pw) == false) { return SW_INCORRECT_PARAMS(); } - double_hash_pin(pw, pw_len, hsh + 1); + double_hash_pin(pw.data, pw.len, hsh + 1); memcpy(data_hsh, file_get_data(ef_otp_pin), sizeof(data_hsh)); if (data_hsh[0] == 0 || memcmp(data_hsh + 1, hsh + 1, 32) != 0) { if (data_hsh[0] > 0) { @@ -567,32 +564,33 @@ int cmd_verify_otp_pin() { } int cmd_verify_hotp() { - size_t key_len = 0, chal_len = 0, name_len = 0, code_len = 0; - uint8_t *key = NULL, *chal = NULL, *name = NULL, *code = NULL; + asn1_ctx_t ctxi, key = { 0 }, chal = { 0 }, name = { 0 }, code = { 0 }; + asn1_ctx_init(apdu.data, apdu.nc, &ctxi); uint32_t code_int = 0; - if (asn1_find_tag(apdu.data, apdu.nc, TAG_NAME, &name_len, &name) == false) { + if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) { return SW_INCORRECT_PARAMS(); } - file_t *ef = find_oath_cred(name, name_len); + file_t *ef = find_oath_cred(name.data, name.len); if (file_has_data(ef) == false) { return SW_DATA_INVALID(); } - if (asn1_find_tag(file_get_data(ef), file_get_size(ef), TAG_KEY, &key_len, &key) == false) { + asn1_ctx_t ctxe; + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxe); + if (asn1_find_tag(&ctxe, TAG_KEY, &key) == false) { return SW_INCORRECT_PARAMS(); } - if ((key[0] & OATH_TYPE_MASK) != OATH_TYPE_HOTP) { + if ((key.data[0] & OATH_TYPE_MASK) != OATH_TYPE_HOTP) { return SW_DATA_INVALID(); } - if (asn1_find_tag(file_get_data(ef), file_get_size(ef), TAG_IMF, &chal_len, - &chal) == false) { + if (asn1_find_tag(&ctxe, TAG_IMF, &chal) == false) { return SW_INCORRECT_PARAMS(); } - if (asn1_find_tag(apdu.data, apdu.nc, TAG_RESPONSE, &code_len, &code) == true) { - code_int = (code[0] << 24) | (code[1] << 16) | (code[2] << 8) | code[3]; + if (asn1_find_tag(&ctxi, TAG_RESPONSE, &code) == true) { + code_int = (code.data[0] << 24) | (code.data[1] << 16) | (code.data[2] << 8) | code.data[3]; } - int ret = calculate_oath(0x01, key, key_len, chal, chal_len); + int ret = calculate_oath(0x01, key.data, key.len, chal.data, chal.len); if (ret != CCID_OK) { return SW_EXEC_ERROR(); } From 82ed96b2e2ab096277cda6796a59b4045a165209 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 21:22:05 +0100 Subject: [PATCH 31/39] Fix asn1 struct initialization. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index e055d4c..151ae5f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit e055d4cfc9df1a41585ac83d484b903088f3db13 +Subproject commit 151ae5fae4c5815042fce5d5cbcc06d76561dc9c From f3f34cf66b19ba4c809f1b2e031ea5500e07700b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 22:06:00 +0100 Subject: [PATCH 32/39] Fix oath crash. Signed-off-by: Pol Henarejos --- src/fido/oath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fido/oath.c b/src/fido/oath.c index c2e942a..75c1ae7 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -385,7 +385,7 @@ int cmd_calculate() { return SW_DATA_INVALID(); } asn1_ctx_t ctxe; - asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi); + asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxe); if (asn1_find_tag(&ctxe, TAG_KEY, &key) == false) { return SW_INCORRECT_PARAMS(); } From 1f0e1fb8f4d723d859626dd80bf5245d5cc73fd0 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 5 May 2024 00:58:51 +0200 Subject: [PATCH 33/39] Use latest Pico Keys SDK. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_client_pin.c | 16 ++++++++-------- src/fido/cbor_config.c | 12 ++++++------ src/fido/cbor_cred_mgmt.c | 2 +- src/fido/cbor_get_assertion.c | 2 +- src/fido/cbor_large_blobs.c | 2 +- src/fido/cbor_make_credential.c | 2 +- src/fido/cbor_vendor.c | 8 ++++---- src/fido/cmd_authenticate.c | 2 +- src/fido/credential.c | 6 +++--- src/fido/fido.c | 12 ++++++------ src/fido/management.c | 2 +- src/fido/oath.c | 16 ++++++++-------- src/fido/otp.c | 14 +++++++------- 14 files changed, 49 insertions(+), 49 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 151ae5f..88071e1 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 151ae5fae4c5815042fce5d5cbcc06d76561dc9c +Subproject commit 88071e117222bbc3ab018bc45f6d691a4fcf78f3 diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index c7c13d8..0e3d6e9 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -169,7 +169,7 @@ int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret) { int resetPinUvAuthToken() { uint8_t t[32]; random_gen(NULL, t, sizeof(t)); - flash_write_data_to_file(ef_authtoken, t, sizeof(t)); + file_put_data(ef_authtoken, t, sizeof(t)); paut.permissions = 0; paut.data = file_get_data(ef_authtoken); paut.len = file_get_size(ef_authtoken); @@ -417,7 +417,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { hsh[0] = MAX_PIN_RETRIES; hsh[1] = pin_len; mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), paddedNewPin, pin_len, hsh + 2); - flash_write_data_to_file(ef_pin, hsh, 2 + 16); + file_put_data(ef_pin, hsh, 2 + 16); low_flash_available(); goto err; //No return } @@ -464,7 +464,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { uint8_t pin_data[18]; memcpy(pin_data, file_get_data(ef_pin), 18); pin_data[0] -= 1; - flash_write_data_to_file(ef_pin, pin_data, sizeof(pin_data)); + file_put_data(ef_pin, pin_data, sizeof(pin_data)); low_flash_available(); uint8_t retries = pin_data[0]; uint8_t paddedNewPin[64]; @@ -489,7 +489,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { } } pin_data[0] = MAX_PIN_RETRIES; - flash_write_data_to_file(ef_pin, pin_data, sizeof(pin_data)); + file_put_data(ef_pin, pin_data, sizeof(pin_data)); low_flash_available(); new_pin_mismatches = 0; ret = decrypt(pinUvAuthProtocol, sharedSecret, newPinEnc.data, newPinEnc.len, paddedNewPin); @@ -520,12 +520,12 @@ int cbor_client_pin(const uint8_t *data, size_t len) { memcmp(hsh + 2, file_get_data(ef_pin) + 2, 16) == 0) { CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION); } - flash_write_data_to_file(ef_pin, hsh, 2 + 16); + file_put_data(ef_pin, hsh, 2 + 16); if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) { uint8_t *tmp = (uint8_t *) calloc(1, file_get_size(ef_minpin)); memcpy(tmp, file_get_data(ef_minpin), file_get_size(ef_minpin)); tmp[1] = 0; - flash_write_data_to_file(ef_minpin, tmp, file_get_size(ef_minpin)); + file_put_data(ef_minpin, tmp, file_get_size(ef_minpin)); free(tmp); } low_flash_available(); @@ -573,7 +573,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { uint8_t pin_data[18]; memcpy(pin_data, file_get_data(ef_pin), 18); pin_data[0] -= 1; - flash_write_data_to_file(ef_pin, pin_data, sizeof(pin_data)); + file_put_data(ef_pin, pin_data, sizeof(pin_data)); low_flash_available(); uint8_t retries = pin_data[0]; uint8_t paddedNewPin[64], poff = (pinUvAuthProtocol - 1) * IV_SIZE; @@ -599,7 +599,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { } pin_data[0] = MAX_PIN_RETRIES; new_pin_mismatches = 0; - flash_write_data_to_file(ef_pin, pin_data, sizeof(pin_data)); + file_put_data(ef_pin, pin_data, sizeof(pin_data)); low_flash_available(); file_t *ef_minpin = search_by_fid(EF_MINPINLEN, NULL, SPECIFY_EF); if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) { diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index 4026cc7..b8cb73f 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -142,9 +142,9 @@ int cbor_config(const uint8_t *data, size_t len) { if (has_keydev_dec == false) { CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID); } - flash_write_data_to_file(ef_keydev, keydev_dec, sizeof(keydev_dec)); + file_put_data(ef_keydev, keydev_dec, sizeof(keydev_dec)); mbedtls_platform_zeroize(keydev_dec, sizeof(keydev_dec)); - flash_write_data_to_file(ef_keydev_enc, NULL, 0); // Set ef to 0 bytes + file_put_data(ef_keydev_enc, NULL, 0); // Set ef to 0 bytes low_flash_available(); } else if (vendorCommandId == CTAP_CONFIG_AUT_ENABLE) { @@ -178,10 +178,10 @@ int cbor_config(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); } - flash_write_data_to_file(ef_keydev_enc, key_dev_enc, sizeof(key_dev_enc)); + file_put_data(ef_keydev_enc, key_dev_enc, sizeof(key_dev_enc)); mbedtls_platform_zeroize(key_dev_enc, sizeof(key_dev_enc)); - flash_write_data_to_file(ef_keydev, key_dev_enc, file_get_size(ef_keydev)); // Overwrite ef with 0 - flash_write_data_to_file(ef_keydev, NULL, 0); // Set ef to 0 bytes + file_put_data(ef_keydev, key_dev_enc, file_get_size(ef_keydev)); // Overwrite ef with 0 + file_put_data(ef_keydev, NULL, 0); // Set ef to 0 bytes low_flash_available(); } else { @@ -216,7 +216,7 @@ int cbor_config(const uint8_t *data, size_t len) { data + 2 + m * 32, 0); } - flash_write_data_to_file(ef_minpin, data, 2 + minPinLengthRPIDs_len * 32); + file_put_data(ef_minpin, data, 2 + minPinLengthRPIDs_len * 32); low_flash_available(); goto err; //No return } diff --git a/src/fido/cbor_cred_mgmt.c b/src/fido/cbor_cred_mgmt.c index 68e95a8..f5b9fdd 100644 --- a/src/fido/cbor_cred_mgmt.c +++ b/src/fido/cbor_cred_mgmt.c @@ -380,7 +380,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { delete_file(rp_ef); } else { - flash_write_data_to_file(rp_ef, rp_data, file_get_size(rp_ef)); + file_put_data(rp_ef, rp_data, file_get_size(rp_ef)); } free(rp_data); break; diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index f3a2516..87c6363 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -640,7 +640,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); ctr++; - flash_write_data_to_file(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); + file_put_data(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); low_flash_available(); err: CBOR_FREE_BYTE_STRING(clientDataHash); diff --git a/src/fido/cbor_large_blobs.c b/src/fido/cbor_large_blobs.c index c3ebd70..432464d 100644 --- a/src/fido/cbor_large_blobs.c +++ b/src/fido/cbor_large_blobs.c @@ -155,7 +155,7 @@ int cbor_large_blobs(const uint8_t *data, size_t len) { if (expectedLength > 17 && memcmp(sha, temp_lba + expectedLength - 16, 16) != 0) { CBOR_ERROR(CTAP2_ERR_INTEGRITY_FAILURE); } - flash_write_data_to_file(ef_largeblob, temp_lba, expectedLength); + file_put_data(ef_largeblob, temp_lba, expectedLength); low_flash_available(); } goto err; diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 44a488f..614ae5a 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -518,7 +518,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { } } ctr++; - flash_write_data_to_file(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); + file_put_data(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); low_flash_available(); err: CBOR_FREE_BYTE_STRING(clientDataHash); diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index afe939b..d1b6f54 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -121,9 +121,9 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { } uint8_t zeros[32]; memset(zeros, 0, sizeof(zeros)); - flash_write_data_to_file(ef_keydev_enc, vendorParam.data, vendorParam.len); - flash_write_data_to_file(ef_keydev, zeros, file_get_size(ef_keydev)); // Overwrite ef with 0 - flash_write_data_to_file(ef_keydev, NULL, 0); // Set ef to 0 bytes + file_put_data(ef_keydev_enc, vendorParam.data, vendorParam.len); + file_put_data(ef_keydev, zeros, file_get_size(ef_keydev)); // Overwrite ef with 0 + file_put_data(ef_keydev, NULL, 0); // Set ef to 0 bytes low_flash_available(); goto err; } @@ -306,7 +306,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { } file_t *ef_ee_ea = search_by_fid(EF_EE_DEV_EA, NULL, SPECIFY_EF); if (ef_ee_ea) { - flash_write_data_to_file(ef_ee_ea, vendorParam.data, vendorParam.len); + file_put_data(ef_ee_ea, vendorParam.data, vendorParam.len); } low_flash_available(); goto err; diff --git a/src/fido/cmd_authenticate.c b/src/fido/cmd_authenticate.c index 6f458d6..b3c7f9d 100644 --- a/src/fido/cmd_authenticate.c +++ b/src/fido/cmd_authenticate.c @@ -97,7 +97,7 @@ int cmd_authenticate() { res_APDU_size = 1 + 4 + olen; ctr++; - flash_write_data_to_file(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); + file_put_data(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); low_flash_available(); return SW_OK(); } diff --git a/src/fido/credential.c b/src/fido/credential.c index b43388b..ea44ebb 100644 --- a/src/fido/credential.c +++ b/src/fido/credential.c @@ -306,7 +306,7 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t * memcpy(data, rp_id_hash, 32); memcpy(data + 32, cred_id, cred_id_len); file_t *ef = file_new(EF_CRED + sloti); - flash_write_data_to_file(ef, data, cred_id_len + 32); + file_put_data(ef, data, cred_id_len + 32); free(data); if (new_record == true) { //increase rps @@ -332,7 +332,7 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t * data = (uint8_t *) calloc(1, file_get_size(ef)); memcpy(data, file_get_data(ef), file_get_size(ef)); data[0] += 1; - flash_write_data_to_file(ef, data, file_get_size(ef)); + file_put_data(ef, data, file_get_size(ef)); free(data); } else { @@ -341,7 +341,7 @@ int credential_store(const uint8_t *cred_id, size_t cred_id_len, const uint8_t * data[0] = 1; memcpy(data + 1, rp_id_hash, 32); memcpy(data + 1 + 32, cred.rpId.data, cred.rpId.len); - flash_write_data_to_file(ef, data, 1 + 32 + cred.rpId.len); + file_put_data(ef, data, 1 + 32 + cred.rpId.len); free(data); } } diff --git a/src/fido/fido.c b/src/fido/fido.c index 79a935d..e1ffbdb 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -317,7 +317,7 @@ int scan_files() { uint8_t kdata[32]; int key_size = mbedtls_mpi_size(&ecdsa.d); mbedtls_mpi_write_binary(&ecdsa.d, kdata, key_size); - ret = flash_write_data_to_file(ef_keydev, kdata, key_size); + ret = file_put_data(ef_keydev, kdata, key_size); mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_ecdsa_free(&ecdsa); if (ret != CCID_OK) { @@ -353,7 +353,7 @@ int scan_files() { if (ret <= 0) { return ret; } - flash_write_data_to_file(ef_certdev, cert + sizeof(cert) - ret, ret); + file_put_data(ef_certdev, cert + sizeof(cert) - ret, ret); } } else { @@ -363,7 +363,7 @@ int scan_files() { if (ef_counter) { if (!file_has_data(ef_counter)) { uint32_t v = 0; - flash_write_data_to_file(ef_counter, (uint8_t *) &v, sizeof(v)); + file_put_data(ef_counter, (uint8_t *) &v, sizeof(v)); } } else { @@ -375,7 +375,7 @@ int scan_files() { if (!file_has_data(ef_authtoken)) { uint8_t t[32]; random_gen(NULL, t, sizeof(t)); - flash_write_data_to_file(ef_authtoken, t, sizeof(t)); + file_put_data(ef_authtoken, t, sizeof(t)); } paut.data = file_get_data(ef_authtoken); paut.len = file_get_size(ef_authtoken); @@ -385,7 +385,7 @@ int scan_files() { } ef_largeblob = search_by_fid(EF_LARGEBLOB, NULL, SPECIFY_EF); if (!file_has_data(ef_largeblob)) { - flash_write_data_to_file(ef_largeblob, + file_put_data(ef_largeblob, (const uint8_t *) "\x80\x76\xbe\x8b\x52\x8d\x00\x75\xf7\xaa\xe9\x8d\x6f\xa5\x7a\x6d\x3c", 17); } @@ -447,7 +447,7 @@ uint8_t get_opts() { void set_opts(uint8_t opts) { file_t *ef = search_by_fid(EF_OPTS, NULL, SPECIFY_EF); - flash_write_data_to_file(ef, &opts, sizeof(uint8_t)); + file_put_data(ef, &opts, sizeof(uint8_t)); low_flash_available(); } diff --git a/src/fido/management.c b/src/fido/management.c index fb305c8..f7590d0 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -130,7 +130,7 @@ int cmd_write_config() { return SW_WRONG_DATA(); } file_t *ef = file_new(EF_DEV_CONF); - flash_write_data_to_file(ef, apdu.data + 1, apdu.nc - 1); + file_put_data(ef, apdu.data + 1, apdu.nc - 1); low_flash_available(); return SW_OK(); } diff --git a/src/fido/oath.c b/src/fido/oath.c index 75c1ae7..03ee790 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -158,7 +158,7 @@ int cmd_put() { } file_t *ef = find_oath_cred(name.data, name.len); if (file_has_data(ef)) { - flash_write_data_to_file(ef, apdu.data, apdu.nc); + file_put_data(ef, apdu.data, apdu.nc); low_flash_available(); } else { @@ -166,7 +166,7 @@ int cmd_put() { file_t *ef = search_dynamic_file(EF_OATH_CRED + i); if (!file_has_data(ef)) { ef = file_new(EF_OATH_CRED + i); - flash_write_data_to_file(ef, apdu.data, apdu.nc); + file_put_data(ef, apdu.data, apdu.nc); low_flash_available(); return SW_OK(); } @@ -247,7 +247,7 @@ int cmd_set_code() { } random_gen(NULL, challenge, sizeof(challenge)); file_t *ef = file_new(EF_OATH_CODE); - flash_write_data_to_file(ef, key.data, key.len); + file_put_data(ef, key.data, key.len); low_flash_available(); validated = false; return SW_OK(); @@ -429,7 +429,7 @@ int cmd_calculate() { chal.data[5] = v >> 16; chal.data[6] = v >> 8; chal.data[7] = v & 0xff; - flash_write_data_to_file(ef, tmp, ef_size); + file_put_data(ef, tmp, ef_size); low_flash_available(); free(tmp); } @@ -504,7 +504,7 @@ int cmd_set_otp_pin() { } hsh[0] = MAX_OTP_COUNTER; double_hash_pin(pw.data, pw.len, hsh + 1); - flash_write_data_to_file(ef_otp_pin, hsh, sizeof(hsh)); + file_put_data(ef_otp_pin, hsh, sizeof(hsh)); low_flash_available(); return SW_OK(); } @@ -529,7 +529,7 @@ int cmd_change_otp_pin() { } hsh[0] = MAX_OTP_COUNTER; double_hash_pin(new_pw.data, new_pw.len, hsh + 1); - flash_write_data_to_file(ef_otp_pin, hsh, sizeof(hsh)); + file_put_data(ef_otp_pin, hsh, sizeof(hsh)); low_flash_available(); return SW_OK(); } @@ -551,13 +551,13 @@ int cmd_verify_otp_pin() { if (data_hsh[0] > 0) { data_hsh[0] -= 1; } - flash_write_data_to_file(ef_otp_pin, data_hsh, sizeof(data_hsh)); + file_put_data(ef_otp_pin, data_hsh, sizeof(data_hsh)); low_flash_available(); validated = false; return SW_SECURITY_STATUS_NOT_SATISFIED(); } data_hsh[0] = MAX_OTP_COUNTER; - flash_write_data_to_file(ef_otp_pin, data_hsh, sizeof(data_hsh)); + file_put_data(ef_otp_pin, data_hsh, sizeof(data_hsh)); low_flash_available(); validated = true; return SW_OK(); diff --git a/src/fido/otp.c b/src/fido/otp.c index e37e779..7d5be77 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -169,7 +169,7 @@ void init_otp() { memcpy(new_data, data, sizeof(new_data)); new_data[otp_config_size] = counter >> 8; new_data[otp_config_size + 1] = counter & 0xff; - flash_write_data_to_file(ef, new_data, sizeof(new_data)); + file_put_data(ef, new_data, sizeof(new_data)); } } } @@ -258,7 +258,7 @@ int otp_button_pressed(uint8_t slot) { uint8_t new_otp_config[otp_config_size + sizeof(new_chal)]; memcpy(new_otp_config, otp_config, otp_config_size); memcpy(new_otp_config + otp_config_size, new_chal, sizeof(new_chal)); - flash_write_data_to_file(ef, new_otp_config, sizeof(new_otp_config)); + file_put_data(ef, new_otp_config, sizeof(new_otp_config)); low_flash_available(); } if (otp_config->tkt_flags & APPEND_CR) { @@ -322,7 +322,7 @@ int otp_button_pressed(uint8_t slot) { memcpy(new_data, data, sizeof(new_data)); new_data[otp_config_size] = counter >> 8; new_data[otp_config_size + 1] = counter & 0xff; - flash_write_data_to_file(ef, new_data, sizeof(new_data)); + file_put_data(ef, new_data, sizeof(new_data)); low_flash_available(); } } @@ -387,7 +387,7 @@ int cmd_otp() { return SW_WRONG_DATA(); } memset(apdu.data + otp_config_size, 0, 8); // Add 8 bytes extra - flash_write_data_to_file(ef, apdu.data, otp_config_size + 8); + file_put_data(ef, apdu.data, otp_config_size + 8); low_flash_available(); config_seq++; return otp_status(); @@ -420,7 +420,7 @@ int cmd_otp() { (odata->tkt_flags & TKTFLAG_UPDATE_MASK); odata->cfg_flags = (otpc->cfg_flags & ~CFGFLAG_UPDATE_MASK) | (odata->cfg_flags & CFGFLAG_UPDATE_MASK); - flash_write_data_to_file(ef, apdu.data, otp_config_size); + file_put_data(ef, apdu.data, otp_config_size); low_flash_available(); } } @@ -434,13 +434,13 @@ int cmd_otp() { ef1_data = true; } if (file_has_data(ef2)) { - flash_write_data_to_file(ef1, file_get_data(ef2), file_get_size(ef2)); + file_put_data(ef1, file_get_data(ef2), file_get_size(ef2)); } else { delete_file(ef1); } if (ef1_data) { - flash_write_data_to_file(ef2, tmp, sizeof(tmp)); + file_put_data(ef2, tmp, sizeof(tmp)); } else { delete_file(ef2); From b0b0187919409858e0d03bfca59cd40bd0e769a1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 7 Jun 2024 20:57:21 +0200 Subject: [PATCH 34/39] Fix cleared permissions on make credential when UP is not present. Following 14.1, flags shall be cleared only when UP == true. Signed-off-by: Pol Henarejos --- src/fido/cbor_make_credential.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 614ae5a..4de194a 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -313,9 +313,11 @@ int cbor_make_credential(const uint8_t *data, size_t len) { } } flags |= FIDO2_AUT_FLAG_UP; - clearUserPresentFlag(); - clearUserVerifiedFlag(); - clearPinUvAuthTokenPermissionsExceptLbw(); + if (options.up == ptrue) { + clearUserPresentFlag(); + clearUserVerifiedFlag(); + clearPinUvAuthTokenPermissionsExceptLbw(); + } } const known_app_t *ka = find_app_by_rp_id_hash(rp_id_hash); From 54bbc0e9ea83510bcdf48e3fc61c21180a1882fe Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 30 Jun 2024 00:31:29 +0200 Subject: [PATCH 35/39] Fix return value when bad key type is provided. Fixes #47. Signed-off-by: Pol Henarejos --- src/fido/cbor_make_credential.c | 6 +++--- tests/pico-fido/test_020_register.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 4de194a..33ccc98 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -225,9 +225,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) { else if (pubKeyCredParams[i].alg <= FIDO2_ALG_RS256 && pubKeyCredParams[i].alg >= FIDO2_ALG_RS512) { // pass } - else { - CBOR_ERROR(CTAP2_ERR_CBOR_UNEXPECTED_TYPE); - } + //else { + // CBOR_ERROR(CTAP2_ERR_CBOR_UNEXPECTED_TYPE); + //} if (curve > 0 && alg == 0) { alg = pubKeyCredParams[i].alg; } diff --git a/tests/pico-fido/test_020_register.py b/tests/pico-fido/test_020_register.py index 378a13e..3a80e7d 100644 --- a/tests/pico-fido/test_020_register.py +++ b/tests/pico-fido/test_020_register.py @@ -151,7 +151,7 @@ def test_unsupported_algorithm(device): with pytest.raises(CtapError) as e: device.doMC(key_params=[{"alg": 1337, "type": "public-key"}]) - assert e.value.code == CtapError.ERR.CBOR_UNEXPECTED_TYPE + assert e.value.code == CtapError.ERR.UNSUPPORTED_ALGORITHM def test_exclude_list(resetdevice): resetdevice.doMC(exclude_list=[{"id": b"1234", "type": "rot13"}]) From d5fe405a878075162afe2449325cffcface7b5da Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 30 Jun 2024 00:32:40 +0200 Subject: [PATCH 36/39] Fix test bad pub type. Signed-off-by: Pol Henarejos --- tests/pico-fido/test_020_register.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/pico-fido/test_020_register.py b/tests/pico-fido/test_020_register.py index 3a80e7d..bbb2dd1 100644 --- a/tests/pico-fido/test_020_register.py +++ b/tests/pico-fido/test_020_register.py @@ -147,6 +147,8 @@ def test_bad_type_pubKeyCredParams_alg(device): with pytest.raises(CtapError) as e: device.doMC(key_params=[{"alg": "7", "type": "public-key"}]) + assert e.value.code == CtapError.ERR.CBOR_UNEXPECTED_TYPE + def test_unsupported_algorithm(device): with pytest.raises(CtapError) as e: device.doMC(key_params=[{"alg": 1337, "type": "public-key"}]) From 6fe16a63e490dbb5f8150bf7e8bd2e2939ab6b3d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 20 Jul 2024 20:04:41 +0200 Subject: [PATCH 37/39] Upgrade Pico Keys SDK Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 88071e1..f4ad8e1 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 88071e117222bbc3ab018bc45f6d691a4fcf78f3 +Subproject commit f4ad8e1af2e2657f3900f1e01db031d7d73d623b From e96da09a844be4785152861bcb305b454cb1524e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 20 Jul 2024 20:04:48 +0200 Subject: [PATCH 38/39] Fixes for mbedtls 3.6 Signed-off-by: Pol Henarejos --- src/fido/fido.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fido/fido.c b/src/fido/fido.c index e1ffbdb..1adf712 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -215,7 +215,8 @@ int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_con } } uint8_t hmac[32], d[32]; - int ret = mbedtls_ecp_write_key(key, d, sizeof(d)); + size_t olen = 0; + int ret = mbedtls_ecp_write_key_ext(key, &olen, d, sizeof(d)); if (key == NULL) { mbedtls_ecdsa_free(&ctx); } From f21e2030939e01076d8445d38d74bdc1659d4f10 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 20 Jul 2024 20:05:00 +0200 Subject: [PATCH 39/39] Fix compilation Signed-off-by: Pol Henarejos --- src/fido/otp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fido/otp.c b/src/fido/otp.c index 7d5be77..daee316 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -23,6 +23,7 @@ #include "version.h" #include "asn1.h" #include "hid/ctap_hid.h" +#include "usb.h" #ifndef ENABLE_EMULATION #include "bsp/board.h" #endif