kopia lustrzana https://github.com/conorpp/u2f-zero
Merge pull request #63 from conorpp/fix_multiple_keyhandle_bug
Fix multiple keyhandle bugpull/70/head
commit
255c520e01
|
@ -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[];
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
# silabs utility debugger debugger id C2
|
||||
FlashUtilCL.exe FLASHEraseUSB "$1" 1
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Ładowanie…
Reference in New Issue