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

Commit

Permalink
[whisper] Move needed aes_gcm crypto in-crate (#10647)
Browse files Browse the repository at this point in the history
In the latest `parity-crypto` release (upcoming 0.4), the aes GCM features were removed (done to remove the dependency on `ring`).
This PR adds the bare minimum crypto needed for Whisper directly to the crate itself and as those were the only features needed from `parity-crypto`, removes the dependency on that crate altogether.
  • Loading branch information
dvdplm authored and ordian committed May 13, 2019
1 parent 2cf0d7d commit 42268fd
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 11 deletions.
22 changes: 15 additions & 7 deletions 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 whisper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ bitflags = "0.9"
byteorder = "1.0.0"
ethereum-types = "0.4"
ethcore-network = { path = "../util/network" }
parity-crypto = "0.3.0"
ring = "0.14.6"
ethkey = { path = "../accounts/ethkey" }
hex = "0.2"
log = "0.4"
Expand Down
113 changes: 113 additions & 0 deletions whisper/src/aes_gcm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use ring;

/// AES GCM encryptor.
pub struct Encryptor<'a> {
key: ring::aead::SealingKey,
ad: &'a [u8],
offset: usize,
}

impl<'a> Encryptor<'a> {
pub fn aes_256_gcm(key: &[u8; 32]) -> Result<Encryptor<'a>, ring::error::Unspecified> {
let sk = ring::aead::SealingKey::new(&ring::aead::AES_256_GCM, key)?;
Ok(Encryptor {
key: sk,
ad: &[],
offset: 0,
})
}

/// Optional offset value. Only the slice `[offset..]` will be encrypted.
pub fn offset(&mut self, off: usize) -> &mut Self {
self.offset = off;
self
}

/// Please note that the pair (key, nonce) must never be reused. Using random nonces
/// limits the number of messages encrypted with the same key to 2^32 (cf. [[1]])
///
/// [1]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
pub fn encrypt(&self, nonce: &[u8; 12], mut data: Vec<u8>) -> Result<Vec<u8>, ring::error::Unspecified> {
if self.offset > data.len() {
return Err(ring::error::Unspecified)
}
let tag_len = ring::aead::AES_256_GCM.tag_len();
data.extend(::std::iter::repeat(0).take(tag_len));
let nonce = ring::aead::Nonce::assume_unique_for_key(*nonce);
let aad = ring::aead::Aad::from(self.ad);
let len = ring::aead::seal_in_place(&self.key, nonce, aad, &mut data[self.offset ..], tag_len)?;
data.truncate(self.offset + len);
Ok(data)
}
}

/// AES GCM decryptor.
pub struct Decryptor<'a> {
key: ring::aead::OpeningKey,
ad: &'a [u8],
offset: usize,
}

impl<'a> Decryptor<'a> {
pub fn aes_256_gcm(key: &[u8; 32]) -> Result<Decryptor<'a>, ring::error::Unspecified> {
let ok = ring::aead::OpeningKey::new(&ring::aead::AES_256_GCM, key)?;
Ok(Decryptor {
key: ok,
ad: &[],
offset: 0,
})
}

pub fn decrypt(&self, nonce: &[u8; 12], mut data: Vec<u8>) -> Result<Vec<u8>, ring::error::Unspecified> {
if self.offset > data.len() {
return Err(ring::error::Unspecified)
}
let nonce = ring::aead::Nonce::assume_unique_for_key(*nonce);
let aad = ring::aead::Aad::from(self.ad);
let len = ring::aead::open_in_place(&self.key, nonce, aad, 0, &mut data[self.offset ..])?.len();
data.truncate(self.offset + len);
Ok(data)
}
}

#[cfg(test)]
mod tests {
use super::{Encryptor, Decryptor};

#[test]
fn aes_gcm_256() {
let secret = b"12345678901234567890123456789012";
let nonce = b"123456789012";
let message = b"So many books, so little time";

let ciphertext = Encryptor::aes_256_gcm(secret)
.unwrap()
.encrypt(nonce, message.to_vec())
.unwrap();

assert!(ciphertext != message);

let plaintext = Decryptor::aes_256_gcm(secret)
.unwrap()
.decrypt(nonce, ciphertext)
.unwrap();

assert_eq!(plaintext, message)
}
}
4 changes: 3 additions & 1 deletion whisper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#![cfg_attr(feature = "time_checked_add", feature(time_checked_add))]

extern crate byteorder;
extern crate parity_crypto as crypto;
extern crate ethcore_network as network;
extern crate ethereum_types;
extern crate ethkey;
Expand All @@ -29,6 +28,7 @@ extern crate memzero;
extern crate ordered_float;
extern crate parking_lot;
extern crate rand;
extern crate ring;
extern crate rlp;
extern crate serde;
extern crate slab;
Expand Down Expand Up @@ -60,3 +60,5 @@ pub use self::net::{Network, MessageHandler};
pub mod message;
pub mod net;
pub mod rpc;

mod aes_gcm;
4 changes: 2 additions & 2 deletions whisper/src/rpc/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! Encryption schemes supported by RPC layer.

use crypto::aes_gcm::{Encryptor, Decryptor};
use aes_gcm::{Encryptor, Decryptor};
use ethkey::crypto::ecies;
use ethereum_types::H256;
use ethkey::{self, Public, Secret};
Expand Down Expand Up @@ -77,7 +77,7 @@ impl EncryptionInstance {
EncryptionInner::AES(key, nonce, encode) => {
match encode {
AesEncode::AppendedNonce => {
let mut enc = Encryptor::aes_256_gcm(&*key).ok()?;
let enc = Encryptor::aes_256_gcm(&*key).ok()?;
let mut buf = enc.encrypt(&nonce, plain.to_vec()).ok()?;
buf.extend(&nonce[..]);
Some(buf)
Expand Down

0 comments on commit 42268fd

Please sign in to comment.