1pub struct HkdfLabelSha256;
6
7enum ServerOrClient {
8 Server,
9 Client,
10}
11
12impl HkdfLabelSha256 {
13 pub fn tls13_c_e_traffic(ctx: &[u8; 32]) -> [u8; 54] {
14 let mut r: [u8; 54] = [0; 54];
15 const PREFIX: [u8; 17] = *b"tls13 c e traffic";
16 r[1] = 53;
17 r[2..18].copy_from_slice(&PREFIX);
18 r[18] = 32;
19 r[19..54].copy_from_slice(ctx);
20 r
21 }
22
23 pub const fn tls13_res_binder() -> [u8; 20] {
24 [
26 0, 32, 16, 116, 108, 115, 49, 51, 32, 0x72, 0x65, 0x73, 0x20, 0x62, 0x69, 0x6E, 0x64,
27 0x65, 0x72, 00,
28 ]
29 }
30 #[inline]
32 pub fn tls13_derived_secret_sha256() -> [u8; 49] {
33 Self::tls13_early_secret_sha256()
34 }
35 #[inline]
37 pub fn tls13_early_secret_sha256() -> [u8; 49] {
38 let r: [u8; 49] = [
40 0, 32, 13, 116, 108, 115, 49, 51, 32, 100, 101, 114, 105, 118, 101, 100, 32, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
47 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
48 0x78, 0x52, 0xb8, 0x55,
49 ];
50
51 assert_eq!(&r[3..16], b"tls13 derived");
52 r
53 }
54 #[inline]
55 pub fn tls13_hanshake_finished(hash_len: u8) -> [u8; 18] {
56 let r: [u8; 18] = [
58 0, hash_len, 14, 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x66, 0x69, 0x6E, 0x69, 0x73,
59 0x68, 0x65, 0x64, 0x00,
60 ];
61 assert_eq!(&r[3..17], b"tls13 finished");
62 r
63 }
64 #[inline]
65 pub fn tls13_secret_key(key_len: u8) -> [u8; 13] {
66 let r: [u8; 13] = [0, key_len, 9, 116, 108, 115, 49, 51, 32, 107, 101, 121, 0];
68 assert_eq!(&r[3..12], b"tls13 key");
69 r
70 }
71 #[inline]
72 pub fn tls13_secret_iv(iv_len: u8) -> [u8; 12] {
73 let r: [u8; 12] = [0, iv_len, 8, 116, 108, 115, 49, 51, 32, 105, 118, 00];
75 assert_eq!(&r[3..11], b"tls13 iv");
76 r
77 }
78 #[inline]
79 fn _tls13_application_traffic(which: ServerOrClient, ctx: &[u8; 32]) -> [u8; 54] {
80 let prefix: [u8; 18] = match which {
81 ServerOrClient::Client => *b"tls13 c ap traffic",
82 ServerOrClient::Server => *b"tls13 s ap traffic",
83 };
84 let mut r: [u8; 54] = [0; 54];
85 r[1] = 32;
86 r[2] = 18;
87 r[3..21].copy_from_slice(&prefix);
88 r[21] = 32;
89 r[22..54].copy_from_slice(ctx);
90 r
91 }
92 #[inline]
93 fn _tls13_handshake_traffic(which: ServerOrClient, ctx: &[u8; 32]) -> [u8; 54] {
94 let prefix: [u8; 18] = match which {
95 ServerOrClient::Client => *b"tls13 c hs traffic",
96 ServerOrClient::Server => *b"tls13 s hs traffic",
97 };
98 let mut r: [u8; 54] = [0; 54];
99 r[1] = 32;
100 r[2] = 18;
101 r[3..21].copy_from_slice(&prefix);
102 r[21] = 32;
103 r[22..54].copy_from_slice(ctx);
104 r
105 }
106 #[inline]
108 pub fn tls13_client_handshake_traffic(ctx: &[u8; 32]) -> [u8; 54] {
109 Self::_tls13_handshake_traffic(ServerOrClient::Client, ctx)
110 }
111 #[inline]
112 pub fn tls13_server_handshake_traffic(ctx: &[u8; 32]) -> [u8; 54] {
113 Self::_tls13_handshake_traffic(ServerOrClient::Server, ctx)
114 }
115 #[inline]
117 pub fn tls13_client_application_traffic(ctx: &[u8; 32]) -> [u8; 54] {
118 Self::_tls13_application_traffic(ServerOrClient::Client, ctx)
119 }
120 #[inline]
121 pub fn tls13_server_application_traffic(ctx: &[u8; 32]) -> [u8; 54] {
122 Self::_tls13_application_traffic(ServerOrClient::Server, ctx)
123 }
124}
125
126#[cfg(test)]
127mod test_rfc8448 {
128 use super::*;
131 use hex_literal::hex;
132 use hkdf::{hmac::Hmac, GenericHkdf, Hkdf};
133 use sha2::Sha256;
134
135 const fn client_hello() -> &'static [u8; 196] {
136 &hex!(
137 "01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
138 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
139 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
140 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
141 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
142 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
143 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
144 af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
145 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
146 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"
147 )
148 }
149
150 const fn server_hello() -> &'static [u8; 90] {
151 &hex!(
152 "02 00 00 56 03 03 a6 af 06 a4 12 18 60
153 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
154 d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
155 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
156 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"
157 )
158 }
159
160 fn early_secret_no_psk() -> ([u8; 32], GenericHkdf<Hmac<Sha256>>) {
162 let ikm: [u8; 32] = [0; 32];
166 let salt: [u8; 1] = [0; 1];
167 let (early_secret, hk) = Hkdf::<Sha256>::extract(Some(&salt[..]), &ikm);
168 (early_secret.into(), hk)
169 }
170
171 #[test]
173 fn early_secret_no_psk_ok() {
174 let (ek, _hk) = early_secret_no_psk();
175 assert_eq!(
176 ek,
177 hex!(
178 "33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
179 e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a"
180 )
181 );
182 }
183
184 fn derived_sha256() -> ([u8; 32], GenericHkdf<Hmac<Sha256>>) {
186 let (_ek, hk) = early_secret_no_psk();
187 let label_derived = HkdfLabelSha256::tls13_early_secret_sha256();
192 assert_eq!(
193 label_derived,
194 hex!(
195 "00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
196 20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
197 64 9b 93 4c a4 95 99 1b 78 52 b8 55"
198 )
199 );
200
201 let mut derived_secret: [u8; 32] = [0; 32];
202 hk.expand(&label_derived, &mut derived_secret).unwrap();
203 (derived_secret, hk)
204 }
205
206 #[test]
207 fn derived_sha256_ok() {
208 let (derived_secret, _hk) = derived_sha256();
209 assert_eq!(
210 derived_secret,
211 hex!(
212 "6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
213 b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba"
214 )
215 );
216 }
217
218 fn shared_secret() -> &'static [u8; 32] {
219 &hex!(
220 "8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
221 35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d"
222 )
223 }
224
225 fn handshake_secret() -> ([u8; 32], GenericHkdf<Hmac<Sha256>>) {
226 let (derived_secret, _derived_hk) = derived_sha256();
227 let shared_secret = shared_secret();
228 let (handshake_secret, hk) = Hkdf::<Sha256>::extract(Some(&derived_secret), shared_secret);
229 (handshake_secret.into(), hk)
230 }
231
232 #[test]
233 fn handshake_secret_ok() {
234 let (handshake_secret, _hk) = handshake_secret();
235 assert_eq!(
236 handshake_secret,
237 hex!(
238 "1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
239 01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac"
240 )
241 );
242 }
243
244 fn handshake_traffic_hash_input() -> &'static [u8; 32] {
247 &hex!(
248 "86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
249 d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"
250 )
251 }
252
253 #[test]
254 fn label_tls13_server_handshake_traffic_label_ok() {
255 let hello_hash = handshake_traffic_hash_input();
256 let label = HkdfLabelSha256::tls13_server_handshake_traffic(hello_hash);
257
258 assert_eq!(
259 &label,
260 &hex!(
261 "00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
262 61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
263 ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"
264 )
265 );
266 }
267
268 fn server_hs_traffic_secret() -> ([u8; 32], GenericHkdf<Hmac<Sha256>>) {
272 let (_handshake_secret, hk) = handshake_secret();
273 let hello_hash = handshake_traffic_hash_input();
274 let label = HkdfLabelSha256::tls13_server_handshake_traffic(hello_hash);
275 let mut server_secret: [u8; 32] = [0; 32];
276 hk.expand(&label, &mut server_secret).unwrap();
277 (server_secret, hk)
278 }
279
280 #[test]
281 fn server_hs_traffic_secret_ok() {
282 let (server_secret, _hk) = server_hs_traffic_secret();
283 assert_eq!(
284 &server_secret,
285 &hex!(
286 "b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
287 37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38"
288 )
289 );
290 }
291
292 #[test]
293 fn server_hs_traffic_secret_key_ok() {
294 let (server_secret, _hk) = server_hs_traffic_secret();
295
296 let hk = Hkdf::<Sha256>::from_prk(&server_secret).expect("PRK should be large enough");
297 let mut server_handshake_key: [u8; 16] = [0; 16];
298 let key_label = HkdfLabelSha256::tls13_secret_key(16);
299 assert_eq!(&key_label, &hex!("00 10 09 74 6c 73 31 33 20 6b 65 79 00"));
300 hk.expand(&key_label, &mut server_handshake_key).unwrap();
301 assert_eq!(
302 &server_handshake_key,
303 &hex!("3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e e4 03 bc")
304 );
305 }
306
307 #[test]
308 fn server_hs_traffic_secret_iv_ok() {
309 let (server_secret, _hk) = server_hs_traffic_secret();
310
311 let hk = Hkdf::<Sha256>::from_prk(&server_secret).expect("PRK should be large enough");
312 let mut server_handshake_iv: [u8; 12] = [0; 12];
313 let iv_label = HkdfLabelSha256::tls13_secret_iv(12);
314 assert_eq!(&iv_label, &hex!("00 0c 08 74 6c 73 31 33 20 69 76 00"));
315 hk.expand(&iv_label, &mut server_handshake_iv).unwrap();
316 assert_eq!(
317 &server_handshake_iv,
318 &hex!("5d 31 3e b2 67 12 76 ee 13 00 0b 30")
319 );
320 }
321}