1use libcrux_secrets::U8;
6
7use super::slice::KeyGenError;
8
9#[derive(Debug, PartialEq, Eq)]
11pub enum EncryptError {
12 WrongCiphertextLength,
14
15 PlaintextTooLong,
17
18 AadTooLong,
20
21 WrongKey,
23
24 WrongTag,
26
27 WrongNonce,
29
30 Unknown,
32}
33
34#[derive(Debug, PartialEq, Eq)]
36pub enum DecryptError {
37 InvalidTag,
40
41 WrongPlaintextLength,
43
44 PlaintextTooLong,
46
47 AadTooLong,
49
50 WrongKey,
52
53 WrongTag,
55
56 WrongNonce,
58
59 Unknown,
61}
62
63impl From<super::arrayref::EncryptError> for EncryptError {
64 fn from(value: super::arrayref::EncryptError) -> Self {
65 match value {
66 super::arrayref::EncryptError::WrongCiphertextLength => {
67 EncryptError::WrongCiphertextLength
68 }
69 super::arrayref::EncryptError::PlaintextTooLong => EncryptError::PlaintextTooLong,
70 super::arrayref::EncryptError::AadTooLong => EncryptError::AadTooLong,
71 super::arrayref::EncryptError::Unknown => EncryptError::Unknown,
72 }
73 }
74}
75
76impl From<super::arrayref::DecryptError> for DecryptError {
77 fn from(value: super::arrayref::DecryptError) -> Self {
78 match value {
79 super::arrayref::DecryptError::InvalidTag => DecryptError::InvalidTag,
80 super::arrayref::DecryptError::WrongPlaintextLength => {
81 DecryptError::WrongPlaintextLength
82 }
83 super::arrayref::DecryptError::PlaintextTooLong => DecryptError::PlaintextTooLong,
84 super::arrayref::DecryptError::AadTooLong => DecryptError::AadTooLong,
85 super::arrayref::DecryptError::Unknown => DecryptError::Unknown,
86 }
87 }
88}
89
90impl core::fmt::Display for EncryptError {
91 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
92 let text = match self {
93 EncryptError::WrongCiphertextLength => "ciphertext buffer has wrong length",
94 EncryptError::PlaintextTooLong => {
95 "plaintext is too long for algorithm or implementation"
96 }
97 EncryptError::AadTooLong => "aad is too long for algorithm or implementation",
98 EncryptError::Unknown => "an unknown error occurred",
99 EncryptError::WrongKey => "key is for wrong algorithm",
100 EncryptError::WrongTag => "tag is for wrong algorithm",
101 EncryptError::WrongNonce => "nonce is for wrong algorithm",
102 };
103
104 f.write_str(text)
105 }
106}
107
108impl core::fmt::Display for DecryptError {
109 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110 let text = match self {
111 DecryptError::InvalidTag => "invalid authentication tag",
112 DecryptError::WrongPlaintextLength => "plaintext buffer has wrong length",
113 DecryptError::PlaintextTooLong => {
114 "plaintext is too long for algorithm or implementation"
115 }
116 DecryptError::AadTooLong => "aad is too long for algorithm or implementation",
117 DecryptError::Unknown => "an unknown error occurred",
118 DecryptError::WrongKey => "key is for wrong algorithm",
119 DecryptError::WrongTag => "tag is for wrong algorithm",
120 DecryptError::WrongNonce => "nonce is for wrong algorithm",
121 };
122
123 f.write_str(text)
124 }
125}
126
127#[derive(Clone, Copy)]
137pub struct KeyRef<'a, Algo> {
138 algorithm: Algo,
139 key: &'a [U8],
140}
141
142pub struct KeyMut<'a, Algo> {
145 algorithm: Algo,
146 key: &'a mut [U8],
147}
148
149#[derive(Clone, Copy)]
152pub struct TagRef<'a, Algo> {
153 algorithm: Algo,
154 tag: &'a [U8],
155}
156
157pub struct TagMut<'a, Algo> {
160 algorithm: Algo,
161 tag: &'a mut [U8],
162}
163
164#[derive(Clone, Copy)]
167pub struct NonceRef<'a, Algo> {
168 algorithm: Algo,
169 nonce: &'a [U8],
170}
171
172impl<'a, Algo: Aead + core::fmt::Debug> core::fmt::Debug for KeyRef<'a, Algo> {
173 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
174 f.debug_tuple("Key")
175 .field(&self.algorithm)
176 .field(&"***")
177 .finish()
178 }
179}
180
181pub trait Aead: Copy + PartialEq {
188 fn key_len(&self) -> usize;
190 fn tag_len(&self) -> usize;
192 fn nonce_len(&self) -> usize;
194
195 fn keygen<'a>(&self, key: KeyMut<'a, Self>, rand: &[U8]) -> Result<(), KeyGenError>;
197
198 fn encrypt<'a>(
201 &self,
202 ciphertext: &mut [u8],
203 tag: TagMut<'a, Self>,
204 key: KeyRef<'a, Self>,
205 nonce: NonceRef<'a, Self>,
206 aad: &[u8],
207 plaintext: &[U8],
208 ) -> Result<(), EncryptError>;
209
210 fn decrypt<'a>(
213 &self,
214 plaintext: &mut [U8],
215 key: KeyRef<'a, Self>,
216 nonce: NonceRef<'a, Self>,
217 aad: &[u8],
218 ciphertext: &[u8],
219 tag: TagRef<'a, Self>,
220 ) -> Result<(), DecryptError>;
221
222 fn new_key<'a>(self, key: &'a [U8]) -> Result<KeyRef<'a, Self>, WrongLengthError> {
224 KeyRef::new_for_algo(self, key)
225 }
226 fn new_key_mut<'a>(self, key: &'a mut [U8]) -> Result<KeyMut<'a, Self>, WrongLengthError> {
228 KeyMut::new_for_algo(self, key)
229 }
230 fn new_tag<'a>(self, tag: &'a [U8]) -> Result<TagRef<'a, Self>, WrongLengthError> {
232 TagRef::new_for_algo(self, tag)
233 }
234 fn new_tag_mut<'a>(self, tag_mut: &'a mut [U8]) -> Result<TagMut<'a, Self>, WrongLengthError> {
236 TagMut::new_for_algo(self, tag_mut)
237 }
238 fn new_nonce<'a>(self, nonce: &'a [U8]) -> Result<NonceRef<'a, Self>, WrongLengthError> {
240 NonceRef::new_for_algo(self, nonce)
241 }
242}
243
244impl<
245 const KEY_LEN: usize,
246 const TAG_LEN: usize,
247 const NONCE_LEN: usize,
248 Algo: super::typed_owned::Aead<
249 Key = [U8; KEY_LEN],
250 Tag = [U8; TAG_LEN],
251 Nonce = [U8; NONCE_LEN],
252 Rand = [U8; KEY_LEN],
253 > + Copy
254 + PartialEq,
255 > Aead for Algo
256{
257 fn key_len(&self) -> usize {
258 KEY_LEN
259 }
260
261 fn tag_len(&self) -> usize {
262 TAG_LEN
263 }
264
265 fn nonce_len(&self) -> usize {
266 NONCE_LEN
267 }
268
269 fn keygen<'a>(&self, key: KeyMut<'a, Self>, rand: &[U8]) -> Result<(), KeyGenError> {
270 if rand.len() < KEY_LEN {
271 return Err(KeyGenError::InsufficientRandomness);
272 }
273
274 key.key.copy_from_slice(rand);
275
276 Ok(())
277 }
278
279 fn encrypt<'a>(
280 &self,
281 ciphertext: &mut [u8],
282 mut tag: TagMut<'a, Self>,
283 key: KeyRef<'a, Self>,
284 nonce: NonceRef<'a, Self>,
285 aad: &[u8],
286 plaintext: &[U8],
287 ) -> Result<(), EncryptError> {
288 if key.algo() != self {
289 return Err(EncryptError::WrongKey);
290 }
291 if tag.algo() != self {
292 return Err(EncryptError::WrongTag);
293 }
294 if nonce.algo() != self {
295 return Err(EncryptError::WrongNonce);
296 }
297
298 let key: &[U8; KEY_LEN] = key.as_ref().try_into().map_err(|_| EncryptError::Unknown)?;
300
301 let tag_raw: &mut [U8; TAG_LEN] =
302 tag.as_mut().try_into().map_err(|_| EncryptError::Unknown)?;
303
304 let nonce: &[U8; NONCE_LEN] = nonce
305 .as_ref()
306 .try_into()
307 .map_err(|_| EncryptError::Unknown)?;
308
309 <Self as super::typed_owned::Aead>::encrypt(
310 ciphertext,
311 tag_raw.into(),
312 key.into(),
313 nonce.into(),
314 aad,
315 plaintext,
316 )
317 .map_err(EncryptError::from)
318 }
319
320 fn decrypt<'a>(
321 &self,
322 plaintext: &mut [U8],
323 key: KeyRef<'a, Self>,
324 nonce: NonceRef<'a, Self>,
325 aad: &[u8],
326 ciphertext: &[u8],
327 tag: TagRef<'a, Self>,
328 ) -> Result<(), DecryptError> {
329 if key.algo() != self {
330 return Err(DecryptError::WrongKey);
331 }
332 if tag.algo() != self {
333 return Err(DecryptError::WrongTag);
334 }
335 if nonce.algo() != self {
336 return Err(DecryptError::WrongNonce);
337 }
338
339 let key: &[U8; KEY_LEN] = key.as_ref().try_into().map_err(|_| DecryptError::Unknown)?;
341
342 let tag: &[U8; TAG_LEN] = tag.as_ref().try_into().map_err(|_| DecryptError::Unknown)?;
343
344 let nonce: &[U8; NONCE_LEN] = nonce
345 .as_ref()
346 .try_into()
347 .map_err(|_| DecryptError::Unknown)?;
348
349 <Self as super::typed_owned::Aead>::decrypt(
350 plaintext,
351 key.into(),
352 nonce.into(),
353 aad,
354 ciphertext,
355 tag.into(),
356 )
357 .map_err(DecryptError::from)
358 }
359}
360
361#[derive(Debug, Clone, Copy)]
362pub struct WrongLengthError;
363
364impl<'a, Algo: Aead> KeyRef<'a, Algo> {
365 pub fn new_for_algo(algo: Algo, key: &'a [U8]) -> Result<Self, WrongLengthError> {
367 (key.len() == algo.key_len())
368 .then_some(KeyRef {
369 algorithm: algo,
370 key,
371 })
372 .ok_or(WrongLengthError)
373 }
374
375 pub fn encrypt(
378 &self,
379 ciphertext: &mut [u8],
380 tag: TagMut<'a, Algo>,
381 nonce: NonceRef<'a, Algo>,
382 aad: &[u8],
383 plaintext: &[U8],
384 ) -> Result<(), EncryptError> {
385 self.algorithm
386 .encrypt(ciphertext, tag, *self, nonce, aad, plaintext)
387 }
388
389 pub fn decrypt(
392 &self,
393 plaintext: &mut [U8],
394 nonce: NonceRef<'a, Algo>,
395 aad: &[u8],
396 ciphertext: &[u8],
397 tag: TagRef<'a, Algo>,
398 ) -> Result<(), DecryptError> {
399 self.algorithm
400 .decrypt(plaintext, *self, nonce, aad, ciphertext, tag)
401 }
402}
403
404impl<'a, Algo: Aead> AsRef<[U8]> for KeyRef<'a, Algo> {
405 fn as_ref(&self) -> &[U8] {
406 self.key
407 }
408}
409
410impl<'a, Algo: Aead> AsMut<[U8]> for KeyMut<'a, Algo> {
411 fn as_mut(&mut self) -> &mut [U8] {
412 self.key
413 }
414}
415
416impl<'a, Algo> KeyRef<'a, Algo> {
417 pub fn algo(&self) -> &Algo {
419 &self.algorithm
420 }
421}
422
423impl<'a, Algo: Aead> KeyMut<'a, Algo> {
424 pub fn new_for_algo(algo: Algo, key: &'a mut [U8]) -> Result<Self, WrongLengthError> {
426 (key.len() == algo.key_len())
427 .then_some(KeyMut {
428 algorithm: algo,
429 key,
430 })
431 .ok_or(WrongLengthError)
432 }
433}
434
435impl<'a, Algo> KeyMut<'a, Algo> {
436 pub fn algo(&self) -> &Algo {
438 &self.algorithm
439 }
440}
441
442impl<'a, Algo: Aead> TagRef<'a, Algo> {
443 pub fn new_for_algo(algo: Algo, tag: &'a [U8]) -> Result<Self, WrongLengthError> {
445 (tag.len() == algo.tag_len())
446 .then_some(TagRef {
447 algorithm: algo,
448 tag,
449 })
450 .ok_or(WrongLengthError)
451 }
452}
453
454impl<'a, Algo: Aead> AsRef<[U8]> for TagRef<'a, Algo> {
455 fn as_ref(&self) -> &[U8] {
456 self.tag
457 }
458}
459
460impl<'a, Algo> TagRef<'a, Algo> {
461 pub fn algo(&self) -> &Algo {
463 &self.algorithm
464 }
465}
466
467impl<'a, Algo: Aead> TagMut<'a, Algo> {
468 pub fn new_for_algo(algo: Algo, tag: &'a mut [U8]) -> Result<Self, WrongLengthError> {
470 (tag.len() == algo.tag_len())
471 .then_some(TagMut {
472 algorithm: algo,
473 tag,
474 })
475 .ok_or(WrongLengthError)
476 }
477}
478
479impl<'a, Algo: Aead> From<TagMut<'a, Algo>> for TagRef<'a, Algo> {
480 fn from(tag: TagMut<'a, Algo>) -> Self {
481 TagRef {
482 algorithm: tag.algorithm,
483 tag: tag.tag,
484 }
485 }
486}
487
488impl<'a, Algo> TagMut<'a, Algo> {
489 pub fn algo(&self) -> &Algo {
491 &self.algorithm
492 }
493}
494
495impl<'a, Algo: Aead> NonceRef<'a, Algo> {
496 pub fn new_for_algo(algo: Algo, nonce: &'a [U8]) -> Result<Self, WrongLengthError> {
498 (nonce.len() == algo.nonce_len())
499 .then_some(NonceRef {
500 algorithm: algo,
501 nonce,
502 })
503 .ok_or(WrongLengthError)
504 }
505}
506
507impl<'a, Algo> NonceRef<'a, Algo> {
508 pub fn algo(&self) -> &Algo {
510 &self.algorithm
511 }
512}
513
514impl<'a, Algo: Aead> AsRef<[U8]> for NonceRef<'a, Algo> {
515 fn as_ref(&self) -> &[U8] {
516 self.nonce
517 }
518}
519
520impl<'a, Algo: Aead> AsMut<[U8]> for TagMut<'a, Algo> {
521 fn as_mut(&mut self) -> &mut [U8] {
522 self.tag
523 }
524}
525
526pub trait Multiplexes<Algo>: Aead + Sized {
530 fn mux_algo(&self) -> Option<Algo>;
532
533 fn wrap_algo(algo: Algo) -> Self;
535
536 fn mux_key<'a>(key: KeyRef<'a, Self>) -> Option<KeyRef<'a, Algo>> {
538 let KeyRef { algorithm, key } = key;
539 algorithm
540 .mux_algo()
541 .map(|algorithm| KeyRef { algorithm, key })
542 }
543
544 fn wrap_key<'a>(k: KeyRef<'a, Algo>) -> KeyRef<'a, Self> {
546 KeyRef {
547 algorithm: Self::wrap_algo(k.algorithm),
548 key: k.key,
549 }
550 }
551
552 fn mux_key_mut<'a>(key: KeyMut<'a, Self>) -> Option<KeyMut<'a, Algo>> {
554 let KeyMut { algorithm, key } = key;
555 algorithm
556 .mux_algo()
557 .map(|algorithm| KeyMut { algorithm, key })
558 }
559
560 fn wrap_key_mut<'a>(k: KeyMut<'a, Algo>) -> KeyMut<'a, Self> {
562 KeyMut {
563 algorithm: Self::wrap_algo(k.algorithm),
564 key: k.key,
565 }
566 }
567
568 fn mux_tag<'a>(tag: TagRef<'a, Self>) -> Option<TagRef<'a, Algo>> {
570 let TagRef { algorithm, tag } = tag;
571 algorithm
572 .mux_algo()
573 .map(|algorithm| TagRef { algorithm, tag })
574 }
575
576 fn wrap_tag<'a>(tag: TagRef<'a, Algo>) -> TagRef<'a, Self> {
578 TagRef {
579 algorithm: Self::wrap_algo(tag.algorithm),
580 tag: tag.tag,
581 }
582 }
583
584 fn mux_tag_mut<'a>(tag: TagMut<'a, Self>) -> Option<TagMut<'a, Algo>> {
586 let TagMut { algorithm, tag } = tag;
587 algorithm
588 .mux_algo()
589 .map(|algorithm| TagMut { algorithm, tag })
590 }
591
592 fn wrap_tag_mut<'a>(tag: TagMut<'a, Algo>) -> TagMut<'a, Self> {
594 TagMut {
595 algorithm: Self::wrap_algo(tag.algorithm),
596 tag: tag.tag,
597 }
598 }
599
600 fn mux_nonce<'a>(nonce: NonceRef<'a, Self>) -> Option<NonceRef<'a, Algo>> {
602 let NonceRef { algorithm, nonce } = nonce;
603 algorithm
604 .mux_algo()
605 .map(|algorithm| NonceRef { algorithm, nonce })
606 }
607
608 fn wrap_nonce<'a>(nonce: NonceRef<'a, Algo>) -> NonceRef<'a, Self> {
610 NonceRef {
611 algorithm: Self::wrap_algo(nonce.algorithm),
612 nonce: nonce.nonce,
613 }
614 }
615}