From 8a9bb9d79e40c2dcf026cf611302109f776bec83 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 19 Dec 2024 18:01:19 +0100 Subject: [PATCH] core: Flatten public module structure This patch makes some modules of the core crate private and re-exports their contents from the crate root. This has two benefits: It makes it easier to read the crate documentation because the most important types are directly visible from the root. And it makes the imports for the most important types less verbose. See also: https://github.com/trussed-dev/trussed/issues/155 --- .github/workflows/ci.yml | 3 +- core/src/client.rs | 29 +- core/src/client/crypto.rs | 648 ------------------------------------- core/src/lib.rs | 27 +- core/src/mechanisms.rs | 656 ++++++++++++++++++++++++++++++++++++++ core/src/types.rs | 4 +- src/client.rs | 16 +- src/client/mechanisms.rs | 29 +- src/error.rs | 1 + src/interrupt.rs | 1 + src/lib.rs | 4 +- 11 files changed, 704 insertions(+), 714 deletions(-) create mode 100644 core/src/mechanisms.rs create mode 100644 src/error.rs create mode 100644 src/interrupt.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea89cfccf76..f058b63d899 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,6 +102,5 @@ jobs: - name: Check documentation run: | export RUSTDOCFLAGS="-D warnings" - cargo doc --no-deps --features serde-extensions,virt - cargo doc --no-deps --package trussed-core --all-features + cargo doc --no-deps --workspace --all-features if: matrix.target == 'x86_64-unknown-linux-gnu' diff --git a/core/src/client.rs b/core/src/client.rs index 8f8ca132dd4..a27e1d5e711 100644 --- a/core/src/client.rs +++ b/core/src/client.rs @@ -7,34 +7,19 @@ use crate::{ }; #[cfg(feature = "attestation-client")] -mod attestation; +pub mod attestation; #[cfg(feature = "certificate-client")] -mod certificate; +pub mod certificate; #[cfg(feature = "counter-client")] -mod counter; +pub mod counter; #[cfg(feature = "crypto-client")] -mod crypto; +pub mod crypto; #[cfg(feature = "filesystem-client")] -mod filesystem; +pub mod filesystem; #[cfg(feature = "management-client")] -mod management; +pub mod management; #[cfg(feature = "ui-client")] -mod ui; - -#[cfg(feature = "attestation-client")] -pub use attestation::AttestationClient; -#[cfg(feature = "certificate-client")] -pub use certificate::CertificateClient; -#[cfg(feature = "counter-client")] -pub use counter::CounterClient; -#[cfg(feature = "crypto-client")] -pub use crypto::*; -#[cfg(feature = "filesystem-client")] -pub use filesystem::FilesystemClient; -#[cfg(feature = "management-client")] -pub use management::ManagementClient; -#[cfg(feature = "ui-client")] -pub use ui::UiClient; +pub mod ui; // to be fair, this is a programmer error, // and could also just panic diff --git a/core/src/client/crypto.rs b/core/src/client/crypto.rs index 6bacfedcba5..31b8a2ddd43 100644 --- a/core/src/client/crypto.rs +++ b/core/src/client/crypto.rs @@ -282,651 +282,3 @@ pub trait CryptoClient: PollClient { }) } } - -#[cfg(feature = "aes256-cbc")] -pub trait Aes256Cbc: CryptoClient { - fn decrypt_aes256cbc<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - iv: &[u8], - ) -> ClientResult<'c, reply::Decrypt, Self> { - self.decrypt(Mechanism::Aes256Cbc, key, message, &[], iv, &[]) - } - - fn wrap_key_aes256cbc( - &mut self, - wrapping_key: KeyId, - key: KeyId, - iv: Option<&[u8; 16]>, - ) -> ClientResult<'_, reply::WrapKey, Self> { - self.wrap_key( - Mechanism::Aes256Cbc, - wrapping_key, - key, - &[], - iv.and_then(|iv| ShortData::from_slice(iv).ok()), - ) - } -} - -#[cfg(feature = "chacha8-poly1305")] -pub trait Chacha8Poly1305: CryptoClient { - fn decrypt_chacha8poly1305<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - associated_data: &[u8], - nonce: &[u8], - tag: &[u8], - ) -> ClientResult<'c, reply::Decrypt, Self> { - self.decrypt( - Mechanism::Chacha8Poly1305, - key, - message, - associated_data, - nonce, - tag, - ) - } - - fn encrypt_chacha8poly1305<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - associated_data: &[u8], - nonce: Option<&[u8; 12]>, - ) -> ClientResult<'c, reply::Encrypt, Self> { - self.encrypt( - Mechanism::Chacha8Poly1305, - key, - message, - associated_data, - nonce.and_then(|nonce| ShortData::from_slice(nonce).ok()), - ) - } - - fn generate_chacha8poly1305_key( - &mut self, - persistence: Location, - ) -> ClientResult<'_, reply::GenerateKey, Self> { - self.generate_key( - Mechanism::Chacha8Poly1305, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn unwrap_key_chacha8poly1305<'c>( - &'c mut self, - wrapping_key: KeyId, - wrapped_key: &[u8], - associated_data: &[u8], - location: Location, - ) -> ClientResult<'c, reply::UnwrapKey, Self> { - self.unwrap_key( - Mechanism::Chacha8Poly1305, - wrapping_key, - Message::from_slice(wrapped_key).map_err(|_| ClientError::DataTooLarge)?, - associated_data, - &[], - StorageAttributes::new().set_persistence(location), - ) - } - - fn wrap_key_chacha8poly1305<'c>( - &'c mut self, - wrapping_key: KeyId, - key: KeyId, - associated_data: &[u8], - nonce: Option<&[u8; 12]>, - ) -> ClientResult<'c, reply::WrapKey, Self> { - self.wrap_key( - Mechanism::Chacha8Poly1305, - wrapping_key, - key, - associated_data, - nonce.and_then(|nonce| ShortData::from_slice(nonce).ok()), - ) - } -} - -#[cfg(feature = "hmac-blake2s")] -pub trait HmacBlake2s: CryptoClient { - fn hmacblake2s_derive_key( - &mut self, - base_key: KeyId, - message: &[u8], - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::HmacBlake2s, - base_key, - Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn sign_hmacblake2s<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign( - Mechanism::HmacBlake2s, - key, - message, - SignatureSerialization::Raw, - ) - } -} - -#[cfg(feature = "hmac-sha1")] -pub trait HmacSha1: CryptoClient { - fn hmacsha1_derive_key( - &mut self, - base_key: KeyId, - message: &[u8], - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::HmacSha1, - base_key, - Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn sign_hmacsha1<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign( - Mechanism::HmacSha1, - key, - message, - SignatureSerialization::Raw, - ) - } -} - -#[cfg(feature = "hmac-sha256")] -pub trait HmacSha256: CryptoClient { - fn hmacsha256_derive_key( - &mut self, - base_key: KeyId, - message: &[u8], - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::HmacSha256, - base_key, - Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn sign_hmacsha256<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign( - Mechanism::HmacSha256, - key, - message, - SignatureSerialization::Raw, - ) - } -} - -#[cfg(feature = "hmac-sha512")] -pub trait HmacSha512: CryptoClient { - fn hmacsha512_derive_key( - &mut self, - base_key: KeyId, - message: &[u8], - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::HmacSha512, - base_key, - Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn sign_hmacsha512<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign( - Mechanism::HmacSha512, - key, - message, - SignatureSerialization::Raw, - ) - } -} - -#[cfg(feature = "ed255")] -pub trait Ed255: CryptoClient { - fn generate_ed255_private_key( - &mut self, - persistence: Location, - ) -> ClientResult<'_, reply::GenerateKey, Self> { - self.generate_key( - Mechanism::Ed255, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn derive_ed255_public_key( - &mut self, - private_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::Ed255, - private_key, - None, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn deserialize_ed255_key<'c>( - &'c mut self, - serialized_key: &[u8], - format: KeySerialization, - attributes: StorageAttributes, - ) -> ClientResult<'c, reply::DeserializeKey, Self> { - self.deserialize_key(Mechanism::Ed255, serialized_key, format, attributes) - } - - fn serialize_ed255_key( - &mut self, - key: KeyId, - format: KeySerialization, - ) -> ClientResult<'_, reply::SerializeKey, Self> { - self.serialize_key(Mechanism::Ed255, key, format) - } - - fn sign_ed255<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign(Mechanism::Ed255, key, message, SignatureSerialization::Raw) - } - - fn verify_ed255<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - signature: &[u8], - ) -> ClientResult<'c, reply::Verify, Self> { - self.verify( - Mechanism::Ed255, - key, - message, - signature, - SignatureSerialization::Raw, - ) - } -} - -#[cfg(feature = "p256")] -pub trait P256: CryptoClient { - fn generate_p256_private_key( - &mut self, - persistence: Location, - ) -> ClientResult<'_, reply::GenerateKey, Self> { - self.generate_key( - Mechanism::P256, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn derive_p256_public_key( - &mut self, - private_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::P256, - private_key, - None, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn deserialize_p256_key<'c>( - &'c mut self, - serialized_key: &[u8], - format: KeySerialization, - attributes: StorageAttributes, - ) -> ClientResult<'c, reply::DeserializeKey, Self> { - self.deserialize_key(Mechanism::P256, serialized_key, format, attributes) - } - - fn serialize_p256_key( - &mut self, - key: KeyId, - format: KeySerialization, - ) -> ClientResult<'_, reply::SerializeKey, Self> { - self.serialize_key(Mechanism::P256, key, format) - } - - // generally, don't offer multiple versions of a mechanism, if possible. - // try using the simplest when given the choice. - // hashing is something users can do themselves hopefully :) - // - // on the other hand: if users need sha256, then if the service runs in secure trustzone - // domain, we'll maybe need two copies of the sha2 code - fn sign_p256<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - format: SignatureSerialization, - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign(Mechanism::P256, key, message, format) - } - - fn verify_p256<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - signature: &[u8], - ) -> ClientResult<'c, reply::Verify, Self> { - self.verify( - Mechanism::P256, - key, - message, - signature, - SignatureSerialization::Raw, - ) - } - - fn agree_p256( - &mut self, - private_key: KeyId, - public_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::Agree, Self> { - self.agree( - Mechanism::P256, - private_key, - public_key, - StorageAttributes::new().set_persistence(persistence), - ) - } -} - -#[cfg(feature = "p384")] -pub trait P384: CryptoClient { - fn generate_p384_private_key( - &mut self, - persistence: Location, - ) -> ClientResult<'_, reply::GenerateKey, Self> { - self.generate_key( - Mechanism::P384, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn derive_p384_public_key( - &mut self, - private_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::P384, - private_key, - None, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn deserialize_p384_key<'c>( - &'c mut self, - serialized_key: &[u8], - format: KeySerialization, - attributes: StorageAttributes, - ) -> ClientResult<'c, reply::DeserializeKey, Self> { - self.deserialize_key(Mechanism::P384, serialized_key, format, attributes) - } - - fn serialize_p384_key( - &mut self, - key: KeyId, - format: KeySerialization, - ) -> ClientResult<'_, reply::SerializeKey, Self> { - self.serialize_key(Mechanism::P384, key, format) - } - - // generally, don't offer multiple versions of a mechanism, if possible. - // try using the simplest when given the choice. - // hashing is something users can do themselves hopefully :) - // - // on the other hand: if users need sha256, then if the service runs in secure trustzone - // domain, we'll maybe need two copies of the sha2 code - fn sign_p384<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - format: SignatureSerialization, - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign(Mechanism::P384, key, message, format) - } - - fn verify_p384<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - signature: &[u8], - ) -> ClientResult<'c, reply::Verify, Self> { - self.verify( - Mechanism::P384, - key, - message, - signature, - SignatureSerialization::Raw, - ) - } - - fn agree_p384( - &mut self, - private_key: KeyId, - public_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::Agree, Self> { - self.agree( - Mechanism::P384, - private_key, - public_key, - StorageAttributes::new().set_persistence(persistence), - ) - } -} - -#[cfg(feature = "p521")] -pub trait P521: CryptoClient { - fn generate_p521_private_key( - &mut self, - persistence: Location, - ) -> ClientResult<'_, reply::GenerateKey, Self> { - self.generate_key( - Mechanism::P521, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn derive_p521_public_key( - &mut self, - private_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::P521, - private_key, - None, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn deserialize_p521_key<'c>( - &'c mut self, - serialized_key: &[u8], - format: KeySerialization, - attributes: StorageAttributes, - ) -> ClientResult<'c, reply::DeserializeKey, Self> { - self.deserialize_key(Mechanism::P521, serialized_key, format, attributes) - } - - fn serialize_p521_key( - &mut self, - key: KeyId, - format: KeySerialization, - ) -> ClientResult<'_, reply::SerializeKey, Self> { - self.serialize_key(Mechanism::P521, key, format) - } - - // generally, don't offer multiple versions of a mechanism, if possible. - // try using the simplest when given the choice. - // hashing is something users can do themselves hopefully :) - // - // on the other hand: if users need sha256, then if the service runs in secure trustzone - // domain, we'll maybe need two copies of the sha2 code - fn sign_p521<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - format: SignatureSerialization, - ) -> ClientResult<'c, reply::Sign, Self> { - self.sign(Mechanism::P521, key, message, format) - } - - fn verify_p521<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - signature: &[u8], - ) -> ClientResult<'c, reply::Verify, Self> { - self.verify( - Mechanism::P521, - key, - message, - signature, - SignatureSerialization::Raw, - ) - } - - fn agree_p521( - &mut self, - private_key: KeyId, - public_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::Agree, Self> { - self.agree( - Mechanism::P521, - private_key, - public_key, - StorageAttributes::new().set_persistence(persistence), - ) - } -} - -#[cfg(feature = "sha256")] -pub trait Sha256: CryptoClient { - fn sha256_derive_key( - &mut self, - shared_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::Sha256, - shared_key, - None, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn hash_sha256<'c>(&'c mut self, message: &[u8]) -> ClientResult<'c, reply::Hash, Self> { - self.hash( - Mechanism::Sha256, - Message::from_slice(message).map_err(|_| ClientError::DataTooLarge)?, - ) - } -} - -#[cfg(feature = "tdes")] -pub trait Tdes: CryptoClient { - fn decrypt_tdes<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Decrypt, Self> { - self.decrypt(Mechanism::Tdes, key, message, &[], &[], &[]) - } - - fn encrypt_tdes<'c>( - &'c mut self, - key: KeyId, - message: &[u8], - ) -> ClientResult<'c, reply::Encrypt, Self> { - self.encrypt(Mechanism::Tdes, key, message, &[], None) - } -} - -#[cfg(feature = "totp")] -pub trait Totp: CryptoClient { - fn sign_totp(&mut self, key: KeyId, timestamp: u64) -> ClientResult<'_, reply::Sign, Self> { - self.sign( - Mechanism::Totp, - key, - timestamp.to_le_bytes().as_ref(), - SignatureSerialization::Raw, - ) - } -} - -#[cfg(feature = "x255")] -pub trait X255: CryptoClient { - fn generate_x255_secret_key( - &mut self, - persistence: Location, - ) -> ClientResult<'_, reply::GenerateKey, Self> { - self.generate_key( - Mechanism::X255, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn derive_x255_public_key( - &mut self, - secret_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::DeriveKey, Self> { - self.derive_key( - Mechanism::X255, - secret_key, - None, - StorageAttributes::new().set_persistence(persistence), - ) - } - - fn agree_x255( - &mut self, - private_key: KeyId, - public_key: KeyId, - persistence: Location, - ) -> ClientResult<'_, reply::Agree, Self> { - self.agree( - Mechanism::X255, - private_key, - public_key, - StorageAttributes::new().set_persistence(persistence), - ) - } -} diff --git a/core/src/lib.rs b/core/src/lib.rs index 4fbfeb95bd5..55664fb5dd4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -6,11 +6,32 @@ //! //! [`trussed`]: https://docs.rs/trussed +mod client; +mod error; +mod interrupt; + pub mod api; -pub mod client; pub mod config; -pub mod error; -pub mod interrupt; +#[cfg(feature = "crypto-client")] +pub mod mechanisms; #[cfg(feature = "serde-extensions")] pub mod serde_extensions; pub mod types; + +#[cfg(feature = "attestation-client")] +pub use client::attestation::AttestationClient; +#[cfg(feature = "certificate-client")] +pub use client::certificate::CertificateClient; +#[cfg(feature = "counter-client")] +pub use client::counter::CounterClient; +#[cfg(feature = "crypto-client")] +pub use client::crypto::CryptoClient; +#[cfg(feature = "filesystem-client")] +pub use client::filesystem::FilesystemClient; +#[cfg(feature = "management-client")] +pub use client::management::ManagementClient; +#[cfg(feature = "ui-client")] +pub use client::ui::UiClient; +pub use client::{ClientError, ClientResult, FutureResult, PollClient}; +pub use error::{Error, Result}; +pub use interrupt::{FromU8Error, InterruptFlag, InterruptState}; diff --git a/core/src/mechanisms.rs b/core/src/mechanisms.rs new file mode 100644 index 00000000000..04a48b61a60 --- /dev/null +++ b/core/src/mechanisms.rs @@ -0,0 +1,656 @@ +use crate::{ + api::reply, + client::{crypto::CryptoClient, ClientError, ClientResult}, + types::{ + KeyId, KeySerialization, Location, Mechanism, MediumData, Message, ShortData, + SignatureSerialization, StorageAttributes, + }, +}; + +#[cfg(feature = "aes256-cbc")] +pub trait Aes256Cbc: CryptoClient { + fn decrypt_aes256cbc<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + iv: &[u8], + ) -> ClientResult<'c, reply::Decrypt, Self> { + self.decrypt(Mechanism::Aes256Cbc, key, message, &[], iv, &[]) + } + + fn wrap_key_aes256cbc( + &mut self, + wrapping_key: KeyId, + key: KeyId, + iv: Option<&[u8; 16]>, + ) -> ClientResult<'_, reply::WrapKey, Self> { + self.wrap_key( + Mechanism::Aes256Cbc, + wrapping_key, + key, + &[], + iv.and_then(|iv| ShortData::from_slice(iv).ok()), + ) + } +} + +#[cfg(feature = "chacha8-poly1305")] +pub trait Chacha8Poly1305: CryptoClient { + fn decrypt_chacha8poly1305<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + associated_data: &[u8], + nonce: &[u8], + tag: &[u8], + ) -> ClientResult<'c, reply::Decrypt, Self> { + self.decrypt( + Mechanism::Chacha8Poly1305, + key, + message, + associated_data, + nonce, + tag, + ) + } + + fn encrypt_chacha8poly1305<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + associated_data: &[u8], + nonce: Option<&[u8; 12]>, + ) -> ClientResult<'c, reply::Encrypt, Self> { + self.encrypt( + Mechanism::Chacha8Poly1305, + key, + message, + associated_data, + nonce.and_then(|nonce| ShortData::from_slice(nonce).ok()), + ) + } + + fn generate_chacha8poly1305_key( + &mut self, + persistence: Location, + ) -> ClientResult<'_, reply::GenerateKey, Self> { + self.generate_key( + Mechanism::Chacha8Poly1305, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn unwrap_key_chacha8poly1305<'c>( + &'c mut self, + wrapping_key: KeyId, + wrapped_key: &[u8], + associated_data: &[u8], + location: Location, + ) -> ClientResult<'c, reply::UnwrapKey, Self> { + self.unwrap_key( + Mechanism::Chacha8Poly1305, + wrapping_key, + Message::from_slice(wrapped_key).map_err(|_| ClientError::DataTooLarge)?, + associated_data, + &[], + StorageAttributes::new().set_persistence(location), + ) + } + + fn wrap_key_chacha8poly1305<'c>( + &'c mut self, + wrapping_key: KeyId, + key: KeyId, + associated_data: &[u8], + nonce: Option<&[u8; 12]>, + ) -> ClientResult<'c, reply::WrapKey, Self> { + self.wrap_key( + Mechanism::Chacha8Poly1305, + wrapping_key, + key, + associated_data, + nonce.and_then(|nonce| ShortData::from_slice(nonce).ok()), + ) + } +} + +#[cfg(feature = "hmac-blake2s")] +pub trait HmacBlake2s: CryptoClient { + fn hmacblake2s_derive_key( + &mut self, + base_key: KeyId, + message: &[u8], + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::HmacBlake2s, + base_key, + Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn sign_hmacblake2s<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign( + Mechanism::HmacBlake2s, + key, + message, + SignatureSerialization::Raw, + ) + } +} + +#[cfg(feature = "hmac-sha1")] +pub trait HmacSha1: CryptoClient { + fn hmacsha1_derive_key( + &mut self, + base_key: KeyId, + message: &[u8], + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::HmacSha1, + base_key, + Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn sign_hmacsha1<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign( + Mechanism::HmacSha1, + key, + message, + SignatureSerialization::Raw, + ) + } +} + +#[cfg(feature = "hmac-sha256")] +pub trait HmacSha256: CryptoClient { + fn hmacsha256_derive_key( + &mut self, + base_key: KeyId, + message: &[u8], + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::HmacSha256, + base_key, + Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn sign_hmacsha256<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign( + Mechanism::HmacSha256, + key, + message, + SignatureSerialization::Raw, + ) + } +} + +#[cfg(feature = "hmac-sha512")] +pub trait HmacSha512: CryptoClient { + fn hmacsha512_derive_key( + &mut self, + base_key: KeyId, + message: &[u8], + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::HmacSha512, + base_key, + Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?), + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn sign_hmacsha512<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign( + Mechanism::HmacSha512, + key, + message, + SignatureSerialization::Raw, + ) + } +} + +#[cfg(feature = "ed255")] +pub trait Ed255: CryptoClient { + fn generate_ed255_private_key( + &mut self, + persistence: Location, + ) -> ClientResult<'_, reply::GenerateKey, Self> { + self.generate_key( + Mechanism::Ed255, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn derive_ed255_public_key( + &mut self, + private_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::Ed255, + private_key, + None, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn deserialize_ed255_key<'c>( + &'c mut self, + serialized_key: &[u8], + format: KeySerialization, + attributes: StorageAttributes, + ) -> ClientResult<'c, reply::DeserializeKey, Self> { + self.deserialize_key(Mechanism::Ed255, serialized_key, format, attributes) + } + + fn serialize_ed255_key( + &mut self, + key: KeyId, + format: KeySerialization, + ) -> ClientResult<'_, reply::SerializeKey, Self> { + self.serialize_key(Mechanism::Ed255, key, format) + } + + fn sign_ed255<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign(Mechanism::Ed255, key, message, SignatureSerialization::Raw) + } + + fn verify_ed255<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + signature: &[u8], + ) -> ClientResult<'c, reply::Verify, Self> { + self.verify( + Mechanism::Ed255, + key, + message, + signature, + SignatureSerialization::Raw, + ) + } +} + +#[cfg(feature = "p256")] +pub trait P256: CryptoClient { + fn generate_p256_private_key( + &mut self, + persistence: Location, + ) -> ClientResult<'_, reply::GenerateKey, Self> { + self.generate_key( + Mechanism::P256, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn derive_p256_public_key( + &mut self, + private_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::P256, + private_key, + None, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn deserialize_p256_key<'c>( + &'c mut self, + serialized_key: &[u8], + format: KeySerialization, + attributes: StorageAttributes, + ) -> ClientResult<'c, reply::DeserializeKey, Self> { + self.deserialize_key(Mechanism::P256, serialized_key, format, attributes) + } + + fn serialize_p256_key( + &mut self, + key: KeyId, + format: KeySerialization, + ) -> ClientResult<'_, reply::SerializeKey, Self> { + self.serialize_key(Mechanism::P256, key, format) + } + + // generally, don't offer multiple versions of a mechanism, if possible. + // try using the simplest when given the choice. + // hashing is something users can do themselves hopefully :) + // + // on the other hand: if users need sha256, then if the service runs in secure trustzone + // domain, we'll maybe need two copies of the sha2 code + fn sign_p256<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + format: SignatureSerialization, + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign(Mechanism::P256, key, message, format) + } + + fn verify_p256<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + signature: &[u8], + ) -> ClientResult<'c, reply::Verify, Self> { + self.verify( + Mechanism::P256, + key, + message, + signature, + SignatureSerialization::Raw, + ) + } + + fn agree_p256( + &mut self, + private_key: KeyId, + public_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::Agree, Self> { + self.agree( + Mechanism::P256, + private_key, + public_key, + StorageAttributes::new().set_persistence(persistence), + ) + } +} + +#[cfg(feature = "p384")] +pub trait P384: CryptoClient { + fn generate_p384_private_key( + &mut self, + persistence: Location, + ) -> ClientResult<'_, reply::GenerateKey, Self> { + self.generate_key( + Mechanism::P384, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn derive_p384_public_key( + &mut self, + private_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::P384, + private_key, + None, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn deserialize_p384_key<'c>( + &'c mut self, + serialized_key: &[u8], + format: KeySerialization, + attributes: StorageAttributes, + ) -> ClientResult<'c, reply::DeserializeKey, Self> { + self.deserialize_key(Mechanism::P384, serialized_key, format, attributes) + } + + fn serialize_p384_key( + &mut self, + key: KeyId, + format: KeySerialization, + ) -> ClientResult<'_, reply::SerializeKey, Self> { + self.serialize_key(Mechanism::P384, key, format) + } + + // generally, don't offer multiple versions of a mechanism, if possible. + // try using the simplest when given the choice. + // hashing is something users can do themselves hopefully :) + // + // on the other hand: if users need sha256, then if the service runs in secure trustzone + // domain, we'll maybe need two copies of the sha2 code + fn sign_p384<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + format: SignatureSerialization, + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign(Mechanism::P384, key, message, format) + } + + fn verify_p384<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + signature: &[u8], + ) -> ClientResult<'c, reply::Verify, Self> { + self.verify( + Mechanism::P384, + key, + message, + signature, + SignatureSerialization::Raw, + ) + } + + fn agree_p384( + &mut self, + private_key: KeyId, + public_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::Agree, Self> { + self.agree( + Mechanism::P384, + private_key, + public_key, + StorageAttributes::new().set_persistence(persistence), + ) + } +} + +#[cfg(feature = "p521")] +pub trait P521: CryptoClient { + fn generate_p521_private_key( + &mut self, + persistence: Location, + ) -> ClientResult<'_, reply::GenerateKey, Self> { + self.generate_key( + Mechanism::P521, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn derive_p521_public_key( + &mut self, + private_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::P521, + private_key, + None, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn deserialize_p521_key<'c>( + &'c mut self, + serialized_key: &[u8], + format: KeySerialization, + attributes: StorageAttributes, + ) -> ClientResult<'c, reply::DeserializeKey, Self> { + self.deserialize_key(Mechanism::P521, serialized_key, format, attributes) + } + + fn serialize_p521_key( + &mut self, + key: KeyId, + format: KeySerialization, + ) -> ClientResult<'_, reply::SerializeKey, Self> { + self.serialize_key(Mechanism::P521, key, format) + } + + // generally, don't offer multiple versions of a mechanism, if possible. + // try using the simplest when given the choice. + // hashing is something users can do themselves hopefully :) + // + // on the other hand: if users need sha256, then if the service runs in secure trustzone + // domain, we'll maybe need two copies of the sha2 code + fn sign_p521<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + format: SignatureSerialization, + ) -> ClientResult<'c, reply::Sign, Self> { + self.sign(Mechanism::P521, key, message, format) + } + + fn verify_p521<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + signature: &[u8], + ) -> ClientResult<'c, reply::Verify, Self> { + self.verify( + Mechanism::P521, + key, + message, + signature, + SignatureSerialization::Raw, + ) + } + + fn agree_p521( + &mut self, + private_key: KeyId, + public_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::Agree, Self> { + self.agree( + Mechanism::P521, + private_key, + public_key, + StorageAttributes::new().set_persistence(persistence), + ) + } +} + +#[cfg(feature = "sha256")] +pub trait Sha256: CryptoClient { + fn sha256_derive_key( + &mut self, + shared_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::Sha256, + shared_key, + None, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn hash_sha256<'c>(&'c mut self, message: &[u8]) -> ClientResult<'c, reply::Hash, Self> { + self.hash( + Mechanism::Sha256, + Message::from_slice(message).map_err(|_| ClientError::DataTooLarge)?, + ) + } +} + +#[cfg(feature = "tdes")] +pub trait Tdes: CryptoClient { + fn decrypt_tdes<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Decrypt, Self> { + self.decrypt(Mechanism::Tdes, key, message, &[], &[], &[]) + } + + fn encrypt_tdes<'c>( + &'c mut self, + key: KeyId, + message: &[u8], + ) -> ClientResult<'c, reply::Encrypt, Self> { + self.encrypt(Mechanism::Tdes, key, message, &[], None) + } +} + +#[cfg(feature = "totp")] +pub trait Totp: CryptoClient { + fn sign_totp(&mut self, key: KeyId, timestamp: u64) -> ClientResult<'_, reply::Sign, Self> { + self.sign( + Mechanism::Totp, + key, + timestamp.to_le_bytes().as_ref(), + SignatureSerialization::Raw, + ) + } +} + +#[cfg(feature = "x255")] +pub trait X255: CryptoClient { + fn generate_x255_secret_key( + &mut self, + persistence: Location, + ) -> ClientResult<'_, reply::GenerateKey, Self> { + self.generate_key( + Mechanism::X255, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn derive_x255_public_key( + &mut self, + secret_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::DeriveKey, Self> { + self.derive_key( + Mechanism::X255, + secret_key, + None, + StorageAttributes::new().set_persistence(persistence), + ) + } + + fn agree_x255( + &mut self, + private_key: KeyId, + public_key: KeyId, + persistence: Location, + ) -> ClientResult<'_, reply::Agree, Self> { + self.agree( + Mechanism::X255, + private_key, + public_key, + StorageAttributes::new().set_persistence(persistence), + ) + } +} diff --git a/core/src/types.rs b/core/src/types.rs index 14071b3a250..91c0788d214 100644 --- a/core/src/types.rs +++ b/core/src/types.rs @@ -343,8 +343,8 @@ pub struct StorageAttributes { // persistent: bool, pub persistence: Location, - /// Wether a the result of an [`agree`](crate::client::CryptoClient::agree) can be serialized - /// with [`serialize_key`](crate::client::CryptoClient::serialize_key) + /// Wether a the result of an [`agree`](crate::CryptoClient::agree) can be serialized with + /// [`serialize_key`](crate::CryptoClient::serialize_key) pub serializable: bool, // cryptoki: user must be logged in // private: bool, diff --git a/src/client.rs b/src/client.rs index 7c903b11cdd..e311ca5d15c 100644 --- a/src/client.rs +++ b/src/client.rs @@ -92,22 +92,22 @@ pub mod mechanisms; #[cfg(feature = "crypto-client")] pub use mechanisms::*; -pub use trussed_core::client::{ClientError, ClientResult, FutureResult, PollClient}; +pub use trussed_core::{ClientError, ClientResult, FutureResult, PollClient}; #[cfg(feature = "attestation-client")] -pub use trussed_core::client::AttestationClient; +pub use trussed_core::AttestationClient; #[cfg(feature = "certificate-client")] -pub use trussed_core::client::CertificateClient; +pub use trussed_core::CertificateClient; #[cfg(feature = "counter-client")] -pub use trussed_core::client::CounterClient; +pub use trussed_core::CounterClient; #[cfg(feature = "crypto-client")] -pub use trussed_core::client::CryptoClient; +pub use trussed_core::CryptoClient; #[cfg(feature = "filesystem-client")] -pub use trussed_core::client::FilesystemClient; +pub use trussed_core::FilesystemClient; #[cfg(feature = "management-client")] -pub use trussed_core::client::ManagementClient; +pub use trussed_core::ManagementClient; #[cfg(feature = "ui-client")] -pub use trussed_core::client::UiClient; +pub use trussed_core::UiClient; /// All-in-one trait bounding on the sub-traits. #[cfg(feature = "all-clients")] diff --git a/src/client/mechanisms.rs b/src/client/mechanisms.rs index 1808ec9662f..df1041a9644 100644 --- a/src/client/mechanisms.rs +++ b/src/client/mechanisms.rs @@ -1,34 +1,7 @@ use super::ClientImplementation; use crate::platform::Syscall; -#[cfg(feature = "aes256-cbc")] -pub use trussed_core::client::Aes256Cbc; -#[cfg(feature = "chacha8-poly1305")] -pub use trussed_core::client::Chacha8Poly1305; -#[cfg(feature = "ed255")] -pub use trussed_core::client::Ed255; -#[cfg(feature = "hmac-blake2s")] -pub use trussed_core::client::HmacBlake2s; -#[cfg(feature = "hmac-sha1")] -pub use trussed_core::client::HmacSha1; -#[cfg(feature = "hmac-sha256")] -pub use trussed_core::client::HmacSha256; -#[cfg(feature = "hmac-sha512")] -pub use trussed_core::client::HmacSha512; -#[cfg(feature = "sha256")] -pub use trussed_core::client::Sha256; -#[cfg(feature = "tdes")] -pub use trussed_core::client::Tdes; -#[cfg(feature = "totp")] -pub use trussed_core::client::Totp; -#[cfg(feature = "p256")] -pub use trussed_core::client::P256; -#[cfg(feature = "p384")] -pub use trussed_core::client::P384; -#[cfg(feature = "p521")] -pub use trussed_core::client::P521; -#[cfg(feature = "x255")] -pub use trussed_core::client::X255; +pub use trussed_core::mechanisms::*; #[cfg(feature = "aes256-cbc")] impl Aes256Cbc for ClientImplementation {} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 00000000000..0efde2b47ef --- /dev/null +++ b/src/error.rs @@ -0,0 +1 @@ +pub use trussed_core::{Error, Result}; diff --git a/src/interrupt.rs b/src/interrupt.rs new file mode 100644 index 00000000000..9b918c6be88 --- /dev/null +++ b/src/interrupt.rs @@ -0,0 +1 @@ +pub use trussed_core::{FromU8Error, InterruptFlag, InterruptState}; diff --git a/src/lib.rs b/src/lib.rs index 0303caec996..772648cc91e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,8 @@ pub mod api; pub mod backend; pub mod client; pub mod config; +pub mod error; +pub mod interrupt; pub mod key; #[cfg(feature = "crypto-client")] pub mod mechanisms; @@ -52,7 +54,7 @@ pub use error::Error; pub use platform::Platform; pub use service::Service; -pub use trussed_core::{block, error, interrupt, syscall, try_syscall}; +pub use trussed_core::{block, syscall, try_syscall}; pub use cbor_smol::cbor_deserialize; pub use heapless_bytes::Bytes;