Skip to content

Commit 2affd20

Browse files
Update to heapless 0.9
1 parent 01a2653 commit 2affd20

File tree

9 files changed

+95
-77
lines changed

9 files changed

+95
-77
lines changed

Cargo.toml

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ description = "FIDO authenticator Trussed app"
1111
[dependencies]
1212
cbor-smol = { version = "0.5" }
1313
ctap-types = { version = "0.4", features = ["get-info-full", "large-blobs", "third-party-payment"] }
14-
cosey = "0.3"
14+
cosey = "0.4"
1515
delog = "0.1.0"
16-
heapless = "0.7"
17-
heapless-bytes = "0.3"
16+
heapless = "0.9"
17+
heapless-bytes = { version = "0.5", features = ["heapless-0.9"]}
1818
littlefs2-core = "0.1"
1919
serde = { version = "1.0", default-features = false }
2020
serde_bytes = { version = "0.11.14", default-features = false }
@@ -27,7 +27,7 @@ trussed-chunked = { version = "0.2.0", optional = true }
2727

2828
apdu-app = { version = "0.1", optional = true }
2929
ctaphid-app = { version = "0.1.0-rc.1", optional = true }
30-
iso7816 = { version = "0.1.2", optional = true }
30+
iso7816 = { version = "0.2", optional = true }
3131

3232
[features]
3333
dispatch = ["apdu-dispatch", "ctaphid-dispatch", "iso7816"]
@@ -61,7 +61,7 @@ hex-literal = "0.4.1"
6161
hmac = "0.12.1"
6262
interchange = "0.3.0"
6363
itertools = "0.14.0"
64-
littlefs2 = "0.6.0"
64+
littlefs2 = "0.7.0"
6565
log = "0.4.21"
6666
p256 = { version = "0.13.2", features = ["ecdh"] }
6767
rand = "0.8.4"
@@ -78,10 +78,24 @@ x509-parser = "0.16.0"
7878
features = ["dispatch"]
7979

8080
[patch.crates-io]
81-
admin-app = { git = "https://github.com/Nitrokey/admin-app.git", tag = "v0.1.0-nitrokey.20" }
82-
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "024e0eca5fb7dbd2457831f7c7bffe4341e08775" }
83-
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "7922d67e9637a87e5625aaff9e5111f0d4ec0346" }
84-
trussed-usbip = { git = "https://github.com/trussed-dev/pc-usbip-runner.git", rev = "504674453c9573a30aa2f155101df49eb2af1ba7" }
81+
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" }
82+
trussed-core = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" }
83+
trussed-manage = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" }
84+
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" }
85+
trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" }
86+
87+
88+
littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "e9d3a1ca98f80e92cd20ee9b94707067810b9036" }
89+
littlefs2-core = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "e9d3a1ca98f80e92cd20ee9b94707067810b9036" }
90+
littlefs2-sys = { git = "https://github.com/trussed-dev/littlefs2-sys", rev = "v0.3.1-nitrokey.1" }
91+
salty = { git = "https://github.com/ycrypto/salty.git", rev = "ae17f04ec965913e08032d266f6a47c001031f06" }
92+
ctaphid-app = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "f11fdcbc62d06b8be23e6cbae21bcfefd52c0661" }
93+
ctaphid-dispatch = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "f11fdcbc62d06b8be23e6cbae21bcfefd52c0661" }
94+
apdu-app = { git = "https://github.com/trussed-dev/apdu-dispatch.git", rev = "931c4269d1d293954fae2012d809e9663cd2cb7e" }
95+
admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "2b3f758016afbc56535d8a65f98a067d5a2d843e" }
96+
trussed-usbip = { git = "https://github.com/trussed-dev/pc-usbip-runner.git", rev = "0ff1992f15c273c87e0607384e3dd94d341b721e" }
97+
usbd-ctaphid = { git = "https://github.com/trussed-dev/usbd-ctaphid.git", rev = "94881f83a6b4229a7a3187a5dd7b3ccf6eb6dc00" }
98+
ctap-types = { git = "https://github.com/trussed-dev/ctap-types", rev = "cff44662b48088511fa8ae30557c457f8252f220"}
8599

86100
[profile.test]
87101
opt-level = 2

fuzz/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ doc = false
2424
bench = false
2525

2626
[patch.crates-io]
27-
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "6bba8fde36d05c0227769eb63345744e87d84b2b" }
28-
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "1e1ca03a3a62ea9b802f4070ea4bce002eeb4bec" }
27+
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" }
28+
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "eff09d1613641531630d962f81136f64f3dd2716" }

src/credential.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,14 @@ impl Credential {
202202
fn deserialize_bytes<E: serde::de::Error, const N: usize>(
203203
s: &[u8],
204204
) -> core::result::Result<Bytes<N>, E> {
205-
Bytes::from_slice(s).map_err(|_| E::invalid_length(s.len(), &"a fixed-size sequence of bytes"))
205+
Bytes::try_from(s).map_err(|_| E::invalid_length(s.len(), &"a fixed-size sequence of bytes"))
206206
}
207207

208208
fn deserialize_str<E: serde::de::Error, const N: usize>(
209209
s: &str,
210210
) -> core::result::Result<String<N>, E> {
211-
Ok(s.into())
211+
s.try_into()
212+
.map_err(|_| E::custom("Serialized string doesn't fit "))
212213
}
213214

214215
#[derive(Clone, Copy, Debug, PartialEq)]

src/ctap1.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
//! The `ctap_types::ctap1::Authenticator` implementation.
22
3-
use ctap_types::{
4-
ctap1::{authenticate, register, Authenticator, ControlByte, Error, Result},
5-
heapless_bytes::Bytes,
6-
};
3+
use ctap_types::ctap1::{authenticate, register, Authenticator, ControlByte, Error, Result};
4+
use heapless_bytes::Bytes;
75
use serde_bytes::ByteArray;
86

97
use trussed_core::{
@@ -71,9 +69,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
7169
syscall!(self.trussed.delete(private_key));
7270

7371
let key = Key::WrappedKey(
74-
wrapped_key
75-
.to_bytes()
76-
.map_err(|_| Error::UnspecifiedCheckingError)?,
72+
Bytes::try_from(&*wrapped_key).map_err(|_| Error::UnspecifiedCheckingError)?,
7773
);
7874
let nonce = ByteArray::new(self.nonce());
7975

@@ -124,14 +120,15 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
124120
(Some((key, cert)), _aaguid) => {
125121
info!("aaguid: {}", hex_str!(&_aaguid));
126122
(
127-
syscall!(self.trussed.sign(
128-
Mechanism::P256,
129-
key,
130-
&commitment,
131-
SignatureSerialization::Asn1Der
132-
))
133-
.signature
134-
.to_bytes()
123+
Bytes::try_from(
124+
&*syscall!(self.trussed.sign(
125+
Mechanism::P256,
126+
key,
127+
&commitment,
128+
SignatureSerialization::Asn1Der
129+
))
130+
.signature,
131+
)
135132
.unwrap(),
136133
cert,
137134
)
@@ -226,14 +223,15 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
226223
.unwrap();
227224
commitment.extend_from_slice(auth.challenge).unwrap();
228225

229-
let signature = syscall!(self.trussed.sign(
230-
Mechanism::P256,
231-
key,
232-
&commitment,
233-
SignatureSerialization::Asn1Der
234-
))
235-
.signature
236-
.to_bytes()
226+
let signature = Bytes::try_from(
227+
&*syscall!(self.trussed.sign(
228+
Mechanism::P256,
229+
key,
230+
&commitment,
231+
SignatureSerialization::Asn1Der
232+
))
233+
.signature,
234+
)
237235
.unwrap();
238236

239237
Ok(authenticate::Response {

src/ctap2.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
9696
let mut response = ctap2::get_info::Response::default();
9797
response.versions = versions;
9898
response.extensions = Some(extensions);
99-
response.aaguid = Bytes::from_slice(&aaguid).unwrap();
99+
response.aaguid = Bytes::try_from(&aaguid).unwrap();
100100
response.options = Some(options);
101101
response.transports = Some(transports);
102102
// 1200
@@ -293,7 +293,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
293293
// Turns out it's size 92 (enum serialization not optimized yet...)
294294
// let mut wrapped_key = Bytes::<60>::new();
295295
// wrapped_key.extend_from_slice(&wrapped_key_msg).unwrap();
296-
Key::WrappedKey(wrapped_key.to_bytes().map_err(|_| Error::Other)?)
296+
Key::WrappedKey(Bytes::try_from(&*wrapped_key).map_err(|_| Error::Other)?)
297297
}
298298
};
299299

@@ -450,7 +450,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
450450
attestation_algorithm.sign(&mut self.trussed, attestation_key, &commitment);
451451
let packed = PackedAttestationStatement {
452452
alg: attestation_algorithm.into(),
453-
sig: signature.to_bytes().map_err(|_| Error::Other)?,
453+
sig: Bytes::try_from(&*signature).map_err(|_| Error::Other)?,
454454
x5c: attestation_maybe.as_ref().map(|attestation| {
455455
// See: https://www.w3.org/TR/webauthn-2/#sctn-packed-attestation-cert-requirements
456456
let cert = attestation.1.clone();
@@ -1249,7 +1249,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
12491249
return Err(Error::PinPolicyViolation);
12501250
}
12511251

1252-
pin.resize_default(pin_length).unwrap();
1252+
pin.resize_zero(pin_length).unwrap();
12531253

12541254
Ok(pin)
12551255
}
@@ -1286,7 +1286,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
12861286

12871287
// check pinAuth
12881288
let mut data: Bytes<{ sizes::MAX_CREDENTIAL_ID_LENGTH_PLUS_256 }> =
1289-
Bytes::from_slice(&[parameters.sub_command as u8]).unwrap();
1289+
Bytes::try_from(&[parameters.sub_command as u8]).unwrap();
12901290
let len = 1 + match parameters.sub_command {
12911291
Subcommand::EnumerateCredentialsBegin
12921292
| Subcommand::DeleteCredential
@@ -1468,7 +1468,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
14681468
let cred_random = syscall!(self.trussed.derive_key(
14691469
Mechanism::HmacSha256,
14701470
credential_key,
1471-
Some(Bytes::from_slice(&[get_assertion_state.uv_performed as u8]).unwrap()),
1471+
Some(Bytes::try_from(&[get_assertion_state.uv_performed as u8]).unwrap()),
14721472
StorageAttributes::new().set_persistence(Location::Volatile)
14731473
))
14741474
.key;
@@ -1515,7 +1515,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
15151515

15161516
shared_secret.delete(&mut self.trussed);
15171517

1518-
output.hmac_secret = Some(Bytes::from_slice(&output_enc).unwrap());
1518+
output.hmac_secret = Some(Bytes::try_from(&*output_enc).unwrap());
15191519
}
15201520

15211521
if extensions.third_party_payment.unwrap_or_default() {
@@ -1619,10 +1619,8 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
16191619

16201620
let signing_algorithm =
16211621
SigningAlgorithm::try_from(credential.algorithm()).map_err(|_| Error::Other)?;
1622-
let signature = signing_algorithm
1623-
.sign(&mut self.trussed, key, &commitment)
1624-
.to_bytes()
1625-
.unwrap();
1622+
let signature =
1623+
Bytes::try_from(&*signing_algorithm.sign(&mut self.trussed, key, &commitment)).unwrap();
16261624

16271625
// select preferred format or skip attestation statement
16281626
let att_stmt_fmt = data
@@ -1645,7 +1643,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
16451643
&commitment,
16461644
);
16471645
(
1648-
signature.to_bytes().map_err(|_| Error::Other)?,
1646+
Bytes::try_from(&*signature).map_err(|_| Error::Other)?,
16491647
signing_algorithm.into(),
16501648
)
16511649
} else {

src/ctap2/pin.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<T: CryptoClient> PinTokenMut<'_, T> {
106106
// in spec: encrypt(..., pinUvAuthToken)
107107
pub fn encrypt(&mut self, shared_secret: &SharedSecret) -> Result<Bytes<48>> {
108108
let token = shared_secret.wrap(self.trussed, self.pin_token.key_id);
109-
Bytes::from_slice(&token).map_err(|_| Error::Other)
109+
Bytes::try_from(&*token).map_err(|_| Error::Other)
110110
}
111111
}
112112

@@ -119,7 +119,7 @@ struct Rp {
119119
impl Rp {
120120
fn new<T: CryptoClient>(trussed: &mut T, id: String<256>) -> Self {
121121
let hash =
122-
syscall!(trussed.hash(Mechanism::Sha256, Message::from_slice(id.as_ref()).unwrap()))
122+
syscall!(trussed.hash(Mechanism::Sha256, Message::try_from(id.as_bytes()).unwrap()))
123123
.hash
124124
.as_slice()
125125
.try_into()
@@ -366,7 +366,7 @@ impl<'a, T: CryptoClient + HkdfClient + HmacSha256 + P256> PinProtocol<'a, T> {
366366
// operations. For simplicity, we store two separate keys instead.
367367
fn kdf_v2(&mut self, input: KeyId) -> Option<SharedSecret> {
368368
fn hkdf<T: HkdfClient>(trussed: &mut T, okm: OkmId, info: &[u8]) -> Option<KeyId> {
369-
let info = Message::from_slice(info).ok()?;
369+
let info = Message::try_from(info).ok()?;
370370
try_syscall!(trussed.hkdf_expand(okm, info, 32, Location::Volatile))
371371
.ok()
372372
.map(|reply| reply.key)
@@ -420,11 +420,10 @@ impl SharedSecret {
420420

421421
fn generate_iv<T: CryptoClient>(&self, trussed: &mut T) -> ShortData {
422422
match self {
423-
Self::V1 { .. } => ShortData::from_slice(&[0; 16]).unwrap(),
424-
Self::V2 { .. } => syscall!(trussed.random_bytes(16))
425-
.bytes
426-
.try_convert_into()
427-
.unwrap(),
423+
Self::V1 { .. } => ShortData::try_from(&[0; 16]).unwrap(),
424+
Self::V2 { .. } => {
425+
ShortData::try_from(&*syscall!(trussed.random_bytes(16)).bytes).unwrap()
426+
}
428427
}
429428
}
430429

@@ -436,7 +435,10 @@ impl SharedSecret {
436435
syscall!(trussed.encrypt(Mechanism::Aes256Cbc, key_id, data, &[], Some(iv.clone())))
437436
.ciphertext;
438437
if matches!(self, Self::V2 { .. }) {
439-
ciphertext.insert_slice_at(&iv, 0).unwrap();
438+
let ciphertext_len = ciphertext.len();
439+
ciphertext.resize_zero(iv.len() + ciphertext_len).unwrap();
440+
ciphertext.copy_within(..ciphertext_len, iv.len());
441+
ciphertext[..iv.len()].copy_from_slice(&iv);
440442
}
441443
ciphertext
442444
}
@@ -454,7 +456,10 @@ impl SharedSecret {
454456
))
455457
.wrapped_key;
456458
if matches!(self, Self::V2 { .. }) {
457-
wrapped_key.insert_slice_at(&iv, 0).unwrap();
459+
let wrapped_key_len = wrapped_key.len();
460+
wrapped_key.resize_zero(iv.len() + wrapped_key_len).unwrap();
461+
wrapped_key.copy_within(..wrapped_key_len, iv.len());
462+
wrapped_key[..iv.len()].copy_from_slice(&iv);
458463
}
459464
wrapped_key
460465
}

src/dispatch.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use crate::msp;
88
use crate::{Authenticator, TrussedRequirements, UserPresence};
99

1010
use ctap_types::{ctap1, ctap2};
11-
use iso7816::{command::CommandView, Data, Status};
11+
use heapless::VecView;
12+
use iso7816::{command::CommandView, Status};
1213

1314
impl<UP, T> iso7816::App for Authenticator<UP, T>
1415
where
@@ -21,10 +22,10 @@ where
2122

2223
#[inline(never)]
2324
/// Deserialize U2F, call authenticator, serialize response *Result*.
24-
fn handle_ctap1_from_hid<T, UP, const R: usize>(
25+
fn handle_ctap1_from_hid<T, UP>(
2526
authenticator: &mut Authenticator<UP, T>,
2627
data: &[u8],
27-
response: &mut Data<R>,
28+
response: &mut VecView<u8>,
2829
) where
2930
T: TrussedRequirements,
3031
UP: UserPresence,
@@ -65,10 +66,10 @@ fn handle_ctap1_from_hid<T, UP, const R: usize>(
6566

6667
#[inline(never)]
6768
/// Deserialize CBOR, call authenticator, serialize response *Result*.
68-
fn handle_ctap2<T, UP, const R: usize>(
69+
fn handle_ctap2<T, UP>(
6970
authenticator: &mut Authenticator<UP, T>,
7071
data: &[u8],
71-
response: &mut Data<R>,
72+
response: &mut VecView<u8>,
7273
) where
7374
T: TrussedRequirements,
7475
UP: UserPresence,
@@ -89,10 +90,10 @@ fn handle_ctap2<T, UP, const R: usize>(
8990
}
9091

9192
#[inline(never)]
92-
fn try_handle_ctap1<T, UP, const R: usize>(
93+
fn try_handle_ctap1<T, UP>(
9394
authenticator: &mut Authenticator<UP, T>,
9495
command: CommandView<'_>,
95-
response: &mut Data<R>,
96+
response: &mut VecView<u8>,
9697
) -> Result<(), Status>
9798
where
9899
T: TrussedRequirements,
@@ -124,10 +125,10 @@ where
124125
}
125126

126127
#[inline(never)]
127-
fn try_handle_ctap2<T, UP, const R: usize>(
128+
fn try_handle_ctap2<T, UP>(
128129
authenticator: &mut Authenticator<UP, T>,
129130
data: &[u8],
130-
response: &mut Data<R>,
131+
response: &mut VecView<u8>,
131132
) -> Result<(), u8>
132133
where
133134
T: TrussedRequirements,

0 commit comments

Comments
 (0)