Skip to content

Commit

Permalink
Merge pull request #471 from Nitrokey/space-migrate-enable-se050
Browse files Browse the repository at this point in the history
Enable SE050 by default
  • Loading branch information
sosthene-nitrokey authored Apr 12, 2024
2 parents 0756683 + 133529b commit aae21b8
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 29 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ version = "1.7.0-rc.1"
memory-regions = { path = "components/memory-regions" }

# forked
admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "v0.1.0-nitrokey.12" }
admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "c257432dbe2efb53424d6847d82d90ddb527c53b" }
cbor-smol = { git = "https://github.com/Nitrokey/cbor-smol.git", tag = "v0.4.0-nitrokey.3"}
fido-authenticator = { git = "https://github.com/Nitrokey/fido-authenticator.git", tag = "v0.1.1-nitrokey.14" }
lpc55-hal = { git = "https://github.com/Nitrokey/lpc55-hal", tag = "v0.3.0-nitrokey.2" }
serde-indexed = { git = "https://github.com/nitrokey/serde-indexed.git", tag = "v0.1.0-nitrokey.2" }
trussed = { git = "https://github.com/Nitrokey/trussed.git", rev = "371e8f7a07817c2ed57978bd86e3412bd9877647" }
trussed = { git = "https://github.com/Nitrokey/trussed.git", tag = "v0.1.0-nitrokey.19" }

# unreleased upstream changes
apdu-dispatch = { git = "https://github.com/Nitrokey/apdu-dispatch.git", tag = "v0.1.2-nitrokey.3" }
Expand All @@ -43,13 +43,12 @@ trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git",
trussed-manage = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "manage-v0.1.0" }
trussed-wrap-key-to-file = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "wrap-key-to-file-v0.1.0" }
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "v0.3.0" }
trussed-auth = { git = "https://github.com/Nitrokey/trussed-auth", tag = "v0.3.0-nitrokey.1" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth", rev = "947ffe6cff426ccbbbb2d0f689437f427665919e" }
trussed-hkdf = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "hkdf-v0.2.0" }
trussed-rsa-alloc = { git = "https://github.com/trussed-dev/trussed-rsa-backend.git", rev = "9732a9a3e98af72112286afdc9b7174c66c2869a" }
trussed-usbip = { git = "https://github.com/Nitrokey/pc-usbip-runner.git", tag = "v0.0.1-nitrokey.3" }
trussed-se050-manage = { git = "https://github.com/Nitrokey/trussed-se050-backend.git", tag = "se050-manage-v0.1.0" }
trussed-se050-backend = { git = "https://github.com/Nitrokey/trussed-se050-backend.git", rev = "46b5af1842ccae7db76171aca5813f13991054c9" }

trussed-se050-backend = { git = "https://github.com/Nitrokey/trussed-se050-backend.git", rev = "23d3511276176da396b6c3e788cd1c2f4dd37c9d" }

[profile.release]
codegen-units = 1
Expand Down
1 change: 1 addition & 0 deletions components/apps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = { workspace = true }
edition = "2021"

[dependencies]
delog = "0.1"
apdu-dispatch = "0.1"
bitflags = "2"
ctaphid-dispatch = "0.1"
Expand Down
13 changes: 9 additions & 4 deletions components/apps/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ use trussed::{
api::{Reply, Request},
error::Error as TrussedError,
service::ServiceResources,
types::{Context, Location},
types::Context,
Platform,
};

#[cfg(feature = "backend-auth")]
use trussed::types::Location;

use littlefs2::{path, path::Path};

use if_chain::if_chain;
Expand Down Expand Up @@ -118,13 +121,15 @@ const NAMESPACE: trussed_se050_backend::namespacing::Namespace = {
])
};

#[cfg(any(feature = "backend-auth", feature = "se050"))]
pub const AUTH_LOCATION: Location = Location::Internal;

impl<T: Twi, D: Delay> Dispatch<T, D> {
#[allow(clippy::new_without_default)]
pub fn new(
auth_location: Location,
#[cfg(any(feature = "backend-auth", feature = "se050"))] auth_location: Location,
#[cfg(feature = "se050")] se050: Option<Se05X<T, D>>,
) -> Self {
#[cfg(not(all(feature = "backend-auth", feature = "se050")))]
let _ = auth_location;
Self {
#[cfg(feature = "backend-auth")]
auth: AuthBackend::new(auth_location, TRUSSED_AUTH_FS_LAYOUT),
Expand Down
118 changes: 109 additions & 9 deletions components/apps/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,30 @@ use ctaphid_dispatch::app::App as CtaphidApp;
#[cfg(feature = "se050")]
use embedded_hal::blocking::delay::DelayUs;
use heapless::Vec;
#[cfg(all(feature = "opcard", any(feature = "factory-reset", feature = "se050")))]
use littlefs2::path;

#[cfg(feature = "factory-reset")]
use admin_app::ResetConfigResult;

#[macro_use]
extern crate delog;

generate_macros!();

use serde::{Deserialize, Serialize};
#[cfg(all(feature = "opcard", feature = "se050"))]
use trussed::{api::NotBefore, service::Filestore};
use trussed::{
backend::BackendId, client::ClientBuilder, interrupt::InterruptFlag, platform::Syscall,
store::filestore::ClientFilestore, types::Path, ClientImplementation, Platform, Service,
backend::BackendId,
client::ClientBuilder,
interrupt::InterruptFlag,
platform::Syscall,
store::filestore::ClientFilestore,
types::{Location, Path},
ClientImplementation, Platform, Service,
};

use utils::Version;

pub use admin_app::Reboot;
Expand All @@ -31,6 +50,9 @@ mod dispatch;
use dispatch::Backend;
pub use dispatch::Dispatch;

#[cfg(any(feature = "backend-auth", feature = "se050"))]
pub use dispatch::AUTH_LOCATION;

fn is_default<T: Default + PartialEq>(value: &T) -> bool {
value == &Default::default()
}
Expand Down Expand Up @@ -79,6 +101,15 @@ impl admin_app::Config for Config {
}
}

#[cfg(feature = "factory-reset")]
fn reset_client_config(&mut self, key: &str) -> ResetConfigResult {
match key {
"fido" => self.fido.reset_config(),
"opcard" => self.opcard.reset_config(),
_ => ResetConfigResult::WrongKey,
}
}

fn migration_version(&self) -> Option<u32> {
Some(self.fs_version)
}
Expand Down Expand Up @@ -111,9 +142,21 @@ impl FidoConfig {
) -> Option<(&'static Path, &'static ResetSignalAllocation)> {
None
}

#[cfg(feature = "factory-reset")]
fn reset_config(&mut self) -> ResetConfigResult {
use core::mem;
let old = mem::take(self);

if &old == self {
ResetConfigResult::Unchanged
} else {
ResetConfigResult::Changed
}
}
}

#[derive(Debug, Default, PartialEq, Deserialize, Serialize)]
#[derive(Debug, PartialEq, Deserialize, Serialize, Default)]
pub struct OpcardConfig {
#[cfg(feature = "se050")]
#[serde(default, rename = "s", skip_serializing_if = "is_default")]
Expand Down Expand Up @@ -146,6 +189,18 @@ impl OpcardConfig {
}

impl OpcardConfig {
/// The config value used for initialization and after a factory-reset
///
/// This is distinct from the `Default` value because the old default config was not
/// enabled
#[cfg(any(feature = "factory-reset", feature = "se050"))]
fn init() -> Self {
Self {
#[cfg(feature = "se050")]
use_se050_backend: true,
}
}

fn field(&mut self, key: &str) -> Option<ConfigValueMut<'_>> {
match key {
#[cfg(feature = "se050")]
Expand All @@ -161,12 +216,24 @@ impl OpcardConfig {
) -> Option<(&'static Path, &'static ResetSignalAllocation)> {
match key {
#[cfg(feature = "factory-reset")]
"" => Some((littlefs2::path!("opcard"), &OPCARD_RESET_SIGNAL)),
"" => Some((path!("opcard"), &OPCARD_RESET_SIGNAL)),
#[cfg(feature = "se050")]
"use_se050_backend" => Some((littlefs2::path!("opcard"), &OPCARD_RESET_SIGNAL)),
"use_se050_backend" => Some((path!("opcard"), &OPCARD_RESET_SIGNAL)),
_ => None,
}
}

#[cfg(feature = "factory-reset")]
fn reset_config(&mut self) -> ResetConfigResult {
use core::mem;
let old = mem::replace(self, Self::init());

if &old == self {
ResetConfigResult::Unchanged
} else {
ResetConfigResult::Changed
}
}
}

pub trait Runner {
Expand Down Expand Up @@ -378,6 +445,39 @@ impl<R: Runner> Apps<R> {
)
});

#[cfg(all(feature = "opcard", feature = "se050"))]
if !data.init_status.contains(InitStatus::CONFIG_ERROR)
&& app.config().fs_version == 0
&& !app.config().opcard.use_se050_backend
{
use core::mem;
let opcard_trussed_auth_used = trussed_auth::AuthBackend::is_client_active(
trussed_auth::FilesystemLayout::V0,
dispatch::AUTH_LOCATION,
path!("opcard"),
data.store,
)
.unwrap_or_default();
let mut fs = ClientFilestore::new(path!("opcard").into(), data.store);
let opcard_used = !fs
.read_dir_first(path!(""), Location::External, &NotBefore::None)
.unwrap_or_default()
.is_none();

if !opcard_trussed_auth_used && !opcard_used {
// No need to factory reset because the app is not yet created yet
let mut config = OpcardConfig::init();
mem::swap(&mut app.config_mut().opcard, &mut config);
app.save_config_filestore(&mut filestore)
.map_err(|_err| {
// We reset the config to the old on file version to avoid invalid operations
mem::swap(&mut app.config_mut().opcard, &mut config);
error_now!("Failed to save config after migration: {_err:?}");
})
.ok();
}
}

let migration_version = used_migrators
.iter()
.map(|m| m.version)
Expand Down Expand Up @@ -698,7 +798,7 @@ impl<R: Runner> App<R> for FidoApp<R> {
};
let large_blobs = if cfg!(feature = "test") && runner.is_efs_available() {
Some(fido_authenticator::LargeBlobsConfig {
location: trussed::types::Location::External,
location: Location::External,
max_size: 4096,
})
} else {
Expand Down Expand Up @@ -738,7 +838,7 @@ impl<R: Runner> App<R> for WebcryptApp<R> {
Webcrypt::new_with_options(
trussed,
webcrypt::Options::new(
trussed::types::Location::External,
Location::External,
[uuid[0], uuid[1], uuid[2], uuid[3]],
WEBCRYPT_APP_CREDENTIALS_COUNT_LIMIT,
),
Expand Down Expand Up @@ -766,7 +866,7 @@ impl<R: Runner> App<R> for SecretsApp<R> {
fn with_client(runner: &R, trussed: Client<R>, _: (), _: &()) -> Self {
let uuid = runner.uuid();
let options = secrets_app::Options::new(
trussed::types::Location::External,
Location::External,
CustomStatus::ReverseHotpSuccess.into(),
CustomStatus::ReverseHotpError.into(),
[uuid[0], uuid[1], uuid[2], uuid[3]],
Expand Down Expand Up @@ -804,7 +904,7 @@ impl<R: Runner> App<R> for OpcardApp<R> {
// See scd/app-openpgp.c in GnuPG for the manufacturer IDs
options.manufacturer = 0x000Fu16.to_be_bytes();
options.serial = [uuid[0], uuid[1], uuid[2], uuid[3]];
options.storage = trussed::types::Location::External;
options.storage = Location::External;
#[cfg(feature = "se050")]
{
if config.use_se050_backend {
Expand Down
12 changes: 8 additions & 4 deletions components/boards/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use apdu_dispatch::{
dispatch::ApduDispatch,
interchanges::{Channel as CcidChannel, Responder as CcidResponder, SIZE as CCID_SIZE},
};
#[cfg(any(feature = "trussed-auth", feature = "se050"))]
use apps::AUTH_LOCATION;
use apps::{AdminData, Data, Dispatch, FidoData, InitStatus};

use ctaphid_dispatch::{dispatch::Dispatch as CtaphidDispatch, types::Channel as CtapChannel};
#[cfg(not(feature = "no-delog"))]
use delog::delog;
Expand All @@ -11,7 +14,7 @@ use nfc_device::Iso14443;
use rand::{CryptoRng, Rng as _, RngCore, SeedableRng};
use rand_chacha::ChaCha8Rng;
use ref_swap::OptionRefSwap;
use trussed::{interrupt::InterruptFlag, platform::Store as _, types::Location};
use trussed::{interrupt::InterruptFlag, platform::Store as _};
use usb_device::{
bus::UsbBusAllocator,
device::{UsbDevice, UsbDeviceBuilder, UsbVidPid},
Expand Down Expand Up @@ -257,21 +260,22 @@ pub fn init_trussed<B: Board, R: CryptoRng + RngCore>(
#[cfg(feature = "trussed-auth")]
let dispatch = if let Some(hw_key) = hw_key {
Dispatch::with_hw_key(
Location::Internal,
AUTH_LOCATION,
trussed::types::Bytes::from_slice(hw_key).unwrap(),
#[cfg(feature = "se050")]
se050,
)
} else {
Dispatch::new(
Location::Internal,
AUTH_LOCATION,
#[cfg(feature = "se050")]
se050,
)
};
#[cfg(not(feature = "trussed-auth"))]
let dispatch = Dispatch::new(
Location::Internal,
#[cfg(feature = "se050")]
AUTH_LOCATION,
#[cfg(feature = "se050")]
se050,
);
Expand Down
6 changes: 3 additions & 3 deletions runners/embedded/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ utils = { path = "../../components/utils", features = ["build"] }
[features]
default = ["alloc"]

test = ["apps/nk3-test", "utils/test", "se050"]
test = ["apps/nk3-test", "utils/test"]
develop = ["no-encrypted-storage", "apps/no-reset-time-window", "log-traceP"]
develop-no-press = ["develop", "no-buttons"]
provisioner = ["apps/nk3-provisioner", "boards/provisioner", "write-undefined-flash", "no-buttons", "apps/no-reset-time-window", "lpc55-hardware-checks"]
Expand All @@ -80,8 +80,8 @@ format-filesystem = []

alloc = ["alloc-cortex-m"]

board-nk3am = ["boards/board-nk3am", "soc-nrf52"]
board-nk3xn = ["boards/board-nk3xn", "soc-lpc55"]
board-nk3am = ["boards/board-nk3am", "soc-nrf52", "se050"]
board-nk3xn = ["boards/board-nk3xn", "soc-lpc55", "se050"]

soc-nrf52 = ["nrf52840-hal", "nrf52840-pac"]
soc-lpc55 = ["lpc55-hal", "lpc55-pac", "nb", "systick-monotonic"]
Expand Down

0 comments on commit aae21b8

Please sign in to comment.