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/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;