fix hid write back buffering

This commit is contained in:
Conor Patrick 2018-05-07 00:00:06 -04:00
parent 7722fb0c56
commit 71a0f1b55c
5 changed files with 117 additions and 95 deletions

6
ctap.c
View File

@ -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;
}

6
ctap.h
View File

@ -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

View File

@ -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()
{

150
ctaphid.c
View File

@ -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:

View File

@ -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();