From 8056e64cabbcfcd0612ed75e56e5164c9f7b616c Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Wed, 8 Nov 2023 13:56:37 +0100 Subject: [PATCH 01/50] Update pico-fido-patch-vidpid.sh Match any previous VID:PID in the image and replace with the new ones. --- pico-fido-patch-vidpid.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-fido-patch-vidpid.sh b/pico-fido-patch-vidpid.sh index 7715a60..b61bc83 100755 --- a/pico-fido-patch-vidpid.sh +++ b/pico-fido-patch-vidpid.sh @@ -87,7 +87,7 @@ fi LITTLE_VID="\x${VID:2:2}\x${VID:0:2}" LITTLE_PID="\x${PID:2:2}\x${PID:0:2}" -perl -pi -e "s/\xfe\xca\x31\x42\x$VERSION_MINOR\x$VERSION_MAJOR\x01\x02\x03\x01/$LITTLE_VID$LITTLE_PID\x$VERSION_MINOR\x$VERSION_MAJOR\x01\x02\x03\x01/" $UF2_FILE_OF +perl -pi -e "s/[\x00-\xff]{4}\x$VERSION_MINOR\x$VERSION_MAJOR\x01\x02\x03\x01\x00\x00/$LITTLE_VID$LITTLE_PID\x$VERSION_MINOR\x$VERSION_MAJOR\x01\x02\x03\x01\x00\x00/" $UF2_FILE_OF echo "Done!" echo "" From 041bb788f9b44305034e4ee3a68edb6bc8a35a8e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 18 Sep 2023 10:13:06 +0200 Subject: [PATCH 02/50] 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 b99181a00c6d0d5ad863578f2abb73a7446be8c8 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 18 Sep 2023 10:39:21 +0200 Subject: [PATCH 03/50] 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 011429a98263b5cb1118c8a9af3ba81ad20632bb Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:51:36 +0200 Subject: [PATCH 04/50] 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 849221fd9507ed89ce2ed851ffa74aaa50b8444b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:52:07 +0200 Subject: [PATCH 05/50] 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 28e979939af01c739e5a4868e81d965d299c4c9a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:53:06 +0200 Subject: [PATCH 06/50] 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 599fd706ce7806e5184898bfb8a16d0b61b5bcdf Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 28 Oct 2023 20:57:53 +0200 Subject: [PATCH 07/50] 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 4fd4d75e21c30f5e839b5e984b1a03fbfc374b56 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 30 Oct 2023 16:51:56 +0100 Subject: [PATCH 08/50] 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 68b5614fb91103271c91cfc70a6b1858cf336476 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 31 Oct 2023 00:40:56 +0100 Subject: [PATCH 09/50] 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 ba57cc4527db7348fa9407778e41fa31b98b2ad9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 31 Oct 2023 17:35:59 +0100 Subject: [PATCH 10/50] 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 01a6c9f77fc99fa6f3afa396dc45fc52403195c2 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 09:32:19 +0100 Subject: [PATCH 11/50] 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 19197e54a8623cf87cff6ce4a9aaa6c6cdf2f6c3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 22:08:49 +0100 Subject: [PATCH 12/50] 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 0464ad89648893578c7237851f8d6e232d13f92a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 22:13:45 +0100 Subject: [PATCH 13/50] 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 85298062cdde54bdd165dc3f34eb371fe7c89185 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Nov 2023 22:14:42 +0100 Subject: [PATCH 14/50] 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 04238509ee42d774d7fbd66b3d75382de4330078 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:48:32 +0100 Subject: [PATCH 15/50] 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 cf152c16929fdcac169a506764fd969d6e7a5d88 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:49:18 +0100 Subject: [PATCH 16/50] 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 5c6f87ab8fa78cf5125fa31afbeb214428bfc954 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:49:42 +0100 Subject: [PATCH 17/50] 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 a0f1d2334de665f15ec0c7971c6f556443e4c264 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 11:57:08 +0100 Subject: [PATCH 18/50] 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 779db90713dc07d56932ae91ee73311f278cfe49 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 13:01:10 +0100 Subject: [PATCH 19/50] 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 6157a91fdf1e9368d251a54c7471453e255602ee Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 14:27:57 +0100 Subject: [PATCH 20/50] 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 107e5c34db7cdd55f1d7487730dd79e455acae6a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 14:28:09 +0100 Subject: [PATCH 21/50] 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 bef1922c8f33db365e72bb6ab3b732b1319fe416 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 15:22:28 +0100 Subject: [PATCH 22/50] 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 0b00e0118795b4861684bf148eb074b0cf7850e9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 6 Nov 2023 15:32:25 +0100 Subject: [PATCH 23/50] 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 d985cf6301f4ccd76655f97434d1d06669655942 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 16 Nov 2023 20:12:01 +0100 Subject: [PATCH 24/50] 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 34bfc3b2ef8ddb7120bd5de57f8e5ae802d46ab9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 16 Nov 2023 20:12:48 +0100 Subject: [PATCH 25/50] 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 a9be759da335c44304bc2a9b7f3f81e54c8d264b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 16 Nov 2023 20:16:23 +0100 Subject: [PATCH 26/50] 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 1d9107d4bb46d3261914d77d4f9aa649f021a3ed Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 21 Nov 2023 11:42:27 +0100 Subject: [PATCH 27/50] 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 e54df525c48ccbfba78bcfbe3f956693c3d94d0d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 21 Nov 2023 11:53:47 +0100 Subject: [PATCH 28/50] 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 7e2ecdbc5659fb4de39b848503d759e39d85d573 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 21 Nov 2023 12:01:47 +0100 Subject: [PATCH 29/50] 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 30/50] 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 31/50] 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 32/50] 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 33/50] 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 34/50] 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 35/50] 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 36/50] 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 37/50] 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 38/50] 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 39/50] 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 40/50] 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 From 69ec24209527a2ba0cad3f14989b92dea8f4ed14 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 20 Jul 2024 20:28:09 +0200 Subject: [PATCH 41/50] Update README. Signed-off-by: Pol Henarejos --- README.md | 75 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index e9b5963..cc97fae 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Pico FIDO -This project aims at transforming your Raspberry Pico into a FIDO key integrated. The Pico works as a FIDO key, like a normal USB key for authentication. +This project transforms your Raspberry Pi Pico into an integrated FIDO key, functioning like a standard USB key for authentication. ## Features -Pico FIDO has implemented the following features: +Pico FIDO includes the following features: - CTAP 2.1 / CTAP 1 - WebAuthn @@ -10,16 +10,16 @@ Pico FIDO has implemented the following features: - HMAC-Secret extension - CredProtect extension - User presence enforcement through physical button -- User Verification with PIN +- User verification with PIN - Discoverable credentials - Credential management - ECDSA authentication -- Authentication with SECP256R1, SECP384R1, SECP521R1 and SECP256K1 curves. +- Support for SECP256R1, SECP384R1, SECP521R1, and SECP256K1 curves - App registration and login - Device selection -- Support for vendor Config +- Support for vendor configuration - Backup with 24 words -- Secure lock to protect the device from flash dumpings +- Secure lock to protect the device from flash dumps - Permissions support (MC, GA, CM, ACFG, LBW) - Authenticator configuration - minPinLength extension @@ -27,50 +27,54 @@ Pico FIDO has implemented the following features: - Enterprise attestation - credBlobs extension - largeBlobKey extension -- largeBlobs support (2048 bytes máx.) +- Large blobs support (2048 bytes max) - OATH (based on YKOATH protocol specification) - TOTP / HOTP - Yubikey OTP - Challenge-response generation - Emulated keyboard interface -- Button press generates an OTP that is written directly is it was typed +- Button press generates an OTP that is directly typed - Yubico YKMAN compatible - Nitrokey nitropy and nitroapp compatible -All these features are compliant with the specification. Therefore, if you detect some behaviour that is not expected or it does not follow the rules of specs, please open an issue. +All features comply with the specifications. If you encounter unexpected behavior or deviations from the specifications, please open an issue. -## Security considerations -Pico FIDO is an open platform so be careful. The contents in the flash memory may be easily dumpled and obtain the private/master keys. Therefore, it is not possible to encrypt the content. At least, one key (the master, the supreme key) must be stored in clear text. +## Security Considerations -If the Pico is stolen the contents of private and secret keys can be read. +Pico FIDO is an open platform, so exercise caution. The flash memory contents can be easily dumped, potentially revealing private/master keys. It is not feasible to encrypt the content, meaning at least one key (the master key) must be stored in clear text. + +If the Pico is stolen, the private and secret keys can be accessed. ## Download -Please, go to the [Release page](https://github.com/polhenarejos/pico-fido/releases "Release page") and download the UF2 file for your board. +Please visit the [Release page](https://github.com/polhenarejos/pico-fido/releases "Release page") to download the UF2 file for your board. -Note that UF2 files are shiped with a dummy VID/PID to avoid license issues (FEFF:FCFD). If you are planning to use it with OpenSC or similar, you should modify Info.plist of CCID driver to add these VID/PID or use the [Pico Patcher tool](https://www.picokeys.com/pico-patcher/). +Note that UF2 files are shipped with a dummy VID/PID to avoid license issues (FEFF:FCFD). If you plan to use it with OpenSC or similar software, you will need to modify the Info.plist of the CCID driver to add these VID/PID values or use the [Pico Patcher tool](https://www.picokeys.com/pico-patcher/). -Alternatively you can use the legacy VID/PID patcher as follows: -`./patch_vidpid.sh VID:PID input_hsm_file.uf2 output_hsm_file.uf2` +Alternatively, you can use the legacy VID/PID patcher with the following command: +```sh +./patch_vidpid.sh VID:PID input_hsm_file.uf2 output_hsm_file.uf2 +``` +You can use any VID/PID (e.g., 234b:0000 from FISJ), but remember that you are not authorized to distribute the binary with a VID/PID that you do not own. -You can use whatever VID/PID (i.e., 234b:0000 from FISJ), but remember that you are not authorized to distribute the binary with a VID/PID that you do not own. - -Note that the pure-browser option [Pico Patcher tool](https://www.picokeys.com/pico-patcher/) is the most recommended. +For ease of use, the pure-browser option [Pico Patcher tool](https://www.picokeys.com/pico-patcher/) is highly recommended. ## Build -Before building, ensure you have installed the toolchain for the Pico and the Pico SDK is properly located in your drive. +Before building, ensure you have installed the toolchain for the Pico and that the Pico SDK is properly located on your drive. - git clone https://github.com/polhenarejos/pico-fido - cd pico-fido - mkdir build - cd build - PICO_SDK_PATH=/path/to/pico-sdk cmake .. -DPICO_BOARD=board_type -DUSB_VID=0x1234 -DUSB_PID=0x5678 - make +```sh +git clone https://github.com/polhenarejos/pico-fido +cd pico-fido +mkdir build +cd build +PICO_SDK_PATH=/path/to/pico-sdk cmake .. -DPICO_BOARD=board_type -DUSB_VID=0x1234 -DUSB_PID=0x5678 +make +``` -Note that PICO_BOARD, USB_VID and USB_PID are optional. If not provided, pico board and VID/PID FEFF:FCFD will be used. +Note that `PICO_BOARD`, `USB_VID`, and `USB_PID` are optional. If not provided, the default Pico board and VID/PID `FEFF:FCFD` will be used. -After make ends, the binary file pico_fido.uf2 will be generated. Put your pico board into loading mode, by pushing BOOTSEL button while pluging on, and copy the UF2 to the new fresh usb mass storage Pico device. Once copied, the pico mass storage will be disconnected automatically and the pico board will reset with the new firmware. A blinking led will indicate the device is ready to work. +After `make` finishes, the binary file `pico_fido.uf2` will be generated. Put your Pico board into loading mode by holding the BOOTSEL button while plugging it in, then copy the UF2 file to the new USB mass storage Pico device. Once copied, the Pico mass storage will disconnect automatically, and the Pico board will reset with the new firmware. A blinking LED will indicate that the device is ready to work. -**Remark:** Pico Fido uses HID interface and thus, VID/PID values are irrelevant in terms of operativity. You can safely use any arbitrary value or the default ones. +**Remark:** Pico FIDO uses the HID interface, so VID/PID values are irrelevant in terms of operativity. You can safely use any arbitrary values or the default ones. ## Led blink Pico FIDO uses the led to indicate the current status. Four states are available: @@ -96,20 +100,21 @@ While processing, the Pico FIDO is busy and cannot receive additional commands u ## Driver -Pico FIDO uses the `HID` driver, present in all OS. It should be detected by all OS and browser/applications, like normal USB FIDO keys. +Pico FIDO uses the `HID` driver, which is present in all operating systems. It should be detected by all OS and browser/applications just like normal USB FIDO keys. ## Tests -Tests can be found at `tests` folder. It is based on [FIDO2 tests](https://github.com/solokeys/fido2-tests "FIDO2 tests") from Solokeys, but adapted to [python-fido2](https://github.com/Yubico/python-fido2 "python-fido2") v1.0 package, which is a major refactor from previous 0.8 version and includes latests improvements from CTAP 2.1. +Tests can be found in the `tests` folder. They are based on [FIDO2 tests](https://github.com/solokeys/fido2-tests "FIDO2 tests") from Solokeys but adapted to the [python-fido2](https://github.com/Yubico/python-fido2 "python-fido2") v1.0 package, which is a major refactor from the previous 0.8 version and includes the latest improvements from CTAP 2.1. -All tests can be run by +To run all tests, use: -``` +```sh pytest ``` -or by selecting a subset with `-k ` flag: -``` +To run a subset of tests, use the `-k ` flag: + +```sh pytest -k test_credprotect ``` From 5b95e35ca9a38798cc0a90e9e295b2cba0a4c2a5 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 20 Jul 2024 20:29:40 +0200 Subject: [PATCH 42/50] Upgrade to version 5.10 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 04945c3..ed77b99 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -1,7 +1,7 @@ #!/bin/bash VERSION_MAJOR="5" -VERSION_MINOR="8" +VERSION_MINOR="10" rm -rf release/* cd build_release diff --git a/src/fido/version.h b/src/fido/version.h index 789f039..d700cdf 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 0x0508 +#define PICO_FIDO_VERSION 0x050A #define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff) #define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff) From 1b4dd9bed09452cc5fc201a5e4c879a01f943504 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 18 Aug 2024 23:53:18 +0200 Subject: [PATCH 43/50] Fix ESP32 build. Signed-off-by: Pol Henarejos --- src/fido/cbor.c | 7 +++- src/fido/cbor_client_pin.c | 6 ++- src/fido/cbor_get_assertion.c | 2 +- src/fido/cbor_reset.c | 5 ++- src/fido/cbor_vendor.c | 18 +------- src/fido/cmd_register.c | 2 +- src/fido/credential.c | 2 +- src/fido/ctap2_cbor.h | 4 ++ src/fido/fido.c | 17 ++++---- src/fido/fido.h | 9 +++- src/fido/management.c | 6 +-- src/fido/management.h | 2 +- src/fido/oath.c | 9 +--- src/fido/otp.c | 79 +++++++++++++++++------------------ 14 files changed, 83 insertions(+), 85 deletions(-) diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 9483d44..3dd7fc1 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #endif #include "hid/ctap_hid.h" @@ -130,6 +130,9 @@ void cbor_thread() { uint32_t flag = EV_EXEC_FINISHED; queue_add_blocking(&card_to_usb_q, &flag); } +#ifdef ESP_PLATFORM + vTaskDelete(NULL); +#endif } #endif @@ -139,7 +142,7 @@ int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len) { cmd = last_cmd; res_APDU = ctap_resp->init.data + 1; res_APDU_size = 0; - return 1; + return 2; // CBOR processing } CborError COSE_key_params(int crv, diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index 0e3d6e9..2d324da 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -15,7 +15,11 @@ * along with this program. If not, see . */ +#ifndef ESP_PLATFORM #include "common.h" +#else +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#endif #include "mbedtls/ecp.h" #include "mbedtls/ecdh.h" #include "mbedtls/sha256.h" @@ -23,7 +27,7 @@ #include "cbor.h" #include "ctap.h" #include "ctap2_cbor.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "bsp/board.h" #endif #include "hid/ctap_hid.h" diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index 87c6363..aa22e3b 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -17,7 +17,7 @@ #include "cbor.h" #include "ctap.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "bsp/board.h" #endif #include "hid/ctap_hid.h" diff --git a/src/fido/cbor_reset.c b/src/fido/cbor_reset.c index 62b17a9..b3a07d5 100644 --- a/src/fido/cbor_reset.c +++ b/src/fido/cbor_reset.c @@ -18,9 +18,12 @@ #include "file.h" #include "fido.h" #include "ctap.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "bsp/board.h" #endif +#ifdef ESP_PLATFORM +#include "esp_compat.h" +#endif extern void scan_all(); diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index d1b6f54..3b78c01 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -256,27 +256,11 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { mbedtls_ecdsa_free(&ekey); CBOR_ERROR(CTAP2_ERR_PROCESSING); } -#ifndef ENABLE_EMULATION - pico_unique_board_id_t rpiid; - pico_get_unique_board_id(&rpiid); -#else - struct { - uint8_t id[8]; - } rpiid = { 0 }; -#endif mbedtls_x509write_csr ctx; mbedtls_x509write_csr_init(&ctx); snprintf((char *) buffer, sizeof(buffer), - "C=ES,O=Pico Keys,OU=Authenticator Attestation,CN=Pico Fido EE Serial %02x%02x%02x%02x%02x%02x%02x%02x", - rpiid.id[0], - rpiid.id[1], - rpiid.id[2], - rpiid.id[3], - rpiid.id[4], - rpiid.id[5], - rpiid.id[6], - rpiid.id[7]); + "C=ES,O=Pico Keys,OU=Authenticator Attestation,CN=Pico Fido EE Serial %s", pico_serial_str); mbedtls_x509write_csr_set_subject_name(&ctx, (char *) buffer); mbedtls_pk_context key; mbedtls_pk_init(&key); diff --git a/src/fido/cmd_register.c b/src/fido/cmd_register.c index 7962719..237f70f 100644 --- a/src/fido/cmd_register.c +++ b/src/fido/cmd_register.c @@ -41,7 +41,7 @@ int u2f_select(app_t *a) { return CCID_ERR_FILE_NOT_FOUND; } -void __attribute__((constructor)) u2f_ctor() { +INITIALIZER ( u2f_ctor ) { register_app(u2f_select, u2f_aid); } diff --git a/src/fido/credential.c b/src/fido/credential.c index ea44ebb..f1f1994 100644 --- a/src/fido/credential.c +++ b/src/fido/credential.c @@ -18,7 +18,7 @@ #include "mbedtls/chachapoly.h" #include "mbedtls/sha256.h" #include "credential.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "bsp/board.h" #endif #include "hid/ctap_hid.h" diff --git a/src/fido/ctap2_cbor.h b/src/fido/ctap2_cbor.h index 9a8c8d1..84723da 100644 --- a/src/fido/ctap2_cbor.h +++ b/src/fido/ctap2_cbor.h @@ -19,7 +19,11 @@ #define _CTAP2_CBOR_H_ #include "cbor.h" +#ifndef ESP_PLATFORM #include "common.h" +#else +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#endif #include "mbedtls/ecp.h" #include "mbedtls/ecdh.h" diff --git a/src/fido/fido.c b/src/fido/fido.c index 1adf712..3f772cf 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -27,12 +27,12 @@ #if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION) #include "ccid/ccid.h" #endif -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "bsp/board.h" #endif #include #include "management.h" -#include "ctap_hid.h" +#include "hid/ctap_hid.h" #include "version.h" int fido_process_apdu(); @@ -79,7 +79,7 @@ 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() { +INITIALIZER ( fido_ctor ) { #if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION) ccid_atr = atr_fido; #endif @@ -315,9 +315,12 @@ int scan_files() { mbedtls_ecdsa_free(&ecdsa); return ret; } - uint8_t kdata[32]; - int key_size = mbedtls_mpi_size(&ecdsa.d); - mbedtls_mpi_write_binary(&ecdsa.d, kdata, key_size); + uint8_t kdata[64]; + size_t key_size = 0; + ret = mbedtls_ecp_write_key_ext(&ecdsa, &key_size, kdata, sizeof(kdata)); + if (ret != CCID_OK) { + return ret; + } ret = file_put_data(ef_keydev, kdata, key_size); mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_ecdsa_free(&ecdsa); @@ -333,7 +336,7 @@ int scan_files() { ef_certdev = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF); if (ef_certdev) { if (!file_has_data(ef_certdev)) { - uint8_t cert[4096]; + uint8_t cert[2048]; mbedtls_ecdsa_context key; mbedtls_ecdsa_init(&key); int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, diff --git a/src/fido/fido.h b/src/fido/fido.h index f12dc5d..aab14e8 100644 --- a/src/fido/fido.h +++ b/src/fido/fido.h @@ -18,13 +18,18 @@ #ifndef _FIDO_H_ #define _FIDO_H_ -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #endif +#ifndef ESP_PLATFORM #include "common.h" +#else +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#endif + #include "mbedtls/ecdsa.h" #ifndef ENABLE_EMULATION -#include "ctap_hid.h" +#include "hid/ctap_hid.h" #else #include #endif diff --git a/src/fido/management.c b/src/fido/management.c index f7590d0..26ae35e 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -43,7 +43,7 @@ int man_select(app_t *a) { return CCID_OK; } -void __attribute__((constructor)) man_ctor() { +INITIALIZER ( man_ctor ) { register_app(man_select, man_aid); } @@ -82,9 +82,7 @@ int man_get_config() { res_APDU[res_APDU_size++] = CAP_OTP | CAP_U2F | CAP_OATH; res_APDU[res_APDU_size++] = TAG_SERIAL; res_APDU[res_APDU_size++] = 4; -#ifndef ENABLE_EMULATION - pico_get_unique_board_id_string((char *) res_APDU + res_APDU_size, 4); -#endif + memcpy(res_APDU + res_APDU_size, pico_serial.id, 4); res_APDU_size += 4; res_APDU[res_APDU_size++] = TAG_FORM_FACTOR; res_APDU[res_APDU_size++] = 1; diff --git a/src/fido/management.h b/src/fido/management.h index 6a5ff0d..a8a6331 100644 --- a/src/fido/management.h +++ b/src/fido/management.h @@ -19,7 +19,7 @@ #define _MANAGEMENT_H_ #include -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #endif diff --git a/src/fido/oath.c b/src/fido/oath.c index 03ee790..3bf212f 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -80,12 +80,7 @@ int oath_select(app_t *a) { 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; -#else - memset(res_APDU + res_APDU_size, 0, 8); res_APDU_size += 8; -#endif + memcpy(res_APDU + res_APDU_size, pico_serial_str, 8); if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) { random_gen(NULL, challenge, sizeof(challenge)); res_APDU[res_APDU_size++] = TAG_CHALLENGE; @@ -109,7 +104,7 @@ int oath_select(app_t *a) { return CCID_ERR_FILE_NOT_FOUND; } -void __attribute__((constructor)) oath_ctor() { +INITIALIZER ( oath_ctor ) { register_app(oath_select, oath_aid); } diff --git a/src/fido/otp.c b/src/fido/otp.c index daee316..4198ac4 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -24,11 +24,12 @@ #include "asn1.h" #include "hid/ctap_hid.h" #include "usb.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "bsp/board.h" #endif #include "mbedtls/aes.h" #include "management.h" +#include "tusb.h" #define FIXED_SIZE 16 #define KEY_SIZE 16 @@ -331,7 +332,7 @@ int otp_button_pressed(uint8_t slot) { return 0; } -void __attribute__((constructor)) otp_ctor() { +INITIALIZER( otp_ctor ) { register_app(otp_select, otp_aid); button_pressed_cb = otp_button_pressed; #ifndef ENABLE_EMULATION @@ -449,9 +450,7 @@ int cmd_otp() { low_flash_available(); } else if (p1 == 0x10) { -#ifndef ENABLE_EMULATION - pico_get_unique_board_id_string((char *) res_APDU, 4); -#endif + memcpy(res_APDU, pico_serial.id, 4); res_APDU_size = 4; } else if (p1 == 0x13) { @@ -479,9 +478,7 @@ int cmd_otp() { else if (p1 == 0x20 || p1 == 0x28) { uint8_t challenge[16]; memcpy(challenge, apdu.data, 6); -#ifndef ENABLE_EMULATION - pico_get_unique_board_id_string((char *) challenge + 6, 10); -#endif + memcpy(challenge + 6, pico_serial_str, 10); mbedtls_aes_context ctx; mbedtls_aes_init(&ctx); mbedtls_aes_setkey_enc(&ctx, otp_config->aes_key, 128); @@ -547,39 +544,41 @@ int otp_hid_set_report_cb(uint8_t itf, 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); - } + if (itf == ITF_KEYBOARD) { + if (report_type == 3) { + DEBUG_PAYLOAD(buffer, bufsize); + if (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)); } - else { - printf("[OTP] Bad CRC!\n"); + 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"); + } } } } From 163e936231032d6389158788fe62483e30bdfcb9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 18 Aug 2024 23:59:52 +0200 Subject: [PATCH 44/50] Fix potential bug in CBOR encoding. It happen if a keepalive packet is sent in the middle of an encoding. Signed-off-by: Pol Henarejos --- src/fido/cbor_client_pin.c | 4 ++-- src/fido/cbor_config.c | 4 ++-- src/fido/cbor_cred_mgmt.c | 4 ++-- src/fido/cbor_get_assertion.c | 4 ++-- src/fido/cbor_get_info.c | 2 +- src/fido/cbor_large_blobs.c | 2 +- src/fido/cbor_make_credential.c | 4 ++-- src/fido/cbor_vendor.c | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index 2d324da..4c8a3a9 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -336,7 +336,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { } CBOR_PARSE_MAP_END(map, 1); - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); if (subcommand == 0x0) { CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); } @@ -632,7 +632,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); - resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + resp_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); err: CBOR_FREE_BYTE_STRING(pinUvAuthParam); CBOR_FREE_BYTE_STRING(newPinEnc); diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index b8cb73f..4886bc0 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -106,7 +106,7 @@ int cbor_config(const uint8_t *data, size_t len) { } CBOR_PARSE_MAP_END(map, 1); - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); if (pinUvAuthParam.present == false) { CBOR_ERROR(CTAP2_ERR_PUAT_REQUIRED); @@ -228,7 +228,7 @@ int cbor_config(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); - resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + resp_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); err: CBOR_FREE_BYTE_STRING(pinUvAuthParam); diff --git a/src/fido/cbor_cred_mgmt.c b/src/fido/cbor_cred_mgmt.c index f5b9fdd..16416dc 100644 --- a/src/fido/cbor_cred_mgmt.c +++ b/src/fido/cbor_cred_mgmt.c @@ -120,7 +120,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { } } - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); if (subcommand == 0x01) { if (verify(pinUvAuthProtocol, paut.data, (const uint8_t *) "\x01", 1, pinUvAuthParam.data) != CborNoError) { @@ -442,7 +442,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_NO_CREDENTIALS); } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); - resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + resp_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); err: CBOR_FREE_BYTE_STRING(pinUvAuthParam); diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index aa22e3b..b1c8728 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -585,7 +585,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { if (extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { lfields++; } - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, lfields)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); @@ -638,7 +638,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { } mbedtls_platform_zeroize(largeBlobKey, sizeof(largeBlobKey)); CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); - resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + resp_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); ctr++; file_put_data(ef_counter, (uint8_t *) &ctr, sizeof(ctr)); low_flash_available(); diff --git a/src/fido/cbor_get_info.c b/src/fido/cbor_get_info.c index 0864725..38cbf8d 100644 --- a/src/fido/cbor_get_info.c +++ b/src/fido/cbor_get_info.c @@ -26,7 +26,7 @@ int cbor_get_info() { CborEncoder encoder, mapEncoder, arrayEncoder, mapEncoder2; CborError error = CborNoError; - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 15)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); diff --git a/src/fido/cbor_large_blobs.c b/src/fido/cbor_large_blobs.c index 432464d..9f65e37 100644 --- a/src/fido/cbor_large_blobs.c +++ b/src/fido/cbor_large_blobs.c @@ -79,7 +79,7 @@ int cbor_large_blobs(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); } - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); if (get > 0) { if (length != 0) { CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 33ccc98..176843b 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -468,7 +468,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { } } - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, extensions.largeBlobKey == ptrue && options.rk == ptrue ? 5 : 4)); @@ -512,7 +512,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { } mbedtls_platform_zeroize(largeBlobKey, sizeof(largeBlobKey)); CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); - resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + resp_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); if (options.rk == ptrue) { if (credential_store(cred_id, cred_id_len, rp_id_hash) != 0) { diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index 3b78c01..01b0bdb 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -101,7 +101,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { } CBOR_PARSE_MAP_END(map, 1); - cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_PACKET_SIZE, 0); + cbor_encoder_init(&encoder, res_APDU + 1, CTAP_MAX_PACKET_SIZE, 0); if (cmd == CTAP_VENDOR_BACKUP) { if (vendorCmd == 0x01) { @@ -300,7 +300,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); - resp_size = cbor_encoder_get_buffer_size(&encoder, ctap_resp->init.data + 1); + resp_size = cbor_encoder_get_buffer_size(&encoder, res_APDU + 1); err: CBOR_FREE_BYTE_STRING(pinUvAuthParam); From 0c5280e12aa1bff44fd69af5fa59a55dd7fae01b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 19 Aug 2024 00:08:31 +0200 Subject: [PATCH 45/50] Add support to ESP32 build. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5f60bc..d0b67bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,11 @@ cmake_minimum_required(VERSION 3.13) +if(ESP_PLATFORM) +set(EXTRA_COMPONENT_DIRS src pico-keys-sdk/src) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +else() + if(ENABLE_EMULATION) else() include(pico_sdk_import.cmake) @@ -33,7 +38,7 @@ pico_sdk_init() endif() add_executable(pico_fido) - +endif() option(ENABLE_UP_BUTTON "Enable/disable user presence button" ON) if(ENABLE_UP_BUTTON) add_definitions(-DENABLE_UP_BUTTON=1) @@ -110,11 +115,13 @@ endif() set(USB_ITF_HID 1) include(pico-keys-sdk/pico_keys_sdk_import.cmake) - +if(ESP_PLATFORM) + project(pico_fido) +endif() set(INCLUDES ${INCLUDES} ${CMAKE_CURRENT_LIST_DIR}/src/fido ) - +if(NOT ESP_PLATFORM) target_sources(pico_fido PUBLIC ${SOURCES}) target_include_directories(pico_fido PUBLIC ${INCLUDES}) @@ -149,3 +156,4 @@ else() pico_add_extra_outputs(pico_fido) 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() +endif() From af4eb075c77bf15bd358d3dcf0d41e3a2c92b460 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 19 Aug 2024 00:09:05 +0200 Subject: [PATCH 46/50] Add HID/CCID fixes for ESP32. 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 f4ad8e1..93c491d 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit f4ad8e1af2e2657f3900f1e01db031d7d73d623b +Subproject commit 93c491d72c6576bde99f00beefe04a0a5061f733 From d7d75caecf10b9151cf5db48c019043b466321d4 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 19 Aug 2024 13:11:48 +0200 Subject: [PATCH 47/50] Fix OATH selection. 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 3bf212f..0a5d681 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -80,7 +80,7 @@ int oath_select(app_t *a) { res_APDU[res_APDU_size++] = 0; res_APDU[res_APDU_size++] = TAG_NAME; res_APDU[res_APDU_size++] = 8; - memcpy(res_APDU + res_APDU_size, pico_serial_str, 8); + memcpy(res_APDU + res_APDU_size, pico_serial_str, 8); res_APDU_size += 8; if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) { random_gen(NULL, challenge, sizeof(challenge)); res_APDU[res_APDU_size++] = TAG_CHALLENGE; From a9799dc77ffda0d77d58ae3dad79fc482e64b664 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 19 Aug 2024 13:12:04 +0200 Subject: [PATCH 48/50] Fix CBOR error. Signed-off-by: Pol Henarejos --- src/fido/cbor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 3dd7fc1..c1ee944 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -122,7 +122,7 @@ void cbor_thread() { } else { res_APDU[0] = apdu.sw; - apdu.sw = 0; + //apdu.sw = 0; } finished_data_size = res_APDU_size + 1; From ed12d6f8e9465764be2397c83c2cc848e2fa03f9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 19 Aug 2024 13:18:03 +0200 Subject: [PATCH 49/50] Fix emulation build. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fido/otp.c b/src/fido/otp.c index 4198ac4..29b03d2 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -29,7 +29,9 @@ #endif #include "mbedtls/aes.h" #include "management.h" +#ifndef ENABLE_EMULATION #include "tusb.h" +#endif #define FIXED_SIZE 16 #define KEY_SIZE 16 From 910fb66f3c8d199f453a753c8a7ac357727615a2 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 19 Aug 2024 16:45:11 +0200 Subject: [PATCH 50/50] Fix keepalive 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 93c491d..d379a39 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 93c491d72c6576bde99f00beefe04a0a5061f733 +Subproject commit d379a39bd699a679e2f5e5605af95922dc35576f