rustls_rustcrypto/
quic.rs1#![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)] pub 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 iv: Iv,
49
50 #[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 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 payload.copy_from_slice(&payload_);
107
108 let plain_len = payload_len - self.tag_len();
109 Ok(&payload[..plain_len])
110 }
111
112 #[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)] pub 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}