Skip to content

Commit 6b9e316

Browse files
Improve byte array serialization
Per default, byte arrays are serialized inefficiently by serde. serde-byte-array provides a wrapper type with a more efficient serialization format. Fixes #11
1 parent 97eeb4c commit 6b9e316

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ description = "Authentication extension and backend for Trussed"
1212

1313
[dependencies]
1414
serde = { version = "1", default-features = false }
15+
serde-byte-array = "0.1.0"
1516
sha2 = { version = "0.10.6", default-features = false }
1617
subtle = { version = "2.4.1", default-features = false }
1718
trussed = { git = "https://github.com/trussed-dev/trussed", rev = "1c55b3b2dd6a9e1cfc55758635baf0d0bbf387d1", features = ["serde-extensions"] }

src/backend/data.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use core::ops::Deref;
55

66
use serde::{Deserialize, Serialize};
7+
use serde_byte_array::ByteArray;
78
use sha2::{Digest as _, Sha256};
89
use subtle::ConstantTimeEq as _;
910
use trussed::{
@@ -19,8 +20,8 @@ const SIZE: usize = 256;
1920
const SALT_LEN: usize = 16;
2021
const HASH_LEN: usize = 32;
2122

22-
type Salt = [u8; SALT_LEN];
23-
type Hash = [u8; HASH_LEN];
23+
type Salt = ByteArray<SALT_LEN>;
24+
type Hash = ByteArray<HASH_LEN>;
2425

2526
#[derive(Debug, Deserialize, Serialize)]
2627
pub(crate) struct PinData {
@@ -37,7 +38,7 @@ impl PinData {
3738
R: CryptoRng + RngCore,
3839
{
3940
let mut salt = Salt::default();
40-
rng.fill_bytes(&mut salt);
41+
rng.fill_bytes(salt.as_mut());
4142
let hash = hash(id, pin, &salt);
4243
Self {
4344
id,
@@ -111,7 +112,10 @@ impl<'a> PinDataMut<'a> {
111112
if self.is_blocked() {
112113
return false;
113114
}
114-
let success = hash(self.id, pin, &self.salt).ct_eq(&self.hash).into();
115+
let success = hash(self.id, pin, &self.salt)
116+
.as_ref()
117+
.ct_eq(self.hash.as_ref())
118+
.into();
115119
if let Some(retries) = &mut self.data.retries {
116120
if success {
117121
if retries.reset() {
@@ -169,8 +173,8 @@ fn hash(id: PinId, pin: &Pin, salt: &Salt) -> Hash {
169173
digest.update([u8::from(id)]);
170174
digest.update([pin_len(pin)]);
171175
digest.update(pin);
172-
digest.update(salt);
173-
digest.finalize().into()
176+
digest.update(salt.as_ref());
177+
Hash::new(digest.finalize().into())
174178
}
175179

176180
fn pin_len(pin: &Pin) -> u8 {
@@ -191,10 +195,19 @@ mod tests {
191195
max: u8::MAX,
192196
left: u8::MAX,
193197
}),
194-
salt: [u8::MAX; SALT_LEN],
195-
hash: [u8::MAX; HASH_LEN],
198+
salt: [u8::MAX; SALT_LEN].into(),
199+
hash: [u8::MAX; HASH_LEN].into(),
196200
};
197201
let serialized = trussed::cbor_serialize_bytes::<_, 1024>(&data).unwrap();
198202
assert!(serialized.len() <= SIZE);
199203
}
204+
205+
#[test]
206+
#[allow(clippy::unwrap_used)]
207+
fn test_salt_size() {
208+
// We allow one byte overhead for byte array serialization
209+
let salt = Salt::from([u8::MAX; SALT_LEN]);
210+
let serialized = trussed::cbor_serialize_bytes::<_, 1024>(&salt).unwrap();
211+
assert!(serialized.len() <= SALT_LEN + 1, "{}", serialized.len());
212+
}
200213
}

0 commit comments

Comments
 (0)