From c43006f8c21a6ab67093b5f3ccfa0b778e6a695d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 12 Sep 2024 19:01:04 +0200 Subject: [PATCH 01/51] Protect keydev if available (only for RP2350). Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor.c | 1 + src/fido/cbor_make_credential.c | 7 ++++++- src/fido/cmd_register.c | 8 +++++++- src/fido/fido.c | 12 ++++++++++++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 9f65a2c..108cfec 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 9f65a2cfa024b721a6b7c16863e00558ac1a6f88 +Subproject commit 108cfec47c8b72472acbf6d3f8cc50260bfb09bd diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 74c5822..cddde7e 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include "pico_keys.h" #if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #endif diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 2a99b08..1c3f6e5 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -440,7 +440,12 @@ int cbor_make_credential(const uint8_t *data, size_t len) { if (enterpriseAttestation == 2 || (ka && ka->use_self_attestation == pfalse)) { mbedtls_ecdsa_free(&ekey); mbedtls_ecdsa_init(&ekey); - ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, file_get_data(ef_keydev), 32); + uint8_t key[32] = {0}; + if (load_keydev(key) != 0) { + CBOR_ERROR(CTAP1_ERR_OTHER); + } + ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &ekey, key, 32); + mbedtls_platform_zeroize(key, sizeof(key)); md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); self_attestation = false; } diff --git a/src/fido/cmd_register.c b/src/fido/cmd_register.c index 325508c..e06df87 100644 --- a/src/fido/cmd_register.c +++ b/src/fido/cmd_register.c @@ -100,7 +100,13 @@ int cmd_register() { return SW_EXEC_ERROR(); } mbedtls_ecdsa_init(&key); - ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &key, file_get_data(ef_keydev), 32); + uint8_t key_dev[32] = {0}; + ret = load_keydev(key_dev); + if (ret != CCID_OK) { + return SW_EXEC_ERROR(); + } + ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &key, key_dev, 32); + mbedtls_platform_zeroize(key_dev, sizeof(key_dev)); if (ret != CCID_OK) { mbedtls_ecdsa_free(&key); return SW_EXEC_ERROR(); diff --git a/src/fido/fido.c b/src/fido/fido.c index 7ac7e4e..cac3d3e 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -34,6 +34,8 @@ #include "management.h" #include "hid/ctap_hid.h" #include "version.h" +#include "crypto_utils.h" +#include "otp.h" int fido_process_apdu(); int fido_unload(); @@ -178,12 +180,19 @@ int load_keydev(uint8_t *key) { if (has_keydev_dec == false && !file_has_data(ef_keydev)) { return CCID_ERR_MEMORY_FATAL; } + if (has_keydev_dec == true) { memcpy(key, keydev_dec, sizeof(keydev_dec)); } else { memcpy(key, file_get_data(ef_keydev), file_get_size(ef_keydev)); +#ifdef PICO_RP2350 + if (aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != CCID_OK) { + return CCID_EXEC_ERROR; + } +#endif } + //return mkek_decrypt(key, file_get_size(ef_keydev)); return CCID_OK; } @@ -292,6 +301,9 @@ int scan_files() { if (ret != CCID_OK) { return ret; } +#ifdef PICO_RP2350 + ret = aes_encrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, kdata, 32); +#endif ret = file_put_data(ef_keydev, kdata, (uint16_t)key_size); mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_ecdsa_free(&ecdsa); From ec612a451da5e8cbee61de866dd273f214e6cd5c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 13 Sep 2024 21:03:34 +0200 Subject: [PATCH 02/51] Fix ssh-keygen creation. Fixes #59 Signed-off-by: Pol Henarejos --- src/fido/cbor.c | 9 +++++++-- src/fido/cbor_make_credential.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/fido/cbor.c b/src/fido/cbor.c index cddde7e..68842b7 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -120,8 +120,13 @@ void cbor_thread(void) { DEBUG_DATA(res_APDU + 1, res_APDU_size); } else { - res_APDU[0] = apdu.sw; - //apdu.sw = 0; + if (apdu.sw >= CTAP1_ERR_INVALID_CHANNEL) { + res_APDU[-1] = apdu.sw; + apdu.sw = 0; + } + else { + res_APDU[0] = apdu.sw; + } } finished_data_size = res_APDU_size + 1; diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 1c3f6e5..e522d3f 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -45,7 +45,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { CredExtensions extensions = { 0 }; //options.present = true; //options.up = ptrue; - //options.uv = pfalse; + options.uv = pfalse; //options.rk = pfalse; CBOR_CHECK(cbor_parser_init(data, len, 0, &parser, &map)); @@ -246,7 +246,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { //else if (options.up == NULL) //5.7 //rup = ptrue; } - if (pinUvAuthParam.present == false && options.uv != ptrue && file_has_data(ef_pin)) { //8.1 + if (pinUvAuthParam.present == false && options.uv == pfalse && file_has_data(ef_pin)) { //8.1 CBOR_ERROR(CTAP2_ERR_PUAT_REQUIRED); } if (enterpriseAttestation > 0) { From 2fca44540aa753710045884ea1df17476fe9c055 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 13 Sep 2024 21:04:21 +0200 Subject: [PATCH 03/51] Add sha256 hardware accelerator. 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 108cfec..1bf323c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 108cfec47c8b72472acbf6d3f8cc50260bfb09bd +Subproject commit 1bf323c36789e7c1a9273ca7ae5f3ad221fcbef5 From cf5dbc9ae511c1a8f685a6208947d74171bbaf5e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 18 Sep 2024 19:42:14 +0200 Subject: [PATCH 04/51] Add support for dynamic VIDPID via PHY. Signed-off-by: Pol Henarejos --- src/fido/cbor_config.c | 55 +++++++++++++++++++++++++++++++++++++++--- src/fido/cbor_vendor.c | 53 ++++++---------------------------------- src/fido/ctap.h | 2 ++ 3 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index d12b11a..e29eb2b 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -27,6 +27,7 @@ #include "mbedtls/ecdh.h" #include "mbedtls/chachapoly.h" #include "mbedtls/sha256.h" +#include "file.h" extern uint8_t keydev_dec[32]; extern bool has_keydev_dec; @@ -35,7 +36,7 @@ int cbor_config(const uint8_t *data, size_t len) { CborParser parser; CborValue map; CborError error = CborNoError; - uint64_t subcommand = 0, pinUvAuthProtocol = 0, vendorCommandId = 0, newMinPinLength = 0; + uint64_t subcommand = 0, pinUvAuthProtocol = 0, vendorCommandId = 0, newMinPinLength = 0, vendorParam = 0; CborByteString pinUvAuthParam = { 0 }, vendorAutCt = { 0 }; CborCharString minPinLengthRPIDs[32] = { 0 }; size_t resp_size = 0, raw_subpara_len = 0, minPinLengthRPIDs_len = 0; @@ -65,7 +66,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 == 0x7f) { + if (subcommand == 0x7f) { // Config Aut CBOR_FIELD_GET_UINT(subpara, 2); if (subpara == 0x01) { CBOR_FIELD_GET_UINT(vendorCommandId, 2); @@ -74,7 +75,7 @@ int cbor_config(const uint8_t *data, size_t len) { CBOR_FIELD_GET_BYTES(vendorAutCt, 2); } } - else if (subcommand == 0x03) { + else if (subcommand == 0x03) { // Extensions CBOR_FIELD_GET_UINT(subpara, 2); if (subpara == 0x01) { CBOR_FIELD_GET_UINT(newMinPinLength, 2); @@ -94,6 +95,15 @@ int cbor_config(const uint8_t *data, size_t len) { CBOR_FIELD_GET_BOOL(forceChangePin, 2); } } + else if (subcommand == 0x1B) { // PHY + CBOR_FIELD_GET_UINT(subpara, 2); + if (subpara == 0x01) { + CBOR_FIELD_GET_UINT(vendorCommandId, 2); + } + else if (subpara == 0x02) { + CBOR_FIELD_GET_UINT(vendorParam, 2); + } + } } CBOR_PARSE_MAP_END(_f1, 2); raw_subpara_len = cbor_value_get_next_byte(&_f1) - raw_subpara; @@ -212,6 +222,45 @@ int cbor_config(const uint8_t *data, size_t len) { set_opts(get_opts() | FIDO2_OPT_EA); goto err; } +#ifndef ENABLE_EMULATION + else if (subcommand == 0x1B) { + uint8_t tmp[PHY_MAX_SIZE]; + memset(tmp, 0, sizeof(tmp)); + uint16_t opts = 0; + if (file_has_data(ef_phy)) { + memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy))); + if (file_get_size(ef_phy) >= 8) { + opts = (tmp[PHY_OPTS] << 8) | tmp[PHY_OPTS + 1]; + } + } + if (vendorCommandId == CTAP_CONFIG_PHY_VIDPID) { + if (vendorParam != 0) { + uint8_t d[4] = { (vendorParam >> 24) & 0xFF, (vendorParam >> 16) & 0xFF, (vendorParam >> 8) & 0xFF, vendorParam & 0xFF }; + memcpy(tmp + PHY_VID, d, sizeof(d)); + opts |= PHY_OPT_VPID; + } + else { + CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); + } + } + else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) { + if (vendorParam != 0) { + uint16_t opt = (uint16_t)vendorParam; + opts = (opts & ~PHY_OPT_MASK) | (opt & PHY_OPT_MASK); + } + else { + CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); + } + } + else { + CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); + } + tmp[PHY_OPTS] = opts >> 8; + tmp[PHY_OPTS + 1] = opts & 0xff; + file_put_data(ef_phy, tmp, sizeof(tmp)); + low_flash_available(); + } +#endif else { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index 3e99c92..d2ef5f4 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -37,14 +37,7 @@ int mse_decrypt_ct(uint8_t *data, size_t len) { mbedtls_chachapoly_context chatx; mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12); - int ret = mbedtls_chachapoly_auth_decrypt(&chatx, - len - 16, - mse.key_enc, - mse.Qpt, - 65, - data + len - 16, - data, - data); + int ret = mbedtls_chachapoly_auth_decrypt(&chatx, len - 16, mse.key_enc, mse.Qpt, 65, data + len - 16, data, data); mbedtls_chachapoly_free(&chatx); return ret; } @@ -112,8 +105,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1)); CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); - CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, file_get_data(ef_keydev_enc), - file_get_size(ef_keydev_enc))); + CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, file_get_data(ef_keydev_enc), file_get_size(ef_keydev_enc))); } else if (vendorCmd == 0x02) { if (vendorParam.present == false) { @@ -140,11 +132,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { mbedtls_ecdh_context hkey; mbedtls_ecdh_init(&hkey); mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1); - int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, - &hkey.ctx.mbed_ecdh.d, - &hkey.ctx.mbed_ecdh.Q, - random_gen, - NULL); + int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen, NULL); mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1); if (ret != 0) { CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); @@ -160,37 +148,19 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { uint8_t buf[MBEDTLS_ECP_MAX_BYTES]; size_t olen = 0; - ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, - &hkey.ctx.mbed_ecdh.Qp, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, - mse.Qpt, - sizeof(mse.Qpt)); + ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Qp, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, mse.Qpt,sizeof(mse.Qpt)); if (ret != 0) { mbedtls_ecdh_free(&hkey); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); } - ret = mbedtls_ecdh_calc_secret(&hkey, - &olen, - buf, - MBEDTLS_ECP_MAX_BYTES, - random_gen, - NULL); + ret = mbedtls_ecdh_calc_secret(&hkey, &olen, buf, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); if (ret != 0) { mbedtls_ecdh_free(&hkey); mbedtls_platform_zeroize(buf, sizeof(buf)); CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER); } - ret = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), - NULL, - 0, - buf, - olen, - mse.Qpt, - sizeof(mse.Qpt), - mse.key_enc, - sizeof(mse.key_enc)); + ret = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0, buf, olen, mse.Qpt, sizeof(mse.Qpt), mse.key_enc, sizeof(mse.key_enc)); mbedtls_platform_zeroize(buf, sizeof(buf)); if (ret != 0) { mbedtls_ecdh_free(&hkey); @@ -248,9 +218,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { } 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 %s", pico_serial_str); + snprintf((char *) buffer, sizeof(buffer), "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); @@ -258,12 +226,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { key.pk_ctx = &ekey; mbedtls_x509write_csr_set_key(&ctx, &key); mbedtls_x509write_csr_set_md_alg(&ctx, MBEDTLS_MD_SHA256); - mbedtls_x509write_csr_set_extension(&ctx, - "\x2B\x06\x01\x04\x01\x82\xE5\x1C\x01\x01\x04", - 0xB, - 0, - aaguid, - sizeof(aaguid)); + mbedtls_x509write_csr_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xE5\x1C\x01\x01\x04", 0xB, 0, aaguid, sizeof(aaguid)); ret = mbedtls_x509write_csr_der(&ctx, buffer, sizeof(buffer), random_gen, NULL); mbedtls_ecdsa_free(&ekey); if (ret <= 0) { diff --git a/src/fido/ctap.h b/src/fido/ctap.h index 79d00f6..1a82ade 100644 --- a/src/fido/ctap.h +++ b/src/fido/ctap.h @@ -114,6 +114,8 @@ typedef struct { #define CTAP_CONFIG_AUT_ENABLE 0x03e43f56b34285e2 #define CTAP_CONFIG_AUT_DISABLE 0x1831a40f04a25ed9 +#define CTAP_CONFIG_PHY_VIDPID 0x6fcb19b0cbe3acfa +#define CTAP_CONFIG_PHY_OPTS 0x969f3b09eceb805f #define CTAP_VENDOR_CBOR (CTAPHID_VENDOR_FIRST + 1) From ffbe3fcbadbb16751979a45f7ea03804275c60cd Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 18 Sep 2024 19:43:54 +0200 Subject: [PATCH 05/51] Add OTP support and sha256 hardware acceleration. 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 1bf323c..739e9f1 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 1bf323c36789e7c1a9273ca7ae5f3ad221fcbef5 +Subproject commit 739e9f1b98c4f8aacedfa67a11df87d773ebf776 From 39e2ff40c3fa03564efaad8caaf4f314fb2473a3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 18 Sep 2024 19:44:02 +0200 Subject: [PATCH 06/51] Add support for dynamic VIDPID via PHY. Signed-off-by: Pol Henarejos --- tools/pico-fido-tool.py | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 89d1615..5cd8240 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -77,11 +77,15 @@ class VendorConfig(Config): class PARAM(IntEnum): VENDOR_COMMAND_ID = 0x01 VENDOR_AUT_CT = 0x02 + VENDOR_PARAM = 0x02 class CMD(IntEnum): - CONFIG_AUT_ENABLE = 0x03e43f56b34285e2 - CONFIG_AUT_DISABLE = 0x1831a40f04a25ed9 + CONFIG_AUT_ENABLE = 0x03e43f56b34285e2 + CONFIG_AUT_DISABLE = 0x1831a40f04a25ed9 CONFIG_VENDOR_PROTOTYPE = 0x7f + CONFIG_VENDOR_PHY = 0x1b + CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa + CONFIG_PHY_OPTS = 0x969f3b09eceb805f class RESP(IntEnum): KEY_AGREEMENT = 0x01 @@ -106,6 +110,15 @@ def disable_device_aut(self): }, ) + def vidpid(self, vid, pid): + self._call( + VendorConfig.CMD.CONFIG_VENDOR_PHY, + { + VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_VIDPID, + VendorConfig.PARAM.VENDOR_PARAM: (vid & 0xFFFF) << 16 | pid + }, + ) + class Ctap2Vendor(Ctap2): def __init__(self, device: CtapDevice, strict_cbor: bool = True): super().__init__(device=device, strict_cbor=strict_cbor) @@ -393,6 +406,9 @@ def upload_ea(self, der): } ) + def vidpid(self, vid, pid): + return self.vcfg.vidpid(vid, pid) + def parse_args(): parser = argparse.ArgumentParser() subparser = parser.add_subparsers(title="commands", dest="command") @@ -408,6 +424,11 @@ def parse_args(): parser_attestation.add_argument('subcommand', choices=['csr']) parser_attestation.add_argument('--filename', help='Uploads the certificate filename to the device as enterprise attestation certificate. If not provided, it will generate an enterprise attestation certificate automatically.') + parser_phy = subparser.add_parser('phy', help='Set PHY options.') + subparser_phy = parser_phy.add_subparsers(title='commands', dest='subcommand', required=True) + parser_phy_vp = subparser_phy.add_parser('vidpid', help='Sets VID/PID. Use VID:PID format (e.g. 1234:5678)') + parser_phy_vp.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + args = parser.parse_args() return args @@ -441,8 +462,22 @@ def attestation(vdr, args): cert = x509.load_pem_x509_certificate(dataf) vdr.upload_ea(cert.public_bytes(Encoding.DER)) +def phy(vdr, args): + val = args.value if 'value' in args else None + if (val): + if (args.subcommand == 'vidpid'): + sp = val.split(':') + if (len(sp) != 2): + print('ERROR: VID/PID have wrong format. Use VID:PID format (e.g. 1234:5678)') + ret = vdr.vidpid(int(sp[0],16), int(sp[1],16)) + if (ret): + print(f'Current value: {hexlify(ret)}') + else: + print('Command executed successfully. Please, restart your Pico Key.') + + def main(args): - print('Pico Fido Tool v1.6') + print('Pico Fido Tool v1.8') print('Author: Pol Henarejos') print('Report bugs to https://github.com/polhenarejos/pico-fido/issues') print('') @@ -460,6 +495,8 @@ def main(args): backup(vdr, args) elif (args.command == 'attestation'): attestation(vdr, args) + elif (args.command == 'phy'): + phy(vdr, args) def run(): args = parse_args() From 6f517e8fca3cd1871c228b675d40e0d6a117e522 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 18:26:04 +0200 Subject: [PATCH 07/51] Fix header in Linux. Fixes #63 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 739e9f1..839e824 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 739e9f1b98c4f8aacedfa67a11df87d773ebf776 +Subproject commit 839e8244d95aeef8f83748f13a73781952185cca From f276e993421667e51aa44d3fef5e0f5b13f9696b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 19:26:04 +0200 Subject: [PATCH 08/51] Add autobuild for ESP32 Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 1 + workflows/autobuild_esp32.sh | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 workflows/autobuild_esp32.sh diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b32ec43..77a6674 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -67,6 +67,7 @@ jobs: - run: | echo "Run, Build Application using script" ./workflows/autobuild.sh + ./workflows/autobuild_esp32.sh - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh new file mode 100644 index 0000000..11d8e29 --- /dev/null +++ b/workflows/autobuild_esp32.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +git submodule update --init --recursive +sudo apt update +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 submodule update --init +cd .. +mkdir build +cd build +cmake -DPICO_SDK_PATH=../pico-sdk .. +make + +sudo apt install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 +git clone --recursive https://github.com/espressif/esp-idf.git +cd esp-idf +./install.sh esp32s3 +. ./export.sh +cd .. +mkdir build_esp +cd build_esp +idf.py all From 38eca2fdd4fa27c0b4ee6a5112b597dbfa0e5156 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 19:30:03 +0200 Subject: [PATCH 09/51] Fix permissions. Signed-off-by: Pol Henarejos --- workflows/autobuild_esp32.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 workflows/autobuild_esp32.sh diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh old mode 100644 new mode 100755 From e05115ffaca4fbbf3b3414b697be5c4a2ce3075b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 19:37:01 +0200 Subject: [PATCH 10/51] Fix autobuild for ESP32. Signed-off-by: Pol Henarejos --- workflows/autobuild_esp32.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh index 11d8e29..aba7c35 100755 --- a/workflows/autobuild_esp32.sh +++ b/workflows/autobuild_esp32.sh @@ -2,16 +2,6 @@ git submodule update --init --recursive sudo apt update -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 submodule update --init -cd .. -mkdir build -cd build -cmake -DPICO_SDK_PATH=../pico-sdk .. -make - sudo apt install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 git clone --recursive https://github.com/espressif/esp-idf.git cd esp-idf From e07b5194e350d97bc4e666279f2f384ea60d47fa Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 19:47:27 +0200 Subject: [PATCH 11/51] Fix again... Signed-off-by: Pol Henarejos --- workflows/autobuild_esp32.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh index aba7c35..1055d9e 100755 --- a/workflows/autobuild_esp32.sh +++ b/workflows/autobuild_esp32.sh @@ -8,6 +8,4 @@ cd esp-idf ./install.sh esp32s3 . ./export.sh cd .. -mkdir build_esp -cd build_esp idf.py all From 7071949a1f919b2e2445957819e36da592bdb7b0 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 19:55:18 +0200 Subject: [PATCH 12/51] More fixes Signed-off-by: Pol Henarejos --- workflows/autobuild_esp32.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh index 1055d9e..7bcea55 100755 --- a/workflows/autobuild_esp32.sh +++ b/workflows/autobuild_esp32.sh @@ -8,4 +8,5 @@ cd esp-idf ./install.sh esp32s3 . ./export.sh cd .. +rm -rf build idf.py all From 4fe1c0804c1fe95637a65d94a1c16fcfd4eead89 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 20:12:52 +0200 Subject: [PATCH 13/51] Add set target to ESP32-S3 Signed-off-by: Pol Henarejos --- workflows/autobuild_esp32.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh index 7bcea55..eb8e7b8 100755 --- a/workflows/autobuild_esp32.sh +++ b/workflows/autobuild_esp32.sh @@ -9,4 +9,5 @@ cd esp-idf . ./export.sh cd .. rm -rf build +idf.py set-target esp32s3 idf.py all From f98df743f97c544264e6f0ec33bc7105b0540e7f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 19 Sep 2024 20:27:00 +0200 Subject: [PATCH 14/51] Upgrade CodeQL to v3 Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 4 ++-- workflows/autobuild.sh | 4 ++-- workflows/autobuild_esp32.sh | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 77a6674..85212bc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -42,7 +42,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -70,4 +70,4 @@ jobs: ./workflows/autobuild_esp32.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index 09ef1c7..c128ad9 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -7,7 +7,7 @@ git clone https://github.com/raspberrypi/pico-sdk cd pico-sdk git submodule update --init cd .. -mkdir build -cd build +mkdir build_pico +cd build_pico cmake -DPICO_SDK_PATH=../pico-sdk .. make diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh index eb8e7b8..12c12c7 100755 --- a/workflows/autobuild_esp32.sh +++ b/workflows/autobuild_esp32.sh @@ -8,6 +8,5 @@ cd esp-idf ./install.sh esp32s3 . ./export.sh cd .. -rm -rf build idf.py set-target esp32s3 idf.py all From 2e16036bb5f0189576a1afc060ce735e7fcc1c26 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 24 Sep 2024 00:44:58 +0200 Subject: [PATCH 15/51] Update pico_sdk_import Signed-off-by: Pol Henarejos --- pico_sdk_import.cmake | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake index 28efe9e..a0721d0 100644 --- a/pico_sdk_import.cmake +++ b/pico_sdk_import.cmake @@ -18,9 +18,20 @@ if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_P message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") endif () +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_TAG} AND (NOT PICO_SDK_FETCH_FROM_GIT_TAG)) + set(PICO_SDK_FETCH_FROM_GIT_TAG $ENV{PICO_SDK_FETCH_FROM_GIT_TAG}) + message("Using PICO_SDK_FETCH_FROM_GIT_TAG from environment ('${PICO_SDK_FETCH_FROM_GIT_TAG}')") +endif () + +if (PICO_SDK_FETCH_FROM_GIT AND NOT PICO_SDK_FETCH_FROM_GIT_TAG) + set(PICO_SDK_FETCH_FROM_GIT_TAG "master") + message("Using master as default value for PICO_SDK_FETCH_FROM_GIT_TAG") +endif() + set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") +set(PICO_SDK_FETCH_FROM_GIT_TAG "${PICO_SDK_FETCH_FROM_GIT_TAG}" CACHE FILEPATH "release tag for SDK") if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT) @@ -29,11 +40,22 @@ if (NOT PICO_SDK_PATH) if (PICO_SDK_FETCH_FROM_GIT_PATH) get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") endif () - FetchContent_Declare( - pico_sdk - GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk - GIT_TAG master - ) + # GIT_SUBMODULES_RECURSE was added in 3.17 + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + GIT_SUBMODULES_RECURSE FALSE + ) + else () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + ) + endif () + if (NOT pico_sdk) message("Downloading Raspberry Pi Pico SDK") FetchContent_Populate(pico_sdk) From 0e54998d584af3016f07034a851016bb6dde7128 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 11:09:13 +0200 Subject: [PATCH 16/51] Add nightly deploy workflow Signed-off-by: Pol Henarejos --- .github/workflows/nightly.yml | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000..19fbc81 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,37 @@ +name: "Nightly deploy" + +on: + push: + branches: [ "main", "development" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main", "development" ] + schedule: + - cron: '0 2 * * *' + workflow_dispatch: + +jobs: + nightly: + name: Deploy nightly + strategy: + fail-fast: false + matrix: + refs: [main, development] + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ matrix.refs }} + submodules: 'recursive' + - name : Build + run: | + ./workflows/autobuild.sh + ./build_pico_fido.sh + - name: Update nightly release + uses: pyTooling/Actions/releaser@main + with: + tag: nightly-${{ matrix.refs }} + rm: true + token: ${{ secrets.GITHUB_TOKEN }} + files: release/*.* From cbef14beec8c5d088ee73edd722e44c3c37ca265 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 11:09:34 +0200 Subject: [PATCH 17/51] Add manual trigger to workflows Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 1 + .github/workflows/test.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 85212bc..42c5133 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,6 +19,7 @@ on: branches: [ "main", "development" ] schedule: - cron: '23 5 * * 4' + workflow_dispatch: jobs: analyze: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 88a4cbf..0a55586 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,7 @@ on: branches: [ "main", "development" ] schedule: - cron: '23 5 * * 4' + workflow_dispatch: jobs: build: From 7bc4a703192363a082d038a696cd9001fa1fc430 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 11:20:43 +0200 Subject: [PATCH 18/51] Fix nightly build Signed-off-by: Pol Henarejos --- .github/workflows/nightly.yml | 7 ++----- build_pico_fido.sh | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 19fbc81..4ad3de3 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,11 +1,6 @@ name: "Nightly deploy" on: - push: - branches: [ "main", "development" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main", "development" ] schedule: - cron: '0 2 * * *' workflow_dispatch: @@ -25,6 +20,8 @@ jobs: ref: ${{ matrix.refs }} submodules: 'recursive' - name : Build + env: + PICO_SDK_PATH: ../pico-sdk run: | ./workflows/autobuild.sh ./build_pico_fido.sh diff --git a/build_pico_fido.sh b/build_pico_fido.sh index 332a14b..b661942 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -4,6 +4,8 @@ VERSION_MAJOR="5" VERSION_MINOR="12" rm -rf release/* +mkdir -p build_release +mkdir -p release cd build_release for board in 0xcb_helios \ @@ -96,7 +98,7 @@ for board in 0xcb_helios \ wiznet_w5100s_evb_pico do rm -rf * - PICO_SDK_PATH=../../pico-sdk cmake .. -DPICO_BOARD=$board + PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" cmake .. -DPICO_BOARD=$board make -kj20 mv pico_fido.uf2 ../release/pico_fido_$board-$VERSION_MAJOR.$VERSION_MINOR.uf2 From 24521dff4ba496900bb9011a3570f0cecbb6b5d5 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 11:25:21 +0200 Subject: [PATCH 19/51] Add nightly builds to main Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 6 ++++-- .github/workflows/nightly.yml | 34 ++++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 1 + build_pico_fido.sh | 4 +++- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b32ec43..42c5133 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,6 +19,7 @@ on: branches: [ "main", "development" ] schedule: - cron: '23 5 * * 4' + workflow_dispatch: jobs: analyze: @@ -42,7 +43,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -67,6 +68,7 @@ jobs: - run: | echo "Run, Build Application using script" ./workflows/autobuild.sh + ./workflows/autobuild_esp32.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000..4ad3de3 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,34 @@ +name: "Nightly deploy" + +on: + schedule: + - cron: '0 2 * * *' + workflow_dispatch: + +jobs: + nightly: + name: Deploy nightly + strategy: + fail-fast: false + matrix: + refs: [main, development] + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ matrix.refs }} + submodules: 'recursive' + - name : Build + env: + PICO_SDK_PATH: ../pico-sdk + run: | + ./workflows/autobuild.sh + ./build_pico_fido.sh + - name: Update nightly release + uses: pyTooling/Actions/releaser@main + with: + tag: nightly-${{ matrix.refs }} + rm: true + token: ${{ secrets.GITHUB_TOKEN }} + files: release/*.* diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 88a4cbf..0a55586 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,7 @@ on: branches: [ "main", "development" ] schedule: - cron: '23 5 * * 4' + workflow_dispatch: jobs: build: diff --git a/build_pico_fido.sh b/build_pico_fido.sh index 332a14b..b661942 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -4,6 +4,8 @@ VERSION_MAJOR="5" VERSION_MINOR="12" rm -rf release/* +mkdir -p build_release +mkdir -p release cd build_release for board in 0xcb_helios \ @@ -96,7 +98,7 @@ for board in 0xcb_helios \ wiznet_w5100s_evb_pico do rm -rf * - PICO_SDK_PATH=../../pico-sdk cmake .. -DPICO_BOARD=$board + PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" cmake .. -DPICO_BOARD=$board make -kj20 mv pico_fido.uf2 ../release/pico_fido_$board-$VERSION_MAJOR.$VERSION_MINOR.uf2 From b2e45b0f7f495c5bb76e9521fd2363ca3e278d32 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 11:33:29 +0200 Subject: [PATCH 20/51] Fix build for boards with WS2812. 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 839e824..30df1d9 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 839e8244d95aeef8f83748f13a73781952185cca +Subproject commit 30df1d9202c2b35dc0e0f0b51081b269ecff408f From effb8e4063a656b78c8aeb334efd19a30f219c01 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 12:01:55 +0200 Subject: [PATCH 21/51] Fix build for WS2812 boards. 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 30df1d9..86674fd 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 30df1d9202c2b35dc0e0f0b51081b269ecff408f +Subproject commit 86674fd6caaa40accf47f59db0df817d894aba11 From 1f839c5f9943fe78f2b3c66a1eee2a4d6d2e6ab1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 13:24:29 +0200 Subject: [PATCH 22/51] Append sha to nightly builds. Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index b661942..c74225e 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -2,6 +2,12 @@ VERSION_MAJOR="5" VERSION_MINOR="12" +SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}" +if [[ -z "${GITHUB_SHA}" ]]; then +; +else + SUFFIX="${SUFFIX}.${GITHUB_SHA}" +fi rm -rf release/* mkdir -p build_release @@ -99,7 +105,6 @@ for board in 0xcb_helios \ do rm -rf * PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" cmake .. -DPICO_BOARD=$board - make -kj20 - mv pico_fido.uf2 ../release/pico_fido_$board-$VERSION_MAJOR.$VERSION_MINOR.uf2 - + make -j`nproc` + mv pico_fido.uf2 ../release/pico_fido_$board-$SUFFIX.uf2 done From ed560f10a43cbce1d04d83cfc6f025b78f86da5b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 13:24:44 +0200 Subject: [PATCH 23/51] Install picotool Signed-off-by: Pol Henarejos --- workflows/autobuild.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index c128ad9..5130fa1 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -2,12 +2,21 @@ git submodule update --init --recursive sudo apt update -sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib +sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib build-essential pkg-config libusb-1.0-0-dev git clone https://github.com/raspberrypi/pico-sdk cd pico-sdk git submodule update --init cd .. +git clone https://github.com/raspberrypi/picotool +cd picotool +git submodule update --init lib/mbedtls +mkdir build +cd build +cmake .. +make -j`nproc` +sudo make install +cd ../.. mkdir build_pico cd build_pico cmake -DPICO_SDK_PATH=../pico-sdk .. -make +make -j`nproc` From b9e791ca90e2e4c52d71f245a14773516d6fccca Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 13:49:20 +0200 Subject: [PATCH 24/51] Fix nightly build Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 4 +--- workflows/autobuild.sh | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index c74225e..4faa108 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -3,9 +3,7 @@ VERSION_MAJOR="5" VERSION_MINOR="12" SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}" -if [[ -z "${GITHUB_SHA}" ]]; then -; -else +if ! [[ -z "${GITHUB_SHA}" ]]; then SUFFIX="${SUFFIX}.${GITHUB_SHA}" fi diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index 5130fa1..9cb1c3a 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -9,7 +9,7 @@ git submodule update --init cd .. git clone https://github.com/raspberrypi/picotool cd picotool -git submodule update --init lib/mbedtls +git submodule update --init mkdir build cd build cmake .. From e2b06b908eeecf13ebb4fd5a4fffd2c378126ab7 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 15:16:57 +0200 Subject: [PATCH 25/51] Do not add SHA to filename, since it not will be able to rm. Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 6 +++--- workflows/autobuild.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index 4faa108..8308979 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -3,9 +3,9 @@ VERSION_MAJOR="5" VERSION_MINOR="12" SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}" -if ! [[ -z "${GITHUB_SHA}" ]]; then - SUFFIX="${SUFFIX}.${GITHUB_SHA}" -fi +#if ! [[ -z "${GITHUB_SHA}" ]]; then +# SUFFIX="${SUFFIX}.${GITHUB_SHA}" +#fi rm -rf release/* mkdir -p build_release diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index 9cb1c3a..b7d2e28 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -12,7 +12,7 @@ cd picotool git submodule update --init mkdir build cd build -cmake .. +cmake -DPICO_SDK_PATH=../pico-sdk .. make -j`nproc` sudo make install cd ../.. From 623db840d3b3cdbd49c2773c127553a4d603b3b3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 15:36:45 +0200 Subject: [PATCH 26/51] Fix autobuild picotool 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 b7d2e28..b808bbd 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -12,7 +12,7 @@ cd picotool git submodule update --init mkdir build cd build -cmake -DPICO_SDK_PATH=../pico-sdk .. +cmake -DPICO_SDK_PATH=../../pico-sdk .. make -j`nproc` sudo make install cd ../.. From 8838ac9e54e3887e6c32b67860ab42df7d03381c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 19:29:08 +0200 Subject: [PATCH 27/51] Improve led driver support. 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 86674fd..15d81be 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 86674fd6caaa40accf47f59db0df817d894aba11 +Subproject commit 15d81be6ded2d26c5569961f48c7097edb4f6c0b From aeea3c7183394c2f079e45a4fe288d3c60fad63b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 25 Sep 2024 19:40:29 +0200 Subject: [PATCH 28/51] Fix ESP & emulation 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 15d81be..fe396bc 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 15d81be6ded2d26c5569961f48c7097edb4f6c0b +Subproject commit fe396bc5b8139df962186fb804c13b10eae13c3d From 720c2e45f3cc6842497a8a8fbfa54fca54026b6e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 27 Sep 2024 20:21:03 +0200 Subject: [PATCH 29/51] Add support to LED_GPIO and LED_BTNESS vendor options. Signed-off-by: Pol Henarejos --- src/fido/cbor_config.c | 15 +++++++++++++++ src/fido/ctap.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index e29eb2b..9a2ffb3 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -243,6 +243,21 @@ int cbor_config(const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); } } + else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO || vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { + if (vendorParam != 0) { + if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) { + tmp[PHY_LED_GPIO] = (uint8_t)vendorParam; + opts |= PHY_OPT_GPIO; + } + else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { + tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam; + opts |= PHY_OPT_BTNESS; + } + } + else { + CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); + } + } else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) { if (vendorParam != 0) { uint16_t opt = (uint16_t)vendorParam; diff --git a/src/fido/ctap.h b/src/fido/ctap.h index 1a82ade..28f6bb0 100644 --- a/src/fido/ctap.h +++ b/src/fido/ctap.h @@ -115,6 +115,8 @@ typedef struct { #define CTAP_CONFIG_AUT_ENABLE 0x03e43f56b34285e2 #define CTAP_CONFIG_AUT_DISABLE 0x1831a40f04a25ed9 #define CTAP_CONFIG_PHY_VIDPID 0x6fcb19b0cbe3acfa +#define CTAP_CONFIG_PHY_LED_GPIO 0x7b392a394de9f948 +#define CTAP_CONFIG_PHY_LED_BTNESS 0x76a85945985d02fd #define CTAP_CONFIG_PHY_OPTS 0x969f3b09eceb805f #define CTAP_VENDOR_CBOR (CTAPHID_VENDOR_FIRST + 1) From 2d09a5c8e5c67bdf9524233dac9c1ff7264e8e03 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 27 Sep 2024 20:56:33 +0200 Subject: [PATCH 30/51] Added support to configure LED GPIO, LED brightness and LED dimming. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_config.c | 17 +++----- src/fido/cbor_vendor.c | 15 +++++++ src/fido/ctap.h | 1 + tools/pico-fido-tool.py | 87 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 109 insertions(+), 13 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index fe396bc..a816b6f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit fe396bc5b8139df962186fb804c13b10eae13c3d +Subproject commit a816b6f747604c3430faadb66aefba067326f8ed diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index 9a2ffb3..90311c3 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -244,18 +244,13 @@ int cbor_config(const uint8_t *data, size_t len) { } } else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO || vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { - if (vendorParam != 0) { - if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) { - tmp[PHY_LED_GPIO] = (uint8_t)vendorParam; - opts |= PHY_OPT_GPIO; - } - else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { - tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam; - opts |= PHY_OPT_BTNESS; - } + if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) { + tmp[PHY_LED_GPIO] = (uint8_t)vendorParam; + opts |= PHY_OPT_GPIO; } - else { - CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); + else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { + tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam; + opts |= PHY_OPT_BTNESS; } } else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) { diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index d2ef5f4..215056d 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -249,6 +249,21 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { goto err; } } + else if (cmd == CTAP_VENDOR_PHY_OPTS) { + if (vendorCmd == 0x01) { + uint16_t opts = 0; + if (file_has_data(ef_phy)) { + uint8_t *data = file_get_data(ef_phy); + opts = (data[PHY_OPTS] << 8) | data[PHY_OPTS+1]; + } + CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1)); + CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01)); + CBOR_CHECK(cbor_encode_uint(&mapEncoder, opts)); + } + else { + CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); + } + } else { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } diff --git a/src/fido/ctap.h b/src/fido/ctap.h index 28f6bb0..6d22edf 100644 --- a/src/fido/ctap.h +++ b/src/fido/ctap.h @@ -125,6 +125,7 @@ typedef struct { #define CTAP_VENDOR_MSE 0x02 #define CTAP_VENDOR_UNLOCK 0x03 #define CTAP_VENDOR_EA 0x04 +#define CTAP_VENDOR_PHY_OPTS 0x05 #define CTAP_PERMISSION_MC 0x01 // MakeCredential #define CTAP_PERMISSION_GA 0x02 // GetAssertion diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 5cd8240..5d0d173 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -86,6 +86,8 @@ class CMD(IntEnum): CONFIG_VENDOR_PHY = 0x1b CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa CONFIG_PHY_OPTS = 0x969f3b09eceb805f + CONFIG_PHY_LED_GPIO = 0x7b392a394de9f948 + CONFIG_PHY_LED_BTNESS = 0x76a85945985d02fd class RESP(IntEnum): KEY_AGREEMENT = 0x01 @@ -119,6 +121,33 @@ def vidpid(self, vid, pid): }, ) + def led_gpio(self, gpio): + self._call( + VendorConfig.CMD.CONFIG_VENDOR_PHY, + { + VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_GPIO, + VendorConfig.PARAM.VENDOR_PARAM: gpio + }, + ) + + def led_brightness(self, brightness): + self._call( + VendorConfig.CMD.CONFIG_VENDOR_PHY, + { + VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_BTNESS, + VendorConfig.PARAM.VENDOR_PARAM: brightness + }, + ) + + def phy_opts(self, opts): + self._call( + VendorConfig.CMD.CONFIG_VENDOR_PHY, + { + VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_OPTS, + VendorConfig.PARAM.VENDOR_PARAM: opts + }, + ) + class Ctap2Vendor(Ctap2): def __init__(self, device: CtapDevice, strict_cbor: bool = True): super().__init__(device=device, strict_cbor=strict_cbor) @@ -203,6 +232,7 @@ class CMD(IntEnum): VENDOR_MSE = 0x02 VENDOR_UNLOCK = 0x03 VENDOR_EA = 0x04 + VENDOR_PHY = 0x05 @unique class PARAM(IntEnum): @@ -220,6 +250,10 @@ class RESP(IntEnum): PARAM = 0x01 COSE_KEY = 0x02 + class PHY_OPTS(IntEnum): + PHY_OPT_WCID = 0x1 + PHY_OPT_DIMM = 0x10 + def __init__( self, ctap: Ctap2Vendor, @@ -409,6 +443,38 @@ def upload_ea(self, der): def vidpid(self, vid, pid): return self.vcfg.vidpid(vid, pid) + def led_gpio(self, gpio): + return self.vcfg.led_gpio(gpio) + + def led_brightness(self, brightness): + if (brightness > 15): + print('ERROR: Brightness must be between 0 and 15') + return + return self.vcfg.led_brightness(brightness) + + def led_dimmable(self, onoff): + opts = self.phy_opts() + if (onoff): + opts |= Vendor.PHY_OPTS.PHY_OPT_DIMM + else: + opts &= ~Vendor.PHY_OPTS.PHY_OPT_DIMM + print(f'opts: {opts}') + return self.vcfg.phy_opts(opts) + + def wcid(self, onoff): + opts = self.phy_opts() + if (onoff): + opts |= Vendor.PHY_OPTS.PHY_OPT_WCID + else: + opts &= ~Vendor.PHY_OPTS.PHY_OPT_WCID + return self.vcfg.phy_opts(opts) + + def phy_opts(self): + return self._call( + Vendor.CMD.VENDOR_PHY, + Vendor.SUBCMD.ENABLE, + )[Vendor.RESP.PARAM] + def parse_args(): parser = argparse.ArgumentParser() subparser = parser.add_subparsers(title="commands", dest="command") @@ -428,6 +494,14 @@ def parse_args(): subparser_phy = parser_phy.add_subparsers(title='commands', dest='subcommand', required=True) parser_phy_vp = subparser_phy.add_parser('vidpid', help='Sets VID/PID. Use VID:PID format (e.g. 1234:5678)') parser_phy_vp.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_phy_ledn = subparser_phy.add_parser('led_gpio', help='Sets LED GPIO number.') + parser_phy_ledn.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_phy_optwcid = subparser_phy.add_parser('wcid', help='Enable/Disable Web CCID interface.') + parser_phy_optwcid.add_argument('value', choices=['enable', 'disable'], help='Enable/Disable Web CCID interface.', nargs='?') + parser_phy_ledbtness = subparser_phy.add_parser('led_brightness', help='Sets LED max. brightness.') + parser_phy_ledbtness.add_argument('value', help='Value of the max. brightness.', metavar='VAL', nargs='?') + parser_phy_optdimm = subparser_phy.add_parser('led_dimmable', help='Enable/Disable LED dimming.') + parser_phy_optdimm.add_argument('value', choices=['enable', 'disable'], help='Enable/Disable LED dimming.', nargs='?') args = parser.parse_args() return args @@ -469,7 +543,18 @@ def phy(vdr, args): sp = val.split(':') if (len(sp) != 2): print('ERROR: VID/PID have wrong format. Use VID:PID format (e.g. 1234:5678)') - ret = vdr.vidpid(int(sp[0],16), int(sp[1],16)) + ret = vdr.vidpid(int(sp[0],16), int(sp[1],16)) + elif (args.subcommand == 'led_gpio'): + val = int(val) + ret = vdr.led_gpio(val) + elif (args.subcommand == 'led_brightness'): + val = int(val) + ret = vdr.led_brightness(val) + elif (args.subcommand == 'led_dimmable'): + ret = vdr.led_dimmable(val == 'enable') + elif (args.subcommand == 'wcid'): + ret = vdr.wcid(val == 'enable') + if (ret): print(f'Current value: {hexlify(ret)}') else: From dc07653ae753cb0c318df4e00c099da7e027019f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 27 Sep 2024 21:00:39 +0200 Subject: [PATCH 31/51] Fix emulation build. Signed-off-by: Pol Henarejos --- src/fido/cbor_vendor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fido/cbor_vendor.c b/src/fido/cbor_vendor.c index 215056d..501a22e 100644 --- a/src/fido/cbor_vendor.c +++ b/src/fido/cbor_vendor.c @@ -249,6 +249,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { goto err; } } +#ifndef ENABLE_EMULATION else if (cmd == CTAP_VENDOR_PHY_OPTS) { if (vendorCmd == 0x01) { uint16_t opts = 0; @@ -264,6 +265,7 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } } + #endif else { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } From 53ed3a46c41912a302e238dcef680d3fad9c7f65 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 1 Oct 2024 09:34:22 +0200 Subject: [PATCH 32/51] Add autobuild for local. Harmonize with other repos. Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 4 ++-- workflows/autobuild.sh | 21 +++++++++++++++++++-- workflows/autobuild_esp32.sh | 12 ------------ 3 files changed, 21 insertions(+), 16 deletions(-) delete mode 100755 workflows/autobuild_esp32.sh diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 42c5133..ba8d07f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,6 +36,7 @@ jobs: language: [ 'cpp', 'python' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + mode: [ 'pico', 'esp32', 'local' ] steps: - name: Checkout repository @@ -67,8 +68,7 @@ jobs: - run: | echo "Run, Build Application using script" - ./workflows/autobuild.sh - ./workflows/autobuild_esp32.sh + ./workflows/autobuild.sh ${{ matrix.mode }} - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index b808bbd..d90e1a4 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -2,7 +2,9 @@ git submodule update --init --recursive sudo apt update -sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib build-essential pkg-config libusb-1.0-0-dev + +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 submodule update --init @@ -19,4 +21,19 @@ cd ../.. mkdir build_pico cd build_pico cmake -DPICO_SDK_PATH=../pico-sdk .. -make -j`nproc` +make +elif [[ $1 == "esp32" ]]; then +sudo apt install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 +git clone --recursive https://github.com/espressif/esp-idf.git +cd esp-idf +./install.sh esp32s3 +. ./export.sh +cd .. +idf.py set-target esp32s3 +idf.py all +else +mkdir build +cd build +cmake -DENABLE_EMULATION=1 .. +make +fi diff --git a/workflows/autobuild_esp32.sh b/workflows/autobuild_esp32.sh deleted file mode 100755 index 12c12c7..0000000 --- a/workflows/autobuild_esp32.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -git submodule update --init --recursive -sudo apt update -sudo apt install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 -git clone --recursive https://github.com/espressif/esp-idf.git -cd esp-idf -./install.sh esp32s3 -. ./export.sh -cd .. -idf.py set-target esp32s3 -idf.py all From ef49560d0acbb93b763b98c8bd989d2306bc024e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 2 Oct 2024 11:55:34 +0200 Subject: [PATCH 33/51] Fix nightly build Signed-off-by: Pol Henarejos --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 4ad3de3..7c15511 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -23,7 +23,7 @@ jobs: env: PICO_SDK_PATH: ../pico-sdk run: | - ./workflows/autobuild.sh + ./workflows/autobuild.sh pico ./build_pico_fido.sh - name: Update nightly release uses: pyTooling/Actions/releaser@main From 3ce8496faa31fd2ad723fc12ed3dd3d9456ca170 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 4 Oct 2024 17:53:59 +0200 Subject: [PATCH 34/51] Update workflows. Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 1 - .github/workflows/nightly.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 42c5133..f3fc397 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -68,7 +68,6 @@ jobs: - run: | echo "Run, Build Application using script" ./workflows/autobuild.sh - ./workflows/autobuild_esp32.sh - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 4ad3de3..7c15511 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -23,7 +23,7 @@ jobs: env: PICO_SDK_PATH: ../pico-sdk run: | - ./workflows/autobuild.sh + ./workflows/autobuild.sh pico ./build_pico_fido.sh - name: Update nightly release uses: pyTooling/Actions/releaser@main From 0df1330f92a396bdc8883b4ee6b94afd9cd44e3f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 4 Nov 2024 18:25:42 +0100 Subject: [PATCH 35/51] Add support for commissioning. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_make_credential.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index a816b6f..6f7d92a 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit a816b6f747604c3430faadb66aefba067326f8ed +Subproject commit 6f7d92a5913d4a985cbaa71a0f74df04405ce162 diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index e522d3f..161fb7a 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -364,8 +364,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, l)); if (extensions.credBlob.present == true) { CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder, "credBlob")); - CBOR_CHECK(cbor_encode_boolean(&mapEncoder, - extensions.credBlob.len < MAX_CREDBLOB_LENGTH)); + CBOR_CHECK(cbor_encode_boolean(&mapEncoder, extensions.credBlob.len < MAX_CREDBLOB_LENGTH)); } if (extensions.credProtect != 0) { CBOR_CHECK(cbor_encode_text_stringz(&mapEncoder, "credProtect")); @@ -452,6 +451,21 @@ int cbor_make_credential(const uint8_t *data, size_t len) { ret = mbedtls_ecdsa_write_signature(&ekey, mbedtls_md_get_type(md), hash, mbedtls_md_get_size(md), sig, sizeof(sig), &olen, random_gen, NULL); mbedtls_ecdsa_free(&ekey); + if (user.id.len > 0 && user.parent.name.len > 0 && user.displayName.len > 0) { + if (memcmp(user.parent.name.data, "+pico", 5) == 0) { + options.rk = pfalse; +#ifndef ENABLE_EMULATION + uint8_t *p = (uint8_t *)user.parent.name.data + 5; + if (memcmp(p, "CommissionProfile", 17) == 0) { + ret = parse_phy_data(user.id.data, user.id.len); + } +#endif + if (ret != 0) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } + } + } + uint8_t largeBlobKey[32] = {0}; if (extensions.largeBlobKey == ptrue && options.rk == ptrue) { ret = credential_derive_large_blob_key(cred_id, cred_id_len, largeBlobKey); From e5910b1cbaeeaac35ebaf07126c3a4f86cddb15b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 00:29:32 +0100 Subject: [PATCH 36/51] Enable WCID by default. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89f4936..c89573a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ endif(ENABLE_OTP_APP) if(ENABLE_OTP_APP OR ENABLE_OATH_APP) set(USB_ITF_CCID 1) + set(USB_ITF_WCID 1) else() set(USB_ITF_CCID 0) endif() From 4ce6b2df5c0ab20f6f32bb32ea06bcd617953000 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 00:29:58 +0100 Subject: [PATCH 37/51] Refactor PHY to support more flexible and scalable architecture. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_config.c | 36 ++++++++++++++------------------- src/fido/cbor_make_credential.c | 6 +++++- tools/pico-fido-tool.py | 2 +- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 6f7d92a..e4a3124 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 6f7d92a5913d4a985cbaa71a0f74df04405ce162 +Subproject commit e4a3124876c19ada97332f4a242458878b595f05 diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index 90311c3..ede79a3 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -224,20 +224,11 @@ int cbor_config(const uint8_t *data, size_t len) { } #ifndef ENABLE_EMULATION else if (subcommand == 0x1B) { - uint8_t tmp[PHY_MAX_SIZE]; - memset(tmp, 0, sizeof(tmp)); - uint16_t opts = 0; - if (file_has_data(ef_phy)) { - memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy))); - if (file_get_size(ef_phy) >= 8) { - opts = (tmp[PHY_OPTS] << 8) | tmp[PHY_OPTS + 1]; - } - } if (vendorCommandId == CTAP_CONFIG_PHY_VIDPID) { if (vendorParam != 0) { - uint8_t d[4] = { (vendorParam >> 24) & 0xFF, (vendorParam >> 16) & 0xFF, (vendorParam >> 8) & 0xFF, vendorParam & 0xFF }; - memcpy(tmp + PHY_VID, d, sizeof(d)); - opts |= PHY_OPT_VPID; + phy_data.vid = (vendorParam >> 16) & 0xFFFF; + phy_data.pid = vendorParam & 0xFFFF; + phy_data.vidpid_present = true; } else { CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); @@ -245,18 +236,17 @@ int cbor_config(const uint8_t *data, size_t len) { } else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO || vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) { - tmp[PHY_LED_GPIO] = (uint8_t)vendorParam; - opts |= PHY_OPT_GPIO; + phy_data.led_gpio = (uint8_t)vendorParam; + phy_data.led_gpio_present = true; } else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { - tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam; - opts |= PHY_OPT_BTNESS; + phy_data.led_brightness = (uint8_t)vendorParam; + phy_data.led_brightness_present = true; } } else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) { if (vendorParam != 0) { - uint16_t opt = (uint16_t)vendorParam; - opts = (opts & ~PHY_OPT_MASK) | (opt & PHY_OPT_MASK); + phy_data.opts = (uint16_t)vendorParam; } else { CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); @@ -265,9 +255,13 @@ int cbor_config(const uint8_t *data, size_t len) { else { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); } - tmp[PHY_OPTS] = opts >> 8; - tmp[PHY_OPTS + 1] = opts & 0xff; - file_put_data(ef_phy, tmp, sizeof(tmp)); + 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) != CCID_OK) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } + file_put_data(ef_phy, tmp, tmp_len); low_flash_available(); } #endif diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 161fb7a..ed1fddd 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -457,12 +457,16 @@ int cbor_make_credential(const uint8_t *data, size_t len) { #ifndef ENABLE_EMULATION uint8_t *p = (uint8_t *)user.parent.name.data + 5; if (memcmp(p, "CommissionProfile", 17) == 0) { - ret = parse_phy_data(user.id.data, user.id.len); + ret = phy_unserialize_data(user.id.data, user.id.len, &phy_data); + if (ret == CCID_OK) { + file_put_data(ef_phy, user.id.data, user.id.len); + } } #endif if (ret != 0) { CBOR_ERROR(CTAP2_ERR_PROCESSING); } + low_flash_available(); } } diff --git a/tools/pico-fido-tool.py b/tools/pico-fido-tool.py index 5d0d173..377e6b6 100644 --- a/tools/pico-fido-tool.py +++ b/tools/pico-fido-tool.py @@ -252,7 +252,7 @@ class RESP(IntEnum): class PHY_OPTS(IntEnum): PHY_OPT_WCID = 0x1 - PHY_OPT_DIMM = 0x10 + PHY_OPT_DIMM = 0x2 def __init__( self, From 1fbf3da4f513e5a69657eef2743dc3195345f9b4 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 09:43:07 +0100 Subject: [PATCH 38/51] Fix usb initialization for emulation. 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 e4a3124..27a685b 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit e4a3124876c19ada97332f4a242458878b595f05 +Subproject commit 27a685b93181b66f56a3aa19aa666a69af838c5b From df2977e6adfcccd68b77bc220632b692bba74d4e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 18:21:11 +0100 Subject: [PATCH 39/51] Add rescue app. 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 27a685b..242e357 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 27a685b93181b66f56a3aa19aa666a69af838c5b +Subproject commit 242e357a7482573b565330356351b87811949c45 From 3fad6baf89126c02b3688d92a21d29567ee80678 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 18:21:42 +0100 Subject: [PATCH 40/51] Rename CCID_ code names to PICOKEY_ Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor_config.c | 2 +- src/fido/cbor_make_credential.c | 2 +- src/fido/cmd_authenticate.c | 4 ++-- src/fido/cmd_register.c | 14 +++++++------- src/fido/fido.c | 22 +++++++++++----------- src/fido/management.c | 4 ++-- src/fido/oath.c | 16 ++++++++-------- src/fido/otp.c | 8 ++++---- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 242e357..6625678 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 242e357a7482573b565330356351b87811949c45 +Subproject commit 6625678c3059554ef9fc38c1fd0ff16fa4dbad3e diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index ede79a3..cc44cfc 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -258,7 +258,7 @@ int cbor_config(const uint8_t *data, size_t 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) != CCID_OK) { + if (phy_serialize_data(&phy_data, tmp, &tmp_len) != PICOKEY_OK) { CBOR_ERROR(CTAP2_ERR_PROCESSING); } file_put_data(ef_phy, tmp, tmp_len); diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index ed1fddd..5640b2f 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -458,7 +458,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) { uint8_t *p = (uint8_t *)user.parent.name.data + 5; if (memcmp(p, "CommissionProfile", 17) == 0) { ret = phy_unserialize_data(user.id.data, user.id.len, &phy_data); - if (ret == CCID_OK) { + if (ret == PICOKEY_OK) { file_put_data(ef_phy, user.id.data, user.id.len); } } diff --git a/src/fido/cmd_authenticate.c b/src/fido/cmd_authenticate.c index 81e71a4..aecf75b 100644 --- a/src/fido/cmd_authenticate.c +++ b/src/fido/cmd_authenticate.c @@ -26,7 +26,7 @@ int cmd_authenticate() { CTAP_AUTHENTICATE_REQ *req = (CTAP_AUTHENTICATE_REQ *) apdu.data; CTAP_AUTHENTICATE_RESP *resp = (CTAP_AUTHENTICATE_RESP *) res_APDU; - //if (scan_files(true) != CCID_OK) + //if (scan_files(true) != PICOKEY_OK) // return SW_EXEC_ERROR(); if (apdu.nc < CTAP_CHAL_SIZE + CTAP_APPID_SIZE + 1 + 1) { return SW_WRONG_DATA(); @@ -55,7 +55,7 @@ int cmd_authenticate() { } } free(tmp_kh); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { mbedtls_ecdsa_free(&key); return SW_EXEC_ERROR(); } diff --git a/src/fido/cmd_register.c b/src/fido/cmd_register.c index e06df87..f62bf72 100644 --- a/src/fido/cmd_register.c +++ b/src/fido/cmd_register.c @@ -37,9 +37,9 @@ int u2f_select(app_t *a, uint8_t force) { if (cap_supported(CAP_U2F)) { a->process_apdu = u2f_process_apdu; a->unload = u2f_unload; - return CCID_OK; + return PICOKEY_OK; } - return CCID_ERR_FILE_NOT_FOUND; + return PICOKEY_ERR_FILE_NOT_FOUND; } INITIALIZER ( u2f_ctor ) { @@ -47,7 +47,7 @@ INITIALIZER ( u2f_ctor ) { } int u2f_unload() { - return CCID_OK; + return PICOKEY_OK; } const uint8_t *bogus_firefox = (const uint8_t *) "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; @@ -59,7 +59,7 @@ int cmd_register() { CTAP_REGISTER_RESP *resp = (CTAP_REGISTER_RESP *) res_APDU; resp->registerId = CTAP_REGISTER_ID; resp->keyHandleLen = KEY_HANDLE_LEN; - //if (scan_files(true) != CCID_OK) + //if (scan_files(true) != PICOKEY_OK) // return SW_EXEC_ERROR(); if (apdu.nc != CTAP_APPID_SIZE + CTAP_CHAL_SIZE) { return SW_WRONG_LENGTH(); @@ -77,7 +77,7 @@ int cmd_register() { mbedtls_ecdsa_context key; mbedtls_ecdsa_init(&key); int ret = derive_key(req->appId, true, resp->keyHandleCertSig, MBEDTLS_ECP_DP_SECP256R1, &key); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { mbedtls_ecdsa_free(&key); return SW_EXEC_ERROR(); } @@ -102,12 +102,12 @@ int cmd_register() { mbedtls_ecdsa_init(&key); uint8_t key_dev[32] = {0}; ret = load_keydev(key_dev); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { return SW_EXEC_ERROR(); } ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &key, key_dev, 32); mbedtls_platform_zeroize(key_dev, sizeof(key_dev)); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { mbedtls_ecdsa_free(&key); return SW_EXEC_ERROR(); } diff --git a/src/fido/fido.c b/src/fido/fido.c index cac3d3e..a929ae4 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -68,9 +68,9 @@ int fido_select(app_t *a, uint8_t force) { if (cap_supported(CAP_FIDO2)) { a->process_apdu = fido_process_apdu; a->unload = fido_unload; - return CCID_OK; + return PICOKEY_OK; } - return CCID_ERR_FILE_NOT_FOUND; + return PICOKEY_ERR_FILE_NOT_FOUND; } extern uint8_t (*get_version_major)(); @@ -86,7 +86,7 @@ INITIALIZER ( fido_ctor ) { } int fido_unload() { - return CCID_OK; + return PICOKEY_OK; } mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve) { @@ -178,7 +178,7 @@ int x509_create_cert(mbedtls_ecdsa_context *ecdsa, uint8_t *buffer, size_t buffe int load_keydev(uint8_t *key) { if (has_keydev_dec == false && !file_has_data(ef_keydev)) { - return CCID_ERR_MEMORY_FATAL; + return PICOKEY_ERR_MEMORY_FATAL; } if (has_keydev_dec == true) { @@ -187,14 +187,14 @@ int load_keydev(uint8_t *key) { else { memcpy(key, file_get_data(ef_keydev), file_get_size(ef_keydev)); #ifdef PICO_RP2350 - if (aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != CCID_OK) { - return CCID_EXEC_ERROR; + if (aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != PICOKEY_OK) { + return PICOKEY_EXEC_ERROR; } #endif } //return mkek_decrypt(key, file_get_size(ef_keydev)); - return CCID_OK; + return PICOKEY_OK; } int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *key) { @@ -234,7 +234,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur uint8_t outk[67] = { 0 }; //SECP521R1 key is 66 bytes length int r = 0; memset(outk, 0, sizeof(outk)); - if ((r = load_keydev(outk)) != CCID_OK) { + if ((r = load_keydev(outk)) != PICOKEY_OK) { printf("Error loading keydev: %d\n", r); return r; } @@ -298,7 +298,7 @@ int scan_files() { 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) { + if (ret != PICOKEY_OK) { return ret; } #ifdef PICO_RP2350 @@ -307,7 +307,7 @@ int scan_files() { ret = file_put_data(ef_keydev, kdata, (uint16_t)key_size); mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_ecdsa_free(&ecdsa); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { return ret; } printf(" done!\n"); @@ -372,7 +372,7 @@ int scan_files() { 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); } low_flash_available(); - return CCID_OK; + return PICOKEY_OK; } void scan_all() { diff --git a/src/fido/management.c b/src/fido/management.c index 57cd47c..1141658 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -42,7 +42,7 @@ int man_select(app_t *a, uint8_t force) { scan_all(); init_otp(); } - return CCID_OK; + return PICOKEY_OK; } INITIALIZER ( man_ctor ) { @@ -50,7 +50,7 @@ INITIALIZER ( man_ctor ) { } int man_unload() { - return CCID_OK; + return PICOKEY_OK; } bool cap_supported(uint16_t cap) { diff --git a/src/fido/oath.c b/src/fido/oath.c index b0c7cc4..8e396d1 100644 --- a/src/fido/oath.c +++ b/src/fido/oath.c @@ -100,9 +100,9 @@ int oath_select(app_t *a, uint8_t force) { res_APDU[res_APDU_size++] = 1; res_APDU[res_APDU_size++] = ALG_HMAC_SHA1; apdu.ne = res_APDU_size; - return CCID_OK; + return PICOKEY_OK; } - return CCID_ERR_FILE_NOT_FOUND; + return PICOKEY_ERR_FILE_NOT_FOUND; } INITIALIZER ( oath_ctor ) { @@ -110,7 +110,7 @@ INITIALIZER ( oath_ctor ) { } int oath_unload() { - return CCID_OK; + return PICOKEY_OK; } file_t *find_oath_cred(const uint8_t *name, size_t name_len) { @@ -337,7 +337,7 @@ int calculate_oath(uint8_t truncate, const uint8_t *key, size_t key_len, const u int r = mbedtls_md_hmac(md_info, key + 2, key_len - 2, chal, chal_len, hmac); size_t hmac_size = mbedtls_md_get_size(md_info); if (r != 0) { - return CCID_EXEC_ERROR; + return PICOKEY_EXEC_ERROR; } if (truncate == 0x01) { res_APDU[res_APDU_size++] = 4 + 1; @@ -354,7 +354,7 @@ int calculate_oath(uint8_t truncate, const uint8_t *key, size_t key_len, const u memcpy(res_APDU + res_APDU_size, hmac, hmac_size); res_APDU_size += (uint16_t)hmac_size; } apdu.ne = res_APDU_size; - return CCID_OK; + return PICOKEY_OK; } int cmd_calculate() { @@ -391,7 +391,7 @@ int cmd_calculate() { res_APDU[res_APDU_size++] = TAG_RESPONSE + P2(apdu); int ret = calculate_oath(P2(apdu), key.data, key.len, chal.data, chal.len); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { return SW_EXEC_ERROR(); } if ((key.data[0] & OATH_TYPE_MASK) == OATH_TYPE_HOTP) { @@ -466,7 +466,7 @@ int cmd_calculate_all() { else { res_APDU[res_APDU_size++] = TAG_RESPONSE + P2(apdu); int ret = calculate_oath(P2(apdu), key.data, key.len, chal.data, chal.len); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { res_APDU[res_APDU_size++] = 1; res_APDU[res_APDU_size++] = key.data[1]; } @@ -581,7 +581,7 @@ int cmd_verify_hotp() { } int ret = calculate_oath(0x01, key.data, key.len, chal.data, chal.len); - if (ret != CCID_OK) { + if (ret != PICOKEY_OK) { return SW_EXEC_ERROR(); } uint32_t res_int = (res_APDU[2] << 24) | (res_APDU[3] << 16) | (res_APDU[4] << 8) | res_APDU[5]; diff --git a/src/fido/otp.c b/src/fido/otp.c index 67089b5..2970aeb 100644 --- a/src/fido/otp.c +++ b/src/fido/otp.c @@ -144,9 +144,9 @@ int otp_select(app_t *a, uint8_t force) { memmove(res_APDU, res_APDU + 1, 6); res_APDU_size = 6; apdu.ne = res_APDU_size; - return CCID_OK; + return PICOKEY_OK; } - return CCID_ERR_FILE_NOT_FOUND; + return PICOKEY_ERR_FILE_NOT_FOUND; } uint8_t modhex_tab[] = @@ -243,7 +243,7 @@ int otp_button_pressed(uint8_t slot) { { imf >> 56, imf >> 48, imf >> 40, imf >> 32, imf >> 24, imf >> 16, imf >> 8, imf & 0xff }; res_APDU_size = 0; int ret = calculate_oath(1, tmp_key, sizeof(tmp_key), chal, sizeof(chal)); - if (ret == CCID_OK) { + if (ret == PICOKEY_OK) { uint32_t base = otp_config->cfg_flags & OATH_HOTP8 ? 1e8 : 1e6; uint32_t number = (res_APDU[2] << 24) | (res_APDU[3] << 16) | (res_APDU[4] << 8) | res_APDU[5]; @@ -348,7 +348,7 @@ INITIALIZER( otp_ctor ) { } int otp_unload() { - return CCID_OK; + return PICOKEY_OK; } uint16_t otp_status() { From bc0e022d859a7c42276e2ee6e598cada9bb29c8f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 18:37:11 +0100 Subject: [PATCH 41/51] Fix version header. 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 6625678..e85d77c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 6625678c3059554ef9fc38c1fd0ff16fa4dbad3e +Subproject commit e85d77c08437e7f2ba269dc91f796ad49df1f0f8 From a68fbd65e92c748e11c0776a048134b72ef2a3bd Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 5 Nov 2024 18:57:28 +0100 Subject: [PATCH 42/51] Compact PHY config. Signed-off-by: Pol Henarejos --- src/fido/cbor_config.c | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index cc44cfc..f443ea9 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -224,33 +224,24 @@ int cbor_config(const uint8_t *data, size_t len) { } #ifndef ENABLE_EMULATION else if (subcommand == 0x1B) { + if (vendorParam == 0) { + CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); + } if (vendorCommandId == CTAP_CONFIG_PHY_VIDPID) { - if (vendorParam != 0) { - phy_data.vid = (vendorParam >> 16) & 0xFFFF; - phy_data.pid = vendorParam & 0xFFFF; - phy_data.vidpid_present = true; - } - else { - CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); - } + phy_data.vid = (vendorParam >> 16) & 0xFFFF; + phy_data.pid = vendorParam & 0xFFFF; + phy_data.vidpid_present = true; } - else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO || vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { - if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) { - phy_data.led_gpio = (uint8_t)vendorParam; - phy_data.led_gpio_present = true; - } - else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { - phy_data.led_brightness = (uint8_t)vendorParam; - phy_data.led_brightness_present = true; - } + else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) { + phy_data.led_gpio = (uint8_t)vendorParam; + phy_data.led_gpio_present = true; + } + else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) { + phy_data.led_brightness = (uint8_t)vendorParam; + phy_data.led_brightness_present = true; } else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) { - if (vendorParam != 0) { - phy_data.opts = (uint16_t)vendorParam; - } - else { - CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER); - } + phy_data.opts = (uint16_t)vendorParam; } else { CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); From 78604f820d8c182f9715175f289906c38ec4905c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 6 Nov 2024 17:02:51 +0100 Subject: [PATCH 43/51] Always enable WCID interface. 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 e85d77c..3dbf969 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit e85d77c08437e7f2ba269dc91f796ad49df1f0f8 +Subproject commit 3dbf969e12471b90e476051d8371fa96d353cd65 From 244c18fb511ff1cf3b3e8bd2e5992959c2949680 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 6 Nov 2024 17:11:44 +0100 Subject: [PATCH 44/51] Fix esp32 build with wcid. 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 3dbf969..5f27c0d 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 3dbf969e12471b90e476051d8371fa96d353cd65 +Subproject commit 5f27c0d75dd07ce0121ead6acefb225871862356 From 3b43c5112b1fb868522c8e98735924f813d5115f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 8 Nov 2024 19:33:40 +0100 Subject: [PATCH 45/51] Add command to reset device via management app. Signed-off-by: Pol Henarejos --- src/fido/management.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/fido/management.c b/src/fido/management.c index 1141658..8c25a9c 100644 --- a/src/fido/management.c +++ b/src/fido/management.c @@ -135,12 +135,20 @@ int cmd_write_config() { return SW_OK(); } +extern int cbor_reset(); +int cmd_factory_reset() { + cbor_reset(); + return SW_OK(); +} + #define INS_READ_CONFIG 0x1D #define INS_WRITE_CONFIG 0x1C +#define INS_RESET 0x1E // Reset device static const cmd_t cmds[] = { { INS_READ_CONFIG, cmd_read_config }, { INS_WRITE_CONFIG, cmd_write_config }, + { INS_RESET, cmd_factory_reset }, { 0x00, 0x0 } }; From 77c3568885ee2a336043184cbab088a49950a948 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 9 Nov 2024 00:23:04 +0100 Subject: [PATCH 46/51] Add PICO_PRODUCT. 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 a929ae4..67a3a1e 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -40,6 +40,8 @@ int fido_process_apdu(); int fido_unload(); +uint8_t PICO_PRODUCT = 2; // Pico FIDO + pinUvAuthToken_t paut = { 0 }; uint8_t keydev_dec[32]; From 646b423fe4f0b212c5f686ad660e1841189bac05 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 9 Nov 2024 00:24:47 +0100 Subject: [PATCH 47/51] Add compiler flags for optimized builds in ESP32. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- sdkconfig.defaults | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 5f27c0d..5bce3e4 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 5f27c0d75dd07ce0121ead6acefb225871862356 +Subproject commit 5bce3e4c838f424c8d17728814284352f1b53bff diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 1cb2487..2014bb3 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -11,6 +11,7 @@ CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/config/esp32/partitions.csv" CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_MODE_PERF=y +COMPILER_OPTIMIZATION="Performance" CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_CHACHA20_C=y From 4ecb325e07201eef3de7360ad7ddc3c078f4338d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 10 Nov 2024 00:50:27 +0100 Subject: [PATCH 48/51] Upgrade Pico Keys SDK v7.0 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 5bce3e4..8c25e9b 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 5bce3e4c838f424c8d17728814284352f1b53bff +Subproject commit 8c25e9be87f5556738550d309358198163111420 From 730e76af756e899775727583daba794fb9b09dcf Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 10 Nov 2024 01:07:31 +0100 Subject: [PATCH 49/51] Enable OTP master key for ESP32-S3. Signed-off-by: Pol Henarejos --- src/fido/fido.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/fido/fido.c b/src/fido/fido.c index 67a3a1e..e59d3c2 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -188,11 +188,9 @@ int load_keydev(uint8_t *key) { } else { memcpy(key, file_get_data(ef_keydev), file_get_size(ef_keydev)); -#ifdef PICO_RP2350 - if (aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != PICOKEY_OK) { + if (otp_key_1 && aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != PICOKEY_OK) { return PICOKEY_EXEC_ERROR; } -#endif } //return mkek_decrypt(key, file_get_size(ef_keydev)); @@ -303,9 +301,9 @@ int scan_files() { if (ret != PICOKEY_OK) { return ret; } -#ifdef PICO_RP2350 - ret = aes_encrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, kdata, 32); -#endif + if (otp_key_1) { + ret = aes_encrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, kdata, 32); + } ret = file_put_data(ef_keydev, kdata, (uint16_t)key_size); mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_ecdsa_free(&ecdsa); From 10c58b4be7c9c1eee512a2af415a9118c3409825 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 10 Nov 2024 01:20:52 +0100 Subject: [PATCH 50/51] Update README Signed-off-by: Pol Henarejos --- README.md | 57 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d2c43f4..602182c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Pico FIDO -This project transforms your Raspberry Pi Pico into an integrated FIDO Passkey, functioning like a standard USB Passkey for authentication. +This project transforms your Raspberry Pi Pico or ESP32 microcontroller into an integrated FIDO Passkey, functioning like a standard USB Passkey for authentication. ## Features Pico FIDO includes the following features: @@ -30,51 +30,68 @@ Pico FIDO includes the following features: - Large blobs support (2048 bytes max) - OATH (based on YKOATH protocol specification) - TOTP / HOTP -- Yubikey OTP +- Yubikey One Time Password - Challenge-response generation - Emulated keyboard interface - Button press generates an OTP that is directly typed - Yubico YKMAN compatible - Nitrokey nitropy and nitroapp compatible +- Secure Boot and Secure Lock in RP2350 and ESP32-S3 MCUs +- One Time Programming to store the master key that encrypts all resident keys and seeds. +- Rescue interface to allow recovery of the device if it becomes unresponsive or undetectable. +- LED customization with Pico Commissioner. All features comply with the specifications. If you encounter unexpected behavior or deviations from the specifications, please open an issue. ## Security Considerations +Microcontrollers RP2350 and ESP32-S3 are designed to support secure environments when Secure Boot is enabled, and optionally, Secure Lock. These features allow a master key encryption key (MKEK) to be stored in a one-time programmable (OTP) memory region, which is inaccessible from outside secure code. This master key is then used to encrypt all private and secret keys on the device, protecting sensitive data from potential flash memory dumps. -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. +**However**, the RP2040 microcontroller lacks this level of security hardware, meaning that it cannot provide the same protection. Data stored on its flash memory, including private or master keys, can be easily accessed or dumped, as encryption of the master key itself is not feasible. Consequently, if an RP2040 device is stolen, any stored private or secret keys may be exposed. ## Download -Please visit the [Release page](https://github.com/polhenarejos/pico-fido/releases "Release page") to download the UF2 file for your board. +**If you own an ESP32-S3 board, go to [ESP32 Flasher](https://www.picokeys.com/esp32-flasher/) for flashing your Pico FIDO.** -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/). +If you own a Raspberry Pico (RP2040 or RP2350), go to [Download page](https://www.picokeys.com/getting-started/), select your vendor and model and download the proper firmware; or go to [Release page](https://www.github.com/polhenarejos/pico-fido/releases/) and download the UF2 file for your board. -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. +Note that UF2 files are shiped with a dummy VID/PID to avoid license issues (FEFF:FCFD). If you plan to use it with other proprietary tools, you should modify Info.plist of CCID driver to add these VID/PID or use the [Pico Commissioner](https://www.picokeys.com/pico-commissioner/ "Pico Commissioner"). + +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. -For ease of use, the pure-browser option [Pico Patcher tool](https://www.picokeys.com/pico-patcher/) is highly recommended. +Note that the pure-browser option [Pico Commissioner](https://www.picokeys.com/pico-commissioner/ "Pico Commissioner") is the most recommended. -## Build +## Build for Raspberry Pico Before building, ensure you have installed the toolchain for the Pico and that the Pico SDK is properly located on your drive. ```sh git clone https://github.com/polhenarejos/pico-fido +git submodule update --init --recursive 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, the default Pico board and VID/PID `FEFF:FCFD` will be used. - -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 the HID interface, so VID/PID values are irrelevant in terms of operativity. You can safely use any arbitrary values or the default ones. They are only necessary in case you need to use 3rd-party tools from other vendors. +Note that `PICO_BOARD`, `USB_VID` and `USB_PID` are optional. If not provided, `pico` board and VID/PID `FEFF:FCFD` will be used. + +Additionally, you can pass the `VIDPID=value` parameter to build the firmware with a known VID/PID. The supported values are: + +- `NitroHSM` +- `NitroFIDO2` +- `NitroStart` +- `NitroPro` +- `Nitro3` +- `Yubikey5` +- `YubikeyNeo` +- `YubiHSM` +- `Gnuk` +- `GnuPG` + +After running `make`, the binary file `pico_fido.uf2` will be generated. To load this onto your Pico board: + +1. Put the Pico board into loading mode by holding the `BOOTSEL` button while plugging it in. +2. Copy the `pico_fido.uf2` file to the new USB mass storage device that appears. +3. Once the file is copied, the Pico mass storage device will automatically disconnect, and the Pico board will reset with the new firmware. +4. A blinking LED will indicate that the device is ready to work. ## Led blink Pico FIDO uses the led to indicate the current status. Four states are available: From 7a59b518494d46e01dd768e5d9af4a9caaf3bd74 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 10 Nov 2024 01:21:51 +0100 Subject: [PATCH 51/51] Upgrade to v6.0 Signed-off-by: Pol Henarejos --- build_pico_fido.sh | 4 ++-- src/fido/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_pico_fido.sh b/build_pico_fido.sh index 8308979..6a952f2 100755 --- a/build_pico_fido.sh +++ b/build_pico_fido.sh @@ -1,7 +1,7 @@ #!/bin/bash -VERSION_MAJOR="5" -VERSION_MINOR="12" +VERSION_MAJOR="6" +VERSION_MINOR="0" 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 239abe6..97c8be1 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 0x050C +#define PICO_FIDO_VERSION 0x0600 #define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff) #define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff)