diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3b56a7ffde..ea89cfccf76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,28 @@ jobs: done if: matrix.target == 'x86_64-unknown-linux-gnu' + - name: Check all targets with only one mechanism feature + run: | + # trussed-core + trussed + for mechanism in \ + aes256-cbc chacha8-poly1305 ed255 hmac-blake2s hmac-sha1 hmac-sha256 hmac-sha512 \ + p256 p384 p521 sha256 shared-secret tdes totp trng x255 + do + for package in trussed-core trussed + do + echo "${package}: ${mechanism}" + cargo check --package ${package} --all-targets --no-default-features --features crypto-client,${mechanism} + done + done + # trussed-core only + for mechanism in \ + brainpoolp256r1 brainpoolp384r1 brainpoolp512r1 rsa2048 rsa3072 rsa4096 secp256k1 + do + echo "trussed-core: ${mechanism}" + cargo check --package trussed-core --all-targets --no-default-features --features crypto-client,${mechanism} + done + if: matrix.target == 'x86_64-unknown-linux-gnu' + - name: Check all targets with default features run: | cargo check --workspace --all-targets @@ -66,7 +88,7 @@ jobs: if: matrix.target == 'x86_64-unknown-linux-gnu' - name: Run tests - run: cargo test --workspace --features serde-extensions,virt,p384,p521 + run: cargo test --workspace --all-features if: matrix.target == 'x86_64-unknown-linux-gnu' - name: Check formatting diff --git a/CHANGELOG.md b/CHANGELOG.md index 674cc53af1c..4373c9e3987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed `Id::hex_clean` to format zero as `"00"`. - Change client and mechanism selection: - Put all client traits, requests, replies and implementations behind feature flags. + - Put all mechanisms behind feature flags. - Move `CryptoClient::attest` into new `AttestationClient`. ### Fixed diff --git a/Cargo.toml b/Cargo.toml index a2e0bd51c9d..fd62c984749 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,25 +109,27 @@ default-mechanisms = [ # "hmac-sha512", "p256", "sha256", + "shared-secret", "tdes", "totp", "trng", ] -aes256-cbc = [] -chacha8-poly1305 = [] -ed255 = [] -x255 = [] -hmac-blake2s = ["blake2"] -hmac-sha1 = [] -hmac-sha256 = [] -hmac-sha512 = [] -p256 = [] -p384 = ["dep:p384"] -p521 = ["dep:p521", "dep:ecdsa"] -sha256 = [] -tdes = ["des"] -totp = ["sha-1"] -trng = ["sha-1"] +aes256-cbc = ["trussed-core/aes256-cbc"] +chacha8-poly1305 = ["trussed-core/chacha8-poly1305"] +ed255 = ["trussed-core/ed255"] +x255 = ["trussed-core/x255"] +hmac-blake2s = ["trussed-core/hmac-blake2s", "blake2"] +hmac-sha1 = ["trussed-core/hmac-sha1", "sha-1"] +hmac-sha256 = ["trussed-core/hmac-sha256"] +hmac-sha512 = ["trussed-core/hmac-sha512"] +p256 = ["trussed-core/p256"] +p384 = ["trussed-core/p384", "dep:p384"] +p521 = ["trussed-core/p521", "dep:p521", "dep:ecdsa"] +sha256 = ["trussed-core/sha256"] +shared-secret = ["trussed-core/shared-secret"] +tdes = ["trussed-core/tdes", "des"] +totp = ["trussed-core/totp", "sha-1"] +trng = ["trussed-core/trng", "sha-1"] # clients all-clients = [ @@ -139,7 +141,7 @@ all-clients = [ "management-client", "ui-client", ] -attestation-client = ["crypto-client", "trussed-core/attestation-client"] +attestation-client = ["crypto-client", "ed255", "p256", "trussed-core/attestation-client"] certificate-client = ["trussed-core/certificate-client"] crypto-client = ["trussed-core/crypto-client"] counter-client = ["trussed-core/counter-client"] @@ -161,8 +163,50 @@ clients-11 = [] clients-12 = [] test-attestation-cert-ids = [] -# [patch.crates-io] -# interchange = { git = "https://github.com/trussed-dev/interchange", branch = "main" } + +[[test]] +name = "aes256cbc" +required-features = ["crypto-client", "default-mechanisms", "virt"] + +[[test]] +name = "backends" +required-features = ["filesystem-client", "virt"] + +[[test]] +name = "certificate" +required-features = ["certificate-client", "virt"] + +[[test]] +name = "counter" +required-features = ["counter-client", "virt"] + +[[test]] +name = "filesystem" +required-features = ["crypto-client", "default-mechanisms", "filesystem-client", "virt"] + +[[test]] +name = "key_confusion" +required-features = ["crypto-client", "default-mechanisms", "hmac-blake2s", "hmac-sha512", "virt"] + +[[test]] +name = "p256" +required-features = ["crypto-client", "default-mechanisms", "virt"] + +[[test]] +name = "serde_extensions" +required-features = ["serde-extensions", "virt"] + +[[test]] +name = "tdes" +required-features = ["crypto-client", "tdes", "virt"] + +[[test]] +name = "virt" +required-features = ["filesystem-client", "management-client", "virt"] + +[[test]] +name = "x255" +required-features = ["crypto-client", "default-mechanisms", "virt"] [package.metadata.docs.rs] features = ["serde-extensions", "virt"] diff --git a/README.md b/README.md index a8d3e8ad2f0..91cc1962c23 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Very much WIP. Actively developed. Unstable APIs. ## Running tests ```bash -cargo test --features serde-extensions,virt +cargo test --all-features ``` #### License diff --git a/core/Cargo.toml b/core/Cargo.toml index faf2bf89ba7..cc169c8bfa8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -16,6 +16,9 @@ serde.workspace = true serde-indexed = "0.1" [features] +serde-extensions = [] + +# client traits attestation-client = [] certificate-client = [] crypto-client = [] @@ -24,4 +27,27 @@ filesystem-client = [] management-client = [] ui-client = [] -serde-extensions = [] +# mechanisms +aes256-cbc = [] +brainpoolp256r1 = [] +brainpoolp384r1 = [] +brainpoolp512r1 = [] +chacha8-poly1305 = [] +ed255 = [] +hmac-blake2s = [] +hmac-sha1 = [] +hmac-sha256 = [] +hmac-sha512 = [] +p256 = [] +p384 = [] +p521 = [] +rsa2048 = [] +rsa3072 = [] +rsa4096 = [] +secp256k1 = [] +sha256 = [] +shared-secret = [] +tdes = [] +totp = [] +trng = [] +x255 = [] diff --git a/core/src/client.rs b/core/src/client.rs index 152e959b1dd..662552818cd 100644 --- a/core/src/client.rs +++ b/core/src/client.rs @@ -28,10 +28,7 @@ pub use certificate::CertificateClient; #[cfg(feature = "counter-client")] pub use counter::CounterClient; #[cfg(feature = "crypto-client")] -pub use crypto::{ - Aes256Cbc, Chacha8Poly1305, CryptoClient, Ed255, HmacBlake2s, HmacSha1, HmacSha256, HmacSha512, - Sha256, Tdes, Totp, P256, P384, P521, X255, -}; +pub use crypto::*; #[cfg(feature = "filesystem-client")] pub use filesystem::FilesystemClient; #[cfg(feature = "management-client")] diff --git a/core/src/client/crypto.rs b/core/src/client/crypto.rs index 36396655f03..6bacfedcba5 100644 --- a/core/src/client/crypto.rs +++ b/core/src/client/crypto.rs @@ -283,6 +283,7 @@ pub trait CryptoClient: PollClient { } } +#[cfg(feature = "aes256-cbc")] pub trait Aes256Cbc: CryptoClient { fn decrypt_aes256cbc<'c>( &'c mut self, @@ -309,6 +310,7 @@ pub trait Aes256Cbc: CryptoClient { } } +#[cfg(feature = "chacha8-poly1305")] pub trait Chacha8Poly1305: CryptoClient { fn decrypt_chacha8poly1305<'c>( &'c mut self, @@ -388,6 +390,7 @@ pub trait Chacha8Poly1305: CryptoClient { } } +#[cfg(feature = "hmac-blake2s")] pub trait HmacBlake2s: CryptoClient { fn hmacblake2s_derive_key( &mut self, @@ -417,6 +420,7 @@ pub trait HmacBlake2s: CryptoClient { } } +#[cfg(feature = "hmac-sha1")] pub trait HmacSha1: CryptoClient { fn hmacsha1_derive_key( &mut self, @@ -446,6 +450,7 @@ pub trait HmacSha1: CryptoClient { } } +#[cfg(feature = "hmac-sha256")] pub trait HmacSha256: CryptoClient { fn hmacsha256_derive_key( &mut self, @@ -475,6 +480,7 @@ pub trait HmacSha256: CryptoClient { } } +#[cfg(feature = "hmac-sha512")] pub trait HmacSha512: CryptoClient { fn hmacsha512_derive_key( &mut self, @@ -504,6 +510,7 @@ pub trait HmacSha512: CryptoClient { } } +#[cfg(feature = "ed255")] pub trait Ed255: CryptoClient { fn generate_ed255_private_key( &mut self, @@ -569,6 +576,7 @@ pub trait Ed255: CryptoClient { } } +#[cfg(feature = "p256")] pub trait P256: CryptoClient { fn generate_p256_private_key( &mut self, @@ -655,6 +663,7 @@ pub trait P256: CryptoClient { } } +#[cfg(feature = "p384")] pub trait P384: CryptoClient { fn generate_p384_private_key( &mut self, @@ -741,6 +750,7 @@ pub trait P384: CryptoClient { } } +#[cfg(feature = "p521")] pub trait P521: CryptoClient { fn generate_p521_private_key( &mut self, @@ -827,6 +837,7 @@ pub trait P521: CryptoClient { } } +#[cfg(feature = "sha256")] pub trait Sha256: CryptoClient { fn sha256_derive_key( &mut self, @@ -849,6 +860,7 @@ pub trait Sha256: CryptoClient { } } +#[cfg(feature = "tdes")] pub trait Tdes: CryptoClient { fn decrypt_tdes<'c>( &'c mut self, @@ -867,6 +879,7 @@ pub trait Tdes: CryptoClient { } } +#[cfg(feature = "totp")] pub trait Totp: CryptoClient { fn sign_totp(&mut self, key: KeyId, timestamp: u64) -> ClientResult<'_, reply::Sign, Self> { self.sign( @@ -878,6 +891,7 @@ pub trait Totp: CryptoClient { } } +#[cfg(feature = "x255")] pub trait X255: CryptoClient { fn generate_x255_secret_key( &mut self, diff --git a/core/src/types.rs b/core/src/types.rs index 5d6798449e6..52300fb6dfe 100644 --- a/core/src/types.rs +++ b/core/src/types.rs @@ -427,55 +427,162 @@ impl Client { #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] #[non_exhaustive] pub enum Mechanism { + #[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, // P256XSha256, + #[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 = "brainpoolp256r1")] BrainpoolP256R1, + #[cfg(feature = "brainpoolp256r1")] BrainpoolP256R1Prehashed, + #[cfg(feature = "brainpoolp384r1")] BrainpoolP384R1, + #[cfg(feature = "brainpoolp384r1")] BrainpoolP384R1Prehashed, + #[cfg(feature = "brainpoolp512r1")] BrainpoolP512R1, + #[cfg(feature = "brainpoolp512r1")] BrainpoolP512R1Prehashed, + #[cfg(feature = "secp256k1")] Secp256k1, + #[cfg(feature = "secp256k1")] Secp256k1Prehashed, // clients can also do hashing by themselves + #[cfg(feature = "sha256")] Sha256, + #[cfg(feature = "tdes")] Tdes, + #[cfg(feature = "totp")] Totp, + #[cfg(feature = "trng")] Trng, + #[cfg(feature = "x255")] X255, /// Used to serialize the output of a diffie-hellman + #[cfg(feature = "shared-secret")] SharedSecret, /// Exposes the Raw RSA encryption/decryption primitive. Be aware this is dangerous. /// Not having any padding can allow an attacker to obtain plaintexts and forge signatures. /// It should only be used if absolutely necessary. + #[cfg(feature = "rsa2048")] Rsa2048Raw, /// Exposes the Raw RSA encryption/decryption primitive. Be aware this is dangerous. /// Not having any padding can allow an attacker to obtain plaintexts and forge signatures. /// It should only be used if absolutely necessary. + #[cfg(feature = "rsa3072")] Rsa3072Raw, /// Exposes the Raw RSA encryption/decryption primitive. Be aware this is dangerous. /// Not having any padding can allow an attacker to obtain plaintexts and forge signatures. /// It should only be used if absolutely necessary. + #[cfg(feature = "rsa4096")] Rsa4096Raw, + #[cfg(feature = "rsa2048")] Rsa2048Pkcs1v15, + #[cfg(feature = "rsa3072")] Rsa3072Pkcs1v15, + #[cfg(feature = "rsa4096")] Rsa4096Pkcs1v15, } +impl Mechanism { + /// All enabled mechanisms. + /// + /// The contents of this constant depends on the enabled features. + pub const ENABLED: &[Self] = &[ + #[cfg(feature = "aes256-cbc")] + Self::Aes256Cbc, + #[cfg(feature = "chacha8-poly1305")] + Self::Chacha8Poly1305, + #[cfg(feature = "ed255")] + Self::Ed255, + #[cfg(feature = "hmac-blake2s")] + Self::HmacBlake2s, + #[cfg(feature = "hmac-sha1")] + Self::HmacSha1, + #[cfg(feature = "hmac-sha256")] + Self::HmacSha256, + #[cfg(feature = "hmac-sha512")] + Self::HmacSha512, + #[cfg(feature = "p256")] + Self::P256, + #[cfg(feature = "p256")] + Self::P256Prehashed, + #[cfg(feature = "p384")] + Self::P384, + #[cfg(feature = "p384")] + Self::P384Prehashed, + #[cfg(feature = "p521")] + Self::P521, + #[cfg(feature = "p521")] + Self::P521Prehashed, + #[cfg(feature = "brainpoolp256r1")] + Self::BrainpoolP256R1, + #[cfg(feature = "brainpoolp256r1")] + Self::BrainpoolP256R1Prehashed, + #[cfg(feature = "brainpoolp384r1")] + Self::BrainpoolP384R1, + #[cfg(feature = "brainpoolp384r1")] + Self::BrainpoolP384R1Prehashed, + #[cfg(feature = "brainpoolp512r1")] + Self::BrainpoolP512R1, + #[cfg(feature = "brainpoolp512r1")] + Self::BrainpoolP512R1Prehashed, + #[cfg(feature = "secp256k1")] + Self::Secp256k1, + #[cfg(feature = "secp256k1")] + Self::Secp256k1Prehashed, + #[cfg(feature = "sha256")] + Self::Sha256, + #[cfg(feature = "tdes")] + Self::Tdes, + #[cfg(feature = "totp")] + Self::Totp, + #[cfg(feature = "trng")] + Self::Trng, + #[cfg(feature = "x255")] + Self::X255, + #[cfg(feature = "shared-secret")] + Self::SharedSecret, + #[cfg(feature = "rsa2048")] + Self::Rsa2048Raw, + #[cfg(feature = "rsa3072")] + Self::Rsa3072Raw, + #[cfg(feature = "rsa4096")] + Self::Rsa4096Raw, + #[cfg(feature = "rsa2048")] + Self::Rsa2048Pkcs1v15, + #[cfg(feature = "rsa3072")] + Self::Rsa3072Pkcs1v15, + #[cfg(feature = "rsa4096")] + Self::Rsa4096Pkcs1v15, + ]; +} + #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum KeySerialization { // Asn1Der, diff --git a/src/client/mechanisms.rs b/src/client/mechanisms.rs index b3bd605e9a5..1808ec9662f 100644 --- a/src/client/mechanisms.rs +++ b/src/client/mechanisms.rs @@ -1,10 +1,34 @@ use super::ClientImplementation; use crate::platform::Syscall; -pub use trussed_core::client::{ - Aes256Cbc, Chacha8Poly1305, Ed255, HmacBlake2s, HmacSha1, HmacSha256, HmacSha512, Sha256, Tdes, - Totp, P256, P384, P521, X255, -}; +#[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; #[cfg(feature = "aes256-cbc")] impl Aes256Cbc for ClientImplementation {} diff --git a/src/mechanisms.rs b/src/mechanisms.rs index 380ce65c40d..fd7e6f5e2b6 100644 --- a/src/mechanisms.rs +++ b/src/mechanisms.rs @@ -11,65 +11,90 @@ // should be revisited. // TODO: rename to aes256-cbc-zero-iv +#[cfg(feature = "aes256-cbc")] pub struct Aes256Cbc {} +#[cfg(feature = "aes256-cbc")] mod aes256cbc; +#[cfg(feature = "chacha8-poly1305")] pub struct Chacha8Poly1305 {} +#[cfg(feature = "chacha8-poly1305")] mod chacha8poly1305; +#[cfg(feature = "shared-secret")] pub struct SharedSecret {} +#[cfg(feature = "shared-secret")] mod shared_secret; +#[cfg(feature = "ed255")] pub struct Ed255 {} +#[cfg(feature = "ed255")] mod ed255; +#[cfg(feature = "hmac-blake2s")] pub struct HmacBlake2s {} #[cfg(feature = "hmac-blake2s")] mod hmacblake2s; -#[cfg(not(feature = "hmac-blake2s"))] -impl crate::service::DeriveKey for HmacBlake2s {} -#[cfg(not(feature = "hmac-blake2s"))] -impl crate::service::Sign for HmacBlake2s {} +#[cfg(feature = "hmac-sha1")] pub struct HmacSha1 {} +#[cfg(feature = "hmac-sha1")] mod hmacsha1; +#[cfg(feature = "hmac-sha256")] pub struct HmacSha256 {} +#[cfg(feature = "hmac-sha256")] mod hmacsha256; +#[cfg(feature = "hmac-sha512")] pub struct HmacSha512 {} #[cfg(feature = "hmac-sha512")] mod hmacsha512; -#[cfg(not(feature = "hmac-sha512"))] -impl crate::service::DeriveKey for HmacSha512 {} -#[cfg(not(feature = "hmac-sha512"))] -impl crate::service::Sign for HmacSha512 {} +#[cfg(feature = "p256")] pub struct P256 {} +#[cfg(feature = "p256")] pub struct P256Prehashed {} +#[cfg(feature = "p256")] mod p256; +#[cfg(feature = "p384")] pub struct P384 {} +#[cfg(feature = "p384")] pub struct P384Prehashed {} +#[cfg(feature = "p384")] mod p384; +#[cfg(feature = "p521")] pub struct P521 {} +#[cfg(feature = "p521")] pub struct P521Prehashed {} +#[cfg(feature = "p521")] mod p521; +#[cfg(feature = "sha256")] pub struct Sha256 {} +#[cfg(feature = "sha256")] mod sha256; +#[cfg(feature = "tdes")] pub struct Tdes {} +#[cfg(feature = "tdes")] mod tdes; +#[cfg(feature = "totp")] pub struct Totp {} +#[cfg(feature = "totp")] mod totp; +#[cfg(feature = "trng")] pub struct Trng {} +#[cfg(feature = "trng")] mod trng; +#[cfg(feature = "x255")] pub struct X255 {} +#[cfg(feature = "x255")] mod x255; // pub enum MechanismEnum { diff --git a/src/mechanisms/aes256cbc.rs b/src/mechanisms/aes256cbc.rs index c70aba15591..01f83ea3d78 100644 --- a/src/mechanisms/aes256cbc.rs +++ b/src/mechanisms/aes256cbc.rs @@ -7,7 +7,6 @@ use crate::types::{Mechanism, Message, ShortData}; const AES256_KEY_SIZE: usize = 32; -#[cfg(feature = "aes256-cbc")] impl Encrypt for super::Aes256Cbc { /// Encrypts the input *with zero IV* fn encrypt( @@ -66,7 +65,6 @@ impl Encrypt for super::Aes256Cbc { } } -#[cfg(feature = "aes256-cbc")] impl WrapKey for super::Aes256Cbc { fn wrap_key( keystore: &mut impl Keystore, @@ -101,7 +99,6 @@ impl WrapKey for super::Aes256Cbc { } } -#[cfg(feature = "aes256-cbc")] impl Decrypt for super::Aes256Cbc { fn decrypt( keystore: &mut impl Keystore, @@ -160,7 +157,6 @@ impl Decrypt for super::Aes256Cbc { } } -#[cfg(feature = "aes256-cbc")] impl UnsafeInjectKey for super::Aes256Cbc { fn unsafe_inject_key( keystore: &mut impl Keystore, @@ -180,12 +176,3 @@ impl UnsafeInjectKey for super::Aes256Cbc { Ok(reply::UnsafeInjectKey { key: key_id }) } } - -#[cfg(not(feature = "aes256-cbc"))] -impl UnsafeInjectKey for super::Aes256Cbc {} -#[cfg(not(feature = "aes256-cbc"))] -impl Decrypt for super::Aes256Cbc {} -#[cfg(not(feature = "aes256-cbc"))] -impl Encrypt for super::Aes256Cbc {} -#[cfg(not(feature = "aes256-cbc"))] -impl WrapKey for super::Aes256Cbc {} diff --git a/src/mechanisms/chacha8poly1305.rs b/src/mechanisms/chacha8poly1305.rs index 07a7f305af2..2b072887216 100644 --- a/src/mechanisms/chacha8poly1305.rs +++ b/src/mechanisms/chacha8poly1305.rs @@ -20,7 +20,6 @@ const TAG_LEN: usize = 16; const KIND: key::Kind = key::Kind::Symmetric(KEY_LEN); const KIND_NONCE: key::Kind = key::Kind::Symmetric32Nonce(NONCE_LEN); -#[cfg(feature = "chacha8-poly1305")] impl GenerateKey for super::Chacha8Poly1305 { #[inline(never)] fn generate_key( @@ -64,7 +63,6 @@ fn increment_nonce(nonce: &mut [u8]) -> Result<(), Error> { } } -#[cfg(feature = "chacha8-poly1305")] impl Decrypt for super::Chacha8Poly1305 { #[inline(never)] fn decrypt( @@ -168,7 +166,6 @@ impl Encrypt for super::Chacha8Poly1305 { } } -#[cfg(feature = "chacha8-poly1305")] impl WrapKey for super::Chacha8Poly1305 { #[inline(never)] fn wrap_key( @@ -199,7 +196,6 @@ impl WrapKey for super::Chacha8Poly1305 { } } -#[cfg(feature = "chacha8-poly1305")] impl UnwrapKey for super::Chacha8Poly1305 { #[inline(never)] fn unwrap_key( @@ -242,14 +238,3 @@ impl UnwrapKey for super::Chacha8Poly1305 { Ok(reply::UnwrapKey { key: Some(key_id) }) } } - -#[cfg(not(feature = "chacha8-poly1305"))] -impl Decrypt for super::Chacha8Poly1305 {} -#[cfg(not(feature = "chacha8-poly1305"))] -impl Encrypt for super::Chacha8Poly1305 {} -#[cfg(not(feature = "chacha8-poly1305"))] -impl WrapKey for super::Chacha8Poly1305 {} -#[cfg(not(feature = "chacha8-poly1305"))] -impl UnwrapKey for super::Chacha8Poly1305 {} -#[cfg(not(feature = "chacha8-poly1305"))] -impl GenerateKey for super::Chacha8Poly1305 {} diff --git a/src/mechanisms/ed255.rs b/src/mechanisms/ed255.rs index 9e8ce5084ce..d3f9cd8a88e 100644 --- a/src/mechanisms/ed255.rs +++ b/src/mechanisms/ed255.rs @@ -43,7 +43,6 @@ fn load_keypair(keystore: &mut impl Keystore, key_id: &KeyId) -> Result Result { @@ -210,7 +204,6 @@ impl Sign for super::Ed255 { } } -#[cfg(feature = "ed255")] impl Verify for super::Ed255 { #[inline(never)] fn verify( @@ -268,18 +261,3 @@ impl UnsafeInjectKey for super::Ed255 { .map(|key| reply::UnsafeInjectKey { key }) } } - -#[cfg(not(feature = "ed255"))] -impl Exists for super::Ed255 {} -#[cfg(not(feature = "ed255"))] -impl DeriveKey for super::Ed255 {} -#[cfg(not(feature = "ed255"))] -impl GenerateKey for super::Ed255 {} -#[cfg(not(feature = "ed255"))] -impl SerializeKey for super::Ed255 {} -#[cfg(not(feature = "ed255"))] -impl DeserializeKey for super::Ed255 {} -#[cfg(not(feature = "ed255"))] -impl Sign for super::Ed255 {} -#[cfg(not(feature = "ed255"))] -impl Verify for super::Ed255 {} diff --git a/src/mechanisms/hmacblake2s.rs b/src/mechanisms/hmacblake2s.rs index 9ee4d834c54..b1f8a3c98da 100644 --- a/src/mechanisms/hmacblake2s.rs +++ b/src/mechanisms/hmacblake2s.rs @@ -5,7 +5,6 @@ use crate::service::{DeriveKey, Sign}; use crate::store::keystore::Keystore; use crate::types::Signature; -#[cfg(feature = "hmac-blake2s")] impl DeriveKey for super::HmacBlake2s { #[inline(never)] fn derive_key( @@ -40,7 +39,6 @@ impl DeriveKey for super::HmacBlake2s { } } -#[cfg(feature = "hmac-blake2s")] impl Sign for super::HmacBlake2s { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -64,8 +62,3 @@ impl Sign for super::HmacBlake2s { Ok(reply::Sign { signature }) } } - -#[cfg(not(feature = "hmac-blake2s"))] -impl DeriveKey for super::HmacBlake2s {} -#[cfg(not(feature = "hmac-blake2s"))] -impl Sign for super::HmacBlake2s {} diff --git a/src/mechanisms/hmacsha1.rs b/src/mechanisms/hmacsha1.rs index ff630329534..b73d7e158c6 100644 --- a/src/mechanisms/hmacsha1.rs +++ b/src/mechanisms/hmacsha1.rs @@ -5,7 +5,6 @@ use crate::service::{DeriveKey, Sign}; use crate::store::keystore::Keystore; use crate::types::Signature; -#[cfg(feature = "hmac-sha1")] impl DeriveKey for super::HmacSha1 { #[inline(never)] fn derive_key( @@ -40,7 +39,6 @@ impl DeriveKey for super::HmacSha1 { } } -#[cfg(feature = "hmac-sha1")] impl Sign for super::HmacSha1 { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -65,8 +63,3 @@ impl Sign for super::HmacSha1 { Ok(reply::Sign { signature }) } } - -#[cfg(not(feature = "hmac-sha1"))] -impl DeriveKey for super::HmacSha1 {} -#[cfg(not(feature = "hmac-sha1"))] -impl Sign for super::HmacSha1 {} diff --git a/src/mechanisms/hmacsha256.rs b/src/mechanisms/hmacsha256.rs index 573bbf46b08..8e120956bb4 100644 --- a/src/mechanisms/hmacsha256.rs +++ b/src/mechanisms/hmacsha256.rs @@ -5,7 +5,6 @@ use crate::service::{DeriveKey, Sign}; use crate::store::keystore::Keystore; use crate::types::Signature; -#[cfg(feature = "hmac-sha256")] impl DeriveKey for super::HmacSha256 { #[inline(never)] fn derive_key( @@ -45,7 +44,6 @@ impl DeriveKey for super::HmacSha256 { } } -#[cfg(feature = "hmac-sha256")] impl Sign for super::HmacSha256 { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -70,8 +68,3 @@ impl Sign for super::HmacSha256 { Ok(reply::Sign { signature }) } } - -#[cfg(not(feature = "hmac-sha256"))] -impl DeriveKey for super::HmacSha256 {} -#[cfg(not(feature = "hmac-sha256"))] -impl Sign for super::HmacSha256 {} diff --git a/src/mechanisms/hmacsha512.rs b/src/mechanisms/hmacsha512.rs index e4d1dc4d8be..be037eea3c7 100644 --- a/src/mechanisms/hmacsha512.rs +++ b/src/mechanisms/hmacsha512.rs @@ -5,7 +5,6 @@ use crate::service::{DeriveKey, Sign}; use crate::store::keystore::Keystore; use crate::types::Signature; -#[cfg(feature = "hmac-sha512")] impl DeriveKey for super::HmacSha512 { #[inline(never)] fn derive_key( @@ -40,7 +39,6 @@ impl DeriveKey for super::HmacSha512 { } } -#[cfg(feature = "hmac-sha512")] impl Sign for super::HmacSha512 { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -64,8 +62,3 @@ impl Sign for super::HmacSha512 { Ok(reply::Sign { signature }) } } - -#[cfg(not(feature = "hmac-sha512"))] -impl DeriveKey for super::HmacSha512 {} -#[cfg(not(feature = "hmac-sha512"))] -impl Sign for super::HmacSha512 {} diff --git a/src/mechanisms/p256.rs b/src/mechanisms/p256.rs index e25df84ad3c..1a4f667b5b4 100644 --- a/src/mechanisms/p256.rs +++ b/src/mechanisms/p256.rs @@ -44,7 +44,6 @@ fn load_public_key( .map_err(|_| Error::InternalError) } -#[cfg(feature = "p256")] impl Agree for super::P256 { #[inline(never)] fn agree( @@ -83,7 +82,6 @@ impl Agree for super::P256 { } } -#[cfg(feature = "p256")] impl DeriveKey for super::P256 { #[inline(never)] fn derive_key( @@ -106,7 +104,6 @@ impl DeriveKey for super::P256 { } } -#[cfg(feature = "p256")] impl DeserializeKey for super::P256 { #[inline(never)] fn deserialize_key( @@ -180,7 +177,6 @@ impl DeserializeKey for super::P256 { } } -#[cfg(feature = "p256")] impl GenerateKey for super::P256 { #[inline(never)] fn generate_key( @@ -202,7 +198,6 @@ impl GenerateKey for super::P256 { } } -#[cfg(feature = "p256")] impl SerializeKey for super::P256 { #[inline(never)] fn serialize_key( @@ -252,7 +247,6 @@ impl SerializeKey for super::P256 { } } -#[cfg(feature = "p256")] impl Exists for super::P256 { #[inline(never)] fn exists( @@ -265,7 +259,6 @@ impl Exists for super::P256 { } } -#[cfg(feature = "p256")] impl Sign for super::P256 { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -293,7 +286,6 @@ impl Sign for super::P256 { } } -#[cfg(feature = "p256")] impl Sign for super::P256Prehashed { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -321,7 +313,6 @@ impl Sign for super::P256Prehashed { } } -#[cfg(feature = "p256")] impl Verify for super::P256 { #[inline(never)] fn verify( @@ -374,22 +365,3 @@ impl UnsafeInjectKey for super::P256 { .map(|key| reply::UnsafeInjectKey { key }) } } - -#[cfg(not(feature = "p256"))] -impl Agree for super::P256 {} -#[cfg(not(feature = "p256"))] -impl Exists for super::P256 {} -#[cfg(not(feature = "p256"))] -impl DeriveKey for super::P256 {} -#[cfg(not(feature = "p256"))] -impl GenerateKey for super::P256 {} -#[cfg(not(feature = "p256"))] -impl DeserializeKey for super::P256 {} -#[cfg(not(feature = "p256"))] -impl SerializeKey for super::P256 {} -#[cfg(not(feature = "p256"))] -impl Sign for super::P256 {} -#[cfg(not(feature = "p256"))] -impl Sign for super::P256Prehashed {} -#[cfg(not(feature = "p256"))] -impl Verify for super::P256 {} diff --git a/src/mechanisms/p384.rs b/src/mechanisms/p384.rs index 4bf9705ea07..67d2fdda409 100644 --- a/src/mechanisms/p384.rs +++ b/src/mechanisms/p384.rs @@ -1,357 +1,318 @@ -#[cfg(feature = "p384")] -mod impls { - use p384::{ - ecdh::diffie_hellman, - ecdsa::{ - signature::{hazmat::RandomizedPrehashSigner, RandomizedSigner, Verifier}, - SigningKey, VerifyingKey, - }, - elliptic_curve::sec1::ToEncodedPoint, - SecretKey, - }; - - use super::super::{P384Prehashed, P384}; - use crate::{ - api::{reply, request}, - key, - service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, - UnsafeInjectKey, Verify, - }, - store::keystore::Keystore, - types::{KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization}, - Error, - }; - - const SCALAR_SIZE: usize = 48; +use p384::{ + ecdh::diffie_hellman, + ecdsa::{ + signature::{hazmat::RandomizedPrehashSigner, RandomizedSigner, Verifier}, + SigningKey, VerifyingKey, + }, + elliptic_curve::sec1::ToEncodedPoint, + SecretKey, +}; + +use super::{P384Prehashed, P384}; +use crate::{ + api::{reply, request}, + key, + service::{ + Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, + Verify, + }, + store::keystore::Keystore, + types::{KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization}, + Error, +}; + +const SCALAR_SIZE: usize = 48; + +#[inline(never)] +fn load_secret_key(keystore: &mut impl Keystore, key_id: &KeyId) -> Result { + // info_now!("loading keypair"); + let secret_scalar: [u8; SCALAR_SIZE] = keystore + .load_key(key::Secrecy::Secret, Some(key::Kind::P384), key_id)? + .material + .as_slice() + .try_into() + .map_err(|_| Error::InternalError)?; + + let secret_key = + p384::SecretKey::from_bytes((&secret_scalar).into()).map_err(|_| Error::InternalError)?; + Ok(secret_key) +} - #[inline(never)] - fn load_secret_key( - keystore: &mut impl Keystore, - key_id: &KeyId, - ) -> Result { - // info_now!("loading keypair"); - let secret_scalar: [u8; SCALAR_SIZE] = keystore - .load_key(key::Secrecy::Secret, Some(key::Kind::P384), key_id)? - .material - .as_slice() - .try_into() - .map_err(|_| Error::InternalError)?; - - let secret_key = p384::SecretKey::from_bytes((&secret_scalar).into()) - .map_err(|_| Error::InternalError)?; - Ok(secret_key) - } +#[inline(never)] +fn load_public_key(keystore: &mut impl Keystore, key_id: &KeyId) -> Result { + let compressed_public_key = keystore + .load_key(key::Secrecy::Public, Some(key::Kind::P384), key_id)? + .material; - #[inline(never)] - fn load_public_key( - keystore: &mut impl Keystore, - key_id: &KeyId, - ) -> Result { - let compressed_public_key = keystore - .load_key(key::Secrecy::Public, Some(key::Kind::P384), key_id)? - .material; + p384::PublicKey::from_sec1_bytes(&compressed_public_key).map_err(|_| Error::InternalError) +} - p384::PublicKey::from_sec1_bytes(&compressed_public_key).map_err(|_| Error::InternalError) - } +fn to_sec1_bytes(public_key: &p384::PublicKey) -> heapless::Vec { + let encoded_point: p384::EncodedPoint = public_key.into(); + encoded_point.as_bytes().try_into().unwrap() +} - fn to_sec1_bytes(public_key: &p384::PublicKey) -> heapless::Vec { - let encoded_point: p384::EncodedPoint = public_key.into(); - encoded_point.as_bytes().try_into().unwrap() +impl Agree for P384 { + fn agree( + keystore: &mut impl Keystore, + request: &request::Agree, + ) -> Result { + let secret_key = load_secret_key(keystore, &request.private_key)?; + let public_key = load_public_key(keystore, &request.public_key)?; + let shared_secret: [u8; SCALAR_SIZE] = + (*diffie_hellman(secret_key.to_nonzero_scalar(), public_key.as_affine()) + .raw_secret_bytes()) + .into(); + let flags = if request.attributes.serializable { + key::Flags::SERIALIZABLE + } else { + key::Flags::empty() + }; + let info = key::Info { + kind: key::Kind::Shared(shared_secret.len()), + flags, + }; + + let key_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Secret, + info, + &shared_secret, + )?; + + // return handle + Ok(reply::Agree { + shared_secret: key_id, + }) } +} +impl DeriveKey for P384 { + #[inline(never)] + fn derive_key( + keystore: &mut impl Keystore, + request: &request::DeriveKey, + ) -> Result { + let base_id = request.base_key; - impl Agree for P384 { - fn agree( - keystore: &mut impl Keystore, - request: &request::Agree, - ) -> Result { - let secret_key = load_secret_key(keystore, &request.private_key)?; - let public_key = load_public_key(keystore, &request.public_key)?; - let shared_secret: [u8; SCALAR_SIZE] = - (*diffie_hellman(secret_key.to_nonzero_scalar(), public_key.as_affine()) - .raw_secret_bytes()) - .into(); - let flags = if request.attributes.serializable { - key::Flags::SERIALIZABLE - } else { - key::Flags::empty() - }; - let info = key::Info { - kind: key::Kind::Shared(shared_secret.len()), - flags, - }; - - let key_id = keystore.store_key( - request.attributes.persistence, - key::Secrecy::Secret, - info, - &shared_secret, - )?; + let secret_key = load_secret_key(keystore, &base_id)?; + let public_key = secret_key.public_key(); - // return handle - Ok(reply::Agree { - shared_secret: key_id, - }) - } - } - impl DeriveKey for P384 { - #[inline(never)] - fn derive_key( - keystore: &mut impl Keystore, - request: &request::DeriveKey, - ) -> Result { - let base_id = request.base_key; - - let secret_key = load_secret_key(keystore, &base_id)?; - let public_key = secret_key.public_key(); - - let public_id = keystore.store_key( - request.attributes.persistence, - key::Secrecy::Public, - key::Kind::P384, - &to_sec1_bytes(&public_key), - )?; + let public_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Public, + key::Kind::P384, + &to_sec1_bytes(&public_key), + )?; - Ok(reply::DeriveKey { key: public_id }) - } + Ok(reply::DeriveKey { key: public_id }) } - impl DeserializeKey for P384 { - #[inline(never)] - fn deserialize_key( - keystore: &mut impl Keystore, - request: &request::DeserializeKey, - ) -> Result { - // - mechanism: Mechanism - // - serialized_key: Message - // - attributes: StorageAttributes - - let public_key = match request.format { - KeySerialization::Raw => { - if request.serialized_key.len() != 2 * SCALAR_SIZE { - return Err(Error::InvalidSerializedKey); - } - - let mut serialized_key = [4; 2 * SCALAR_SIZE + 1]; - serialized_key[1..].copy_from_slice(&request.serialized_key[..2 * SCALAR_SIZE]); - - p384::PublicKey::from_sec1_bytes(&serialized_key) - .map_err(|_| Error::InvalidSerializedKey)? +} +impl DeserializeKey for P384 { + #[inline(never)] + fn deserialize_key( + keystore: &mut impl Keystore, + request: &request::DeserializeKey, + ) -> Result { + // - mechanism: Mechanism + // - serialized_key: Message + // - attributes: StorageAttributes + + let public_key = match request.format { + KeySerialization::Raw => { + if request.serialized_key.len() != 2 * SCALAR_SIZE { + return Err(Error::InvalidSerializedKey); } - _ => { - return Err(Error::InternalError); - } - }; + let mut serialized_key = [4; 2 * SCALAR_SIZE + 1]; + serialized_key[1..].copy_from_slice(&request.serialized_key[..2 * SCALAR_SIZE]); - let public_id = keystore.store_key( - request.attributes.persistence, - key::Secrecy::Public, - key::Kind::P384, - &to_sec1_bytes(&public_key), - )?; + p384::PublicKey::from_sec1_bytes(&serialized_key) + .map_err(|_| Error::InvalidSerializedKey)? + } - Ok(reply::DeserializeKey { key: public_id }) - } + _ => { + return Err(Error::InternalError); + } + }; + + let public_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Public, + key::Kind::P384, + &to_sec1_bytes(&public_key), + )?; + + Ok(reply::DeserializeKey { key: public_id }) } - impl SerializeKey for P384 { - #[inline(never)] - fn serialize_key( - keystore: &mut impl Keystore, - request: &request::SerializeKey, - ) -> Result { - let key_id = request.key; - - let public_key = load_public_key(keystore, &key_id)?; - - let serialized_key = match request.format { - KeySerialization::Raw => { - let mut serialized_key = SerializedKey::new(); - let affine_point = public_key.as_affine().to_encoded_point(false); - serialized_key - .extend_from_slice(affine_point.x().ok_or(Error::InternalError)?) - .map_err(|_| Error::InternalError)?; - serialized_key - .extend_from_slice(affine_point.y().ok_or(Error::InternalError)?) - .map_err(|_| Error::InternalError)?; - serialized_key - } - KeySerialization::Sec1 => { - let mut serialized_key = SerializedKey::new(); - serialized_key - .extend_from_slice(&to_sec1_bytes(&public_key)) - .map_err(|_| Error::InternalError)?; - serialized_key - } - _ => return Err(Error::InvalidSerializationFormat), - }; +} +impl SerializeKey for P384 { + #[inline(never)] + fn serialize_key( + keystore: &mut impl Keystore, + request: &request::SerializeKey, + ) -> Result { + let key_id = request.key; + + let public_key = load_public_key(keystore, &key_id)?; + + let serialized_key = match request.format { + KeySerialization::Raw => { + let mut serialized_key = SerializedKey::new(); + let affine_point = public_key.as_affine().to_encoded_point(false); + serialized_key + .extend_from_slice(affine_point.x().ok_or(Error::InternalError)?) + .map_err(|_| Error::InternalError)?; + serialized_key + .extend_from_slice(affine_point.y().ok_or(Error::InternalError)?) + .map_err(|_| Error::InternalError)?; + serialized_key + } + KeySerialization::Sec1 => { + let mut serialized_key = SerializedKey::new(); + serialized_key + .extend_from_slice(&to_sec1_bytes(&public_key)) + .map_err(|_| Error::InternalError)?; + serialized_key + } + _ => return Err(Error::InvalidSerializationFormat), + }; - Ok(reply::SerializeKey { serialized_key }) - } + Ok(reply::SerializeKey { serialized_key }) } - impl Exists for P384 { - #[inline(never)] - fn exists( - keystore: &mut impl Keystore, - request: &request::Exists, - ) -> Result { - let key_id = request.key; - let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::P384), &key_id); - Ok(reply::Exists { exists }) - } +} +impl Exists for P384 { + #[inline(never)] + fn exists( + keystore: &mut impl Keystore, + request: &request::Exists, + ) -> Result { + let key_id = request.key; + 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 { - 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_with_rng(keystore.rng(), &request.message); - - // 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 signature - Ok(reply::Sign { - 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() - } - }; +impl Sign for P384 { + #[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_with_rng(keystore.rng(), &request.message); + + // 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 signature - Ok(reply::Sign { - signature: serialized_signature, - }) - } + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) } - - impl UnsafeInjectKey for P384 { - fn unsafe_inject_key( - keystore: &mut impl Keystore, - request: &request::UnsafeInjectKey, - ) -> Result { - if request.format != KeySerialization::Raw { - return Err(Error::InvalidSerializationFormat); +} +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(), + }; - let sk = p384::SecretKey::from_bytes((&**request.raw_key).into()) - .map_err(|_| Error::InvalidSerializedKey)?; - - let info = key::Info { - flags: key::Flags::SENSITIVE, - kind: key::Kind::P384, - }; - - keystore - .store_key( - request.attributes.persistence, - key::Secrecy::Secret, - info, - &sk.to_bytes(), - ) - .map(|key| reply::UnsafeInjectKey { key }) - } + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) } +} - impl Verify for P384 { - #[inline(never)] - fn verify( - keystore: &mut impl Keystore, - request: &request::Verify, - ) -> Result { - let key_id = request.key; - - let public_key = load_public_key(keystore, &key_id)?; - let verifying_key: VerifyingKey = public_key.into(); - - if let SignatureSerialization::Raw = request.format { - } else { - // well more TODO - return Err(Error::InvalidSerializationFormat); - } +impl UnsafeInjectKey for P384 { + fn unsafe_inject_key( + keystore: &mut impl Keystore, + request: &request::UnsafeInjectKey, + ) -> Result { + if request.format != KeySerialization::Raw { + return Err(Error::InvalidSerializationFormat); + } - let signature_bytes = (&**request.signature).into(); + let sk = p384::SecretKey::from_bytes((&**request.raw_key).into()) + .map_err(|_| Error::InvalidSerializedKey)?; - let signature = p384::ecdsa::Signature::from_bytes(signature_bytes) - .map_err(|_| Error::InvalidSerializedRequest)?; + let info = key::Info { + flags: key::Flags::SENSITIVE, + kind: key::Kind::P384, + }; - let valid = verifying_key.verify(&request.message, &signature).is_ok(); - Ok(reply::Verify { valid }) - } - } - impl GenerateKey for P384 { - fn generate_key( - keystore: &mut impl Keystore, - request: &request::GenerateKey, - ) -> Result { - let private_key = SecretKey::random(keystore.rng()); - // store keys - let key_id = keystore.store_key( + keystore + .store_key( request.attributes.persistence, key::Secrecy::Secret, - key::Info::from(key::Kind::P384).with_local_flag(), - &private_key.to_bytes(), - )?; + info, + &sk.to_bytes(), + ) + .map(|key| reply::UnsafeInjectKey { key }) + } +} + +impl Verify for P384 { + #[inline(never)] + fn verify( + keystore: &mut impl Keystore, + request: &request::Verify, + ) -> Result { + let key_id = request.key; + + let public_key = load_public_key(keystore, &key_id)?; + let verifying_key: VerifyingKey = public_key.into(); - // return handle - Ok(reply::GenerateKey { key: key_id }) + if let SignatureSerialization::Raw = request.format { + } else { + // well more TODO + return Err(Error::InvalidSerializationFormat); } + + let signature_bytes = (&**request.signature).into(); + + let signature = p384::ecdsa::Signature::from_bytes(signature_bytes) + .map_err(|_| Error::InvalidSerializedRequest)?; + + let valid = verifying_key.verify(&request.message, &signature).is_ok(); + Ok(reply::Verify { valid }) } } - -#[cfg(not(feature = "p384"))] -mod impls { - use super::super::{P384Prehashed, P384}; - use crate::service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, - Verify, - }; - - impl UnsafeInjectKey for P384 {} - impl Agree for P384 {} - impl Exists for P384 {} - impl DeriveKey for P384 {} - impl GenerateKey for P384 {} - impl DeserializeKey for P384 {} - impl SerializeKey for P384 {} - impl Sign for P384 {} - impl Sign for P384Prehashed {} - impl Verify for P384 {} +impl GenerateKey for P384 { + fn generate_key( + keystore: &mut impl Keystore, + request: &request::GenerateKey, + ) -> Result { + let private_key = SecretKey::random(keystore.rng()); + // store keys + let key_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Secret, + key::Info::from(key::Kind::P384).with_local_flag(), + &private_key.to_bytes(), + )?; + + // return handle + Ok(reply::GenerateKey { key: key_id }) + } } diff --git a/src/mechanisms/p521.rs b/src/mechanisms/p521.rs index 5605a33f0b2..224e793d380 100644 --- a/src/mechanisms/p521.rs +++ b/src/mechanisms/p521.rs @@ -1,361 +1,322 @@ -#[cfg(feature = "p521")] -mod impls { - use p521::{ - ecdh::diffie_hellman, - ecdsa::{ - signature::{hazmat::RandomizedPrehashSigner, RandomizedSigner, Verifier}, - SigningKey, VerifyingKey, - }, - elliptic_curve::sec1::ToEncodedPoint, - SecretKey, - }; - - use super::super::{P521Prehashed, P521}; - use crate::{ - api::{reply, request}, - key, - service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, - UnsafeInjectKey, Verify, - }, - store::keystore::Keystore, - types::{KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization}, - Error, - }; - - const SCALAR_SIZE: usize = 66; +use p521::{ + ecdh::diffie_hellman, + ecdsa::{ + signature::{hazmat::RandomizedPrehashSigner, RandomizedSigner, Verifier}, + SigningKey, VerifyingKey, + }, + elliptic_curve::sec1::ToEncodedPoint, + SecretKey, +}; + +use super::{P521Prehashed, P521}; +use crate::{ + api::{reply, request}, + key, + service::{ + Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, + Verify, + }, + store::keystore::Keystore, + types::{KeyId, KeySerialization, SerializedKey, Signature, SignatureSerialization}, + Error, +}; + +const SCALAR_SIZE: usize = 66; + +#[inline(never)] +fn load_secret_key(keystore: &mut impl Keystore, key_id: &KeyId) -> Result { + // info_now!("loading keypair"); + let secret_scalar: [u8; SCALAR_SIZE] = keystore + .load_key(key::Secrecy::Secret, Some(key::Kind::P521), key_id)? + .material + .as_slice() + .try_into() + .map_err(|_| Error::InternalError)?; + + let secret_key = p521::SecretKey::from_bytes(secret_scalar.as_slice().into()) + .map_err(|_| Error::InternalError)?; + Ok(secret_key) +} - #[inline(never)] - fn load_secret_key( +#[inline(never)] +fn load_public_key(keystore: &mut impl Keystore, key_id: &KeyId) -> Result { + let compressed_public_key = keystore + .load_key(key::Secrecy::Public, Some(key::Kind::P521), key_id)? + .material; + + p521::PublicKey::from_sec1_bytes(&compressed_public_key).map_err(|_| Error::InternalError) +} + +fn to_sec1_bytes(public_key: &p521::PublicKey) -> heapless::Vec { + let encoded_point: p521::EncodedPoint = public_key.into(); + encoded_point.as_bytes().try_into().unwrap() +} + +impl Agree for P521 { + fn agree( keystore: &mut impl Keystore, - key_id: &KeyId, - ) -> Result { - // info_now!("loading keypair"); - let secret_scalar: [u8; SCALAR_SIZE] = keystore - .load_key(key::Secrecy::Secret, Some(key::Kind::P521), key_id)? - .material + request: &request::Agree, + ) -> Result { + let secret_key = load_secret_key(keystore, &request.private_key)?; + let public_key = load_public_key(keystore, &request.public_key)?; + let shared_secret: [u8; SCALAR_SIZE] = + (*diffie_hellman(secret_key.to_nonzero_scalar(), public_key.as_affine()) + .raw_secret_bytes()) .as_slice() .try_into() - .map_err(|_| Error::InternalError)?; - - let secret_key = p521::SecretKey::from_bytes(secret_scalar.as_slice().into()) - .map_err(|_| Error::InternalError)?; - Ok(secret_key) + .expect("Older generic_array does not impl .into() for [T; 66]"); + let flags = if request.attributes.serializable { + key::Flags::SERIALIZABLE + } else { + key::Flags::empty() + }; + let info = key::Info { + kind: key::Kind::Shared(shared_secret.len()), + flags, + }; + + let key_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Secret, + info, + &shared_secret, + )?; + + // return handle + Ok(reply::Agree { + shared_secret: key_id, + }) } - +} +impl DeriveKey for P521 { #[inline(never)] - fn load_public_key( + fn derive_key( keystore: &mut impl Keystore, - key_id: &KeyId, - ) -> Result { - let compressed_public_key = keystore - .load_key(key::Secrecy::Public, Some(key::Kind::P521), key_id)? - .material; + request: &request::DeriveKey, + ) -> Result { + let base_id = request.base_key; - p521::PublicKey::from_sec1_bytes(&compressed_public_key).map_err(|_| Error::InternalError) - } + let secret_key = load_secret_key(keystore, &base_id)?; + let public_key = secret_key.public_key(); - fn to_sec1_bytes(public_key: &p521::PublicKey) -> heapless::Vec { - let encoded_point: p521::EncodedPoint = public_key.into(); - encoded_point.as_bytes().try_into().unwrap() - } - - impl Agree for P521 { - fn agree( - keystore: &mut impl Keystore, - request: &request::Agree, - ) -> Result { - let secret_key = load_secret_key(keystore, &request.private_key)?; - let public_key = load_public_key(keystore, &request.public_key)?; - let shared_secret: [u8; SCALAR_SIZE] = - (*diffie_hellman(secret_key.to_nonzero_scalar(), public_key.as_affine()) - .raw_secret_bytes()) - .as_slice() - .try_into() - .expect("Older generic_array does not impl .into() for [T; 66]"); - let flags = if request.attributes.serializable { - key::Flags::SERIALIZABLE - } else { - key::Flags::empty() - }; - let info = key::Info { - kind: key::Kind::Shared(shared_secret.len()), - flags, - }; - - let key_id = keystore.store_key( - request.attributes.persistence, - key::Secrecy::Secret, - info, - &shared_secret, - )?; + let public_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Public, + key::Kind::P521, + &to_sec1_bytes(&public_key), + )?; - // return handle - Ok(reply::Agree { - shared_secret: key_id, - }) - } + Ok(reply::DeriveKey { key: public_id }) } - impl DeriveKey for P521 { - #[inline(never)] - fn derive_key( - keystore: &mut impl Keystore, - request: &request::DeriveKey, - ) -> Result { - let base_id = request.base_key; - - let secret_key = load_secret_key(keystore, &base_id)?; - let public_key = secret_key.public_key(); - - let public_id = keystore.store_key( - request.attributes.persistence, - key::Secrecy::Public, - key::Kind::P521, - &to_sec1_bytes(&public_key), - )?; - - Ok(reply::DeriveKey { key: public_id }) - } - } - impl DeserializeKey for P521 { - #[inline(never)] - fn deserialize_key( - keystore: &mut impl Keystore, - request: &request::DeserializeKey, - ) -> Result { - // - mechanism: Mechanism - // - serialized_key: Message - // - attributes: StorageAttributes - - let public_key = match request.format { - KeySerialization::Raw => { - if request.serialized_key.len() != 2 * SCALAR_SIZE { - return Err(Error::InvalidSerializedKey); - } - - let mut serialized_key = [4; 2 * SCALAR_SIZE + 1]; - serialized_key[1..].copy_from_slice(&request.serialized_key[..2 * SCALAR_SIZE]); - - p521::PublicKey::from_sec1_bytes(&serialized_key) - .map_err(|_| Error::InvalidSerializedKey)? - } - - _ => { - return Err(Error::InternalError); +} +impl DeserializeKey for P521 { + #[inline(never)] + fn deserialize_key( + keystore: &mut impl Keystore, + request: &request::DeserializeKey, + ) -> Result { + // - mechanism: Mechanism + // - serialized_key: Message + // - attributes: StorageAttributes + + let public_key = match request.format { + KeySerialization::Raw => { + if request.serialized_key.len() != 2 * SCALAR_SIZE { + return Err(Error::InvalidSerializedKey); } - }; - let public_id = keystore.store_key( - request.attributes.persistence, - key::Secrecy::Public, - key::Kind::P521, - &to_sec1_bytes(&public_key), - )?; + let mut serialized_key = [4; 2 * SCALAR_SIZE + 1]; + serialized_key[1..].copy_from_slice(&request.serialized_key[..2 * SCALAR_SIZE]); - Ok(reply::DeserializeKey { key: public_id }) - } - } - impl SerializeKey for P521 { - #[inline(never)] - fn serialize_key( - keystore: &mut impl Keystore, - request: &request::SerializeKey, - ) -> Result { - let key_id = request.key; - - let public_key = load_public_key(keystore, &key_id)?; - - let serialized_key = match request.format { - KeySerialization::Raw => { - let mut serialized_key = SerializedKey::new(); - let affine_point = public_key.as_affine().to_encoded_point(false); - serialized_key - .extend_from_slice(affine_point.x().ok_or(Error::InternalError)?) - .map_err(|_| Error::InternalError)?; - serialized_key - .extend_from_slice(affine_point.y().ok_or(Error::InternalError)?) - .map_err(|_| Error::InternalError)?; - serialized_key - } - KeySerialization::Sec1 => { - let mut serialized_key = SerializedKey::new(); - serialized_key - .extend_from_slice(&to_sec1_bytes(&public_key)) - .map_err(|_| Error::InternalError)?; - serialized_key - } - _ => return Err(Error::InvalidSerializationFormat), - }; + p521::PublicKey::from_sec1_bytes(&serialized_key) + .map_err(|_| Error::InvalidSerializedKey)? + } - Ok(reply::SerializeKey { serialized_key }) - } - } - impl Exists for P521 { - #[inline(never)] - fn exists( - keystore: &mut impl Keystore, - request: &request::Exists, - ) -> Result { - let key_id = request.key; - let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::P521), &key_id); - Ok(reply::Exists { exists }) - } - } + _ => { + return Err(Error::InternalError); + } + }; - impl Sign for P521 { - #[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)?; - // Why is this intermediate step necessary? - let signing_key = SigningKey::from(ecdsa::SigningKey::from(secret_key)); - let signature: p521::ecdsa::Signature = - signing_key.sign_with_rng(keystore.rng(), &request.message); - - // 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() - } - }; + let public_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Public, + key::Kind::P521, + &to_sec1_bytes(&public_key), + )?; - // return signature - Ok(reply::Sign { - signature: serialized_signature, - }) - } + Ok(reply::DeserializeKey { key: public_id }) } - 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() - } - }; +} +impl SerializeKey for P521 { + #[inline(never)] + fn serialize_key( + keystore: &mut impl Keystore, + request: &request::SerializeKey, + ) -> Result { + let key_id = request.key; + + let public_key = load_public_key(keystore, &key_id)?; + + let serialized_key = match request.format { + KeySerialization::Raw => { + let mut serialized_key = SerializedKey::new(); + let affine_point = public_key.as_affine().to_encoded_point(false); + serialized_key + .extend_from_slice(affine_point.x().ok_or(Error::InternalError)?) + .map_err(|_| Error::InternalError)?; + serialized_key + .extend_from_slice(affine_point.y().ok_or(Error::InternalError)?) + .map_err(|_| Error::InternalError)?; + serialized_key + } + KeySerialization::Sec1 => { + let mut serialized_key = SerializedKey::new(); + serialized_key + .extend_from_slice(&to_sec1_bytes(&public_key)) + .map_err(|_| Error::InternalError)?; + serialized_key + } + _ => return Err(Error::InvalidSerializationFormat), + }; - // return signature - Ok(reply::Sign { - signature: serialized_signature, - }) - } + Ok(reply::SerializeKey { serialized_key }) + } +} +impl Exists for P521 { + #[inline(never)] + fn exists( + keystore: &mut impl Keystore, + request: &request::Exists, + ) -> Result { + let key_id = request.key; + let exists = keystore.exists_key(key::Secrecy::Secret, Some(key::Kind::P521), &key_id); + Ok(reply::Exists { exists }) } +} - impl UnsafeInjectKey for P521 { - fn unsafe_inject_key( - keystore: &mut impl Keystore, - request: &request::UnsafeInjectKey, - ) -> Result { - if request.format != KeySerialization::Raw { - return Err(Error::InvalidSerializationFormat); +impl Sign for P521 { + #[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)?; + // Why is this intermediate step necessary? + let signing_key = SigningKey::from(ecdsa::SigningKey::from(secret_key)); + let signature: p521::ecdsa::Signature = + signing_key.sign_with_rng(keystore.rng(), &request.message); + + // 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(), + }; - let sk = p521::SecretKey::from_bytes((&**request.raw_key).into()) - .map_err(|_| Error::InvalidSerializedKey)?; - - let info = key::Info { - flags: key::Flags::SENSITIVE, - kind: key::Kind::P521, - }; - - keystore - .store_key( - request.attributes.persistence, - key::Secrecy::Secret, - info, - &sk.to_bytes(), - ) - .map(|key| reply::UnsafeInjectKey { key }) - } + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) } - - impl Verify for P521 { - #[inline(never)] - fn verify( - keystore: &mut impl Keystore, - request: &request::Verify, - ) -> Result { - let key_id = request.key; - - let public_key = load_public_key(keystore, &key_id)?; - let verifying_key = VerifyingKey::from(ecdsa::VerifyingKey::from(public_key)); - - if let SignatureSerialization::Raw = request.format { - } else { - // well more TODO - return Err(Error::InvalidSerializationFormat); +} +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(), + }; - let signature_bytes = (&**request.signature).into(); - - let signature = p521::ecdsa::Signature::from_bytes(signature_bytes) - .map_err(|_| Error::InvalidSerializedRequest)?; + // return signature + Ok(reply::Sign { + signature: serialized_signature, + }) + } +} - let valid = verifying_key.verify(&request.message, &signature).is_ok(); - Ok(reply::Verify { valid }) +impl UnsafeInjectKey for P521 { + fn unsafe_inject_key( + keystore: &mut impl Keystore, + request: &request::UnsafeInjectKey, + ) -> Result { + if request.format != KeySerialization::Raw { + return Err(Error::InvalidSerializationFormat); } - } - impl GenerateKey for P521 { - fn generate_key( - keystore: &mut impl Keystore, - request: &request::GenerateKey, - ) -> Result { - let private_key = SecretKey::random(keystore.rng()); - // store keys - let key_id = keystore.store_key( + let sk = p521::SecretKey::from_bytes((&**request.raw_key).into()) + .map_err(|_| Error::InvalidSerializedKey)?; + + let info = key::Info { + flags: key::Flags::SENSITIVE, + kind: key::Kind::P521, + }; + + keystore + .store_key( request.attributes.persistence, key::Secrecy::Secret, - key::Info::from(key::Kind::P521).with_local_flag(), - &private_key.to_bytes(), - )?; + info, + &sk.to_bytes(), + ) + .map(|key| reply::UnsafeInjectKey { key }) + } +} + +impl Verify for P521 { + #[inline(never)] + fn verify( + keystore: &mut impl Keystore, + request: &request::Verify, + ) -> Result { + let key_id = request.key; + + let public_key = load_public_key(keystore, &key_id)?; + let verifying_key = VerifyingKey::from(ecdsa::VerifyingKey::from(public_key)); - // return handle - Ok(reply::GenerateKey { key: key_id }) + if let SignatureSerialization::Raw = request.format { + } else { + // well more TODO + return Err(Error::InvalidSerializationFormat); } + + let signature_bytes = (&**request.signature).into(); + + let signature = p521::ecdsa::Signature::from_bytes(signature_bytes) + .map_err(|_| Error::InvalidSerializedRequest)?; + + let valid = verifying_key.verify(&request.message, &signature).is_ok(); + Ok(reply::Verify { valid }) } } -#[cfg(not(feature = "p521"))] -mod impls { - use super::super::{P521Prehashed, P521}; - use crate::service::{ - Agree, DeriveKey, DeserializeKey, Exists, GenerateKey, SerializeKey, Sign, UnsafeInjectKey, - Verify, - }; - - impl UnsafeInjectKey for P521 {} - impl Agree for P521 {} - impl Exists for P521 {} - impl DeriveKey for P521 {} - impl GenerateKey for P521 {} - impl DeserializeKey for P521 {} - impl SerializeKey for P521 {} - impl Sign for P521 {} - impl Sign for P521Prehashed {} - impl Verify for P521 {} +impl GenerateKey for P521 { + fn generate_key( + keystore: &mut impl Keystore, + request: &request::GenerateKey, + ) -> Result { + let private_key = SecretKey::random(keystore.rng()); + // store keys + let key_id = keystore.store_key( + request.attributes.persistence, + key::Secrecy::Secret, + key::Info::from(key::Kind::P521).with_local_flag(), + &private_key.to_bytes(), + )?; + + // return handle + Ok(reply::GenerateKey { key: key_id }) + } } diff --git a/src/mechanisms/sha256.rs b/src/mechanisms/sha256.rs index 073daa42d1c..92460277fe2 100644 --- a/src/mechanisms/sha256.rs +++ b/src/mechanisms/sha256.rs @@ -5,7 +5,6 @@ use crate::service::{DeriveKey, Hash}; use crate::store::keystore::Keystore; use crate::types::ShortData; -#[cfg(feature = "sha256")] impl DeriveKey for super::Sha256 { #[inline(never)] fn derive_key( @@ -35,7 +34,6 @@ impl DeriveKey for super::Sha256 { } } -#[cfg(feature = "sha256")] impl Hash for super::Sha256 { #[inline(never)] fn hash(_keystore: &mut impl Keystore, request: &request::Hash) -> Result { @@ -49,8 +47,3 @@ impl Hash for super::Sha256 { Ok(reply::Hash { hash: hashed }) } } - -#[cfg(not(feature = "sha256"))] -impl DeriveKey for super::Sha256 {} -#[cfg(not(feature = "sha256"))] -impl Hash for super::Sha256 {} diff --git a/src/mechanisms/tdes.rs b/src/mechanisms/tdes.rs index c4bb2db05f6..51a63efc6d1 100644 --- a/src/mechanisms/tdes.rs +++ b/src/mechanisms/tdes.rs @@ -6,7 +6,6 @@ // use cortex_m_semihosting::{dbg, hprintln}; // needed to even get ::new() from des... -#[cfg(feature = "tdes")] use des::cipher::{BlockDecrypt, BlockEncrypt, KeyInit}; use generic_array::GenericArray; @@ -18,7 +17,6 @@ use crate::store::keystore::Keystore; const TDES_KEY_SIZE: usize = 24; -#[cfg(feature = "tdes")] impl Encrypt for super::Tdes { /// Encrypts a single block. Let's hope we don't have to support ECB!! #[inline(never)] @@ -61,7 +59,6 @@ impl Encrypt for super::Tdes { } } -#[cfg(feature = "tdes")] impl Decrypt for super::Tdes { /// Decrypts a single block. Let's hope we don't have to support ECB!! #[inline(never)] @@ -112,9 +109,3 @@ impl UnsafeInjectKey for super::Tdes { Ok(reply::UnsafeInjectKey { key: key_id }) } } - -#[cfg(not(feature = "tdes"))] -impl Encrypt for super::Tdes {} - -#[cfg(not(feature = "tdes"))] -impl Decrypt for super::Tdes {} diff --git a/src/mechanisms/totp.rs b/src/mechanisms/totp.rs index affe67ac72e..c38c3662ef9 100644 --- a/src/mechanisms/totp.rs +++ b/src/mechanisms/totp.rs @@ -11,13 +11,11 @@ const TOTP_KEY_SIZE: usize = 20; // https://tools.ietf.org/html/rfc4226#section-5.3 -#[cfg(feature = "totp")] #[inline(never)] fn hotp_raw(key: &[u8], counter: u64, digits: u32) -> u64 { hmac_and_truncate(key, &counter.to_be_bytes(), digits) } -#[cfg(feature = "totp")] #[inline(never)] fn hmac_and_truncate(key: &[u8], message: &[u8], digits: u32) -> u64 { use hmac::{Hmac, Mac}; @@ -46,7 +44,6 @@ fn dynamic_truncation(hs: &[u8]) -> u64 { p & 0x7fff_ffff } -#[cfg(feature = "totp")] impl Sign for super::Totp { #[inline(never)] fn sign(keystore: &mut impl Keystore, request: &request::Sign) -> Result { @@ -77,7 +74,6 @@ impl Sign for super::Totp { } } -#[cfg(feature = "totp")] impl Exists for super::Totp { #[inline(never)] fn exists( @@ -95,12 +91,7 @@ impl Exists for super::Totp { } } -#[cfg(not(feature = "totp"))] -impl Sign for super::Totp {} -#[cfg(not(feature = "totp"))] -impl Exists for super::Totp {} - -#[cfg(all(test, feature = "totp"))] +#[cfg(test)] mod tests { use super::*; diff --git a/src/mechanisms/trng.rs b/src/mechanisms/trng.rs index 6ef8e475767..2550d52c7d8 100644 --- a/src/mechanisms/trng.rs +++ b/src/mechanisms/trng.rs @@ -6,7 +6,6 @@ use crate::key; use crate::service::GenerateKey; use crate::store::keystore::Keystore; -#[cfg(feature = "trng")] impl GenerateKey for super::Trng { fn generate_key( keystore: &mut impl Keystore, diff --git a/src/mechanisms/x255.rs b/src/mechanisms/x255.rs index 69ad0ce5441..0cf53ea6a6e 100644 --- a/src/mechanisms/x255.rs +++ b/src/mechanisms/x255.rs @@ -41,7 +41,6 @@ fn load_secret_key( Ok(keypair) } -#[cfg(feature = "x255")] impl Agree for super::X255 { // #[inline(never)] fn agree( @@ -78,7 +77,6 @@ impl Agree for super::X255 { } } -#[cfg(feature = "x255")] impl GenerateKey for super::X255 { // #[inline(never)] fn generate_key( @@ -102,7 +100,6 @@ impl GenerateKey for super::X255 { } } -#[cfg(feature = "x255")] impl Exists for super::X255 { // #[inline(never)] fn exists( @@ -115,7 +112,6 @@ impl Exists for super::X255 { } } -#[cfg(feature = "x255")] impl DeriveKey for super::X255 { // #[inline(never)] fn derive_key( @@ -139,7 +135,6 @@ impl DeriveKey for super::X255 { } } -#[cfg(feature = "x255")] impl SerializeKey for super::X255 { // #[inline(never)] fn serialize_key( @@ -166,7 +161,6 @@ impl SerializeKey for super::X255 { } } -#[cfg(feature = "x255")] impl DeserializeKey for super::X255 { // #[inline(never)] fn deserialize_key( @@ -227,16 +221,3 @@ impl UnsafeInjectKey for super::X255 { .map(|key| reply::UnsafeInjectKey { key }) } } - -#[cfg(not(feature = "x255"))] -impl Agree for super::X255 {} -#[cfg(not(feature = "x255"))] -impl GenerateKey for super::X255 {} -#[cfg(not(feature = "x255"))] -impl Exists for super::X255 {} -#[cfg(not(feature = "x255"))] -impl DeriveKey for super::X255 {} -#[cfg(not(feature = "x255"))] -impl SerializeKey for super::X255 {} -#[cfg(not(feature = "x255"))] -impl DeserializeKey for super::X255 {} diff --git a/src/service.rs b/src/service.rs index bb791fa8da4..b4162240bdb 100644 --- a/src/service.rs +++ b/src/service.rs @@ -176,9 +176,13 @@ impl ServiceResources

{ #[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), } @@ -202,12 +206,15 @@ 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), } @@ -215,27 +222,37 @@ impl ServiceResources

{ #[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), } @@ -243,18 +260,23 @@ impl ServiceResources

{ #[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) } @@ -264,12 +286,15 @@ impl ServiceResources

{ #[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), } @@ -295,11 +320,17 @@ 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), } @@ -307,21 +338,27 @@ impl ServiceResources

{ #[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) } @@ -352,27 +389,35 @@ 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) } @@ -396,6 +441,7 @@ 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), } @@ -585,21 +631,27 @@ 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) } @@ -609,31 +661,43 @@ impl ServiceResources

{ #[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), } @@ -647,6 +711,7 @@ 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) } @@ -656,9 +721,13 @@ impl ServiceResources

{ #[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), } @@ -666,9 +735,11 @@ impl ServiceResources

{ #[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) } diff --git a/src/types.rs b/src/types.rs index 24e8a5d55e4..5af673bca84 100644 --- a/src/types.rs +++ b/src/types.rs @@ -53,6 +53,41 @@ pub mod consent { } } +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 = "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 diff --git a/tests/aes256cbc.rs b/tests/aes256cbc.rs index 9310dfa21a0..ef70836b537 100644 --- a/tests/aes256cbc.rs +++ b/tests/aes256cbc.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use trussed::client::CryptoClient; use trussed::syscall; diff --git a/tests/backends.rs b/tests/backends.rs index c4557b279ed..a3d19a4209e 100644 --- a/tests/backends.rs +++ b/tests/backends.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use littlefs2_core::path; use trussed::{ api::{reply::ReadFile, Reply, Request}, diff --git a/tests/certificate.rs b/tests/certificate.rs index 55eeeea4c67..a1edf22095c 100644 --- a/tests/certificate.rs +++ b/tests/certificate.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - mod client; use trussed::{client::CertificateClient as _, syscall, try_syscall, types::Location::*}; diff --git a/tests/counter.rs b/tests/counter.rs index 0e177d2eb1f..59d6d8aead4 100644 --- a/tests/counter.rs +++ b/tests/counter.rs @@ -1,6 +1,3 @@ -#![cfg(feature = "virt")] -#![cfg(feature = "counter-client")] - mod client; mod store; diff --git a/tests/filesystem.rs b/tests/filesystem.rs index 0100a5090f9..768910ea47b 100644 --- a/tests/filesystem.rs +++ b/tests/filesystem.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use std::assert_eq; use littlefs2_core::path; diff --git a/tests/key_confusion.rs b/tests/key_confusion.rs index dafcc296147..d09fcb88e90 100644 --- a/tests/key_confusion.rs +++ b/tests/key_confusion.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use serial_test::serial; use trussed::client::mechanisms::{P256, X255}; use trussed::client::CryptoClient; diff --git a/tests/p256.rs b/tests/p256.rs index 0e30a91a843..4a565853b5d 100644 --- a/tests/p256.rs +++ b/tests/p256.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use trussed::client::mechanisms::{HmacSha256, P256}; use trussed::client::CryptoClient; use trussed::types::{KeySerialization, Mechanism, StorageAttributes}; diff --git a/tests/serde_extensions.rs b/tests/serde_extensions.rs index 78437b28303..87982a4a208 100644 --- a/tests/serde_extensions.rs +++ b/tests/serde_extensions.rs @@ -1,5 +1,3 @@ -#![cfg(all(feature = "serde-extensions", feature = "virt"))] - // Example displaying and testing multiple backends and extensions: // // Extensions (in module `extensions`): diff --git a/tests/tdes.rs b/tests/tdes.rs index 0a52ceb5e3d..b5e01869122 100644 --- a/tests/tdes.rs +++ b/tests/tdes.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use trussed::client::CryptoClient; use trussed::syscall; diff --git a/tests/virt.rs b/tests/virt.rs index d39cfbb1727..946cf5e95e6 100644 --- a/tests/virt.rs +++ b/tests/virt.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use littlefs2_core::path; use std::time::Duration; use trussed::{ diff --git a/tests/x255.rs b/tests/x255.rs index ad973bc0105..d23d9870450 100644 --- a/tests/x255.rs +++ b/tests/x255.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "virt")] - use trussed::client::mechanisms::{HmacSha256, X255}; use trussed::client::CryptoClient; use trussed::types::{KeySerialization, Mechanism, StorageAttributes};