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/aes128.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, 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-128 round keys
17
type RoundKeys = [__m128i; 11];
18
19
/// AES-128 block cipher
20
#[derive(Clone)]
21
pub struct Aes128 {
22
    encrypt_keys: RoundKeys,
23
    decrypt_keys: RoundKeys,
24
}
25
26
impl Aes128 {
27
    #[inline(always)]
28
358
    pub(crate) fn encrypt8(&self, mut blocks: U128x8) -> U128x8 {
29
        #[inline]
30
        #[target_feature(enable = "aes")]
31
358
        unsafe fn aesni128_encrypt8(keys: &RoundKeys, blocks: &mut U128x8) {
32
358
            xor8(blocks, keys[0]);
33
358
            aesenc8(blocks, keys[1]);
34
358
            aesenc8(blocks, keys[2]);
35
358
            aesenc8(blocks, keys[3]);
36
358
            aesenc8(blocks, keys[4]);
37
358
            aesenc8(blocks, keys[5]);
38
358
            aesenc8(blocks, keys[6]);
39
358
            aesenc8(blocks, keys[7]);
40
358
            aesenc8(blocks, keys[8]);
41
358
            aesenc8(blocks, keys[9]);
42
358
            aesenclast8(blocks, keys[10]);
43
358
        }
44
358
        unsafe { aesni128_encrypt8(&self.encrypt_keys, &mut blocks) };
45
358
        blocks
46
358
    }
47
48
    #[inline(always)]
49
8.15k
    pub(crate) fn encrypt(&self, block: __m128i) -> __m128i {
50
        #[inline]
51
        #[target_feature(enable = "aes")]
52
8.15k
        unsafe fn aesni128_encrypt1(keys: &RoundKeys, mut block: __m128i) -> __m128i {
53
8.15k
            block = _mm_xor_si128(block, keys[0]);
54
8.15k
            block = _mm_aesenc_si128(block, keys[1]);
55
8.15k
            block = _mm_aesenc_si128(block, keys[2]);
56
8.15k
            block = _mm_aesenc_si128(block, keys[3]);
57
8.15k
            block = _mm_aesenc_si128(block, keys[4]);
58
8.15k
            block = _mm_aesenc_si128(block, keys[5]);
59
8.15k
            block = _mm_aesenc_si128(block, keys[6]);
60
8.15k
            block = _mm_aesenc_si128(block, keys[7]);
61
8.15k
            block = _mm_aesenc_si128(block, keys[8]);
62
8.15k
            block = _mm_aesenc_si128(block, keys[9]);
63
8.15k
            _mm_aesenclast_si128(block, keys[10])
64
8.15k
        }
65
8.15k
        unsafe { aesni128_encrypt1(&self.encrypt_keys, block) }
66
8.15k
    }
67
}
68
69
impl NewBlockCipher for Aes128 {
70
    type KeySize = U16;
71
72
    #[inline]
73
2.43k
    fn new(key: &GenericArray<u8, U16>) -> Self {
74
2.43k
        let key = unsafe { &*(key as *const _ as *const [u8; 16]) };
75
76
2.43k
        let (encrypt_keys, decrypt_keys) = expand::expand(key);
77
78
2.43k
        Self {
79
2.43k
            encrypt_keys,
80
2.43k
            decrypt_keys,
81
2.43k
        }
82
2.43k
    }
83
}
84
85
impl BlockCipher for Aes128 {
86
    type BlockSize = U16;
87
    type ParBlocks = U8;
88
}
89
90
impl BlockEncrypt for Aes128 {
91
    #[inline]
92
8.15k
    fn encrypt_block(&self, block: &mut Block) {
93
        // Safety: `loadu` and `storeu` support unaligned access
94
        #[allow(clippy::cast_ptr_alignment)]
95
8.15k
        unsafe {
96
8.15k
            let b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
97
8.15k
            let b = self.encrypt(b);
98
8.15k
            _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
99
8.15k
        }
100
8.15k
    }
101
102
    #[inline]
103
358
    fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) {
104
358
        let b = self.encrypt8(load8(blocks));
105
358
        store8(blocks, b);
106
358
    }
107
}
108
109
impl BlockDecrypt for Aes128 {
110
    #[inline]
111
0
    fn decrypt_block(&self, block: &mut Block) {
112
        #[inline]
113
        #[target_feature(enable = "aes")]
114
0
        unsafe fn aes128_decrypt1(block: &mut Block, keys: &RoundKeys) {
115
            // Safety: `loadu` and `storeu` support unaligned access
116
            #[allow(clippy::cast_ptr_alignment)]
117
0
            let mut b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
118
119
0
            b = _mm_xor_si128(b, keys[10]);
120
0
            b = _mm_aesdec_si128(b, keys[9]);
121
0
            b = _mm_aesdec_si128(b, keys[8]);
122
0
            b = _mm_aesdec_si128(b, keys[7]);
123
0
            b = _mm_aesdec_si128(b, keys[6]);
124
0
            b = _mm_aesdec_si128(b, keys[5]);
125
0
            b = _mm_aesdec_si128(b, keys[4]);
126
0
            b = _mm_aesdec_si128(b, keys[3]);
127
0
            b = _mm_aesdec_si128(b, keys[2]);
128
0
            b = _mm_aesdec_si128(b, keys[1]);
129
0
            b = _mm_aesdeclast_si128(b, keys[0]);
130
131
            // Safety: `loadu` and `storeu` support unaligned access
132
            #[allow(clippy::cast_ptr_alignment)]
133
0
            _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
134
0
        }
135
136
0
        unsafe { aes128_decrypt1(block, &self.decrypt_keys) }
137
0
    }
138
139
    #[inline]
140
0
    fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) {
141
        #[inline]
142
        #[target_feature(enable = "aes")]
143
0
        unsafe fn aes128_decrypt8(blocks: &mut ParBlocks, keys: &RoundKeys) {
144
0
            let mut b = load8(blocks);
145
0
            xor8(&mut b, keys[10]);
146
0
            aesdec8(&mut b, keys[9]);
147
0
            aesdec8(&mut b, keys[8]);
148
0
            aesdec8(&mut b, keys[7]);
149
0
            aesdec8(&mut b, keys[6]);
150
0
            aesdec8(&mut b, keys[5]);
151
0
            aesdec8(&mut b, keys[4]);
152
0
            aesdec8(&mut b, keys[3]);
153
0
            aesdec8(&mut b, keys[2]);
154
0
            aesdec8(&mut b, keys[1]);
155
0
            aesdeclast8(&mut b, keys[0]);
156
0
            store8(blocks, b);
157
0
        }
158
159
0
        unsafe { aes128_decrypt8(blocks, &self.decrypt_keys) }
160
0
    }
161
}
162
163
opaque_debug::implement!(Aes128);