rustls_rustcrypto/
quic.rs

1#![allow(clippy::duplicate_mod)]
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5
6use aead::AeadCore;
7use chacha20poly1305::{AeadInPlace, KeyInit, KeySizeUser};
8use crypto_common::typenum::Unsigned;
9use rustls::crypto::cipher::{self, AeadKey, Iv};
10use rustls::{quic, Error, Tls13CipherSuite};
11
12#[allow(dead_code)] // TODO
13pub struct HeaderProtectionKey(AeadKey);
14
15impl HeaderProtectionKey {
16    pub fn new(key: AeadKey) -> Self {
17        Self(key)
18    }
19}
20
21impl quic::HeaderProtectionKey for HeaderProtectionKey {
22    fn encrypt_in_place(
23        &self,
24        _sample: &[u8],
25        _first: &mut u8,
26        _packet_number: &mut [u8],
27    ) -> Result<(), Error> {
28        todo!()
29    }
30
31    fn decrypt_in_place(
32        &self,
33        _sample: &[u8],
34        _first: &mut u8,
35        _packet_number: &mut [u8],
36    ) -> Result<(), Error> {
37        todo!()
38    }
39
40    #[inline]
41    fn sample_len(&self) -> usize {
42        todo!()
43    }
44}
45
46pub struct PacketKey {
47    /// Computes unique nonces for each packet
48    iv: Iv,
49
50    /// The cipher suite used for this packet key
51    #[allow(dead_code)]
52    suite: &'static Tls13CipherSuite,
53
54    crypto: chacha20poly1305::ChaCha20Poly1305,
55}
56
57impl PacketKey {
58    pub fn new(suite: &'static Tls13CipherSuite, key: AeadKey, iv: Iv) -> Self {
59        Self {
60            iv,
61            suite,
62            crypto: chacha20poly1305::ChaCha20Poly1305::new_from_slice(key.as_ref())
63                .expect("key should be valid"),
64        }
65    }
66}
67
68impl quic::PacketKey for PacketKey {
69    fn encrypt_in_place(
70        &self,
71        packet_number: u64,
72        aad: &[u8],
73        payload: &mut [u8],
74    ) -> Result<quic::Tag, Error> {
75        let nonce = cipher::Nonce::new(&self.iv, packet_number).0;
76
77        let tag = self
78            .crypto
79            .encrypt_in_place_detached(&nonce.into(), aad, payload)
80            .map_err(|_| rustls::Error::EncryptError)?;
81        Ok(quic::Tag::from(tag.as_ref()))
82    }
83
84    /// Decrypt a QUIC packet
85    ///
86    /// Takes the packet `header`, which is used as the additional authenticated
87    /// data, and the `payload`, which includes the authentication tag.
88    ///
89    /// If the return value is `Ok`, the decrypted payload can be found in
90    /// `payload`, up to the length found in the return value.
91    fn decrypt_in_place<'a>(
92        &self,
93        packet_number: u64,
94        aad: &[u8],
95        payload: &'a mut [u8],
96    ) -> Result<&'a [u8], Error> {
97        let mut payload_ = payload.to_vec();
98        let payload_len = payload_.len();
99        let nonce = chacha20poly1305::Nonce::from(cipher::Nonce::new(&self.iv, packet_number).0);
100
101        self.crypto
102            .decrypt_in_place(&nonce, aad, &mut payload_)
103            .map_err(|_| rustls::Error::DecryptError)?;
104
105        // Unfortunately the lifetime bound on decrypt_in_place sucks
106        payload.copy_from_slice(&payload_);
107
108        let plain_len = payload_len - self.tag_len();
109        Ok(&payload[..plain_len])
110    }
111
112    /// Tag length for the underlying AEAD algorithm
113    #[inline]
114    fn tag_len(&self) -> usize {
115        <chacha20poly1305::ChaCha20Poly1305 as AeadCore>::TagSize::to_usize()
116    }
117
118    fn integrity_limit(&self) -> u64 {
119        1 << 36
120    }
121
122    fn confidentiality_limit(&self) -> u64 {
123        u64::MAX
124    }
125}
126
127#[allow(dead_code)] // TODO
128pub struct KeyBuilder(AeadKey);
129
130impl rustls::quic::Algorithm for KeyBuilder {
131    fn packet_key(&self, _key: AeadKey, _iv: Iv) -> Box<dyn quic::PacketKey> {
132        todo!()
133    }
134
135    fn header_protection_key(&self, key: AeadKey) -> Box<dyn quic::HeaderProtectionKey> {
136        Box::new(HeaderProtectionKey::new(key))
137    }
138
139    fn aead_key_len(&self) -> usize {
140        chacha20poly1305::ChaCha20Poly1305::key_size()
141    }
142}