Пример #1
0
    def _set_ciphers(self):
        """Generate out/inbound encryption keys and initialise respective ciphers."""

        prk = hkdf.hkdf_extract(self.CIPHER_SALT, self.shared_key)
        self.outgoing_key = hkdf.hkdf_expand(prk, self.OUT_CIPHER_INFO, 32)

        prk = hkdf.hkdf_extract(self.CIPHER_SALT, self.shared_key)
        self.incoming_key = hkdf.hkdf_expand(prk, self.IN_CIPHER_INFO, 32)
Пример #2
0
    def pair_verify_m1_m2(self, client_public):
        self.client_curve_public = client_public

        self.accessory_curve = x25519.X25519PrivateKey.generate()
        self.accessory_curve_public = self.accessory_curve.public_key(
        ).public_bytes(encoding=serialization.Encoding.Raw,
                       format=serialization.PublicFormat.Raw)
        self.accessory_shared_key = self.accessory_curve.exchange(
            x25519.X25519PublicKey.from_public_bytes(client_public))

        accessory_info = self.accessory_curve_public + self.accessory_id + client_public
        accessory_signed = self.accessory_ltsk.sign(accessory_info)
        accessory_sig = accessory_signed.signature

        sub_tlv = Tlv8.encode([
            Tlv8.Tag.IDENTIFIER, self.accessory_id, Tlv8.Tag.SIGNATURE,
            accessory_sig
        ])

        prk = hkdf.hkdf_extract(b"Pair-Verify-Encrypt-Salt",
                                self.accessory_shared_key)
        session_key = hkdf.hkdf_expand(prk, b"Pair-Verify-Encrypt-Info", 32)

        c = ChaCha20_Poly1305.new(key=session_key, nonce=b"PV-Msg02")
        enc_tlv, tag = c.encrypt_and_digest(sub_tlv)

        return [
            Tlv8.Tag.STATE, PairingState.M2, Tlv8.Tag.PUBLICKEY,
            self.accessory_curve_public, Tlv8.Tag.ENCRYPTEDDATA, enc_tlv + tag
        ]
Пример #3
0
    def _makeRelayCrypto(self, secret_input):
        '''Derive shared key material using HKDF from secret_input.

        :returns: **oppy.crypto.relaycrypto.RelayCrypto** initialized with
            shared key data
        '''
        prk = hkdf.hkdf_extract(salt=T_KEY, input_key_material=secret_input,
                                hash=hashlib.sha256)
        km = hkdf.hkdf_expand(pseudo_random_key=prk, info=M_EXPAND,
                              length=72, hash=hashlib.sha256)

        df = km[: DIGEST_LEN]
        db = km[DIGEST_LEN : DIGEST_LEN * 2]
        kf = km[DIGEST_LEN * 2 : DIGEST_LEN * 2 + KEY_LEN]
        kb = km[DIGEST_LEN * 2 + KEY_LEN : DIGEST_LEN * 2 + KEY_LEN * 2]

        f_digest = hashlib.sha1(df)
        b_digest = hashlib.sha1(db)
        f_cipher = util.makeAES128CTRCipher(kf)
        b_cipher = util.makeAES128CTRCipher(kb)

        return RelayCrypto(forward_digest=f_digest,
                           backward_digest=b_digest,
                           forward_cipher=f_cipher,
                           backward_cipher=b_cipher)
Пример #4
0
    def pair_verify_m3_m4(self, encrypted):
        prk = hkdf.hkdf_extract(b"Pair-Verify-Encrypt-Salt",
                                self.accessory_shared_key)
        session_key = hkdf.hkdf_expand(prk, b"Pair-Verify-Encrypt-Info", 32)

        c = ChaCha20_Poly1305.new(key=session_key, nonce=b"PV-Msg03")
        enc_tlv = encrypted[:-16]
        tag = encrypted[-16:]
        dec_tlv = c.decrypt_and_verify(enc_tlv, tag)

        sub_tlv = Tlv8.decode(dec_tlv)
        device_id = sub_tlv[Tlv8.Tag.IDENTIFIER]
        device_sig = sub_tlv[Tlv8.Tag.SIGNATURE]

        device_info = self.client_curve_public + device_id + self.accessory_curve_public
        device_pairing_filepath = "./pairings/" + device_id.decode(
            "utf-8") + ".pub"
        if path.exists(device_pairing_filepath):
            with open(device_pairing_filepath, "rb") as device_pairing_file:
                self.device_ltpk = device_pairing_file.read()

            verify_key = nacl.signing.VerifyKey(self.device_ltpk)
            verify_key.verify(device_info, device_sig)
            return True, [Tlv8.Tag.STATE, PairingState.M4]
        else:
            return False, [Tlv8.Tag.ERROR, PairingErrors.AUTHENTICATION]
Пример #5
0
    def _makeRelayCrypto(self, secret_input):
        '''Derive shared key material using HKDF from secret_input.

        :returns: **oppy.crypto.relaycrypto.RelayCrypto** initialized with
            shared key data
        '''
        prk = hkdf.hkdf_extract(salt=T_KEY,
                                input_key_material=secret_input,
                                hash=hashlib.sha256)
        km = hkdf.hkdf_expand(pseudo_random_key=prk,
                              info=M_EXPAND,
                              length=72,
                              hash=hashlib.sha256)

        df = km[:DIGEST_LEN]
        db = km[DIGEST_LEN:DIGEST_LEN * 2]
        kf = km[DIGEST_LEN * 2:DIGEST_LEN * 2 + KEY_LEN]
        kb = km[DIGEST_LEN * 2 + KEY_LEN:DIGEST_LEN * 2 + KEY_LEN * 2]

        f_digest = hashlib.sha1(df)
        b_digest = hashlib.sha1(db)
        f_cipher = util.makeAES128CTRCipher(kf)
        b_cipher = util.makeAES128CTRCipher(kb)

        return RelayCrypto(forward_digest=f_digest,
                           backward_digest=b_digest,
                           forward_cipher=f_cipher,
                           backward_cipher=b_cipher)
Пример #6
0
    def hkdf(self, ecdhSecret):
        prk = hkdf_extract(salt=b"54686579206c6976696e272069742075702061742074686520486f74656c2043616c69666f726e69610a576861742061206e6963652073757270726973652028776861742061206e696365207375727072697365290a4272696e6720796f757220616c69626973",
                           hash=hashlib.sha256,
                           input_key_material=ecdhSecret)

        return hkdf_expand(pseudo_random_key=prk,
                           info=b"knock",
                           length=16)
Пример #7
0
def compute_ik(shared_secret, service_public_key, beacon_public_key):
    salt = service_public_key + beacon_public_key
    prk = hkdf.hkdf_extract(salt, shared_secret, hash=hashlib.sha256)
    ik = hkdf.hkdf_expand(prk, b"", 32, hash=hashlib.sha256)[:16]
    print(b'shared: ' + binascii.hexlify(shared_secret))
    print(b'service: ' + binascii.hexlify(service_public_key))
    print(b'beacon: ' + binascii.hexlify(beacon_public_key))
    print(b'ik: ' + binascii.hexlify(ik))
    return ik
Пример #8
0
def GetAndPrintIdentityKey(shared_secret,
                           service_public_key, beacon_public_key):
  """Compute the identity key from a Curve25519 shared secret."""
  salt = service_public_key + beacon_public_key
  PrintBinary("Salt", salt)
  prk = hkdf.hkdf_extract(salt, shared_secret, hash=hashlib.sha256)
  PrintBinary("Prk (extracted bytes)", prk)
  ik = hkdf.hkdf_expand(prk, "", 32, hash=hashlib.sha256)[:16]
  PrintBinary("Identity key", ik)
  return ik
Пример #9
0
def GetAndPrintIdentityKey(shared_secret, service_public_key,
                           beacon_public_key):
    """Compute the identity key from a Curve25519 shared secret."""
    salt = service_public_key + beacon_public_key
    PrintBinary("Salt", salt)
    prk = hkdf.hkdf_extract(salt, shared_secret, hash=hashlib.sha256)
    PrintBinary("Prk (extracted bytes)", prk)
    ik = hkdf.hkdf_expand(prk, "", 32, hash=hashlib.sha256)[:16]
    PrintBinary("Identity key", ik)
    return ik
Пример #10
0
    def pair_setup_m5_m6_1(self, encrypted):
        prk = hkdf.hkdf_extract(b"Pair-Setup-Encrypt-Salt",
                                self.ctx.session_key)
        session_key = hkdf.hkdf_expand(prk, b"Pair-Setup-Encrypt-Info", 32)
        c = ChaCha20_Poly1305.new(key=session_key, nonce=b"PS-Msg05")
        enc_tlv = encrypted[:-16]
        tag = encrypted[-16:]
        dec_tlv = c.decrypt_and_verify(enc_tlv, tag)

        return Tlv8.decode(dec_tlv), session_key
Пример #11
0
def get_subkey(keyname, salt = None):
    b64_pairing_key = get_from_datadir("pairingkey")
    if b64_pairing_key is None:
        pairing_key = random(32)
        save_to_datadir("pairingkey",
                            standard_b64encode(pairing_key).decode('ascii'))
    else:
        pairing_key = standard_b64decode(b64_pairing_key)

    if type(keyname) == str:
        keyname = keyname.encode()
    return hkdf_expand(hkdf_extract(salt, pairing_key), keyname, 32)
Пример #12
0
    def pair_setup_m5_m6_2(self, dec_tlv):
        self.device_id = dec_tlv[Tlv8.Tag.IDENTIFIER]
        self.device_ltpk = dec_tlv[Tlv8.Tag.PUBLICKEY]
        device_sig = dec_tlv[Tlv8.Tag.SIGNATURE]

        prk = hkdf.hkdf_extract(b"Pair-Setup-Controller-Sign-Salt",
                                self.ctx.session_key)
        device_x = hkdf.hkdf_expand(prk, b"Pair-Setup-Controller-Sign-Info",
                                    32)
        device_info = device_x + self.device_id + self.device_ltpk

        verify_key = nacl.signing.VerifyKey(self.device_ltpk)
        verify_key.verify(device_info, device_sig)
Пример #13
0
    def _hkdfDeriveParameter(self, hashFunction, masterSecret, masterSalt, id, algorithm, type, length):

        info = cbor.dumps([
            id,
            algorithm,
            unicode(type), # encode as text string
            length
        ])

        extract = hkdf.hkdf_extract(salt=masterSalt, input_key_material=masterSecret, hash=hashFunction)
        expand = hkdf.hkdf_expand(pseudo_random_key=extract, info=info, length=length, hash=hashFunction)

        return expand
Пример #14
0
    def _kdf(self, master_salt, master_secret, role_id, out_type):
        out_bytes = {'Key': self.algorithm.key_bytes, 'IV': self.algorithm.iv_bytes}[out_type]

        info = cbor.dumps([
            role_id,
            self.id_context,
            self.algorithm.value,
            out_type,
            out_bytes
            ])
        extracted = hkdf.hkdf_extract(master_salt, master_secret, hash=self.hashfun)
        expanded = hkdf.hkdf_expand(extracted, info=info, hash=self.hashfun,
                length=out_bytes)
        return expanded
Пример #15
0
    def _kdf(self, master_secret, master_salt, role_id, out_type):
        out_bytes = {
            'Key': self.algorithm.key_bytes,
            'IV': self.algorithm.iv_bytes
        }[out_type]

        info = cbor.dumps([role_id, self.algorithm.value, out_type, out_bytes])
        extracted = hkdf.hkdf_extract(master_salt,
                                      master_secret,
                                      hash=self.hashfun)
        expanded = hkdf.hkdf_expand(extracted,
                                    info=info,
                                    hash=self.hashfun,
                                    length=out_bytes)
        return expanded
Пример #16
0
def solicitar_diffie_hellman(p, g, sock):
    mensagem = str(p) + '/' + str(g) # mensagem = valor p/valor g
    mensagem = adicionar_padding(mensagem) # Preenche a mensagem até atingir o tamanho do payload
    sock.send(bytes(mensagem, 'utf-8')) # Envia os parâmetros iniciais p e g para o servidor

    A = random.randint(1, 10000)
    a = g ** A % p

    resposta = sock.recv(TAM_PAYLOAD)
    resposta = remover_padding(resposta)
    b = int(resposta) # Armazena o valor 'b' recebido do servidor

    mensagem = str(a) # mensagem = valor a
    mensagem = adicionar_padding(mensagem)
    sock.send(bytes(mensagem, 'utf-8')) # Compartilha o valor gerado 'a' com o servidor

    chave_compartilhada = str(b ** A % p)
    print("[+] Chave compartilhada gerada: {}".format(chave_compartilhada))

    # Deriva uma chave que possa ser usada pelo algoritmo de criptografia
    chave_compartilhada = derivar_chave(bytes(chave_compartilhada, 'utf-8'))
    print(f"[+] Chave derivada: {chave_compartilhada.decode()}")

    k = hkdf.hkdf_extract(None, chave_compartilhada)

    nova_chave = hkdf.hkdf_expand(k) # Expande a chave utilizando hkdf
    nova_chave = derivar_chave(nova_chave)

    mensagem = str(nova_chave)
    mensagem = criptografar(mensagem, chave_compartilhada).decode()
    mensagem += gerar_hmac(chave_compartilhada, mensagem)
    mensagem = adicionar_padding(mensagem)
    sock.send(bytes(mensagem, 'utf-8'))

    chave_compartilhada = nova_chave # Atualiza a chave para a nova chave gerada
    print("[+] Nova chave gerada: {}\n".format(chave_compartilhada.decode()))

    resposta = sock.recv(TAM_PAYLOAD)

    if verificar_hmac(resposta, chave_compartilhada) == 'NOK':
        print("[+] O HMAC da mensagem recebida não corresponde aos dados.")
        raise SystemExit

    resposta = remover_padding(resposta)
    resposta = resposta[:-64] # Retira os últimos 64 bytes da mensagem (HMAC)
    resposta = decodificar(resposta, chave_compartilhada)
    print(resposta)
    return chave_compartilhada
Пример #17
0
def derive_key(key_material, salt, info):
    """
    Derive a fixed-size (64-byte) key for use in cryptographic operations.

    The key is derived using HKDF with the SHA-512 hash function. See
    https://tools.ietf.org/html/rfc5869.

    :type key_material: str or bytes
    :type salt: bytes
    :type info: bytes
    """
    if not isinstance(key_material, bytes):
        key_material = key_material.encode()

    pseudorandom_key = hkdf_extract(salt, key_material, hash=hashlib.sha512)
    return hkdf_expand(pseudorandom_key, info, length=64, hash=hashlib.sha512)
Пример #18
0
def compute_identity_key(shared_secret, service_public_key, beacon_public_key):
    logger.debug('service_public_key: {}'.format(
        binascii.hexlify(service_public_key)))
    logger.debug('beacon_public_key: {}'.format(
        binascii.hexlify(beacon_public_key)))

    salt = service_public_key + beacon_public_key
    logger.debug('salt: {}'.format(binascii.hexlify(salt)))

    prk = hkdf.hkdf_extract(salt, shared_secret, hash=hashlib.sha256)
    logger.debug('prk: {}'.format(binascii.hexlify(prk)))

    identity_key = hkdf.hkdf_expand(prk, b"", 32, hash=hashlib.sha256)[:16]
    logger.debug('identity_key: {}'.format(binascii.hexlify(identity_key)))

    return identity_key
Пример #19
0
def derive_key(key_material, salt, info):
    """
    Derive a fixed-size (64-byte) key for use in cryptographic operations.

    The key is derived using HKDF with the SHA-512 hash function. See
    https://tools.ietf.org/html/rfc5869.

    :type key_material: str or bytes
    :type salt: bytes
    :type info: bytes
    """
    if not isinstance(key_material, bytes):
        key_material = key_material.encode()

    pseudorandom_key = hkdf_extract(salt, key_material, hash=hashlib.sha512)
    return hkdf_expand(pseudorandom_key, info, length=64, hash=hashlib.sha512)
Пример #20
0
    def pair_setup_m5_m6_2(self, dec_tlv):
        self.device_id = dec_tlv[Tlv8.Tag.IDENTIFIER]
        self.device_ltpk = dec_tlv[Tlv8.Tag.PUBLICKEY]
        device_sig = dec_tlv[Tlv8.Tag.SIGNATURE]

        prk = hkdf.hkdf_extract(b"Pair-Setup-Controller-Sign-Salt",
                                self.ctx.session_key)
        device_x = hkdf.hkdf_expand(prk, b"Pair-Setup-Controller-Sign-Info",
                                    32)
        device_info = device_x + self.device_id + self.device_ltpk

        verify_key = nacl.signing.VerifyKey(self.device_ltpk)
        verify_key.verify(device_info, device_sig)

        with open("./pairings/" + self.device_id.decode("utf-8") + ".pub",
                  "wb") as device_pairing_file:
            device_pairing_file.write(self.device_ltpk)
Пример #21
0
def check_fun_tv(tv):
	'''
	Generate and check HKDF pseudorandom key and output key material for a specific test vector
	
	PRK = HKDF-Extract([test vector values])
	OKM = HKDF-Expand(PRK, [test vector values])
	'''

	test_prk = hkdf.hkdf_extract(tv["salt"], tv["IKM"], tv["hash"])
	test_okm = hkdf.hkdf_expand(test_prk, tv["info"], tv["L"], tv["hash"])
	print "%s" % tv
	print "PRK: %s" % ("match" if test_prk == tv["PRK"] else "FAIL")
	print "OKM: %s" % ("match" if test_okm == tv["OKM"] else "FAIL")
	print

	assert_equals(test_prk, tv["PRK"])
	assert_equals(test_okm, tv["OKM"])
Пример #22
0
    def pair_verify_m3_m4(self, encrypted):
        prk = hkdf.hkdf_extract(b"Pair-Verify-Encrypt-Salt",
                                self.accessory_shared_key)
        session_key = hkdf.hkdf_expand(prk, b"Pair-Verify-Encrypt-Info", 32)

        c = ChaCha20_Poly1305.new(key=session_key, nonce=b"PV-Msg03")
        enc_tlv = encrypted[:-16]
        tag = encrypted[-16:]
        dec_tlv = c.decrypt_and_verify(enc_tlv, tag)

        sub_tlv = Tlv8.decode(dec_tlv)
        device_id = sub_tlv[Tlv8.Tag.IDENTIFIER]
        device_sig = sub_tlv[Tlv8.Tag.SIGNATURE]

        device_info = self.client_curve_public + device_id + self.accessory_curve_public
        verify_key = nacl.signing.VerifyKey(self.device_ltpk)
        verify_key.verify(device_info, device_sig)

        return [Tlv8.Tag.STATE, PairingState.M4]
Пример #23
0
    def pair_setup_m5_m6_3(self, session_key):
        prk = hkdf.hkdf_extract(b"Pair-Setup-Accessory-Sign-Salt",
                                self.ctx.session_key)
        accessory_x = hkdf.hkdf_expand(prk, b"Pair-Setup-Accessory-Sign-Info",
                                       32)

        # self.accessory_ltsk = nacl.signing.SigningKey.generate()
        # self.accessory_ltpk = bytes(self.accessory_ltsk.verify_key)

        accessory_info = accessory_x + self.accessory_id + self.accessory_ltpk
        accessory_signed = self.accessory_ltsk.sign(accessory_info)
        accessory_sig = accessory_signed.signature

        dec_tlv = Tlv8.encode([
            Tlv8.Tag.IDENTIFIER, self.accessory_id, Tlv8.Tag.PUBLICKEY,
            self.accessory_ltpk, Tlv8.Tag.SIGNATURE, accessory_sig
        ])

        c = ChaCha20_Poly1305.new(key=session_key, nonce=b"PS-Msg06")
        enc_tlv, tag = c.encrypt_and_digest(dec_tlv)

        return enc_tlv, tag
Пример #24
0
def prng_rerandomize(prng_seed, newseed, info):
    m1 = hkdf.hkdf_expand(prng_seed, info, 128)
    return hkdf.hkdf_extract(m1[64:],
                             input_key_material=(m1[:64] + newseed),
                             hash=hashlib.sha512)
Пример #25
0
def prng_init(seed, salt):
    # extract the secret m
    return hkdf.hkdf_extract(salt,
                             input_key_material=seed,
                             hash=hashlib.sha512)
Пример #26
0
def tv_expand(tv_number):
	tv = test_vectors[tv_number]
	test_prk = hkdf.hkdf_extract(tv["salt"], tv["IKM"], tv["hash"])
	return hkdf.hkdf_expand(test_prk, tv["info"], tv["L"], tv["hash"])
Пример #27
0
def tv_extract(tv_number):
	tv = test_vectors[tv_number]
	return hkdf.hkdf_extract(tv["salt"], tv["IKM"], tv["hash"])
Пример #28
0
import hkdf

prk = hkdf.hkdf_extract(bytes.fromhex("8e94ef805b93e683ff18"), b"asecretpassword")
key = hkdf.hkdf_expand(prk, b"context1", 32)
print (key)
Пример #29
0
 def hkdf_extract(self, salt: bytes, input_key_material: bytes) -> bytes:
     if input_key_material is None:
         input_key_material = b"\x00" * self.hash_len
     return hkdf.hkdf_extract(salt, input_key_material, self.hashmod)
Пример #30
0
 def hkdf_extract(self, salt, input_key_material):
     import hkdf
     if input_key_material is None:
         input_key_material = b"\x00" * hashlib.sha256().digest_size
     return hkdf.hkdf_extract(salt, input_key_material, hashlib.sha256)
Пример #31
0
def get_subkey(keyname, salt = None):
    if type(keyname) == str:
        keyname = keyname.encode()
    return hkdf_expand(hkdf_extract(salt, pairing_key), keyname, 32)
Пример #32
0
    0x5b,
    0xe0,
    0xcd,
    0x19,
    0x13,
    0x7e,
    0x21,
    0x79,
])

ciphersuite = b"\0"
d = 32

# extract the secret m
m = hkdf.hkdf_extract(salt=DOM_SEP_PARAM_GEN,
                      input_key_material=seed,
                      hash=hashlib.sha512)

# generate h using hash_to_group
info = bytes("H2G_h", "ascii")
# expand the secret
key = hkdf.hkdf_expand(pseudo_random_key=m,
                       info=info,
                       length=32,
                       hash=hashlib.sha512)
# hash to G2
h = map2curve_osswu2(key, ciphersuite)

# generate hlistusing hash_to_group
hlist = []
for i in range(d + 1):