Flash partition works!
This commit is contained in:
parent
828aa54618
commit
974cb1a7c1
4 changed files with 107 additions and 36 deletions
7
db97.py
7
db97.py
|
|
@ -268,3 +268,10 @@ class Db():
|
|||
|
||||
return rsp[8:8+sz]
|
||||
|
||||
def write_flash(self, which, addr, buf):
|
||||
self.tls.cmd(wtf_hardcoded)
|
||||
cmd = pack('<BBBHLL', 0x41, which, 1, 0, addr, len(buf)) + buf
|
||||
rsp=self.tls.cmd(cmd)
|
||||
assert_status(rsp)
|
||||
self.flush_changes()
|
||||
|
||||
|
|
|
|||
|
|
@ -8,22 +8,20 @@ from fastecdsa.ecdsa import verify
|
|||
from fastecdsa.point import Point
|
||||
from fastecdsa.keys import get_public_key
|
||||
|
||||
#4f 0000 0000
|
||||
|
||||
blob4f=unhex('''
|
||||
00000c000000100000100000000020000100f000010407000010000000100000000000009da
|
||||
4f0000000000000c000000100000100000000020000100f000010407000010000000100000000000009da
|
||||
6bb3eb1d4d1641811b0a2402ba5010d6d0f2f7ffd8debc7e7e68c31473333020102000020000000e00300
|
||||
00000000840acfea4e998b5302df52db54b7654b164a1057681149fcbb3ec7a559c80db20505030000000
|
||||
40000800000000000005c70f7ccce2fc2d7620f69da63548fc392877c88393e9c45327a10c21d46267f06
|
||||
0603000080040000800000000000005a5eeb284ee05ddae47ee27dc75fafaf09bc8b112a652bde4eab8af
|
||||
c61f2df75040305000000050000000300000000000e828eaff826a0454f6a50f60a36d5014372aaaf2621
|
||||
41e5ced9d0a0056907c20500bc01170000002000000000b0330e8b22509dd47b3bc2b48540d5bf8946097
|
||||
678663c23a04ca43911567300000000000000000000000000000000000000000000000000000000000000
|
||||
000000000069ebc98290a346b0b7be5bb697c24c653ee885e12f497bf44cdf563f7f26af0c00000000000
|
||||
41e5ced9d0a0056907c20500bc011700000020000000ebfaf1f684cd4e4739e56588695ba19b515be4c16
|
||||
f3e89bfe6b33f59b209a26b00000000000000000000000000000000000000000000000000000000000000
|
||||
00000000003870b373e2a0c3b7b09c16cdb8bd5f04bfdfdd55583c67db236c5b522ad6b49000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000004600000030440220593e87ba9cd31
|
||||
4bbfddb3feaa2392bd23906d0f5191a3f2a886c4e87d55ac469022025fb00eaa8b29896ec891d7fc6f51c
|
||||
7dacaba244c4987b772ce221a6f7028c59000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000460000003044022036a452cef79a1
|
||||
f146ca26dcf06eb58b333f95fab2d49eb89abbcb07c39dbe4c602200dc95d991f7f89e66ad8ee546619dc
|
||||
4262617fb813e6e53f4333bbe21fe705d3000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
|
@ -40,6 +38,9 @@ ffffffffff00000000ffffffff000000000000000000000000000000000000000000000000000000
|
|||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
''')
|
||||
|
||||
#skip 4f 0000 0000
|
||||
blob4f=blob4f[5:]
|
||||
|
||||
while len(blob4f) > 0:
|
||||
hdr, blob4f = blob4f[:4], blob4f[4:]
|
||||
id, l = unpack('<HH', hdr)
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@ from tls97 import *
|
|||
from hashlib import sha256
|
||||
from struct import pack
|
||||
from usb97 import *
|
||||
from Crypto.Random import get_random_bytes
|
||||
from Crypto.Cipher import AES
|
||||
from fastecdsa.encoding.der import DEREncoder
|
||||
from fastecdsa.curve import P256
|
||||
from fastecdsa.ecdsa import sign
|
||||
from fastecdsa.point import Point
|
||||
from fastecdsa.keys import gen_private_key, get_public_key
|
||||
from util import assert_status
|
||||
|
||||
flash_layout_hardcoded=[
|
||||
# id ?? acc offset size
|
||||
|
|
@ -20,19 +23,6 @@ flash_layout_hardcoded=[
|
|||
# unhex('08 08 0500 00000000 000000ff'), # <-- hack to make the whole flash contents readable
|
||||
]
|
||||
|
||||
blk3_hardcoded=unhex('''
|
||||
170000000001000001000000fcffffffffffffffffffffff00000000000000000000000001000000fffff
|
||||
fff0000000000000000000000000000000000000000000000000000000000000000000000004b60d2273e
|
||||
3cce3bf6b053ccb0061d65bc86987655bdebb3e7933aaad835c65a0000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000096c298d84539a1f4a033eb2d817d0377f240a463e5e6
|
||||
bcf847422ce1f2d1176b00000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000f551bf376840b6cbce5e316b5733ce2b169e0f7c4aebe78e9b7f1afee242e34f00000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000512563fcc2cab9f3849e17a7adf
|
||||
ae6bcffffffffffffffff00000000ffffffff000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000ffffffffffffffffffffffff00000000000000000000000001000000fffff
|
||||
fff000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
''')
|
||||
|
||||
enable_blob=unhex('''
|
||||
06020000013920c0cdd8e7e68d6ef897ee686fbf657f83b9514341e1d3c0835a28c9cd1ccd0016644f74d
|
||||
d02a73b85d95f4d352417cee76ba0bca3ce474159c62ade3e10797715a13f15a292f5d57c6d46cf8f5ef6
|
||||
|
|
@ -330,6 +320,19 @@ def make_cert():
|
|||
msg += b'\0'*(444 - len(msg))
|
||||
return msg
|
||||
|
||||
def encrypt_key():
|
||||
x = unhexlify('%064x' % client_public.x)[::-1]
|
||||
y = unhexlify('%064x' % client_public.y)[::-1]
|
||||
d = unhexlify('%064x' % client_private)[::-1]
|
||||
|
||||
m = x+y+d
|
||||
iv = get_random_bytes(AES.block_size)
|
||||
aes = AES.new(psk_encryption_key, AES.MODE_CBC, iv)
|
||||
c = iv + aes.encrypt(m)
|
||||
sig = hmac.new(psk_validation_key, c, sha256).digest()
|
||||
return b'\x02' + c + sig
|
||||
|
||||
|
||||
def make_flash_params(flash_size, sector_size, erase_cmd):
|
||||
return pack('<LLxxBx', flash_size, sector_size, erase_cmd)
|
||||
|
||||
|
|
@ -339,10 +342,17 @@ cmd = unhex('4f 0000 0000')
|
|||
cmd += with_hdr(0, make_flash_params(0x100000, 0x1000, 0x20))
|
||||
cmd += with_hdr(1, b''.join([i + b'\0'*4 + sha256(i).digest() for i in flash_layout_hardcoded]))
|
||||
cmd += with_hdr(5, make_cert())
|
||||
cmd += with_hdr(3, blk3_hardcoded)
|
||||
cmd += with_hdr(3, crt_hardcoded)
|
||||
|
||||
usb=Usb()
|
||||
usb.trace_enabled=True
|
||||
|
||||
tls=Tls(usb)
|
||||
tls.trace_enabled=True
|
||||
tls.handle_priv(encrypt_key())
|
||||
|
||||
db=Db(tls)
|
||||
|
||||
usb.open()
|
||||
usb.cmd(enable_blob)
|
||||
rsp=usb.cmd(unhex('3e'))
|
||||
|
|
@ -359,29 +369,44 @@ rsp=usb.cmd(unhex('3e'))
|
|||
# 05 05 0300 00000400 00800000
|
||||
# 06 06 0300 00800400 00800000
|
||||
# 04 03 0500 00000500 00000300
|
||||
#rsp=usb.cmd(cmd)
|
||||
# ^ todo validate response
|
||||
rsp=usb.cmd(cmd)
|
||||
assert_status(rsp)
|
||||
rsp=rsp[2:]
|
||||
crt_len, rsp=rsp[:4], rsp[4:]
|
||||
crt_len, = unpack('<L', crt_len)
|
||||
tls.handle_cert(rsp[:crt_len])
|
||||
# ^ TODO - validate cert
|
||||
rsp = rsp[crt_len:]
|
||||
# ^ TODO - figure out what the rest of rsp means
|
||||
|
||||
rsp=usb.cmd(unhex('01'))
|
||||
assert_status(rsp)
|
||||
# ^ get device info, contains firmware version which is needed to lookup pubkey for server cert validation
|
||||
|
||||
rsp=usb.cmd(unhex('50'))
|
||||
# ^ response contains server cert -- TODO validate it
|
||||
# ^ TODO validate response
|
||||
# It should be signed by the firmware private key.
|
||||
# The corresponding pub key is hardcoded for each fw revision in the synaWudfBioUsb.dll.
|
||||
# for my device it is: x=f727653b4e16ce0665a6894d7f3a30d7d0a0be310d1292a743671fdf69f6a8d3, y=a85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94
|
||||
assert_status(rsp)
|
||||
rsp=rsp[2:]
|
||||
l,=unpack('<L', rsp[:4])
|
||||
tls.handle_ecdh(rsp[l-400:])
|
||||
|
||||
rsp=usb.cmd(unhex('1a'))
|
||||
assert_status(rsp)
|
||||
|
||||
tls=Tls(usb)
|
||||
db=Db(tls)
|
||||
# TODO -- explicitly set crypto params on tls object (they are not persisted on flash yet)
|
||||
#tls.open()
|
||||
tls.open()
|
||||
|
||||
# Wipe newly created partitions clean
|
||||
#db.erase_flash(1)
|
||||
#db.erase_flash(2)
|
||||
#db.erase_flash(5)
|
||||
#db.erase_flash(6)
|
||||
#db.erase_flash(4)
|
||||
db.erase_flash(1)
|
||||
db.erase_flash(2)
|
||||
db.erase_flash(5)
|
||||
db.erase_flash(6)
|
||||
db.erase_flash(4)
|
||||
|
||||
# Persist certs and keys on cert partition.
|
||||
#db.write_flash(1, ...)
|
||||
db.write_flash(1, 0, tls.makeTlsFlash())
|
||||
|
||||
# Reboot
|
||||
tls.cmd(unhex('050200'))
|
||||
|
|
|
|||
38
tls97.py
38
tls97.py
|
|
@ -3,6 +3,7 @@ import hmac
|
|||
import sys
|
||||
from hashlib import sha256, md5, sha1
|
||||
from binascii import *
|
||||
from usb97 import unhex
|
||||
from struct import pack, unpack
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Random import get_random_bytes
|
||||
|
|
@ -24,6 +25,19 @@ hw_key= bytes(product_name, 'ascii') + b'\0' + \
|
|||
password_hardcoded=unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033')
|
||||
gwk_sign_hardcoded=unhexlify('3a4c76b76a97981d1274247e166610e77f4d9c9d07d3c728e532916bdd28b454')
|
||||
|
||||
crt_hardcoded=unhex('''
|
||||
170000000001000001000000fcffffffffffffffffffffff00000000000000000000000001000000fffff
|
||||
fff0000000000000000000000000000000000000000000000000000000000000000000000004b60d2273e
|
||||
3cce3bf6b053ccb0061d65bc86987655bdebb3e7933aaad835c65a0000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000096c298d84539a1f4a033eb2d817d0377f240a463e5e6
|
||||
bcf847422ce1f2d1176b00000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000f551bf376840b6cbce5e316b5733ce2b169e0f7c4aebe78e9b7f1afee242e34f00000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000512563fcc2cab9f3849e17a7adf
|
||||
ae6bcffffffffffffffff00000000ffffffff000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000ffffffffffffffffffffffff00000000000000000000000001000000fffff
|
||||
fff000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
''')
|
||||
|
||||
def prf(secret, seed, length):
|
||||
n = (length + 0x20 - 1) // 0x20
|
||||
|
||||
|
|
@ -45,6 +59,7 @@ def hs_key():
|
|||
key=password_hardcoded[:0x10]
|
||||
seed=password_hardcoded[0x10:] + b'\xaa'*2
|
||||
hs_key=prf(key, b'HS_KEY_PAIR_GEN' + seed, 0x20)
|
||||
print(hs_key.hex())
|
||||
return int(hs_key[::-1].hex(), 16)
|
||||
|
||||
def with_2bytes_size(chunk):
|
||||
|
|
@ -383,6 +398,8 @@ class Tls():
|
|||
if id == 0xffff:
|
||||
break
|
||||
|
||||
self.trace('block id %04x (%d bytes)' % (id, sz))
|
||||
|
||||
m=sha256()
|
||||
m.update(body)
|
||||
|
||||
|
|
@ -395,6 +412,8 @@ class Tls():
|
|||
self.handle_ecdh(body)
|
||||
elif id == 3:
|
||||
self.handle_cert(body)
|
||||
elif id == 0:
|
||||
self.handle_empty(body)
|
||||
elif id == 1:
|
||||
self.handle_empty(body)
|
||||
elif id == 2:
|
||||
|
|
@ -402,6 +421,23 @@ class Tls():
|
|||
else:
|
||||
self.trace('unhandled block id %04x (%d bytes): %s' % (id, sz, hexlify(body)))
|
||||
|
||||
def makeTlsFlashBlock(self, id, body):
|
||||
m=sha256()
|
||||
m.update(body)
|
||||
hdr = pack('<HH', id, len(body))
|
||||
return hdr+m.digest()+body
|
||||
|
||||
def makeTlsFlash(self):
|
||||
b = self.makeTlsFlashBlock(0, b'\0')
|
||||
b+= self.makeTlsFlashBlock(4, self.priv_blob)
|
||||
b+= self.makeTlsFlashBlock(3, self.tls_cert)
|
||||
b+= self.makeTlsFlashBlock(5, crt_hardcoded)
|
||||
b+= self.makeTlsFlashBlock(1, b'\0' * 0x100)
|
||||
b+= self.makeTlsFlashBlock(2, b'\0' * 0x100)
|
||||
b+= self.makeTlsFlashBlock(6, self.ecdh_blob)
|
||||
b+= b'\xff' * (0x1000 - len(b))
|
||||
return b
|
||||
|
||||
def handle_empty(self, body):
|
||||
if body != b'\0' * len(body):
|
||||
raise Exception('Expected empty block')
|
||||
|
|
@ -413,6 +449,7 @@ class Tls():
|
|||
|
||||
def handle_ecdh(self, body):
|
||||
# TODO check the signature
|
||||
self.ecdh_blob = body
|
||||
x = body[0x8:0x8+0x20]
|
||||
y = body[0x4c:0x4c+0x20]
|
||||
|
||||
|
|
@ -428,6 +465,7 @@ class Tls():
|
|||
|
||||
|
||||
def handle_priv(self, body):
|
||||
self.priv_blob = body
|
||||
prefix, body = body[0], body[1:]
|
||||
if prefix != 2:
|
||||
raise Exception('Unknown private key prefix %02x' % prefix)
|
||||
|
|
|
|||
Loading…
Reference in a new issue