rustls/tls13/
key_schedule.rs

1use crate::cipher::{Iv, IvLen, MessageDecrypter};
2use crate::common_state::{CommonState, Side};
3use crate::error::Error;
4use crate::msgs::base::PayloadU8;
5#[cfg(feature = "quic")]
6use crate::quic;
7#[cfg(feature = "secret_extraction")]
8use crate::suites::{ConnectionTrafficSecrets, PartiallyExtractedSecrets};
9use crate::{KeyLog, Tls13CipherSuite};
10
11/// Key schedule maintenance for TLS1.3
12use ring::{
13    aead,
14    digest::{self, Digest},
15    hkdf::{self, KeyType as _},
16    hmac,
17};
18
19use super::{Tls13MessageDecrypter, Tls13MessageEncrypter};
20
21/// The kinds of secret we can extract from `KeySchedule`.
22#[derive(Debug, Clone, Copy, PartialEq)]
23enum SecretKind {
24    ResumptionPskBinderKey,
25    ClientEarlyTrafficSecret,
26    ClientHandshakeTrafficSecret,
27    ServerHandshakeTrafficSecret,
28    ClientApplicationTrafficSecret,
29    ServerApplicationTrafficSecret,
30    ExporterMasterSecret,
31    ResumptionMasterSecret,
32    DerivedSecret,
33}
34
35impl SecretKind {
36    fn to_bytes(self) -> &'static [u8] {
37        use self::SecretKind::*;
38        match self {
39            ResumptionPskBinderKey => b"res binder",
40            ClientEarlyTrafficSecret => b"c e traffic",
41            ClientHandshakeTrafficSecret => b"c hs traffic",
42            ServerHandshakeTrafficSecret => b"s hs traffic",
43            ClientApplicationTrafficSecret => b"c ap traffic",
44            ServerApplicationTrafficSecret => b"s ap traffic",
45            ExporterMasterSecret => b"exp master",
46            ResumptionMasterSecret => b"res master",
47            DerivedSecret => b"derived",
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
67/// This is the TLS1.3 key schedule.  It stores the current secret and
68/// the type of hash.  This isn't used directly; but only through the
69/// typestates.
70struct KeySchedule {
71    current: hkdf::Prk,
72    suite: &'static Tls13CipherSuite,
73}
74
75// We express the state of a contained KeySchedule using these
76// typestates.  This means we can write code that cannot accidentally
77// (e.g.) encrypt application data using a KeySchedule solely constructed
78// with an empty or trivial secret, or extract the wrong kind of secrets
79// at a given point.
80
81/// KeySchedule for early data stage.
82pub(crate) struct KeyScheduleEarly {
83    ks: KeySchedule,
84}
85
86impl KeyScheduleEarly {
87    pub(crate) fn new(suite: &'static Tls13CipherSuite, secret: &[u8]) -> Self {
88        Self {
89            ks: KeySchedule::new(suite, secret),
90        }
91    }
92
93    pub(crate) fn client_early_traffic_secret(
94        &self,
95        hs_hash: &Digest,
96        key_log: &dyn KeyLog,
97        client_random: &[u8; 32],
98        common: &mut CommonState,
99    ) {
100        let client_early_traffic_secret = self.ks.derive_logged_secret(
101            SecretKind::ClientEarlyTrafficSecret,
102            hs_hash.as_ref(),
103            key_log,
104            client_random,
105        );
106
107        match common.side {
108            Side::Client => self
109                .ks
110                .set_encrypter(&client_early_traffic_secret, common),
111            Side::Server => self
112                .ks
113                .set_decrypter(&client_early_traffic_secret, common),
114        }
115
116        #[cfg(feature = "quic")]
117        if common.is_quic() {
118            // If 0-RTT should be rejected, this will be clobbered by ExtensionProcessing
119            // before the application can see.
120            common.quic.early_secret = Some(client_early_traffic_secret);
121        }
122    }
123
124    pub(crate) fn resumption_psk_binder_key_and_sign_verify_data(
125        &self,
126        hs_hash: &Digest,
127    ) -> hmac::Tag {
128        let resumption_psk_binder_key = self
129            .ks
130            .derive_for_empty_hash(SecretKind::ResumptionPskBinderKey);
131        self.ks
132            .sign_verify_data(&resumption_psk_binder_key, hs_hash)
133    }
134}
135
136/// Pre-handshake key schedule
137///
138/// The inner `KeySchedule` is either constructed without any secrets based on ths HKDF algorithm
139/// or is extracted from a `KeyScheduleEarly`. This can then be used to derive the `KeyScheduleHandshakeStart`.
140pub(crate) struct KeySchedulePreHandshake {
141    ks: KeySchedule,
142}
143
144impl KeySchedulePreHandshake {
145    pub(crate) fn new(suite: &'static Tls13CipherSuite) -> Self {
146        Self {
147            ks: KeySchedule::new_with_empty_secret(suite),
148        }
149    }
150
151    pub(crate) fn into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshakeStart {
152        self.ks.input_secret(secret);
153        KeyScheduleHandshakeStart { ks: self.ks }
154    }
155}
156
157impl From<KeyScheduleEarly> for KeySchedulePreHandshake {
158    fn from(KeyScheduleEarly { ks }: KeyScheduleEarly) -> Self {
159        Self { ks }
160    }
161}
162
163/// KeySchedule during handshake.
164pub(crate) struct KeyScheduleHandshakeStart {
165    ks: KeySchedule,
166}
167
168impl KeyScheduleHandshakeStart {
169    pub(crate) fn derive_client_handshake_secrets(
170        mut self,
171        early_data_enabled: bool,
172        hs_hash: Digest,
173        suite: &'static Tls13CipherSuite,
174        key_log: &dyn KeyLog,
175        client_random: &[u8; 32],
176        common: &mut CommonState,
177    ) -> KeyScheduleHandshake {
178        debug_assert_eq!(common.side, Side::Client);
179        // Suite might have changed due to resumption
180        self.ks.suite = suite;
181        let new = self.into_handshake(hs_hash, key_log, client_random, common);
182
183        // Decrypt with the peer's key, encrypt with our own key
184        new.ks
185            .set_decrypter(&new.server_handshake_traffic_secret, common);
186
187        if !early_data_enabled {
188            // Set the client encryption key for handshakes if early data is not used
189            new.ks
190                .set_encrypter(&new.client_handshake_traffic_secret, common);
191        }
192
193        new
194    }
195
196    pub(crate) fn derive_server_handshake_secrets(
197        self,
198        hs_hash: Digest,
199        key_log: &dyn KeyLog,
200        client_random: &[u8; 32],
201        common: &mut CommonState,
202    ) -> KeyScheduleHandshake {
203        debug_assert_eq!(common.side, Side::Server);
204        let new = self.into_handshake(hs_hash, key_log, client_random, common);
205
206        // Set up to encrypt with handshake secrets, but decrypt with early_data keys.
207        // If not doing early_data after all, this is corrected later to the handshake
208        // keys (now stored in key_schedule).
209        new.ks
210            .set_encrypter(&new.server_handshake_traffic_secret, common);
211        new
212    }
213
214    fn into_handshake(
215        self,
216        hs_hash: Digest,
217        key_log: &dyn KeyLog,
218        client_random: &[u8; 32],
219        _common: &mut CommonState,
220    ) -> KeyScheduleHandshake {
221        // Use an empty handshake hash for the initial handshake.
222        let client_secret = self.ks.derive_logged_secret(
223            SecretKind::ClientHandshakeTrafficSecret,
224            hs_hash.as_ref(),
225            key_log,
226            client_random,
227        );
228
229        let server_secret = self.ks.derive_logged_secret(
230            SecretKind::ServerHandshakeTrafficSecret,
231            hs_hash.as_ref(),
232            key_log,
233            client_random,
234        );
235
236        #[cfg(feature = "quic")]
237        if _common.is_quic() {
238            _common.quic.hs_secrets = Some(quic::Secrets::new(
239                client_secret.clone(),
240                server_secret.clone(),
241                self.ks.suite,
242                _common.side,
243                _common.quic.version,
244            ));
245        }
246
247        KeyScheduleHandshake {
248            ks: self.ks,
249            client_handshake_traffic_secret: client_secret,
250            server_handshake_traffic_secret: server_secret,
251        }
252    }
253}
254
255pub(crate) struct KeyScheduleHandshake {
256    ks: KeySchedule,
257    client_handshake_traffic_secret: hkdf::Prk,
258    server_handshake_traffic_secret: hkdf::Prk,
259}
260
261impl KeyScheduleHandshake {
262    pub(crate) fn sign_server_finish(&self, hs_hash: &Digest) -> hmac::Tag {
263        self.ks
264            .sign_finish(&self.server_handshake_traffic_secret, hs_hash)
265    }
266
267    pub(crate) fn set_handshake_encrypter(&self, common: &mut CommonState) {
268        debug_assert_eq!(common.side, Side::Client);
269        self.ks
270            .set_encrypter(&self.client_handshake_traffic_secret, common);
271    }
272
273    pub(crate) fn set_handshake_decrypter(
274        &self,
275        skip_requested: Option<usize>,
276        common: &mut CommonState,
277    ) {
278        debug_assert_eq!(common.side, Side::Server);
279        let secret = &self.client_handshake_traffic_secret;
280        match skip_requested {
281            None => self.ks.set_decrypter(secret, common),
282            Some(max_early_data_size) => common
283                .record_layer
284                .set_message_decrypter_with_trial_decryption(
285                    self.ks
286                        .derive_decrypter(&self.client_handshake_traffic_secret),
287                    max_early_data_size,
288                ),
289        }
290    }
291
292    pub(crate) fn into_traffic_with_client_finished_pending(
293        self,
294        hs_hash: Digest,
295        key_log: &dyn KeyLog,
296        client_random: &[u8; 32],
297        common: &mut CommonState,
298    ) -> KeyScheduleTrafficWithClientFinishedPending {
299        debug_assert_eq!(common.side, Side::Server);
300
301        let traffic = KeyScheduleTraffic::new(self.ks, hs_hash, key_log, client_random);
302        let (_client_secret, server_secret) = (
303            &traffic.current_client_traffic_secret,
304            &traffic.current_server_traffic_secret,
305        );
306
307        traffic
308            .ks
309            .set_encrypter(server_secret, common);
310
311        #[cfg(feature = "quic")]
312        if common.is_quic() {
313            common.quic.traffic_secrets = Some(quic::Secrets::new(
314                _client_secret.clone(),
315                server_secret.clone(),
316                traffic.ks.suite,
317                common.side,
318                common.quic.version,
319            ));
320        }
321
322        KeyScheduleTrafficWithClientFinishedPending {
323            handshake_client_traffic_secret: self.client_handshake_traffic_secret,
324            traffic,
325        }
326    }
327
328    pub(crate) fn into_pre_finished_client_traffic(
329        self,
330        pre_finished_hash: Digest,
331        handshake_hash: Digest,
332        key_log: &dyn KeyLog,
333        client_random: &[u8; 32],
334    ) -> (KeyScheduleClientBeforeFinished, hmac::Tag) {
335        let traffic = KeyScheduleTraffic::new(self.ks, pre_finished_hash, key_log, client_random);
336        let tag = traffic
337            .ks
338            .sign_finish(&self.client_handshake_traffic_secret, &handshake_hash);
339        (KeyScheduleClientBeforeFinished { traffic }, tag)
340    }
341}
342
343pub(crate) struct KeyScheduleClientBeforeFinished {
344    traffic: KeyScheduleTraffic,
345}
346
347impl KeyScheduleClientBeforeFinished {
348    pub(crate) fn into_traffic(self, common: &mut CommonState) -> KeyScheduleTraffic {
349        debug_assert_eq!(common.side, Side::Client);
350        let (client_secret, server_secret) = (
351            &self
352                .traffic
353                .current_client_traffic_secret,
354            &self
355                .traffic
356                .current_server_traffic_secret,
357        );
358
359        self.traffic
360            .ks
361            .set_decrypter(server_secret, common);
362        self.traffic
363            .ks
364            .set_encrypter(client_secret, common);
365
366        #[cfg(feature = "quic")]
367        if common.is_quic() {
368            common.quic.traffic_secrets = Some(quic::Secrets::new(
369                client_secret.clone(),
370                server_secret.clone(),
371                self.traffic.ks.suite,
372                common.side,
373                common.quic.version,
374            ));
375        }
376
377        self.traffic
378    }
379}
380
381/// KeySchedule during traffic stage, retaining the ability to calculate the client's
382/// finished verify_data. The traffic stage key schedule can be extracted from it
383/// through signing the client finished hash.
384pub(crate) struct KeyScheduleTrafficWithClientFinishedPending {
385    handshake_client_traffic_secret: hkdf::Prk,
386    traffic: KeyScheduleTraffic,
387}
388
389impl KeyScheduleTrafficWithClientFinishedPending {
390    pub(crate) fn update_decrypter(&self, common: &mut CommonState) {
391        debug_assert_eq!(common.side, Side::Server);
392        self.traffic
393            .ks
394            .set_decrypter(&self.handshake_client_traffic_secret, common);
395    }
396
397    pub(crate) fn sign_client_finish(
398        self,
399        hs_hash: &Digest,
400        common: &mut CommonState,
401    ) -> (KeyScheduleTraffic, hmac::Tag) {
402        debug_assert_eq!(common.side, Side::Server);
403        let tag = self
404            .traffic
405            .ks
406            .sign_finish(&self.handshake_client_traffic_secret, hs_hash);
407
408        // Install keying to read future messages.
409        self.traffic.ks.set_decrypter(
410            &self
411                .traffic
412                .current_client_traffic_secret,
413            common,
414        );
415
416        (self.traffic, tag)
417    }
418}
419
420/// KeySchedule during traffic stage.  All traffic & exporter keys are guaranteed
421/// to be available.
422pub(crate) struct KeyScheduleTraffic {
423    ks: KeySchedule,
424    current_client_traffic_secret: hkdf::Prk,
425    current_server_traffic_secret: hkdf::Prk,
426    current_exporter_secret: hkdf::Prk,
427}
428
429impl KeyScheduleTraffic {
430    fn new(
431        mut ks: KeySchedule,
432        hs_hash: Digest,
433        key_log: &dyn KeyLog,
434        client_random: &[u8; 32],
435    ) -> Self {
436        ks.input_empty();
437
438        let current_client_traffic_secret = ks.derive_logged_secret(
439            SecretKind::ClientApplicationTrafficSecret,
440            hs_hash.as_ref(),
441            key_log,
442            client_random,
443        );
444
445        let current_server_traffic_secret = ks.derive_logged_secret(
446            SecretKind::ServerApplicationTrafficSecret,
447            hs_hash.as_ref(),
448            key_log,
449            client_random,
450        );
451
452        let current_exporter_secret = ks.derive_logged_secret(
453            SecretKind::ExporterMasterSecret,
454            hs_hash.as_ref(),
455            key_log,
456            client_random,
457        );
458
459        Self {
460            ks,
461            current_client_traffic_secret,
462            current_server_traffic_secret,
463            current_exporter_secret,
464        }
465    }
466
467    pub(crate) fn update_encrypter_and_notify(&mut self, common: &mut CommonState) {
468        let secret = self.next_application_traffic_secret(common.side);
469        common.enqueue_key_update_notification();
470        self.ks.set_encrypter(&secret, common);
471    }
472
473    pub(crate) fn update_decrypter(&mut self, common: &mut CommonState) {
474        let secret = self.next_application_traffic_secret(common.side.peer());
475        self.ks.set_decrypter(&secret, common);
476    }
477
478    pub(crate) fn next_application_traffic_secret(&mut self, side: Side) -> hkdf::Prk {
479        let current = match side {
480            Side::Client => &mut self.current_client_traffic_secret,
481            Side::Server => &mut self.current_server_traffic_secret,
482        };
483
484        let secret = self.ks.derive_next(current);
485        *current = secret.clone();
486        secret
487    }
488
489    pub(crate) fn resumption_master_secret_and_derive_ticket_psk(
490        &self,
491        hs_hash: &Digest,
492        nonce: &[u8],
493    ) -> Vec<u8> {
494        let resumption_master_secret = self.ks.derive(
495            self.ks.algorithm(),
496            SecretKind::ResumptionMasterSecret,
497            hs_hash.as_ref(),
498        );
499        self.ks
500            .derive_ticket_psk(&resumption_master_secret, nonce)
501    }
502
503    pub(crate) fn export_keying_material(
504        &self,
505        out: &mut [u8],
506        label: &[u8],
507        context: Option<&[u8]>,
508    ) -> Result<(), Error> {
509        self.ks
510            .export_keying_material(&self.current_exporter_secret, out, label, context)
511    }
512
513    #[cfg(feature = "secret_extraction")]
514    pub(crate) fn extract_secrets(&self, side: Side) -> Result<PartiallyExtractedSecrets, Error> {
515        fn expand<const KEY_LEN: usize, const IV_LEN: usize>(
516            secret: &hkdf::Prk,
517        ) -> Result<([u8; KEY_LEN], [u8; IV_LEN]), Error> {
518            let mut key = [0u8; KEY_LEN];
519            let mut iv = [0u8; IV_LEN];
520
521            hkdf_expand_info(secret, PayloadU8Len(key.len()), b"key", &[], |okm| {
522                okm.fill(&mut key)
523            })
524            .map_err(|_| Error::General("hkdf_expand_info failed".to_string()))?;
525
526            hkdf_expand_info(secret, PayloadU8Len(iv.len()), b"iv", &[], |okm| {
527                okm.fill(&mut iv)
528            })
529            .map_err(|_| Error::General("hkdf_expand_info failed".to_string()))?;
530
531            Ok((key, iv))
532        }
533
534        let client_secrets;
535        let server_secrets;
536
537        let algo = self.ks.suite.common.aead_algorithm;
538        if algo == &aead::AES_128_GCM {
539            let extract = |secret: &hkdf::Prk| -> Result<ConnectionTrafficSecrets, Error> {
540                let (key, iv_in) = expand::<16, 12>(secret)?;
541
542                let mut salt = [0u8; 4];
543                salt.copy_from_slice(&iv_in[..4]);
544
545                let mut iv = [0u8; 8];
546                iv.copy_from_slice(&iv_in[4..]);
547
548                Ok(ConnectionTrafficSecrets::Aes128Gcm { key, salt, iv })
549            };
550
551            client_secrets = extract(&self.current_client_traffic_secret)?;
552            server_secrets = extract(&self.current_server_traffic_secret)?;
553        } else if algo == &aead::AES_256_GCM {
554            let extract = |secret: &hkdf::Prk| -> Result<ConnectionTrafficSecrets, Error> {
555                let (key, iv_in) = expand::<32, 12>(secret)?;
556
557                let mut salt = [0u8; 4];
558                salt.copy_from_slice(&iv_in[..4]);
559
560                let mut iv = [0u8; 8];
561                iv.copy_from_slice(&iv_in[4..]);
562
563                Ok(ConnectionTrafficSecrets::Aes256Gcm { key, salt, iv })
564            };
565
566            client_secrets = extract(&self.current_client_traffic_secret)?;
567            server_secrets = extract(&self.current_server_traffic_secret)?;
568        } else if algo == &aead::CHACHA20_POLY1305 {
569            let extract = |secret: &hkdf::Prk| -> Result<ConnectionTrafficSecrets, Error> {
570                let (key, iv) = expand::<32, 12>(secret)?;
571                Ok(ConnectionTrafficSecrets::Chacha20Poly1305 { key, iv })
572            };
573
574            client_secrets = extract(&self.current_client_traffic_secret)?;
575            server_secrets = extract(&self.current_server_traffic_secret)?;
576        } else {
577            return Err(Error::General(format!(
578                "exporting secrets for {:?}: unimplemented",
579                algo
580            )));
581        }
582
583        let (tx, rx) = match side {
584            Side::Client => (client_secrets, server_secrets),
585            Side::Server => (server_secrets, client_secrets),
586        };
587        Ok(PartiallyExtractedSecrets { tx, rx })
588    }
589}
590
591impl KeySchedule {
592    fn new(suite: &'static Tls13CipherSuite, secret: &[u8]) -> Self {
593        let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
594        let salt = hkdf::Salt::new(suite.hkdf_algorithm, &zeroes[..suite.hkdf_algorithm.len()]);
595        Self {
596            current: salt.extract(secret),
597            suite,
598        }
599    }
600
601    fn set_encrypter(&self, secret: &hkdf::Prk, common: &mut CommonState) {
602        let key = derive_traffic_key(secret, self.suite.common.aead_algorithm);
603        let iv = derive_traffic_iv(secret);
604
605        common
606            .record_layer
607            .set_message_encrypter(Box::new(Tls13MessageEncrypter {
608                enc_key: aead::LessSafeKey::new(key),
609                iv,
610            }));
611    }
612
613    fn set_decrypter(&self, secret: &hkdf::Prk, common: &mut CommonState) {
614        common
615            .record_layer
616            .set_message_decrypter(self.derive_decrypter(secret));
617    }
618
619    fn derive_decrypter(&self, secret: &hkdf::Prk) -> Box<dyn MessageDecrypter> {
620        let key = derive_traffic_key(secret, self.suite.common.aead_algorithm);
621        let iv = derive_traffic_iv(secret);
622        Box::new(Tls13MessageDecrypter {
623            dec_key: aead::LessSafeKey::new(key),
624            iv,
625        })
626    }
627
628    #[inline]
629    fn algorithm(&self) -> hkdf::Algorithm {
630        self.suite.hkdf_algorithm
631    }
632
633    fn new_with_empty_secret(suite: &'static Tls13CipherSuite) -> Self {
634        let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
635        Self::new(suite, &zeroes[..suite.hkdf_algorithm.len()])
636    }
637
638    /// Input the empty secret.
639    fn input_empty(&mut self) {
640        let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
641        self.input_secret(&zeroes[..self.suite.hkdf_algorithm.len()]);
642    }
643
644    /// Input the given secret.
645    fn input_secret(&mut self, secret: &[u8]) {
646        let salt: hkdf::Salt = self.derive_for_empty_hash(SecretKind::DerivedSecret);
647        self.current = salt.extract(secret);
648    }
649
650    /// Derive a secret of given `kind`, using current handshake hash `hs_hash`.
651    fn derive<T, L>(&self, key_type: L, kind: SecretKind, hs_hash: &[u8]) -> T
652    where
653        T: for<'a> From<hkdf::Okm<'a, L>>,
654        L: hkdf::KeyType,
655    {
656        hkdf_expand(&self.current, key_type, kind.to_bytes(), hs_hash)
657    }
658
659    fn derive_logged_secret(
660        &self,
661        kind: SecretKind,
662        hs_hash: &[u8],
663        key_log: &dyn KeyLog,
664        client_random: &[u8; 32],
665    ) -> hkdf::Prk {
666        let log_label = kind
667            .log_label()
668            .expect("not a loggable secret");
669        if key_log.will_log(log_label) {
670            let secret = self
671                .derive::<PayloadU8, _>(
672                    PayloadU8Len(self.suite.hkdf_algorithm.len()),
673                    kind,
674                    hs_hash,
675                )
676                .into_inner();
677            key_log.log(log_label, client_random, &secret);
678        }
679        self.derive(self.suite.hkdf_algorithm, kind, hs_hash)
680    }
681
682    /// Derive a secret of given `kind` using the hash of the empty string
683    /// for the handshake hash.  Useful only for
684    /// `SecretKind::ResumptionPSKBinderKey` and
685    /// `SecretKind::DerivedSecret`.
686    fn derive_for_empty_hash<T>(&self, kind: SecretKind) -> T
687    where
688        T: for<'a> From<hkdf::Okm<'a, hkdf::Algorithm>>,
689    {
690        let digest_alg = self
691            .suite
692            .hkdf_algorithm
693            .hmac_algorithm()
694            .digest_algorithm();
695        let empty_hash = digest::digest(digest_alg, &[]);
696        self.derive(self.suite.hkdf_algorithm, kind, empty_hash.as_ref())
697    }
698
699    /// Sign the finished message consisting of `hs_hash` using a current
700    /// traffic secret.
701    fn sign_finish(&self, base_key: &hkdf::Prk, hs_hash: &Digest) -> hmac::Tag {
702        self.sign_verify_data(base_key, hs_hash)
703    }
704
705    /// Sign the finished message consisting of `hs_hash` using the key material
706    /// `base_key`.
707    fn sign_verify_data(&self, base_key: &hkdf::Prk, hs_hash: &Digest) -> hmac::Tag {
708        let hmac_alg = self
709            .suite
710            .hkdf_algorithm
711            .hmac_algorithm();
712        let hmac_key = hkdf_expand(base_key, hmac_alg, b"finished", &[]);
713        hmac::sign(&hmac_key, hs_hash.as_ref())
714    }
715
716    /// Derive the next application traffic secret, returning it.
717    fn derive_next(&self, base_key: &hkdf::Prk) -> hkdf::Prk {
718        hkdf_expand(base_key, self.suite.hkdf_algorithm, b"traffic upd", &[])
719    }
720
721    /// Derive the PSK to use given a resumption_master_secret and
722    /// ticket_nonce.
723    fn derive_ticket_psk(&self, rms: &hkdf::Prk, nonce: &[u8]) -> Vec<u8> {
724        let payload: PayloadU8 = hkdf_expand(
725            rms,
726            PayloadU8Len(self.suite.hkdf_algorithm.len()),
727            b"resumption",
728            nonce,
729        );
730        payload.into_inner()
731    }
732
733    fn export_keying_material(
734        &self,
735        current_exporter_secret: &hkdf::Prk,
736        out: &mut [u8],
737        label: &[u8],
738        context: Option<&[u8]>,
739    ) -> Result<(), Error> {
740        let digest_alg = self
741            .suite
742            .hkdf_algorithm
743            .hmac_algorithm()
744            .digest_algorithm();
745
746        let h_empty = digest::digest(digest_alg, &[]);
747        let secret: hkdf::Prk = hkdf_expand(
748            current_exporter_secret,
749            self.suite.hkdf_algorithm,
750            label,
751            h_empty.as_ref(),
752        );
753
754        let h_context = digest::digest(digest_alg, context.unwrap_or(&[]));
755
756        // TODO: Test what happens when this fails
757        hkdf_expand_info(
758            &secret,
759            PayloadU8Len(out.len()),
760            b"exporter",
761            h_context.as_ref(),
762            |okm| okm.fill(out),
763        )
764        .map_err(|_| Error::General("exporting too much".to_string()))
765    }
766}
767
768pub(crate) fn hkdf_expand<T, L>(secret: &hkdf::Prk, key_type: L, label: &[u8], context: &[u8]) -> T
769where
770    T: for<'a> From<hkdf::Okm<'a, L>>,
771    L: hkdf::KeyType,
772{
773    hkdf_expand_info(secret, key_type, label, context, |okm| okm.into())
774}
775
776fn hkdf_expand_info<F, T, L>(
777    secret: &hkdf::Prk,
778    key_type: L,
779    label: &[u8],
780    context: &[u8],
781    f: F,
782) -> T
783where
784    F: for<'b> FnOnce(hkdf::Okm<'b, L>) -> T,
785    L: hkdf::KeyType,
786{
787    const LABEL_PREFIX: &[u8] = b"tls13 ";
788
789    let output_len = u16::to_be_bytes(key_type.len() as u16);
790    let label_len = u8::to_be_bytes((LABEL_PREFIX.len() + label.len()) as u8);
791    let context_len = u8::to_be_bytes(context.len() as u8);
792
793    let info = &[
794        &output_len[..],
795        &label_len[..],
796        LABEL_PREFIX,
797        label,
798        &context_len[..],
799        context,
800    ];
801    let okm = secret.expand(info, key_type).unwrap();
802
803    f(okm)
804}
805
806pub(crate) struct PayloadU8Len(pub(crate) usize);
807impl hkdf::KeyType for PayloadU8Len {
808    fn len(&self) -> usize {
809        self.0
810    }
811}
812
813impl From<hkdf::Okm<'_, PayloadU8Len>> for PayloadU8 {
814    fn from(okm: hkdf::Okm<PayloadU8Len>) -> Self {
815        let mut r = vec![0u8; okm.len().0];
816        okm.fill(&mut r[..]).unwrap();
817        Self::new(r)
818    }
819}
820
821pub(crate) fn derive_traffic_key(
822    secret: &hkdf::Prk,
823    aead_algorithm: &'static aead::Algorithm,
824) -> aead::UnboundKey {
825    hkdf_expand(secret, aead_algorithm, b"key", &[])
826}
827
828pub(crate) fn derive_traffic_iv(secret: &hkdf::Prk) -> Iv {
829    hkdf_expand(secret, IvLen, b"iv", &[])
830}
831
832#[cfg(test)]
833mod test {
834    use super::{derive_traffic_iv, derive_traffic_key, KeySchedule, SecretKind};
835    use crate::tls13::TLS13_CHACHA20_POLY1305_SHA256_INTERNAL;
836    use crate::KeyLog;
837    use ring::aead;
838
839    #[test]
840    fn test_vectors() {
841        /* These test vectors generated with OpenSSL. */
842        let hs_start_hash = [
843            0xec, 0x14, 0x7a, 0x06, 0xde, 0xa3, 0xc8, 0x84, 0x6c, 0x02, 0xb2, 0x23, 0x8e, 0x41,
844            0xbd, 0xdc, 0x9d, 0x89, 0xf9, 0xae, 0xa1, 0x7b, 0x5e, 0xfd, 0x4d, 0x74, 0x82, 0xaf,
845            0x75, 0x88, 0x1c, 0x0a,
846        ];
847
848        let hs_full_hash = [
849            0x75, 0x1a, 0x3d, 0x4a, 0x14, 0xdf, 0xab, 0xeb, 0x68, 0xe9, 0x2c, 0xa5, 0x91, 0x8e,
850            0x24, 0x08, 0xb9, 0xbc, 0xb0, 0x74, 0x89, 0x82, 0xec, 0x9c, 0x32, 0x30, 0xac, 0x30,
851            0xbb, 0xeb, 0x23, 0xe2,
852        ];
853
854        let ecdhe_secret = [
855            0xe7, 0xb8, 0xfe, 0xf8, 0x90, 0x3b, 0x52, 0x0c, 0xb9, 0xa1, 0x89, 0x71, 0xb6, 0x9d,
856            0xd4, 0x5d, 0xca, 0x53, 0xce, 0x2f, 0x12, 0xbf, 0x3b, 0xef, 0x93, 0x15, 0xe3, 0x12,
857            0x71, 0xdf, 0x4b, 0x40,
858        ];
859
860        let client_hts = [
861            0x61, 0x7b, 0x35, 0x07, 0x6b, 0x9d, 0x0e, 0x08, 0xcf, 0x73, 0x1d, 0x94, 0xa8, 0x66,
862            0x14, 0x78, 0x41, 0x09, 0xef, 0x25, 0x55, 0x51, 0x92, 0x1d, 0xd4, 0x6e, 0x04, 0x01,
863            0x35, 0xcf, 0x46, 0xab,
864        ];
865
866        let client_hts_key = [
867            0x62, 0xd0, 0xdd, 0x00, 0xf6, 0x96, 0x19, 0xd3, 0xb8, 0x19, 0x3a, 0xb4, 0xa0, 0x95,
868            0x85, 0xa7,
869        ];
870
871        let client_hts_iv = [
872            0xff, 0xf7, 0x5d, 0xf5, 0xad, 0x35, 0xd5, 0xcb, 0x3c, 0x53, 0xf3, 0xa9,
873        ];
874
875        let server_hts = [
876            0xfc, 0xf7, 0xdf, 0xe6, 0x4f, 0xa2, 0xc0, 0x4f, 0x62, 0x35, 0x38, 0x7f, 0x43, 0x4e,
877            0x01, 0x42, 0x23, 0x36, 0xd9, 0xc0, 0x39, 0xde, 0x68, 0x47, 0xa0, 0xb9, 0xdd, 0xcf,
878            0x29, 0xa8, 0x87, 0x59,
879        ];
880
881        let server_hts_key = [
882            0x04, 0x67, 0xf3, 0x16, 0xa8, 0x05, 0xb8, 0xc4, 0x97, 0xee, 0x67, 0x04, 0x7b, 0xbc,
883            0xbc, 0x54,
884        ];
885
886        let server_hts_iv = [
887            0xde, 0x83, 0xa7, 0x3e, 0x9d, 0x81, 0x4b, 0x04, 0xc4, 0x8b, 0x78, 0x09,
888        ];
889
890        let client_ats = [
891            0xc1, 0x4a, 0x6d, 0x79, 0x76, 0xd8, 0x10, 0x2b, 0x5a, 0x0c, 0x99, 0x51, 0x49, 0x3f,
892            0xee, 0x87, 0xdc, 0xaf, 0xf8, 0x2c, 0x24, 0xca, 0xb2, 0x14, 0xe8, 0xbe, 0x71, 0xa8,
893            0x20, 0x6d, 0xbd, 0xa5,
894        ];
895
896        let client_ats_key = [
897            0xcc, 0x9f, 0x5f, 0x98, 0x0b, 0x5f, 0x10, 0x30, 0x6c, 0xba, 0xd7, 0xbe, 0x98, 0xd7,
898            0x57, 0x2e,
899        ];
900
901        let client_ats_iv = [
902            0xb8, 0x09, 0x29, 0xe8, 0xd0, 0x2c, 0x70, 0xf6, 0x11, 0x62, 0xed, 0x6b,
903        ];
904
905        let server_ats = [
906            0x2c, 0x90, 0x77, 0x38, 0xd3, 0xf8, 0x37, 0x02, 0xd1, 0xe4, 0x59, 0x8f, 0x48, 0x48,
907            0x53, 0x1d, 0x9f, 0x93, 0x65, 0x49, 0x1b, 0x9f, 0x7f, 0x52, 0xc8, 0x22, 0x29, 0x0d,
908            0x4c, 0x23, 0x21, 0x92,
909        ];
910
911        let server_ats_key = [
912            0x0c, 0xb2, 0x95, 0x62, 0xd8, 0xd8, 0x8f, 0x48, 0xb0, 0x2c, 0xbf, 0xbe, 0xd7, 0xe6,
913            0x2b, 0xb3,
914        ];
915
916        let server_ats_iv = [
917            0x0d, 0xb2, 0x8f, 0x98, 0x85, 0x86, 0xa1, 0xb7, 0xe4, 0xd5, 0xc6, 0x9c,
918        ];
919
920        let mut ks = KeySchedule::new_with_empty_secret(TLS13_CHACHA20_POLY1305_SHA256_INTERNAL);
921        ks.input_secret(&ecdhe_secret);
922
923        assert_traffic_secret(
924            &ks,
925            SecretKind::ClientHandshakeTrafficSecret,
926            &hs_start_hash,
927            &client_hts,
928            &client_hts_key,
929            &client_hts_iv,
930        );
931
932        assert_traffic_secret(
933            &ks,
934            SecretKind::ServerHandshakeTrafficSecret,
935            &hs_start_hash,
936            &server_hts,
937            &server_hts_key,
938            &server_hts_iv,
939        );
940
941        ks.input_empty();
942
943        assert_traffic_secret(
944            &ks,
945            SecretKind::ClientApplicationTrafficSecret,
946            &hs_full_hash,
947            &client_ats,
948            &client_ats_key,
949            &client_ats_iv,
950        );
951
952        assert_traffic_secret(
953            &ks,
954            SecretKind::ServerApplicationTrafficSecret,
955            &hs_full_hash,
956            &server_ats,
957            &server_ats_key,
958            &server_ats_iv,
959        );
960    }
961
962    fn assert_traffic_secret(
963        ks: &KeySchedule,
964        kind: SecretKind,
965        hash: &[u8],
966        expected_traffic_secret: &[u8],
967        expected_key: &[u8],
968        expected_iv: &[u8],
969    ) {
970        struct Log<'a>(&'a [u8]);
971        impl KeyLog for Log<'_> {
972            fn log(&self, _label: &str, _client_random: &[u8], secret: &[u8]) {
973                assert_eq!(self.0, secret);
974            }
975        }
976        let log = Log(expected_traffic_secret);
977        let traffic_secret = ks.derive_logged_secret(kind, hash, &log, &[0; 32]);
978
979        // Since we can't test key equality, we test the output of sealing with the key instead.
980        let aead_alg = &aead::AES_128_GCM;
981        let key = derive_traffic_key(&traffic_secret, aead_alg);
982        let seal_output = seal_zeroes(key);
983        let expected_key = aead::UnboundKey::new(aead_alg, expected_key).unwrap();
984        let expected_seal_output = seal_zeroes(expected_key);
985        assert_eq!(seal_output, expected_seal_output);
986        assert!(seal_output.len() >= 48); // Sanity check.
987
988        let iv = derive_traffic_iv(&traffic_secret);
989        assert_eq!(iv.value(), expected_iv);
990    }
991
992    fn seal_zeroes(key: aead::UnboundKey) -> Vec<u8> {
993        let key = aead::LessSafeKey::new(key);
994        let mut seal_output = vec![0; 32];
995        key.seal_in_place_append_tag(
996            aead::Nonce::assume_unique_for_key([0; aead::NONCE_LEN]),
997            aead::Aad::empty(),
998            &mut seal_output,
999        )
1000        .unwrap();
1001        seal_output
1002    }
1003}
1004
1005#[cfg(bench)]
1006mod benchmarks {
1007    #[bench]
1008    fn bench_sha256(b: &mut test::Bencher) {
1009        use super::{derive_traffic_iv, derive_traffic_key, KeySchedule, SecretKind};
1010        use crate::tls13::TLS13_CHACHA20_POLY1305_SHA256_INTERNAL;
1011        use crate::KeyLog;
1012        use ring::aead;
1013
1014        fn extract_traffic_secret(ks: &KeySchedule, kind: SecretKind) {
1015            struct Log;
1016
1017            impl KeyLog for Log {
1018                fn log(&self, _label: &str, _client_random: &[u8], _secret: &[u8]) {}
1019            }
1020
1021            let aead_alg = &aead::CHACHA20_POLY1305;
1022            let hash = [0u8; 32];
1023            let traffic_secret = ks.derive_logged_secret(kind, &hash, &Log, &[0u8; 32]);
1024            test::black_box(derive_traffic_key(&traffic_secret, aead_alg));
1025            test::black_box(derive_traffic_iv(&traffic_secret));
1026        }
1027
1028        b.iter(|| {
1029            let mut ks =
1030                KeySchedule::new_with_empty_secret(TLS13_CHACHA20_POLY1305_SHA256_INTERNAL);
1031            ks.input_secret(&[0u8; 32]);
1032
1033            extract_traffic_secret(&ks, SecretKind::ClientHandshakeTrafficSecret);
1034            extract_traffic_secret(&ks, SecretKind::ServerHandshakeTrafficSecret);
1035
1036            ks.input_empty();
1037
1038            extract_traffic_secret(&ks, SecretKind::ClientApplicationTrafficSecret);
1039            extract_traffic_secret(&ks, SecretKind::ServerApplicationTrafficSecret);
1040        });
1041    }
1042}