Skip to main content

veilid_core/crypto/crypto_system/
mod.rs

1use std::ops::Range;
2
3use super::*;
4mod blake3digest512;
5
6#[cfg(feature = "enable-crypto-none")]
7pub(crate) mod none;
8#[cfg(feature = "enable-crypto-vld0")]
9pub(crate) mod vld0;
10// #[cfg(feature = "enable-crypto-vld1")]
11// pub(crate) mod vld1;
12
13pub(crate) const VEILID_DOMAIN_API: &[u8] = b"VEILID_API";
14
15#[cfg(feature = "enable-crypto-none")]
16pub use none::sizes::*;
17#[cfg(feature = "enable-crypto-none")]
18pub use none::*;
19#[cfg(feature = "enable-crypto-vld0")]
20pub use vld0::sizes::*;
21#[cfg(feature = "enable-crypto-vld0")]
22pub use vld0::*;
23// #[cfg(feature = "enable-crypto-vld1")]
24// pub use vld1::*;
25
26pub use blake3digest512::*;
27
28pub trait CryptoSystemBuffer: AsRef<[u8]> + AsMut<[u8]> {
29    /// Get the length of the buffer
30    fn len(&self) -> usize;
31
32    /// Is the buffer empty?
33    fn is_empty(&self) -> bool;
34
35    /// Extend this buffer from the given slice
36    fn extend_from_slice(&mut self, other: &[u8]);
37
38    /// Truncate this buffer to the given size
39    fn truncate(&mut self, len: usize);
40}
41
42impl CryptoSystemBuffer for Vec<u8> {
43    fn len(&self) -> usize {
44        Vec::<u8>::len(self)
45    }
46
47    fn is_empty(&self) -> bool {
48        Vec::<u8>::is_empty(self)
49    }
50
51    fn extend_from_slice(&mut self, other: &[u8]) {
52        Vec::<u8>::extend_from_slice(self, other);
53    }
54
55    fn truncate(&mut self, len: usize) {
56        Vec::<u8>::truncate(self, len);
57    }
58}
59
60impl CryptoSystemBuffer for BytesMut {
61    fn len(&self) -> usize {
62        BytesMut::len(self)
63    }
64
65    fn is_empty(&self) -> bool {
66        BytesMut::is_empty(self)
67    }
68
69    fn extend_from_slice(&mut self, other: &[u8]) {
70        BytesMut::extend_from_slice(self, other);
71    }
72
73    fn truncate(&mut self, len: usize) {
74        BytesMut::truncate(self, len);
75    }
76}
77
78pub trait CryptoSystem {
79    // Accessors
80    fn kind(&self) -> CryptoKind;
81    fn crypto(&self) -> VeilidComponentGuard<'_, Crypto>;
82
83    // Cached Operations
84    fn cached_dh(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<SharedSecret>;
85
86    // Generation
87    fn random_bytes(&self, len: usize) -> Vec<u8>;
88    fn hash_password(&self, password: &[u8], salt: &[u8]) -> VeilidAPIResult<String>;
89    fn verify_password(&self, password: &[u8], password_hash: &str) -> VeilidAPIResult<bool>;
90    fn derive_shared_secret(&self, password: &[u8], salt: &[u8]) -> VeilidAPIResult<SharedSecret>;
91    fn random_nonce(&self) -> Nonce;
92    fn random_shared_secret(&self) -> SharedSecret;
93    fn compute_dh(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<SharedSecret>;
94    fn generate_shared_secret(
95        &self,
96        key: &PublicKey,
97        secret: &SecretKey,
98        domain: &[u8],
99    ) -> VeilidAPIResult<SharedSecret> {
100        let dh = self.compute_dh(key, secret)?;
101        let hash = self.generate_hash(&[&dh.into_value(), domain, VEILID_DOMAIN_API].concat());
102        Ok(SharedSecret::new(
103            hash.kind(),
104            BareSharedSecret::new(&hash.into_value()),
105        ))
106    }
107    fn generate_keypair(&self) -> KeyPair;
108    fn generate_hash(&self, data: &[u8]) -> HashDigest;
109    fn generate_hash_reader(&self, reader: &mut dyn std::io::Read) -> VeilidAPIResult<PublicKey>;
110
111    // Validation
112    fn shared_secret_length(&self) -> usize;
113    fn nonce_length(&self) -> usize;
114    fn hash_digest_length(&self) -> usize;
115    fn public_key_length(&self) -> usize;
116    fn secret_key_length(&self) -> usize;
117    fn signature_length(&self) -> usize;
118    fn default_salt_length(&self) -> usize;
119    fn aead_overhead(&self) -> usize;
120
121    fn check_shared_secret(&self, secret: &SharedSecret) -> VeilidAPIResult<()> {
122        if secret.kind() != self.kind() {
123            apibail_generic!("incorrect shared secret kind");
124        }
125        if secret.value().len() != self.shared_secret_length() {
126            apibail_generic!(
127                "invalid shared secret length: {} != {}",
128                secret.value().len(),
129                self.shared_secret_length()
130            );
131        }
132        Ok(())
133    }
134    fn check_nonce(&self, nonce: &Nonce) -> VeilidAPIResult<()> {
135        if nonce.len() != self.nonce_length() {
136            apibail_generic!(
137                "invalid nonce length: {} != {}",
138                nonce.len(),
139                self.nonce_length()
140            );
141        }
142        Ok(())
143    }
144    fn check_hash_digest(&self, hash: &HashDigest) -> VeilidAPIResult<()> {
145        if hash.kind() != self.kind() {
146            apibail_generic!("incorrect hash digest kind");
147        }
148        if hash.value().len() != self.hash_digest_length() {
149            apibail_generic!(
150                "invalid hash digest length: {} != {}",
151                hash.value().len(),
152                self.hash_digest_length()
153            );
154        }
155        Ok(())
156    }
157    fn check_public_key(&self, key: &PublicKey) -> VeilidAPIResult<()> {
158        if key.kind() != self.kind() {
159            apibail_generic!("incorrect public key kind");
160        }
161        if key.value().len() != self.public_key_length() {
162            apibail_generic!(
163                "invalid public key length: {} != {}",
164                key.value().len(),
165                self.public_key_length()
166            );
167        }
168        Ok(())
169    }
170    fn check_secret_key(&self, key: &SecretKey) -> VeilidAPIResult<()> {
171        if key.kind() != self.kind() {
172            apibail_generic!("incorrect secret key kind");
173        }
174        if key.value().len() != self.secret_key_length() {
175            apibail_generic!(
176                "invalid secret key length: {} != {}",
177                key.value().len(),
178                self.secret_key_length()
179            );
180        }
181        Ok(())
182    }
183    fn check_signature(&self, signature: &Signature) -> VeilidAPIResult<()> {
184        if signature.kind() != self.kind() {
185            apibail_generic!("incorrect signature kind");
186        }
187        if signature.value().len() != self.signature_length() {
188            apibail_generic!(
189                "invalid signature length: {} != {}",
190                signature.value().len(),
191                self.signature_length()
192            );
193        }
194        Ok(())
195    }
196    fn check_keypair(&self, keypair: &KeyPair) -> VeilidAPIResult<()> {
197        if keypair.kind() != self.kind() {
198            apibail_generic!("incorrect keypair kind");
199        }
200        self.check_public_key(&keypair.key())?;
201        self.check_secret_key(&keypair.secret())?;
202        Ok(())
203    }
204
205    fn validate_keypair(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<bool>;
206    fn validate_hash(&self, data: &[u8], hash: &HashDigest) -> VeilidAPIResult<bool>;
207    fn validate_hash_reader(
208        &self,
209        reader: &mut dyn std::io::Read,
210        hash: &HashDigest,
211    ) -> VeilidAPIResult<bool>;
212
213    // Authentication
214    fn sign(
215        &self,
216        public_key: &PublicKey,
217        secret: &SecretKey,
218        data: &[u8],
219    ) -> VeilidAPIResult<Signature>;
220    fn sign_in_place(
221        &self,
222        public_key: &PublicKey,
223        secret: &SecretKey,
224        data: &mut [u8],
225        range: Range<usize>,
226        sig_idx: usize,
227    ) -> VeilidAPIResult<()>;
228    fn verify(
229        &self,
230        public_key: &PublicKey,
231        data: &[u8],
232        signature: &Signature,
233    ) -> VeilidAPIResult<bool>;
234    fn verify_in_place(
235        &self,
236        public_key: &PublicKey,
237        data: &[u8],
238        range: Range<usize>,
239        sig_idx: usize,
240    ) -> VeilidAPIResult<bool>;
241
242    // AEAD Encrypt/Decrypt
243    fn decrypt_in_place_aead(
244        &self,
245        body: &mut dyn CryptoSystemBuffer,
246        nonce: &Nonce,
247        shared_secret: &SharedSecret,
248        associated_data: Option<&[u8]>,
249    ) -> VeilidAPIResult<()>;
250    fn decrypt_aead(
251        &self,
252        body: &[u8],
253        nonce: &Nonce,
254        shared_secret: &SharedSecret,
255        associated_data: Option<&[u8]>,
256    ) -> VeilidAPIResult<Vec<u8>>;
257    fn encrypt_in_place_aead(
258        &self,
259        body: &mut dyn CryptoSystemBuffer,
260        nonce: &Nonce,
261        shared_secret: &SharedSecret,
262        associated_data: Option<&[u8]>,
263    ) -> VeilidAPIResult<()>;
264    fn encrypt_aead(
265        &self,
266        body: &[u8],
267        nonce: &Nonce,
268        shared_secret: &SharedSecret,
269        associated_data: Option<&[u8]>,
270    ) -> VeilidAPIResult<Vec<u8>>;
271
272    // NoAuth Encrypt/Decrypt
273    fn crypt_in_place_no_auth(
274        &self,
275        body: &mut [u8],
276        nonce: &Nonce,
277        shared_secret: &SharedSecret,
278    ) -> VeilidAPIResult<()>;
279    fn crypt_b2b_no_auth(
280        &self,
281        in_buf: &[u8],
282        out_buf: &mut [u8],
283        nonce: &Nonce,
284        shared_secret: &SharedSecret,
285    ) -> VeilidAPIResult<()>;
286    fn crypt_no_auth_aligned_8(
287        &self,
288        body: &[u8],
289        nonce: &Nonce,
290        shared_secret: &SharedSecret,
291    ) -> VeilidAPIResult<Vec<u8>>;
292    fn crypt_no_auth_unaligned(
293        &self,
294        body: &[u8],
295        nonce: &Nonce,
296        shared_secret: &SharedSecret,
297    ) -> VeilidAPIResult<Vec<u8>>;
298}