diff --git a/ctap.c b/ctap.c index f3c51e4..31919a1 100644 --- a/ctap.c +++ b/ctap.c @@ -736,7 +736,7 @@ uint8_t ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) pkt_raw++; - uint8_t buf[1024]; + static uint8_t buf[1024]; memset(buf,0,sizeof(buf)); resp->data = buf; @@ -769,6 +769,7 @@ uint8_t ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) resp->length = cbor_encoder_get_buffer_size(&encoder, buf); + break; case CTAP_CLIENT_PIN: printf("CTAP_CLIENT_PIN\n"); @@ -783,6 +784,7 @@ uint8_t ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) printf("error, invalid cmd\n"); } - printf("cbor structure: %d bytes\n", length - 1); + printf("cbor input structure: %d bytes\n", length - 1); + printf("cbor output structure: %d bytes\n", resp->length); return 0; } diff --git a/ctap.h b/ctap.h index 89026d8..da1bb63 100644 --- a/ctap.h +++ b/ctap.h @@ -138,11 +138,7 @@ extern int ctap_user_verification(uint8_t arg); // Must be implemented by application // data is HID_MESSAGE_SIZE long in bytes -extern void ctap_write_block(uint8_t * data); +extern void ctaphid_write_block(uint8_t * data); -// Buffer data and send in HID_MESSAGE_SIZE chunks -// if len == 0, FLUSH -// if len == -1, RESET -extern void ctap_write(void * _data, int len); #endif diff --git a/ctap_device.c b/ctap_device.c index bf17863..2901270 100644 --- a/ctap_device.c +++ b/ctap_device.c @@ -12,46 +12,12 @@ #include "usbhid.h" -void ctap_write_block(uint8_t * data) +void ctaphid_write_block(uint8_t * data) { printf("<< "); dump_hex(data, 64); usbhid_send(data); } -void ctap_write(void * _data, int len) -{ - static uint8_t buf[HID_MESSAGE_SIZE]; - static int offset = 0; - - uint8_t * data = (uint8_t *) _data; - - if (len == 0) - { - if (offset > 0) - { - memset(buf + offset, 0, HID_MESSAGE_SIZE - offset); - ctap_write_block(buf); - } - offset = 0; - return; - } - else if (len == -1) - { - memset(buf, 0, HID_MESSAGE_SIZE); - offset = 0; - } - - int i; - for (i = 0; i < len; i++) - { - buf[offset++] = data[i]; - if (offset == HID_MESSAGE_SIZE) - { - ctap_write_block(buf); - offset = 0; - } - } -} int ctap_user_presence_test() { diff --git a/ctaphid.c b/ctaphid.c index a4f8cae..bc2cdd5 100644 --- a/ctaphid.c +++ b/ctaphid.c @@ -21,6 +21,19 @@ typedef enum BUFFERED, } CTAP_BUFFER_STATE; + +typedef struct +{ + uint8_t cmd; + uint32_t cid; + uint16_t bcnt; + int offset; + int bytes_written; + uint8_t seq; + uint8_t buf[HID_MESSAGE_SIZE]; +} CTAPHID_WRITE_BUFFER; + + #define SUCESS 0 #define SEQUENCE_ERROR 1 @@ -39,13 +52,19 @@ static uint32_t _next_cid = 0; static void buffer_reset(); +#define CTAPHID_WRITE_INIT 0x01 +#define CTAPHID_WRITE_FLUSH 0x02 +#define CTAPHID_WRITE_RESET 0x04 + +#define ctaphid_write_buffer_init(x) memset(x,0,sizeof(CTAPHID_WRITE_BUFFER)) +static void ctaphid_write(CTAPHID_WRITE_BUFFER * wb, void * _data, int len); + void ctaphid_init() { state = IDLE; active_cid = 0; buffer_reset(); active_cid_timestamp = millis(); - ctap_write(NULL, -1); } static uint32_t set_next_cid(uint32_t cid) @@ -161,18 +180,75 @@ static int buffer_len() return ctap_buffer_bcnt; } +// Buffer data and send in HID_MESSAGE_SIZE chunks +// if len == 0, FLUSH +static void ctaphid_write(CTAPHID_WRITE_BUFFER * wb, void * _data, int len) +{ + uint8_t * data = (uint8_t *)_data; + if (len == 0) + { + if (wb->offset == 0 && wb->bytes_written == 0) + { + memmove(wb->buf, &wb->cid, 4); + wb->offset += 4; + + wb->buf[4] = wb->cmd; + wb->buf[5] = (wb->bcnt & 0xff00) >> 8; + wb->buf[6] = (wb->bcnt & 0xff) >> 0; + wb->offset += 3; + } + + if (wb->offset > 0) + { + memset(wb->buf + wb->offset, 0, HID_MESSAGE_SIZE - wb->offset); + ctaphid_write_block(wb->buf); + } + return; + } + int i; + for (i = 0; i < len; i++) + { + if (wb->offset == 0 ) + { + memmove(wb->buf, &wb->cid, 4); + wb->offset += 4; + + if (wb->bytes_written == 0) + { + wb->buf[4] = wb->cmd; + wb->buf[5] = (wb->bcnt & 0xff00) >> 8; + wb->buf[6] = (wb->bcnt & 0xff) >> 0; + wb->offset += 3; + } + else + { + wb->buf[4] = wb->seq++; + wb->offset += 1; + } + } + wb->buf[wb->offset++] = data[i]; + wb->bytes_written += 1; + if (wb->offset == HID_MESSAGE_SIZE) + { + ctaphid_write_block(wb->buf); + wb->offset = 0; + } + } +} + static void ctaphid_send_error(uint32_t cid, uint8_t error) { uint8_t buf[HID_MESSAGE_SIZE]; - memset(buf,0,sizeof(buf)); - CTAPHID_RESPONSE * resp = (CTAPHID_RESPONSE *) buf; - resp->cid = cid; - resp->cmd = CTAPHID_ERROR; - resp->bcnth = 0; - resp->bcntl = 1; - buf[sizeof(CTAPHID_RESPONSE)] = error; - ctap_write_block(buf); + CTAPHID_WRITE_BUFFER wb; + ctaphid_write_buffer_init(&wb); + + wb.cid = cid; + wb.cmd = CTAPHID_ERROR; + wb.bcnt = 1; + + ctaphid_write(&wb, &error, 1); + ctaphid_write(&wb, NULL, 0); } void ctaphid_handle_packet(uint8_t * pkt_raw) @@ -188,7 +264,7 @@ void ctaphid_handle_packet(uint8_t * pkt_raw) uint8_t status; uint32_t oldcid; static CTAPHID_INIT_RESPONSE init_resp; - static CTAPHID_RESPONSE resp; + static CTAPHID_WRITE_BUFFER wb; CTAP_RESPONSE ctap_resp; @@ -298,10 +374,11 @@ start_over: printf("cid: %08x\n",active_cid); active_cid_timestamp = millis(); - init_resp.broadcast = CTAPHID_BROADCAST_CID; - init_resp.cmd = CTAPHID_INIT; - init_resp.bcnth = (17 & 0xff00) >> 8; - init_resp.bcntl = (17 & 0xff) >> 0; + ctaphid_write_buffer_init(&wb); + wb.cid = CTAPHID_BROADCAST_CID; + wb.cmd = CTAPHID_INIT; + wb.bcnt = 17; + memmove(init_resp.nonce, pkt->pkt.init.payload, 8); init_resp.cid = active_cid; init_resp.protocol_version = 0;//? @@ -310,21 +387,20 @@ start_over: init_resp.build_version = 0;//? init_resp.capabilities = CAPABILITY_WINK | CAPABILITY_CBOR; - ctap_write(&init_resp,sizeof(CTAPHID_INIT_RESPONSE)); - ctap_write(NULL,0); + ctaphid_write(&wb,&init_resp,sizeof(CTAPHID_INIT_RESPONSE)); + ctaphid_write(&wb,NULL,0); break; case CTAPHID_PING: - resp.cid = active_cid; - resp.cmd = CTAPHID_PING; - resp.bcnth = (buffer_len() & 0xff00) >> 8; - resp.bcntl = (buffer_len() & 0xff) >> 0; + ctaphid_write_buffer_init(&wb); + wb.cid = active_cid; + wb.cmd = CTAPHID_PING; + wb.bcnt = buffer_len(); - ctap_write(&resp,sizeof(CTAPHID_RESPONSE)); - ctap_write(ctap_buffer, buffer_len()); - ctap_write(NULL,0); + ctaphid_write(&wb, ctap_buffer, buffer_len()); + ctaphid_write(&wb, NULL,0); printf("CTAPHID_PING\n"); break; @@ -339,13 +415,12 @@ start_over: return; } - resp.cid = active_cid; - resp.cmd = CTAPHID_WINK; - resp.bcntl = 0; - resp.bcnth = 0; + ctaphid_write_buffer_init(&wb); - ctap_write(&resp,sizeof(CTAPHID_RESPONSE)); - ctap_write(NULL,0); + wb.cid = active_cid; + wb.cmd = CTAPHID_WINK; + + ctaphid_write(&wb,NULL,0); printf("CTAPHID_WINK\n"); break; @@ -362,17 +437,14 @@ start_over: status = ctap_handle_packet(ctap_buffer, buffer_len(), &ctap_resp); - resp.cid = active_cid; - resp.cmd = CTAPHID_CBOR; - resp.bcntl = ((ctap_resp.length+1) & 0x00ff) >> 0; - resp.bcnth = ((ctap_resp.length+1) & 0xff00) >> 8; - - ctap_write(&resp,sizeof(CTAPHID_RESPONSE)); - ctap_write(&status, 1); - ctap_write(ctap_resp.data, ctap_resp.length); - ctap_write(NULL, 0); - + ctaphid_write_buffer_init(&wb); + wb.cid = active_cid; + wb.cmd = CTAPHID_CBOR; + wb.bcnt = (ctap_resp.length+1); + ctaphid_write(&wb, &status, 1); + ctaphid_write(&wb, ctap_resp.data, ctap_resp.length); + ctaphid_write(&wb, NULL, 0); break; default: diff --git a/ctaphid.h b/ctaphid.h index e7c2561..e641da9 100644 --- a/ctaphid.h +++ b/ctaphid.h @@ -55,10 +55,6 @@ typedef struct typedef struct { - uint32_t broadcast; - uint8_t cmd; - uint8_t bcnth; - uint8_t bcntl; uint8_t nonce[8]; uint32_t cid; uint8_t protocol_version; @@ -68,16 +64,6 @@ typedef struct uint8_t capabilities; } __attribute__((packed)) CTAPHID_INIT_RESPONSE; -typedef struct -{ - uint32_t cid; - uint8_t cmd; - uint8_t bcnth; - uint8_t bcntl; -} __attribute__((packed)) CTAPHID_RESPONSE; - - - void ctaphid_init();