diff --git a/.github/workflows/cargo_check.yml b/.github/workflows/cargo_check.yml index 60b96d19ab21563dcadf78964f408ac81998e7d3..a6c4c4696cca73994152d3ee1422399374e7f768 100644 --- a/.github/workflows/cargo_check.yml +++ b/.github/workflows/cargo_check.yml @@ -58,6 +58,12 @@ jobs: command: check args: --target thumbv7em-none-eabi --release --features debug_allocations + - name: Check OpenSK ram_storage + uses: actions-rs/cargo@v1 + with: + command: check + args: --target thumbv7em-none-eabi --release --features ram_storage + - name: Check OpenSK debug_ctap,with_ctap1 uses: actions-rs/cargo@v1 with: diff --git a/Cargo.toml b/Cargo.toml index 03dc0349d493bf75828a645f6828688665a1d8ca..3155106e9d79fc478ea7c9669c79fefd6124b884 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ debug_ctap = ["crypto/derive_debug"] with_ctap1 = ["crypto/with_ctap1"] panic_console = ["libtock/panic_console"] debug_allocations = ["libtock/debug_allocations"] +ram_storage = [] [dev-dependencies] elf2tab = "0.4.0" diff --git a/deploy.py b/deploy.py index ee7f54f083eeface34e00352e0a99cb052c64fd0..dc69c24ea4921d73e03577649edbcbdf995d677b 100755 --- a/deploy.py +++ b/deploy.py @@ -405,6 +405,14 @@ if __name__ == "__main__": "(i.e. more debug messages will be sent over the console port " "such as hexdumps of packets)."), ) + app_commands.add_argument( + "--no-persistent-storage", + action="append_const", + const="ram_storage", + dest="features", + help=("Compiles and installs the OpenSK application without persistent " + "storage (i.e. unplugging the key will reset the key)."), + ) apps_group = app_commands.add_mutually_exclusive_group() apps_group.add_argument( "--opensk", diff --git a/run_desktop_tests.sh b/run_desktop_tests.sh index e3f2b1ef9ad1442008977d683199c715e6db426d..b8e889620ec90eafaef5916faf291efbf2327f19 100755 --- a/run_desktop_tests.sh +++ b/run_desktop_tests.sh @@ -30,6 +30,7 @@ cargo check --release --target=thumbv7em-none-eabi --features with_ctap1 cargo check --release --target=thumbv7em-none-eabi --features debug_ctap cargo check --release --target=thumbv7em-none-eabi --features panic_console cargo check --release --target=thumbv7em-none-eabi --features debug_allocations +cargo check --release --target=thumbv7em-none-eabi --features ram_storage cargo check --release --target=thumbv7em-none-eabi --features debug_ctap,with_ctap1 cargo check --release --target=thumbv7em-none-eabi --features debug_ctap,with_ctap1,panic_console,debug_allocations diff --git a/src/ctap/storage.rs b/src/ctap/storage.rs index e693a136aa18edc7ab5ad72c7a18fc9728f5f802..7569c1b0fc956474b933ba90cf10e2549af0914a 100644 --- a/src/ctap/storage.rs +++ b/src/ctap/storage.rs @@ -21,9 +21,9 @@ use alloc::vec::Vec; use core::convert::TryInto; use ctap2::embedded_flash::{self, StoreConfig, StoreEntry, StoreError, StoreIndex}; -#[cfg(test)] +#[cfg(any(test, feature = "ram_storage"))] type Storage = embedded_flash::BufferStorage; -#[cfg(not(test))] +#[cfg(not(any(test, feature = "ram_storage")))] type Storage = embedded_flash::SyscallStorage; // Those constants may be modified before compilation to tune the behavior of the key. @@ -44,6 +44,9 @@ type Storage = embedded_flash::SyscallStorage; // We have: I = ((P - 1) * 4092 - K * S) / 12 * C // // With P=20 and K=150, we have I > 2M which is enough for 500 increments per day for 10 years. +#[cfg(feature = "ram_storage")] +const NUM_PAGES: usize = 2; +#[cfg(not(feature = "ram_storage"))] const NUM_PAGES: usize = 20; const MAX_SUPPORTED_RESIDENTIAL_KEYS: usize = 150; @@ -130,10 +133,14 @@ pub struct PersistentStore { store: embedded_flash::Store<Storage, Config>, } +#[cfg(feature = "ram_storage")] +const PAGE_SIZE: usize = 0x100; +#[cfg(not(feature = "ram_storage"))] const PAGE_SIZE: usize = 0x1000; + const STORE_SIZE: usize = NUM_PAGES * PAGE_SIZE; -#[cfg(not(test))] +#[cfg(not(any(test, feature = "ram_storage")))] #[link_section = ".app_state"] static STORE: [u8; STORE_SIZE] = [0xff; STORE_SIZE]; @@ -144,9 +151,9 @@ 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(test))] + #[cfg(not(any(test, feature = "ram_storage")))] let storage = PersistentStore::new_prod_storage(); - #[cfg(test)] + #[cfg(any(test, feature = "ram_storage"))] let storage = PersistentStore::new_test_storage(); let mut store = PersistentStore { store: embedded_flash::Store::new(storage, Config).unwrap(), @@ -155,7 +162,7 @@ impl PersistentStore { store } - #[cfg(not(test))] + #[cfg(not(any(test, feature = "ram_storage")))] fn new_prod_storage() -> Storage { let store = unsafe { // Safety: The store cannot alias because this function is called only once. @@ -167,7 +174,7 @@ impl PersistentStore { } } - #[cfg(test)] + #[cfg(any(test, feature = "ram_storage"))] fn new_test_storage() -> Storage { let store = vec![0xff; STORE_SIZE].into_boxed_slice(); let options = embedded_flash::BufferOptions { diff --git a/src/embedded_flash/buffer.rs b/src/embedded_flash/buffer.rs index b7cf3f1ea89775a64739ef02707bf484d4be5a95..4fcd80fe8d50d0a312fca6bb4ec170c5b7613228 100644 --- a/src/embedded_flash/buffer.rs +++ b/src/embedded_flash/buffer.rs @@ -13,6 +13,7 @@ // limitations under the License. use super::{Index, Storage, StorageError, StorageResult}; +use alloc::boxed::Box; pub struct BufferStorage { storage: Box<[u8]>, @@ -230,7 +231,7 @@ impl Snapshot { fn get(&mut self) -> Result<Box<[u8]>, usize> { let mut snapshot = Snapshot::Ready; - std::mem::swap(self, &mut snapshot); + core::mem::swap(self, &mut snapshot); match snapshot { Snapshot::Armed { delay } => Err(delay), Snapshot::Taken { storage } => Ok(storage), diff --git a/src/embedded_flash/mod.rs b/src/embedded_flash/mod.rs index 5e54059e2e2c65301a5292411cf48ca2510b1f9c..8551a52721dce1342d70f414974e21f246079285 100644 --- a/src/embedded_flash/mod.rs +++ b/src/embedded_flash/mod.rs @@ -12,13 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(feature = "std")] mod buffer; mod storage; mod store; mod syscall; -#[cfg(feature = "std")] pub use self::buffer::{BufferOptions, BufferStorage}; pub use self::storage::{Index, Storage, StorageError, StorageResult}; pub use self::store::{Store, StoreConfig, StoreEntry, StoreError, StoreIndex};