-
Notifications
You must be signed in to change notification settings - Fork 63
Expand file tree
/
Copy pathaes.rs
More file actions
120 lines (105 loc) · 3.35 KB
/
Copy pathaes.rs
File metadata and controls
120 lines (105 loc) · 3.35 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! AES block cipher.
use super::sealed::BlockCipher;
use crate::Cipher;
use ::aes::{Aes128, Aes192, Aes256, Block};
use ::cipher::{
BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncClosure, BlockCipherEncrypt,
BlockSizeUser, InvalidLength, KeyInit, array::sizes::U16,
};
use core::fmt;
use core::fmt::Debug;
/// Advanced Encryption Standard (AES) low-level block cipher.
///
/// Supports 128-bit, 192-bit, and 256-bit keys.
pub struct Aes {
inner: Inner,
}
/// Inner enum over supported key sizes.
enum Inner {
Aes128(Aes128),
Aes192(Aes192),
Aes256(Aes256),
}
impl Aes {
/// Create a new AES block cipher instance.
///
/// Supports `key` whose length is 16-bytes (128-bit), 24-bytes (192-bits), or 32-bytes
/// (256-bits).
///
/// # Errors
/// Returns [`InvalidLength`] if the length of `key` is not any of the above.
pub fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
if let Ok(cipher) = Aes128::new_from_slice(key) {
return Ok(Self {
inner: Inner::Aes128(cipher),
});
}
if let Ok(cipher) = Aes192::new_from_slice(key) {
return Ok(Self {
inner: Inner::Aes192(cipher),
});
}
if let Ok(cipher) = Aes256::new_from_slice(key) {
return Ok(Self {
inner: Inner::Aes256(cipher),
});
}
Err(InvalidLength)
}
}
impl BlockCipher for Aes {
fn new_from_slice(slice: &[u8]) -> Result<Self, InvalidLength> {
Aes::new_from_slice(slice)
}
fn is_supported(cipher: Cipher) -> bool {
matches!(
cipher,
Cipher::Aes128Cbc
| Cipher::Aes192Cbc
| Cipher::Aes256Cbc
| Cipher::Aes128Ctr
| Cipher::Aes192Ctr
| Cipher::Aes256Ctr
)
}
}
impl BlockCipherDecrypt for Aes {
fn decrypt_blocks(&self, blocks: &mut [Block]) {
match &self.inner {
Inner::Aes128(aes) => aes.decrypt_blocks(blocks),
Inner::Aes192(aes) => aes.decrypt_blocks(blocks),
Inner::Aes256(aes) => aes.decrypt_blocks(blocks),
}
}
fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure<BlockSize = Self::BlockSize>) {
match &self.inner {
Inner::Aes128(aes) => aes.decrypt_with_backend(f),
Inner::Aes192(aes) => aes.decrypt_with_backend(f),
Inner::Aes256(aes) => aes.decrypt_with_backend(f),
}
}
}
impl BlockCipherEncrypt for Aes {
fn encrypt_blocks(&self, blocks: &mut [Block]) {
match &self.inner {
Inner::Aes128(aes) => aes.encrypt_blocks(blocks),
Inner::Aes192(aes) => aes.encrypt_blocks(blocks),
Inner::Aes256(aes) => aes.encrypt_blocks(blocks),
}
}
fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure<BlockSize = Self::BlockSize>) {
match &self.inner {
Inner::Aes128(aes) => aes.encrypt_with_backend(f),
Inner::Aes192(aes) => aes.encrypt_with_backend(f),
Inner::Aes256(aes) => aes.encrypt_with_backend(f),
}
}
}
impl BlockSizeUser for Aes {
type BlockSize = U16;
}
impl Debug for Aes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Aes").finish_non_exhaustive()
}
}