1use alloc::boxed::Box;
4use alloc::string::ToString;
5
6use crate::common_state::{CommonState, Side};
7use crate::crypto::cipher::{AeadKey, Iv, MessageDecrypter, Tls13AeadAlgorithm};
8use crate::crypto::tls13::{Hkdf, HkdfExpander, OkmBlock, OutputLengthError, expand};
9use crate::crypto::{SharedSecret, hash, hmac};
10use crate::error::Error;
11use crate::msgs::message::Message;
12use crate::suites::PartiallyExtractedSecrets;
13use crate::{ConnectionTrafficSecrets, KeyLog, Tls13CipherSuite, quic};
14
15#[derive(Debug, Clone, Copy, PartialEq)]
17enum SecretKind {
18 ResumptionPskBinderKey,
19 ClientEarlyTrafficSecret,
20 ClientHandshakeTrafficSecret,
21 ServerHandshakeTrafficSecret,
22 ClientApplicationTrafficSecret,
23 ServerApplicationTrafficSecret,
24 ExporterMasterSecret,
25 ResumptionMasterSecret,
26 DerivedSecret,
27 ServerEchConfirmationSecret,
28 ServerEchHrrConfirmationSecret,
29}
30
31impl SecretKind {
32 fn to_bytes(self) -> &'static [u8] {
33 use self::SecretKind::*;
34 match self {
35 ResumptionPskBinderKey => b"res binder",
36 ClientEarlyTrafficSecret => b"c e traffic",
37 ClientHandshakeTrafficSecret => b"c hs traffic",
38 ServerHandshakeTrafficSecret => b"s hs traffic",
39 ClientApplicationTrafficSecret => b"c ap traffic",
40 ServerApplicationTrafficSecret => b"s ap traffic",
41 ExporterMasterSecret => b"exp master",
42 ResumptionMasterSecret => b"res master",
43 DerivedSecret => b"derived",
44 ServerEchConfirmationSecret => b"ech accept confirmation",
46 ServerEchHrrConfirmationSecret => b"hrr ech accept confirmation",
48 }
49 }
50
51 fn log_label(self) -> Option<&'static str> {
52 use self::SecretKind::*;
53 Some(match self {
54 ClientEarlyTrafficSecret => "CLIENT_EARLY_TRAFFIC_SECRET",
55 ClientHandshakeTrafficSecret => "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
56 ServerHandshakeTrafficSecret => "SERVER_HANDSHAKE_TRAFFIC_SECRET",
57 ClientApplicationTrafficSecret => "CLIENT_TRAFFIC_SECRET_0",
58 ServerApplicationTrafficSecret => "SERVER_TRAFFIC_SECRET_0",
59 ExporterMasterSecret => "EXPORTER_SECRET",
60 _ => {
61 return None;
62 }
63 })
64 }
65}
66
67struct KeySchedule {
71 current: Box<dyn HkdfExpander>,
72 suite: &'static Tls13CipherSuite,
73}
74
75pub(crate) struct KeyScheduleEarly {
89 ks: KeySchedule,
90}
91
92impl KeyScheduleEarly {
93 pub(crate) fn new(suite: &'static Tls13CipherSuite, secret: &[u8]) -> Self {
94 Self {
95 ks: KeySchedule::new(suite, secret),
96 }
97 }
98
99 pub(crate) fn client_early_traffic_secret(
109 &self,
110 hs_hash: &hash::Output,
111 key_log: &dyn KeyLog,
112 client_random: &[u8; 32],
113 common: &mut CommonState,
114 ) {
115 let client_early_traffic_secret = self.ks.derive_logged_secret(
116 SecretKind::ClientEarlyTrafficSecret,
117 hs_hash.as_ref(),
118 key_log,
119 client_random,
120 );
121
122 match common.side {
123 Side::Client => self
124 .ks
125 .set_encrypter(&client_early_traffic_secret, common),
126 Side::Server => self
127 .ks
128 .set_decrypter(&client_early_traffic_secret, common),
129 }
130
131 if common.is_quic() {
132 common.quic.early_secret = Some(client_early_traffic_secret);
135 }
136 }
137
138 pub(crate) fn resumption_psk_binder_key_and_sign_verify_data(
139 &self,
140 hs_hash: &hash::Output,
141 ) -> hmac::Tag {
142 let resumption_psk_binder_key = self
143 .ks
144 .derive_for_empty_hash(SecretKind::ResumptionPskBinderKey);
145 self.ks
146 .sign_verify_data(&resumption_psk_binder_key, hs_hash)
147 }
148}
149
150pub(crate) struct KeySchedulePreHandshake {
174 ks: KeySchedule,
175}
176
177impl KeySchedulePreHandshake {
178 pub(crate) fn new(suite: &'static Tls13CipherSuite) -> Self {
180 Self {
181 ks: KeySchedule::new_with_empty_secret(suite),
182 }
183 }
184
185 pub(crate) fn into_handshake(
192 mut self,
193 shared_secret: SharedSecret,
194 ) -> KeyScheduleHandshakeStart {
195 self.ks
196 .input_secret(shared_secret.secret_bytes());
197 KeyScheduleHandshakeStart { ks: self.ks }
198 }
199}
200
201impl From<KeyScheduleEarly> for KeySchedulePreHandshake {
203 fn from(KeyScheduleEarly { ks }: KeyScheduleEarly) -> Self {
204 Self { ks }
205 }
206}
207
208pub(crate) struct KeyScheduleHandshakeStart {
212 ks: KeySchedule,
213}
214
215impl KeyScheduleHandshakeStart {
216 pub(crate) fn derive_client_handshake_secrets(
217 mut self,
218 early_data_enabled: bool,
219 hs_hash: hash::Output,
220 suite: &'static Tls13CipherSuite,
221 key_log: &dyn KeyLog,
222 client_random: &[u8; 32],
223 common: &mut CommonState,
224 ) -> KeyScheduleHandshake {
225 debug_assert_eq!(common.side, Side::Client);
226 self.ks.suite = suite;
228 let new = self.into_handshake(hs_hash, key_log, client_random, common);
229
230 new.ks
232 .set_decrypter(&new.server_handshake_traffic_secret, common);
233
234 if !early_data_enabled {
235 new.ks
237 .set_encrypter(&new.client_handshake_traffic_secret, common);
238 }
239
240 new
241 }
242
243 pub(crate) fn derive_server_handshake_secrets(
244 self,
245 hs_hash: hash::Output,
246 key_log: &dyn KeyLog,
247 client_random: &[u8; 32],
248 common: &mut CommonState,
249 ) -> KeyScheduleHandshake {
250 debug_assert_eq!(common.side, Side::Server);
251 let new = self.into_handshake(hs_hash, key_log, client_random, common);
252
253 new.ks
257 .set_encrypter(&new.server_handshake_traffic_secret, common);
258 new
259 }
260
261 pub(crate) fn server_ech_confirmation_secret(
262 &mut self,
263 client_hello_inner_random: &[u8],
264 hs_hash: hash::Output,
265 ) -> [u8; 8] {
266 hkdf_expand_label(
275 self.ks
276 .suite
277 .hkdf_provider
278 .extract_from_secret(None, client_hello_inner_random)
279 .as_ref(),
280 SecretKind::ServerEchConfirmationSecret.to_bytes(),
281 hs_hash.as_ref(),
282 )
283 }
284
285 fn into_handshake(
286 self,
287 hs_hash: hash::Output,
288 key_log: &dyn KeyLog,
289 client_random: &[u8; 32],
290 common: &mut CommonState,
291 ) -> KeyScheduleHandshake {
292 let client_secret = self.ks.derive_logged_secret(
294 SecretKind::ClientHandshakeTrafficSecret,
295 hs_hash.as_ref(),
296 key_log,
297 client_random,
298 );
299
300 let server_secret = self.ks.derive_logged_secret(
301 SecretKind::ServerHandshakeTrafficSecret,
302 hs_hash.as_ref(),
303 key_log,
304 client_random,
305 );
306
307 if common.is_quic() {
308 common.quic.hs_secrets = Some(quic::Secrets::new(
309 client_secret.clone(),
310 server_secret.clone(),
311 self.ks.suite,
312 self.ks.suite.quic.unwrap(),
313 common.side,
314 common.quic.version,
315 ));
316 }
317
318 KeyScheduleHandshake {
319 ks: self.ks,
320 client_handshake_traffic_secret: client_secret,
321 server_handshake_traffic_secret: server_secret,
322 }
323 }
324}
325
326pub(crate) struct KeyScheduleHandshake {
327 ks: KeySchedule,
328 client_handshake_traffic_secret: OkmBlock,
329 server_handshake_traffic_secret: OkmBlock,
330}
331
332impl KeyScheduleHandshake {
333 pub(crate) fn sign_server_finish(&self, hs_hash: &hash::Output) -> hmac::Tag {
334 self.ks
335 .sign_finish(&self.server_handshake_traffic_secret, hs_hash)
336 }
337
338 pub(crate) fn set_handshake_encrypter(&self, common: &mut CommonState) {
339 debug_assert_eq!(common.side, Side::Client);
340 self.ks
341 .set_encrypter(&self.client_handshake_traffic_secret, common);
342 }
343
344 pub(crate) fn set_handshake_decrypter(
345 &self,
346 skip_requested: Option<usize>,
347 common: &mut CommonState,
348 ) {
349 debug_assert_eq!(common.side, Side::Server);
350 let secret = &self.client_handshake_traffic_secret;
351 match skip_requested {
352 None => self.ks.set_decrypter(secret, common),
353 Some(max_early_data_size) => common
354 .record_layer
355 .set_message_decrypter_with_trial_decryption(
356 self.ks
357 .derive_decrypter(&self.client_handshake_traffic_secret),
358 max_early_data_size,
359 ),
360 }
361 }
362
363 pub(crate) fn into_traffic_with_client_finished_pending(
364 self,
365 hs_hash: hash::Output,
366 key_log: &dyn KeyLog,
367 client_random: &[u8; 32],
368 common: &mut CommonState,
369 ) -> KeyScheduleTrafficWithClientFinishedPending {
370 debug_assert_eq!(common.side, Side::Server);
371
372 let traffic = KeyScheduleTraffic::new(self.ks, hs_hash, key_log, client_random);
373 let (_client_secret, server_secret) = (
374 &traffic.current_client_traffic_secret,
375 &traffic.current_server_traffic_secret,
376 );
377
378 traffic
379 .ks
380 .set_encrypter(server_secret, common);
381
382 if common.is_quic() {
383 common.quic.traffic_secrets = Some(quic::Secrets::new(
384 _client_secret.clone(),
385 server_secret.clone(),
386 traffic.ks.suite,
387 traffic.ks.suite.quic.unwrap(),
388 common.side,
389 common.quic.version,
390 ));
391 }
392
393 KeyScheduleTrafficWithClientFinishedPending {
394 handshake_client_traffic_secret: self.client_handshake_traffic_secret,
395 traffic,
396 }
397 }
398
399 pub(crate) fn into_pre_finished_client_traffic(
400 self,
401 pre_finished_hash: hash::Output,
402 handshake_hash: hash::Output,
403 key_log: &dyn KeyLog,
404 client_random: &[u8; 32],
405 ) -> (KeyScheduleClientBeforeFinished, hmac::Tag) {
406 let traffic = KeyScheduleTraffic::new(self.ks, pre_finished_hash, key_log, client_random);
407 let tag = traffic
408 .ks
409 .sign_finish(&self.client_handshake_traffic_secret, &handshake_hash);
410 (KeyScheduleClientBeforeFinished { traffic }, tag)
411 }
412}
413
414pub(crate) struct KeyScheduleClientBeforeFinished {
415 traffic: KeyScheduleTraffic,
416}
417
418impl KeyScheduleClientBeforeFinished {
419 pub(crate) fn into_traffic(self, common: &mut CommonState) -> KeyScheduleTraffic {
420 debug_assert_eq!(common.side, Side::Client);
421 let (client_secret, server_secret) = (
422 &self
423 .traffic
424 .current_client_traffic_secret,
425 &self
426 .traffic
427 .current_server_traffic_secret,
428 );
429
430 self.traffic
431 .ks
432 .set_decrypter(server_secret, common);
433 self.traffic
434 .ks
435 .set_encrypter(client_secret, common);
436
437 if common.is_quic() {
438 common.quic.traffic_secrets = Some(quic::Secrets::new(
439 client_secret.clone(),
440 server_secret.clone(),
441 self.traffic.ks.suite,
442 self.traffic.ks.suite.quic.unwrap(),
443 common.side,
444 common.quic.version,
445 ));
446 }
447
448 self.traffic
449 }
450}
451
452pub(crate) struct KeyScheduleTrafficWithClientFinishedPending {
456 handshake_client_traffic_secret: OkmBlock,
457 traffic: KeyScheduleTraffic,
458}
459
460impl KeyScheduleTrafficWithClientFinishedPending {
461 pub(crate) fn update_decrypter(&self, common: &mut CommonState) {
462 debug_assert_eq!(common.side, Side::Server);
463 self.traffic
464 .ks
465 .set_decrypter(&self.handshake_client_traffic_secret, common);
466 }
467
468 pub(crate) fn sign_client_finish(
469 self,
470 hs_hash: &hash::Output,
471 common: &mut CommonState,
472 ) -> (KeyScheduleTraffic, hmac::Tag) {
473 debug_assert_eq!(common.side, Side::Server);
474 let tag = self
475 .traffic
476 .ks
477 .sign_finish(&self.handshake_client_traffic_secret, hs_hash);
478
479 self.traffic.ks.set_decrypter(
481 &self
482 .traffic
483 .current_client_traffic_secret,
484 common,
485 );
486
487 (self.traffic, tag)
488 }
489}
490
491pub(crate) struct KeyScheduleTraffic {
494 ks: KeySchedule,
495 current_client_traffic_secret: OkmBlock,
496 current_server_traffic_secret: OkmBlock,
497 current_exporter_secret: OkmBlock,
498}
499
500impl KeyScheduleTraffic {
501 fn new(
502 mut ks: KeySchedule,
503 hs_hash: hash::Output,
504 key_log: &dyn KeyLog,
505 client_random: &[u8; 32],
506 ) -> Self {
507 ks.input_empty();
508
509 let current_client_traffic_secret = ks.derive_logged_secret(
510 SecretKind::ClientApplicationTrafficSecret,
511 hs_hash.as_ref(),
512 key_log,
513 client_random,
514 );
515
516 let current_server_traffic_secret = ks.derive_logged_secret(
517 SecretKind::ServerApplicationTrafficSecret,
518 hs_hash.as_ref(),
519 key_log,
520 client_random,
521 );
522
523 let current_exporter_secret = ks.derive_logged_secret(
524 SecretKind::ExporterMasterSecret,
525 hs_hash.as_ref(),
526 key_log,
527 client_random,
528 );
529
530 Self {
531 ks,
532 current_client_traffic_secret,
533 current_server_traffic_secret,
534 current_exporter_secret,
535 }
536 }
537
538 pub(crate) fn update_encrypter_and_notify(&mut self, common: &mut CommonState) {
539 let secret = self.next_application_traffic_secret(common.side);
540 common.enqueue_key_update_notification();
541 self.ks.set_encrypter(&secret, common);
542 }
543
544 pub(crate) fn request_key_update_and_update_encrypter(
545 &mut self,
546 common: &mut CommonState,
547 ) -> Result<(), Error> {
548 common.check_aligned_handshake()?;
549 common.send_msg_encrypt(Message::build_key_update_request().into());
550 let secret = self.next_application_traffic_secret(common.side);
551 self.ks.set_encrypter(&secret, common);
552 Ok(())
553 }
554
555 pub(crate) fn update_decrypter(&mut self, common: &mut CommonState) {
556 let secret = self.next_application_traffic_secret(common.side.peer());
557 self.ks.set_decrypter(&secret, common);
558 }
559
560 pub(crate) fn next_application_traffic_secret(&mut self, side: Side) -> OkmBlock {
561 let current = match side {
562 Side::Client => &mut self.current_client_traffic_secret,
563 Side::Server => &mut self.current_server_traffic_secret,
564 };
565
566 let secret = self.ks.derive_next(current);
567 *current = secret.clone();
568 secret
569 }
570
571 pub(crate) fn export_keying_material(
572 &self,
573 out: &mut [u8],
574 label: &[u8],
575 context: Option<&[u8]>,
576 ) -> Result<(), Error> {
577 self.ks
578 .export_keying_material(&self.current_exporter_secret, out, label, context)
579 }
580
581 pub(crate) fn refresh_traffic_secret(
582 &mut self,
583 side: Side,
584 ) -> Result<ConnectionTrafficSecrets, Error> {
585 let secret = self.next_application_traffic_secret(side);
586 let (key, iv) = expand_secret(
587 &secret,
588 self.ks.suite.hkdf_provider,
589 self.ks.suite.aead_alg.key_len(),
590 );
591 Ok(self
592 .ks
593 .suite
594 .aead_alg
595 .extract_keys(key, iv)?)
596 }
597
598 pub(crate) fn extract_secrets(&self, side: Side) -> Result<PartiallyExtractedSecrets, Error> {
599 let (client_key, client_iv) = expand_secret(
600 &self.current_client_traffic_secret,
601 self.ks.suite.hkdf_provider,
602 self.ks.suite.aead_alg.key_len(),
603 );
604 let (server_key, server_iv) = expand_secret(
605 &self.current_server_traffic_secret,
606 self.ks.suite.hkdf_provider,
607 self.ks.suite.aead_alg.key_len(),
608 );
609 let client_secrets = self
610 .ks
611 .suite
612 .aead_alg
613 .extract_keys(client_key, client_iv)?;
614 let server_secrets = self
615 .ks
616 .suite
617 .aead_alg
618 .extract_keys(server_key, server_iv)?;
619
620 let (tx, rx) = match side {
621 Side::Client => (client_secrets, server_secrets),
622 Side::Server => (server_secrets, client_secrets),
623 };
624 Ok(PartiallyExtractedSecrets { tx, rx })
625 }
626}
627
628fn expand_secret(secret: &OkmBlock, hkdf: &'static dyn Hkdf, aead_key_len: usize) -> (AeadKey, Iv) {
629 let expander = hkdf.expander_for_okm(secret);
630
631 (
632 hkdf_expand_label_aead_key(expander.as_ref(), aead_key_len, b"key", &[]),
633 hkdf_expand_label(expander.as_ref(), b"iv", &[]),
634 )
635}
636
637pub(crate) struct ResumptionSecret<'a> {
638 kst: &'a KeyScheduleTraffic,
639 resumption_master_secret: OkmBlock,
640}
641
642impl<'a> ResumptionSecret<'a> {
643 pub(crate) fn new(kst: &'a KeyScheduleTraffic, hs_hash: &hash::Output) -> Self {
644 ResumptionSecret {
645 kst,
646 resumption_master_secret: kst
647 .ks
648 .derive(SecretKind::ResumptionMasterSecret, hs_hash.as_ref()),
649 }
650 }
651
652 pub(crate) fn derive_ticket_psk(&self, nonce: &[u8]) -> OkmBlock {
653 self.kst
654 .ks
655 .derive_ticket_psk(&self.resumption_master_secret, nonce)
656 }
657}
658
659impl KeySchedule {
660 fn new(suite: &'static Tls13CipherSuite, secret: &[u8]) -> Self {
661 Self {
662 current: suite
663 .hkdf_provider
664 .extract_from_secret(None, secret),
665 suite,
666 }
667 }
668
669 fn set_encrypter(&self, secret: &OkmBlock, common: &mut CommonState) {
670 let expander = self
671 .suite
672 .hkdf_provider
673 .expander_for_okm(secret);
674 let key = derive_traffic_key(expander.as_ref(), self.suite.aead_alg);
675 let iv = derive_traffic_iv(expander.as_ref());
676
677 common
678 .record_layer
679 .set_message_encrypter(
680 self.suite.aead_alg.encrypter(key, iv),
681 self.suite.common.confidentiality_limit,
682 );
683 }
684
685 fn set_decrypter(&self, secret: &OkmBlock, common: &mut CommonState) {
686 common
687 .record_layer
688 .set_message_decrypter(self.derive_decrypter(secret));
689 }
690
691 fn derive_decrypter(&self, secret: &OkmBlock) -> Box<dyn MessageDecrypter> {
692 let expander = self
693 .suite
694 .hkdf_provider
695 .expander_for_okm(secret);
696 let key = derive_traffic_key(expander.as_ref(), self.suite.aead_alg);
697 let iv = derive_traffic_iv(expander.as_ref());
698 self.suite.aead_alg.decrypter(key, iv)
699 }
700
701 fn new_with_empty_secret(suite: &'static Tls13CipherSuite) -> Self {
703 Self {
704 current: suite
705 .hkdf_provider
706 .extract_from_zero_ikm(None),
707 suite,
708 }
709 }
710
711 fn input_empty(&mut self) {
717 let salt = self.derive_for_empty_hash(SecretKind::DerivedSecret);
718 self.current = self
719 .suite
720 .hkdf_provider
721 .extract_from_zero_ikm(Some(salt.as_ref()));
722 }
723
724 fn input_secret(&mut self, secret: &[u8]) {
726 let salt = self.derive_for_empty_hash(SecretKind::DerivedSecret);
727 self.current = self
728 .suite
729 .hkdf_provider
730 .extract_from_secret(Some(salt.as_ref()), secret);
731 }
732
733 fn derive(&self, kind: SecretKind, hs_hash: &[u8]) -> OkmBlock {
741 hkdf_expand_label_block(self.current.as_ref(), kind.to_bytes(), hs_hash)
742 }
743
744 fn derive_logged_secret(
745 &self,
746 kind: SecretKind,
747 hs_hash: &[u8],
748 key_log: &dyn KeyLog,
749 client_random: &[u8; 32],
750 ) -> OkmBlock {
751 let output = self.derive(kind, hs_hash);
752
753 let log_label = kind
754 .log_label()
755 .expect("not a loggable secret");
756 if key_log.will_log(log_label) {
757 key_log.log(log_label, client_random, output.as_ref());
758 }
759 output
760 }
761
762 fn derive_for_empty_hash(&self, kind: SecretKind) -> OkmBlock {
776 let empty_hash = self
777 .suite
778 .common
779 .hash_provider
780 .start()
781 .finish();
782 self.derive(kind, empty_hash.as_ref())
783 }
784
785 fn sign_finish(&self, base_key: &OkmBlock, hs_hash: &hash::Output) -> hmac::Tag {
790 self.sign_verify_data(base_key, hs_hash)
791 }
792
793 fn sign_verify_data(&self, base_key: &OkmBlock, hs_hash: &hash::Output) -> hmac::Tag {
798 let expander = self
799 .suite
800 .hkdf_provider
801 .expander_for_okm(base_key);
802 let hmac_key = hkdf_expand_label_block(expander.as_ref(), b"finished", &[]);
803
804 self.suite
805 .hkdf_provider
806 .hmac_sign(&hmac_key, hs_hash.as_ref())
807 }
808
809 fn derive_next(&self, base_key: &OkmBlock) -> OkmBlock {
811 let expander = self
812 .suite
813 .hkdf_provider
814 .expander_for_okm(base_key);
815 hkdf_expand_label_block(expander.as_ref(), b"traffic upd", &[])
816 }
817
818 fn derive_ticket_psk(&self, rms: &OkmBlock, nonce: &[u8]) -> OkmBlock {
821 let expander = self
822 .suite
823 .hkdf_provider
824 .expander_for_okm(rms);
825 hkdf_expand_label_block(expander.as_ref(), b"resumption", nonce)
826 }
827
828 fn export_keying_material(
829 &self,
830 current_exporter_secret: &OkmBlock,
831 out: &mut [u8],
832 label: &[u8],
833 context: Option<&[u8]>,
834 ) -> Result<(), Error> {
835 let secret = {
836 let h_empty = self
837 .suite
838 .common
839 .hash_provider
840 .hash(&[]);
841
842 let expander = self
843 .suite
844 .hkdf_provider
845 .expander_for_okm(current_exporter_secret);
846 hkdf_expand_label_block(expander.as_ref(), label, h_empty.as_ref())
847 };
848
849 let h_context = self
850 .suite
851 .common
852 .hash_provider
853 .hash(context.unwrap_or(&[]));
854
855 let expander = self
856 .suite
857 .hkdf_provider
858 .expander_for_okm(&secret);
859 hkdf_expand_label_slice(expander.as_ref(), b"exporter", h_context.as_ref(), out)
860 .map_err(|_| Error::General("exporting too much".to_string()))
861 }
862}
863
864pub fn derive_traffic_key(
868 expander: &dyn HkdfExpander,
869 aead_alg: &dyn Tls13AeadAlgorithm,
870) -> AeadKey {
871 hkdf_expand_label_aead_key(expander, aead_alg.key_len(), b"key", &[])
872}
873
874pub fn derive_traffic_iv(expander: &dyn HkdfExpander) -> Iv {
878 hkdf_expand_label(expander, b"iv", &[])
879}
880
881pub(crate) fn hkdf_expand_label<T: From<[u8; N]>, const N: usize>(
886 expander: &dyn HkdfExpander,
887 label: &[u8],
888 context: &[u8],
889) -> T {
890 hkdf_expand_label_inner(expander, label, context, N, |e, info| expand(e, info))
891}
892
893pub(crate) fn hkdf_expand_label_block(
895 expander: &dyn HkdfExpander,
896 label: &[u8],
897 context: &[u8],
898) -> OkmBlock {
899 hkdf_expand_label_inner(expander, label, context, expander.hash_len(), |e, info| {
900 e.expand_block(info)
901 })
902}
903
904pub(crate) fn hkdf_expand_label_aead_key(
906 expander: &dyn HkdfExpander,
907 key_len: usize,
908 label: &[u8],
909 context: &[u8],
910) -> AeadKey {
911 hkdf_expand_label_inner(expander, label, context, key_len, |e, info| {
912 let key: AeadKey = expand(e, info);
913 key.with_length(key_len)
914 })
915}
916
917fn hkdf_expand_label_slice(
921 expander: &dyn HkdfExpander,
922 label: &[u8],
923 context: &[u8],
924 output: &mut [u8],
925) -> Result<(), OutputLengthError> {
926 hkdf_expand_label_inner(expander, label, context, output.len(), |e, info| {
927 e.expand_slice(info, output)
928 })
929}
930
931pub(crate) fn server_ech_hrr_confirmation_secret(
932 hkdf_provider: &'static dyn Hkdf,
933 client_hello_inner_random: &[u8],
934 hs_hash: hash::Output,
935) -> [u8; 8] {
936 hkdf_expand_label(
946 hkdf_provider
947 .extract_from_secret(None, client_hello_inner_random)
948 .as_ref(),
949 SecretKind::ServerEchHrrConfirmationSecret.to_bytes(),
950 hs_hash.as_ref(),
951 )
952}
953
954fn hkdf_expand_label_inner<F, T>(
955 expander: &dyn HkdfExpander,
956 label: &[u8],
957 context: &[u8],
958 n: usize,
959 f: F,
960) -> T
961where
962 F: FnOnce(&dyn HkdfExpander, &[&[u8]]) -> T,
963{
964 const LABEL_PREFIX: &[u8] = b"tls13 ";
965
966 let output_len = u16::to_be_bytes(n as u16);
967 let label_len = u8::to_be_bytes((LABEL_PREFIX.len() + label.len()) as u8);
968 let context_len = u8::to_be_bytes(context.len() as u8);
969
970 let info = &[
971 &output_len[..],
972 &label_len[..],
973 LABEL_PREFIX,
974 label,
975 &context_len[..],
976 context,
977 ];
978
979 f(expander, info)
980}
981
982#[cfg(test)]
983#[macro_rules_attribute::apply(test_for_each_provider)]
984mod tests {
985 use core::fmt::Debug;
986 use std::prelude::v1::*;
987 use std::vec;
988
989 use super::provider::ring_like::aead;
990 use super::provider::tls13::{
991 TLS13_AES_128_GCM_SHA256_INTERNAL, TLS13_CHACHA20_POLY1305_SHA256_INTERNAL,
992 };
993 use super::{KeySchedule, SecretKind, derive_traffic_iv, derive_traffic_key};
994 use crate::KeyLog;
995
996 #[test]
997 fn test_vectors() {
998 let hs_start_hash = [
1000 0xec, 0x14, 0x7a, 0x06, 0xde, 0xa3, 0xc8, 0x84, 0x6c, 0x02, 0xb2, 0x23, 0x8e, 0x41,
1001 0xbd, 0xdc, 0x9d, 0x89, 0xf9, 0xae, 0xa1, 0x7b, 0x5e, 0xfd, 0x4d, 0x74, 0x82, 0xaf,
1002 0x75, 0x88, 0x1c, 0x0a,
1003 ];
1004
1005 let hs_full_hash = [
1006 0x75, 0x1a, 0x3d, 0x4a, 0x14, 0xdf, 0xab, 0xeb, 0x68, 0xe9, 0x2c, 0xa5, 0x91, 0x8e,
1007 0x24, 0x08, 0xb9, 0xbc, 0xb0, 0x74, 0x89, 0x82, 0xec, 0x9c, 0x32, 0x30, 0xac, 0x30,
1008 0xbb, 0xeb, 0x23, 0xe2,
1009 ];
1010
1011 let ecdhe_secret = [
1012 0xe7, 0xb8, 0xfe, 0xf8, 0x90, 0x3b, 0x52, 0x0c, 0xb9, 0xa1, 0x89, 0x71, 0xb6, 0x9d,
1013 0xd4, 0x5d, 0xca, 0x53, 0xce, 0x2f, 0x12, 0xbf, 0x3b, 0xef, 0x93, 0x15, 0xe3, 0x12,
1014 0x71, 0xdf, 0x4b, 0x40,
1015 ];
1016
1017 let client_hts = [
1018 0x61, 0x7b, 0x35, 0x07, 0x6b, 0x9d, 0x0e, 0x08, 0xcf, 0x73, 0x1d, 0x94, 0xa8, 0x66,
1019 0x14, 0x78, 0x41, 0x09, 0xef, 0x25, 0x55, 0x51, 0x92, 0x1d, 0xd4, 0x6e, 0x04, 0x01,
1020 0x35, 0xcf, 0x46, 0xab,
1021 ];
1022
1023 let client_hts_key = [
1024 0x62, 0xd0, 0xdd, 0x00, 0xf6, 0x96, 0x19, 0xd3, 0xb8, 0x19, 0x3a, 0xb4, 0xa0, 0x95,
1025 0x85, 0xa7,
1026 ];
1027
1028 let client_hts_iv = [
1029 0xff, 0xf7, 0x5d, 0xf5, 0xad, 0x35, 0xd5, 0xcb, 0x3c, 0x53, 0xf3, 0xa9,
1030 ];
1031
1032 let server_hts = [
1033 0xfc, 0xf7, 0xdf, 0xe6, 0x4f, 0xa2, 0xc0, 0x4f, 0x62, 0x35, 0x38, 0x7f, 0x43, 0x4e,
1034 0x01, 0x42, 0x23, 0x36, 0xd9, 0xc0, 0x39, 0xde, 0x68, 0x47, 0xa0, 0xb9, 0xdd, 0xcf,
1035 0x29, 0xa8, 0x87, 0x59,
1036 ];
1037
1038 let server_hts_key = [
1039 0x04, 0x67, 0xf3, 0x16, 0xa8, 0x05, 0xb8, 0xc4, 0x97, 0xee, 0x67, 0x04, 0x7b, 0xbc,
1040 0xbc, 0x54,
1041 ];
1042
1043 let server_hts_iv = [
1044 0xde, 0x83, 0xa7, 0x3e, 0x9d, 0x81, 0x4b, 0x04, 0xc4, 0x8b, 0x78, 0x09,
1045 ];
1046
1047 let client_ats = [
1048 0xc1, 0x4a, 0x6d, 0x79, 0x76, 0xd8, 0x10, 0x2b, 0x5a, 0x0c, 0x99, 0x51, 0x49, 0x3f,
1049 0xee, 0x87, 0xdc, 0xaf, 0xf8, 0x2c, 0x24, 0xca, 0xb2, 0x14, 0xe8, 0xbe, 0x71, 0xa8,
1050 0x20, 0x6d, 0xbd, 0xa5,
1051 ];
1052
1053 let client_ats_key = [
1054 0xcc, 0x9f, 0x5f, 0x98, 0x0b, 0x5f, 0x10, 0x30, 0x6c, 0xba, 0xd7, 0xbe, 0x98, 0xd7,
1055 0x57, 0x2e,
1056 ];
1057
1058 let client_ats_iv = [
1059 0xb8, 0x09, 0x29, 0xe8, 0xd0, 0x2c, 0x70, 0xf6, 0x11, 0x62, 0xed, 0x6b,
1060 ];
1061
1062 let server_ats = [
1063 0x2c, 0x90, 0x77, 0x38, 0xd3, 0xf8, 0x37, 0x02, 0xd1, 0xe4, 0x59, 0x8f, 0x48, 0x48,
1064 0x53, 0x1d, 0x9f, 0x93, 0x65, 0x49, 0x1b, 0x9f, 0x7f, 0x52, 0xc8, 0x22, 0x29, 0x0d,
1065 0x4c, 0x23, 0x21, 0x92,
1066 ];
1067
1068 let server_ats_key = [
1069 0x0c, 0xb2, 0x95, 0x62, 0xd8, 0xd8, 0x8f, 0x48, 0xb0, 0x2c, 0xbf, 0xbe, 0xd7, 0xe6,
1070 0x2b, 0xb3,
1071 ];
1072
1073 let server_ats_iv = [
1074 0x0d, 0xb2, 0x8f, 0x98, 0x85, 0x86, 0xa1, 0xb7, 0xe4, 0xd5, 0xc6, 0x9c,
1075 ];
1076
1077 let mut ks = KeySchedule::new_with_empty_secret(TLS13_CHACHA20_POLY1305_SHA256_INTERNAL);
1078 ks.input_secret(&ecdhe_secret);
1079
1080 assert_traffic_secret(
1081 &ks,
1082 SecretKind::ClientHandshakeTrafficSecret,
1083 &hs_start_hash,
1084 &client_hts,
1085 &client_hts_key,
1086 &client_hts_iv,
1087 );
1088
1089 assert_traffic_secret(
1090 &ks,
1091 SecretKind::ServerHandshakeTrafficSecret,
1092 &hs_start_hash,
1093 &server_hts,
1094 &server_hts_key,
1095 &server_hts_iv,
1096 );
1097
1098 ks.input_empty();
1099
1100 assert_traffic_secret(
1101 &ks,
1102 SecretKind::ClientApplicationTrafficSecret,
1103 &hs_full_hash,
1104 &client_ats,
1105 &client_ats_key,
1106 &client_ats_iv,
1107 );
1108
1109 assert_traffic_secret(
1110 &ks,
1111 SecretKind::ServerApplicationTrafficSecret,
1112 &hs_full_hash,
1113 &server_ats,
1114 &server_ats_key,
1115 &server_ats_iv,
1116 );
1117 }
1118
1119 fn assert_traffic_secret(
1120 ks: &KeySchedule,
1121 kind: SecretKind,
1122 hash: &[u8],
1123 expected_traffic_secret: &[u8],
1124 expected_key: &[u8],
1125 expected_iv: &[u8],
1126 ) {
1127 #[derive(Debug)]
1128 struct Log<'a>(&'a [u8]);
1129 impl KeyLog for Log<'_> {
1130 fn log(&self, _label: &str, _client_random: &[u8], secret: &[u8]) {
1131 assert_eq!(self.0, secret);
1132 }
1133 }
1134 let log = Log(expected_traffic_secret);
1135 let traffic_secret = ks.derive_logged_secret(kind, hash, &log, &[0; 32]);
1136
1137 let aead_alg = &aead::AES_128_GCM;
1139 let expander = TLS13_AES_128_GCM_SHA256_INTERNAL
1140 .hkdf_provider
1141 .expander_for_okm(&traffic_secret);
1142 let key = derive_traffic_key(
1143 expander.as_ref(),
1144 TLS13_AES_128_GCM_SHA256_INTERNAL.aead_alg,
1145 );
1146 let key = aead::UnboundKey::new(aead_alg, key.as_ref()).unwrap();
1147 let seal_output = seal_zeroes(key);
1148 let expected_key = aead::UnboundKey::new(aead_alg, expected_key).unwrap();
1149 let expected_seal_output = seal_zeroes(expected_key);
1150 assert_eq!(seal_output, expected_seal_output);
1151 assert!(seal_output.len() >= 48); let iv = derive_traffic_iv(expander.as_ref());
1154 assert_eq!(iv.as_ref(), expected_iv);
1155 }
1156
1157 fn seal_zeroes(key: aead::UnboundKey) -> Vec<u8> {
1158 let key = aead::LessSafeKey::new(key);
1159 let mut seal_output = vec![0; 32];
1160 key.seal_in_place_append_tag(
1161 aead::Nonce::assume_unique_for_key([0; aead::NONCE_LEN]),
1162 aead::Aad::empty(),
1163 &mut seal_output,
1164 )
1165 .unwrap();
1166 seal_output
1167 }
1168}
1169
1170#[cfg(all(test, bench))]
1171#[macro_rules_attribute::apply(bench_for_each_provider)]
1172mod benchmarks {
1173 #[bench]
1174 fn bench_sha256(b: &mut test::Bencher) {
1175 use core::fmt::Debug;
1176
1177 use super::provider::tls13::TLS13_CHACHA20_POLY1305_SHA256_INTERNAL;
1178 use super::{KeySchedule, SecretKind, derive_traffic_iv, derive_traffic_key};
1179 use crate::KeyLog;
1180
1181 fn extract_traffic_secret(ks: &KeySchedule, kind: SecretKind) {
1182 #[derive(Debug)]
1183 struct Log;
1184
1185 impl KeyLog for Log {
1186 fn log(&self, _label: &str, _client_random: &[u8], _secret: &[u8]) {}
1187 }
1188
1189 let hash = [0u8; 32];
1190 let traffic_secret = ks.derive_logged_secret(kind, &hash, &Log, &[0u8; 32]);
1191 let traffic_secret_expander = TLS13_CHACHA20_POLY1305_SHA256_INTERNAL
1192 .hkdf_provider
1193 .expander_for_okm(&traffic_secret);
1194 test::black_box(derive_traffic_key(
1195 traffic_secret_expander.as_ref(),
1196 TLS13_CHACHA20_POLY1305_SHA256_INTERNAL.aead_alg,
1197 ));
1198 test::black_box(derive_traffic_iv(traffic_secret_expander.as_ref()));
1199 }
1200
1201 b.iter(|| {
1202 let mut ks =
1203 KeySchedule::new_with_empty_secret(TLS13_CHACHA20_POLY1305_SHA256_INTERNAL);
1204 ks.input_secret(&[0u8; 32]);
1205
1206 extract_traffic_secret(&ks, SecretKind::ClientHandshakeTrafficSecret);
1207 extract_traffic_secret(&ks, SecretKind::ServerHandshakeTrafficSecret);
1208
1209 ks.input_empty();
1210
1211 extract_traffic_secret(&ks, SecretKind::ClientApplicationTrafficSecret);
1212 extract_traffic_secret(&ks, SecretKind::ServerApplicationTrafficSecret);
1213 });
1214 }
1215}