Skip to main content

aes/backends/
x86_vaes256.rs

1use super::x86_aes::RoundKeys;
2use cipher::{
3    Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend,
4    BlockCipherEncClosure, BlockSizeUser, ParBlocks, ParBlocksSizeUser,
5    consts::{U16, U30},
6    inout::InOut,
7};
8
9mod encdec;
10
11pub(crate) type Aes128<'a> = Aes<'a, 11>;
12pub(crate) type Aes192<'a> = Aes<'a, 13>;
13pub(crate) type Aes256<'a> = Aes<'a, 15>;
14
15#[derive(Clone, Copy)]
16pub(crate) struct Aes<'a, const RK: usize> {
17    rk: &'a RoundKeys<RK>,
18    rk2: encdec::RoundKeys2<RK>,
19}
20
21impl<'a, const RK: usize> Aes<'a, RK> {
22    #[inline]
23    #[target_feature(enable = "vaes")]
24    pub(crate) fn encrypt(rk: &'a RoundKeys<RK>, f: impl BlockCipherEncClosure<BlockSize = U16>) {
25        let rk2 = encdec::broadcast_keys(rk);
26        let backend = Self { rk, rk2 };
27        f.call(&backend)
28    }
29
30    #[inline]
31    #[target_feature(enable = "vaes")]
32    pub(crate) fn decrypt(rk: &'a RoundKeys<RK>, f: impl BlockCipherDecClosure<BlockSize = U16>) {
33        let rk2 = encdec::broadcast_keys(rk);
34        let backend = Self { rk, rk2 };
35        f.call(&backend)
36    }
37}
38
39impl<const RK: usize> BlockSizeUser for Aes<'_, RK> {
40    type BlockSize = U16;
41}
42
43// Block size of 30 is chosen based on AVX2's 16 YMM registers.
44//
45// - 1 register holds round key
46// - 15 registers hold 2 data blocks
47impl<const RK: usize> ParBlocksSizeUser for Aes<'_, RK> {
48    type ParBlocksSize = U30;
49}
50
51impl<const RK: usize> BlockCipherEncBackend for Aes<'_, RK> {
52    #[inline(always)]
53    fn encrypt_block(&self, block: InOut<'_, '_, Block<Self>>) {
54        // SAFETY: this trait impl is used only by the `Self::encrypt` method marked with
55        // `#[target_feature(enable = "vaes")]`
56        unsafe { super::x86_aes::encrypt(self.rk, block) };
57    }
58
59    #[inline(always)]
60    fn encrypt_par_blocks(&self, blocks: InOut<'_, '_, ParBlocks<Self>>) {
61        // SAFETY: this trait impl is used only by the `Self::encrypt` method marked with
62        // `#[target_feature(enable = "vaes")]`
63        unsafe { encdec::batch_encrypt(&self.rk2, blocks) };
64    }
65}
66
67impl<const RK: usize> BlockCipherDecBackend for Aes<'_, RK> {
68    #[inline(always)]
69    fn decrypt_block(&self, block: InOut<'_, '_, Block<Self>>) {
70        // SAFETY: this trait impl is used only by the `Self::decrypt` method marked with
71        // `#[target_feature(enable = "vaes")]`
72        unsafe { super::x86_aes::decrypt(self.rk, block) };
73    }
74
75    #[inline(always)]
76    fn decrypt_par_blocks(&self, blocks: InOut<'_, '_, ParBlocks<Self>>) {
77        // SAFETY: this trait impl is used only by the `Self::decrypt` method marked with
78        // `#[target_feature(enable = "vaes")]`
79        unsafe { encdec::batch_decrypt(&self.rk2, blocks) };
80    }
81}