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
21#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
22extern {
23 pub fn rust_crypto_util_fixed_time_eq_asm(
24 lhsp: *const u8,
25 rhsp: *const u8,
26 count: libc::size_t) -> u32;
27 pub fn rust_crypto_util_secure_memset(
28 dst: *mut u8,
29 val: libc::uint8_t,
30 count: libc::size_t);
31}
32
33#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
34pub fn secure_memset(dst: &mut [u8], val: u8) {
35 unsafe {
36 rust_crypto_util_secure_memset(
37 dst.as_mut_ptr(),
38 val,
39 dst.len() as libc::size_t);
40 }
41}
42
43#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
46pub fn fixed_time_eq(lhs: &[u8], rhs: &[u8]) -> bool {
47 if lhs.len() != rhs.len() {
48 false
49 } else {
50 let count = lhs.len() as libc::size_t;
51
52 unsafe {
53 let lhsp = lhs.get_unchecked(0);
54 let rhsp = rhs.get_unchecked(0);
55 rust_crypto_util_fixed_time_eq_asm(lhsp, rhsp, count) == 0
56 }
57 }
58}
59
60#[cfg(all(not(target_arch = "x86"), not(target_arch = "x86_64")))]
61pub fn secure_memset(dst: &mut [u8], val: u8) {
62 for i in 0..dst.len() {
63 dst[i] = val;
64 }
65}
66
67#[cfg(all(not(target_arch = "x86"), not(target_arch = "x86_64")))]
70pub fn fixed_time_eq(lhs: &[u8], rhs: &[u8]) -> bool {
71 if lhs.len() != rhs.len() {
72 false
73 } else {
74 let mut v = 0;
75 for i in 0..lhs.len() {
76 let a = lhs[i];
77 let b = rhs[i];
78 v = v | (a ^ b);
79 };
80 v == 0
81 }
82}
83
84#[cfg(test)]
85mod test {
86 use util::fixed_time_eq;
87
88 #[test]
89 pub fn test_fixed_time_eq() {
90 let a = [0, 1, 2];
91 let b = [0, 1, 2];
92 let c = [0, 1, 9];
93 let d = [9, 1, 2];
94 let e = [2, 1, 0];
95 let f = [2, 2, 2];
96 let g = [0, 0, 0];
97
98 assert!(fixed_time_eq(&a, &a));
99 assert!(fixed_time_eq(&a, &b));
100
101 assert!(!fixed_time_eq(&a, &c));
102 assert!(!fixed_time_eq(&a, &d));
103 assert!(!fixed_time_eq(&a, &e));
104 assert!(!fixed_time_eq(&a, &f));
105 assert!(!fixed_time_eq(&a, &g));
106 }
107}