Update trussed to the simplified Store trait

This commit is contained in:
Robin Krahl
2025-03-07 12:24:47 +01:00
parent a0e9b85580
commit d0774abda2
4 changed files with 192 additions and 145 deletions
Generated
+30 -41
View File
@@ -83,16 +83,14 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bindgen"
version = "0.69.5"
version = "0.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
dependencies = [
"bitflags 2.6.0",
"cexpr",
"clang-sys",
"itertools",
"lazy_static",
"lazycell",
"proc-macro2",
"quote",
"regex",
@@ -472,16 +470,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "embedded-hal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
]
[[package]]
name = "embedded-time"
version = "0.12.1"
@@ -560,6 +548,17 @@ dependencies = [
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "glob"
version = "0.3.1"
@@ -720,12 +719,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.146"
@@ -744,9 +737,9 @@ dependencies = [
[[package]]
name = "littlefs2"
version = "0.5.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6857dedc8aba748ea287177abe2bdfb3bb43464c3003f93cdc0a72e1e542b60f"
checksum = "32a43f3c0c6a7d127e3e1241665dd896d8bf1ca31cf9d826a1dc65239bd59868"
dependencies = [
"delog",
"generic-array",
@@ -757,9 +750,9 @@ dependencies = [
[[package]]
name = "littlefs2-core"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "250ec1e3017a4540932dc8b33daca325cb6195cded097e1addd9111d9ea2c48f"
checksum = "9a81a4745d38b288b7583fe8ea3736897628df81f4d0f1d0314fa5a3af570de4"
dependencies = [
"bitflags 2.6.0",
"heapless-bytes",
@@ -768,9 +761,9 @@ dependencies = [
[[package]]
name = "littlefs2-sys"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e9a93267fadc37e91758279342f2055b6c03b1187ec7a6b1419c3710172466e"
checksum = "32f7d54a8325846d818335f6e0a3ce4d4ff1d6a5cea7be989a76913dcb73afdc"
dependencies = [
"bindgen",
"cc",
@@ -826,15 +819,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.1.0",
]
[[package]]
name = "nb"
version = "1.1.0"
@@ -1098,6 +1082,9 @@ name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "ref-swap"
@@ -1453,7 +1440,7 @@ dependencies = [
[[package]]
name = "trussed"
version = "0.1.0"
source = "git+https://github.com/trussed-dev/trussed.git?rev=805fe7657e79e06b3220324481cd6325b94877d7#805fe7657e79e06b3220324481cd6325b94877d7"
source = "git+https://github.com/trussed-dev/trussed.git?rev=ac106d63ab5e19021b0e37f0efb4313f8168a110#ac106d63ab5e19021b0e37f0efb4313f8168a110"
dependencies = [
"aes",
"bitflags 2.6.0",
@@ -1465,7 +1452,6 @@ dependencies = [
"cosey",
"delog",
"des",
"embedded-hal",
"flexiber",
"generic-array",
"heapless",
@@ -1475,7 +1461,7 @@ dependencies = [
"interchange",
"littlefs2",
"littlefs2-core",
"nb 1.1.0",
"nb",
"p256-cortex-m4",
"postcard",
"rand_chacha",
@@ -1513,9 +1499,12 @@ dependencies = [
"delog",
"heapless-bytes",
"interchange",
"littlefs2",
"littlefs2-core",
"log",
"pretty_env_logger",
"rand_chacha",
"rand_core",
"trussed",
"usb-device",
"usbd-ccid",
@@ -1612,10 +1601,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "void"
version = "1.0.2"
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
+5 -2
View File
@@ -6,7 +6,10 @@ edition = "2021"
[dependencies]
interchange = "0.3.0"
littlefs2-core = "0.1"
log = { version = "0.4.14", default-features = false }
rand_chacha = { version = "0.3", default-features = false }
rand_core = { version = "0.6", features = ["getrandom"] }
trussed = { version = "0.1", default-features = false, features = ["log-all", "virt"] }
usb-device = { version = "0.2.7", default-features = false }
usbip-device = "0.1.5"
@@ -24,7 +27,7 @@ clap = { version = "3.0.0", features = ["derive"] }
clap-num = "1.0.0"
delog = { version = "0.1.6", features = ["std-log"] }
heapless-bytes = "0.3"
littlefs2-core = "0.1"
littlefs2 = "0.6"
pretty_env_logger = "0.4.0"
trussed = "0.1"
@@ -34,4 +37,4 @@ ctaphid = ["ctaphid-dispatch", "usbd-ctaphid"]
ccid = ["apdu-dispatch", "usbd-ccid"]
[patch.crates-io]
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "805fe7657e79e06b3220324481cd6325b94877d7" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "ac106d63ab5e19021b0e37f0efb4313f8168a110" }
+27 -10
View File
@@ -16,7 +16,11 @@ use ctaphid_dispatch::app::{Command, Error, VendorCommand};
use clap::Parser;
use clap_num::maybe_hex;
use littlefs2_core::path;
use littlefs2::{
const_ram_storage,
fs::{Allocation, Filesystem},
};
use littlefs2_core::{path, DynFilesystem};
use trussed::{
backend::{CoreOnly, NoId},
client::Client,
@@ -24,9 +28,8 @@ use trussed::{
service::Service,
syscall,
types::{CoreContext, NoData},
virt::{self, Platform, StoreProvider},
};
use trussed_usbip::Syscall;
use trussed_usbip::{Platform, Store, Syscall};
/// USP/IP based virtualization a Trussed device.
#[derive(Parser, Debug)]
@@ -91,13 +94,11 @@ struct Apps<C: Client> {
dummy: DummyApp<C>,
}
impl<'a, S: StoreProvider> trussed_usbip::Apps<'a, S, CoreOnly>
for Apps<trussed_usbip::Client<CoreOnly>>
{
impl<'a> trussed_usbip::Apps<'a, CoreOnly> for Apps<trussed_usbip::Client<CoreOnly>> {
type Data = ();
fn new(
_service: &mut Service<Platform<S>, CoreOnly>,
_service: &mut Service<Platform, CoreOnly>,
endpoints: &mut Vec<ServiceEndpoint<'static, NoId, NoData>>,
syscall: Syscall,
_data: (),
@@ -130,12 +131,27 @@ impl<'a, S: StoreProvider> trussed_usbip::Apps<'a, S, CoreOnly>
}
}
const_ram_storage!(RamStorage, 512 * 128);
fn ram_filesystem() -> &'static dyn DynFilesystem {
let storage = Box::leak(Box::new(RamStorage::new()));
Filesystem::format(storage).expect("failed to format RAM filesystem");
let alloc = Box::leak(Box::new(Allocation::new()));
let fs = Filesystem::mount(alloc, storage).expect("failed to mount RAM filesystem");
Box::leak(Box::new(fs))
}
fn main() {
pretty_env_logger::init();
let args = Args::parse();
let store = virt::Filesystem::new(args.state_file);
// TODO: use filesystem storage for IFS
let store = Store {
ifs: ram_filesystem(),
efs: ram_filesystem(),
vfs: ram_filesystem(),
};
let options = trussed_usbip::Options {
manufacturer: Some(args.manufacturer),
product: Some(args.name),
@@ -145,7 +161,8 @@ fn main() {
};
log::info!("Initializing Trussed");
trussed_usbip::Builder::new(store, options)
let platform = Platform::new(store);
trussed_usbip::Builder::new(options)
.build::<Apps<_>>()
.exec(|_| ());
.exec(platform, ());
}
+130 -92
View File
@@ -13,11 +13,16 @@ use std::{
time::{Duration, Instant},
};
use littlefs2_core::DynFilesystem;
use rand_chacha::ChaCha8Rng;
use rand_core::SeedableRng as _;
use trussed::{
backend::{CoreOnly, Dispatch},
pipe::ServiceEndpoint,
platform,
service::Service,
virt::{self, Platform, StoreProvider},
store,
virt::UserInterface,
ClientImplementation,
};
use usb_device::{
@@ -34,7 +39,7 @@ pub fn set_waiting(waiting: bool) {
pub type Client<D = CoreOnly> = ClientImplementation<'static, Syscall, D>;
pub type InitPlatform<S> = Box<dyn Fn(&mut Platform<S>)>;
pub type InitPlatform = Box<dyn Fn(&mut Platform)>;
pub struct Options {
pub manufacturer: Option<String>,
@@ -50,11 +55,11 @@ impl Options {
}
}
pub trait Apps<'interrupt, S: StoreProvider, D: Dispatch> {
pub trait Apps<'interrupt, D: Dispatch> {
type Data;
fn new(
service: &mut Service<Platform<S>, D>,
service: &mut Service<Platform, D>,
endpoints: &mut Vec<ServiceEndpoint<'static, D::BackendId, D::Context>>,
syscall: Syscall,
data: Self::Data,
@@ -78,140 +83,173 @@ pub trait Apps<'interrupt, S: StoreProvider, D: Dispatch> {
) -> T;
}
pub struct Runner<S: StoreProvider, D, A> {
store: S,
// virt::Store uses non-static references. To be able to use the usbip runner with apps that
// require direct access to the store, e. g. provisioner-app, we use a custom store implementation
// with static lifetimes here.
#[derive(Copy, Clone)]
pub struct Store {
pub ifs: &'static dyn DynFilesystem,
pub efs: &'static dyn DynFilesystem,
pub vfs: &'static dyn DynFilesystem,
}
impl store::Store for Store {
fn ifs(&self) -> &'static dyn DynFilesystem {
self.ifs
}
fn efs(&self) -> &'static dyn DynFilesystem {
self.efs
}
fn vfs(&self) -> &'static dyn DynFilesystem {
self.vfs
}
}
pub struct Platform {
rng: ChaCha8Rng,
store: Store,
ui: UserInterface,
}
impl Platform {
pub fn new(store: Store) -> Self {
Self {
store,
rng: ChaCha8Rng::from_entropy(),
ui: UserInterface::new(),
}
}
}
unsafe impl platform::Platform for Platform {
type R = ChaCha8Rng;
type S = Store;
type UI = UserInterface;
fn user_interface(&mut self) -> &mut Self::UI {
&mut self.ui
}
fn rng(&mut self) -> &mut Self::R {
&mut self.rng
}
fn store(&self) -> Self::S {
self.store
}
}
pub struct Runner<D, A> {
options: Options,
dispatch: D,
init_platform: Option<InitPlatform<S>>,
_marker: PhantomData<A>,
}
impl<'interrupt, S: StoreProvider, D: Dispatch, A: Apps<'interrupt, S, D>> Runner<S, D, A>
impl<'interrupt, D: Dispatch, A: Apps<'interrupt, D>> Runner<D, A>
where
D::BackendId: Send + Sync,
D::Context: Send + Sync,
{
pub fn builder(store: S, options: Options) -> Builder<S> {
Builder::new(store, options)
pub fn builder(options: Options) -> Builder {
Builder::new(options)
}
pub fn exec<F: Fn(&mut Platform<S>) -> A::Data>(self, make_data: F) {
virt::with_platform(self.store, |mut platform| {
if let Some(init_platform) = &self.init_platform {
init_platform(&mut platform);
}
let data = make_data(&mut platform);
pub fn exec(self, platform: Platform, data: A::Data) {
// To change IP or port see usbip-device-0.1.4/src/handler.rs:26
let bus_allocator = UsbBusAllocator::new(UsbIpBus::new());
// To change IP or port see usbip-device-0.1.4/src/handler.rs:26
let bus_allocator = UsbBusAllocator::new(UsbIpBus::new());
#[cfg(feature = "ctaphid")]
let ctap_channel = ctaphid_dispatch::Channel::new();
#[cfg(feature = "ctaphid")]
let (mut ctaphid, mut ctaphid_dispatch) = ctaphid::setup(&bus_allocator, &ctap_channel);
#[cfg(feature = "ctaphid")]
let ctap_channel = ctaphid_dispatch::Channel::new();
#[cfg(feature = "ctaphid")]
let (mut ctaphid, mut ctaphid_dispatch) = ctaphid::setup(&bus_allocator, &ctap_channel);
#[cfg(feature = "ccid")]
let (contact, contactless) = Default::default();
#[cfg(feature = "ccid")]
let (mut ccid, mut apdu_dispatch) = ccid::setup(&bus_allocator, &contact, &contactless);
#[cfg(feature = "ccid")]
let (contact, contactless) = Default::default();
#[cfg(feature = "ccid")]
let (mut ccid, mut apdu_dispatch) = ccid::setup(&bus_allocator, &contact, &contactless);
let mut usb_device = build_device(&bus_allocator, &self.options);
let mut service = Service::with_dispatch(platform, self.dispatch);
let mut endpoints = Vec::new();
let (syscall_sender, syscall_receiver) = mpsc::channel();
let syscall = Syscall(syscall_sender);
let mut apps = A::new(&mut service, &mut endpoints, syscall, data);
let mut usb_device = build_device(&bus_allocator, &self.options);
let mut service = Service::with_dispatch(platform, self.dispatch);
let mut endpoints = Vec::new();
let (syscall_sender, syscall_receiver) = mpsc::channel();
let syscall = Syscall(syscall_sender);
let mut apps = A::new(&mut service, &mut endpoints, syscall, data);
log::info!("Ready for work");
thread::scope(|s| {
// usb poll + keepalive task
s.spawn(move || {
let _epoch = Instant::now();
#[cfg(feature = "ctaphid")]
let mut timeout_ctaphid = Timeout::new();
#[cfg(feature = "ccid")]
let mut timeout_ccid = Timeout::new();
log::info!("Ready for work");
thread::scope(|s| {
// usb poll + keepalive task
s.spawn(move || {
let _epoch = Instant::now();
#[cfg(feature = "ctaphid")]
let mut timeout_ctaphid = Timeout::new();
#[cfg(feature = "ccid")]
let mut timeout_ccid = Timeout::new();
loop {
thread::sleep(Duration::from_millis(5));
usb_device.poll(&mut [
#[cfg(feature = "ctaphid")]
&mut ctaphid,
#[cfg(feature = "ccid")]
&mut ccid,
]);
#[cfg(feature = "ctaphid")]
ctaphid::keepalive(&mut ctaphid, &mut timeout_ctaphid, _epoch);
#[cfg(feature = "ccid")]
ccid::keepalive(&mut ccid, &mut timeout_ccid, _epoch);
}
});
// trussed task
s.spawn(move || {
for _ in syscall_receiver.iter() {
service.process(&mut endpoints)
}
});
// apps task
loop {
thread::sleep(Duration::from_millis(5));
usb_device.poll(&mut [
#[cfg(feature = "ctaphid")]
&mut ctaphid,
#[cfg(feature = "ccid")]
&mut ccid,
]);
#[cfg(feature = "ctaphid")]
apps.with_ctaphid_apps(|apps| ctaphid_dispatch.poll(apps));
ctaphid::keepalive(&mut ctaphid, &mut timeout_ctaphid, _epoch);
#[cfg(feature = "ccid")]
apps.with_ccid_apps(|apps| apdu_dispatch.poll(apps));
ccid::keepalive(&mut ccid, &mut timeout_ccid, _epoch);
}
});
})
// trussed task
s.spawn(move || {
for _ in syscall_receiver.iter() {
service.process(&mut endpoints)
}
});
// apps task
loop {
thread::sleep(Duration::from_millis(5));
#[cfg(feature = "ctaphid")]
apps.with_ctaphid_apps(|apps| ctaphid_dispatch.poll(apps));
#[cfg(feature = "ccid")]
apps.with_ccid_apps(|apps| apdu_dispatch.poll(apps));
}
});
}
}
pub struct Builder<S: StoreProvider, D = CoreOnly> {
store: S,
pub struct Builder<D = CoreOnly> {
options: Options,
dispatch: D,
init_platform: Option<InitPlatform<S>>,
}
impl<S: StoreProvider> Builder<S> {
pub fn new(store: S, options: Options) -> Self {
impl Builder {
pub fn new(options: Options) -> Self {
Self {
store,
options,
dispatch: Default::default(),
init_platform: Default::default(),
}
}
}
impl<S: StoreProvider, D> Builder<S, D> {
pub fn dispatch<E>(self, dispatch: E) -> Builder<S, E> {
impl<D> Builder<D> {
pub fn dispatch<E>(self, dispatch: E) -> Builder<E> {
Builder {
store: self.store,
options: self.options,
dispatch,
init_platform: self.init_platform,
}
}
pub fn init_platform<F>(mut self, f: F) -> Self
where
F: Fn(&mut Platform<S>) + 'static,
{
self.init_platform = Some(Box::new(f));
self
}
}
impl<S: StoreProvider, D: Dispatch> Builder<S, D> {
pub fn build<'interrupt, A: Apps<'interrupt, S, D>>(self) -> Runner<S, D, A> {
impl<D: Dispatch> Builder<D> {
pub fn build<'interrupt, A: Apps<'interrupt, D>>(self) -> Runner<D, A> {
Runner {
store: self.store,
options: self.options,
dispatch: self.dispatch,
init_platform: self.init_platform,
_marker: Default::default(),
}
}