Merge rust-bitcoin/rust-bitcoin#4289: [hashes] Disable fixed-time equality cmp when building for fuzzers, use fixed-time equality for `Hmac`
2d9e240fb6
[hashes] Use `fixed_time_eq` for `Hmac::eq` (Matt Corallo)7ac7273013
[hashes] Disable fixed-time equality cmp when building for fuzzers (Matt Corallo) Pull request description: Fuzzers want to break memcmp calls into separate comparisons for coverage monitoring, allowing them to not-quite-brute-force find inputs that fully match. Thus, we disable our fancy fixed-time comparison when built with the `hashes_fuzz` cfg. ACKs for top commit: Kixunil: ACK2d9e240fb6
apoelstra: ACK 2d9e240fb6ae13e6139713f9bb8ccb51e5dc0bff; successfully ran local tests Tree-SHA512: 372e344ae5497a10ca03a50baadb9d2e8a6dac914bbc4ca91fd5c9b839fb036f42c8b47c252ca3466c15286e889a6f5b51390cc0d938ba24dc50b13e8b863463
This commit is contained in:
commit
3748bfcd66
|
@ -15,6 +15,14 @@
|
|||
/// As of rust 1.31.0 disassembly looks completely within reason for this, see
|
||||
/// <https://godbolt.org/z/mMbGQv>.
|
||||
pub fn fixed_time_eq(a: &[u8], b: &[u8]) -> bool {
|
||||
#[cfg(hashes_fuzz)]
|
||||
{
|
||||
// Fuzzers want to break memcmp calls into separate comparisons for coverage monitoring,
|
||||
// so we avoid our fancy fixed-time comparison below for fuzzers.
|
||||
a == b
|
||||
}
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
{
|
||||
assert!(a.len() == b.len());
|
||||
let count = a.len();
|
||||
let lhs = &a[..count];
|
||||
|
@ -51,6 +59,7 @@ pub fn fixed_time_eq(a: &[u8], b: &[u8]) -> bool {
|
|||
}
|
||||
unsafe { (::core::ptr::read_volatile(&r) & 1) == 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -15,8 +15,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|||
use crate::{Hash, HashEngine};
|
||||
|
||||
/// A hash computed from a RFC 2104 HMAC. Parameterized by the underlying hash function.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Copy, Clone, PartialOrd, Ord, Hash)]
|
||||
#[repr(transparent)]
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
pub struct Hmac<T: Hash>(T);
|
||||
|
||||
impl<T: Hash + str::FromStr> str::FromStr for Hmac<T> {
|
||||
|
@ -24,6 +25,14 @@ impl<T: Hash + str::FromStr> str::FromStr for Hmac<T> {
|
|||
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Hmac(str::FromStr::from_str(s)?)) }
|
||||
}
|
||||
|
||||
impl<T: Hash> PartialEq for Hmac<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
crate::cmp::fixed_time_eq(self.as_ref(), other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> Eq for Hmac<T> {}
|
||||
|
||||
/// Pair of underlying hash engines, used for the inner and outer hash of HMAC.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HmacEngine<T: HashEngine> {
|
||||
|
|
Loading…
Reference in New Issue