Skip to content

Commit ca6a657

Browse files
authored
aes: implement ZeroizeOnDrop for aes keys (#310)
1 parent 7fcdd7c commit ca6a657

File tree

7 files changed

+187
-3
lines changed

7 files changed

+187
-3
lines changed

Cargo.lock

+3-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aes/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ categories = ["cryptography", "no-std"]
1515
[dependencies]
1616
cfg-if = "1"
1717
cipher = "0.4.2"
18+
zeroize = { version = "1.5.4", optional = true, default_features = false }
1819

1920
[target.'cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))'.dependencies]
2021
cpufeatures = "0.2"
@@ -25,7 +26,6 @@ hex-literal = "0.3"
2526

2627
[features]
2728
hazmat = [] # Expose cryptographically hazardous APIs
28-
zeroize = ["cipher/zeroize"]
2929

3030
[package.metadata.docs.rs]
3131
all-features = true

aes/src/armv8.rs

+25
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ macro_rules! define_aes_impl {
122122
}
123123
}
124124

125+
#[cfg(feature = "zeroize")]
126+
impl zeroize::ZeroizeOnDrop for $name {}
127+
125128
#[doc=$doc]
126129
#[doc = "block cipher (encrypt-only)"]
127130
#[derive(Clone)]
@@ -172,6 +175,17 @@ macro_rules! define_aes_impl {
172175
}
173176
}
174177

178+
impl Drop for $name_enc {
179+
#[inline]
180+
fn drop(&mut self) {
181+
#[cfg(feature = "zeroize")]
182+
zeroize::Zeroize::zeroize(&mut self.round_keys);
183+
}
184+
}
185+
186+
#[cfg(feature = "zeroize")]
187+
impl zeroize::ZeroizeOnDrop for $name_enc {}
188+
175189
#[doc=$doc]
176190
#[doc = "block cipher (decrypt-only)"]
177191
#[derive(Clone)]
@@ -235,6 +249,17 @@ macro_rules! define_aes_impl {
235249
}
236250
}
237251

252+
impl Drop for $name_dec {
253+
#[inline]
254+
fn drop(&mut self) {
255+
#[cfg(feature = "zeroize")]
256+
zeroize::Zeroize::zeroize(&mut self.round_keys);
257+
}
258+
}
259+
260+
#[cfg(feature = "zeroize")]
261+
impl zeroize::ZeroizeOnDrop for $name_dec {}
262+
238263
pub(crate) struct $name_back_enc<'a>(&'a $name_enc);
239264

240265
impl<'a> BlockSizeUser for $name_back_enc<'a> {

aes/src/autodetect.rs

+42
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,20 @@ macro_rules! define_aes_impl {
180180
}
181181
}
182182

183+
impl Drop for $name {
184+
#[inline]
185+
fn drop(&mut self) {
186+
if self.token.get() {
187+
unsafe { ManuallyDrop::drop(&mut self.inner.intrinsics) };
188+
} else {
189+
unsafe { ManuallyDrop::drop(&mut self.inner.soft) };
190+
};
191+
}
192+
}
193+
194+
#[cfg(feature = "zeroize")]
195+
impl zeroize::ZeroizeOnDrop for $name {}
196+
183197
#[doc=$doc]
184198
#[doc = "block cipher (encrypt-only)"]
185199
pub struct $name_enc {
@@ -266,6 +280,20 @@ macro_rules! define_aes_impl {
266280
}
267281
}
268282

283+
impl Drop for $name_enc {
284+
#[inline]
285+
fn drop(&mut self) {
286+
if self.token.get() {
287+
unsafe { ManuallyDrop::drop(&mut self.inner.intrinsics) };
288+
} else {
289+
unsafe { ManuallyDrop::drop(&mut self.inner.soft) };
290+
};
291+
}
292+
}
293+
294+
#[cfg(feature = "zeroize")]
295+
impl zeroize::ZeroizeOnDrop for $name_enc {}
296+
269297
#[doc=$doc]
270298
#[doc = "block cipher (decrypt-only)"]
271299
pub struct $name_dec {
@@ -380,6 +408,20 @@ macro_rules! define_aes_impl {
380408
f.write_str(stringify!($name_dec))
381409
}
382410
}
411+
412+
impl Drop for $name_dec {
413+
#[inline]
414+
fn drop(&mut self) {
415+
if self.token.get() {
416+
unsafe { ManuallyDrop::drop(&mut self.inner.intrinsics) };
417+
} else {
418+
unsafe { ManuallyDrop::drop(&mut self.inner.soft) };
419+
};
420+
}
421+
}
422+
423+
#[cfg(feature = "zeroize")]
424+
impl zeroize::ZeroizeOnDrop for $name_dec {}
383425
};
384426
}
385427

aes/src/lib.rs

+74
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,77 @@ use cipher::{
159159
pub type Block = GenericArray<u8, U16>;
160160
/// Eight 128-bit AES blocks
161161
pub type Block8 = GenericArray<Block, U8>;
162+
163+
#[cfg(test)]
164+
mod tests {
165+
#[cfg(feature = "zeroize")]
166+
#[test]
167+
fn zeroize_works() {
168+
use super::soft;
169+
170+
fn test_for<T: zeroize::ZeroizeOnDrop>(val: T) {
171+
use core::mem::{size_of, ManuallyDrop};
172+
173+
let mut val = ManuallyDrop::new(val);
174+
let ptr = &val as *const _ as *const u8;
175+
let len = size_of::<ManuallyDrop<T>>();
176+
177+
unsafe { ManuallyDrop::drop(&mut val) };
178+
179+
let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
180+
181+
assert!(slice.iter().all(|&byte| byte == 0));
182+
}
183+
184+
let key_128 = [42; 16].into();
185+
let key_192 = [42; 24].into();
186+
let key_256 = [42; 32].into();
187+
188+
use cipher::KeyInit as _;
189+
test_for(soft::Aes128::new(&key_128));
190+
test_for(soft::Aes128Enc::new(&key_128));
191+
test_for(soft::Aes128Dec::new(&key_128));
192+
test_for(soft::Aes192::new(&key_192));
193+
test_for(soft::Aes192Enc::new(&key_192));
194+
test_for(soft::Aes192Dec::new(&key_192));
195+
test_for(soft::Aes256::new(&key_256));
196+
test_for(soft::Aes256Enc::new(&key_256));
197+
test_for(soft::Aes256Dec::new(&key_256));
198+
199+
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(aes_force_soft)))]
200+
{
201+
use super::ni;
202+
203+
cpufeatures::new!(aes_intrinsics, "aes");
204+
if aes_intrinsics::get() {
205+
test_for(ni::Aes128::new(&key_128));
206+
test_for(ni::Aes128Enc::new(&key_128));
207+
test_for(ni::Aes128Dec::new(&key_128));
208+
test_for(ni::Aes192::new(&key_192));
209+
test_for(ni::Aes192Enc::new(&key_192));
210+
test_for(ni::Aes192Dec::new(&key_192));
211+
test_for(ni::Aes256::new(&key_256));
212+
test_for(ni::Aes256Enc::new(&key_256));
213+
test_for(ni::Aes256Dec::new(&key_256));
214+
}
215+
}
216+
217+
#[cfg(all(target_arch = "aarch64", aes_armv8, not(aes_force_soft)))]
218+
{
219+
use super::armv8;
220+
221+
cpufeatures::new!(aes_intrinsics, "aes");
222+
if aes_intrinsics::get() {
223+
test_for(armv8::Aes128::new(&key_128));
224+
test_for(armv8::Aes128Enc::new(&key_128));
225+
test_for(armv8::Aes128Dec::new(&key_128));
226+
test_for(armv8::Aes192::new(&key_192));
227+
test_for(armv8::Aes192Enc::new(&key_192));
228+
test_for(armv8::Aes192Dec::new(&key_192));
229+
test_for(armv8::Aes256::new(&key_256));
230+
test_for(armv8::Aes256Enc::new(&key_256));
231+
test_for(armv8::Aes256Dec::new(&key_256));
232+
}
233+
}
234+
}
235+
}

aes/src/ni.rs

+25
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ macro_rules! define_aes_impl {
133133
}
134134
}
135135

136+
#[cfg(feature = "zeroize")]
137+
impl zeroize::ZeroizeOnDrop for $name {}
138+
136139
#[doc=$doc]
137140
#[doc = "block cipher (encrypt-only)"]
138141
#[derive(Clone)]
@@ -185,6 +188,17 @@ macro_rules! define_aes_impl {
185188
}
186189
}
187190

191+
impl Drop for $name_enc {
192+
#[inline]
193+
fn drop(&mut self) {
194+
#[cfg(feature = "zeroize")]
195+
zeroize::Zeroize::zeroize(&mut self.round_keys);
196+
}
197+
}
198+
199+
#[cfg(feature = "zeroize")]
200+
impl zeroize::ZeroizeOnDrop for $name_enc {}
201+
188202
#[doc=$doc]
189203
#[doc = "block cipher (decrypt-only)"]
190204
#[derive(Clone)]
@@ -248,6 +262,17 @@ macro_rules! define_aes_impl {
248262
}
249263
}
250264

265+
impl Drop for $name_dec {
266+
#[inline]
267+
fn drop(&mut self) {
268+
#[cfg(feature = "zeroize")]
269+
zeroize::Zeroize::zeroize(&mut self.round_keys);
270+
}
271+
}
272+
273+
#[cfg(feature = "zeroize")]
274+
impl zeroize::ZeroizeOnDrop for $name_dec {}
275+
251276
pub(crate) struct $name_back_enc<'a>(&'a $name_enc);
252277

253278
impl<'a> BlockSizeUser for $name_back_enc<'a> {

aes/src/soft.rs

+17
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ macro_rules! define_aes_impl {
112112
}
113113
}
114114

115+
impl Drop for $name {
116+
#[inline]
117+
fn drop(&mut self) {
118+
#[cfg(feature = "zeroize")]
119+
zeroize::Zeroize::zeroize(&mut self.keys);
120+
}
121+
}
122+
123+
#[cfg(feature = "zeroize")]
124+
impl zeroize::ZeroizeOnDrop for $name {}
125+
115126
#[doc=$doc]
116127
#[doc = "block cipher (encrypt-only)"]
117128
#[derive(Clone)]
@@ -162,6 +173,9 @@ macro_rules! define_aes_impl {
162173
}
163174
}
164175

176+
#[cfg(feature = "zeroize")]
177+
impl zeroize::ZeroizeOnDrop for $name_enc {}
178+
165179
#[doc=$doc]
166180
#[doc = "block cipher (decrypt-only)"]
167181
#[derive(Clone)]
@@ -228,6 +242,9 @@ macro_rules! define_aes_impl {
228242
}
229243
}
230244

245+
#[cfg(feature = "zeroize")]
246+
impl zeroize::ZeroizeOnDrop for $name_dec {}
247+
231248
pub(crate) struct $name_back_enc<'a>(&'a $name);
232249

233250
impl<'a> BlockSizeUser for $name_back_enc<'a> {

0 commit comments

Comments
 (0)