1 use crate::cipher::{Iv, IvLen};
2 use crate::error::TLSError;
3 use crate::msgs::base::PayloadU8;
4 use crate::KeyLog;
5 /// Key schedule maintenance for TLS1.3
6 use ring::{
7     aead, digest,
8     hkdf::{self, KeyType as _},
9     hmac,
10 };
11 
12 /// The kinds of secret we can extract from `KeySchedule`.
13 #[derive(Debug, Clone, Copy, PartialEq)]
14 enum SecretKind {
15     ResumptionPSKBinderKey,
16     ClientEarlyTrafficSecret,
17     ClientHandshakeTrafficSecret,
18     ServerHandshakeTrafficSecret,
19     ClientApplicationTrafficSecret,
20     ServerApplicationTrafficSecret,
21     ExporterMasterSecret,
22     ResumptionMasterSecret,
23     DerivedSecret,
24 }
25 
26 impl SecretKind {
to_bytes(self) -> &'static [u8]27     fn to_bytes(self) -> &'static [u8] {
28         match self {
29             SecretKind::ResumptionPSKBinderKey => b"res binder",
30             SecretKind::ClientEarlyTrafficSecret => b"c e traffic",
31             SecretKind::ClientHandshakeTrafficSecret => b"c hs traffic",
32             SecretKind::ServerHandshakeTrafficSecret => b"s hs traffic",
33             SecretKind::ClientApplicationTrafficSecret => b"c ap traffic",
34             SecretKind::ServerApplicationTrafficSecret => b"s ap traffic",
35             SecretKind::ExporterMasterSecret => b"exp master",
36             SecretKind::ResumptionMasterSecret => b"res master",
37             SecretKind::DerivedSecret => b"derived",
38         }
39     }
40 
log_label(self) -> Option<&'static str>41     fn log_label(self) -> Option<&'static str> {
42         use self::SecretKind::*;
43         Some(match self {
44             ClientEarlyTrafficSecret => "CLIENT_EARLY_TRAFFIC_SECRET",
45             ClientHandshakeTrafficSecret => "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
46             ServerHandshakeTrafficSecret => "SERVER_HANDSHAKE_TRAFFIC_SECRET",
47             ClientApplicationTrafficSecret => "CLIENT_TRAFFIC_SECRET_0",
48             ServerApplicationTrafficSecret => "SERVER_TRAFFIC_SECRET_0",
49             ExporterMasterSecret => "EXPORTER_SECRET",
50             _ => {
51                 return None;
52             }
53         })
54     }
55 }
56 
57 /// This is the TLS1.3 key schedule.  It stores the current secret and
58 /// the type of hash.  This isn't used directly; but only through the
59 /// typestates.
60 struct KeySchedule {
61     current: hkdf::Prk,
62     algorithm: ring::hkdf::Algorithm,
63 }
64 
65 // We express the state of a contained KeySchedule using these
66 // typestates.  This means we can write code that cannot accidentally
67 // (eg) encrypt application data using a KeySchedule solely constructed
68 // with an empty or trivial secret, or extract the wrong kind of secrets
69 // at a given point.
70 
71 /// KeySchedule for early data stage.
72 pub struct KeyScheduleEarly {
73     ks: KeySchedule,
74 }
75 
76 impl KeyScheduleEarly {
new(algorithm: hkdf::Algorithm, secret: &[u8]) -> KeyScheduleEarly77     pub fn new(algorithm: hkdf::Algorithm, secret: &[u8]) -> KeyScheduleEarly {
78         KeyScheduleEarly {
79             ks: KeySchedule::new(algorithm, secret),
80         }
81     }
82 
client_early_traffic_secret( &self, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], ) -> hkdf::Prk83     pub fn client_early_traffic_secret(
84         &self,
85         hs_hash: &[u8],
86         key_log: &dyn KeyLog,
87         client_random: &[u8; 32],
88     ) -> hkdf::Prk {
89         self.ks.derive_logged_secret(
90             SecretKind::ClientEarlyTrafficSecret,
91             hs_hash,
92             key_log,
93             client_random,
94         )
95     }
96 
resumption_psk_binder_key_and_sign_verify_data(&self, hs_hash: &[u8]) -> Vec<u8>97     pub fn resumption_psk_binder_key_and_sign_verify_data(&self, hs_hash: &[u8]) -> Vec<u8> {
98         let resumption_psk_binder_key = self
99             .ks
100             .derive_for_empty_hash(SecretKind::ResumptionPSKBinderKey);
101         self.ks
102             .sign_verify_data(&resumption_psk_binder_key, hs_hash)
103     }
104 
into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshake105     pub fn into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshake {
106         self.ks.input_secret(secret);
107         KeyScheduleHandshake {
108             ks: self.ks,
109             current_client_traffic_secret: None,
110             current_server_traffic_secret: None,
111         }
112     }
113 }
114 
115 /// KeySchedule for skipping early data stage.  No secrets can be extracted
116 /// (since there are none), but the handshake secret can be input.
117 pub struct KeyScheduleNonSecret {
118     ks: KeySchedule,
119 }
120 
121 impl KeyScheduleNonSecret {
new(algorithm: hkdf::Algorithm) -> KeyScheduleNonSecret122     pub fn new(algorithm: hkdf::Algorithm) -> KeyScheduleNonSecret {
123         KeyScheduleNonSecret {
124             ks: KeySchedule::new_with_empty_secret(algorithm),
125         }
126     }
127 
into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshake128     pub fn into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshake {
129         self.ks.input_secret(secret);
130         KeyScheduleHandshake {
131             ks: self.ks,
132             current_client_traffic_secret: None,
133             current_server_traffic_secret: None,
134         }
135     }
136 }
137 
138 /// KeySchedule during handshake.
139 pub struct KeyScheduleHandshake {
140     ks: KeySchedule,
141     current_client_traffic_secret: Option<hkdf::Prk>,
142     current_server_traffic_secret: Option<hkdf::Prk>,
143 }
144 
145 impl KeyScheduleHandshake {
client_handshake_traffic_secret( &mut self, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], ) -> hkdf::Prk146     pub fn client_handshake_traffic_secret(
147         &mut self,
148         hs_hash: &[u8],
149         key_log: &dyn KeyLog,
150         client_random: &[u8; 32],
151     ) -> hkdf::Prk {
152         let secret = self.ks.derive_logged_secret(
153             SecretKind::ClientHandshakeTrafficSecret,
154             hs_hash,
155             key_log,
156             client_random,
157         );
158         self.current_client_traffic_secret = Some(secret.clone());
159         secret
160     }
161 
server_handshake_traffic_secret( &mut self, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], ) -> hkdf::Prk162     pub fn server_handshake_traffic_secret(
163         &mut self,
164         hs_hash: &[u8],
165         key_log: &dyn KeyLog,
166         client_random: &[u8; 32],
167     ) -> hkdf::Prk {
168         let secret = self.ks.derive_logged_secret(
169             SecretKind::ServerHandshakeTrafficSecret,
170             hs_hash,
171             key_log,
172             client_random,
173         );
174         self.current_server_traffic_secret = Some(secret.clone());
175         secret
176     }
177 
sign_server_finish(&self, hs_hash: &[u8]) -> Vec<u8>178     pub fn sign_server_finish(&self, hs_hash: &[u8]) -> Vec<u8> {
179         self.ks.sign_finish(
180             self.current_server_traffic_secret
181                 .as_ref()
182                 .unwrap(),
183             hs_hash,
184         )
185     }
186 
into_traffic_with_client_finished_pending( mut self, ) -> KeyScheduleTrafficWithClientFinishedPending187     pub fn into_traffic_with_client_finished_pending(
188         mut self,
189     ) -> KeyScheduleTrafficWithClientFinishedPending {
190         self.ks.input_empty();
191         KeyScheduleTrafficWithClientFinishedPending {
192             ks: self.ks,
193             handshake_client_traffic_secret: self
194                 .current_client_traffic_secret
195                 .unwrap(),
196             current_client_traffic_secret: None,
197             current_server_traffic_secret: None,
198             current_exporter_secret: None,
199         }
200     }
201 }
202 
203 /// KeySchedule during traffic stage, retaining the ability to calculate the client's
204 /// finished verify_data, and incrementally generate the first traffic keys.
205 pub struct KeyScheduleTrafficWithClientFinishedPending {
206     ks: KeySchedule,
207     handshake_client_traffic_secret: hkdf::Prk,
208     current_client_traffic_secret: Option<hkdf::Prk>,
209     current_server_traffic_secret: Option<hkdf::Prk>,
210     current_exporter_secret: Option<hkdf::Prk>,
211 }
212 
213 impl KeyScheduleTrafficWithClientFinishedPending {
sign_client_finish(&self, hs_hash: &[u8]) -> Vec<u8>214     pub fn sign_client_finish(&self, hs_hash: &[u8]) -> Vec<u8> {
215         self.ks
216             .sign_finish(&self.handshake_client_traffic_secret, hs_hash)
217     }
218 
server_application_traffic_secret( &mut self, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], ) -> hkdf::Prk219     pub fn server_application_traffic_secret(
220         &mut self,
221         hs_hash: &[u8],
222         key_log: &dyn KeyLog,
223         client_random: &[u8; 32],
224     ) -> hkdf::Prk {
225         let secret = self.ks.derive_logged_secret(
226             SecretKind::ServerApplicationTrafficSecret,
227             hs_hash,
228             key_log,
229             client_random,
230         );
231         self.current_server_traffic_secret = Some(secret.clone());
232         secret
233     }
234 
client_application_traffic_secret( &mut self, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], ) -> hkdf::Prk235     pub fn client_application_traffic_secret(
236         &mut self,
237         hs_hash: &[u8],
238         key_log: &dyn KeyLog,
239         client_random: &[u8; 32],
240     ) -> hkdf::Prk {
241         let secret = self.ks.derive_logged_secret(
242             SecretKind::ClientApplicationTrafficSecret,
243             hs_hash,
244             key_log,
245             client_random,
246         );
247         self.current_client_traffic_secret = Some(secret.clone());
248         secret
249     }
250 
exporter_master_secret( &mut self, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], )251     pub fn exporter_master_secret(
252         &mut self,
253         hs_hash: &[u8],
254         key_log: &dyn KeyLog,
255         client_random: &[u8; 32],
256     ) {
257         let secret = self.ks.derive_logged_secret(
258             SecretKind::ExporterMasterSecret,
259             hs_hash,
260             key_log,
261             client_random,
262         );
263         self.current_exporter_secret = Some(secret);
264     }
265 
into_traffic(self) -> KeyScheduleTraffic266     pub fn into_traffic(self) -> KeyScheduleTraffic {
267         KeyScheduleTraffic {
268             ks: self.ks,
269             current_client_traffic_secret: self
270                 .current_client_traffic_secret
271                 .unwrap(),
272             current_server_traffic_secret: self
273                 .current_server_traffic_secret
274                 .unwrap(),
275             current_exporter_secret: self.current_exporter_secret.unwrap(),
276         }
277     }
278 }
279 
280 /// KeySchedule during traffic stage.  All traffic & exporter keys are guaranteed
281 /// to be available.
282 pub struct KeyScheduleTraffic {
283     ks: KeySchedule,
284     current_client_traffic_secret: hkdf::Prk,
285     current_server_traffic_secret: hkdf::Prk,
286     current_exporter_secret: hkdf::Prk,
287 }
288 
289 impl KeyScheduleTraffic {
next_server_application_traffic_secret(&mut self) -> hkdf::Prk290     pub fn next_server_application_traffic_secret(&mut self) -> hkdf::Prk {
291         let secret = self
292             .ks
293             .derive_next(&self.current_server_traffic_secret);
294         self.current_server_traffic_secret = secret.clone();
295         secret
296     }
297 
next_client_application_traffic_secret(&mut self) -> hkdf::Prk298     pub fn next_client_application_traffic_secret(&mut self) -> hkdf::Prk {
299         let secret = self
300             .ks
301             .derive_next(&self.current_client_traffic_secret);
302         self.current_client_traffic_secret = secret.clone();
303         secret
304     }
305 
resumption_master_secret_and_derive_ticket_psk( &self, hs_hash: &[u8], nonce: &[u8], ) -> Vec<u8>306     pub fn resumption_master_secret_and_derive_ticket_psk(
307         &self,
308         hs_hash: &[u8],
309         nonce: &[u8],
310     ) -> Vec<u8> {
311         let resumption_master_secret = self.ks.derive(
312             self.ks.algorithm(),
313             SecretKind::ResumptionMasterSecret,
314             hs_hash,
315         );
316         self.ks
317             .derive_ticket_psk(&resumption_master_secret, nonce)
318     }
319 
export_keying_material( &self, out: &mut [u8], label: &[u8], context: Option<&[u8]>, ) -> Result<(), TLSError>320     pub fn export_keying_material(
321         &self,
322         out: &mut [u8],
323         label: &[u8],
324         context: Option<&[u8]>,
325     ) -> Result<(), TLSError> {
326         self.ks
327             .export_keying_material(&self.current_exporter_secret, out, label, context)
328     }
329 }
330 
331 impl KeySchedule {
new(algorithm: hkdf::Algorithm, secret: &[u8]) -> KeySchedule332     fn new(algorithm: hkdf::Algorithm, secret: &[u8]) -> KeySchedule {
333         let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
334         let zeroes = &zeroes[..algorithm.len()];
335         let salt = hkdf::Salt::new(algorithm, &zeroes);
336         KeySchedule {
337             current: salt.extract(secret),
338             algorithm,
339         }
340     }
341 
342     #[inline]
algorithm(&self) -> hkdf::Algorithm343     fn algorithm(&self) -> hkdf::Algorithm {
344         self.algorithm
345     }
346 
new_with_empty_secret(algorithm: hkdf::Algorithm) -> KeySchedule347     fn new_with_empty_secret(algorithm: hkdf::Algorithm) -> KeySchedule {
348         let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
349         Self::new(algorithm, &zeroes[..algorithm.len()])
350     }
351 
352     /// Input the empty secret.
input_empty(&mut self)353     fn input_empty(&mut self) {
354         let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
355         self.input_secret(&zeroes[..self.algorithm.len()]);
356     }
357 
358     /// Input the given secret.
input_secret(&mut self, secret: &[u8])359     fn input_secret(&mut self, secret: &[u8]) {
360         let salt: hkdf::Salt = self.derive_for_empty_hash(SecretKind::DerivedSecret);
361         self.current = salt.extract(secret);
362     }
363 
364     /// Derive a secret of given `kind`, using current handshake hash `hs_hash`.
derive<T, L>(&self, key_type: L, kind: SecretKind, hs_hash: &[u8]) -> T where T: for<'a> From<hkdf::Okm<'a, L>>, L: hkdf::KeyType,365     fn derive<T, L>(&self, key_type: L, kind: SecretKind, hs_hash: &[u8]) -> T
366     where
367         T: for<'a> From<hkdf::Okm<'a, L>>,
368         L: hkdf::KeyType,
369     {
370         hkdf_expand(&self.current, key_type, kind.to_bytes(), hs_hash)
371     }
372 
derive_logged_secret( &self, kind: SecretKind, hs_hash: &[u8], key_log: &dyn KeyLog, client_random: &[u8; 32], ) -> hkdf::Prk373     fn derive_logged_secret(
374         &self,
375         kind: SecretKind,
376         hs_hash: &[u8],
377         key_log: &dyn KeyLog,
378         client_random: &[u8; 32],
379     ) -> hkdf::Prk {
380         let log_label = kind
381             .log_label()
382             .expect("not a loggable secret");
383         if key_log.will_log(log_label) {
384             let secret = self
385                 .derive::<PayloadU8, _>(PayloadU8Len(self.algorithm.len()), kind, hs_hash)
386                 .into_inner();
387             key_log.log(log_label, client_random, &secret);
388         }
389         self.derive(self.algorithm, kind, hs_hash)
390     }
391 
392     /// Derive a secret of given `kind` using the hash of the empty string
393     /// for the handshake hash.  Useful only for
394     /// `SecretKind::ResumptionPSKBinderKey` and
395     /// `SecretKind::DerivedSecret`.
derive_for_empty_hash<T>(&self, kind: SecretKind) -> T where T: for<'a> From<hkdf::Okm<'a, hkdf::Algorithm>>,396     fn derive_for_empty_hash<T>(&self, kind: SecretKind) -> T
397     where
398         T: for<'a> From<hkdf::Okm<'a, hkdf::Algorithm>>,
399     {
400         let digest_alg = self
401             .algorithm
402             .hmac_algorithm()
403             .digest_algorithm();
404         let empty_hash = digest::digest(digest_alg, &[]);
405         self.derive(self.algorithm, kind, empty_hash.as_ref())
406     }
407 
408     /// Sign the finished message consisting of `hs_hash` using a current
409     /// traffic secret.
sign_finish(&self, base_key: &hkdf::Prk, hs_hash: &[u8]) -> Vec<u8>410     fn sign_finish(&self, base_key: &hkdf::Prk, hs_hash: &[u8]) -> Vec<u8> {
411         self.sign_verify_data(base_key, hs_hash)
412     }
413 
414     /// Sign the finished message consisting of `hs_hash` using the key material
415     /// `base_key`.
sign_verify_data(&self, base_key: &hkdf::Prk, hs_hash: &[u8]) -> Vec<u8>416     fn sign_verify_data(&self, base_key: &hkdf::Prk, hs_hash: &[u8]) -> Vec<u8> {
417         let hmac_alg = self.algorithm.hmac_algorithm();
418         let hmac_key = hkdf_expand(base_key, hmac_alg, b"finished", &[]);
419         hmac::sign(&hmac_key, hs_hash)
420             .as_ref()
421             .to_vec()
422     }
423 
424     /// Derive the next application traffic secret, returning it.
derive_next(&self, base_key: &hkdf::Prk) -> hkdf::Prk425     fn derive_next(&self, base_key: &hkdf::Prk) -> hkdf::Prk {
426         hkdf_expand(&base_key, self.algorithm, b"traffic upd", &[])
427     }
428 
429     /// Derive the PSK to use given a resumption_master_secret and
430     /// ticket_nonce.
derive_ticket_psk(&self, rms: &hkdf::Prk, nonce: &[u8]) -> Vec<u8>431     fn derive_ticket_psk(&self, rms: &hkdf::Prk, nonce: &[u8]) -> Vec<u8> {
432         let payload: PayloadU8 = hkdf_expand(
433             rms,
434             PayloadU8Len(self.algorithm.len()),
435             b"resumption",
436             nonce,
437         );
438         payload.into_inner()
439     }
440 
export_keying_material( &self, current_exporter_secret: &hkdf::Prk, out: &mut [u8], label: &[u8], context: Option<&[u8]>, ) -> Result<(), TLSError>441     fn export_keying_material(
442         &self,
443         current_exporter_secret: &hkdf::Prk,
444         out: &mut [u8],
445         label: &[u8],
446         context: Option<&[u8]>,
447     ) -> Result<(), TLSError> {
448         let digest_alg = self
449             .algorithm
450             .hmac_algorithm()
451             .digest_algorithm();
452 
453         let h_empty = digest::digest(digest_alg, &[]);
454         let secret: hkdf::Prk = hkdf_expand(
455             current_exporter_secret,
456             self.algorithm,
457             label,
458             h_empty.as_ref(),
459         );
460 
461         let h_context = digest::digest(digest_alg, context.unwrap_or(&[]));
462 
463         // TODO: Test what happens when this fails
464         hkdf_expand_info(
465             &secret,
466             PayloadU8Len(out.len()),
467             b"exporter",
468             h_context.as_ref(),
469             |okm| okm.fill(out),
470         )
471         .map_err(|_| TLSError::General("exporting too much".to_string()))
472     }
473 }
474 
hkdf_expand<T, L>(secret: &hkdf::Prk, key_type: L, label: &[u8], context: &[u8]) -> T where T: for<'a> From<hkdf::Okm<'a, L>>, L: hkdf::KeyType,475 pub(crate) fn hkdf_expand<T, L>(secret: &hkdf::Prk, key_type: L, label: &[u8], context: &[u8]) -> T
476 where
477     T: for<'a> From<hkdf::Okm<'a, L>>,
478     L: hkdf::KeyType,
479 {
480     hkdf_expand_info(secret, key_type, label, context, |okm| okm.into())
481 }
482 
hkdf_expand_info<F, T, L>( secret: &hkdf::Prk, key_type: L, label: &[u8], context: &[u8], f: F, ) -> T where F: for<'b> FnOnce(hkdf::Okm<'b, L>) -> T, L: hkdf::KeyType,483 fn hkdf_expand_info<F, T, L>(
484     secret: &hkdf::Prk,
485     key_type: L,
486     label: &[u8],
487     context: &[u8],
488     f: F,
489 ) -> T
490 where
491     F: for<'b> FnOnce(hkdf::Okm<'b, L>) -> T,
492     L: hkdf::KeyType,
493 {
494     const LABEL_PREFIX: &[u8] = b"tls13 ";
495 
496     let output_len = u16::to_be_bytes(key_type.len() as u16);
497     let label_len = u8::to_be_bytes((LABEL_PREFIX.len() + label.len()) as u8);
498     let context_len = u8::to_be_bytes(context.len() as u8);
499 
500     let info = &[
501         &output_len[..],
502         &label_len[..],
503         LABEL_PREFIX,
504         label,
505         &context_len[..],
506         context,
507     ];
508     let okm = secret.expand(info, key_type).unwrap();
509 
510     f(okm)
511 }
512 
513 pub(crate) struct PayloadU8Len(pub(crate) usize);
514 impl hkdf::KeyType for PayloadU8Len {
len(&self) -> usize515     fn len(&self) -> usize {
516         self.0
517     }
518 }
519 
520 impl From<hkdf::Okm<'_, PayloadU8Len>> for PayloadU8 {
from(okm: hkdf::Okm<PayloadU8Len>) -> Self521     fn from(okm: hkdf::Okm<PayloadU8Len>) -> Self {
522         let mut r = vec![0u8; okm.len().0];
523         okm.fill(&mut r[..]).unwrap();
524         PayloadU8::new(r)
525     }
526 }
527 
derive_traffic_key( secret: &hkdf::Prk, aead_algorithm: &'static aead::Algorithm, ) -> aead::UnboundKey528 pub fn derive_traffic_key(
529     secret: &hkdf::Prk,
530     aead_algorithm: &'static aead::Algorithm,
531 ) -> aead::UnboundKey {
532     hkdf_expand(secret, aead_algorithm, b"key", &[])
533 }
534 
derive_traffic_iv(secret: &hkdf::Prk) -> Iv535 pub(crate) fn derive_traffic_iv(secret: &hkdf::Prk) -> Iv {
536     hkdf_expand(secret, IvLen, b"iv", &[])
537 }
538 
539 #[cfg(test)]
540 mod test {
541     use super::{derive_traffic_iv, derive_traffic_key, KeySchedule, SecretKind};
542     use crate::KeyLog;
543     use ring::{aead, hkdf};
544 
545     #[test]
test_vectors()546     fn test_vectors() {
547         /* These test vectors generated with OpenSSL. */
548         let hs_start_hash = [
549             0xec, 0x14, 0x7a, 0x06, 0xde, 0xa3, 0xc8, 0x84, 0x6c, 0x02, 0xb2, 0x23, 0x8e, 0x41,
550             0xbd, 0xdc, 0x9d, 0x89, 0xf9, 0xae, 0xa1, 0x7b, 0x5e, 0xfd, 0x4d, 0x74, 0x82, 0xaf,
551             0x75, 0x88, 0x1c, 0x0a,
552         ];
553 
554         let hs_full_hash = [
555             0x75, 0x1a, 0x3d, 0x4a, 0x14, 0xdf, 0xab, 0xeb, 0x68, 0xe9, 0x2c, 0xa5, 0x91, 0x8e,
556             0x24, 0x08, 0xb9, 0xbc, 0xb0, 0x74, 0x89, 0x82, 0xec, 0x9c, 0x32, 0x30, 0xac, 0x30,
557             0xbb, 0xeb, 0x23, 0xe2,
558         ];
559 
560         let ecdhe_secret = [
561             0xe7, 0xb8, 0xfe, 0xf8, 0x90, 0x3b, 0x52, 0x0c, 0xb9, 0xa1, 0x89, 0x71, 0xb6, 0x9d,
562             0xd4, 0x5d, 0xca, 0x53, 0xce, 0x2f, 0x12, 0xbf, 0x3b, 0xef, 0x93, 0x15, 0xe3, 0x12,
563             0x71, 0xdf, 0x4b, 0x40,
564         ];
565 
566         let client_hts = [
567             0x61, 0x7b, 0x35, 0x07, 0x6b, 0x9d, 0x0e, 0x08, 0xcf, 0x73, 0x1d, 0x94, 0xa8, 0x66,
568             0x14, 0x78, 0x41, 0x09, 0xef, 0x25, 0x55, 0x51, 0x92, 0x1d, 0xd4, 0x6e, 0x04, 0x01,
569             0x35, 0xcf, 0x46, 0xab,
570         ];
571 
572         let client_hts_key = [
573             0x62, 0xd0, 0xdd, 0x00, 0xf6, 0x96, 0x19, 0xd3, 0xb8, 0x19, 0x3a, 0xb4, 0xa0, 0x95,
574             0x85, 0xa7,
575         ];
576 
577         let client_hts_iv = [
578             0xff, 0xf7, 0x5d, 0xf5, 0xad, 0x35, 0xd5, 0xcb, 0x3c, 0x53, 0xf3, 0xa9,
579         ];
580 
581         let server_hts = [
582             0xfc, 0xf7, 0xdf, 0xe6, 0x4f, 0xa2, 0xc0, 0x4f, 0x62, 0x35, 0x38, 0x7f, 0x43, 0x4e,
583             0x01, 0x42, 0x23, 0x36, 0xd9, 0xc0, 0x39, 0xde, 0x68, 0x47, 0xa0, 0xb9, 0xdd, 0xcf,
584             0x29, 0xa8, 0x87, 0x59,
585         ];
586 
587         let server_hts_key = [
588             0x04, 0x67, 0xf3, 0x16, 0xa8, 0x05, 0xb8, 0xc4, 0x97, 0xee, 0x67, 0x04, 0x7b, 0xbc,
589             0xbc, 0x54,
590         ];
591 
592         let server_hts_iv = [
593             0xde, 0x83, 0xa7, 0x3e, 0x9d, 0x81, 0x4b, 0x04, 0xc4, 0x8b, 0x78, 0x09,
594         ];
595 
596         let client_ats = [
597             0xc1, 0x4a, 0x6d, 0x79, 0x76, 0xd8, 0x10, 0x2b, 0x5a, 0x0c, 0x99, 0x51, 0x49, 0x3f,
598             0xee, 0x87, 0xdc, 0xaf, 0xf8, 0x2c, 0x24, 0xca, 0xb2, 0x14, 0xe8, 0xbe, 0x71, 0xa8,
599             0x20, 0x6d, 0xbd, 0xa5,
600         ];
601 
602         let client_ats_key = [
603             0xcc, 0x9f, 0x5f, 0x98, 0x0b, 0x5f, 0x10, 0x30, 0x6c, 0xba, 0xd7, 0xbe, 0x98, 0xd7,
604             0x57, 0x2e,
605         ];
606 
607         let client_ats_iv = [
608             0xb8, 0x09, 0x29, 0xe8, 0xd0, 0x2c, 0x70, 0xf6, 0x11, 0x62, 0xed, 0x6b,
609         ];
610 
611         let server_ats = [
612             0x2c, 0x90, 0x77, 0x38, 0xd3, 0xf8, 0x37, 0x02, 0xd1, 0xe4, 0x59, 0x8f, 0x48, 0x48,
613             0x53, 0x1d, 0x9f, 0x93, 0x65, 0x49, 0x1b, 0x9f, 0x7f, 0x52, 0xc8, 0x22, 0x29, 0x0d,
614             0x4c, 0x23, 0x21, 0x92,
615         ];
616 
617         let server_ats_key = [
618             0x0c, 0xb2, 0x95, 0x62, 0xd8, 0xd8, 0x8f, 0x48, 0xb0, 0x2c, 0xbf, 0xbe, 0xd7, 0xe6,
619             0x2b, 0xb3,
620         ];
621 
622         let server_ats_iv = [
623             0x0d, 0xb2, 0x8f, 0x98, 0x85, 0x86, 0xa1, 0xb7, 0xe4, 0xd5, 0xc6, 0x9c,
624         ];
625 
626         let hkdf = hkdf::HKDF_SHA256;
627         let mut ks = KeySchedule::new_with_empty_secret(hkdf);
628         ks.input_secret(&ecdhe_secret);
629 
630         assert_traffic_secret(
631             &ks,
632             SecretKind::ClientHandshakeTrafficSecret,
633             &hs_start_hash,
634             &client_hts,
635             &client_hts_key,
636             &client_hts_iv,
637         );
638 
639         assert_traffic_secret(
640             &ks,
641             SecretKind::ServerHandshakeTrafficSecret,
642             &hs_start_hash,
643             &server_hts,
644             &server_hts_key,
645             &server_hts_iv,
646         );
647 
648         ks.input_empty();
649 
650         assert_traffic_secret(
651             &ks,
652             SecretKind::ClientApplicationTrafficSecret,
653             &hs_full_hash,
654             &client_ats,
655             &client_ats_key,
656             &client_ats_iv,
657         );
658 
659         assert_traffic_secret(
660             &ks,
661             SecretKind::ServerApplicationTrafficSecret,
662             &hs_full_hash,
663             &server_ats,
664             &server_ats_key,
665             &server_ats_iv,
666         );
667     }
668 
assert_traffic_secret( ks: &KeySchedule, kind: SecretKind, hash: &[u8], expected_traffic_secret: &[u8], expected_key: &[u8], expected_iv: &[u8], )669     fn assert_traffic_secret(
670         ks: &KeySchedule,
671         kind: SecretKind,
672         hash: &[u8],
673         expected_traffic_secret: &[u8],
674         expected_key: &[u8],
675         expected_iv: &[u8],
676     ) {
677         struct Log<'a>(&'a [u8]);
678         impl KeyLog for Log<'_> {
679             fn log(&self, _label: &str, _client_random: &[u8], secret: &[u8]) {
680                 assert_eq!(self.0, secret);
681             }
682         }
683         let log = Log(expected_traffic_secret);
684         let traffic_secret = ks.derive_logged_secret(kind, &hash, &log, &[0; 32]);
685 
686         // Since we can't test key equality, we test the output of sealing with the key instead.
687         let aead_alg = &aead::AES_128_GCM;
688         let key = derive_traffic_key(&traffic_secret, aead_alg);
689         let seal_output = seal_zeroes(key);
690         let expected_key = aead::UnboundKey::new(aead_alg, expected_key).unwrap();
691         let expected_seal_output = seal_zeroes(expected_key);
692         assert_eq!(seal_output, expected_seal_output);
693         assert!(seal_output.len() >= 48); // Sanity check.
694 
695         let iv = derive_traffic_iv(&traffic_secret);
696         assert_eq!(iv.value(), expected_iv);
697     }
698 
seal_zeroes(key: aead::UnboundKey) -> Vec<u8>699     fn seal_zeroes(key: aead::UnboundKey) -> Vec<u8> {
700         let key = aead::LessSafeKey::new(key);
701         let mut seal_output = vec![0; 32];
702         key.seal_in_place_append_tag(
703             aead::Nonce::assume_unique_for_key([0; aead::NONCE_LEN]),
704             aead::Aad::empty(),
705             &mut seal_output,
706         )
707         .unwrap();
708         seal_output
709     }
710 }
711