1
1
//! Streaming AEAD support.
2
2
//!
3
- //! Implementation of the STREAM online authenticated encryption construction
4
- //! as described in the paper
5
- //! [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1].
3
+ //! See the [`aead-stream`] crate for a generic implementation of the STREAM construction.
6
4
//!
7
- //! ## About
8
- //!
9
- //! The STREAM construction supports encrypting/decrypting sequences of AEAD
10
- //! message segments, which is useful in cases where the overall message is too
11
- //! large to fit in a single buffer and needs to be processed incrementally.
12
- //!
13
- //! STREAM defends against reordering and truncation attacks which are common
14
- //! in naive schemes which attempt to provide these properties, and is proven
15
- //! to meet the security definition of "nonce-based online authenticated
16
- //! encryption" (nOAE) as given in the aforementioned paper.
17
- //!
18
- //! ## Diagram
19
- //!
20
- //! 
21
- //!
22
- //! Legend:
23
- //!
24
- //! - 𝐄k: AEAD encryption under key `k`
25
- //! - 𝐌: message
26
- //! - 𝐍: nonce
27
- //! - 𝐀: additional associated data
28
- //! - 𝐂: ciphertext
29
- //! - 𝜏: MAC tag
30
- //!
31
- //! [1]: https://eprint.iacr.org/2015/189.pdf
5
+ //! [`aead-stream`]: https://docs.rs/aead-stream
32
6
33
7
#![ allow( clippy:: upper_case_acronyms) ]
34
8
35
9
use crate :: { AeadCore , AeadInPlace , Buffer , Error , Key , KeyInit , Result } ;
36
10
use core:: ops:: { AddAssign , Sub } ;
37
- use crypto_common:: array:: {
38
- typenum:: { Unsigned , U4 , U5 } ,
39
- Array , ArraySize ,
40
- } ;
11
+ use crypto_common:: array:: { Array , ArraySize } ;
41
12
42
13
#[ cfg( feature = "alloc" ) ]
43
- use { crate :: Payload , alloc:: vec:: Vec } ;
14
+ use { crate :: Payload , alloc:: vec:: Vec , crypto_common :: array :: typenum :: Unsigned } ;
44
15
45
16
/// Nonce as used by a given AEAD construction and STREAM primitive.
46
17
pub type Nonce < A , S > = Array < u8 , NonceSize < A , S > > ;
@@ -50,22 +21,6 @@ pub type Nonce<A, S> = Array<u8, NonceSize<A, S>>;
50
21
pub type NonceSize < A , S > =
51
22
<<A as AeadCore >:: NonceSize as Sub < <S as StreamPrimitive < A > >:: NonceOverhead > >:: Output ;
52
23
53
- /// STREAM encryptor instantiated with [`StreamBE32`] as the underlying
54
- /// STREAM primitive.
55
- pub type EncryptorBE32 < A > = Encryptor < A , StreamBE32 < A > > ;
56
-
57
- /// STREAM decryptor instantiated with [`StreamBE32`] as the underlying
58
- /// STREAM primitive.
59
- pub type DecryptorBE32 < A > = Decryptor < A , StreamBE32 < A > > ;
60
-
61
- /// STREAM encryptor instantiated with [`StreamLE31`] as the underlying
62
- /// STREAM primitive.
63
- pub type EncryptorLE31 < A > = Encryptor < A , StreamLE31 < A > > ;
64
-
65
- /// STREAM decryptor instantiated with [`StreamLE31`] as the underlying
66
- /// STREAM primitive.
67
- pub type DecryptorLE31 < A > = Decryptor < A , StreamLE31 < A > > ;
68
-
69
24
/// Create a new STREAM from the provided AEAD.
70
25
pub trait NewStream < A > : StreamPrimitive < A >
71
26
where
@@ -354,188 +309,3 @@ impl_stream_object!(
354
309
"decrypt" ,
355
310
"𝒟 STREAM decryptor"
356
311
) ;
357
-
358
- /// The original "Rogaway-flavored" STREAM as described in the paper
359
- /// [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1].
360
- ///
361
- /// Uses a 32-bit big endian counter and 1-byte "last block" flag stored as
362
- /// the last 5-bytes of the AEAD nonce.
363
- ///
364
- /// [1]: https://eprint.iacr.org/2015/189.pdf
365
- #[ derive( Debug ) ]
366
- pub struct StreamBE32 < A >
367
- where
368
- A : AeadInPlace ,
369
- A :: NonceSize : Sub < U5 > ,
370
- <<A as AeadCore >:: NonceSize as Sub < U5 > >:: Output : ArraySize ,
371
- {
372
- /// Underlying AEAD cipher
373
- aead : A ,
374
-
375
- /// Nonce (sans STREAM overhead)
376
- nonce : Nonce < A , Self > ,
377
- }
378
-
379
- impl < A > NewStream < A > for StreamBE32 < A >
380
- where
381
- A : AeadInPlace ,
382
- A :: NonceSize : Sub < U5 > ,
383
- <<A as AeadCore >:: NonceSize as Sub < U5 > >:: Output : ArraySize ,
384
- {
385
- fn from_aead ( aead : A , nonce : & Nonce < A , Self > ) -> Self {
386
- Self {
387
- aead,
388
- nonce : nonce. clone ( ) ,
389
- }
390
- }
391
- }
392
-
393
- impl < A > StreamPrimitive < A > for StreamBE32 < A >
394
- where
395
- A : AeadInPlace ,
396
- A :: NonceSize : Sub < U5 > ,
397
- <<A as AeadCore >:: NonceSize as Sub < U5 > >:: Output : ArraySize ,
398
- {
399
- type NonceOverhead = U5 ;
400
- type Counter = u32 ;
401
- const COUNTER_INCR : u32 = 1 ;
402
- const COUNTER_MAX : u32 = u32:: MAX ;
403
-
404
- fn encrypt_in_place (
405
- & self ,
406
- position : u32 ,
407
- last_block : bool ,
408
- associated_data : & [ u8 ] ,
409
- buffer : & mut dyn Buffer ,
410
- ) -> Result < ( ) > {
411
- let nonce = self . aead_nonce ( position, last_block) ;
412
- self . aead . encrypt_in_place ( & nonce, associated_data, buffer)
413
- }
414
-
415
- fn decrypt_in_place (
416
- & self ,
417
- position : Self :: Counter ,
418
- last_block : bool ,
419
- associated_data : & [ u8 ] ,
420
- buffer : & mut dyn Buffer ,
421
- ) -> Result < ( ) > {
422
- let nonce = self . aead_nonce ( position, last_block) ;
423
- self . aead . decrypt_in_place ( & nonce, associated_data, buffer)
424
- }
425
- }
426
-
427
- impl < A > StreamBE32 < A >
428
- where
429
- A : AeadInPlace ,
430
- A :: NonceSize : Sub < U5 > ,
431
- <<A as AeadCore >:: NonceSize as Sub < U5 > >:: Output : ArraySize ,
432
- {
433
- /// Compute the full AEAD nonce including the STREAM counter and last
434
- /// block flag.
435
- fn aead_nonce ( & self , position : u32 , last_block : bool ) -> crate :: Nonce < A > {
436
- let mut result = Array :: default ( ) ;
437
-
438
- // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics)
439
- let ( prefix, tail) = result. split_at_mut ( NonceSize :: < A , Self > :: to_usize ( ) ) ;
440
- prefix. copy_from_slice ( & self . nonce ) ;
441
-
442
- let ( counter, flag) = tail. split_at_mut ( 4 ) ;
443
- counter. copy_from_slice ( & position. to_be_bytes ( ) ) ;
444
- flag[ 0 ] = last_block as u8 ;
445
-
446
- result
447
- }
448
- }
449
-
450
- /// STREAM as instantiated with a 31-bit little endian counter and 1-bit
451
- /// "last block" flag stored as the most significant bit of the counter
452
- /// when interpreted as a 32-bit integer.
453
- ///
454
- /// The 31-bit + 1-bit value is stored as the last 4 bytes of the AEAD nonce.
455
- #[ derive( Debug ) ]
456
- pub struct StreamLE31 < A >
457
- where
458
- A : AeadInPlace ,
459
- A :: NonceSize : Sub < U4 > ,
460
- <<A as AeadCore >:: NonceSize as Sub < U4 > >:: Output : ArraySize ,
461
- {
462
- /// Underlying AEAD cipher
463
- aead : A ,
464
-
465
- /// Nonce (sans STREAM overhead)
466
- nonce : Nonce < A , Self > ,
467
- }
468
-
469
- impl < A > NewStream < A > for StreamLE31 < A >
470
- where
471
- A : AeadInPlace ,
472
- A :: NonceSize : Sub < U4 > ,
473
- <<A as AeadCore >:: NonceSize as Sub < U4 > >:: Output : ArraySize ,
474
- {
475
- fn from_aead ( aead : A , nonce : & Nonce < A , Self > ) -> Self {
476
- Self {
477
- aead,
478
- nonce : nonce. clone ( ) ,
479
- }
480
- }
481
- }
482
-
483
- impl < A > StreamPrimitive < A > for StreamLE31 < A >
484
- where
485
- A : AeadInPlace ,
486
- A :: NonceSize : Sub < U4 > ,
487
- <<A as AeadCore >:: NonceSize as Sub < U4 > >:: Output : ArraySize ,
488
- {
489
- type NonceOverhead = U4 ;
490
- type Counter = u32 ;
491
- const COUNTER_INCR : u32 = 1 ;
492
- const COUNTER_MAX : u32 = 0xfff_ffff ;
493
-
494
- fn encrypt_in_place (
495
- & self ,
496
- position : u32 ,
497
- last_block : bool ,
498
- associated_data : & [ u8 ] ,
499
- buffer : & mut dyn Buffer ,
500
- ) -> Result < ( ) > {
501
- let nonce = self . aead_nonce ( position, last_block) ?;
502
- self . aead . encrypt_in_place ( & nonce, associated_data, buffer)
503
- }
504
-
505
- fn decrypt_in_place (
506
- & self ,
507
- position : Self :: Counter ,
508
- last_block : bool ,
509
- associated_data : & [ u8 ] ,
510
- buffer : & mut dyn Buffer ,
511
- ) -> Result < ( ) > {
512
- let nonce = self . aead_nonce ( position, last_block) ?;
513
- self . aead . decrypt_in_place ( & nonce, associated_data, buffer)
514
- }
515
- }
516
-
517
- impl < A > StreamLE31 < A >
518
- where
519
- A : AeadInPlace ,
520
- A :: NonceSize : Sub < U4 > ,
521
- <<A as AeadCore >:: NonceSize as Sub < U4 > >:: Output : ArraySize ,
522
- {
523
- /// Compute the full AEAD nonce including the STREAM counter and last
524
- /// block flag.
525
- fn aead_nonce ( & self , position : u32 , last_block : bool ) -> Result < crate :: Nonce < A > > {
526
- if position > Self :: COUNTER_MAX {
527
- return Err ( Error ) ;
528
- }
529
-
530
- let mut result = Array :: default ( ) ;
531
-
532
- // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics)
533
- let ( prefix, tail) = result. split_at_mut ( NonceSize :: < A , Self > :: to_usize ( ) ) ;
534
- prefix. copy_from_slice ( & self . nonce ) ;
535
-
536
- let position_with_flag = position | ( ( last_block as u32 ) << 31 ) ;
537
- tail. copy_from_slice ( & position_with_flag. to_le_bytes ( ) ) ;
538
-
539
- Ok ( result)
540
- }
541
- }
0 commit comments