Merge pull request #63 from conorpp/fix_multiple_keyhandle_bug

Fix multiple keyhandle bug
pull/70/head
Conor Patrick 2017-11-06 13:03:50 -05:00 zatwierdzone przez GitHub
commit 255c520e01
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
15 zmienionych plików z 118 dodań i 90 usunięć

Wyświetl plik

@ -44,6 +44,9 @@
#define U2F_SUPPORT_RNG_CUSTOM
#define U2F_SUPPORT_SEED_CUSTOM
// comment out this if using bootloader
//#define U2F_USING_BOOTLOADER
// Uncomment this to make configuration firmware
//#define ATECC_SETUP_DEVICE
@ -129,8 +132,6 @@ struct config_msg
uint8_t buf[HID_PACKET_SIZE-1];
};
extern uint8_t hidmsgbuf[64];
extern data struct APP_DATA appdata;
extern code uint8_t WMASK[];

Wyświetl plik

@ -38,7 +38,9 @@
#define U2F_APDU_SIZE 7
#define U2F_CHALLENGE_SIZE 32
#define U2F_APPLICATION_SIZE 32
#define U2F_KEY_HANDLE_SIZE 36
#define U2F_KEY_HANDLE_ID_SIZE 8
#define U2F_KEY_HANDLE_KEY_SIZE 36
#define U2F_KEY_HANDLE_SIZE (U2F_KEY_HANDLE_KEY_SIZE+U2F_KEY_HANDLE_ID_SIZE)
#define U2F_REGISTER_REQUEST_SIZE (U2F_CHALLENGE_SIZE+U2F_APPLICATION_SIZE)
#define U2F_MAX_REQUEST_PAYLOAD (1 + U2F_CHALLENGE_SIZE+U2F_APPLICATION_SIZE + 1 + U2F_KEY_HANDLE_SIZE)

Wyświetl plik

@ -87,6 +87,7 @@ int8_t atecc_recv(uint8_t * buf, uint8_t buflen, struct atecc_response* res)
if (SMB_FLAGS & SMB_READ_TRUNC)
{
set_app_error(ERROR_READ_TRUNCATED);
return -1;
}
if (pkt_len <= buflen && pkt_len >= 4)

Wyświetl plik

@ -78,6 +78,7 @@ uint8_t custom_command(struct u2f_hid_msg * msg)
break;
#endif
#ifdef U2F_USING_BOOTLOADER
case U2F_CONFIG_BOOTLOADER:
atecc_send_recv(ATECC_CMD_READ,
@ -101,6 +102,7 @@ uint8_t custom_command(struct u2f_hid_msg * msg)
appdata.tmp, sizeof(appdata.tmp), &res);
break;
#endif
default:
return 0;
}

Wyświetl plik

@ -141,8 +141,6 @@ int16_t main(void) {
uint16_t ms_grad;
uint8_t winks = 0, light = 1, grad_dir = 0;
int8_t grad_inc = 0;
int8_t ii;
uint16_t i;
data uint8_t xdata * clear = 0;
enter_DefaultMode_from_RESET();
@ -158,12 +156,14 @@ int16_t main(void) {
IE_EA = 1;
watchdog();
u2f_prints("U2F ZERO\r\n");
if (RSTSRC & RSTSRC_WDTRSF__SET)
{
error = ERROR_DAMN_WATCHDOG;
//error = ERROR_DAMN_WATCHDOG;
u2f_prints("r");
}
u2f_prints("U2F ZERO\r\n");
run_tests();
@ -259,9 +259,9 @@ int16_t main(void) {
{
u2f_printx("error: ", 1, (uint16_t)error);
#ifdef U2F_BLINK_ERRORS
for (ii=0; ii < 8; ii++)
for (ms_grad=0; ms_grad < 8; ms_grad++)
{
if (error & (1<<ii))
if (error & (1<<ms_grad))
{
rgb_hex(U2F_DEFAULT_COLOR_INPUT_SUCCESS);
}
@ -277,17 +277,16 @@ int16_t main(void) {
#else
rgb_hex(U2F_DEFAULT_COLOR_ERROR);
// wipe ram
for (i=0; i<0x400;i++)
for (ms_grad=0; ms_grad<0x400;ms_grad++)
{
*(clear++) = 0x0;
watchdog();
}
#endif
error = 0;
while(!ms_since(ms_heart,500))
{
watchdog();
}
// wait for watchdog to reset
while(1)
;
}

Wyświetl plik

@ -146,7 +146,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
if (control == U2F_AUTHENTICATE_CHECK)
{
u2f_hid_set_len(2);
if (u2f_load_key(req->kh) == 0 )//&& u2f_appid_eq(req->kh, req->app) == 0)
if (u2f_appid_eq(req->kh, req->app) == 0)
{
return U2F_SW_CONDITIONS_NOT_SATISFIED;
}
@ -155,12 +155,13 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
return U2F_SW_WRONG_DATA;
}
}
if (
if (
control != U2F_AUTHENTICATE_SIGN ||
req->khl != U2F_KEY_HANDLE_SIZE ||
u2f_load_key(req->kh, req->app) != 0 //||
//u2f_appid_eq(req->kh, req->app) != 0
)
u2f_appid_eq(req->kh, req->app) != 0 || // Order of checks is important
u2f_load_key(req->kh, req->app) != 0
)
{
u2f_hid_set_len(2);
return U2F_SW_WRONG_PAYLOAD;

Wyświetl plik

@ -30,6 +30,8 @@
*/
#include "app.h"
#undef U2F_DISABLE
#ifndef U2F_DISABLE
#include "bsp.h"
#include "u2f.h"
@ -38,6 +40,7 @@
#include "atecc508a.h"
static void gen_u2f_zero_tag(uint8_t * dst, uint8_t * appid, uint8_t * handle);
static struct u2f_hid_msg res;
static uint8_t* resbuf = (uint8_t*)&res;
@ -233,7 +236,6 @@ int8_t u2f_ecdsa_sign(uint8_t * dest, uint8_t * handle, uint8_t * appid)
}
// bad if this gets interrupted
int8_t u2f_new_keypair(uint8_t * handle, uint8_t * appid, uint8_t * pubkey)
{
@ -270,7 +272,7 @@ int8_t u2f_new_keypair(uint8_t * handle, uint8_t * appid, uint8_t * pubkey)
}
watchdog();
compute_key_hash(private_key, WMASK);
memmove(handle+4, res_digest.buf, 32); // size of key handle must be 36
memmove(handle+4, res_digest.buf, 32); // size of key handle must be 36+8
if ( atecc_privwrite(U2F_TEMP_KEY_SLOT, private_key, WMASK, handle+4) != 0)
@ -289,15 +291,18 @@ int8_t u2f_new_keypair(uint8_t * handle, uint8_t * appid, uint8_t * pubkey)
memmove(pubkey, res.buf, 64);
// the + 8
gen_u2f_zero_tag(handle + U2F_KEY_HANDLE_KEY_SIZE, appid, handle);
return 0;
}
int8_t u2f_load_key(uint8_t * handle, uint8_t * appid)
{
struct atecc_response res;
uint8_t private_key[36];
int i;
watchdog();
SHA_HMAC_KEY = U2F_MASTER_KEY_SLOT;
SHA_FLAGS = ATECC_SHA_HMACSTART;
u2f_sha256_start();
@ -312,34 +317,30 @@ int8_t u2f_load_key(uint8_t * handle, uint8_t * appid)
{
private_key[i] ^= RMASK[i];
}
return atecc_privwrite(U2F_TEMP_KEY_SLOT, private_key, WMASK, handle+4);
}
static void gen_u2f_zero_tag(uint8_t * dst, uint8_t * appid, uint8_t * handle)
{
const char * u2f_zero_const = "\xc1\xff\x67\x0d\x66\xe5\x55\xbb\xdc\x56\xaf\x7b\x41\x27\x4a\x21";
SHA_HMAC_KEY = U2F_MASTER_KEY_SLOT;
SHA_FLAGS = ATECC_SHA_HMACSTART;
u2f_sha256_start();
u2f_sha256_update(handle,U2F_KEY_HANDLE_KEY_SIZE);
u2f_sha256_update(u2f_zero_const,16);
u2f_sha256_update(appid,32);
SHA_FLAGS = ATECC_SHA_HMACEND;
u2f_sha256_finish();
if (dst) memmove(dst, res_digest.buf, U2F_KEY_HANDLE_ID_SIZE);
}
int8_t u2f_appid_eq(uint8_t * handle, uint8_t * appid)
{
// struct atecc_response res;
// uint8_t private_key[36];
// int i;
//
// SHA_HMAC_KEY = U2F_MASTER_KEY_SLOT;
// SHA_FLAGS = ATECC_SHA_HMACSTART;
// u2f_sha256_start();
// u2f_sha256_update(appid,32);
// SHA_FLAGS = ATECC_SHA_HMACEND;
// u2f_sha256_finish();
//
// memset(private_key,0,4);
// memmove(private_key+4, res_digest.buf, 32);
//
// for (i=4; i<36; i++)
// {
// private_key[i] ^= RMASK[i];
// }
//
// compute_key_hash(private_key, WMASK);
// return memcmp(handle, res_digest.buf, U2F_KEY_HANDLE_SIZE);
return 0;
gen_u2f_zero_tag(NULL,appid, handle);
return memcmp(handle+U2F_KEY_HANDLE_KEY_SIZE, res_digest.buf, U2F_KEY_HANDLE_ID_SIZE);
}
uint32_t u2f_count()

Wyświetl plik

@ -77,7 +77,7 @@ static struct hid_layer_param
// total length of response in bytes
uint16_t res_len;
#define BUFFER_SIZE 270
#define BUFFER_SIZE (270)
uint8_t buffer[BUFFER_SIZE];
} hid_layer;
@ -87,7 +87,7 @@ uint32_t _hid_lockt = 0;
uint32_t _hid_lock_cid = 0;
#endif
static struct CID CIDS[5];
static struct CID CIDS[4];
static uint8_t CID_NUM = 0;
@ -149,7 +149,6 @@ void u2f_hid_writeback(uint8_t * payload, uint16_t len)
do
{
if (_hid_offset == 0)
{
r->cid = hid_layer.current_cid;
@ -354,24 +353,19 @@ static uint8_t hid_u2f_parse(struct u2f_hid_msg* req)
break;
case U2FHID_MSG:
if (U2FHID_LEN(req) < 4)
{
stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
goto fail;
}
// buffer 2 payloads (120 bytes) to get full U2F message
// assuming key handle is < 45 bytes
// 7 bytes for apdu header
// 7 + 66 bytes + key handle for authenticate message
// 7 + 64 for register message
if (hid_layer.bytes_buffered == 0)
{
if (U2FHID_LEN(req) < 4)
{
stamp_error(hid_layer.current_cid, ERR_INVALID_LEN);
goto fail;
}
start_buffering(req);
if (hid_layer.bytes_buffered >= U2FHID_LEN(req))
{
u2f_request((struct u2f_request_apdu *)hid_layer.buffer);
}
}
else
{
@ -380,6 +374,7 @@ static uint8_t hid_u2f_parse(struct u2f_hid_msg* req)
{
u2f_request((struct u2f_request_apdu *)hid_layer.buffer);
}
}
@ -466,7 +461,7 @@ static uint8_t hid_u2f_parse(struct u2f_hid_msg* req)
break;
#endif
default:
set_app_error(ERROR_HID_INVALID_CMD);
//set_app_error(ERROR_HID_INVALID_CMD);
stamp_error(hid_layer.current_cid, ERR_INVALID_CMD);
u2f_printb("invalid cmd: ",1,hid_layer.current_cmd);
}
@ -501,13 +496,13 @@ void u2f_hid_request(struct u2f_hid_msg* req)
struct CID* cid = NULL;
cid = get_cid(req->cid);
// Error checking
if ((U2FHID_IS_INIT(req->pkt.init.cmd)))
{
if (U2FHID_LEN(req) > 7609)
{
stamp_error(req->cid, ERR_INVALID_LEN);
return;
}
if (req->pkt.init.cmd != U2FHID_INIT && req->cid != hid_layer.current_cid && u2f_hid_busy())
@ -522,6 +517,7 @@ void u2f_hid_request(struct u2f_hid_msg* req)
return;
}
if (!req->cid)
{
stamp_error(req->cid, ERR_SYNC_FAIL);

Wyświetl plik

@ -1,3 +0,0 @@
#!/bin/bash
# silabs utility debugger debugger id C2
FlashUtilCL.exe FLASHEraseUSB "$1" 1

Wyświetl plik

@ -1,4 +1,25 @@
#!/bin/bash
# silabs utility debugger file debugger id power C2
FlashUtilCL.exe DownloadUSB -R $1 "$2" 0 1
ret=$(curl --request POST http://127.0.0.1:4040/ --data "port=$2" --data "firmware=$(cat "$1")")
if [[ $ret != *"Success"* ]]
then
exit 1
fi
exit 0
#export FW=$2
#PORT=$1 python - <<END
#import requests, sys, os
#url = 'http://127.0.0.1:4040/'
#payload = {'port': os.environ['PORT'], 'firmware': open(os.environ['FW'], 'r').read()}
#print requests.post(url, data = payload)
#END

Wyświetl plik

@ -5,7 +5,7 @@
openssl req -new -key "$1" -out "$1".csr
# CA sign the request
openssl x509 -req -in "$1".csr -CA "$2" -CAkey "$3" -out "$4" -set_serial 0
openssl x509 -days 1825 -req -in "$1".csr -CA "$2" -CAkey "$3" -out "$4" -set_serial 0
openssl x509 -in "$4" -outform der -out "$4".der

Wyświetl plik

@ -10,7 +10,7 @@ openssl ecparam -genkey -name "$curve" -out "$keyname"
# generate a "signing request"
openssl req -new -key "$keyname" -out "$keyname".csr
# self sign the request
openssl x509 -req -in "$keyname".csr -signkey "$keyname" -out "$certname"
openssl x509 -req -days 1825 -in "$keyname".csr -signkey "$keyname" -out "$certname"
# convert to smaller size format DER
openssl x509 -in $certname -outform der -out $smallcertname

Wyświetl plik

@ -4,12 +4,14 @@
export PATH=$PATH:`pwd`/flashing:../../../u2f_zero_client:../../../gencert
export attest_priv=gencert/ca/key.pem
export attest_pub=gencert/ca/cert.der
export attest_pub=gencert/ca/attest.der
adapters[0]=0
num_adapters=0
adapters[1]=COM3
adapters[2]=COM4
num_adapters=2
firmware=../firmware
export setup=setup_device.sh
export starting_SN=CAFEBABE00000000
export starting_SN=DAFE1E340AB70000
setup_SNs=(0 CAFEBABEFFFFFFF0 CAFEBABEFFFFFFF1 CAFEBABEFFFFFFF2)
if [[ -n "$1" ]] ; then
@ -57,17 +59,17 @@ function start_programming {
}
for i in `seq 1 100` ; do
#for i in `seq 1 100` ; do
adapters[$i]=$(FlashUtilCL.exe DeviceSN $i)
#adapters[$i]=$(FlashUtilCL.exe DeviceSN $i)
if [[ ${adapters[$i]} = *"out of range"* ]]
then
break
fi
#if [[ ${adapters[$i]} = *"out of range"* ]]
#then
#break
#fi
num_adapters=$(($num_adapters + 1))
done
#num_adapters=$(($num_adapters + 1))
#done
export num_adapters=$num_adapters
export adapters=$adapters

Wyświetl plik

@ -32,19 +32,17 @@ if [[ $FLASH_TOOLS = 1 ]]
then
# setup atecc
echo "erasing..."
erase.sh $SN
while [[ "$?" -ne "0" ]] ; do
echo "$SN is retrying erase ... "
sleep 0.2
erase.sh $SN
done
#echo "erasing..."
#erase.sh $SN
echo "programming setup..."
program.sh $SETUP_HEX $SN
[[ "$?" -ne "0" ]] && exit 1
while [[ "$?" -ne "0" ]] ; do
echo "$SN is retrying program... "
sleep 0.2
program.sh $SETUP_HEX $SN
done
fi

Wyświetl plik

@ -52,6 +52,9 @@ import logging as log
import json
import traceback
import argparse
import binascii
from u2flib_server.utils import websafe_encode, websafe_decode
def get_origin(environ):
@ -126,6 +129,10 @@ class U2FServer(object):
user = self.users[username]
enroll = user.pop('_u2f_enroll_')
device, cert = complete_registration(enroll, data, [self.facet])
print
print 'device, ' , device
print 'key handle', binascii.hexlify(websafe_decode(device['keyHandle']))
print
user.setdefault('_u2f_devices_', []).append(device.json)
log.info("U2F device enrolled. Username: %s", username)