Skip to main content

aes/backends/
x86_aes.rs

1use cipher::{
2    Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend,
3    BlockCipherEncClosure, BlockSizeUser, ParBlocks, ParBlocksSizeUser,
4    consts::{U8, U16},
5    inout::InOut,
6};
7
8mod encdec;
9mod expand;
10mod utils;
11
12#[cfg(feature = "hazmat")]
13pub(crate) mod hazmat;
14
15pub(crate) use encdec::{decrypt, encrypt};
16pub(crate) use expand::RoundKeys;
17
18pub(crate) type Aes128 = Aes<11>;
19pub(crate) type Aes192 = Aes<13>;
20pub(crate) type Aes256 = Aes<15>;
21
22pub(crate) type Aes128Enc = AesEnc<11>;
23pub(crate) type Aes192Enc = AesEnc<13>;
24pub(crate) type Aes256Enc = AesEnc<15>;
25
26pub(crate) type Aes128Dec = AesDec<11>;
27pub(crate) type Aes192Dec = AesDec<13>;
28pub(crate) type Aes256Dec = AesDec<15>;
29
30type ParBlocksSize = U8;
31
32#[derive(Clone, Copy)]
33pub(crate) struct Aes<const RK: usize> {
34    pub(crate) enc_rk: RoundKeys<RK>,
35    pub(crate) dec_rk: RoundKeys<RK>,
36}
37
38impl<const RK: usize> Aes<RK> {
39    #[inline]
40    #[target_feature(enable = "aes")]
41    pub(crate) fn encrypt(&self, f: impl BlockCipherEncClosure<BlockSize = U16>) {
42        f.call(self);
43    }
44
45    #[inline]
46    #[target_feature(enable = "aes")]
47    pub(crate) fn decrypt(&self, f: impl BlockCipherDecClosure<BlockSize = U16>) {
48        f.call(self);
49    }
50}
51
52impl<const RK: usize> BlockSizeUser for Aes<RK> {
53    type BlockSize = U16;
54}
55
56impl<const RK: usize> ParBlocksSizeUser for Aes<RK> {
57    type ParBlocksSize = ParBlocksSize;
58}
59
60impl<const RK: usize> BlockCipherEncBackend for Aes<RK> {
61    #[inline(always)]
62    fn encrypt_block(&self, block: InOut<'_, '_, Block<Self>>) {
63        // SAFETY: this trait impl is used only by the `Self::encrypt` method marked with
64        // `#[target_feature(enable = "aes")]`
65        unsafe { encdec::encrypt(&self.enc_rk, block) };
66    }
67
68    #[inline(always)]
69    fn encrypt_par_blocks(&self, blocks: InOut<'_, '_, ParBlocks<Self>>) {
70        // SAFETY: this trait impl is used only by the `Self::encrypt` method marked with
71        // `#[target_feature(enable = "aes")]`
72        unsafe { encdec::batch_encrypt(&self.enc_rk, blocks) };
73    }
74}
75
76impl<const RK: usize> BlockCipherDecBackend for Aes<RK> {
77    #[inline(always)]
78    fn decrypt_block(&self, block: InOut<'_, '_, Block<Self>>) {
79        // SAFETY: this trait impl is used only by the `Self::decrypt` method marked with
80        // `#[target_feature(enable = "aes")]`
81        unsafe { encdec::decrypt(&self.dec_rk, block) };
82    }
83
84    #[inline(always)]
85    fn decrypt_par_blocks(&self, blocks: InOut<'_, '_, ParBlocks<Self>>) {
86        // SAFETY: this trait impl is used only by the `Self::decrypt` method marked with
87        // `#[target_feature(enable = "aes")]`
88        unsafe { encdec::decrypt_par(&self.dec_rk, blocks) };
89    }
90}
91
92#[derive(Clone, Copy)]
93pub(crate) struct AesEnc<const RK: usize> {
94    pub(crate) enc_rk: RoundKeys<RK>,
95}
96
97impl<const RK: usize> AesEnc<RK> {
98    #[inline]
99    #[target_feature(enable = "aes")]
100    pub(crate) fn as_encdec(&self) -> Aes<RK> {
101        let enc_rk = self.enc_rk;
102        let dec_rk = expand::inv_expanded_keys(&enc_rk);
103        Aes { enc_rk, dec_rk }
104    }
105
106    #[inline]
107    #[target_feature(enable = "aes")]
108    pub(crate) fn as_dec(&self) -> AesDec<RK> {
109        let dec_rk = expand::inv_expanded_keys(&self.enc_rk);
110        AesDec { dec_rk }
111    }
112
113    #[inline]
114    #[target_feature(enable = "aes")]
115    pub(crate) fn encrypt(&self, f: impl BlockCipherEncClosure<BlockSize = U16>) {
116        f.call(self)
117    }
118}
119
120impl<const RK: usize> BlockSizeUser for AesEnc<RK> {
121    type BlockSize = U16;
122}
123
124impl<const RK: usize> ParBlocksSizeUser for AesEnc<RK> {
125    type ParBlocksSize = ParBlocksSize;
126}
127
128impl<const RK: usize> BlockCipherEncBackend for AesEnc<RK> {
129    #[inline(always)]
130    fn encrypt_block(&self, block: InOut<'_, '_, Block<Self>>) {
131        // SAFETY: this trait impl is used only by the `Self::encrypt` method marked with
132        // `#[target_feature(enable = "aes")]`
133        unsafe { encdec::encrypt(&self.enc_rk, block) };
134    }
135
136    #[inline(always)]
137    fn encrypt_par_blocks(&self, blocks: InOut<'_, '_, ParBlocks<Self>>) {
138        // SAFETY: this trait impl is used only by the `Self::encrypt` method marked with
139        // `#[target_feature(enable = "aes")]`
140        unsafe { encdec::batch_encrypt(&self.enc_rk, blocks) };
141    }
142}
143
144#[derive(Clone, Copy)]
145pub(crate) struct AesDec<const RK: usize> {
146    pub(crate) dec_rk: RoundKeys<RK>,
147}
148
149impl<const RK: usize> AesDec<RK> {
150    #[inline]
151    #[target_feature(enable = "aes")]
152    pub(crate) fn decrypt(&self, f: impl BlockCipherDecClosure<BlockSize = U16>) {
153        f.call(self);
154    }
155}
156
157impl<const RK: usize> BlockSizeUser for AesDec<RK> {
158    type BlockSize = U16;
159}
160
161impl<const RK: usize> ParBlocksSizeUser for AesDec<RK> {
162    type ParBlocksSize = ParBlocksSize;
163}
164
165impl<const RK: usize> BlockCipherDecBackend for AesDec<RK> {
166    #[inline(always)]
167    fn decrypt_block(&self, block: InOut<'_, '_, Block<Self>>) {
168        // SAFETY: this trait impl is used only by the `Self::decrypt` method marked with
169        // `#[target_feature(enable = "aes")]`
170        unsafe { encdec::decrypt(&self.dec_rk, block) };
171    }
172
173    #[inline(always)]
174    fn decrypt_par_blocks(&self, blocks: InOut<'_, '_, ParBlocks<Self>>) {
175        // SAFETY: this trait impl is used only by the `Self::decrypt` method marked with
176        // `#[target_feature(enable = "aes")]`
177        unsafe { encdec::decrypt_par(&self.dec_rk, blocks) };
178    }
179}
180
181macro_rules! impl_key_init {
182    ($name:ty, $name_enc:ty, $name_dec:ty, $key_size:literal, $expand_fn:ident) => {
183        impl $name {
184            #[inline]
185            #[target_feature(enable = "aes")]
186            pub(crate) fn new(key: &[u8; $key_size]) -> Self {
187                let enc_rk = expand::$expand_fn(key);
188                let dec_rk = expand::inv_expanded_keys(&enc_rk);
189                Self { enc_rk, dec_rk }
190            }
191        }
192
193        impl $name_enc {
194            #[inline]
195            #[target_feature(enable = "aes")]
196            pub(crate) fn new(key: &[u8; $key_size]) -> Self {
197                let enc_rk = expand::$expand_fn(key);
198                Self { enc_rk }
199            }
200        }
201
202        impl $name_dec {
203            #[inline]
204            #[target_feature(enable = "aes")]
205            pub(crate) fn new(key: &[u8; $key_size]) -> Self {
206                let enc_rk = expand::$expand_fn(key);
207                let dec_rk = expand::inv_expanded_keys(&enc_rk);
208                Self { dec_rk }
209            }
210        }
211    };
212}
213
214impl_key_init!(Aes128, Aes128Enc, Aes128Dec, 16, aes128_expand_key);
215impl_key_init!(Aes192, Aes192Enc, Aes192Dec, 24, aes192_expand_key);
216impl_key_init!(Aes256, Aes256Enc, Aes256Dec, 32, aes256_expand_key);