[hashes] Disable fixed-time equality cmp when building for fuzzers

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.
This commit is contained in:
Matt Corallo 2025-03-26 18:45:13 +00:00
parent 158240c3c9
commit 7ac7273013
1 changed files with 38 additions and 29 deletions

View File

@ -15,41 +15,50 @@
/// As of rust 1.31.0 disassembly looks completely within reason for this, see /// As of rust 1.31.0 disassembly looks completely within reason for this, see
/// <https://godbolt.org/z/mMbGQv>. /// <https://godbolt.org/z/mMbGQv>.
pub fn fixed_time_eq(a: &[u8], b: &[u8]) -> bool { pub fn fixed_time_eq(a: &[u8], b: &[u8]) -> bool {
assert!(a.len() == b.len()); #[cfg(hashes_fuzz)]
let count = a.len(); {
let lhs = &a[..count]; // Fuzzers want to break memcmp calls into separate comparisons for coverage monitoring,
let rhs = &b[..count]; // 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];
let rhs = &b[..count];
let mut r: u8 = 0; let mut r: u8 = 0;
for i in 0..count { for i in 0..count {
let mut rs = unsafe { core::ptr::read_volatile(&r) }; let mut rs = unsafe { core::ptr::read_volatile(&r) };
rs |= lhs[i] ^ rhs[i]; rs |= lhs[i] ^ rhs[i];
unsafe { unsafe {
core::ptr::write_volatile(&mut r, rs); core::ptr::write_volatile(&mut r, rs);
}
} }
} {
{ let mut t = unsafe { core::ptr::read_volatile(&r) };
let mut t = unsafe { core::ptr::read_volatile(&r) }; t |= t >> 4;
t |= t >> 4; unsafe {
unsafe { core::ptr::write_volatile(&mut r, t);
core::ptr::write_volatile(&mut r, t); }
} }
} {
{ let mut t = unsafe { core::ptr::read_volatile(&r) };
let mut t = unsafe { core::ptr::read_volatile(&r) }; t |= t >> 2;
t |= t >> 2; unsafe {
unsafe { core::ptr::write_volatile(&mut r, t);
core::ptr::write_volatile(&mut r, t); }
} }
} {
{ let mut t = unsafe { core::ptr::read_volatile(&r) };
let mut t = unsafe { core::ptr::read_volatile(&r) }; t |= t >> 1;
t |= t >> 1; unsafe {
unsafe { core::ptr::write_volatile(&mut r, t);
core::ptr::write_volatile(&mut r, t); }
} }
unsafe { (::core::ptr::read_volatile(&r) & 1) == 0 }
} }
unsafe { (::core::ptr::read_volatile(&r) & 1) == 0 }
} }
#[cfg(test)] #[cfg(test)]