Use indirection to implement the default KeyStore
This commit is contained in:
@@ -50,7 +50,10 @@ pub struct Error;
|
|||||||
/// Key of the environment store reserved for the key store.
|
/// Key of the environment store reserved for the key store.
|
||||||
pub const STORE_KEY: usize = 2046;
|
pub const STORE_KEY: usize = 2046;
|
||||||
|
|
||||||
impl<T: Env> KeyStore for T {
|
/// Implements a default key store using the environment rng and store.
|
||||||
|
pub trait Helper: Env {}
|
||||||
|
|
||||||
|
impl<T: Helper> KeyStore for T {
|
||||||
fn key_handle_encryption(&mut self) -> Result<[u8; 32], Error> {
|
fn key_handle_encryption(&mut self) -> Result<[u8; 32], Error> {
|
||||||
Ok(get_master_keys(self)?.encryption)
|
Ok(get_master_keys(self)?.encryption)
|
||||||
}
|
}
|
||||||
@@ -114,28 +117,33 @@ impl From<StoreError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn test_key_store() {
|
mod test {
|
||||||
let mut env = crate::env::test::TestEnv::new();
|
use super::*;
|
||||||
let key_store = env.key_store();
|
|
||||||
|
|
||||||
// Master keys are well-defined and stable.
|
#[test]
|
||||||
let encryption_key = key_store.key_handle_encryption().unwrap();
|
fn test_key_store() {
|
||||||
let authentication_key = key_store.key_handle_authentication().unwrap();
|
let mut env = crate::env::test::TestEnv::new();
|
||||||
assert_eq!(key_store.key_handle_encryption(), Ok(encryption_key));
|
let key_store = env.key_store();
|
||||||
assert_eq!(
|
|
||||||
key_store.key_handle_authentication(),
|
|
||||||
Ok(authentication_key)
|
|
||||||
);
|
|
||||||
|
|
||||||
// ECDSA seeds are well-defined and stable.
|
// Master keys are well-defined and stable.
|
||||||
let ecdsa_seed = key_store.generate_ecdsa_seed().unwrap();
|
let encryption_key = key_store.key_handle_encryption().unwrap();
|
||||||
let ecdsa_key = key_store.derive_ecdsa(&ecdsa_seed).unwrap();
|
let authentication_key = key_store.key_handle_authentication().unwrap();
|
||||||
assert_eq!(key_store.derive_ecdsa(&ecdsa_seed), Ok(ecdsa_key));
|
assert_eq!(key_store.key_handle_encryption(), Ok(encryption_key));
|
||||||
|
assert_eq!(
|
||||||
|
key_store.key_handle_authentication(),
|
||||||
|
Ok(authentication_key)
|
||||||
|
);
|
||||||
|
|
||||||
// Master keys change after reset. We don't require this for ECDSA seeds because it's not the
|
// ECDSA seeds are well-defined and stable.
|
||||||
// case, but it might be better.
|
let ecdsa_seed = key_store.generate_ecdsa_seed().unwrap();
|
||||||
key_store.reset().unwrap();
|
let ecdsa_key = key_store.derive_ecdsa(&ecdsa_seed).unwrap();
|
||||||
assert!(key_store.key_handle_encryption().unwrap() != encryption_key);
|
assert_eq!(key_store.derive_ecdsa(&ecdsa_seed), Ok(ecdsa_key));
|
||||||
assert!(key_store.key_handle_authentication().unwrap() != authentication_key);
|
|
||||||
|
// Master keys change after reset. We don't require this for ECDSA seeds because it's not
|
||||||
|
// the case, but it might be better.
|
||||||
|
key_store.reset().unwrap();
|
||||||
|
assert!(key_store.key_handle_encryption().unwrap() != encryption_key);
|
||||||
|
assert!(key_store.key_handle_authentication().unwrap() != authentication_key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
src/env/test/mod.rs
vendored
3
src/env/test/mod.rs
vendored
@@ -16,6 +16,7 @@ use self::upgrade_storage::BufferUpgradeStorage;
|
|||||||
use crate::api::connection::{HidConnection, SendOrRecvResult, SendOrRecvStatus};
|
use crate::api::connection::{HidConnection, SendOrRecvResult, SendOrRecvStatus};
|
||||||
use crate::api::customization::DEFAULT_CUSTOMIZATION;
|
use crate::api::customization::DEFAULT_CUSTOMIZATION;
|
||||||
use crate::api::firmware_protection::FirmwareProtection;
|
use crate::api::firmware_protection::FirmwareProtection;
|
||||||
|
use crate::api::key_store;
|
||||||
use crate::api::user_presence::{UserPresence, UserPresenceResult};
|
use crate::api::user_presence::{UserPresence, UserPresenceResult};
|
||||||
use crate::clock::ClockInt;
|
use crate::clock::ClockInt;
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
@@ -147,6 +148,8 @@ impl FirmwareProtection for TestEnv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl key_store::Helper for TestEnv {}
|
||||||
|
|
||||||
impl Env for TestEnv {
|
impl Env for TestEnv {
|
||||||
type Rng = TestRng256;
|
type Rng = TestRng256;
|
||||||
type UserPresence = TestUserPresence;
|
type UserPresence = TestUserPresence;
|
||||||
|
|||||||
3
src/env/tock/mod.rs
vendored
3
src/env/tock/mod.rs
vendored
@@ -16,6 +16,7 @@ pub use self::storage::{TockStorage, TockUpgradeStorage};
|
|||||||
use crate::api::connection::{HidConnection, SendOrRecvError, SendOrRecvResult, SendOrRecvStatus};
|
use crate::api::connection::{HidConnection, SendOrRecvError, SendOrRecvResult, SendOrRecvStatus};
|
||||||
use crate::api::customization::{CustomizationImpl, DEFAULT_CUSTOMIZATION};
|
use crate::api::customization::{CustomizationImpl, DEFAULT_CUSTOMIZATION};
|
||||||
use crate::api::firmware_protection::FirmwareProtection;
|
use crate::api::firmware_protection::FirmwareProtection;
|
||||||
|
use crate::api::key_store;
|
||||||
use crate::api::user_presence::{UserPresence, UserPresenceError, UserPresenceResult};
|
use crate::api::user_presence::{UserPresence, UserPresenceError, UserPresenceResult};
|
||||||
use crate::clock::{ClockInt, KEEPALIVE_DELAY_MS};
|
use crate::clock::{ClockInt, KEEPALIVE_DELAY_MS};
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
@@ -193,6 +194,8 @@ impl FirmwareProtection for TockEnv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl key_store::Helper for TockEnv {}
|
||||||
|
|
||||||
impl Env for TockEnv {
|
impl Env for TockEnv {
|
||||||
type Rng = TockRng256;
|
type Rng = TockRng256;
|
||||||
type UserPresence = Self;
|
type UserPresence = Self;
|
||||||
|
|||||||
Reference in New Issue
Block a user