1 // Copyright 2020 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15 #![cfg(any(not(target_arch = "wasm32"), feature = "wasm32_c"))]
16 use ring::{constant_time, error, rand};
17
18 #[cfg(target_arch = "wasm32")]
19 use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
20
21 #[cfg(target_arch = "wasm32")]
22 wasm_bindgen_test_configure!(run_in_browser);
23
24 // This logic is loosly based on BoringSSL's `TEST(ConstantTimeTest, MemCmp)`.
25 #[test]
26 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm32_c"), wasm_bindgen_test)]
test_verify_slices_are_equal()27 fn test_verify_slices_are_equal() {
28 let initial: [u8; 256] = rand::generate(&rand::SystemRandom::new()).unwrap().expose();
29
30 {
31 let copy = initial;
32 for len in 0..copy.len() {
33 // Not equal because the lengths do not match.
34 assert_eq!(
35 constant_time::verify_slices_are_equal(&initial, ©[..len]),
36 Err(error::Unspecified)
37 );
38 // Equal lengths and equal contents.
39 assert_eq!(
40 constant_time::verify_slices_are_equal(&initial[..len], ©[..len]),
41 Ok(())
42 );
43 }
44 // Equal lengths and equal contents.
45 assert_eq!(
46 constant_time::verify_slices_are_equal(&initial, ©),
47 Ok(())
48 );
49 }
50
51 for i in 0..initial.len() {
52 for bit in 0..8 {
53 let mut copy = initial;
54 copy[i] ^= 1u8 << bit;
55
56 for len in 0..=initial.len() {
57 // We flipped at least one bit in `copy`.
58 assert_ne!(&initial[..], ©[..]);
59
60 let a = &initial[..len];
61 let b = ©[..len];
62
63 let expected_result = if i < len {
64 // The flipped bit is within `b` so `a` and `b` are not equal.
65 Err(error::Unspecified)
66 } else {
67 // The flipped bit is outside of `b` so `a` and `b` are equal.
68 Ok(())
69 };
70 assert_eq!(a == b, expected_result.is_ok()); // Sanity check.
71 assert_eq!(
72 constant_time::verify_slices_are_equal(&a, &b),
73 expected_result
74 );
75 assert_eq!(
76 constant_time::verify_slices_are_equal(&b, &a),
77 expected_result
78 );
79 }
80 }
81 }
82 }
83