Skip to content

ci: modernize and fix pc#5

Open
0x0ece wants to merge 22 commits into
leetronics:mainfrom
solokeys:0x0ece/fix-194
Open

ci: modernize and fix pc#5
0x0ece wants to merge 22 commits into
leetronics:mainfrom
solokeys:0x0ece/fix-194

Conversation

@0x0ece
Copy link
Copy Markdown

@0x0ece 0x0ece commented Apr 19, 2026

No description provided.

manuel-domke and others added 20 commits March 25, 2026 23:20
- interchange 0.2.2 → 0.3
- apdu-dispatch 0.1.1 → 0.3
- ctaphid-dispatch 0.1.1 → 0.3
- ctap-types 0.1 → 0.4
- fido-authenticator 0.1.1 → 0.2
- usbd-ccid 0.1.0 → 0.3
- usbd-ctaphid 0.1.0 → 0.3
- littlefs2 0.3.2 → 0.6 (git tag v0.6.1-nitrokey.1)
- trussed: pin to git rev e107ed3
- admin-app: pin to git tag v0.1.0-nitrokey.20
- trussed-staging v0.3.3 with hkdf/fs-info/manage features (required by fido-authenticator 0.2)
- Add trussed-core, trussed-fs-info, trussed-hkdf, trussed-manage, ref-swap deps
- [patch.crates-io] for littlefs2, littlefs2-sys, littlefs2-core (resolves DynFilesystem trait version mismatch)
- Remove oath-authenticator from default features
- Remove trussed/clients-N feature flags (no longer needed with new trussed API)
- Update runners/pc and component Cargo.toml files to match
API migration for trussed 0.2 / interchange 0.3 / usbd-ccid 0.3:

Source changes:
- types/usb.rs: CcidClass gains 'static,'static lifetime params; CtapHidClass
  gains 3 lifetime params + const N; use usbd_ccid::Status (types module is
  private in 0.3)
- initializer.rs + stages.rs: replace interchange::Interchange static claims with
  Channel::new().split(); wire CTAPHID interrupt flag (OptionRefSwap);
  use CtapHid::with_interrupt for interrupt-based dispatch coordination
- lib.rs: remove unused Board import
- board/trussed.rs: add wildcard arm to exhaustive match
- ndef-app/ndef.rs, nfc-device/iso14443.rs: update apdu-dispatch 0.3 API
  (App<ResponseSize>, CommandView, Data, Interface types)
- main.rs: usbd_ccid::types::Status -> usbd_ccid::Status

Extension dispatch (required by fido-authenticator 0.2):
- types.rs: add Dispatch struct wrapping StagingBackend (provides FsInfoClient,
  HkdfClient for fido-authenticator; ManageClient for admin-app)
- BackendIds enum, ExtensionIds enum (Hkdf=1, Manage=2, FsInfo=4)
- STAGING_BACKENDS: [StagingBackend, Core] — Core is critical; omitting it causes
  all standard crypto calls to fail with RequestNotAvailable
- Trussed wrapper struct holding Service + service endpoints; replaces bare
  trussed::Service<Board> type alias
- Static TrussedChannel per app; make_client() splits channel and registers endpoint
- Apps struct rebuilt with new client provisioning pattern
- AdminApp gains StatusBytes type param (AdminStatus); uses with_default_config()
- fido_authenticator::Config gains nfc_transport field
…t coordination

Fix a deadlock that caused all CTAP2 commands to hang indefinitely:

ctaphid_dispatch.poll() was called inside usb_classes.lock(), which creates
an RTIC critical section that masks interrupts. When a FIDO/admin app calls
syscall!() to access trussed, it pends OS_EVENT and waits for the response.
OS_EVENT cannot run while interrupts are masked, so the device hangs.

Fix: move ctaphid_dispatch.poll() outside usb_classes.lock() so OS_EVENT
can preempt and process trussed requests during CTAP2 command handling.

Also fix USB poll ordering: usb_classes.poll() must run before
ctaphid_dispatch.poll() to ensure received USB packets are available
for processing by the dispatcher.

Fix vendor command dispatch order: admin-app must be checked before
fido-authenticator so admin vendor commands (VERSION, UUID, etc.) are
not absorbed by the FIDO handler.

Add minimal defmt logging for USB interrupts and CTAP2 flow.
… logging

Patch usbd-ctaphid to use a fork that fixes a WouldBlock race condition:
when a PING or other single-packet response is sent, the upstream crate
returns WouldBlock on retry instead of completing the transfer, causing
CTAP HID to stall indefinitely.

Also enable defmt logging on usbd-ctaphid (log-info + defmt-logging features)
and add log-defmt to the develop feature set for debug builds.
nisty is unmaintained and uses an internal ECC implementation. Replace it
with the actively maintained p256 crate for P-256 key generation and
attestation certificate operations.

Migrate the provisioner to the new apdu-dispatch 0.3 API (CommandView,
Interface, Data types) and update heapless to 0.8. Also clean up the key
serialization documentation (the binary format for trussed key objects).
Integrate trussed-secrets-app v0.14.0 to support Yubico OATH AID (TOTP/HOTP).

The secrets-app requires an Auth extension backend for PIN-protected credentials.
Extend the dispatch system with AuthBackend (trussed-auth-backend v0.4.0) alongside
the existing StagingBackend:

- Add BackendIds::Auth and ExtensionIds::Auth = 0 to the dispatch
- RunnerContext replaces StagingContext as the dispatch context type, combining
  AuthContext and StagingContext
- AUTH_BACKENDS: [Auth, Core] for secrets-app (auth extension must be first)
- make_client() now accepts a backends slice parameter to support both
  STAGING_BACKENDS (fido/admin/piv) and AUTH_BACKENDS (secrets-app)

Available features:
- oath = dep:secrets-app (APDU only; ctaphid-dispatch not used due to
  ctaphid-app 0.1.0-rc.1 vs 0.1.0 version conflict)
- develop-secrets = develop + oath (for debug builds with OATH support)
Enable oath feature in default features
runners/lpc55: add PIV authenticator support with extension backends
Switch secrets-app from upstream v0.14.0 to the fork at
leetronics/solokeys-secrets-app-fork branch fix-pin-protection-isolation-v0.14
which backports the PIN protection key isolation security fix.

Also:
- Add trussed-chunked/hpke/wrap-key-to-file as direct deps (required by
  unconditional imports in types.rs for PIV extension dispatch)
- Enable chunked/hpke/wrap-key-to-file features in trussed-staging so
  StagingBackend implements ExtensionImpl for those PIV extensions
- Enable ctaphid feature in secrets-app (allows OATH access via CTAPHID
  vendor command H70, ctaphid-app 0.1.0-rc.1 compatible with 0.1.0)
runners/lpc55: use PIN protection fix fork (v0.14.1)
Bump the full trussed ecosystem to support the v0.15 secrets-app branch
(fix-pin-protection-isolation) which is based on trussed-core v0.2.

Dependency changes:
- trussed: rev e107ed3 → 0f8df68 (trussed-core v0.2 basis)
- trussed-core: 0.1 → 0.2
- trussed-auth: 0.4 → 0.5
- trussed-auth-backend: tag v0.4.0 → backend-v0.1.0
- trussed-staging: v0.3.3 → v0.4.0 (adds chunked, hpke, wrap-key-to-file)
- apdu-dispatch: 0.3 → 0.4
- ctaphid-dispatch: 0.3 → 0.4
- fido-authenticator: 0.2 → 0.3 (requires dispatch feature)
- piv-authenticator: v0.5.3 → v0.6.0
- admin-app patch: v0.1.0-nitrokey.20 → v0.1.0-nitrokey.21
- usbd-ccid: 0.3 → 0.4
- usbd-ctaphid: 0.3 → 0.4 (crates.io; wouldblock fork no longer needed)
- littlefs2: git v0.6.1-nitrokey.1 → crates.io 0.7
- littlefs2-core patch: v0.6.1-nitrokey.1 → core-0.1.2 (has heapless-bytes05)
- ctap-types: 0.4 → 0.5
- components/ndef-app, nfc-device: heapless→0.9, apdu-dispatch→0.4, iso7816→0.2

API fixes:
- apdu_dispatch::App no longer has a ResponseSize generic param
- apdu_dispatch::iso7816::Interface replaces dispatch::Interface
- ctaphid_dispatch::App no longer has a message size generic param
- ndef-app: use VecView<u8> instead of Data<ResponseSize> (apdu-app 0.2)

Tested on hardware: CTAPHID PING, FIDO2 GET_INFO all pass. WouldBlock fix
confirmed unnecessary with usbd-ctaphid 0.4.
Integrates opcard-rs v1.7.0 as the OpenPGP smartcard applet. The applet
is included in the default feature set alongside PIV and TOTP.

Key implementation details:
- OPCARD_BACKENDS: [Auth, StagingBackend, Core] — same as PIV, needed
  for PIN operations (has_pin/set_pin/get_pin_key) and key wrapping
- opts.storage = Location::Internal so card state (PINs, keys,
  ADMIN_USER_KEY_BACKUP) persists across reboots; the default
  Location::External causes init_pins() to write to ExternalStorage,
  which on a 2-block filesystem has zero data blocks and panics via
  syscall!() → panic_halt
- ExternalStorage bumped to 8192 bytes whenever piv-authenticator or
  opcard is active (both write to External during init_pins)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants