Support storing in RAM instead of flash

This permits to run without persistent storage. The benefit is that the board
doesn't implement a the syscall API in Tock. The disadvantage is that rebooting
the key will reset the storage.
This commit is contained in:
Julien Cretin
2020-03-03 23:47:32 +01:00
committed by Julien Cretin
parent 9001cbd864
commit e52a671810
7 changed files with 32 additions and 10 deletions

View File

@@ -58,6 +58,12 @@ jobs:
command: check command: check
args: --target thumbv7em-none-eabi --release --features debug_allocations 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 - name: Check OpenSK debug_ctap,with_ctap1
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:

View File

@@ -23,6 +23,7 @@ debug_ctap = ["crypto/derive_debug"]
with_ctap1 = ["crypto/with_ctap1"] with_ctap1 = ["crypto/with_ctap1"]
panic_console = ["libtock/panic_console"] panic_console = ["libtock/panic_console"]
debug_allocations = ["libtock/debug_allocations"] debug_allocations = ["libtock/debug_allocations"]
ram_storage = []
[dev-dependencies] [dev-dependencies]
elf2tab = "0.4.0" elf2tab = "0.4.0"

View File

@@ -405,6 +405,14 @@ if __name__ == "__main__":
"(i.e. more debug messages will be sent over the console port " "(i.e. more debug messages will be sent over the console port "
"such as hexdumps of packets)."), "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 = app_commands.add_mutually_exclusive_group()
apps_group.add_argument( apps_group.add_argument(
"--opensk", "--opensk",

View File

@@ -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 debug_ctap
cargo check --release --target=thumbv7em-none-eabi --features panic_console 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 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
cargo check --release --target=thumbv7em-none-eabi --features debug_ctap,with_ctap1,panic_console,debug_allocations cargo check --release --target=thumbv7em-none-eabi --features debug_ctap,with_ctap1,panic_console,debug_allocations

View File

@@ -21,9 +21,9 @@ use alloc::vec::Vec;
use core::convert::TryInto; use core::convert::TryInto;
use ctap2::embedded_flash::{self, StoreConfig, StoreEntry, StoreError, StoreIndex}; use ctap2::embedded_flash::{self, StoreConfig, StoreEntry, StoreError, StoreIndex};
#[cfg(test)] #[cfg(any(test, feature = "ram_storage"))]
type Storage = embedded_flash::BufferStorage; type Storage = embedded_flash::BufferStorage;
#[cfg(not(test))] #[cfg(not(any(test, feature = "ram_storage")))]
type Storage = embedded_flash::SyscallStorage; type Storage = embedded_flash::SyscallStorage;
// Those constants may be modified before compilation to tune the behavior of the key. // 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 // 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. // 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 NUM_PAGES: usize = 20;
const MAX_SUPPORTED_RESIDENTIAL_KEYS: usize = 150; const MAX_SUPPORTED_RESIDENTIAL_KEYS: usize = 150;
@@ -130,10 +133,14 @@ pub struct PersistentStore {
store: embedded_flash::Store<Storage, Config>, 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 PAGE_SIZE: usize = 0x1000;
const STORE_SIZE: usize = NUM_PAGES * PAGE_SIZE; const STORE_SIZE: usize = NUM_PAGES * PAGE_SIZE;
#[cfg(not(test))] #[cfg(not(any(test, feature = "ram_storage")))]
#[link_section = ".app_state"] #[link_section = ".app_state"]
static STORE: [u8; STORE_SIZE] = [0xff; STORE_SIZE]; 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. /// This should be at most one instance of persistent store per program lifetime.
pub fn new(rng: &mut impl Rng256) -> PersistentStore { pub fn new(rng: &mut impl Rng256) -> PersistentStore {
#[cfg(not(test))] #[cfg(not(any(test, feature = "ram_storage")))]
let storage = PersistentStore::new_prod_storage(); let storage = PersistentStore::new_prod_storage();
#[cfg(test)] #[cfg(any(test, feature = "ram_storage"))]
let storage = PersistentStore::new_test_storage(); let storage = PersistentStore::new_test_storage();
let mut store = PersistentStore { let mut store = PersistentStore {
store: embedded_flash::Store::new(storage, Config).unwrap(), store: embedded_flash::Store::new(storage, Config).unwrap(),
@@ -155,7 +162,7 @@ impl PersistentStore {
store store
} }
#[cfg(not(test))] #[cfg(not(any(test, feature = "ram_storage")))]
fn new_prod_storage() -> Storage { fn new_prod_storage() -> Storage {
let store = unsafe { let store = unsafe {
// Safety: The store cannot alias because this function is called only once. // 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 { fn new_test_storage() -> Storage {
let store = vec![0xff; STORE_SIZE].into_boxed_slice(); let store = vec![0xff; STORE_SIZE].into_boxed_slice();
let options = embedded_flash::BufferOptions { let options = embedded_flash::BufferOptions {

View File

@@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
use super::{Index, Storage, StorageError, StorageResult}; use super::{Index, Storage, StorageError, StorageResult};
use alloc::boxed::Box;
pub struct BufferStorage { pub struct BufferStorage {
storage: Box<[u8]>, storage: Box<[u8]>,
@@ -230,7 +231,7 @@ impl Snapshot {
fn get(&mut self) -> Result<Box<[u8]>, usize> { fn get(&mut self) -> Result<Box<[u8]>, usize> {
let mut snapshot = Snapshot::Ready; let mut snapshot = Snapshot::Ready;
std::mem::swap(self, &mut snapshot); core::mem::swap(self, &mut snapshot);
match snapshot { match snapshot {
Snapshot::Armed { delay } => Err(delay), Snapshot::Armed { delay } => Err(delay),
Snapshot::Taken { storage } => Ok(storage), Snapshot::Taken { storage } => Ok(storage),

View File

@@ -12,13 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#[cfg(feature = "std")]
mod buffer; mod buffer;
mod storage; mod storage;
mod store; mod store;
mod syscall; mod syscall;
#[cfg(feature = "std")]
pub use self::buffer::{BufferOptions, BufferStorage}; pub use self::buffer::{BufferOptions, BufferStorage};
pub use self::storage::{Index, Storage, StorageError, StorageResult}; pub use self::storage::{Index, Storage, StorageError, StorageResult};
pub use self::store::{Store, StoreConfig, StoreEntry, StoreError, StoreIndex}; pub use self::store::{Store, StoreConfig, StoreEntry, StoreError, StoreIndex};