]> git.proxmox.com Git - cargo.git/blob - vendor/openssl/src/memcmp.rs
New upstream version 0.40.0
[cargo.git] / vendor / openssl / src / memcmp.rs
1 //! Utilities to safely compare cryptographic values.
2 //!
3 //! Extra care must be taken when comparing values in
4 //! cryptographic code. If done incorrectly, it can lead
5 //! to a [timing attack](https://en.wikipedia.org/wiki/Timing_attack).
6 //! By analyzing the time taken to execute parts of a cryptographic
7 //! algorithm, and attacker can attempt to compromise the
8 //! cryptosystem.
9 //!
10 //! The utilities in this module are designed to be resistant
11 //! to this type of attack.
12 //!
13 //! # Examples
14 //!
15 //! To perform a constant-time comparision of two arrays of the same length but different
16 //! values:
17 //!
18 //! ```
19 //! use openssl::memcmp::eq;
20 //!
21 //! // We want to compare `a` to `b` and `c`, without giving
22 //! // away through timing analysis that `c` is more similar to `a`
23 //! // than `b`.
24 //! let a = [0, 0, 0];
25 //! let b = [1, 1, 1];
26 //! let c = [0, 0, 1];
27 //!
28 //! // These statements will execute in the same amount of time.
29 //! assert!(!eq(&a, &b));
30 //! assert!(!eq(&a, &c));
31 //! ```
32 use ffi;
33 use libc::size_t;
34
35 /// Returns `true` iff `a` and `b` contain the same bytes.
36 ///
37 /// This operation takes an amount of time dependent on the length of the two
38 /// arrays given, but is independent of the contents of a and b.
39 ///
40 /// # Panics
41 ///
42 /// This function will panic the current task if `a` and `b` do not have the same
43 /// length.
44 ///
45 /// # Examples
46 ///
47 /// To perform a constant-time comparision of two arrays of the same length but different
48 /// values:
49 ///
50 /// ```
51 /// use openssl::memcmp::eq;
52 ///
53 /// // We want to compare `a` to `b` and `c`, without giving
54 /// // away through timing analysis that `c` is more similar to `a`
55 /// // than `b`.
56 /// let a = [0, 0, 0];
57 /// let b = [1, 1, 1];
58 /// let c = [0, 0, 1];
59 ///
60 /// // These statements will execute in the same amount of time.
61 /// assert!(!eq(&a, &b));
62 /// assert!(!eq(&a, &c));
63 /// ```
64 pub fn eq(a: &[u8], b: &[u8]) -> bool {
65 assert!(a.len() == b.len());
66 let ret = unsafe {
67 ffi::CRYPTO_memcmp(
68 a.as_ptr() as *const _,
69 b.as_ptr() as *const _,
70 a.len() as size_t,
71 )
72 };
73 ret == 0
74 }
75
76 #[cfg(test)]
77 mod tests {
78 use super::eq;
79
80 #[test]
81 fn test_eq() {
82 assert!(eq(&[], &[]));
83 assert!(eq(&[1], &[1]));
84 assert!(!eq(&[1, 2, 3], &[1, 2, 4]));
85 }
86
87 #[test]
88 #[should_panic]
89 fn test_diff_lens() {
90 eq(&[], &[1]);
91 }
92 }