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

Enable SE050 by default #471

Merged
merged 7 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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