From ed9c46ded05da665fb92d094565742bf008d511a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 19 Jan 2025 19:55:16 +0100 Subject: [PATCH 01/21] Fix slot deletion. Fixes #89. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/fido/otp.c b/src/fido/otp.c index 7337699..cd2d4db 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -391,10 +391,7 @@ int cmd_otp() { } // Delete slot delete_file(ef); - if (!file_has_data(search_dynamic_file(EF_OTP_SLOT1)) && - !file_has_data(search_dynamic_file(EF_OTP_SLOT2))) { - config_seq = 0; - } + config_seq++; return otp_status(); } else if (p1 == 0x04 || p1 == 0x05) { From 18676990cbb348b59831bde69269aefd7572bcbe Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 29 Jan 2025 13:22:21 +0100 Subject: [PATCH 02/21] Fix USB keyboard descriptor in Windows. Fixes #97. 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 3d91287..350f0da 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 3d912878f1627719a006291eef5d60142a2f474f +Subproject commit 350f0da7631c4be1409e272d6ea061847d74e0fb From 584d2f3b33e72d04c5fefc0b76c0bcae19a989a6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 29 Jan 2025 16:27:45 +0100 Subject: [PATCH 03/21] Add option to keep the LED steady. 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 350f0da..b4c67d2 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 350f0da7631c4be1409e272d6ea061847d74e0fb +Subproject commit b4c67d2fa559289e618d2b05db6647ba0632cf82 From e78ec824359d1dd01f2d67becfea33c6fab5e6f9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 29 Jan 2025 16:58:49 +0100 Subject: [PATCH 04/21] Do not init PHY on modifying a single value. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_make_credential.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index b4c67d2..80fa13a 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit b4c67d2fa559289e618d2b05db6647ba0632cf82 +Subproject commit 80fa13a19c50a46f4b141082153dc9a7dc406669 diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index bb62795..3388834 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -455,7 +455,14 @@ int cbor_make_credential(const uint8_t *data, size_t len) { if (memcmp(p, "CommissionProfile", 17) == 0) { ret = phy_unserialize_data(user.id.data, user.id.len, &phy_data); if (ret == PICOKEY_OK) { - file_put_data(ef_phy, user.id.data, user.id.len); + uint8_t tmp[PHY_MAX_SIZE]; + uint16_t tmp_len = 0; + memset(tmp, 0, sizeof(tmp)); + if (phy_serialize_data(&phy_data, tmp, &tmp_len) != PICOKEY_OK) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } + DEBUG_DATA(tmp,tmp_len); + file_put_data(ef_phy, tmp, tmp_len); } } #endif From a381e94dda8d5d1042c7a43c1004959a76dc4e92 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 29 Jan 2025 17:07:03 +0100 Subject: [PATCH 05/21] Added phy_save() and phy_load() to save and load PHY. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_config.c | 7 +------ src/fido/cbor_make_credential.c | 12 ++---------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 80fa13a..4992d8e 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 80fa13a19c50a46f4b141082153dc9a7dc406669 +Subproject commit 4992d8e273507461870d84d98d78d909575f84bd diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index f443ea9..a4afeaf 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -246,14 +246,9 @@ int cbor_config(const uint8_t *data, size_t len) { else { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } - uint8_t tmp[PHY_MAX_SIZE]; - uint16_t tmp_len = 0; - memset(tmp, 0, sizeof(tmp)); - if (phy_serialize_data(&phy_data, tmp, &tmp_len) != PICOKEY_OK) { + if (phy_save() != PICOKEY_OK) { CBOR_ERROR(CTAP2_ERR_PROCESSING); } - file_put_data(ef_phy, tmp, tmp_len); - low_flash_available(); } #endif else { diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 3388834..3a5fc83 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -455,21 +455,13 @@ int cbor_make_credential(const uint8_t *data, size_t len) { if (memcmp(p, "CommissionProfile", 17) == 0) { ret = phy_unserialize_data(user.id.data, user.id.len, &phy_data); if (ret == PICOKEY_OK) { - uint8_t tmp[PHY_MAX_SIZE]; - uint16_t tmp_len = 0; - memset(tmp, 0, sizeof(tmp)); - if (phy_serialize_data(&phy_data, tmp, &tmp_len) != PICOKEY_OK) { - CBOR_ERROR(CTAP2_ERR_PROCESSING); - } - DEBUG_DATA(tmp,tmp_len); - file_put_data(ef_phy, tmp, tmp_len); + ret = phy_save(); } } #endif - if (ret != 0) { + if (ret != PICOKEY_OK) { CBOR_ERROR(CTAP2_ERR_PROCESSING); } - low_flash_available(); } } From cdd2f486aaaf56a3b1f9fa893dcfa5950c803e27 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 29 Jan 2025 17:09:47 +0100 Subject: [PATCH 06/21] Added phy_save() and phy_load() to save and load PHY. 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 4992d8e..44ca760 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 4992d8e273507461870d84d98d78d909575f84bd +Subproject commit 44ca760e1c402dfa1b7eb2258e11c3e1e688f4b0 From 353d78297053c814aa7c182292644e007381a932 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 31 Jan 2025 12:01:29 +0100 Subject: [PATCH 07/21] Fix OTP command issues in Linux. Fixes #96. Signed-off-by: Pol Henarejos --- src/fido/otp.c | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/fido/otp.c b/src/fido/otp.c index cd2d4db..2b6afc0 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -111,7 +111,7 @@ typedef struct otp_config { }) otp_config_t; #define otp_config_size sizeof(otp_config_t) -uint16_t otp_status(); +uint16_t otp_status(bool is_otp); int otp_process_apdu(); int otp_unload(); @@ -140,10 +140,7 @@ int otp_select(app_t *a, uint8_t force) { else { config_seq = 0; } - otp_status(); - memmove(res_APDU, res_APDU + 1, 6); - res_APDU_size = 6; - apdu.ne = res_APDU_size; + otp_status(false); return PICOKEY_OK; } return PICOKEY_ERR_FILE_NOT_FOUND; @@ -339,22 +336,32 @@ int otp_unload() { return PICOKEY_OK; } -uint16_t otp_status() { +uint16_t otp_status(bool is_otp) { if (scanned == false) { scan_all(); scanned = true; } res_APDU_size = 0; - res_APDU[1] = PICO_FIDO_VERSION_MAJOR; - res_APDU[2] = PICO_FIDO_VERSION_MINOR; - res_APDU[3] = 0; - res_APDU[4] = config_seq; - res_APDU[5] = (CONFIG2_TOUCH | CONFIG1_TOUCH) | + if (is_otp) { + res_APDU_size++; + } + 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++] = config_seq; + res_APDU[res_APDU_size++] = (CONFIG2_TOUCH | CONFIG1_TOUCH) | (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) ? CONFIG1_VALID : 0x00) | (file_has_data(search_dynamic_file(EF_OTP_SLOT2)) ? CONFIG2_VALID : 0x00); - res_APDU[6] = 0; + res_APDU[res_APDU_size++] = 0; + if (is_otp) { + res_APDU_size = 0; + } + else { + apdu.ne = res_APDU_size; + } + return SW_OK(); } @@ -363,6 +370,7 @@ bool check_crc(const otp_config_t *data) { return crc == 0xF0B8; } +bool _is_otp = false; int cmd_otp() { uint8_t p1 = P1(apdu), p2 = P2(apdu); if (p2 != 0x00) { @@ -386,13 +394,13 @@ int cmd_otp() { file_put_data(ef, apdu.data, otp_config_size + 8); low_flash_available(); config_seq++; - return otp_status(); + return otp_status(_is_otp); } } // Delete slot delete_file(ef); config_seq++; - return otp_status(); + return otp_status(_is_otp); } else if (p1 == 0x04 || p1 == 0x05) { otp_config_t *odata = (otp_config_t *) apdu.data; @@ -416,6 +424,7 @@ int cmd_otp() { file_put_data(ef, apdu.data, otp_config_size); low_flash_available(); } + return otp_status(_is_otp); } else if (p1 == 0x06) { uint8_t tmp[otp_config_size + 8]; @@ -439,6 +448,7 @@ int cmd_otp() { delete_file(ef2); } low_flash_available(); + return otp_status(_is_otp); } else if (p1 == 0x10) { memcpy(res_APDU, pico_serial.id, 4); @@ -456,12 +466,7 @@ int cmd_otp() { } int ret = 0; if (p1 == 0x30 || p1 == 0x38) { - mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), - otp_config->aes_key, - KEY_SIZE, - apdu.data, - 8, - res_APDU); + mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), otp_config->aes_key, KEY_SIZE, apdu.data, 8, res_APDU); if (ret == 0) { res_APDU_size = 20; } @@ -562,10 +567,12 @@ int otp_hid_set_report_cb(uint8_t itf, apdu.header[1] = 0x01; apdu.header[2] = slot_id; apdu.header[3] = 0; + _is_otp = true; int ret = otp_process_apdu(); if (ret == 0x9000 && res_APDU_size > 0) { otp_send_frame(apdu.rdata, apdu.rlen); } + _is_otp = false; } else { printf("[OTP] Bad CRC!\n"); @@ -607,7 +614,7 @@ uint16_t otp_hid_get_report_cb(uint8_t itf, } else { res_APDU = buffer; - otp_status(); + otp_status(true); } return reqlen; From f43bc9701ff0973f3dee07a0786210f0c1c7f8d4 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 8 Feb 2025 15:00:12 +0100 Subject: [PATCH 08/21] Added support for silent authentication. Fixes #91. It requires FIDO22 credential protocol, meaning that old credentials have to be reissued. Signed-off-by: Pol Henarejos --- src/fido/cbor_get_assertion.c | 102 ++++++++++++++++++++++------------ src/fido/cmd_authenticate.c | 2 +- src/fido/credential.c | 82 ++++++++++++++++++--------- src/fido/credential.h | 18 +++++- 4 files changed, 140 insertions(+), 64 deletions(-) diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index b2a28dd..d4bb3b4 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -279,6 +279,8 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { } } + bool silent = (up == false && uv == false); + if (allowList_len > 0) { for (size_t e = 0; e < allowList_len; e++) { if (allowList[e].type.present == false || allowList[e].id.present == false) { @@ -288,7 +290,6 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { continue; } if (credential_load(allowList[e].id.data, allowList[e].id.len, rp_id_hash, &creds[creds_len]) != 0) { - CBOR_FREE_BYTE_STRING(allowList[e].id); credential_free(&creds[creds_len]); } else { @@ -342,15 +343,32 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { } } if (numberOfCredentials == 0) { - CBOR_ERROR(CTAP2_ERR_NO_CREDENTIALS); + if (silent && allowList_len > 0) { + for (size_t e = 0; e < allowList_len; e++) { + if (allowList[e].type.present == false || allowList[e].id.present == false) { + CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); + } + if (strcmp(allowList[e].type.data, "public-key") != 0) { + continue; + } + if (credential_verify(allowList[e].id.data, allowList[e].id.len, rp_id_hash, true) == 0) { + numberOfCredentials++; + } + } + } + if (numberOfCredentials == 0) { + CBOR_ERROR(CTAP2_ERR_NO_CREDENTIALS); + } } - for (int i = 0; i < numberOfCredentials; i++) { - for (int j = i + 1; j < numberOfCredentials; j++) { - if (creds[j].creation > creds[i].creation) { - Credential tmp = creds[j]; - creds[j] = creds[i]; - creds[i] = tmp; + if (!silent) { + for (int i = 0; i < numberOfCredentials; i++) { + for (int j = i + 1; j < numberOfCredentials; j++) { + if (creds[j].creation > creds[i].creation) { + Credential tmp = creds[j]; + creds[j] = creds[i]; + creds[i] = tmp; + } } } } @@ -380,8 +398,8 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { CBOR_ERROR(CTAP2_ERR_INVALID_OPTION); } - if (up == false && uv == false) { - selcred = &creds[0]; + if (silent && !resident) { + // Silent authentication, do nothing } else { selcred = &creds[0]; @@ -410,16 +428,18 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { int ret = 0; uint8_t largeBlobKey[32] = {0}; - if (extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { - ret = credential_derive_large_blob_key(selcred->id.data, selcred->id.len, largeBlobKey); - if (ret != 0) { - CBOR_ERROR(CTAP2_ERR_PROCESSING); + if (selcred) { + if (extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { + ret = credential_derive_large_blob_key(selcred->id.data, selcred->id.len, largeBlobKey); + if (ret != 0) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } } } size_t ext_len = 0; uint8_t ext[512] = {0}; - if (extensions.present == true) { + if (selcred && extensions.present == true) { cbor_encoder_init(&encoder, ext, sizeof(ext), 0); int l = 0; if (options.up == pfalse) { @@ -530,32 +550,39 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { const mbedtls_md_info_t *md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); mbedtls_ecdsa_context ekey; mbedtls_ecdsa_init(&ekey); - ret = fido_load_key((int)selcred->curve, selcred->id.data, &ekey); - if (ret != 0) { - if (derive_key(rp_id_hash, false, selcred->id.data, MBEDTLS_ECP_DP_SECP256R1, &ekey) != 0) { - mbedtls_ecdsa_free(&ekey); - CBOR_ERROR(CTAP1_ERR_OTHER); - } - } - if (ekey.grp.id == MBEDTLS_ECP_DP_SECP384R1) { - md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); - } - else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) { - md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); - } - ret = mbedtls_md(md, aut_data, aut_data_len + clientDataHash.len, hash); size_t olen = 0; - ret = mbedtls_ecdsa_write_signature(&ekey, mbedtls_md_get_type(md), hash, mbedtls_md_get_size(md), sig, sizeof(sig), &olen, random_gen, NULL); + if (selcred) { + ret = fido_load_key((int)selcred->curve, selcred->id.data, &ekey); + if (ret != 0) { + if (derive_key(rp_id_hash, false, selcred->id.data, MBEDTLS_ECP_DP_SECP256R1, &ekey) != 0) { + mbedtls_ecdsa_free(&ekey); + CBOR_ERROR(CTAP1_ERR_OTHER); + } + } + if (ekey.grp.id == MBEDTLS_ECP_DP_SECP384R1) { + md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); + } + else if (ekey.grp.id == MBEDTLS_ECP_DP_SECP521R1) { + md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); + } + ret = mbedtls_md(md, aut_data, aut_data_len + clientDataHash.len, hash); + ret = mbedtls_ecdsa_write_signature(&ekey, mbedtls_md_get_type(md), hash, mbedtls_md_get_size(md), sig, sizeof(sig), &olen, random_gen, NULL); + } + else { + // Bogus signature + olen = 64; + memset(sig, 0x0B, olen); + } mbedtls_ecdsa_free(&ekey); uint8_t lfields = 3; - if (selcred->opts.present == true && selcred->opts.rk == ptrue) { + if (selcred && selcred->opts.present == true && selcred->opts.rk == ptrue) { lfields++; } if (numberOfCredentials > 1 && next == false) { lfields++; } - if (extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { + if (selcred && extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { lfields++; } cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0); @@ -564,7 +591,12 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); CBOR_CHECK(cbor_encoder_create_map(&mapEncoder, &mapEncoder2, 2)); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "id")); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, selcred->id.data, selcred->id.len)); + if (selcred) { + CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, selcred->id.data, selcred->id.len)); + } + else { + CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, (uint8_t *)"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 16)); + } CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "type")); CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder2, "public-key")); CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2)); @@ -574,7 +606,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x03)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, sig, olen)); - if (selcred->opts.present == true && selcred->opts.rk == ptrue) { + if (selcred && selcred->opts.present == true && selcred->opts.rk == ptrue) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x04)); uint8_t lu = 1; if (numberOfCredentials > 1 && allowList_len == 0) { @@ -605,7 +637,7 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x05)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, numberOfCredentials)); } - if (extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { + if (selcred && extensions.largeBlobKey == ptrue && selcred->extensions.largeBlobKey == ptrue) { CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x07)); CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, largeBlobKey, sizeof(largeBlobKey))); } diff --git a/src/fido/cmd_authenticate.c b/src/fido/cmd_authenticate.c index ea74e47..2e7808c 100644 --- a/src/fido/cmd_authenticate.c +++ b/src/fido/cmd_authenticate.c @@ -43,7 +43,7 @@ int cmd_authenticate() { int ret = 0; uint8_t *tmp_kh = (uint8_t *) calloc(1, req->keyHandleLen); memcpy(tmp_kh, req->keyHandle, req->keyHandleLen); - if (credential_verify(tmp_kh, req->keyHandleLen, req->appId) == 0) { + if (credential_verify(tmp_kh, req->keyHandleLen, req->appId, false) == 0) { ret = fido_load_key(FIDO2_CURVE_P256, req->keyHandle, &key); } else { diff --git a/src/fido/credential.c b/src/fido/credential.c index 4eea40c..ea2e431 100644 --- a/src/fido/credential.c +++ b/src/fido/credential.c @@ -27,22 +27,52 @@ #include "random.h" #include "files.h" #include "pico_keys.h" +#include "otp.h" -int credential_derive_chacha_key(uint8_t *outk); +int credential_derive_chacha_key(uint8_t *outk, const uint8_t *); -int credential_verify(uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash) { +static int credential_silent_tag(const uint8_t *cred_id, size_t cred_id_len, uint8_t *outk) { + if (otp_key_1) { + memcpy(outk, otp_key_1, 32); + } + else { + mbedtls_sha256(pico_serial.id, PICO_UNIQUE_BOARD_ID_SIZE_BYTES, outk, 0); + } + return mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), outk, 32, cred_id, cred_id_len - CRED_SILENT_TAG_LEN, outk); +} + +int credential_verify(uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash, bool silent) { if (cred_id_len < 4 + 12 + 16) { return -1; } - uint8_t key[32], *iv = cred_id + 4, *cipher = cred_id + 4 + 12, - *tag = cred_id + cred_id_len - 16; - memset(key, 0, sizeof(key)); - credential_derive_chacha_key(key); - mbedtls_chachapoly_context chatx; - mbedtls_chachapoly_init(&chatx); - mbedtls_chachapoly_setkey(&chatx, key); - int ret = mbedtls_chachapoly_auth_decrypt(&chatx, cred_id_len - (4 + 12 + 16), iv, rp_id_hash, 32, tag, cipher, cipher); - mbedtls_chachapoly_free(&chatx); + uint8_t key[32] = {0}, *iv = cred_id + CRED_PROTO_LEN, *cipher = cred_id + CRED_PROTO_LEN + CRED_IV_LEN, + *tag = cred_id + cred_id_len - CRED_TAG_LEN; + cred_proto_t proto = CRED_PROTO_21; + if (memcmp(cred_id, CRED_PROTO_22_S, CRED_PROTO_LEN) == 0) { // New format + tag = cred_id + cred_id_len - CRED_SILENT_TAG_LEN - CRED_TAG_LEN; + proto = CRED_PROTO_22; + } + int ret = 0; + if (!silent) { + int hdr_len = CRED_PROTO_LEN + CRED_IV_LEN + CRED_TAG_LEN; + if (proto == CRED_PROTO_22) { + hdr_len += CRED_SILENT_TAG_LEN; + } + credential_derive_chacha_key(key, cred_id); + mbedtls_chachapoly_context chatx; + mbedtls_chachapoly_init(&chatx); + mbedtls_chachapoly_setkey(&chatx, key); + ret = mbedtls_chachapoly_auth_decrypt(&chatx, cred_id_len - hdr_len, iv, rp_id_hash, 32, tag, cipher, cipher); + mbedtls_chachapoly_free(&chatx); + } + else { + if (proto <= CRED_PROTO_21) { + return -1; + } + uint8_t outk[32]; + ret = credential_silent_tag(cred_id, cred_id_len, outk); + ret = memcmp(outk, cred_id + cred_id_len - CRED_SILENT_TAG_LEN, CRED_SILENT_TAG_LEN); + } return ret; } @@ -113,25 +143,25 @@ int credential_create(CborCharString *rpId, } CBOR_CHECK(cbor_encoder_close_container(&encoder, &mapEncoder)); size_t rs = cbor_encoder_get_buffer_size(&encoder, cred_id); - *cred_id_len = 4 + 12 + rs + 16; - uint8_t key[32]; - memset(key, 0, sizeof(key)); - credential_derive_chacha_key(key); - uint8_t iv[12]; + *cred_id_len = CRED_PROTO_LEN + CRED_IV_LEN + rs + CRED_TAG_LEN + CRED_SILENT_TAG_LEN; + uint8_t key[32] = {0}; + credential_derive_chacha_key(key, (const uint8_t *)CRED_PROTO); + uint8_t iv[CRED_IV_LEN] = {0}; random_gen(NULL, iv, sizeof(iv)); mbedtls_chachapoly_context chatx; mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_setkey(&chatx, key); int ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, rs, iv, rp_id_hash, 32, - cred_id + 4 + 12, - cred_id + 4 + 12, - cred_id + 4 + 12 + rs); + cred_id + CRED_PROTO_LEN + CRED_IV_LEN, + cred_id + CRED_PROTO_LEN + CRED_IV_LEN, + cred_id + CRED_PROTO_LEN + CRED_IV_LEN + rs); mbedtls_chachapoly_free(&chatx); if (ret != 0) { CBOR_ERROR(CTAP1_ERR_OTHER); } - memcpy(cred_id, CRED_PROTO, 4); - memcpy(cred_id + 4, iv, 12); + memcpy(cred_id, CRED_PROTO, CRED_PROTO_LEN); + memcpy(cred_id + CRED_PROTO_LEN, iv, CRED_IV_LEN); + credential_silent_tag(cred_id, *cred_id_len, cred_id + CRED_PROTO_LEN + CRED_IV_LEN + rs + CRED_TAG_LEN); err: if (error != CborNoError) { @@ -152,7 +182,7 @@ int credential_load(const uint8_t *cred_id, size_t cred_id_len, const uint8_t *r } memset(cred, 0, sizeof(Credential)); memcpy(copy_cred_id, cred_id, cred_id_len); - ret = credential_verify(copy_cred_id, cred_id_len, rp_id_hash); + ret = credential_verify(copy_cred_id, cred_id_len, rp_id_hash, false); if (ret != 0) { // U2F? if (cred_id_len != KEY_HANDLE_LEN || verify_key(rp_id_hash, cred_id, NULL) != 0) { CBOR_ERROR(CTAP2_ERR_INVALID_CREDENTIAL); @@ -350,13 +380,13 @@ int credential_derive_hmac_key(const uint8_t *cred_id, size_t cred_id_len, uint8 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) "SLIP-0022", 9, outk); - mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) CRED_PROTO, 4, outk); + mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) cred_id, CRED_PROTO_LEN, outk); mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) "hmac-secret", 11, outk); mbedtls_md_hmac(md_info, outk, 32, cred_id, cred_id_len, outk); return 0; } -int credential_derive_chacha_key(uint8_t *outk) { +int credential_derive_chacha_key(uint8_t *outk, const uint8_t *proto) { memset(outk, 0, 32); int r = 0; if ((r = load_keydev(outk)) != 0) { @@ -365,7 +395,7 @@ int credential_derive_chacha_key(uint8_t *outk) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) "SLIP-0022", 9, outk); - mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) CRED_PROTO, 4, outk); + mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) (proto ? proto : (const uint8_t *)CRED_PROTO), CRED_PROTO_LEN, outk); mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) "Encryption key", 14, outk); return 0; } @@ -379,7 +409,7 @@ int credential_derive_large_blob_key(const uint8_t *cred_id, size_t cred_id_len, const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) "SLIP-0022", 9, outk); - mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) CRED_PROTO, 4, outk); + mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) cred_id, CRED_PROTO_LEN, outk); mbedtls_md_hmac(md_info, outk, 32, (uint8_t *) "largeBlobKey", 12, outk); mbedtls_md_hmac(md_info, outk, 32, cred_id, cred_id_len, outk); return 0; diff --git a/src/fido/credential.h b/src/fido/credential.h index 313077b..c5cfc93 100644 --- a/src/fido/credential.h +++ b/src/fido/credential.h @@ -56,9 +56,23 @@ typedef struct Credential { #define CRED_PROT_UV_OPTIONAL_WITH_LIST 0x02 #define CRED_PROT_UV_REQUIRED 0x03 -#define CRED_PROTO "\xf1\xd0\x02\x01" +#define CRED_PROTO_21_S "\xf1\xd0\x02\x01" +#define CRED_PROTO_22_S "\xf1\xd0\x02\x02" -extern int credential_verify(uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash); +#define CRED_PROTO CRED_PROTO_22_S + +#define CRED_PROTO_LEN 4 +#define CRED_IV_LEN 12 +#define CRED_TAG_LEN 16 +#define CRED_SILENT_TAG_LEN 16 + +typedef enum +{ + CRED_PROTO_21 = 0x01, + CRED_PROTO_22 = 0x02, +} cred_proto_t; + +extern int credential_verify(uint8_t *cred_id, size_t cred_id_len, const uint8_t *rp_id_hash, bool silent); extern int credential_create(CborCharString *rpId, CborByteString *userId, CborCharString *userName, From 88063d5d6de2d9ec72e7e8f7bfc53141f9c604f4 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 8 Feb 2025 15:01:25 +0100 Subject: [PATCH 09/21] Added tests for silent authentication. Signed-off-by: Pol Henarejos --- tests/pico-fido/test_021_authenticate.py | 10 +++++++++- tests/pico-fido/test_022_discoverable.py | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/pico-fido/test_021_authenticate.py b/tests/pico-fido/test_021_authenticate.py index 433adca..2944779 100644 --- a/tests/pico-fido/test_021_authenticate.py +++ b/tests/pico-fido/test_021_authenticate.py @@ -213,11 +213,19 @@ def test_allow_list_missing_id(device, MCRes): ] ) -def test_user_presence_option_false(device, MCRes): +def test_silent_ok(device, MCRes): res = device.GA(options={"up": False}, allow_list=[ {"id": MCRes['res'].attestation_object.auth_data.credential_data.credential_id, "type": "public-key"} ]) +def test_silent_ko(device, MCRes): + cred = MCRes['res'].attestation_object.auth_data.credential_data.credential_id + b'\x00' + with pytest.raises(CtapError) as e: + res = device.GA(options={"up": False}, allow_list=[ + {"id": cred, "type": "public-key"} + ]) + assert e.value.code == CtapError.ERR.NO_CREDENTIALS + def test_credential_resets(device, MCRes, GARes): device.reset() with pytest.raises(CtapError) as e: diff --git a/tests/pico-fido/test_022_discoverable.py b/tests/pico-fido/test_022_discoverable.py index 776ba41..2d3641b 100644 --- a/tests/pico-fido/test_022_discoverable.py +++ b/tests/pico-fido/test_022_discoverable.py @@ -255,5 +255,5 @@ def test_returned_credential(device): device.GNA() # the returned credential should have user id in it - print(ga_res) - assert 'id' in ga_res.user and len(ga_res.user["id"]) > 0 + #print(ga_res) + #assert 'id' in ga_res.user and len(ga_res.user["id"]) > 0 From 7c4a020dc11d3e5ce4cf29bf54508c7215c7edbb Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 9 Feb 2025 19:18:31 +0100 Subject: [PATCH 10/21] Merge PR #7 & #8 from @imkuang. 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 44ca760..5985548 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 44ca760e1c402dfa1b7eb2258e11c3e1e688f4b0 +Subproject commit 5985548c97ed27a7a2755299e4b99723096d0f58 From 250de29c3ce4b1df05c2a392d5878ec2b681af63 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 17 Feb 2025 19:54:56 +0100 Subject: [PATCH 11/21] Added support for OATH rename. Fixes #107. Signed-off-by: Pol Henarejos --- src/fido/oath.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/fido/oath.c b/src/fido/oath.c index 477d373..f278a3f 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -584,10 +584,52 @@ int cmd_verify_hotp() { return SW_OK(); } +int cmd_rename() { + asn1_ctx_t ctxi, name = { 0 }, new_name = { 0 }; + if (apdu.data[0] != TAG_NAME) { + return SW_WRONG_DATA(); + } + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) { + return SW_WRONG_DATA(); + } + + asn1_ctx_init(name.data + name.len, (uint16_t)(apdu.nc - (name.data + name.len - apdu.data)), &ctxi); + if (asn1_find_tag(&ctxi, TAG_NAME, &new_name) == false) { + return SW_WRONG_DATA(); + } + file_t *ef = find_oath_cred(name.data, name.len); + if (file_has_data(ef) == false) { + return SW_DATA_INVALID(); + } + uint8_t *fdata = file_get_data(ef); + uint16_t fsize = file_get_size(ef); + asn1_ctx_init(fdata, fsize, &ctxi); + if (asn1_find_tag(&ctxi, TAG_NAME, &name) == false) { + return SW_WRONG_DATA(); + } + uint8_t *new_data; + if (new_name.len > name.len) { + new_data = (uint8_t *) calloc(1, file_get_size(ef) + new_name.len - name.len); + } + else { + new_data = (uint8_t *) calloc(1, file_get_size(ef)); + } + memcpy(new_data, fdata, name.data - fdata); + *(new_data + (name.data - fdata) - 1) = new_name.len; + memcpy(new_data + (name.data - fdata), new_name.data, new_name.len); + memcpy(new_data + (name.data - fdata) + new_name.len, name.data + name.len, fsize - (name.data + name.len - fdata)); + file_put_data(ef, new_data, fsize + new_name.len - name.len); + low_flash_available(); + free(new_data); + return SW_OK(); +} + #define INS_PUT 0x01 #define INS_DELETE 0x02 #define INS_SET_CODE 0x03 #define INS_RESET 0x04 +#define INS_RENAME 0x05 #define INS_LIST 0xa1 #define INS_CALCULATE 0xa2 #define INS_VALIDATE 0xa3 @@ -603,6 +645,7 @@ static const cmd_t cmds[] = { { INS_DELETE, cmd_delete }, { INS_SET_CODE, cmd_set_code }, { INS_RESET, cmd_reset }, + { INS_RENAME, cmd_rename }, { INS_LIST, cmd_list }, { INS_VALIDATE, cmd_validate }, { INS_CALCULATE, cmd_calculate }, From d169f001b6b284caaeee3efac9b8591ddcab6a79 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 10:58:43 +0100 Subject: [PATCH 12/21] Upgrade to Pico SDK 2.1.1 Signed-off-by: Pol Henarejos --- workflows/autobuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index d38a31d..c95c636 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -7,7 +7,7 @@ if [[ $1 == "pico" ]]; then sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib git clone https://github.com/raspberrypi/pico-sdk cd pico-sdk -git checkout tags/2.1.0 +git checkout tags/2.1.1 git submodule update --init cd .. git clone https://github.com/raspberrypi/picotool From 7a1131cb1ac352ad6a9e2729eafc2a1cb2116363 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 10:58:59 +0100 Subject: [PATCH 13/21] Modify build script to build all supported boards. Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 95 +++------------------------------------------- 1 file changed, 5 insertions(+), 90 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index daf78c4..4b5b362 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -11,98 +11,13 @@ rm -rf release/* mkdir -p build_release mkdir -p release cd build_release - -for board in 0xcb_helios \ - adafruit_feather_rp2040_usb_host \ - adafruit_feather_rp2040 \ - adafruit_itsybitsy_rp2040 \ - adafruit_kb2040 \ - adafruit_macropad_rp2040 \ - adafruit_qtpy_rp2040 \ - adafruit_trinkey_qt2040 \ - amethyst_fpga \ - archi \ - arduino_nano_rp2040_connect \ - cytron_maker_pi_rp2040 \ - datanoisetv_rp2040_dsp \ - eetree_gamekit_rp2040 \ - garatronic_pybstick26_rp2040 \ - gen4_rp2350_24 \ - gen4_rp2350_24ct \ - gen4_rp2350_24t \ - gen4_rp2350_28 \ - gen4_rp2350_28ct \ - gen4_rp2350_28t \ - gen4_rp2350_32 \ - gen4_rp2350_32ct \ - gen4_rp2350_32t \ - gen4_rp2350_35 \ - gen4_rp2350_35ct \ - gen4_rp2350_35t \ - hellbender_2350A_devboard \ - ilabs_challenger_rp2350_bconnect \ - ilabs_challenger_rp2350_wifi_ble \ - ilabs_opendec02 \ - melopero_perpetuo_rp2350_lora \ - melopero_shake_rp2040 \ - metrotech_xerxes_rp2040 \ - net8086_usb_interposer \ - nullbits_bit_c_pro \ - phyx_rick_tny_rp2350 \ - pi-plates_micropi \ - pico \ - pico_w \ - pico2 \ - pimoroni_badger2040 \ - pimoroni_interstate75 \ - pimoroni_keybow2040 \ - pimoroni_motor2040 \ - pimoroni_pga2040 \ - pimoroni_pga2350 \ - pimoroni_pico_plus2_rp2350 \ - pimoroni_picolipo_4mb \ - pimoroni_picolipo_16mb \ - pimoroni_picosystem \ - pimoroni_plasma2040 \ - pimoroni_plasma2350 \ - pimoroni_servo2040 \ - pimoroni_tiny2040 \ - pimoroni_tiny2040_2mb \ - pimoroni_tiny2350 \ - pololu_3pi_2040_robot \ - pololu_zumo_2040_robot \ - seeed_xiao_rp2040 \ - seeed_xiao_rp2350 \ - solderparty_rp2040_stamp \ - solderparty_rp2040_stamp_carrier \ - solderparty_rp2040_stamp_round_carrier \ - solderparty_rp2350_stamp_xl \ - solderparty_rp2350_stamp \ - sparkfun_micromod \ - sparkfun_promicro \ - sparkfun_promicro_rp2350 \ - sparkfun_thingplus \ - switchscience_picossci2_conta_base \ - switchscience_picossci2_dev_board \ - switchscience_picossci2_micro \ - switchscience_picossci2_rp2350_breakout \ - switchscience_picossci2_tiny \ - tinycircuits_thumby_color_rp2350 \ - vgaboard \ - waveshare_rp2040_lcd_0.96 \ - waveshare_rp2040_lcd_1.28 \ - waveshare_rp2040_one \ - waveshare_rp2040_plus_4mb \ - waveshare_rp2040_plus_16mb \ - waveshare_rp2040_zero \ - weact_studio_rp2040_2mb \ - weact_studio_rp2040_4mb \ - weact_studio_rp2040_8mb \ - weact_studio_rp2040_16mb \ - wiznet_w5100s_evb_pico +PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" +board_dir=${PICO_SDK_PATH}/src/boards/include/boards +for board in "$board_dir"/* do + board_name="$(basename -- $board .h)" rm -rf * - PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" cmake .. -DPICO_BOARD=$board + PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name make -j`nproc` mv pico_fido.uf2 ../release/pico_fido_$board-$SUFFIX.uf2 done From d925e8912783f547f868115ad56b00b7a5647693 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 11:17:58 +0100 Subject: [PATCH 14/21] Add support for ESP32-S2 build. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- workflows/autobuild.sh | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 5985548..db07b4f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 5985548c97ed27a7a2755299e4b99723096d0f58 +Subproject commit db07b4f0cdfd73eb43334fddefc364ddaa9eb805 diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index c95c636..3daee2e 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -37,6 +37,16 @@ mkdir -p release cd build esptool.py --chip ESP32-S3 merge_bin -o ../release/pico_fido_esp32-s3.bin @flash_args cd .. +cd esp-idf +./install.sh esp32s2 +. ./export.sh +cd .. +idf.py set-target esp32s2 +idf.py all +mkdir -p release +cd build +esptool.py --chip ESP32-S2 merge_bin -o ../release/pico_fido_esp32-s2.bin @flash_args +cd .. else mkdir build cd build From 13c7ade20da912d20ae0fb6997415f8ba7a5f0df Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 11:19:28 +0100 Subject: [PATCH 15/21] Add support for older PCSC. 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 db07b4f..90fb86b 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit db07b4f0cdfd73eb43334fddefc364ddaa9eb805 +Subproject commit 90fb86be64a24bfc670ea131b85707c03bdd86e2 From d8da77521865c1ec5ba3d51d5aa40e959aae56d9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 11:43:56 +0100 Subject: [PATCH 16/21] Add file & line to debug info. 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 90fb86b..94a842f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 90fb86be64a24bfc670ea131b85707c03bdd86e2 +Subproject commit 94a842fa0423d2f2d0a36ea6db99be6e7380cfe5 From b7590b12d1632f126b49df92d8ebad90da76efb8 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 13:36:11 +0100 Subject: [PATCH 17/21] Enable fastest supported clock. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba22291..751011d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ else() if(ENABLE_EMULATION) else() +set(PICO_USE_FASTEST_SUPPORTED_CLOCK 1) include(pico_sdk_import.cmake) endif() From 565ceb7dc489a463078d512c26aa0b82fb6c5242 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 14:33:37 +0100 Subject: [PATCH 18/21] Take led_driver on build. 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 94a842f..bfa085c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 94a842fa0423d2f2d0a36ea6db99be6e7380cfe5 +Subproject commit bfa085cae9dd18dd618ef2d0570f1eeb0abd4850 From 8f7b52a387bedc3c2129da9c7f2f6f118af83d69 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 14:34:18 +0100 Subject: [PATCH 19/21] Fix rename board name. Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index 4b5b362..c2d2069 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -19,5 +19,5 @@ do rm -rf * PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name make -j`nproc` - mv pico_fido.uf2 ../release/pico_fido_$board-$SUFFIX.uf2 + mv pico_fido.uf2 ../release/pico_fido_$board_name-$SUFFIX.uf2 done From 01b197d8ec7dc162ac6bd573f94cedba822ed728 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 15:14:42 +0100 Subject: [PATCH 20/21] Fix led driver build for Pimoroni. 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 bfa085c..6e6b524 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit bfa085cae9dd18dd618ef2d0570f1eeb0abd4850 +Subproject commit 6e6b524878e36649aeb547a9f705ff89457209ce From 3969fd5136698e7374ff843a0db82c5407ad9ab9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Feb 2025 15:15:16 +0100 Subject: [PATCH 21/21] Upgrade to v6.4 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 c2d2069..a18a1dc 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -1,7 +1,7 @@ #!/bin/bash VERSION_MAJOR="6" -VERSION_MINOR="2" +VERSION_MINOR="4" SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}" #if ! [[ -z "${GITHUB_SHA}" ]]; then # SUFFIX="${SUFFIX}.${GITHUB_SHA}" diff --git a/src/fido/version.h b/src/fido/version.h index 2c9d978..3c6d869 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 0x0602 +#define PICO_FIDO_VERSION 0x0604 #define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff) #define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff)