rustls/
quic.rs

1use alloc::boxed::Box;
2use alloc::collections::VecDeque;
3use alloc::vec::Vec;
4#[cfg(feature = "std")]
5use core::fmt::Debug;
6
7/// This module contains optional APIs for implementing QUIC TLS.
8use crate::common_state::Side;
9use crate::crypto::cipher::{AeadKey, Iv};
10use crate::crypto::tls13::{Hkdf, HkdfExpander, OkmBlock};
11use crate::enums::AlertDescription;
12use crate::error::Error;
13use crate::tls13::key_schedule::{
14    hkdf_expand_label, hkdf_expand_label_aead_key, hkdf_expand_label_block,
15};
16use crate::tls13::Tls13CipherSuite;
17
18#[cfg(feature = "std")]
19mod connection {
20    use alloc::sync::Arc;
21    use alloc::vec;
22    use alloc::vec::Vec;
23    use core::fmt::{self, Debug};
24    use core::ops::{Deref, DerefMut};
25
26    use pki_types::ServerName;
27
28    use super::{DirectionalKeys, KeyChange, Version};
29    use crate::client::{ClientConfig, ClientConnectionData};
30    use crate::common_state::{CommonState, Protocol, DEFAULT_BUFFER_LIMIT};
31    use crate::conn::{ConnectionCore, SideData};
32    use crate::enums::{AlertDescription, ContentType, ProtocolVersion};
33    use crate::error::Error;
34    use crate::msgs::deframer::buffers::{DeframerVecBuffer, Locator};
35    use crate::msgs::handshake::{ClientExtension, ServerExtension};
36    use crate::msgs::message::InboundPlainMessage;
37    use crate::server::{ServerConfig, ServerConnectionData};
38    use crate::vecbuf::ChunkVecBuffer;
39
40    /// A QUIC client or server connection.
41    #[derive(Debug)]
42    pub enum Connection {
43        /// A client connection
44        Client(ClientConnection),
45        /// A server connection
46        Server(ServerConnection),
47    }
48
49    impl Connection {
50        /// Return the TLS-encoded transport parameters for the session's peer.
51        ///
52        /// See [`ConnectionCommon::quic_transport_parameters()`] for more details.
53        pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
54            match self {
55                Self::Client(conn) => conn.quic_transport_parameters(),
56                Self::Server(conn) => conn.quic_transport_parameters(),
57            }
58        }
59
60        /// Compute the keys for encrypting/decrypting 0-RTT packets, if available
61        pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
62            match self {
63                Self::Client(conn) => conn.zero_rtt_keys(),
64                Self::Server(conn) => conn.zero_rtt_keys(),
65            }
66        }
67
68        /// Consume unencrypted TLS handshake data.
69        ///
70        /// Handshake data obtained from separate encryption levels should be supplied in separate calls.
71        pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
72            match self {
73                Self::Client(conn) => conn.read_hs(plaintext),
74                Self::Server(conn) => conn.read_hs(plaintext),
75            }
76        }
77
78        /// Emit unencrypted TLS handshake data.
79        ///
80        /// When this returns `Some(_)`, the new keys must be used for future handshake data.
81        pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
82            match self {
83                Self::Client(conn) => conn.write_hs(buf),
84                Self::Server(conn) => conn.write_hs(buf),
85            }
86        }
87
88        /// Emit the TLS description code of a fatal alert, if one has arisen.
89        ///
90        /// Check after `read_hs` returns `Err(_)`.
91        pub fn alert(&self) -> Option<AlertDescription> {
92            match self {
93                Self::Client(conn) => conn.alert(),
94                Self::Server(conn) => conn.alert(),
95            }
96        }
97
98        /// Derives key material from the agreed connection secrets.
99        ///
100        /// This function fills in `output` with `output.len()` bytes of key
101        /// material derived from the master session secret using `label`
102        /// and `context` for diversification. Ownership of the buffer is taken
103        /// by the function and returned via the Ok result to ensure no key
104        /// material leaks if the function fails.
105        ///
106        /// See RFC5705 for more details on what this does and is for.
107        ///
108        /// For TLS1.3 connections, this function does not use the
109        /// "early" exporter at any point.
110        ///
111        /// This function fails if called prior to the handshake completing;
112        /// check with [`CommonState::is_handshaking`] first.
113        #[inline]
114        pub fn export_keying_material<T: AsMut<[u8]>>(
115            &self,
116            output: T,
117            label: &[u8],
118            context: Option<&[u8]>,
119        ) -> Result<T, Error> {
120            match self {
121                Self::Client(conn) => conn
122                    .core
123                    .export_keying_material(output, label, context),
124                Self::Server(conn) => conn
125                    .core
126                    .export_keying_material(output, label, context),
127            }
128        }
129    }
130
131    impl Deref for Connection {
132        type Target = CommonState;
133
134        fn deref(&self) -> &Self::Target {
135            match self {
136                Self::Client(conn) => &conn.core.common_state,
137                Self::Server(conn) => &conn.core.common_state,
138            }
139        }
140    }
141
142    impl DerefMut for Connection {
143        fn deref_mut(&mut self) -> &mut Self::Target {
144            match self {
145                Self::Client(conn) => &mut conn.core.common_state,
146                Self::Server(conn) => &mut conn.core.common_state,
147            }
148        }
149    }
150
151    /// A QUIC client connection.
152    pub struct ClientConnection {
153        inner: ConnectionCommon<ClientConnectionData>,
154    }
155
156    impl ClientConnection {
157        /// Make a new QUIC ClientConnection.
158        ///
159        /// This differs from `ClientConnection::new()` in that it takes an extra `params` argument,
160        /// which contains the TLS-encoded transport parameters to send.
161        pub fn new(
162            config: Arc<ClientConfig>,
163            quic_version: Version,
164            name: ServerName<'static>,
165            params: Vec<u8>,
166        ) -> Result<Self, Error> {
167            if !config.supports_version(ProtocolVersion::TLSv1_3) {
168                return Err(Error::General(
169                    "TLS 1.3 support is required for QUIC".into(),
170                ));
171            }
172
173            if !config.supports_protocol(Protocol::Quic) {
174                return Err(Error::General(
175                    "at least one ciphersuite must support QUIC".into(),
176                ));
177            }
178
179            let ext = match quic_version {
180                Version::V1Draft => ClientExtension::TransportParametersDraft(params),
181                Version::V1 | Version::V2 => ClientExtension::TransportParameters(params),
182            };
183
184            let mut inner = ConnectionCore::for_client(config, name, vec![ext], Protocol::Quic)?;
185            inner.common_state.quic.version = quic_version;
186            Ok(Self {
187                inner: inner.into(),
188            })
189        }
190
191        /// Returns True if the server signalled it will process early data.
192        ///
193        /// If you sent early data and this returns false at the end of the
194        /// handshake then the server will not process the data.  This
195        /// is not an error, but you may wish to resend the data.
196        pub fn is_early_data_accepted(&self) -> bool {
197            self.inner.core.is_early_data_accepted()
198        }
199    }
200
201    impl Deref for ClientConnection {
202        type Target = ConnectionCommon<ClientConnectionData>;
203
204        fn deref(&self) -> &Self::Target {
205            &self.inner
206        }
207    }
208
209    impl DerefMut for ClientConnection {
210        fn deref_mut(&mut self) -> &mut Self::Target {
211            &mut self.inner
212        }
213    }
214
215    impl Debug for ClientConnection {
216        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217            f.debug_struct("quic::ClientConnection")
218                .finish()
219        }
220    }
221
222    impl From<ClientConnection> for Connection {
223        fn from(c: ClientConnection) -> Self {
224            Self::Client(c)
225        }
226    }
227
228    /// A QUIC server connection.
229    pub struct ServerConnection {
230        inner: ConnectionCommon<ServerConnectionData>,
231    }
232
233    impl ServerConnection {
234        /// Make a new QUIC ServerConnection.
235        ///
236        /// This differs from `ServerConnection::new()` in that it takes an extra `params` argument,
237        /// which contains the TLS-encoded transport parameters to send.
238        pub fn new(
239            config: Arc<ServerConfig>,
240            quic_version: Version,
241            params: Vec<u8>,
242        ) -> Result<Self, Error> {
243            if !config.supports_version(ProtocolVersion::TLSv1_3) {
244                return Err(Error::General(
245                    "TLS 1.3 support is required for QUIC".into(),
246                ));
247            }
248
249            if !config.supports_protocol(Protocol::Quic) {
250                return Err(Error::General(
251                    "at least one ciphersuite must support QUIC".into(),
252                ));
253            }
254
255            if config.max_early_data_size != 0 && config.max_early_data_size != 0xffff_ffff {
256                return Err(Error::General(
257                    "QUIC sessions must set a max early data of 0 or 2^32-1".into(),
258                ));
259            }
260
261            let ext = match quic_version {
262                Version::V1Draft => ServerExtension::TransportParametersDraft(params),
263                Version::V1 | Version::V2 => ServerExtension::TransportParameters(params),
264            };
265
266            let mut core = ConnectionCore::for_server(config, vec![ext])?;
267            core.common_state.protocol = Protocol::Quic;
268            core.common_state.quic.version = quic_version;
269            Ok(Self { inner: core.into() })
270        }
271
272        /// Explicitly discard early data, notifying the client
273        ///
274        /// Useful if invariants encoded in `received_resumption_data()` cannot be respected.
275        ///
276        /// Must be called while `is_handshaking` is true.
277        pub fn reject_early_data(&mut self) {
278            self.inner.core.reject_early_data()
279        }
280
281        /// Retrieves the server name, if any, used to select the certificate and
282        /// private key.
283        ///
284        /// This returns `None` until some time after the client's server name indication
285        /// (SNI) extension value is processed during the handshake. It will never be
286        /// `None` when the connection is ready to send or process application data,
287        /// unless the client does not support SNI.
288        ///
289        /// This is useful for application protocols that need to enforce that the
290        /// server name matches an application layer protocol hostname. For
291        /// example, HTTP/1.1 servers commonly expect the `Host:` header field of
292        /// every request on a connection to match the hostname in the SNI extension
293        /// when the client provides the SNI extension.
294        ///
295        /// The server name is also used to match sessions during session resumption.
296        pub fn server_name(&self) -> Option<&str> {
297            self.inner.core.get_sni_str()
298        }
299    }
300
301    impl Deref for ServerConnection {
302        type Target = ConnectionCommon<ServerConnectionData>;
303
304        fn deref(&self) -> &Self::Target {
305            &self.inner
306        }
307    }
308
309    impl DerefMut for ServerConnection {
310        fn deref_mut(&mut self) -> &mut Self::Target {
311            &mut self.inner
312        }
313    }
314
315    impl Debug for ServerConnection {
316        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317            f.debug_struct("quic::ServerConnection")
318                .finish()
319        }
320    }
321
322    impl From<ServerConnection> for Connection {
323        fn from(c: ServerConnection) -> Self {
324            Self::Server(c)
325        }
326    }
327
328    /// A shared interface for QUIC connections.
329    pub struct ConnectionCommon<Data> {
330        core: ConnectionCore<Data>,
331        deframer_buffer: DeframerVecBuffer,
332        sendable_plaintext: ChunkVecBuffer,
333    }
334
335    impl<Data: SideData> ConnectionCommon<Data> {
336        /// Return the TLS-encoded transport parameters for the session's peer.
337        ///
338        /// While the transport parameters are technically available prior to the
339        /// completion of the handshake, they cannot be fully trusted until the
340        /// handshake completes, and reliance on them should be minimized.
341        /// However, any tampering with the parameters will cause the handshake
342        /// to fail.
343        pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
344            self.core
345                .common_state
346                .quic
347                .params
348                .as_ref()
349                .map(|v| v.as_ref())
350        }
351
352        /// Compute the keys for encrypting/decrypting 0-RTT packets, if available
353        pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
354            let suite = self
355                .core
356                .common_state
357                .suite
358                .and_then(|suite| suite.tls13())?;
359            Some(DirectionalKeys::new(
360                suite,
361                suite.quic?,
362                self.core
363                    .common_state
364                    .quic
365                    .early_secret
366                    .as_ref()?,
367                self.core.common_state.quic.version,
368            ))
369        }
370
371        /// Consume unencrypted TLS handshake data.
372        ///
373        /// Handshake data obtained from separate encryption levels should be supplied in separate calls.
374        pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
375            let range = self.deframer_buffer.extend(plaintext);
376
377            self.core.hs_deframer.input_message(
378                InboundPlainMessage {
379                    typ: ContentType::Handshake,
380                    version: ProtocolVersion::TLSv1_3,
381                    payload: &self.deframer_buffer.filled()[range.clone()],
382                },
383                &Locator::new(self.deframer_buffer.filled()),
384                range.end,
385            );
386
387            // `core.process_new_packets` should not process any data in `deframer_buffer`;
388            // it is already ready in `hs_deframer`.
389            self.deframer_buffer.processed = range.end;
390
391            self.core
392                .hs_deframer
393                .coalesce(self.deframer_buffer.filled_mut())?;
394
395            self.core
396                .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)?;
397
398            Ok(())
399        }
400
401        /// Emit unencrypted TLS handshake data.
402        ///
403        /// When this returns `Some(_)`, the new keys must be used for future handshake data.
404        pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
405            self.core
406                .common_state
407                .quic
408                .write_hs(buf)
409        }
410
411        /// Emit the TLS description code of a fatal alert, if one has arisen.
412        ///
413        /// Check after `read_hs` returns `Err(_)`.
414        pub fn alert(&self) -> Option<AlertDescription> {
415            self.core.common_state.quic.alert
416        }
417    }
418
419    impl<Data> Deref for ConnectionCommon<Data> {
420        type Target = CommonState;
421
422        fn deref(&self) -> &Self::Target {
423            &self.core.common_state
424        }
425    }
426
427    impl<Data> DerefMut for ConnectionCommon<Data> {
428        fn deref_mut(&mut self) -> &mut Self::Target {
429            &mut self.core.common_state
430        }
431    }
432
433    impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
434        fn from(core: ConnectionCore<Data>) -> Self {
435            Self {
436                core,
437                deframer_buffer: DeframerVecBuffer::default(),
438                sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
439            }
440        }
441    }
442}
443
444#[cfg(feature = "std")]
445pub use connection::{ClientConnection, Connection, ConnectionCommon, ServerConnection};
446
447#[derive(Default)]
448pub(crate) struct Quic {
449    /// QUIC transport parameters received from the peer during the handshake
450    pub(crate) params: Option<Vec<u8>>,
451    pub(crate) alert: Option<AlertDescription>,
452    pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
453    pub(crate) early_secret: Option<OkmBlock>,
454    pub(crate) hs_secrets: Option<Secrets>,
455    pub(crate) traffic_secrets: Option<Secrets>,
456    /// Whether keys derived from traffic_secrets have been passed to the QUIC implementation
457    #[cfg(feature = "std")]
458    pub(crate) returned_traffic_keys: bool,
459    pub(crate) version: Version,
460}
461
462#[cfg(feature = "std")]
463impl Quic {
464    pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
465        while let Some((_, msg)) = self.hs_queue.pop_front() {
466            buf.extend_from_slice(&msg);
467            if let Some(&(true, _)) = self.hs_queue.front() {
468                if self.hs_secrets.is_some() {
469                    // Allow the caller to switch keys before proceeding.
470                    break;
471                }
472            }
473        }
474
475        if let Some(secrets) = self.hs_secrets.take() {
476            return Some(KeyChange::Handshake {
477                keys: Keys::new(&secrets),
478            });
479        }
480
481        if let Some(mut secrets) = self.traffic_secrets.take() {
482            if !self.returned_traffic_keys {
483                self.returned_traffic_keys = true;
484                let keys = Keys::new(&secrets);
485                secrets.update();
486                return Some(KeyChange::OneRtt {
487                    keys,
488                    next: secrets,
489                });
490            }
491        }
492
493        None
494    }
495}
496
497/// Secrets used to encrypt/decrypt traffic
498#[derive(Clone)]
499pub struct Secrets {
500    /// Secret used to encrypt packets transmitted by the client
501    pub(crate) client: OkmBlock,
502    /// Secret used to encrypt packets transmitted by the server
503    pub(crate) server: OkmBlock,
504    /// Cipher suite used with these secrets
505    suite: &'static Tls13CipherSuite,
506    quic: &'static dyn Algorithm,
507    side: Side,
508    version: Version,
509}
510
511impl Secrets {
512    pub(crate) fn new(
513        client: OkmBlock,
514        server: OkmBlock,
515        suite: &'static Tls13CipherSuite,
516        quic: &'static dyn Algorithm,
517        side: Side,
518        version: Version,
519    ) -> Self {
520        Self {
521            client,
522            server,
523            suite,
524            quic,
525            side,
526            version,
527        }
528    }
529
530    /// Derive the next set of packet keys
531    pub fn next_packet_keys(&mut self) -> PacketKeySet {
532        let keys = PacketKeySet::new(self);
533        self.update();
534        keys
535    }
536
537    pub(crate) fn update(&mut self) {
538        self.client = hkdf_expand_label_block(
539            self.suite
540                .hkdf_provider
541                .expander_for_okm(&self.client)
542                .as_ref(),
543            self.version.key_update_label(),
544            &[],
545        );
546        self.server = hkdf_expand_label_block(
547            self.suite
548                .hkdf_provider
549                .expander_for_okm(&self.server)
550                .as_ref(),
551            self.version.key_update_label(),
552            &[],
553        );
554    }
555
556    fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
557        match self.side {
558            Side::Client => (&self.client, &self.server),
559            Side::Server => (&self.server, &self.client),
560        }
561    }
562}
563
564/// Keys used to communicate in a single direction
565pub struct DirectionalKeys {
566    /// Encrypts or decrypts a packet's headers
567    pub header: Box<dyn HeaderProtectionKey>,
568    /// Encrypts or decrypts the payload of a packet
569    pub packet: Box<dyn PacketKey>,
570}
571
572impl DirectionalKeys {
573    pub(crate) fn new(
574        suite: &'static Tls13CipherSuite,
575        quic: &'static dyn Algorithm,
576        secret: &OkmBlock,
577        version: Version,
578    ) -> Self {
579        let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
580        Self {
581            header: builder.header_protection_key(),
582            packet: builder.packet_key(),
583        }
584    }
585}
586
587/// All AEADs we support have 16-byte tags.
588const TAG_LEN: usize = 16;
589
590/// Authentication tag from an AEAD seal operation.
591pub struct Tag([u8; TAG_LEN]);
592
593impl From<&[u8]> for Tag {
594    fn from(value: &[u8]) -> Self {
595        let mut array = [0u8; TAG_LEN];
596        array.copy_from_slice(value);
597        Self(array)
598    }
599}
600
601impl AsRef<[u8]> for Tag {
602    fn as_ref(&self) -> &[u8] {
603        &self.0
604    }
605}
606
607/// How a `Tls13CipherSuite` generates `PacketKey`s and `HeaderProtectionKey`s.
608pub trait Algorithm: Send + Sync {
609    /// Produce a `PacketKey` encrypter/decrypter for this suite.
610    ///
611    /// `suite` is the entire suite this `Algorithm` appeared in.
612    /// `key` and `iv` is the key material to use.
613    fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
614
615    /// Produce a `HeaderProtectionKey` encrypter/decrypter for this suite.
616    ///
617    /// `key` is the key material, which is `aead_key_len()` bytes in length.
618    fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
619
620    /// The length in bytes of keys for this Algorithm.
621    ///
622    /// This controls the size of `AeadKey`s presented to `packet_key()` and `header_protection_key()`.
623    fn aead_key_len(&self) -> usize;
624
625    /// Whether this algorithm is FIPS-approved.
626    fn fips(&self) -> bool {
627        false
628    }
629}
630
631/// A QUIC header protection key
632pub trait HeaderProtectionKey: Send + Sync {
633    /// Adds QUIC Header Protection.
634    ///
635    /// `sample` must contain the sample of encrypted payload; see
636    /// [Header Protection Sample].
637    ///
638    /// `first` must reference the first byte of the header, referred to as
639    /// `packet[0]` in [Header Protection Application].
640    ///
641    /// `packet_number` must reference the Packet Number field; this is
642    /// `packet[pn_offset:pn_offset+pn_length]` in [Header Protection Application].
643    ///
644    /// Returns an error without modifying anything if `sample` is not
645    /// the correct length (see [Header Protection Sample] and [`Self::sample_len()`]),
646    /// or `packet_number` is longer than allowed (see [Packet Number Encoding and Decoding]).
647    ///
648    /// Otherwise, `first` and `packet_number` will have the header protection added.
649    ///
650    /// [Header Protection Application]: https://datatracker.ietf.org/doc/html/rfc9001#section-5.4.1
651    /// [Header Protection Sample]: https://datatracker.ietf.org/doc/html/rfc9001#section-5.4.2
652    /// [Packet Number Encoding and Decoding]: https://datatracker.ietf.org/doc/html/rfc9000#section-17.1
653    fn encrypt_in_place(
654        &self,
655        sample: &[u8],
656        first: &mut u8,
657        packet_number: &mut [u8],
658    ) -> Result<(), Error>;
659
660    /// Removes QUIC Header Protection.
661    ///
662    /// `sample` must contain the sample of encrypted payload; see
663    /// [Header Protection Sample].
664    ///
665    /// `first` must reference the first byte of the header, referred to as
666    /// `packet[0]` in [Header Protection Application].
667    ///
668    /// `packet_number` must reference the Packet Number field; this is
669    /// `packet[pn_offset:pn_offset+pn_length]` in [Header Protection Application].
670    ///
671    /// Returns an error without modifying anything if `sample` is not
672    /// the correct length (see [Header Protection Sample] and [`Self::sample_len()`]),
673    /// or `packet_number` is longer than allowed (see
674    /// [Packet Number Encoding and Decoding]).
675    ///
676    /// Otherwise, `first` and `packet_number` will have the header protection removed.
677    ///
678    /// [Header Protection Application]: https://datatracker.ietf.org/doc/html/rfc9001#section-5.4.1
679    /// [Header Protection Sample]: https://datatracker.ietf.org/doc/html/rfc9001#section-5.4.2
680    /// [Packet Number Encoding and Decoding]: https://datatracker.ietf.org/doc/html/rfc9000#section-17.1
681    fn decrypt_in_place(
682        &self,
683        sample: &[u8],
684        first: &mut u8,
685        packet_number: &mut [u8],
686    ) -> Result<(), Error>;
687
688    /// Expected sample length for the key's algorithm
689    fn sample_len(&self) -> usize;
690}
691
692/// Keys to encrypt or decrypt the payload of a packet
693pub trait PacketKey: Send + Sync {
694    /// Encrypt a QUIC packet
695    ///
696    /// Takes a `packet_number`, used to derive the nonce; the packet `header`, which is used as
697    /// the additional authenticated data; and the `payload`. The authentication tag is returned if
698    /// encryption succeeds.
699    ///
700    /// Fails if and only if the payload is longer than allowed by the cipher suite's AEAD algorithm.
701    fn encrypt_in_place(
702        &self,
703        packet_number: u64,
704        header: &[u8],
705        payload: &mut [u8],
706    ) -> Result<Tag, Error>;
707
708    /// Decrypt a QUIC packet
709    ///
710    /// Takes the packet `header`, which is used as the additional authenticated data, and the
711    /// `payload`, which includes the authentication tag.
712    ///
713    /// If the return value is `Ok`, the decrypted payload can be found in `payload`, up to the
714    /// length found in the return value.
715    fn decrypt_in_place<'a>(
716        &self,
717        packet_number: u64,
718        header: &[u8],
719        payload: &'a mut [u8],
720    ) -> Result<&'a [u8], Error>;
721
722    /// Tag length for the underlying AEAD algorithm
723    fn tag_len(&self) -> usize;
724
725    /// Number of QUIC messages that can be safely encrypted with a single key of this type.
726    ///
727    /// Once a `MessageEncrypter` produced for this suite has encrypted more than
728    /// `confidentiality_limit` messages, an attacker gains an advantage in distinguishing it
729    /// from an ideal pseudorandom permutation (PRP).
730    ///
731    /// This is to be set on the assumption that messages are maximally sized --
732    /// 2 ** 16. For non-QUIC TCP connections see [`CipherSuiteCommon::confidentiality_limit`][csc-limit].
733    ///
734    /// [csc-limit]: crate::crypto::CipherSuiteCommon::confidentiality_limit
735    fn confidentiality_limit(&self) -> u64;
736
737    /// Number of QUIC messages that can be safely decrypted with a single key of this type
738    ///
739    /// Once a `MessageDecrypter` produced for this suite has failed to decrypt `integrity_limit`
740    /// messages, an attacker gains an advantage in forging messages.
741    ///
742    /// This is not relevant for TLS over TCP (which is also implemented in this crate)
743    /// because a single failed decryption is fatal to the connection.
744    /// However, this quantity is used by QUIC.
745    fn integrity_limit(&self) -> u64;
746}
747
748/// Packet protection keys for bidirectional 1-RTT communication
749pub struct PacketKeySet {
750    /// Encrypts outgoing packets
751    pub local: Box<dyn PacketKey>,
752    /// Decrypts incoming packets
753    pub remote: Box<dyn PacketKey>,
754}
755
756impl PacketKeySet {
757    fn new(secrets: &Secrets) -> Self {
758        let (local, remote) = secrets.local_remote();
759        let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
760        Self {
761            local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
762            remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
763        }
764    }
765}
766
767pub(crate) struct KeyBuilder<'a> {
768    expander: Box<dyn HkdfExpander>,
769    version: Version,
770    alg: &'a dyn Algorithm,
771}
772
773impl<'a> KeyBuilder<'a> {
774    pub(crate) fn new(
775        secret: &OkmBlock,
776        version: Version,
777        alg: &'a dyn Algorithm,
778        hkdf: &'a dyn Hkdf,
779    ) -> Self {
780        Self {
781            expander: hkdf.expander_for_okm(secret),
782            version,
783            alg,
784        }
785    }
786
787    /// Derive packet keys
788    pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
789        let aead_key_len = self.alg.aead_key_len();
790        let packet_key = hkdf_expand_label_aead_key(
791            self.expander.as_ref(),
792            aead_key_len,
793            self.version.packet_key_label(),
794            &[],
795        );
796
797        let packet_iv =
798            hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
799        self.alg
800            .packet_key(packet_key, packet_iv)
801    }
802
803    /// Derive header protection keys
804    pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
805        let header_key = hkdf_expand_label_aead_key(
806            self.expander.as_ref(),
807            self.alg.aead_key_len(),
808            self.version.header_key_label(),
809            &[],
810        );
811        self.alg
812            .header_protection_key(header_key)
813    }
814}
815
816/// Produces QUIC initial keys from a TLS 1.3 ciphersuite and a QUIC key generation algorithm.
817#[derive(Clone, Copy)]
818pub struct Suite {
819    /// The TLS 1.3 ciphersuite used to derive keys.
820    pub suite: &'static Tls13CipherSuite,
821    /// The QUIC key generation algorithm used to derive keys.
822    pub quic: &'static dyn Algorithm,
823}
824
825impl Suite {
826    /// Produce a set of initial keys given the connection ID, side and version
827    pub fn keys(&self, client_dst_connection_id: &[u8], side: Side, version: Version) -> Keys {
828        Keys::initial(
829            version,
830            self.suite,
831            self.quic,
832            client_dst_connection_id,
833            side,
834        )
835    }
836}
837
838/// Complete set of keys used to communicate with the peer
839pub struct Keys {
840    /// Encrypts outgoing packets
841    pub local: DirectionalKeys,
842    /// Decrypts incoming packets
843    pub remote: DirectionalKeys,
844}
845
846impl Keys {
847    /// Construct keys for use with initial packets
848    pub fn initial(
849        version: Version,
850        suite: &'static Tls13CipherSuite,
851        quic: &'static dyn Algorithm,
852        client_dst_connection_id: &[u8],
853        side: Side,
854    ) -> Self {
855        const CLIENT_LABEL: &[u8] = b"client in";
856        const SERVER_LABEL: &[u8] = b"server in";
857        let salt = version.initial_salt();
858        let hs_secret = suite
859            .hkdf_provider
860            .extract_from_secret(Some(salt), client_dst_connection_id);
861
862        let secrets = Secrets {
863            version,
864            client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
865            server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
866            suite,
867            quic,
868            side,
869        };
870        Self::new(&secrets)
871    }
872
873    fn new(secrets: &Secrets) -> Self {
874        let (local, remote) = secrets.local_remote();
875        Self {
876            local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
877            remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
878        }
879    }
880}
881
882/// Key material for use in QUIC packet spaces
883///
884/// QUIC uses 4 different sets of keys (and progressive key updates for long-running connections):
885///
886/// * Initial: these can be created from [`Keys::initial()`]
887/// * 0-RTT keys: can be retrieved from [`ConnectionCommon::zero_rtt_keys()`]
888/// * Handshake: these are returned from [`ConnectionCommon::write_hs()`] after `ClientHello` and
889///   `ServerHello` messages have been exchanged
890/// * 1-RTT keys: these are returned from [`ConnectionCommon::write_hs()`] after the handshake is done
891///
892/// Once the 1-RTT keys have been exchanged, either side may initiate a key update. Progressive
893/// update keys can be obtained from the [`Secrets`] returned in [`KeyChange::OneRtt`]. Note that
894/// only packet keys are updated by key updates; header protection keys remain the same.
895pub enum KeyChange {
896    /// Keys for the handshake space
897    Handshake {
898        /// Header and packet keys for the handshake space
899        keys: Keys,
900    },
901    /// Keys for 1-RTT data
902    OneRtt {
903        /// Header and packet keys for 1-RTT data
904        keys: Keys,
905        /// Secrets to derive updated keys from
906        next: Secrets,
907    },
908}
909
910/// QUIC protocol version
911///
912/// Governs version-specific behavior in the TLS layer
913#[non_exhaustive]
914#[derive(Clone, Copy, Debug)]
915pub enum Version {
916    /// Draft versions 29, 30, 31 and 32
917    V1Draft,
918    /// First stable RFC
919    V1,
920    /// Anti-ossification variant of V1
921    V2,
922}
923
924impl Version {
925    fn initial_salt(self) -> &'static [u8; 20] {
926        match self {
927            Self::V1Draft => &[
928                // https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-32#section-5.2
929                0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
930                0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
931            ],
932            Self::V1 => &[
933                // https://www.rfc-editor.org/rfc/rfc9001.html#name-initial-secrets
934                0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
935                0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
936            ],
937            Self::V2 => &[
938                // https://www.ietf.org/archive/id/draft-ietf-quic-v2-10.html#name-initial-salt-2
939                0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
940                0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
941            ],
942        }
943    }
944
945    /// Key derivation label for packet keys.
946    pub(crate) fn packet_key_label(&self) -> &'static [u8] {
947        match self {
948            Self::V1Draft | Self::V1 => b"quic key",
949            Self::V2 => b"quicv2 key",
950        }
951    }
952
953    /// Key derivation label for packet "IV"s.
954    pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
955        match self {
956            Self::V1Draft | Self::V1 => b"quic iv",
957            Self::V2 => b"quicv2 iv",
958        }
959    }
960
961    /// Key derivation for header keys.
962    pub(crate) fn header_key_label(&self) -> &'static [u8] {
963        match self {
964            Self::V1Draft | Self::V1 => b"quic hp",
965            Self::V2 => b"quicv2 hp",
966        }
967    }
968
969    fn key_update_label(&self) -> &'static [u8] {
970        match self {
971            Self::V1Draft | Self::V1 => b"quic ku",
972            Self::V2 => b"quicv2 ku",
973        }
974    }
975}
976
977impl Default for Version {
978    fn default() -> Self {
979        Self::V1
980    }
981}
982
983#[cfg(test)]
984mod tests {
985    use std::prelude::v1::*;
986
987    use super::PacketKey;
988    use crate::quic::HeaderProtectionKey;
989
990    #[test]
991    fn auto_traits() {
992        fn assert_auto<T: Send + Sync>() {}
993        assert_auto::<Box<dyn PacketKey>>();
994        assert_auto::<Box<dyn HeaderProtectionKey>>();
995    }
996}