10 Commits

Author SHA1 Message Date
Pol Henarejos
9c28f72d17 Merge branch 'development' 2025-06-22 18:00:08 +02:00
Pol Henarejos
0518ac3655 Flash size is obtained dynamically rather than in build time. It will allow to reduce dramatically the number of builds.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-30 12:06:34 +02:00
Pol Henarejos
b4d9e8b693 Update README.md
Add link to Pico Fido2
2025-05-30 11:22:17 +02:00
Pol Henarejos
93523faf02 Fix bool build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-25 19:20:14 +02:00
Pol Henarejos
a018a7f66c Update pointer to support dynamic AID
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-25 19:15:45 +02:00
Pol Henarejos
9b75c5c175 Check OpenPGP and PIV dynamically as it can be loaded separately.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-25 19:07:52 +02:00
Pol Henarejos
513642663b Move PRODUCT def to another file.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:49:15 +02:00
Pol Henarejos
e4ed703b6b Rename scan_files to scan_files_fido
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:25:33 +02:00
Pol Henarejos
91aaee5beb Force 8-digit serial number
Fixes #149.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-19 10:01:07 +02:00
Pol Henarejos
a61bb91824 Fix eddsa output folder.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-10 19:56:06 +02:00
11 changed files with 56 additions and 11 deletions

View File

@@ -98,6 +98,7 @@ set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_vendor.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_vendor.c
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_large_blobs.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_large_blobs.c
${CMAKE_CURRENT_LIST_DIR}/src/fido/management.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/management.c
${CMAKE_CURRENT_LIST_DIR}/src/fido/defs.c
) )
if (${ENABLE_OATH_APP}) if (${ENABLE_OATH_APP})
set(SOURCES ${SOURCES} set(SOURCES ${SOURCES}

View File

@@ -1,6 +1,8 @@
# Pico FIDO # Pico FIDO
This project transforms your Raspberry Pi Pico or ESP32 microcontroller 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.
If you are looking for a Fido + OpenPGP, see: https://github.com/polhenarejos/pico-fido2
## Features ## Features
Pico FIDO includes the following features: Pico FIDO includes the following features:

View File

@@ -42,6 +42,6 @@ if [[ $NO_EDDSA -eq 0 ]]; then
rm -rf -- ./* rm -rf -- ./*
PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name -DSECURE_BOOT_PKEY=../../ec_private_key.pem -DENABLE_EDDSA=1 PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name -DSECURE_BOOT_PKEY=../../ec_private_key.pem -DENABLE_EDDSA=1
make -j`nproc` make -j`nproc`
mv pico_fido.uf2 ../release/pico_fido_$board_name-$SUFFIX-eddsa1.uf2 mv pico_fido.uf2 ../release_eddsa/pico_fido_$board_name-$SUFFIX-eddsa1.uf2
done done
fi fi

View File

@@ -26,7 +26,7 @@
int cmd_authenticate() { int cmd_authenticate() {
CTAP_AUTHENTICATE_REQ *req = (CTAP_AUTHENTICATE_REQ *) apdu.data; CTAP_AUTHENTICATE_REQ *req = (CTAP_AUTHENTICATE_REQ *) apdu.data;
CTAP_AUTHENTICATE_RESP *resp = (CTAP_AUTHENTICATE_RESP *) res_APDU; CTAP_AUTHENTICATE_RESP *resp = (CTAP_AUTHENTICATE_RESP *) res_APDU;
//if (scan_files(true) != PICOKEY_OK) //if (scan_files_fido(true) != PICOKEY_OK)
// return SW_EXEC_ERROR(); // return SW_EXEC_ERROR();
if (apdu.nc < CTAP_CHAL_SIZE + CTAP_APPID_SIZE + 1 + 1) { if (apdu.nc < CTAP_CHAL_SIZE + CTAP_APPID_SIZE + 1 + 1) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();

View File

@@ -59,7 +59,7 @@ int cmd_register() {
CTAP_REGISTER_RESP *resp = (CTAP_REGISTER_RESP *) res_APDU; CTAP_REGISTER_RESP *resp = (CTAP_REGISTER_RESP *) res_APDU;
resp->registerId = CTAP_REGISTER_ID; resp->registerId = CTAP_REGISTER_ID;
resp->keyHandleLen = KEY_HANDLE_LEN; resp->keyHandleLen = KEY_HANDLE_LEN;
//if (scan_files(true) != PICOKEY_OK) //if (scan_files_fido(true) != PICOKEY_OK)
// return SW_EXEC_ERROR(); // return SW_EXEC_ERROR();
if (apdu.nc != CTAP_APPID_SIZE + CTAP_CHAL_SIZE) { if (apdu.nc != CTAP_APPID_SIZE + CTAP_CHAL_SIZE) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();

20
src/fido/defs.c Normal file
View File

@@ -0,0 +1,20 @@
/*
* This file is part of the Pico FIDO distribution (https://github.com/polhenarejos/pico-fido).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fido.h"
uint8_t PICO_PRODUCT = 2; // Pico FIDO

View File

@@ -41,8 +41,6 @@
int fido_process_apdu(); int fido_process_apdu();
int fido_unload(); int fido_unload();
uint8_t PICO_PRODUCT = 2; // Pico FIDO
pinUvAuthToken_t paut = { 0 }; pinUvAuthToken_t paut = { 0 };
uint8_t keydev_dec[32]; uint8_t keydev_dec[32];
@@ -307,7 +305,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
return r; return r;
} }
int scan_files() { int scan_files_fido() {
ef_keydev = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); ef_keydev = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF);
ef_keydev_enc = search_by_fid(EF_KEY_DEV_ENC, NULL, SPECIFY_EF); ef_keydev_enc = search_by_fid(EF_KEY_DEV_ENC, NULL, SPECIFY_EF);
ef_mkek = search_by_fid(EF_MKEK, NULL, SPECIFY_EF); ef_mkek = search_by_fid(EF_MKEK, NULL, SPECIFY_EF);
@@ -432,7 +430,7 @@ int scan_files() {
void scan_all() { void scan_all() {
scan_flash(); scan_flash();
scan_files(); scan_files_fido();
} }
extern void init_otp(); extern void init_otp();

View File

@@ -43,7 +43,7 @@
#define SHA256_DIGEST_LENGTH (32) #define SHA256_DIGEST_LENGTH (32)
#define KEY_HANDLE_LEN (KEY_PATH_LEN + SHA256_DIGEST_LENGTH) #define KEY_HANDLE_LEN (KEY_PATH_LEN + SHA256_DIGEST_LENGTH)
extern int scan_files(); extern int scan_files_fido();
extern int derive_key(const uint8_t *app_id, extern int derive_key(const uint8_t *app_id,
bool new_key, bool new_key,
uint8_t *key_handle, uint8_t *key_handle,

View File

@@ -74,17 +74,34 @@ bool cap_supported(uint16_t cap) {
return true; return true;
} }
static uint8_t _openpgp_aid[] = {
6,
0xD2, 0x76, 0x00, 0x01, 0x24, 0x01,
};
static uint8_t _piv_aid[] = {
5,
0xA0, 0x00, 0x00, 0x03, 0x8,
};
int man_get_config() { int man_get_config() {
file_t *ef = search_dynamic_file(EF_DEV_CONF); file_t *ef = search_dynamic_file(EF_DEV_CONF);
res_APDU_size = 0; res_APDU_size = 0;
res_APDU[res_APDU_size++] = 0; // Overall length. Filled later res_APDU[res_APDU_size++] = 0; // Overall length. Filled later
res_APDU[res_APDU_size++] = TAG_USB_SUPPORTED; res_APDU[res_APDU_size++] = TAG_USB_SUPPORTED;
res_APDU[res_APDU_size++] = 2; res_APDU[res_APDU_size++] = 2;
res_APDU[res_APDU_size++] = CAP_FIDO2 >> 8; uint16_t caps = CAP_FIDO2 | CAP_OTP | CAP_U2F | CAP_OATH;
res_APDU[res_APDU_size++] = CAP_OTP | CAP_U2F | CAP_OATH; if (app_exists(_openpgp_aid + 1, _openpgp_aid[0])) {
caps |= CAP_OPENPGP;
}
if (app_exists(_piv_aid + 1, _piv_aid[0])) {
caps |= CAP_PIV;
}
res_APDU[res_APDU_size++] = caps >> 8;
res_APDU[res_APDU_size++] = caps & 0xFF;
res_APDU[res_APDU_size++] = TAG_SERIAL; res_APDU[res_APDU_size++] = TAG_SERIAL;
res_APDU[res_APDU_size++] = 4; res_APDU[res_APDU_size++] = 4;
memcpy(res_APDU + res_APDU_size, pico_serial.id, 4); memcpy(res_APDU + res_APDU_size, pico_serial.id, 4);
res_APDU[res_APDU_size] &= ~0xFC; // Force 8-digit serial number
res_APDU_size += 4; res_APDU_size += 4;
res_APDU[res_APDU_size++] = TAG_FORM_FACTOR; res_APDU[res_APDU_size++] = TAG_FORM_FACTOR;
res_APDU[res_APDU_size++] = 1; res_APDU[res_APDU_size++] = 1;
@@ -110,6 +127,12 @@ int man_get_config() {
if (cap_supported(CAP_OATH)) { if (cap_supported(CAP_OATH)) {
caps |= CAP_OATH; caps |= CAP_OATH;
} }
if (cap_supported(CAP_OPENPGP)) {
caps |= CAP_OPENPGP;
}
if (cap_supported(CAP_PIV)) {
caps |= CAP_PIV;
}
res_APDU[res_APDU_size++] = caps >> 8; res_APDU[res_APDU_size++] = caps >> 8;
res_APDU[res_APDU_size++] = caps & 0xFF; res_APDU[res_APDU_size++] = caps & 0xFF;
res_APDU[res_APDU_size++] = TAG_DEVICE_FLAGS; res_APDU[res_APDU_size++] = TAG_DEVICE_FLAGS;

View File

@@ -476,6 +476,7 @@ int cmd_otp() {
} }
else if (p1 == 0x10) { else if (p1 == 0x10) {
memcpy(res_APDU, pico_serial.id, 4); memcpy(res_APDU, pico_serial.id, 4);
res_APDU[0] &= ~0xFC; // Force 8-digit serial number
res_APDU_size = 4; res_APDU_size = 4;
} }
else if (p1 == 0x13) { // Get config else if (p1 == 0x13) { // Get config