diff --git a/Cargo.toml b/Cargo.toml index 4653b04..cd57d99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,9 @@ default-features = false default-features = false version = "0.2" +[dependencies.clear_on_drop] +version = "0.2" + [dev-dependencies] criterion = "0.2" rand = "0.5" @@ -38,6 +41,6 @@ harness = false [features] default = ["std", "nightly", "u64_backend"] std = ["curve25519-dalek/std"] -nightly = ["curve25519-dalek/nightly"] +nightly = ["curve25519-dalek/nightly", "clear_on_drop/nightly"] u64_backend = ["curve25519-dalek/u64_backend"] u32_backend = ["curve25519-dalek/u32_backend"] diff --git a/src/lib.rs b/src/lib.rs index 8119480..1dabcaa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,6 +126,8 @@ #![cfg_attr(feature = "bench", feature(test))] #![deny(missing_docs)] +extern crate clear_on_drop; + extern crate curve25519_dalek; extern crate rand_core; diff --git a/src/x25519.rs b/src/x25519.rs index 921b454..ccbcbcd 100644 --- a/src/x25519.rs +++ b/src/x25519.rs @@ -12,6 +12,10 @@ //! This implements x25519 key exchange as specified by Mike Hamburg //! and Adam Langley in [RFC7748](https://tools.ietf.org/html/rfc7748). +use core::fmt::{Debug}; + +use clear_on_drop::clear::Clear; + use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::scalar::Scalar; @@ -19,6 +23,26 @@ use curve25519_dalek::scalar::Scalar; use rand_core::RngCore; use rand_core::CryptoRng; +/// The length of a curve25519 EdDSA `SecretKey`, in bytes. +pub const SECRET_KEY_LENGTH: usize = 32; + +/// An EdDSA secret key. +#[repr(C)] +#[derive(Default)] // we derive Default in order to use the clear() method in Drop +pub struct SecretKey(pub (crate) [u8; SECRET_KEY_LENGTH]); + +impl Debug for SecretKey { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "SecretKey: {:?}", &self.0[..]) + } +} + +/// Overwrite secret key material with null bytes when it goes out of scope. +impl Drop for SecretKey { + fn drop(&mut self) { + self.0.clear(); + } +} /// "Decode" a scalar from a 32-byte array. /// /// By "decode" here, what is really meant is applying key clamping by twiddling