Skip to content

Commit

Permalink
Moves soft reset parameters into Env
Browse files Browse the repository at this point in the history
  • Loading branch information
kaczmarczyck committed Jan 9, 2024
1 parent 1e9579d commit 1bf8611
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 27 deletions.
4 changes: 2 additions & 2 deletions libraries/opensk/fuzz/fuzz_helper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub fn process_ctap_any_type(data: &[u8]) -> arbitrary::Result<()> {

let data = unstructured.take_rest();
// Initialize ctap state and hid and get the allocated cid.
let mut ctap = Ctap::new(env, false);
let mut ctap = Ctap::new(env);
let cid = initialize(&mut ctap);
// Wrap input as message with the allocated cid.
let mut command = cid.to_vec();
Expand Down Expand Up @@ -191,7 +191,7 @@ pub fn process_ctap_specific_type(data: &[u8], input_type: InputType) -> arbitra
return Ok(());
}
// Initialize ctap state and hid and get the allocated cid.
let mut ctap = Ctap::new(env, false);
let mut ctap = Ctap::new(env);
let cid = initialize(&mut ctap);
// Wrap input as message with allocated cid and command type.
let mut command = cid.to_vec();
Expand Down
31 changes: 21 additions & 10 deletions libraries/opensk/src/ctap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,13 +410,26 @@ pub struct StatefulPermission<E: Env> {
channel: Option<Channel>,
}

impl<E: Env> Default for StatefulPermission<E> {
/// Creates the command state at device startup without user action.
///
/// Reset is not granted after a forced reboot. The user replugging the device is a required
/// to avoid accidental data loss.
fn default() -> StatefulPermission<E> {
StatefulPermission {
permission: <E::Clock as Clock>::Timer::default(),
command_type: None,
channel: None,
}
}
}

impl<E: Env> StatefulPermission<E> {
/// Creates the command state at device startup.
///
/// Resets are only possible after a power cycle. Therefore, there is no way to grant the Reset
/// permission outside of this function. If you initialize the app without a power cycle
/// (potentially after waking up from sleep), `clear` the permissions.
/// means allowing Reset, and Reset cannot be granted later.
/// (potentially after waking up from sleep), call `default` instead.
pub fn new_reset(env: &mut E) -> StatefulPermission<E> {
StatefulPermission {
permission: env.clock().make_timer(RESET_TIMEOUT_DURATION_MS),
Expand Down Expand Up @@ -545,22 +558,20 @@ impl<E: Env> CtapState<E> {
pub fn new(env: &mut E) -> Self {
storage::init(env).ok().unwrap();
let client_pin = ClientPin::new(env);
let stateful_command_permission = if env.boots_after_soft_reset() {
StatefulPermission::default()
} else {
StatefulPermission::new_reset(env)
};
CtapState {
client_pin,
#[cfg(feature = "with_ctap1")]
u2f_up_state: U2fUserPresenceState::new(),
stateful_command_permission: StatefulPermission::new_reset(env),
stateful_command_permission,
large_blobs: LargeBlobs::new(),
}
}

/// Creates new CTAP state that doesn't assume a user intended power cycle.
pub fn new_soft_reset(env: &mut E) -> Self {
let mut ctap_state = CtapState::new(env);
ctap_state.stateful_command_permission.clear();
ctap_state
}

pub fn increment_global_signature_counter(
&mut self,
env: &mut E,
Expand Down
3 changes: 3 additions & 0 deletions libraries/opensk/src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ pub trait Env {
#[cfg(feature = "vendor_hid")]
fn vendor_hid_connection(&mut self) -> &mut Self::HidConnection;

/// Indicates that the last power cycle was not caused by user action.
fn boots_after_soft_reset(&self) -> bool;

/// Option to return a firmware version that is shown as device info.
fn firmware_version(&self) -> Option<u64> {
None
Expand Down
20 changes: 20 additions & 0 deletions libraries/opensk/src/env/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct TestEnv {
store: Store<BufferStorage>,
customization: TestCustomization,
clock: TestClock,
soft_reset: bool,
}

pub type TestRng = StdRng;
Expand Down Expand Up @@ -127,6 +128,7 @@ impl Default for TestEnv {
store,
customization,
clock,
soft_reset: false,
}
}
}
Expand All @@ -139,6 +141,10 @@ impl TestEnv {
pub fn seed_rng_from_u64(&mut self, seed: u64) {
self.rng = StdRng::seed_from_u64(seed);
}

pub fn set_boots_after_soft_reset(&mut self, value: bool) {
self.soft_reset = value;
}
}

impl TestUserPresence {
Expand Down Expand Up @@ -227,6 +233,10 @@ impl Env for TestEnv {
self
}

fn boots_after_soft_reset(&self) -> bool {
self.soft_reset
}

fn firmware_version(&self) -> Option<u64> {
Some(0)
}
Expand All @@ -247,4 +257,14 @@ mod test {
clock.advance(1);
assert!(clock.is_elapsed(&timer));
}

#[test]
fn test_soft_reset() {
let mut env = TestEnv::default();
assert!(!env.boots_after_soft_reset());
env.set_boots_after_soft_reset(true);
assert!(env.boots_after_soft_reset());
env.set_boots_after_soft_reset(false);
assert!(!env.boots_after_soft_reset());
}
}
25 changes: 11 additions & 14 deletions libraries/opensk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,8 @@ impl<E: Env> Ctap<E> {
/// Instantiates a CTAP implementation given its environment.
// This should only take the environment, but it temporarily takes the boot time until the
// clock is part of the environment.
pub fn new(mut env: E, is_soft_reset: bool) -> Self {
let state = if is_soft_reset {
CtapState::<E>::new_soft_reset(&mut env)
} else {
CtapState::<E>::new(&mut env)
};
pub fn new(mut env: E) -> Self {
let state = CtapState::<E>::new(&mut env);
let hid = MainHid::default();
#[cfg(feature = "vendor_hid")]
let vendor_hid = VendorHid::default();
Expand Down Expand Up @@ -163,7 +159,7 @@ mod test {
#[test]
fn test_wink() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, false);
let mut ctap = Ctap::<TestEnv>::new(env);

// Send Init, receive Init response and check wink if disabled.
let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid);
Expand All @@ -182,7 +178,7 @@ mod test {
#[test]
fn test_locked_channel_id() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, false);
let mut ctap = Ctap::<TestEnv>::new(env);

// Send Init, receive Init response.
let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid);
Expand All @@ -204,7 +200,7 @@ mod test {
#[test]
fn test_hard_reset() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, false);
let mut ctap = Ctap::<TestEnv>::new(env);

// Send Init, receive Init response.
let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid);
Expand All @@ -224,8 +220,9 @@ mod test {

#[test]
fn test_soft_reset() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, true);
let mut env = TestEnv::default();
env.set_boots_after_soft_reset(true);
let mut ctap = Ctap::<TestEnv>::new(env);

// Send Init, receive Init response.
let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid);
Expand All @@ -246,15 +243,15 @@ mod test {
#[test]
fn test_env_api() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, true);
let mut ctap = Ctap::<TestEnv>::new(env);
assert_eq!(ctap.env().firmware_version(), Some(0));
}

#[test]
#[cfg(feature = "vendor_hid")]
fn test_locked_transport() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, false);
let mut ctap = Ctap::<TestEnv>::new(env);

// Send Init, receive Init response.
let mut init_response = ctap.process_hid_packet(&init_packet(), Transport::MainHid);
Expand All @@ -277,7 +274,7 @@ mod test {
#[cfg(feature = "with_ctap1")]
fn test_ctap1_initial_state() {
let env = TestEnv::default();
let mut ctap = Ctap::<TestEnv>::new(env, false);
let mut ctap = Ctap::<TestEnv>::new(env);
// Granting doesn't work until a CTAP1 request was processed.
ctap.u2f_grant_user_presence();
assert!(!ctap.u2f_needs_user_presence());
Expand Down
4 changes: 4 additions & 0 deletions src/env/tock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ impl<S: Syscalls, C: platform::subscribe::Config + platform::allow_ro::Config> E
commands::process_vendor_command(self, bytes, channel)
}

fn boots_after_soft_reset(&self) -> bool {
false
}

fn firmware_version(&self) -> Option<u64> {
self.upgrade_storage
.as_ref()
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn main() {
}

let env = TockEnv::<SyscallImplementation>::default();
let mut ctap = opensk::Ctap::new(env, false);
let mut ctap = opensk::Ctap::new(env);

let mut led_counter = 0;
let mut led_blink_timer =
Expand Down

0 comments on commit 1bf8611

Please sign in to comment.