1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! Initialization-vector parameter abstraction.
/// Parameters that provide an initialization vector.
///
/// Implementations only expose the caller's value. The consuming mode
/// defines and validates the supported IV lengths: CBC takes exactly one
/// block, CFB and OFB take up to one block and right-align a shorter one over
/// zeros, and CTR fills the leading bytes of its counter block. Implement this
/// trait, alongside the engine's parameter trait, to pass your own parameter
/// type to a mode, or use [`KeyWithIvRef`](crate::KeyWithIvRef),
/// [`KeyWithIvFixed`](crate::KeyWithIvFixed) or `KeyWithIvOwned`.
///
/// # Example
///
/// A custom parameter type; for CFB, its empty IV acts as an all-zero IV:
///
/// ```
/// use tc_aes::AesEngine;
/// use tc_block_cipher::{BlockCipher, BlockCipherInit, CipherDirection, KeyParams};
/// use tc_block_modes::{FixedCfbBlockCipher, IvParams, KeyWithIvRef};
///
/// struct Session {
/// key: [u8; 16],
/// iv: Vec<u8>,
/// }
///
/// impl KeyParams for Session {
/// fn key(&self) -> &[u8] {
/// &self.key
/// }
/// }
///
/// impl IvParams for Session {
/// fn iv(&self) -> &[u8] {
/// &self.iv
/// }
/// }
///
/// let session = Session { key: [0x42; 16], iv: Vec::new() };
/// let mut mode = FixedCfbBlockCipher::<_, 16, 16>::new(AesEngine::new());
/// let mut empty = [0; 16];
/// mode.init(CipherDirection::Encrypt, &session)?;
/// mode.process_block(&[0; 16], &mut empty)?;
///
/// let mut zero = [0; 16];
/// mode.init(CipherDirection::Encrypt, &KeyWithIvRef::new(&session.key, &[0; 16]))?;
/// mode.process_block(&[0; 16], &mut zero)?;
/// assert_eq!(empty, zero);
/// # Ok::<(), Box<dyn core::error::Error>>(())
/// ```