Skip to main content

veilid_core/crypto/
guard.rs

1use core::marker::PhantomData;
2
3use super::*;
4
5/// Guard to access a particular cryptosystem
6#[must_use]
7pub struct CryptoSystemGuard<'a> {
8    crypto_system: Arc<dyn CryptoSystem + Send + Sync>,
9    _phantom: core::marker::PhantomData<&'a (dyn CryptoSystem + Send + Sync)>,
10}
11
12impl<'a> CryptoSystemGuard<'a> {
13    pub(super) fn new(crypto_system: Arc<dyn CryptoSystem + Send + Sync>) -> Self {
14        Self {
15            crypto_system,
16            _phantom: PhantomData,
17        }
18    }
19    pub fn as_async(self) -> AsyncCryptoSystemGuard<'a> {
20        AsyncCryptoSystemGuard { guard: self }
21    }
22}
23
24impl core::ops::Deref for CryptoSystemGuard<'_> {
25    type Target = dyn CryptoSystem + Send + Sync;
26
27    fn deref(&self) -> &Self::Target {
28        self.crypto_system.as_ref()
29    }
30}
31
32/// Async cryptosystem guard to help break up heavy blocking operations
33#[must_use]
34pub struct AsyncCryptoSystemGuard<'a> {
35    guard: CryptoSystemGuard<'a>,
36}
37
38async fn yielding<R, T: FnOnce() -> R>(x: T) -> R {
39    let out = x();
40    sleep(0).await;
41    out
42}
43
44impl AsyncCryptoSystemGuard<'_> {
45    // Accessors
46    pub fn kind(&self) -> CryptoKind {
47        self.guard.kind()
48    }
49    #[must_use]
50    pub fn crypto(&self) -> VeilidComponentGuard<'_, Crypto> {
51        self.guard.crypto()
52    }
53
54    // Cached Operations
55    pub async fn cached_dh(
56        &self,
57        key: &PublicKey,
58        secret: &SecretKey,
59    ) -> VeilidAPIResult<SharedSecret> {
60        yielding(|| self.guard.cached_dh(key, secret)).await
61    }
62
63    // Generation
64    pub async fn random_bytes(&self, len: usize) -> Vec<u8> {
65        yielding(|| self.guard.random_bytes(len)).await
66    }
67
68    pub async fn hash_password(&self, password: &[u8], salt: &[u8]) -> VeilidAPIResult<String> {
69        yielding(|| self.guard.hash_password(password, salt)).await
70    }
71    pub async fn verify_password(
72        &self,
73        password: &[u8],
74        password_hash: &str,
75    ) -> VeilidAPIResult<bool> {
76        yielding(|| self.guard.verify_password(password, password_hash)).await
77    }
78    pub async fn derive_shared_secret(
79        &self,
80        password: &[u8],
81        salt: &[u8],
82    ) -> VeilidAPIResult<SharedSecret> {
83        yielding(|| self.guard.derive_shared_secret(password, salt)).await
84    }
85    pub async fn random_nonce(&self) -> Nonce {
86        yielding(|| self.guard.random_nonce()).await
87    }
88    pub async fn random_shared_secret(&self) -> SharedSecret {
89        yielding(|| self.guard.random_shared_secret()).await
90    }
91    pub async fn compute_dh(
92        &self,
93        key: &PublicKey,
94        secret: &SecretKey,
95    ) -> VeilidAPIResult<SharedSecret> {
96        yielding(|| self.guard.compute_dh(key, secret)).await
97    }
98    pub async fn generate_shared_secret(
99        &self,
100        key: &PublicKey,
101        secret: &SecretKey,
102        domain: &[u8],
103    ) -> VeilidAPIResult<SharedSecret> {
104        let dh = self.compute_dh(key, secret).await?;
105        let hash = self
106            .generate_hash(&[&dh.into_value(), domain, VEILID_DOMAIN_API].concat())
107            .await;
108        Ok(SharedSecret::new(
109            hash.kind(),
110            BareSharedSecret::new(&hash.into_value()),
111        ))
112    }
113
114    pub async fn generate_keypair(&self) -> KeyPair {
115        yielding(|| self.guard.generate_keypair()).await
116    }
117
118    pub async fn generate_hash(&self, data: &[u8]) -> HashDigest {
119        yielding(|| self.guard.generate_hash(data)).await
120    }
121
122    pub async fn generate_hash_reader(
123        &self,
124        reader: &mut dyn std::io::Read,
125    ) -> VeilidAPIResult<PublicKey> {
126        yielding(|| self.guard.generate_hash_reader(reader)).await
127    }
128
129    // Validation
130    #[must_use]
131    pub fn shared_secret_length(&self) -> usize {
132        self.guard.shared_secret_length()
133    }
134    #[must_use]
135    pub fn nonce_length(&self) -> usize {
136        self.guard.nonce_length()
137    }
138    #[must_use]
139    pub fn hash_digest_length(&self) -> usize {
140        self.guard.hash_digest_length()
141    }
142    #[must_use]
143    pub fn public_key_length(&self) -> usize {
144        self.guard.public_key_length()
145    }
146    #[must_use]
147    pub fn secret_key_length(&self) -> usize {
148        self.guard.secret_key_length()
149    }
150    #[must_use]
151    pub fn signature_length(&self) -> usize {
152        self.guard.signature_length()
153    }
154    #[must_use]
155    pub fn aead_overhead(&self) -> usize {
156        self.guard.aead_overhead()
157    }
158    #[must_use]
159    pub fn default_salt_length(&self) -> usize {
160        self.guard.default_salt_length()
161    }
162    pub fn check_shared_secret(&self, secret: &SharedSecret) -> VeilidAPIResult<()> {
163        self.guard.check_shared_secret(secret)
164    }
165    pub fn check_nonce(&self, nonce: &Nonce) -> VeilidAPIResult<()> {
166        self.guard.check_nonce(nonce)
167    }
168    pub fn check_hash_digest(&self, hash: &HashDigest) -> VeilidAPIResult<()> {
169        self.guard.check_hash_digest(hash)
170    }
171    pub fn check_public_key(&self, key: &PublicKey) -> VeilidAPIResult<()> {
172        self.guard.check_public_key(key)
173    }
174    pub fn check_secret_key(&self, key: &SecretKey) -> VeilidAPIResult<()> {
175        self.guard.check_secret_key(key)
176    }
177    pub fn check_signature(&self, signature: &Signature) -> VeilidAPIResult<()> {
178        self.guard.check_signature(signature)
179    }
180    pub async fn validate_keypair(
181        &self,
182        key: &PublicKey,
183        secret: &SecretKey,
184    ) -> VeilidAPIResult<bool> {
185        yielding(|| self.guard.validate_keypair(key, secret)).await
186    }
187
188    pub async fn validate_hash(&self, data: &[u8], hash: &HashDigest) -> VeilidAPIResult<bool> {
189        yielding(|| self.guard.validate_hash(data, hash)).await
190    }
191
192    pub async fn validate_hash_reader(
193        &self,
194        reader: &mut dyn std::io::Read,
195        hash: &HashDigest,
196    ) -> VeilidAPIResult<bool> {
197        yielding(|| self.guard.validate_hash_reader(reader, hash)).await
198    }
199
200    // Authentication
201    pub async fn sign(
202        &self,
203        key: &PublicKey,
204        secret: &SecretKey,
205        data: &[u8],
206    ) -> VeilidAPIResult<Signature> {
207        yielding(|| self.guard.sign(key, secret, data)).await
208    }
209    pub async fn verify(
210        &self,
211        key: &PublicKey,
212        data: &[u8],
213        signature: &Signature,
214    ) -> VeilidAPIResult<bool> {
215        yielding(|| self.guard.verify(key, data, signature)).await
216    }
217
218    // AEAD Encrypt/Decrypt
219    pub async fn decrypt_in_place_aead(
220        &self,
221        body: &mut Vec<u8>,
222        nonce: &Nonce,
223        shared_secret: &SharedSecret,
224        associated_data: Option<&[u8]>,
225    ) -> VeilidAPIResult<()> {
226        yielding(|| {
227            self.guard
228                .decrypt_in_place_aead(body, nonce, shared_secret, associated_data)
229        })
230        .await
231    }
232
233    pub async fn decrypt_aead(
234        &self,
235        body: &[u8],
236        nonce: &Nonce,
237        shared_secret: &SharedSecret,
238        associated_data: Option<&[u8]>,
239    ) -> VeilidAPIResult<Vec<u8>> {
240        yielding(|| {
241            self.guard
242                .decrypt_aead(body, nonce, shared_secret, associated_data)
243        })
244        .await
245    }
246
247    pub async fn encrypt_in_place_aead(
248        &self,
249        body: &mut Vec<u8>,
250        nonce: &Nonce,
251        shared_secret: &SharedSecret,
252        associated_data: Option<&[u8]>,
253    ) -> VeilidAPIResult<()> {
254        yielding(|| {
255            self.guard
256                .encrypt_in_place_aead(body, nonce, shared_secret, associated_data)
257        })
258        .await
259    }
260
261    pub async fn encrypt_aead(
262        &self,
263        body: &[u8],
264        nonce: &Nonce,
265        shared_secret: &SharedSecret,
266        associated_data: Option<&[u8]>,
267    ) -> VeilidAPIResult<Vec<u8>> {
268        yielding(|| {
269            self.guard
270                .encrypt_aead(body, nonce, shared_secret, associated_data)
271        })
272        .await
273    }
274
275    // NoAuth Encrypt/Decrypt
276    pub async fn crypt_in_place_no_auth(
277        &self,
278        body: &mut [u8],
279        nonce: &Nonce,
280        shared_secret: &SharedSecret,
281    ) -> VeilidAPIResult<()> {
282        yielding(|| {
283            self.guard
284                .crypt_in_place_no_auth(body, nonce, shared_secret)
285        })
286        .await
287    }
288
289    pub async fn crypt_b2b_no_auth(
290        &self,
291        in_buf: &[u8],
292        out_buf: &mut [u8],
293        nonce: &Nonce,
294        shared_secret: &SharedSecret,
295    ) -> VeilidAPIResult<()> {
296        yielding(|| {
297            self.guard
298                .crypt_b2b_no_auth(in_buf, out_buf, nonce, shared_secret)
299        })
300        .await
301    }
302
303    pub async fn crypt_no_auth_aligned_8(
304        &self,
305        body: &[u8],
306        nonce: &Nonce,
307        shared_secret: &SharedSecret,
308    ) -> VeilidAPIResult<Vec<u8>> {
309        yielding(|| {
310            self.guard
311                .crypt_no_auth_aligned_8(body, nonce, shared_secret)
312        })
313        .await
314    }
315
316    pub async fn crypt_no_auth_unaligned(
317        &self,
318        body: &[u8],
319        nonce: &Nonce,
320        shared_secret: &SharedSecret,
321    ) -> VeilidAPIResult<Vec<u8>> {
322        yielding(|| {
323            self.guard
324                .crypt_no_auth_unaligned(body, nonce, shared_secret)
325        })
326        .await
327    }
328}