diff --git a/.github/workflows/rng256_test.yml b/.github/workflows/rng256_test.yml new file mode 100644 index 0000000..c81304c --- /dev/null +++ b/.github/workflows/rng256_test.yml @@ -0,0 +1,39 @@ +--- +name: RNG library tests +on: + push: + paths: + - 'libraries/rng256/**' + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'libraries/rng256/**' + +jobs: + rng256_test: + runs-on: ubuntu-18.04 + 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.toml b/Cargo.toml index 19e0c5b..29527e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ libtock_drivers = { path = "third_party/libtock-drivers" } lang_items = { path = "third_party/lang-items" } 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" @@ -29,7 +30,7 @@ rand = { version = "0.8.4", optional = true } debug_allocations = ["lang_items/debug_allocations"] debug_ctap = ["libtock_drivers/debug_ctap"] panic_console = ["lang_items/panic_console"] -std = ["crypto/std", "lang_items/std", "persistent_store/std", "rand"] +std = ["crypto/std", "lang_items/std", "persistent_store/std", "rng256/std", "rand"] verbose = ["debug_ctap", "libtock_drivers/verbose_usb"] with_ctap1 = ["crypto/with_ctap1"] with_nfc = ["libtock_drivers/with_nfc"] diff --git a/examples/crypto_bench.rs b/examples/crypto_bench.rs index 1e99517..2a1bd65 100644 --- a/examples/crypto_bench.rs +++ b/examples/crypto_bench.rs @@ -20,11 +20,12 @@ extern crate lang_items; use alloc::format; use alloc::vec::Vec; use core::fmt::Write; -use crypto::{aes256, cbc, ecdsa, rng256, sha256, Hash256}; +use crypto::{aes256, cbc, ecdsa, sha256, Hash256}; use libtock_drivers::console::Console; use libtock_drivers::result::FlexUnwrap; use libtock_drivers::timer; use libtock_drivers::timer::{Timer, Timestamp}; +use rng256::TockRng256; libtock_core::stack_size! {0x800} @@ -35,7 +36,7 @@ fn main() { let mut with_callback = timer::with_callback(|_, _| {}); let timer = with_callback.init().flex_unwrap(); - let mut rng = rng256::TockRng256 {}; + let mut rng = TockRng256 {}; writeln!(console, "****************************************").unwrap(); writeln!( diff --git a/fuzz/fuzz_helper/Cargo.toml b/fuzz/fuzz_helper/Cargo.toml index 1c23476..219458c 100644 --- a/fuzz/fuzz_helper/Cargo.toml +++ b/fuzz/fuzz_helper/Cargo.toml @@ -10,6 +10,7 @@ arrayref = "0.3.6" embedded-time = "0.12.1" libtock_drivers = { path = "../../third_party/libtock-drivers" } crypto = { path = "../../libraries/crypto", features = ['std'] } +rng256 = { path = "../../libraries/rng256", features = ['std'] } sk-cbor = { path = "../../libraries/cbor" } ctap2 = { path = "../..", features = ["fuzz"] } lang_items = { path = "../../third_party/lang-items", features = ['std'] } diff --git a/libraries/crypto/Cargo.toml b/libraries/crypto/Cargo.toml index 13c7361..4bb5d45 100644 --- a/libraries/crypto/Cargo.toml +++ b/libraries/crypto/Cargo.toml @@ -11,17 +11,17 @@ edition = "2018" [dependencies] libtock_drivers = { path = "../../third_party/libtock-drivers" } +rng256 = { path = "../rng256" } arrayref = "0.3.6" subtle = { version = "2.2.3", default-features = false, features = ["nightly"] } byteorder = { version = "1", default-features = false } hex = { version = "0.3.2", default-features = false, optional = true } ring = { version = "0.16.11", optional = true } untrusted = { version = "0.7.0", optional = true } -rand = { version = "0.6.5", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } serde_json = { version = "=1.0.69", optional = true } regex = { version = "1", optional = true } [features] -std = ["hex", "rand", "ring", "untrusted", "serde", "serde_json", "regex"] +std = ["hex", "ring", "rng256/std", "untrusted", "serde", "serde_json", "regex"] with_ctap1 = [] diff --git a/libraries/crypto/src/ec/exponent256.rs b/libraries/crypto/src/ec/exponent256.rs index 4a31aee..8f4a87d 100644 --- a/libraries/crypto/src/ec/exponent256.rs +++ b/libraries/crypto/src/ec/exponent256.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::super::rng256::Rng256; use super::int256::{Digit, Int256}; use core::ops::Mul; +use rng256::Rng256; use subtle::{self, Choice, ConditionallySelectable, CtOption}; // An exponent on the elliptic curve, that is an element modulo the curve order N. diff --git a/libraries/crypto/src/ec/int256.rs b/libraries/crypto/src/ec/int256.rs index 8927b19..45a7fc3 100644 --- a/libraries/crypto/src/ec/int256.rs +++ b/libraries/crypto/src/ec/int256.rs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::super::rng256::Rng256; use alloc::vec; 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 subtle::{self, Choice, ConditionallySelectable, ConstantTimeEq}; const BITS_PER_DIGIT: usize = 32; diff --git a/libraries/crypto/src/ecdh.rs b/libraries/crypto/src/ecdh.rs index 4a03679..d5560de 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 super::rng256::Rng256; +use rng256::Rng256; pub const NBYTES: usize = int256::NBYTES; @@ -98,8 +98,8 @@ impl PubKey { #[cfg(test)] mod test { - use super::super::rng256::ThreadRng256; use super::*; + use rng256::ThreadRng256; // Run more test iterations in release mode, as the code should be faster. #[cfg(not(debug_assertions))] diff --git a/libraries/crypto/src/ecdsa.rs b/libraries/crypto/src/ecdsa.rs index 89e93a6..1cf48bd 100644 --- a/libraries/crypto/src/ecdsa.rs +++ b/libraries/crypto/src/ecdsa.rs @@ -17,7 +17,6 @@ use super::ec::int256; use super::ec::int256::Int256; use super::ec::point::PointP256; use super::hmac::hmac_256; -use super::rng256::Rng256; use super::Hash256; use alloc::vec; use alloc::vec::Vec; @@ -25,6 +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; pub const NBYTES: usize = int256::NBYTES; @@ -347,9 +347,9 @@ where #[cfg(test)] mod test { - use super::super::rng256::ThreadRng256; use super::super::sha256::Sha256; use super::*; + use rng256::ThreadRng256; // Run more test iterations in release mode, as the code should be faster. #[cfg(not(debug_assertions))] diff --git a/libraries/crypto/src/lib.rs b/libraries/crypto/src/lib.rs index 9f44983..6a8e103 100644 --- a/libraries/crypto/src/lib.rs +++ b/libraries/crypto/src/lib.rs @@ -24,7 +24,6 @@ pub mod ecdh; pub mod ecdsa; pub mod hkdf; pub mod hmac; -pub mod rng256; pub mod sha256; pub mod util; diff --git a/libraries/rng256/Cargo.toml b/libraries/rng256/Cargo.toml new file mode 100644 index 0000000..60d7bad --- /dev/null +++ b/libraries/rng256/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "rng256" +version = "0.1.0" +authors = [ + "Fabian Kaczmarczyck ", + "Guillaume Endignoux ", + "Jean-Michel Picod ", +] +license = "Apache-2.0" +edition = "2018" + +[dependencies] +libtock_drivers = { path = "../../third_party/libtock-drivers" } +arrayref = "0.3.6" +rand = { version = "0.6.5", optional = true } + +[features] +std = ["rand"] diff --git a/libraries/crypto/src/rng256.rs b/libraries/rng256/src/lib.rs similarity index 96% rename from libraries/crypto/src/rng256.rs rename to libraries/rng256/src/lib.rs index 87300b8..398b091 100644 --- a/libraries/crypto/src/rng256.rs +++ b/libraries/rng256/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019-2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,8 +12,12 @@ // 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; use libtock_drivers::rng; +#[cfg(feature = "std")] +use rand::Rng; // Lightweight RNG trait to generate uniformly distributed 256 bits. pub trait Rng256 { @@ -55,8 +59,6 @@ pub struct ThreadRng256 {} #[cfg(feature = "std")] impl Rng256 for ThreadRng256 { fn gen_uniform_u8x32(&mut self) -> [u8; 32] { - use rand::Rng; - let mut rng = rand::thread_rng(); let mut result = [Default::default(); 32]; rng.fill(&mut result); diff --git a/run_desktop_tests.sh b/run_desktop_tests.sh index cbbf43d..74dfa3a 100755 --- a/run_desktop_tests.sh +++ b/run_desktop_tests.sh @@ -23,6 +23,9 @@ cd ../.. cd libraries/crypto cargo fmt --all -- --check cd ../.. +cd libraries/rng256 +cargo fmt --all -- --check +cd ../.. cd libraries/persistent_store cargo fmt --all -- --check cd ../.. @@ -100,6 +103,9 @@ 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 ../.. @@ -109,6 +115,9 @@ 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/ctap/client_pin.rs b/src/ctap/client_pin.rs index 8d4da7e..e7b6361 100644 --- a/src/ctap/client_pin.rs +++ b/src/ctap/client_pin.rs @@ -28,11 +28,11 @@ use alloc::str; use alloc::string::String; use alloc::vec::Vec; use crypto::hmac::hmac_256; -use crypto::rng256::Rng256; use crypto::sha256::Sha256; use crypto::Hash256; #[cfg(test)] use enum_iterator::IntoEnumIterator; +use rng256::Rng256; use subtle::ConstantTimeEq; /// The prefix length of the PIN hash that is stored and compared. diff --git a/src/ctap/credential_management.rs b/src/ctap/credential_management.rs index 10bf954..a2758d3 100644 --- a/src/ctap/credential_management.rs +++ b/src/ctap/credential_management.rs @@ -364,7 +364,7 @@ mod test { use super::super::CtapState; use super::*; use crate::env::test::TestEnv; - use crypto::rng256::Rng256; + use rng256::Rng256; const DUMMY_CHANNEL: Channel = Channel::MainHid([0x12, 0x34, 0x56, 0x78]); diff --git a/src/ctap/crypto_wrapper.rs b/src/ctap/crypto_wrapper.rs index 76c6fb6..1128b90 100644 --- a/src/ctap/crypto_wrapper.rs +++ b/src/ctap/crypto_wrapper.rs @@ -15,7 +15,7 @@ use crate::ctap::status_code::Ctap2StatusCode; use alloc::vec::Vec; use crypto::cbc::{cbc_decrypt, cbc_encrypt}; -use crypto::rng256::Rng256; +use rng256::Rng256; /// Wraps the AES256-CBC encryption to match what we need in CTAP. pub fn aes256_cbc_encrypt( diff --git a/src/ctap/data_formats.rs b/src/ctap/data_formats.rs index ff9d345..8cd820b 100644 --- a/src/ctap/data_formats.rs +++ b/src/ctap/data_formats.rs @@ -1226,8 +1226,8 @@ mod test { cbor_array, cbor_bool, cbor_bytes, cbor_bytes_lit, cbor_false, cbor_int, cbor_null, cbor_text, cbor_unsigned, }; - use crypto::rng256::Rng256; use crypto::sha256::Sha256; + use rng256::Rng256; #[test] fn test_extract_unsigned() { diff --git a/src/ctap/mod.rs b/src/ctap/mod.rs index 2a73544..4553e75 100644 --- a/src/ctap/mod.rs +++ b/src/ctap/mod.rs @@ -77,10 +77,10 @@ use arrayref::array_ref; use byteorder::{BigEndian, ByteOrder}; use core::convert::TryFrom; use crypto::hmac::{hmac_256, verify_hmac_256}; -use crypto::rng256::Rng256; use crypto::sha256::Sha256; use crypto::{ecdsa, Hash256}; use embedded_time::duration::Milliseconds; +use rng256::Rng256; use sk_cbor as cbor; use sk_cbor::cbor_map_options; diff --git a/src/ctap/pin_protocol.rs b/src/ctap/pin_protocol.rs index 10dd9f2..b1831d6 100644 --- a/src/ctap/pin_protocol.rs +++ b/src/ctap/pin_protocol.rs @@ -23,9 +23,9 @@ use crypto::hkdf::hkdf_empty_salt_256; #[cfg(test)] use crypto::hmac::hmac_256; use crypto::hmac::{verify_hmac_256, verify_hmac_256_first_128bits}; -use crypto::rng256::Rng256; use crypto::sha256::Sha256; use crypto::Hash256; +use rng256::Rng256; /// Implements common functions between existing PIN protocols for handshakes. pub struct PinProtocol { diff --git a/src/ctap/storage.rs b/src/ctap/storage.rs index 2130a52..90b8795 100644 --- a/src/ctap/storage.rs +++ b/src/ctap/storage.rs @@ -30,8 +30,8 @@ use alloc::vec::Vec; use arrayref::array_ref; use core::cmp; use core::convert::TryInto; -use crypto::rng256::Rng256; use persistent_store::{fragment, StoreUpdate}; +use rng256::Rng256; use sk_cbor::cbor_array_vec; /// Wrapper for master keys. @@ -729,7 +729,7 @@ mod test { use super::*; use crate::ctap::data_formats::{PublicKeyCredentialSource, PublicKeyCredentialType}; use crate::env::test::TestEnv; - use crypto::rng256::Rng256; + use rng256::Rng256; fn create_credential_source( rng: &mut impl Rng256, diff --git a/src/env/mod.rs b/src/env/mod.rs index f222817..c230192 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -3,8 +3,8 @@ use crate::api::firmware_protection::FirmwareProtection; use crate::api::upgrade_storage::UpgradeStorage; use crate::ctap::status_code::Ctap2StatusCode; use crate::ctap::Channel; -use crypto::rng256::Rng256; use persistent_store::{Storage, Store}; +use rng256::Rng256; #[cfg(feature = "std")] pub mod test; diff --git a/src/env/test/mod.rs b/src/env/test/mod.rs index d96b0c8..a777a37 100644 --- a/src/env/test/mod.rs +++ b/src/env/test/mod.rs @@ -4,11 +4,11 @@ use crate::api::firmware_protection::FirmwareProtection; use crate::ctap::status_code::Ctap2StatusCode; use crate::ctap::Channel; use crate::env::{Env, UserPresence}; -use crypto::rng256::Rng256; use customization::TestCustomization; use persistent_store::{BufferOptions, BufferStorage, Store}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; +use rng256::Rng256; mod customization; mod upgrade_storage; diff --git a/src/env/tock/mod.rs b/src/env/tock/mod.rs index 700fcb1..a835fc8 100644 --- a/src/env/tock/mod.rs +++ b/src/env/tock/mod.rs @@ -7,7 +7,6 @@ use crate::ctap::Channel; use crate::env::{Env, UserPresence}; use core::cell::Cell; use core::sync::atomic::{AtomicBool, Ordering}; -use crypto::rng256::TockRng256; use libtock_core::result::{CommandError, EALREADY}; use libtock_drivers::buttons::{self, ButtonState}; use libtock_drivers::console::Console; @@ -15,6 +14,7 @@ use libtock_drivers::result::{FlexUnwrap, TockError}; use libtock_drivers::timer::Duration; use libtock_drivers::{crp, led, timer, usb_ctap_hid}; use persistent_store::{StorageResult, Store}; +use rng256::TockRng256; mod storage;