From 99f8118d3b0b1d80e0ef4375a8de6e98db8b2697 Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 10:02:31 +0200 Subject: [PATCH 01/11] [parity-crypto] bump version to 0.4.0 --- parity-crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index eb0fc3d01..4c50c0f73 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-crypto" -version = "0.3.1" +version = "0.4.0" authors = ["Parity Technologies "] repository = "https://github.com/paritytech/parity-common" description = "Crypto utils used by ethstore and network." From b36ec773c32716dab0084f1fad7271809aa81ff4 Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 11:16:59 +0200 Subject: [PATCH 02/11] Beta --- parity-crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index 4c50c0f73..121a23ee0 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-crypto" -version = "0.4.0" +version = "0.4.0-beta.1" authors = ["Parity Technologies "] repository = "https://github.com/paritytech/parity-common" description = "Crypto utils used by ethstore and network." From b27bf1297fba41e352ee2d87df4e232728904d75 Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 15:06:04 +0200 Subject: [PATCH 03/11] Upgrade scrypt to latest and prefer subtle to constant_time_eq. Add Changelog section to readme --- parity-crypto/Cargo.toml | 5 +++-- parity-crypto/README.md | 5 +++++ parity-crypto/src/lib.rs | 19 +++++++++++++++++-- parity-crypto/src/pbkdf2/test.rs | 1 - 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index 121a23ee0..365ed5f4d 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -15,7 +15,7 @@ harness = false [dependencies] quick-error = "1.2.2" tiny-keccak = "1.4" -scrypt = { version = "0.1.1", default-features = false } +scrypt = { version = "0.2", default-features = false } ripemd160 = "0.8.0" sha2 = "0.8.0" digest = "0.8" @@ -24,7 +24,8 @@ aes = "0.3.2" aes-ctr = "0.3.0" block-modes = "0.3.3" pbkdf2 = "0.3.0" -constant_time_eq = "0.1.3" +subtle = "2.1" +#constant_time_eq = "0.1.3" [dev-dependencies] criterion = "0.2" diff --git a/parity-crypto/README.md b/parity-crypto/README.md index 9e3c41767..e8d9cb11d 100644 --- a/parity-crypto/README.md +++ b/parity-crypto/README.md @@ -3,3 +3,8 @@ General cryptographic utilities for Ethereum. By default, this library is compiled with the `secp256k1` feature, which provides ECDH and ECIES capability on that curve. It can be compiled without to avoid a dependency on the `libsecp256k1` library. + + +## Changelog + +The 0.4 release removes the dependency on `ring` and replaces it with prue-rust alternatives. As a consequence of this, AES GCM support has been removed. `subtle` replaces the `constant_time_eq` crate for constant time equality testing. diff --git a/parity-crypto/src/lib.rs b/parity-crypto/src/lib.rs index a04514249..695b048d7 100644 --- a/parity-crypto/src/lib.rs +++ b/parity-crypto/src/lib.rs @@ -28,7 +28,7 @@ extern crate aes as raes; extern crate aes_ctr; extern crate block_modes; extern crate pbkdf2 as rpbkdf2; -extern crate constant_time_eq; +extern crate subtle; pub mod aes; pub mod error; @@ -40,6 +40,7 @@ pub mod pbkdf2; pub use error::Error; use tiny_keccak::Keccak; +use subtle::ConstantTimeEq; pub const KEY_LENGTH: usize = 32; pub const KEY_ITERATIONS: usize = 10240; @@ -78,5 +79,19 @@ pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec { } pub fn is_equal(a: &[u8], b: &[u8]) -> bool { - constant_time_eq::constant_time_eq(a, b) + a.ct_eq(b).into() +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn can_test_for_equality() { + let a = b"abc"; + let b = b"abc"; + let c = b"efg"; + assert!(is_equal(a, b)); + assert!(!is_equal(a, c)); + } } diff --git a/parity-crypto/src/pbkdf2/test.rs b/parity-crypto/src/pbkdf2/test.rs index 399a05a17..0aca66967 100644 --- a/parity-crypto/src/pbkdf2/test.rs +++ b/parity-crypto/src/pbkdf2/test.rs @@ -15,7 +15,6 @@ // along with Parity. If not, see . use super::*; -use std::num::NonZeroU32; #[test] fn basic_test() { From 65a6407c4df83c0677481bdd6f1e03bfc93ebb62 Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 15:19:04 +0200 Subject: [PATCH 04/11] remove cruft --- parity-crypto/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index 365ed5f4d..6953a3707 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -25,7 +25,6 @@ aes-ctr = "0.3.0" block-modes = "0.3.3" pbkdf2 = "0.3.0" subtle = "2.1" -#constant_time_eq = "0.1.3" [dev-dependencies] criterion = "0.2" From 01c8860ec8284e1f6a876f167b2cf469d1e2c13f Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 18:51:26 +0200 Subject: [PATCH 05/11] Fix hash sizes --- parity-crypto/Cargo.toml | 2 +- parity-crypto/src/hmac/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index 6953a3707..245847dab 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-crypto" -version = "0.4.0-beta.1" +version = "0.4.0-beta.3" authors = ["Parity Technologies "] repository = "https://github.com/paritytech/parity-common" description = "Crypto utils used by ethstore and network." diff --git a/parity-crypto/src/hmac/mod.rs b/parity-crypto/src/hmac/mod.rs index 44f24d911..bbb0589b5 100644 --- a/parity-crypto/src/hmac/mod.rs +++ b/parity-crypto/src/hmac/mod.rs @@ -44,8 +44,8 @@ impl Deref for Signature { pub struct SigKey(KeyInner, PhantomData); enum KeyInner { - Sha256(GenericArray), - Sha512(GenericArray), + Sha256(GenericArray), + Sha512(GenericArray), } impl SigKey { From 366452e34c5b24f1565f6b57c1a91753bdf0e37c Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 18:57:35 +0200 Subject: [PATCH 06/11] Improve wording --- parity-crypto/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity-crypto/README.md b/parity-crypto/README.md index e8d9cb11d..b6b6cc539 100644 --- a/parity-crypto/README.md +++ b/parity-crypto/README.md @@ -7,4 +7,4 @@ By default, this library is compiled with the `secp256k1` feature, which provide ## Changelog -The 0.4 release removes the dependency on `ring` and replaces it with prue-rust alternatives. As a consequence of this, AES GCM support has been removed. `subtle` replaces the `constant_time_eq` crate for constant time equality testing. +The 0.4 release removes the dependency on `ring` and replaces it with prue-rust alternatives. As a consequence of this, AES GCM support has been removed. `subtle` is used for constant time equality testing. From 393aefcf5445c4bd9e58e1a96788b0549e24730f Mon Sep 17 00:00:00 2001 From: David Palm Date: Mon, 13 May 2019 18:58:26 +0200 Subject: [PATCH 07/11] =?UTF-8?q?Remove=20mention=20of=20secp256k1=20?= =?UTF-8?q?=E2=80=93=20not=20available=20in=20this=20lib.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- parity-crypto/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/parity-crypto/README.md b/parity-crypto/README.md index b6b6cc539..ad54a4bef 100644 --- a/parity-crypto/README.md +++ b/parity-crypto/README.md @@ -2,8 +2,6 @@ General cryptographic utilities for Ethereum. -By default, this library is compiled with the `secp256k1` feature, which provides ECDH and ECIES capability on that curve. It can be compiled without to avoid a dependency on the `libsecp256k1` library. - ## Changelog From ad1d4b7cb168ca991340d5ec6faf670667532597 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sun, 19 May 2019 18:56:27 +0200 Subject: [PATCH 08/11] bump beta version --- parity-crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index f4d0f9f80..9683946b3 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-crypto" -version = "0.4.0-beta.3" +version = "0.4.0-beta.4" authors = ["Parity Technologies "] repository = "https://github.com/paritytech/parity-common" description = "Crypto utils used by ethstore and network." From a1b39ef42476a2046c2c76889f5230d924a4d7b4 Mon Sep 17 00:00:00 2001 From: David Palm Date: Sun, 19 May 2019 21:15:47 +0200 Subject: [PATCH 09/11] Implement error handling without quick_error --- parity-crypto/Cargo.toml | 1 - parity-crypto/src/error.rs | 170 +++++++++++++++++++++++++------------ parity-crypto/src/lib.rs | 2 - 3 files changed, 114 insertions(+), 59 deletions(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index 9683946b3..1a15c09d7 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -13,7 +13,6 @@ harness = false [dependencies] -quick-error = "1.2.2" tiny-keccak = "1.4" scrypt = { version = "0.2", default-features = false } ripemd160 = "0.8.0" diff --git a/parity-crypto/src/error.rs b/parity-crypto/src/error.rs index 8759c3e2d..e8ff9483c 100644 --- a/parity-crypto/src/error.rs +++ b/parity-crypto/src/error.rs @@ -18,80 +18,113 @@ use rscrypt; use block_modes; use aes_ctr; use std::error::Error as StdError; +use std::{fmt, result}; -quick_error! { - #[derive(Debug)] - pub enum Error { - Scrypt(e: ScryptError) { - cause(e) - from() - } - Symm(e: SymmError) { - cause(e) - from() - } - AsymShort(det: &'static str) { - description(det) - } - AsymFull(e: Box) { - cause(&**e) - description(e.description()) +#[derive(Debug)] +pub enum Error { + Scrypt(ScryptError), + Symm(SymmError), + // TODO: used anywhere? + AsymShort(&'static str), + // TODO: used anywhere? + AsymFull(Box) +} + +#[derive(Debug)] +pub enum ScryptError { + // log(N) < r / 16 + InvalidN, + // p <= (2^31-1 * 32)/(128 * r) + InvalidP, + ScryptParam(rscrypt::errors::InvalidParams), + ScryptLength(rscrypt::errors::InvalidOutputLen), +} + +#[derive(Debug)] +pub struct SymmError(PrivSymmErr); + +#[derive(Debug)] +enum PrivSymmErr { + Offset(usize), // TODO: never constructed – can remove? + BlockMode(block_modes::BlockModeError), + KeyStream(aes_ctr::stream_cipher::LoopError), + InvalidKeyLength(block_modes::InvalidKeyIvLength), +} + +impl StdError for Error { + fn source(&self) -> Option<&(StdError + 'static)> { + match self { + Error::Scrypt(scrypt_err) => Some(scrypt_err), + Error::Symm(symm_err) => Some(symm_err), + Error::AsymShort(_)=> None, + Error::AsymFull(err)=> Some(&**err), } } } -impl Into for Error { - fn into(self) -> std::io::Error { - std::io::Error::new(std::io::ErrorKind::Other, format!("Crypto error: {}",self)) +impl StdError for ScryptError { + fn source(&self) -> Option<&(StdError + 'static)> { + match self { + ScryptError::ScryptParam(err) => Some(err), + ScryptError::ScryptLength(err) => Some(err), + _ => None, + } } } -quick_error! { - #[derive(Debug)] - pub enum ScryptError { - // log(N) < r / 16 - InvalidN { - display("Invalid N argument of the scrypt encryption") - } - // p <= (2^31-1 * 32)/(128 * r) - InvalidP { - display("Invalid p argument of the scrypt encryption") - } - ScryptParam(e: rscrypt::errors::InvalidParams) { - display("invalid params for scrypt: {}", e) - cause(e) - from() - } - ScryptLength(e: rscrypt::errors::InvalidOutputLen) { - display("invalid scrypt output length: {}", e) - cause(e) - from() +impl StdError for SymmError { + fn source(&self) -> Option<&(StdError + 'static)> { + match &self.0 { + PrivSymmErr::BlockMode(err) => Some(err), + // TODO: the trait `std::error::Error` is not implemented for + // `aes_ctr::stream_cipher::LoopError` – but afaict it **is**: + // https://github.com/RustCrypto/traits/blob/master/stream-cipher/src/errors.rs#L16 + // PrivSymmErr::KeyStream(err) => Some(err), + PrivSymmErr::InvalidKeyLength(err) => Some(err), + _ => None, } } } - -quick_error! { - #[derive(Debug)] - pub enum SymmError wraps PrivSymmErr { - Offset(x: usize) { - display("offset {} greater than slice length", x) - } - BlockMode(e: block_modes::BlockModeError) { - display("symmetric crypto error") - from() +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { + match self { + Error::Scrypt(err)=> write!(f, "scrypt error: {}", err), + Error::Symm(err) => write!(f, "symm error: {}", err), + Error::AsymShort(err_str) => write!(f, "asymm error: {}", err_str), + Error::AsymFull(err) => write!(f, "asymm error: {}", err), } - KeyStream(e: aes_ctr::stream_cipher::LoopError) { - display("ctr key stream ended") - from() + } +} + +impl fmt::Display for ScryptError { + fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { + match self { + ScryptError::InvalidN => write!(f, "invalid n argument"), + ScryptError::InvalidP => write!(f, "invalid p argument"), + ScryptError::ScryptParam(err) => write!(f, "invalid params: {}", err), + ScryptError::ScryptLength(err) => write!(f, "invalid output length: {}", err), } - InvalidKeyLength(e: block_modes::InvalidKeyIvLength) { - display("Error with RustCrypto key length : {}", e) - from() + } +} + +impl fmt::Display for SymmError { + fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { + match self { + SymmError(PrivSymmErr::Offset(x)) => write!(f, "offset {} greater than slice length", x), + SymmError(PrivSymmErr::BlockMode(err)) => write!(f, "block cipher error: {}", err), + SymmError(PrivSymmErr::KeyStream(err)) => write!(f, "ctr key stream ended: {}", err), + SymmError(PrivSymmErr::InvalidKeyLength(err)) => write!(f, "block cipher key length: {}", err), } } } +impl Into for Error { + fn into(self) -> std::io::Error { + std::io::Error::new(std::io::ErrorKind::Other, format!("Crypto error: {}",self)) + } +} + impl From for SymmError { fn from(e: block_modes::BlockModeError) -> SymmError { SymmError(PrivSymmErr::BlockMode(e)) @@ -109,3 +142,28 @@ impl From for SymmError { SymmError(PrivSymmErr::KeyStream(e)) } } + +impl From for ScryptError { + fn from(e: rscrypt::errors::InvalidParams) -> ScryptError { + ScryptError::ScryptParam(e) + } +} + +impl From for ScryptError { + fn from(e: rscrypt::errors::InvalidOutputLen) -> ScryptError { + ScryptError::ScryptLength(e) + } +} + +impl From for Error { + fn from(e: ScryptError) -> Error { + Error::Scrypt(e) + } +} + +impl From for Error { + fn from(e: SymmError) -> Error { + Error::Symm(e) + } +} + diff --git a/parity-crypto/src/lib.rs b/parity-crypto/src/lib.rs index 7edfb12ba..7d3fda363 100644 --- a/parity-crypto/src/lib.rs +++ b/parity-crypto/src/lib.rs @@ -16,8 +16,6 @@ //! Crypto utils used by ethstore and network. -#[macro_use] -extern crate quick_error; extern crate tiny_keccak; extern crate scrypt as rscrypt; extern crate ripemd160 as rripemd160; From e588fcb5d42dab320ca6880360c598994ca10100 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 22 May 2019 13:56:18 +0200 Subject: [PATCH 10/11] Remove unused error variants --- parity-crypto/README.md | 2 +- parity-crypto/src/error.rs | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/parity-crypto/README.md b/parity-crypto/README.md index ad54a4bef..51390fe4f 100644 --- a/parity-crypto/README.md +++ b/parity-crypto/README.md @@ -5,4 +5,4 @@ General cryptographic utilities for Ethereum. ## Changelog -The 0.4 release removes the dependency on `ring` and replaces it with prue-rust alternatives. As a consequence of this, AES GCM support has been removed. `subtle` is used for constant time equality testing. +The 0.4 release removes the dependency on `ring` and replaces it with prue-rust alternatives. As a consequence of this, AES GCM support has been removed. `subtle` is used for constant time equality testing and error handling is pared down to the bare minimum required. diff --git a/parity-crypto/src/error.rs b/parity-crypto/src/error.rs index e8ff9483c..1cbee709f 100644 --- a/parity-crypto/src/error.rs +++ b/parity-crypto/src/error.rs @@ -24,10 +24,6 @@ use std::{fmt, result}; pub enum Error { Scrypt(ScryptError), Symm(SymmError), - // TODO: used anywhere? - AsymShort(&'static str), - // TODO: used anywhere? - AsymFull(Box) } #[derive(Debug)] @@ -45,7 +41,6 @@ pub struct SymmError(PrivSymmErr); #[derive(Debug)] enum PrivSymmErr { - Offset(usize), // TODO: never constructed – can remove? BlockMode(block_modes::BlockModeError), KeyStream(aes_ctr::stream_cipher::LoopError), InvalidKeyLength(block_modes::InvalidKeyIvLength), @@ -56,8 +51,6 @@ impl StdError for Error { match self { Error::Scrypt(scrypt_err) => Some(scrypt_err), Error::Symm(symm_err) => Some(symm_err), - Error::AsymShort(_)=> None, - Error::AsymFull(err)=> Some(&**err), } } } @@ -76,10 +69,6 @@ impl StdError for SymmError { fn source(&self) -> Option<&(StdError + 'static)> { match &self.0 { PrivSymmErr::BlockMode(err) => Some(err), - // TODO: the trait `std::error::Error` is not implemented for - // `aes_ctr::stream_cipher::LoopError` – but afaict it **is**: - // https://github.com/RustCrypto/traits/blob/master/stream-cipher/src/errors.rs#L16 - // PrivSymmErr::KeyStream(err) => Some(err), PrivSymmErr::InvalidKeyLength(err) => Some(err), _ => None, } @@ -91,8 +80,6 @@ impl fmt::Display for Error { match self { Error::Scrypt(err)=> write!(f, "scrypt error: {}", err), Error::Symm(err) => write!(f, "symm error: {}", err), - Error::AsymShort(err_str) => write!(f, "asymm error: {}", err_str), - Error::AsymFull(err) => write!(f, "asymm error: {}", err), } } } @@ -111,7 +98,6 @@ impl fmt::Display for ScryptError { impl fmt::Display for SymmError { fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { match self { - SymmError(PrivSymmErr::Offset(x)) => write!(f, "offset {} greater than slice length", x), SymmError(PrivSymmErr::BlockMode(err)) => write!(f, "block cipher error: {}", err), SymmError(PrivSymmErr::KeyStream(err)) => write!(f, "ctr key stream ended: {}", err), SymmError(PrivSymmErr::InvalidKeyLength(err)) => write!(f, "block cipher key length: {}", err), From b32ef58e52b090b4e5f70a64a05a1148f5781037 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 22 May 2019 14:20:29 +0200 Subject: [PATCH 11/11] 0.4 --- parity-crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index 1a15c09d7..5f4b8ef54 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-crypto" -version = "0.4.0-beta.4" +version = "0.4.0" authors = ["Parity Technologies "] repository = "https://github.com/paritytech/parity-common" description = "Crypto utils used by ethstore and network."