     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80

    // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
    // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
    // option. This file may not be copied, modified, or distributed
    // except according to those terms.

    use libc;

    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    extern {
        pub fn rust_crypto_util_supports_aesni() -> u32;
    }

    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    pub fn supports_aesni() -> bool {
        unsafe {
            rust_crypto_util_supports_aesni() != 0
        }
    }

    extern {
        pub fn rust_crypto_util_fixed_time_eq_asm(
                lhsp: *const u8,
                rhsp: *const u8,
                count: libc::size_t) -> u32;
        pub fn rust_crypto_util_secure_memset(
                dst: *mut u8,
                val: libc::uint8_t,
                count: libc::size_t);
    }

    pub fn secure_memset(dst: &mut [u8], val: u8) {
        unsafe {
            rust_crypto_util_secure_memset(
                dst.as_mut_ptr(),
                val,
                dst.len() as libc::size_t);
        }
    }

    /// Compare two vectors using a fixed number of operations. If the two vectors are not of equal
    /// length, the function returns false immediately.
    pub fn fixed_time_eq(lhs: &[u8], rhs: &[u8]) -> bool {
        if lhs.len() != rhs.len() {
            false
        } else {
            let count = lhs.len() as libc::size_t;

            unsafe {
                let lhsp = lhs.get_unchecked(0);
                let rhsp = rhs.get_unchecked(0);
                rust_crypto_util_fixed_time_eq_asm(lhsp, rhsp, count) == 0
            }
        }
    }

    #[cfg(test)]
    mod test {
        use util::fixed_time_eq;

        #[test]
        pub fn test_fixed_time_eq() {
            let a = [0, 1, 2];
            let b = [0, 1, 2];
            let c = [0, 1, 9];
            let d = [9, 1, 2];
            let e = [2, 1, 0];
            let f = [2, 2, 2];
            let g = [0, 0, 0];

            assert!(fixed_time_eq(&a, &a));
            assert!(fixed_time_eq(&a, &b));

            assert!(!fixed_time_eq(&a, &c));
            assert!(!fixed_time_eq(&a, &d));
            assert!(!fixed_time_eq(&a, &e));
            assert!(!fixed_time_eq(&a, &f));
            assert!(!fixed_time_eq(&a, &g));
        }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result
+
  Collapse/expand all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)