def handle_ecdh(self, body): self.ecdh_blob = body key, signature = body[:0x90], body[0x90:] x = key[0x8:0x8+0x20] y = key[0x4c:0x4c+0x20] x, y = [int(hexlify(i[::-1]), 0x10) for i in [x, y]] if not P256.is_point_on_curve( (x, y) ): raise Exception('Point is not on the curve') self.ecdh_q = Point(x, y, P256) self.trace('ECDH params:') self.trace('x=0x%x' % x) self.trace('y=0x%x' % y) l, signature = signature[:4], signature[4:] l, = unpack('<L', l) signature, zeroes = signature[:l], signature[l:] if zeroes != b'\0'*len(zeroes): raise Exception('Zeroes expected') # The following pub key is hardcoded for each fw revision in the synaWudfBioUsb.dll. # Corresponding private key should only be known to a genuine Synaptic device. fwpub=Point( 0xf727653b4e16ce0665a6894d7f3a30d7d0a0be310d1292a743671fdf69f6a8d3, 0xa85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94, P256) signature=DEREncoder().decode_signature(signature) if not verify(signature, key, fwpub): raise Exception('Untrusted device')
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) c, hs = body[:-0x20], body[-0x20:] sig=hmac.new(psk_validation_key, c, sha256).digest() if hs != sig: raise Exception('Signature verification failed. This device was probably paired with another computer.') iv, c = c[:AES.block_size], c[AES.block_size:] aes=AES.new(psk_encryption_key, AES.MODE_CBC, iv) m=aes.decrypt(c) m=m[:-m[-1]] # unpad (standard this time) x, m = m[:0x20], m[0x20:] y, m = m[:0x20], m[0x20:] d, m = m[:0x20], m[0x20:] x, y, d = [int(hexlify(i[::-1]), 0x10) for i in [x, y, d]] if not P256.is_point_on_curve( (x, y) ): raise Exception('Point is not on the curve') # TODO check if the priv key belogs to this public key self.trace('Private key:') self.trace('x=0x%x' % x) self.trace('y=0x%x' % y) self.trace('d=0x%x' % d) self.pub_key = Point(x, y, P256) self.priv_key = d
def handle_ecdh(self, body): # TODO check the signature self.ecdh_blob = body x = body[0x8:0x8+0x20] y = body[0x4c:0x4c+0x20] x, y = [int(hexlify(i[::-1]), 0x10) for i in [x, y]] if not P256.is_point_on_curve( (x, y) ): raise Exception('Point is not on the curve') self.ecdh_q = Point(x, y, P256) self.trace('ECDH params:') self.trace('x=0x%x' % x) self.trace('y=0x%x' % y)
if keysz != 0x20: raise Exception('Unexpected key size') x, p = p[:0x20], p[0x20:] x = int(hexlify(x[::-1]).decode(), 16) print('block 5, x=%x' % x) nulls, p = p[:0x24], p[0x24:] if nulls != b'\0' * len(nulls): raise Exception('Nulls expected') y, p = p[:0x20], p[0x20:] y = int(hexlify(y[::-1]).decode(), 16) print('block 5, y=%x' % y) if not P256.is_point_on_curve((x, y)): raise Exception('pub key point is not on curve') nulls, p = p[:0x4c], p[0x4c:] if nulls != b'\0' * len(nulls): raise Exception('Nulls expected') ssz, p = p[:4], p[4:] ssz, = unpack('<L', ssz) signature, nulls = p[:ssz], p[ssz:] if nulls != b'\0' * len(nulls): raise Exception('Nulls expected') signature = DEREncoder().decode_signature(signature) msg = (pack('<LL', 0x17, 0x20) + unhexlify('%064x' % x)[::-1] +