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