From a0d6d2a692adb4ee8f8d2abeb5808fa69357a860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 8 Sep 2025 17:22:12 +0200 Subject: [PATCH] Update to heapless 0.9 --- Cargo.toml | 32 ++++++++++++++++++++-------- fuzz/Cargo.toml | 15 ++++++++++--- fuzz/fuzz_targets/ctap.rs | 3 ++- src/credential.rs | 41 ++++++++++++++++++------------------ src/ctap1.rs | 44 +++++++++++++++++++-------------------- src/ctap2.rs | 36 +++++++++++++++++--------------- src/ctap2/pin.rs | 25 +++++++++++++--------- src/dispatch.rs | 19 +++++++++-------- src/dispatch/apdu.rs | 11 +++++----- src/dispatch/ctaphid.rs | 10 ++++----- tests/virt/pipe.rs | 2 +- 11 files changed, 135 insertions(+), 103 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6cc2bda..914d670 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,10 @@ description = "FIDO authenticator Trussed app" [dependencies] cbor-smol = { version = "0.5" } ctap-types = { version = "0.4", features = ["get-info-full", "large-blobs", "third-party-payment"] } -cosey = "0.3" +cosey = "0.4" delog = "0.1.0" -heapless = "0.7" -heapless-bytes = "0.3" +heapless = "0.9" +heapless-bytes = { version = "0.5", features = ["heapless-0.9"]} littlefs2-core = "0.1" serde = { version = "1.0", default-features = false } serde_bytes = { version = "0.11.14", default-features = false } @@ -27,7 +27,7 @@ trussed-chunked = { version = "0.2.0", optional = true } apdu-app = { version = "0.1", optional = true } ctaphid-app = { version = "0.1.0-rc.1", optional = true } -iso7816 = { version = "0.1.2", optional = true } +iso7816 = { version = "0.2", optional = true } [features] dispatch = ["apdu-dispatch", "ctaphid-dispatch", "iso7816"] @@ -61,7 +61,7 @@ hex-literal = "0.4.1" hmac = "0.12.1" interchange = "0.3.0" itertools = "0.14.0" -littlefs2 = "0.6.0" +littlefs2 = "0.7.0" log = "0.4.21" p256 = { version = "0.13.2", features = ["ecdh"] } rand = "0.8.4" @@ -78,10 +78,24 @@ x509-parser = "0.16.0" features = ["dispatch"] [patch.crates-io] -admin-app = { git = "https://github.com/Nitrokey/admin-app.git", tag = "v0.1.0-nitrokey.20" } -trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "024e0eca5fb7dbd2457831f7c7bffe4341e08775" } -trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "7922d67e9637a87e5625aaff9e5111f0d4ec0346" } -trussed-usbip = { git = "https://github.com/trussed-dev/pc-usbip-runner.git", rev = "504674453c9573a30aa2f155101df49eb2af1ba7" } +trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" } +trussed-core = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" } +trussed-manage = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" } +trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" } +trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" } + + +littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "e9d3a1ca98f80e92cd20ee9b94707067810b9036" } +littlefs2-core = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "e9d3a1ca98f80e92cd20ee9b94707067810b9036" } +littlefs2-sys = { git = "https://github.com/trussed-dev/littlefs2-sys", rev = "v0.3.1-nitrokey.1" } +salty = { git = "https://github.com/ycrypto/salty.git", rev = "ae17f04ec965913e08032d266f6a47c001031f06" } +ctaphid-app = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "f11fdcbc62d06b8be23e6cbae21bcfefd52c0661" } +ctaphid-dispatch = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "f11fdcbc62d06b8be23e6cbae21bcfefd52c0661" } +apdu-app = { git = "https://github.com/trussed-dev/apdu-dispatch.git", rev = "931c4269d1d293954fae2012d809e9663cd2cb7e" } +admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "2b3f758016afbc56535d8a65f98a067d5a2d843e" } +trussed-usbip = { git = "https://github.com/trussed-dev/pc-usbip-runner.git", rev = "0ff1992f15c273c87e0607384e3dd94d341b721e" } +usbd-ctaphid = { git = "https://github.com/trussed-dev/usbd-ctaphid.git", rev = "94881f83a6b4229a7a3187a5dd7b3ccf6eb6dc00" } +ctap-types = { git = "https://github.com/trussed-dev/ctap-types", rev = "cff44662b48088511fa8ae30557c457f8252f220"} [profile.test] opt-level = 2 diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 9b9d04b..fad1b8e 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -10,7 +10,7 @@ cargo-fuzz = true [dependencies] ctap-types = { version = "0.4", features = ["arbitrary"] } libfuzzer-sys = "0.4" -trussed = { version = "0.1", features = ["clients-1", "certificate-client", "crypto-client", "filesystem-client", "management-client", "aes256-cbc", "ed255", "p256", "sha256"] } +trussed = { version = "0.1", features = ["certificate-client", "crypto-client", "filesystem-client", "management-client", "aes256-cbc", "ed255", "p256", "sha256"] } trussed-staging = { version = "0.3.0", features = ["chunked", "hkdf", "virt", "fs-info"] } [dependencies.fido-authenticator] @@ -24,5 +24,14 @@ doc = false bench = false [patch.crates-io] -trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "6bba8fde36d05c0227769eb63345744e87d84b2b" } -trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "1e1ca03a3a62ea9b802f4070ea4bce002eeb4bec" } +trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" } +trussed-core = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" } +trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" } +trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" } + + +littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "e9d3a1ca98f80e92cd20ee9b94707067810b9036" } +littlefs2-core = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "e9d3a1ca98f80e92cd20ee9b94707067810b9036" } +littlefs2-sys = { git = "https://github.com/trussed-dev/littlefs2-sys", rev = "v0.3.1-nitrokey.1" } +salty = { git = "https://github.com/ycrypto/salty.git", rev = "ae17f04ec965913e08032d266f6a47c001031f06" } +ctap-types = { git = "https://github.com/trussed-dev/ctap-types", rev = "cff44662b48088511fa8ae30557c457f8252f220"} diff --git a/fuzz/fuzz_targets/ctap.rs b/fuzz/fuzz_targets/ctap.rs index 01c4aad..815c731 100644 --- a/fuzz/fuzz_targets/ctap.rs +++ b/fuzz/fuzz_targets/ctap.rs @@ -2,12 +2,13 @@ use ctap_types::{authenticator::Request, ctap1::Authenticator as _, ctap2::Authenticator as _}; use fido_authenticator::{Authenticator, Config, Conforming}; +use trussed::virt::StoreConfig; use trussed_staging::virt; use libfuzzer_sys::fuzz_target; fuzz_target!(|requests: Vec>| { - virt::with_ram_client("fido", |client| { + virt::with_client(StoreConfig::ram(), "fido", |client| { let mut authenticator = Authenticator::new( client, Conforming {}, diff --git a/src/credential.rs b/src/credential.rs index 7aabed7..bb70f15 100644 --- a/src/credential.rs +++ b/src/credential.rs @@ -202,13 +202,14 @@ impl Credential { fn deserialize_bytes( s: &[u8], ) -> core::result::Result, E> { - Bytes::from_slice(s).map_err(|_| E::invalid_length(s.len(), &"a fixed-size sequence of bytes")) + Bytes::try_from(s).map_err(|_| E::invalid_length(s.len(), &"a fixed-size sequence of bytes")) } fn deserialize_str( s: &str, ) -> core::result::Result, E> { - Ok(s.into()) + s.try_into() + .map_err(|_| E::custom("Serialized string doesn't fit ")) } #[derive(Clone, Copy, Debug, PartialEq)] @@ -794,12 +795,12 @@ mod test { fn credential_data() -> CredentialData { CredentialData { rp: Rp::new(PublicKeyCredentialRpEntity { - id: String::from("John Doe"), + id: String::try_from("John Doe").unwrap(), name: None, icon: None, }), user: User::new(PublicKeyCredentialUserEntity { - id: Bytes::from_slice(&[1, 2, 3]).unwrap(), + id: Bytes::from(&[1, 2, 3]), icon: None, name: None, display_name: None, @@ -807,7 +808,7 @@ mod test { creation_time: 123, use_counter: false, algorithm: -7, - key: Key::WrappedKey(Bytes::from_slice(&[1, 2, 3]).unwrap()), + key: Key::WrappedKey(Bytes::from(&[1, 2, 3])), hmac_secret: Some(false), cred_protect: None, use_short_id: Some(true), @@ -821,7 +822,7 @@ mod test { rp: Rp { format: SerializationFormat::Long, inner: PublicKeyCredentialRpEntity { - id: String::from("John Doe"), + id: String::try_from("John Doe").unwrap(), name: None, icon: None, }, @@ -829,7 +830,7 @@ mod test { user: User { format: SerializationFormat::Long, inner: PublicKeyCredentialUserEntity { - id: Bytes::from_slice(&[1, 2, 3]).unwrap(), + id: Bytes::from(&[1, 2, 3]), icon: None, name: None, display_name: None, @@ -838,7 +839,7 @@ mod test { creation_time: 123, use_counter: false, algorithm: -7, - key: Key::WrappedKey(Bytes::from_slice(&[1, 2, 3]).unwrap()), + key: Key::WrappedKey(Bytes::from(&[1, 2, 3])), hmac_secret: Some(false), cred_protect: None, use_short_id: None, @@ -865,7 +866,7 @@ mod test { let between = Uniform::from(0..(N + 1)); let n = between.sample(&mut OsRng); - bytes.resize_default(n).unwrap(); + bytes.resize_zero(n).unwrap(); OsRng.fill_bytes(&mut bytes); bytes @@ -1079,7 +1080,7 @@ mod test { #[test] fn max_credential_id() { let rp_id: String<256> = core::iter::repeat_n('?', 256).collect(); - let key = Bytes::from_slice(&[u8::MAX; 128]).unwrap(); + let key = Bytes::from(&[u8::MAX; 128]); let credential = StrippedCredential { ctap: CtapVersion::Fido21Pre, creation_time: u32::MAX, @@ -1160,8 +1161,8 @@ mod test { fn inner(&self) -> PublicKeyCredentialRpEntity { PublicKeyCredentialRpEntity { - id: self.id.into(), - name: self.name.map(From::from), + id: self.id.try_into().unwrap(), + name: self.name.map(|n| n.try_into().unwrap()), icon: None, } } @@ -1225,10 +1226,10 @@ mod test { fn inner(&self) -> PublicKeyCredentialUserEntity { PublicKeyCredentialUserEntity { - id: Bytes::from_slice(self.id).unwrap(), - icon: self.icon.map(From::from), - name: self.name.map(From::from), - display_name: self.display_name.map(From::from), + id: Bytes::try_from(self.id).unwrap(), + icon: self.icon.map(|v| v.try_into().unwrap()), + name: self.name.map(|v| v.try_into().unwrap()), + display_name: self.display_name.map(|v| v.try_into().unwrap()), } } } @@ -1300,7 +1301,7 @@ mod test { " ); - let credential = FullCredential::deserialize(&Bytes::from_slice(&data).unwrap()).unwrap(); + let credential = FullCredential::deserialize(&Bytes::from(&data)).unwrap(); assert!(matches!(credential.ctap, CtapVersion::Fido21Pre)); assert_eq!(credential.nonce, &hex!("F62CA01ED181A3D03D561FC7")); assert_eq!( @@ -1309,7 +1310,7 @@ mod test { rp: Rp { format: SerializationFormat::Long, inner: PublicKeyCredentialRpEntity { - id: "webauthn.io".into(), + id: "webauthn.io".try_into().unwrap(), name: None, icon: None, }, @@ -1317,9 +1318,9 @@ mod test { user: User { format: SerializationFormat::Long, inner: PublicKeyCredentialUserEntity { - id: Bytes::from_slice(&hex!("6447567A644445")).unwrap(), + id: Bytes::from(&hex!("6447567A644445")), icon: None, - name: Some("test1".into()), + name: Some("test1".try_into().unwrap()), display_name: None, }, }, diff --git a/src/ctap1.rs b/src/ctap1.rs index b472a4e..50e4d0c 100644 --- a/src/ctap1.rs +++ b/src/ctap1.rs @@ -1,9 +1,7 @@ //! The `ctap_types::ctap1::Authenticator` implementation. -use ctap_types::{ - ctap1::{authenticate, register, Authenticator, ControlByte, Error, Result}, - heapless_bytes::Bytes, -}; +use ctap_types::ctap1::{authenticate, register, Authenticator, ControlByte, Error, Result}; +use heapless_bytes::Bytes; use serde_bytes::ByteArray; use trussed_core::{ @@ -71,9 +69,7 @@ impl Authenticator for crate::Authenti syscall!(self.trussed.delete(private_key)); let key = Key::WrappedKey( - wrapped_key - .to_bytes() - .map_err(|_| Error::UnspecifiedCheckingError)?, + Bytes::try_from(&*wrapped_key).map_err(|_| Error::UnspecifiedCheckingError)?, ); let nonce = ByteArray::new(self.nonce()); @@ -124,14 +120,15 @@ impl Authenticator for crate::Authenti (Some((key, cert)), _aaguid) => { info!("aaguid: {}", hex_str!(&_aaguid)); ( - syscall!(self.trussed.sign( - Mechanism::P256, - key, - &commitment, - SignatureSerialization::Asn1Der - )) - .signature - .to_bytes() + Bytes::try_from( + &*syscall!(self.trussed.sign( + Mechanism::P256, + key, + &commitment, + SignatureSerialization::Asn1Der + )) + .signature, + ) .unwrap(), cert, ) @@ -226,14 +223,15 @@ impl Authenticator for crate::Authenti .unwrap(); commitment.extend_from_slice(auth.challenge).unwrap(); - let signature = syscall!(self.trussed.sign( - Mechanism::P256, - key, - &commitment, - SignatureSerialization::Asn1Der - )) - .signature - .to_bytes() + let signature = Bytes::try_from( + &*syscall!(self.trussed.sign( + Mechanism::P256, + key, + &commitment, + SignatureSerialization::Asn1Der + )) + .signature, + ) .unwrap(); Ok(authenticate::Response { diff --git a/src/ctap2.rs b/src/ctap2.rs index d30a443..1081079 100644 --- a/src/ctap2.rs +++ b/src/ctap2.rs @@ -96,7 +96,7 @@ impl Authenticator for crate::Authenti let mut response = ctap2::get_info::Response::default(); response.versions = versions; response.extensions = Some(extensions); - response.aaguid = Bytes::from_slice(&aaguid).unwrap(); + response.aaguid = Bytes::from(&aaguid); response.options = Some(options); response.transports = Some(transports); // 1200 @@ -293,7 +293,7 @@ impl Authenticator for crate::Authenti // Turns out it's size 92 (enum serialization not optimized yet...) // let mut wrapped_key = Bytes::<60>::new(); // wrapped_key.extend_from_slice(&wrapped_key_msg).unwrap(); - Key::WrappedKey(wrapped_key.to_bytes().map_err(|_| Error::Other)?) + Key::WrappedKey(Bytes::try_from(&*wrapped_key).map_err(|_| Error::Other)?) } }; @@ -450,7 +450,7 @@ impl Authenticator for crate::Authenti attestation_algorithm.sign(&mut self.trussed, attestation_key, &commitment); let packed = PackedAttestationStatement { alg: attestation_algorithm.into(), - sig: signature.to_bytes().map_err(|_| Error::Other)?, + sig: Bytes::try_from(&*signature).map_err(|_| Error::Other)?, x5c: attestation_maybe.as_ref().map(|attestation| { // See: https://www.w3.org/TR/webauthn-2/#sctn-packed-attestation-cert-requirements let cert = attestation.1.clone(); @@ -900,11 +900,15 @@ impl Authenticator for crate::Authenti fn vendor(&mut self, op: VendorOperation) -> Result<()> { info_now!("hello VO {:?}", &op); match op.into() { - 0x79 => syscall!(self.trussed.debug_dump_store()), - _ => return Err(Error::InvalidCommand), - }; - - Ok(()) + 0x79 => { + #[allow(deprecated)] + { + syscall!(self.trussed.debug_dump_store()); + } + Err(Error::InvalidCommand) + } + _ => Err(Error::InvalidCommand), + } } #[inline(never)] @@ -1249,7 +1253,7 @@ impl crate::Authenticator { return Err(Error::PinPolicyViolation); } - pin.resize_default(pin_length).unwrap(); + pin.resize_zero(pin_length).unwrap(); Ok(pin) } @@ -1286,7 +1290,7 @@ impl crate::Authenticator { // check pinAuth let mut data: Bytes<{ sizes::MAX_CREDENTIAL_ID_LENGTH_PLUS_256 }> = - Bytes::from_slice(&[parameters.sub_command as u8]).unwrap(); + Bytes::from(&[parameters.sub_command as u8]); let len = 1 + match parameters.sub_command { Subcommand::EnumerateCredentialsBegin | Subcommand::DeleteCredential @@ -1468,7 +1472,7 @@ impl crate::Authenticator { let cred_random = syscall!(self.trussed.derive_key( Mechanism::HmacSha256, credential_key, - Some(Bytes::from_slice(&[get_assertion_state.uv_performed as u8]).unwrap()), + Some(Bytes::from(&[get_assertion_state.uv_performed as u8])), StorageAttributes::new().set_persistence(Location::Volatile) )) .key; @@ -1515,7 +1519,7 @@ impl crate::Authenticator { shared_secret.delete(&mut self.trussed); - output.hmac_secret = Some(Bytes::from_slice(&output_enc).unwrap()); + output.hmac_secret = Some(Bytes::try_from(&*output_enc).unwrap()); } if extensions.third_party_payment.unwrap_or_default() { @@ -1619,10 +1623,8 @@ impl crate::Authenticator { let signing_algorithm = SigningAlgorithm::try_from(credential.algorithm()).map_err(|_| Error::Other)?; - let signature = signing_algorithm - .sign(&mut self.trussed, key, &commitment) - .to_bytes() - .unwrap(); + let signature = + Bytes::try_from(&*signing_algorithm.sign(&mut self.trussed, key, &commitment)).unwrap(); // select preferred format or skip attestation statement let att_stmt_fmt = data @@ -1645,7 +1647,7 @@ impl crate::Authenticator { &commitment, ); ( - signature.to_bytes().map_err(|_| Error::Other)?, + Bytes::try_from(&*signature).map_err(|_| Error::Other)?, signing_algorithm.into(), ) } else { diff --git a/src/ctap2/pin.rs b/src/ctap2/pin.rs index a06f223..096d6a3 100644 --- a/src/ctap2/pin.rs +++ b/src/ctap2/pin.rs @@ -106,7 +106,7 @@ impl PinTokenMut<'_, T> { // in spec: encrypt(..., pinUvAuthToken) pub fn encrypt(&mut self, shared_secret: &SharedSecret) -> Result> { let token = shared_secret.wrap(self.trussed, self.pin_token.key_id); - Bytes::from_slice(&token).map_err(|_| Error::Other) + Bytes::try_from(&*token).map_err(|_| Error::Other) } } @@ -119,7 +119,7 @@ struct Rp { impl Rp { fn new(trussed: &mut T, id: String<256>) -> Self { let hash = - syscall!(trussed.hash(Mechanism::Sha256, Message::from_slice(id.as_ref()).unwrap())) + syscall!(trussed.hash(Mechanism::Sha256, Message::try_from(id.as_bytes()).unwrap())) .hash .as_slice() .try_into() @@ -366,7 +366,7 @@ impl<'a, T: CryptoClient + HkdfClient + HmacSha256 + P256> PinProtocol<'a, T> { // operations. For simplicity, we store two separate keys instead. fn kdf_v2(&mut self, input: KeyId) -> Option { fn hkdf(trussed: &mut T, okm: OkmId, info: &[u8]) -> Option { - let info = Message::from_slice(info).ok()?; + let info = Message::try_from(info).ok()?; try_syscall!(trussed.hkdf_expand(okm, info, 32, Location::Volatile)) .ok() .map(|reply| reply.key) @@ -420,11 +420,10 @@ impl SharedSecret { fn generate_iv(&self, trussed: &mut T) -> ShortData { match self { - Self::V1 { .. } => ShortData::from_slice(&[0; 16]).unwrap(), - Self::V2 { .. } => syscall!(trussed.random_bytes(16)) - .bytes - .try_convert_into() - .unwrap(), + Self::V1 { .. } => ShortData::from(&[0; 16]), + Self::V2 { .. } => { + ShortData::try_from(&*syscall!(trussed.random_bytes(16)).bytes).unwrap() + } } } @@ -436,7 +435,10 @@ impl SharedSecret { syscall!(trussed.encrypt(Mechanism::Aes256Cbc, key_id, data, &[], Some(iv.clone()))) .ciphertext; if matches!(self, Self::V2 { .. }) { - ciphertext.insert_slice_at(&iv, 0).unwrap(); + let ciphertext_len = ciphertext.len(); + ciphertext.resize_zero(iv.len() + ciphertext_len).unwrap(); + ciphertext.copy_within(..ciphertext_len, iv.len()); + ciphertext[..iv.len()].copy_from_slice(&iv); } ciphertext } @@ -454,7 +456,10 @@ impl SharedSecret { )) .wrapped_key; if matches!(self, Self::V2 { .. }) { - wrapped_key.insert_slice_at(&iv, 0).unwrap(); + let wrapped_key_len = wrapped_key.len(); + wrapped_key.resize_zero(iv.len() + wrapped_key_len).unwrap(); + wrapped_key.copy_within(..wrapped_key_len, iv.len()); + wrapped_key[..iv.len()].copy_from_slice(&iv); } wrapped_key } diff --git a/src/dispatch.rs b/src/dispatch.rs index 50e4c96..92e6b69 100644 --- a/src/dispatch.rs +++ b/src/dispatch.rs @@ -8,7 +8,8 @@ use crate::msp; use crate::{Authenticator, TrussedRequirements, UserPresence}; use ctap_types::{ctap1, ctap2}; -use iso7816::{command::CommandView, Data, Status}; +use heapless::VecView; +use iso7816::{command::CommandView, Status}; impl iso7816::App for Authenticator where @@ -21,10 +22,10 @@ where #[inline(never)] /// Deserialize U2F, call authenticator, serialize response *Result*. -fn handle_ctap1_from_hid( +fn handle_ctap1_from_hid( authenticator: &mut Authenticator, data: &[u8], - response: &mut Data, + response: &mut VecView, ) where T: TrussedRequirements, UP: UserPresence, @@ -65,10 +66,10 @@ fn handle_ctap1_from_hid( #[inline(never)] /// Deserialize CBOR, call authenticator, serialize response *Result*. -fn handle_ctap2( +fn handle_ctap2( authenticator: &mut Authenticator, data: &[u8], - response: &mut Data, + response: &mut VecView, ) where T: TrussedRequirements, UP: UserPresence, @@ -89,10 +90,10 @@ fn handle_ctap2( } #[inline(never)] -fn try_handle_ctap1( +fn try_handle_ctap1( authenticator: &mut Authenticator, command: CommandView<'_>, - response: &mut Data, + response: &mut VecView, ) -> Result<(), Status> where T: TrussedRequirements, @@ -124,10 +125,10 @@ where } #[inline(never)] -fn try_handle_ctap2( +fn try_handle_ctap2( authenticator: &mut Authenticator, data: &[u8], - response: &mut Data, + response: &mut VecView, ) -> Result<(), u8> where T: TrussedRequirements, diff --git a/src/dispatch/apdu.rs b/src/dispatch/apdu.rs index f572766..143237d 100644 --- a/src/dispatch/apdu.rs +++ b/src/dispatch/apdu.rs @@ -1,6 +1,7 @@ use apdu_app::Interface; use ctap_types::{serde::error::Error as SerdeError, Error}; -use iso7816::{command::CommandView, Data, Status}; +use heapless::VecView; +use iso7816::{command::CommandView, Status}; use crate::{Authenticator, TrussedRequirements, UserPresence}; @@ -21,7 +22,7 @@ impl From for Error { } } -impl apdu_app::App for Authenticator +impl apdu_app::App for Authenticator where UP: UserPresence, T: TrussedRequirements, @@ -30,7 +31,7 @@ where &mut self, interface: Interface, _: CommandView<'_>, - reply: &mut Data, + reply: &mut VecView, ) -> apdu_app::Result { // FIDO-over-CCID does not seem to officially be a thing; we don't support it. // If we would, need to review the following cases catering to semi-documented U2F legacy. @@ -48,7 +49,7 @@ where &mut self, interface: Interface, apdu: CommandView<'_>, - response: &mut Data, + response: &mut VecView, ) -> apdu_app::Result { // FIDO-over-CCID does not seem to officially be a thing; we don't support it. // If we would, need to review the following cases catering to semi-documented U2F legacy. @@ -77,7 +78,7 @@ where super::handle_ctap2(self, apdu.data(), response) } Ok(ctaphid_app::Command::Msg) => super::try_handle_ctap1(self, apdu, response)?, - Ok(ctaphid_app::Command::Deselect) => apdu_app::App::::deselect(self), + Ok(ctaphid_app::Command::Deselect) => apdu_app::App::deselect(self), _ => { info!("Unsupported ins for fido app {:02x}", instruction); return Err(iso7816::Status::InstructionNotSupportedOrInvalid); diff --git a/src/dispatch/ctaphid.rs b/src/dispatch/ctaphid.rs index 34e9cc0..b2c1844 100644 --- a/src/dispatch/ctaphid.rs +++ b/src/dispatch/ctaphid.rs @@ -1,12 +1,12 @@ use ctaphid_app::{App, Command, Error}; -use heapless_bytes::Bytes; +use heapless_bytes::BytesView; use trussed_core::InterruptFlag; #[allow(unused_imports)] use crate::msp; use crate::{Authenticator, TrussedRequirements, UserPresence}; -impl App<'static, N> for Authenticator +impl App<'static> for Authenticator where UP: UserPresence, T: TrussedRequirements, @@ -20,7 +20,7 @@ where &mut self, command: Command, request: &[u8], - response: &mut Bytes, + response: &mut BytesView, ) -> Result<(), Error> { debug_now!( "ctaphid-dispatch: remaining stack: {} bytes", @@ -35,8 +35,8 @@ where // info_now!("request: "); // blocking::dump_hex(request, request.len()); match command { - Command::Cbor => super::handle_ctap2(self, request, response), - Command::Msg => super::handle_ctap1_from_hid(self, request, response), + Command::Cbor => super::handle_ctap2(self, request, response.as_mut()), + Command::Msg => super::handle_ctap1_from_hid(self, request, response.as_mut()), _ => { debug_now!("ctaphid trying to dispatch {:?}", command); } diff --git a/tests/virt/pipe.rs b/tests/virt/pipe.rs index 5d1b3ae..b360742 100644 --- a/tests/virt/pipe.rs +++ b/tests/virt/pipe.rs @@ -369,7 +369,7 @@ impl<'a, const N: usize> Pipe<'a, N> { } match self.interchange.request(( request.command, - Bytes::from_slice(&self.buffer[..request.length as usize]).unwrap(), + Bytes::try_from(&self.buffer[..request.length as usize]).unwrap(), )) { Ok(_) => { self.state = State::WaitingOnAuthenticator(request);