quinn_noise/
aead.rs

1use bytes::BytesMut;
2use chacha20poly1305::{
3    aead::{AeadInPlace, NewAead},
4    ChaCha8Poly1305, Key, Nonce, Tag,
5};
6use quinn_proto::crypto::{CryptoError, HeaderKey, KeyPair, PacketKey};
7
8pub fn header_keypair() -> KeyPair<Box<dyn HeaderKey>> {
9    KeyPair {
10        local: Box::new(PlaintextHeaderKey),
11        remote: Box::new(PlaintextHeaderKey),
12    }
13}
14
15#[derive(Clone)]
16pub struct ChaCha8PacketKey(ChaCha8Poly1305);
17
18impl ChaCha8PacketKey {
19    pub fn new(key: [u8; 32]) -> Self {
20        let key = Key::from(key);
21        Self(ChaCha8Poly1305::new(&key))
22    }
23}
24
25impl PacketKey for ChaCha8PacketKey {
26    fn encrypt(&self, packet: u64, buf: &mut [u8], header_len: usize) {
27        let mut nonce = [0; 12];
28        nonce[4..].copy_from_slice(&packet.to_le_bytes());
29        let nonce = Nonce::from(nonce);
30        let (header, payload) = buf.split_at_mut(header_len);
31        let (content, auth) = payload.split_at_mut(payload.len() - self.tag_len());
32        let tag = self
33            .0
34            .encrypt_in_place_detached(&nonce, header, content)
35            .unwrap();
36        auth.copy_from_slice(&tag);
37    }
38
39    fn decrypt(
40        &self,
41        packet: u64,
42        header: &[u8],
43        payload: &mut BytesMut,
44    ) -> Result<(), CryptoError> {
45        let mut nonce = [0; 12];
46        nonce[4..].copy_from_slice(&packet.to_le_bytes());
47        let nonce = Nonce::from(nonce);
48        let len = payload.len() - self.tag_len();
49        let (content, tag) = payload.split_at_mut(len);
50        let tag = Tag::from_slice(tag);
51        self.0
52            .decrypt_in_place_detached(&nonce, header, content, tag)
53            .map_err(|_| CryptoError)?;
54        payload.truncate(len);
55        Ok(())
56    }
57
58    fn tag_len(&self) -> usize {
59        16
60    }
61
62    fn confidentiality_limit(&self) -> u64 {
63        u64::MAX
64    }
65
66    fn integrity_limit(&self) -> u64 {
67        u64::MAX
68    }
69}
70
71pub struct PlaintextHeaderKey;
72
73impl HeaderKey for PlaintextHeaderKey {
74    fn decrypt(&self, _pn_offset: usize, _packet: &mut [u8]) {}
75
76    fn encrypt(&self, _pn_offset: usize, _packet: &mut [u8]) {}
77
78    fn sample_size(&self) -> usize {
79        0
80    }
81}