diff --git a/.github/workflows/rng256_test.yml b/.github/workflows/rng256_test.yml deleted file mode 100644 index 9860293..0000000 --- a/.github/workflows/rng256_test.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: RNG library tests -on: - push: - paths: - - 'libraries/rng256/**' - pull_request: - types: [opened, synchronize, reopened] - paths: - - 'libraries/rng256/**' - -jobs: - rng256_test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: "true" - - name: Install Rust toolchain - run: rustup show - - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - name: Install Python dependencies - run: python -m pip install --upgrade pip setuptools wheel - - name: Set up OpenSK - run: ./setup.sh - - - name: Unit testing of rng256library (release mode) - uses: actions-rs/cargo@v1 - with: - command: test - args: --manifest-path libraries/rng256/Cargo.toml --release --features std - - - name: Unit testing of rng256 library (debug mode) - uses: actions-rs/cargo@v1 - with: - command: test - args: --manifest-path libraries/rng256/Cargo.toml --features std diff --git a/Cargo.lock b/Cargo.lock index 0920207..1a63227 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -62,15 +53,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "crypto" version = "0.1.0" @@ -78,9 +60,9 @@ dependencies = [ "arrayref", "byteorder", "hex", + "rand_core", "regex", "ring", - "rng256", "serde", "serde_json", "subtle", @@ -102,8 +84,7 @@ dependencies = [ "opensk", "openssl", "persistent_store", - "rand 0.8.5", - "rng256", + "rand_core", "sk-cbor", "uuid", ] @@ -149,12 +130,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "getrandom" version = "0.2.7" @@ -262,8 +237,8 @@ dependencies = [ "ed25519-compact", "openssl", "persistent_store", - "rand 0.8.5", - "rng256", + "rand", + "rand_core", "sk-cbor", "subtle", "uuid", @@ -301,7 +276,7 @@ version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cc", "libc", "pkg-config", @@ -320,9 +295,9 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" @@ -342,25 +317,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] - [[package]] name = "rand" version = "0.8.5" @@ -368,18 +324,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -389,24 +335,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.6.4" @@ -416,77 +347,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "regex" version = "1.6.0" @@ -519,14 +379,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rng256" -version = "0.1.0" -dependencies = [ - "arrayref", - "rand 0.6.5", -] - [[package]] name = "ryu" version = "1.0.11" diff --git a/Cargo.toml b/Cargo.toml index b7766d9..ac45dda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,18 +17,17 @@ lang_items = { path = "third_party/lang-items" } opensk = { path = "libraries/opensk" } sk-cbor = { path = "libraries/cbor" } crypto = { path = "libraries/crypto" } -rng256 = { path = "libraries/rng256" } persistent_store = { path = "libraries/persistent_store" } byteorder = { version = "1", default-features = false } arrayref = "0.3.6" -rand = { version = "0.8.4", optional = true } +rand_core = "0.6.4" ed25519-compact = { version = "1", default-features = false, optional = true } [features] debug_allocations = ["lang_items/debug_allocations"] debug_ctap = ["libtock_drivers/debug_ctap", "opensk/debug_ctap"] panic_console = ["lang_items/panic_console"] -std = ["crypto/std", "lang_items/std", "persistent_store/std", "rng256/std", "rand", "opensk/std"] +std = ["crypto/std", "lang_items/std", "persistent_store/std", "opensk/std"] verbose = ["debug_ctap", "libtock_drivers/verbose_usb"] with_ctap1 = ["crypto/with_ctap1", "opensk/with_ctap1"] with_nfc = ["libtock_drivers/with_nfc"] diff --git a/examples/crypto_bench.rs b/examples/crypto_bench.rs index 97401a8..5972d5c 100644 --- a/examples/crypto_bench.rs +++ b/examples/crypto_bench.rs @@ -21,7 +21,7 @@ use alloc::format; use alloc::vec::Vec; use core::fmt::Write; use crypto::{aes256, cbc, ecdsa, sha256, Hash256}; -use ctap2::env::tock::TockRng256; +use ctap2::env::tock::TockRng; use libtock_drivers::console::Console; use libtock_drivers::result::FlexUnwrap; use libtock_drivers::timer; @@ -36,7 +36,7 @@ fn main() { let mut with_callback = timer::with_callback(|_, _| {}); let timer = with_callback.init().flex_unwrap(); - let mut rng = TockRng256 {}; + let mut rng = TockRng {}; writeln!(console, "****************************************").unwrap(); writeln!( diff --git a/libraries/crypto/Cargo.toml b/libraries/crypto/Cargo.toml index 12944d0..fa1dd42 100644 --- a/libraries/crypto/Cargo.toml +++ b/libraries/crypto/Cargo.toml @@ -10,7 +10,6 @@ license = "Apache-2.0" edition = "2018" [dependencies] -rng256 = { path = "../rng256" } arrayref = "0.3.6" subtle = { version = "2.2.3", default-features = false, features = ["nightly"] } byteorder = { version = "1", default-features = false } @@ -20,7 +19,8 @@ untrusted = { version = "0.7.0", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } serde_json = { version = "=1.0.69", optional = true } regex = { version = "1", optional = true } +rand_core = "0.6.4" [features] -std = ["hex", "ring", "rng256/std", "untrusted", "serde", "serde_json", "regex"] +std = ["hex", "ring", "untrusted", "serde", "serde_json", "regex", "rand_core/getrandom"] with_ctap1 = [] diff --git a/libraries/crypto/src/ec/exponent256.rs b/libraries/crypto/src/ec/exponent256.rs index 8f4a87d..ea703a7 100644 --- a/libraries/crypto/src/ec/exponent256.rs +++ b/libraries/crypto/src/ec/exponent256.rs @@ -14,7 +14,7 @@ use super::int256::{Digit, Int256}; use core::ops::Mul; -use rng256::Rng256; +use rand_core::RngCore; use subtle::{self, Choice, ConditionallySelectable, CtOption}; // An exponent on the elliptic curve, that is an element modulo the curve order N. @@ -112,7 +112,7 @@ impl NonZeroExponentP256 { // Generates a uniformly distributed element 0 < k < N pub fn gen_uniform(r: &mut R) -> NonZeroExponentP256 where - R: Rng256, + R: RngCore, { loop { let x = Int256::gen_uniform_256(r); @@ -293,52 +293,4 @@ pub mod test { assert_eq!(ONE.inv(), ONE); assert_eq!(N_MIN_1.inv(), N_MIN_1); } - - /** RNG **/ - // Mock rng that samples through a list of values, then panics. - struct StressTestingRng { - values: Vec, - index: usize, - } - - impl StressTestingRng { - pub fn new(values: Vec) -> StressTestingRng { - StressTestingRng { values, index: 0 } - } - } - - impl Rng256 for StressTestingRng { - // This function is unused, as we redefine gen_uniform_u32x8. - fn gen_uniform_u8x32(&mut self) -> [u8; 32] { - unreachable!() - } - - fn gen_uniform_u32x8(&mut self) -> [u32; 8] { - let result = self.values[self.index].digits(); - self.index += 1; - result - } - } - - #[test] - fn test_uniform_non_zero_is_below_n() { - let mut rng = StressTestingRng::new(vec![ - Int256::new([ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, - ]), - Int256::N, - N_MIN_1.to_int(), - Int256::N_MIN_2, - ]); - - assert_eq!(NonZeroExponentP256::gen_uniform(&mut rng), N_MIN_1); - } - - #[test] - fn test_uniform_n_is_above_zero() { - let mut rng = StressTestingRng::new(vec![Int256::ZERO]); - - assert_eq!(NonZeroExponentP256::gen_uniform(&mut rng), ONE); - } } diff --git a/libraries/crypto/src/ec/int256.rs b/libraries/crypto/src/ec/int256.rs index 45a7fc3..5455a71 100644 --- a/libraries/crypto/src/ec/int256.rs +++ b/libraries/crypto/src/ec/int256.rs @@ -17,7 +17,7 @@ use alloc::vec::Vec; use arrayref::{array_mut_ref, array_ref}; use byteorder::{BigEndian, ByteOrder}; use core::ops::{Add, AddAssign, Sub, SubAssign}; -use rng256::Rng256; +use rand_core::RngCore; use subtle::{self, Choice, ConditionallySelectable, ConstantTimeEq}; const BITS_PER_DIGIT: usize = 32; @@ -119,11 +119,13 @@ impl Int256 { // Generates a uniformly distributed integer 0 <= x < 2^256 pub fn gen_uniform_256(r: &mut R) -> Int256 where - R: Rng256, + R: RngCore, { - Int256 { - digits: r.gen_uniform_u32x8(), + let mut digits = [0; NDIGITS]; + for i in 0..NDIGITS { + digits[i] = r.next_u32(); } + Int256 { digits } } /** Serialization **/ diff --git a/libraries/crypto/src/ecdh.rs b/libraries/crypto/src/ecdh.rs index d5560de..89adf1f 100644 --- a/libraries/crypto/src/ecdh.rs +++ b/libraries/crypto/src/ecdh.rs @@ -16,7 +16,7 @@ use super::ec::exponent256::NonZeroExponentP256; use super::ec::int256; use super::ec::int256::Int256; use super::ec::point::PointP256; -use rng256::Rng256; +use rand_core::RngCore; pub const NBYTES: usize = int256::NBYTES; @@ -32,7 +32,7 @@ pub struct PubKey { impl SecKey { pub fn gensk(rng: &mut R) -> SecKey where - R: Rng256, + R: RngCore, { SecKey { a: NonZeroExponentP256::gen_uniform(rng), @@ -99,7 +99,7 @@ impl PubKey { #[cfg(test)] mod test { use super::*; - use rng256::ThreadRng256; + use rand_core::OsRng; // Run more test iterations in release mode, as the code should be faster. #[cfg(not(debug_assertions))] @@ -110,7 +110,7 @@ mod test { /** Test that key generation creates valid keys **/ #[test] fn test_gen_pub_is_valid_random() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { let sk = SecKey::gensk(&mut rng); @@ -122,7 +122,7 @@ mod test { /** Test that the exchanged key is the same on both sides **/ #[test] fn test_exchange_x_is_symmetric() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { let sk_a = SecKey::gensk(&mut rng); @@ -135,7 +135,7 @@ mod test { #[test] fn test_exchange_x_bytes_is_symmetric() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { let sk_a = SecKey::gensk(&mut rng); diff --git a/libraries/crypto/src/ecdsa.rs b/libraries/crypto/src/ecdsa.rs index dd5830f..7310824 100644 --- a/libraries/crypto/src/ecdsa.rs +++ b/libraries/crypto/src/ecdsa.rs @@ -24,7 +24,7 @@ use alloc::vec::Vec; use arrayref::array_mut_ref; use arrayref::{array_ref, mut_array_refs}; use core::marker::PhantomData; -use rng256::Rng256; +use rand_core::RngCore; pub const NBYTES: usize = int256::NBYTES; @@ -46,7 +46,7 @@ pub struct PubKey { impl SecKey { pub fn gensk(rng: &mut R) -> SecKey where - R: Rng256, + R: RngCore, { SecKey { k: NonZeroExponentP256::gen_uniform(rng), @@ -67,7 +67,7 @@ impl SecKey { pub fn sign_rng(&self, msg: &[u8], rng: &mut R) -> Signature where H: Hash256, - R: Rng256, + R: RngCore, { let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg))); @@ -347,7 +347,7 @@ where mod test { use super::super::sha256::Sha256; use super::*; - use rng256::ThreadRng256; + use rand_core::OsRng; // Run more test iterations in release mode, as the code should be faster. #[cfg(not(debug_assertions))] @@ -355,10 +355,16 @@ mod test { #[cfg(debug_assertions)] const ITERATIONS: u32 = 500; + fn gen_random_message(rng: &mut impl RngCore) -> [u8; 32] { + let mut bytes = [0; 32]; + rng.fill_bytes(&mut bytes); + bytes + } + /** Test that key generation creates valid keys **/ #[test] fn test_genpk_is_valid_random() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { let sk = SecKey::gensk(&mut rng); @@ -370,7 +376,7 @@ mod test { /** Serialization **/ #[test] fn test_seckey_to_bytes_from_bytes() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { let sk = SecKey::gensk(&mut rng); @@ -461,10 +467,10 @@ mod test { // Test that signed message hashes are correctly verified. #[test] fn test_sign_rfc6979_verify_hash_random() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { - let msg = rng.gen_uniform_u8x32(); + let msg = gen_random_message(&mut rng); let sk = SecKey::gensk(&mut rng); let pk = sk.genpk(); let sign = sk.sign_rfc6979::(&msg); @@ -476,10 +482,10 @@ mod test { // Test that signed messages are correctly verified. #[test] fn test_sign_rfc6979_verify_random() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { - let msg = rng.gen_uniform_u8x32(); + let msg = gen_random_message(&mut rng); let sk = SecKey::gensk(&mut rng); let pk = sk.genpk(); let sign = sk.sign_rfc6979::(&msg); @@ -490,10 +496,10 @@ mod test { // Test that signed messages are correctly verified. #[test] fn test_sign_verify_random() { - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { - let msg = rng.gen_uniform_u8x32(); + let msg = gen_random_message(&mut rng); let sk = SecKey::gensk(&mut rng); let pk = sk.genpk(); let sign = sk.sign_rng::(&msg, &mut rng); @@ -578,10 +584,10 @@ mod test { fn test_self_sign_ring_verify() { use ring::signature::VerificationAlgorithm; - let mut rng = ThreadRng256 {}; + let mut rng = OsRng::default(); for _ in 0..ITERATIONS { - let msg_bytes = rng.gen_uniform_u8x32(); + let msg_bytes = gen_random_message(&mut rng); let sk = SecKey::gensk(&mut rng); let pk = sk.genpk(); let sign = sk.sign_rng::(&msg_bytes, &mut rng); diff --git a/libraries/opensk/Cargo.toml b/libraries/opensk/Cargo.toml index c469a74..ba80814 100644 --- a/libraries/opensk/Cargo.toml +++ b/libraries/opensk/Cargo.toml @@ -14,16 +14,15 @@ rust-version = "1.47" [dependencies] sk-cbor = { path = "../cbor" } crypto = { path = "../crypto" } -rng256 = { path = "../rng256" } persistent_store = { path = "../persistent_store" } byteorder = { version = "1", default-features = false } arrayref = "0.3.6" subtle = { version = "2.2", default-features = false, features = ["nightly"] } arbitrary = { version = "0.4.7", features = ["derive"], optional = true } -rand = { version = "0.8.4", optional = true } ed25519-compact = { version = "1", default-features = false, optional = true } p256 = { version = "0.13.0", features = ["ecdh"], optional = true } -rand_core = { version = "0.6.4", optional = true } +rand_core = "0.6.4" +rand = { version = "0.8.5", optional = true } sha2 = { version = "0.10.6", optional = true } hmac = { version = "0.12.1", optional = true } hkdf = { version = "0.12.3", optional = true } @@ -32,12 +31,12 @@ cbc = { version = "0.1.2", optional = true } [features] debug_ctap = [] -std = ["crypto/std", "persistent_store/std", "rng256/std", "rand"] +std = ["crypto/std", "persistent_store/std", "rand"] with_ctap1 = ["crypto/with_ctap1"] vendor_hid = [] fuzz = ["arbitrary", "std"] ed25519 = ["ed25519-compact"] -rust_crypto = ["p256", "rand_core", "sha2", "hmac", "hkdf", "aes", "cbc"] +rust_crypto = ["p256", "sha2", "hmac", "hkdf", "aes", "cbc"] [dev-dependencies] enum-iterator = "0.6.0" diff --git a/libraries/opensk/fuzz/fuzz_helper/Cargo.toml b/libraries/opensk/fuzz/fuzz_helper/Cargo.toml index 09ae13d..6e00633 100644 --- a/libraries/opensk/fuzz/fuzz_helper/Cargo.toml +++ b/libraries/opensk/fuzz/fuzz_helper/Cargo.toml @@ -9,6 +9,5 @@ edition = "2018" arrayref = "0.3.6" opensk = { path = "../..", features = ["fuzz"] } crypto = { path = "../../../crypto", features = ['std'] } -rng256 = { path = "../../../rng256", features = ['std'] } sk-cbor = { path = "../../../cbor" } arbitrary = { version = "0.4.7", features = ["derive"] } diff --git a/libraries/opensk/fuzz/fuzz_helper/src/lib.rs b/libraries/opensk/fuzz/fuzz_helper/src/lib.rs index ba0f1b2..cab68a5 100644 --- a/libraries/opensk/fuzz/fuzz_helper/src/lib.rs +++ b/libraries/opensk/fuzz/fuzz_helper/src/lib.rs @@ -137,7 +137,7 @@ pub fn process_ctap_any_type(data: &[u8]) -> arbitrary::Result<()> { let mut unstructured = Unstructured::new(data); let mut env = TestEnv::default(); - env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?); + env.seed_rng_from_u64(u64::arbitrary(&mut unstructured)?); let data = unstructured.take_rest(); // Initialize ctap state and hid and get the allocated cid. @@ -184,7 +184,7 @@ pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) -> arbitra let mut unstructured = Unstructured::new(data); let mut env = TestEnv::default(); - env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?); + env.seed_rng_from_u64(u64::arbitrary(&mut unstructured)?); let data = unstructured.take_rest(); if !is_type(data, input_type) { @@ -218,7 +218,7 @@ pub fn process_ctap_structured(data: &[u8], input_type: InputType) -> FuzzResult let unstructured = &mut Unstructured::new(data); let mut env = TestEnv::default(); - env.rng().seed_from_u64(u64::arbitrary(unstructured)?); + env.seed_rng_from_u64(u64::arbitrary(unstructured)?); setup_customization(unstructured, env.customization_mut())?; let mut state = CtapState::new(&mut env); @@ -255,7 +255,7 @@ pub fn split_assemble_hid_packets(data: &[u8]) -> arbitrary::Result<()> { let mut unstructured = Unstructured::new(data); let mut env = TestEnv::default(); - env.rng().seed_from_u64(u64::arbitrary(&mut unstructured)?); + env.seed_rng_from_u64(u64::arbitrary(&mut unstructured)?); let data = unstructured.take_rest(); let message = raw_to_message(data); diff --git a/libraries/opensk/src/api/crypto/ecdh.rs b/libraries/opensk/src/api/crypto/ecdh.rs index ecd5b89..5e47a51 100644 --- a/libraries/opensk/src/api/crypto/ecdh.rs +++ b/libraries/opensk/src/api/crypto/ecdh.rs @@ -13,7 +13,7 @@ // limitations under the License. use super::EC_FIELD_SIZE; -use rng256::Rng256; +use crate::api::rng::Rng; /// Container for all ECDH cryptographic material. pub trait Ecdh { @@ -28,7 +28,7 @@ pub trait SecretKey { type SharedSecret: SharedSecret; /// Generates a new random secret key. - fn random(rng: &mut impl Rng256) -> Self; + fn random(rng: &mut impl Rng) -> Self; /// Computes the corresponding public key for this private key. fn public_key(&self) -> Self::PublicKey; diff --git a/libraries/opensk/src/api/crypto/ecdsa.rs b/libraries/opensk/src/api/crypto/ecdsa.rs index c0cdf8d..ea3b588 100644 --- a/libraries/opensk/src/api/crypto/ecdsa.rs +++ b/libraries/opensk/src/api/crypto/ecdsa.rs @@ -13,8 +13,8 @@ // limitations under the License. use super::{EC_FIELD_SIZE, EC_SIGNATURE_SIZE}; +use crate::api::rng::Rng; use alloc::vec::Vec; -use rng256::Rng256; /// Container for all ECDSA cryptographic material. pub trait Ecdsa { @@ -29,7 +29,7 @@ pub trait SecretKey: Sized { type Signature: Signature; /// Generates a new random secret key. - fn random(rng: &mut impl Rng256) -> Self; + fn random(rng: &mut impl Rng) -> Self; /// Creates a signing key from its representation in bytes. fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option; diff --git a/libraries/opensk/src/api/crypto/mod.rs b/libraries/opensk/src/api/crypto/mod.rs index 006ad4b..fc752ac 100644 --- a/libraries/opensk/src/api/crypto/mod.rs +++ b/libraries/opensk/src/api/crypto/mod.rs @@ -72,6 +72,7 @@ mod test { use crate::api::crypto::ecdh::{PublicKey as _, SecretKey as _, SharedSecret}; use crate::api::crypto::ecdsa::{PublicKey as _, SecretKey as _}; use crate::env::test::TestEnv; + use crate::env::Env; use core::convert::TryFrom; #[test] @@ -143,7 +144,7 @@ mod test { assert!(SoftwareHmac256::verify_truncated_left( &key, &data, - &truncated_mac + truncated_mac )); } diff --git a/libraries/opensk/src/api/crypto/rust_crypto.rs b/libraries/opensk/src/api/crypto/rust_crypto.rs index efdf284..eaacc54 100644 --- a/libraries/opensk/src/api/crypto/rust_crypto.rs +++ b/libraries/opensk/src/api/crypto/rust_crypto.rs @@ -28,6 +28,7 @@ use crate::api::crypto::{ ecdh, ecdsa, Crypto, AES_BLOCK_SIZE, AES_KEY_SIZE, EC_FIELD_SIZE, EC_SIGNATURE_SIZE, HASH_SIZE, HMAC_KEY_SIZE, TRUNCATED_HMAC_SIZE, }; +use crate::api::rng::Rng; use aes::cipher::generic_array::GenericArray; use aes::cipher::{ BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, KeyInit, KeyIvInit, @@ -38,9 +39,6 @@ use p256::ecdh::EphemeralSecret; use p256::ecdsa::signature::{SignatureEncoding, Signer, Verifier}; use p256::ecdsa::{SigningKey, VerifyingKey}; use p256::elliptic_curve::sec1::ToEncodedPoint; -// TODO: implement CryptoRngCore for our Rng instead -use rand_core::OsRng; -use rng256::Rng256; use sha2::Digest; pub struct SoftwareCrypto; @@ -70,8 +68,8 @@ impl ecdh::SecretKey for SoftwareEcdhSecretKey { type PublicKey = SoftwareEcdhPublicKey; type SharedSecret = SoftwareEcdhSharedSecret; - fn random(_rng: &mut impl Rng256) -> Self { - let ephemeral_secret = EphemeralSecret::random(&mut OsRng); + fn random(rng: &mut impl Rng) -> Self { + let ephemeral_secret = EphemeralSecret::random(rng); Self { ephemeral_secret } } @@ -131,8 +129,8 @@ impl ecdsa::SecretKey for SoftwareEcdsaSecretKey { type PublicKey = SoftwareEcdsaPublicKey; type Signature = SoftwareEcdsaSignature; - fn random(_rng: &mut impl Rng256) -> Self { - let signing_key = SigningKey::random(&mut OsRng); + fn random(rng: &mut impl Rng) -> Self { + let signing_key = SigningKey::random(rng); SoftwareEcdsaSecretKey { signing_key } } @@ -273,7 +271,7 @@ pub struct SoftwareAes256 { impl Aes256 for SoftwareAes256 { fn new(key: &[u8; AES_KEY_SIZE]) -> Self { - SoftwareAes256 { key: key.clone() } + SoftwareAes256 { key: *key } } fn encrypt_block(&self, block: &mut [u8; AES_BLOCK_SIZE]) { diff --git a/libraries/opensk/src/api/crypto/software_crypto.rs b/libraries/opensk/src/api/crypto/software_crypto.rs index 7052cb9..71d4c2d 100644 --- a/libraries/opensk/src/api/crypto/software_crypto.rs +++ b/libraries/opensk/src/api/crypto/software_crypto.rs @@ -20,9 +20,9 @@ use crate::api::crypto::{ ecdh, ecdsa, Crypto, AES_BLOCK_SIZE, AES_KEY_SIZE, EC_FIELD_SIZE, EC_SIGNATURE_SIZE, HASH_SIZE, HMAC_KEY_SIZE, TRUNCATED_HMAC_SIZE, }; +use crate::api::rng::Rng; use alloc::vec::Vec; use crypto::Hash256; -use rng256::Rng256; pub struct SoftwareCrypto; pub struct SoftwareEcdh; @@ -51,7 +51,7 @@ impl ecdh::SecretKey for SoftwareEcdhSecretKey { type PublicKey = SoftwareEcdhPublicKey; type SharedSecret = SoftwareEcdhSharedSecret; - fn random(rng: &mut impl Rng256) -> Self { + fn random(rng: &mut impl Rng) -> Self { let sec_key = crypto::ecdh::SecKey::gensk(rng); Self { sec_key } } @@ -105,7 +105,7 @@ impl ecdsa::SecretKey for SoftwareEcdsaSecretKey { type PublicKey = SoftwareEcdsaPublicKey; type Signature = SoftwareEcdsaSignature; - fn random(rng: &mut impl Rng256) -> Self { + fn random(rng: &mut impl Rng) -> Self { let sec_key = crypto::ecdsa::SecKey::gensk(rng); Self { sec_key } } diff --git a/libraries/opensk/src/api/key_store.rs b/libraries/opensk/src/api/key_store.rs index 14438cb..96b3ae4 100644 --- a/libraries/opensk/src/api/key_store.rs +++ b/libraries/opensk/src/api/key_store.rs @@ -13,10 +13,10 @@ // limitations under the License. use crate::api::crypto::ecdsa::SecretKey as _; +use crate::api::rng::Rng; use crate::env::{EcdsaSk, Env}; use alloc::vec::Vec; use persistent_store::StoreError; -use rng256::Rng256; /// Provides storage for secret keys. /// diff --git a/libraries/opensk/src/api/mod.rs b/libraries/opensk/src/api/mod.rs index 414e6bc..a15c0ec 100644 --- a/libraries/opensk/src/api/mod.rs +++ b/libraries/opensk/src/api/mod.rs @@ -24,5 +24,6 @@ pub mod crypto; pub mod customization; pub mod firmware_protection; pub mod key_store; +pub mod rng; pub mod upgrade_storage; pub mod user_presence; diff --git a/libraries/opensk/src/api/rng.rs b/libraries/opensk/src/api/rng.rs new file mode 100644 index 0000000..a7c7516 --- /dev/null +++ b/libraries/opensk/src/api/rng.rs @@ -0,0 +1,30 @@ +// Copyright 2023 Google LLC +// +// 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 rand_core::{CryptoRng, RngCore}; + +/// Random number generator. +/// +/// Reuses the common API from `RngCore`. Implementing the marker trait `CryptoRng` asserts that +/// your random output is usable for sensitive key material. +pub trait Rng: CryptoRng + RngCore { + /// Provides a random byte array. + /// + /// This is a convenience function, as CTAP often requires such keys or tokens. + fn gen_uniform_u8x32(&mut self) -> [u8; 32] { + let mut bytes = [0; 32]; + self.fill_bytes(&mut bytes); + bytes + } +} diff --git a/libraries/opensk/src/ctap/client_pin.rs b/libraries/opensk/src/ctap/client_pin.rs index d165007..5d76f64 100644 --- a/libraries/opensk/src/ctap/client_pin.rs +++ b/libraries/opensk/src/ctap/client_pin.rs @@ -116,8 +116,8 @@ pub struct ClientPin { impl ClientPin { pub fn new(env: &mut E) -> Self { ClientPin { - pin_protocol_v1: PinProtocol::new(env.rng()), - pin_protocol_v2: PinProtocol::new(env.rng()), + pin_protocol_v1: PinProtocol::new(env), + pin_protocol_v2: PinProtocol::new(env), consecutive_pin_mismatches: 0, pin_uv_auth_token_state: PinUvAuthTokenState::new(), } @@ -176,7 +176,7 @@ impl ClientPin { if !bool::from(pin_hash.ct_eq(&pin_hash_dec)) { self.get_mut_pin_protocol(pin_uv_auth_protocol) - .regenerate(env.rng()); + .regenerate(env); if storage::pin_retries(env)? == 0 { return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED); } @@ -278,8 +278,8 @@ impl ClientPin { self.verify_pin_hash_enc(env, pin_uv_auth_protocol, &shared_secret, pin_hash_enc)?; check_and_store_new_pin(env, &shared_secret, new_pin_enc)?; - self.pin_protocol_v1.reset_pin_uv_auth_token(env.rng()); - self.pin_protocol_v2.reset_pin_uv_auth_token(env.rng()); + self.pin_protocol_v1.reset_pin_uv_auth_token(env); + self.pin_protocol_v2.reset_pin_uv_auth_token(env); Ok(()) } @@ -311,13 +311,13 @@ impl ClientPin { return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID); } - self.pin_protocol_v1.reset_pin_uv_auth_token(env.rng()); - self.pin_protocol_v2.reset_pin_uv_auth_token(env.rng()); + self.pin_protocol_v1.reset_pin_uv_auth_token(env); + self.pin_protocol_v2.reset_pin_uv_auth_token(env); self.pin_uv_auth_token_state .begin_using_pin_uv_auth_token(env); self.pin_uv_auth_token_state.set_default_permissions(); let pin_uv_auth_token = shared_secret.encrypt( - env.rng(), + env, self.get_pin_protocol(pin_uv_auth_protocol) .get_pin_uv_auth_token(), )?; @@ -434,10 +434,10 @@ impl ClientPin { /// Resets all held state. pub fn reset(&mut self, env: &mut E) { - self.pin_protocol_v1.regenerate(env.rng()); - self.pin_protocol_v1.reset_pin_uv_auth_token(env.rng()); - self.pin_protocol_v2.regenerate(env.rng()); - self.pin_protocol_v2.reset_pin_uv_auth_token(env.rng()); + self.pin_protocol_v1.regenerate(env); + self.pin_protocol_v1.reset_pin_uv_auth_token(env); + self.pin_protocol_v2.regenerate(env); + self.pin_protocol_v2.reset_pin_uv_auth_token(env); self.consecutive_pin_mismatches = 0; self.pin_uv_auth_token_state.stop_using_pin_uv_auth_token(); } @@ -476,7 +476,7 @@ impl ClientPin { let mut output2 = Hmac::::mac(cred_random, &decrypted_salts[32..]).to_vec(); output.append(&mut output2); } - shared_secret.encrypt(env.rng(), &output) + shared_secret.encrypt(env, &output) } /// Consumes flags and permissions related to the pinUvAuthToken. @@ -563,8 +563,8 @@ impl ClientPin { pin_uv_auth_token_state.set_permissions(0xFF); pin_uv_auth_token_state.begin_using_pin_uv_auth_token(env); Self { - pin_protocol_v1: PinProtocol::::new_test(key_agreement_key_v1, pin_uv_auth_token), - pin_protocol_v2: PinProtocol::::new_test(key_agreement_key_v2, pin_uv_auth_token), + pin_protocol_v1: PinProtocol::new_test(key_agreement_key_v1, pin_uv_auth_token), + pin_protocol_v2: PinProtocol::new_test(key_agreement_key_v2, pin_uv_auth_token), consecutive_pin_mismatches: 0, pin_uv_auth_token_state, } @@ -594,7 +594,7 @@ mod test { let mut env = TestEnv::default(); let mut padded_pin = [0u8; 64]; padded_pin[..pin.len()].copy_from_slice(&pin[..]); - shared_secret.encrypt(env.rng(), &padded_pin).unwrap() + shared_secret.encrypt(&mut env, &padded_pin).unwrap() } /// Generates a ClientPin instance and a shared secret for testing. @@ -638,9 +638,9 @@ mod test { let mut padded_pin = [0u8; 64]; padded_pin[..pin.len()].copy_from_slice(&pin[..]); let pin_hash = Sha::::digest(&padded_pin); - let new_pin_enc = shared_secret.encrypt(env.rng(), &padded_pin).unwrap(); + let new_pin_enc = shared_secret.encrypt(&mut env, &padded_pin).unwrap(); let pin_uv_auth_param = shared_secret.authenticate(&new_pin_enc); - let pin_hash_enc = shared_secret.encrypt(env.rng(), &pin_hash[..16]).unwrap(); + let pin_hash_enc = shared_secret.encrypt(&mut env, &pin_hash[..16]).unwrap(); let (permissions, permissions_rp_id) = match sub_command { ClientPinSubCommand::GetPinUvAuthTokenUsingUvWithPermissions | ClientPinSubCommand::GetPinUvAuthTokenUsingPinWithPermissions => { @@ -679,30 +679,30 @@ mod test { let shared_secret_v2 = pin_protocol_v2 .decapsulate(pin_protocol_v2.get_public_key(), PinUvAuthProtocol::V2) .unwrap(); - let ciphertext = shared_secret_v1.encrypt(env.rng(), &message).unwrap(); + let ciphertext = shared_secret_v1.encrypt(&mut env, &message).unwrap(); let plaintext = shared_secret_v2.decrypt(&ciphertext).unwrap(); assert_ne!(&message, &plaintext); - let ciphertext = shared_secret_v2.encrypt(env.rng(), &message).unwrap(); + let ciphertext = shared_secret_v2.encrypt(&mut env, &message).unwrap(); let plaintext = shared_secret_v1.decrypt(&ciphertext).unwrap(); assert_ne!(&message, &plaintext); let fake_secret_v1 = pin_protocol_v1 .decapsulate(pin_protocol_v2.get_public_key(), PinUvAuthProtocol::V1) .unwrap(); - let ciphertext = shared_secret_v1.encrypt(env.rng(), &message).unwrap(); + let ciphertext = shared_secret_v1.encrypt(&mut env, &message).unwrap(); let plaintext = fake_secret_v1.decrypt(&ciphertext).unwrap(); assert_ne!(&message, &plaintext); - let ciphertext = fake_secret_v1.encrypt(env.rng(), &message).unwrap(); + let ciphertext = fake_secret_v1.encrypt(&mut env, &message).unwrap(); let plaintext = shared_secret_v1.decrypt(&ciphertext).unwrap(); assert_ne!(&message, &plaintext); let fake_secret_v2 = pin_protocol_v2 .decapsulate(pin_protocol_v1.get_public_key(), PinUvAuthProtocol::V2) .unwrap(); - let ciphertext = shared_secret_v2.encrypt(env.rng(), &message).unwrap(); + let ciphertext = shared_secret_v2.encrypt(&mut env, &message).unwrap(); let plaintext = fake_secret_v2.decrypt(&ciphertext).unwrap(); assert_ne!(&message, &plaintext); - let ciphertext = fake_secret_v2.encrypt(env.rng(), &message).unwrap(); + let ciphertext = fake_secret_v2.encrypt(&mut env, &message).unwrap(); let plaintext = shared_secret_v2.decrypt(&ciphertext).unwrap(); assert_ne!(&message, &plaintext); } @@ -721,7 +721,7 @@ mod test { ]; storage::set_pin(&mut env, &pin_hash, 4).unwrap(); - let pin_hash_enc = shared_secret.encrypt(env.rng(), &pin_hash).unwrap(); + let pin_hash_enc = shared_secret.encrypt(&mut env, &pin_hash).unwrap(); assert_eq!( client_pin.verify_pin_hash_enc( &mut env, @@ -743,7 +743,7 @@ mod test { Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID) ); - let pin_hash_enc = shared_secret.encrypt(env.rng(), &pin_hash).unwrap(); + let pin_hash_enc = shared_secret.encrypt(&mut env, &pin_hash).unwrap(); client_pin.consecutive_pin_mismatches = 3; assert_eq!( client_pin.verify_pin_hash_enc( @@ -1147,7 +1147,7 @@ mod test { fn test_helper_decrypt_pin(pin_uv_auth_protocol: PinUvAuthProtocol) { let mut env = TestEnv::default(); - let pin_protocol = PinProtocol::::new(env.rng()); + let pin_protocol = PinProtocol::::new(&mut env); let shared_secret = pin_protocol .decapsulate(pin_protocol.get_public_key(), pin_uv_auth_protocol) .unwrap(); @@ -1191,7 +1191,7 @@ mod test { fn test_helper_check_and_store_new_pin(pin_uv_auth_protocol: PinUvAuthProtocol) { let mut env = TestEnv::default(); - let pin_protocol = PinProtocol::::new(env.rng()); + let pin_protocol = PinProtocol::::new(&mut env); let shared_secret = pin_protocol .decapsulate(pin_protocol.get_public_key(), pin_uv_auth_protocol) .unwrap(); @@ -1250,7 +1250,7 @@ mod test { let mut env = TestEnv::default(); let (client_pin, shared_secret) = create_client_pin_and_shared_secret(pin_uv_auth_protocol); - let salt_enc = shared_secret.encrypt(env.rng(), &salt).unwrap(); + let salt_enc = shared_secret.encrypt(&mut env, &salt).unwrap(); let salt_auth = shared_secret.authenticate(&salt_enc); let hmac_secret_input = GetAssertionHmacSecretInput { key_agreement: client_pin diff --git a/libraries/opensk/src/ctap/credential_id.rs b/libraries/opensk/src/ctap/credential_id.rs index fd225ac..90c9da2 100644 --- a/libraries/opensk/src/ctap/credential_id.rs +++ b/libraries/opensk/src/ctap/credential_id.rs @@ -179,7 +179,7 @@ pub fn encrypt_to_credential_id( add_padding(&mut payload)?; let aes_key = AesKey::::new(&env.key_store().key_handle_encryption()?); - let encrypted_payload = aes256_cbc_encrypt::(env.rng(), &aes_key, &payload, true)?; + let encrypted_payload = aes256_cbc_encrypt(env, &aes_key, &payload, true)?; let mut credential_id = encrypted_payload; credential_id.insert(0, CBOR_CREDENTIAL_ID_VERSION); @@ -380,7 +380,7 @@ mod test { /// This is a copy of the function that genereated deprecated key handles. fn legacy_encrypt_to_credential_id( - env: &mut impl Env, + env: &mut TestEnv, private_key: EcdsaSk, application: &[u8; 32], ) -> Result, Ctap2StatusCode> { @@ -389,8 +389,7 @@ mod test { private_key.to_slice(array_mut_ref!(plaintext, 0, 32)); plaintext[32..64].copy_from_slice(application); - let mut encrypted_id = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, true)?; + let mut encrypted_id = aes256_cbc_encrypt(env, &aes_key, &plaintext, true)?; let id_hmac = Hmac::::mac( &env.key_store().key_handle_authentication()?, &encrypted_id[..], diff --git a/libraries/opensk/src/ctap/credential_management.rs b/libraries/opensk/src/ctap/credential_management.rs index 2ed4ccb..9b6dbde 100644 --- a/libraries/opensk/src/ctap/credential_management.rs +++ b/libraries/opensk/src/ctap/credential_management.rs @@ -359,9 +359,9 @@ mod test { use super::super::CtapState; use super::*; use crate::api::crypto::ecdh::SecretKey as _; + use crate::api::rng::Rng; use crate::env::test::TestEnv; use crate::env::EcdhSk; - use rng256::Rng256; const DUMMY_CHANNEL: Channel = Channel::MainHid([0x12, 0x34, 0x56, 0x78]); diff --git a/libraries/opensk/src/ctap/crypto_wrapper.rs b/libraries/opensk/src/ctap/crypto_wrapper.rs index b308caf..6ab4689 100644 --- a/libraries/opensk/src/ctap/crypto_wrapper.rs +++ b/libraries/opensk/src/ctap/crypto_wrapper.rs @@ -15,19 +15,21 @@ use crate::api::crypto::aes256::Aes256; use crate::api::crypto::ecdsa::{SecretKey as _, Signature}; use crate::api::key_store::KeyStore; +#[cfg(feature = "ed25519")] +use crate::api::rng::Rng; use crate::ctap::data_formats::{extract_array, extract_byte_string, CoseKey, SignatureAlgorithm}; use crate::ctap::status_code::Ctap2StatusCode; use crate::env::{AesKey, EcdsaSk, Env}; use alloc::vec; use alloc::vec::Vec; use core::convert::TryFrom; -use rng256::Rng256; +use rand_core::RngCore; use sk_cbor as cbor; use sk_cbor::{cbor_array, cbor_bytes, cbor_int}; /// Wraps the AES256-CBC encryption to match what we need in CTAP. pub fn aes256_cbc_encrypt( - rng: &mut dyn Rng256, + env: &mut E, aes_key: &AesKey, plaintext: &[u8], embeds_iv: bool, @@ -35,11 +37,10 @@ pub fn aes256_cbc_encrypt( if plaintext.len() % 16 != 0 { return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER); } - // The extra 1 capacity is because encrypt_key_handle adds a version number. - let mut ciphertext = Vec::with_capacity(plaintext.len() + 16 * embeds_iv as usize + 1); + let mut ciphertext = Vec::with_capacity(plaintext.len() + 16 * embeds_iv as usize); let iv = if embeds_iv { - let random_bytes = rng.gen_uniform_u8x32(); - ciphertext.extend_from_slice(&random_bytes[..16]); + ciphertext.resize(16, 0); + env.rng().fill_bytes(&mut ciphertext[..16]); *array_ref!(ciphertext, 0, 16) } else { [0u8; 16] @@ -227,8 +228,7 @@ mod test { let mut env = TestEnv::default(); let aes_key = AesKey::::new(&[0xC2; 32]); let plaintext = vec![0xAA; 64]; - let ciphertext = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, true).unwrap(); + let ciphertext = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, true).unwrap(); let decrypted = aes256_cbc_decrypt::(&aes_key, &ciphertext, true).unwrap(); assert_eq!(decrypted, plaintext); } @@ -238,8 +238,7 @@ mod test { let mut env = TestEnv::default(); let aes_key = AesKey::::new(&[0xC2; 32]); let plaintext = vec![0xAA; 64]; - let ciphertext = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, false).unwrap(); + let ciphertext = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, false).unwrap(); let decrypted = aes256_cbc_decrypt::(&aes_key, &ciphertext, false).unwrap(); assert_eq!(decrypted, plaintext); } @@ -250,7 +249,7 @@ mod test { let aes_key = AesKey::::new(&[0xC2; 32]); let plaintext = vec![0xAA; 64]; let mut ciphertext_no_iv = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, false).unwrap(); + aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, false).unwrap(); let mut ciphertext_with_iv = vec![0u8; 16]; ciphertext_with_iv.append(&mut ciphertext_no_iv); let decrypted = aes256_cbc_decrypt::(&aes_key, &ciphertext_with_iv, true).unwrap(); @@ -262,8 +261,7 @@ mod test { let mut env = TestEnv::default(); let aes_key = AesKey::::new(&[0xC2; 32]); let plaintext = vec![0xAA; 64]; - let mut ciphertext = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, true).unwrap(); + let mut ciphertext = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, true).unwrap(); let mut expected_plaintext = plaintext; for i in 0..16 { ciphertext[i] ^= 0xBB; @@ -278,10 +276,8 @@ mod test { let mut env = TestEnv::default(); let aes_key = AesKey::::new(&[0xC2; 32]); let plaintext = vec![0xAA; 64]; - let ciphertext1 = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, true).unwrap(); - let ciphertext2 = - aes256_cbc_encrypt::(env.rng(), &aes_key, &plaintext, true).unwrap(); + let ciphertext1 = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, true).unwrap(); + let ciphertext2 = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, true).unwrap(); assert_eq!(ciphertext1.len(), 80); assert_eq!(ciphertext2.len(), 80); // The ciphertext should mutate in all blocks with a different IV. diff --git a/libraries/opensk/src/ctap/data_formats.rs b/libraries/opensk/src/ctap/data_formats.rs index 3889d84..4beb396 100644 --- a/libraries/opensk/src/ctap/data_formats.rs +++ b/libraries/opensk/src/ctap/data_formats.rs @@ -1232,13 +1232,13 @@ mod test { use super::*; use crate::api::crypto::ecdh::PublicKey as _; use crate::api::crypto::ecdsa::PublicKey as _; + use crate::api::rng::Rng; use crate::env::test::TestEnv; - use crate::env::{EcdhPk, EcdsaPk}; + use crate::env::{EcdhPk, EcdsaPk, Env}; use cbor::{ cbor_array, cbor_bool, cbor_bytes, cbor_bytes_lit, cbor_false, cbor_int, cbor_null, cbor_text, cbor_unsigned, }; - use rng256::Rng256; #[test] fn test_extract_unsigned() { diff --git a/libraries/opensk/src/ctap/mod.rs b/libraries/opensk/src/ctap/mod.rs index 9909988..763288f 100644 --- a/libraries/opensk/src/ctap/mod.rs +++ b/libraries/opensk/src/ctap/mod.rs @@ -70,6 +70,7 @@ use crate::api::crypto::hmac256::Hmac256; use crate::api::crypto::sha256::Sha256; use crate::api::customization::Customization; use crate::api::firmware_protection::FirmwareProtection; +use crate::api::rng::Rng; use crate::api::upgrade_storage::UpgradeStorage; use crate::api::user_presence::{UserPresence, UserPresenceError}; use crate::env::{EcdsaSk, Env, Hmac, Sha}; @@ -79,7 +80,7 @@ use alloc::vec; use alloc::vec::Vec; use byteorder::{BigEndian, ByteOrder}; use core::convert::TryFrom; -use rng256::Rng256; +use rand_core::RngCore; use sk_cbor as cbor; use sk_cbor::cbor_map_options; @@ -510,7 +511,7 @@ impl CtapState { env: &mut E, ) -> Result<(), Ctap2StatusCode> { if env.customization().use_signature_counter() { - let increment = env.rng().gen_uniform_u32x8()[0] % 8 + 1; + let increment = env.rng().next_u32() % 8 + 1; storage::incr_global_signature_counter(env, increment)?; } Ok(()) @@ -2414,7 +2415,7 @@ mod test { .unwrap(); let salt = vec![0x01; 32]; - let salt_enc = shared_secret.encrypt(env.rng(), &salt).unwrap(); + let salt_enc = shared_secret.encrypt(&mut env, &salt).unwrap(); let salt_auth = shared_secret.authenticate(&salt_enc); let hmac_secret_input = GetAssertionHmacSecretInput { key_agreement: CoseKey::from_ecdh_public_key(platform_public_key), diff --git a/libraries/opensk/src/ctap/pin_protocol.rs b/libraries/opensk/src/ctap/pin_protocol.rs index 4194369..77fd87c 100644 --- a/libraries/opensk/src/ctap/pin_protocol.rs +++ b/libraries/opensk/src/ctap/pin_protocol.rs @@ -17,6 +17,7 @@ use crate::api::crypto::ecdh::{PublicKey as _, SecretKey as _, SharedSecret as _ use crate::api::crypto::hkdf256::Hkdf256; use crate::api::crypto::hmac256::Hmac256; use crate::api::crypto::sha256::Sha256; +use crate::api::rng::Rng; use crate::ctap::client_pin::PIN_TOKEN_LENGTH; use crate::ctap::crypto_wrapper::{aes256_cbc_decrypt, aes256_cbc_encrypt}; use crate::ctap::data_formats::{CoseKey, PinUvAuthProtocol}; @@ -25,7 +26,6 @@ use crate::ctap::status_code::Ctap2StatusCode; use crate::env::test::TestEnv; use crate::env::{AesKey, EcdhPk, EcdhSk, Env, Hkdf, Hmac, Sha}; use alloc::vec::Vec; -use rng256::Rng256; /// Implements common functions between existing PIN protocols for handshakes. pub struct PinProtocol { @@ -37,9 +37,9 @@ impl PinProtocol { /// This process is run by the authenticator at power-on. /// /// This function implements "initialize" from the specification. - pub fn new(rng: &mut impl Rng256) -> Self { - let key_agreement_key = EcdhSk::::random(rng); - let pin_uv_auth_token = rng.gen_uniform_u8x32(); + pub fn new(env: &mut E) -> Self { + let key_agreement_key = EcdhSk::::random(env.rng()); + let pin_uv_auth_token = env.rng().gen_uniform_u8x32(); PinProtocol { key_agreement_key, pin_uv_auth_token, @@ -47,13 +47,13 @@ impl PinProtocol { } /// Generates a fresh public key. - pub fn regenerate(&mut self, rng: &mut impl Rng256) { - self.key_agreement_key = EcdhSk::::random(rng); + pub fn regenerate(&mut self, env: &mut E) { + self.key_agreement_key = EcdhSk::::random(env.rng()); } /// Generates a fresh pinUvAuthToken. - pub fn reset_pin_uv_auth_token(&mut self, rng: &mut impl Rng256) { - self.pin_uv_auth_token = rng.gen_uniform_u8x32(); + pub fn reset_pin_uv_auth_token(&mut self, env: &mut E) { + self.pin_uv_auth_token = env.rng().gen_uniform_u8x32(); } /// Returns the authenticator’s public key as a CoseKey structure. @@ -138,14 +138,10 @@ impl SharedSecret { } /// Returns the encrypted plaintext. - pub fn encrypt( - &self, - rng: &mut dyn Rng256, - plaintext: &[u8], - ) -> Result, Ctap2StatusCode> { + pub fn encrypt(&self, env: &mut E, plaintext: &[u8]) -> Result, Ctap2StatusCode> { match self { - SharedSecret::V1(s) => s.encrypt(rng, plaintext), - SharedSecret::V2(s) => s.encrypt(rng, plaintext), + SharedSecret::V1(s) => s.encrypt(env, plaintext), + SharedSecret::V2(s) => s.encrypt(env, plaintext), } } @@ -221,8 +217,8 @@ impl SharedSecretV1 { } } - fn encrypt(&self, rng: &mut dyn Rng256, plaintext: &[u8]) -> Result, Ctap2StatusCode> { - aes256_cbc_encrypt::(rng, &self.aes_key, plaintext, false) + fn encrypt(&self, env: &mut E, plaintext: &[u8]) -> Result, Ctap2StatusCode> { + aes256_cbc_encrypt(env, &self.aes_key, plaintext, false) } fn decrypt(&self, ciphertext: &[u8]) -> Result, Ctap2StatusCode> { @@ -254,8 +250,8 @@ impl SharedSecretV2 { } } - fn encrypt(&self, rng: &mut dyn Rng256, plaintext: &[u8]) -> Result, Ctap2StatusCode> { - aes256_cbc_encrypt::(rng, &self.aes_key, plaintext, true) + fn encrypt(&self, env: &mut E, plaintext: &[u8]) -> Result, Ctap2StatusCode> { + aes256_cbc_encrypt(env, &self.aes_key, plaintext, true) } fn decrypt(&self, ciphertext: &[u8]) -> Result, Ctap2StatusCode> { @@ -280,9 +276,9 @@ mod test { #[test] fn test_pin_protocol_public_key() { let mut env = TestEnv::default(); - let mut pin_protocol = PinProtocol::::new(env.rng()); + let mut pin_protocol = PinProtocol::::new(&mut env); let public_key = pin_protocol.get_public_key(); - pin_protocol.regenerate(env.rng()); + pin_protocol.regenerate(&mut env); let new_public_key = pin_protocol.get_public_key(); assert_ne!(public_key, new_public_key); } @@ -290,9 +286,9 @@ mod test { #[test] fn test_pin_protocol_pin_uv_auth_token() { let mut env = TestEnv::default(); - let mut pin_protocol = PinProtocol::::new(env.rng()); + let mut pin_protocol = PinProtocol::::new(&mut env); let token = *pin_protocol.get_pin_uv_auth_token(); - pin_protocol.reset_pin_uv_auth_token(env.rng()); + pin_protocol.reset_pin_uv_auth_token(&mut env); let new_token = pin_protocol.get_pin_uv_auth_token(); assert_ne!(&token, new_token); } @@ -302,7 +298,7 @@ mod test { let mut env = TestEnv::default(); let shared_secret = SharedSecretV1::::new([0x55; 32]); let plaintext = vec![0xAA; 64]; - let ciphertext = shared_secret.encrypt(env.rng(), &plaintext).unwrap(); + let ciphertext = shared_secret.encrypt(&mut env, &plaintext).unwrap(); assert_eq!(shared_secret.decrypt(&ciphertext), Ok(plaintext)); } @@ -338,7 +334,7 @@ mod test { let mut env = TestEnv::default(); let shared_secret = SharedSecretV2::::new([0x55; 32]); let plaintext = vec![0xAA; 64]; - let ciphertext = shared_secret.encrypt(env.rng(), &plaintext).unwrap(); + let ciphertext = shared_secret.encrypt(&mut env, &plaintext).unwrap(); assert_eq!(shared_secret.decrypt(&ciphertext), Ok(plaintext)); } @@ -373,8 +369,8 @@ mod test { #[test] fn test_decapsulate_symmetric() { let mut env = TestEnv::default(); - let pin_protocol1 = PinProtocol::::new(env.rng()); - let pin_protocol2 = PinProtocol::::new(env.rng()); + let pin_protocol1 = PinProtocol::::new(&mut env); + let pin_protocol2 = PinProtocol::::new(&mut env); for &protocol in &[PinUvAuthProtocol::V1, PinUvAuthProtocol::V2] { let shared_secret1 = pin_protocol1 .decapsulate(pin_protocol2.get_public_key(), protocol) @@ -383,7 +379,7 @@ mod test { .decapsulate(pin_protocol1.get_public_key(), protocol) .unwrap(); let plaintext = vec![0xAA; 64]; - let ciphertext = shared_secret1.encrypt(env.rng(), &plaintext).unwrap(); + let ciphertext = shared_secret1.encrypt(&mut env, &plaintext).unwrap(); assert_eq!(plaintext, shared_secret2.decrypt(&ciphertext).unwrap()); } } diff --git a/libraries/opensk/src/ctap/storage.rs b/libraries/opensk/src/ctap/storage.rs index d8577a0..ebe9845 100644 --- a/libraries/opensk/src/ctap/storage.rs +++ b/libraries/opensk/src/ctap/storage.rs @@ -17,6 +17,7 @@ mod key; use crate::api::attestation_store::{self, AttestationStore}; use crate::api::customization::Customization; use crate::api::key_store::KeyStore; +use crate::api::rng::Rng; use crate::ctap::client_pin::PIN_AUTH_LENGTH; use crate::ctap::data_formats::{ extract_array, extract_text_string, PublicKeyCredentialSource, PublicKeyCredentialUserEntity, @@ -31,7 +32,6 @@ use arrayref::array_ref; use core::cmp; use core::convert::TryInto; use persistent_store::{fragment, StoreUpdate}; -use rng256::Rng256; use sk_cbor::cbor_array_vec; /// Wrapper for PIN properties. @@ -626,7 +626,6 @@ mod test { CredentialProtectionPolicy, PublicKeyCredentialSource, PublicKeyCredentialType, }; use crate::env::test::TestEnv; - use rng256::Rng256; fn create_credential_source( env: &mut TestEnv, diff --git a/libraries/opensk/src/env/mod.rs b/libraries/opensk/src/env/mod.rs index 1a37ceb..95bdc7b 100644 --- a/libraries/opensk/src/env/mod.rs +++ b/libraries/opensk/src/env/mod.rs @@ -21,10 +21,10 @@ use crate::api::crypto::Crypto; use crate::api::customization::Customization; use crate::api::firmware_protection::FirmwareProtection; use crate::api::key_store::KeyStore; +use crate::api::rng::Rng; use crate::api::upgrade_storage::UpgradeStorage; use crate::api::user_presence::UserPresence; use persistent_store::{Storage, Store}; -use rng256::Rng256; #[cfg(feature = "std")] pub mod test; @@ -40,7 +40,7 @@ pub type Hkdf = <::Crypto as Crypto>::Hkdf256; /// Describes what CTAP needs to function. pub trait Env { - type Rng: Rng256; + type Rng: Rng; type UserPresence: UserPresence; type Storage: Storage; type KeyStore: KeyStore; diff --git a/libraries/opensk/src/env/test/mod.rs b/libraries/opensk/src/env/test/mod.rs index 208971a..0c03ea3 100644 --- a/libraries/opensk/src/env/test/mod.rs +++ b/libraries/opensk/src/env/test/mod.rs @@ -19,20 +19,20 @@ use crate::api::connection::{HidConnection, SendOrRecvResult, SendOrRecvStatus}; use crate::api::crypto::software_crypto::SoftwareCrypto; use crate::api::customization::DEFAULT_CUSTOMIZATION; use crate::api::firmware_protection::FirmwareProtection; +use crate::api::rng::Rng; use crate::api::user_presence::{UserPresence, UserPresenceResult}; use crate::api::{attestation_store, key_store}; use crate::env::Env; use customization::TestCustomization; use persistent_store::{BufferOptions, BufferStorage, Store}; use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; -use rng256::Rng256; +use rand::SeedableRng; pub mod customization; mod upgrade_storage; pub struct TestEnv { - rng: TestRng256, + rng: TestRng, user_presence: TestUserPresence, store: Store, upgrade_storage: Option, @@ -40,23 +40,9 @@ pub struct TestEnv { clock: TestClock, } -pub struct TestRng256 { - rng: StdRng, -} +pub type TestRng = StdRng; -impl TestRng256 { - pub fn seed_from_u64(&mut self, state: u64) { - self.rng = StdRng::seed_from_u64(state); - } -} - -impl Rng256 for TestRng256 { - fn gen_uniform_u8x32(&mut self) -> [u8; 32] { - let mut result = [Default::default(); 32]; - self.rng.fill(&mut result); - result - } -} +impl Rng for TestRng {} #[derive(Debug, Default, PartialEq)] pub struct TestTimer { @@ -131,9 +117,7 @@ impl HidConnection for TestEnv { impl Default for TestEnv { fn default() -> Self { - let rng = TestRng256 { - rng: StdRng::seed_from_u64(0), - }; + let rng = StdRng::seed_from_u64(0); let user_presence = TestUserPresence { check: Box::new(|| Ok(())), }; @@ -162,8 +146,8 @@ impl TestEnv { &mut self.customization } - pub fn rng(&mut self) -> &mut TestRng256 { - &mut self.rng + pub fn seed_rng_from_u64(&mut self, seed: u64) { + self.rng = StdRng::seed_from_u64(seed); } } @@ -207,7 +191,7 @@ impl AttestationStore for TestEnv { } impl Env for TestEnv { - type Rng = TestRng256; + type Rng = TestRng; type UserPresence = TestUserPresence; type Storage = BufferStorage; type KeyStore = Self; diff --git a/libraries/rng256/Cargo.toml b/libraries/rng256/Cargo.toml deleted file mode 100644 index 26cb5f1..0000000 --- a/libraries/rng256/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "rng256" -version = "0.1.0" -authors = [ - "Fabian Kaczmarczyck ", - "Guillaume Endignoux ", - "Jean-Michel Picod ", -] -license = "Apache-2.0" -edition = "2018" - -[dependencies] -arrayref = "0.3.6" -rand = { version = "0.6.5", optional = true } - -[features] -std = ["rand"] diff --git a/libraries/rng256/src/lib.rs b/libraries/rng256/src/lib.rs deleted file mode 100644 index 2904c29..0000000 --- a/libraries/rng256/src/lib.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2019-2023 Google LLC -// -// 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. - -#![cfg_attr(not(feature = "std"), no_std)] - -use arrayref::array_ref; -#[cfg(feature = "std")] -use rand::Rng; - -// Lightweight RNG trait to generate uniformly distributed 256 bits. -pub trait Rng256 { - fn gen_uniform_u8x32(&mut self) -> [u8; 32]; - - fn gen_uniform_u32x8(&mut self) -> [u32; 8] { - bytes_to_u32(self.gen_uniform_u8x32()) - } -} - -// The TockOS rng driver fills a buffer of bytes, but we need 32-bit words for ECDSA. -// This function does the conversion in safe Rust, using the native endianness to avoid unnecessary -// instructions. -// An unsafe one-line equivalent could be implemented with mem::transmute, but let's use safe Rust -// when possible. -fn bytes_to_u32(bytes: [u8; 32]) -> [u32; 8] { - let mut result: [u32; 8] = [Default::default(); 8]; - for (i, r) in result.iter_mut().enumerate() { - *r = u32::from_ne_bytes(*array_ref![bytes, 4 * i, 4]); - } - result -} - -// For tests on the desktop, we use the cryptographically secure thread rng as entropy source. -#[cfg(feature = "std")] -pub struct ThreadRng256 {} - -#[cfg(feature = "std")] -impl Rng256 for ThreadRng256 { - fn gen_uniform_u8x32(&mut self) -> [u8; 32] { - let mut rng = rand::thread_rng(); - let mut result = [Default::default(); 32]; - rng.fill(&mut result); - result - } -} - -#[cfg(test)] -pub mod test { - use super::*; - - #[test] - fn test_bytes_to_u32() { - // This tests that all bytes of the input are indeed used in the output, once each. - // Otherwise the result of gen_uniform_u32x8 wouldn't be uniformly distributed. - let bytes = b"\x00\x01\x02\x03\x04\x05\x06\x07\ - \x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\ - \x10\x11\x12\x13\x14\x15\x16\x17\ - \x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; - #[cfg(target_endian = "big")] - let expected = [ - 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, 0x18191a1b, - 0x1c1d1e1f, - ]; - #[cfg(target_endian = "little")] - let expected = [ - 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0x13121110, 0x17161514, 0x1b1a1918, - 0x1f1e1d1c, - ]; - - assert_eq!(bytes_to_u32(*bytes), expected); - } -} diff --git a/run_desktop_tests.sh b/run_desktop_tests.sh index 90b0daf..ffaddd7 100755 --- a/run_desktop_tests.sh +++ b/run_desktop_tests.sh @@ -26,9 +26,6 @@ cd ../.. cd libraries/crypto cargo fmt -- --check cd ../.. -cd libraries/rng256 -cargo fmt -- --check -cd ../.. cd libraries/persistent_store cargo fmt -- --check cd ../.. @@ -111,9 +108,6 @@ then cd libraries/cbor cargo test --release cd ../.. - cd libraries/rng256 - cargo test --release --features std - cd ../.. cd libraries/persistent_store cargo test --release --features std cd ../.. @@ -124,9 +118,6 @@ then cd libraries/cbor cargo test cd ../.. - cd libraries/rng256 - cargo test --features std - cd ../.. cd libraries/persistent_store cargo test --features std cd ../.. diff --git a/src/env/tock/mod.rs b/src/env/tock/mod.rs index afa8adf..fbf0cfc 100644 --- a/src/env/tock/mod.rs +++ b/src/env/tock/mod.rs @@ -30,11 +30,12 @@ use opensk::api::connection::{ use opensk::api::crypto::software_crypto::SoftwareCrypto; use opensk::api::customization::{CustomizationImpl, AAGUID_LENGTH, DEFAULT_CUSTOMIZATION}; use opensk::api::firmware_protection::FirmwareProtection; +use opensk::api::rng::Rng; use opensk::api::user_presence::{UserPresence, UserPresenceError, UserPresenceResult}; use opensk::api::{attestation_store, key_store}; use opensk::env::Env; use persistent_store::{StorageResult, Store}; -use rng256::Rng256; +use rand_core::{impls, CryptoRng, Error, RngCore}; mod clock; mod storage; @@ -48,16 +49,31 @@ const TOCK_CUSTOMIZATION: CustomizationImpl = CustomizationImpl { }; /// RNG backed by the TockOS rng driver. -pub struct TockRng256 {} +pub struct TockRng {} -impl Rng256 for TockRng256 { - fn gen_uniform_u8x32(&mut self) -> [u8; 32] { - let mut buf: [u8; 32] = [Default::default(); 32]; - rng::fill_buffer(&mut buf); - buf +impl CryptoRng for TockRng {} + +impl RngCore for TockRng { + fn next_u32(&mut self) -> u32 { + impls::next_u32_via_fill(self) + } + + fn next_u64(&mut self) -> u64 { + impls::next_u64_via_fill(self) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + rng::fill_buffer(dest); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + self.fill_bytes(dest); + Ok(()) } } +impl Rng for TockRng {} + pub struct TockHidConnection { endpoint: UsbEndpoint, } @@ -80,7 +96,7 @@ impl HidConnection for TockHidConnection { } pub struct TockEnv { - rng: TockRng256, + rng: TockRng, store: Store, upgrade_storage: Option, main_connection: TockHidConnection, @@ -102,7 +118,7 @@ impl Default for TockEnv { let store = Store::new(storage).ok().unwrap(); let upgrade_storage = TockUpgradeStorage::new().ok(); TockEnv { - rng: TockRng256 {}, + rng: TockRng {}, store, upgrade_storage, main_connection: TockHidConnection { @@ -239,7 +255,7 @@ impl AttestationStore for TockEnv { } impl Env for TockEnv { - type Rng = TockRng256; + type Rng = TockRng; type UserPresence = Self; type Storage = TockStorage; type KeyStore = Self;