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++; pkt_raw++;
uint8_t buf[1024]; static uint8_t buf[1024];
memset(buf,0,sizeof(buf)); memset(buf,0,sizeof(buf));
resp->data = 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); resp->length = cbor_encoder_get_buffer_size(&encoder, buf);
break; break;
case CTAP_CLIENT_PIN: case CTAP_CLIENT_PIN:
printf("CTAP_CLIENT_PIN\n"); 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("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; return 0;
} }

6
ctap.h
View File

@ -138,11 +138,7 @@ extern int ctap_user_verification(uint8_t arg);
// Must be implemented by application // Must be implemented by application
// data is HID_MESSAGE_SIZE long in bytes // 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 #endif

View File

@ -12,46 +12,12 @@
#include "usbhid.h" #include "usbhid.h"
void ctap_write_block(uint8_t * data) void ctaphid_write_block(uint8_t * data)
{ {
printf("<< "); dump_hex(data, 64); printf("<< "); dump_hex(data, 64);
usbhid_send(data); 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() int ctap_user_presence_test()
{ {

150
ctaphid.c
View File

@ -21,6 +21,19 @@ typedef enum
BUFFERED, BUFFERED,
} CTAP_BUFFER_STATE; } 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 SUCESS 0
#define SEQUENCE_ERROR 1 #define SEQUENCE_ERROR 1
@ -39,13 +52,19 @@ static uint32_t _next_cid = 0;
static void buffer_reset(); 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() void ctaphid_init()
{ {
state = IDLE; state = IDLE;
active_cid = 0; active_cid = 0;
buffer_reset(); buffer_reset();
active_cid_timestamp = millis(); active_cid_timestamp = millis();
ctap_write(NULL, -1);
} }
static uint32_t set_next_cid(uint32_t cid) static uint32_t set_next_cid(uint32_t cid)
@ -161,18 +180,75 @@ static int buffer_len()
return ctap_buffer_bcnt; 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) static void ctaphid_send_error(uint32_t cid, uint8_t error)
{ {
uint8_t buf[HID_MESSAGE_SIZE]; uint8_t buf[HID_MESSAGE_SIZE];
memset(buf,0,sizeof(buf)); CTAPHID_WRITE_BUFFER wb;
CTAPHID_RESPONSE * resp = (CTAPHID_RESPONSE *) buf; ctaphid_write_buffer_init(&wb);
resp->cid = cid;
resp->cmd = CTAPHID_ERROR; wb.cid = cid;
resp->bcnth = 0; wb.cmd = CTAPHID_ERROR;
resp->bcntl = 1; wb.bcnt = 1;
buf[sizeof(CTAPHID_RESPONSE)] = error;
ctap_write_block(buf); ctaphid_write(&wb, &error, 1);
ctaphid_write(&wb, NULL, 0);
} }
void ctaphid_handle_packet(uint8_t * pkt_raw) void ctaphid_handle_packet(uint8_t * pkt_raw)
@ -188,7 +264,7 @@ void ctaphid_handle_packet(uint8_t * pkt_raw)
uint8_t status; uint8_t status;
uint32_t oldcid; uint32_t oldcid;
static CTAPHID_INIT_RESPONSE init_resp; static CTAPHID_INIT_RESPONSE init_resp;
static CTAPHID_RESPONSE resp; static CTAPHID_WRITE_BUFFER wb;
CTAP_RESPONSE ctap_resp; CTAP_RESPONSE ctap_resp;
@ -298,10 +374,11 @@ start_over:
printf("cid: %08x\n",active_cid); printf("cid: %08x\n",active_cid);
active_cid_timestamp = millis(); active_cid_timestamp = millis();
init_resp.broadcast = CTAPHID_BROADCAST_CID; ctaphid_write_buffer_init(&wb);
init_resp.cmd = CTAPHID_INIT; wb.cid = CTAPHID_BROADCAST_CID;
init_resp.bcnth = (17 & 0xff00) >> 8; wb.cmd = CTAPHID_INIT;
init_resp.bcntl = (17 & 0xff) >> 0; wb.bcnt = 17;
memmove(init_resp.nonce, pkt->pkt.init.payload, 8); memmove(init_resp.nonce, pkt->pkt.init.payload, 8);
init_resp.cid = active_cid; init_resp.cid = active_cid;
init_resp.protocol_version = 0;//? init_resp.protocol_version = 0;//?
@ -310,21 +387,20 @@ start_over:
init_resp.build_version = 0;//? init_resp.build_version = 0;//?
init_resp.capabilities = CAPABILITY_WINK | CAPABILITY_CBOR; init_resp.capabilities = CAPABILITY_WINK | CAPABILITY_CBOR;
ctap_write(&init_resp,sizeof(CTAPHID_INIT_RESPONSE)); ctaphid_write(&wb,&init_resp,sizeof(CTAPHID_INIT_RESPONSE));
ctap_write(NULL,0); ctaphid_write(&wb,NULL,0);
break; break;
case CTAPHID_PING: case CTAPHID_PING:
resp.cid = active_cid; ctaphid_write_buffer_init(&wb);
resp.cmd = CTAPHID_PING; wb.cid = active_cid;
resp.bcnth = (buffer_len() & 0xff00) >> 8; wb.cmd = CTAPHID_PING;
resp.bcntl = (buffer_len() & 0xff) >> 0; wb.bcnt = buffer_len();
ctap_write(&resp,sizeof(CTAPHID_RESPONSE)); ctaphid_write(&wb, ctap_buffer, buffer_len());
ctap_write(ctap_buffer, buffer_len()); ctaphid_write(&wb, NULL,0);
ctap_write(NULL,0);
printf("CTAPHID_PING\n"); printf("CTAPHID_PING\n");
break; break;
@ -339,13 +415,12 @@ start_over:
return; return;
} }
resp.cid = active_cid; ctaphid_write_buffer_init(&wb);
resp.cmd = CTAPHID_WINK;
resp.bcntl = 0;
resp.bcnth = 0;
ctap_write(&resp,sizeof(CTAPHID_RESPONSE)); wb.cid = active_cid;
ctap_write(NULL,0); wb.cmd = CTAPHID_WINK;
ctaphid_write(&wb,NULL,0);
printf("CTAPHID_WINK\n"); printf("CTAPHID_WINK\n");
break; break;
@ -362,17 +437,14 @@ start_over:
status = ctap_handle_packet(ctap_buffer, buffer_len(), &ctap_resp); status = ctap_handle_packet(ctap_buffer, buffer_len(), &ctap_resp);
resp.cid = active_cid; ctaphid_write_buffer_init(&wb);
resp.cmd = CTAPHID_CBOR; wb.cid = active_cid;
resp.bcntl = ((ctap_resp.length+1) & 0x00ff) >> 0; wb.cmd = CTAPHID_CBOR;
resp.bcnth = ((ctap_resp.length+1) & 0xff00) >> 8; wb.bcnt = (ctap_resp.length+1);
ctap_write(&resp,sizeof(CTAPHID_RESPONSE));
ctap_write(&status, 1);
ctap_write(ctap_resp.data, ctap_resp.length);
ctap_write(NULL, 0);
ctaphid_write(&wb, &status, 1);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
ctaphid_write(&wb, NULL, 0);
break; break;
default: default:

View File

@ -55,10 +55,6 @@ typedef struct
typedef struct typedef struct
{ {
uint32_t broadcast;
uint8_t cmd;
uint8_t bcnth;
uint8_t bcntl;
uint8_t nonce[8]; uint8_t nonce[8];
uint32_t cid; uint32_t cid;
uint8_t protocol_version; uint8_t protocol_version;
@ -68,16 +64,6 @@ typedef struct
uint8_t capabilities; uint8_t capabilities;
} __attribute__((packed)) CTAPHID_INIT_RESPONSE; } __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(); void ctaphid_init();