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
Beispiel #3
0
    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] +