From 83aa95b21b1cdae6b83291b8cf69f61294378fe0 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 9 May 2019 16:35:34 +0200 Subject: [PATCH] Replace ring with hmac for hmacs --- parity-crypto/Cargo.toml | 1 + parity-crypto/src/hmac/mod.rs | 92 +++++++++++++++++++++++++---------- parity-crypto/src/lib.rs | 1 + 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/parity-crypto/Cargo.toml b/parity-crypto/Cargo.toml index f5d113290..23128e662 100644 --- a/parity-crypto/Cargo.toml +++ b/parity-crypto/Cargo.toml @@ -19,6 +19,7 @@ scrypt = { version = "0.1.1", default-features = false } ripemd160 = "0.8.0" sha2 = "0.8.0" digest = "0.8" +hmac = "0.7" aes = "0.3.2" aes-ctr = "0.3.0" block-modes = "0.3.3" diff --git a/parity-crypto/src/hmac/mod.rs b/parity-crypto/src/hmac/mod.rs index 1372fbe10..44f24d911 100644 --- a/parity-crypto/src/hmac/mod.rs +++ b/parity-crypto/src/hmac/mod.rs @@ -14,77 +14,119 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use digest; -use ring::digest::{SHA256, SHA512}; -use ring::hmac::{self, SigningContext}; +use digest::{Sha256, Sha512}; +use rdigest::generic_array::{GenericArray, typenum::U32, typenum::U64, typenum::U128}; +use rhmac::{Hmac, Mac as _}; +use rsha2; use std::marker::PhantomData; use std::ops::Deref; /// HMAC signature. -pub struct Signature(hmac::Signature, PhantomData); +pub struct Signature(HashInner, PhantomData); + +enum HashInner { + Sha256(GenericArray), + Sha512(GenericArray), +} impl Deref for Signature { type Target = [u8]; + fn deref(&self) -> &Self::Target { - self.0.as_ref() + match &self.0 { + HashInner::Sha256(a) => a.as_slice(), + HashInner::Sha512(a) => a.as_slice(), + } } } /// HMAC signing key. -pub struct SigKey(hmac::SigningKey, PhantomData); +pub struct SigKey(KeyInner, PhantomData); + +enum KeyInner { + Sha256(GenericArray), + Sha512(GenericArray), +} -impl SigKey { - pub fn sha256(key: &[u8]) -> SigKey { - SigKey(hmac::SigningKey::new(&SHA256, key), PhantomData) +impl SigKey { + pub fn sha256(key: &[u8]) -> SigKey { + SigKey(KeyInner::Sha256(*GenericArray::from_slice(key)), PhantomData) } } -impl SigKey { - pub fn sha512(key: &[u8]) -> SigKey { - SigKey(hmac::SigningKey::new(&SHA512, key), PhantomData) +impl SigKey { + pub fn sha512(key: &[u8]) -> SigKey { + SigKey(KeyInner::Sha512(*GenericArray::from_slice(key)), PhantomData) } } /// Compute HMAC signature of `data`. pub fn sign(k: &SigKey, data: &[u8]) -> Signature { - Signature(hmac::sign(&k.0, data), PhantomData) + let mut signer = Signer::with(k); + signer.update(data); + signer.sign() } /// Stateful HMAC computation. -pub struct Signer(SigningContext, PhantomData); +pub struct Signer(SignerInner, PhantomData); + +enum SignerInner { + Sha256(Hmac), + Sha512(Hmac), +} impl Signer { pub fn with(key: &SigKey) -> Signer { - Signer(hmac::SigningContext::with_key(&key.0), PhantomData) + match &key.0 { + KeyInner::Sha256(k) => Signer(SignerInner::Sha256(Hmac::new(k)), PhantomData), + KeyInner::Sha512(k) => Signer(SignerInner::Sha512(Hmac::new(k)), PhantomData), + } } pub fn update(&mut self, data: &[u8]) { - self.0.update(data) + match &mut self.0 { + SignerInner::Sha256(hmac) => hmac.input(data), + SignerInner::Sha512(hmac) => hmac.input(data), + } } pub fn sign(self) -> Signature { - Signature(self.0.sign(), PhantomData) + match self.0 { + SignerInner::Sha256(hmac) => Signature(HashInner::Sha256(hmac.result().code()), PhantomData), + SignerInner::Sha512(hmac) => Signature(HashInner::Sha512(hmac.result().code()), PhantomData), + } } } /// HMAC signature verification key. -pub struct VerifyKey(hmac::VerificationKey, PhantomData); +pub struct VerifyKey(KeyInner, PhantomData); -impl VerifyKey { - pub fn sha256(key: &[u8]) -> VerifyKey { - VerifyKey(hmac::VerificationKey::new(&SHA256, key), PhantomData) +impl VerifyKey { + pub fn sha256(key: &[u8]) -> VerifyKey { + VerifyKey(KeyInner::Sha256(*GenericArray::from_slice(key)), PhantomData) } } -impl VerifyKey { - pub fn sha512(key: &[u8]) -> VerifyKey { - VerifyKey(hmac::VerificationKey::new(&SHA512, key), PhantomData) +impl VerifyKey { + pub fn sha512(key: &[u8]) -> VerifyKey { + VerifyKey(KeyInner::Sha512(*GenericArray::from_slice(key)), PhantomData) } } /// Verify HMAC signature of `data`. pub fn verify(k: &VerifyKey, data: &[u8], sig: &[u8]) -> bool { - hmac::verify(&k.0, data, sig).is_ok() + match &k.0 { + KeyInner::Sha256(k) => { + let mut ctxt = Hmac::::new(k); + ctxt.input(data); + ctxt.verify(sig).is_ok() + } + KeyInner::Sha512(k) => { + let mut ctxt = Hmac::::new(k); + ctxt.input(data); + ctxt.verify(sig).is_ok() + } + } } #[cfg(test)] diff --git a/parity-crypto/src/lib.rs b/parity-crypto/src/lib.rs index 379e2619b..bb7dd296a 100644 --- a/parity-crypto/src/lib.rs +++ b/parity-crypto/src/lib.rs @@ -24,6 +24,7 @@ extern crate scrypt as rscrypt; extern crate ripemd160 as rripemd160; extern crate sha2 as rsha2; extern crate digest as rdigest; +extern crate hmac as rhmac; extern crate aes as raes; extern crate aes_ctr; extern crate block_modes;