Skip to content

Commit

Permalink
aes: implement ZeroizeOnDrop for aes keys (#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
aticu committed Mar 18, 2022
1 parent 7fcdd7c commit ca6a657
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion aes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ categories = ["cryptography", "no-std"]
[dependencies]
cfg-if = "1"
cipher = "0.4.2"
zeroize = { version = "1.5.4", optional = true, default_features = false }

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

[features]
hazmat = [] # Expose cryptographically hazardous APIs
zeroize = ["cipher/zeroize"]

[package.metadata.docs.rs]
all-features = true
Expand Down
25 changes: 25 additions & 0 deletions aes/src/armv8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ macro_rules! define_aes_impl {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name {}

#[doc=$doc]
#[doc = "block cipher (encrypt-only)"]
#[derive(Clone)]
Expand Down Expand Up @@ -172,6 +175,17 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name_enc {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
zeroize::Zeroize::zeroize(&mut self.round_keys);
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_enc {}

#[doc=$doc]
#[doc = "block cipher (decrypt-only)"]
#[derive(Clone)]
Expand Down Expand Up @@ -235,6 +249,17 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name_dec {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
zeroize::Zeroize::zeroize(&mut self.round_keys);
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_dec {}

pub(crate) struct $name_back_enc<'a>(&'a $name_enc);

impl<'a> BlockSizeUser for $name_back_enc<'a> {
Expand Down
42 changes: 42 additions & 0 deletions aes/src/autodetect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,20 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name {
#[inline]
fn drop(&mut self) {
if self.token.get() {
unsafe { ManuallyDrop::drop(&mut self.inner.intrinsics) };
} else {
unsafe { ManuallyDrop::drop(&mut self.inner.soft) };
};
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name {}

#[doc=$doc]
#[doc = "block cipher (encrypt-only)"]
pub struct $name_enc {
Expand Down Expand Up @@ -266,6 +280,20 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name_enc {
#[inline]
fn drop(&mut self) {
if self.token.get() {
unsafe { ManuallyDrop::drop(&mut self.inner.intrinsics) };
} else {
unsafe { ManuallyDrop::drop(&mut self.inner.soft) };
};
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_enc {}

#[doc=$doc]
#[doc = "block cipher (decrypt-only)"]
pub struct $name_dec {
Expand Down Expand Up @@ -380,6 +408,20 @@ macro_rules! define_aes_impl {
f.write_str(stringify!($name_dec))
}
}

impl Drop for $name_dec {
#[inline]
fn drop(&mut self) {
if self.token.get() {
unsafe { ManuallyDrop::drop(&mut self.inner.intrinsics) };
} else {
unsafe { ManuallyDrop::drop(&mut self.inner.soft) };
};
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_dec {}
};
}

Expand Down
74 changes: 74 additions & 0 deletions aes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,77 @@ use cipher::{
pub type Block = GenericArray<u8, U16>;
/// Eight 128-bit AES blocks
pub type Block8 = GenericArray<Block, U8>;

#[cfg(test)]
mod tests {
#[cfg(feature = "zeroize")]
#[test]
fn zeroize_works() {
use super::soft;

fn test_for<T: zeroize::ZeroizeOnDrop>(val: T) {
use core::mem::{size_of, ManuallyDrop};

let mut val = ManuallyDrop::new(val);
let ptr = &val as *const _ as *const u8;
let len = size_of::<ManuallyDrop<T>>();

unsafe { ManuallyDrop::drop(&mut val) };

let slice = unsafe { core::slice::from_raw_parts(ptr, len) };

assert!(slice.iter().all(|&byte| byte == 0));
}

let key_128 = [42; 16].into();
let key_192 = [42; 24].into();
let key_256 = [42; 32].into();

use cipher::KeyInit as _;
test_for(soft::Aes128::new(&key_128));
test_for(soft::Aes128Enc::new(&key_128));
test_for(soft::Aes128Dec::new(&key_128));
test_for(soft::Aes192::new(&key_192));
test_for(soft::Aes192Enc::new(&key_192));
test_for(soft::Aes192Dec::new(&key_192));
test_for(soft::Aes256::new(&key_256));
test_for(soft::Aes256Enc::new(&key_256));
test_for(soft::Aes256Dec::new(&key_256));

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(aes_force_soft)))]
{
use super::ni;

cpufeatures::new!(aes_intrinsics, "aes");
if aes_intrinsics::get() {
test_for(ni::Aes128::new(&key_128));
test_for(ni::Aes128Enc::new(&key_128));
test_for(ni::Aes128Dec::new(&key_128));
test_for(ni::Aes192::new(&key_192));
test_for(ni::Aes192Enc::new(&key_192));
test_for(ni::Aes192Dec::new(&key_192));
test_for(ni::Aes256::new(&key_256));
test_for(ni::Aes256Enc::new(&key_256));
test_for(ni::Aes256Dec::new(&key_256));
}
}

#[cfg(all(target_arch = "aarch64", aes_armv8, not(aes_force_soft)))]
{
use super::armv8;

cpufeatures::new!(aes_intrinsics, "aes");
if aes_intrinsics::get() {
test_for(armv8::Aes128::new(&key_128));
test_for(armv8::Aes128Enc::new(&key_128));
test_for(armv8::Aes128Dec::new(&key_128));
test_for(armv8::Aes192::new(&key_192));
test_for(armv8::Aes192Enc::new(&key_192));
test_for(armv8::Aes192Dec::new(&key_192));
test_for(armv8::Aes256::new(&key_256));
test_for(armv8::Aes256Enc::new(&key_256));
test_for(armv8::Aes256Dec::new(&key_256));
}
}
}
}
25 changes: 25 additions & 0 deletions aes/src/ni.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ macro_rules! define_aes_impl {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name {}

#[doc=$doc]
#[doc = "block cipher (encrypt-only)"]
#[derive(Clone)]
Expand Down Expand Up @@ -185,6 +188,17 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name_enc {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
zeroize::Zeroize::zeroize(&mut self.round_keys);
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_enc {}

#[doc=$doc]
#[doc = "block cipher (decrypt-only)"]
#[derive(Clone)]
Expand Down Expand Up @@ -248,6 +262,17 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name_dec {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
zeroize::Zeroize::zeroize(&mut self.round_keys);
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_dec {}

pub(crate) struct $name_back_enc<'a>(&'a $name_enc);

impl<'a> BlockSizeUser for $name_back_enc<'a> {
Expand Down
17 changes: 17 additions & 0 deletions aes/src/soft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ macro_rules! define_aes_impl {
}
}

impl Drop for $name {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
zeroize::Zeroize::zeroize(&mut self.keys);
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name {}

#[doc=$doc]
#[doc = "block cipher (encrypt-only)"]
#[derive(Clone)]
Expand Down Expand Up @@ -162,6 +173,9 @@ macro_rules! define_aes_impl {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_enc {}

#[doc=$doc]
#[doc = "block cipher (decrypt-only)"]
#[derive(Clone)]
Expand Down Expand Up @@ -228,6 +242,9 @@ macro_rules! define_aes_impl {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for $name_dec {}

pub(crate) struct $name_back_enc<'a>(&'a $name);

impl<'a> BlockSizeUser for $name_back_enc<'a> {
Expand Down

0 comments on commit ca6a657

Please sign in to comment.