mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-07 20:50:39 +00:00
Merge branch 'feature/drop-with-clear' into develop
This commit is contained in:
commit
318898fac1
3 changed files with 46 additions and 4 deletions
|
|
@ -16,7 +16,7 @@ exclude = [ ".gitignore", "TESTVECTORS", "res/*" ]
|
||||||
travis-ci = { repository = "dalek-cryptography/ed25519-dalek", branch = "master"}
|
travis-ci = { repository = "dalek-cryptography/ed25519-dalek", branch = "master"}
|
||||||
|
|
||||||
[dependencies.curve25519-dalek]
|
[dependencies.curve25519-dalek]
|
||||||
version = "0.18"
|
version = "0.19"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[dependencies.rand]
|
[dependencies.rand]
|
||||||
|
|
@ -42,6 +42,9 @@ optional = true
|
||||||
version = "^0.1.1"
|
version = "^0.1.1"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
|
[dependencies.clear_on_drop]
|
||||||
|
version = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = "^0.3"
|
hex = "^0.3"
|
||||||
sha2 = "^0.7"
|
sha2 = "^0.7"
|
||||||
|
|
@ -56,7 +59,7 @@ harness = false
|
||||||
default = ["std", "u64_backend"]
|
default = ["std", "u64_backend"]
|
||||||
# We don't add "rand/std" here because it would enable a bunch of Fuchsia dependencies.
|
# We don't add "rand/std" here because it would enable a bunch of Fuchsia dependencies.
|
||||||
std = ["curve25519-dalek/std"]
|
std = ["curve25519-dalek/std"]
|
||||||
nightly = ["curve25519-dalek/nightly", "rand/nightly"]
|
nightly = ["curve25519-dalek/nightly", "rand/nightly", "clear_on_drop/nightly"]
|
||||||
asm = ["sha2/asm"]
|
asm = ["sha2/asm"]
|
||||||
yolocrypto = ["curve25519-dalek/yolocrypto"]
|
yolocrypto = ["curve25519-dalek/yolocrypto"]
|
||||||
u64_backend = ["curve25519-dalek/u64_backend"]
|
u64_backend = ["curve25519-dalek/u64_backend"]
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
//! A Rust implementation of ed25519 EdDSA key generation, signing, and
|
//! A Rust implementation of ed25519 EdDSA key generation, signing, and
|
||||||
//! verification.
|
//! verification.
|
||||||
|
|
||||||
|
use core::default::Default;
|
||||||
use core::fmt::{Debug};
|
use core::fmt::{Debug};
|
||||||
|
|
||||||
use rand::CryptoRng;
|
use rand::CryptoRng;
|
||||||
|
|
@ -27,6 +28,8 @@ use serde::de::Visitor;
|
||||||
#[cfg(feature = "sha2")]
|
#[cfg(feature = "sha2")]
|
||||||
use sha2::Sha512;
|
use sha2::Sha512;
|
||||||
|
|
||||||
|
use clear_on_drop::clear::Clear;
|
||||||
|
|
||||||
use digest::Digest;
|
use digest::Digest;
|
||||||
|
|
||||||
use generic_array::typenum::U64;
|
use generic_array::typenum::U64;
|
||||||
|
|
@ -165,6 +168,7 @@ impl<'d> Deserialize<'d> for Signature {
|
||||||
|
|
||||||
/// An EdDSA secret key.
|
/// An EdDSA secret key.
|
||||||
#[repr(C)]
|
#[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]);
|
pub struct SecretKey(pub (crate) [u8; SECRET_KEY_LENGTH]);
|
||||||
|
|
||||||
impl Debug for SecretKey {
|
impl Debug for SecretKey {
|
||||||
|
|
@ -173,6 +177,13 @@ impl Debug for SecretKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Overwrite secret key material with null bytes when it goes out of scope.
|
||||||
|
impl Drop for SecretKey {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SecretKey {
|
impl SecretKey {
|
||||||
/// Expand this `SecretKey` into an `ExpandedSecretKey`.
|
/// Expand this `SecretKey` into an `ExpandedSecretKey`.
|
||||||
pub fn expand<D>(&self) -> ExpandedSecretKey where D: Digest<OutputSize = U64> + Default {
|
pub fn expand<D>(&self) -> ExpandedSecretKey where D: Digest<OutputSize = U64> + Default {
|
||||||
|
|
@ -370,11 +381,20 @@ impl<'d> Deserialize<'d> for SecretKey {
|
||||||
// better-designed, Schnorr-based signature scheme, see Trevor Perrin's work on
|
// better-designed, Schnorr-based signature scheme, see Trevor Perrin's work on
|
||||||
// "generalised EdDSA" and "VXEdDSA".
|
// "generalised EdDSA" and "VXEdDSA".
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Default)] // we derive Default in order to use the clear() method in Drop
|
||||||
pub struct ExpandedSecretKey {
|
pub struct ExpandedSecretKey {
|
||||||
pub (crate) key: Scalar,
|
pub (crate) key: Scalar,
|
||||||
pub (crate) nonce: [u8; 32],
|
pub (crate) nonce: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Overwrite secret key material with null bytes when it goes out of scope.
|
||||||
|
impl Drop for ExpandedSecretKey {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.key.clear();
|
||||||
|
self.nonce.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sha2")]
|
#[cfg(feature = "sha2")]
|
||||||
impl<'a> From<&'a SecretKey> for ExpandedSecretKey {
|
impl<'a> From<&'a SecretKey> for ExpandedSecretKey {
|
||||||
/// Construct an `ExpandedSecretKey` from a `SecretKey`.
|
/// Construct an `ExpandedSecretKey` from a `SecretKey`.
|
||||||
|
|
@ -683,7 +703,7 @@ impl<'d> Deserialize<'d> for ExpandedSecretKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An ed25519 public key.
|
/// An ed25519 public key.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Default, Eq, PartialEq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct PublicKey(pub (crate) CompressedEdwardsY);
|
pub struct PublicKey(pub (crate) CompressedEdwardsY);
|
||||||
|
|
||||||
|
|
@ -894,7 +914,7 @@ impl<'d> Deserialize<'d> for PublicKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An ed25519 keypair.
|
/// An ed25519 keypair.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)] // we derive Default in order to use the clear() method in Drop
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Keypair {
|
pub struct Keypair {
|
||||||
/// The secret half of this keypair.
|
/// The secret half of this keypair.
|
||||||
|
|
@ -1416,6 +1436,24 @@ mod test {
|
||||||
175, 002, 026, 104, 247, 007, 081, 026, ]))))
|
175, 002, 026, 104, 247, 007, 081, 026, ]))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn keypair_clear_on_drop() {
|
||||||
|
let mut keypair: Keypair = Keypair::from_bytes(&[15u8; KEYPAIR_LENGTH][..]).unwrap();
|
||||||
|
|
||||||
|
keypair.clear();
|
||||||
|
|
||||||
|
fn as_bytes<T>(x: &T) -> &[u8] {
|
||||||
|
use core::mem;
|
||||||
|
use core::slice;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts(x as *const T as *const u8, mem::size_of_val(x))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(!as_bytes(&keypair).contains(&0x15));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(all(test, feature = "serde"))]
|
#[cfg(all(test, feature = "serde"))]
|
||||||
use bincode::{serialize, deserialize, Infinite};
|
use bincode::{serialize, deserialize, Infinite};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ extern crate generic_array;
|
||||||
extern crate digest;
|
extern crate digest;
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
extern crate clear_on_drop;
|
||||||
|
|
||||||
#[cfg(any(feature = "std", test))]
|
#[cfg(any(feature = "std", test))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue