Replaces Rng256 with new Rng API (#612)
* Replaces the Rng256 with RngCore from rand_core The old trait was designed with our software crypto in mind. We should use a more standard API going forward. - Removes libraries/rng256/ - Ports libraries/crypto/ to rand_core - Moves the used RNG trait to api/ * Use StdRng directy in TestEnv
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<Self>;
|
||||
|
||||
@@ -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
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -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]) {
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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;
|
||||
|
||||
30
libraries/opensk/src/api/rng.rs
Normal file
30
libraries/opensk/src/api/rng.rs
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -116,8 +116,8 @@ pub struct ClientPin<E: Env> {
|
||||
impl<E: Env> ClientPin<E> {
|
||||
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<E: Env> ClientPin<E> {
|
||||
|
||||
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<E: Env> ClientPin<E> {
|
||||
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<E: Env> ClientPin<E> {
|
||||
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<E: Env> ClientPin<E> {
|
||||
|
||||
/// 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<E: Env> ClientPin<E> {
|
||||
let mut output2 = Hmac::<E>::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<E: Env> ClientPin<E> {
|
||||
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::<E>::new_test(key_agreement_key_v1, pin_uv_auth_token),
|
||||
pin_protocol_v2: PinProtocol::<E>::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::<TestEnv>::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::<TestEnv>::new(env.rng());
|
||||
let pin_protocol = PinProtocol::<TestEnv>::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::<TestEnv>::new(env.rng());
|
||||
let pin_protocol = PinProtocol::<TestEnv>::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
|
||||
|
||||
@@ -179,7 +179,7 @@ pub fn encrypt_to_credential_id<E: Env>(
|
||||
add_padding(&mut payload)?;
|
||||
|
||||
let aes_key = AesKey::<E>::new(&env.key_store().key_handle_encryption()?);
|
||||
let encrypted_payload = aes256_cbc_encrypt::<E>(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<TestEnv>,
|
||||
application: &[u8; 32],
|
||||
) -> Result<Vec<u8>, 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::<TestEnv>(env.rng(), &aes_key, &plaintext, true)?;
|
||||
let mut encrypted_id = aes256_cbc_encrypt(env, &aes_key, &plaintext, true)?;
|
||||
let id_hmac = Hmac::<TestEnv>::mac(
|
||||
&env.key_store().key_handle_authentication()?,
|
||||
&encrypted_id[..],
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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<E: Env>(
|
||||
rng: &mut dyn Rng256,
|
||||
env: &mut E,
|
||||
aes_key: &AesKey<E>,
|
||||
plaintext: &[u8],
|
||||
embeds_iv: bool,
|
||||
@@ -35,11 +37,10 @@ pub fn aes256_cbc_encrypt<E: Env>(
|
||||
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::<TestEnv>::new(&[0xC2; 32]);
|
||||
let plaintext = vec![0xAA; 64];
|
||||
let ciphertext =
|
||||
aes256_cbc_encrypt::<TestEnv>(env.rng(), &aes_key, &plaintext, true).unwrap();
|
||||
let ciphertext = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, true).unwrap();
|
||||
let decrypted = aes256_cbc_decrypt::<TestEnv>(&aes_key, &ciphertext, true).unwrap();
|
||||
assert_eq!(decrypted, plaintext);
|
||||
}
|
||||
@@ -238,8 +238,7 @@ mod test {
|
||||
let mut env = TestEnv::default();
|
||||
let aes_key = AesKey::<TestEnv>::new(&[0xC2; 32]);
|
||||
let plaintext = vec![0xAA; 64];
|
||||
let ciphertext =
|
||||
aes256_cbc_encrypt::<TestEnv>(env.rng(), &aes_key, &plaintext, false).unwrap();
|
||||
let ciphertext = aes256_cbc_encrypt(&mut env, &aes_key, &plaintext, false).unwrap();
|
||||
let decrypted = aes256_cbc_decrypt::<TestEnv>(&aes_key, &ciphertext, false).unwrap();
|
||||
assert_eq!(decrypted, plaintext);
|
||||
}
|
||||
@@ -250,7 +249,7 @@ mod test {
|
||||
let aes_key = AesKey::<TestEnv>::new(&[0xC2; 32]);
|
||||
let plaintext = vec![0xAA; 64];
|
||||
let mut ciphertext_no_iv =
|
||||
aes256_cbc_encrypt::<TestEnv>(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::<TestEnv>(&aes_key, &ciphertext_with_iv, true).unwrap();
|
||||
@@ -262,8 +261,7 @@ mod test {
|
||||
let mut env = TestEnv::default();
|
||||
let aes_key = AesKey::<TestEnv>::new(&[0xC2; 32]);
|
||||
let plaintext = vec![0xAA; 64];
|
||||
let mut ciphertext =
|
||||
aes256_cbc_encrypt::<TestEnv>(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::<TestEnv>::new(&[0xC2; 32]);
|
||||
let plaintext = vec![0xAA; 64];
|
||||
let ciphertext1 =
|
||||
aes256_cbc_encrypt::<TestEnv>(env.rng(), &aes_key, &plaintext, true).unwrap();
|
||||
let ciphertext2 =
|
||||
aes256_cbc_encrypt::<TestEnv>(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.
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<E: Env> CtapState<E> {
|
||||
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),
|
||||
|
||||
@@ -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<E: Env> {
|
||||
@@ -37,9 +37,9 @@ impl<E: Env> PinProtocol<E> {
|
||||
/// 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::<E>::random(rng);
|
||||
let pin_uv_auth_token = rng.gen_uniform_u8x32();
|
||||
pub fn new(env: &mut E) -> Self {
|
||||
let key_agreement_key = EcdhSk::<E>::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<E: Env> PinProtocol<E> {
|
||||
}
|
||||
|
||||
/// Generates a fresh public key.
|
||||
pub fn regenerate(&mut self, rng: &mut impl Rng256) {
|
||||
self.key_agreement_key = EcdhSk::<E>::random(rng);
|
||||
pub fn regenerate(&mut self, env: &mut E) {
|
||||
self.key_agreement_key = EcdhSk::<E>::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<E: Env> SharedSecret<E> {
|
||||
}
|
||||
|
||||
/// Returns the encrypted plaintext.
|
||||
pub fn encrypt(
|
||||
&self,
|
||||
rng: &mut dyn Rng256,
|
||||
plaintext: &[u8],
|
||||
) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
pub fn encrypt(&self, env: &mut E, plaintext: &[u8]) -> Result<Vec<u8>, 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<E: Env> SharedSecretV1<E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt(&self, rng: &mut dyn Rng256, plaintext: &[u8]) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
aes256_cbc_encrypt::<E>(rng, &self.aes_key, plaintext, false)
|
||||
fn encrypt(&self, env: &mut E, plaintext: &[u8]) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
aes256_cbc_encrypt(env, &self.aes_key, plaintext, false)
|
||||
}
|
||||
|
||||
fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
@@ -254,8 +250,8 @@ impl<E: Env> SharedSecretV2<E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt(&self, rng: &mut dyn Rng256, plaintext: &[u8]) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
aes256_cbc_encrypt::<E>(rng, &self.aes_key, plaintext, true)
|
||||
fn encrypt(&self, env: &mut E, plaintext: &[u8]) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
aes256_cbc_encrypt(env, &self.aes_key, plaintext, true)
|
||||
}
|
||||
|
||||
fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
@@ -280,9 +276,9 @@ mod test {
|
||||
#[test]
|
||||
fn test_pin_protocol_public_key() {
|
||||
let mut env = TestEnv::default();
|
||||
let mut pin_protocol = PinProtocol::<TestEnv>::new(env.rng());
|
||||
let mut pin_protocol = PinProtocol::<TestEnv>::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::<TestEnv>::new(env.rng());
|
||||
let mut pin_protocol = PinProtocol::<TestEnv>::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::<TestEnv>::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::<TestEnv>::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::<TestEnv>::new(env.rng());
|
||||
let pin_protocol2 = PinProtocol::<TestEnv>::new(env.rng());
|
||||
let pin_protocol1 = PinProtocol::<TestEnv>::new(&mut env);
|
||||
let pin_protocol2 = PinProtocol::<TestEnv>::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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
4
libraries/opensk/src/env/mod.rs
vendored
4
libraries/opensk/src/env/mod.rs
vendored
@@ -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<E> = <<E as Env>::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;
|
||||
|
||||
34
libraries/opensk/src/env/test/mod.rs
vendored
34
libraries/opensk/src/env/test/mod.rs
vendored
@@ -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<BufferStorage>,
|
||||
upgrade_storage: Option<BufferUpgradeStorage>,
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user