kopia lustrzana https://github.com/conorpp/u2f-zero
programming by serial number for adapter and token for parallelized programming
rodzic
adbc2bb7a8
commit
2a4bc901bf
|
@ -63,6 +63,7 @@ pubkey.c.txt
|
||||||
*.__i
|
*.__i
|
||||||
*.__ia
|
*.__ia
|
||||||
release/
|
release/
|
||||||
|
workers/
|
||||||
*~
|
*~
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// generated
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
code uint8_t __attest[] =
|
||||||
|
"\x30\x82\x01\x5a\x30\x82\x01\x00\x02\x01\x01\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d"
|
||||||
|
"\x04\x03\x02\x30\x39\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x56\x41\x31\x14"
|
||||||
|
"\x30\x12\x06\x03\x55\x04\x0a\x0c\x0b\x43\x6f\x6e\x6f\x72\x43\x6f\x20\x4c\x4c\x43"
|
||||||
|
"\x31\x14\x30\x12\x06\x03\x55\x04\x03\x0c\x0b\x75\x32\x66\x7a\x65\x72\x6f\x2e\x63"
|
||||||
|
"\x6f\x6d\x30\x1e\x17\x0d\x31\x36\x30\x37\x32\x34\x30\x35\x33\x34\x35\x30\x5a\x17"
|
||||||
|
"\x0d\x32\x32\x30\x37\x32\x33\x30\x35\x33\x34\x35\x30\x5a\x30\x39\x31\x0b\x30\x09"
|
||||||
|
"\x06\x03\x55\x04\x06\x13\x02\x56\x41\x31\x14\x30\x12\x06\x03\x55\x04\x0a\x0c\x0b"
|
||||||
|
"\x43\x6f\x6e\x6f\x72\x43\x6f\x20\x4c\x4c\x43\x31\x14\x30\x12\x06\x03\x55\x04\x03"
|
||||||
|
"\x0c\x0b\x75\x32\x66\x7a\x65\x72\x6f\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07\x2a"
|
||||||
|
"\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04"
|
||||||
|
"\x80\xfe\xb0\x59\x0d\xad\x1a\x96\x5d\xd6\x66\xdd\x77\x67\x90\xb5\xfa\x70\xb3\x1d"
|
||||||
|
"\x51\xb3\x0f\xf5\x5d\xbe\x08\x60\x73\x76\x38\x02\x21\xf6\x19\x8f\x37\x91\x80\x4a"
|
||||||
|
"\xa9\xd5\x39\x12\x97\x20\x86\x34\x52\x3c\xb0\x76\x95\x2b\x02\xcb\x9f\x10\xd7\xa5"
|
||||||
|
"\x77\xbc\xe9\xf9\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00\x30"
|
||||||
|
"\x45\x02\x20\x5a\x06\x89\xd5\xfc\x1f\x15\x29\x54\x8b\x09\x10\x65\x53\x9f\xe8\x30"
|
||||||
|
"\x81\xae\x91\x6b\xca\x93\x32\x1f\x9d\xf6\xca\x0e\x8a\x1e\x21\x02\x21\x00\xf7\x78"
|
||||||
|
"\x14\xb1\xe6\x24\x17\x13\xbf\xd9\x0d\xcd\x27\x1a\xc3\x28\xa4\xcb\xd8\x2e\x84\x1f"
|
||||||
|
"\x0c\xa9\x2a\x9e\x65\x31\xca\x4a\x3d\xeb"
|
||||||
|
;
|
||||||
|
const uint16_t __attest_size = sizeof(__attest)-1;
|
|
@ -126,8 +126,9 @@ SI_SEGMENT_VARIABLE(configDesc[],
|
||||||
#define LANG_STRING htole16( SLAB_USB_LANGUAGE )
|
#define LANG_STRING htole16( SLAB_USB_LANGUAGE )
|
||||||
#define MFR_STRING "Silicon Labs"
|
#define MFR_STRING "Silicon Labs"
|
||||||
#define PROD_STRING "U2F Zero"
|
#define PROD_STRING "U2F Zero"
|
||||||
#define SER_STRING "0123456789ABCDEF"
|
#define SER_STRING "CAFEBABEFFFFFFFD"
|
||||||
#define INT0_STRING "HID Keyboard"
|
#define INT0_STRING "U2F Zero"
|
||||||
|
|
||||||
|
|
||||||
LANGID_STATIC_CONST_STRING_DESC( langDesc[], LANG_STRING );
|
LANGID_STATIC_CONST_STRING_DESC( langDesc[], LANG_STRING );
|
||||||
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( mfrDesc[], MFR_STRING );
|
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( mfrDesc[], MFR_STRING );
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# silabs utility debugger debugger id C2
|
# silabs utility debugger debugger id C2
|
||||||
FlashUtilCL.exe FLASHEraseUSB "EC3004BCC9E" 1
|
FlashUtilCL.exe FLASHEraseUSB "$1" 1
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# silabs utility debugger file debugger id power C2
|
# silabs utility debugger file debugger id power C2
|
||||||
FlashUtilCL.exe DownloadUSB -R $1 "EC3004BCC9E" 0 1
|
FlashUtilCL.exe DownloadUSB -R $1 "$2" 0 1
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
export PATH=$PATH:`pwd`/flashing:../../../u2f_zero_client:../../../gencert
|
||||||
|
|
||||||
|
key=gencert/ca/key.pem
|
||||||
|
adapters[0]=0
|
||||||
|
num_adapters=0
|
||||||
|
firmware=../firmware
|
||||||
|
setup=setup_device.sh
|
||||||
|
|
||||||
|
for i in `seq 1 100` ; do
|
||||||
|
|
||||||
|
adapters[$i]=$(FlashUtilCL.exe DeviceSN $i)
|
||||||
|
|
||||||
|
if [[ ${adapters[$i]} = *"out of range"* ]]
|
||||||
|
then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
num_adapters=$(($num_adapters + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -rf workers
|
||||||
|
mkdir workers
|
||||||
|
|
||||||
|
for i in `seq 1 $num_adapters` ; do
|
||||||
|
echo ${adapters[$i]}
|
||||||
|
mkdir workers/${adapters[$i]}
|
||||||
|
mkdir workers/${adapters[$i]}/worker
|
||||||
|
cp -rf $firmware workers/${adapters[$i]}
|
||||||
|
cp $setup workers/${adapters[$i]}/worker
|
||||||
|
done
|
||||||
|
|
||||||
|
cd workers/${adapters[1]}/worker && ./$setup ../../../$key ${adapters[1]} CAFEBABE00000001
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,26 @@
|
||||||
|
|
||||||
SETUP_HEX=../firmware/SETUP.hex
|
SETUP_HEX=../firmware/SETUP.hex
|
||||||
FINAL_HEX=../firmware/release/u2f-firmware.hex
|
FINAL_HEX=../firmware/release/u2f-firmware.hex
|
||||||
FLASH_TOOLS=0
|
FLASH_TOOLS=1
|
||||||
|
SN=
|
||||||
|
SN_build=
|
||||||
|
|
||||||
if [[ $# != "1" ]]
|
if [[ $# != "1" ]] && [[ $# != "2" ]] && [[ $# != "3" ]]
|
||||||
then
|
then
|
||||||
|
|
||||||
echo "usage: $0 <ca-key>"
|
echo "usage: $0 <ca-key> [debugger-SN] [new-SN-for-U2F-token]"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ $# != "1" ]] ; then
|
||||||
|
SN=$2
|
||||||
|
if [[ $# = "3" ]] ; then
|
||||||
|
SN_build=$3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
export PATH=$PATH:gencert:u2f_zero_client:flashing
|
export PATH=$PATH:gencert:u2f_zero_client:flashing
|
||||||
|
|
||||||
if [[ $FLASH_TOOLS = 1 ]]
|
if [[ $FLASH_TOOLS = 1 ]]
|
||||||
|
@ -19,22 +29,27 @@ then
|
||||||
|
|
||||||
# setup atecc
|
# setup atecc
|
||||||
echo "erasing..."
|
echo "erasing..."
|
||||||
erase.sh
|
erase.sh $SN
|
||||||
|
|
||||||
while [[ "$?" -ne "0" ]] ; do
|
while [[ "$?" -ne "0" ]] ; do
|
||||||
sleep .1
|
sleep .1
|
||||||
erase.sh
|
erase.sh $SN
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "programming setup..."
|
echo "programming setup..."
|
||||||
program.sh $SETUP_HEX
|
program.sh $SETUP_HEX $SN
|
||||||
|
|
||||||
[[ "$?" -ne "0" ]] && exit 1
|
[[ "$?" -ne "0" ]] && exit 1
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "configuring..."
|
echo "configuring..."
|
||||||
client.py configure pubkey.hex >/dev/null
|
|
||||||
|
if [[ -n $SN_build ]] ; then
|
||||||
|
client.py configure pubkey.hex -s $SN_build >/dev/null
|
||||||
|
else
|
||||||
|
client.py configure pubkey.hex >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
while [[ "$?" -ne "0" ]] ; do
|
while [[ "$?" -ne "0" ]] ; do
|
||||||
sleep .2
|
sleep .2
|
||||||
|
@ -47,6 +62,14 @@ gencert.sh "$1" "$(cat pubkey.hex)" attest.der > ../firmware/src/cert.c
|
||||||
|
|
||||||
[[ "$?" -ne "0" ]] && exit 1
|
[[ "$?" -ne "0" ]] && exit 1
|
||||||
|
|
||||||
|
if [[ -n $SN_build ]] ; then
|
||||||
|
sed -i "/#define SER_STRING.*/c\#define SER_STRING \"$SN_build\"" ../firmware/src/descriptors.c
|
||||||
|
rm ../firmware/release/u2f-firmware.omf
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i "s/firmware.*src.*cert.c/tools\/workers\/$SN\/firmware\/src\/cert.c/g" ../firmware/release/src/cert.__i
|
||||||
|
sed -i "s/firmware.*src.*descriptors.c/tools\/workers\/$SN\/firmware\/src\/descriptors.c/g" ../firmware/release/src/descriptors.__i
|
||||||
|
|
||||||
echo "done."
|
echo "done."
|
||||||
echo "building..."
|
echo "building..."
|
||||||
|
|
||||||
|
@ -60,20 +83,21 @@ then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PATH1=$PATH
|
PATH1=$PATH
|
||||||
cd ../firmware/release && make all && cd ../../tools
|
cur=`pwd`
|
||||||
export PATH=$PATH1
|
cd ../firmware/release && make all && cd $cur
|
||||||
|
|
||||||
|
|
||||||
[[ "$?" -ne "0" ]] && exit 1
|
[[ "$?" -ne "0" ]] && exit 1
|
||||||
|
|
||||||
|
export PATH=$PATH1
|
||||||
|
|
||||||
echo "programming final build..."
|
echo "programming final build..."
|
||||||
cp $FINAL_HEX prog.hex
|
cp $FINAL_HEX prog.hex
|
||||||
program.sh prog.hex
|
program.sh prog.hex $SN
|
||||||
#rm prog.hex
|
#rm prog.hex
|
||||||
|
|
||||||
while [[ "$?" -ne "0" ]] ; do
|
while [[ "$?" -ne "0" ]] ; do
|
||||||
sleep .2
|
sleep .2
|
||||||
program.sh prog.hex
|
program.sh prog.hex $SN
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ "$?" -ne "0" ]] && exit 1
|
[[ "$?" -ne "0" ]] && exit 1
|
||||||
|
|
|
@ -65,28 +65,40 @@ class commands:
|
||||||
U2F_CUSTOM_IDLE_COLOR = 0x25
|
U2F_CUSTOM_IDLE_COLOR = 0x25
|
||||||
U2F_CUSTOM_IDLE_COLORP = 0x26
|
U2F_CUSTOM_IDLE_COLORP = 0x26
|
||||||
|
|
||||||
if len(sys.argv) not in [2,3,4]:
|
if len(sys.argv) not in [2,3,4,5,6]:
|
||||||
print('usage: %s <action> [<arguments>]' % sys.argv[0])
|
print('usage: %s <action> [<arguments>] [-s serial-number]' % sys.argv[0])
|
||||||
print('actions: ')
|
print('actions: ')
|
||||||
print(' configure <output-file>: setup the device configuration. must specify pubkey output.')
|
print(' configure <output-file>: setup the device configuration. must specify pubkey output.')
|
||||||
print(' rng: Continuously dump random numbers from the devices hardware RNG.')
|
print(' rng: Continuously dump random numbers from the devices hardware RNG.')
|
||||||
print(' seed: update the hardware RNG seed with input from stdin')
|
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.')
|
print(' wipe: wipe all registered keys on U2F Zero. Must also press button 5 times. Not reversible.')
|
||||||
|
print(' list: list all connected U2F Zero tokens.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def open_u2f():
|
def open_u2f(SN=None):
|
||||||
h = hid.device()
|
h = hid.device()
|
||||||
try:
|
try:
|
||||||
h.open(0x10c4,0x8acf)
|
h.open(0x10c4,0x8acf,unicode(SN))
|
||||||
except IOError as ex:
|
except IOError as ex:
|
||||||
try:
|
try:
|
||||||
h.open(0x10c4,0x8acf)
|
h.open(0x10c4,0x8acf)
|
||||||
except:
|
except:
|
||||||
print( ex)
|
print( ex)
|
||||||
print( 'U2F Zero not found')
|
if SN is None: print( 'U2F Zero not found')
|
||||||
|
else: print ('U2F Zero %s not found' % SN)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return h
|
return h
|
||||||
|
|
||||||
|
|
||||||
|
def do_list():
|
||||||
|
for d in hid.enumerate(0x10c4, 0x8acf):
|
||||||
|
keys = d.keys()
|
||||||
|
keys.sort()
|
||||||
|
for key in keys:
|
||||||
|
print("%s : %s" % (key, d[key]))
|
||||||
|
print('')
|
||||||
|
|
||||||
|
|
||||||
def die(msg):
|
def die(msg):
|
||||||
print( msg)
|
print( msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -191,6 +203,7 @@ def do_rng(h):
|
||||||
else:
|
else:
|
||||||
data = array.array('B',rng[6+1:6+1+32]).tostring()
|
data = array.array('B',rng[6+1:6+1+32]).tostring()
|
||||||
sys.stdout.write(data)
|
sys.stdout.write(data)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def do_seed(h):
|
def do_seed(h):
|
||||||
cmd = cmd_prefix + [ commands.U2F_CUSTOM_SEED, 0,20]
|
cmd = cmd_prefix + [ commands.U2F_CUSTOM_SEED, 0,20]
|
||||||
|
@ -269,26 +282,40 @@ def set_led_pulse(h,s):
|
||||||
h.close()
|
h.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
action = sys.argv[1].lower()
|
action = sys.argv[1].lower()
|
||||||
h = open_u2f()
|
h = None
|
||||||
|
SN = None
|
||||||
|
if '-s' in sys.argv:
|
||||||
|
if sys.argv.index('-s') + 1 > len(sys.argv):
|
||||||
|
print('need serial number')
|
||||||
|
sys.exit(1)
|
||||||
|
SN = sys.argv[sys.argv.index('-s') + 1]
|
||||||
|
|
||||||
if action == 'configure':
|
if action == 'configure':
|
||||||
|
h = open_u2f(SN)
|
||||||
if len(sys.argv) != 3:
|
if len(sys.argv) != 3:
|
||||||
print( 'error: need output file')
|
print( 'error: need output file')
|
||||||
h.close()
|
h.close()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
do_configure(h, sys.argv[2])
|
do_configure(h, sys.argv[2])
|
||||||
elif action == 'rng':
|
elif action == 'rng':
|
||||||
|
h = open_u2f(SN)
|
||||||
do_rng(h)
|
do_rng(h)
|
||||||
elif action == 'seed':
|
elif action == 'seed':
|
||||||
|
h = open_u2f(SN)
|
||||||
do_seed(h)
|
do_seed(h)
|
||||||
elif action == 'wipe':
|
elif action == 'wipe':
|
||||||
|
h = open_u2f(SN)
|
||||||
do_wipe(h)
|
do_wipe(h)
|
||||||
|
elif action == 'list':
|
||||||
|
do_list()
|
||||||
else:
|
else:
|
||||||
print( 'error: invalid action: ', action)
|
print( 'error: invalid action: ', action)
|
||||||
h.close()
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
h.close()
|
|
||||||
|
if h is not None: h.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue