Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

replace memzero with zeroize crate #10816

Merged
merged 2 commits into from
Jun 29, 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
24 changes: 23 additions & 1 deletion 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 accounts/ethkey/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
ethereum-types = "0.6.0"
lazy_static = "1.0"
log = "0.4"
parity-util-mem = "0.1"
parity-wordlist = "1.2"
quick-error = "1.2.2"
rand = "0.6"
rustc-hex = "1.0"
serde = "1.0"
serde_derive = "1.0"
tiny-keccak = "1.4"
zeroize = "0.9.1"
2 changes: 1 addition & 1 deletion accounts/ethkey/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
extern crate edit_distance;
extern crate parity_crypto;
extern crate ethereum_types;
extern crate parity_util_mem;
extern crate parity_wordlist;
#[macro_use]
extern crate quick_error;
Expand All @@ -28,6 +27,7 @@ extern crate rustc_hex;
extern crate secp256k1;
extern crate serde;
extern crate tiny_keccak;
extern crate zeroize;

#[macro_use]
extern crate lazy_static;
Expand Down
18 changes: 12 additions & 6 deletions accounts/ethkey/src/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,23 @@ use rustc_hex::ToHex;
use secp256k1::constants::{SECRET_KEY_SIZE as SECP256K1_SECRET_KEY_SIZE};
use secp256k1::key;
use ethereum_types::H256;
use parity_util_mem::Memzero;
use zeroize::Zeroize;
use {Error, SECP256K1};

#[derive(Clone, PartialEq, Eq)]
pub struct Secret {
inner: Memzero<H256>,
inner: H256,
}

impl Drop for Secret {
fn drop(&mut self) {
self.inner.0.zeroize()
}
}

impl ToHex for Secret {
fn to_hex(&self) -> String {
format!("{:x}", *self.inner)
format!("{:x}", self.inner)
}
}

Expand Down Expand Up @@ -61,12 +67,12 @@ impl Secret {
}
let mut h = H256::zero();
h.as_bytes_mut().copy_from_slice(&key[0..32]);
Some(Secret { inner: Memzero::from(h) })
Some(Secret { inner: h })
}

/// Creates zero key, which is invalid for crypto operations, but valid for math operation.
pub fn zero() -> Self {
Secret { inner: Memzero::from(H256::zero()) }
Secret { inner: H256::zero() }
}

/// Imports and validates the key.
Expand Down Expand Up @@ -214,7 +220,7 @@ impl FromStr for Secret {

impl From<[u8; 32]> for Secret {
fn from(k: [u8; 32]) -> Self {
Secret { inner: Memzero::from(H256(k)) }
Secret { inner: H256(k) }
}
}

Expand Down
1 change: 1 addition & 0 deletions whisper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ time-utils = { path = "../util/time-utils" }
jsonrpc-core = "10.0.1"
jsonrpc-derive = "10.0.2"
jsonrpc-pubsub = "10.0.1"
zeroize = "0.9.1"
1 change: 1 addition & 0 deletions whisper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern crate serde;
extern crate slab;
extern crate smallvec;
extern crate tiny_keccak;
extern crate zeroize;

extern crate jsonrpc_core;
extern crate jsonrpc_derive;
Expand Down
21 changes: 11 additions & 10 deletions whisper/src/rpc/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use aes_gcm::{Encryptor, Decryptor};
use ethkey::crypto::ecies;
use ethereum_types::H256;
use ethkey::{self, Public, Secret};
use parity_util_mem::Memzero;
use zeroize::Zeroizing;

/// Length of AES key
pub const AES_KEY_LEN: usize = 32;
Expand All @@ -37,7 +37,7 @@ enum AesEncode {
}

enum EncryptionInner {
AES(Memzero<[u8; AES_KEY_LEN]>, [u8; AES_NONCE_LEN], AesEncode),
AES(Zeroizing<[u8; AES_KEY_LEN]>, [u8; AES_NONCE_LEN], AesEncode),
ECIES(Public),
}

Expand All @@ -59,15 +59,15 @@ impl EncryptionInstance {
///
/// If generating nonces with a secure RNG, limit uses such that
/// the chance of collision is negligible.
pub fn aes(key: Memzero<[u8; AES_KEY_LEN]>, nonce: [u8; AES_NONCE_LEN]) -> Self {
pub fn aes(key: Zeroizing<[u8; AES_KEY_LEN]>, nonce: [u8; AES_NONCE_LEN]) -> Self {
EncryptionInstance(EncryptionInner::AES(key, nonce, AesEncode::AppendedNonce))
}

/// Broadcast encryption for the message based on the given topics.
///
/// Key reuse here is extremely dangerous. It should be randomly generated
/// with a secure RNG.
pub fn broadcast(key: Memzero<[u8; AES_KEY_LEN]>, topics: Vec<H256>) -> Self {
pub fn broadcast(key: Zeroizing<[u8; AES_KEY_LEN]>, topics: Vec<H256>) -> Self {
EncryptionInstance(EncryptionInner::AES(key, BROADCAST_IV, AesEncode::OnTopics(topics)))
}

Expand Down Expand Up @@ -111,7 +111,7 @@ fn xor(a: &mut [u8; 32], b: &[u8; 32]) {
}

enum AesExtract {
AppendedNonce(Memzero<[u8; AES_KEY_LEN]>), // extract appended nonce.
AppendedNonce(Zeroizing<[u8; AES_KEY_LEN]>), // extract appended nonce.
OnTopics(usize, usize, H256), // number of topics, index we know, topic we know.
}

Expand All @@ -132,7 +132,7 @@ impl DecryptionInstance {
}

/// 256-bit AES GCM decryption with appended nonce.
pub fn aes(key: Memzero<[u8; AES_KEY_LEN]>) -> Self {
pub fn aes(key: Zeroizing<[u8; AES_KEY_LEN]>) -> Self {
DecryptionInstance(DecryptionInner::AES(AesExtract::AppendedNonce(key)))
}

Expand Down Expand Up @@ -167,7 +167,7 @@ impl DecryptionInstance {
}
let mut salted_topic = H256::zero();
salted_topic.as_bytes_mut().copy_from_slice(&ciphertext[(known_index * 32)..][..32]);
let key = Memzero::from((salted_topic ^ known_topic).0);
let key = Zeroizing::new((salted_topic ^ known_topic).0);
let offset = num_topics * 32;
Decryptor::aes_256_gcm(&*key).ok()?
.decrypt(&BROADCAST_IV, Vec::from(&ciphertext[offset..]))
Expand All @@ -187,6 +187,7 @@ impl DecryptionInstance {
mod tests {
use super::*;
use rand::{Rng, rngs::OsRng};
use std::ops::Deref;


#[test]
Expand Down Expand Up @@ -217,9 +218,9 @@ mod tests {
fn encrypt_symmetric() {
let mut rng = OsRng::new().unwrap();
let mut test_message = move |message: &[u8]| {
let key = Memzero::from(rng.gen::<[u8; 32]>());
let key = Zeroizing::new(rng.gen::<[u8; 32]>());

let instance = EncryptionInstance::aes(key.clone(), rng.gen());
let instance = EncryptionInstance::aes(Zeroizing::new(*key.deref()), rng.gen());
let ciphertext = instance.encrypt(message).unwrap();

if !message.is_empty() {
Expand All @@ -245,7 +246,7 @@ mod tests {
let all_topics = (0..5).map(|_| H256::random_using(&mut rng)).collect::<Vec<_>>();
let known_idx = 2;
let known_topic = all_topics[2];
let key = Memzero::from(rng.gen::<[u8; 32]>());
let key = Zeroizing::new(rng.gen::<[u8; 32]>());

let instance = EncryptionInstance::broadcast(key, all_topics);
let ciphertext = instance.encrypt(message).unwrap();
Expand Down
13 changes: 7 additions & 6 deletions whisper/src/rpc/key_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use std::collections::HashMap;

use ethereum_types::H256;
use ethkey::{KeyPair, Public, Secret};
use parity_util_mem::Memzero;
use zeroize::Zeroizing;
use std::ops::Deref;
use rand::{Rng, rngs::OsRng};

use rpc::crypto::{AES_KEY_LEN, EncryptionInstance, DecryptionInstance};
Expand All @@ -35,7 +36,7 @@ pub enum Key {
/// and signing.
Asymmetric(KeyPair),
/// AES-256 GCM mode. Suitable for encryption, decryption, but not signing.
Symmetric(Memzero<[u8; AES_KEY_LEN]>),
Symmetric(Zeroizing<[u8; AES_KEY_LEN]>),
}

impl Key {
Expand All @@ -49,7 +50,7 @@ impl Key {

/// Generate a random symmetric key with the given cryptographic RNG.
pub fn new_symmetric(rng: &mut OsRng) -> Self {
Key::Symmetric(Memzero::from(rng.gen::<[u8; 32]>()))
Key::Symmetric(Zeroizing::new(rng.gen::<[u8; 32]>()))
}

/// From secret asymmetric key. Fails if secret is invalid.
Expand All @@ -59,7 +60,7 @@ impl Key {

/// From raw symmetric key.
pub fn from_raw_symmetric(key: [u8; AES_KEY_LEN]) -> Self {
Key::Symmetric(Memzero::from(key))
Key::Symmetric(Zeroizing::new(key))
}

/// Get a handle to the public key if this is an asymmetric key.
Expand Down Expand Up @@ -138,7 +139,7 @@ impl KeyStore {
.map_err(|_| "could not create encryption instance for id"),
Key::Symmetric(ref key) =>
OsRng::new()
.map(|mut rng| EncryptionInstance::aes(key.clone(), rng.gen()))
.map(|mut rng| EncryptionInstance::aes(Zeroizing::new(*key.deref()), rng.gen()))
.map_err(|_| "unable to get secure randomness")
})
}
Expand All @@ -149,7 +150,7 @@ impl KeyStore {
self.get(id).map(|key| match *key {
Key::Asymmetric(ref pair) => DecryptionInstance::ecies(pair.secret().clone())
.expect("all keys stored are valid; qed"),
Key::Symmetric(ref key) => DecryptionInstance::aes(key.clone()),
Key::Symmetric(ref key) => DecryptionInstance::aes(Zeroizing::new(*key.deref())),
})
}

Expand Down
4 changes: 2 additions & 2 deletions whisper/src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use jsonrpc_derive::rpc;
use jsonrpc_pubsub::{Session, PubSubMetadata, SubscriptionId, typed::Subscriber};

use ethereum_types::H256;
use parity_util_mem::Memzero;
use zeroize::Zeroizing;
use parking_lot::RwLock;

use self::filter::Filter;
Expand Down Expand Up @@ -284,7 +284,7 @@ impl<P: PoolHandle + 'static, M: Send + Sync + 'static> Whisper for WhisperClien
let mut rng = OsRng::new()
.map_err(|_| whisper_error("unable to acquire secure randomness"))?;

let key = Memzero::from(rng.gen::<[u8; 32]>());
let key = Zeroizing::new(rng.gen::<[u8; 32]>());
if req.topics.is_empty() {
return Err(whisper_error("must supply at least one topic for broadcast message"));
}
Expand Down