Skip to content

Commit

Permalink
Move choice between prod and test storage to embedded_flash module
Browse files Browse the repository at this point in the history
This way all users of storage can share the logic to choose between flash or RAM
storage depending on the "std" feature. This is needed because the store_latency
example assumes flash storage but is built when running `cargo test
--features=std`.
  • Loading branch information
ia0 committed Dec 10, 2020
1 parent ece546a commit 371b8af
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 35 deletions.
11 changes: 6 additions & 5 deletions examples/store_latency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ extern crate lang_items;

use alloc::vec;
use core::fmt::Write;
use ctap2::embedded_flash::SyscallStorage;
use ctap2::embedded_flash::{new_storage, Storage};
use libtock_drivers::console::Console;
use libtock_drivers::timer::{self, Duration, Timer, Timestamp};
use persistent_store::{Storage, Store};
use persistent_store::Store;

fn timestamp(timer: &Timer) -> Timestamp<f64> {
Timestamp::<f64>::from_clock_value(timer.get_current_clock().ok().unwrap())
Expand All @@ -36,10 +36,11 @@ fn measure<T>(timer: &Timer, operation: impl FnOnce() -> T) -> (T, Duration<f64>
}

// Only use one store at a time.
unsafe fn boot_store(num_pages: usize, erase: bool) -> Store<SyscallStorage> {
let mut storage = SyscallStorage::new(num_pages).unwrap();
unsafe fn boot_store(num_pages: usize, erase: bool) -> Store<Storage> {
let mut storage = new_storage(num_pages);
if erase {
for page in 0..storage.num_pages() {
for page in 0..num_pages {
use persistent_store::Storage;
storage.erase_page(page).unwrap();
}
}
Expand Down
32 changes: 2 additions & 30 deletions src/ctap/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::ctap::key_material;
use crate::ctap::pin_protocol_v1::PIN_AUTH_LENGTH;
use crate::ctap::status_code::Ctap2StatusCode;
use crate::ctap::INITIAL_SIGNATURE_COUNTER;
use crate::embedded_flash::{new_storage, Storage};
#[cfg(feature = "with_ctap2_1")]
use alloc::string::String;
use alloc::vec;
Expand All @@ -31,11 +32,6 @@ use cbor::cbor_array_vec;
use core::convert::TryInto;
use crypto::rng256::Rng256;

#[cfg(feature = "std")]
type Storage = persistent_store::BufferStorage;
#[cfg(not(feature = "std"))]
type Storage = crate::embedded_flash::SyscallStorage;

// Those constants may be modified before compilation to tune the behavior of the key.
//
// The number of pages should be at least 3 and at most what the flash can hold. There should be no
Expand Down Expand Up @@ -89,38 +85,14 @@ impl PersistentStore {
///
/// This should be at most one instance of persistent store per program lifetime.
pub fn new(rng: &mut impl Rng256) -> PersistentStore {
#[cfg(not(feature = "std"))]
let storage = PersistentStore::new_prod_storage();
#[cfg(feature = "std")]
let storage = PersistentStore::new_test_storage();
let storage = new_storage(NUM_PAGES);
let mut store = PersistentStore {
store: persistent_store::Store::new(storage).ok().unwrap(),
};
store.init(rng).unwrap();
store
}

/// Creates a syscall storage in flash.
#[cfg(not(feature = "std"))]
fn new_prod_storage() -> Storage {
Storage::new(NUM_PAGES).unwrap()
}

/// Creates a buffer storage in RAM.
#[cfg(feature = "std")]
fn new_test_storage() -> Storage {
const PAGE_SIZE: usize = 0x1000;
let store = vec![0xff; NUM_PAGES * PAGE_SIZE].into_boxed_slice();
let options = persistent_store::BufferOptions {
word_size: 4,
page_size: PAGE_SIZE,
max_word_writes: 2,
max_page_erases: 10000,
strict_mode: true,
};
Storage::new(store, options)
}

/// Initializes the store by creating missing objects.
fn init(&mut self, rng: &mut impl Rng256) -> Result<(), Ctap2StatusCode> {
// Generate and store the master keys if they are missing.
Expand Down
33 changes: 33 additions & 0 deletions src/embedded_flash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,36 @@ mod syscall;

#[cfg(not(feature = "std"))]
pub use self::syscall::SyscallStorage;

/// Storage definition for production.
#[cfg(not(feature = "std"))]
mod prod {
pub type Storage = super::SyscallStorage;

pub fn new_storage(num_pages: usize) -> Storage {
Storage::new(num_pages).unwrap()
}
}
#[cfg(not(feature = "std"))]
pub use self::prod::{new_storage, Storage};

/// Storage definition for testing.
#[cfg(feature = "std")]
mod test {
pub type Storage = persistent_store::BufferStorage;

pub fn new_storage(num_pages: usize) -> Storage {
const PAGE_SIZE: usize = 0x1000;
let store = vec![0xff; num_pages * PAGE_SIZE].into_boxed_slice();
let options = persistent_store::BufferOptions {
word_size: 4,
page_size: PAGE_SIZE,
max_word_writes: 2,
max_page_erases: 10000,
strict_mode: true,
};
Storage::new(store, options)
}
}
#[cfg(feature = "std")]
pub use self::test::{new_storage, Storage};

0 comments on commit 371b8af

Please sign in to comment.