identify key handle by 8 byte hmac addition

pull/63/head
Conor Patrick 2017-11-04 20:18:12 -04:00
rodzic c3bb8ce57e
commit aafd0539be
11 zmienionych plików z 109 dodań i 84 usunięć

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

@ -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();
@ -162,7 +160,7 @@ int16_t main(void) {
if (RSTSRC & RSTSRC_WDTRSF__SET)
{
error = ERROR_DAMN_WATCHDOG;
//error = ERROR_DAMN_WATCHDOG;
}
run_tests();
@ -259,9 +257,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 +275,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);
static struct u2f_hid_msg res;
static uint8_t* resbuf = (uint8_t*)&res;
@ -152,14 +155,14 @@ static int atecc_prep_encryption()
appdata.tmp, 32,
appdata.tmp, 40, &res) != 0 )
{
u2f_prints("pass through to tempkey failed\r\n");
// u2f_prints("pass through to tempkey failed\r\n");
return -1;
}
if( atecc_send_recv(ATECC_CMD_GENDIG,
ATECC_RW_DATA, U2F_MASTER_KEY_SLOT, NULL, 0,
appdata.tmp, 40, &res) != 0)
{
u2f_prints("GENDIG failed\r\n");
// u2f_prints("GENDIG failed\r\n");
return -1;
}
@ -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)
{
@ -242,6 +244,8 @@ int8_t u2f_new_keypair(uint8_t * handle, uint8_t * appid, uint8_t * pubkey)
int i;
watchdog();
// u2f_prints("new key appid,khandle\r\n");
// dump_hex(appid,32);
if (atecc_send_recv(ATECC_CMD_RNG,ATECC_RNG_P1,ATECC_RNG_P2,
NULL, 0,
@ -270,7 +274,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 +293,21 @@ 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);
//dump_hex(handle,U2F_KEY_HANDLE_SIZE);
return 0;
}
int8_t u2f_load_key(uint8_t * handle, uint8_t * appid)
{
struct atecc_response res;
uint8_t private_key[36];
int i;
// u2f_prints("load key appid,rnum\r\n");
// dump_hex(appid,32);
// dump_hex(handle,4);
SHA_HMAC_KEY = U2F_MASTER_KEY_SLOT;
SHA_FLAGS = ATECC_SHA_HMACSTART;
u2f_sha256_start();
@ -316,30 +326,24 @@ int8_t u2f_load_key(uint8_t * handle, uint8_t * appid)
return atecc_privwrite(U2F_TEMP_KEY_SLOT, private_key, WMASK, handle+4);
}
static void gen_u2f_zero_tag(uint8_t * dst, uint8_t * appid)
{
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(appid,32);
u2f_sha256_update(u2f_zero_const,16);
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);
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 - 70)
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);
}
}

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

@ -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)