Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zeroize: Add ZeroizeOnDrop marker trait + custom derive #168

Merged
merged 1 commit into from
Mar 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion zeroize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! ## Usage
//!
//! ```
//! extern crate zeroize;
//! use zeroize::Zeroize;
//!
//! fn main() {
Expand Down Expand Up @@ -32,6 +31,33 @@
//! impl [Default], which implements [Zeroize] by overwriting a value with
//! the default value.
//!
//! ## Custom Derive Support
//!
//! This crate has custom derive support for the `Zeroize` trait, which
//! automatically calls `zeroize()` on all members of a struct or tuple struct:
//!
//! ```
//! // Ensure you import the crate with `macro_use`:
//! // #[macro_use]
//! // extern crate zeroize;
//!
//! use zeroize::Zeroize;
//!
//! #[derive(Zeroize)]
//! struct MyStruct([u8; 64]);
//! ```
//!
//! Additionally, you can derive `ZeroizeOnDrop`, which will automatically
//! derive a `Drop` handler that calls `zeroize()`:
//!
//! ```
//! use zeroize::{Zeroize, ZeroizeOnDrop};
//!
//! // This struct will be zeroized on drop
//! #[derive(Zeroize, ZeroizeOnDrop)]
//! struct MyStruct([u8; 64]);
//! ```
//!
//! ## About
//!
//! [Zeroing memory securely is hard] - compilers optimize for performance, and
Expand Down Expand Up @@ -235,6 +261,13 @@ pub trait Zeroize {
/// Marker trait for types whose `Default` is the desired zeroization result
pub trait DefaultIsZeroes: Copy + Default + Sized {}

/// Marker trait intended for use with `zeroize_derive` which indicates that
/// a type should have a drop handler which calls Zeroize.
///
/// Use `#[derive(ZeroizeOnDrop)]` to automatically impl this trait and an
/// associated drop handler.
pub trait ZeroizeOnDrop: Zeroize + Drop {}

impl<Z> Zeroize for Z
where
Z: DefaultIsZeroes,
Expand Down
21 changes: 20 additions & 1 deletion zeroize_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ macro_rules! q {
}

#[proc_macro_derive(Zeroize)]
pub fn derive(input: TokenStream) -> TokenStream {
pub fn derive_zeroize(input: TokenStream) -> TokenStream {
let ast: syn::DeriveInput = syn::parse(input).unwrap();

let zeroizers = match ast.data {
Expand All @@ -38,6 +38,25 @@ pub fn derive(input: TokenStream) -> TokenStream {
zeroize_impl.into()
}

#[proc_macro_derive(ZeroizeOnDrop)]
pub fn derive_zeroize_on_drop(input: TokenStream) -> TokenStream {
let ast: syn::DeriveInput = syn::parse(input).unwrap();
let name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();

let zeroize_on_drop_impl = q! {
impl #impl_generics Drop for #name #ty_generics #where_clause {
fn drop(&mut self) {
self.zeroize();
}
}

impl #impl_generics ZeroizeOnDrop for #name #ty_generics #where_clause {}
};

zeroize_on_drop_impl.into()
}

fn derive_struct_zeroizers(fields: &syn::Fields) -> proc_macro2::TokenStream {
let self_ident = syn::Ident::new("self", proc_macro2::Span::call_site());

Expand Down