Skip to content

Commit df2867d

Browse files
Remove serde trait implementations for requests and replies
Implementing Serialize and Deserialize for the request and reply structs leaks implementation details, especially when using serde_indexed. This patch removes these implementations for the request and reply structs and also for some other types that presumably only had them because they were used in these structs and that are not serialized or deserialized anywhere in the Trussed ecosystem. To make it easier to store encrypted data – where previously reply::Encrypt could be used direcly – this patch adds an EncryptedData struct that implemente Serialize and Deserialize. Fixes: #183
1 parent 1b62220 commit df2867d

File tree

5 files changed

+72
-28
lines changed

5 files changed

+72
-28
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4646
- Add `nonce` argument to `wrap_key` and `unwrap_key` syscalls.
4747
- Use nonce as IV for Aes256Cbc mechanism.
4848
- Updated `cbor-smol` to 0.5.0.
49+
- Removed `serde::{Deserialize, Serialize}` implementations for the API request
50+
and reply structs, `types::{consent::{Error, Level}, reboot::To, StorageAttributes,
51+
KeySerialization, SignatureSerialization}`.
4952

5053
### Fixed
5154

core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ littlefs2-core.workspace = true
1414
postcard.workspace = true
1515
rand_core.workspace = true
1616
serde.workspace = true
17-
1817
serde-indexed = "0.1"
1918

2019
[features]

core/src/api/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ macro_rules! impl_request {
7070
)*)
7171
=> {$(
7272
$(#[$attr])?
73-
#[derive(Clone, Eq, PartialEq, Debug, serde_indexed::DeserializeIndexed, serde_indexed::SerializeIndexed)]
73+
#[derive(Clone, Eq, PartialEq, Debug)]
7474
pub struct $request {
7575
$(
7676
pub $name: $type,
@@ -109,7 +109,7 @@ macro_rules! impl_reply {
109109
=> {$(
110110

111111
$(#[$attr])?
112-
#[derive(Clone, Eq, PartialEq, Debug, serde_indexed::DeserializeIndexed, serde_indexed::SerializeIndexed)]
112+
#[derive(Clone, Eq, PartialEq, Debug)]
113113
pub struct $reply {
114114
$(
115115
pub $name: $type,

core/src/types.rs

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ pub use heapless::String;
77
pub use heapless_bytes::Bytes;
88
pub use littlefs2_core::{DirEntry, Metadata, PathBuf};
99

10+
use crate::api::{reply, request};
1011
use crate::config::{
1112
MAX_KEY_MATERIAL_LENGTH, MAX_MEDIUM_DATA_LENGTH, MAX_MESSAGE_LENGTH, MAX_SHORT_DATA_LENGTH,
1213
MAX_SIGNATURE_LENGTH, MAX_USER_ATTRIBUTE_LENGTH,
1314
};
1415

1516
pub mod consent {
16-
use serde::{Deserialize, Serialize};
17-
18-
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
17+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
1918
pub enum Level {
2019
/// There is no user present
2120
None,
@@ -27,7 +26,7 @@ pub mod consent {
2726
Strong,
2827
}
2928

30-
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
29+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
3130
pub enum Error {
3231
FailedToInterrupt,
3332
Interrupted,
@@ -39,9 +38,7 @@ pub mod consent {
3938
}
4039

4140
pub mod reboot {
42-
use serde::{Deserialize, Serialize};
43-
44-
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
41+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
4542
pub enum To {
4643
Application,
4744
ApplicationUpdate,
@@ -240,7 +237,7 @@ pub enum Location {
240237
External,
241238
}
242239

243-
#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
240+
#[derive(Clone, Eq, PartialEq, Debug)]
244241
#[non_exhaustive]
245242
pub struct StorageAttributes {
246243
// each object must have a unique ID
@@ -350,7 +347,7 @@ pub enum Mechanism {
350347
Rsa4096Pkcs1v15,
351348
}
352349

353-
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
350+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
354351
pub enum KeySerialization {
355352
// Asn1Der,
356353
Cose,
@@ -366,10 +363,59 @@ pub enum KeySerialization {
366363
Pkcs8Der,
367364
}
368365

369-
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
366+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
370367
pub enum SignatureSerialization {
371368
Asn1Der,
372369
// Cose,
373370
Raw,
374371
// Sec1,
375372
}
373+
374+
/// Serializable version of [`reply::Encrypt`][].
375+
///
376+
/// Sometimes it is necessary the result of an encryption together with the metadata required for
377+
/// decryption, for example when wrapping keys. This struct stores the data that is returned by
378+
/// the [`request::Encrypt`][] syscall, see [`reply::Encrypt`][], in a serializable format.
379+
#[derive(
380+
Clone, Debug, Eq, PartialEq, serde_indexed::DeserializeIndexed, serde_indexed::SerializeIndexed,
381+
)]
382+
#[non_exhaustive]
383+
pub struct EncryptedData {
384+
pub ciphertext: Message,
385+
pub nonce: ShortData,
386+
pub tag: ShortData,
387+
}
388+
389+
impl EncryptedData {
390+
/// Creates a decryption request to decrypt the stored data.
391+
pub fn decrypt(
392+
self,
393+
mechanism: Mechanism,
394+
key: KeyId,
395+
associated_data: Message,
396+
) -> request::Decrypt {
397+
request::Decrypt {
398+
mechanism,
399+
key,
400+
message: self.ciphertext,
401+
associated_data,
402+
nonce: self.nonce,
403+
tag: self.tag,
404+
}
405+
}
406+
}
407+
408+
impl From<reply::Encrypt> for EncryptedData {
409+
fn from(reply: reply::Encrypt) -> Self {
410+
let reply::Encrypt {
411+
ciphertext,
412+
nonce,
413+
tag,
414+
} = reply;
415+
Self {
416+
ciphertext,
417+
nonce,
418+
tag,
419+
}
420+
}
421+
}

src/mechanisms/chacha8poly1305.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use generic_array::GenericArray;
22
use rand_core::RngCore;
3+
use trussed_core::types::EncryptedData;
34

45
use crate::api::{reply, request};
56
use crate::error::Error;
@@ -190,8 +191,9 @@ impl WrapKey for super::Chacha8Poly1305 {
190191
};
191192
let encryption_reply = <super::Chacha8Poly1305>::encrypt(keystore, &encryption_request)?;
192193

194+
let wrapped_key = EncryptedData::from(encryption_reply);
193195
let wrapped_key =
194-
crate::postcard_serialize_bytes(&encryption_reply).map_err(|_| Error::CborError)?;
196+
crate::postcard_serialize_bytes(&wrapped_key).map_err(|_| Error::CborError)?;
195197

196198
Ok(reply::WrapKey { wrapped_key })
197199
}
@@ -204,20 +206,14 @@ impl UnwrapKey for super::Chacha8Poly1305 {
204206
keystore: &mut impl Keystore,
205207
request: &request::UnwrapKey,
206208
) -> Result<reply::UnwrapKey, Error> {
207-
let reply::Encrypt {
208-
ciphertext,
209-
nonce,
210-
tag,
211-
} = crate::postcard_deserialize(&request.wrapped_key).map_err(|_| Error::CborError)?;
212-
213-
let decryption_request = request::Decrypt {
214-
mechanism: Mechanism::Chacha8Poly1305,
215-
key: request.wrapping_key,
216-
message: ciphertext,
217-
associated_data: request.associated_data.clone(),
218-
nonce,
219-
tag,
220-
};
209+
let encrypted_data: EncryptedData =
210+
crate::postcard_deserialize(&request.wrapped_key).map_err(|_| Error::CborError)?;
211+
212+
let decryption_request = encrypted_data.decrypt(
213+
Mechanism::Chacha8Poly1305,
214+
request.wrapping_key,
215+
request.associated_data.clone(),
216+
);
221217

222218
let serialized_key = if let Some(serialized_key) =
223219
<super::Chacha8Poly1305>::decrypt(keystore, &decryption_request)?.plaintext

0 commit comments

Comments
 (0)