Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ SPDX-License-Identifier: CC0-1.0

[Unreleased]: https://github.com/trussed-dev/trussed-rsa-backend/compare/v0.3.0...HEAD

-
- Move `RsaImportFormat` and `RsaPublicParts` to the `trussed-rsa-types` crate.

## [v0.3.0][] (2025-07-31)

Expand Down
38 changes: 28 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
# Copyright (C) Nitrokey GmbH
# SPDX-License-Identifier: CC0-1.0

[workspace]
members = ["types"]

[workspace.package]
authors = ["Nitrokey GmbH <[email protected]>"]
edition = "2021"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/trussed-dev/trussed-rsa-backend"

[workspace.dependencies]
heapless-bytes = "0.5"
trussed-core = "0.1"

[package]
name = "trussed-rsa-alloc"
version = "0.3.0"
edition = "2021"
description = "Trussed backend adding support for the RSA algorithm using an allocator"
authors = ["Nitrokey GmbH <[email protected]>"]
license = "Apache-2.0 OR MIT"
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
rust-version = "1.66"
keywords = ["trussed", "rsa", "no-std"]

[dependencies]
heapless-bytes.workspace = true
delog = "0.1.6"
heapless-bytes = "0.3.0"
num-bigint-dig = { version = "0.8.2", default-features = false }
postcard = { version = "0.7", default-features = false, features = ["heapless"] }
rsa = { version = "0.9", default-features = false, features = ["sha2"]}
serde = { version = "1.0.152", default-features = false, features = ["derive"] }

trussed = { version = "0.1", default-features = false }
trussed-core = { version = "0.1.0-rc.1", features = ["crypto-client", "rsa2048", "rsa3072", "rsa4096"] }
trussed-core = { workspace = true, features = ["crypto-client", "rsa2048", "rsa3072", "rsa4096"] }
trussed-rsa-types = "0.1"

[dev-dependencies]
hex-literal = "0.3.4"
Expand All @@ -29,10 +42,10 @@ delog = { version = "0.1.6", features = ["std-log"] }
test-log = "0.2.11"
env_logger = "0.10.0"
rand = "0.8.5"
trussed = { version = "0.1", default-features = false, features = ["certificate-client", "clients-1", "crypto-client"] }
trussed = { version = "0.1", default-features = false, features = ["certificate-client", "crypto-client"] }

[features]

default = ["virt"]
virt = ["std", "trussed/virt"]
std = []

Expand All @@ -48,7 +61,12 @@ log-warn = []
log-error = []

[patch.crates-io]
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "6bba8fde36d05c0227769eb63345744e87d84b2b" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" }
trussed-core = { git = "https://github.com/trussed-dev/trussed.git", rev = "1e7b09a983dc8ae64a7ad8401ce541a9a77e5939" }
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" }
trussed-rsa-types.path = "types"

[profile.dev.package.rsa]
opt-level = 2
Expand Down
14 changes: 8 additions & 6 deletions src/crypto_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ use trussed_core::{
types::{
KeyId, KeySerialization, Location, Mechanism, SignatureSerialization, StorageAttributes,
},
ClientError, ClientResult, CryptoClient,
{ClientError, ClientResult, CryptoClient},
};

use crate::{RsaImportFormat, RsaPublicParts};
use trussed_rsa_types::{RsaImportFormat, RsaPublicParts};

impl<C: CryptoClient> Rsa2048Pkcs1v15 for C {}

Expand Down Expand Up @@ -46,11 +45,12 @@ pub trait Rsa2048Pkcs1v15: CryptoClient {
/// Serializes an RSA 2048 bit key.
///
/// The resulting [`serialized_key`](trussed_core::api::reply::SerializeKey::serialized_key) contains a buffer of the parts of the key
/// as a serialized [`RsaPublicParts`](crate::RsaPublicParts):
/// as a serialized [`RsaPublicParts`](trussed_rsa_types::RsaPublicParts):
/// ```
///# #[cfg(feature = "virt")]
///# {
///# use trussed_rsa_alloc::*;
///# use trussed_rsa_types::*;
///# use trussed_core::{syscall,types::Location::{Volatile,Internal}};
///# virt::with_ram_client("rsa tests", |mut client| {
///# let sk = syscall!(client.generate_rsa2048pkcs_private_key(Internal)).key;
Expand Down Expand Up @@ -189,11 +189,12 @@ pub trait Rsa3072Pkcs1v15: CryptoClient {
/// Serializes an RSA 3072 bit key.
///
/// The resulting [`serialized_key`](trussed_core::api::reply::SerializeKey::serialized_key) contains a buffer of the parts of the key
/// as a serialized [`RsaPublicParts`](crate::RsaPublicParts):
/// as a serialized [`RsaPublicParts`](trussed_rsa_types::RsaPublicParts):
/// ```
///# #[cfg(feature = "virt")]
///# {
///# use trussed_rsa_alloc::*;
///# use trussed_rsa_types::*;
///# use trussed_core::{syscall,types::Location::{Volatile,Internal}};
///# virt::with_ram_client("rsa tests", |mut client| {
///# let sk = syscall!(client.generate_rsa3072pkcs_private_key(Internal)).key;
Expand Down Expand Up @@ -332,11 +333,12 @@ pub trait Rsa4096Pkcs1v15: CryptoClient {
/// Serializes an RSA 4096 bit key.
///
/// The resulting [`serialized_key`](trussed_core::api::reply::SerializeKey::serialized_key) contains a buffer of the parts of the key
/// as a serialized [`RsaPublicParts`](crate::RsaPublicParts):
/// as a serialized [`RsaPublicParts`](trussed_rsa_types::RsaPublicParts):
/// ```
///# #[cfg(feature = "virt")]
///# {
///# use trussed_rsa_alloc::*;
///# use trussed_rsa_types::*;
///# use trussed_core::{syscall,types::Location::{Volatile,Internal}};
///# virt::with_ram_client("rsa tests", |mut client| {
///# let sk = syscall!(client.generate_rsa4096pkcs_private_key(Internal)).key;
Expand Down
7 changes: 3 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use trussed::{
},
Error,
};
use trussed_rsa_types::{RsaImportFormat, RsaPublicParts};

#[cfg(feature = "virt")]
pub mod virt;
Expand All @@ -38,8 +39,6 @@ generate_macros!();
#[macro_use]
extern crate alloc;

mod types;
pub use types::{RsaImportFormat, RsaPublicParts};
mod crypto_traits;
pub use crypto_traits::{Rsa2048Pkcs1v15, Rsa3072Pkcs1v15, Rsa4096Pkcs1v15};

Expand Down Expand Up @@ -271,7 +270,7 @@ fn sign(
Error::InternalError
})?;
let our_signature =
Signature::from_slice(&native_signature.to_bytes()).unwrap_or_else(|_| panic!());
Signature::try_from(&*native_signature.to_bytes()).unwrap_or_else(|_| panic!());

Ok(reply::Sign {
signature: our_signature,
Expand Down Expand Up @@ -338,7 +337,7 @@ fn decrypt(
})?;

Ok(reply::Decrypt {
plaintext: Some(Bytes::from_slice(&res).map_err(|_| {
plaintext: Some(Bytes::try_from(&*res).map_err(|_| {
error!("Failed type conversion");
Error::InternalError
})?),
Expand Down
22 changes: 6 additions & 16 deletions src/virt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,17 @@ impl Dispatch for Dispatcher {
}
}

use std::path::PathBuf;
use trussed::{
backend::{Backend, BackendId, Dispatch},
virt::{self, Filesystem, Ram, StoreProvider},
virt::{self, StoreConfig},
Platform,
};

pub type Client<S, D = Dispatcher> = virt::Client<S, D>;
pub type Client<'a, D = Dispatcher> = virt::Client<'a, D>;

pub fn with_client<S, R, F>(store: S, client_id: &str, f: F) -> R
pub fn with_client<R, F>(store: StoreConfig, client_id: &str, f: F) -> R
where
F: FnOnce(Client<S>) -> R,
S: StoreProvider,
F: FnOnce(Client) -> R,
{
virt::with_platform(store, |platform| {
platform.run_client_with_backends(
Expand All @@ -47,17 +45,9 @@ where
})
}

pub fn with_fs_client<P, R, F>(internal: P, client_id: &str, f: F) -> R
where
F: FnOnce(Client<Filesystem>) -> R,
P: Into<PathBuf>,
{
with_client(Filesystem::new(internal), client_id, f)
}

pub fn with_ram_client<R, F>(client_id: &str, f: F) -> R
where
F: FnOnce(Client<Ram>) -> R,
F: FnOnce(Client) -> R,
{
with_client(Ram::default(), client_id, f)
with_client(StoreConfig::ram(), client_id, f)
}
3 changes: 2 additions & 1 deletion tests/rsa2048.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

use rsa::sha2::Sha256;
use rsa::{traits::PublicKeyParts, Pkcs1v15Encrypt, Pkcs1v15Sign};
use trussed::client::CryptoClient;
use trussed::syscall;
use trussed::types::KeyId;
use trussed::types::KeySerialization;
use trussed::types::Location::*;
use trussed::types::Mechanism;
use trussed::types::StorageAttributes;
use trussed_core::CryptoClient;

use trussed_rsa_alloc::*;
use trussed_rsa_types::*;

use hex_literal::hex;
use num_bigint_dig::BigUint;
Expand Down
3 changes: 2 additions & 1 deletion tests/rsa3072.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use rsa::sha2::Sha384;
use rsa::{traits::PublicKeyParts, Pkcs1v15Encrypt, Pkcs1v15Sign};
use trussed::client::CryptoClient;
use trussed_core::CryptoClient;
use trussed::syscall;
use trussed::types::KeyId;
use trussed::types::KeySerialization;
Expand All @@ -14,6 +14,7 @@ use trussed::types::Mechanism;
use trussed::types::StorageAttributes;

use trussed_rsa_alloc::*;
use trussed_rsa_types::*;

use hex_literal::hex;
use num_bigint_dig::BigUint;
Expand Down
3 changes: 2 additions & 1 deletion tests/rsa4096.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

use rsa::sha2::Sha512;
use rsa::{traits::PublicKeyParts, Pkcs1v15Encrypt, Pkcs1v15Sign};
use trussed::client::CryptoClient;
use trussed::syscall;
use trussed::types::KeyId;
use trussed::types::KeySerialization;
use trussed::types::Location::*;
use trussed::types::Mechanism;
use trussed::types::StorageAttributes;
use trussed_core::CryptoClient;

use trussed_rsa_alloc::*;
use trussed_rsa_types::*;

use hex_literal::hex;
use num_bigint_dig::BigUint;
Expand Down
15 changes: 15 additions & 0 deletions types/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!--
Copyright (C) Nitrokey GmbH
SPDX-License-Identifier: CC0-1.0
-->

# Changelog

## [Unreleased](https://github.com/trussed-dev/trussed-rsa-backend/compare/types-v0.1.0...HEAD)

-

## [v0.1.0](https://github.com/trussed-dev/trussed-rsa-backend/releases/tag/types-v0.1.0)

- Add `Error`, `ErrorKind`, `RsaImportFormat` and `RsaPublicParts` from `trussed-rsa-alloc` v0.3.0.

18 changes: 18 additions & 0 deletions types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (C) Nitrokey GmbH
# SPDX-License-Identifier: CC0-1.0

[package]
name = "trussed-rsa-types"
version = "0.1.0"
description = "Helper types for the trussed-rsa-alloc backend"
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
keywords = ["trussed", "rsa", "no-std"]

[dependencies]
heapless-bytes.workspace = true
postcard = { version = "0.7", default-features = false, features = ["heapless"] }
serde = { version = "1.0.152", default-features = false, features = ["derive"] }
trussed-core.workspace = true
26 changes: 19 additions & 7 deletions src/types.rs → types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright (C) Nitrokey GmbH
// SPDX-License-Identifier: Apache-2.0 or MIT

#![no_std]

use heapless_bytes::Bytes;
use serde::{Deserialize, Serialize};
use trussed::types::SerializedKey;
use trussed_core::types::SerializedKey;

/// Error type
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
Expand All @@ -25,6 +27,16 @@ pub struct Error {
kind: ErrorKind,
}

pub(crate) fn postcard_serialize_bytes<T: serde::Serialize, const N: usize>(
object: &T,
) -> postcard::Result<Bytes<N>> {
let mut vec = Bytes::new();
vec.resize_to_capacity();
let serialized = postcard::to_slice(object, &mut vec)?.len();
vec.resize(serialized, 0).unwrap();
Ok(vec)
}

/// Structure containing the public part of an RSA key
///
/// Given how Trussed extensions are implemented, this structure cannot be sent as-is to the backend,
Expand All @@ -42,16 +54,16 @@ pub struct RsaPublicParts<'d> {
impl<'d> RsaPublicParts<'d> {
pub fn serialize(&self) -> Result<SerializedKey, Error> {
use postcard::Error as PError;
let vec = postcard::to_vec(self).map_err(|err| match err {
Ok(postcard_serialize_bytes(self).map_err(|err| match err {
PError::SerializeBufferFull => Error {
kind: ErrorKind::SerializeBufferFull,
},
_ => Error {
kind: ErrorKind::SerializeCustom,
},
})?;
Ok(Bytes::from(vec))
})?)
}

pub fn deserialize(data: &'d [u8]) -> Result<Self, Error> {
postcard::from_bytes(data).map_err(|_err| Error {
kind: ErrorKind::Deseralization,
Expand All @@ -78,16 +90,16 @@ pub struct RsaImportFormat<'d> {
impl<'d> RsaImportFormat<'d> {
pub fn serialize(&self) -> Result<SerializedKey, Error> {
use postcard::Error as PError;
let vec = postcard::to_vec(self).map_err(|err| match err {
Ok(postcard_serialize_bytes(self).map_err(|err| match err {
PError::SerializeBufferFull => Error {
kind: ErrorKind::SerializeBufferFull,
},
_ => Error {
kind: ErrorKind::SerializeCustom,
},
})?;
Ok(Bytes::from(vec))
})?)
}

pub fn deserialize(data: &'d [u8]) -> Result<Self, Error> {
postcard::from_bytes(data).map_err(|_err| Error {
kind: ErrorKind::Deseralization,
Expand Down
Loading