diff --git a/libraries/crypto/src/sha256.rs b/libraries/crypto/src/sha256.rs index 09e32e0d..cf98b753 100644 --- a/libraries/crypto/src/sha256.rs +++ b/libraries/crypto/src/sha256.rs @@ -15,18 +15,11 @@ use super::{Hash256, HashBlockSize64Bytes}; use arrayref::{array_mut_ref, array_ref}; use byteorder::{BigEndian, ByteOrder}; -use core::cell::Cell; use core::num::Wrapping; use zeroize::Zeroize; 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], @@ -46,7 +39,6 @@ impl Drop for Sha256 { impl Hash256 for Sha256 { fn new() -> Self { - assert!(!BUSY.replace(true)); Sha256 { state: Sha256::H, block: [0; BLOCK_SIZE], @@ -112,7 +104,6 @@ impl Hash256 for Sha256 { for i in 0..8 { BigEndian::write_u32(array_mut_ref![output, 4 * i, 4], self.state[i].0); } - BUSY.set(false); } } diff --git a/libraries/opensk/src/api/crypto/rust_crypto.rs b/libraries/opensk/src/api/crypto/rust_crypto.rs index c03932ad..59d6cea7 100644 --- a/libraries/opensk/src/api/crypto/rust_crypto.rs +++ b/libraries/opensk/src/api/crypto/rust_crypto.rs @@ -34,6 +34,8 @@ use aes::cipher::{ BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, KeyInit, KeyIvInit, }; use alloc::vec::Vec; +#[cfg(test)] +use core::cell::RefCell; use core::convert::TryFrom; use hmac::digest::FixedOutput; use hmac::Mac; @@ -43,6 +45,18 @@ use p256::ecdsa::signature::{SignatureEncoding, Signer, Verifier}; use p256::ecdsa::{SigningKey, VerifyingKey}; use p256::elliptic_curve::sec1::ToEncodedPoint; use sha2::Digest; +#[cfg(test)] +use std::sync::{Mutex, MutexGuard}; + +// To be able to support hardware cryptography, we want to make sure we never compute multiple +// sha256 in parallel. Note that calling `digest` or `digest_mut` is statically correct. +// These variables track whether `new` was called but `finalize` wasn't called yet. +#[cfg(test)] +static BUSY: Mutex<()> = Mutex::new(()); +#[cfg(test)] +thread_local! { + static BUSY_GUARD: RefCell>> = RefCell::new(None); +} pub struct SoftwareCrypto; pub struct SoftwareEcdh; @@ -224,6 +238,11 @@ impl Sha256 for SoftwareSha256 { } fn new() -> Self { + #[cfg(test)] + BUSY_GUARD.with_borrow_mut(|guard| { + assert!(guard.is_none()); + *guard = Some(BUSY.lock().unwrap()); + }); let hasher = sha2::Sha256::new(); Self { hasher } } @@ -236,6 +255,11 @@ impl Sha256 for SoftwareSha256 { /// Finalizes the hashing process, returns the hash value. fn finalize(self, output: &mut [u8; HASH_SIZE]) { FixedOutput::finalize_into(self.hasher, output.into()); + #[cfg(test)] + BUSY_GUARD.with_borrow_mut(|guard| { + assert!(guard.is_some()); + *guard = None; + }); } } diff --git a/libraries/opensk/src/api/crypto/software_crypto.rs b/libraries/opensk/src/api/crypto/software_crypto.rs index 6ce9bbb1..89c73d24 100644 --- a/libraries/opensk/src/api/crypto/software_crypto.rs +++ b/libraries/opensk/src/api/crypto/software_crypto.rs @@ -22,9 +22,23 @@ use crate::api::crypto::{ }; use crate::api::rng::Rng; use alloc::vec::Vec; +#[cfg(test)] +use core::cell::RefCell; use crypto::Hash256; +#[cfg(test)] +use std::sync::{Mutex, MutexGuard}; use zeroize::Zeroize; +// To be able to support hardware cryptography, we want to make sure we never compute multiple +// sha256 in parallel. Note that calling `digest` or `digest_mut` is statically correct. +// These variables track whether `new` was called but `finalize` wasn't called yet. +#[cfg(test)] +static BUSY: Mutex<()> = Mutex::new(()); +#[cfg(test)] +thread_local! { + static BUSY_GUARD: RefCell>> = RefCell::new(None); +} + /// Cryptography implementation using our own library of primitives. /// /// Warning: The used library does not implement zeroization. @@ -184,6 +198,11 @@ pub struct SoftwareSha256 { impl Sha256 for SoftwareSha256 { fn new() -> Self { + #[cfg(test)] + BUSY_GUARD.with_borrow_mut(|guard| { + assert!(guard.is_none()); + *guard = Some(BUSY.lock().unwrap()); + }); let hasher = crypto::sha256::Sha256::new(); Self { hasher } } @@ -195,7 +214,12 @@ impl Sha256 for SoftwareSha256 { /// Finalizes the hashing process, returns the hash value. fn finalize(self, output: &mut [u8; HASH_SIZE]) { - self.hasher.finalize(output) + self.hasher.finalize(output); + #[cfg(test)] + BUSY_GUARD.with_borrow_mut(|guard| { + assert!(guard.is_some()); + *guard = None; + }); } }