Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add migration for data #16

Merged
merged 5 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ serde.workspace = true
trussed.workspace = true

se05x = { version = "0.1.1", features = ["serde", "builder"] }
trussed-auth = "0.2.2"
trussed-auth = "0.3.0"
trussed-manage = "0.1.0"
trussed-se050-manage = "0.1.0"
trussed-wrap-key-to-file = "0.1.0"
Expand All @@ -46,14 +46,18 @@ crypto-bigint = { version = "0.5.3", default-features = false }
p256 = { version = "0.13.2", default-features = false, features = ["ecdsa-core"] }
salty = "0.3.0"
p256-cortex-m4 = { version = "0.1.0-alpha.6", features = ["prehash", "sec1-signatures"] }
admin-app = "0.1.0"

[patch.crates-io]
littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "ebd27e49ca321089d01d8c9b169c4aeb58ceeeca" }
trussed = { git = "https://github.com/Nitrokey/trussed.git", tag = "v0.1.0-nitrokey.18" }
trussed-auth = { git = "https://github.com/Nitrokey/trussed-auth", rev = "49c13eae6d9a225676191d4776d514848e4eab5b" }
apdu-dispatch = { git = "https://github.com/trussed-dev/apdu-dispatch.git", rev = "915fc237103fcecc29d0f0b73391f19abf6576de" }
ctaphid-dispatch = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "57cb3317878a8593847595319aa03ef17c29ec5b" }
trussed = { git = "https://github.com/Nitrokey/trussed.git", rev = "dd7836a155c78e93a2087611666e60308ed8ff1d" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", tag = "v0.3.0"}
trussed-manage = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "manage-v0.1.0" }
trussed-rsa-alloc = { git = "https://github.com/Nitrokey/trussed-rsa-backend.git", rev = "2088e2f8a8d706276c1559717b4c6b6d4f270253" }
trussed-wrap-key-to-file = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "wrap-key-to-file-v0.1.0" }
admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "9f832f3b7f79108353b82e28f78449f10883abdc" }

trussed-se050-manage = { path = "extensions/se050-manage" }

Expand Down
61 changes: 61 additions & 0 deletions FILESYSTEM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Filesystem layout resulting from the use of the backend

- The directory for the backend `BACKEND_DIR=se050-bak`
- The directory for per-client auth data: `AUTH_DIR=auth`
- The directory for the core keys `CORE_DIR=se050-core`

## Trussed auth impl:

```
/
|- opcard
| |
| |- dat
| |- sec
| |- pub
| |- BACKEND_DIR
| | |- AUTH (`let fs = once(|resources, _| resources.raw_filestore(backend_path))`)
| | | |- pin.XX
| | | |- pin.XX
| | | |- application_salt
|
|- BACKEND_DIR (`let global_fs = once(|resources, _| resources.raw_filestore(PathBuf::from(BACKEND_DIR)))`)
| |- salt
```

## Core API impl

```
/
|- opcard
| |- dat
| |- sec
| |- pub
| |- BACKEND_DIR
| | |- CORE_DIR
| | | |- sec
| | | |- pub
```

## TOTAL:

```
/
|- opcard
| |
| |- dat
| |- sec
| |- pub
| |- BACKEND_DIR
| | |- CORE_DIR
| | | |- sec
| | | |- pub
| | |- AUTH (`let fs = once(|resources, _| resources.raw_filestore(backend_path))`)
| | | |- pin.XX
| | | |- pin.XX
| | | |- application_salt
|
|- BACKEND_DIR (`let global_fs = once(|resources, _| resources.raw_filestore(PathBuf::from(BACKEND_DIR)))`)
| |- salt
```

1 change: 1 addition & 0 deletions extensions/se050-manage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub struct InfoReply {
pub transient_reset: u16,
}

#[allow(clippy::large_enum_variant)]
#[derive(Debug, Deserialize, Serialize)]
pub enum Se050ManageReply {
Info(InfoReply),
Expand Down
53 changes: 26 additions & 27 deletions src/core_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,10 +1189,10 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {

match key_id {
ParsedObjectId::VolatileRsaKey(obj_id) => {
self.rsa_decrypt_volatile(key, obj_id, &message, se050_keystore, algo, kind)
self.rsa_decrypt_volatile(key, obj_id, message, se050_keystore, algo, kind)
}
ParsedObjectId::PersistentKey(obj_id) => {
self.rsa_decrypt_persistent(obj_id, &message, algo)
self.rsa_decrypt_persistent(obj_id, message, algo)
}
_ => Err(Error::ObjectHandleInvalid),
}
Expand Down Expand Up @@ -2990,17 +2990,14 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
backend_path.push(&PathBuf::from(BACKEND_DIR));
backend_path.push(&PathBuf::from(CORE_DIR));

// Used to ensure that the keystore is only created once.
// Keystore creation is expensive because it forks the rng.
let assert_once: [Request; 0] = [];
// Create the keystore lazily
let core_keystore = move |resources: &mut ServiceResources<P>,
core_ctx: &mut CoreContext| {
drop(assert_once);
resources.keystore(core_ctx.path.clone())
};
let se050_keystore =
move |resources: &mut ServiceResources<P>| resources.keystore(backend_path);
/// Coerce an FnMut into a FnOnce to ensure the stores are not created twice by mistake
fn once<R, P>(
generator: impl FnMut(&mut ServiceResources<P>, &mut CoreContext) -> R,
) -> impl FnOnce(&mut ServiceResources<P>, &mut CoreContext) -> R {
generator
}
let core_keystore = once(|resources, core_ctx| resources.keystore(core_ctx.path.clone()));
let se050_keystore = once(|resources, _core_ctx| resources.keystore(backend_path.clone()));

let backend_ctx = backend_ctx.with_namespace(&self.ns, &core_ctx.path);
let ns = backend_ctx.ns;
Expand All @@ -3011,7 +3008,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
.agree(
req,
&mut core_keystore(resources, core_ctx)?,
&mut se050_keystore(resources)?,
&mut se050_keystore(resources, core_ctx)?,
ns,
)?
.into(),
Expand All @@ -3020,15 +3017,15 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
req.key,
req.mechanism,
&req.message,
&mut se050_keystore(resources)?,
&mut se050_keystore(resources, core_ctx)?,
ns,
)?
.into(),
Request::DeriveKey(req) if supported(req.mechanism) => self
.derive_key(
req,
&mut core_keystore(resources, core_ctx)?,
&mut se050_keystore(resources)?,
&mut se050_keystore(resources, core_ctx)?,
ns,
)?
.into(),
Expand All @@ -3042,34 +3039,36 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
.serialize_key(req, &mut core_keystore(resources, core_ctx)?)?
.into(),
Request::Delete(request::Delete { key }) => self
.delete(key, ns, &mut se050_keystore(resources)?)?
.delete(key, ns, &mut se050_keystore(resources, core_ctx)?)?
.into(),
Request::Clear(req) => self
.clear(req, &mut se050_keystore(resources, core_ctx)?, ns)?
.into(),
Request::Clear(req) => self.clear(req, &mut se050_keystore(resources)?, ns)?.into(),
Request::DeleteAllKeys(req) => self
.delete_all_keys(
req,
&mut core_keystore(resources, core_ctx)?,
&mut se050_keystore(resources)?,
&mut se050_keystore(resources, core_ctx)?,
ns,
)?
.into(),
Request::Exists(req) if supported(req.mechanism) => self
.exists(req, &mut se050_keystore(resources)?, ns)?
.exists(req, &mut se050_keystore(resources, core_ctx)?, ns)?
.into(),
Request::GenerateKey(req) if supported(req.mechanism) => self
.generate_key(req, &mut se050_keystore(resources)?, ns)?
.generate_key(req, &mut se050_keystore(resources, core_ctx)?, ns)?
.into(),
Request::Sign(req) if supported(req.mechanism) => self
.sign(req, &mut se050_keystore(resources, core_ctx)?, ns)?
.into(),
Request::Sign(req) if supported(req.mechanism) => {
self.sign(req, &mut se050_keystore(resources)?, ns)?.into()
}
Request::UnsafeInjectKey(req) if supported(req.mechanism) => self
.unsafe_inject_key(req, &mut se050_keystore(resources)?, ns)?
.unsafe_inject_key(req, &mut se050_keystore(resources, core_ctx)?, ns)?
.into(),
Request::UnwrapKey(req) => self
.unwrap_key(
req,
&mut core_keystore(resources, core_ctx)?,
&mut se050_keystore(resources)?,
&mut se050_keystore(resources, core_ctx)?,
ns,
)?
.into(),
Expand All @@ -3080,7 +3079,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
.wrap_key(
req,
&mut core_keystore(resources, core_ctx)?,
&mut se050_keystore(resources)?,
&mut se050_keystore(resources, core_ctx)?,
ns,
)?
.into(),
Expand Down
13 changes: 12 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::ops::Range;

use embedded_hal::blocking::delay::DelayUs;
use hex_literal::hex;
use littlefs2::path;
use littlefs2::path::Path;
use namespacing::{Namespace, NamespaceValue};
use se05x::{
Expand All @@ -24,10 +25,11 @@ mod staging;

mod core_api;
mod manage;
pub mod migrate;
pub mod namespacing;

/// Need overhead for TLV + SW bytes
const BACKEND_DIR: &str = "se050-bak";
const BACKEND_DIR: &Path = path!("se050-bak");

pub const GLOBAL_ATTEST_ID: ObjectId = ObjectId(hex!("F0000012"));

Expand All @@ -51,13 +53,20 @@ enum EnableState {
Failed(se05x::se05x::Error),
}

#[derive(Clone, Debug)]
pub enum FilesystemLayout {
V0,
V1,
}

pub struct Se050Backend<Twi, D> {
se: Se05X<Twi, D>,
enabled: EnableState,
metadata_location: Location,
hw_key: HardwareKey,
ns: Namespace,
configured: bool,
layout: FilesystemLayout,
}

impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
Expand All @@ -66,6 +75,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
metadata_location: Location,
hardware_key: Option<Bytes<{ MAX_HW_KEY_LEN }>>,
ns: Namespace,
layout: FilesystemLayout,
) -> Self {
Se050Backend {
se,
Expand All @@ -77,6 +87,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
},
ns,
configured: false,
layout,
}
}

Expand Down
Loading