1use core::marker::PhantomData;
2use std::ops::Range;
3
4use super::*;
5
6#[must_use]
8pub struct CryptoSystemGuard<'a> {
9 crypto_system: Arc<dyn CryptoSystem + Send + Sync>,
10 _phantom: core::marker::PhantomData<&'a (dyn CryptoSystem + Send + Sync)>,
11}
12
13impl<'a> CryptoSystemGuard<'a> {
14 pub(super) fn new(crypto_system: Arc<dyn CryptoSystem + Send + Sync>) -> Self {
15 Self {
16 crypto_system,
17 _phantom: PhantomData,
18 }
19 }
20 pub fn as_async(self) -> AsyncCryptoSystemGuard<'a> {
21 AsyncCryptoSystemGuard { guard: self }
22 }
23 pub(super) fn clone_arc(&self) -> Arc<dyn CryptoSystem + Send + Sync> {
25 self.crypto_system.clone()
26 }
27}
28
29impl core::ops::Deref for CryptoSystemGuard<'_> {
30 type Target = dyn CryptoSystem + Send + Sync;
31
32 fn deref(&self) -> &Self::Target {
33 self.crypto_system.as_ref()
34 }
35}
36
37#[must_use]
39pub struct AsyncCryptoSystemGuard<'a> {
40 guard: CryptoSystemGuard<'a>,
41}
42
43impl AsyncCryptoSystemGuard<'_> {
44 pub fn kind(&self) -> CryptoKind {
46 self.guard.kind()
47 }
48 #[must_use]
49 pub fn crypto(&self) -> VeilidComponentGuard<'_, Crypto> {
50 self.guard.crypto()
51 }
52
53 pub async fn cached_dh(
55 &self,
56 key: &PublicKey,
57 secret: &SecretKey,
58 ) -> VeilidAPIResult<SharedSecret> {
59 yielding(|| self.guard.cached_dh(key, secret)).await
60 }
61
62 pub async fn random_bytes(&self, len: usize) -> Bytes {
64 yielding(|| self.guard.random_bytes(len).into()).await
65 }
66
67 pub async fn hash_password(&self, password: Bytes, salt: Bytes) -> VeilidAPIResult<String> {
68 let cs = self.guard.clone_arc();
69 let salt = salt.to_vec();
70 cpu_yielding(move || cs.hash_password(&password, &salt)).await
71 }
72 pub async fn verify_password(
73 &self,
74 password: Bytes,
75 password_hash: &str,
76 ) -> VeilidAPIResult<bool> {
77 let cs = self.guard.clone_arc();
78 let password_hash = password_hash.to_string();
79 cpu_yielding(move || cs.verify_password(&password, &password_hash)).await
80 }
81 pub async fn derive_shared_secret(
82 &self,
83 password: Bytes,
84 salt: Bytes,
85 ) -> VeilidAPIResult<SharedSecret> {
86 yielding(|| self.guard.derive_shared_secret(&password, &salt)).await
87 }
88 pub async fn random_nonce(&self) -> Nonce {
89 yielding(|| self.guard.random_nonce()).await
90 }
91 pub async fn random_shared_secret(&self) -> SharedSecret {
92 yielding(|| self.guard.random_shared_secret()).await
93 }
94 pub async fn compute_dh(
95 &self,
96 key: &PublicKey,
97 secret: &SecretKey,
98 ) -> VeilidAPIResult<SharedSecret> {
99 let cs = self.guard.clone_arc();
100 let key = key.clone();
101 let secret = secret.clone();
102 cpu_yielding(move || cs.compute_dh(&key, &secret)).await
103 }
104 pub async fn generate_shared_secret(
105 &self,
106 key: &PublicKey,
107 secret: &SecretKey,
108 domain: Bytes,
109 ) -> VeilidAPIResult<SharedSecret> {
110 let dh = self.compute_dh(key, secret).await?;
111 let data = [
112 dh.ref_value().bytes().as_ref(),
113 domain.as_ref(),
114 VEILID_DOMAIN_API,
115 ]
116 .concat()
117 .into();
118 let hash = self.generate_hash(data).await;
119 Ok(SharedSecret::new(
120 hash.kind(),
121 BareSharedSecret::new(&hash.into_value()),
122 ))
123 }
124
125 pub async fn generate_keypair(&self) -> KeyPair {
126 yielding(|| self.guard.generate_keypair()).await
127 }
128
129 pub async fn generate_hash(&self, data: Bytes) -> HashDigest {
130 yielding(|| self.guard.generate_hash(&data)).await
131 }
132
133 pub async fn generate_hash_reader(
134 &self,
135 reader: &mut dyn std::io::Read,
136 ) -> VeilidAPIResult<PublicKey> {
137 yielding(|| self.guard.generate_hash_reader(reader)).await
138 }
139
140 #[must_use]
142 pub fn shared_secret_length(&self) -> usize {
143 self.guard.shared_secret_length()
144 }
145 #[must_use]
146 pub fn nonce_length(&self) -> usize {
147 self.guard.nonce_length()
148 }
149 #[must_use]
150 pub fn hash_digest_length(&self) -> usize {
151 self.guard.hash_digest_length()
152 }
153 #[must_use]
154 pub fn public_key_length(&self) -> usize {
155 self.guard.public_key_length()
156 }
157 #[must_use]
158 pub fn secret_key_length(&self) -> usize {
159 self.guard.secret_key_length()
160 }
161 #[must_use]
162 pub fn signature_length(&self) -> usize {
163 self.guard.signature_length()
164 }
165 #[must_use]
166 pub fn aead_overhead(&self) -> usize {
167 self.guard.aead_overhead()
168 }
169 #[must_use]
170 pub fn default_salt_length(&self) -> usize {
171 self.guard.default_salt_length()
172 }
173 pub fn check_shared_secret(&self, secret: &SharedSecret) -> VeilidAPIResult<()> {
174 self.guard.check_shared_secret(secret)
175 }
176 pub fn check_nonce(&self, nonce: &Nonce) -> VeilidAPIResult<()> {
177 self.guard.check_nonce(nonce)
178 }
179 pub fn check_hash_digest(&self, hash: &HashDigest) -> VeilidAPIResult<()> {
180 self.guard.check_hash_digest(hash)
181 }
182 pub fn check_public_key(&self, key: &PublicKey) -> VeilidAPIResult<()> {
183 self.guard.check_public_key(key)
184 }
185 pub fn check_secret_key(&self, key: &SecretKey) -> VeilidAPIResult<()> {
186 self.guard.check_secret_key(key)
187 }
188 pub fn check_signature(&self, signature: &Signature) -> VeilidAPIResult<()> {
189 self.guard.check_signature(signature)
190 }
191 pub async fn validate_keypair(
192 &self,
193 key: &PublicKey,
194 secret: &SecretKey,
195 ) -> VeilidAPIResult<bool> {
196 yielding(|| self.guard.validate_keypair(key, secret)).await
197 }
198
199 pub async fn validate_hash(&self, data: Bytes, hash: &HashDigest) -> VeilidAPIResult<bool> {
200 yielding(|| self.guard.validate_hash(&data, hash)).await
201 }
202
203 pub async fn validate_hash_reader(
204 &self,
205 reader: &mut dyn std::io::Read,
206 hash: &HashDigest,
207 ) -> VeilidAPIResult<bool> {
208 yielding(|| self.guard.validate_hash_reader(reader, hash)).await
209 }
210
211 pub async fn sign(
213 &self,
214 public_key: &PublicKey,
215 secret: &SecretKey,
216 data: Bytes,
217 ) -> VeilidAPIResult<Signature> {
218 let cs = self.guard.clone_arc();
219 let public_key = public_key.clone();
220 let secret = secret.clone();
221 cpu_yielding(move || cs.sign(&public_key, &secret, &data)).await
222 }
223
224 pub async fn sign_in_place(
225 &self,
226 public_key: &PublicKey,
227 secret: &SecretKey,
228 mut data: BytesMut,
229 range: Range<usize>,
230 sig_idx: usize,
231 ) -> VeilidAPIResult<BytesMut> {
232 let cs = self.guard.clone_arc();
233 let public_key = public_key.clone();
234 let secret = secret.clone();
235 cpu_yielding(move || {
236 cs.sign_in_place(&public_key, &secret, &mut data, range, sig_idx)?;
237 Ok(data)
238 })
239 .await
240 }
241
242 pub async fn verify(
243 &self,
244 public_key: &PublicKey,
245 data: Bytes,
246 signature: &Signature,
247 ) -> VeilidAPIResult<bool> {
248 let cs = self.guard.clone_arc();
249 let public_key = public_key.clone();
250 let signature = signature.clone();
251 cpu_yielding(move || cs.verify(&public_key, &data, &signature)).await
252 }
253
254 pub async fn verify_in_place(
255 &self,
256 public_key: &PublicKey,
257 data: Bytes,
258 range: Range<usize>,
259 sig_idx: usize,
260 ) -> VeilidAPIResult<bool> {
261 let cs = self.guard.clone_arc();
262 let public_key = public_key.clone();
263 cpu_yielding(move || cs.verify_in_place(&public_key, &data, range, sig_idx)).await
264 }
265
266 pub async fn decrypt_aead(
268 &self,
269 body: Bytes,
270 nonce: &Nonce,
271 shared_secret: &SharedSecret,
272 associated_data: Option<Bytes>,
273 ) -> VeilidAPIResult<Bytes> {
274 let cs = self.guard.clone_arc();
275 let nonce = nonce.clone();
276 let shared_secret = shared_secret.clone();
277 scaled_yielding(body.len(), 1024, 8192, move || {
278 Ok(cs
279 .decrypt_aead(&body, &nonce, &shared_secret, associated_data.as_deref())?
280 .into())
281 })
282 .await
283 }
284 pub async fn decrypt_in_place_aead(
285 &self,
286 mut body: BytesMut,
287 nonce: &Nonce,
288 shared_secret: &SharedSecret,
289 associated_data: Option<Bytes>,
290 ) -> VeilidAPIResult<BytesMut> {
291 let cs = self.guard.clone_arc();
292 let nonce = nonce.clone();
293 let shared_secret = shared_secret.clone();
294 scaled_yielding(body.len(), 1024, 8192, move || {
295 cs.decrypt_in_place_aead(
296 &mut body,
297 &nonce,
298 &shared_secret,
299 associated_data.as_deref(),
300 )?;
301
302 Ok(body)
303 })
304 .await
305 }
306
307 pub async fn encrypt_aead(
308 &self,
309 body: Bytes,
310 nonce: &Nonce,
311 shared_secret: &SharedSecret,
312 associated_data: Option<Bytes>,
313 ) -> VeilidAPIResult<Bytes> {
314 let cs = self.guard.clone_arc();
315 let nonce = nonce.clone();
316 let shared_secret = shared_secret.clone();
317 scaled_yielding(body.len(), 1024, 8192, move || {
318 Ok(cs
319 .encrypt_aead(&body, &nonce, &shared_secret, associated_data.as_deref())?
320 .into())
321 })
322 .await
323 }
324
325 pub async fn encrypt_in_place_aead(
326 &self,
327 mut body: BytesMut,
328 nonce: &Nonce,
329 shared_secret: &SharedSecret,
330 associated_data: Option<Bytes>,
331 ) -> VeilidAPIResult<BytesMut> {
332 let cs = self.guard.clone_arc();
333 let nonce = nonce.clone();
334 let shared_secret = shared_secret.clone();
335 scaled_yielding(body.len(), 1024, 8192, move || {
336 cs.encrypt_in_place_aead(
337 &mut body,
338 &nonce,
339 &shared_secret,
340 associated_data.as_deref(),
341 )?;
342
343 Ok(body)
344 })
345 .await
346 }
347
348 pub async fn crypt_b2b_no_auth(
350 &self,
351 in_buf: Bytes,
352 mut out_buf: BytesMut,
353 out_idx: usize,
354 nonce: &Nonce,
355 shared_secret: &SharedSecret,
356 ) -> VeilidAPIResult<BytesMut> {
357 let cs = self.guard.clone_arc();
358 let nonce = nonce.clone();
359 let shared_secret = shared_secret.clone();
360 scaled_yielding(in_buf.len(), 1024, 8192, move || {
361 cs.crypt_b2b_no_auth(
362 &in_buf,
363 &mut out_buf[out_idx..out_idx + in_buf.len()],
364 &nonce,
365 &shared_secret,
366 )?;
367 Ok(out_buf)
368 })
369 .await
370 }
371
372 pub async fn crypt_in_place_no_auth(
373 &self,
374 mut body: BytesMut,
375 range: Range<usize>,
376 nonce: &Nonce,
377 shared_secret: &SharedSecret,
378 ) -> VeilidAPIResult<BytesMut> {
379 let cs = self.guard.clone_arc();
380 let nonce = nonce.clone();
381 let shared_secret = shared_secret.clone();
382 scaled_yielding(body.len(), 1024, 8192, move || {
383 cs.crypt_in_place_no_auth(
384 body.as_mut()
385 .get_mut(range)
386 .ok_or_else(|| VeilidAPIError::internal("range is out of bounds"))?,
387 &nonce,
388 &shared_secret,
389 )?;
390 Ok(body)
391 })
392 .await
393 }
394
395 pub async fn crypt_no_auth_aligned_8(
396 &self,
397 body: Bytes,
398 nonce: &Nonce,
399 shared_secret: &SharedSecret,
400 ) -> VeilidAPIResult<Vec<u8>> {
401 let cs = self.guard.clone_arc();
402 let nonce = nonce.clone();
403 let shared_secret = shared_secret.clone();
404 scaled_yielding(body.len(), 1024, 8192, move || {
405 cs.crypt_no_auth_aligned_8(&body, &nonce, &shared_secret)
406 })
407 .await
408 }
409
410 pub async fn crypt_no_auth_unaligned(
411 &self,
412 body: Bytes,
413 nonce: &Nonce,
414 shared_secret: &SharedSecret,
415 ) -> VeilidAPIResult<Vec<u8>> {
416 let cs = self.guard.clone_arc();
417 let nonce = nonce.clone();
418 let shared_secret = shared_secret.clone();
419 scaled_yielding(body.len(), 1024, 8192, move || {
420 cs.crypt_no_auth_unaligned(&body, &nonce, &shared_secret)
421 })
422 .await
423 }
424}