diff --git a/src/usb/hid/hid.c b/src/usb/hid/hid.c index c44885c..42e80c0 100644 --- a/src/usb/hid/hid.c +++ b/src/usb/hid/hid.c @@ -125,6 +125,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep usb_rx(buffer, bufsize); } +uint32_t last_cmd_time = 0, last_packet_time = 0; int ctap_error(uint8_t error) { ctap_resp = (CTAPHID_FRAME *)usb_get_tx(); memset(ctap_resp, 0, sizeof(CTAPHID_FRAME)); @@ -134,6 +135,7 @@ int ctap_error(uint8_t error) { ctap_resp->init.data[0] = error; hid_write(64); usb_clear_rx(); + last_packet_time = 0; return 0; } @@ -145,10 +147,9 @@ uint32_t lock = 0; uint8_t thread_type = 0; //1 is APDU, 2 is CBOR extern void cbor_thread(); extern void init_fido(); -uint32_t last_cmd_time = 0, last_packet_time = 0; int driver_process_usb_nopacket() { - if (last_packet_time+500 < board_millis()) { + if (last_packet_time > 0 && last_packet_time+500 < board_millis()) { ctap_error(CTAP1_ERR_MSG_TIMEOUT); last_packet_time = 0; msg_packet.len = msg_packet.current_len = 0; @@ -165,14 +166,18 @@ int driver_process_usb_packet(uint16_t read) { memset(ctap_resp, 0, sizeof(CTAPHID_FRAME)); if (ctap_req->cid == 0x0 || (ctap_req->cid == CID_BROADCAST && ctap_req->init.cmd != CTAPHID_INIT)) return ctap_error(CTAP1_ERR_INVALID_CHANNEL); - if (board_millis() < lock && ctap_req->cid != last_req.cid && last_cmd_time+1000 > board_millis()) + if (board_millis() < lock && ctap_req->cid != last_req.cid && last_cmd_time+100 > board_millis()) return ctap_error(CTAP1_ERR_CHANNEL_BUSY); if (FRAME_TYPE(ctap_req) == TYPE_INIT) { if (MSG_LEN(ctap_req) > CTAP_MAX_PACKET_SIZE) return ctap_error(CTAP1_ERR_INVALID_LEN); - if (msg_packet.len > 0 && last_req.cid != ctap_req->cid && last_cmd_time+1000 > board_millis()) //We are in a transaction - return ctap_error(CTAP1_ERR_CHANNEL_BUSY); + if (msg_packet.len > 0 && last_cmd_time+100 > board_millis() && ctap_req->init.cmd != CTAPHID_INIT) { + if (last_req.cid != ctap_req->cid) //We are in a transaction + return ctap_error(CTAP1_ERR_CHANNEL_BUSY); + else + return ctap_error(CTAP1_ERR_INVALID_SEQ); + } printf("command %x\n", FRAME_CMD(ctap_req)); printf("len %d\n", MSG_LEN(ctap_req)); msg_packet.len = msg_packet.current_len = 0; @@ -196,9 +201,11 @@ int driver_process_usb_packet(uint16_t read) { memcpy(msg_packet.data + msg_packet.current_len, ctap_req->cont.data, 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)); + last_seq++; } - //else // Received a cont from another channel. Silently discard - last_seq++; + else if (last_cmd_time+100 > board_millis()) + return ctap_error(CTAP1_ERR_CHANNEL_BUSY); + } if (ctap_req->init.cmd == CTAPHID_INIT) { @@ -219,7 +226,8 @@ int driver_process_usb_packet(uint16_t read) { ctap_resp->init.bcntl = 17; ctap_resp->init.bcnth = 0; driver_exec_finished(17); - printf("OK\n"); + msg_packet.len = msg_packet.current_len = 0; + last_packet_time = 0; } else if (ctap_req->init.cmd == CTAPHID_WINK) { if (MSG_LEN(ctap_req) != 0) { @@ -229,6 +237,8 @@ int driver_process_usb_packet(uint16_t read) { memcpy(ctap_resp, ctap_req, sizeof(CTAPHID_FRAME)); sleep_ms(1000); //For blinking the device during 1 seg hid_write(64); + msg_packet.len = msg_packet.current_len = 0; + last_packet_time = 0; } else if ((last_cmd == CTAPHID_PING || last_cmd == CTAPHID_SYNC) && (msg_packet.len == 0 || (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { ctap_resp = (CTAPHID_FRAME *)usb_get_tx(); @@ -241,6 +251,7 @@ int driver_process_usb_packet(uint16_t read) { driver_exec_finished(MSG_LEN(ctap_req)); } msg_packet.len = msg_packet.current_len = 0; + last_packet_time = 0; } else if (ctap_req->init.cmd == CTAPHID_LOCK) { if (MSG_LEN(ctap_req) != 1) @@ -253,6 +264,8 @@ int driver_process_usb_packet(uint16_t read) { ctap_resp->cid = ctap_req->cid; ctap_resp->init.cmd = ctap_req->init.cmd; hid_write(64); + msg_packet.len = msg_packet.current_len = 0; + last_packet_time = 0; } else if (last_cmd == CTAPHID_MSG && (msg_packet.len == 0 || (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { @@ -266,7 +279,8 @@ int driver_process_usb_packet(uint16_t read) { else apdu_sent = apdu_process(ctap_req->init.data, MSG_LEN(ctap_req)); DEBUG_PAYLOAD(apdu.data, (int)apdu.nc); - msg_packet.len = msg_packet.current_len = 0; //Reset the transaction + msg_packet.len = msg_packet.current_len = 0; + last_packet_time = 0; } else if (last_cmd == CTAPHID_CBOR && (msg_packet.len == 0 || (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { @@ -277,7 +291,8 @@ int driver_process_usb_packet(uint16_t read) { apdu_sent = cbor_process(msg_packet.data, msg_packet.len); else apdu_sent = cbor_process(ctap_req->init.data, MSG_LEN(ctap_req)); - msg_packet.len = msg_packet.current_len = 0; //Reset the transaction + msg_packet.len = msg_packet.current_len = 0; + last_packet_time = 0; if (apdu_sent < 0) return ctap_error(-apdu_sent); } @@ -293,7 +308,7 @@ int driver_process_usb_packet(uint16_t read) { return apdu_sent; } -void driver_exec_timeout() { +void send_keepalive() { ctap_resp = (CTAPHID_FRAME *)usb_get_tx(); memset(ctap_resp, 0, sizeof(CTAPHID_FRAME)); ctap_resp->cid = ctap_req->cid; @@ -305,6 +320,10 @@ void driver_exec_timeout() { ctap_resp->init.data[0] = bck; } +void driver_exec_timeout() { + send_keepalive(); +} + uint8_t *driver_prepare_response() { ctap_resp = (CTAPHID_FRAME *)usb_get_tx(); apdu.rdata = ctap_resp->init.data;