replace memzero with zeroize crate (#10816)
* [whisper] replace memzero with zeroize * [ethkey] replace memzero with zeroize
This commit is contained in:
committed by
Marek Kotewicz
parent
bd9a8aa22b
commit
cd088a4345
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ 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))
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ impl EncryptionInstance {
|
||||
///
|
||||
/// 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)))
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
|
||||
@@ -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..]))
|
||||
@@ -187,6 +187,7 @@ impl DecryptionInstance {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rand::{Rng, rngs::OsRng};
|
||||
use std::ops::Deref;
|
||||
|
||||
|
||||
#[test]
|
||||
@@ -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() {
|
||||
@@ -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();
|
||||
|
||||
@@ -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};
|
||||
@@ -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 {
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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")
|
||||
})
|
||||
}
|
||||
@@ -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())),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user