constant_time_tests.rs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. #![cfg(any(not(target_arch = "wasm32"), feature = "wasm32_c"))]
  15. use ring::{constant_time, error, rand};
  16. #[cfg(target_arch = "wasm32")]
  17. use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
  18. #[cfg(target_arch = "wasm32")]
  19. wasm_bindgen_test_configure!(run_in_browser);
  20. // This logic is loosly based on BoringSSL's `TEST(ConstantTimeTest, MemCmp)`.
  21. #[test]
  22. #[cfg_attr(all(target_arch = "wasm32", feature = "wasm32_c"), wasm_bindgen_test)]
  23. fn test_verify_slices_are_equal() {
  24. let initial: [u8; 256] = rand::generate(&rand::SystemRandom::new()).unwrap().expose();
  25. {
  26. let copy = initial;
  27. for len in 0..copy.len() {
  28. // Not equal because the lengths do not match.
  29. assert_eq!(
  30. constant_time::verify_slices_are_equal(&initial, &copy[..len]),
  31. Err(error::Unspecified)
  32. );
  33. // Equal lengths and equal contents.
  34. assert_eq!(
  35. constant_time::verify_slices_are_equal(&initial[..len], &copy[..len]),
  36. Ok(())
  37. );
  38. }
  39. // Equal lengths and equal contents.
  40. assert_eq!(
  41. constant_time::verify_slices_are_equal(&initial, &copy),
  42. Ok(())
  43. );
  44. }
  45. for i in 0..initial.len() {
  46. for bit in 0..8 {
  47. let mut copy = initial;
  48. copy[i] ^= 1u8 << bit;
  49. for len in 0..=initial.len() {
  50. // We flipped at least one bit in `copy`.
  51. assert_ne!(&initial[..], &copy[..]);
  52. let a = &initial[..len];
  53. let b = &copy[..len];
  54. let expected_result = if i < len {
  55. // The flipped bit is within `b` so `a` and `b` are not equal.
  56. Err(error::Unspecified)
  57. } else {
  58. // The flipped bit is outside of `b` so `a` and `b` are equal.
  59. Ok(())
  60. };
  61. assert_eq!(a == b, expected_result.is_ok()); // Sanity check.
  62. assert_eq!(
  63. constant_time::verify_slices_are_equal(&a, &b),
  64. expected_result
  65. );
  66. assert_eq!(
  67. constant_time::verify_slices_are_equal(&b, &a),
  68. expected_result
  69. );
  70. }
  71. }
  72. }
  73. }