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