From 78c673bda6eebe7d53d8190e98955a89146bcf09 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Sat, 5 Mar 2022 22:03:47 +0100 Subject: [PATCH 01/18] Inline never in usbd-{ccid,ctaphid} --- components/dispatch-fido/Cargo.toml | 31 --- components/dispatch-fido/src/cbor.rs | 155 -------------- components/dispatch-fido/src/fido.rs | 296 --------------------------- components/dispatch-fido/src/lib.rs | 15 -- components/usbd-ccid/src/class.rs | 1 + components/usbd-ccid/src/pipe.rs | 2 + components/usbd-ctaphid/src/class.rs | 8 +- components/usbd-ctaphid/src/pipe.rs | 10 +- 8 files changed, 10 insertions(+), 508 deletions(-) delete mode 100644 components/dispatch-fido/Cargo.toml delete mode 100644 components/dispatch-fido/src/cbor.rs delete mode 100644 components/dispatch-fido/src/fido.rs delete mode 100644 components/dispatch-fido/src/lib.rs diff --git a/components/dispatch-fido/Cargo.toml b/components/dispatch-fido/Cargo.toml deleted file mode 100644 index 9e9ce6d4..00000000 --- a/components/dispatch-fido/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "dispatch-fido" -version = "0.1.0" -authors = ["Conor Patrick "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -delog = "0.1.0" -heapless = "0.6" -heapless-bytes = "0.3" -interchange = "0.2.0" -serde = { version = "1", default-features = false } - -apdu-dispatch = { git = "https://github.com/solokeys/apdu-dispatch" } -ctaphid-dispatch = { git = "https://github.com/solokeys/ctaphid-dispatch" } -ctap-types = { git = "https://github.com/solokeys/ctap-types" } -fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator" } -iso7816 = { git = "https://github.com/ycrypto/iso7816" } -trussed = { git = "https://github.com/trussed-dev/trussed" } - -[features] -default = [] - -log-all = [] -log-none = [] -log-info = [] -log-debug = [] -log-warn = [] -log-error = [] diff --git a/components/dispatch-fido/src/cbor.rs b/components/dispatch-fido/src/cbor.rs deleted file mode 100644 index dc403b83..00000000 --- a/components/dispatch-fido/src/cbor.rs +++ /dev/null @@ -1,155 +0,0 @@ -use core::convert::From; -use core::convert::TryFrom; -use ctap_types::{ - authenticator::{Request, Error as AuthenticatorError}, - operation::Operation, - serde::{cbor_deserialize, error::Error as SerdeError}, -}; - -pub enum CtapMappingError { - InvalidCommand(u8), - ParsingError(SerdeError), -} - -impl From for AuthenticatorError { - fn from(mapping_error: CtapMappingError) -> AuthenticatorError { - match mapping_error { - CtapMappingError::InvalidCommand(_cmd) => { - AuthenticatorError::InvalidCommand - } - CtapMappingError::ParsingError(cbor_error) => { - match cbor_error { - SerdeError::SerdeMissingField => AuthenticatorError::MissingParameter, - _ => AuthenticatorError::InvalidCbor - } - } - } - - } -} - -pub fn parse_cbor(data: &[u8]) -> core::result::Result { - - if data.len() < 1 { - return Err(CtapMappingError::ParsingError(SerdeError::DeserializeUnexpectedEnd)); - } - - let operation_u8: u8 = data[0]; - - let operation = match Operation::try_from(operation_u8) { - Ok(operation) => { - operation - }, - _ => { - return Err(CtapMappingError::InvalidCommand(operation_u8)); - } - }; - - // use ctap_types::ctap2::*; - use ctap_types::authenticator::*; - - match operation { - Operation::MakeCredential => { - info!("authenticatorMakeCredential"); - match cbor_deserialize(&data[1..]) { - Ok(params) => { - Ok(Request::Ctap2(ctap2::Request::MakeCredential(params))) - }, - Err(error) => { - Err(CtapMappingError::ParsingError(error)) - } - } - // TODO: ensure earlier that RPC send queue is empty - } - - Operation::GetAssertion => { - info!("authenticatorGetAssertion"); - - match cbor_deserialize(&data[1..]) { - Ok(params) => { - Ok(Request::Ctap2(ctap2::Request::GetAssertion(params))) - }, - Err(error) => { - Err(CtapMappingError::ParsingError(error)) - } - } - // TODO: ensure earlier that RPC send queue is empty - } - - Operation::GetNextAssertion => { - info!("authenticatorGetNextAssertion"); - - // TODO: ensure earlier that RPC send queue is empty - Ok(Request::Ctap2(ctap2::Request::GetNextAssertion)) - } - - Operation::CredentialManagement => { - info!("authenticatorCredentialManagement"); - - match cbor_deserialize(&data[1..]) { - Ok(params) => { - Ok(Request::Ctap2(ctap2::Request::CredentialManagement(params))) - }, - Err(error) => { - Err(CtapMappingError::ParsingError(error)) - } - } - // TODO: ensure earlier that RPC send queue is empty - } - - Operation::Reset => { - info!("authenticatorReset"); - - // TODO: ensure earlier that RPC send queue is empty - Ok(Request::Ctap2(ctap2::Request::Reset)) - } - - Operation::GetInfo => { - info!("authenticatorGetInfo"); - // TODO: ensure earlier that RPC send queue is empty - Ok(Request::Ctap2(ctap2::Request::GetInfo)) - } - - Operation::ClientPin => { - info!("authenticatorClientPin"); - match cbor_deserialize(&data[1..]) - { - Ok(params) => { - - Ok(Request::Ctap2(ctap2::Request::ClientPin(params))) - }, - Err(error) => { - - Err(CtapMappingError::ParsingError(error)) - } - } - // TODO: ensure earlier that RPC send queue is empty - } - - Operation::Vendor(vendor_operation) => { - info!("authenticatorVendor({:?})", &vendor_operation); - - let vo_u8: u8 = vendor_operation.into(); - if vo_u8 == 0x41 { - // copy-pasta for now - match cbor_deserialize(&data[1..]) - { - Ok(params) => { - Ok(Request::Ctap2(ctap2::Request::CredentialManagement(params))) - }, - Err(error) => { - Err(CtapMappingError::ParsingError(error)) - } - } - // TODO: ensure earlier that RPC send queue is empty - - } else { - // TODO: ensure earlier that RPC send queue is empty - Ok(Request::Ctap2(ctap2::Request::Vendor(vendor_operation))) - } - } - _ => { - Err(CtapMappingError::InvalidCommand(operation_u8)) - } - } -} diff --git a/components/dispatch-fido/src/fido.rs b/components/dispatch-fido/src/fido.rs deleted file mode 100644 index dd4b9b83..00000000 --- a/components/dispatch-fido/src/fido.rs +++ /dev/null @@ -1,296 +0,0 @@ -use core::convert::TryFrom; -use iso7816::{Instruction, Status}; -use apdu_dispatch::{Command, response, app}; -use ctaphid_dispatch::command::Command as FidoCommand; -use ctap_types::{ - authenticator::Error as AuthenticatorError, - authenticator::Request as AuthenticatorRequest, - serde::{cbor_serialize}, - ctap1::{Command as U2fCommand}, -}; - -use crate::cbor::{parse_cbor}; - -use trussed::client; -use fido_authenticator::{Authenticator, UserPresence}; -use ctaphid_dispatch::app as hid; - -pub struct Fido -where UP: UserPresence, -{ - authenticator: Authenticator, -} - -impl Fido -where UP: UserPresence, - Trussed: client::Client - + client::P256 - + client::Chacha8Poly1305 - + client::Aes256Cbc - + client::Sha256 - + client::HmacSha256 - + client::Ed255 - + client::Totp -{ - pub fn new(authenticator: Authenticator) -> Fido { - Self { authenticator } - } - - fn response_from_object(&mut self, object: Option, reply: &mut response::Data) -> app::Result { - reply.resize_default(reply.capacity()).ok(); - if let Some(object) = object { - match cbor_serialize(&object, &mut reply[1..]) { - Ok(ser) => { - let l = ser.len(); - reply[0] = 0; - reply.resize_default(l + 1).unwrap(); - } - Err(_) => { - reply[0] = AuthenticatorError::Other as u8; - reply.resize_default(1).unwrap(); - } - } - } else { - reply[0] = 0; - reply.resize_default(1).unwrap(); - } - Ok(()) - } - - fn call_authenticator(&mut self, request: &AuthenticatorRequest, reply: &mut response::Data) -> app::Result { - - let result = self.authenticator.call(request); - match &result { - Err(error) => { - info!("error {}", *error as u8); - reply.push(*error as u8).ok(); - Ok(()) - } - - Ok(response) => { - use ctap_types::authenticator::Response; - match response { - Response::Ctap1(_response) => { - todo!("CTAP1 responses"); - } - - Response::Ctap2(response) => { - use ctap_types::authenticator::ctap2::Response; - match response { - Response::GetInfo(response) => { - self.response_from_object(Some(response), reply) - }, - - Response::MakeCredential(response) => { - self.response_from_object(Some(response), reply) - }, - - Response::ClientPin(response) => { - self.response_from_object(Some(response), reply) - }, - - Response::GetAssertion(response) => { - self.response_from_object(Some(response), reply) - }, - - Response::GetNextAssertion(response) => { - self.response_from_object(Some(response), reply) - }, - - Response::CredentialManagement(response) => { - self.response_from_object(Some(response), reply) - }, - - Response::Reset => { - self.response_from_object::<()>(None, reply) - }, - - Response::Vendor => { - self.response_from_object::<()>(None, reply) - }, - } - } - } - } - } - } - - #[inline(never)] - fn call_authenticator_u2f_with_bytes(&mut self, request: &response::Data, reply: &mut response::Data) -> app::Result { - match &Command::try_from(request) { - Ok(command) => { - self.call_authenticator_u2f(command, reply) - }, - _ => { - Err(Status::IncorrectDataParameter) - } - } - } - - #[inline(never)] - fn call_authenticator_u2f(&mut self, apdu: &Command, reply: &mut response::Data) -> app::Result { - let u2f_command = U2fCommand::try_from(apdu)?; - let result = self.authenticator.call_u2f(&u2f_command); - match result { - Ok(u2f_response) => { - u2f_response.serialize(reply).unwrap(); - Ok(()) - } - Err(err)=> Err(err) - } - } - - - -} - -impl iso7816::App for Fido -where UP: UserPresence, -{ - fn aid(&self) -> iso7816::Aid { - iso7816::Aid::new(&[ 0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01]) - } -} - -impl app::App< - {apdu_dispatch::command::SIZE}, - {apdu_dispatch::response::SIZE}, -> for Fido -where UP: UserPresence, - T: client::Client - + client::P256 - + client::Chacha8Poly1305 - + client::Aes256Cbc - + client::Sha256 - + client::HmacSha256 - + client::Ed255 - + client::Totp -{ - - - fn select(&mut self, _apdu: &Command, reply: &mut response::Data) -> app::Result { - // U2F_V2 - reply.extend_from_slice(& [0x55, 0x32, 0x46, 0x5f, 0x56, 0x32,]).unwrap(); - Ok(()) - } - - fn deselect(&mut self) {} - - fn call(&mut self, _type: app::Interface, apdu: &Command, reply: &mut response::Data) -> app::Result { - let instruction = apdu.instruction(); - - match instruction { - Instruction::Unknown(ins) => { - // TODO need to tidy up these ins codes somewhere - match ins { - // U2F ins codes - 0x00 | 0x01 | 0x02 => { - self.call_authenticator_u2f(apdu, reply) - } - _ => { - match FidoCommand::try_from(ins) { - Ok(FidoCommand::Cbor) => { - match parse_cbor(apdu.data()) { - Ok(request) => { - info!("parsed cbor"); - self.call_authenticator(&request, reply) - } - Err(mapping_error) => { - let authenticator_error: AuthenticatorError = mapping_error.into(); - info!("cbor mapping error: {}", authenticator_error as u8); - reply.push(authenticator_error as u8).ok(); - Ok(()) - } - } - } - Ok(FidoCommand::Msg) => { - self.call_authenticator_u2f(apdu, reply) - } - Ok(FidoCommand::Deselect) => { - self.deselect(); - Ok(()) - } - _ => { - info!("Unsupported ins for fido app {:02x}", ins); - Err(Status::InstructionNotSupportedOrInvalid) - } - } - } - } - - } - _ => { - info!("Unsupported ins for fido app"); - Err(Status::InstructionNotSupportedOrInvalid) - } - } - } - -} - -impl hid::App for Fido -where UP: UserPresence, - T: client::Client - + client::P256 - + client::Chacha8Poly1305 - + client::Aes256Cbc - + client::Sha256 - + client::HmacSha256 - + client::Ed255 - + client::Totp -{ - - fn commands(&self,) -> &'static [hid::Command] { - &[ hid::Command::Cbor, hid::Command::Msg ] - } - - #[inline(never)] - fn call(&mut self, command: hid::Command, request: &hid::Message, response: &mut hid::Message) -> hid::AppResult { - - if request.len() < 1 { - return Err(hid::Error::InvalidLength); - } - // info_now!("request: "); - // blocking::dump_hex(request, request.len()); - match command { - hid::Command::Cbor => { - match parse_cbor(request) { - Ok(request) => { - self.call_authenticator(&request, response).ok(); - Ok(()) - } - Err(mapping_error) => { - let authenticator_error: AuthenticatorError = mapping_error.into(); - info!("authenticator_error: {}", authenticator_error as u8); - response.extend_from_slice(&[ - authenticator_error as u8 - ]).ok(); - Ok(()) - } - } - }, - // hid::Command::Msg is only other registered command. - _ => { - let result = self.call_authenticator_u2f_with_bytes(request, response); - match result { - Ok(()) => { - info!("U2F response {} bytes", response.len()); - // Need to add x9000 success code (normally the apdu-dispatch does this, but - // since u2f uses apdus over hid, we must do it here.) - response.extend_from_slice(&[0x90, 0x00]).ok(); - }, - Err(status) => { - let code: [u8; 2] = status.into(); - info!("U2F error. {}", hex_str!(&code)); - response.extend_from_slice(&code).ok(); - }, - } - Ok(()) - - }, - } - - } - - -} diff --git a/components/dispatch-fido/src/lib.rs b/components/dispatch-fido/src/lib.rs deleted file mode 100644 index 9591f899..00000000 --- a/components/dispatch-fido/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! # dispatch-fido -//! -//! This library implements the `apdu-dispatch` and `ctaphid-dispatch` App traits -//! for the `fido-authenticator`, allowing it to be called over both interfaces -//! in the Solo 2 security key. -#![no_std] - -#[macro_use] -extern crate delog; -generate_macros!(); - -pub mod fido; -pub use fido::*; - -pub mod cbor; diff --git a/components/usbd-ccid/src/class.rs b/components/usbd-ccid/src/class.rs index 4f3f482f..0d597132 100644 --- a/components/usbd-ccid/src/class.rs +++ b/components/usbd-ccid/src/class.rs @@ -114,6 +114,7 @@ where .then(|| FUNCTIONAL_INTERFACE_STRING) } + #[inline(never)] fn poll(&mut self) { // info_now!("poll of ccid"); self.pipe.poll_app(); diff --git a/components/usbd-ccid/src/pipe.rs b/components/usbd-ccid/src/pipe.rs index 52a853d2..c0f52685 100644 --- a/components/usbd-ccid/src/pipe.rs +++ b/components/usbd-ccid/src/pipe.rs @@ -351,6 +351,7 @@ where self.state = State::Processing; } + #[inline(never)] pub fn poll_app(&mut self) { if let State::Processing = self.state { // info!("processing, checking for response, interchange state {:?}", @@ -476,6 +477,7 @@ where self.maybe_send_packet(); } + #[inline(never)] pub fn maybe_send_packet(&mut self) { if let Some(packet) = self.outbox.as_ref() { let needs_zlp = packet.len() == PACKET_SIZE; diff --git a/components/usbd-ctaphid/src/class.rs b/components/usbd-ctaphid/src/class.rs index b4e5364e..f243954a 100644 --- a/components/usbd-ctaphid/src/class.rs +++ b/components/usbd-ctaphid/src/class.rs @@ -48,7 +48,7 @@ where pipe, } } - + /// Indicate in INIT response that Wink command is implemented. pub fn implements_wink(mut self) -> Self { self.pipe.implements |= 0x01; @@ -188,11 +188,9 @@ where Bus: UsbBus Ok(()) } + #[inline(never)] fn poll(&mut self) { - // if self.pipe.interchange.recv.ready() { - // // hprintln!("recv pipe ready").ok(); - // } - // // hprintln!("state = {:?}", self.pipe.state).ok(); + // debug!("state = {:?}", self.pipe().state); self.pipe.handle_response(); self.pipe.maybe_write_packet(); } diff --git a/components/usbd-ctaphid/src/pipe.rs b/components/usbd-ctaphid/src/pipe.rs index 988a70ef..8ea17f97 100644 --- a/components/usbd-ctaphid/src/pipe.rs +++ b/components/usbd-ctaphid/src/pipe.rs @@ -20,11 +20,7 @@ use core::convert::TryFrom; use ctaphid_dispatch::types::HidInterchange; use ctaphid_dispatch::command::Command; -use ctap_types::{ - authenticator::Error as AuthenticatorError, -}; - - +use ctap_types::Error as AuthenticatorError; use interchange::Requester; @@ -38,7 +34,7 @@ use usb_device::{ use crate::{ constants::{ - // 7609 + // 1200 MESSAGE_SIZE, // 64 PACKET_SIZE, @@ -540,6 +536,7 @@ impl<'alloc, Bus: UsbBus> Pipe<'alloc, Bus> { } } + #[inline(never)] pub fn handle_response(&mut self) { if let State::WaitingOnAuthenticator(request) = self.state { @@ -598,6 +595,7 @@ impl<'alloc, Bus: UsbBus> Pipe<'alloc, Bus> { } // called from poll, and when a packet has been sent + #[inline(never)] pub(crate) fn maybe_write_packet(&mut self) { match self.state { From 1b9dd4d4fd5bf1723607ab4d119ac37046c74b0b Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Sat, 5 Mar 2022 22:04:20 +0100 Subject: [PATCH 02/18] Bump dependencies to published versions --- components/nfc-device/Cargo.toml | 4 ++-- components/provisioner-app/Cargo.toml | 2 +- components/usbd-ccid/Cargo.toml | 4 ++-- components/usbd-ctaphid/Cargo.toml | 4 ++-- components/usbd-ctaphid/src/constants.rs | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/nfc-device/Cargo.toml b/components/nfc-device/Cargo.toml index 3de57a43..e663d6f4 100644 --- a/components/nfc-device/Cargo.toml +++ b/components/nfc-device/Cargo.toml @@ -10,8 +10,8 @@ embedded-time = "0.12" heapless = "0.7" nb = "1" -apdu-dispatch = { git = "https://github.com/solokeys/apdu-dispatch" } -iso7816 = { git = "https://github.com/ycrypto/iso7816" } +apdu-dispatch = "0.1" +iso7816 = "0.1" interchange = "0.2.1" [features] diff --git a/components/provisioner-app/Cargo.toml b/components/provisioner-app/Cargo.toml index 59b23b5c..180ca454 100644 --- a/components/provisioner-app/Cargo.toml +++ b/components/provisioner-app/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -apdu-dispatch = { git = "https://github.com/solokeys/apdu-dispatch" } +apdu-dispatch = "0.1" delog = "0.1.1" heapless = "0.7" heapless-bytes = "0.3" diff --git a/components/usbd-ccid/Cargo.toml b/components/usbd-ccid/Cargo.toml index 20be1dc4..cc2d7ffd 100644 --- a/components/usbd-ccid/Cargo.toml +++ b/components/usbd-ccid/Cargo.toml @@ -11,8 +11,8 @@ delog = "0.1.0" embedded-time = "0.12" heapless = "0.7" # heapless-bytes = "0.3" -interchange = "0.2.0" -iso7816 = { git = "https://github.com/ycrypto/iso7816" } +interchange = "0.2" +iso7816 = "0.1" usb-device = { version = "0.2.3", features = ["control-buffer-256"] } [features] diff --git a/components/usbd-ctaphid/Cargo.toml b/components/usbd-ctaphid/Cargo.toml index a60bcca3..488ed22e 100644 --- a/components/usbd-ctaphid/Cargo.toml +++ b/components/usbd-ctaphid/Cargo.toml @@ -6,6 +6,8 @@ license = "Apache-2.0 OR MIT" edition = "2018" [dependencies] +ctap-types = "0.1.0" +ctaphid-dispatch = "0.1.0" embedded-time = "0.12" delog = "0.1.0" heapless = "0.7" @@ -14,8 +16,6 @@ interchange = "0.2.0" serde = { version = "1.0", default-features = false } usb-device = "0.2.3" -ctaphid-dispatch = { git = "https://github.com/solokeys/ctaphid-dispatch" } -ctap-types = { git = "https://github.com/solokeys/ctap-types" } [features] default = [] diff --git a/components/usbd-ctaphid/src/constants.rs b/components/usbd-ctaphid/src/constants.rs index 9a4026c2..f212e739 100644 --- a/components/usbd-ctaphid/src/constants.rs +++ b/components/usbd-ctaphid/src/constants.rs @@ -3,5 +3,5 @@ pub const INTERRUPT_POLL_MILLISECONDS: u8 = 5; pub const PACKET_SIZE: usize = 64; -// 7609 bytes -pub const MESSAGE_SIZE: usize = PACKET_SIZE - 7 + 128 * (PACKET_SIZE - 5); +// 1200 +pub const MESSAGE_SIZE: usize = ctap_types::sizes::REALISTIC_MAX_MESSAGE_SIZE; From 1a3da2496eb3c5986e0b61d90e983243d4eddc49 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Sat, 5 Mar 2022 22:13:29 +0100 Subject: [PATCH 03/18] Bump versions, remove serial USB + ndef app --- runners/lpc55/Cargo.toml | 16 ++++++++------ runners/lpc55/Makefile | 4 ++++ runners/lpc55/bacon.toml | 2 +- runners/lpc55/build.rs | 9 +++++++- runners/lpc55/src/initializer.rs | 4 ++-- runners/lpc55/src/lib.rs | 4 +++- runners/lpc55/src/main.rs | 37 +++++++++++++++++++++++++++++--- runners/lpc55/src/types.rs | 9 +++++--- runners/lpc55/src/types/usb.rs | 8 +++---- 9 files changed, 71 insertions(+), 22 deletions(-) diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index 97e611c0..eca38f34 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "runner" -version = "1.0.9" +version = "1.794.0" authors = ["Nicolas Stalder ", "Conor Patrick "] edition = "2018" resolver = "2" @@ -27,10 +27,10 @@ usb-device = "0.2.3" usbd-serial = "0.1.0" admin-app = { git = "https://github.com/solokeys/admin-app", optional = true } -apdu-dispatch = { git = "https://github.com/solokeys/apdu-dispatch" } -ctaphid-dispatch = { git = "https://github.com/solokeys/ctaphid-dispatch" } +apdu-dispatch = "0.1" +ctaphid-dispatch = "0.1" ctap-types = { git = "https://github.com/solokeys/ctap-types" } -fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", optional = true } +fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", branch = "less-ram", features = ["dispatch"], optional = true } oath-authenticator = { git = "https://github.com/trussed-dev/oath-authenticator", features = ["apdu-dispatch"], optional = true } piv-authenticator = { git = "https://github.com/solokeys/piv-authenticator", features = ["apdu-dispatch"], optional = true } trussed = { git = "https://github.com/trussed-dev/trussed" } @@ -39,7 +39,7 @@ trussed = { git = "https://github.com/trussed-dev/trussed" } board = { path = "board" } # components -dispatch-fido = {path = "../../components/dispatch-fido"} +# dispatch-fido = {path = "../../components/dispatch-fido"} ndef-app = { path = "../../components/ndef-app", optional = true } # NB: when using this app, need to raise trussed/clients-5 provisioner-app = { path = "../../components/provisioner-app", optional = true } @@ -57,9 +57,11 @@ panic-halt = "0.2.0" littlefs2 = { version = "0.3.2", features = ["c-stubs"] } [features] -default = ["admin-app", "fido-authenticator", "ndef-app", "oath-authenticator", "trussed/clients-3"] +# default = ["admin-app", "fido-authenticator", "ndef-app", "oath-authenticator", "trussed/clients-4"] +default = ["admin-app", "fido-authenticator", "oath-authenticator", "trussed/clients-3"] -develop = ["piv-authenticator", "no-encrypted-storage", "no-buttons", "no-reset-time-window", "trussed/clients-4"] +# develop = ["piv-authenticator", "no-encrypted-storage", "no-buttons", "no-reset-time-window", "trussed/clients-4"] +develop = ["no-encrypted-storage", "no-buttons", "no-reset-time-window", "trussed/clients-3"] develop-provisioner = ["piv-authenticator", "no-encrypted-storage", "no-buttons", "no-reset-time-window", "provisioner-app", "trussed/clients-5"] # Do not use encryption for the filesystem diff --git a/runners/lpc55/Makefile b/runners/lpc55/Makefile index 526e7c9e..2f700626 100644 --- a/runners/lpc55/Makefile +++ b/runners/lpc55/Makefile @@ -13,6 +13,10 @@ build-pro: cargo build --release $(PROVISIONER) cargo objcopy --release $(PROVISIONER) -- -O binary provisioner.bin +.PHONY: today-as-minor-version +today-in-days: + python -c "from datetime import date as d; print((d.today() - d(2020, 1, 1)).days)" + run-dev: cargo run --release $(DEVELOP) diff --git a/runners/lpc55/bacon.toml b/runners/lpc55/bacon.toml index e3fea662..b4793a9b 100644 --- a/runners/lpc55/bacon.toml +++ b/runners/lpc55/bacon.toml @@ -10,7 +10,7 @@ command = ["cargo", "check", "--color", "always", "--features", "board-lpcxpress need_stdout = false [jobs.build-dev] -command = ["cargo", "build", "--color", "always", "--features", "board-lpcxpresso55,develop"] +command = ["cargo", "build", "--color", "always", "--release", "--features", "board-lpcxpresso55,develop"] need_stdout = false [jobs.check] diff --git a/runners/lpc55/build.rs b/runners/lpc55/build.rs index 29dfc62b..0f38e108 100644 --- a/runners/lpc55/build.rs +++ b/runners/lpc55/build.rs @@ -22,6 +22,13 @@ macro_rules! add_build_variable{ .expect("Could not write build_constants.rs file"); }; + ($file:expr, $name:literal, u16) => { + let value = env!($name); + let value: u16 = str::parse(value).expect("Version components must be able to fit in a u16."); + writeln!($file, "pub const {}: u16 = {};", $name, value) + .expect("Could not write build_constants.rs file"); + }; + ($file:expr, $name:literal, $value:expr, u32) => { writeln!($file, "pub const {}: u32 = {};", $name, $value) .expect("Could not write build_constants.rs file"); @@ -113,7 +120,7 @@ fn main() -> Result<(), Box> { writeln!(&mut f, "pub mod build_constants {{").expect("Could not write build_constants.rs."); add_build_variable!(&mut f, "CARGO_PKG_VERSION_MAJOR", u8); - add_build_variable!(&mut f, "CARGO_PKG_VERSION_MINOR", u8); + add_build_variable!(&mut f, "CARGO_PKG_VERSION_MINOR", u16); add_build_variable!(&mut f, "CARGO_PKG_VERSION_PATCH", u8); add_build_variable!(&mut f, "CARGO_PKG_HASH", hash_long); diff --git a/runners/lpc55/src/initializer.rs b/runners/lpc55/src/initializer.rs index 0066f944..0fb65c9a 100644 --- a/runners/lpc55/src/initializer.rs +++ b/runners/lpc55/src/initializer.rs @@ -510,7 +510,7 @@ impl Initializer { .implements_ctap2() .implements_wink(); - let serial = usbd_serial::SerialPort::new(usb_bus); + // let serial = usbd_serial::SerialPort::new(usb_bus); // Only 16 bits, so take the upper bits of our semver let device_release = @@ -533,7 +533,7 @@ impl Initializer { .composite_with_iads() .build(); - usb_classes = Some(types::UsbClasses::new(usbd, ccid, ctaphid, /*keyboard,*/ serial)); + usb_classes = Some(types::UsbClasses::new(usbd, ccid, ctaphid));//, /*keyboard,*/ serial)); } diff --git a/runners/lpc55/src/lib.rs b/runners/lpc55/src/lib.rs index 90d82d14..b8220f08 100644 --- a/runners/lpc55/src/lib.rs +++ b/runners/lpc55/src/lib.rs @@ -4,6 +4,7 @@ include!(concat!(env!("OUT_DIR"), "/build_constants.rs")); // panic handler, depending on debug/release build // BUT: need to run in release anyway, to have USB work use panic_halt as _; +// use panic_semihosting as _; use usb_device::device::UsbVidPid; use board::clock_controller; @@ -40,7 +41,8 @@ impl delog::Flusher for Flusher { } } -delog!(Delogger, 16*1024, 3*1024, Flusher); +// delog!(Delogger, 16*1024, 3*1024, Flusher); +delog!(Delogger, 1, 256, Flusher); #[cfg(any(feature = "log-semihosting", feature = "log-serial"))] static FLUSHER: Flusher = Flusher {}; diff --git a/runners/lpc55/src/main.rs b/runners/lpc55/src/main.rs index a297653d..a8cb17df 100644 --- a/runners/lpc55/src/main.rs +++ b/runners/lpc55/src/main.rs @@ -25,6 +25,15 @@ const NFC_INTERRUPT: board::hal::raw::Interrupt = board::hal::raw::Interrupt::PI extern crate delog; generate_macros!(); +use core::arch::asm; + +#[inline] +pub fn msp() -> u32 { + let r; + unsafe { asm!("mrs {}, MSP", out(reg) r, options(nomem, nostack, preserves_flags)) }; + r +} + #[rtic::app(device = runner::hal::raw, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { @@ -131,7 +140,7 @@ const APP: () = { let schedule = c.schedule; - info_now!("inside IDLE"); + info_now!("inside IDLE, initial SP = {:08X}", msp()); loop { let mut time = 0; @@ -200,15 +209,25 @@ const APP: () = { /// Manages all traffic on the USB bus. #[task(binds = USB1, resources = [usb_classes], schedule = [ccid_wait_extension, ctaphid_keepalive], priority=6)] fn usb(c: usb::Context) { + // let remaining = msp() - 0x2000_0000; + // if remaining < 100_000 { + // debug_now!("USB interrupt: remaining stack size: {} bytes", remaining); + // } let usb = unsafe { hal::raw::Peripherals::steal().USB1 } ; let before = Instant::now(); let usb_classes = c.resources.usb_classes.as_mut().unwrap(); ////////////// + // if remaining < 60_000 { + // debug_now!("polling usb classes"); + // } usb_classes.poll(); match usb_classes.ccid.did_start_processing() { usbd_ccid::types::Status::ReceivedData(milliseconds) => { + // if remaining < 60_000 { + // debug_now!("scheduling CCID wait extension"); + // } c.schedule.ccid_wait_extension( Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() ).ok(); @@ -217,6 +236,9 @@ const APP: () = { } match usb_classes.ctaphid.did_start_processing() { usbd_ctaphid::types::Status::ReceivedData(milliseconds) => { + // if remaining < 60_000 { + // debug_now!("scheduling CTAPHID wait extension"); + // } c.schedule.ctaphid_keepalive( Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() ).ok(); @@ -248,6 +270,10 @@ const APP: () = { // usb.intstat.write(|w| unsafe{ w.bits( usb.intstat.read().bits() ) }); } + // if remaining < 60_000 { + // debug_now!("USB interrupt done: {} bytes", remaining); + // } + } @@ -256,7 +282,8 @@ const APP: () = { /// until the application replied. #[task(resources = [usb_classes], schedule = [ccid_wait_extension], priority = 6)] fn ccid_wait_extension(c: ccid_wait_extension::Context) { - debug!("CCID WAIT EXTENSION"); + debug_now!("CCID WAIT EXTENSION"); + debug_now!("remaining stack size: {} bytes", msp() - 0x2000_0000); let status = c.resources.usb_classes.as_mut().unwrap().ccid.send_wait_extension(); match status { usbd_ccid::types::Status::ReceivedData(milliseconds) => { @@ -271,7 +298,8 @@ const APP: () = { /// Same as with CCID, but sending ctaphid keepalive statuses. #[task(resources = [usb_classes], schedule = [ctaphid_keepalive], priority = 6)] fn ctaphid_keepalive(c: ctaphid_keepalive::Context) { - debug!("keepalive"); + debug_now!("CTAPHID keepalive"); + debug_now!("remaining stack size: {} bytes", msp() - 0x2000_0000); let status = c.resources.usb_classes.as_mut().unwrap().ctaphid.send_keepalive( board::trussed::UserPresenceStatus::waiting() ); @@ -288,6 +316,7 @@ const APP: () = { #[task(binds = MAILBOX, resources = [usb_classes], priority = 5)] #[allow(unused_mut,unused_variables)] fn mailbox(mut c: mailbox::Context) { + // debug_now!("mailbox: remaining stack size: {} bytes", msp() - 0x2000_0000); #[cfg(feature = "log-serial")] c.resources.usb_classes.lock(|usb_classes_maybe| { match usb_classes_maybe.as_mut() { @@ -310,6 +339,7 @@ const APP: () = { #[task(binds = OS_EVENT, resources = [trussed], priority = 5)] fn os_event(c: os_event::Context) { + // debug_now!("os event: remaining stack size: {} bytes", msp() - 0x2000_0000); c.resources.trussed.process(); } @@ -317,6 +347,7 @@ const APP: () = { fn update_ui(mut c: update_ui::Context) { static mut UPDATES: u32 = 1; + // debug_now!("update UI: remaining stack size: {} bytes", msp() - 0x2000_0000); // let wait_periods = c.resources.trussed.lock(|trussed| trussed.update_ui()); c.resources.trussed.lock(|trussed| trussed.update_ui()); diff --git a/runners/lpc55/src/types.rs b/runners/lpc55/src/types.rs index ae347510..915c6300 100644 --- a/runners/lpc55/src/types.rs +++ b/runners/lpc55/src/types.rs @@ -112,7 +112,7 @@ pub type PivApp = piv_authenticator::Authenticator; #[cfg(feature = "fido-authenticator")] -pub type FidoApp = dispatch_fido::Fido; +pub type FidoApp = fido_authenticator::Authenticator; #[cfg(feature = "ndef-app")] pub type NdefApp = ndef_app::App<'static>; #[cfg(feature = "provisioner-app")] @@ -193,10 +193,11 @@ impl TrussedApp for FidoApp { fn with_client(trussed: TrussedClient, _: ()) -> Self { let authnr = fido_authenticator::Authenticator::new( trussed, - fido_authenticator::NonSilentAuthenticator {}, + fido_authenticator::Conforming {}, ); - Self::new(authnr) + // Self::new(authnr) + authnr } } @@ -267,6 +268,7 @@ impl Apps { } } + #[inline(never)] pub fn apdu_dispatch(&mut self, f: F) -> T where F: FnOnce(&mut [&mut dyn @@ -289,6 +291,7 @@ impl Apps { ]) } + #[inline(never)] pub fn ctaphid_dispatch(&mut self, f: F) -> T where F: FnOnce(&mut [&mut dyn CtaphidApp ]) -> T diff --git a/runners/lpc55/src/types/usb.rs b/runners/lpc55/src/types/usb.rs index 299ee4f1..45184dec 100644 --- a/runners/lpc55/src/types/usb.rs +++ b/runners/lpc55/src/types/usb.rs @@ -22,12 +22,12 @@ pub struct UsbClasses { pub ccid: CcidClass, pub ctaphid: CtapHidClass, // pub keyboard: KeyboardClass, - pub serial: SerialClass, + // pub serial: SerialClass, } impl UsbClasses { - pub fn new(usbd: Usbd, ccid: CcidClass, ctaphid: CtapHidClass, serial: SerialClass) -> Self { - Self{ usbd, ccid, ctaphid, serial } + pub fn new(usbd: Usbd, ccid: CcidClass, ctaphid: CtapHidClass) -> Self {//, serial: SerialClass) -> Self { + Self{ usbd, ccid, ctaphid }//, serial } } pub fn poll(&mut self) { self.ctaphid.check_for_app_response(); @@ -35,7 +35,7 @@ impl UsbClasses { self.usbd.poll(&mut [ &mut self.ccid, &mut self.ctaphid, - &mut self.serial, + // &mut self.serial, ]); } } From 082be576203ff6c7cb582de4d67b295c4c3f8c20 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Tue, 8 Mar 2022 01:44:07 +0100 Subject: [PATCH 04/18] Implement winking, slight board code cleanup --- runners/lpc55/board/Cargo.toml | 1 + runners/lpc55/board/src/trussed.rs | 154 ++++++++++++++++------------- 2 files changed, 85 insertions(+), 70 deletions(-) diff --git a/runners/lpc55/board/Cargo.toml b/runners/lpc55/board/Cargo.toml index 9f2aa513..acd11876 100644 --- a/runners/lpc55/board/Cargo.toml +++ b/runners/lpc55/board/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" delog = "0.1.0" fm11nc08 = {path = "../../../components/fm11nc08"} lpc55-hal = { version = "0.3", features = ["littlefs", "rtic-peripherals"] } +micromath = "2" nb = "1" trussed = { git = "https://github.com/trussed-dev/trussed" } diff --git a/runners/lpc55/board/src/trussed.rs b/runners/lpc55/board/src/trussed.rs index acb2008b..40a7b8fc 100644 --- a/runners/lpc55/board/src/trussed.rs +++ b/runners/lpc55/board/src/trussed.rs @@ -1,35 +1,18 @@ //! Implementation of `trussed::Platform` for the board, //! using the specific implementation of our `crate::traits`. +use core::time::Duration; + use crate::hal::{ peripherals::rtc::Rtc, typestates::init_state, }; use crate::traits::buttons::{Press, Edge}; -use crate::traits::rgb_led::RgbLed; -use trussed::platform::{ - ui, - reboot, - consent, -}; - -// translated from https://stackoverflow.com/a/2284929/2490057 -fn sin(x: f32) -> f32 -{ - - let mut res = 0f32; - let mut pow = x; - let mut fact = 1f32; - for i in 0..5 { - res += pow/fact; - pow *= -1f32 * x * x; - fact *= ((2*(i+1))*(2*(i+1)+1)) as f32; - } - - res -} +use crate::traits::rgb_led::{Intensities, RgbLed}; +use micromath::F32; +use trussed::platform::{consent, ui}; -// Assuming there will only be one way to +// Assuming there will only be one way to // get user presence, this should be fine. // Used for Ctaphid.keepalive message status. static mut WAITING: bool = false; @@ -52,6 +35,8 @@ RGB: RgbLed, rtc: Rtc, buttons: Option, rgb: Option, + status: ui::Status, + wink_until: Duration, } impl UserInterface @@ -59,16 +44,29 @@ where BUTTONS: Press + Edge, RGB: RgbLed, { - pub fn new(rtc: Rtc, _buttons: Option, rgb: Option) -> Self { - #[cfg(not(feature = "no-buttons"))] - let ui = Self { rtc, buttons: _buttons, rgb }; + pub fn new(rtc: Rtc, buttons: Option, rgb: Option) -> Self { + #[allow(unused_mut)] + let mut buttons = buttons; #[cfg(feature = "no-buttons")] - let ui = Self { rtc, buttons: None, rgb }; - - ui + { + buttons = None; + } + Self { + rtc, buttons, rgb, + status: ui::Status::Idle, + wink_until: Duration::new(0, 0), + } } } +// color codes Conor picked +const BLACK: Intensities = Intensities { red: 0, green: 0, blue: 0 }; +// const RED: Intensities = Intensities { red: u8::MAX, green: 0, blue: 0 }; +// const GREEN: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x02 }; +const BLUE: Intensities = Intensities { red: 0, green: 0, blue: u8::MAX }; +// const TEAL: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x5a }; +// const ORANGE: Intensities = Intensities { red: u8::MAX, green: 0x7e, blue: 0 }; + impl trussed::platform::UserInterface for UserInterface where BUTTONS: Press + Edge, @@ -104,62 +102,78 @@ RGB: RgbLed, fn set_status(&mut self, status: ui::Status) { - if let Some(rgb) = &mut self.rgb { - - match status { - ui::Status::Idle => { - // green - rgb.set(0x00_ff_02.into()); - }, - ui::Status::Processing => { - // teal - rgb.set(0x00_ff_5a.into()); - } - ui::Status::WaitingForUserPresence => { - // orange - rgb.set(0xff_7e_00.into()); - }, - ui::Status::Error => { - // Red - rgb.set(0xff_00_00.into()); - }, - } - - } + self.status = status; + debug_now!("status set to {:?}", status); + + // self.refresh runs periodically and would overwrite this + // if let Some(rgb) = &mut self.rgb { + // rgb.set(match status { + // ui::Status::Idle => GREEN, + // ui::Status::Processing => TEAL, + // ui::Status::WaitingForUserPresence => ORANGE, + // ui::Status::Error => RED, + // }); + // } } fn refresh(&mut self) { - if self.rgb.is_some() && self.buttons.is_some() { - // 1. Get time & pick a period (here 4096). - // 2. Map it to a value between 0 and pi. - // 3. Calculate sine and map to amplitude between 0 and 255. - let time = (self.uptime().as_millis()) % 4096; - let amplitude = (sin((time as f32) * 3.14159265f32/4096f32) * 255f32) as u32; - - let state = self.buttons.as_mut().unwrap().state(); - let color = if state.a || state.b || state.middle { - // Use blue if button is pressed. - 0x00_00_01 | (amplitude << 0) - } else { + let uptime = self.uptime(); + + if let Some(rgb) = self.rgb.as_mut() { + let period = Duration::new(5, 0).as_millis() as u32; + let tau = F32(6.283185); + let angle = F32(uptime.as_millis() as f32) * tau / (period as f32); + let min_amplitude: u8 = 4; + let max_amplitude: u8 = 64; + let rel_amplitude = max_amplitude - min_amplitude; + + // sinoidal wave on top of a baseline brightness + let amplitude = min_amplitude + (angle.sin().abs() * (rel_amplitude as f32)).floor().0 as u8; + + let any_button = self.buttons.as_mut() + .map(|buttons| buttons.state()) + .map(|state| state.a || state.b || state.middle) + .unwrap_or(false); + + let mut color = if !any_button { // Use green if no button is pressed. - 0x00_00_01 | (amplitude << 8) + Intensities { + red: 0, + green: amplitude, + blue: 0, + } + } else { + // Use blue if button is pressed. + Intensities { + red: 0, + green: 0, + blue: amplitude, + } }; + if self.status == ui::Status::WaitingForUserPresence { + color = BLUE; + } + if uptime < self.wink_until { + let on = (((F32(uptime.as_secs_f32())*4.0f32).round().0 as u32) % 2) != 0; + color = if on { BLUE } else { BLACK }; + } + // use logging::hex::*; // use logging::hex; // crate::logger::info!("time: {}", time).ok(); - // crate::logger::info!("amp: {}", hex!(amplitude)).ok(); + // debug_now!("amp: {:08X}", amplitude); // crate::logger::info!("color: {}", hex!(color)).ok(); - self.rgb.as_mut().unwrap().set(color.into()); + rgb.set(color.into()); } } - fn uptime(&mut self) -> core::time::Duration { + fn uptime(&mut self) -> Duration { self.rtc.uptime() } - // delete this function after trussed is updated - fn reboot(&mut self, _to: reboot::To) -> ! { - panic!("this should no longer be called."); + fn wink(&mut self, duration: Duration) { + debug_now!("winking for {:?}", duration); + self.wink_until = self.uptime() + duration; } } From 7302d5c75c48f61a7d1e3fa179795905f8e5ba49 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Tue, 8 Mar 2022 14:04:21 +0100 Subject: [PATCH 05/18] Configurably larger CTAP pipe; winking --- components/usbd-ctaphid/src/constants.rs | 3 +- components/usbd-ctaphid/src/pipe.rs | 2 +- runners/lpc55/.cargo/{config => config.toml} | 2 +- runners/lpc55/Cargo.toml | 20 +++-- runners/lpc55/board/src/trussed.rs | 94 +++++++++++--------- runners/lpc55/rust-toolchain.toml | 4 + runners/lpc55/src/initializer.rs | 62 +++++++------ runners/lpc55/src/lib.rs | 2 +- runners/lpc55/src/main.rs | 3 +- runners/lpc55/src/types.rs | 7 ++ runners/pc/Cargo.toml | 2 - 11 files changed, 118 insertions(+), 83 deletions(-) rename runners/lpc55/.cargo/{config => config.toml} (92%) create mode 100644 runners/lpc55/rust-toolchain.toml diff --git a/components/usbd-ctaphid/src/constants.rs b/components/usbd-ctaphid/src/constants.rs index f212e739..ab1610b6 100644 --- a/components/usbd-ctaphid/src/constants.rs +++ b/components/usbd-ctaphid/src/constants.rs @@ -4,4 +4,5 @@ pub const INTERRUPT_POLL_MILLISECONDS: u8 = 5; pub const PACKET_SIZE: usize = 64; // 1200 -pub const MESSAGE_SIZE: usize = ctap_types::sizes::REALISTIC_MAX_MESSAGE_SIZE; +// pub const MESSAGE_SIZE: usize = ctap_types::sizes::REALISTIC_MAX_MESSAGE_SIZE; +pub const MESSAGE_SIZE: usize = 3072; diff --git a/components/usbd-ctaphid/src/pipe.rs b/components/usbd-ctaphid/src/pipe.rs index 8ea17f97..02244db3 100644 --- a/components/usbd-ctaphid/src/pipe.rs +++ b/components/usbd-ctaphid/src/pipe.rs @@ -34,7 +34,7 @@ use usb_device::{ use crate::{ constants::{ - // 1200 + // 3072 MESSAGE_SIZE, // 64 PACKET_SIZE, diff --git a/runners/lpc55/.cargo/config b/runners/lpc55/.cargo/config.toml similarity index 92% rename from runners/lpc55/.cargo/config rename to runners/lpc55/.cargo/config.toml index d086b8cd..8fec6e14 100644 --- a/runners/lpc55/.cargo/config +++ b/runners/lpc55/.cargo/config.toml @@ -3,7 +3,7 @@ runner = "arm-none-eabi-gdb -q -x jlink.gdb" rustflags = [ "-C", "linker=flip-link", "-C", "link-arg=-Tlink.x", - # "-Dwarnings", + "-Dwarnings", ] [build] diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index eca38f34..c5ef1e36 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -1,11 +1,9 @@ -# cargo-features = ["resolver"] - [package] name = "runner" version = "1.794.0" authors = ["Nicolas Stalder ", "Conor Patrick "] -edition = "2018" -resolver = "2" +edition = "2021" +rust-version = "1.59.0" [lib] name = "runner" @@ -29,7 +27,7 @@ usbd-serial = "0.1.0" admin-app = { git = "https://github.com/solokeys/admin-app", optional = true } apdu-dispatch = "0.1" ctaphid-dispatch = "0.1" -ctap-types = { git = "https://github.com/solokeys/ctap-types" } +ctap-types = "0.1" fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", branch = "less-ram", features = ["dispatch"], optional = true } oath-authenticator = { git = "https://github.com/trussed-dev/oath-authenticator", features = ["apdu-dispatch"], optional = true } piv-authenticator = { git = "https://github.com/solokeys/piv-authenticator", features = ["apdu-dispatch"], optional = true } @@ -57,12 +55,16 @@ panic-halt = "0.2.0" littlefs2 = { version = "0.3.2", features = ["c-stubs"] } [features] -# default = ["admin-app", "fido-authenticator", "ndef-app", "oath-authenticator", "trussed/clients-4"] +# ndef-app is an annoyance on some mobile platforms default = ["admin-app", "fido-authenticator", "oath-authenticator", "trussed/clients-3"] -# develop = ["piv-authenticator", "no-encrypted-storage", "no-buttons", "no-reset-time-window", "trussed/clients-4"] -develop = ["no-encrypted-storage", "no-buttons", "no-reset-time-window", "trussed/clients-3"] -develop-provisioner = ["piv-authenticator", "no-encrypted-storage", "no-buttons", "no-reset-time-window", "provisioner-app", "trussed/clients-5"] +# develop = ["no-encrypted-storage", "no-buttons", "no-reset-time-window"] +# develop = ["no-encrypted-storage", "no-reset-time-window"] +# develop = ["no-encrypted-storage", "no-buttons"] +develop = ["no-encrypted-storage", "trussed/clients-3"] + +develop-piv = ["develop", "piv-authenticator", "trussed/clients-4"] +develop-provisioner = ["develop", "provisioner-app", "trussed/clients-4"] # Do not use encryption for the filesystem no-encrypted-storage = [] diff --git a/runners/lpc55/board/src/trussed.rs b/runners/lpc55/board/src/trussed.rs index 40a7b8fc..741cb116 100644 --- a/runners/lpc55/board/src/trussed.rs +++ b/runners/lpc55/board/src/trussed.rs @@ -61,11 +61,12 @@ RGB: RgbLed, // color codes Conor picked const BLACK: Intensities = Intensities { red: 0, green: 0, blue: 0 }; -// const RED: Intensities = Intensities { red: u8::MAX, green: 0, blue: 0 }; -// const GREEN: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x02 }; +const RED: Intensities = Intensities { red: u8::MAX, green: 0, blue: 0 }; +const GREEN: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x02 }; const BLUE: Intensities = Intensities { red: 0, green: 0, blue: u8::MAX }; -// const TEAL: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x5a }; -// const ORANGE: Intensities = Intensities { red: u8::MAX, green: 0x7e, blue: 0 }; +const TEAL: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x5a }; +#[allow(dead_code)] +const ORANGE: Intensities = Intensities { red: u8::MAX, green: 0x7e, blue: 0 }; impl trussed::platform::UserInterface for UserInterface where @@ -106,57 +107,57 @@ RGB: RgbLed, debug_now!("status set to {:?}", status); // self.refresh runs periodically and would overwrite this - // if let Some(rgb) = &mut self.rgb { - // rgb.set(match status { - // ui::Status::Idle => GREEN, - // ui::Status::Processing => TEAL, - // ui::Status::WaitingForUserPresence => ORANGE, - // ui::Status::Error => RED, - // }); - // } + if let Some(rgb) = &mut self.rgb { + rgb.set(match status { + ui::Status::Idle => GREEN, + ui::Status::Processing => TEAL, + // ui::Status::WaitingForUserPresence => ORANGE, + ui::Status::WaitingForUserPresence => BLUE, + ui::Status::Error => RED, + }); + } } fn refresh(&mut self) { - let uptime = self.uptime(); + let uptime = self.uptime().as_millis() as u32; if let Some(rgb) = self.rgb.as_mut() { - let period = Duration::new(5, 0).as_millis() as u32; - let tau = F32(6.283185); - let angle = F32(uptime.as_millis() as f32) * tau / (period as f32); - let min_amplitude: u8 = 4; - let max_amplitude: u8 = 64; - let rel_amplitude = max_amplitude - min_amplitude; - - // sinoidal wave on top of a baseline brightness - let amplitude = min_amplitude + (angle.sin().abs() * (rel_amplitude as f32)).floor().0 as u8; + let waiting_for_user = self.status == ui::Status::WaitingForUserPresence; + let winking = uptime < self.wink_until.as_millis() as u32; let any_button = self.buttons.as_mut() .map(|buttons| buttons.state()) .map(|state| state.a || state.b || state.middle) .unwrap_or(false); - let mut color = if !any_button { - // Use green if no button is pressed. - Intensities { - red: 0, - green: amplitude, - blue: 0, - } + let color = if waiting_for_user { + + // breathe fast, in blue + + let amplitude = calculate_amplitude(uptime, 2, 4, 128); + Intensities { red: 0, green: 0, blue: amplitude } + + } else if winking { + + // blink rapidly + + let on = (((F32(uptime as f32) / 250.0).round().0 as u32) % 2) != 0; + if on { BLUE } else { BLACK } + } else { - // Use blue if button is pressed. - Intensities { - red: 0, - green: 0, - blue: amplitude, + + // regular behaviour: breathe slowly + + let amplitude = calculate_amplitude(uptime, 5, 4, 64); + + if !any_button { + // Use green if no button is pressed. + Intensities { red: 0, green: amplitude, blue: 0 } + } else { + // Use blue if button is pressed. + Intensities { red: 0, green: 0, blue: amplitude } } }; - if self.status == ui::Status::WaitingForUserPresence { - color = BLUE; - } - if uptime < self.wink_until { - let on = (((F32(uptime.as_secs_f32())*4.0f32).round().0 as u32) % 2) != 0; - color = if on { BLUE } else { BLACK }; - } // use logging::hex::*; // use logging::hex; @@ -177,3 +178,14 @@ RGB: RgbLed, } } + +fn calculate_amplitude(now_millis: u32, period_secs: u8, min_amplitude: u8, max_amplitude: u8) -> u8 { + let period = Duration::new(period_secs as u64, 0).as_millis() as u32; + let tau = F32(6.283185); + let angle = F32(now_millis as f32) * tau / (period as f32); + let rel_amplitude = max_amplitude - min_amplitude; + + // sinoidal wave on top of a baseline brightness + let amplitude = min_amplitude + (angle.sin().abs() * (rel_amplitude as f32)).floor().0 as u8; + amplitude +} diff --git a/runners/lpc55/rust-toolchain.toml b/runners/lpc55/rust-toolchain.toml new file mode 100644 index 00000000..b3da8293 --- /dev/null +++ b/runners/lpc55/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.59.0" +components = ["rustfmt"] +targets = ["thumbv8m.main-none-eabi"] diff --git a/runners/lpc55/src/initializer.rs b/runners/lpc55/src/initializer.rs index 0fb65c9a..b358b0c8 100644 --- a/runners/lpc55/src/initializer.rs +++ b/runners/lpc55/src/initializer.rs @@ -308,8 +308,6 @@ impl Initializer { let clocks = clock_stage.clocks; - let mut three_buttons: Option = None; - let pmc = &mut self.pmc; let syscon = &mut self.syscon; @@ -332,28 +330,34 @@ impl Initializer { let iocon = &mut clock_stage.iocon; let gpio = &mut clock_stage.gpio; - #[cfg(feature = "board-lpcxpresso55")] - let mut rgb = board::RgbLed::new( - Pwm::new(ctimer2.enabled(syscon, clocks.support_1mhz_fro_token().unwrap())), - iocon, - ); + let rgb = if !self.is_nfc_passive { + #[cfg(feature = "board-lpcxpresso55")] + let rgb = board::RgbLed::new( + Pwm::new(ctimer2.enabled(syscon, clocks.support_1mhz_fro_token().unwrap())), + iocon, + ); - #[cfg(feature = "board-solo2")] - let mut rgb = board::RgbLed::new( - Pwm::new(_ctimer3.enabled(syscon, clocks.support_1mhz_fro_token().unwrap())), - iocon, - ); + #[cfg(feature = "board-solo2")] + let rgb = board::RgbLed::new( + Pwm::new(_ctimer3.enabled(syscon, clocks.support_1mhz_fro_token().unwrap())), + iocon, + ); - if !self.is_nfc_passive { + Some(rgb) + } else { + None + }; + + let mut three_buttons = if !self.is_nfc_passive { #[cfg(feature = "board-lpcxpresso55")] - let new_three_buttons = board::ThreeButtons::new( + let three_buttons = board::ThreeButtons::new( Timer::new(ctimer1.enabled(syscon, clocks.support_1mhz_fro_token().unwrap())), gpio, iocon, ); #[cfg(feature = "board-solo2")] - let new_three_buttons = { + let three_buttons = { // TODO this should get saved somewhere to be released later. let mut dma = hal::Dma::from(_dma).enabled(syscon); @@ -368,20 +372,26 @@ impl Initializer { ) }; - three_buttons = Some(new_three_buttons); - } + Some(three_buttons) + } else { + None + }; let mut pfr = pfr.enabled(&clocks).unwrap(); Self::validate_cfpa(&mut pfr, self.config.secure_firmware_version, self.config.require_prince); - if self.config.boot_to_bootrom && three_buttons.is_some() { - info!("bootrom request start {}", perf_timer.elapsed().0/1000); - if self.is_bootrom_requested(three_buttons.as_mut().unwrap(), &mut delay_timer) { - // Give a small red blink show success - rgb.red(200); rgb.green(200); rgb.blue(0); - delay_timer.start(100_000.microseconds()); nb::block!(delay_timer.wait()).ok(); - - hal::boot_to_bootrom() + if self.config.boot_to_bootrom { + if let Some(three_buttons) = three_buttons.as_mut() { + info!("bootrom request start {}", perf_timer.elapsed().0/1000); + if self.is_bootrom_requested(three_buttons, &mut delay_timer) { + if let Some(mut rgb) = rgb { + // Give a small red blink show success + rgb.red(200); rgb.green(200); rgb.blue(0); + } + delay_timer.start(100_000.microseconds()); nb::block!(delay_timer.wait()).ok(); + + hal::boot_to_bootrom() + } } } @@ -392,7 +402,7 @@ impl Initializer { adc, three_buttons, - rgb: Some(rgb), + rgb, } } diff --git a/runners/lpc55/src/lib.rs b/runners/lpc55/src/lib.rs index b8220f08..e7d9f2b6 100644 --- a/runners/lpc55/src/lib.rs +++ b/runners/lpc55/src/lib.rs @@ -42,7 +42,7 @@ impl delog::Flusher for Flusher { } // delog!(Delogger, 16*1024, 3*1024, Flusher); -delog!(Delogger, 1, 256, Flusher); +delog!(Delogger, 1, 2048, Flusher); #[cfg(any(feature = "log-semihosting", feature = "log-serial"))] static FLUSHER: Flusher = Flusher {}; diff --git a/runners/lpc55/src/main.rs b/runners/lpc55/src/main.rs index a8cb17df..cb230c8e 100644 --- a/runners/lpc55/src/main.rs +++ b/runners/lpc55/src/main.rs @@ -17,6 +17,7 @@ use rtic::cyccnt::{Instant, U32Ext as _}; const CLOCK_FREQ: u32 = 96_000_000; const PERIOD: u32 = CLOCK_FREQ/16; +// const PERIOD: u32 = CLOCK_FREQ/4; const USB_INTERRUPT: board::hal::raw::Interrupt = board::hal::raw::Interrupt::USB1; const NFC_INTERRUPT: board::hal::raw::Interrupt = board::hal::raw::Interrupt::PIN_INT0; @@ -354,7 +355,7 @@ const APP: () = { // c.schedule.update_ui(Instant::now() + wait_periods * PERIOD.cycles()).unwrap(); c.schedule.update_ui(Instant::now() + PERIOD.cycles()).unwrap(); - *UPDATES += 1; + *UPDATES = UPDATES.wrapping_add(1); } diff --git a/runners/lpc55/src/types.rs b/runners/lpc55/src/types.rs index 915c6300..64fa8a86 100644 --- a/runners/lpc55/src/types.rs +++ b/runners/lpc55/src/types.rs @@ -113,6 +113,8 @@ pub type PivApp = piv_authenticator::Authenticator; #[cfg(feature = "fido-authenticator")] pub type FidoApp = fido_authenticator::Authenticator; +#[cfg(feature = "fido-authenticator")] +pub type FidoConfig = fido_authenticator::Config; #[cfg(feature = "ndef-app")] pub type NdefApp = ndef_app::App<'static>; #[cfg(feature = "provisioner-app")] @@ -194,6 +196,11 @@ impl TrussedApp for FidoApp { let authnr = fido_authenticator::Authenticator::new( trussed, fido_authenticator::Conforming {}, + FidoConfig { + max_msg_size: usbd_ctaphid::constants::MESSAGE_SIZE, + // max_creds_in_list: ctap_types::sizes::MAX_CREDENTIAL_COUNT_IN_LIST, + // max_cred_id_length: ctap_types::sizes::MAX_CREDENTIAL_ID_LENGTH, + }, ); // Self::new(authnr) diff --git a/runners/pc/Cargo.toml b/runners/pc/Cargo.toml index 4ca6f212..d4c16c34 100644 --- a/runners/pc/Cargo.toml +++ b/runners/pc/Cargo.toml @@ -9,7 +9,6 @@ chacha20 = { version = "0.7", features = ["rng"] } delog = "0.1.0" embedded-hal = { version = "0.2", features = ["unproven"] } generic-array = "0.14.3" -heapless = "0.6" interchange = "0.2.0" nb = "1" @@ -26,7 +25,6 @@ usbd-ccid = { path = "../../components/usbd-ccid" } usbd-ctaphid = { path = "../../components/usbd-ctaphid" } nfc-device = {path = "./../../components/nfc-device"} ndef-app = {path = "./../../components/ndef-app"} -dispatch-fido = {path = "./../../components/dispatch-fido"} # storage littlefs2 = "0.3.1" From d776a6d5676c39cf8fe3dd49af6bdf59f27a4166 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Tue, 8 Mar 2022 14:20:07 +0100 Subject: [PATCH 06/18] PC build fixes --- runners/lpc55/Cargo.toml | 1 - runners/lpc55/rust-toolchain.toml | 2 +- runners/pc/Cargo.toml | 9 +++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index c5ef1e36..96e8731a 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -37,7 +37,6 @@ trussed = { git = "https://github.com/trussed-dev/trussed" } board = { path = "board" } # components -# dispatch-fido = {path = "../../components/dispatch-fido"} ndef-app = { path = "../../components/ndef-app", optional = true } # NB: when using this app, need to raise trussed/clients-5 provisioner-app = { path = "../../components/provisioner-app", optional = true } diff --git a/runners/lpc55/rust-toolchain.toml b/runners/lpc55/rust-toolchain.toml index b3da8293..a02802c9 100644 --- a/runners/lpc55/rust-toolchain.toml +++ b/runners/lpc55/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] channel = "1.59.0" -components = ["rustfmt"] +components = ["rustfmt", "llvm-tools-preview"] targets = ["thumbv8m.main-none-eabi"] diff --git a/runners/pc/Cargo.toml b/runners/pc/Cargo.toml index d4c16c34..46b95425 100644 --- a/runners/pc/Cargo.toml +++ b/runners/pc/Cargo.toml @@ -13,10 +13,11 @@ interchange = "0.2.0" nb = "1" admin-app = { git = "https://github.com/solokeys/admin-app" } -apdu-dispatch = { git = "https://github.com/solokeys/apdu-dispatch", features = ["std"] } -ctap-types = { git = "https://github.com/solokeys/ctap-types" } -ctaphid-dispatch = { git = "https://github.com/solokeys/ctaphid-dispatch", features = ["std"] } -fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator" } +apdu-dispatch = "0.1" +ctap-types = "0.1" +ctaphid-dispatch = "0.1" +# fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator" } +fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", branch = "less-ram", features = ["dispatch"], optional = true } piv-authenticator = { git = "https://github.com/solokeys/piv-authenticator" } trussed = { git = "https://github.com/trussed-dev/trussed", features = ["clients-3"] } From b43e3f287443fe36a2a4f6ec288d4f703a71d753 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Tue, 8 Mar 2022 23:30:54 +0100 Subject: [PATCH 07/18] Allow setting versions in CTAPHID_INIT --- components/usbd-ctaphid/src/class.rs | 5 +++++ components/usbd-ctaphid/src/lib.rs | 8 ++++++++ components/usbd-ctaphid/src/pipe.rs | 13 ++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/components/usbd-ctaphid/src/class.rs b/components/usbd-ctaphid/src/class.rs index f243954a..a45b1044 100644 --- a/components/usbd-ctaphid/src/class.rs +++ b/components/usbd-ctaphid/src/class.rs @@ -49,6 +49,11 @@ where } } + /// Set versions returned in CTAPHID_INIT + pub fn set_version(&mut self, version: crate::Version) { + self.pipe.set_version(version); + } + /// Indicate in INIT response that Wink command is implemented. pub fn implements_wink(mut self) -> Self { self.pipe.implements |= 0x01; diff --git a/components/usbd-ctaphid/src/lib.rs b/components/usbd-ctaphid/src/lib.rs index d669c025..ec6e394a 100644 --- a/components/usbd-ctaphid/src/lib.rs +++ b/components/usbd-ctaphid/src/lib.rs @@ -22,3 +22,11 @@ pub use class::CtapHid; pub mod pipe; pub mod types; +/// major/minor/build version bytes returned in CTAPHID_INIT +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +pub struct Version { + pub major: u8, + pub minor: u8, + pub build: u8, +} + diff --git a/components/usbd-ctaphid/src/pipe.rs b/components/usbd-ctaphid/src/pipe.rs index 02244db3..6b17d348 100644 --- a/components/usbd-ctaphid/src/pipe.rs +++ b/components/usbd-ctaphid/src/pipe.rs @@ -148,6 +148,8 @@ pub struct Pipe<'alloc, Bus: UsbBus> { started_processing: bool, needs_keepalive: bool, + + pub(crate) version: crate::Version, } impl<'alloc, Bus: UsbBus> Pipe<'alloc, Bus> { @@ -175,9 +177,14 @@ impl<'alloc, Bus: UsbBus> Pipe<'alloc, Bus> { last_milliseconds: initial_milliseconds, started_processing: false, needs_keepalive: false, + version: Default::default(), } } + pub(crate) fn set_version(&mut self, version: crate::Version) { + self.version = version; + } + pub fn read_address(&self) -> EndpointAddress { self.read_endpoint.address() } @@ -445,11 +452,11 @@ impl<'alloc, Bus: UsbBus> Pipe<'alloc, Bus> { // CTAPHID protocol version self.buffer[12] = 2; // major device version number - self.buffer[13] = 0; + self.buffer[13] = self.version.major; // minor device version number - self.buffer[14] = 0; + self.buffer[14] = self.version.minor; // build device version number - self.buffer[15] = 0; + self.buffer[15] = self.version.build; // capabilities flags // 0x1: implements WINK // 0x4: implements CBOR From 223fe451d8280573af887fbf0d6f82e1419c45c6 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Tue, 8 Mar 2022 23:32:28 +0100 Subject: [PATCH 08/18] Tweaks - put NDEF app back in - set CTAPHID_INIT versions - blink in green when processing --- components/ndef-app/Cargo.toml | 4 ++-- runners/lpc55/Cargo.toml | 10 +++++----- runners/lpc55/Makefile | 4 ++++ runners/lpc55/board/src/trussed.rs | 13 +++++++++++-- runners/lpc55/src/initializer.rs | 8 +++++++- tests/basic.py | 26 +++++++++++++++----------- 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/components/ndef-app/Cargo.toml b/components/ndef-app/Cargo.toml index b47a7ad9..4ae69cf6 100644 --- a/components/ndef-app/Cargo.toml +++ b/components/ndef-app/Cargo.toml @@ -9,5 +9,5 @@ edition = "2018" [dependencies] heapless = "0.7" -apdu-dispatch = { git = "https://github.com/solokeys/apdu-dispatch" } -iso7816 = { git = "https://github.com/ycrypto/iso7816" } +apdu-dispatch = "0.1" +iso7816 = "0.1" diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index 96e8731a..2adce83a 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runner" -version = "1.794.0" +version = "1.797.0" authors = ["Nicolas Stalder ", "Conor Patrick "] edition = "2021" rust-version = "1.59.0" @@ -55,15 +55,15 @@ littlefs2 = { version = "0.3.2", features = ["c-stubs"] } [features] # ndef-app is an annoyance on some mobile platforms -default = ["admin-app", "fido-authenticator", "oath-authenticator", "trussed/clients-3"] +default = ["admin-app", "fido-authenticator", "ndef-app", "oath-authenticator", "trussed/clients-4"] # develop = ["no-encrypted-storage", "no-buttons", "no-reset-time-window"] # develop = ["no-encrypted-storage", "no-reset-time-window"] # develop = ["no-encrypted-storage", "no-buttons"] -develop = ["no-encrypted-storage", "trussed/clients-3"] +develop = ["no-encrypted-storage", "trussed/clients-4"] -develop-piv = ["develop", "piv-authenticator", "trussed/clients-4"] -develop-provisioner = ["develop", "provisioner-app", "trussed/clients-4"] +develop-piv = ["develop", "piv-authenticator", "trussed/clients-5"] +develop-provisioner = ["develop", "provisioner-app", "trussed/clients-5"] # Do not use encryption for the filesystem no-encrypted-storage = [] diff --git a/runners/lpc55/Makefile b/runners/lpc55/Makefile index 2f700626..a4bd58c2 100644 --- a/runners/lpc55/Makefile +++ b/runners/lpc55/Makefile @@ -13,6 +13,10 @@ build-pro: cargo build --release $(PROVISIONER) cargo objcopy --release $(PROVISIONER) -- -O binary provisioner.bin +build-release: + cargo build --release --features board-solo2 + cargo objcopy --release --features board-solo2 -- -O binary app-solo2.bin + .PHONY: today-as-minor-version today-in-days: python -c "from datetime import date as d; print((d.today() - d(2020, 1, 1)).days)" diff --git a/runners/lpc55/board/src/trussed.rs b/runners/lpc55/board/src/trussed.rs index 741cb116..ad3967fa 100644 --- a/runners/lpc55/board/src/trussed.rs +++ b/runners/lpc55/board/src/trussed.rs @@ -118,12 +118,17 @@ RGB: RgbLed, } } + fn status(&self) -> ui::Status { + self.status + } + fn refresh(&mut self) { let uptime = self.uptime().as_millis() as u32; if let Some(rgb) = self.rgb.as_mut() { let waiting_for_user = self.status == ui::Status::WaitingForUserPresence; + let processing = self.status == ui::Status::Processing; let winking = uptime < self.wink_until.as_millis() as u32; let any_button = self.buttons.as_mut() .map(|buttons| buttons.state()) @@ -137,6 +142,9 @@ RGB: RgbLed, let amplitude = calculate_amplitude(uptime, 2, 4, 128); Intensities { red: 0, green: 0, blue: amplitude } + } else if processing { + let on = (((F32(uptime as f32) / 250.0).round().0 as u32) % 2) != 0; + if on { GREEN } else { BLACK } } else if winking { // blink rapidly @@ -148,11 +156,12 @@ RGB: RgbLed, // regular behaviour: breathe slowly - let amplitude = calculate_amplitude(uptime, 5, 4, 64); + let amplitude = calculate_amplitude(uptime, 10, 4, 64); if !any_button { // Use green if no button is pressed. - Intensities { red: 0, green: amplitude, blue: 0 } + // Intensities { red: 0, green: amplitude, blue: 0 } + Intensities { red: amplitude, green: 0, blue: 0 } } else { // Use blue if button is pressed. Intensities { red: 0, green: 0, blue: amplitude } diff --git a/runners/lpc55/src/initializer.rs b/runners/lpc55/src/initializer.rs index b358b0c8..7527c9f5 100644 --- a/runners/lpc55/src/initializer.rs +++ b/runners/lpc55/src/initializer.rs @@ -515,11 +515,17 @@ impl Initializer { // So for instance "Hacker Solo 2" would work, but "Solo 2 (custom)" would not. let ccid = usbd_ccid::Ccid::new(usb_bus, contact_requester, Some(b"Solo 2")); let current_time = basic_stage.perf_timer.elapsed().0/1000; - let ctaphid = usbd_ctaphid::CtapHid::new(usb_bus, ctaphid_requester, current_time) + let mut ctaphid = usbd_ctaphid::CtapHid::new(usb_bus, ctaphid_requester, current_time) .implements_ctap1() .implements_ctap2() .implements_wink(); + ctaphid.set_version(usbd_ctaphid::Version { + major: crate::build_constants::CARGO_PKG_VERSION_MAJOR, + minor: crate::build_constants::CARGO_PKG_VERSION_MINOR.to_be_bytes()[0], + build: crate::build_constants::CARGO_PKG_VERSION_MINOR.to_be_bytes()[1], + }); + // let serial = usbd_serial::SerialPort::new(usb_bus); // Only 16 bits, so take the upper bits of our semver diff --git a/tests/basic.py b/tests/basic.py index e2b986bf..e8ea43f4 100644 --- a/tests/basic.py +++ b/tests/basic.py @@ -13,6 +13,8 @@ dev_info = dev.get_info() +N = 3 + print(dev_info) if dev_info.options.get('clientPin', False): pin_token = client_pin.get_pin_token(pin) @@ -56,6 +58,7 @@ credential_id = att.auth_data.credential_data.credential_id print(att.auth_data.credential_data) + print(f":: Credential ID (len{len(credential_id)}):\n{credential_id.hex()}") credential_ids.append(credential_id) public_key = att.auth_data.credential_data.public_key @@ -64,19 +67,20 @@ # basic sanity check - would raise assert att.fmt == "packed" verifier = fido2.attestation.Attestation.for_type(att.fmt)() - verifier.verify( - att.att_statement, att.auth_data, b"1234567890ABCDEF1234567890ABCDEF" - ) + # verifier.verify( + # att.att_statement, att.auth_data, b"1234567890ABCDEF1234567890ABCDEF" + # ) client_data_hash = b"some_client_data_hash_abcdefghij" - assn = dev.get_assertion( - "yamnord.com", - client_data_hash, - # allow_list=[{"type": "public-key", "id": credential_id}], - ) - - # basic sanity check - would raise - assn.verify(client_data_hash, public_key) + for _ in range(N): + assn = dev.get_assertion( + "yamnord.com", + client_data_hash, + allow_list=[{"type": "public-key", "id": credential_id}], + ) + + # basic sanity check - would raise + assn.verify(client_data_hash, public_key) # GA/GNA combo assn = dev.get_assertion("yamnord.com", client_data_hash) From 8c1e81f407a30dcdd84e3e76f0d085c7a5433b1a Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Wed, 16 Mar 2022 21:34:04 +0100 Subject: [PATCH 09/18] Big bug: No DWT.CYCCNT in locked devices - quick fix --- runners/lpc55/Cargo.toml | 2 +- runners/lpc55/board/Cargo.toml | 2 +- runners/lpc55/board/src/trussed.rs | 11 ++++-- runners/lpc55/src/main.rs | 63 +++++++++++++++++++++--------- runners/lpc55/src/types.rs | 4 ++ 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index 2adce83a..19454a55 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runner" -version = "1.797.0" +version = "1.797.1" authors = ["Nicolas Stalder ", "Conor Patrick "] edition = "2021" rust-version = "1.59.0" diff --git a/runners/lpc55/board/Cargo.toml b/runners/lpc55/board/Cargo.toml index acd11876..ea099956 100644 --- a/runners/lpc55/board/Cargo.toml +++ b/runners/lpc55/board/Cargo.toml @@ -2,7 +2,7 @@ name = "board" version = "0.0.0-unreleased" authors = ["Conor Patrick "] -edition = "2018" +edition = "2021" [dependencies] delog = "0.1.0" diff --git a/runners/lpc55/board/src/trussed.rs b/runners/lpc55/board/src/trussed.rs index ad3967fa..f529c455 100644 --- a/runners/lpc55/board/src/trussed.rs +++ b/runners/lpc55/board/src/trussed.rs @@ -64,9 +64,11 @@ const BLACK: Intensities = Intensities { red: 0, green: 0, blue: 0 }; const RED: Intensities = Intensities { red: u8::MAX, green: 0, blue: 0 }; const GREEN: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x02 }; const BLUE: Intensities = Intensities { red: 0, green: 0, blue: u8::MAX }; -const TEAL: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x5a }; +// const TEAL: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x5a }; #[allow(dead_code)] const ORANGE: Intensities = Intensities { red: u8::MAX, green: 0x7e, blue: 0 }; +#[allow(dead_code)] +const WHITE: Intensities = Intensities { red: u8::MAX, green: u8::MAX, blue: u8::MAX }; impl trussed::platform::UserInterface for UserInterface where @@ -109,8 +111,10 @@ RGB: RgbLed, // self.refresh runs periodically and would overwrite this if let Some(rgb) = &mut self.rgb { rgb.set(match status { - ui::Status::Idle => GREEN, - ui::Status::Processing => TEAL, + // ui::Status::Idle => GREEN, + ui::Status::Idle => RED, + // ui::Status::Processing => TEAL, + ui::Status::Processing => GREEN, // ui::Status::WaitingForUserPresence => ORANGE, ui::Status::WaitingForUserPresence => BLUE, ui::Status::Error => RED, @@ -151,6 +155,7 @@ RGB: RgbLed, let on = (((F32(uptime as f32) / 250.0).round().0 as u32) % 2) != 0; if on { BLUE } else { BLACK } + // if on { WHITE } else { BLACK } } else { diff --git a/runners/lpc55/src/main.rs b/runners/lpc55/src/main.rs index cb230c8e..e4ddacc0 100644 --- a/runners/lpc55/src/main.rs +++ b/runners/lpc55/src/main.rs @@ -13,10 +13,11 @@ use hal::traits::wg::timer::CountDown; use hal::drivers::timer::Elapsed; use hal::time::{DurationExtensions, Microseconds}; -use rtic::cyccnt::{Instant, U32Ext as _}; +// use rtic::cyccnt::{Instant, U32Ext as _}; const CLOCK_FREQ: u32 = 96_000_000; -const PERIOD: u32 = CLOCK_FREQ/16; +const REFRESH_MILLISECS: i32 = 50; +// const PERIOD: u32 = CLOCK_FREQ/16; // const PERIOD: u32 = CLOCK_FREQ/4; const USB_INTERRUPT: board::hal::raw::Interrupt = board::hal::raw::Interrupt::USB1; @@ -35,7 +36,27 @@ pub fn msp() -> u32 { r } -#[rtic::app(device = runner::hal::raw, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] +pub struct StolenRtc; + +impl rtic::Monotonic for StolenRtc { + // intended to be: milliseconds + type Instant = i32;//core::time::Duration; + unsafe fn reset() {} + fn ratio() -> rtic::Fraction { + rtic::Fraction { numerator: CLOCK_FREQ/1000, denominator: 1 } + } + fn now() -> Self::Instant { + let rtc = unsafe { crate::hal::raw::Peripherals::steal() }.RTC; + let secs = rtc.count.read().bits() as i32; + let ticks_32k = rtc.subsec.read().bits() as i32; + secs*1000 + ((ticks_32k * 61)/2000) + } + fn zero() -> Self::Instant { + Self::Instant::default() + } +} + +#[rtic::app(device = runner::hal::raw, peripherals = true, monotonic = crate::StolenRtc)] const APP: () = { struct Resources { @@ -107,8 +128,8 @@ const APP: () = { // don't toggle LED in passive mode if usb_classes.is_some() { hal::enable_cycle_counter(); - c.schedule.update_ui(Instant::now() + PERIOD.cycles()).unwrap(); - + // c.schedule.update_ui(Instant::now() + PERIOD.cycles()).unwrap(); + c.schedule.update_ui(::now() + REFRESH_MILLISECS).unwrap(); } init::LateResources { @@ -181,7 +202,8 @@ const APP: () = { match usb_classes.ccid.did_start_processing() { usbd_ccid::types::Status::ReceivedData(milliseconds) => { schedule.ccid_wait_extension( - Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -190,7 +212,8 @@ const APP: () = { match usb_classes.ctaphid.did_start_processing() { usbd_ctaphid::types::Status::ReceivedData(milliseconds) => { schedule.ctaphid_keepalive( - Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -215,7 +238,7 @@ const APP: () = { // debug_now!("USB interrupt: remaining stack size: {} bytes", remaining); // } let usb = unsafe { hal::raw::Peripherals::steal().USB1 } ; - let before = Instant::now(); + // let before = Instant::now(); let usb_classes = c.resources.usb_classes.as_mut().unwrap(); ////////////// @@ -230,7 +253,8 @@ const APP: () = { // debug_now!("scheduling CCID wait extension"); // } c.schedule.ccid_wait_extension( - Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -241,18 +265,19 @@ const APP: () = { // debug_now!("scheduling CTAPHID wait extension"); // } c.schedule.ctaphid_keepalive( - Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} } ////////////// - let after = Instant::now(); - let length = (after - before).as_cycles(); - if length > 10_000 { - // debug!("poll took {:?} cycles", length); - } + // let after = Instant::now(); + // let length = (after - before).as_cycles(); + // if length > 10_000 { + // // debug!("poll took {:?} cycles", length); + // } let inten = usb.inten.read().bits(); let intstat = usb.intstat.read().bits(); let mask = inten & intstat; @@ -289,7 +314,8 @@ const APP: () = { match status { usbd_ccid::types::Status::ReceivedData(milliseconds) => { c.schedule.ccid_wait_extension( - Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -307,7 +333,8 @@ const APP: () = { match status { usbd_ctaphid::types::Status::ReceivedData(milliseconds) => { c.schedule.ctaphid_keepalive( - Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -353,7 +380,7 @@ const APP: () = { // let wait_periods = c.resources.trussed.lock(|trussed| trussed.update_ui()); c.resources.trussed.lock(|trussed| trussed.update_ui()); // c.schedule.update_ui(Instant::now() + wait_periods * PERIOD.cycles()).unwrap(); - c.schedule.update_ui(Instant::now() + PERIOD.cycles()).unwrap(); + c.schedule.update_ui(::now() + REFRESH_MILLISECS).ok(); *UPDATES = UPDATES.wrapping_add(1); } diff --git a/runners/lpc55/src/types.rs b/runners/lpc55/src/types.rs index 64fa8a86..395ee451 100644 --- a/runners/lpc55/src/types.rs +++ b/runners/lpc55/src/types.rs @@ -103,6 +103,10 @@ impl admin_app::Reboot for Lpc55Reboot { hal::drivers::flash::FlashGordon::new(flash).erase_page(0).ok(); hal::raw::SCB::sys_reset() } + fn locked() -> bool { + let seal = &unsafe { hal::raw::Peripherals::steal() }.FLASH_CMPA.sha256_digest; + seal.iter().any(|word| word.read().bits() != 0) + } } #[cfg(feature = "admin-app")] From 483c0a30cf5314af7a9b62a606419cbc81d22285 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Wed, 16 Mar 2022 21:59:11 +0100 Subject: [PATCH 10/18] Move Monotonic and Reboot zero-sized types into `board` --- runners/lpc55/Cargo.toml | 7 +-- runners/lpc55/board/Cargo.toml | 8 ++-- runners/lpc55/board/README.md | 6 +-- runners/lpc55/board/src/lib.rs | 22 ++++++---- runners/lpc55/board/src/lpcxpresso55/led.rs | 8 ++-- runners/lpc55/board/src/shared.rs | 48 +++++++++++++++++++++ runners/lpc55/board/src/traits.rs | 4 ++ runners/lpc55/board/src/traits/monotonic.rs | 1 + runners/lpc55/board/src/traits/reboot.rs | 1 + runners/lpc55/src/main.rs | 44 ++++--------------- runners/lpc55/src/types.rs | 27 +----------- 11 files changed, 94 insertions(+), 82 deletions(-) create mode 100644 runners/lpc55/board/src/shared.rs create mode 100644 runners/lpc55/board/src/traits/monotonic.rs create mode 100644 runners/lpc55/board/src/traits/reboot.rs diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index 19454a55..605fedbe 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -80,9 +80,10 @@ no-reset-time-window = ["fido-authenticator/disable-reset-time-window"] # Format filesystem anyway format-filesystem = [] -board-lpcxpresso55 = ["board/board-lpcxpresso55"] -board-okdoe1 = ["board/board-okdoe1", "board-lpcxpresso55", "usbfs-peripheral"] -board-solo2 = ["board/board-solo2"] +# TODO: get rid of these (depends on moving "initialize_basic" &friends into `board` +board-lpcxpresso55 = ["board/lpcxpresso55"] +board-okdoe1 = ["board/okdoe1", "usbfs-peripheral"] +board-solo2 = ["board/solo2"] log-rtt = ["rtt-target"] log-semihosting = ["cortex-m-semihosting"] diff --git a/runners/lpc55/board/Cargo.toml b/runners/lpc55/board/Cargo.toml index ea099956..4338e57e 100644 --- a/runners/lpc55/board/Cargo.toml +++ b/runners/lpc55/board/Cargo.toml @@ -5,17 +5,19 @@ authors = ["Conor Patrick "] edition = "2021" [dependencies] +admin-app = { git = "https://github.com/solokeys/admin-app" } delog = "0.1.0" fm11nc08 = {path = "../../../components/fm11nc08"} lpc55-hal = { version = "0.3", features = ["littlefs", "rtic-peripherals"] } +lpc55-rtic = "0.5.7" micromath = "2" nb = "1" trussed = { git = "https://github.com/trussed-dev/trussed" } [features] -board-lpcxpresso55 = [] -board-okdoe1 = ["board-lpcxpresso55"] -board-solo2 = [] +lpcxpresso55 = [] +okdoe1 = ["lpcxpresso55"] +solo2 = [] no-buttons = [] no-clock-controller = [] diff --git a/runners/lpc55/board/README.md b/runners/lpc55/board/README.md index 907bda16..6d5d0811 100644 --- a/runners/lpc55/board/README.md +++ b/runners/lpc55/board/README.md @@ -6,7 +6,7 @@ The main ones are: - [LPCXpresso55S69][lpcxpresso], the official development board by NXP - [Solo 2][solo2], the new security key by SoloKeys -These can be selected via the features `board-lpcxpresso55` and `board-solo2`, +These can be selected via the features `lpcxpresso55` and `solo2`, respectively. It is more convenient to develop on the LPC55S69-EVK as it has `PIO0_5`, the `ISP0` pin, exposed. @@ -18,8 +18,8 @@ on the dev kit, two buttons instead of three, and the RGB led doesn't work prope There is also some low-effort support for the (cheap!) [OKdo E1][okdoe1]. This board however does not have a crystal soldered by default, and hence cannot run the USB HS peripheral. This also means it has one less bidirectional USB endpoint; keep this in mind when -USB classes stop working. It can be selected via the `board-okdoe1`, which patches -the `board-lpcxpresso55` implementation. +USB classes stop working. It can be selected via the `okdoe1`, which patches +the `lpcxpresso55` implementation. For development, on the main boards, we recommend using Segger's JLinkGDBServer: ``` diff --git a/runners/lpc55/board/src/lib.rs b/runners/lpc55/board/src/lib.rs index 81225eff..5e5e2bb5 100644 --- a/runners/lpc55/board/src/lib.rs +++ b/runners/lpc55/board/src/lib.rs @@ -2,26 +2,32 @@ pub use lpc55_hal as hal; +pub mod shared; pub mod traits; // board support package -#[cfg(not(any(feature = "board-lpcxpresso55", feature = "board-solo2")))] +#[cfg(not(any(feature = "lpcxpresso55", feature = "solo2")))] compile_error!("Please select one of the board features."); -#[cfg(feature = "board-lpcxpresso55")] -pub mod lpcxpresso55; -#[cfg(feature = "board-lpcxpresso55")] -pub use lpcxpresso55 as specifics; - #[macro_use] extern crate delog; generate_macros!(); -#[cfg(feature = "board-solo2")] +#[cfg(feature = "lpcxpresso55")] +pub mod lpcxpresso55; +#[cfg(feature = "lpcxpresso55")] +pub use lpcxpresso55 as specifics; + +#[cfg(feature = "solo2")] pub mod solo2; -#[cfg(feature = "board-solo2")] +#[cfg(feature = "solo2")] pub use solo2 as specifics; +pub use shared::{ + Monotonic, + Reboot, +}; + pub use specifics::{ button::ThreeButtons, led::RgbLed, diff --git a/runners/lpc55/board/src/lpcxpresso55/led.rs b/runners/lpc55/board/src/lpcxpresso55/led.rs index a43c0d71..9d102787 100644 --- a/runners/lpc55/board/src/lpcxpresso55/led.rs +++ b/runners/lpc55/board/src/lpcxpresso55/led.rs @@ -22,16 +22,16 @@ pub enum Color { use crate::traits::rgb_led; // OKdo E1 has pins switched for red+blue LED -#[cfg(not(feature = "board-okdoe1"))] +#[cfg(not(feature = "okdoe1"))] pub type RedLedPin = pins::Pio1_6; -#[cfg(feature = "board-okdoe1")] +#[cfg(feature = "okdoe1")] pub type RedLedPin = pins::Pio1_4; pub type GreenLedPin = pins::Pio1_7; -#[cfg(not(feature = "board-okdoe1"))] +#[cfg(not(feature = "okdoe1"))] pub type BlueLedPin = pins::Pio1_4; -#[cfg(feature = "board-okdoe1")] +#[cfg(feature = "okdoe1")] pub type BlueLedPin = pins::Pio1_6; diff --git a/runners/lpc55/board/src/shared.rs b/runners/lpc55/board/src/shared.rs new file mode 100644 index 00000000..c064841c --- /dev/null +++ b/runners/lpc55/board/src/shared.rs @@ -0,0 +1,48 @@ +use crate::hal; + +pub struct Monotonic; +pub struct Reboot; + +const CLOCK_FREQ: u32 = 96_000_000; + +impl crate::traits::Monotonic for Monotonic { + // intended to be: milliseconds + type Instant = i32;//core::time::Duration; + unsafe fn reset() {} + fn ratio() -> rtic::Fraction { + rtic::Fraction { numerator: CLOCK_FREQ/1000, denominator: 1 } + } + fn now() -> Self::Instant { + let rtc = unsafe { crate::hal::raw::Peripherals::steal() }.RTC; + let secs = rtc.count.read().bits() as i32; + let ticks_32k = rtc.subsec.read().bits() as i32; + secs*1000 + ((ticks_32k * 61)/2000) + } + fn zero() -> Self::Instant { + Self::Instant::default() + } +} + +impl crate::traits::Reboot for Reboot { + fn reboot() -> ! { + hal::raw::SCB::sys_reset() + } + fn reboot_to_firmware_update() -> ! { + hal::boot_to_bootrom() + } + fn reboot_to_firmware_update_destructive() -> ! { + // Erasing the first flash page & rebooting will keep processor in bootrom persistently. + // This is however destructive, as a valid firmware will need to be flashed. + use hal::traits::flash::WriteErase; + let flash = unsafe { hal::peripherals::flash::Flash::steal() }.enabled( + &mut unsafe {hal::peripherals::syscon::Syscon::steal()} + ); + hal::drivers::flash::FlashGordon::new(flash).erase_page(0).ok(); + hal::raw::SCB::sys_reset() + } + fn locked() -> bool { + let seal = &unsafe { hal::raw::Peripherals::steal() }.FLASH_CMPA.sha256_digest; + seal.iter().any(|word| word.read().bits() != 0) + } +} + diff --git a/runners/lpc55/board/src/traits.rs b/runners/lpc55/board/src/traits.rs index 210b3427..aba050e2 100644 --- a/runners/lpc55/board/src/traits.rs +++ b/runners/lpc55/board/src/traits.rs @@ -1,2 +1,6 @@ pub mod buttons; +pub mod monotonic; +pub use monotonic::Monotonic; +pub mod reboot; +pub use reboot::Reboot; pub mod rgb_led; diff --git a/runners/lpc55/board/src/traits/monotonic.rs b/runners/lpc55/board/src/traits/monotonic.rs new file mode 100644 index 00000000..8abd1593 --- /dev/null +++ b/runners/lpc55/board/src/traits/monotonic.rs @@ -0,0 +1 @@ +pub use rtic::Monotonic; diff --git a/runners/lpc55/board/src/traits/reboot.rs b/runners/lpc55/board/src/traits/reboot.rs new file mode 100644 index 00000000..469b617e --- /dev/null +++ b/runners/lpc55/board/src/traits/reboot.rs @@ -0,0 +1 @@ +pub use admin_app::Reboot; diff --git a/runners/lpc55/src/main.rs b/runners/lpc55/src/main.rs index e4ddacc0..be73f1cc 100644 --- a/runners/lpc55/src/main.rs +++ b/runners/lpc55/src/main.rs @@ -6,19 +6,13 @@ #![no_main] // #![deny(warnings)] -use core::convert::TryFrom; use runner::hal; use hal::traits::wg::timer::Cancel; use hal::traits::wg::timer::CountDown; use hal::drivers::timer::Elapsed; use hal::time::{DurationExtensions, Microseconds}; -// use rtic::cyccnt::{Instant, U32Ext as _}; - -const CLOCK_FREQ: u32 = 96_000_000; const REFRESH_MILLISECS: i32 = 50; -// const PERIOD: u32 = CLOCK_FREQ/16; -// const PERIOD: u32 = CLOCK_FREQ/4; const USB_INTERRUPT: board::hal::raw::Interrupt = board::hal::raw::Interrupt::USB1; const NFC_INTERRUPT: board::hal::raw::Interrupt = board::hal::raw::Interrupt::PIN_INT0; @@ -36,27 +30,7 @@ pub fn msp() -> u32 { r } -pub struct StolenRtc; - -impl rtic::Monotonic for StolenRtc { - // intended to be: milliseconds - type Instant = i32;//core::time::Duration; - unsafe fn reset() {} - fn ratio() -> rtic::Fraction { - rtic::Fraction { numerator: CLOCK_FREQ/1000, denominator: 1 } - } - fn now() -> Self::Instant { - let rtc = unsafe { crate::hal::raw::Peripherals::steal() }.RTC; - let secs = rtc.count.read().bits() as i32; - let ticks_32k = rtc.subsec.read().bits() as i32; - secs*1000 + ((ticks_32k * 61)/2000) - } - fn zero() -> Self::Instant { - Self::Instant::default() - } -} - -#[rtic::app(device = runner::hal::raw, peripherals = true, monotonic = crate::StolenRtc)] +#[rtic::app(device = runner::hal::raw, peripherals = true, monotonic = board::Monotonic)] const APP: () = { struct Resources { @@ -129,7 +103,7 @@ const APP: () = { if usb_classes.is_some() { hal::enable_cycle_counter(); // c.schedule.update_ui(Instant::now() + PERIOD.cycles()).unwrap(); - c.schedule.update_ui(::now() + REFRESH_MILLISECS).unwrap(); + c.schedule.update_ui(::now() + REFRESH_MILLISECS).unwrap(); } init::LateResources { @@ -203,7 +177,7 @@ const APP: () = { usbd_ccid::types::Status::ReceivedData(milliseconds) => { schedule.ccid_wait_extension( // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() - ::now() + milliseconds.0 as i32 + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -213,7 +187,7 @@ const APP: () = { usbd_ctaphid::types::Status::ReceivedData(milliseconds) => { schedule.ctaphid_keepalive( // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() - ::now() + milliseconds.0 as i32 + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -254,7 +228,7 @@ const APP: () = { // } c.schedule.ccid_wait_extension( // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() - ::now() + milliseconds.0 as i32 + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -266,7 +240,7 @@ const APP: () = { // } c.schedule.ctaphid_keepalive( // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() - ::now() + milliseconds.0 as i32 + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -315,7 +289,7 @@ const APP: () = { usbd_ccid::types::Status::ReceivedData(milliseconds) => { c.schedule.ccid_wait_extension( // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() - ::now() + milliseconds.0 as i32 + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -334,7 +308,7 @@ const APP: () = { usbd_ctaphid::types::Status::ReceivedData(milliseconds) => { c.schedule.ctaphid_keepalive( // Instant::now() + (CLOCK_FREQ/1_000 * milliseconds.0).cycles() - ::now() + milliseconds.0 as i32 + ::now() + milliseconds.0 as i32 ).ok(); } _ => {} @@ -380,7 +354,7 @@ const APP: () = { // let wait_periods = c.resources.trussed.lock(|trussed| trussed.update_ui()); c.resources.trussed.lock(|trussed| trussed.update_ui()); // c.schedule.update_ui(Instant::now() + wait_periods * PERIOD.cycles()).unwrap(); - c.schedule.update_ui(::now() + REFRESH_MILLISECS).ok(); + c.schedule.update_ui(::now() + REFRESH_MILLISECS).ok(); *UPDATES = UPDATES.wrapping_add(1); } diff --git a/runners/lpc55/src/types.rs b/runners/lpc55/src/types.rs index 395ee451..a407cb64 100644 --- a/runners/lpc55/src/types.rs +++ b/runners/lpc55/src/types.rs @@ -1,5 +1,4 @@ include!(concat!(env!("OUT_DIR"), "/build_constants.rs")); -use core::convert::TryInto; use crate::hal; use hal::drivers::timer; @@ -85,32 +84,8 @@ pub type ExternalInterrupt = hal::Pint; pub type ApduDispatch = apdu_dispatch::dispatch::ApduDispatch; pub type CtaphidDispatch = ctaphid_dispatch::dispatch::Dispatch; -pub struct Lpc55Reboot {} -impl admin_app::Reboot for Lpc55Reboot { - fn reboot() -> ! { - hal::raw::SCB::sys_reset() - } - fn reboot_to_firmware_update() -> ! { - hal::boot_to_bootrom() - } - fn reboot_to_firmware_update_destructive() -> ! { - // Erasing the first flash page & rebooting will keep processor in bootrom persistently. - // This is however destructive, as a valid firmware will need to be flashed. - use hal::traits::flash::WriteErase; - let flash = unsafe { hal::peripherals::flash::Flash::steal() }.enabled( - &mut unsafe {hal::peripherals::syscon::Syscon::steal()} - ); - hal::drivers::flash::FlashGordon::new(flash).erase_page(0).ok(); - hal::raw::SCB::sys_reset() - } - fn locked() -> bool { - let seal = &unsafe { hal::raw::Peripherals::steal() }.FLASH_CMPA.sha256_digest; - seal.iter().any(|word| word.read().bits() != 0) - } -} - #[cfg(feature = "admin-app")] -pub type AdminApp = admin_app::App; +pub type AdminApp = admin_app::App; #[cfg(feature = "piv-authenticator")] pub type PivApp = piv_authenticator::Authenticator; #[cfg(feature = "oath-authenticator")] From a9727cab07522f1413d5729cf33b74d7acee7e54 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Thu, 17 Mar 2022 03:13:58 +0100 Subject: [PATCH 11/18] Bump version, use merged fido-authenticator --- runners/lpc55/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index 605fedbe..943e7044 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runner" -version = "1.797.1" +version = "1.806.0" authors = ["Nicolas Stalder ", "Conor Patrick "] edition = "2021" rust-version = "1.59.0" @@ -28,7 +28,7 @@ admin-app = { git = "https://github.com/solokeys/admin-app", optional = true } apdu-dispatch = "0.1" ctaphid-dispatch = "0.1" ctap-types = "0.1" -fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", branch = "less-ram", features = ["dispatch"], optional = true } +fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", features = ["dispatch"], optional = true } oath-authenticator = { git = "https://github.com/trussed-dev/oath-authenticator", features = ["apdu-dispatch"], optional = true } piv-authenticator = { git = "https://github.com/solokeys/piv-authenticator", features = ["apdu-dispatch"], optional = true } trussed = { git = "https://github.com/trussed-dev/trussed" } From 48b0637d44d156a1302815102d2641bc2852ff07 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Thu, 17 Mar 2022 03:49:34 +0100 Subject: [PATCH 12/18] Use published Trussed and apps --- runners/lpc55/Cargo.toml | 8 ++++---- runners/lpc55/board/Cargo.toml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index 943e7044..0256fd4d 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -24,14 +24,14 @@ usb-device = "0.2.3" # usbd-hid = { version = "0.4.5", optional = true } usbd-serial = "0.1.0" -admin-app = { git = "https://github.com/solokeys/admin-app", optional = true } +admin-app = { version = "0.1", optional = true } apdu-dispatch = "0.1" ctaphid-dispatch = "0.1" ctap-types = "0.1" -fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", features = ["dispatch"], optional = true } -oath-authenticator = { git = "https://github.com/trussed-dev/oath-authenticator", features = ["apdu-dispatch"], optional = true } +fido-authenticator = { version = "0.1", features = ["dispatch"], optional = true } +oath-authenticator = { version = "0.1", features = ["apdu-dispatch"], optional = true } piv-authenticator = { git = "https://github.com/solokeys/piv-authenticator", features = ["apdu-dispatch"], optional = true } -trussed = { git = "https://github.com/trussed-dev/trussed" } +trussed = "0.1" # board board = { path = "board" } diff --git a/runners/lpc55/board/Cargo.toml b/runners/lpc55/board/Cargo.toml index 4338e57e..6c8fb03f 100644 --- a/runners/lpc55/board/Cargo.toml +++ b/runners/lpc55/board/Cargo.toml @@ -1,18 +1,18 @@ [package] name = "board" -version = "0.0.0-unreleased" +version = "0.1.0-unreleased" authors = ["Conor Patrick "] edition = "2021" [dependencies] -admin-app = { git = "https://github.com/solokeys/admin-app" } -delog = "0.1.0" +admin-app = "0.1" +delog = "0.1" fm11nc08 = {path = "../../../components/fm11nc08"} lpc55-hal = { version = "0.3", features = ["littlefs", "rtic-peripherals"] } lpc55-rtic = "0.5.7" micromath = "2" nb = "1" -trussed = { git = "https://github.com/trussed-dev/trussed" } +trussed = "0.1" [features] lpcxpresso55 = [] From 330e93e84b02ee1cd7d8c8903f81c9295b079b7a Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Thu, 17 Mar 2022 03:56:31 +0100 Subject: [PATCH 13/18] Some more dependency fixes --- components/provisioner-app/Cargo.toml | 4 ++-- runners/pc/Cargo.toml | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/components/provisioner-app/Cargo.toml b/components/provisioner-app/Cargo.toml index 180ca454..4bf93bc8 100644 --- a/components/provisioner-app/Cargo.toml +++ b/components/provisioner-app/Cargo.toml @@ -8,13 +8,13 @@ edition = "2018" [dependencies] apdu-dispatch = "0.1" -delog = "0.1.1" +delog = "0.1" heapless = "0.7" heapless-bytes = "0.3" lpc55-hal = { version = "0.3", features = ["littlefs", "rtic-peripherals"] } littlefs2 = "0.3.1" salty = { version = "0.2", features = ["cose"] } -trussed = { git = "https://github.com/trussed-dev/trussed" } +trussed = "0.1" [dependencies.nisty] version = "0.1.0-alpha.5" diff --git a/runners/pc/Cargo.toml b/runners/pc/Cargo.toml index 46b95425..ebb11cab 100644 --- a/runners/pc/Cargo.toml +++ b/runners/pc/Cargo.toml @@ -12,14 +12,13 @@ generic-array = "0.14.3" interchange = "0.2.0" nb = "1" -admin-app = { git = "https://github.com/solokeys/admin-app" } +admin-app = "0.1" apdu-dispatch = "0.1" ctap-types = "0.1" ctaphid-dispatch = "0.1" -# fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator" } -fido-authenticator = { git = "https://github.com/solokeys/fido-authenticator", branch = "less-ram", features = ["dispatch"], optional = true } +fido-authenticator = { version = "0.1", features = ["dispatch"], optional = true } piv-authenticator = { git = "https://github.com/solokeys/piv-authenticator" } -trussed = { git = "https://github.com/trussed-dev/trussed", features = ["clients-3"] } +trussed = { version = "0.1", features = ["clients-3"] } # components usbd-ccid = { path = "../../components/usbd-ccid" } From 567d142d07fbf6104c41ba2e118eb4e4d8dfa1c6 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 19 May 2022 20:23:01 +0200 Subject: [PATCH 14/18] Remove unnecessary targets from Makefile This patch removes solo2-specific targets from the Makefile. --- runners/lpc55/Makefile | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/runners/lpc55/Makefile b/runners/lpc55/Makefile index 270b8e77..ec796fee 100644 --- a/runners/lpc55/Makefile +++ b/runners/lpc55/Makefile @@ -12,14 +12,6 @@ else ifeq "${PROVISIONER}" "1" FEATURES := ${FEATURES},provisioner endif -build-release: - cargo build --release --features board-solo2 - cargo objcopy --release --features board-solo2 -- -O binary app-solo2.bin - -.PHONY: today-as-minor-version -today-in-days: - python -c "from datetime import date as d; print((d.today() - d(2020, 1, 1)).days)" - ifeq "${PROVISIONER}" "1" FILENAME_PREFIX := provisioner- else @@ -67,10 +59,3 @@ bacon: jlink: -../../scripts/bump-jlink JLinkGDBServer -strict -device LPC55S69 -if SWD -vd - - -PACK_VERSION := $(shell wget -O - -qq https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.pidx|grep LPC55S69|python -c'import sys; print(sys.stdin.read().rsplit("version=\"", 1)[1].split("\"", 1)[0])') -PACK := NXP.LPC55S69_DFP.$(PACK_VERSION).pack -get-cmsis-pack: - wget -qq https://mcuxpresso.nxp.com/cmsis_pack/repo/$(PACK) -O ./lpc55s69.pack - From ebbd01e18c597a7a4215d9d919de7452b097a369 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 19 May 2022 20:26:52 +0200 Subject: [PATCH 15/18] Disable LED pulsing This patch indicates the LED pulsing. This does not change the current behavior for production devices as LED pulsing is not working due to a missing peripheral in locked mode in the current firmware version. --- runners/lpc55/Cargo.lock | 7 ----- runners/lpc55/board/Cargo.toml | 1 - runners/lpc55/board/src/trussed.rs | 43 +++--------------------------- 3 files changed, 4 insertions(+), 47 deletions(-) diff --git a/runners/lpc55/Cargo.lock b/runners/lpc55/Cargo.lock index d55b02a5..5f153dfd 100644 --- a/runners/lpc55/Cargo.lock +++ b/runners/lpc55/Cargo.lock @@ -202,7 +202,6 @@ dependencies = [ "fm11nc08", "lpc55-hal", "lpc55-rtic", - "micromath", "nb 1.0.0", "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -951,12 +950,6 @@ dependencies = [ "cty", ] -[[package]] -name = "micromath" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39617bc909d64b068dcffd0e3e31679195b5576d0c83fadc52690268cc2b2b55" - [[package]] name = "nb" version = "0.1.3" diff --git a/runners/lpc55/board/Cargo.toml b/runners/lpc55/board/Cargo.toml index 33a7a54e..291585fc 100644 --- a/runners/lpc55/board/Cargo.toml +++ b/runners/lpc55/board/Cargo.toml @@ -10,7 +10,6 @@ delog = "0.1" fm11nc08 = {path = "../../../components/fm11nc08"} lpc55-hal = { version = "0.3", features = ["littlefs", "rtic-peripherals"] } lpc55-rtic = "0.5.7" -micromath = "2" nb = "1" trussed = "0.1" diff --git a/runners/lpc55/board/src/trussed.rs b/runners/lpc55/board/src/trussed.rs index 19c39512..9a666592 100644 --- a/runners/lpc55/board/src/trussed.rs +++ b/runners/lpc55/board/src/trussed.rs @@ -9,7 +9,6 @@ use crate::hal::{ }; use crate::traits::buttons::{Press, Edge}; use crate::traits::rgb_led::{Intensities, RgbLed}; -use micromath::F32; use trussed::platform::{consent, ui}; // Assuming there will only be one way to @@ -60,10 +59,10 @@ RGB: RgbLed, } // color codes Conor picked -#[allow(dead_code)] const BLACK: Intensities = Intensities { red: 0, green: 0, blue: 0 }; const RED: Intensities = Intensities { red: u8::MAX, green: 0, blue: 0 }; const GREEN: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x02 }; +#[allow(dead_code)] const BLUE: Intensities = Intensities { red: 0, green: 0, blue: u8::MAX }; const TEAL: Intensities = Intensities { red: 0, green: u8::MAX, blue: 0x5a }; const ORANGE: Intensities = Intensities { red: u8::MAX, green: 0x7e, blue: 0 }; @@ -156,30 +155,8 @@ RGB: RgbLed, } else { self.wink = None; } - } - - if self.buttons.is_some() { - // 1. Get time & pick a period (here 4096). - // 2. Map it to a value between 0 and pi. - // 3. Calculate sine and map to amplitude between 0 and 255. - let time = (self.uptime().as_millis()) % 4096; - let amplitude = calculate_amplitude(time as u32, 2, 4, 128); - - let state = self.buttons.as_mut().unwrap().state(); - let mut color = if state.a || state.b || state.middle { - // Use blue if button is pressed. - BLUE - } else { - // Use green if no button is pressed. - GREEN - }; - - // use logging::hex::*; - // use logging::hex; - // crate::logger::info!("time: {}", time).ok(); - // crate::logger::info!("amp: {}", hex!(amplitude)).ok(); - // crate::logger::info!("color: {}", hex!(color)).ok(); - self.rgb.as_mut().unwrap().set(color.scale_by(&litude).into()); + } else { + self.set_status(ui::Status::Idle); } } @@ -190,18 +167,6 @@ RGB: RgbLed, fn wink(&mut self, duration: Duration) { let time = self.uptime(); self.wink = Some(time..time + duration); - self.rgb.as_mut().unwrap().set(0xff_ff_ff.into()); + self.rgb.as_mut().unwrap().set(WHITE.into()); } } - - -fn calculate_amplitude(now_millis: u32, period_secs: u8, min_amplitude: u8, max_amplitude: u8) -> u8 { - let period = Duration::new(period_secs as u64, 0).as_millis() as u32; - let tau = F32(6.283185); - let angle = F32(now_millis as f32) * tau / (period as f32); - let rel_amplitude = max_amplitude - min_amplitude; - - // sinoidal wave on top of a baseline brightness - let amplitude = min_amplitude + (angle.sin().abs() * (rel_amplitude as f32)).floor().0 as u8; - amplitude -} From 3408e6cdc89deac6c6fa7dd3c57164f70ae8e9b4 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 19 May 2022 20:29:45 +0200 Subject: [PATCH 16/18] Remove dummy serial number from USB device Instead of setting an all-zero serial number for the USB device, we remove the serial number entirely to maintain the status quo. --- runners/lpc55/src/initializer.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/runners/lpc55/src/initializer.rs b/runners/lpc55/src/initializer.rs index 5fb7841d..4672e570 100644 --- a/runners/lpc55/src/initializer.rs +++ b/runners/lpc55/src/initializer.rs @@ -72,18 +72,6 @@ pub struct Initializer { config: Config, } -fn get_serial_number() -> &'static str { - /*static mut SERIAL_NUMBER: heapless::String = heapless::String(heapless::i::String::new()); - use core::fmt::Write; - unsafe { - let uuid = crate::hal::uuid(); - SERIAL_NUMBER.write_fmt(format_args!("{}", hexstr!(&uuid))).unwrap(); - &SERIAL_NUMBER - }*/ - "00000000-0000-0000-00000000" -} - - // SoloKeys stores a product string in the first 64 bytes of CMPA. fn get_product_string(pfr: &mut Pfr) -> &'static str { let data = pfr.cmpa_customer_data(); @@ -552,12 +540,10 @@ impl Initializer { UsbProductName::Custom(name) => name, UsbProductName::UsePfr => get_product_string(&mut basic_stage.pfr), }; - let serial_number = get_serial_number(); let usbd = UsbDeviceBuilder::new(usb_bus, usb_config.vid_pid) .manufacturer(usb_config.manufacturer_name) .product(product_string) - .serial_number(serial_number) .device_release(device_release) .max_packet_size_0(64) .composite_with_iads() From 4f75fb699d20aeeed902700c2842135ea30fa8b0 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 19 May 2022 20:30:38 +0200 Subject: [PATCH 17/18] Allow cargo warnings This patch removes the -Dwarnings flag from the cargo configuration that fails the build if there is a warning. While this setting makes sense in the CI, it is annoying during development. --- runners/lpc55/.cargo/config.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/runners/lpc55/.cargo/config.toml b/runners/lpc55/.cargo/config.toml index 8fec6e14..bc5e0202 100644 --- a/runners/lpc55/.cargo/config.toml +++ b/runners/lpc55/.cargo/config.toml @@ -3,7 +3,6 @@ runner = "arm-none-eabi-gdb -q -x jlink.gdb" rustflags = [ "-C", "linker=flip-link", "-C", "link-arg=-Tlink.x", - "-Dwarnings", ] [build] From d582512179ed89abcdada7e099cd7cb99f57a60d Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 24 May 2022 10:11:42 +0200 Subject: [PATCH 18/18] Fix blinking LED during confirmation request Due to recent changes in Trussed, the LED is blinking during a user confirmation request if it is processing data, for example on webauthn.bin.coffee. This patch restores the old behavior by using a custom Trussed version that does not change the LED when processing data and by fixing the refresh method in board/src/trussed.rs. --- runners/lpc55/Cargo.lock | 15 +++++++-------- runners/lpc55/Cargo.toml | 3 +++ runners/lpc55/board/src/trussed.rs | 3 +-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/runners/lpc55/Cargo.lock b/runners/lpc55/Cargo.lock index 5f153dfd..33e94bd6 100644 --- a/runners/lpc55/Cargo.lock +++ b/runners/lpc55/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ "ctaphid-dispatch", "delog", "iso7816 0.1.0", - "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trussed 0.1.0 (git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset)", ] [[package]] @@ -203,7 +203,7 @@ dependencies = [ "lpc55-hal", "lpc55-rtic", "nb 1.0.0", - "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trussed 0.1.0 (git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset)", ] [[package]] @@ -599,7 +599,7 @@ dependencies = [ "serde", "serde-indexed", "serde_cbor", - "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trussed 0.1.0 (git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset)", ] [[package]] @@ -1088,7 +1088,7 @@ dependencies = [ "interchange", "iso7816 0.1.0", "serde", - "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trussed 0.1.0 (git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset)", ] [[package]] @@ -1213,7 +1213,7 @@ dependencies = [ "lpc55-hal", "nisty", "salty", - "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trussed 0.1.0 (git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset)", ] [[package]] @@ -1327,7 +1327,7 @@ dependencies = [ "piv-authenticator", "provisioner-app", "rtt-target", - "trussed 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trussed 0.1.0 (git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset)", "usb-device", "usbd-ccid", "usbd-ctaphid", @@ -1523,8 +1523,7 @@ dependencies = [ [[package]] name = "trussed" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7173399ed80afefa978da6c601d9712d1de03f7c6e2b9d4630addfcc0598f5e" +source = "git+https://github.com/nitrokey/trussed?branch=no-ui-status-reset#0994607f6fe84a3fbec9b137c9e8247f1232d536" dependencies = [ "aes", "bitflags", diff --git a/runners/lpc55/Cargo.toml b/runners/lpc55/Cargo.toml index c022e990..2ffab6a5 100644 --- a/runners/lpc55/Cargo.toml +++ b/runners/lpc55/Cargo.toml @@ -104,6 +104,9 @@ log-debug = [] log-warn = [] log-error = [] +[patch.crates-io] +trussed = { git = "https://github.com/nitrokey/trussed", branch = "no-ui-status-reset" } + [profile.release] codegen-units = 1 lto = true diff --git a/runners/lpc55/board/src/trussed.rs b/runners/lpc55/board/src/trussed.rs index 9a666592..946ce81d 100644 --- a/runners/lpc55/board/src/trussed.rs +++ b/runners/lpc55/board/src/trussed.rs @@ -153,10 +153,9 @@ RGB: RgbLed, self.rgb.as_mut().unwrap().set(color.into()); return; } else { + self.set_status(ui::Status::Idle); self.wink = None; } - } else { - self.set_status(ui::Status::Idle); } }