1use rand_core::{CryptoRng, RngCore};
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7use crate::handshake::HandshakeVersion;
8
9pub mod backends;
10#[cfg(any(test, feature = "keylog"))]
11pub mod keylog;
12pub mod noise;
13pub mod transport;
14
15#[derive(Debug)]
16pub enum CryptoError {
17 DecryptionFailed,
18 InvalidProtocol,
19 UnsupportedProtocol,
20 UnsupportedSecretKey,
21 InvalidInitialization,
22 InvalidKeySize,
23 InvalidState,
24 InsufficientBuffer,
25 StateExhausted,
26 Internal,
27}
28
29impl core::fmt::Display for CryptoError {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 core::fmt::Debug::fmt(&self, f)
32 }
33}
34
35impl core::error::Error for CryptoError {}
36
37pub const HYPHAE_AEAD_KEY_LEN: usize = 32;
38pub const HYPHAE_AEAD_TAG_LEN: usize = 16;
39pub const HYPHAE_AEAD_NONCE_LEN: usize = 12;
40pub const HYPHAE_HEADER_SAMPLE_LEN: usize = 16;
41pub const HYPHAE_HEADER_MASK_MAX_LEN: usize = 16;
42
43#[derive(Clone, Zeroize, ZeroizeOnDrop, Default)]
44pub struct SymmetricKey ([u8; Self::SIZE]);
45
46impl SymmetricKey {
47 pub const SIZE: usize = HYPHAE_AEAD_KEY_LEN;
48}
49
50impl AsRef<[u8; Self::SIZE]> for SymmetricKey {
51 fn as_ref(&self) -> &[u8; Self::SIZE] {
52 &self.0
53 }
54}
55
56impl AsMut<[u8; Self::SIZE]> for SymmetricKey {
57 fn as_mut(&mut self) -> &mut [u8; Self::SIZE] {
58 &mut self.0
59 }
60}
61
62#[non_exhaustive]
63pub enum SecretKeySetup<'a> {
64 Local (&'a [u8]),
67
68 BackendRemote,
71}
72
73impl SecretKeySetup<'_> {
74 pub fn remote() -> SecretKeySetup<'static> {
75 SecretKeySetup::BackendRemote
76 }
77}
78
79impl <'a> From<&'a [u8]> for SecretKeySetup<'a> {
80 fn from(value: &'a [u8]) -> Self {
81 SecretKeySetup::Local(value)
82 }
83}
84
85pub trait CryptoBackend {
86 type InitialCrypto: InitialCrypto;
88
89 type NoiseHandshake: NoiseHandshake;
91
92 type TransportCrypto: TransportCrypto;
94
95 type TransportRekey: TransportRekey;
97
98 fn protocol_supported(&self, noise_protocol: &str) -> bool;
101
102 fn initial_crypto(&self) -> Self::InitialCrypto;
109
110 fn new_handshake(&self) -> Result<Self::NoiseHandshake, CryptoError>;
113
114 fn transport_crypto(&self, handshake: &Self::NoiseHandshake) -> Result<Self::TransportCrypto, CryptoError>;
120
121 fn export_1rtt_rekey(&self, handshake: &mut Self::NoiseHandshake, rekey: &mut Self::TransportRekey) -> Result<(), CryptoError>;
123
124}
125
126pub trait NoiseHandshake {
127 fn initialize<'a> (
128 &mut self,
129 rng: &mut (impl CryptoRng + RngCore),
130 protocol_name: &str,
131 initiator: bool,
132 prologue: impl Iterator<Item = &'a[u8]>,
133 s: Option<SecretKeySetup>,
134 rs: Option<&[u8]>
135 ) -> Result<(), CryptoError>;
136
137 fn write_message_in_place(&mut self, buffer: &mut [u8]) -> Result<(), CryptoError>;
138
139 fn read_message_in_place<'a> (&mut self, buffer: &'a mut [u8]) -> Result<&'a [u8], CryptoError>;
140
141 fn next_message_layout(&self) -> Result<(usize, usize), CryptoError>;
142
143 fn is_reset(&self) -> bool;
144
145 fn is_initiator(&self) -> bool;
146
147 fn is_my_turn(&self) -> bool;
148
149 fn is_finished(&self) -> bool;
150
151 fn remote_public(&self) -> Option<&[u8]>;
152
153 fn handshake_hash(&self) -> &[u8];
154
155 fn get_ask(&mut self, label: &[u8], key: &mut SymmetricKey) -> Result<(), CryptoError>;
156}
157
158pub trait InitialCrypto: TransportCrypto {
159 fn initial_level_secret(&self, handshake_version: HandshakeVersion, transport_label: &[u8], client_dcid: &[u8], level_secret: &mut SymmetricKey) -> Result<(), CryptoError>;
160
161 fn retry_tag_secret(&self, handshake_version: HandshakeVersion, transport_label: &[u8], client_dcid: &[u8], level_secret: &mut SymmetricKey) -> Result<(), CryptoError>;
162}
163
164pub trait TransportCrypto: Clone {
165 type Hash: Send + Sync + 'static;
166
167 fn zeros_hash(&self) -> Self::Hash;
168
169 fn hash_into(&self, message: &[u8], output: &mut Self::Hash);
171
172 fn hkdf(&self, key: &Self::Hash, ikm: &[u8], info: &[u8], output: &mut Self::Hash);
173
174 fn hash_as_slice<'a> (&self, hash: &'a Self::Hash) -> &'a [u8];
175
176 fn hash_as_mut_slice<'a> (&self, hash: &'a mut Self::Hash) -> &'a mut[u8];
177
178 fn derive_subkey(&self, level_secret: &SymmetricKey, label: &[u8], output_key: &mut SymmetricKey);
179
180 fn aead_confidentiality_limit(&self) -> u64;
181
182 fn aead_integrity_limit(&self) -> u64;
183
184 fn encrypt_in_place(&self, packet_key: &SymmetricKey, packet_id: u64, ad: &[u8], buffer: &mut [u8]) -> Result<(), CryptoError>;
185
186 fn decrypt_in_place<'a> (&self, packet_key: &SymmetricKey, packet_id: u64, ad: &[u8], buffer: &'a mut [u8]) -> Result<&'a [u8], CryptoError>;
187
188 fn header_protection_mask(&self, header_key: &SymmetricKey, sample: &[u8], mask: &mut [u8]) -> Result<(), CryptoError>;
189}
190
191pub trait TransportRekey: Default {
192 fn next_1rtt_secret(&mut self, level_secret: &mut SymmetricKey);
193}
194
195pub trait SyncCryptoBackend:
200 CryptoBackend<
201 InitialCrypto: Send + Sync + 'static,
202 NoiseHandshake: Send + Sync + 'static,
203 TransportCrypto: Send + Sync + 'static,
204 TransportRekey: Send + Sync + 'static,
205 > + Sync + Send + 'static
206{}
207
208impl <B> SyncCryptoBackend for B
209where
210 B: CryptoBackend + Send + Sync + 'static,
211 B::InitialCrypto: Send + Sync + 'static,
212 B::NoiseHandshake: Send + Sync + 'static,
213 B::TransportCrypto: Send + Sync + 'static,
214 B::TransportRekey: Send + Sync + 'static,
215{}