1use libc;
8
9#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
10extern {
11 pub fn rust_crypto_util_supports_aesni() -> u32;
12}
13
14#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
15pub fn supports_aesni() -> bool {
16 unsafe {
17 rust_crypto_util_supports_aesni() != 0
18 }
19}
20
21extern {
22 pub fn rust_crypto_util_fixed_time_eq_asm(
23 lhsp: *const u8,
24 rhsp: *const u8,
25 count: libc::size_t) -> u32;
26 pub fn rust_crypto_util_secure_memset(
27 dst: *mut u8,
28 val: libc::uint8_t,
29 count: libc::size_t);
30}
31
32pub fn secure_memset(dst: &mut [u8], val: u8) {
33 unsafe {
34 rust_crypto_util_secure_memset(
35 dst.as_mut_ptr(),
36 val,
37 dst.len() as libc::size_t);
38 }
39}
40
41pub fn fixed_time_eq(lhs: &[u8], rhs: &[u8]) -> bool {
44 if lhs.len() != rhs.len() {
45 false
46 } else {
47 let count = lhs.len() as libc::size_t;
48
49 unsafe {
50 let lhsp = lhs.get_unchecked(0);
51 let rhsp = rhs.get_unchecked(0);
52 rust_crypto_util_fixed_time_eq_asm(lhsp, rhsp, count) == 0
53 }
54 }
55}
56
57#[cfg(test)]
58mod test {
59 use util::fixed_time_eq;
60
61 #[test]
62 pub fn test_fixed_time_eq() {
63 let a = [0, 1, 2];
64 let b = [0, 1, 2];
65 let c = [0, 1, 9];
66 let d = [9, 1, 2];
67 let e = [2, 1, 0];
68 let f = [2, 2, 2];
69 let g = [0, 0, 0];
70
71 assert!(fixed_time_eq(&a, &a));
72 assert!(fixed_time_eq(&a, &b));
73
74 assert!(!fixed_time_eq(&a, &c));
75 assert!(!fixed_time_eq(&a, &d));
76 assert!(!fixed_time_eq(&a, &e));
77 assert!(!fixed_time_eq(&a, &f));
78 assert!(!fixed_time_eq(&a, &g));
79 }
80}