Skip to content

Commit

Permalink
Merge pull request #16 from Nitrokey/dat-migrations-admin
Browse files Browse the repository at this point in the history
Add migration for data
  • Loading branch information
sosthene-nitrokey authored Apr 2, 2024
2 parents af9502a + 96257a2 commit 2c06c5b
Show file tree
Hide file tree
Showing 7 changed files with 344 additions and 38 deletions.
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", tag = "v0.1.0-nitrokey.12" }

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

0 comments on commit 2c06c5b

Please sign in to comment.