Merge branch 'development' into eddsa
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include "apdu.h"
|
||||
#include "management.h"
|
||||
#include "ctap2_cbor.h"
|
||||
#include "version.h"
|
||||
|
||||
const bool _btrue = true, _bfalse = false;
|
||||
|
||||
@@ -40,6 +41,8 @@ int cbor_config(const uint8_t *data, size_t len);
|
||||
int cbor_vendor(const uint8_t *data, size_t len);
|
||||
int cbor_large_blobs(const uint8_t *data, size_t len);
|
||||
|
||||
extern int cmd_read_config();
|
||||
|
||||
const uint8_t aaguid[16] =
|
||||
{ 0x89, 0xFB, 0x94, 0xB7, 0x06, 0xC9, 0x36, 0x73, 0x9B, 0x7E, 0x30, 0x52, 0x6D, 0x96, 0x81, 0x45 }; // First 16 bytes of SHA256("Pico FIDO2")
|
||||
|
||||
@@ -91,6 +94,12 @@ int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len) {
|
||||
else if (cmd == CTAP_VENDOR_CBOR) {
|
||||
return cbor_vendor(data, len);
|
||||
}
|
||||
else if (cmd == 0xC2) {
|
||||
if (cmd_read_config() == 0x9000) {
|
||||
res_APDU_size -= 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CTAP1_ERR_INVALID_CMD;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "files.h"
|
||||
#include "random.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
|
||||
uint32_t usage_timer = 0, initial_usage_time_limit = 0;
|
||||
@@ -181,12 +181,12 @@ int resetPinUvAuthToken() {
|
||||
int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out) {
|
||||
if (protocol == 1) {
|
||||
memcpy(out, in, in_len);
|
||||
return aes_encrypt(key, NULL, 32 * 8, HSM_AES_MODE_CBC, out, in_len);
|
||||
return aes_encrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len);
|
||||
}
|
||||
else if (protocol == 2) {
|
||||
random_gen(NULL, out, IV_SIZE);
|
||||
memcpy(out + IV_SIZE, in, in_len);
|
||||
return aes_encrypt(key + 32, out, 32 * 8, HSM_AES_MODE_CBC, out + IV_SIZE, in_len);
|
||||
return aes_encrypt(key + 32, out, 32 * 8, PICO_KEYS_AES_MODE_CBC, out + IV_SIZE, in_len);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -195,11 +195,11 @@ int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_l
|
||||
int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, size_t in_len, uint8_t *out) {
|
||||
if (protocol == 1) {
|
||||
memcpy(out, in, in_len);
|
||||
return aes_decrypt(key, NULL, 32 * 8, HSM_AES_MODE_CBC, out, in_len);
|
||||
return aes_decrypt(key, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len);
|
||||
}
|
||||
else if (protocol == 2) {
|
||||
memcpy(out, in + IV_SIZE, in_len);
|
||||
return aes_decrypt(key + 32, in, 32 * 8, HSM_AES_MODE_CBC, out, in_len - IV_SIZE);
|
||||
return aes_decrypt(key + 32, in, 32 * 8, PICO_KEYS_AES_MODE_CBC, out, in_len - IV_SIZE);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "files.h"
|
||||
#include "apdu.h"
|
||||
#include "credential.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "random.h"
|
||||
#include "mbedtls/ecdh.h"
|
||||
#include "mbedtls/chachapoly.h"
|
||||
@@ -64,7 +64,7 @@ int cbor_config(const uint8_t *data, size_t len) {
|
||||
raw_subpara = (uint8_t *) cbor_value_get_next_byte(&_f1);
|
||||
CBOR_PARSE_MAP_START(_f1, 2)
|
||||
{
|
||||
if (subcommand == 0xff) {
|
||||
if (subcommand == 0x7f) {
|
||||
CBOR_FIELD_GET_UINT(subpara, 2);
|
||||
if (subpara == 0x01) {
|
||||
CBOR_FIELD_GET_UINT(vendorCommandId, 2);
|
||||
@@ -134,7 +134,7 @@ int cbor_config(const uint8_t *data, size_t len) {
|
||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||
}
|
||||
|
||||
if (subcommand == 0xff) {
|
||||
if (subcommand == 0x7f) {
|
||||
if (vendorCommandId == CTAP_CONFIG_AUT_DISABLE) {
|
||||
if (!file_has_data(ef_keydev_enc)) {
|
||||
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "files.h"
|
||||
#include "apdu.h"
|
||||
#include "credential.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
|
||||
uint8_t rp_counter = 1;
|
||||
uint8_t rp_total = 0;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "fido.h"
|
||||
#include "files.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "cbor_make_credential.h"
|
||||
#include "credential.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "hid/ctap_hid.h"
|
||||
#include "files.h"
|
||||
#include "apdu.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
static uint64_t expectedLength = 0, expectedNextOffset = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "credential.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "random.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
|
||||
int cbor_make_credential(const uint8_t *data, size_t len) {
|
||||
CborParser parser;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "hid/ctap_hid.h"
|
||||
#include "files.h"
|
||||
#include "apdu.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "random.h"
|
||||
#include "mbedtls/ecdh.h"
|
||||
#include "mbedtls/chachapoly.h"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "fido.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "ctap.h"
|
||||
#include "random.h"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "fido.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "ctap.h"
|
||||
#include "random.h"
|
||||
@@ -32,18 +32,17 @@ const uint8_t u2f_aid[] = {
|
||||
int u2f_unload();
|
||||
int u2f_process_apdu();
|
||||
|
||||
app_t *u2f_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, u2f_aid + 1, MIN(aid_len, u2f_aid[0])) && cap_supported(CAP_U2F)) {
|
||||
a->aid = u2f_aid;
|
||||
int u2f_select(app_t *a) {
|
||||
if (cap_supported(CAP_U2F)) {
|
||||
a->process_apdu = u2f_process_apdu;
|
||||
a->unload = u2f_unload;
|
||||
return a;
|
||||
return CCID_OK;
|
||||
}
|
||||
return NULL;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
void __attribute__((constructor)) u2f_ctor() {
|
||||
register_app(u2f_select);
|
||||
register_app(u2f_select, u2f_aid);
|
||||
}
|
||||
|
||||
int u2f_unload() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "apdu.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
|
||||
int cmd_version() {
|
||||
memcpy(res_APDU, "U2F_V2", strlen("U2F_V2"));
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "ctap.h"
|
||||
#include "random.h"
|
||||
#include "files.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
|
||||
int credential_derive_chacha_key(uint8_t *outk);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "fido.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "ctap.h"
|
||||
#include "files.h"
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <math.h>
|
||||
#include "management.h"
|
||||
#include "ctap_hid.h"
|
||||
#include "version.h"
|
||||
|
||||
int fido_process_apdu();
|
||||
int fido_unload();
|
||||
@@ -42,7 +43,7 @@ pinUvAuthToken_t paut = { 0 };
|
||||
uint8_t keydev_dec[32];
|
||||
bool has_keydev_dec = false;
|
||||
|
||||
const uint8_t fido_aid[] = {
|
||||
const uint8_t _fido_aid[] = {
|
||||
8,
|
||||
0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01
|
||||
};
|
||||
@@ -53,21 +54,44 @@ const uint8_t atr_fido[] = {
|
||||
0x75, 0x62, 0x69, 0x4b, 0x65, 0x79, 0x40
|
||||
};
|
||||
|
||||
app_t *fido_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, fido_aid + 1, MIN(aid_len, fido_aid[0])) && cap_supported(CAP_FIDO2)) {
|
||||
a->aid = fido_aid;
|
||||
uint8_t fido_get_version_major() {
|
||||
return PICO_FIDO_VERSION_MAJOR;
|
||||
}
|
||||
uint8_t fido_get_version_minor() {
|
||||
return PICO_FIDO_VERSION_MINOR;
|
||||
}
|
||||
|
||||
int fido_select(app_t *a) {
|
||||
if (cap_supported(CAP_FIDO2)) {
|
||||
a->process_apdu = fido_process_apdu;
|
||||
a->unload = fido_unload;
|
||||
return a;
|
||||
return CCID_OK;
|
||||
}
|
||||
return NULL;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
extern uint8_t (*get_version_major)();
|
||||
extern uint8_t (*get_version_minor)();
|
||||
extern const uint8_t *fido_aid;
|
||||
extern void (*init_fido_cb)();
|
||||
extern void (*cbor_thread_func)();
|
||||
extern int (*cbor_process_cb)(uint8_t, const uint8_t *, size_t);
|
||||
extern void cbor_thread();
|
||||
extern int cbor_process(uint8_t last_cmd, const uint8_t *data, size_t len);
|
||||
|
||||
void __attribute__((constructor)) fido_ctor() {
|
||||
#if defined(USB_ITF_CCID) || defined(ENABLE_EMULATION)
|
||||
ccid_atr = atr_fido;
|
||||
#endif
|
||||
register_app(fido_select);
|
||||
get_version_major = fido_get_version_major;
|
||||
get_version_minor = fido_get_version_minor;
|
||||
fido_aid = _fido_aid;
|
||||
init_fido_cb = init_fido;
|
||||
#ifndef ENABLE_EMULATION
|
||||
cbor_thread_func = cbor_thread;
|
||||
#endif
|
||||
cbor_process_cb = cbor_process;
|
||||
register_app(fido_select, fido_aid);
|
||||
}
|
||||
|
||||
int fido_unload() {
|
||||
@@ -389,8 +413,10 @@ void scan_all() {
|
||||
scan_files();
|
||||
}
|
||||
|
||||
extern void init_otp();
|
||||
void init_fido() {
|
||||
scan_all();
|
||||
init_otp();
|
||||
}
|
||||
|
||||
bool wait_button_pressed() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "fido.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "version.h"
|
||||
#include "files.h"
|
||||
@@ -31,22 +31,20 @@ const uint8_t man_aid[] = {
|
||||
0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17
|
||||
};
|
||||
extern void scan_all();
|
||||
app_t *man_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, man_aid + 1, MIN(aid_len, man_aid[0]))) {
|
||||
a->aid = man_aid;
|
||||
a->process_apdu = man_process_apdu;
|
||||
a->unload = man_unload;
|
||||
sprintf((char *) res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR);
|
||||
res_APDU_size = strlen((char *) res_APDU);
|
||||
apdu.ne = res_APDU_size;
|
||||
scan_all();
|
||||
return a;
|
||||
}
|
||||
return NULL;
|
||||
extern void init_otp();
|
||||
int man_select(app_t *a) {
|
||||
a->process_apdu = man_process_apdu;
|
||||
a->unload = man_unload;
|
||||
sprintf((char *) res_APDU, "%d.%d.0", PICO_FIDO_VERSION_MAJOR, PICO_FIDO_VERSION_MINOR);
|
||||
res_APDU_size = strlen((char *) res_APDU);
|
||||
apdu.ne = res_APDU_size;
|
||||
scan_all();
|
||||
init_otp();
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
void __attribute__((constructor)) man_ctor() {
|
||||
register_app(man_select);
|
||||
register_app(man_select, man_aid);
|
||||
}
|
||||
|
||||
int man_unload() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "fido.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "files.h"
|
||||
#include "random.h"
|
||||
@@ -68,9 +68,8 @@ const uint8_t oath_aid[] = {
|
||||
0xa0, 0x00, 0x00, 0x05, 0x27, 0x21, 0x01
|
||||
};
|
||||
|
||||
app_t *oath_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, oath_aid + 1, MIN(aid_len, oath_aid[0])) && cap_supported(CAP_OATH)) {
|
||||
a->aid = oath_aid;
|
||||
int oath_select(app_t *a) {
|
||||
if (cap_supported(CAP_OATH)) {
|
||||
a->process_apdu = oath_process_apdu;
|
||||
a->unload = oath_unload;
|
||||
res_APDU_size = 0;
|
||||
@@ -82,10 +81,10 @@ app_t *oath_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
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;
|
||||
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;
|
||||
memset(res_APDU + res_APDU_size, 0, 8); res_APDU_size += 8;
|
||||
#endif
|
||||
if (file_has_data(search_dynamic_file(EF_OATH_CODE)) == true) {
|
||||
random_gen(NULL, challenge, sizeof(challenge));
|
||||
@@ -105,13 +104,13 @@ app_t *oath_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = ALG_HMAC_SHA1;
|
||||
apdu.ne = res_APDU_size;
|
||||
return a;
|
||||
return CCID_OK;
|
||||
}
|
||||
return NULL;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
void __attribute__((constructor)) oath_ctor() {
|
||||
register_app(oath_select);
|
||||
register_app(oath_select, oath_aid);
|
||||
}
|
||||
|
||||
int oath_unload() {
|
||||
@@ -455,6 +454,7 @@ int cmd_calculate_all() {
|
||||
if (asn1_find_tag(apdu.data, apdu.nc, TAG_CHALLENGE, &chal_len, &chal) == false) {
|
||||
return SW_INCORRECT_PARAMS();
|
||||
}
|
||||
res_APDU_size = 0;
|
||||
for (int i = 0; i < MAX_OATH_CRED; i++) {
|
||||
file_t *ef = search_dynamic_file(EF_OATH_CRED + i);
|
||||
if (file_has_data(ef)) {
|
||||
|
||||
154
src/fido/otp.c
154
src/fido/otp.c
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "fido.h"
|
||||
#include "hsm.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "files.h"
|
||||
#include "random.h"
|
||||
@@ -111,14 +111,20 @@ uint16_t otp_status();
|
||||
int otp_process_apdu();
|
||||
int otp_unload();
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
extern int (*hid_set_report_cb)(uint8_t, uint8_t, hid_report_type_t, uint8_t const *, uint16_t);
|
||||
extern uint16_t (*hid_get_report_cb)(uint8_t, uint8_t, hid_report_type_t, uint8_t *, uint16_t);
|
||||
int otp_hid_set_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t const *, uint16_t);
|
||||
uint16_t otp_hid_get_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t *, uint16_t);
|
||||
#endif
|
||||
|
||||
const uint8_t otp_aid[] = {
|
||||
7,
|
||||
0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01
|
||||
};
|
||||
|
||||
app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, otp_aid + 1, MIN(aid_len, otp_aid[0])) && cap_supported(CAP_OTP)) {
|
||||
a->aid = otp_aid;
|
||||
int otp_select(app_t *a) {
|
||||
if (cap_supported(CAP_OTP)) {
|
||||
a->process_apdu = otp_process_apdu;
|
||||
a->unload = otp_unload;
|
||||
if (file_has_data(search_dynamic_file(EF_OTP_SLOT1)) ||
|
||||
@@ -132,9 +138,9 @@ app_t *otp_select(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
memmove(res_APDU, res_APDU + 1, 6);
|
||||
res_APDU_size = 6;
|
||||
apdu.ne = res_APDU_size;
|
||||
return a;
|
||||
return CCID_OK;
|
||||
}
|
||||
return NULL;
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
uint8_t modhex_tab[] =
|
||||
@@ -176,6 +182,22 @@ extern int calculate_oath(uint8_t truncate,
|
||||
size_t key_len,
|
||||
const uint8_t *chal,
|
||||
size_t chal_len);
|
||||
|
||||
uint16_t calculate_crc(const uint8_t *data, size_t data_len) {
|
||||
uint16_t crc = 0xFFFF;
|
||||
for (size_t idx = 0; idx < data_len; idx++) {
|
||||
crc ^= data[idx];
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
uint16_t j = crc & 0x1;
|
||||
crc >>= 1;
|
||||
if (j == 1) {
|
||||
crc ^= 0x8408;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc & 0xFFFF;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
static uint8_t session_counter[2] = { 0 };
|
||||
#endif
|
||||
@@ -244,10 +266,11 @@ int otp_button_pressed(uint8_t slot) {
|
||||
}
|
||||
}
|
||||
else if (otp_config->cfg_flags & SHORT_TICKET || otp_config->cfg_flags & STATIC_TICKET) {
|
||||
if (otp_config->cfg_flags & SHORT_TICKET) {
|
||||
otp_config->fixed_size /= 2;
|
||||
uint8_t fixed_size = FIXED_SIZE + UID_SIZE + KEY_SIZE;
|
||||
if (otp_config->cfg_flags & SHORT_TICKET) { // Not clear which is the purpose of SHORT_TICKET
|
||||
//fixed_size /= 2;
|
||||
}
|
||||
add_keyboard_buffer(otp_config->fixed_data, otp_config->fixed_size, false);
|
||||
add_keyboard_buffer(otp_config->fixed_data, fixed_size, false);
|
||||
if (otp_config->tkt_flags & APPEND_CR) {
|
||||
append_keyboard_buffer((const uint8_t *) "\x28", 1);
|
||||
}
|
||||
@@ -308,8 +331,12 @@ int otp_button_pressed(uint8_t slot) {
|
||||
}
|
||||
|
||||
void __attribute__((constructor)) otp_ctor() {
|
||||
register_app(otp_select);
|
||||
register_app(otp_select, otp_aid);
|
||||
button_pressed_cb = otp_button_pressed;
|
||||
#ifndef ENABLE_EMULATION
|
||||
hid_set_report_cb = otp_hid_set_report_cb;
|
||||
hid_get_report_cb = otp_hid_get_report_cb;
|
||||
#endif
|
||||
}
|
||||
|
||||
int otp_unload() {
|
||||
@@ -489,3 +516,110 @@ int otp_process_apdu() {
|
||||
}
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
}
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
|
||||
uint8_t otp_frame_rx[70] = {0};
|
||||
uint8_t otp_frame_tx[70] = {0};
|
||||
uint8_t otp_exp_seq = 0, otp_curr_seq = 0;
|
||||
uint8_t otp_header[4] = {0};
|
||||
|
||||
extern uint16_t *get_send_buffer_size(uint8_t itf);
|
||||
|
||||
int otp_send_frame(uint8_t *frame, size_t frame_len) {
|
||||
uint16_t crc = calculate_crc(frame, frame_len);
|
||||
frame[frame_len] = ~crc & 0xff;
|
||||
frame[frame_len + 1] = ~crc >> 8;
|
||||
frame_len += 2;
|
||||
*get_send_buffer_size(ITF_KEYBOARD) = frame_len;
|
||||
otp_exp_seq = (frame_len / 7);
|
||||
if (frame_len % 7) {
|
||||
otp_exp_seq++;
|
||||
}
|
||||
otp_curr_seq = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int otp_hid_set_report_cb(uint8_t itf,
|
||||
uint8_t report_id,
|
||||
hid_report_type_t report_type,
|
||||
uint8_t const *buffer,
|
||||
uint16_t bufsize)
|
||||
{
|
||||
if (report_type == 3) {
|
||||
DEBUG_PAYLOAD(buffer, bufsize);
|
||||
if (itf == ITF_KEYBOARD && buffer[7] == 0xFF) { // reset
|
||||
*get_send_buffer_size(ITF_KEYBOARD) = 0;
|
||||
otp_curr_seq = otp_exp_seq = 0;
|
||||
memset(otp_frame_tx, 0, sizeof(otp_frame_tx));
|
||||
}
|
||||
else if (buffer[7] & 0x80) { // a frame
|
||||
uint8_t rseq = buffer[7] & 0x1F;
|
||||
if (rseq < 10) {
|
||||
if (rseq == 0) {
|
||||
memset(otp_frame_rx, 0, sizeof(otp_frame_rx));
|
||||
}
|
||||
memcpy(otp_frame_rx + rseq * 7, buffer, 7);
|
||||
if (rseq == 9) {
|
||||
DEBUG_DATA(otp_frame_rx, sizeof(otp_frame_rx));
|
||||
uint16_t residual_crc = calculate_crc(otp_frame_rx, 64), rcrc = (otp_frame_rx[66] << 8 | otp_frame_rx[65]);
|
||||
uint8_t slot_id = otp_frame_rx[64];
|
||||
if (residual_crc == rcrc) {
|
||||
apdu.data = otp_frame_rx;
|
||||
apdu.nc = 64;
|
||||
apdu.rdata = otp_frame_tx;
|
||||
apdu.header[0] = 0;
|
||||
apdu.header[1] = 0x01;
|
||||
apdu.header[2] = slot_id;
|
||||
apdu.header[3] = 0;
|
||||
int ret = otp_process_apdu();
|
||||
if (ret == 0x9000 && res_APDU_size > 0) {
|
||||
otp_send_frame(apdu.rdata, apdu.rlen);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[OTP] Bad CRC!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t otp_hid_get_report_cb(uint8_t itf,
|
||||
uint8_t report_id,
|
||||
hid_report_type_t report_type,
|
||||
uint8_t *buffer,
|
||||
uint16_t reqlen) {
|
||||
// TODO not Implemented
|
||||
(void) itf;
|
||||
(void) report_id;
|
||||
(void) report_type;
|
||||
(void) buffer;
|
||||
(void) reqlen;
|
||||
uint16_t send_buffer_size = *get_send_buffer_size(ITF_KEYBOARD);
|
||||
if (send_buffer_size > 0) {
|
||||
uint8_t seq = otp_curr_seq++;
|
||||
memset(buffer, 0, 8);
|
||||
memcpy(buffer, otp_frame_tx + 7 * seq, MIN(7, send_buffer_size));
|
||||
buffer[7] = 0x40 | seq;
|
||||
DEBUG_DATA(buffer, 8);
|
||||
*get_send_buffer_size(ITF_KEYBOARD) -= MIN(7, send_buffer_size);
|
||||
}
|
||||
else if (otp_curr_seq == otp_exp_seq && otp_exp_seq > 0) {
|
||||
memset(buffer, 0, 7);
|
||||
buffer[7] = 0x40;
|
||||
DEBUG_DATA(buffer,8);
|
||||
otp_curr_seq = otp_exp_seq = 0;
|
||||
}
|
||||
else {
|
||||
otp_status();
|
||||
memcpy(buffer, res_APDU, 7);
|
||||
}
|
||||
|
||||
return reqlen;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef __VERSION_H_
|
||||
#define __VERSION_H_
|
||||
|
||||
#define PICO_FIDO_VERSION 0x0507
|
||||
#define PICO_FIDO_VERSION 0x0508
|
||||
|
||||
#define PICO_FIDO_VERSION_MAJOR ((PICO_FIDO_VERSION >> 8) & 0xff)
|
||||
#define PICO_FIDO_VERSION_MINOR (PICO_FIDO_VERSION & 0xff)
|
||||
|
||||
Reference in New Issue
Block a user