1
- use core:: arch:: asm;
2
1
use core:: ops:: { BitAnd , BitOr , BitXor , Not } ;
3
2
use core:: { mem, slice} ;
4
3
5
4
#[ derive( Eq , PartialEq , Copy , Clone ) ]
6
5
#[ repr( C , align( 16 ) ) ]
6
+ #[ must_use]
7
7
pub struct AesBlock ( u32 , u32 , u32 , u32 ) ;
8
8
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 ;
19
18
}
20
19
21
20
macro_rules! outer {
22
21
( $name: ident, $msg: ident, $rk: ident) => { {
23
22
#[ 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 {
25
24
let mut value = rk;
26
25
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 ) ;
31
30
}
32
31
value
33
32
}
34
33
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 ) ,
39
38
)
40
39
} } ;
41
40
}
@@ -107,7 +106,9 @@ impl AesBlock {
107
106
#[ inline]
108
107
pub fn store_to ( self , dst : & mut [ u8 ] ) {
109
108
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
+ }
111
112
}
112
113
113
114
#[ inline]
@@ -116,61 +117,62 @@ impl AesBlock {
116
117
}
117
118
118
119
#[ inline]
120
+ #[ must_use]
119
121
pub fn is_zero ( self ) -> bool {
120
122
( self . 0 | self . 1 | self . 2 | self . 3 ) == 0
121
123
}
122
124
123
125
#[ inline( always) ]
124
126
pub ( crate ) fn pre_enc ( self , round_key : Self ) -> Self {
125
- outer ! ( aes32esm , self , round_key)
127
+ outer ! ( aes32esmi , self , round_key)
126
128
}
127
129
128
- /// Performs one round of AES encryption function (ShiftRows-> SubBytes-> MixColumns-> AddRoundKey)
130
+ /// Performs one round of AES encryption function (` ShiftRows`->` SubBytes`->` MixColumns`->` AddRoundKey` )
129
131
#[ inline]
130
132
pub fn enc ( self , round_key : Self ) -> Self {
131
133
self . pre_enc ( Self :: zero ( ) ) ^ round_key
132
134
}
133
135
134
136
#[ inline( always) ]
135
137
pub ( crate ) fn pre_enc_last ( self , round_key : Self ) -> Self {
136
- outer ! ( aes32es , self , round_key)
138
+ outer ! ( aes32esi , self , round_key)
137
139
}
138
140
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` )
140
142
#[ inline]
141
143
pub fn enc_last ( self , round_key : Self ) -> Self {
142
144
self . pre_enc_last ( Self :: zero ( ) ) ^ round_key
143
145
}
144
146
145
147
#[ inline( always) ]
146
148
pub ( crate ) fn pre_dec ( self , round_key : Self ) -> Self {
147
- outer ! ( aes32dsm , self , round_key)
149
+ outer ! ( aes32dsmi , self , round_key)
148
150
}
149
151
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` )
151
153
#[ inline]
152
154
pub fn dec ( self , round_key : Self ) -> Self {
153
155
self . pre_dec ( Self :: zero ( ) ) ^ round_key
154
156
}
155
157
156
158
#[ inline( always) ]
157
159
pub ( crate ) fn pre_dec_last ( self , round_key : Self ) -> Self {
158
- outer ! ( aes32ds , self , round_key)
160
+ outer ! ( aes32dsi , self , round_key)
159
161
}
160
162
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` )
162
164
#[ inline]
163
165
pub fn dec_last ( self , round_key : Self ) -> Self {
164
166
self . pre_dec_last ( Self :: zero ( ) ) ^ round_key
165
167
}
166
168
167
- /// Performs the MixColumns operation
169
+ /// Performs the ` MixColumns` operation
168
170
#[ inline]
169
171
pub fn mc ( self ) -> Self {
170
172
self . pre_dec_last ( Self :: zero ( ) ) . enc ( Self :: zero ( ) )
171
173
}
172
174
173
- /// Performs the InvMixColumns operation
175
+ /// Performs the `InvMixColumn`s operation
174
176
#[ inline]
175
177
pub fn imc ( self ) -> Self {
176
178
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
183
185
fn sub_word ( xor : u32 , word : u32 ) -> u32 {
184
186
let mut value = xor;
185
187
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 ) ;
190
192
}
191
193
value
192
194
}
0 commit comments