Skip to main content

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