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(¶ms)?;
+
+ params.0 = Param::from_slice(data);
+ session.invoke(PTA_SYSTEM_ADD_RNG_ENTROPY, ¶ms)?;
+
+ 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),