diff --git a/CHANGELOG.md b/CHANGELOG.md index 8da3c2f13fe..cebc013ba2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed the `Copy` requirement. - Removed the `unsafe` keyword for the `Store` trait. - Removed the `unsafe` keyword for the `Platform` trait. +- Replaced the mechanism RPC traits in `service` with a single `MechanismImpl` trait. +- Made the `mechanisms` module private. Mechanism implementation can still be accessed via the `Mechanism` enum. ### Fixed diff --git a/src/lib.rs b/src/lib.rs index 772648cc91e..12132dc0232 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ pub mod error; pub mod interrupt; pub mod key; #[cfg(feature = "crypto-client")] -pub mod mechanisms; +mod mechanisms; pub mod pipe; pub mod platform; #[cfg(feature = "serde-extensions")] diff --git a/src/mechanisms.rs b/src/mechanisms.rs index fd7e6f5e2b6..4ca2baae4f2 100644 --- a/src/mechanisms.rs +++ b/src/mechanisms.rs @@ -12,104 +12,87 @@ // TODO: rename to aes256-cbc-zero-iv #[cfg(feature = "aes256-cbc")] -pub struct Aes256Cbc {} +pub struct Aes256Cbc; #[cfg(feature = "aes256-cbc")] mod aes256cbc; #[cfg(feature = "chacha8-poly1305")] -pub struct Chacha8Poly1305 {} +pub struct Chacha8Poly1305; #[cfg(feature = "chacha8-poly1305")] mod chacha8poly1305; #[cfg(feature = "shared-secret")] -pub struct SharedSecret {} +pub struct SharedSecret; #[cfg(feature = "shared-secret")] mod shared_secret; #[cfg(feature = "ed255")] -pub struct Ed255 {} +pub struct Ed255; #[cfg(feature = "ed255")] mod ed255; #[cfg(feature = "hmac-blake2s")] -pub struct HmacBlake2s {} +pub struct HmacBlake2s; #[cfg(feature = "hmac-blake2s")] mod hmacblake2s; #[cfg(feature = "hmac-sha1")] -pub struct HmacSha1 {} +pub struct HmacSha1; #[cfg(feature = "hmac-sha1")] mod hmacsha1; #[cfg(feature = "hmac-sha256")] -pub struct HmacSha256 {} +pub struct HmacSha256; #[cfg(feature = "hmac-sha256")] mod hmacsha256; #[cfg(feature = "hmac-sha512")] -pub struct HmacSha512 {} +pub struct HmacSha512; #[cfg(feature = "hmac-sha512")] mod hmacsha512; #[cfg(feature = "p256")] -pub struct P256 {} +pub struct P256; #[cfg(feature = "p256")] -pub struct P256Prehashed {} +pub struct P256Prehashed; #[cfg(feature = "p256")] mod p256; #[cfg(feature = "p384")] -pub struct P384 {} +pub struct P384; #[cfg(feature = "p384")] -pub struct P384Prehashed {} +pub struct P384Prehashed; #[cfg(feature = "p384")] mod p384; #[cfg(feature = "p521")] -pub struct P521 {} +pub struct P521; #[cfg(feature = "p521")] -pub struct P521Prehashed {} +pub struct P521Prehashed; #[cfg(feature = "p521")] mod p521; #[cfg(feature = "sha256")] -pub struct Sha256 {} +pub struct Sha256; #[cfg(feature = "sha256")] mod sha256; #[cfg(feature = "tdes")] -pub struct Tdes {} +pub struct Tdes; #[cfg(feature = "tdes")] mod tdes; #[cfg(feature = "totp")] -pub struct Totp {} +pub struct Totp; #[cfg(feature = "totp")] mod totp; #[cfg(feature = "trng")] -pub struct Trng {} +pub struct Trng; #[cfg(feature = "trng")] mod trng; #[cfg(feature = "x255")] -pub struct X255 {} +pub struct X255; #[cfg(feature = "x255")] mod x255; - -// pub enum MechanismEnum { -// NotImplemented, -// Ed255(ed255::Ed255), -// P256(p256::P256), -// } - -// use crate::types::Mechanism; -// pub fn enum_to_type(mechanism: Mechanism) -> MechanismEnum { -// match mechanism { -// #[cfg(feature = "ed255")] -// Mechanism::Ed255 => MechanismEnum::Ed255(ed255::Ed255 {} ), -// #[cfg(feature = "p256")] -// Mechanism::P256 => MechanismEnum::P256(p256::P256 {} ), -// _ => MechanismEnum::NotImplemented, -// } -// } diff --git a/src/mechanisms/aes256cbc.rs b/src/mechanisms/aes256cbc.rs index 01f83ea3d78..81993a0d9c4 100644 --- a/src/mechanisms/aes256cbc.rs +++ b/src/mechanisms/aes256cbc.rs @@ -1,15 +1,16 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{Decrypt, Encrypt, UnsafeInjectKey, WrapKey}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::{Mechanism, Message, ShortData}; const AES256_KEY_SIZE: usize = 32; -impl Encrypt for super::Aes256Cbc { +impl MechanismImpl for super::Aes256Cbc { /// Encrypts the input *with zero IV* fn encrypt( + &self, keystore: &mut impl Keystore, request: &request::Encrypt, ) -> Result { @@ -63,10 +64,9 @@ impl Encrypt for super::Aes256Cbc { tag: ShortData::new(), }) } -} -impl WrapKey for super::Aes256Cbc { fn wrap_key( + &self, keystore: &mut impl Keystore, request: &request::WrapKey, ) -> Result { @@ -91,16 +91,15 @@ impl WrapKey for super::Aes256Cbc { associated_data: request.associated_data.clone(), nonce: request.nonce.clone(), }; - let encryption_reply = ::encrypt(keystore, &encryption_request)?; + let encryption_reply = self.encrypt(keystore, &encryption_request)?; let wrapped_key = encryption_reply.ciphertext; Ok(reply::WrapKey { wrapped_key }) } -} -impl Decrypt for super::Aes256Cbc { fn decrypt( + &self, keystore: &mut impl Keystore, request: &request::Decrypt, ) -> Result { @@ -155,10 +154,9 @@ impl Decrypt for super::Aes256Cbc { plaintext: Some(plaintext), }) } -} -impl UnsafeInjectKey for super::Aes256Cbc { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { diff --git a/src/mechanisms/chacha8poly1305.rs b/src/mechanisms/chacha8poly1305.rs index 2b072887216..422a3dd4c71 100644 --- a/src/mechanisms/chacha8poly1305.rs +++ b/src/mechanisms/chacha8poly1305.rs @@ -5,7 +5,7 @@ use trussed_core::types::EncryptedData; use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{Decrypt, Encrypt, GenerateKey, UnwrapKey, WrapKey}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::{Mechanism, Message, ShortData}; @@ -20,9 +20,26 @@ const TAG_LEN: usize = 16; const KIND: key::Kind = key::Kind::Symmetric(KEY_LEN); const KIND_NONCE: key::Kind = key::Kind::Symmetric32Nonce(NONCE_LEN); -impl GenerateKey for super::Chacha8Poly1305 { +#[inline(never)] +fn increment_nonce(nonce: &mut [u8]) -> Result<(), Error> { + assert_eq!(nonce.len(), NONCE_LEN); + let mut carry: u16 = 1; + for digit in nonce.iter_mut() { + let x = (*digit as u16) + carry; + *digit = x as u8; + carry = x >> 8; + } + if carry == 0 { + Ok(()) + } else { + Err(Error::NonceOverflow) + } +} + +impl MechanismImpl for super::Chacha8Poly1305 { #[inline(never)] fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { @@ -45,27 +62,10 @@ impl GenerateKey for super::Chacha8Poly1305 { Ok(reply::GenerateKey { key: key_id }) } -} -#[inline(never)] -fn increment_nonce(nonce: &mut [u8]) -> Result<(), Error> { - assert_eq!(nonce.len(), NONCE_LEN); - let mut carry: u16 = 1; - for digit in nonce.iter_mut() { - let x = (*digit as u16) + carry; - *digit = x as u8; - carry = x >> 8; - } - if carry == 0 { - Ok(()) - } else { - Err(Error::NonceOverflow) - } -} - -impl Decrypt for super::Chacha8Poly1305 { #[inline(never)] fn decrypt( + &self, keystore: &mut impl Keystore, request: &request::Decrypt, ) -> Result { @@ -103,12 +103,10 @@ impl Decrypt for super::Chacha8Poly1305 { }, }) } -} -#[cfg(feature = "chacha8-poly1305")] -impl Encrypt for super::Chacha8Poly1305 { #[inline(never)] fn encrypt( + &self, keystore: &mut impl Keystore, request: &request::Encrypt, ) -> Result { @@ -164,11 +162,10 @@ impl Encrypt for super::Chacha8Poly1305 { tag, }) } -} -impl WrapKey for super::Chacha8Poly1305 { #[inline(never)] fn wrap_key( + &self, keystore: &mut impl Keystore, request: &request::WrapKey, ) -> Result { @@ -186,7 +183,7 @@ impl WrapKey for super::Chacha8Poly1305 { associated_data: request.associated_data.clone(), nonce: request.nonce.clone(), }; - let encryption_reply = ::encrypt(keystore, &encryption_request)?; + let encryption_reply = self.encrypt(keystore, &encryption_request)?; let wrapped_key = EncryptedData::from(encryption_reply); let wrapped_key = @@ -194,11 +191,10 @@ impl WrapKey for super::Chacha8Poly1305 { Ok(reply::WrapKey { wrapped_key }) } -} -impl UnwrapKey for super::Chacha8Poly1305 { #[inline(never)] fn unwrap_key( + &self, keystore: &mut impl Keystore, request: &request::UnwrapKey, ) -> Result { @@ -211,13 +207,12 @@ impl UnwrapKey for super::Chacha8Poly1305 { request.associated_data.clone(), ); - let serialized_key = if let Some(serialized_key) = - ::decrypt(keystore, &decryption_request)?.plaintext - { - serialized_key - } else { - return Ok(reply::UnwrapKey { key: None }); - }; + let serialized_key = + if let Some(serialized_key) = self.decrypt(keystore, &decryption_request)?.plaintext { + serialized_key + } else { + return Ok(reply::UnwrapKey { key: None }); + }; // TODO: probably change this to returning Option too let key::Key { diff --git a/src/mechanisms/ed255.rs b/src/mechanisms/ed255.rs index d3f9cd8a88e..13136ced79b 100644 --- a/src/mechanisms/ed255.rs +++ b/src/mechanisms/ed255.rs @@ -3,9 +3,7 @@ use rand_core::RngCore; use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{ - DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, Verify, -}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::{ Bytes, KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization, @@ -43,9 +41,10 @@ fn load_keypair(keystore: &mut impl Keystore, key_id: &KeyId) -> Result Result { @@ -61,11 +60,10 @@ impl DeriveKey for super::Ed255 { Ok(reply::DeriveKey { key: public_id }) } -} -impl DeserializeKey for super::Ed255 { #[inline(never)] fn deserialize_key( + &self, keystore: &mut impl Keystore, request: &request::DeserializeKey, ) -> Result { @@ -94,11 +92,10 @@ impl DeserializeKey for super::Ed255 { Ok(reply::DeserializeKey { key: public_id }) } -} -impl GenerateKey for super::Ed255 { #[inline(never)] fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { @@ -120,11 +117,10 @@ impl GenerateKey for super::Ed255 { // return handle Ok(reply::GenerateKey { key: key_id }) } -} -impl SerializeKey for super::Ed255 { #[inline(never)] fn serialize_key( + &self, keystore: &mut impl Keystore, request: &request::SerializeKey, ) -> Result { @@ -157,11 +153,10 @@ impl SerializeKey for super::Ed255 { Ok(reply::SerializeKey { serialized_key }) } -} -impl Exists for super::Ed255 { #[inline(never)] fn exists( + &self, keystore: &mut impl Keystore, request: &request::Exists, ) -> Result { @@ -170,11 +165,13 @@ impl Exists for super::Ed255 { let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::Ed255), &key_id); Ok(reply::Exists { exists }) } -} -impl Sign for super::Ed255 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { // Not so nice, expands to // `trussed::/home/nicolas/projects/solo-bee/components/trussed/src/mechanisms/ed255.rs:151 // Ed255::Sign`, i.e. VEERY long @@ -202,11 +199,10 @@ impl Sign for super::Ed255 { signature: our_signature, }) } -} -impl Verify for super::Ed255 { #[inline(never)] fn verify( + &self, keystore: &mut impl Keystore, request: &request::Verify, ) -> Result { @@ -232,10 +228,9 @@ impl Verify for super::Ed255 { .is_ok(), }) } -} -impl UnsafeInjectKey for super::Ed255 { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { diff --git a/src/mechanisms/hmacblake2s.rs b/src/mechanisms/hmacblake2s.rs index b1f8a3c98da..930568fe5dd 100644 --- a/src/mechanisms/hmacblake2s.rs +++ b/src/mechanisms/hmacblake2s.rs @@ -1,13 +1,14 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{DeriveKey, Sign}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::Signature; -impl DeriveKey for super::HmacBlake2s { +impl MechanismImpl for super::HmacBlake2s { #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -37,11 +38,13 @@ impl DeriveKey for super::HmacBlake2s { Ok(reply::DeriveKey { key }) } -} -impl Sign for super::HmacBlake2s { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { use blake2::Blake2s256; use hmac::{Mac, SimpleHmac}; type HmacBlake2s = SimpleHmac; diff --git a/src/mechanisms/hmacsha1.rs b/src/mechanisms/hmacsha1.rs index b73d7e158c6..4d5259329db 100644 --- a/src/mechanisms/hmacsha1.rs +++ b/src/mechanisms/hmacsha1.rs @@ -1,13 +1,14 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{DeriveKey, Sign}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::Signature; -impl DeriveKey for super::HmacSha1 { +impl MechanismImpl for super::HmacSha1 { #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -37,11 +38,13 @@ impl DeriveKey for super::HmacSha1 { Ok(reply::DeriveKey { key: key_id }) } -} -impl Sign for super::HmacSha1 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { use hmac::{Hmac, Mac}; use sha1::Sha1; type HmacSha1 = Hmac; diff --git a/src/mechanisms/hmacsha256.rs b/src/mechanisms/hmacsha256.rs index 8e120956bb4..034aca3a89a 100644 --- a/src/mechanisms/hmacsha256.rs +++ b/src/mechanisms/hmacsha256.rs @@ -1,13 +1,14 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{DeriveKey, Sign}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::Signature; -impl DeriveKey for super::HmacSha256 { +impl MechanismImpl for super::HmacSha256 { #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -42,11 +43,13 @@ impl DeriveKey for super::HmacSha256 { Ok(reply::DeriveKey { key: key_id }) } -} -impl Sign for super::HmacSha256 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { use hmac::{Hmac, Mac}; use sha2::Sha256; type HmacSha256 = Hmac; diff --git a/src/mechanisms/hmacsha512.rs b/src/mechanisms/hmacsha512.rs index be037eea3c7..95a247e5f61 100644 --- a/src/mechanisms/hmacsha512.rs +++ b/src/mechanisms/hmacsha512.rs @@ -1,13 +1,14 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{DeriveKey, Sign}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::Signature; -impl DeriveKey for super::HmacSha512 { +impl MechanismImpl for super::HmacSha512 { #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -37,11 +38,13 @@ impl DeriveKey for super::HmacSha512 { Ok(reply::DeriveKey { key }) } -} -impl Sign for super::HmacSha512 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { use hmac::{Hmac, Mac}; use sha2::Sha512; type HmacSha512 = Hmac; diff --git a/src/mechanisms/p256.rs b/src/mechanisms/p256.rs index b2ea0813fb7..e0e6a2d0c91 100644 --- a/src/mechanisms/p256.rs +++ b/src/mechanisms/p256.rs @@ -1,10 +1,7 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, - Verify, -}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::{ Bytes, KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization, @@ -44,9 +41,10 @@ fn load_public_key( .map_err(|_| Error::InternalError) } -impl Agree for super::P256 { +impl MechanismImpl for super::P256 { #[inline(never)] fn agree( + &self, keystore: &mut impl Keystore, request: &request::Agree, ) -> Result { @@ -80,11 +78,10 @@ impl Agree for super::P256 { shared_secret: key_id, }) } -} -impl DeriveKey for super::P256 { #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -102,11 +99,10 @@ impl DeriveKey for super::P256 { Ok(reply::DeriveKey { key: public_id }) } -} -impl DeserializeKey for super::P256 { #[inline(never)] fn deserialize_key( + &self, keystore: &mut impl Keystore, request: &request::DeserializeKey, ) -> Result { @@ -175,11 +171,10 @@ impl DeserializeKey for super::P256 { Ok(reply::DeserializeKey { key: public_id }) } -} -impl GenerateKey for super::P256 { #[inline(never)] fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { @@ -196,11 +191,10 @@ impl GenerateKey for super::P256 { // return handle Ok(reply::GenerateKey { key: key_id }) } -} -impl SerializeKey for super::P256 { #[inline(never)] fn serialize_key( + &self, keystore: &mut impl Keystore, request: &request::SerializeKey, ) -> Result { @@ -245,11 +239,10 @@ impl SerializeKey for super::P256 { Ok(reply::SerializeKey { serialized_key }) } -} -impl Exists for super::P256 { #[inline(never)] fn exists( + &self, keystore: &mut impl Keystore, request: &request::Exists, ) -> Result { @@ -257,11 +250,13 @@ impl Exists for super::P256 { let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::P256), &key_id); Ok(reply::Exists { exists }) } -} -impl Sign for super::P256 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { let key_id = request.key; let secret_key = load_secret_key(keystore, &key_id)?; @@ -287,41 +282,10 @@ impl Sign for super::P256 { signature: serialized_signature, }) } -} -impl Sign for super::P256Prehashed { - #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { - let key_id = request.key; - - let secret_key = load_secret_key(keystore, &key_id)?; - let signature = secret_key.sign_prehashed(&request.message, keystore.rng()); - - // debug_now!("making signature"); - let serialized_signature = match request.format { - SignatureSerialization::Asn1Der => { - let mut buffer = [0u8; 72]; - let l = signature.to_sec1_bytes(&mut buffer); - Signature::from_slice(&buffer[..l]).unwrap() - } - SignatureSerialization::Raw => { - Signature::from_slice(&signature.to_untagged_bytes()).unwrap() - } - _ => { - return Err(Error::InvalidSerializationFormat); - } - }; - - // return signature - Ok(reply::Sign { - signature: serialized_signature, - }) - } -} - -impl Verify for super::P256 { #[inline(never)] fn verify( + &self, keystore: &mut impl Keystore, request: &request::Verify, ) -> Result { @@ -342,10 +306,9 @@ impl Verify for super::P256 { let valid = public_key.verify(&request.message, &signature); Ok(reply::Verify { valid }) } -} -impl UnsafeInjectKey for super::P256 { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { @@ -371,3 +334,37 @@ impl UnsafeInjectKey for super::P256 { .map(|key| reply::UnsafeInjectKey { key }) } } + +impl MechanismImpl for super::P256Prehashed { + #[inline(never)] + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { + let key_id = request.key; + + let secret_key = load_secret_key(keystore, &key_id)?; + let signature = secret_key.sign_prehashed(&request.message, keystore.rng()); + + // debug_now!("making signature"); + let serialized_signature = match request.format { + SignatureSerialization::Asn1Der => { + let mut buffer = [0u8; 72]; + let l = signature.to_sec1_bytes(&mut buffer); + Signature::from_slice(&buffer[..l]).unwrap() + } + SignatureSerialization::Raw => { + Signature::from_slice(&signature.to_untagged_bytes()).unwrap() + } + _ => { + return Err(Error::InvalidSerializationFormat); + } + }; + + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) + } +} diff --git a/src/mechanisms/p384.rs b/src/mechanisms/p384.rs index 775cb3cf35e..91eaf6b488e 100644 --- a/src/mechanisms/p384.rs +++ b/src/mechanisms/p384.rs @@ -12,10 +12,7 @@ use super::{P384Prehashed, P384}; use crate::{ api::{reply, request}, key, - service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, - Verify, - }, + service::MechanismImpl, store::keystore::Keystore, types::{KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization}, Error, @@ -52,8 +49,9 @@ fn to_sec1_bytes(public_key: &p384::PublicKey) -> heapless::Vec Result { @@ -85,10 +83,10 @@ impl Agree for P384 { shared_secret: key_id, }) } -} -impl DeriveKey for P384 { + #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -106,10 +104,10 @@ impl DeriveKey for P384 { Ok(reply::DeriveKey { key: public_id }) } -} -impl DeserializeKey for P384 { + #[inline(never)] fn deserialize_key( + &self, keystore: &mut impl Keystore, request: &request::DeserializeKey, ) -> Result { @@ -144,10 +142,10 @@ impl DeserializeKey for P384 { Ok(reply::DeserializeKey { key: public_id }) } -} -impl SerializeKey for P384 { + #[inline(never)] fn serialize_key( + &self, keystore: &mut impl Keystore, request: &request::SerializeKey, ) -> Result { @@ -179,10 +177,10 @@ impl SerializeKey for P384 { Ok(reply::SerializeKey { serialized_key }) } -} -impl Exists for P384 { + #[inline(never)] fn exists( + &self, keystore: &mut impl Keystore, request: &request::Exists, ) -> Result { @@ -190,11 +188,13 @@ impl Exists for P384 { let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::P384), &key_id); Ok(reply::Exists { exists }) } -} -impl Sign for P384 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { let key_id = request.key; let secret_key = load_secret_key(keystore, &key_id)?; @@ -219,39 +219,9 @@ impl Sign for P384 { signature: serialized_signature, }) } -} -impl Sign for P384Prehashed { - #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { - let key_id = request.key; - - let secret_key = load_secret_key(keystore, &key_id)?; - let signing_key = SigningKey::from(secret_key); - let signature: p384::ecdsa::Signature = signing_key - .sign_prehash_with_rng(keystore.rng(), &request.message) - .map_err(|_| Error::InvalidSerializedRequest)?; - - // debug_now!("making signature"); - let serialized_signature = match request.format { - SignatureSerialization::Asn1Der => { - let der = signature.to_der(); - Signature::from_slice(der.as_bytes()).unwrap() - } - SignatureSerialization::Raw => Signature::from_slice(&signature.to_bytes()).unwrap(), - _ => { - return Err(Error::InvalidSerializationFormat); - } - }; - // return signature - Ok(reply::Sign { - signature: serialized_signature, - }) - } -} - -impl UnsafeInjectKey for P384 { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { @@ -276,11 +246,10 @@ impl UnsafeInjectKey for P384 { ) .map(|key| reply::UnsafeInjectKey { key }) } -} -impl Verify for P384 { #[inline(never)] fn verify( + &self, keystore: &mut impl Keystore, request: &request::Verify, ) -> Result { @@ -303,9 +272,9 @@ impl Verify for P384 { let valid = verifying_key.verify(&request.message, &signature).is_ok(); Ok(reply::Verify { valid }) } -} -impl GenerateKey for P384 { + fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { @@ -322,3 +291,37 @@ impl GenerateKey for P384 { Ok(reply::GenerateKey { key: key_id }) } } + +impl MechanismImpl for P384Prehashed { + #[inline(never)] + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { + let key_id = request.key; + + let secret_key = load_secret_key(keystore, &key_id)?; + let signing_key = SigningKey::from(secret_key); + let signature: p384::ecdsa::Signature = signing_key + .sign_prehash_with_rng(keystore.rng(), &request.message) + .map_err(|_| Error::InvalidSerializedRequest)?; + + // debug_now!("making signature"); + let serialized_signature = match request.format { + SignatureSerialization::Asn1Der => { + let der = signature.to_der(); + Signature::from_slice(der.as_bytes()).unwrap() + } + SignatureSerialization::Raw => Signature::from_slice(&signature.to_bytes()).unwrap(), + _ => { + return Err(Error::InvalidSerializationFormat); + } + }; + + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) + } +} diff --git a/src/mechanisms/p521.rs b/src/mechanisms/p521.rs index 9f45fd84bae..227eab2947b 100644 --- a/src/mechanisms/p521.rs +++ b/src/mechanisms/p521.rs @@ -12,10 +12,7 @@ use super::{P521Prehashed, P521}; use crate::{ api::{reply, request}, key, - service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, - Verify, - }, + service::MechanismImpl, store::keystore::Keystore, types::{KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization}, Error, @@ -52,8 +49,9 @@ fn to_sec1_bytes(public_key: &p521::PublicKey) -> heapless::Vec Result { @@ -87,10 +85,10 @@ impl Agree for P521 { shared_secret: key_id, }) } -} -impl DeriveKey for P521 { + #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -108,10 +106,10 @@ impl DeriveKey for P521 { Ok(reply::DeriveKey { key: public_id }) } -} -impl DeserializeKey for P521 { + #[inline(never)] fn deserialize_key( + &self, keystore: &mut impl Keystore, request: &request::DeserializeKey, ) -> Result { @@ -146,10 +144,10 @@ impl DeserializeKey for P521 { Ok(reply::DeserializeKey { key: public_id }) } -} -impl SerializeKey for P521 { + #[inline(never)] fn serialize_key( + &self, keystore: &mut impl Keystore, request: &request::SerializeKey, ) -> Result { @@ -181,10 +179,10 @@ impl SerializeKey for P521 { Ok(reply::SerializeKey { serialized_key }) } -} -impl Exists for P521 { + #[inline(never)] fn exists( + &self, keystore: &mut impl Keystore, request: &request::Exists, ) -> Result { @@ -192,11 +190,13 @@ impl Exists for P521 { let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::P521), &key_id); Ok(reply::Exists { exists }) } -} -impl Sign for P521 { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { let key_id = request.key; let secret_key = load_secret_key(keystore, &key_id)?; @@ -222,39 +222,9 @@ impl Sign for P521 { signature: serialized_signature, }) } -} -impl Sign for P521Prehashed { - #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { - let key_id = request.key; - - let secret_key = load_secret_key(keystore, &key_id)?; - let signing_key = SigningKey::from(ecdsa::SigningKey::from(secret_key)); - let signature: p521::ecdsa::Signature = signing_key - .sign_prehash_with_rng(keystore.rng(), &request.message) - .map_err(|_| Error::InvalidSerializedRequest)?; - - // debug_now!("making signature"); - let serialized_signature = match request.format { - SignatureSerialization::Asn1Der => { - let der = signature.to_der(); - Signature::from_slice(der.as_bytes()).unwrap() - } - SignatureSerialization::Raw => Signature::from_slice(&signature.to_bytes()).unwrap(), - _ => { - return Err(Error::InvalidSerializationFormat); - } - }; - - // return signature - Ok(reply::Sign { - signature: serialized_signature, - }) - } -} -impl UnsafeInjectKey for P521 { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { @@ -279,11 +249,10 @@ impl UnsafeInjectKey for P521 { ) .map(|key| reply::UnsafeInjectKey { key }) } -} -impl Verify for P521 { #[inline(never)] fn verify( + &self, keystore: &mut impl Keystore, request: &request::Verify, ) -> Result { @@ -306,10 +275,9 @@ impl Verify for P521 { let valid = verifying_key.verify(&request.message, &signature).is_ok(); Ok(reply::Verify { valid }) } -} -impl GenerateKey for P521 { fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { @@ -326,3 +294,37 @@ impl GenerateKey for P521 { Ok(reply::GenerateKey { key: key_id }) } } + +impl MechanismImpl for P521Prehashed { + #[inline(never)] + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { + let key_id = request.key; + + let secret_key = load_secret_key(keystore, &key_id)?; + let signing_key = SigningKey::from(ecdsa::SigningKey::from(secret_key)); + let signature: p521::ecdsa::Signature = signing_key + .sign_prehash_with_rng(keystore.rng(), &request.message) + .map_err(|_| Error::InvalidSerializedRequest)?; + + // debug_now!("making signature"); + let serialized_signature = match request.format { + SignatureSerialization::Asn1Der => { + let der = signature.to_der(); + Signature::from_slice(der.as_bytes()).unwrap() + } + SignatureSerialization::Raw => Signature::from_slice(&signature.to_bytes()).unwrap(), + _ => { + return Err(Error::InvalidSerializationFormat); + } + }; + + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) + } +} diff --git a/src/mechanisms/sha256.rs b/src/mechanisms/sha256.rs index 92460277fe2..a2e2213a3cf 100644 --- a/src/mechanisms/sha256.rs +++ b/src/mechanisms/sha256.rs @@ -1,13 +1,14 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{DeriveKey, Hash}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::ShortData; -impl DeriveKey for super::Sha256 { +impl MechanismImpl for super::Sha256 { #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -32,11 +33,13 @@ impl DeriveKey for super::Sha256 { Ok(reply::DeriveKey { key: key_id }) } -} -impl Hash for super::Sha256 { #[inline(never)] - fn hash(_keystore: &mut impl Keystore, request: &request::Hash) -> Result { + fn hash( + &self, + _keystore: &mut impl Keystore, + request: &request::Hash, + ) -> Result { use sha2::digest::Digest; let mut hash = sha2::Sha256::new(); hash.update(&request.message); diff --git a/src/mechanisms/shared_secret.rs b/src/mechanisms/shared_secret.rs index 904654604bc..76097bc52d8 100644 --- a/src/mechanisms/shared_secret.rs +++ b/src/mechanisms/shared_secret.rs @@ -1,13 +1,14 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{SerializeKey, UnsafeInjectKey}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::{KeySerialization, SerializedKey}; -impl SerializeKey for super::SharedSecret { +impl MechanismImpl for super::SharedSecret { #[inline(never)] fn serialize_key( + &self, keystore: &mut impl Keystore, request: &request::SerializeKey, ) -> Result { @@ -28,10 +29,9 @@ impl SerializeKey for super::SharedSecret { Ok(reply::SerializeKey { serialized_key }) } -} -impl UnsafeInjectKey for super::SharedSecret { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { diff --git a/src/mechanisms/tdes.rs b/src/mechanisms/tdes.rs index 51a63efc6d1..829de59549d 100644 --- a/src/mechanisms/tdes.rs +++ b/src/mechanisms/tdes.rs @@ -12,15 +12,16 @@ use generic_array::GenericArray; use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{Decrypt, Encrypt, UnsafeInjectKey}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; const TDES_KEY_SIZE: usize = 24; -impl Encrypt for super::Tdes { +impl MechanismImpl for super::Tdes { /// Encrypts a single block. Let's hope we don't have to support ECB!! #[inline(never)] fn encrypt( + &self, keystore: &mut impl Keystore, request: &request::Encrypt, ) -> Result { @@ -57,12 +58,11 @@ impl Encrypt for super::Tdes { tag: Default::default(), }) } -} -impl Decrypt for super::Tdes { /// Decrypts a single block. Let's hope we don't have to support ECB!! #[inline(never)] fn decrypt( + &self, keystore: &mut impl Keystore, request: &request::Decrypt, ) -> Result { @@ -88,10 +88,9 @@ impl Decrypt for super::Tdes { plaintext: Some(message), }) } -} -impl UnsafeInjectKey for super::Tdes { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { diff --git a/src/mechanisms/totp.rs b/src/mechanisms/totp.rs index c38c3662ef9..e7015af5cc8 100644 --- a/src/mechanisms/totp.rs +++ b/src/mechanisms/totp.rs @@ -1,7 +1,7 @@ use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{Exists, Sign}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; // code copied from https://github.com/avacariu/rust-oath @@ -44,9 +44,13 @@ fn dynamic_truncation(hs: &[u8]) -> u64 { p & 0x7fff_ffff } -impl Sign for super::Totp { +impl MechanismImpl for super::Totp { #[inline(never)] - fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { + fn sign( + &self, + keystore: &mut impl Keystore, + request: &request::Sign, + ) -> Result { let key_id = request.key; let key = keystore.load_key(key::Secrecy::Secret, None, &key_id)?; @@ -72,11 +76,10 @@ impl Sign for super::Totp { signature: crate::Bytes::from_slice(totp_material.to_le_bytes().as_ref()).unwrap(), }) } -} -impl Exists for super::Totp { #[inline(never)] fn exists( + &self, keystore: &mut impl Keystore, request: &request::Exists, ) -> Result { diff --git a/src/mechanisms/trng.rs b/src/mechanisms/trng.rs index 2550d52c7d8..a2ba95cdd77 100644 --- a/src/mechanisms/trng.rs +++ b/src/mechanisms/trng.rs @@ -3,11 +3,12 @@ use rand_core::RngCore; use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::GenerateKey; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; -impl GenerateKey for super::Trng { +impl MechanismImpl for super::Trng { fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { diff --git a/src/mechanisms/x255.rs b/src/mechanisms/x255.rs index 0cf53ea6a6e..cf9fe86f13a 100644 --- a/src/mechanisms/x255.rs +++ b/src/mechanisms/x255.rs @@ -4,9 +4,7 @@ use salty::agreement; use crate::api::{reply, request}; use crate::error::Error; use crate::key; -use crate::service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, UnsafeInjectKey, -}; +use crate::service::MechanismImpl; use crate::store::keystore::Keystore; use crate::types::{KeyId, KeySerialization, SerializedKey}; @@ -41,9 +39,10 @@ fn load_secret_key( Ok(keypair) } -impl Agree for super::X255 { +impl MechanismImpl for super::X255 { // #[inline(never)] fn agree( + &self, keystore: &mut impl Keystore, request: &request::Agree, ) -> Result { @@ -75,11 +74,10 @@ impl Agree for super::X255 { shared_secret: key_id, }) } -} -impl GenerateKey for super::X255 { // #[inline(never)] fn generate_key( + &self, keystore: &mut impl Keystore, request: &request::GenerateKey, ) -> Result { @@ -98,11 +96,10 @@ impl GenerateKey for super::X255 { // return handle Ok(reply::GenerateKey { key: key_id }) } -} -impl Exists for super::X255 { // #[inline(never)] fn exists( + &self, keystore: &mut impl Keystore, request: &request::Exists, ) -> Result { @@ -110,11 +107,10 @@ impl Exists for super::X255 { let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::X255), &key_id); Ok(reply::Exists { exists }) } -} -impl DeriveKey for super::X255 { // #[inline(never)] fn derive_key( + &self, keystore: &mut impl Keystore, request: &request::DeriveKey, ) -> Result { @@ -133,11 +129,10 @@ impl DeriveKey for super::X255 { Ok(reply::DeriveKey { key: public_id }) } -} -impl SerializeKey for super::X255 { // #[inline(never)] fn serialize_key( + &self, keystore: &mut impl Keystore, request: &request::SerializeKey, ) -> Result { @@ -159,11 +154,10 @@ impl SerializeKey for super::X255 { Ok(reply::SerializeKey { serialized_key }) } -} -impl DeserializeKey for super::X255 { // #[inline(never)] fn deserialize_key( + &self, keystore: &mut impl Keystore, request: &request::DeserializeKey, ) -> Result { @@ -192,10 +186,9 @@ impl DeserializeKey for super::X255 { Ok(reply::DeserializeKey { key: public_id }) } -} -impl UnsafeInjectKey for super::X255 { fn unsafe_inject_key( + &self, keystore: &mut impl Keystore, request: &request::UnsafeInjectKey, ) -> Result { diff --git a/src/service.rs b/src/service.rs index 950c7af203d..f959e8817d6 100644 --- a/src/service.rs +++ b/src/service.rs @@ -29,31 +29,145 @@ pub mod attest; // mod macros; #[cfg(feature = "crypto-client")] -macro_rules! rpc_trait { ($($Name:ident, $name:ident,)*) => { $( +macro_rules! impl_mechanisms { + { + [ + $( + #[cfg($($cfg_cond:tt)*)] + $mechanism:ident, + )* + ] + } => { + pub const IMPLEMENTED_MECHANISMS: &[Mechanism] = &[ + $( + #[cfg($($cfg_cond)*)] + Mechanism::$mechanism, + )* + ]; + } +} + +#[cfg(feature = "crypto-client")] +macro_rules! impl_rpc_method { + { + $struct:ident, + $method:ident, + mechanisms = [$( + #[cfg($($cfg_cond:tt)*)] + $mechanism:ident, + )*], + } => { + #[inline(never)] + fn $method( + &self, + keystore: &mut impl Keystore, + request: &request::$struct, + ) -> Result { + match self { + $( + #[cfg($($cfg_cond)*)] + Self::$mechanism => mechanisms::$mechanism.$method(keystore, request), + )* + _ => Err(Error::MechanismNotAvailable), + } + } + } +} + +#[cfg(feature = "crypto-client")] +macro_rules! rpc_trait { + { + methods = [$($method:ident: $struct:ident,)*], + mechanisms = $mechanisms:tt, + } => { + pub trait MechanismImpl { + $( + fn $method( + &self, + keystore: &mut impl Keystore, + request: &request::$struct, + ) -> Result { + let _ = (keystore, request); + Err(Error::MechanismNotAvailable) + } + )* + } + + impl MechanismImpl for Mechanism { + $( + impl_rpc_method! { + $struct, + $method, + mechanisms = $mechanisms, + } + )* + } - pub trait $Name { - fn $name(_keystore: &mut impl Keystore, _request: &request::$Name) - -> Result { Err(Error::MechanismNotAvailable) } + impl_mechanisms! { + $mechanisms + } } -)* } } +} #[cfg(feature = "crypto-client")] rpc_trait! { - Agree, agree, - Decrypt, decrypt, - DeriveKey, derive_key, - DeserializeKey, deserialize_key, - Encrypt, encrypt, - Exists, exists, - GenerateKey, generate_key, - Hash, hash, - SerializeKey, serialize_key, - Sign, sign, - UnsafeInjectKey, unsafe_inject_key, - UnwrapKey, unwrap_key, - Verify, verify, - // TODO: can the default implementation be implemented in terms of Encrypt? - WrapKey, wrap_key, + methods = [ + agree: Agree, + decrypt: Decrypt, + derive_key: DeriveKey, + deserialize_key: DeserializeKey, + encrypt: Encrypt, + exists: Exists, + generate_key: GenerateKey, + hash: Hash, + serialize_key: SerializeKey, + sign: Sign, + unsafe_inject_key: UnsafeInjectKey, + unwrap_key: UnwrapKey, + verify: Verify, + // TODO: can the default implementation be implemented in terms of Encrypt? + wrap_key: WrapKey, + ], + mechanisms = [ + #[cfg(feature = "aes256-cbc")] + Aes256Cbc, + #[cfg(feature = "chacha8-poly1305")] + Chacha8Poly1305, + #[cfg(feature = "ed255")] + Ed255, + #[cfg(feature = "hmac-blake2s")] + HmacBlake2s, + #[cfg(feature = "hmac-sha1")] + HmacSha1, + #[cfg(feature = "hmac-sha256")] + HmacSha256, + #[cfg(feature = "hmac-sha512")] + HmacSha512, + #[cfg(feature = "p256")] + P256, + #[cfg(feature = "p256")] + P256Prehashed, + #[cfg(feature = "p384")] + P384, + #[cfg(feature = "p384")] + P384Prehashed, + #[cfg(feature = "p521")] + P521, + #[cfg(feature = "p521")] + P521Prehashed, + #[cfg(feature = "sha256")] + Sha256, + #[cfg(feature = "shared-secret")] + SharedSecret, + #[cfg(feature = "tdes")] + Tdes, + #[cfg(feature = "totp")] + Totp, + #[cfg(feature = "trng")] + Trng, + #[cfg(feature = "x255")] + X255, + ], } pub struct ServiceResources

@@ -169,18 +283,10 @@ impl ServiceResources

{ Request::DummyRequest => Ok(Reply::DummyReply), #[cfg(feature = "crypto-client")] - Request::Agree(request) => match request.mechanism { - #[cfg(feature = "p521")] - Mechanism::P521 => mechanisms::P521::agree(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p384")] - Mechanism::P384 => mechanisms::P384::agree(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p256")] - Mechanism::P256 => mechanisms::P256::agree(&mut keystore(self, ctx)?, request), - #[cfg(feature = "x255")] - Mechanism::X255 => mechanisms::X255::agree(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Agree), + Request::Agree(request) => request + .mechanism + .agree(&mut keystore(self, ctx)?, request) + .map(Reply::Agree), #[cfg(feature = "attestation-client")] Request::Attest(request) => { @@ -199,100 +305,28 @@ impl ServiceResources

{ } #[cfg(feature = "crypto-client")] - Request::Decrypt(request) => match request.mechanism { - #[cfg(feature = "aes256-cbc")] - Mechanism::Aes256Cbc => { - mechanisms::Aes256Cbc::decrypt(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "chacha8-poly1305")] - Mechanism::Chacha8Poly1305 => { - mechanisms::Chacha8Poly1305::decrypt(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "tdes")] - Mechanism::Tdes => mechanisms::Tdes::decrypt(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Decrypt), + Request::Decrypt(request) => request + .mechanism + .decrypt(&mut keystore(self, ctx)?, request) + .map(Reply::Decrypt), #[cfg(feature = "crypto-client")] - Request::DeriveKey(request) => match request.mechanism { - #[cfg(feature = "hmac-blake2s")] - Mechanism::HmacBlake2s => { - mechanisms::HmacBlake2s::derive_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "hmac-sha1")] - Mechanism::HmacSha1 => { - mechanisms::HmacSha1::derive_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "hmac-sha256")] - Mechanism::HmacSha256 => { - mechanisms::HmacSha256::derive_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "hmac-sha512")] - Mechanism::HmacSha512 => { - mechanisms::HmacSha512::derive_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "ed255")] - Mechanism::Ed255 => { - mechanisms::Ed255::derive_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p521")] - Mechanism::P521 => mechanisms::P521::derive_key(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p384")] - Mechanism::P384 => mechanisms::P384::derive_key(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p256")] - Mechanism::P256 => mechanisms::P256::derive_key(&mut keystore(self, ctx)?, request), - #[cfg(feature = "sha256")] - Mechanism::Sha256 => { - mechanisms::Sha256::derive_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "x255")] - Mechanism::X255 => mechanisms::X255::derive_key(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::DeriveKey), + Request::DeriveKey(request) => request + .mechanism + .derive_key(&mut keystore(self, ctx)?, request) + .map(Reply::DeriveKey), #[cfg(feature = "crypto-client")] - Request::DeserializeKey(request) => match request.mechanism { - #[cfg(feature = "ed255")] - Mechanism::Ed255 => { - mechanisms::Ed255::deserialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p521")] - Mechanism::P521 => { - mechanisms::P521::deserialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p384")] - Mechanism::P384 => { - mechanisms::P384::deserialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p256")] - Mechanism::P256 => { - mechanisms::P256::deserialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "x255")] - Mechanism::X255 => { - mechanisms::X255::deserialize_key(&mut keystore(self, ctx)?, request) - } - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::DeserializeKey), + Request::DeserializeKey(request) => request + .mechanism + .deserialize_key(&mut keystore(self, ctx)?, request) + .map(Reply::DeserializeKey), #[cfg(feature = "crypto-client")] - Request::Encrypt(request) => match request.mechanism { - #[cfg(feature = "aes256-cbc")] - Mechanism::Aes256Cbc => { - mechanisms::Aes256Cbc::encrypt(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "chacha8-poly1305")] - Mechanism::Chacha8Poly1305 => { - mechanisms::Chacha8Poly1305::encrypt(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "tdes")] - Mechanism::Tdes => mechanisms::Tdes::encrypt(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Encrypt), + Request::Encrypt(request) => request + .mechanism + .encrypt(&mut keystore(self, ctx)?, request) + .map(Reply::Encrypt), #[cfg(feature = "crypto-client")] Request::Delete(request) => { @@ -313,52 +347,16 @@ impl ServiceResources

{ } #[cfg(feature = "crypto-client")] - Request::Exists(request) => match request.mechanism { - #[cfg(feature = "ed255")] - Mechanism::Ed255 => mechanisms::Ed255::exists(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p521")] - Mechanism::P521 => mechanisms::P521::exists(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p384")] - Mechanism::P384 => mechanisms::P384::exists(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p256")] - Mechanism::P256 => mechanisms::P256::exists(&mut keystore(self, ctx)?, request), - #[cfg(feature = "totp")] - Mechanism::Totp => mechanisms::Totp::exists(&mut keystore(self, ctx)?, request), - #[cfg(feature = "x255")] - Mechanism::X255 => mechanisms::X255::exists(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Exists), + Request::Exists(request) => request + .mechanism + .exists(&mut keystore(self, ctx)?, request) + .map(Reply::Exists), #[cfg(feature = "crypto-client")] - Request::GenerateKey(request) => match request.mechanism { - #[cfg(feature = "chacha8-poly1305")] - Mechanism::Chacha8Poly1305 => { - mechanisms::Chacha8Poly1305::generate_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "ed255")] - Mechanism::Ed255 => { - mechanisms::Ed255::generate_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p521")] - Mechanism::P521 => { - mechanisms::P521::generate_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p384")] - Mechanism::P384 => { - mechanisms::P384::generate_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p256")] - Mechanism::P256 => { - mechanisms::P256::generate_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "x255")] - Mechanism::X255 => { - mechanisms::X255::generate_key(&mut keystore(self, ctx)?, request) - } - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::GenerateKey), + Request::GenerateKey(request) => request + .mechanism + .generate_key(&mut keystore(self, ctx)?, request) + .map(Reply::GenerateKey), #[cfg(feature = "crypto-client")] Request::GenerateSecretKey(request) => { @@ -382,42 +380,10 @@ impl ServiceResources

{ // deprecated #[cfg(feature = "crypto-client")] - Request::UnsafeInjectKey(request) => match request.mechanism { - #[cfg(feature = "p521")] - Mechanism::P521 => { - mechanisms::P521::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p384")] - Mechanism::P384 => { - mechanisms::P384::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p256")] - Mechanism::P256 => { - mechanisms::P256::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "x255")] - Mechanism::X255 => { - mechanisms::X255::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "ed255")] - Mechanism::Ed255 => { - mechanisms::Ed255::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "shared-secret")] - Mechanism::SharedSecret => { - mechanisms::SharedSecret::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "aes256-cbc")] - Mechanism::Aes256Cbc => { - mechanisms::Aes256Cbc::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "tdes")] - Mechanism::Tdes => { - mechanisms::Tdes::unsafe_inject_key(&mut keystore(self, ctx)?, request) - } - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::UnsafeInjectKey), + Request::UnsafeInjectKey(request) => request + .mechanism + .unsafe_inject_key(&mut keystore(self, ctx)?, request) + .map(Reply::UnsafeInjectKey), #[cfg(feature = "crypto-client")] Request::UnsafeInjectSharedKey(request) => { @@ -434,12 +400,10 @@ impl ServiceResources

{ } #[cfg(feature = "crypto-client")] - Request::Hash(request) => match request.mechanism { - #[cfg(feature = "sha256")] - Mechanism::Sha256 => mechanisms::Sha256::hash(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Hash), + Request::Hash(request) => request + .mechanism + .hash(&mut keystore(self, ctx)?, request) + .map(Reply::Hash), #[cfg(feature = "filesystem-client")] Request::LocateFile(request) => { @@ -593,78 +557,16 @@ impl ServiceResources

{ } #[cfg(feature = "crypto-client")] - Request::SerializeKey(request) => match request.mechanism { - #[cfg(feature = "ed255")] - Mechanism::Ed255 => { - mechanisms::Ed255::serialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p521")] - Mechanism::P521 => { - mechanisms::P521::serialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p384")] - Mechanism::P384 => { - mechanisms::P384::serialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p256")] - Mechanism::P256 => { - mechanisms::P256::serialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "x255")] - Mechanism::X255 => { - mechanisms::X255::serialize_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "shared-secret")] - Mechanism::SharedSecret => { - mechanisms::SharedSecret::serialize_key(&mut keystore(self, ctx)?, request) - } - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::SerializeKey), + Request::SerializeKey(request) => request + .mechanism + .serialize_key(&mut keystore(self, ctx)?, request) + .map(Reply::SerializeKey), #[cfg(feature = "crypto-client")] - Request::Sign(request) => match request.mechanism { - #[cfg(feature = "ed255")] - Mechanism::Ed255 => mechanisms::Ed255::sign(&mut keystore(self, ctx)?, request), - #[cfg(feature = "hmac-blake2s")] - Mechanism::HmacBlake2s => { - mechanisms::HmacBlake2s::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "hmac-sha1")] - Mechanism::HmacSha1 => { - mechanisms::HmacSha1::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "hmac-sha256")] - Mechanism::HmacSha256 => { - mechanisms::HmacSha256::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "hmac-sha512")] - Mechanism::HmacSha512 => { - mechanisms::HmacSha512::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p521")] - Mechanism::P521 => mechanisms::P521::sign(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p521")] - Mechanism::P521Prehashed => { - mechanisms::P521Prehashed::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p384")] - Mechanism::P384 => mechanisms::P384::sign(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p384")] - Mechanism::P384Prehashed => { - mechanisms::P384Prehashed::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "p256")] - Mechanism::P256 => mechanisms::P256::sign(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p256")] - Mechanism::P256Prehashed => { - mechanisms::P256Prehashed::sign(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "totp")] - Mechanism::Totp => mechanisms::Totp::sign(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Sign), + Request::Sign(request) => request + .mechanism + .sign(&mut keystore(self, ctx)?, request) + .map(Reply::Sign), #[cfg(feature = "filesystem-client")] Request::WriteFile(request) => { @@ -673,42 +575,22 @@ impl ServiceResources

{ } #[cfg(feature = "crypto-client")] - Request::UnwrapKey(request) => match request.mechanism { - #[cfg(feature = "chacha8-poly1305")] - Mechanism::Chacha8Poly1305 => { - mechanisms::Chacha8Poly1305::unwrap_key(&mut keystore(self, ctx)?, request) - } - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::UnwrapKey), + Request::UnwrapKey(request) => request + .mechanism + .unwrap_key(&mut keystore(self, ctx)?, request) + .map(Reply::UnwrapKey), #[cfg(feature = "crypto-client")] - Request::Verify(request) => match request.mechanism { - #[cfg(feature = "ed255")] - Mechanism::Ed255 => mechanisms::Ed255::verify(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p521")] - Mechanism::P521 => mechanisms::P521::verify(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p384")] - Mechanism::P384 => mechanisms::P384::verify(&mut keystore(self, ctx)?, request), - #[cfg(feature = "p256")] - Mechanism::P256 => mechanisms::P256::verify(&mut keystore(self, ctx)?, request), - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::Verify), + Request::Verify(request) => request + .mechanism + .verify(&mut keystore(self, ctx)?, request) + .map(Reply::Verify), #[cfg(feature = "crypto-client")] - Request::WrapKey(request) => match request.mechanism { - #[cfg(feature = "aes256-cbc")] - Mechanism::Aes256Cbc => { - mechanisms::Aes256Cbc::wrap_key(&mut keystore(self, ctx)?, request) - } - #[cfg(feature = "chacha8-poly1305")] - Mechanism::Chacha8Poly1305 => { - mechanisms::Chacha8Poly1305::wrap_key(&mut keystore(self, ctx)?, request) - } - _ => Err(Error::MechanismNotAvailable), - } - .map(Reply::WrapKey), + Request::WrapKey(request) => request + .mechanism + .wrap_key(&mut keystore(self, ctx)?, request) + .map(Reply::WrapKey), #[cfg(feature = "ui-client")] Request::RequestUserConsent(request) => { diff --git a/src/service/attest.rs b/src/service/attest.rs index 08e36d40598..b7feb073573 100644 --- a/src/service/attest.rs +++ b/src/service/attest.rs @@ -9,7 +9,7 @@ use crate::{ api::{reply::Attest as AttestReply, request, request::Attest as AttestRequest}, error::Error, key, mechanisms, - service::{DeriveKey, SerializeKey, Sign}, + service::MechanismImpl, store::certstore::Certstore, store::keystore::Keystore, types::{ @@ -67,26 +67,28 @@ pub fn try_attest( let spki = match key_algorithm { KeyAlgorithm::Ed255 => { - let public_key = mechanisms::Ed255::derive_key( - keystore, - &request::DeriveKey { - mechanism: Mechanism::Ed255, - base_key: request.private_key, - additional_data: None, - attributes: StorageAttributes::new().set_persistence(Location::Volatile), - }, - )? - .key; - let serialized_key = mechanisms::Ed255::serialize_key( - keystore, - &request::SerializeKey { - mechanism: Mechanism::Ed255, - key: public_key, - format: KeySerialization::Raw, - }, - ) - .unwrap() - .serialized_key; + let public_key = mechanisms::Ed255 + .derive_key( + keystore, + &request::DeriveKey { + mechanism: Mechanism::Ed255, + base_key: request.private_key, + additional_data: None, + attributes: StorageAttributes::new().set_persistence(Location::Volatile), + }, + )? + .key; + let serialized_key = mechanisms::Ed255 + .serialize_key( + keystore, + &request::SerializeKey { + mechanism: Mechanism::Ed255, + key: public_key, + format: KeySerialization::Raw, + }, + ) + .unwrap() + .serialized_key; keystore.delete_key(&public_key); SerializedSubjectPublicKey::Ed255( @@ -98,26 +100,28 @@ pub fn try_attest( } KeyAlgorithm::P256 => { - let public_key = mechanisms::P256::derive_key( - keystore, - &request::DeriveKey { - mechanism: Mechanism::P256, - base_key: request.private_key, - additional_data: None, - attributes: StorageAttributes::new().set_persistence(Location::Volatile), - }, - )? - .key; - let serialized_key = mechanisms::P256::serialize_key( - keystore, - &request::SerializeKey { - mechanism: Mechanism::P256, - key: public_key, - format: KeySerialization::Sec1, - }, - ) - .unwrap() - .serialized_key; + let public_key = mechanisms::P256 + .derive_key( + keystore, + &request::DeriveKey { + mechanism: Mechanism::P256, + base_key: request.private_key, + additional_data: None, + attributes: StorageAttributes::new().set_persistence(Location::Volatile), + }, + )? + .key; + let serialized_key = mechanisms::P256 + .serialize_key( + keystore, + &request::SerializeKey { + mechanism: Mechanism::P256, + key: public_key, + format: KeySerialization::Sec1, + }, + ) + .unwrap() + .serialized_key; keystore.delete_key(&public_key); SerializedSubjectPublicKey::P256( @@ -156,33 +160,35 @@ pub fn try_attest( // 2. sign the TBS Cert let signature = match signature_algorithm { SignatureAlgorithm::Ed255 => { - let signature = mechanisms::Ed255::sign( - attn_keystore, - &request::Sign { - mechanism: Mechanism::Ed255, - key: ED255_ATTN_KEY, - message, - format: SignatureSerialization::Raw, - }, - ) - .unwrap() - .signature; - SerializedSignature::Ed255(signature.as_ref().try_into().unwrap()) - } - SignatureAlgorithm::P256 => SerializedSignature::P256( - heapless_bytes::Bytes::from_slice( - mechanisms::P256::sign( + let signature = mechanisms::Ed255 + .sign( attn_keystore, &request::Sign { - mechanism: Mechanism::P256, - key: P256_ATTN_KEY, + mechanism: Mechanism::Ed255, + key: ED255_ATTN_KEY, message, - format: SignatureSerialization::Asn1Der, + format: SignatureSerialization::Raw, }, ) .unwrap() - .signature - .as_ref(), + .signature; + SerializedSignature::Ed255(signature.as_ref().try_into().unwrap()) + } + SignatureAlgorithm::P256 => SerializedSignature::P256( + heapless_bytes::Bytes::from_slice( + mechanisms::P256 + .sign( + attn_keystore, + &request::Sign { + mechanism: Mechanism::P256, + key: P256_ATTN_KEY, + message, + format: SignatureSerialization::Asn1Der, + }, + ) + .unwrap() + .signature + .as_ref(), ) .unwrap(), ), diff --git a/src/types.rs b/src/types.rs index 46f7adbf034..2a419889781 100644 --- a/src/types.rs +++ b/src/types.rs @@ -42,45 +42,6 @@ pub mod consent { pub use trussed_core::types::consent::{Error, Level, Result}; } -pub const IMPLEMENTED_MECHANISMS: &[Mechanism] = &[ - #[cfg(feature = "aes256-cbc")] - Mechanism::Aes256Cbc, - #[cfg(feature = "chacha8-poly1305")] - Mechanism::Chacha8Poly1305, - #[cfg(feature = "ed255")] - Mechanism::Ed255, - #[cfg(feature = "hmac-blake2s")] - Mechanism::HmacBlake2s, - #[cfg(feature = "hmac-sha1")] - Mechanism::HmacSha1, - #[cfg(feature = "hmac-sha256")] - Mechanism::HmacSha256, - #[cfg(feature = "hmac-sha512")] - Mechanism::HmacSha512, - #[cfg(feature = "p256")] - Mechanism::P256, - #[cfg(feature = "p256")] - Mechanism::P256Prehashed, - #[cfg(feature = "p384")] - Mechanism::P384, - #[cfg(feature = "p384")] - Mechanism::P384Prehashed, - #[cfg(feature = "p521")] - Mechanism::P521, - #[cfg(feature = "p521")] - Mechanism::P521Prehashed, - #[cfg(feature = "sha256")] - Mechanism::Sha256, - #[cfg(feature = "shared-secret")] - Mechanism::SharedSecret, - #[cfg(feature = "tdes")] - Mechanism::Tdes, - #[cfg(feature = "totp")] - Mechanism::Totp, - #[cfg(feature = "x255")] - Mechanism::X255, -]; - /// The context for a syscall (per client). /// /// The context stores the state used by the standard syscall implementations, see