1use puffin::algebra::error::FnError;
2use ring::digest;
3use ring::hkdf::Prk;
4
5use super::rustls::msgs::handshake::Random;
6use crate::tls::key_exchange::tls13_key_exchange;
7use crate::tls::rustls::hash_hs::HandshakeHash;
8use crate::tls::rustls::key_log::NoKeyLog;
9use crate::tls::rustls::msgs::enums::NamedGroup;
10use crate::tls::rustls::suites::SupportedCipherSuite;
11use crate::tls::rustls::tls13::key_schedule::{
12 KeyScheduleEarly, KeyScheduleHandshake, KeyScheduleHandshakeStart, KeySchedulePreHandshake,
13 KeyScheduleTrafficWithClientFinishedPending,
14};
15
16pub fn tls13_handshake_traffic_secret(
17 server_hello: &HandshakeHash,
18 server_key_share: &Option<Vec<u8>>,
19 psk: &Option<Vec<u8>>,
20 client: bool,
21 group: &NamedGroup,
22 client_random: &Random,
23 suite: &SupportedCipherSuite,
24) -> Result<(Prk, KeyScheduleHandshake), FnError> {
25 let key_schedule = dhe_key_schedule(suite, group, server_key_share, psk)?;
26
27 let (hs, client_secret, server_secret) = key_schedule.derive_handshake_secrets(
28 &server_hello.get_current_hash_raw(),
29 &NoKeyLog {},
30 &client_random.0,
31 );
32
33 Ok((if client { client_secret } else { server_secret }, hs))
34}
35
36pub fn tls13_handshake_traffic_secret_from_shared_secret(
40 server_hello_transcript: &HandshakeHash,
41 client_random: &Random,
42 client: bool,
43 suite: &SupportedCipherSuite,
44 extracted_shared_secret: &Vec<u8>,
45) -> Result<(Prk, KeyScheduleHandshake), FnError> {
46 let hkdf_algorithm = suite
47 .tls13()
48 .ok_or_else(|| FnError::Crypto("No tls 1.3 suite".to_owned()))?
49 .hkdf_algorithm;
50 let key_schedule =
51 KeyScheduleHandshakeStart::new_with_secret(hkdf_algorithm, extracted_shared_secret);
52 let (hs, client_secret, server_secret) = key_schedule.derive_handshake_secrets(
53 &server_hello_transcript.get_current_hash_raw(),
54 &NoKeyLog {},
55 &client_random.0,
56 );
57
58 Ok((if client { client_secret } else { server_secret }, hs))
59}
60
61pub fn tls13_application_traffic_secret(
62 server_hello: &HandshakeHash,
63 server_finished: &HandshakeHash,
64 server_key_share: &Option<Vec<u8>>,
65 psk: &Option<Vec<u8>>,
66 group: &NamedGroup,
67 client: bool,
68 client_random: &Random,
69 suite: &SupportedCipherSuite,
70) -> Result<(Prk, KeyScheduleTrafficWithClientFinishedPending), FnError> {
71 let (_key, key_schedule) = tls13_handshake_traffic_secret(
72 server_hello,
73 server_key_share,
74 psk,
75 client,
76 group,
77 client_random,
78 suite,
79 )?;
80
81 let (pending, client_secret, server_secret) = key_schedule
82 .into_traffic_with_client_finished_pending_raw(
83 &server_finished.get_current_hash_raw(),
84 &NoKeyLog {},
85 &client_random.0,
86 );
87 Ok((if client { client_secret } else { server_secret }, pending))
88}
89
90pub fn tls13_derive_psk(
91 server_hello: &HandshakeHash,
92 server_finished: &HandshakeHash,
93 client_finished: &HandshakeHash,
94 server_key_share: &Option<Vec<u8>>,
95 new_ticket_nonce: &[u8],
96 group: &NamedGroup,
97 client_random: &Random,
98 suite: &SupportedCipherSuite,
99) -> Result<Vec<u8>, FnError> {
100 let (_, pending) = tls13_application_traffic_secret(
101 server_hello,
102 server_finished,
103 server_key_share,
104 &None,
105 group,
106 true,
107 client_random,
108 suite,
109 )?;
110
111 let (traffic, _tag, _client_secret) =
112 pending.sign_client_finish_raw(&server_finished.get_current_hash_raw());
113 let psk = traffic.resumption_master_secret_and_derive_ticket_psk_raw(
114 &client_finished.get_current_hash_raw(),
115 new_ticket_nonce,
116 );
117
118 Ok(psk)
119}
120
121pub fn dhe_key_schedule(
122 suite: &SupportedCipherSuite,
123 group: &NamedGroup,
124 server_key_share: &Option<Vec<u8>>,
125 psk: &Option<Vec<u8>>,
126) -> Result<KeyScheduleHandshakeStart, FnError> {
127 let hkdf_algorithm = suite
128 .tls13()
129 .ok_or_else(|| FnError::Crypto("No tls 1.3 suite".to_owned()))?
130 .hkdf_algorithm;
131
132 let key_schedule = match (server_key_share, psk) {
134 (Some(server_key_share), Some(psk)) => {
135 let shared_secret = tls13_key_exchange(server_key_share, group)?;
136 let early = KeyScheduleEarly::new(hkdf_algorithm, psk.as_slice());
137 let pre: KeySchedulePreHandshake = early.into();
138 Ok(pre.into_handshake(&shared_secret))
139 }
140 (Some(server_key_share), None) => {
141 let shared_secret = tls13_key_exchange(server_key_share, group)?;
142 Ok(KeySchedulePreHandshake::new(hkdf_algorithm).into_handshake(&shared_secret))
143 }
144 (None, Some(psk)) => {
145 let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
147 let early = KeyScheduleEarly::new(hkdf_algorithm, psk.as_slice());
148 let pre: KeySchedulePreHandshake = early.into();
149 Ok(pre.into_handshake(
150 &zeroes[..hkdf_algorithm
151 .hmac_algorithm()
152 .digest_algorithm()
153 .output_len],
154 ))
155 }
156 (None, None) => Err(FnError::Malformed(
157 "Need at least a key share or a psk".to_owned(),
158 )),
159 };
160
161 key_schedule
162}