Skip to content

Commit 2947cd6

Browse files
committed
Fix the implementations
Use LLVM intrinsics for riscv
1 parent 064bee1 commit 2947cd6

10 files changed

+237
-235
lines changed

src/aes_arm.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::{mem, slice};
77

88
#[derive(Copy, Clone)]
99
#[repr(transparent)]
10+
#[must_use]
1011
pub struct AesBlock(uint8x16_t);
1112

1213
impl PartialEq for AesBlock {
@@ -94,6 +95,7 @@ impl AesBlock {
9495
}
9596

9697
#[inline]
98+
#[must_use]
9799
pub fn is_zero(self) -> bool {
98100
#[cfg(not(target_arch = "arm"))]
99101
unsafe {
@@ -120,7 +122,7 @@ impl AesBlock {
120122
self.pre_enc_last(round_key).mc()
121123
}
122124

123-
/// Performs one round of AES encryption function (ShiftRows->SubBytes->MixColumns->AddRoundKey)
125+
/// Performs one round of AES encryption function (`ShiftRows`->`SubBytes`->`MixColumns`->`AddRoundKey`)
124126
#[inline]
125127
pub fn enc(self, round_key: Self) -> Self {
126128
self.pre_enc(Self::zero()) ^ round_key
@@ -136,31 +138,31 @@ impl AesBlock {
136138
self.pre_dec_last(round_key).imc()
137139
}
138140

139-
/// Performs one round of AES decryption function (InvShiftRows->InvSubBytes->InvMixColumns->AddRoundKey)
141+
/// Performs one round of AES decryption function (`InvShiftRows`->`InvSubBytes`->`InvMixColumn`s->`AddRoundKey`)
140142
#[inline]
141143
pub fn dec(self, round_key: Self) -> Self {
142144
self.pre_dec(Self::zero()) ^ round_key
143145
}
144146

145-
/// Performs one round of AES encryption function without MixColumns (ShiftRows->SubBytes->AddRoundKey)
147+
/// Performs one round of AES encryption function without `MixColumns` (`ShiftRows`->`SubBytes`->`AddRoundKey`)
146148
#[inline]
147149
pub fn enc_last(self, round_key: Self) -> Self {
148150
self.pre_enc_last(Self::zero()) ^ round_key
149151
}
150152

151-
/// Performs one round of AES decryption function without InvMixColumns (InvShiftRows->InvSubBytes->AddRoundKey)
153+
/// Performs one round of AES decryption function without `InvMixColumn`s (`InvShiftRows`->`InvSubBytes`->`AddRoundKey`)
152154
#[inline]
153155
pub fn dec_last(self, round_key: Self) -> Self {
154156
self.pre_dec_last(Self::zero()) ^ round_key
155157
}
156158

157-
/// Performs the MixColumns operation
159+
/// Performs the `MixColumns` operation
158160
#[inline]
159161
pub fn mc(self) -> Self {
160162
Self(unsafe { vaesmcq_u8(self.0) })
161163
}
162164

163-
/// Performs the InvMixColumns operation
165+
/// Performs the `InvMixColumn`s operation
164166
#[inline]
165167
pub fn imc(self) -> Self {
166168
Self(unsafe { vaesimcq_u8(self.0) })

src/aes_default.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
#![allow(clippy::unreadable_literal, clippy::cast_possible_truncation)]
12
use core::ops::{BitAnd, BitOr, BitXor, Not};
23

34
#[derive(Copy, Clone, PartialEq, Eq)]
45
#[repr(C, align(16))]
6+
#[must_use]
57
pub struct AesBlock(u32, u32, u32, u32);
68

79
#[inline(always)]
@@ -104,11 +106,12 @@ impl AesBlock {
104106
}
105107

106108
#[inline]
109+
#[must_use]
107110
pub fn is_zero(self) -> bool {
108111
(self.0 | self.1 | self.2 | self.3) == 0
109112
}
110113

111-
/// Performs one round of AES encryption function (ShiftRows->SubBytes->MixColumns->AddRoundKey)
114+
/// Performs one round of AES encryption function (`ShiftRows`->`SubBytes`->`MixColumns`->`AddRoundKey`)
112115
#[inline]
113116
pub fn enc(self, round_key: Self) -> Self {
114117
Self(
@@ -119,7 +122,7 @@ impl AesBlock {
119122
)
120123
}
121124

122-
/// Performs one round of AES encryption function without MixColumns (ShiftRows->SubBytes->AddRoundKey)
125+
/// Performs one round of AES encryption function without `MixColumns` (`ShiftRows`->`SubBytes`->`AddRoundKey`)
123126
#[inline]
124127
pub fn enc_last(self, round_key: Self) -> Self {
125128
Self(
@@ -146,7 +149,7 @@ impl AesBlock {
146149
)
147150
}
148151

149-
/// Performs one round of AES decryption function (InvShiftRows->InvSubBytes->InvMixColumns->AddRoundKey)
152+
/// Performs one round of AES decryption function (`InvShiftRows`->`InvSubBytes`->`InvMixColumn`s->`AddRoundKey`)
150153
#[inline]
151154
pub fn dec(self, round_key: Self) -> Self {
152155
Self(
@@ -157,7 +160,7 @@ impl AesBlock {
157160
)
158161
}
159162

160-
/// Performs one round of AES decryption function without InvMixColumns (InvShiftRows->InvSubBytes->AddRoundKey)
163+
/// Performs one round of AES decryption function without `InvMixColumn`s (`InvShiftRows`->`InvSubBytes`->`AddRoundKey`)
161164
#[inline]
162165
pub fn dec_last(self, round_key: Self) -> Self {
163166
Self(
@@ -184,7 +187,7 @@ impl AesBlock {
184187
)
185188
}
186189

187-
/// Performs the MixColumns operation
190+
/// Performs the `MixColumns` operation
188191
#[inline]
189192
pub fn mc(self) -> Self {
190193
Self(
@@ -207,7 +210,7 @@ impl AesBlock {
207210
)
208211
}
209212

210-
/// Performs the InvMixColumns operation
213+
/// Performs the `InvMixColumn`s operation
211214
#[inline]
212215
pub fn imc(self) -> Self {
213216
Self(

src/aes_riscv32.rs

+37-35
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,40 @@
1-
use core::arch::asm;
21
use core::ops::{BitAnd, BitOr, BitXor, Not};
32
use core::{mem, slice};
43

54
#[derive(Eq, PartialEq, Copy, Clone)]
65
#[repr(C, align(16))]
6+
#[must_use]
77
pub struct AesBlock(u32, u32, u32, u32);
88

9-
macro_rules! _asm {
10-
($instruction:expr, $idx:literal, $rsd:ident, $rs:expr) => {
11-
asm!(
12-
concat!($instruction, "i {rd},{rs1},{rs2},", $idx),
13-
rd = lateout(reg) $rsd,
14-
rs1 = in(reg) $rsd,
15-
rs2 = in(reg) $rs,
16-
options(pure, nomem, nostack)
17-
)
18-
};
9+
extern "unadjusted" {
10+
#[link_name = "llvm.riscv.aes32esmi"]
11+
fn aes32esmi(rs1: u32, rs2: u32, bs: u32) -> u32;
12+
#[link_name = "llvm.riscv.aes32esi"]
13+
fn aes32esi(rs1: u32, rs2: u32, bs: u32) -> u32;
14+
#[link_name = "llvm.riscv.aes32dsmi"]
15+
fn aes32dsmi(rs1: u32, rs2: u32, bs: u32) -> u32;
16+
#[link_name = "llvm.riscv.aes32dsi"]
17+
fn aes32dsi(rs1: u32, rs2: u32, bs: u32) -> u32;
1918
}
2019

2120
macro_rules! outer {
2221
($name:ident, $msg:ident, $rk:ident) => {{
2322
#[inline(always)]
24-
fn $name(t0: u32, t1: u32, t2: u32, t3: u32, rk: u32) -> u32 {
23+
fn inner(t0: u32, t1: u32, t2: u32, t3: u32, rk: u32) -> u32 {
2524
let mut value = rk;
2625
unsafe {
27-
_asm!(stringify!($name), 0, value, t0);
28-
_asm!(stringify!($name), 1, value, t1);
29-
_asm!(stringify!($name), 2, value, t2);
30-
_asm!(stringify!($name), 3, value, t3);
26+
value = $name(value, t0, 0);
27+
value = $name(value, t1, 1);
28+
value = $name(value, t2, 2);
29+
value = $name(value, t3, 3);
3130
}
3231
value
3332
}
3433
AesBlock(
35-
$name($msg.0, $msg.1, $msg.2, $msg.3, $rk.0),
36-
$name($msg.1, $msg.2, $msg.3, $msg.0, $rk.1),
37-
$name($msg.2, $msg.3, $msg.0, $msg.1, $rk.2),
38-
$name($msg.3, $msg.0, $msg.1, $msg.2, $rk.3),
34+
inner($msg.0, $msg.1, $msg.2, $msg.3, $rk.0),
35+
inner($msg.1, $msg.2, $msg.3, $msg.0, $rk.1),
36+
inner($msg.2, $msg.3, $msg.0, $msg.1, $rk.2),
37+
inner($msg.3, $msg.0, $msg.1, $msg.2, $rk.3),
3938
)
4039
}};
4140
}
@@ -107,7 +106,9 @@ impl AesBlock {
107106
#[inline]
108107
pub fn store_to(self, dst: &mut [u8]) {
109108
assert!(dst.len() >= 16);
110-
unsafe { *dst.as_mut_ptr().cast::<[u8; 16]>() = mem::transmute(self) }
109+
unsafe {
110+
dst.as_mut_ptr().cast::<Self>().write_unaligned(self);
111+
}
111112
}
112113

113114
#[inline]
@@ -116,61 +117,62 @@ impl AesBlock {
116117
}
117118

118119
#[inline]
120+
#[must_use]
119121
pub fn is_zero(self) -> bool {
120122
(self.0 | self.1 | self.2 | self.3) == 0
121123
}
122124

123125
#[inline(always)]
124126
pub(crate) fn pre_enc(self, round_key: Self) -> Self {
125-
outer!(aes32esm, self, round_key)
127+
outer!(aes32esmi, self, round_key)
126128
}
127129

128-
/// Performs one round of AES encryption function (ShiftRows->SubBytes->MixColumns->AddRoundKey)
130+
/// Performs one round of AES encryption function (`ShiftRows`->`SubBytes`->`MixColumns`->`AddRoundKey`)
129131
#[inline]
130132
pub fn enc(self, round_key: Self) -> Self {
131133
self.pre_enc(Self::zero()) ^ round_key
132134
}
133135

134136
#[inline(always)]
135137
pub(crate) fn pre_enc_last(self, round_key: Self) -> Self {
136-
outer!(aes32es, self, round_key)
138+
outer!(aes32esi, self, round_key)
137139
}
138140

139-
/// Performs one round of AES encryption function without MixColumns (ShiftRows->SubBytes->AddRoundKey)
141+
/// Performs one round of AES encryption function without `MixColumns` (`ShiftRows`->`SubBytes`->`AddRoundKey`)
140142
#[inline]
141143
pub fn enc_last(self, round_key: Self) -> Self {
142144
self.pre_enc_last(Self::zero()) ^ round_key
143145
}
144146

145147
#[inline(always)]
146148
pub(crate) fn pre_dec(self, round_key: Self) -> Self {
147-
outer!(aes32dsm, self, round_key)
149+
outer!(aes32dsmi, self, round_key)
148150
}
149151

150-
/// Performs one round of AES decryption function (InvShiftRows->InvSubBytes->InvMixColumns->AddRoundKey)
152+
/// Performs one round of AES decryption function (`InvShiftRows`->`InvSubBytes`->`InvMixColumn`s->`AddRoundKey`)
151153
#[inline]
152154
pub fn dec(self, round_key: Self) -> Self {
153155
self.pre_dec(Self::zero()) ^ round_key
154156
}
155157

156158
#[inline(always)]
157159
pub(crate) fn pre_dec_last(self, round_key: Self) -> Self {
158-
outer!(aes32ds, self, round_key)
160+
outer!(aes32dsi, self, round_key)
159161
}
160162

161-
/// Performs one round of AES decryption function without InvMixColumns (InvShiftRows->InvSubBytes->AddRoundKey)
163+
/// Performs one round of AES decryption function without `InvMixColumn`s (`InvShiftRows`->`InvSubBytes`->`AddRoundKey`)
162164
#[inline]
163165
pub fn dec_last(self, round_key: Self) -> Self {
164166
self.pre_dec_last(Self::zero()) ^ round_key
165167
}
166168

167-
/// Performs the MixColumns operation
169+
/// Performs the `MixColumns` operation
168170
#[inline]
169171
pub fn mc(self) -> Self {
170172
self.pre_dec_last(Self::zero()).enc(Self::zero())
171173
}
172174

173-
/// Performs the InvMixColumns operation
175+
/// Performs the `InvMixColumn`s operation
174176
#[inline]
175177
pub fn imc(self) -> Self {
176178
self.pre_enc_last(Self::zero()).dec(Self::zero())
@@ -183,10 +185,10 @@ const RCON: [u32; 10] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0
183185
fn sub_word(xor: u32, word: u32) -> u32 {
184186
let mut value = xor;
185187
unsafe {
186-
_asm!("aes32es", 0, value, word);
187-
_asm!("aes32es", 1, value, word);
188-
_asm!("aes32es", 2, value, word);
189-
_asm!("aes32es", 3, value, word);
188+
value = aes32esi(value, word, 0);
189+
value = aes32esi(value, word, 1);
190+
value = aes32esi(value, word, 2);
191+
value = aes32esi(value, word, 3);
190192
}
191193
value
192194
}

0 commit comments

Comments
 (0)