mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
More standard conform behaviour
Tested with u2f-ref-code/u2f-tests. Known incompatibility: - changed challenge invalidates button press.
This commit is contained in:
parent
96f30a0ba7
commit
68b34af19e
@ -57,7 +57,7 @@ bool protectButton(ButtonRequestType type, bool confirm_only)
|
|||||||
|
|
||||||
// button acked - check buttons
|
// button acked - check buttons
|
||||||
if (acked) {
|
if (acked) {
|
||||||
usbDelay(3500);
|
usbDelay(3300);
|
||||||
buttonUpdate();
|
buttonUpdate();
|
||||||
if (button.YesUp) {
|
if (button.YesUp) {
|
||||||
result = true;
|
result = true;
|
||||||
@ -163,7 +163,7 @@ bool protectPin(bool use_cached)
|
|||||||
}
|
}
|
||||||
layoutDialog(DIALOG_ICON_INFO, NULL, NULL, NULL, "Wrong PIN entered", NULL, "Please wait", secstr, "to continue ...", NULL);
|
layoutDialog(DIALOG_ICON_INFO, NULL, NULL, NULL, "Wrong PIN entered", NULL, "Please wait", secstr, "to continue ...", NULL);
|
||||||
// wait one second
|
// wait one second
|
||||||
usbDelay(840000);
|
usbDelay(800000);
|
||||||
wait--;
|
wait--;
|
||||||
}
|
}
|
||||||
const char *pin;
|
const char *pin;
|
||||||
|
141
firmware/u2f.c
141
firmware/u2f.c
@ -44,8 +44,8 @@
|
|||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
// About 1/2 Second according to values used in protect.c
|
// About 1/2 Second according to values used in protect.c
|
||||||
#define U2F_TIMEOUT 840000/2
|
#define U2F_TIMEOUT (800000/2)
|
||||||
#define U2F_OUT_PKT_BUFFER_LEN 16
|
#define U2F_OUT_PKT_BUFFER_LEN 128
|
||||||
|
|
||||||
// Initialise without a cid
|
// Initialise without a cid
|
||||||
static uint32_t cid = 0;
|
static uint32_t cid = 0;
|
||||||
@ -120,36 +120,6 @@ char *debugInt(const uint32_t i)
|
|||||||
|
|
||||||
static uint32_t dialog_timeout = 0;
|
static uint32_t dialog_timeout = 0;
|
||||||
|
|
||||||
void LayoutHomeAfterTimeout(void)
|
|
||||||
{
|
|
||||||
static bool timeoutLock = false;
|
|
||||||
|
|
||||||
if (timeoutLock || dialog_timeout == 0)
|
|
||||||
return; // Dialog has cleared or already in loop
|
|
||||||
|
|
||||||
timeoutLock = true;
|
|
||||||
U2F_STATE rs = last_req_state;
|
|
||||||
U2F_STATE bs = INIT;
|
|
||||||
while (dialog_timeout-- && rs == last_req_state && bs == 0) {
|
|
||||||
usbPoll(); // may trigger new request
|
|
||||||
bs = buttonState();
|
|
||||||
}
|
|
||||||
timeoutLock = false;
|
|
||||||
|
|
||||||
if (rs != last_req_state)
|
|
||||||
return; // Reset by new request don't clear screen
|
|
||||||
|
|
||||||
if (dialog_timeout == 0) {
|
|
||||||
last_req_state += BTN_NO; // Timeout is like button no
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
last_req_state += bs;
|
|
||||||
dialog_timeout = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
layoutHome();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t next_cid(void)
|
uint32_t next_cid(void)
|
||||||
{
|
{
|
||||||
// extremely unlikely but hey
|
// extremely unlikely but hey
|
||||||
@ -171,6 +141,18 @@ U2F_ReadBuffer *reader;
|
|||||||
|
|
||||||
void u2fhid_read(char tiny, const U2FHID_FRAME *f)
|
void u2fhid_read(char tiny, const U2FHID_FRAME *f)
|
||||||
{
|
{
|
||||||
|
// Always handle init packets directly
|
||||||
|
if (f->init.cmd == U2FHID_INIT) {
|
||||||
|
u2fhid_init(f);
|
||||||
|
if (tiny && reader && f->cid == cid) {
|
||||||
|
// abort current channel
|
||||||
|
reader->cmd = 0;
|
||||||
|
reader->len = 0;
|
||||||
|
reader->seq = 255;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (tiny) {
|
if (tiny) {
|
||||||
// read continue packet
|
// read continue packet
|
||||||
if (reader == 0 || cid != f->cid) {
|
if (reader == 0 || cid != f->cid) {
|
||||||
@ -178,11 +160,19 @@ void u2fhid_read(char tiny, const U2FHID_FRAME *f)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((f->type & TYPE_INIT) || reader->seq != f->cont.seq) {
|
if ((f->type & TYPE_INIT) && reader->seq == 255) {
|
||||||
u2fhid_init_cmd(f);
|
u2fhid_init_cmd(f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reader->seq != f->cont.seq) {
|
||||||
|
send_u2fhid_error(f->cid, ERR_INVALID_SEQ);
|
||||||
|
reader->cmd = 0;
|
||||||
|
reader->len = 0;
|
||||||
|
reader->seq = 255;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check out of bounds
|
// check out of bounds
|
||||||
if ((reader->buf_ptr - reader->buf) >= (signed) reader->len
|
if ((reader->buf_ptr - reader->buf) >= (signed) reader->len
|
||||||
|| (reader->buf_ptr + sizeof(f->cont.data) - reader->buf) > (signed) sizeof(reader->buf))
|
|| (reader->buf_ptr + sizeof(f->cont.data) - reader->buf) > (signed) sizeof(reader->buf))
|
||||||
@ -204,11 +194,6 @@ void u2fhid_init_cmd(const U2FHID_FRAME *f) {
|
|||||||
memcpy(reader->buf_ptr, f->init.data, sizeof(f->init.data));
|
memcpy(reader->buf_ptr, f->init.data, sizeof(f->init.data));
|
||||||
reader->buf_ptr += sizeof(f->init.data);
|
reader->buf_ptr += sizeof(f->init.data);
|
||||||
cid = f->cid;
|
cid = f->cid;
|
||||||
// Check length isnt bigger than spec max
|
|
||||||
if (reader->len > sizeof(reader->buf)) {
|
|
||||||
reader->len = 0;
|
|
||||||
return send_u2fhid_error(cid, ERR_INVALID_LEN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void u2fhid_read_start(const U2FHID_FRAME *f) {
|
void u2fhid_read_start(const U2FHID_FRAME *f) {
|
||||||
@ -217,13 +202,20 @@ void u2fhid_read_start(const U2FHID_FRAME *f) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast is reserved for init
|
||||||
|
if (f->cid == CID_BROADCAST || f->cid == 0) {
|
||||||
|
send_u2fhid_error(f->cid, ERR_INVALID_CID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((unsigned)MSG_LEN(*f) > sizeof(reader->buf)) {
|
||||||
|
send_u2fhid_error(f->cid, ERR_INVALID_LEN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
reader = &readbuffer;
|
reader = &readbuffer;
|
||||||
u2fhid_init_cmd(f);
|
u2fhid_init_cmd(f);
|
||||||
|
|
||||||
// Broadcast is reserved for init
|
|
||||||
if (f->cid == CID_BROADCAST && reader->cmd != U2FHID_INIT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
usbTiny(1);
|
usbTiny(1);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// Do we need to wait for more data
|
// Do we need to wait for more data
|
||||||
@ -234,8 +226,9 @@ void u2fhid_read_start(const U2FHID_FRAME *f) {
|
|||||||
while (reader->seq == lastseq && reader->cmd == lastcmd) {
|
while (reader->seq == lastseq && reader->cmd == lastcmd) {
|
||||||
if (counter-- == 0) {
|
if (counter-- == 0) {
|
||||||
// timeout
|
// timeout
|
||||||
|
send_u2fhid_error(cid, ERR_MSG_TIMEOUT);
|
||||||
cid = 0;
|
cid = 0;
|
||||||
send_u2fhid_error(f->cid, ERR_MSG_TIMEOUT);
|
reader = 0;
|
||||||
usbTiny(0);
|
usbTiny(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -245,15 +238,15 @@ void u2fhid_read_start(const U2FHID_FRAME *f) {
|
|||||||
|
|
||||||
// We have all the data
|
// We have all the data
|
||||||
switch (reader->cmd) {
|
switch (reader->cmd) {
|
||||||
|
case 0:
|
||||||
|
// message was aborted by init
|
||||||
|
break;
|
||||||
case U2FHID_PING:
|
case U2FHID_PING:
|
||||||
u2fhid_ping(reader->buf, reader->len);
|
u2fhid_ping(reader->buf, reader->len);
|
||||||
break;
|
break;
|
||||||
case U2FHID_MSG:
|
case U2FHID_MSG:
|
||||||
u2fhid_msg((APDU *)reader->buf, reader->len);
|
u2fhid_msg((APDU *)reader->buf, reader->len);
|
||||||
break;
|
break;
|
||||||
case U2FHID_INIT:
|
|
||||||
u2fhid_init((const U2FHID_INIT_REQ *)reader->buf);
|
|
||||||
break;
|
|
||||||
case U2FHID_WINK:
|
case U2FHID_WINK:
|
||||||
u2fhid_wink(reader->buf, reader->len);
|
u2fhid_wink(reader->buf, reader->len);
|
||||||
break;
|
break;
|
||||||
@ -264,6 +257,7 @@ void u2fhid_read_start(const U2FHID_FRAME *f) {
|
|||||||
|
|
||||||
// wait for next commmand/ button press
|
// wait for next commmand/ button press
|
||||||
reader->cmd = 0;
|
reader->cmd = 0;
|
||||||
|
reader->seq = 255;
|
||||||
uint8_t bs = 0;
|
uint8_t bs = 0;
|
||||||
while (dialog_timeout-- && bs == 0 && reader->cmd == 0) {
|
while (dialog_timeout-- && bs == 0 && reader->cmd == 0) {
|
||||||
usbPoll(); // may trigger new request
|
usbPoll(); // may trigger new request
|
||||||
@ -279,6 +273,7 @@ void u2fhid_read_start(const U2FHID_FRAME *f) {
|
|||||||
dialog_timeout = 0;
|
dialog_timeout = 0;
|
||||||
}
|
}
|
||||||
cid = 0;
|
cid = 0;
|
||||||
|
reader = 0;
|
||||||
usbTiny(0);
|
usbTiny(0);
|
||||||
layoutHome();
|
layoutHome();
|
||||||
return;
|
return;
|
||||||
@ -311,20 +306,27 @@ void u2fhid_wink(const uint8_t *buf, uint32_t len)
|
|||||||
queue_u2f_pkt(&f);
|
queue_u2f_pkt(&f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void u2fhid_init(const U2FHID_INIT_REQ *init_req)
|
void u2fhid_init(const U2FHID_FRAME *in)
|
||||||
{
|
{
|
||||||
debugLog(0, "", "u2fhid_init");
|
const U2FHID_INIT_REQ *init_req = (const U2FHID_INIT_REQ *)&in->init.data;
|
||||||
U2FHID_FRAME f;
|
U2FHID_FRAME f;
|
||||||
U2FHID_INIT_RESP *resp = (U2FHID_INIT_RESP *)f.init.data;
|
U2FHID_INIT_RESP *resp = (U2FHID_INIT_RESP *)f.init.data;
|
||||||
|
|
||||||
|
debugLog(0, "", "u2fhid_init");
|
||||||
|
|
||||||
|
if (in->cid == 0) {
|
||||||
|
send_u2fhid_error(in->cid, ERR_INVALID_CID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MEMSET_BZERO(&f, sizeof(f));
|
MEMSET_BZERO(&f, sizeof(f));
|
||||||
f.cid = cid;
|
f.cid = in->cid;
|
||||||
f.init.cmd = U2FHID_INIT;
|
f.init.cmd = U2FHID_INIT;
|
||||||
f.init.bcnth = 0;
|
f.init.bcnth = 0;
|
||||||
f.init.bcntl = U2FHID_INIT_RESP_SIZE;
|
f.init.bcntl = U2FHID_INIT_RESP_SIZE;
|
||||||
|
|
||||||
memcpy(resp->nonce, init_req->nonce, sizeof(init_req->nonce));
|
memcpy(resp->nonce, init_req->nonce, sizeof(init_req->nonce));
|
||||||
resp->cid = cid == CID_BROADCAST ? next_cid() : cid;
|
resp->cid = in->cid == CID_BROADCAST ? next_cid() : in->cid;
|
||||||
resp->versionInterface = U2FHID_IF_VERSION;
|
resp->versionInterface = U2FHID_IF_VERSION;
|
||||||
resp->versionMajor = VERSION_MAJOR;
|
resp->versionMajor = VERSION_MAJOR;
|
||||||
resp->versionMinor = VERSION_MINOR;
|
resp->versionMinor = VERSION_MINOR;
|
||||||
@ -358,8 +360,6 @@ uint8_t *u2f_out_data(void)
|
|||||||
|
|
||||||
void u2fhid_msg(const APDU *a, uint32_t len)
|
void u2fhid_msg(const APDU *a, uint32_t len)
|
||||||
{
|
{
|
||||||
static bool lock = false;
|
|
||||||
|
|
||||||
if ((APDU_LEN(*a) + sizeof(APDU)) > len) {
|
if ((APDU_LEN(*a) + sizeof(APDU)) > len) {
|
||||||
debugLog(0, "", "BAD APDU LENGTH");
|
debugLog(0, "", "BAD APDU LENGTH");
|
||||||
debugInt(APDU_LEN(*a));
|
debugInt(APDU_LEN(*a));
|
||||||
@ -367,12 +367,10 @@ void u2fhid_msg(const APDU *a, uint32_t len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very crude locking, incase another message comes in while we wait. This
|
if (a->cla != 0) {
|
||||||
// actually can probably be removed as no code inside calls usbPoll anymore
|
send_u2f_error(U2F_SW_CLA_NOT_SUPPORTED);
|
||||||
if (lock)
|
return;
|
||||||
return send_u2fhid_error(cid, ERR_CHANNEL_BUSY);
|
}
|
||||||
|
|
||||||
lock = true;
|
|
||||||
|
|
||||||
switch (a->ins) {
|
switch (a->ins) {
|
||||||
case U2F_REGISTER:
|
case U2F_REGISTER:
|
||||||
@ -388,10 +386,6 @@ void u2fhid_msg(const APDU *a, uint32_t len)
|
|||||||
debugLog(0, "", "u2f unknown cmd");
|
debugLog(0, "", "u2f unknown cmd");
|
||||||
send_u2f_error(U2F_SW_INS_NOT_SUPPORTED);
|
send_u2f_error(U2F_SW_INS_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock = false;
|
|
||||||
|
|
||||||
//LayoutHomeAfterTimeout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_u2fhid_msg(const uint8_t cmd, const uint8_t *data, const uint32_t len)
|
void send_u2fhid_msg(const uint8_t cmd, const uint8_t *data, const uint32_t len)
|
||||||
@ -447,10 +441,15 @@ void send_u2fhid_error(uint32_t fcid, uint8_t err)
|
|||||||
|
|
||||||
void u2f_version(const APDU *a)
|
void u2f_version(const APDU *a)
|
||||||
{
|
{
|
||||||
|
if (APDU_LEN(*a) != 0) {
|
||||||
|
debugLog(0, "", "u2f version - badlen");
|
||||||
|
send_u2f_error(U2F_SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// INCLUDES SW_NO_ERROR
|
// INCLUDES SW_NO_ERROR
|
||||||
static const uint8_t version_response[] = {'U', '2', 'F', '_',
|
static const uint8_t version_response[] = {'U', '2', 'F', '_',
|
||||||
'V', '2', 0x90, 0x00};
|
'V', '2', 0x90, 0x00};
|
||||||
(void)a;
|
|
||||||
debugLog(0, "", "u2f version");
|
debugLog(0, "", "u2f version");
|
||||||
send_u2f_msg(version_response, sizeof(version_response));
|
send_u2f_msg(version_response, sizeof(version_response));
|
||||||
}
|
}
|
||||||
@ -553,7 +552,7 @@ void u2f_register(const APDU *a)
|
|||||||
debugLog(0, "", "u2f register");
|
debugLog(0, "", "u2f register");
|
||||||
if (APDU_LEN(*a) != sizeof(U2F_REGISTER_REQ)) {
|
if (APDU_LEN(*a) != sizeof(U2F_REGISTER_REQ)) {
|
||||||
debugLog(0, "", "u2f register - badlen");
|
debugLog(0, "", "u2f register - badlen");
|
||||||
send_u2f_error(U2F_SW_WRONG_DATA);
|
send_u2f_error(U2F_SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +570,7 @@ void u2f_register(const APDU *a)
|
|||||||
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
||||||
buttonUpdate(); // Clear button state
|
buttonUpdate(); // Clear button state
|
||||||
layoutU2FDialog("Register", getReadableAppId(req->appId));
|
layoutU2FDialog("Register", getReadableAppId(req->appId));
|
||||||
dialog_timeout = U2F_TIMEOUT;
|
dialog_timeout = 10*U2F_TIMEOUT;
|
||||||
last_req_state = REG;
|
last_req_state = REG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -580,7 +579,7 @@ void u2f_register(const APDU *a)
|
|||||||
if (last_req_state == REG) {
|
if (last_req_state == REG) {
|
||||||
// error: testof-user-presence is required
|
// error: testof-user-presence is required
|
||||||
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
||||||
dialog_timeout = U2F_TIMEOUT;
|
dialog_timeout = 10*U2F_TIMEOUT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,6 +639,7 @@ void u2f_register(const APDU *a)
|
|||||||
1 /* keyhandleLen */ + resp->keyHandleLen +
|
1 /* keyhandleLen */ + resp->keyHandleLen +
|
||||||
sizeof(U2F_ATT_CERT) + sig_len + 2;
|
sizeof(U2F_ATT_CERT) + sig_len + 2;
|
||||||
|
|
||||||
|
last_req_state = INIT;
|
||||||
send_u2f_msg(data, l);
|
send_u2f_msg(data, l);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -655,7 +655,7 @@ void u2f_authenticate(const APDU *a)
|
|||||||
|
|
||||||
if (APDU_LEN(*a) < 64) { /// FIXME: decent value
|
if (APDU_LEN(*a) < 64) { /// FIXME: decent value
|
||||||
debugLog(0, "", "u2f authenticate - badlen");
|
debugLog(0, "", "u2f authenticate - badlen");
|
||||||
send_u2f_error(U2F_SW_WRONG_DATA);
|
send_u2f_error(U2F_SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,19 +699,16 @@ void u2f_authenticate(const APDU *a)
|
|||||||
|
|
||||||
if (last_req_state == INIT) {
|
if (last_req_state == INIT) {
|
||||||
// error: testof-user-presence is required
|
// error: testof-user-presence is required
|
||||||
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
|
||||||
buttonUpdate(); // Clear button state
|
buttonUpdate(); // Clear button state
|
||||||
layoutU2FDialog("Authenticate", getReadableAppId(req->appId));
|
layoutU2FDialog("Authenticate", getReadableAppId(req->appId));
|
||||||
dialog_timeout = U2F_TIMEOUT;
|
|
||||||
last_req_state = AUTH;
|
last_req_state = AUTH;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Awaiting Keypress
|
// Awaiting Keypress
|
||||||
if (last_req_state == AUTH) {
|
if (last_req_state == AUTH) {
|
||||||
// error: testof-user-presence is required
|
// error: testof-user-presence is required
|
||||||
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
|
||||||
dialog_timeout = U2F_TIMEOUT;
|
dialog_timeout = 10*U2F_TIMEOUT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,10 +750,10 @@ void u2f_authenticate(const APDU *a)
|
|||||||
memcpy(buf + sizeof(U2F_AUTHENTICATE_RESP) -
|
memcpy(buf + sizeof(U2F_AUTHENTICATE_RESP) -
|
||||||
U2F_MAX_EC_SIG_SIZE + sig_len,
|
U2F_MAX_EC_SIG_SIZE + sig_len,
|
||||||
"\x90\x00", 2);
|
"\x90\x00", 2);
|
||||||
|
last_req_state = INIT;
|
||||||
send_u2f_msg(buf, sizeof(U2F_AUTHENTICATE_RESP) -
|
send_u2f_msg(buf, sizeof(U2F_AUTHENTICATE_RESP) -
|
||||||
U2F_MAX_EC_SIG_SIZE + sig_len +
|
U2F_MAX_EC_SIG_SIZE + sig_len +
|
||||||
2);
|
2);
|
||||||
last_req_state = INIT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ void u2fhid_read(char tiny, const U2FHID_FRAME *buf);
|
|||||||
void u2fhid_init_cmd(const U2FHID_FRAME *f);
|
void u2fhid_init_cmd(const U2FHID_FRAME *f);
|
||||||
void u2fhid_read_start(const U2FHID_FRAME *f);
|
void u2fhid_read_start(const U2FHID_FRAME *f);
|
||||||
bool u2fhid_write(uint8_t *buf);
|
bool u2fhid_write(uint8_t *buf);
|
||||||
void u2fhid_init(const U2FHID_INIT_REQ *init_req);
|
void u2fhid_init(const U2FHID_FRAME *in);
|
||||||
void u2fhid_ping(const uint8_t *buf, uint32_t len);
|
void u2fhid_ping(const uint8_t *buf, uint32_t len);
|
||||||
void u2fhid_wink(const uint8_t *buf, uint32_t len);
|
void u2fhid_wink(const uint8_t *buf, uint32_t len);
|
||||||
void u2fhid_sync(const uint8_t *buf, uint32_t len);
|
void u2fhid_sync(const uint8_t *buf, uint32_t len);
|
||||||
|
@ -129,8 +129,10 @@ extern "C"
|
|||||||
// Command status responses
|
// Command status responses
|
||||||
|
|
||||||
#define U2F_SW_NO_ERROR 0x9000 // SW_NO_ERROR
|
#define U2F_SW_NO_ERROR 0x9000 // SW_NO_ERROR
|
||||||
#define U2F_SW_WRONG_DATA 0x6984 // SW_WRONG_DATA
|
#define U2F_SW_WRONG_LENGTH 0x6700 // SW_WRONG_LENGTH
|
||||||
|
#define U2F_SW_DATA_INVALID 0x6984 // SW_WRONG_DATA
|
||||||
#define U2F_SW_CONDITIONS_NOT_SATISFIED 0x6985 // SW_CONDITIONS_NOT_SATISFIED
|
#define U2F_SW_CONDITIONS_NOT_SATISFIED 0x6985 // SW_CONDITIONS_NOT_SATISFIED
|
||||||
|
#define U2F_SW_WRONG_DATA 0x6a80 // SW_WRONG_DATA
|
||||||
#define U2F_SW_INS_NOT_SUPPORTED 0x6d00 // SW_INS_NOT_SUPPORTED
|
#define U2F_SW_INS_NOT_SUPPORTED 0x6d00 // SW_INS_NOT_SUPPORTED
|
||||||
#define U2F_SW_CLA_NOT_SUPPORTED 0x6e00 // SW_CLA_NOT_SUPPORTED
|
#define U2F_SW_CLA_NOT_SUPPORTED 0x6e00 // SW_CLA_NOT_SUPPORTED
|
||||||
|
|
||||||
|
@ -165,14 +165,14 @@ static const struct usb_endpoint_descriptor hid_endpoints_u2f[2] = {{
|
|||||||
.bEndpointAddress = ENDPOINT_ADDRESS_U2F_IN,
|
.bEndpointAddress = ENDPOINT_ADDRESS_U2F_IN,
|
||||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||||
.wMaxPacketSize = 64,
|
.wMaxPacketSize = 64,
|
||||||
.bInterval = 1,
|
.bInterval = 2,
|
||||||
}, {
|
}, {
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = ENDPOINT_ADDRESS_U2F_OUT,
|
.bEndpointAddress = ENDPOINT_ADDRESS_U2F_OUT,
|
||||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||||
.wMaxPacketSize = 64,
|
.wMaxPacketSize = 64,
|
||||||
.bInterval = 1,
|
.bInterval = 2,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static const struct usb_interface_descriptor hid_iface_u2f[] = {{
|
static const struct usb_interface_descriptor hid_iface_u2f[] = {{
|
||||||
|
Loading…
Reference in New Issue
Block a user