xref: /aosp_15_r20/external/scapy/scapy/layers/tls/crypto/hkdf.py (revision 7dc08ffc4802948ccbc861daaf1e81c405c2c4bd)
1*7dc08ffcSJunyu Lai## This file is part of Scapy
2*7dc08ffcSJunyu Lai## Copyright (C) 2017 Maxence Tury
3*7dc08ffcSJunyu Lai## This program is published under a GPLv2 license
4*7dc08ffcSJunyu Lai
5*7dc08ffcSJunyu Lai"""
6*7dc08ffcSJunyu LaiStateless HKDF for TLS 1.3.
7*7dc08ffcSJunyu Lai"""
8*7dc08ffcSJunyu Lai
9*7dc08ffcSJunyu Laiimport struct
10*7dc08ffcSJunyu Lai
11*7dc08ffcSJunyu Laifrom scapy.config import conf
12*7dc08ffcSJunyu Laifrom scapy.layers.tls.crypto.pkcs1 import _get_hash
13*7dc08ffcSJunyu Lai
14*7dc08ffcSJunyu Laiif conf.crypto_valid:
15*7dc08ffcSJunyu Lai    from cryptography.hazmat.backends import default_backend
16*7dc08ffcSJunyu Lai    from cryptography.hazmat.primitives.kdf.hkdf import HKDF, HKDFExpand
17*7dc08ffcSJunyu Lai    from cryptography.hazmat.primitives.hashes import Hash
18*7dc08ffcSJunyu Lai    from cryptography.hazmat.primitives.hmac import HMAC
19*7dc08ffcSJunyu Lai
20*7dc08ffcSJunyu Lai
21*7dc08ffcSJunyu Laiclass TLS13_HKDF(object):
22*7dc08ffcSJunyu Lai    def __init__(self, hash_name="sha256"):
23*7dc08ffcSJunyu Lai        self.hash = _get_hash(hash_name)
24*7dc08ffcSJunyu Lai
25*7dc08ffcSJunyu Lai    def extract(self, salt, ikm):
26*7dc08ffcSJunyu Lai        h = self.hash
27*7dc08ffcSJunyu Lai        hkdf = HKDF(h, h.digest_size, salt, None, default_backend())
28*7dc08ffcSJunyu Lai        if ikm is None:
29*7dc08ffcSJunyu Lai            ikm = b"\x00" * h.digest_size
30*7dc08ffcSJunyu Lai        return hkdf._extract(ikm)
31*7dc08ffcSJunyu Lai
32*7dc08ffcSJunyu Lai    def expand(self, prk, info, L):
33*7dc08ffcSJunyu Lai        h = self.hash
34*7dc08ffcSJunyu Lai        hkdf = HKDFExpand(h, L, info, default_backend())
35*7dc08ffcSJunyu Lai        return hkdf.derive(prk)
36*7dc08ffcSJunyu Lai
37*7dc08ffcSJunyu Lai    def expand_label(self, secret, label, hash_value, length):
38*7dc08ffcSJunyu Lai        hkdf_label  = struct.pack("!H", length)
39*7dc08ffcSJunyu Lai        hkdf_label += struct.pack("B", 9 + len(label))
40*7dc08ffcSJunyu Lai        hkdf_label += b"TLS 1.3, "
41*7dc08ffcSJunyu Lai        hkdf_label += label
42*7dc08ffcSJunyu Lai        hkdf_label += struct.pack("B", len(hash_value))
43*7dc08ffcSJunyu Lai        hkdf_label += hash_value
44*7dc08ffcSJunyu Lai        return self.expand(secret, hkdf_label, length)
45*7dc08ffcSJunyu Lai
46*7dc08ffcSJunyu Lai    def derive_secret(self, secret, label, messages):
47*7dc08ffcSJunyu Lai        h = Hash(self.hash, backend=default_backend())
48*7dc08ffcSJunyu Lai        h.update(messages)
49*7dc08ffcSJunyu Lai        hash_messages = h.finalize()
50*7dc08ffcSJunyu Lai        hash_len = self.hash.digest_size
51*7dc08ffcSJunyu Lai        return self.expand_label(secret, label, hash_messages, hash_len)
52*7dc08ffcSJunyu Lai
53*7dc08ffcSJunyu Lai    def compute_verify_data(self, basekey, handshake_context):
54*7dc08ffcSJunyu Lai        hash_len = self.hash.digest_size
55*7dc08ffcSJunyu Lai        finished_key = self.expand_label(basekey, b"finished", b"", hash_len)
56*7dc08ffcSJunyu Lai
57*7dc08ffcSJunyu Lai        h = Hash(self.hash, backend=default_backend())
58*7dc08ffcSJunyu Lai        h.update(handshake_context)
59*7dc08ffcSJunyu Lai        hash_value = h.finalize()
60*7dc08ffcSJunyu Lai
61*7dc08ffcSJunyu Lai        hm = HMAC(finished_key, self.hash, default_backend())
62*7dc08ffcSJunyu Lai        hm.update(hash_value)
63*7dc08ffcSJunyu Lai        return hm.finalize()
64*7dc08ffcSJunyu Lai
65