Restrict Sha256 to be used sequentially
Also remove useless HashBlockSize64Bytes bound.
This commit is contained in:
committed by
Julien Cretin
parent
ca2ea2007e
commit
ce08f82d68
@@ -18,7 +18,7 @@ use super::ec::int256::Int256;
|
|||||||
use super::ec::point::PointP256;
|
use super::ec::point::PointP256;
|
||||||
use super::hmac::hmac_256;
|
use super::hmac::hmac_256;
|
||||||
use super::rng256::Rng256;
|
use super::rng256::Rng256;
|
||||||
use super::{Hash256, HashBlockSize64Bytes};
|
use super::Hash256;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@@ -82,7 +82,7 @@ impl SecKey {
|
|||||||
/// Creates a deterministic ECDSA signature based on RFC 6979.
|
/// Creates a deterministic ECDSA signature based on RFC 6979.
|
||||||
pub fn sign_rfc6979<H>(&self, msg: &[u8]) -> Signature
|
pub fn sign_rfc6979<H>(&self, msg: &[u8]) -> Signature
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg)));
|
let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg)));
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ impl SecKey {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn get_k_rfc6979<H>(&self, msg: &[u8]) -> NonZeroExponentP256
|
pub fn get_k_rfc6979<H>(&self, msg: &[u8]) -> NonZeroExponentP256
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg)));
|
let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg)));
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ impl PubKey {
|
|||||||
|
|
||||||
struct Rfc6979<H>
|
struct Rfc6979<H>
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
k: [u8; 32],
|
k: [u8; 32],
|
||||||
v: [u8; 32],
|
v: [u8; 32],
|
||||||
@@ -297,7 +297,7 @@ where
|
|||||||
|
|
||||||
impl<H> Rfc6979<H>
|
impl<H> Rfc6979<H>
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
pub fn new(sk: &SecKey, msg: &[u8]) -> Rfc6979<H> {
|
pub fn new(sk: &SecKey, msg: &[u8]) -> Rfc6979<H> {
|
||||||
let h1 = H::hash(msg);
|
let h1 = H::hash(msg);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use super::hmac::hmac_256;
|
use super::hmac::hmac_256;
|
||||||
use super::{Hash256, HashBlockSize64Bytes};
|
use super::Hash256;
|
||||||
|
|
||||||
const HASH_SIZE: usize = 32;
|
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.
|
/// default block of zeros and the output length l as 32.
|
||||||
pub fn hkdf_empty_salt_256<H>(ikm: &[u8], info: &[u8]) -> [u8; HASH_SIZE]
|
pub fn hkdf_empty_salt_256<H>(ikm: &[u8], info: &[u8]) -> [u8; HASH_SIZE]
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
// Salt is a zero block here.
|
// Salt is a zero block here.
|
||||||
let prk = hmac_256::<H>(&[0; HASH_SIZE], ikm);
|
let prk = hmac_256::<H>(&[0; HASH_SIZE], ikm);
|
||||||
@@ -55,7 +55,7 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn hkdf<H>(salt: &[u8], ikm: &[u8], l: u8, info: &[u8]) -> Vec<u8>
|
pub fn hkdf<H>(salt: &[u8], ikm: &[u8], l: u8, info: &[u8]) -> Vec<u8>
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
let prk = if salt.is_empty() {
|
let prk = if salt.is_empty() {
|
||||||
hmac_256::<H>(&[0; HASH_SIZE], ikm)
|
hmac_256::<H>(&[0; HASH_SIZE], ikm)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use super::{Hash256, HashBlockSize64Bytes};
|
use super::Hash256;
|
||||||
use arrayref::array_ref;
|
use arrayref::array_ref;
|
||||||
use subtle::ConstantTimeEq;
|
use subtle::ConstantTimeEq;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ const HASH_SIZE: usize = 32;
|
|||||||
|
|
||||||
pub fn verify_hmac_256<H>(key: &[u8], contents: &[u8], mac: &[u8; HASH_SIZE]) -> bool
|
pub fn verify_hmac_256<H>(key: &[u8], contents: &[u8], mac: &[u8; HASH_SIZE]) -> bool
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
let expected_mac = hmac_256::<H>(key, contents);
|
let expected_mac = hmac_256::<H>(key, contents);
|
||||||
bool::from(expected_mac.ct_eq(mac))
|
bool::from(expected_mac.ct_eq(mac))
|
||||||
@@ -31,7 +31,7 @@ where
|
|||||||
// against the pin ¯\_(ツ)_/¯
|
// against the pin ¯\_(ツ)_/¯
|
||||||
pub fn verify_hmac_256_first_128bits<H>(key: &[u8], contents: &[u8], pin: &[u8; 16]) -> bool
|
pub fn verify_hmac_256_first_128bits<H>(key: &[u8], contents: &[u8], pin: &[u8; 16]) -> bool
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
let expected_mac = hmac_256::<H>(key, contents);
|
let expected_mac = hmac_256::<H>(key, contents);
|
||||||
bool::from(array_ref![expected_mac, 0, 16].ct_eq(pin))
|
bool::from(array_ref![expected_mac, 0, 16].ct_eq(pin))
|
||||||
@@ -39,7 +39,7 @@ where
|
|||||||
|
|
||||||
pub fn hmac_256<H>(key: &[u8], contents: &[u8]) -> [u8; HASH_SIZE]
|
pub fn hmac_256<H>(key: &[u8], contents: &[u8]) -> [u8; HASH_SIZE]
|
||||||
where
|
where
|
||||||
H: Hash256 + HashBlockSize64Bytes,
|
H: Hash256,
|
||||||
{
|
{
|
||||||
let mut ipad: [u8; BLOCK_SIZE] = [0x36; BLOCK_SIZE];
|
let mut ipad: [u8; BLOCK_SIZE] = [0x36; BLOCK_SIZE];
|
||||||
let mut opad: [u8; BLOCK_SIZE] = [0x5c; BLOCK_SIZE];
|
let mut opad: [u8; BLOCK_SIZE] = [0x5c; BLOCK_SIZE];
|
||||||
|
|||||||
@@ -15,10 +15,17 @@
|
|||||||
use super::{Hash256, HashBlockSize64Bytes};
|
use super::{Hash256, HashBlockSize64Bytes};
|
||||||
use arrayref::{array_mut_ref, array_ref};
|
use arrayref::{array_mut_ref, array_ref};
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
|
use core::cell::Cell;
|
||||||
use core::num::Wrapping;
|
use core::num::Wrapping;
|
||||||
|
|
||||||
const BLOCK_SIZE: usize = 64;
|
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<bool> = Cell::new(false);
|
||||||
|
|
||||||
pub struct Sha256 {
|
pub struct Sha256 {
|
||||||
state: [Wrapping<u32>; 8],
|
state: [Wrapping<u32>; 8],
|
||||||
block: [u8; BLOCK_SIZE],
|
block: [u8; BLOCK_SIZE],
|
||||||
@@ -27,6 +34,7 @@ pub struct Sha256 {
|
|||||||
|
|
||||||
impl Hash256 for Sha256 {
|
impl Hash256 for Sha256 {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
assert!(!BUSY.replace(true));
|
||||||
Sha256 {
|
Sha256 {
|
||||||
state: Sha256::H,
|
state: Sha256::H,
|
||||||
block: [0; BLOCK_SIZE],
|
block: [0; BLOCK_SIZE],
|
||||||
@@ -93,6 +101,7 @@ impl Hash256 for Sha256 {
|
|||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
BigEndian::write_u32(array_mut_ref![result, 4 * i, 4], self.state[i].0);
|
BigEndian::write_u32(array_mut_ref![result, 4 * i, 4], self.state[i].0);
|
||||||
}
|
}
|
||||||
|
BUSY.set(false);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user