veilid_core/crypto/crypto_system/
mod.rs1use 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;
10pub(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::*;
23pub use blake3digest512::*;
27
28pub trait CryptoSystemBuffer: AsRef<[u8]> + AsMut<[u8]> {
29 fn len(&self) -> usize;
31
32 fn is_empty(&self) -> bool;
34
35 fn extend_from_slice(&mut self, other: &[u8]);
37
38 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 fn kind(&self) -> CryptoKind;
81 fn crypto(&self) -> VeilidComponentGuard<'_, Crypto>;
82
83 fn cached_dh(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<SharedSecret>;
85
86 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 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 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 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 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}