crypto: Implement ConstTimeEq

Implement ConstTimeEq using TEE_MemCompare.

Test: make ta + unit test
Change-Id: I88521607186aff294d3023578d95f33f36164f0e
diff --git a/src/crypto.rs b/src/crypto.rs
index ef7b691..c3fe217 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -19,6 +19,7 @@
 use kmr_common::vec_try;
 
 pub mod clock;
+pub mod eq;
 pub mod sha;
 
 #[cfg(feature = "dev")]
diff --git a/src/crypto/eq.rs b/src/crypto/eq.rs
new file mode 100644
index 0000000..3a43ae1
--- /dev/null
+++ b/src/crypto/eq.rs
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use core::ffi::c_void;
+use kmr_common::crypto;
+use optee_utee_sys;
+
+pub struct Eq;
+
+impl crypto::ConstTimeEq for Eq {
+    fn eq(&self, left: &[u8], right: &[u8]) -> bool {
+        if left.len() != right.len() {
+            return false;
+        }
+
+        // OP-TEE implementation of TEE_MemCompare uses consttime_memcmp,
+        // which is constant-time.
+        // SAFETY: both buffers are valid and equal length.
+        let res = unsafe {
+            optee_utee_sys::TEE_MemCompare(
+                left.as_ptr() as *const c_void,
+                right.as_ptr() as *const c_void,
+                left.len() as usize,
+            )
+        };
+
+        res == 0
+    }
+}
diff --git a/src/crypto/tests.rs b/src/crypto/tests.rs
index 49ac694..86a2cb0 100644
--- a/src/crypto/tests.rs
+++ b/src/crypto/tests.rs
@@ -14,7 +14,7 @@
 // limitations under the License.
 
 use hex;
-use kmr_common::crypto::{MonotonicClock, Sha256};
+use kmr_common::crypto::{ConstTimeEq, MonotonicClock, Sha256};
 use log::info;
 
 /// Test basic hardware-backed key derivation functionality.
@@ -38,6 +38,31 @@
     info!("test_clock: Success");
 }
 
+/// Test basic [`ConstTimeEq`] functionality. Does not test the key constant-time property though.
+pub fn test_eq<E: ConstTimeEq>(comparator: E) {
+    let b0 = [];
+    let b1 = [0u8, 1u8, 2u8];
+    let b2 = [1u8, 1u8, 2u8];
+    let b3 = [0u8, 1u8, 3u8];
+    let b4 = [0u8, 1u8, 2u8, 3u8];
+    let b5 = [42; 4096];
+    let mut b6 = [42; 4096];
+    b6[4095] = 43;
+    assert!(comparator.eq(&b0, &b0));
+    assert!(comparator.eq(&b5, &b5));
+    assert!(comparator.ne(&b0, &b1));
+    assert!(comparator.ne(&b0, &b2));
+    assert!(comparator.ne(&b0, &b3));
+    assert!(comparator.ne(&b0, &b4));
+    assert!(comparator.ne(&b0, &b5));
+    assert!(comparator.eq(&b1, &b1));
+    assert!(comparator.ne(&b1, &b2));
+    assert!(comparator.ne(&b1, &b3));
+    assert!(comparator.ne(&b5, &b4));
+    assert!(comparator.ne(&b5, &b6));
+    info!("test_eq: Success");
+}
+
 /// Test basic SHA-256 functionality.
 pub fn test_sha256<S: Sha256>(sha256: S) {
     struct TestCase {
@@ -68,6 +93,8 @@
 
     test_clock(crate::crypto::clock::Clock);
 
+    test_eq(crate::crypto::eq::Eq);
+
     test_sha256(crate::crypto::sha::Sha256 {});
 
     info!("crypto::tests::run: Done");
diff --git a/src/main.rs b/src/main.rs
index c7f4aeb..2f0619d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -72,7 +72,7 @@
             kmr_common::crypto::Implementation {
                 rng: Box::new(kmr_common::crypto::NoOpRng),
                 clock: Some(Box::new(crypto::clock::Clock)),
-                compare: Box::new(kmr_common::crypto::InsecureEq),
+                compare: Box::new(crypto::eq::Eq),
                 aes: Box::new(kmr_common::crypto::NoOpAes),
                 des: Box::new(kmr_common::crypto::NoOpDes),
                 hmac: Box::new(kmr_common::crypto::NoOpHmac),