crypto: Implement Rng

Implement Rng using the GP API and use the OP_TEE system
PTA's ADD_RNG_ENTROPY to feed entropy to the system random
number generator.

Test: make ta + unit test
Change-Id: I788785c920f5e7c9b998f3f793651d81d7d2e22f
diff --git a/src/crypto.rs b/src/crypto.rs
index c3fe217..8a5b540 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -20,6 +20,7 @@
 
 pub mod clock;
 pub mod eq;
+pub mod rng;
 pub mod sha;
 
 #[cfg(feature = "dev")]
diff --git a/src/crypto/rng.rs b/src/crypto/rng.rs
new file mode 100644
index 0000000..eeaf435
--- /dev/null
+++ b/src/crypto/rng.rs
@@ -0,0 +1,46 @@
+//
+// 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 crate::invoke::{Param, Ta, PTA_SYSTEM_ADD_RNG_ENTROPY};
+use kmr_common::crypto;
+use optee_utee::Random;
+
+pub struct Rng;
+
+impl Rng {
+    fn add_rng_entropy(&self, data: &[u8]) -> Result<(), kmr_common::Error> {
+        if data.len() == 0 {
+            return Ok(());
+        }
+
+        let mut params = Param::empty();
+        let session = Ta::open_system_pta(&params)?;
+
+        params.0 = Param::from_slice(data);
+        session.invoke(PTA_SYSTEM_ADD_RNG_ENTROPY, &params)?;
+
+        Ok(())
+    }
+}
+
+impl crypto::Rng for Rng {
+    fn add_entropy(&mut self, data: &[u8]) {
+        let _ = self.add_rng_entropy(data);
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        Random::generate(dest);
+    }
+}
diff --git a/src/crypto/tests.rs b/src/crypto/tests.rs
index 86a2cb0..b19cd14 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::{ConstTimeEq, MonotonicClock, Sha256};
+use kmr_common::crypto::{ConstTimeEq, MonotonicClock, Rng, Sha256};
 use log::info;
 
 /// Test basic hardware-backed key derivation functionality.
@@ -38,6 +38,23 @@
     info!("test_clock: Success");
 }
 
+/// Test basic [`Rng`] functionality.
+pub fn test_rng<R: Rng>(rng: &mut R) {
+    let u1 = rng.next_u64();
+    let u2 = rng.next_u64();
+    assert_ne!(u1, u2);
+    let mut b1 = [0u8; 16];
+    let mut b2 = [0u8; 16];
+    rng.fill_bytes(&mut b1);
+    rng.fill_bytes(&mut b2);
+    assert_ne!(b1, b2);
+    rng.add_entropy(&b1);
+    rng.add_entropy(&[]);
+    rng.fill_bytes(&mut b1);
+    assert_ne!(b1, b2);
+    info!("test_rng: Success");
+}
+
 /// Test basic [`ConstTimeEq`] functionality. Does not test the key constant-time property though.
 pub fn test_eq<E: ConstTimeEq>(comparator: E) {
     let b0 = [];
@@ -95,6 +112,9 @@
 
     test_eq(crate::crypto::eq::Eq);
 
+    let mut rng = crate::crypto::rng::Rng;
+    test_rng(&mut rng);
+
     test_sha256(crate::crypto::sha::Sha256 {});
 
     info!("crypto::tests::run: Done");
diff --git a/src/main.rs b/src/main.rs
index 2f0619d..8033a70 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -70,7 +70,7 @@
                 supported_num_of_keys_in_csr: kmr_wire::rpc::MINIMUM_SUPPORTED_KEYS_IN_CSR,
             }),
             kmr_common::crypto::Implementation {
-                rng: Box::new(kmr_common::crypto::NoOpRng),
+                rng: Box::new(crypto::rng::Rng),
                 clock: Some(Box::new(crypto::clock::Clock)),
                 compare: Box::new(crypto::eq::Eq),
                 aes: Box::new(kmr_common::crypto::NoOpAes),