Coverage Report

Created: 2026-01-27 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-0.10.62/src/memcmp.rs
Line
Count
Source
1
//! Utilities to safely compare cryptographic values.
2
//!
3
//! Extra care must be taken when comparing values in
4
//! cryptographic code. If done incorrectly, it can lead
5
//! to a [timing attack](https://en.wikipedia.org/wiki/Timing_attack).
6
//! By analyzing the time taken to execute parts of a cryptographic
7
//! algorithm, and attacker can attempt to compromise the
8
//! cryptosystem.
9
//!
10
//! The utilities in this module are designed to be resistant
11
//! to this type of attack.
12
//!
13
//! # Examples
14
//!
15
//! To perform a constant-time comparison of two arrays of the same length but different
16
//! values:
17
//!
18
//! ```
19
//! use openssl::memcmp::eq;
20
//!
21
//! // We want to compare `a` to `b` and `c`, without giving
22
//! // away through timing analysis that `c` is more similar to `a`
23
//! // than `b`.
24
//! let a = [0, 0, 0];
25
//! let b = [1, 1, 1];
26
//! let c = [0, 0, 1];
27
//!
28
//! // These statements will execute in the same amount of time.
29
//! assert!(!eq(&a, &b));
30
//! assert!(!eq(&a, &c));
31
//! ```
32
use libc::size_t;
33
use openssl_macros::corresponds;
34
35
/// Returns `true` iff `a` and `b` contain the same bytes.
36
///
37
/// This operation takes an amount of time dependent on the length of the two
38
/// arrays given, but is independent of the contents of a and b.
39
///
40
/// # Panics
41
///
42
/// This function will panic the current task if `a` and `b` do not have the same
43
/// length.
44
///
45
/// # Examples
46
///
47
/// To perform a constant-time comparison of two arrays of the same length but different
48
/// values:
49
///
50
/// ```
51
/// use openssl::memcmp::eq;
52
///
53
/// // We want to compare `a` to `b` and `c`, without giving
54
/// // away through timing analysis that `c` is more similar to `a`
55
/// // than `b`.
56
/// let a = [0, 0, 0];
57
/// let b = [1, 1, 1];
58
/// let c = [0, 0, 1];
59
///
60
/// // These statements will execute in the same amount of time.
61
/// assert!(!eq(&a, &b));
62
/// assert!(!eq(&a, &c));
63
/// ```
64
#[corresponds(CRYPTO_memcmp)]
65
0
pub fn eq(a: &[u8], b: &[u8]) -> bool {
66
0
    assert!(a.len() == b.len());
67
0
    let ret = unsafe {
68
0
        ffi::CRYPTO_memcmp(
69
0
            a.as_ptr() as *const _,
70
0
            b.as_ptr() as *const _,
71
0
            a.len() as size_t,
72
        )
73
    };
74
0
    ret == 0
75
0
}
76
77
#[cfg(test)]
78
mod tests {
79
    use super::eq;
80
81
    #[test]
82
    fn test_eq() {
83
        assert!(eq(&[], &[]));
84
        assert!(eq(&[1], &[1]));
85
        assert!(!eq(&[1, 2, 3], &[1, 2, 4]));
86
    }
87
88
    #[test]
89
    #[should_panic]
90
    fn test_diff_lens() {
91
        eq(&[], &[1]);
92
    }
93
}