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