Switching to new style.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2023-02-15 00:10:00 +01:00
parent 12bdcbd1f9
commit 43ef33d60b
16 changed files with 429 additions and 521 deletions

View File

@@ -24,8 +24,7 @@ uint8_t *rdata_gr = NULL;
uint16_t rdata_bk = 0x0; uint16_t rdata_bk = 0x0;
extern uint32_t timeout; extern uint32_t timeout;
int process_apdu() int process_apdu() {
{
led_set_blink(BLINK_PROCESSING); led_set_blink(BLINK_PROCESSING);
if (INS(apdu) == 0xA4 && P1(apdu) == 0x04 && (P2(apdu) == 0x00 || P2(apdu) == 0x4)) { //select by AID if (INS(apdu) == 0xA4 && P1(apdu) == 0x04 && (P2(apdu) == 0x00 || P2(apdu) == 0x4)) { //select by AID
if (current_app && current_app->unload) { if (current_app && current_app->unload) {
@@ -44,8 +43,7 @@ int process_apdu()
return set_res_sw(0x6D, 0x00); return set_res_sw(0x6D, 0x00);
} }
size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) {
{
apdu.header = (uint8_t *) buffer; apdu.header = (uint8_t *) buffer;
apdu.nc = apdu.ne = 0; apdu.nc = apdu.ne = 0;
if (buffer_size == 4) { if (buffer_size == 4) {
@@ -53,19 +51,22 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size)
if (apdu.ne == 0) { if (apdu.ne == 0) {
apdu.ne = 256; apdu.ne = 256;
} }
} else if (buffer_size == 5) { }
else if (buffer_size == 5) {
apdu.nc = 0; apdu.nc = 0;
apdu.ne = apdu.header[4]; apdu.ne = apdu.header[4];
if (apdu.ne == 0) { if (apdu.ne == 0) {
apdu.ne = 256; apdu.ne = 256;
} }
} else if (apdu.header[4] == 0x0 && buffer_size >= 7) { }
else if (apdu.header[4] == 0x0 && buffer_size >= 7) {
if (buffer_size == 7) { if (buffer_size == 7) {
apdu.ne = (apdu.header[5] << 8) | apdu.header[6]; apdu.ne = (apdu.header[5] << 8) | apdu.header[6];
if (apdu.ne == 0) { if (apdu.ne == 0) {
apdu.ne = 65536; apdu.ne = 65536;
} }
} else { }
else {
apdu.ne = 0; apdu.ne = 0;
apdu.nc = (apdu.header[5] << 8) | apdu.header[6]; apdu.nc = (apdu.header[5] << 8) | apdu.header[6];
apdu.data = apdu.header + 7; apdu.data = apdu.header + 7;
@@ -76,7 +77,8 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size)
} }
} }
} }
} else { }
else {
apdu.nc = apdu.header[4]; apdu.nc = apdu.header[4];
apdu.data = apdu.header + 5; apdu.data = apdu.header + 5;
apdu.ne = 0; apdu.ne = 0;
@@ -112,13 +114,15 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size)
apdu.sw = 0; apdu.sw = 0;
apdu.rlen = 0; apdu.rlen = 0;
usb_prepare_response(itf); usb_prepare_response(itf);
} else { }
else {
rdata_gr += apdu.ne; rdata_gr += apdu.ne;
rdata_bk = *rdata_gr; rdata_bk = *rdata_gr;
rdata_gr[0] = 0x61; rdata_gr[0] = 0x61;
if (apdu.rlen - apdu.ne >= 256) { if (apdu.rlen - apdu.ne >= 256) {
rdata_gr[1] = 0; rdata_gr[1] = 0;
} else { }
else {
rdata_gr[1] = apdu.rlen - apdu.ne; rdata_gr[1] = apdu.rlen - apdu.ne;
} }
#ifdef USB_ITF_HID #ifdef USB_ITF_HID
@@ -139,7 +143,8 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size)
apdu.rlen -= apdu.ne; apdu.rlen -= apdu.ne;
} }
return 0; return 0;
} else { }
else {
apdu.sw = 0; apdu.sw = 0;
apdu.rlen = 0; apdu.rlen = 0;
apdu.rdata = usb_prepare_response(itf); apdu.rdata = usb_prepare_response(itf);
@@ -149,8 +154,7 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size)
return 0; return 0;
} }
uint16_t set_res_sw(uint8_t sw1, uint8_t sw2) uint16_t set_res_sw(uint8_t sw1, uint8_t sw2) {
{
apdu.sw = (sw1 << 8) | sw2; apdu.sw = (sw1 << 8) | sw2;
if (sw1 != 0x90) { if (sw1 != 0x90) {
res_APDU_size = 0; res_APDU_size = 0;
@@ -159,8 +163,7 @@ uint16_t set_res_sw(uint8_t sw1, uint8_t sw2)
} }
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
void apdu_thread() void apdu_thread() {
{
card_init_core1(); card_init_core1();
while (1) { while (1) {
uint32_t m = 0; uint32_t m = 0;
@@ -169,7 +172,8 @@ void apdu_thread()
if (m == EV_VERIFY_CMD_AVAILABLE || m == EV_MODIFY_CMD_AVAILABLE) { if (m == EV_VERIFY_CMD_AVAILABLE || m == EV_MODIFY_CMD_AVAILABLE) {
set_res_sw(0x6f, 0x00); set_res_sw(0x6f, 0x00);
goto done; goto done;
} else if (m == EV_EXIT) { }
else if (m == EV_EXIT) {
break; break;
} }
@@ -190,8 +194,7 @@ done: ;
} }
#endif #endif
void apdu_finish() void apdu_finish() {
{
apdu.rdata[apdu.rlen] = apdu.sw >> 8; apdu.rdata[apdu.rlen] = apdu.sw >> 8;
apdu.rdata[apdu.rlen + 1] = apdu.sw & 0xff; apdu.rdata[apdu.rlen + 1] = apdu.sw & 0xff;
timeout_stop(); timeout_stop();
@@ -202,18 +205,19 @@ void apdu_finish()
#endif #endif
} }
size_t apdu_next() size_t apdu_next() {
{
if (apdu.sw != 0) { if (apdu.sw != 0) {
if (apdu.rlen <= apdu.ne) { if (apdu.rlen <= apdu.ne) {
return apdu.rlen + 2; return apdu.rlen + 2;
} else { }
else {
rdata_gr = apdu.rdata + apdu.ne; rdata_gr = apdu.rdata + apdu.ne;
rdata_bk = *(uint16_t *) rdata_gr; rdata_bk = *(uint16_t *) rdata_gr;
rdata_gr[0] = 0x61; rdata_gr[0] = 0x61;
if (apdu.rlen - apdu.ne >= 256) { if (apdu.rlen - apdu.ne >= 256) {
rdata_gr[1] = 0; rdata_gr[1] = 0;
} else { }
else {
rdata_gr[1] = apdu.rlen - apdu.ne; rdata_gr[1] = apdu.rlen - apdu.ne;
} }
apdu.rlen -= apdu.ne; apdu.rlen -= apdu.ne;

View File

@@ -17,8 +17,7 @@
#include "asn1.h" #include "asn1.h"
size_t asn1_len_tag(uint16_t tag, size_t len) size_t asn1_len_tag(uint16_t tag, size_t len) {
{
size_t ret = 1 + format_tlv_len(len, NULL) + len; size_t ret = 1 + format_tlv_len(len, NULL) + len;
if (tag > 0x00ff) { if (tag > 0x00ff) {
return ret + 1; return ret + 1;
@@ -26,20 +25,21 @@ size_t asn1_len_tag(uint16_t tag, size_t len)
return ret; return ret;
} }
int format_tlv_len(size_t len, uint8_t *out) int format_tlv_len(size_t len, uint8_t *out) {
{
if (len < 128) { if (len < 128) {
if (out) { if (out) {
*out = len; *out = len;
} }
return 1; return 1;
} else if (len < 256) { }
else if (len < 256) {
if (out) { if (out) {
*out++ = 0x81; *out++ = 0x81;
*out++ = len; *out++ = len;
} }
return 2; return 2;
} else { }
else {
if (out) { if (out) {
*out++ = 0x82; *out++ = 0x82;
*out++ = (len >> 8) & 0xff; *out++ = (len >> 8) & 0xff;
@@ -55,8 +55,7 @@ int walk_tlv(const uint8_t *cdata,
uint8_t **p, uint8_t **p,
uint16_t *tag, uint16_t *tag,
size_t *tag_len, size_t *tag_len,
uint8_t **data) uint8_t **data) {
{
if (!p) { if (!p) {
return 0; return 0;
} }
@@ -77,7 +76,8 @@ int walk_tlv(const uint8_t *cdata,
if (tgl == 0x82) { if (tgl == 0x82) {
tgl = *(*p)++ << 8; tgl = *(*p)++ << 8;
tgl |= *(*p)++; tgl |= *(*p)++;
} else if (tgl == 0x81) { }
else if (tgl == 0x81) {
tgl = *(*p)++; tgl = *(*p)++;
} }
if (tag) { if (tag) {
@@ -97,8 +97,7 @@ bool asn1_find_tag(const uint8_t *data,
size_t data_len, size_t data_len,
uint16_t itag, uint16_t itag,
size_t *tag_len, size_t *tag_len,
uint8_t **tag_data) uint8_t **tag_data) {
{
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *p = NULL; uint8_t *p = NULL;
uint8_t *tdata = NULL; uint8_t *tdata = NULL;

View File

@@ -24,8 +24,7 @@
#include "crypto_utils.h" #include "crypto_utils.h"
#include "hsm.h" #include "hsm.h"
void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]) void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]) {
{
uint8_t o1[32]; uint8_t o1[32];
hash_multi(pin, len, o1); hash_multi(pin, len, o1);
for (int i = 0; i < sizeof(o1); i++) { for (int i = 0; i < sizeof(o1); i++) {
@@ -34,8 +33,7 @@ void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32])
hash_multi(o1, sizeof(o1), output); hash_multi(o1, sizeof(o1), output);
} }
void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]) void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]) {
{
mbedtls_sha256_context ctx; mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx); mbedtls_sha256_init(&ctx);
int iters = 256; int iters = 256;
@@ -60,8 +58,7 @@ void hash_multi(const uint8_t *input, size_t len, uint8_t output[32])
mbedtls_sha256_free(&ctx); mbedtls_sha256_free(&ctx);
} }
void hash256(const uint8_t *input, size_t len, uint8_t output[32]) void hash256(const uint8_t *input, size_t len, uint8_t output[32]) {
{
mbedtls_sha256_context ctx; mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx); mbedtls_sha256_init(&ctx);
@@ -72,8 +69,7 @@ void hash256(const uint8_t *input, size_t len, uint8_t output[32])
mbedtls_sha256_free(&ctx); mbedtls_sha256_free(&ctx);
} }
void generic_hash(mbedtls_md_type_t md, const uint8_t *input, size_t len, uint8_t *output) void generic_hash(mbedtls_md_type_t md, const uint8_t *input, size_t len, uint8_t *output) {
{
mbedtls_md(mbedtls_md_info_from_type(md), input, len, output); mbedtls_md(mbedtls_md_info_from_type(md), input, len, output);
} }
@@ -82,8 +78,7 @@ int aes_encrypt(const uint8_t *key,
int key_size, int key_size,
int mode, int mode,
uint8_t *data, uint8_t *data,
int len) int len) {
{
mbedtls_aes_context aes; mbedtls_aes_context aes;
mbedtls_aes_init(&aes); mbedtls_aes_init(&aes);
uint8_t tmp_iv[IV_SIZE]; uint8_t tmp_iv[IV_SIZE];
@@ -107,8 +102,7 @@ int aes_decrypt(const uint8_t *key,
int key_size, int key_size,
int mode, int mode,
uint8_t *data, uint8_t *data,
int len) int len) {
{
mbedtls_aes_context aes; mbedtls_aes_context aes;
mbedtls_aes_init(&aes); mbedtls_aes_init(&aes);
uint8_t tmp_iv[IV_SIZE]; uint8_t tmp_iv[IV_SIZE];
@@ -128,12 +122,10 @@ int aes_decrypt(const uint8_t *key,
return mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_DECRYPT, len, &iv_offset, tmp_iv, data, data); return mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_DECRYPT, len, &iv_offset, tmp_iv, data, data);
} }
int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len) int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len) {
{
return aes_encrypt(key, iv, 256, HSM_AES_MODE_CFB, data, len); return aes_encrypt(key, iv, 256, HSM_AES_MODE_CFB, data, len);
} }
int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len) int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, int len) {
{
return aes_decrypt(key, iv, 256, HSM_AES_MODE_CFB, data, len); return aes_decrypt(key, iv, 256, HSM_AES_MODE_CFB, data, len);
} }
@@ -184,8 +176,7 @@ struct ec_curve_mbed_id ec_curves_mbed[] = {
{ { NULL, 0 }, MBEDTLS_ECP_DP_NONE } { { NULL, 0 }, MBEDTLS_ECP_DP_NONE }
}; };
mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len) mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len) {
{
for (struct ec_curve_mbed_id *ec = ec_curves_mbed; ec->id != MBEDTLS_ECP_DP_NONE; ec++) { for (struct ec_curve_mbed_id *ec = ec_curves_mbed; ec->id != MBEDTLS_ECP_DP_NONE; ec++) {
if (prime_len == ec->curve.len && memcmp(prime, ec->curve.value, prime_len) == 0) { if (prime_len == ec->curve.len && memcmp(prime, ec->curve.value, prime_len) == 0) {
return ec->id; return ec->id;

View File

@@ -32,8 +32,7 @@ static uint8_t sm_iv[16];
size_t sm_session_pin_len = 0; size_t sm_session_pin_len = 0;
uint8_t sm_session_pin[16]; uint8_t sm_session_pin[16];
bool is_secured_apdu() bool is_secured_apdu() {
{
return CLA(apdu) & 0xC; return CLA(apdu) & 0xC;
} }
@@ -42,8 +41,7 @@ void sm_derive_key(const uint8_t *input,
uint8_t counter, uint8_t counter,
const uint8_t *nonce, const uint8_t *nonce,
size_t nonce_len, size_t nonce_len,
uint8_t *out) uint8_t *out) {
{
uint8_t *b = (uint8_t *) calloc(1, input_len + nonce_len + 4); uint8_t *b = (uint8_t *) calloc(1, input_len + nonce_len + 4);
if (input) { if (input) {
memcpy(b, input, input_len); memcpy(b, input, input_len);
@@ -58,8 +56,7 @@ void sm_derive_key(const uint8_t *input,
free(b); free(b);
} }
void sm_derive_all_keys(const uint8_t *derived, size_t derived_len) void sm_derive_all_keys(const uint8_t *derived, size_t derived_len) {
{
memcpy(nonce, random_bytes_get(8), 8); memcpy(nonce, random_bytes_get(8), 8);
sm_derive_key(derived, derived_len, 1, nonce, sizeof(nonce), sm_kenc); sm_derive_key(derived, derived_len, 1, nonce, sizeof(nonce), sm_kenc);
sm_derive_key(derived, derived_len, 2, nonce, sizeof(nonce), sm_kmac); sm_derive_key(derived, derived_len, 2, nonce, sizeof(nonce), sm_kmac);
@@ -70,28 +67,25 @@ void sm_derive_all_keys(const uint8_t *derived, size_t derived_len)
sm_session_pin_len = 0; sm_session_pin_len = 0;
} }
void sm_set_protocol(MSE_protocol proto) void sm_set_protocol(MSE_protocol proto) {
{
sm_protocol = proto; sm_protocol = proto;
if (proto == MSE_AES) { if (proto == MSE_AES) {
sm_blocksize = 16; sm_blocksize = 16;
} else if (proto == MSE_3DES) { }
else if (proto == MSE_3DES) {
sm_blocksize = 8; sm_blocksize = 8;
} }
} }
MSE_protocol sm_get_protocol() MSE_protocol sm_get_protocol() {
{
return sm_protocol; return sm_protocol;
} }
uint8_t *sm_get_nonce() uint8_t *sm_get_nonce() {
{
return nonce; return nonce;
} }
int sm_sign(uint8_t *in, size_t in_len, uint8_t *out) int sm_sign(uint8_t *in, size_t in_len, uint8_t *out) {
{
return mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB), return mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB),
sm_kmac, sm_kmac,
128, 128,
@@ -100,8 +94,7 @@ int sm_sign(uint8_t *in, size_t in_len, uint8_t *out)
out); out);
} }
int sm_unwrap() int sm_unwrap() {
{
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3; uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
if (sm_indicator == 0) { if (sm_indicator == 0) {
return CCID_OK; return CCID_OK;
@@ -145,8 +138,7 @@ int sm_unwrap()
return CCID_OK; return CCID_OK;
} }
int sm_wrap() int sm_wrap() {
{
uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3; uint8_t sm_indicator = (CLA(apdu) >> 2) & 0x3;
if (sm_indicator == 0) { if (sm_indicator == 0) {
return CCID_OK; return CCID_OK;
@@ -178,12 +170,14 @@ int sm_wrap()
memmove(res_APDU + 2, res_APDU, res_APDU_size); memmove(res_APDU + 2, res_APDU, res_APDU_size);
res_APDU[1] = res_APDU_size; res_APDU[1] = res_APDU_size;
res_APDU_size += 2; res_APDU_size += 2;
} else if (res_APDU_size < 256) { }
else if (res_APDU_size < 256) {
memmove(res_APDU + 3, res_APDU, res_APDU_size); memmove(res_APDU + 3, res_APDU, res_APDU_size);
res_APDU[1] = 0x81; res_APDU[1] = 0x81;
res_APDU[2] = res_APDU_size; res_APDU[2] = res_APDU_size;
res_APDU_size += 3; res_APDU_size += 3;
} else { }
else {
memmove(res_APDU + 4, res_APDU, res_APDU_size); memmove(res_APDU + 4, res_APDU, res_APDU_size);
res_APDU[1] = 0x82; res_APDU[1] = 0x82;
res_APDU[2] = res_APDU_size >> 8; res_APDU[2] = res_APDU_size >> 8;
@@ -210,8 +204,7 @@ int sm_wrap()
return CCID_OK; return CCID_OK;
} }
int sm_get_le() int sm_get_le() {
{
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL; uint8_t *tag_data = NULL, *p = NULL;
size_t tag_len = 0; size_t tag_len = 0;
@@ -227,8 +220,7 @@ int sm_get_le()
return -1; return -1;
} }
void sm_update_iv() void sm_update_iv() {
{
uint8_t tmp_iv[16], sc_counter[16]; uint8_t tmp_iv[16], sc_counter[16];
memset(tmp_iv, 0, sizeof(tmp_iv)); //IV is always 0 for encryption of IV based on counter memset(tmp_iv, 0, sizeof(tmp_iv)); //IV is always 0 for encryption of IV based on counter
mbedtls_mpi_write_binary(&sm_mSSC, sc_counter, sizeof(sc_counter)); mbedtls_mpi_write_binary(&sm_mSSC, sc_counter, sizeof(sc_counter));
@@ -236,8 +228,7 @@ void sm_update_iv()
memcpy(sm_iv, sc_counter, sizeof(sc_counter)); memcpy(sm_iv, sc_counter, sizeof(sc_counter));
} }
int sm_verify() int sm_verify() {
{
uint8_t input[1024]; uint8_t input[1024];
memset(input, 0, sizeof(input)); memset(input, 0, sizeof(input));
int input_len = 0, r = 0; int input_len = 0, r = 0;
@@ -305,8 +296,7 @@ int sm_verify()
return CCID_VERIFICATION_FAILED; return CCID_VERIFICATION_FAILED;
} }
int sm_remove_padding(const uint8_t *data, size_t data_len) int sm_remove_padding(const uint8_t *data, size_t data_len) {
{
int i = data_len - 1; int i = data_len - 1;
for (; i >= 0 && data[i] == 0; i--) { for (; i >= 0 && data[i] == 0; i--) {
; ;

View File

@@ -42,8 +42,7 @@ extern uint8_t *flash_read(uintptr_t addr);
extern void low_flash_available(); extern void low_flash_available();
//puts FCI in the RAPDU //puts FCI in the RAPDU
void process_fci(const file_t *pe, int fmd) void process_fci(const file_t *pe, int fmd) {
{
res_APDU_size = 0; res_APDU_size = 0;
if (fmd) { if (fmd) {
res_APDU[res_APDU_size++] = 0x6f; res_APDU[res_APDU_size++] = 0x6f;
@@ -60,12 +59,14 @@ void process_fci(const file_t *pe, int fmd)
uint16_t len = ((int (*)(const file_t *, int))(pe->data))(pe, 0); uint16_t len = ((int (*)(const file_t *, int))(pe->data))(pe, 0);
res_APDU[res_APDU_size++] = (len >> 8) & 0xff; res_APDU[res_APDU_size++] = (len >> 8) & 0xff;
res_APDU[res_APDU_size++] = len & 0xff; res_APDU[res_APDU_size++] = len & 0xff;
} else { }
else {
uint16_t v = file_get_size(pe); uint16_t v = file_get_size(pe);
res_APDU[res_APDU_size++] = v >> 8; res_APDU[res_APDU_size++] = v >> 8;
res_APDU[res_APDU_size++] = v & 0xff; res_APDU[res_APDU_size++] = v & 0xff;
} }
} else { }
else {
memset(res_APDU + res_APDU_size, 0, 2); memset(res_APDU + res_APDU_size, 0, 2);
res_APDU_size += 2; res_APDU_size += 2;
} }
@@ -75,9 +76,11 @@ void process_fci(const file_t *pe, int fmd)
res_APDU[res_APDU_size] = 0; res_APDU[res_APDU_size] = 0;
if (pe->type == FILE_TYPE_INTERNAL_EF) { if (pe->type == FILE_TYPE_INTERNAL_EF) {
res_APDU[res_APDU_size++] |= 0x08; res_APDU[res_APDU_size++] |= 0x08;
} else if (pe->type == FILE_TYPE_WORKING_EF) { }
else if (pe->type == FILE_TYPE_WORKING_EF) {
res_APDU[res_APDU_size++] |= pe->ef_structure & 0x7; res_APDU[res_APDU_size++] |= pe->ef_structure & 0x7;
} else if (pe->type == FILE_TYPE_DF) { }
else if (pe->type == FILE_TYPE_DF) {
res_APDU[res_APDU_size++] |= 0x38; res_APDU[res_APDU_size++] |= 0x38;
} }
@@ -114,8 +117,7 @@ file_t dynamic_file[MAX_DYNAMIC_FILES];
bool card_terminated = false; bool card_terminated = false;
bool is_parent(const file_t *child, const file_t *parent) bool is_parent(const file_t *child, const file_t *parent) {
{
if (child == parent) { if (child == parent) {
return true; return true;
} }
@@ -125,13 +127,11 @@ bool is_parent(const file_t *child, const file_t *parent)
return is_parent(&file_entries[child->parent], parent); return is_parent(&file_entries[child->parent], parent);
} }
file_t *get_parent(file_t *f) file_t *get_parent(file_t *f) {
{
return &file_entries[f->parent]; return &file_entries[f->parent];
} }
file_t *search_by_name(uint8_t *name, uint16_t namelen) file_t *search_by_name(uint8_t *name, uint16_t namelen) {
{
for (file_t *p = file_entries; p != file_last; p++) { for (file_t *p = file_entries; p != file_last; p++) {
if (p->name && *p->name == apdu.nc && memcmp(p->name + 1, name, namelen) == 0) { if (p->name && *p->name == apdu.nc && memcmp(p->name + 1, name, namelen) == 0) {
return p; return p;
@@ -140,8 +140,7 @@ file_t *search_by_name(uint8_t *name, uint16_t namelen)
return NULL; return NULL;
} }
file_t *search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp) file_t *search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp) {
{
for (file_t *p = file_entries; p != file_last; p++) { for (file_t *p = file_entries; p != file_last; p++) {
if (p->fid != 0x0000 && p->fid == fid) { if (p->fid != 0x0000 && p->fid == fid) {
@@ -157,8 +156,7 @@ file_t *search_by_fid(const uint16_t fid, const file_t *parent, const uint8_t sp
return NULL; return NULL;
} }
uint8_t make_path_buf(const file_t *pe, uint8_t *buf, uint8_t buflen, const file_t *top) uint8_t make_path_buf(const file_t *pe, uint8_t *buf, uint8_t buflen, const file_t *top) {
{
if (!buflen) { if (!buflen) {
return 0; return 0;
} }
@@ -169,8 +167,7 @@ uint8_t make_path_buf(const file_t *pe, uint8_t *buf, uint8_t buflen, const file
return make_path_buf(&file_entries[pe->parent], buf + 2, buflen - 2, top) + 2; return make_path_buf(&file_entries[pe->parent], buf + 2, buflen - 2, top) + 2;
} }
uint8_t make_path(const file_t *pe, const file_t *top, uint8_t *path) uint8_t make_path(const file_t *pe, const file_t *top, uint8_t *path) {
{
uint8_t buf[MAX_DEPTH * 2], *p = path; uint8_t buf[MAX_DEPTH * 2], *p = path;
put_uint16_t(pe->fid, buf); put_uint16_t(pe->fid, buf);
uint8_t depth = make_path_buf(&file_entries[pe->parent], buf + 2, sizeof(buf) - 2, top) + 2; uint8_t depth = make_path_buf(&file_entries[pe->parent], buf + 2, sizeof(buf) - 2, top) + 2;
@@ -181,8 +178,7 @@ uint8_t make_path(const file_t *pe, const file_t *top, uint8_t *path)
return depth; return depth;
} }
file_t *search_by_path(const uint8_t *pe_path, uint8_t pathlen, const file_t *parent) file_t *search_by_path(const uint8_t *pe_path, uint8_t pathlen, const file_t *parent) {
{
uint8_t path[MAX_DEPTH * 2]; uint8_t path[MAX_DEPTH * 2];
if (pathlen > sizeof(path)) { if (pathlen > sizeof(path)) {
return NULL; return NULL;
@@ -201,26 +197,27 @@ file_t *currentDF = NULL;
const file_t *selected_applet = NULL; const file_t *selected_applet = NULL;
bool isUserAuthenticated = false; bool isUserAuthenticated = false;
bool authenticate_action(const file_t *ef, uint8_t op) bool authenticate_action(const file_t *ef, uint8_t op) {
{
uint8_t acl = ef->acl[op]; uint8_t acl = ef->acl[op];
if (acl == 0x0) { if (acl == 0x0) {
return true; return true;
} else if (acl == 0xff) { }
else if (acl == 0xff) {
return false; return false;
} else if (acl == 0x90 || (acl & 0x9F) == 0x10) { }
else if (acl == 0x90 || (acl & 0x9F) == 0x10) {
// PIN required. // PIN required.
if (isUserAuthenticated) { if (isUserAuthenticated) {
return true; return true;
} else { }
else {
return false; return false;
} }
} }
return false; return false;
} }
void initialize_flash(bool hard) void initialize_flash(bool hard) {
{
if (hard) { if (hard) {
const uint8_t empty[8] = { 0 }; const uint8_t empty[8] = { 0 };
flash_program_block(end_data_pool, empty, sizeof(empty)); flash_program_block(end_data_pool, empty, sizeof(empty));
@@ -234,8 +231,7 @@ void initialize_flash(bool hard)
dynamic_files = 0; dynamic_files = 0;
} }
void scan_region(bool persistent) void scan_region(bool persistent) {
{
uintptr_t endp = end_data_pool, startp = start_data_pool; uintptr_t endp = end_data_pool, startp = start_data_pool;
if (persistent) { if (persistent) {
endp = end_rom_pool; endp = end_rom_pool;
@@ -255,7 +251,8 @@ void scan_region(bool persistent)
file = file_new(fid); file = file_new(fid);
} }
if (file) { if (file) {
file->data = (uint8_t *) (base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t)); file->data =
(uint8_t *) (base + sizeof(uintptr_t) + sizeof(uintptr_t) + sizeof(uint16_t));
} }
if (flash_read_uintptr(base) == 0x0) { if (flash_read_uintptr(base) == 0x0) {
break; break;
@@ -263,8 +260,7 @@ void scan_region(bool persistent)
} }
} }
void wait_flash_finish(); void wait_flash_finish();
void scan_flash() void scan_flash() {
{
initialize_flash(false); //soft initialization initialize_flash(false); //soft initialization
if (*(uintptr_t *) flash_read(end_rom_pool) == 0xffffffff && if (*(uintptr_t *) flash_read(end_rom_pool) == 0xffffffff &&
*(uintptr_t *) flash_read(end_rom_pool + sizeof(uintptr_t)) == 0xffffffff) { *(uintptr_t *) flash_read(end_rom_pool + sizeof(uintptr_t)) == 0xffffffff) {
@@ -281,37 +277,31 @@ void scan_flash()
scan_region(false); scan_region(false);
} }
uint8_t *file_read(const uint8_t *addr) uint8_t *file_read(const uint8_t *addr) {
{
return flash_read((uintptr_t) addr); return flash_read((uintptr_t) addr);
} }
uint16_t file_read_uint16(const uint8_t *addr) uint16_t file_read_uint16(const uint8_t *addr) {
{
return flash_read_uint16((uintptr_t) addr); return flash_read_uint16((uintptr_t) addr);
} }
uint8_t file_read_uint8(const uint8_t *addr) uint8_t file_read_uint8(const uint8_t *addr) {
{
return flash_read_uint8((uintptr_t) addr); return flash_read_uint8((uintptr_t) addr);
} }
uint8_t *file_get_data(const file_t *tf) uint8_t *file_get_data(const file_t *tf) {
{
if (!tf || !tf->data) { if (!tf || !tf->data) {
return NULL; return NULL;
} }
return file_read(tf->data + sizeof(uint16_t)); return file_read(tf->data + sizeof(uint16_t));
} }
uint16_t file_get_size(const file_t *tf) uint16_t file_get_size(const file_t *tf) {
{
if (!tf || !tf->data) { if (!tf || !tf->data) {
return 0; return 0;
} }
return file_read_uint16(tf->data); return file_read_uint16(tf->data);
} }
file_t *search_dynamic_file(uint16_t fid) file_t *search_dynamic_file(uint16_t fid) {
{
for (int i = 0; i < dynamic_files; i++) { for (int i = 0; i < dynamic_files; i++) {
if (dynamic_file[i].fid == fid) { if (dynamic_file[i].fid == fid) {
return &dynamic_file[i]; return &dynamic_file[i];
@@ -320,8 +310,7 @@ file_t *search_dynamic_file(uint16_t fid)
return NULL; return NULL;
} }
int delete_dynamic_file(file_t *f) int delete_dynamic_file(file_t *f) {
{
if (f == NULL) { if (f == NULL) {
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
} }
@@ -337,8 +326,7 @@ int delete_dynamic_file(file_t *f)
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
} }
file_t *file_new(uint16_t fid) file_t *file_new(uint16_t fid) {
{
file_t *f; file_t *f;
if ((f = search_dynamic_file(fid)) || (f = search_by_fid(fid, NULL, SPECIFY_EF))) { if ((f = search_dynamic_file(fid)) || (f = search_by_fid(fid, NULL, SPECIFY_EF))) {
return f; return f;
@@ -361,8 +349,7 @@ file_t *file_new(uint16_t fid)
//memset((uint8_t *)f->acl, 0x90, sizeof(f->acl)); //memset((uint8_t *)f->acl, 0x90, sizeof(f->acl));
return f; return f;
} }
int meta_find(uint16_t fid, uint8_t **out) int meta_find(uint16_t fid, uint8_t **out) {
{
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF); file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
if (!ef) { if (!ef) {
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
@@ -384,8 +371,7 @@ int meta_find(uint16_t fid, uint8_t **out)
} }
return 0; return 0;
} }
int meta_delete(uint16_t fid) int meta_delete(uint16_t fid) {
{
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF); file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
if (!ef) { if (!ef) {
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
@@ -404,7 +390,8 @@ int meta_delete(uint16_t fid)
size_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL); size_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL);
if (new_len == 0) { if (new_len == 0) {
flash_clear_file(ef); flash_clear_file(ef);
} else { }
else {
fdata = (uint8_t *) calloc(1, new_len); fdata = (uint8_t *) calloc(1, new_len);
if (tpos > data) { if (tpos > data) {
memcpy(fdata, data, tpos - data); memcpy(fdata, data, tpos - data);
@@ -424,8 +411,7 @@ int meta_delete(uint16_t fid)
} }
return CCID_OK; return CCID_OK;
} }
int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
{
int r; int r;
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF); file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
if (!ef) { if (!ef) {
@@ -451,7 +437,8 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len)
return CCID_EXEC_ERROR; return CCID_EXEC_ERROR;
} }
return CCID_OK; return CCID_OK;
} else { //needs reallocation }
else { //needs reallocation
uint8_t *tpos = p - asn1_len_tag(tag, tag_len); uint8_t *tpos = p - asn1_len_tag(tag, tag_len);
memmove(tpos, p, fdata + ef_size - p); memmove(tpos, p, fdata + ef_size - p);
tpos += fdata + ef_size - p; tpos += fdata + ef_size - p;
@@ -461,7 +448,8 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len)
uint8_t *fdata_new = (uint8_t *) realloc(fdata, ef_size); uint8_t *fdata_new = (uint8_t *) realloc(fdata, ef_size);
if (fdata_new != NULL) { if (fdata_new != NULL) {
fdata = fdata_new; fdata = fdata_new;
} else { }
else {
free(fdata); free(fdata);
return CCID_ERR_MEMORY_FATAL; return CCID_ERR_MEMORY_FATAL;
} }
@@ -496,13 +484,11 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len)
return CCID_OK; return CCID_OK;
} }
bool file_has_data(file_t *f) bool file_has_data(file_t *f) {
{
return f != NULL && f->data != NULL && file_get_size(f) > 0; return f != NULL && f->data != NULL && file_get_size(f) > 0;
} }
int delete_file(file_t *ef) int delete_file(file_t *ef) {
{
if (ef == NULL) { if (ef == NULL) {
return CCID_OK; return CCID_OK;
} }

View File

@@ -60,12 +60,12 @@ extern uint8_t *flash_read(uintptr_t addr);
extern void low_flash_available(); extern void low_flash_available();
uintptr_t allocate_free_addr(uint16_t size, bool persistent) uintptr_t allocate_free_addr(uint16_t size, bool persistent) {
{
if (size > FLASH_SECTOR_SIZE) { if (size > FLASH_SECTOR_SIZE) {
return 0x0; //ERROR return 0x0; //ERROR
} }
size_t real_size = size+sizeof(uint16_t)+sizeof(uintptr_t)+sizeof(uint16_t)+sizeof(uintptr_t); //len+len size+next address+fid+prev_addr size size_t real_size = size + sizeof(uint16_t) + sizeof(uintptr_t) + sizeof(uint16_t) +
sizeof(uintptr_t); //len+len size+next address+fid+prev_addr size
uintptr_t next_base = 0x0, endp = end_data_pool, startp = start_data_pool; uintptr_t next_base = 0x0, endp = end_data_pool, startp = start_data_pool;
if (persistent) { if (persistent) {
endp = end_rom_pool; endp = end_rom_pool;
@@ -84,7 +84,8 @@ uintptr_t allocate_free_addr(uint16_t size, bool persistent)
flash_program_uintptr(potential_addr + sizeof(uintptr_t), base); flash_program_uintptr(potential_addr + sizeof(uintptr_t), base);
flash_program_uintptr(base, potential_addr); flash_program_uintptr(base, potential_addr);
return potential_addr; return potential_addr;
} else if (addr_alg-FLASH_SECTOR_SIZE >= startp) { //check whether it fits in the next sector, so we take addr_aligned as the base }
else if (addr_alg - FLASH_SECTOR_SIZE >= startp) { //check whether it fits in the next sector, so we take addr_aligned as the base
potential_addr = addr_alg - real_size; potential_addr = addr_alg - real_size;
flash_program_uintptr(potential_addr, 0x0); flash_program_uintptr(potential_addr, 0x0);
flash_program_uintptr(potential_addr + sizeof(uintptr_t), base); flash_program_uintptr(potential_addr + sizeof(uintptr_t), base);
@@ -97,7 +98,8 @@ uintptr_t allocate_free_addr(uint16_t size, bool persistent)
else if (addr_alg <= potential_addr && else if (addr_alg <= potential_addr &&
base - base -
(next_base + (next_base +
flash_read_uint16(next_base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t))+ flash_read_uint16(next_base + sizeof(uintptr_t) + sizeof(uintptr_t) +
sizeof(uint16_t)) +
2 * 2 *
sizeof(uint16_t) + 2 * sizeof(uintptr_t)) > base - potential_addr && sizeof(uint16_t) + 2 * sizeof(uintptr_t)) > base - potential_addr &&
(flash_read_uint16(next_base + 2 * sizeof(uintptr_t)) & 0x1000) != 0x1000) { (flash_read_uint16(next_base + 2 * sizeof(uintptr_t)) & 0x1000) != 0x1000) {
@@ -111,8 +113,7 @@ uintptr_t allocate_free_addr(uint16_t size, bool persistent)
return 0x0; //probably never reached return 0x0; //probably never reached
} }
int flash_clear_file(file_t *file) int flash_clear_file(file_t *file) {
{
if (file == NULL) { if (file == NULL) {
return CCID_OK; return CCID_OK;
} }
@@ -134,8 +135,7 @@ int flash_clear_file(file_t *file)
} }
int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len, int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len,
uint16_t offset) uint16_t offset) {
{
if (!file) { if (!file) {
return CCID_ERR_NULL_PARAM; return CCID_ERR_NULL_PARAM;
} }
@@ -151,7 +151,8 @@ int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t
flash_program_block((uintptr_t) file->data + sizeof(uint16_t) + offset, data, len); flash_program_block((uintptr_t) file->data + sizeof(uint16_t) + offset, data, len);
} }
return CCID_OK; return CCID_OK;
} else { //we clear the old file }
else { //we clear the old file
flash_clear_file(file); flash_clear_file(file);
if (offset > 0) { if (offset > 0) {
old_data = (uint8_t *) calloc(1, offset + len); old_data = (uint8_t *) calloc(1, offset + len);
@@ -179,7 +180,6 @@ int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t
} }
return CCID_OK; return CCID_OK;
} }
int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
{
return flash_write_data_to_file_offset(file, data, len, 0); return flash_write_data_to_file_offset(file, data, len, 0);
} }

View File

@@ -71,8 +71,7 @@ bool flash_available = false;
//this function has to be called from the core 0 //this function has to be called from the core 0
void do_flash() void do_flash() {
{
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
if (mutex_try_enter(&mtx_flash, NULL) == true) { if (mutex_try_enter(&mtx_flash, NULL) == true) {
#endif #endif
@@ -101,7 +100,8 @@ void do_flash()
#endif #endif
flash_pages[r].ready = false; flash_pages[r].ready = false;
ready_pages--; ready_pages--;
} else if (flash_pages[r].erase == true) { }
else if (flash_pages[r].erase == true) {
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
while (multicore_lockout_start_timeout_us(1000) == false) { while (multicore_lockout_start_timeout_us(1000) == false) {
; ;
@@ -137,8 +137,7 @@ sem_release(&sem_wait);
} }
//this function has to be called from the core 0 //this function has to be called from the core 0
void low_flash_init() void low_flash_init() {
{
memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES); memset(flash_pages, 0, sizeof(page_flash_t) * TOTAL_FLASH_PAGES);
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
mutex_init(&mtx_flash); mutex_init(&mtx_flash);
@@ -151,8 +150,7 @@ void low_flash_init()
#endif #endif
} }
void low_flash_init_core1() void low_flash_init_core1() {
{
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
mutex_enter_blocking(&mtx_flash); mutex_enter_blocking(&mtx_flash);
multicore_lockout_victim_init(); multicore_lockout_victim_init();
@@ -163,8 +161,7 @@ void low_flash_init_core1()
#endif #endif
} }
void wait_flash_finish() void wait_flash_finish() {
{
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
sem_acquire_blocking(&sem_wait); //blocks until released sem_acquire_blocking(&sem_wait); //blocks until released
//wake up //wake up
@@ -172,8 +169,7 @@ void wait_flash_finish()
#endif #endif
} }
void low_flash_available() void low_flash_available() {
{
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
mutex_enter_blocking(&mtx_flash); mutex_enter_blocking(&mtx_flash);
#endif #endif
@@ -183,8 +179,7 @@ void low_flash_available()
#endif #endif
} }
page_flash_t *find_free_page(uintptr_t addr) page_flash_t *find_free_page(uintptr_t addr) {
{
uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE; uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE;
page_flash_t *p = NULL; page_flash_t *p = NULL;
for (int r = 0; r < TOTAL_FLASH_PAGES; r++) { for (int r = 0; r < TOTAL_FLASH_PAGES; r++) {
@@ -210,8 +205,7 @@ page_flash_t *find_free_page(uintptr_t addr)
return NULL; return NULL;
} }
int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len) int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len) {
{
page_flash_t *p = NULL; page_flash_t *p = NULL;
if (!data || len == 0) { if (!data || len == 0) {
@@ -243,23 +237,19 @@ int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len)
return CCID_OK; return CCID_OK;
} }
int flash_program_halfword(uintptr_t addr, uint16_t data) int flash_program_halfword(uintptr_t addr, uint16_t data) {
{
return flash_program_block(addr, (const uint8_t *) &data, sizeof(uint16_t)); return flash_program_block(addr, (const uint8_t *) &data, sizeof(uint16_t));
} }
int flash_program_word(uintptr_t addr, uint32_t data) int flash_program_word(uintptr_t addr, uint32_t data) {
{
return flash_program_block(addr, (const uint8_t *) &data, sizeof(uint32_t)); return flash_program_block(addr, (const uint8_t *) &data, sizeof(uint32_t));
} }
int flash_program_uintptr(uintptr_t addr, uintptr_t data) int flash_program_uintptr(uintptr_t addr, uintptr_t data) {
{
return flash_program_block(addr, (const uint8_t *) &data, sizeof(uintptr_t)); return flash_program_block(addr, (const uint8_t *) &data, sizeof(uintptr_t));
} }
uint8_t *flash_read(uintptr_t addr) uint8_t *flash_read(uintptr_t addr) {
{
uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE; uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE;
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
mutex_enter_blocking(&mtx_flash); mutex_enter_blocking(&mtx_flash);
@@ -286,8 +276,7 @@ uint8_t *flash_read(uintptr_t addr)
return v; return v;
} }
uintptr_t flash_read_uintptr(uintptr_t addr) uintptr_t flash_read_uintptr(uintptr_t addr) {
{
uint8_t *p = flash_read(addr); uint8_t *p = flash_read(addr);
uintptr_t v = 0x0; uintptr_t v = 0x0;
for (int i = 0; i < sizeof(uintptr_t); i++) { for (int i = 0; i < sizeof(uintptr_t); i++) {
@@ -295,8 +284,7 @@ uintptr_t flash_read_uintptr(uintptr_t addr)
} }
return v; return v;
} }
uint16_t flash_read_uint16(uintptr_t addr) uint16_t flash_read_uint16(uintptr_t addr) {
{
uint8_t *p = flash_read(addr); uint8_t *p = flash_read(addr);
uint16_t v = 0x0; uint16_t v = 0x0;
for (int i = 0; i < sizeof(uint16_t); i++) { for (int i = 0; i < sizeof(uint16_t); i++) {
@@ -304,13 +292,11 @@ uint16_t flash_read_uint16(uintptr_t addr)
} }
return v; return v;
} }
uint8_t flash_read_uint8(uintptr_t addr) uint8_t flash_read_uint8(uintptr_t addr) {
{
return *flash_read(addr); return *flash_read(addr);
} }
int flash_erase_page(uintptr_t addr, size_t page_size) int flash_erase_page(uintptr_t addr, size_t page_size) {
{
page_flash_t *p = NULL; page_flash_t *p = NULL;
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
@@ -340,8 +326,7 @@ int flash_erase_page(uintptr_t addr, size_t page_size)
return CCID_OK; return CCID_OK;
} }
bool flash_check_blank(const uint8_t *p_start, size_t size) bool flash_check_blank(const uint8_t *p_start, size_t size) {
{
const uint8_t *p; const uint8_t *p;
for (p = p_start; p < p_start + size; p++) { for (p = p_start; p < p_start + size; p++) {

View File

@@ -36,8 +36,7 @@ mbedtls_ctr_drbg_context ctr_drbg;
extern uint32_t board_millis(); extern uint32_t board_millis();
#endif #endif
void adc_start() void adc_start() {
{
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
adc_init(); adc_init();
adc_gpio_init(27); adc_gpio_init(27);
@@ -45,12 +44,10 @@ void adc_start()
#endif #endif
} }
void adc_stop() void adc_stop() {
{
} }
#ifdef ENABLE_EMULATION #ifdef ENABLE_EMULATION
uint32_t adc_read() uint32_t adc_read() {
{
return 0; return 0;
} }
#endif #endif
@@ -58,8 +55,7 @@ uint32_t adc_read()
static uint64_t random_word = 0xcbf29ce484222325; static uint64_t random_word = 0xcbf29ce484222325;
static uint8_t ep_round = 0; static uint8_t ep_round = 0;
static void ep_init() static void ep_init() {
{
random_word = 0xcbf29ce484222325; random_word = 0xcbf29ce484222325;
ep_round = 0; ep_round = 0;
#ifdef ENABLE_EMULATION #ifdef ENABLE_EMULATION
@@ -75,8 +71,7 @@ static void ep_init()
} }
/* Here, we assume a little endian architecture. */ /* Here, we assume a little endian architecture. */
static int ep_process() static int ep_process() {
{
if (ep_round == 0) { if (ep_round == 0) {
ep_init(); ep_init();
} }
@@ -103,8 +98,7 @@ static int ep_process()
return 0; return 0;
} }
static const uint32_t *ep_output() static const uint32_t *ep_output() {
{
return (uint32_t *) &random_word; return (uint32_t *) &random_word;
} }
@@ -116,8 +110,7 @@ struct rng_rb {
unsigned int empty : 1; unsigned int empty : 1;
}; };
static void rb_init(struct rng_rb *rb, uint32_t *p, uint8_t size) static void rb_init(struct rng_rb *rb, uint32_t *p, uint8_t size) {
{
#ifdef ENABLE_EMULATION #ifdef ENABLE_EMULATION
#endif #endif
rb->buf = p; rb->buf = p;
@@ -127,8 +120,7 @@ static void rb_init(struct rng_rb *rb, uint32_t *p, uint8_t size)
rb->empty = 1; rb->empty = 1;
} }
static void rb_add(struct rng_rb *rb, uint32_t v) static void rb_add(struct rng_rb *rb, uint32_t v) {
{
rb->buf[rb->tail++] = v; rb->buf[rb->tail++] = v;
if (rb->tail == rb->size) { if (rb->tail == rb->size) {
rb->tail = 0; rb->tail = 0;
@@ -139,8 +131,7 @@ static void rb_add(struct rng_rb *rb, uint32_t v)
rb->empty = 0; rb->empty = 0;
} }
static uint32_t rb_del(struct rng_rb *rb) static uint32_t rb_del(struct rng_rb *rb) {
{
uint32_t v = rb->buf[rb->head++]; uint32_t v = rb->buf[rb->head++];
if (rb->head == rb->size) { if (rb->head == rb->size) {
@@ -156,8 +147,7 @@ static uint32_t rb_del(struct rng_rb *rb)
static struct rng_rb the_ring_buffer; static struct rng_rb the_ring_buffer;
void *neug_task() void *neug_task() {
{
struct rng_rb *rb = &the_ring_buffer; struct rng_rb *rb = &the_ring_buffer;
int n; int n;
@@ -177,8 +167,7 @@ void *neug_task()
return NULL; return NULL;
} }
void neug_init(uint32_t *buf, uint8_t size) void neug_init(uint32_t *buf, uint8_t size) {
{
struct rng_rb *rb = &the_ring_buffer; struct rng_rb *rb = &the_ring_buffer;
rb_init(rb, buf, size); rb_init(rb, buf, size);
@@ -188,8 +177,7 @@ void neug_init(uint32_t *buf, uint8_t size)
ep_init(); ep_init();
} }
void neug_flush(void) void neug_flush(void) {
{
struct rng_rb *rb = &the_ring_buffer; struct rng_rb *rb = &the_ring_buffer;
while (!rb->empty) { while (!rb->empty) {
@@ -197,8 +185,7 @@ void neug_flush(void)
} }
} }
uint32_t neug_get() uint32_t neug_get() {
{
struct rng_rb *rb = &the_ring_buffer; struct rng_rb *rb = &the_ring_buffer;
uint32_t v; uint32_t v;
@@ -210,8 +197,7 @@ uint32_t neug_get()
return v; return v;
} }
void neug_wait_full() void neug_wait_full() {
{
struct rng_rb *rb = &the_ring_buffer; struct rng_rb *rb = &the_ring_buffer;
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
uint core = get_core_num(); uint core = get_core_num();
@@ -220,13 +206,13 @@ void neug_wait_full()
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
if (core == 1) { if (core == 1) {
sleep_ms(1); sleep_ms(1);
} else }
else
#endif #endif
neug_task(); neug_task();
} }
} }
void neug_fini(void) void neug_fini(void) {
{
neug_get(); neug_get();
} }

View File

@@ -24,8 +24,7 @@
#define RANDOM_BYTES_LENGTH 32 #define RANDOM_BYTES_LENGTH 32
static uint32_t random_word[RANDOM_BYTES_LENGTH / sizeof(uint32_t)]; static uint32_t random_word[RANDOM_BYTES_LENGTH / sizeof(uint32_t)];
void random_init(void) void random_init(void) {
{
int i; int i;
neug_init(random_word, RANDOM_BYTES_LENGTH / sizeof(uint32_t)); neug_init(random_word, RANDOM_BYTES_LENGTH / sizeof(uint32_t));
@@ -35,8 +34,7 @@ void random_init(void)
} }
} }
void random_fini(void) void random_fini(void) {
{
neug_fini(); neug_fini();
} }
@@ -45,8 +43,7 @@ void random_fini(void)
*/ */
void random_bytes_free(const uint8_t *p); void random_bytes_free(const uint8_t *p);
#define MAX_RANDOM_BUFFER 1024 #define MAX_RANDOM_BUFFER 1024
const uint8_t *random_bytes_get(size_t len) const uint8_t *random_bytes_get(size_t len) {
{
if (len > MAX_RANDOM_BUFFER) { if (len > MAX_RANDOM_BUFFER) {
return NULL; return NULL;
} }
@@ -62,8 +59,7 @@ const uint8_t *random_bytes_get(size_t len)
/* /*
* Free pointer to random 32-byte * Free pointer to random 32-byte
*/ */
void random_bytes_free(const uint8_t *p) void random_bytes_free(const uint8_t *p) {
{
(void) p; (void) p;
memset(random_word, 0, RANDOM_BYTES_LENGTH); memset(random_word, 0, RANDOM_BYTES_LENGTH);
neug_flush(); neug_flush();
@@ -72,8 +68,7 @@ void random_bytes_free(const uint8_t *p)
/* /*
* Return 4-byte salt * Return 4-byte salt
*/ */
void random_get_salt(uint8_t *p) void random_get_salt(uint8_t *p) {
{
uint32_t rnd; uint32_t rnd;
rnd = neug_get(); rnd = neug_get();
@@ -86,8 +81,7 @@ void random_get_salt(uint8_t *p)
/* /*
* Random byte iterator * Random byte iterator
*/ */
int random_gen(void *arg, unsigned char *out, size_t out_len) int random_gen(void *arg, unsigned char *out, size_t out_len) {
{
uint8_t *index_p = (uint8_t *) arg; uint8_t *index_p = (uint8_t *) arg;
uint8_t index = index_p ? *index_p : 0; uint8_t index = index_p ? *index_p : 0;
size_t n; size_t n;

View File

@@ -102,24 +102,21 @@ struct ccid_header {
uint8_t ccid_status = 1; uint8_t ccid_status = 1;
static uint8_t itf_num; static uint8_t itf_num;
void ccid_write_offset(uint16_t size, uint16_t offset) void ccid_write_offset(uint16_t size, uint16_t offset) {
{
if (*usb_get_tx(ITF_CCID) + offset != 0x81) { if (*usb_get_tx(ITF_CCID) + offset != 0x81) {
DEBUG_PAYLOAD(usb_get_tx(ITF_CCID) + offset, size + 10); DEBUG_PAYLOAD(usb_get_tx(ITF_CCID) + offset, size + 10);
} }
usb_write_offset(ITF_CCID, size + 10, offset); usb_write_offset(ITF_CCID, size + 10, offset);
} }
void ccid_write(uint16_t size) void ccid_write(uint16_t size) {
{
ccid_write_offset(size, 0); ccid_write_offset(size, 0);
} }
struct ccid_header *ccid_response; struct ccid_header *ccid_response;
struct ccid_header *ccid_header; struct ccid_header *ccid_header;
int driver_init_ccid() int driver_init_ccid() {
{
ccid_header = (struct ccid_header *) usb_get_rx(ITF_CCID); ccid_header = (struct ccid_header *) usb_get_rx(ITF_CCID);
// apdu.header = &ccid_header->apdu; // apdu.header = &ccid_header->apdu;
@@ -130,37 +127,31 @@ int driver_init_ccid()
return CCID_OK; return CCID_OK;
} }
void tud_vendor_rx_cb(uint8_t itf) void tud_vendor_rx_cb(uint8_t itf) {
{
(void) itf; (void) itf;
uint32_t len = tud_vendor_available(); uint32_t len = tud_vendor_available();
usb_rx(ITF_CCID, NULL, len); usb_rx(ITF_CCID, NULL, len);
} }
void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) {
{
printf("written %ld\n", sent_bytes); printf("written %ld\n", sent_bytes);
usb_write_flush(ITF_CCID); usb_write_flush(ITF_CCID);
} }
int driver_write_ccid(const uint8_t *buffer, size_t buffer_size) int driver_write_ccid(const uint8_t *buffer, size_t buffer_size) {
{
return tud_vendor_write(buffer, buffer_size); return tud_vendor_write(buffer, buffer_size);
} }
size_t driver_read_ccid(uint8_t *buffer, size_t buffer_size) size_t driver_read_ccid(uint8_t *buffer, size_t buffer_size) {
{
return tud_vendor_read(buffer, buffer_size); return tud_vendor_read(buffer, buffer_size);
} }
int driver_process_usb_nopacket_ccid() int driver_process_usb_nopacket_ccid() {
{
return 0; return 0;
} }
int driver_process_usb_packet_ccid(uint16_t rx_read) int driver_process_usb_packet_ccid(uint16_t rx_read) {
{
if (rx_read >= 10) { if (rx_read >= 10) {
driver_init_ccid(); driver_init_ccid();
//printf("%d %d %x\r\n",tccid->dwLength,rx_read-10,tccid->bMessageType); //printf("%d %d %x\r\n",tccid->dwLength,rx_read-10,tccid->bMessageType);
@@ -177,7 +168,8 @@ int driver_process_usb_packet_ccid(uint16_t rx_read)
ccid_response->abRFU0 = ccid_status; ccid_response->abRFU0 = ccid_status;
ccid_response->abRFU1 = 0; ccid_response->abRFU1 = 0;
ccid_write(0); ccid_write(0);
} else if (ccid_header->bMessageType == 0x62) { }
else if (ccid_header->bMessageType == 0x62) {
size_t size_atr = (ccid_atr ? ccid_atr[0] : 0); size_t size_atr = (ccid_atr ? ccid_atr[0] : 0);
ccid_response->bMessageType = 0x80; ccid_response->bMessageType = 0x80;
ccid_response->dwLength = size_atr; ccid_response->dwLength = size_atr;
@@ -190,7 +182,8 @@ int driver_process_usb_packet_ccid(uint16_t rx_read)
card_start(apdu_thread); card_start(apdu_thread);
ccid_status = 0; ccid_status = 0;
ccid_write(size_atr); ccid_write(size_atr);
} else if (ccid_header->bMessageType == 0x63) { }
else if (ccid_header->bMessageType == 0x63) {
if (ccid_status == 0) { if (ccid_status == 0) {
card_exit(0); card_exit(0);
} }
@@ -202,7 +195,8 @@ int driver_process_usb_packet_ccid(uint16_t rx_read)
ccid_response->abRFU0 = ccid_status; ccid_response->abRFU0 = ccid_status;
ccid_response->abRFU1 = 0; ccid_response->abRFU1 = 0;
ccid_write(0); ccid_write(0);
} else if (ccid_header->bMessageType == 0x6F) { }
else if (ccid_header->bMessageType == 0x6F) {
apdu_sent = apdu_process(ITF_CCID, &ccid_header->apdu, ccid_header->dwLength); apdu_sent = apdu_process(ITF_CCID, &ccid_header->apdu, ccid_header->dwLength);
} }
usb_clear_rx(ITF_CCID); usb_clear_rx(ITF_CCID);
@@ -222,13 +216,11 @@ int driver_process_usb_packet_ccid(uint16_t rx_read)
return 0; return 0;
} }
bool driver_mounted_ccid() bool driver_mounted_ccid() {
{
return tud_vendor_mounted(); return tud_vendor_mounted();
} }
void driver_exec_timeout_ccid() void driver_exec_timeout_ccid() {
{
ccid_response->bMessageType = CCID_DATA_BLOCK_RET; ccid_response->bMessageType = CCID_DATA_BLOCK_RET;
ccid_response->dwLength = 0; ccid_response->dwLength = 0;
ccid_response->bSlot = 0; ccid_response->bSlot = 0;
@@ -238,8 +230,7 @@ void driver_exec_timeout_ccid()
ccid_write(0); ccid_write(0);
} }
void driver_exec_finished_ccid(size_t size_next) void driver_exec_finished_ccid(size_t size_next) {
{
ccid_response->bMessageType = CCID_DATA_BLOCK_RET; ccid_response->bMessageType = CCID_DATA_BLOCK_RET;
ccid_response->dwLength = size_next; ccid_response->dwLength = size_next;
ccid_response->bSlot = 0; ccid_response->bSlot = 0;
@@ -249,8 +240,7 @@ void driver_exec_finished_ccid(size_t size_next)
ccid_write(size_next); ccid_write(size_next);
} }
void driver_exec_finished_cont_ccid(size_t size_next, size_t offset) void driver_exec_finished_cont_ccid(size_t size_next, size_t offset) {
{
ccid_response = (struct ccid_header *) (usb_get_tx(ITF_CCID) + offset - 10); ccid_response = (struct ccid_header *) (usb_get_tx(ITF_CCID) + offset - 10);
ccid_response->bMessageType = CCID_DATA_BLOCK_RET; ccid_response->bMessageType = CCID_DATA_BLOCK_RET;
@@ -262,8 +252,7 @@ void driver_exec_finished_cont_ccid(size_t size_next, size_t offset)
ccid_write_offset(size_next, offset - 10); ccid_write_offset(size_next, offset - 10);
} }
uint8_t *driver_prepare_response_ccid() uint8_t *driver_prepare_response_ccid() {
{
ccid_response = (struct ccid_header *) usb_get_tx(ITF_CCID); ccid_response = (struct ccid_header *) usb_get_tx(ITF_CCID);
apdu.rdata = &ccid_response->apdu; apdu.rdata = &ccid_response->apdu;
return &ccid_response->apdu; return &ccid_response->apdu;
@@ -272,23 +261,20 @@ uint8_t *driver_prepare_response_ccid()
#define MAX_USB_POWER 1 #define MAX_USB_POWER 1
static void ccid_init_cb(void) static void ccid_init_cb(void) {
{
TU_LOG1("-------- CCID INIT\r\n"); TU_LOG1("-------- CCID INIT\r\n");
vendord_init(); vendord_init();
//ccid_notify_slot_change(c); //ccid_notify_slot_change(c);
} }
static void ccid_reset_cb(uint8_t rhport) static void ccid_reset_cb(uint8_t rhport) {
{
TU_LOG1("-------- CCID RESET\r\n"); TU_LOG1("-------- CCID RESET\r\n");
itf_num = 0; itf_num = 0;
vendord_reset(rhport); vendord_reset(rhport);
} }
static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
{
uint8_t *itf_vendor = (uint8_t *) malloc(sizeof(uint8_t) * max_len); uint8_t *itf_vendor = (uint8_t *) malloc(sizeof(uint8_t) * max_len);
//TU_LOG1("-------- CCID OPEN\r\n"); //TU_LOG1("-------- CCID OPEN\r\n");
TU_VERIFY( TU_VERIFY(
@@ -312,8 +298,7 @@ static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc,
// Support for parameterized reset via vendor interface control request // Support for parameterized reset via vendor interface control request
static bool ccid_control_xfer_cb(uint8_t __unused rhport, static bool ccid_control_xfer_cb(uint8_t __unused rhport,
uint8_t stage, uint8_t stage,
tusb_control_request_t const *request) tusb_control_request_t const *request) {
{
// nothing to do with DATA & ACK stage // nothing to do with DATA & ACK stage
TU_LOG2("-------- CCID CTRL XFER\r\n"); TU_LOG2("-------- CCID CTRL XFER\r\n");
if (stage != CONTROL_STAGE_SETUP) { if (stage != CONTROL_STAGE_SETUP) {
@@ -358,8 +343,7 @@ static bool ccid_control_xfer_cb(uint8_t __unused rhport,
static bool ccid_xfer_cb(uint8_t rhport, static bool ccid_xfer_cb(uint8_t rhport,
uint8_t ep_addr, uint8_t ep_addr,
xfer_result_t result, xfer_result_t result,
uint32_t xferred_bytes) uint32_t xferred_bytes) {
{
//printf("------ CALLED XFER_CB\r\n"); //printf("------ CALLED XFER_CB\r\n");
return vendord_xfer_cb(rhport, ep_addr, result, xferred_bytes); return vendord_xfer_cb(rhport, ep_addr, result, xferred_bytes);
//return true; //return true;
@@ -378,8 +362,7 @@ static const usbd_class_driver_t ccid_driver = {
}; };
// Implement callback to add our custom driver // Implement callback to add our custom driver
usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
{
*driver_count = 1; *driver_count = 1;
return &ccid_driver; return &ccid_driver;
} }

View File

@@ -33,8 +33,7 @@
int sock = 0; int sock = 0;
int msleep(long msec) int msleep(long msec) {
{
struct timespec ts; struct timespec ts;
int res; int res;
@@ -53,8 +52,7 @@ int msleep(long msec)
return res; return res;
} }
int emul_init(char *host, uint16_t port) int emul_init(char *host, uint16_t port) {
{
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
fprintf(stderr, "\n Starting emulation envionrment\n"); fprintf(stderr, "\n Starting emulation envionrment\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
@@ -81,14 +79,12 @@ int emul_init(char *host, uint16_t port)
return 0; return 0;
} }
uint8_t *driver_prepare_response_emul() uint8_t *driver_prepare_response_emul() {
{
apdu.rdata = usb_get_tx(ITF_EMUL); apdu.rdata = usb_get_tx(ITF_EMUL);
return apdu.rdata; return apdu.rdata;
} }
int driver_write_emul(const uint8_t *buffer, size_t buffer_size) int driver_write_emul(const uint8_t *buffer, size_t buffer_size) {
{
uint16_t size = htons(buffer_size); uint16_t size = htons(buffer_size);
//DEBUG_PAYLOAD(buffer,buffer_size); //DEBUG_PAYLOAD(buffer,buffer_size);
int ret = 0; int ret = 0;
@@ -107,8 +103,7 @@ int driver_write_emul(const uint8_t *buffer, size_t buffer_size)
return buffer_size; return buffer_size;
} }
uint32_t emul_write_offset(uint16_t size, uint16_t offset) uint32_t emul_write_offset(uint16_t size, uint16_t offset) {
{
if (size > 0) { if (size > 0) {
//DEBUG_PAYLOAD(usb_get_tx(ITF_EMUL)+offset, size); //DEBUG_PAYLOAD(usb_get_tx(ITF_EMUL)+offset, size);
return usb_write_offset(ITF_EMUL, size, offset); return usb_write_offset(ITF_EMUL, size, offset);
@@ -116,18 +111,15 @@ uint32_t emul_write_offset(uint16_t size, uint16_t offset)
return 0; return 0;
} }
uint32_t emul_write(uint16_t size) uint32_t emul_write(uint16_t size) {
{
return emul_write_offset(size, 0); return emul_write_offset(size, 0);
} }
void driver_exec_finished_cont_emul(size_t size_next, size_t offset) void driver_exec_finished_cont_emul(size_t size_next, size_t offset) {
{
emul_write_offset(size_next, offset); emul_write_offset(size_next, offset);
} }
int driver_process_usb_packet_emul(uint16_t len) int driver_process_usb_packet_emul(uint16_t len) {
{
if (len > 0) { if (len > 0) {
uint8_t *data = usb_get_rx(ITF_EMUL), *rdata = usb_get_tx(ITF_EMUL); uint8_t *data = usb_get_rx(ITF_EMUL), *rdata = usb_get_tx(ITF_EMUL);
if (len == 1) { if (len == 1) {
@@ -138,7 +130,8 @@ int driver_process_usb_packet_emul(uint16_t len)
} }
emul_write(ccid_atr ? ccid_atr[0] : 0); emul_write(ccid_atr ? ccid_atr[0] : 0);
} }
} else { }
else {
DEBUG_PAYLOAD(data, len); DEBUG_PAYLOAD(data, len);
if (apdu_process(ITF_EMUL, data, len) > 0) { if (apdu_process(ITF_EMUL, data, len) > 0) {
process_apdu(); process_apdu();
@@ -153,8 +146,7 @@ int driver_process_usb_packet_emul(uint16_t len)
return 0; return 0;
} }
uint16_t emul_read() uint16_t emul_read() {
{
uint16_t len = 0; uint16_t len = 0;
fd_set input; fd_set input;
FD_ZERO(&input); FD_ZERO(&input);
@@ -166,7 +158,8 @@ uint16_t emul_read()
if (n == -1) { if (n == -1) {
printf("read wrong\n"); printf("read wrong\n");
//something wrong //something wrong
} else if (n == 0) { }
else if (n == 0) {
printf("read timeout\n"); printf("read timeout\n");
} }
if (FD_ISSET(sock, &input)) { if (FD_ISSET(sock, &input)) {

View File

@@ -35,20 +35,17 @@ typedef struct msg_packet {
msg_packet_t msg_packet = { 0 }; msg_packet_t msg_packet = { 0 };
void tud_mount_cb() void tud_mount_cb() {
{
mounted = true; mounted = true;
} }
bool driver_mounted_hid() bool driver_mounted_hid() {
{
return mounted; return mounted;
} }
CTAPHID_FRAME *ctap_req = NULL, *ctap_resp = NULL; CTAPHID_FRAME *ctap_req = NULL, *ctap_resp = NULL;
int driver_init_hid() int driver_init_hid() {
{
tud_init(BOARD_TUD_RHPORT); tud_init(BOARD_TUD_RHPORT);
ctap_req = (CTAPHID_FRAME *) usb_get_rx(ITF_HID); ctap_req = (CTAPHID_FRAME *) usb_get_rx(ITF_HID);
apdu.header = ctap_req->init.data; apdu.header = ctap_req->init.data;
@@ -72,8 +69,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf,
uint8_t report_id, uint8_t report_id,
hid_report_type_t report_type, hid_report_type_t report_type,
uint8_t *buffer, uint8_t *buffer,
uint16_t reqlen) uint16_t reqlen) {
{
// TODO not Implemented // TODO not Implemented
(void) itf; (void) itf;
(void) report_id; (void) report_id;
@@ -88,16 +84,14 @@ uint16_t tud_hid_get_report_cb(uint8_t itf,
return reqlen; return reqlen;
} }
uint32_t hid_write_offset(uint16_t size, uint16_t offset) uint32_t hid_write_offset(uint16_t size, uint16_t offset) {
{
if (*usb_get_tx(ITF_HID) != 0x81) { if (*usb_get_tx(ITF_HID) != 0x81) {
DEBUG_PAYLOAD(usb_get_tx(ITF_HID) + offset, size); DEBUG_PAYLOAD(usb_get_tx(ITF_HID) + offset, size);
} }
return usb_write_offset(ITF_HID, size, offset); return usb_write_offset(ITF_HID, size, offset);
} }
uint32_t hid_write(uint16_t size) uint32_t hid_write(uint16_t size) {
{
return hid_write_offset(size, 0); return hid_write_offset(size, 0);
} }
@@ -110,14 +104,12 @@ static const uint8_t conv_table[128][2] = { HID_ASCII_TO_KEYCODE };
static uint8_t keyboard_w = 0; static uint8_t keyboard_w = 0;
static bool sent_key = false; static bool sent_key = false;
void add_keyboard_buffer(const uint8_t *data, size_t data_len) void add_keyboard_buffer(const uint8_t *data, size_t data_len) {
{
keyboard_buffer_len = MIN(sizeof(keyboard_buffer), data_len); keyboard_buffer_len = MIN(sizeof(keyboard_buffer), data_len);
memcpy(keyboard_buffer, data, keyboard_buffer_len); memcpy(keyboard_buffer, data, keyboard_buffer_len);
} }
static void send_hid_report(uint8_t report_id) static void send_hid_report(uint8_t report_id) {
{
if (!tud_hid_ready()) { if (!tud_hid_ready()) {
return; return;
} }
@@ -137,14 +129,16 @@ static void send_hid_report(uint8_t report_id)
keycode) == true) { keycode) == true) {
sent_key = true; sent_key = true;
} }
} else { }
else {
if (tud_hid_n_keyboard_report(ITF_KEYBOARD, REPORT_ID_KEYBOARD, 0, if (tud_hid_n_keyboard_report(ITF_KEYBOARD, REPORT_ID_KEYBOARD, 0,
NULL) == true) { NULL) == true) {
keyboard_w++; keyboard_w++;
sent_key = false; sent_key = false;
} }
} }
} else if (keyboard_w == keyboard_buffer_len && keyboard_buffer_len > 0) { }
else if (keyboard_w == keyboard_buffer_len && keyboard_buffer_len > 0) {
keyboard_w = keyboard_buffer_len = 0; keyboard_w = keyboard_buffer_len = 0;
} }
} }
@@ -154,8 +148,7 @@ static void send_hid_report(uint8_t report_id)
} }
} }
void hid_task(void) void hid_task(void) {
{
// Poll every 10ms // Poll every 10ms
const uint32_t interval_ms = 10; const uint32_t interval_ms = 10;
static uint32_t start_ms = 0; static uint32_t start_ms = 0;
@@ -168,13 +161,13 @@ void hid_task(void)
// Remote wakeup // Remote wakeup
if (tud_suspended() && keyboard_buffer_len > 0) { if (tud_suspended() && keyboard_buffer_len > 0) {
tud_remote_wakeup(); tud_remote_wakeup();
} else { }
else {
send_hid_report(REPORT_ID_KEYBOARD); send_hid_report(REPORT_ID_KEYBOARD);
} }
} }
void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, /*uint16_t*/ uint8_t len) void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, /*uint16_t*/ uint8_t len) {
{
if (send_buffer_size > 0 && instance == ITF_HID) { if (send_buffer_size > 0 && instance == ITF_HID) {
uint8_t seq = report[4] & TYPE_MASK ? 0 : report[4] + 1; uint8_t seq = report[4] & TYPE_MASK ? 0 : report[4] + 1;
if (last_write_result == true) { if (last_write_result == true) {
@@ -188,8 +181,7 @@ void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, /*uint1
} }
} }
int driver_write_hid(const uint8_t *buffer, size_t buffer_size) int driver_write_hid(const uint8_t *buffer, size_t buffer_size) {
{
last_write_result = tud_hid_n_report(ITF_HID, 0, buffer, buffer_size); last_write_result = tud_hid_n_report(ITF_HID, 0, buffer, buffer_size);
printf("result %d\n", last_write_result); printf("result %d\n", last_write_result);
if (last_write_result == false) { if (last_write_result == false) {
@@ -198,8 +190,7 @@ int driver_write_hid(const uint8_t *buffer, size_t buffer_size)
return MIN(64, buffer_size); return MIN(64, buffer_size);
} }
size_t driver_read_hid(uint8_t *buffer, size_t buffer_size) size_t driver_read_hid(uint8_t *buffer, size_t buffer_size) {
{
return 0; return 0;
} }
@@ -209,8 +200,7 @@ void tud_hid_set_report_cb(uint8_t itf,
uint8_t report_id, uint8_t report_id,
hid_report_type_t report_type, hid_report_type_t report_type,
uint8_t const *buffer, uint8_t const *buffer,
uint16_t bufsize) uint16_t bufsize) {
{
// This example doesn't use multiple report and report ID // This example doesn't use multiple report and report ID
(void) itf; (void) itf;
(void) report_id; (void) report_id;
@@ -223,8 +213,7 @@ void tud_hid_set_report_cb(uint8_t itf,
} }
uint32_t last_cmd_time = 0, last_packet_time = 0; uint32_t last_cmd_time = 0, last_packet_time = 0;
int ctap_error(uint8_t error) int ctap_error(uint8_t error) {
{
ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID); ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID);
memset(ctap_resp, 0, sizeof(CTAPHID_FRAME)); memset(ctap_resp, 0, sizeof(CTAPHID_FRAME));
ctap_resp->cid = ctap_req->cid; ctap_resp->cid = ctap_req->cid;
@@ -246,8 +235,7 @@ uint8_t thread_type = 0; //1 is APDU, 2 is CBOR
extern void cbor_thread(); extern void cbor_thread();
extern bool cancel_button; extern bool cancel_button;
int driver_process_usb_nopacket_hid() int driver_process_usb_nopacket_hid() {
{
if (last_packet_time > 0 && last_packet_time + 500 < board_millis()) { if (last_packet_time > 0 && last_packet_time + 500 < board_millis()) {
ctap_error(CTAP1_ERR_MSG_TIMEOUT); ctap_error(CTAP1_ERR_MSG_TIMEOUT);
last_packet_time = 0; last_packet_time = 0;
@@ -258,8 +246,7 @@ int driver_process_usb_nopacket_hid()
extern const uint8_t fido_aid[]; extern const uint8_t fido_aid[];
int driver_process_usb_packet_hid(uint16_t read) int driver_process_usb_packet_hid(uint16_t read) {
{
int apdu_sent = 0; int apdu_sent = 0;
if (read >= 5) { if (read >= 5) {
driver_init_hid(); driver_init_hid();
@@ -282,7 +269,8 @@ int driver_process_usb_packet_hid(uint16_t read)
ctap_req->init.cmd != CTAPHID_INIT) { ctap_req->init.cmd != CTAPHID_INIT) {
if (last_req.cid != ctap_req->cid) { //We are in a transaction if (last_req.cid != ctap_req->cid) { //We are in a transaction
return ctap_error(CTAP1_ERR_CHANNEL_BUSY); return ctap_error(CTAP1_ERR_CHANNEL_BUSY);
} else { }
else {
return ctap_error(CTAP1_ERR_INVALID_SEQ); return ctap_error(CTAP1_ERR_INVALID_SEQ);
} }
} }
@@ -298,7 +286,8 @@ int driver_process_usb_packet_hid(uint16_t read)
last_cmd = ctap_req->init.cmd; last_cmd = ctap_req->init.cmd;
last_seq = 0; last_seq = 0;
last_cmd_time = board_millis(); last_cmd_time = board_millis();
} else { }
else {
if (msg_packet.len == 0) { //Received a cont with a prior init pkt if (msg_packet.len == 0) { //Received a cont with a prior init pkt
return 0; return 0;
} }
@@ -311,7 +300,8 @@ int driver_process_usb_packet_hid(uint16_t read)
msg_packet.current_len += MIN(64 - 5, msg_packet.len - msg_packet.current_len); msg_packet.current_len += MIN(64 - 5, msg_packet.len - msg_packet.current_len);
memcpy(&last_req, ctap_req, sizeof(CTAPHID_FRAME)); memcpy(&last_req, ctap_req, sizeof(CTAPHID_FRAME));
last_seq++; last_seq++;
} else if (last_cmd_time+100 > board_millis()) { }
else if (last_cmd_time + 100 > board_millis()) {
return ctap_error(CTAP1_ERR_CHANNEL_BUSY); return ctap_error(CTAP1_ERR_CHANNEL_BUSY);
} }
@@ -337,7 +327,8 @@ int driver_process_usb_packet_hid(uint16_t read)
hid_write(64); hid_write(64);
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
last_packet_time = 0; last_packet_time = 0;
} else if (ctap_req->init.cmd == CTAPHID_WINK) { }
else if (ctap_req->init.cmd == CTAPHID_WINK) {
if (MSG_LEN(ctap_req) != 0) { if (MSG_LEN(ctap_req) != 0) {
return ctap_error(CTAP1_ERR_INVALID_LEN); return ctap_error(CTAP1_ERR_INVALID_LEN);
} }
@@ -347,14 +338,16 @@ int driver_process_usb_packet_hid(uint16_t read)
hid_write(64); hid_write(64);
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
last_packet_time = 0; last_packet_time = 0;
} else if ((last_cmd == CTAPHID_PING || last_cmd == CTAPHID_SYNC) && }
else if ((last_cmd == CTAPHID_PING || last_cmd == CTAPHID_SYNC) &&
(msg_packet.len == 0 || (msg_packet.len == 0 ||
(msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) {
ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID); ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID);
if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) {
memcpy(ctap_resp->init.data, msg_packet.data, msg_packet.len); memcpy(ctap_resp->init.data, msg_packet.data, msg_packet.len);
driver_exec_finished_hid(msg_packet.len); driver_exec_finished_hid(msg_packet.len);
} else { }
else {
memcpy(ctap_resp->init.data, ctap_req->init.data, MSG_LEN(ctap_req)); memcpy(ctap_resp->init.data, ctap_req->init.data, MSG_LEN(ctap_req));
ctap_resp->cid = ctap_req->cid; ctap_resp->cid = ctap_req->cid;
ctap_resp->init.cmd = last_cmd; ctap_resp->init.cmd = last_cmd;
@@ -364,7 +357,8 @@ int driver_process_usb_packet_hid(uint16_t read)
} }
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
last_packet_time = 0; last_packet_time = 0;
} else if (ctap_req->init.cmd == CTAPHID_LOCK) { }
else if (ctap_req->init.cmd == CTAPHID_LOCK) {
if (MSG_LEN(ctap_req) != 1) { if (MSG_LEN(ctap_req) != 1) {
return ctap_error(CTAP1_ERR_INVALID_LEN); return ctap_error(CTAP1_ERR_INVALID_LEN);
} }
@@ -379,12 +373,14 @@ int driver_process_usb_packet_hid(uint16_t read)
hid_write(64); hid_write(64);
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
last_packet_time = 0; last_packet_time = 0;
} else if (last_cmd == CTAPHID_MSG && }
else if (last_cmd == CTAPHID_MSG &&
(msg_packet.len == 0 || (msg_packet.len == 0 ||
(msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) {
if (current_app == NULL || if (current_app == NULL ||
memcmp(current_app->aid, fido_aid+1, MIN(current_app->aid[0], fido_aid[0])) != 0) { memcmp(current_app->aid, fido_aid + 1,
MIN(current_app->aid[0], fido_aid[0])) != 0) {
for (int a = 0; a < num_apps; a++) { for (int a = 0; a < num_apps; a++) {
if ((current_app = apps[a].select_aid(&apps[a], fido_aid + 1, fido_aid[0]))) { if ((current_app = apps[a].select_aid(&apps[a], fido_aid + 1, fido_aid[0]))) {
break; break;
@@ -397,13 +393,15 @@ int driver_process_usb_packet_hid(uint16_t read)
if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) {
apdu_sent = apdu_process(ITF_HID, msg_packet.data, msg_packet.len); apdu_sent = apdu_process(ITF_HID, msg_packet.data, msg_packet.len);
} else { }
else {
apdu_sent = apdu_process(ITF_HID, ctap_req->init.data, MSG_LEN(ctap_req)); apdu_sent = apdu_process(ITF_HID, ctap_req->init.data, MSG_LEN(ctap_req));
} }
DEBUG_PAYLOAD(apdu.data, (int) apdu.nc); DEBUG_PAYLOAD(apdu.data, (int) apdu.nc);
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
last_packet_time = 0; last_packet_time = 0;
} else if ((last_cmd == CTAPHID_CBOR || }
else if ((last_cmd == CTAPHID_CBOR ||
(last_cmd >= CTAPHID_VENDOR_FIRST && last_cmd <= CTAPHID_VENDOR_LAST)) && (last_cmd >= CTAPHID_VENDOR_FIRST && last_cmd <= CTAPHID_VENDOR_LAST)) &&
(msg_packet.len == 0 || (msg_packet.len == 0 ||
(msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) {
@@ -413,7 +411,8 @@ int driver_process_usb_packet_hid(uint16_t read)
thread_type = 2; thread_type = 2;
if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) {
apdu_sent = cbor_process(last_cmd, msg_packet.data, msg_packet.len); apdu_sent = cbor_process(last_cmd, msg_packet.data, msg_packet.len);
} else { }
else {
apdu_sent = cbor_process(last_cmd, ctap_req->init.data, MSG_LEN(ctap_req)); apdu_sent = cbor_process(last_cmd, ctap_req->init.data, MSG_LEN(ctap_req));
} }
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
@@ -421,12 +420,14 @@ int driver_process_usb_packet_hid(uint16_t read)
if (apdu_sent < 0) { if (apdu_sent < 0) {
return ctap_error(-apdu_sent); return ctap_error(-apdu_sent);
} }
} else if (ctap_req->init.cmd == CTAPHID_CANCEL) { }
else if (ctap_req->init.cmd == CTAPHID_CANCEL) {
ctap_error(0x2D); ctap_error(0x2D);
msg_packet.len = msg_packet.current_len = 0; msg_packet.len = msg_packet.current_len = 0;
last_packet_time = 0; last_packet_time = 0;
cancel_button = true; cancel_button = true;
} else { }
else {
if (msg_packet.len == 0) { if (msg_packet.len == 0) {
return ctap_error(CTAP1_ERR_INVALID_CMD); return ctap_error(CTAP1_ERR_INVALID_CMD);
} }
@@ -439,8 +440,7 @@ int driver_process_usb_packet_hid(uint16_t read)
return apdu_sent; return apdu_sent;
} }
void send_keepalive() void send_keepalive() {
{
CTAPHID_FRAME *resp = (CTAPHID_FRAME *) (usb_get_tx(ITF_HID) + 4096); CTAPHID_FRAME *resp = (CTAPHID_FRAME *) (usb_get_tx(ITF_HID) + 4096);
//memset(ctap_resp, 0, sizeof(CTAPHID_FRAME)); //memset(ctap_resp, 0, sizeof(CTAPHID_FRAME));
resp->cid = ctap_req->cid; resp->cid = ctap_req->cid;
@@ -451,15 +451,13 @@ void send_keepalive()
hid_write_offset(64, 4096); hid_write_offset(64, 4096);
} }
void driver_exec_timeout_hid() void driver_exec_timeout_hid() {
{
if (thread_type == 2) { if (thread_type == 2) {
send_keepalive(); send_keepalive();
} }
} }
uint8_t *driver_prepare_response_hid() uint8_t *driver_prepare_response_hid() {
{
ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID); ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID);
apdu.rdata = ctap_resp->init.data; apdu.rdata = ctap_resp->init.data;
send_buffer_size = 0; send_buffer_size = 0;
@@ -467,20 +465,19 @@ uint8_t *driver_prepare_response_hid()
return ctap_resp->init.data; return ctap_resp->init.data;
} }
void driver_exec_finished_hid(size_t size_next) void driver_exec_finished_hid(size_t size_next) {
{
if (size_next > 0) { if (size_next > 0) {
if (thread_type == 2 && apdu.sw != 0) { if (thread_type == 2 && apdu.sw != 0) {
ctap_error(apdu.sw & 0xff); ctap_error(apdu.sw & 0xff);
} else { }
else {
driver_exec_finished_cont_hid(size_next, 7); driver_exec_finished_cont_hid(size_next, 7);
} }
} }
apdu.sw = 0; apdu.sw = 0;
} }
void driver_exec_finished_cont_hid(size_t size_next, size_t offset) void driver_exec_finished_cont_hid(size_t size_next, size_t offset) {
{
offset -= 7; offset -= 7;
ctap_resp = (CTAPHID_FRAME *) (usb_get_tx(ITF_HID) + offset); ctap_resp = (CTAPHID_FRAME *) (usb_get_tx(ITF_HID) + offset);
ctap_resp->cid = ctap_req->cid; ctap_resp->cid = ctap_req->cid;