From d8796c2f3a6af99397d7d569d41caf2337386528 Mon Sep 17 00:00:00 2001 From: Emanuele Cesena Date: Sat, 18 Apr 2026 20:55:45 -0700 Subject: [PATCH] ci: modernize and fix pc --- .cargo/config.toml | 3 - .github/workflows/ci.yml | 6 +- Cargo.lock | 110 +++++++++++++------ Cargo.toml | 11 +- runners/lpc55/.cargo/config.toml | 2 + runners/pc/.cargo/{config => config.toml} | 0 runners/pc/Cargo.toml | 50 ++++----- runners/pc/src/bin/main.rs | 127 ++++++++++------------ rust-toolchain.toml | 4 + 9 files changed, 168 insertions(+), 145 deletions(-) create mode 100644 runners/lpc55/.cargo/config.toml rename runners/pc/.cargo/{config => config.toml} (100%) create mode 100644 rust-toolchain.toml diff --git a/.cargo/config.toml b/.cargo/config.toml index 99cba13..e7336ef 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,6 +6,3 @@ rustflags = [ "-C", "link-arg=-Tdefmt.x", "-Dwarnings", ] - -[build] -target = "thumbv8m.main-none-eabi" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a442de3..24734a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - board-solo2 # - board-okdoe1 rust: - - stable + - "1.94" defaults: run: working-directory: runners/lpc55 @@ -73,7 +73,7 @@ jobs: path: runners/lpc55/target/thumbv8m.main-none-eabi/release/runner - name: Build Provisioner run: | - cargo build --release --features ${{ matrix.board }},provisioner-app,admin-app,trussed/clients-2,provisioner-app/test-attestation + cargo build --release --features ${{ matrix.board }},provisioner-app,admin-app,provisioner-app/test-attestation - name: Upload Provisioner uses: actions/upload-artifact@v4 continue-on-error: true @@ -91,7 +91,7 @@ jobs: # TODO: some build issue currently # - macos-latest rust: - - stable + - "1.94" defaults: run: working-directory: runners/pc diff --git a/Cargo.lock b/Cargo.lock index bc4aa05..a43210b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", - "generic-array", + "generic-array 0.14.7", "heapless 0.7.17", ] @@ -161,7 +161,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -170,7 +170,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -179,7 +179,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -248,6 +248,18 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "chacha20" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08493fa7707effc63254c66c6ea908675912493cd67952eda23c09fae2610b1" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "rand_core", +] + [[package]] name = "chacha20" version = "0.9.1" @@ -266,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", - "chacha20", + "chacha20 0.9.1", "cipher 0.4.4", "poly1305", "zeroize", @@ -278,7 +290,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -318,23 +330,22 @@ dependencies = [ [[package]] name = "cortex-m-rt" -version = "0.6.15" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "454f278bf469e2de0a4d22ea019d169d8944f86957c8207a39e3f66c32be2fc6" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" dependencies = [ "cortex-m-rt-macros", - "r0", ] [[package]] name = "cortex-m-rt-macros" -version = "0.6.15" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3aa52243e26f5922fa522b0814019e0c98fc567e2756d715dce7ad7a81f49" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -369,7 +380,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core", "subtle", "zeroize", @@ -381,7 +392,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ - "generic-array", + "generic-array 0.14.7", "typenum", ] @@ -391,7 +402,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ - "generic-array", + "generic-array 0.14.7", "subtle", ] @@ -532,7 +543,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -581,7 +592,7 @@ checksum = "83e5c176479da93a0983f0a6fdc3c1b8e7d5be0d7fe3fe05a99f15b96582b9a8" dependencies = [ "crypto-bigint", "ff", - "generic-array", + "generic-array 0.14.7", "group", "rand_core", "subtle", @@ -814,6 +825,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "generic-array" +version = "1.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf57c49a95fd1fe24b90b3033bee6dc7e8f1288d51494cb44e627c295e38542" +dependencies = [ + "rustversion", + "typenum", +] + [[package]] name = "glob" version = "0.3.3" @@ -974,7 +995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ "block-padding", - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -1049,7 +1070,7 @@ checksum = "6c8022e5141ceff5b7b12897113f54fc9dac5ad36402c787941c97272b9241eb" dependencies = [ "bitflags 2.11.0", "delog", - "generic-array", + "generic-array 0.14.7", "heapless 0.9.2", "littlefs2-core", "littlefs2-sys", @@ -1119,17 +1140,17 @@ dependencies = [ [[package]] name = "lpc55-hal" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ca5d2ad4d3068ed67b8d5b2f59eb64d4194e5d59c096657901c7b09e30069f" +checksum = "41e86e4e491dd3f8e07e7ba6de4aace716459ddefebd05743b2cb67b6a566d3c" dependencies = [ - "block-buffer 0.9.0", - "cipher 0.3.0", + "block-buffer 0.10.4", + "cipher 0.4.4", "cortex-m", - "digest 0.9.0", + "digest 0.10.7", "embedded-hal 0.2.7", "embedded-time", - "generic-array", + "generic-array 1.3.5", "lpc55-pac", "nb 1.1.0", "rand_core", @@ -1140,9 +1161,9 @@ dependencies = [ [[package]] name = "lpc55-pac" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1b5b32d313af526145882f5115a55177f479e9328ca667a84aaaa1ae6d65d3" +checksum = "3a4952baed9d9e7e82a6bbc87333f939b90eb41df3e6c0be5e35d0ec61005f91" dependencies = [ "cortex-m", "cortex-m-rt", @@ -1527,12 +1548,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r0" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" - [[package]] name = "rand_chacha" version = "0.3.1" @@ -1966,6 +1981,31 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "solo-pc" +version = "2.2281.0" +dependencies = [ + "admin-app", + "apdu-dispatch 0.4.0", + "chacha20 0.7.3", + "ctap-types", + "ctaphid-dispatch", + "delog", + "embedded-hal 0.2.7", + "fido-authenticator", + "generic-array 0.14.7", + "interchange 0.3.2", + "littlefs2", + "nb 1.1.0", + "ndef-app", + "nfc-device", + "piv-authenticator", + "trussed", + "trussed-core", + "usbd-ccid", + "usbd-ctaphid", +] + [[package]] name = "spin" version = "0.9.8" @@ -2165,13 +2205,13 @@ dependencies = [ "cbc", "cbor-smol", "cfg-if", - "chacha20", + "chacha20 0.9.1", "chacha20poly1305", "cosey", "delog", "des", "flexiber 0.2.0", - "generic-array", + "generic-array 0.14.7", "heapless 0.9.2", "heapless-bytes 0.5.0", "hex-literal 0.4.1", diff --git a/Cargo.toml b/Cargo.toml index 3b76dbb..66a97d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,20 @@ members = [ "runners/lpc55", "runners/lpc55/board", + "runners/pc", "components/ndef-app", "components/nfc-device", "components/fm11nc08", "components/provisioner-app", ] +# Host-buildable members only. The lpc55 runner/board, fm11nc08, and +# provisioner-app (via lpc55-hal) / nfc-device (via embedded deps) all require an +# ARM target and can't link on the host, so they're excluded from default +# commands like `cargo test`. +default-members = [ + "runners/pc", + "components/ndef-app", +] resolver = "2" [workspace.package] @@ -34,7 +43,7 @@ systick-monotonic = "1.0.1" # ── Cortex-M / embedded ─────────────────────────────────────────────────────── cortex-m = { version = "0.7.0", features = ["critical-section-single-core"] } -lpc55-hal = "0.4.1" +lpc55-hal = "0.5.0" micromath = "2" embedded-time = "0.12" embedded-hal = { version = "0.2.5", features = ["unproven"] } diff --git a/runners/lpc55/.cargo/config.toml b/runners/lpc55/.cargo/config.toml new file mode 100644 index 0000000..c87b5c6 --- /dev/null +++ b/runners/lpc55/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "thumbv8m.main-none-eabi" diff --git a/runners/pc/.cargo/config b/runners/pc/.cargo/config.toml similarity index 100% rename from runners/pc/.cargo/config rename to runners/pc/.cargo/config.toml diff --git a/runners/pc/Cargo.toml b/runners/pc/Cargo.toml index a5470fb..b916e93 100644 --- a/runners/pc/Cargo.toml +++ b/runners/pc/Cargo.toml @@ -1,40 +1,40 @@ [package] name = "solo-pc" -version = "0.1.0" -authors = ["Nicolas Stalder ", "Conor Patrick "] -edition = "2018" +version.workspace = true +authors.workspace = true +edition.workspace = true [dependencies] chacha20 = { version = "0.7", features = ["rng"] } delog = "0.1.0" embedded-hal = { version = "0.2", features = ["unproven"] } generic-array = "0.14.3" -interchange = "0.3" -nb = "1" +interchange.workspace = true +nb.workspace = true -admin-app = "0.1" -apdu-dispatch = "0.3" -ctap-types = "0.1" -ctaphid-dispatch = "0.2" -fido-authenticator = { version = "0.2", features = ["dispatch"], optional = true } -piv-authenticator = { git = "https://github.com/trussed-dev/piv-authenticator", tag = "v0.5.3" } -trussed = "0.1" -trussed-core = "0.1" +admin-app.workspace = true +apdu-dispatch.workspace = true +ctap-types.workspace = true +ctaphid-dispatch.workspace = true +fido-authenticator = { workspace = true, optional = true } +piv-authenticator.workspace = true +trussed.workspace = true +trussed-core.workspace = true # components -usbd-ccid = "0.2" -usbd-ctaphid = "0.3" -nfc-device = {path = "./../../components/nfc-device"} -ndef-app = {path = "./../../components/ndef-app"} +usbd-ccid.workspace = true +usbd-ctaphid.workspace = true +nfc-device.workspace = true +ndef-app.workspace = true # storage -littlefs2 = "0.6" +littlefs2.workspace = true [features] default = [] # Use to auto-succeed every user presence check -no-buttons= [] +no-buttons = [] # Reconfigure the NFC chip in any case reconfigure-nfc = [] @@ -45,15 +45,3 @@ log-info = [] log-debug = [] log-warn = [] log-error = [] - -[patch.crates-io] -trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "e107ed315a07dc6c992fac39d542e847cc3a1b6c" } -admin-app = { git = "https://github.com/Nitrokey/admin-app.git", tag = "v0.1.0-nitrokey.20" } -littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", tag = "v0.6.1-nitrokey.1" } -littlefs2-sys = { git = "https://github.com/trussed-dev/littlefs2-sys.git", tag = "v0.3.1-nitrokey.1" } - -[profile.release] -codegen-units = 1 -opt-level = "z" -incremental = false -debug = true diff --git a/runners/pc/src/bin/main.rs b/runners/pc/src/bin/main.rs index 49f1a11..d776095 100644 --- a/runners/pc/src/bin/main.rs +++ b/runners/pc/src/bin/main.rs @@ -2,14 +2,14 @@ use std::{fs::File, io::Write}; pub use embedded_hal::blocking::rng; use littlefs2::{const_ram_storage, consts}; use littlefs2::fs::{Allocation, Filesystem}; -use trussed::types::{LfsResult, LfsStorage}; +use trussed::store::DynFilesystem; use trussed::platform::{ ui, reboot, consent, }; -use trussed::{platform, store}; +use trussed::platform; pub use generic_array::{ GenericArray, @@ -33,7 +33,7 @@ pub mod littlefs_params { pub const BLOCK_CYCLES: isize = -1; pub type CACHE_SIZE = U512; - pub type LOOKAHEADWORDS_SIZE = U16; + pub type LOOKAHEAD_SIZE = U16; /// TODO: We can't actually be changed currently pub type FILENAME_MAX_PLUS_ONE = U256; pub type PATH_MAX_PLUS_ONE = U256; @@ -69,17 +69,17 @@ impl littlefs2::driver::Storage for FileFlash { const BLOCK_CYCLES: isize = littlefs_params::BLOCK_CYCLES; type CACHE_SIZE = littlefs_params::CACHE_SIZE; - type LOOKAHEADWORDS_SIZE = littlefs_params::LOOKAHEADWORDS_SIZE; + type LOOKAHEAD_SIZE = littlefs_params::LOOKAHEAD_SIZE; - fn read(&self, off: usize, buf: &mut [u8]) -> LfsResult { + fn read(&mut self, off: usize, buf: &mut [u8]) -> littlefs2::io::Result { for i in 0 .. buf.len() { buf[i] = self.state[i + off]; } Ok(buf.len()) } - fn write(&mut self, off: usize, data: &[u8]) -> LfsResult { + fn write(&mut self, off: usize, data: &[u8]) -> littlefs2::io::Result { for i in 0 .. data.len() { self.state[i + off] = data[i]; } @@ -89,7 +89,7 @@ impl littlefs2::driver::Storage for FileFlash { Ok(data.len()) } - fn erase(&mut self, off: usize, len: usize) -> LfsResult { + fn erase(&mut self, off: usize, len: usize) -> littlefs2::io::Result { for i in 0 .. len { self.state[i + off] = 0; } @@ -103,7 +103,6 @@ impl littlefs2::driver::Storage for FileFlash { // 8KB of RAM const_ram_storage!( name=VolatileStorage, - trait=LfsStorage, erase_value=0x00, read_size=1, write_size=1, @@ -111,42 +110,30 @@ const_ram_storage!( // this is a limitation of littlefs // https://git.io/JeHp9 block_size=128, - // block_size=128, block_count=8192/128, - lookaheadwords_size_ty=consts::U8, + lookahead_size_ty=consts::U8, filename_max_plus_one_ty=consts::U256, path_max_plus_one_ty=consts::U256, - result=LfsResult, ); // minimum: 2 blocks // TODO: make this optional const_ram_storage!(ExternalStorage, 1024); -store!(Store, - Internal: FileFlash, - External: ExternalStorage, - Volatile: VolatileStorage -); +#[derive(Clone, Copy)] +pub struct RunnerStore { + ifs: &'static dyn DynFilesystem, + efs: &'static dyn DynFilesystem, + vfs: &'static dyn DynFilesystem, +} +impl trussed::store::Store for RunnerStore { + fn ifs(&self) -> &dyn DynFilesystem { self.ifs } + fn efs(&self) -> &dyn DynFilesystem { self.efs } + fn vfs(&self) -> &dyn DynFilesystem { self.vfs } +} - -// #[derive(Default)] -// pub struct Rng { -// count: u64, -// } - -// impl rng::Read for Rng { -// type Error = core::convert::Infallible; -// fn read(&mut self, buffer: &mut [u8]) -> core::result::Result<(), Self::Error> { -// // bad -// for i in 0 .. buffer.len() { -// self.count += 1; -// buffer[i] = (self.count & 0xff) as u8; -// } -// Ok(()) -// } -// } +pub type Store = RunnerStore; #[derive(Default)] @@ -188,51 +175,47 @@ platform!(Board, fn main () { - let filesystem = FileFlash::new(); + // Allocate and mount three filesystems, leaking them to obtain 'static refs. + let internal_storage: &'static mut FileFlash = Box::leak(Box::new(FileFlash::new())); + let internal_alloc: &'static mut Allocation = + Box::leak(Box::new(Filesystem::allocate())); - static mut INTERNAL_STORAGE: Option = None; - unsafe { INTERNAL_STORAGE = Some(filesystem); } - static mut INTERNAL_FS_ALLOC: Option> = None; - unsafe { INTERNAL_FS_ALLOC = Some(Filesystem::allocate()); } + let external_storage: &'static mut ExternalStorage = + Box::leak(Box::new(ExternalStorage::new())); + let external_alloc: &'static mut Allocation = + Box::leak(Box::new(Filesystem::allocate())); - static mut EXTERNAL_STORAGE: ExternalStorage = ExternalStorage::new(); - static mut EXTERNAL_FS_ALLOC: Option> = None; - unsafe { EXTERNAL_FS_ALLOC = Some(Filesystem::allocate()); } + let volatile_storage: &'static mut VolatileStorage = + Box::leak(Box::new(VolatileStorage::new())); + let volatile_alloc: &'static mut Allocation = + Box::leak(Box::new(Filesystem::allocate())); - static mut VOLATILE_STORAGE: VolatileStorage = VolatileStorage::new(); - static mut VOLATILE_FS_ALLOC: Option> = None; - unsafe { VOLATILE_FS_ALLOC = Some(Filesystem::allocate()); } - - - let store = Store::claim().unwrap(); - - let result = store.mount( - unsafe { INTERNAL_FS_ALLOC.as_mut().unwrap() }, - // unsafe { &mut INTERNAL_STORAGE }, - unsafe { INTERNAL_STORAGE.as_mut().unwrap() }, - unsafe { EXTERNAL_FS_ALLOC.as_mut().unwrap() }, - unsafe { &mut EXTERNAL_STORAGE }, - unsafe { VOLATILE_FS_ALLOC.as_mut().unwrap() }, - unsafe { &mut VOLATILE_STORAGE }, - // to trash existing data, set to true - false, - ); - - if result.is_err() { + // Internal FS: try mount, format on failure. + if Filesystem::mount(internal_alloc, internal_storage).is_err() { println!("Not yet formatted! Formatting.."); - store.mount( - unsafe { INTERNAL_FS_ALLOC.as_mut().unwrap() }, - // unsafe { &mut INTERNAL_STORAGE }, - unsafe { INTERNAL_STORAGE.as_mut().unwrap() }, - unsafe { EXTERNAL_FS_ALLOC.as_mut().unwrap() }, - unsafe { &mut EXTERNAL_STORAGE }, - unsafe { VOLATILE_FS_ALLOC.as_mut().unwrap() }, - unsafe { &mut VOLATILE_STORAGE }, - // to trash existing data, set to true - true, - ).unwrap(); + Filesystem::format(internal_storage).unwrap(); } + let internal_fs: &'static mut Filesystem<'static, FileFlash> = Box::leak(Box::new( + Filesystem::mount(internal_alloc, internal_storage).unwrap(), + )); + // External FS (RAM): always needs format on first use. + Filesystem::format(external_storage).unwrap(); + let external_fs: &'static mut Filesystem<'static, ExternalStorage> = Box::leak(Box::new( + Filesystem::mount(external_alloc, external_storage).unwrap(), + )); + + // Volatile FS (RAM): always needs format on first use. + Filesystem::format(volatile_storage).unwrap(); + let volatile_fs: &'static mut Filesystem<'static, VolatileStorage> = Box::leak(Box::new( + Filesystem::mount(volatile_alloc, volatile_storage).unwrap(), + )); + + let store = RunnerStore { + ifs: internal_fs, + efs: external_fs, + vfs: volatile_fs, + }; use trussed::service::SeedableRng; let rng = chacha20::ChaCha8Rng::from_seed([0u8; 32]); diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5929cac --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.94" +components = ["llvm-tools-preview"] +targets = ["thumbv8m.main-none-eabi"]