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