Adjusting code to work with the emulated interface.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2023-01-09 18:07:41 +01:00
parent 46661ee808
commit 4f33d999e3
No known key found for this signature in database
GPG Key ID: C0095B7870A4CCD3
19 changed files with 117 additions and 20 deletions

View File

@ -17,14 +17,20 @@
cmake_minimum_required(VERSION 3.13)
if(ENABLE_EMULATION)
else()
include(pico_sdk_import.cmake)
endif()
project(pico_fido C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
if(ENABLE_EMULATION)
else()
pico_sdk_init()
endif()
add_executable(pico_fido)
@ -70,7 +76,7 @@ else()
set(USB_ITF_CCID 0)
endif()
target_sources(pico_fido PUBLIC
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/fido.c
${CMAKE_CURRENT_LIST_DIR}/src/fido/files.c
${CMAKE_CURRENT_LIST_DIR}/src/fido/cmd_register.c
@ -91,12 +97,12 @@ target_sources(pico_fido PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_large_blobs.c
)
if (${ENABLE_OATH_APP})
target_sources(pico_fido PUBLIC
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/oath.c
)
endif()
if (${ENABLE_OTP_APP})
target_sources(pico_fido PUBLIC
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/otp.c
)
endif()
@ -104,10 +110,13 @@ endif()
set(USB_ITF_HID 1)
include(pico-hsm-sdk/pico_hsm_sdk_import.cmake)
target_include_directories(pico_fido PUBLIC
set(INCLUDES ${INCLUDES}
${CMAKE_CURRENT_LIST_DIR}/src/fido
)
target_sources(pico_fido PUBLIC ${SOURCES})
target_include_directories(pico_fido PUBLIC ${INCLUDES})
target_compile_options(pico_fido PUBLIC
-Wall
-Werror
@ -119,6 +128,16 @@ if (${COMPILER_COLON} GREATER_EQUAL 0)
)
endif()
pico_add_extra_outputs(pico_fido)
if(ENABLE_EMULATION)
target_compile_options(pico_fido PUBLIC
-fdata-sections
-ffunction-sections
)
target_link_options(pico_fido PUBLIC
-Wl,-dead_strip
)
else()
pico_add_extra_outputs(pico_fido)
target_link_libraries(pico_fido PRIVATE pico_hsm_sdk pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc tinyusb_device tinyusb_board)
endif()

@ -1 +1 @@
Subproject commit 88b2978ae5cf3f1de95ebaec0aec0acd3a24878e
Subproject commit 4919eb980f22652aeb5ad91fbdeaeb510ffb7ca3

View File

@ -15,7 +15,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ENABLE_EMULATION
#include "pico/stdlib.h"
#endif
#include "hid/ctap_hid.h"
#include "ctap.h"
#include "fido.h"
#include "usb.h"
@ -45,7 +48,9 @@ int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
if (len == 0)
return CTAP1_ERR_INVALID_LEN;
DEBUG_DATA(data+1,len-1);
#ifndef ENABLE_EMULATION
driver_prepare_response_hid();
#endif
if (cmd == CTAPHID_CBOR) {
if (data[0] == CTAP_MAKE_CREDENTIAL)
return cbor_make_credential(data + 1, len - 1);
@ -74,6 +79,7 @@ int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
return CTAP2_ERR_INVALID_CBOR;
}
#ifndef ENABLE_EMULATION
void cbor_thread() {
card_init_core1();
@ -90,10 +96,12 @@ void cbor_thread() {
DEBUG_DATA(res_APDU + 1, res_APDU_size);
finished_data_size = res_APDU_size+1;
uint32_t flag = EV_EXEC_FINISHED;
queue_add_blocking(&card_to_usb_q, &flag);
}
}
#endif
int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len) {
cbor_data = data;

View File

@ -23,7 +23,10 @@
#include "cbor.h"
#include "ctap.h"
#include "ctap2_cbor.h"
#ifndef ENABLE_EMULATION
#include "bsp/board.h"
#endif
#include "hid/ctap_hid.h"
#include "fido.h"
#include "files.h"
#include "random.h"

View File

@ -18,6 +18,7 @@
#include "ctap2_cbor.h"
#include "fido.h"
#include "ctap.h"
#include "hid/ctap_hid.h"
#include "files.h"
#include "apdu.h"
#include "credential.h"

View File

@ -17,6 +17,7 @@
#include "fido.h"
#include "ctap.h"
#include "hid/ctap_hid.h"
#include "cbor_make_credential.h"
#include "files.h"
#include "apdu.h"

View File

@ -17,7 +17,10 @@
#include "cbor.h"
#include "ctap.h"
#ifndef ENABLE_EMULATION
#include "bsp/board.h"
#endif
#include "hid/ctap_hid.h"
#include "fido.h"
#include "files.h"
#include "crypto_utils.h"

View File

@ -16,6 +16,7 @@
*/
#include "ctap2_cbor.h"
#include "hid/ctap_hid.h"
#include "fido.h"
#include "ctap.h"
#include "files.h"

View File

@ -18,6 +18,7 @@
#include "ctap2_cbor.h"
#include "fido.h"
#include "ctap.h"
#include "hid/ctap_hid.h"
#include "files.h"
#include "apdu.h"
#include "hsm.h"

View File

@ -17,6 +17,7 @@
#include "cbor_make_credential.h"
#include "ctap2_cbor.h"
#include "hid/ctap_hid.h"
#include "fido.h"
#include "ctap.h"
#include "files.h"

View File

@ -19,17 +19,21 @@
#include "file.h"
#include "fido.h"
#include "ctap.h"
#ifndef ENABLE_EMULATION
#include "bsp/board.h"
#endif
extern void scan_all();
int cbor_reset() {
#ifndef ENABLE_EMULATION
#if defined(ENABLE_POWER_ON_RESET) && ENABLE_POWER_ON_RESET==1
if (board_millis() > 10000)
return CTAP2_ERR_NOT_ALLOWED;
#endif
if (wait_button_pressed() == true)
return CTAP2_ERR_USER_ACTION_TIMEOUT;
#endif
initialize_flash(true);
init_fido();
return 0;

View File

@ -18,6 +18,7 @@
#include "ctap2_cbor.h"
#include "fido.h"
#include "ctap.h"
#include "hid/ctap_hid.h"
#include "files.h"
#include "apdu.h"
#include "hsm.h"
@ -241,8 +242,14 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
mbedtls_ecdsa_free(&ekey);
CBOR_ERROR(CTAP2_ERR_PROCESSING);
}
#ifndef ENABLE_EMULATION
pico_unique_board_id_t rpiid;
pico_get_unique_board_id(&rpiid);
#else
struct {
uint8_t id[8];
} rpiid = {0};
#endif
mbedtls_x509write_csr ctx;
mbedtls_x509write_csr_init(&ctx);
snprintf((char *)buffer, sizeof(buffer), "C=ES,O=Pico Keys,OU=Authenticator Attestation,CN=Pico Fido EE Serial %llu", ((uint64_t)rpiid.id[0] << 56) | ((uint64_t)rpiid.id[1] << 48) | ((uint64_t)rpiid.id[2] << 40) | ((uint64_t)rpiid.id[3] << 32) | (rpiid.id[4] << 24) | (rpiid.id[5] << 16) | (rpiid.id[6] << 8) | rpiid.id[7]);

View File

@ -21,6 +21,7 @@
#include "ctap.h"
#include "random.h"
#include "files.h"
#include "hid/ctap_hid.h"
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";
const uint8_t *bogus_chrome = (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
@ -38,7 +39,11 @@ int cmd_register() {
if (wait_button_pressed() == true)
return SW_CONDITIONS_NOT_SATISFIED();
if (memcmp(req->appId, bogus_firefox, CTAP_APPID_SIZE) == 0 || memcmp(req->appId, bogus_chrome, CTAP_APPID_SIZE) == 0)
#ifndef ENABLE_EMULATION
return ctap_error(CTAP1_ERR_CHANNEL_BUSY);
#else
return SW_DATA_INVALID();
#endif
mbedtls_ecdsa_context key;
mbedtls_ecdsa_init(&key);
int ret = derive_key(req->appId, true, resp->keyHandleCertSig, MBEDTLS_ECP_DP_SECP256R1, &key);

View File

@ -18,7 +18,10 @@
#include "mbedtls/chachapoly.h"
#include "mbedtls/sha256.h"
#include "credential.h"
#ifndef ENABLE_EMULATION
#include "bsp/board.h"
#endif
#include "hid/ctap_hid.h"
#include "fido.h"
#include "ctap.h"
#include "random.h"

View File

@ -24,7 +24,9 @@ typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
#else
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#endif
#ifdef __cplusplus

View File

@ -24,8 +24,11 @@
#include "random.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/hkdf.h"
#ifdef USB_ITF_CCID
#include "ccid.h"
#if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION)
#include "ccid/ccid.h"
#endif
#ifndef ENABLE_EMULATION
#include "bsp/board.h"
#endif
#include <math.h>
@ -58,7 +61,7 @@ app_t *fido_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
}
void __attribute__ ((constructor)) fido_ctor() {
#ifdef USB_ITF_CCID
#if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION)
ccid_atr = atr_fido;
#endif
register_app(fido_select);
@ -308,11 +311,13 @@ void init_fido() {
bool wait_button_pressed() {
uint32_t val = EV_PRESS_BUTTON;
#ifndef ENABLE_EMULATION
#if defined(ENABLE_UP_BUTTON) && ENABLE_UP_BUTTON==1
queue_try_add(&card_to_usb_q, &val);
do {
queue_remove_blocking(&usb_to_card_q, &val);
} while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
#endif
#endif
return (val == EV_BUTTON_TIMEOUT);
}

View File

@ -18,10 +18,16 @@
#ifndef _FIDO_H_
#define _FIDO_H_
#ifndef ENABLE_EMULATION
#include "pico/stdlib.h"
#endif
#include "common.h"
#include "mbedtls/ecdsa.h"
#ifndef ENABLE_EMULATION
#include "ctap_hid.h"
#else
#include <stdbool.h>
#endif
#define CTAP_PUBKEY_LEN (65)
#define KEY_PATH_LEN (32)
@ -33,7 +39,6 @@ extern int scan_files();
extern int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int, mbedtls_ecdsa_context *key);
extern int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *);
extern bool wait_button_pressed();
extern CTAPHID_FRAME *ctap_req, *ctap_resp;
extern void init_fido();
extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve);
extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecdsa_context *key);

View File

@ -75,12 +75,17 @@ app_t *oath_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
res_APDU[res_APDU_size++] = 0;
res_APDU[res_APDU_size++] = TAG_NAME;
res_APDU[res_APDU_size++] = 8;
#ifndef ENABLE_EMULATION
pico_get_unique_board_id((pico_unique_board_id_t *)(res_APDU+res_APDU_size)); res_APDU_size += 8;
#else
memset(res_APDU+res_APDU_size,0,8); res_APDU_size += 8;
#endif
if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) {
res_APDU[res_APDU_size++] = TAG_CHALLENGE;
res_APDU[res_APDU_size++] = sizeof(challenge);
memcpy(res_APDU+res_APDU_size, challenge, sizeof(challenge)); res_APDU_size += sizeof(challenge);
}
apdu.ne = res_APDU_size;
return a;
}
return NULL;
@ -248,6 +253,7 @@ int cmd_list() {
}
}
}
apdu.ne = res_APDU_size;
return SW_OK();
}
@ -281,6 +287,7 @@ int cmd_validate() {
res_APDU[res_APDU_size++] = TAG_RESPONSE;
res_APDU[res_APDU_size++] = mbedtls_md_get_size(md_info);
memcpy(res_APDU+res_APDU_size, hmac, mbedtls_md_get_size(md_info)); res_APDU_size += mbedtls_md_get_size(md_info);
apdu.ne = res_APDU_size;
return SW_OK();
}
@ -307,6 +314,7 @@ int calculate_oath(uint8_t truncate, const uint8_t *key, size_t key_len, const u
res_APDU[res_APDU_size++] = key[1];
memcpy(res_APDU+res_APDU_size, hmac, hmac_size); res_APDU_size += hmac_size;
}
apdu.ne = res_APDU_size;
return CCID_OK;
}
@ -357,6 +365,7 @@ int cmd_calculate() {
low_flash_available();
free(tmp);
}
apdu.ne = res_APDU_size;
return SW_OK();
}
@ -399,6 +408,11 @@ int cmd_calculate_all() {
}
}
}
apdu.ne = res_APDU_size;
return SW_OK();
}
int cmd_send_remaining() {
return SW_OK();
}
@ -421,6 +435,7 @@ static const cmd_t cmds[] = {
{ INS_VALIDATE, cmd_validate },
{ INS_CALCULATE, cmd_calculate },
{ INS_CALC_ALL, cmd_calculate_all },
{ INS_SEND_REMAINING, cmd_send_remaining },
{ 0x00, 0x0}
};

View File

@ -36,7 +36,7 @@
#define CONFIG_LED_INV 0x10
#define CONFIG_STATUS_MASK 0x1f
static uint8_t config_seq[2] = {1};
static uint8_t config_seq = {1};
typedef struct otp_config {
uint8_t fixed_data[FIXED_SIZE];
@ -52,13 +52,14 @@ typedef struct otp_config {
} __attribute__((packed)) otp_config_t;
static const size_t otp_config_size = sizeof(otp_config_t);
uint16_t otp_status();
int otp_process_apdu();
int otp_unload();
const uint8_t otp_aid[] = {
7,
0xa0, 0x00, 0x00, 0x05, 0x27, 0x21, 0x01
0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01
};
app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
@ -66,6 +67,12 @@ app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
a->aid = otp_aid;
a->process_apdu = otp_process_apdu;
a->unload = otp_unload;
if (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) || file_has_data(search_dynamic_file(EF_OTP_SLOT2)))
config_seq = 1;
else
config_seq = 0;
otp_status();
apdu.ne = res_APDU_size;
return a;
}
return NULL;
@ -79,13 +86,13 @@ int otp_unload() {
return CCID_OK;
}
uint16_t otp_status(uint8_t slot) {
uint16_t otp_status() {
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR;
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR;
res_APDU[res_APDU_size++] = 0;
res_APDU[res_APDU_size++] = config_seq[slot];
res_APDU[res_APDU_size++] = config_seq;
res_APDU[res_APDU_size++] = 0;
res_APDU[res_APDU_size++] = (CONFIG2_TOUCH | CONFIG1_TOUCH) | (config_seq[0] > 0 ? CONFIG1_VALID : 0x00) | (config_seq[1] > 0 ? CONFIG2_VALID : 0x00);
res_APDU[res_APDU_size++] = (CONFIG2_TOUCH | CONFIG1_TOUCH) | (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) ? CONFIG1_VALID : 0x00) | (file_has_data(search_dynamic_file(EF_OTP_SLOT2)) ? CONFIG2_VALID : 0x00);
return SW_OK();
}
@ -99,7 +106,6 @@ int cmd_otp() {
return SW_WRONG_LENGTH();
if (apdu.data[48] != 0 || apdu.data[49] != 0)
return SW_WRONG_DATA();
uint8_t slot = p1 == 0x01 ? 0 : 1;
file_t *ef = file_new(p1 == 0x01 ? EF_OTP_SLOT1 : EF_OTP_SLOT2);
if (file_has_data(ef)) {
otp_config_t *otpc = (otp_config_t *)file_get_data(ef);
@ -110,14 +116,21 @@ int cmd_otp() {
if (apdu.data[c] != 0) {
flash_write_data_to_file(ef, apdu.data, otp_config_size);
low_flash_available();
config_seq[slot]++;
return otp_status(slot);
config_seq++;
return otp_status();
}
}
// Delete slot
delete_file(ef);
config_seq[slot] = 0;
return otp_status(slot);
if (!file_has_data(search_dynamic_file(EF_OTP_SLOT1)) && !file_has_data(search_dynamic_file(EF_OTP_SLOT2)))
config_seq = 0;
return otp_status();
}
else if (p1 == 0x10) {
#ifndef ENABLE_EMULATION
pico_get_unique_board_id_string((char *)res_APDU, 4);
#endif
res_APDU_size = 4;
}
return SW_OK();
}