diff --git a/CMakeLists.txt b/CMakeLists.txt index d4a6401..63b3cf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ target_sources(pico_fido PUBLIC ${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 + ${CMAKE_CURRENT_LIST_DIR}/src/fido/cmd_authenticate.c ) set(HSM_DRIVER "hid") include(pico-hsm-sdk/pico_hsm_sdk_import.cmake) diff --git a/src/fido/cmd_authenticate.c b/src/fido/cmd_authenticate.c new file mode 100644 index 0000000..1485ff3 --- /dev/null +++ b/src/fido/cmd_authenticate.c @@ -0,0 +1,55 @@ +/* + * 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 . + */ + +#include "fido.h" +#include "hsm.h" +#include "apdu.h" +#include "u2f.h" +#include "mbedtls/ecdsa.h" +#include "random.h" +#include "files.h" + +int cmd_authenticate() { + U2F_AUTHENTICATE_REQ *req = (U2F_AUTHENTICATE_REQ *)apdu.data; + U2F_AUTHENTICATE_RESP *resp = (U2F_AUTHENTICATE_RESP *)res_APDU; + if (scan_files() != CCID_OK) + return SW_EXEC_ERROR(); + resp->flags = 0x1; + resp->ctr[0] = 0; + uint8_t hash[32], sig_base[U2F_APPID_SIZE+1+4+U2F_CHAL_SIZE]; + memcpy(sig_base, req->appId, U2F_APPID_SIZE); + memcpy(sig_base+U2F_APPID_SIZE, &resp->flags, sizeof(uint8_t)); + memcpy(sig_base + U2F_APPID_SIZE + 1, resp->ctr, 4); + memcpy(sig_base + U2F_APPID_SIZE + 1 + 4, req->chal, U2F_CHAL_SIZE); + int ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), sig_base, sizeof(sig_base), hash); + if (ret != 0) + return SW_EXEC_ERROR(); + mbedtls_ecdsa_context key; + mbedtls_ecdsa_init(&key); + ret = derive_key(req->appId, false, req->keyHandle, &key); + if (ret != CCID_OK) { + mbedtls_ecdsa_free(&key); + return SW_EXEC_ERROR(); + } + size_t olen = 0; + ret = mbedtls_ecdsa_write_signature(&key, MBEDTLS_MD_SHA256, hash, 32, (uint8_t *)resp->sig, U2F_MAX_EC_SIG_SIZE, &olen, random_gen, NULL); + mbedtls_ecdsa_free(&key); + if (ret != 0) + return SW_EXEC_ERROR(); + res_APDU_size = 1 + 4 + olen; + return SW_OK(); +} diff --git a/src/fido/fido.c b/src/fido/fido.c index 269a452..08e31da 100644 --- a/src/fido/fido.c +++ b/src/fido/fido.c @@ -193,9 +193,11 @@ typedef struct cmd } cmd_t; extern int cmd_register(); +extern int cmd_authenticate(); static const cmd_t cmds[] = { { U2F_REGISTER, cmd_register }, + { U2F_AUTHENTICATE, cmd_authenticate }, { 0x00, 0x0} }; diff --git a/src/fido/fido.h b/src/fido/fido.h index 255f625..831eca2 100644 --- a/src/fido/fido.h +++ b/src/fido/fido.h @@ -28,6 +28,7 @@ #define SHA256_DIGEST_LENGTH (32) #define KEY_HANDLE_LEN (KEY_PATH_LEN + SHA256_DIGEST_LENGTH) +extern int scan_files(); extern int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, mbedtls_ecdsa_context *key); #endif //_FIDO_H