Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.7.5/src/ni/aes256.rs
Line
Count
Source
1
use super::{
2
    arch::*,
3
    utils::{aesdec8, aesdeclast8, aesenc8, aesenclast8, load8, store8, xor8, U128x8},
4
};
5
use crate::{Block, ParBlocks};
6
use cipher::{
7
    consts::{U16, U32, U8},
8
    generic_array::GenericArray,
9
    BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
10
};
11
12
mod expand;
13
#[cfg(test)]
14
mod test_expand;
15
16
/// AES-256 round keys
17
type RoundKeys = [__m128i; 15];
18
19
/// AES-256 block cipher
20
#[derive(Clone)]
21
pub struct Aes256 {
22
    encrypt_keys: RoundKeys,
23
    decrypt_keys: RoundKeys,
24
}
25
26
impl Aes256 {
27
    #[inline(always)]
28
0
    pub(crate) fn encrypt8(&self, mut blocks: U128x8) -> U128x8 {
29
        #[inline]
30
        #[target_feature(enable = "aes")]
31
0
        unsafe fn aesni256_encrypt8(keys: &RoundKeys, blocks: &mut U128x8) {
32
0
            xor8(blocks, keys[0]);
33
0
            aesenc8(blocks, keys[1]);
34
0
            aesenc8(blocks, keys[2]);
35
0
            aesenc8(blocks, keys[3]);
36
0
            aesenc8(blocks, keys[4]);
37
0
            aesenc8(blocks, keys[5]);
38
0
            aesenc8(blocks, keys[6]);
39
0
            aesenc8(blocks, keys[7]);
40
0
            aesenc8(blocks, keys[8]);
41
0
            aesenc8(blocks, keys[9]);
42
0
            aesenc8(blocks, keys[10]);
43
0
            aesenc8(blocks, keys[11]);
44
0
            aesenc8(blocks, keys[12]);
45
0
            aesenc8(blocks, keys[13]);
46
0
            aesenclast8(blocks, keys[14]);
47
0
        }
48
0
        unsafe { aesni256_encrypt8(&self.encrypt_keys, &mut blocks) };
49
0
        blocks
50
0
    }
51
52
    #[inline(always)]
53
0
    pub(crate) fn encrypt(&self, block: __m128i) -> __m128i {
54
        #[inline]
55
        #[target_feature(enable = "aes")]
56
0
        unsafe fn aesni256_encrypt1(keys: &RoundKeys, mut block: __m128i) -> __m128i {
57
0
            block = _mm_xor_si128(block, keys[0]);
58
0
            block = _mm_aesenc_si128(block, keys[1]);
59
0
            block = _mm_aesenc_si128(block, keys[2]);
60
0
            block = _mm_aesenc_si128(block, keys[3]);
61
0
            block = _mm_aesenc_si128(block, keys[4]);
62
0
            block = _mm_aesenc_si128(block, keys[5]);
63
0
            block = _mm_aesenc_si128(block, keys[6]);
64
0
            block = _mm_aesenc_si128(block, keys[7]);
65
0
            block = _mm_aesenc_si128(block, keys[8]);
66
0
            block = _mm_aesenc_si128(block, keys[9]);
67
0
            block = _mm_aesenc_si128(block, keys[10]);
68
0
            block = _mm_aesenc_si128(block, keys[11]);
69
0
            block = _mm_aesenc_si128(block, keys[12]);
70
0
            block = _mm_aesenc_si128(block, keys[13]);
71
0
            _mm_aesenclast_si128(block, keys[14])
72
0
        }
73
0
        unsafe { aesni256_encrypt1(&self.encrypt_keys, block) }
74
0
    }
75
}
76
77
impl NewBlockCipher for Aes256 {
78
    type KeySize = U32;
79
80
    #[inline]
81
0
    fn new(key: &GenericArray<u8, U32>) -> Self {
82
0
        let key = unsafe { &*(key as *const _ as *const [u8; 32]) };
83
0
        let (encrypt_keys, decrypt_keys) = expand::expand(key);
84
0
        Self {
85
0
            encrypt_keys,
86
0
            decrypt_keys,
87
0
        }
88
0
    }
89
}
90
91
impl BlockCipher for Aes256 {
92
    type BlockSize = U16;
93
    type ParBlocks = U8;
94
}
95
96
impl BlockEncrypt for Aes256 {
97
    #[inline]
98
0
    fn encrypt_block(&self, block: &mut Block) {
99
        // Safety: `loadu` and `storeu` support unaligned access
100
        #[allow(clippy::cast_ptr_alignment)]
101
0
        unsafe {
102
0
            let b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
103
0
            let b = self.encrypt(b);
104
0
            _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
105
0
        }
106
0
    }
107
108
    #[inline]
109
0
    fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) {
110
0
        let b = self.encrypt8(load8(blocks));
111
0
        store8(blocks, b);
112
0
    }
113
}
114
115
impl BlockDecrypt for Aes256 {
116
    #[inline]
117
0
    fn decrypt_block(&self, block: &mut Block) {
118
        #[inline]
119
        #[target_feature(enable = "aes")]
120
0
        unsafe fn aes256_decrypt1(block: &mut Block, keys: &RoundKeys) {
121
            // Safety: `loadu` and `storeu` support unaligned access
122
            #[allow(clippy::cast_ptr_alignment)]
123
0
            let mut b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
124
125
0
            b = _mm_xor_si128(b, keys[14]);
126
0
            b = _mm_aesdec_si128(b, keys[13]);
127
0
            b = _mm_aesdec_si128(b, keys[12]);
128
0
            b = _mm_aesdec_si128(b, keys[11]);
129
0
            b = _mm_aesdec_si128(b, keys[10]);
130
0
            b = _mm_aesdec_si128(b, keys[9]);
131
0
            b = _mm_aesdec_si128(b, keys[8]);
132
0
            b = _mm_aesdec_si128(b, keys[7]);
133
0
            b = _mm_aesdec_si128(b, keys[6]);
134
0
            b = _mm_aesdec_si128(b, keys[5]);
135
0
            b = _mm_aesdec_si128(b, keys[4]);
136
0
            b = _mm_aesdec_si128(b, keys[3]);
137
0
            b = _mm_aesdec_si128(b, keys[2]);
138
0
            b = _mm_aesdec_si128(b, keys[1]);
139
0
            b = _mm_aesdeclast_si128(b, keys[0]);
140
141
            // Safety: `loadu` and `storeu` support unaligned access
142
            #[allow(clippy::cast_ptr_alignment)]
143
0
            _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
144
0
        }
145
146
0
        unsafe { aes256_decrypt1(block, &self.decrypt_keys) }
147
0
    }
148
149
    #[inline]
150
0
    fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) {
151
        #[inline]
152
        #[target_feature(enable = "aes")]
153
0
        unsafe fn aes256_decrypt8(blocks: &mut ParBlocks, keys: &RoundKeys) {
154
0
            let mut b = load8(blocks);
155
0
            xor8(&mut b, keys[14]);
156
0
            aesdec8(&mut b, keys[13]);
157
0
            aesdec8(&mut b, keys[12]);
158
0
            aesdec8(&mut b, keys[11]);
159
0
            aesdec8(&mut b, keys[10]);
160
0
            aesdec8(&mut b, keys[9]);
161
0
            aesdec8(&mut b, keys[8]);
162
0
            aesdec8(&mut b, keys[7]);
163
0
            aesdec8(&mut b, keys[6]);
164
0
            aesdec8(&mut b, keys[5]);
165
0
            aesdec8(&mut b, keys[4]);
166
0
            aesdec8(&mut b, keys[3]);
167
0
            aesdec8(&mut b, keys[2]);
168
0
            aesdec8(&mut b, keys[1]);
169
0
            aesdeclast8(&mut b, keys[0]);
170
0
            store8(blocks, b);
171
0
        }
172
173
0
        unsafe { aes256_decrypt8(blocks, &self.decrypt_keys) }
174
0
    }
175
}
176
177
opaque_debug::implement!(Aes256);