Skip to content

Commit eb309c6

Browse files
authored
aes: refactor ARMv8 expand_key (#367)
Changes `expand_key` to an `unsafe fn` that uses `target_feature`. Removes the TODOs: due to AES-192 this function can't be easily refactored to use `vinterpretq_u8_u32`.
1 parent 8d03900 commit eb309c6

File tree

3 files changed

+16
-18
lines changed

3 files changed

+16
-18
lines changed

aes/src/armv8.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ macro_rules! define_aes_impl {
149149
impl KeyInit for $name_enc {
150150
fn new(key: &Key<Self>) -> Self {
151151
Self {
152-
round_keys: expand_key(key.as_ref()),
152+
round_keys: unsafe { expand_key(key.as_ref()) },
153153
}
154154
}
155155
}

aes/src/armv8/expand.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,18 @@ const WORD_SIZE: usize = 4;
1515
/// AES round constants.
1616
const ROUND_CONSTS: [u32; 10] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
1717

18-
/// AES key expansion
19-
// TODO(tarcieri): big endian support?
20-
#[inline]
21-
pub(super) fn expand_key<const L: usize, const N: usize>(key: &[u8; L]) -> [uint8x16_t; N] {
18+
/// AES key expansion.
19+
#[target_feature(enable = "aes")]
20+
pub unsafe fn expand_key<const L: usize, const N: usize>(key: &[u8; L]) -> [uint8x16_t; N] {
2221
assert!((L == 16 && N == 11) || (L == 24 && N == 13) || (L == 32 && N == 15));
2322

24-
let mut expanded_keys: [uint8x16_t; N] = unsafe { mem::zeroed() };
23+
let mut expanded_keys: [uint8x16_t; N] = mem::zeroed();
2524

26-
// TODO(tarcieri): construct expanded keys using `vreinterpretq_u8_u32`
27-
let ek_words = unsafe {
28-
slice::from_raw_parts_mut(expanded_keys.as_mut_ptr() as *mut u32, N * BLOCK_WORDS)
29-
};
25+
let columns =
26+
slice::from_raw_parts_mut(expanded_keys.as_mut_ptr() as *mut u32, N * BLOCK_WORDS);
3027

3128
for (i, chunk) in key.chunks_exact(WORD_SIZE).enumerate() {
32-
ek_words[i] = u32::from_ne_bytes(chunk.try_into().unwrap());
29+
columns[i] = u32::from_ne_bytes(chunk.try_into().unwrap());
3330
}
3431

3532
// From "The Rijndael Block Cipher" Section 4.1:
@@ -38,15 +35,15 @@ pub(super) fn expand_key<const L: usize, const N: usize>(key: &[u8; L]) -> [uint
3835
let nk = L / WORD_SIZE;
3936

4037
for i in nk..(N * BLOCK_WORDS) {
41-
let mut word = ek_words[i - 1];
38+
let mut word = columns[i - 1];
4239

4340
if i % nk == 0 {
44-
word = unsafe { sub_word(word) }.rotate_right(8) ^ ROUND_CONSTS[i / nk - 1];
41+
word = sub_word(word).rotate_right(8) ^ ROUND_CONSTS[i / nk - 1];
4542
} else if nk > 6 && i % nk == 4 {
46-
word = unsafe { sub_word(word) };
43+
word = sub_word(word);
4744
}
4845

49-
ek_words[i] = ek_words[i - nk] ^ word;
46+
columns[i] = columns[i - nk] ^ word;
5047
}
5148

5249
expanded_keys
@@ -68,6 +65,7 @@ pub(super) unsafe fn inv_expanded_keys<const N: usize>(expanded_keys: &mut [uint
6865
}
6966

7067
/// Sub bytes for a single AES word: used for key expansion.
68+
#[inline]
7169
#[target_feature(enable = "aes")]
7270
unsafe fn sub_word(input: u32) -> u32 {
7371
let input = vreinterpretq_u8_u32(vdupq_n_u32(input));

aes/src/armv8/test_expand.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn store_expanded_keys<const N: usize>(input: [uint8x16_t; N]) -> [[u8; 16]; N]
106106

107107
#[test]
108108
fn aes128_key_expansion() {
109-
let ek = expand_key(&AES128_KEY);
109+
let ek = unsafe { expand_key(&AES128_KEY) };
110110
assert_eq!(store_expanded_keys(ek), AES128_EXP_KEYS);
111111
}
112112

@@ -119,12 +119,12 @@ fn aes128_key_expansion_inv() {
119119

120120
#[test]
121121
fn aes192_key_expansion() {
122-
let ek = expand_key(&AES192_KEY);
122+
let ek = unsafe { expand_key(&AES192_KEY) };
123123
assert_eq!(store_expanded_keys(ek), AES192_EXP_KEYS);
124124
}
125125

126126
#[test]
127127
fn aes256_key_expansion() {
128-
let ek = expand_key(&AES256_KEY);
128+
let ek = unsafe { expand_key(&AES256_KEY) };
129129
assert_eq!(store_expanded_keys(ek), AES256_EXP_KEYS);
130130
}

0 commit comments

Comments
 (0)