ssh_cipher/block_cipher/
aes.rs1use super::sealed::BlockCipher;
4use crate::Cipher;
5use ::aes::{Aes128, Aes192, Aes256, Block};
6use ::cipher::{
7 BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncClosure, BlockCipherEncrypt,
8 BlockSizeUser, InvalidLength, KeyInit, array::sizes::U16,
9};
10use core::fmt;
11use core::fmt::Debug;
12
13pub struct Aes {
17 inner: Inner,
18}
19
20enum Inner {
22 Aes128(Aes128),
23 Aes192(Aes192),
24 Aes256(Aes256),
25}
26
27impl Aes {
28 pub fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
36 if let Ok(cipher) = Aes128::new_from_slice(key) {
37 return Ok(Self {
38 inner: Inner::Aes128(cipher),
39 });
40 }
41
42 if let Ok(cipher) = Aes192::new_from_slice(key) {
43 return Ok(Self {
44 inner: Inner::Aes192(cipher),
45 });
46 }
47
48 if let Ok(cipher) = Aes256::new_from_slice(key) {
49 return Ok(Self {
50 inner: Inner::Aes256(cipher),
51 });
52 }
53
54 Err(InvalidLength)
55 }
56}
57
58impl BlockCipher for Aes {
59 fn new_from_slice(slice: &[u8]) -> Result<Self, InvalidLength> {
60 Aes::new_from_slice(slice)
61 }
62
63 fn is_supported(cipher: Cipher) -> bool {
64 matches!(
65 cipher,
66 Cipher::Aes128Cbc
67 | Cipher::Aes192Cbc
68 | Cipher::Aes256Cbc
69 | Cipher::Aes128Ctr
70 | Cipher::Aes192Ctr
71 | Cipher::Aes256Ctr
72 )
73 }
74}
75
76impl BlockCipherDecrypt for Aes {
77 fn decrypt_blocks(&self, blocks: &mut [Block]) {
78 match &self.inner {
79 Inner::Aes128(aes) => aes.decrypt_blocks(blocks),
80 Inner::Aes192(aes) => aes.decrypt_blocks(blocks),
81 Inner::Aes256(aes) => aes.decrypt_blocks(blocks),
82 }
83 }
84
85 fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure<BlockSize = Self::BlockSize>) {
86 match &self.inner {
87 Inner::Aes128(aes) => aes.decrypt_with_backend(f),
88 Inner::Aes192(aes) => aes.decrypt_with_backend(f),
89 Inner::Aes256(aes) => aes.decrypt_with_backend(f),
90 }
91 }
92}
93
94impl BlockCipherEncrypt for Aes {
95 fn encrypt_blocks(&self, blocks: &mut [Block]) {
96 match &self.inner {
97 Inner::Aes128(aes) => aes.encrypt_blocks(blocks),
98 Inner::Aes192(aes) => aes.encrypt_blocks(blocks),
99 Inner::Aes256(aes) => aes.encrypt_blocks(blocks),
100 }
101 }
102
103 fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure<BlockSize = Self::BlockSize>) {
104 match &self.inner {
105 Inner::Aes128(aes) => aes.encrypt_with_backend(f),
106 Inner::Aes192(aes) => aes.encrypt_with_backend(f),
107 Inner::Aes256(aes) => aes.encrypt_with_backend(f),
108 }
109 }
110}
111
112impl BlockSizeUser for Aes {
113 type BlockSize = U16;
114}
115
116impl Debug for Aes {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 f.debug_struct("Aes").finish_non_exhaustive()
119 }
120}