mirror of
https://github.com/polhenarejos/pico-fido.git
synced 2024-09-20 03:10:10 +00:00
Adding support for clientPIN.
It does not pass the tests yet. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
199091e2b9
commit
ee8f3a0965
@ -39,6 +39,7 @@ target_sources(pico_fido PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_get_info.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_make_credential.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fido/known_apps.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_client_pin.c
|
||||
)
|
||||
set(HSM_DRIVER "hid")
|
||||
include(pico-hsm-sdk/pico_hsm_sdk_import.cmake)
|
||||
|
@ -39,5 +39,7 @@ int cbor_process(const uint8_t *data, size_t len) {
|
||||
return cbor_get_info();
|
||||
else if (data[0] == CTAP_RESET)
|
||||
return cbor_reset();
|
||||
else if (data[0] == CTAP_CLIENT_PIN)
|
||||
return cbor_client_pin(data+1, len-1);
|
||||
return -CTAP2_ERR_INVALID_CBOR;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ bool credential_verify(CborByteString *cred_id, const uint8_t *rp_id_hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int verify(CborByteString *clientDataHash, CborByteString *pinUvAuthParam) {
|
||||
int verify_user(CborByteString *clientDataHash, CborByteString *pinUvAuthParam) {
|
||||
return CborNoError;
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
//Unfinished. See 6.1.2.9
|
||||
}
|
||||
if (pinUvAuthParam.present == true) { //11.1
|
||||
int ret = verify(&clientDataHash, &pinUvAuthParam);
|
||||
int ret = verify_user(&clientDataHash, &pinUvAuthParam);
|
||||
if (ret != CborNoError)
|
||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||
//Check pinUvAuthToken permissions. See 6.1.2.11
|
||||
@ -272,7 +272,7 @@ int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
uint8_t key[32];
|
||||
memset(key, 0, sizeof(key));
|
||||
uint8_t iv[12];
|
||||
memcpy(iv, random_bytes_get(sizeof(iv)), sizeof(iv));
|
||||
random_gen_core0(NULL, iv, sizeof(12));
|
||||
mbedtls_chachapoly_context chatx;
|
||||
mbedtls_chachapoly_init(&chatx);
|
||||
mbedtls_chachapoly_setkey(&chatx, key);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "file.h"
|
||||
#include "usb.h"
|
||||
#include "random.h"
|
||||
#include "bsp/board.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/hkdf.h"
|
||||
@ -36,6 +37,8 @@ void init_fido();
|
||||
int fido_process_apdu();
|
||||
int fido_unload();
|
||||
|
||||
pinUvAuthToken_t paut = {0};
|
||||
|
||||
const uint8_t fido_aid[] = {
|
||||
8,
|
||||
0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01
|
||||
@ -81,7 +84,7 @@ int x509_create_cert(mbedtls_ecdsa_context *ecdsa, uint8_t *buffer, size_t buffe
|
||||
mbedtls_x509write_crt_set_subject_key_identifier(&ctx);
|
||||
mbedtls_x509write_crt_set_authority_key_identifier(&ctx);
|
||||
mbedtls_x509write_crt_set_key_usage(&ctx, MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN);
|
||||
int ret = mbedtls_x509write_crt_der(&ctx, buffer, buffer_size, random_gen, NULL);
|
||||
int ret = mbedtls_x509write_crt_der(&ctx, buffer, buffer_size, random_gen_core0, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -103,7 +106,9 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
|
||||
for (int i = 0; i < KEY_PATH_ENTRIES; i++)
|
||||
{
|
||||
if (new_key == true) {
|
||||
uint32_t val = 0x80000000 | *((uint32_t *)random_bytes_get(sizeof(uint32_t)));
|
||||
uint32_t val = 0;
|
||||
random_gen_core0(NULL, (uint8_t *) &val, sizeof(val));
|
||||
val |= 0x80000000;
|
||||
memcpy(&key_handle[i*sizeof(uint32_t)], &val, sizeof(uint32_t));
|
||||
}
|
||||
r = mbedtls_hkdf(md_info, &key_handle[i * sizeof(uint32_t)], sizeof(uint32_t), outk, 32, outk + 32, 32, outk, sizeof(outk));
|
||||
@ -141,7 +146,7 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
|
||||
int scan_files() {
|
||||
ef_keydev = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF);
|
||||
if (ef_keydev) {
|
||||
if (!ef_keydev->data) {
|
||||
if (!file_has_data(ef_keydev)) {
|
||||
printf("KEY DEVICE is empty. Generating SECP256R1 curve...");
|
||||
mbedtls_ecdsa_context ecdsa;
|
||||
mbedtls_ecdsa_init(&ecdsa);
|
||||
@ -168,7 +173,7 @@ int scan_files() {
|
||||
}
|
||||
ef_certdev = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF);
|
||||
if (ef_certdev) {
|
||||
if (file_get_size(ef_certdev) == 0 || !ef_certdev->data) {
|
||||
if (!file_has_data(ef_certdev)) {
|
||||
uint8_t cert[4096];
|
||||
mbedtls_ecdsa_context key;
|
||||
mbedtls_ecdsa_init(&key);
|
||||
@ -188,7 +193,7 @@ int scan_files() {
|
||||
}
|
||||
ef_counter = search_by_fid(EF_COUNTER, NULL, SPECIFY_EF);
|
||||
if (ef_counter) {
|
||||
if (file_get_size(ef_counter) == 0 || !ef_counter->data) {
|
||||
if (!file_has_data(ef_counter)) {
|
||||
uint32_t v = 0;
|
||||
flash_write_data_to_file(ef_counter, (uint8_t *)&v, sizeof(v));
|
||||
}
|
||||
@ -197,6 +202,19 @@ int scan_files() {
|
||||
printf("FATAL ERROR: Global counter not found in memory!\r\n");
|
||||
}
|
||||
ef_pin = search_by_fid(EF_PIN, NULL, SPECIFY_EF);
|
||||
ef_authtoken = search_by_fid(EF_AUTHTOKEN, NULL, SPECIFY_EF);
|
||||
if (ef_authtoken) {
|
||||
if (!file_has_data(ef_authtoken)) {
|
||||
uint8_t t[32];
|
||||
random_gen_core0(NULL, t, sizeof(t));
|
||||
flash_write_data_to_file(ef_authtoken, t, sizeof(t));
|
||||
}
|
||||
paut.data = file_get_data(ef_authtoken);
|
||||
paut.len = file_get_size(ef_authtoken);
|
||||
}
|
||||
else {
|
||||
printf("FATAL ERROR: Auth Token not found in memory!\r\n");
|
||||
}
|
||||
low_flash_available();
|
||||
return CCID_OK;
|
||||
}
|
||||
@ -218,6 +236,17 @@ bool wait_button_pressed() {
|
||||
return (val == EV_BUTTON_TIMEOUT);
|
||||
}
|
||||
|
||||
uint32_t user_present_time_limit = 0;
|
||||
|
||||
bool check_user_presence() {
|
||||
if (user_present_time_limit == 0 || user_present_time_limit+TRANSPORT_TIME_LIMIT < board_millis()) {
|
||||
if (wait_button() == true) //timeout
|
||||
return false;
|
||||
user_present_time_limit = board_millis();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef struct cmd
|
||||
{
|
||||
uint8_t ins;
|
||||
|
@ -54,6 +54,15 @@ extern CTAPHID_FRAME *ctap_req, *ctap_resp;
|
||||
#define FIDO2_AUT_FLAG_AT 0x40
|
||||
#define FIDO2_AUT_FLAG_ED 0x80
|
||||
|
||||
#define FIDO2_PERMISSION_MC 0x1
|
||||
#define FIDO2_PERMISSION_GA 0x2
|
||||
#define FIDO2_PERMISSION_CM 0x4
|
||||
#define FIDO2_PERMISSION_BE 0x8
|
||||
#define FIDO2_PERMISSION_LBW 0x10
|
||||
#define FIDO2_PERMISSION_ACFG 0x20
|
||||
|
||||
#define MAX_PIN_RETRIES 3
|
||||
|
||||
typedef struct known_app {
|
||||
const uint8_t *rp_id_hash;
|
||||
const char *label;
|
||||
@ -63,4 +72,20 @@ typedef struct known_app {
|
||||
|
||||
extern const known_app_t *find_app_by_rp_id_hash(const uint8_t *rp_id_hash);
|
||||
|
||||
#define TRANSPORT_TIME_LIMIT (30*1000) //USB
|
||||
|
||||
bool check_user_presence();
|
||||
|
||||
typedef struct pinUvAuthToken {
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
bool in_use;
|
||||
uint8_t permissions;
|
||||
uint8_t rp_id_hash[32];
|
||||
} pinUvAuthToken_t;
|
||||
|
||||
extern uint32_t user_present_time_limit;
|
||||
|
||||
extern pinUvAuthToken_t paut;
|
||||
|
||||
#endif //_FIDO_H
|
||||
|
@ -23,7 +23,8 @@ file_t file_entries[] = {
|
||||
{.fid = EF_KEY_DEV, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // Device Key
|
||||
{.fid = EF_EE_DEV, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // End Entity Certificate Device
|
||||
{.fid = EF_COUNTER, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // Global counter
|
||||
{.fid = EF_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // Global counter
|
||||
{.fid = EF_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // PIN
|
||||
{.fid = EF_AUTHTOKEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff}}, // AUTH TOKEN
|
||||
{ .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
|
||||
};
|
||||
|
||||
@ -33,3 +34,4 @@ file_t *ef_keydev = NULL;
|
||||
file_t *ef_certdev = NULL;
|
||||
file_t *ef_counter = NULL;
|
||||
file_t *ef_pin = NULL;
|
||||
file_t *ef_authtoken = NULL;
|
||||
|
@ -24,10 +24,12 @@
|
||||
#define EF_EE_DEV 0xCE00
|
||||
#define EF_COUNTER 0xC000
|
||||
#define EF_PIN 0x1080
|
||||
#define EF_AUTHTOKEN 0x1090
|
||||
|
||||
extern file_t *ef_keydev;
|
||||
extern file_t *ef_certdev;
|
||||
extern file_t *ef_counter;
|
||||
extern file_t *ef_pin;
|
||||
extern file_t *ef_authtoken;
|
||||
|
||||
#endif //_FILES_H_
|
||||
|
Loading…
Reference in New Issue
Block a user