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
19 changed files with 117 additions and 20 deletions

View File

@@ -17,14 +17,20 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
if(ENABLE_EMULATION)
else()
include(pico_sdk_import.cmake) include(pico_sdk_import.cmake)
endif()
project(pico_fido C CXX ASM) project(pico_fido C CXX ASM)
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
if(ENABLE_EMULATION)
else()
pico_sdk_init() pico_sdk_init()
endif()
add_executable(pico_fido) add_executable(pico_fido)
@@ -70,7 +76,7 @@ else()
set(USB_ITF_CCID 0) set(USB_ITF_CCID 0)
endif() endif()
target_sources(pico_fido PUBLIC set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/fido.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/fido.c
${CMAKE_CURRENT_LIST_DIR}/src/fido/files.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_register.c
@@ -91,12 +97,12 @@ target_sources(pico_fido PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_large_blobs.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/cbor_large_blobs.c
) )
if (${ENABLE_OATH_APP}) if (${ENABLE_OATH_APP})
target_sources(pico_fido PUBLIC set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/oath.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/oath.c
) )
endif() endif()
if (${ENABLE_OTP_APP}) if (${ENABLE_OTP_APP})
target_sources(pico_fido PUBLIC set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fido/otp.c ${CMAKE_CURRENT_LIST_DIR}/src/fido/otp.c
) )
endif() endif()
@@ -104,10 +110,13 @@ endif()
set(USB_ITF_HID 1) set(USB_ITF_HID 1)
include(pico-hsm-sdk/pico_hsm_sdk_import.cmake) include(pico-hsm-sdk/pico_hsm_sdk_import.cmake)
target_include_directories(pico_fido PUBLIC set(INCLUDES ${INCLUDES}
${CMAKE_CURRENT_LIST_DIR}/src/fido ${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 target_compile_options(pico_fido PUBLIC
-Wall -Wall
-Werror -Werror
@@ -119,6 +128,16 @@ if (${COMPILER_COLON} GREATER_EQUAL 0)
) )
endif() 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) 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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,6 +18,7 @@
#include "ctap2_cbor.h" #include "ctap2_cbor.h"
#include "fido.h" #include "fido.h"
#include "ctap.h" #include "ctap.h"
#include "hid/ctap_hid.h"
#include "files.h" #include "files.h"
#include "apdu.h" #include "apdu.h"
#include "hsm.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); mbedtls_ecdsa_free(&ekey);
CBOR_ERROR(CTAP2_ERR_PROCESSING); CBOR_ERROR(CTAP2_ERR_PROCESSING);
} }
#ifndef ENABLE_EMULATION
pico_unique_board_id_t rpiid; pico_unique_board_id_t rpiid;
pico_get_unique_board_id(&rpiid); pico_get_unique_board_id(&rpiid);
#else
struct {
uint8_t id[8];
} rpiid = {0};
#endif
mbedtls_x509write_csr ctx; mbedtls_x509write_csr ctx;
mbedtls_x509write_csr_init(&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]); 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 "ctap.h"
#include "random.h" #include "random.h"
#include "files.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_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"; const uint8_t *bogus_chrome = (const uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
@@ -38,7 +39,11 @@ int cmd_register() {
if (wait_button_pressed() == true) if (wait_button_pressed() == true)
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
if (memcmp(req->appId, bogus_firefox, CTAP_APPID_SIZE) == 0 || memcmp(req->appId, bogus_chrome, CTAP_APPID_SIZE) == 0) 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); return ctap_error(CTAP1_ERR_CHANNEL_BUSY);
#else
return SW_DATA_INVALID();
#endif
mbedtls_ecdsa_context key; mbedtls_ecdsa_context key;
mbedtls_ecdsa_init(&key); mbedtls_ecdsa_init(&key);
int ret = derive_key(req->appId, true, resp->keyHandleCertSig, MBEDTLS_ECP_DP_SECP256R1, &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/chachapoly.h"
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
#include "credential.h" #include "credential.h"
#ifndef ENABLE_EMULATION
#include "bsp/board.h" #include "bsp/board.h"
#endif
#include "hid/ctap_hid.h"
#include "fido.h" #include "fido.h"
#include "ctap.h" #include "ctap.h"
#include "random.h" #include "random.h"

View File

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

View File

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

View File

@@ -18,10 +18,16 @@
#ifndef _FIDO_H_ #ifndef _FIDO_H_
#define _FIDO_H_ #define _FIDO_H_
#ifndef ENABLE_EMULATION
#include "pico/stdlib.h" #include "pico/stdlib.h"
#endif
#include "common.h" #include "common.h"
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
#ifndef ENABLE_EMULATION
#include "ctap_hid.h" #include "ctap_hid.h"
#else
#include <stdbool.h>
#endif
#define CTAP_PUBKEY_LEN (65) #define CTAP_PUBKEY_LEN (65)
#define KEY_PATH_LEN (32) #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 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 int verify_key(const uint8_t *appId, const uint8_t *keyHandle, mbedtls_ecdsa_context *);
extern bool wait_button_pressed(); extern bool wait_button_pressed();
extern CTAPHID_FRAME *ctap_req, *ctap_resp;
extern void init_fido(); extern void init_fido();
extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve); 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); 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++] = 0;
res_APDU[res_APDU_size++] = TAG_NAME; res_APDU[res_APDU_size++] = TAG_NAME;
res_APDU[res_APDU_size++] = 8; 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; 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) { if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) {
res_APDU[res_APDU_size++] = TAG_CHALLENGE; res_APDU[res_APDU_size++] = TAG_CHALLENGE;
res_APDU[res_APDU_size++] = sizeof(challenge); res_APDU[res_APDU_size++] = sizeof(challenge);
memcpy(res_APDU+res_APDU_size, challenge, sizeof(challenge)); 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 a;
} }
return NULL; return NULL;
@@ -248,6 +253,7 @@ int cmd_list() {
} }
} }
} }
apdu.ne = res_APDU_size;
return SW_OK(); return SW_OK();
} }
@@ -281,6 +287,7 @@ int cmd_validate() {
res_APDU[res_APDU_size++] = TAG_RESPONSE; res_APDU[res_APDU_size++] = TAG_RESPONSE;
res_APDU[res_APDU_size++] = mbedtls_md_get_size(md_info); 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); 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(); 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]; res_APDU[res_APDU_size++] = key[1];
memcpy(res_APDU+res_APDU_size, hmac, hmac_size); res_APDU_size += hmac_size; memcpy(res_APDU+res_APDU_size, hmac, hmac_size); res_APDU_size += hmac_size;
} }
apdu.ne = res_APDU_size;
return CCID_OK; return CCID_OK;
} }
@@ -357,6 +365,7 @@ int cmd_calculate() {
low_flash_available(); low_flash_available();
free(tmp); free(tmp);
} }
apdu.ne = res_APDU_size;
return SW_OK(); 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(); return SW_OK();
} }
@@ -421,6 +435,7 @@ static const cmd_t cmds[] = {
{ INS_VALIDATE, cmd_validate }, { INS_VALIDATE, cmd_validate },
{ INS_CALCULATE, cmd_calculate }, { INS_CALCULATE, cmd_calculate },
{ INS_CALC_ALL, cmd_calculate_all }, { INS_CALC_ALL, cmd_calculate_all },
{ INS_SEND_REMAINING, cmd_send_remaining },
{ 0x00, 0x0} { 0x00, 0x0}
}; };

View File

@@ -36,7 +36,7 @@
#define CONFIG_LED_INV 0x10 #define CONFIG_LED_INV 0x10
#define CONFIG_STATUS_MASK 0x1f #define CONFIG_STATUS_MASK 0x1f
static uint8_t config_seq[2] = {1}; static uint8_t config_seq = {1};
typedef struct otp_config { typedef struct otp_config {
uint8_t fixed_data[FIXED_SIZE]; uint8_t fixed_data[FIXED_SIZE];
@@ -52,13 +52,14 @@ typedef struct otp_config {
} __attribute__((packed)) otp_config_t; } __attribute__((packed)) otp_config_t;
static const size_t otp_config_size = sizeof(otp_config_t); static const size_t otp_config_size = sizeof(otp_config_t);
uint16_t otp_status();
int otp_process_apdu(); int otp_process_apdu();
int otp_unload(); int otp_unload();
const uint8_t otp_aid[] = { const uint8_t otp_aid[] = {
7, 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) { 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->aid = otp_aid;
a->process_apdu = otp_process_apdu; a->process_apdu = otp_process_apdu;
a->unload = otp_unload; 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 a;
} }
return NULL; return NULL;
@@ -79,13 +86,13 @@ int otp_unload() {
return CCID_OK; 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_MAJOR;
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR; res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR;
res_APDU[res_APDU_size++] = 0; 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++] = 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(); return SW_OK();
} }
@@ -99,7 +106,6 @@ int cmd_otp() {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
if (apdu.data[48] != 0 || apdu.data[49] != 0) if (apdu.data[48] != 0 || apdu.data[49] != 0)
return SW_WRONG_DATA(); return SW_WRONG_DATA();
uint8_t slot = p1 == 0x01 ? 0 : 1;
file_t *ef = file_new(p1 == 0x01 ? EF_OTP_SLOT1 : EF_OTP_SLOT2); file_t *ef = file_new(p1 == 0x01 ? EF_OTP_SLOT1 : EF_OTP_SLOT2);
if (file_has_data(ef)) { if (file_has_data(ef)) {
otp_config_t *otpc = (otp_config_t *)file_get_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) { if (apdu.data[c] != 0) {
flash_write_data_to_file(ef, apdu.data, otp_config_size); flash_write_data_to_file(ef, apdu.data, otp_config_size);
low_flash_available(); low_flash_available();
config_seq[slot]++; config_seq++;
return otp_status(slot); return otp_status();
} }
} }
// Delete slot // Delete slot
delete_file(ef); delete_file(ef);
config_seq[slot] = 0; if (!file_has_data(search_dynamic_file(EF_OTP_SLOT1)) && !file_has_data(search_dynamic_file(EF_OTP_SLOT2)))
return otp_status(slot); 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(); return SW_OK();
} }