Coverage Report

Created: 2026-01-30 06:08

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