diff --git a/libraries/crypto/src/ecdsa.rs b/libraries/crypto/src/ecdsa.rs index 1d14f9a..89e93a6 100644 --- a/libraries/crypto/src/ecdsa.rs +++ b/libraries/crypto/src/ecdsa.rs @@ -18,7 +18,7 @@ use super::ec::int256::Int256; use super::ec::point::PointP256; use super::hmac::hmac_256; use super::rng256::Rng256; -use super::{Hash256, HashBlockSize64Bytes}; +use super::Hash256; use alloc::vec; use alloc::vec::Vec; #[cfg(feature = "std")] @@ -82,7 +82,7 @@ impl SecKey { /// Creates a deterministic ECDSA signature based on RFC 6979. pub fn sign_rfc6979(&self, msg: &[u8]) -> Signature where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); @@ -131,7 +131,7 @@ impl SecKey { #[cfg(test)] pub fn get_k_rfc6979(&self, msg: &[u8]) -> NonZeroExponentP256 where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); @@ -288,7 +288,7 @@ impl PubKey { struct Rfc6979 where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { k: [u8; 32], v: [u8; 32], @@ -297,7 +297,7 @@ where impl Rfc6979 where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { pub fn new(sk: &SecKey, msg: &[u8]) -> Rfc6979 { let h1 = H::hash(msg); diff --git a/libraries/crypto/src/hkdf.rs b/libraries/crypto/src/hkdf.rs index ee276a3..1ec8621 100644 --- a/libraries/crypto/src/hkdf.rs +++ b/libraries/crypto/src/hkdf.rs @@ -13,7 +13,7 @@ // limitations under the License. use super::hmac::hmac_256; -use super::{Hash256, HashBlockSize64Bytes}; +use super::Hash256; const HASH_SIZE: usize = 32; @@ -28,7 +28,7 @@ const HASH_SIZE: usize = 32; /// default block of zeros and the output length l as 32. pub fn hkdf_empty_salt_256(ikm: &[u8], info: &[u8]) -> [u8; HASH_SIZE] where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { // Salt is a zero block here. let prk = hmac_256::(&[0; HASH_SIZE], ikm); @@ -55,7 +55,7 @@ where #[cfg(test)] pub fn hkdf(salt: &[u8], ikm: &[u8], l: u8, info: &[u8]) -> Vec where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { let prk = if salt.is_empty() { hmac_256::(&[0; HASH_SIZE], ikm) diff --git a/libraries/crypto/src/hmac.rs b/libraries/crypto/src/hmac.rs index 338340e..f0a706c 100644 --- a/libraries/crypto/src/hmac.rs +++ b/libraries/crypto/src/hmac.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{Hash256, HashBlockSize64Bytes}; +use super::Hash256; use arrayref::array_ref; use subtle::ConstantTimeEq; @@ -21,7 +21,7 @@ const HASH_SIZE: usize = 32; pub fn verify_hmac_256(key: &[u8], contents: &[u8], mac: &[u8; HASH_SIZE]) -> bool where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { let expected_mac = hmac_256::(key, contents); bool::from(expected_mac.ct_eq(mac)) @@ -31,7 +31,7 @@ where // against the pin ¯\_(ツ)_/¯ pub fn verify_hmac_256_first_128bits(key: &[u8], contents: &[u8], pin: &[u8; 16]) -> bool where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { let expected_mac = hmac_256::(key, contents); bool::from(array_ref![expected_mac, 0, 16].ct_eq(pin)) @@ -39,7 +39,7 @@ where pub fn hmac_256(key: &[u8], contents: &[u8]) -> [u8; HASH_SIZE] where - H: Hash256 + HashBlockSize64Bytes, + H: Hash256, { let mut ipad: [u8; BLOCK_SIZE] = [0x36; BLOCK_SIZE]; let mut opad: [u8; BLOCK_SIZE] = [0x5c; BLOCK_SIZE]; diff --git a/libraries/crypto/src/sha256.rs b/libraries/crypto/src/sha256.rs index aa63a4c..273cd67 100644 --- a/libraries/crypto/src/sha256.rs +++ b/libraries/crypto/src/sha256.rs @@ -15,10 +15,17 @@ use super::{Hash256, HashBlockSize64Bytes}; use arrayref::{array_mut_ref, array_ref}; use byteorder::{BigEndian, ByteOrder}; +use core::cell::Cell; use core::num::Wrapping; const BLOCK_SIZE: usize = 64; +// To be able to support hardware cryptography, we want to make sure we never compute multiple +// sha256 in parallel. (Note that almost all usage of Sha256 is through Hash256::hash which is +// statically correct. There's only 2 low-level usages in the `hmac::hmac_256` and those are +// sequential.) This variable tracks whether `new` was called but `finalize` wasn't called yet. +const BUSY: Cell = Cell::new(false); + pub struct Sha256 { state: [Wrapping; 8], block: [u8; BLOCK_SIZE], @@ -27,6 +34,7 @@ pub struct Sha256 { impl Hash256 for Sha256 { fn new() -> Self { + assert!(!BUSY.replace(true)); Sha256 { state: Sha256::H, block: [0; BLOCK_SIZE], @@ -93,6 +101,7 @@ impl Hash256 for Sha256 { for i in 0..8 { BigEndian::write_u32(array_mut_ref![result, 4 * i, 4], self.state[i].0); } + BUSY.set(false); result } }