aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <[email protected]>2014-10-01 13:05:42 -0700
committerAlex Crichton <[email protected]>2014-10-01 13:28:56 -0700
commitbe0e83c9788cfea1ef0a422a9b56d11ffdc48da0 (patch)
treefa573ced19393e50d0e8cdeba501abedc8213ece /src
parentMerge pull request #57 from vhbit/mut-cleanup (diff)
downloadrust-openssl-be0e83c9788cfea1ef0a422a9b56d11ffdc48da0.tar.xz
rust-openssl-be0e83c9788cfea1ef0a422a9b56d11ffdc48da0.zip
Add bindings to CRYPTO_memcmp
This should help other projects use a constant-time memory comparison.
Diffstat (limited to 'src')
-rw-r--r--src/crypto/memcmp.rs39
-rw-r--r--src/crypto/mod.rs1
-rw-r--r--src/ffi.rs4
3 files changed, 43 insertions, 1 deletions
diff --git a/src/crypto/memcmp.rs b/src/crypto/memcmp.rs
new file mode 100644
index 00000000..c30281d4
--- /dev/null
+++ b/src/crypto/memcmp.rs
@@ -0,0 +1,39 @@
+use libc::size_t;
+use ffi;
+
+/// Returns `true` iff `a` and `b` contain the same bytes.
+///
+/// This operation takes an amount of time dependent on the length of the two
+/// arrays given, but is independent of the contents of a and b.
+///
+/// # Failure
+///
+/// This function will fail the current task if `a` and `b` do not have the same
+/// length.
+pub fn eq(a: &[u8], b: &[u8]) -> bool {
+ assert!(a.len() == b.len());
+ let ret = unsafe {
+ ffi::CRYPTO_memcmp(a.as_ptr() as *const _,
+ b.as_ptr() as *const _,
+ a.len() as size_t)
+ };
+ ret == 0
+}
+
+#[cfg(test)]
+mod tests {
+ use super::eq;
+
+ #[test]
+ fn test_eq() {
+ assert!(eq([], []));
+ assert!(eq([1], [1]));
+ assert!(!eq([1, 2, 3], [1, 2, 4]));
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_diff_lens() {
+ eq([], [1]);
+ }
+}
diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs
index d7c62f98..e695de33 100644
--- a/src/crypto/mod.rs
+++ b/src/crypto/mod.rs
@@ -21,3 +21,4 @@ pub mod pkcs5;
pub mod pkey;
pub mod rand;
pub mod symm;
+pub mod memcmp;
diff --git a/src/ffi.rs b/src/ffi.rs
index 5a8f753a..b31dc1bb 100644
--- a/src/ffi.rs
+++ b/src/ffi.rs
@@ -1,6 +1,6 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
-use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar};
+use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t};
pub type ASN1_INTEGER = c_void;
pub type ASN1_STRING = c_void;
@@ -265,6 +265,8 @@ extern "C" {
file: *const c_char,
line: c_int));
pub fn CRYPTO_free(buf: *const c_char);
+ pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void,
+ len: size_t) -> c_int;
pub fn ERR_get_error() -> c_ulong;