Skip to content

Commit

Permalink
Merge branch 'pr_6'
Browse files Browse the repository at this point in the history
Fix ping issue
conorpp#67

Closes #6
Closes #7
  • Loading branch information
szszszsz committed Jul 6, 2018
2 parents f2f9272 + 4dcac39 commit aaa2b43
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 21 deletions.
10 changes: 10 additions & 0 deletions firmware/inc/u2f_hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ struct u2f_hid_init_response
uint8_t cflags;
};

struct CID
{
uint32_t cid;
uint32_t last_used;
uint8_t busy;
uint8_t last_cmd;
};

typedef enum
{
U2FHID_REPLY=0,
Expand Down Expand Up @@ -137,6 +145,8 @@ void u2f_hid_flush();
// @param req the U2F HID message
void u2f_hid_request(struct u2f_hid_msg* req);

struct CID* get_cid(uint32_t cid);

// app_wink blink a light on the platform
// must be implemented elsewhere for specific platform used
// @color optional hex color
Expand Down
20 changes: 14 additions & 6 deletions firmware/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,21 @@ int16_t main(void) {
case APP_NOTHING: {}break; // Idle state:

case APP_HID_MSG: { // HID msg received, pass to protocols:
uint8_t msg_is_hid_req;

msg_is_hid_req = !custom_command(hid_msg); // Parse at first as a custom cmd: Custom cmd processing
if (msg_is_hid_req) { // It isnt a custom cmd, so must be a HID request
u2f_hid_request(hid_msg); // HID msg processing
#ifndef ATECC_SETUP_DEVICE
struct CID* cid = NULL;
cid = get_cid(hid_msg->cid);
if (!cid->busy) { // There is no ongoing U2FHID transfer
if (!custom_command(hid_msg)) {
u2f_hid_request(hid_msg);
}
} else {
u2f_hid_request(hid_msg);
}

#else
if (!custom_command(hid_msg)) {
u2f_hid_request(hid_msg);
}
#endif
if (state == APP_HID_MSG) { // The USB msg doesnt ask a special app state
state = APP_NOTHING; // We can go back to idle
}
Expand Down
10 changes: 1 addition & 9 deletions firmware/src/u2f_hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@ typedef enum
HID_READY,
} HID_STATE;

struct CID
{
uint32_t cid;
uint32_t last_used;
uint8_t busy;
uint8_t last_cmd;
};

static struct hid_layer_param
{
HID_STATE state;
Expand Down Expand Up @@ -232,7 +224,7 @@ static int8_t add_new_cid(uint32_t cid)
return -1;
}

static struct CID* get_cid(uint32_t cid)
struct CID* get_cid(uint32_t cid)
{
uint8_t i;
for(i = 0; i < CID_MAX; i++)
Expand Down
108 changes: 102 additions & 6 deletions tools/u2f_zero_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
sys.exit(1)



cmd_prefix = [0, 0xff,0xff,0xff,0xff]
cid_broadcast = [0xFF, 0xFF, 0xFF, 0xFF]
cmd_prefix = [0] + cid_broadcast

class commands:
U2F_CONFIG_GET_SERIAL_NUM = 0x80
Expand All @@ -72,14 +72,17 @@ class commands:
U2F_CUSTOM_SEED = 0x22
U2F_CUSTOM_WIPE = 0x23
U2F_CUSTOM_WINK = 0x24

U2F_HID_INIT = 0x86
U2F_HID_PING = 0x81


if len(sys.argv) not in [2,3,4,5,6]:
print('usage: %s <action> [<arguments>] [-s serial-number]' % sys.argv[0])
print('actions: ')
print(""" configure <ecc-private-key> <output-file> [--reuse-keys]: setup the device configuration. Specify ECC P-256 private
key for token attestation. Specify temporary output file for
generated keys. Reuses r/w keys if --reuse-keys is specified.""")
print(""" configure <ecc-private-key> <output-file> [--reuse-keys]: setup the device configuration.
Specify ECC P-256 private key for token attestation. Specify temporary output file for generated
keys. Reuses r/w keys if --reuse-keys is specified.""")
print(' rng: Continuously dump random numbers from the devices hardware RNG.')
print(' seed: update the hardware RNG seed with input from stdin')
print(' wipe: wipe all registered keys on U2F Zero. Must also press button 5 times. Not reversible.')
Expand Down Expand Up @@ -352,7 +355,97 @@ def do_wink(h):
cmd = cmd_prefix + [ commands.U2F_CUSTOM_WINK, 0,0]
h.write(cmd)


def u2fhid_init(h):
nonce = [random.randint(0, 0xFF) for i in xrange(0, 8)]
cmd = cid_broadcast + [commands.U2F_HID_INIT, 0, 8] + nonce
h.write([0] + cmd)
ans = h.read(19, 1000)
return ans[15:19]

def get_response_packet_payload(cmd_seq): # Reads an U2FHID packet, checks it's command/sequence field by the given parameter, returns the payload
ans = h.read(64, 200)
if len(ans) == 0: # Read timeout
return[]
else: # Read success
print('pkt recvd(%i):' % ans[4])
print(" ".join('%03d'%x for x in ans))
if ans[4] == cmd_seq: # Error check: OK
if cmd_seq >= 128: # Initialization packet
return ans[7:] # Payload
else: # Sequence packet
return ans[5:] # Payload
die('ERR: cmd/seq field in received packet is %i instead of %i' % (ans[4], cmd_seq)) # Error check: ERR (1st byte of payload is the error code in case of a command packet)


def do_ping(h, num):
# Init (set U2F HID channel address)
cid = u2fhid_init(h)

# Prepare ping data
dlen = int(num)
data = [random.randint(1, 0xFF) for i in xrange(0, dlen)] # Ping data: random bytes, except 0
data_req = data

# Send initialization packet of request message
cmd = cid + [ commands.U2F_HID_PING, int((dlen & 0xFF00) >> 8), int(dlen & 0x00FF)] + data[0:57] # Send ping command
h.write([0] + cmd)
print('init. pkt sent(%i):' % cmd[4])
print(" ".join('%03d'%x for x in cmd))

# Request/Response transfer in case of one packet composed message
data_resp = []
if dlen < 58: # Message fits into one packet, no continuation packets will be sent
data_resp = get_response_packet_payload(commands.U2F_HID_PING)

# Request/Response transfer in case of a multiple packet composed message
else: # Message doesnt fit into one packet
seq_tx = 0
seq_rx = commands.U2F_HID_PING
data = data[57:]
resp_dlen = 0
while len(data) > 0: # Send remaining data of request message in continuation packets
cmd = cid + [seq_tx] + data[:64 - 5]
h.write([0] + cmd)
data = data[64 - 5:]
print('cont. pkt sent(%i):' % seq_tx)
print(" ".join('%03d'%x for x in cmd))
seq_tx += 1

ans = get_response_packet_payload(seq_rx) # Collect response message packets in the meantime to avoid input buffer ovf
if len(ans):
if seq_rx == commands.U2F_HID_PING:
seq_rx = 0
else:
seq_rx += 1
data_resp += ans
print('Collecting remaining data...')
while True: # Collect remaining response message packets after the total request message has been sent
ans = get_response_packet_payload(seq_rx)
if len(ans):
if seq_rx == commands.U2F_HID_PING:
seq_rx = 0
else:
seq_rx += 1
data_resp += ans
else:
break;
resp_dlen = len(data_resp)

# Adjust ping data: remove padding zeros from the end
for i in reversed(range(resp_dlen)):
if data_resp[i] == 0:
data_resp.pop(i)
else:
break

# Check ping data (compare sent/received message payloads)
# cut response to compare only sent data
data_resp = data_resp[:len(data_req)]
if data_req == data_resp:
print('Ping OK')
else:
print('Ping ERR')
print('{} {}'.format(len(data_req), len(data_resp)))


if __name__ == '__main__':
Expand Down Expand Up @@ -392,6 +485,9 @@ def do_wink(h):
elif action == 'bootloader-destroy':
h = open_u2f(SN)
bootloader_destroy(h)
elif action == 'ping':
h = open_u2f(SN)
do_ping(h, sys.argv[2])
else:
print( 'error: invalid action: ', action)
sys.exit(1)
Expand Down

0 comments on commit aaa2b43

Please sign in to comment.