1use crate::{CipherSuite, CryptoProvider, Hash, errors::Error};
2
3pub fn hkdf_expand_label(
8 provider: &impl CryptoProvider,
9 suite: CipherSuite,
10 secret: &Hash,
11 label: &[u8],
12 context: &[u8],
13 out: &mut [u8],
14) -> Result<(), Error> {
15 provider.hkdf_expand_label(out, suite, secret, label, context)
16}
17
18pub fn derive_secret(
23 provider: &impl CryptoProvider,
24 suite: CipherSuite,
25 secret: &Hash,
26 label: &[u8],
27 transcript_hash: &Hash,
28) -> Result<Hash, Error> {
29 let hash_size = suite.hash_size();
30 let mut out = Hash::new_zeroed(hash_size as u8);
31 hkdf_expand_label(provider, suite, secret, label, transcript_hash, &mut *out)?;
32 Ok(out)
33}
34
35pub fn derive_traffic_keys<C: CryptoProvider + ?Sized>(
41 provider: &C,
42 suite: CipherSuite,
43 traffic_secret: &Hash,
44) -> Result<(C::AeadKey, [u8; 12]), Error> {
45 let key_size = suite.key_size();
46 let mut key_out = [0u8; 32];
47 let mut iv_out = [0u8; 12];
48 hkdf_expand_label(provider, suite, traffic_secret, b"key", b"", &mut key_out[..key_size])?;
49 hkdf_expand_label(provider, suite, traffic_secret, b"iv", b"", &mut iv_out)?;
50 let key = provider.new_aead_key(suite, &key_out[..key_size]);
51 Ok((key, iv_out))
52}
53
54pub fn derive_finished_key(
58 provider: &impl CryptoProvider,
59 suite: CipherSuite,
60 traffic_secret: &Hash,
61) -> Result<Hash, Error> {
62 let hash_size = suite.hash_size();
63 let mut out = Hash::new_zeroed(hash_size as u8);
64 hkdf_expand_label(provider, suite, traffic_secret, b"finished", b"", &mut *out)?;
65 Ok(out)
66}
67
68pub fn compute_finished(
72 provider: &impl CryptoProvider,
73 suite: CipherSuite,
74 finished_key: &Hash,
75 transcript_hash: &Hash,
76) -> Result<Hash, Error> {
77 provider.hmac(suite, finished_key, transcript_hash)
78}
79
80pub fn derive_ticket_psk(
84 provider: &impl CryptoProvider,
85 suite: CipherSuite,
86 resumption_secret: &Hash,
87 ticket_nonce: &[u8],
88) -> Result<Hash, Error> {
89 let hash_size = suite.hash_size();
90 let mut out = Hash::new_zeroed(hash_size as u8);
91 hkdf_expand_label(provider, suite, resumption_secret, b"resumption", ticket_nonce, &mut *out)?;
92 Ok(out)
93}
94
95pub fn key_update_secret(provider: &impl CryptoProvider, suite: CipherSuite, old_secret: &Hash) -> Result<Hash, Error> {
97 let hash_size = suite.hash_size();
98 let mut out = Hash::new_zeroed(hash_size as u8);
99 hkdf_expand_label(provider, suite, old_secret, b"traffic upd", b"", &mut *out)?;
100 Ok(out)
101}
102
103pub fn compute_empty_hash(provider: &impl CryptoProvider, suite: CipherSuite) -> Result<Hash, Error> {
105 provider.hash(suite, &[])
106}