Merge pull request #126 from poanetwork/remove-clear-on-drop

Replaced clear-on-drop with 'std::ptr::write_volatile'.
This commit is contained in:
Andreas Fackler 2018-07-15 10:44:59 +02:00 committed by GitHub
commit 70e8fedb15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 32 deletions

View File

@ -19,7 +19,6 @@ travis-ci = { repository = "poanetwork/hbbft" }
[dependencies] [dependencies]
bincode = "1.0.0" bincode = "1.0.0"
byteorder = "1.2.3" byteorder = "1.2.3"
clear_on_drop = "0.2.3"
derive_deref = "1.0.1" derive_deref = "1.0.1"
env_logger = "0.5.10" env_logger = "0.5.10"
error-chain = "0.11.0" error-chain = "0.11.0"

View File

@ -44,12 +44,10 @@
//! ## Example usage //! ## Example usage
//! //!
//! ```rust //! ```rust
//!# extern crate clear_on_drop;
//!# extern crate hbbft; //!# extern crate hbbft;
//!# extern crate rand; //!# extern crate rand;
//!# fn main() { //!# fn main() {
//!# //!#
//! use clear_on_drop::ClearOnDrop;
//! use hbbft::broadcast::Broadcast; //! use hbbft::broadcast::Broadcast;
//! use hbbft::crypto::SecretKeySet; //! use hbbft::crypto::SecretKeySet;
//! use hbbft::messaging::{DistAlgorithm, NetworkInfo, Target, TargetedMessage}; //! use hbbft::messaging::{DistAlgorithm, NetworkInfo, Target, TargetedMessage};

View File

@ -10,9 +10,9 @@ pub mod serde_impl;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ptr::write_volatile;
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use clear_on_drop::ClearOnDrop;
use init_with::InitWith; use init_with::InitWith;
use pairing::bls12_381::{Bls12, Fr, FrRepr, G1, G1Affine, G2, G2Affine}; use pairing::bls12_381::{Bls12, Fr, FrRepr, G1, G1Affine, G2, G2Affine};
use pairing::{CurveAffine, CurveProjective, Engine, Field, PrimeField}; use pairing::{CurveAffine, CurveProjective, Engine, Field, PrimeField};
@ -130,6 +130,15 @@ impl Default for SecretKey {
} }
} }
impl Drop for SecretKey {
fn drop(&mut self) {
let ptr = self as *mut Self;
unsafe {
write_volatile(ptr, SecretKey::default());
}
}
}
impl SecretKey { impl SecretKey {
/// Creates a secret key from an existing value /// Creates a secret key from an existing value
pub fn from_value(f: Fr) -> Self { pub fn from_value(f: Fr) -> Self {
@ -295,10 +304,8 @@ impl SecretKeySet {
} }
/// Returns the `i`-th secret key share. /// Returns the `i`-th secret key share.
pub fn secret_key_share<T: Into<FrRepr>>(&self, i: T) -> ClearOnDrop<Box<SecretKey>> { pub fn secret_key_share<T: Into<FrRepr>>(&self, i: T) -> SecretKey {
ClearOnDrop::new(Box::new(SecretKey( SecretKey(self.poly.evaluate(from_repr_plus_1::<Fr>(i.into())))
self.poly.evaluate(from_repr_plus_1::<Fr>(i.into())),
)))
} }
/// Returns the corresponding public key set. That information can be shared publicly. /// Returns the corresponding public key set. That information can be shared publicly.
@ -428,9 +435,9 @@ mod tests {
assert_ne!(pk_set.public_key(), pk_set.public_key_share(2)); assert_ne!(pk_set.public_key(), pk_set.public_key_share(2));
// Make sure we don't hand out the main secret key to anyone. // Make sure we don't hand out the main secret key to anyone.
assert_ne!(sk_set.secret_key(), *sk_set.secret_key_share(0)); assert_ne!(sk_set.secret_key(), sk_set.secret_key_share(0));
assert_ne!(sk_set.secret_key(), *sk_set.secret_key_share(1)); assert_ne!(sk_set.secret_key(), sk_set.secret_key_share(1));
assert_ne!(sk_set.secret_key(), *sk_set.secret_key_share(2)); assert_ne!(sk_set.secret_key(), sk_set.secret_key_share(2));
let msg = "Totally real news"; let msg = "Totally real news";

View File

@ -52,7 +52,6 @@ use std::mem;
use std::sync::Arc; use std::sync::Arc;
use bincode; use bincode;
use clear_on_drop::ClearOnDrop;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use self::votes::{SignedVote, VoteCounter}; use self::votes::{SignedVote, VoteCounter};
@ -73,7 +72,7 @@ mod change;
mod error; mod error;
mod votes; mod votes;
type KeyGenOutput = (PublicKeySet, Option<ClearOnDrop<Box<SecretKey>>>); type KeyGenOutput = (PublicKeySet, Option<SecretKey>);
/// The user input for `DynamicHoneyBadger`. /// The user input for `DynamicHoneyBadger`.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -283,9 +282,7 @@ where
// If DKG completed, apply the change. // If DKG completed, apply the change.
debug!("{:?} DKG for {:?} complete!", self.our_id(), change); debug!("{:?} DKG for {:?} complete!", self.our_id(), change);
// If we are a validator, we received a new secret key. Otherwise keep the old one. // If we are a validator, we received a new secret key. Otherwise keep the old one.
let sk = sk.unwrap_or_else(|| { let sk = sk.unwrap_or_else(|| self.netinfo.secret_key().clone());
ClearOnDrop::new(Box::new(self.netinfo.secret_key().clone()))
});
// Restart Honey Badger in the next epoch, and inform the user about the change. // Restart Honey Badger in the next epoch, and inform the user about the change.
self.apply_change(&change, pub_key_set, sk, batch.epoch + 1)?; self.apply_change(&change, pub_key_set, sk, batch.epoch + 1)?;
batch.change = ChangeState::Complete(change); batch.change = ChangeState::Complete(change);
@ -316,7 +313,7 @@ where
&mut self, &mut self,
change: &Change<NodeUid>, change: &Change<NodeUid>,
pub_key_set: PublicKeySet, pub_key_set: PublicKeySet,
sk: ClearOnDrop<Box<SecretKey>>, sk: SecretKey,
epoch: u64, epoch: u64,
) -> Result<()> { ) -> Result<()> {
self.key_gen = None; self.key_gen = None;

View File

@ -100,7 +100,6 @@
extern crate bincode; extern crate bincode;
extern crate byteorder; extern crate byteorder;
extern crate clear_on_drop;
#[macro_use(Deref, DerefMut)] #[macro_use(Deref, DerefMut)]
extern crate derive_deref; extern crate derive_deref;
#[macro_use] #[macro_use]

View File

@ -1,8 +1,6 @@
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Debug; use std::fmt::Debug;
use clear_on_drop::ClearOnDrop;
use crypto::{PublicKey, PublicKeySet, SecretKey}; use crypto::{PublicKey, PublicKeySet, SecretKey};
use fault_log::FaultLog; use fault_log::FaultLog;
@ -131,12 +129,6 @@ impl<'a, D: DistAlgorithm + 'a> Iterator for OutputIter<'a, D> {
} }
/// Common data shared between algorithms. /// Common data shared between algorithms.
///
/// *NOTE* `NetworkInfo` requires its `secret_key` to be heap allocated and
/// wrapped by the `ClearOnDrop` type from the `clear_on_drop` crate. We
/// use this construction to zero out the section of heap memory that is
/// allocated for `secret_key` when the corresponding instance of
/// `NetworkInfo` goes out of scope.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct NetworkInfo<NodeUid> { pub struct NetworkInfo<NodeUid> {
our_uid: NodeUid, our_uid: NodeUid,
@ -144,7 +136,7 @@ pub struct NetworkInfo<NodeUid> {
num_nodes: usize, num_nodes: usize,
num_faulty: usize, num_faulty: usize,
is_validator: bool, is_validator: bool,
secret_key: ClearOnDrop<Box<SecretKey>>, secret_key: SecretKey,
public_key_set: PublicKeySet, public_key_set: PublicKeySet,
public_keys: BTreeMap<NodeUid, PublicKey>, public_keys: BTreeMap<NodeUid, PublicKey>,
node_indices: BTreeMap<NodeUid, usize>, node_indices: BTreeMap<NodeUid, usize>,
@ -154,7 +146,7 @@ impl<NodeUid: Clone + Ord> NetworkInfo<NodeUid> {
pub fn new( pub fn new(
our_uid: NodeUid, our_uid: NodeUid,
all_uids: BTreeSet<NodeUid>, all_uids: BTreeSet<NodeUid>,
secret_key: ClearOnDrop<Box<SecretKey>>, secret_key: SecretKey,
public_key_set: PublicKeySet, public_key_set: PublicKeySet,
) -> Self { ) -> Self {
let num_nodes = all_uids.len(); let num_nodes = all_uids.len();

View File

@ -37,7 +37,6 @@ use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
use bincode; use bincode;
use clear_on_drop::ClearOnDrop;
use pairing::bls12_381::{Fr, G1Affine}; use pairing::bls12_381::{Fr, G1Affine};
use pairing::{CurveAffine, Field}; use pairing::{CurveAffine, Field};
use rand::OsRng; use rand::OsRng;
@ -238,7 +237,7 @@ impl<NodeUid: Ord + Clone + Debug> SyncKeyGen<NodeUid> {
/// ///
/// These are only secure if `is_ready` returned `true`. Otherwise it is not guaranteed that /// These are only secure if `is_ready` returned `true`. Otherwise it is not guaranteed that
/// none of the nodes knows the secret master key. /// none of the nodes knows the secret master key.
pub fn generate(&self) -> (PublicKeySet, Option<ClearOnDrop<Box<SecretKey>>>) { pub fn generate(&self) -> (PublicKeySet, Option<SecretKey>) {
let mut pk_commit = Poly::zero().commitment(); let mut pk_commit = Poly::zero().commitment();
let mut opt_sk_val = self.our_idx.map(|_| Fr::zero()); let mut opt_sk_val = self.our_idx.map(|_| Fr::zero());
let is_complete = |proposal: &&ProposalState| proposal.is_complete(self.threshold); let is_complete = |proposal: &&ProposalState| proposal.is_complete(self.threshold);
@ -249,8 +248,7 @@ impl<NodeUid: Ord + Clone + Debug> SyncKeyGen<NodeUid> {
sk_val.add_assign(&row.evaluate(0)); sk_val.add_assign(&row.evaluate(0));
} }
} }
let opt_sk = let opt_sk = opt_sk_val.map(SecretKey::from_value);
opt_sk_val.map(|sk_val| ClearOnDrop::new(Box::new(SecretKey::from_value(sk_val))));
(pk_commit.into(), opt_sk) (pk_commit.into(), opt_sk)
} }