From 05dc60fafa3ae6fb6c173d0a726d840e70c1eaab Mon Sep 17 00:00:00 2001 From: Thore Sommer Date: Tue, 1 Oct 2024 22:28:41 +0200 Subject: [PATCH] enable non standard key sizes and curves for EK and AK Signed-off-by: Thore Sommer --- keylime-agent/src/agent_handler.rs | 2 +- keylime-agent/src/common.rs | 1 + keylime-agent/src/main.rs | 4 +- keylime/src/algorithms.rs | 111 +++++++++++++++++++++++++---- keylime/src/tpm.rs | 39 ++++++---- 5 files changed, 128 insertions(+), 29 deletions(-) diff --git a/keylime-agent/src/agent_handler.rs b/keylime-agent/src/agent_handler.rs index d75f3fa9..67a0b40e 100644 --- a/keylime-agent/src/agent_handler.rs +++ b/keylime-agent/src/agent_handler.rs @@ -89,7 +89,7 @@ mod tests { async fn test_agent_info() { let mut quotedata = QuoteData::fixture().unwrap(); //#[allow_ci] quotedata.hash_alg = keylime::algorithms::HashAlgorithm::Sha256; - quotedata.enc_alg = keylime::algorithms::EncryptionAlgorithm::Rsa; + quotedata.enc_alg = keylime::algorithms::EncryptionAlgorithm::Rsa2048; quotedata.sign_alg = keylime::algorithms::SignAlgorithm::RsaSsa; quotedata.agent_uuid = "DEADBEEF".to_string(); let data = web::Data::new(quotedata); diff --git a/keylime-agent/src/common.rs b/keylime-agent/src/common.rs index a6cb0702..e3ce9e28 100644 --- a/keylime-agent/src/common.rs +++ b/keylime-agent/src/common.rs @@ -303,6 +303,7 @@ mod tests { let ak = ctx.create_ak( ek_result.key_handle, tpm_hash_alg, + tpm_encryption_alg, tpm_signing_alg, )?; diff --git a/keylime-agent/src/main.rs b/keylime-agent/src/main.rs index e331807b..486bed08 100644 --- a/keylime-agent/src/main.rs +++ b/keylime-agent/src/main.rs @@ -548,6 +548,7 @@ async fn main() -> Result<()> { let new_ak = ctx.create_ak( ek_result.key_handle, tpm_hash_alg, + tpm_encryption_alg, tpm_signing_alg, )?; let ak_handle = ctx.load_ak(ek_result.key_handle, &new_ak)?; @@ -1108,6 +1109,7 @@ mod testing { let ak_result = ctx.create_ak( ek_result.key_handle, tpm_hash_alg, + tpm_encryption_alg, tpm_signing_alg, )?; let ak_handle = ctx.load_ak(ek_result.key_handle, &ak_result)?; @@ -1176,7 +1178,7 @@ mod testing { payload_tx, revocation_tx, hash_alg: keylime::algorithms::HashAlgorithm::Sha256, - enc_alg: keylime::algorithms::EncryptionAlgorithm::Rsa, + enc_alg: keylime::algorithms::EncryptionAlgorithm::Rsa2048, sign_alg: keylime::algorithms::SignAlgorithm::RsaSsa, agent_uuid: test_config.agent.uuid, allow_payload_revocation_actions: test_config diff --git a/keylime/src/algorithms.rs b/keylime/src/algorithms.rs index 9c461954..cda89665 100644 --- a/keylime/src/algorithms.rs +++ b/keylime/src/algorithms.rs @@ -6,8 +6,13 @@ use std::convert::TryFrom; use std::fmt; use thiserror::Error; use tss_esapi::{ - interface_types::algorithm::{ - AsymmetricAlgorithm, HashingAlgorithm, SignatureSchemeAlgorithm, + abstraction::AsymmetricAlgorithmSelection, + interface_types::{ + algorithm::{ + AsymmetricAlgorithm, HashingAlgorithm, SignatureSchemeAlgorithm, + }, + ecc::EccCurve, + key_bits::RsaKeyBits, }, structures::{HashScheme, SignatureScheme}, }; @@ -89,15 +94,68 @@ impl From for MessageDigest { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum EncryptionAlgorithm { - Rsa, - Ecc, + Rsa1024, + Rsa2048, + Rsa3072, + Rsa4096, + Ecc192, + Ecc224, + Ecc256, + Ecc384, + Ecc521, + EccSm2, } impl From for AsymmetricAlgorithm { fn from(enc_alg: EncryptionAlgorithm) -> Self { match enc_alg { - EncryptionAlgorithm::Rsa => AsymmetricAlgorithm::Rsa, - EncryptionAlgorithm::Ecc => AsymmetricAlgorithm::Ecc, + EncryptionAlgorithm::Rsa1024 => AsymmetricAlgorithm::Rsa, + EncryptionAlgorithm::Rsa2048 => AsymmetricAlgorithm::Rsa, + EncryptionAlgorithm::Rsa3072 => AsymmetricAlgorithm::Rsa, + EncryptionAlgorithm::Rsa4096 => AsymmetricAlgorithm::Rsa, + EncryptionAlgorithm::Ecc192 => AsymmetricAlgorithm::Ecc, + EncryptionAlgorithm::Ecc224 => AsymmetricAlgorithm::Ecc, + EncryptionAlgorithm::Ecc256 => AsymmetricAlgorithm::Ecc, + EncryptionAlgorithm::Ecc384 => AsymmetricAlgorithm::Ecc, + EncryptionAlgorithm::Ecc521 => AsymmetricAlgorithm::Ecc, + EncryptionAlgorithm::EccSm2 => AsymmetricAlgorithm::Ecc, + } + } +} + +impl From for AsymmetricAlgorithmSelection { + fn from(enc_alg: EncryptionAlgorithm) -> Self { + match enc_alg { + EncryptionAlgorithm::Rsa1024 => { + AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa1024) + } + EncryptionAlgorithm::Rsa2048 => { + AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048) + } + EncryptionAlgorithm::Rsa3072 => { + AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa3072) + } + EncryptionAlgorithm::Rsa4096 => { + AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa4096) + } + EncryptionAlgorithm::Ecc192 => { + AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP192) + } + EncryptionAlgorithm::Ecc224 => { + AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP224) + } + EncryptionAlgorithm::Ecc256 => { + AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256) + } + EncryptionAlgorithm::Ecc384 => { + AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP384) + } + EncryptionAlgorithm::Ecc521 => { + AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP521) + } + EncryptionAlgorithm::EccSm2 => { + AsymmetricAlgorithmSelection::Ecc(EccCurve::Sm2P256) + } } } } @@ -107,8 +165,25 @@ impl TryFrom<&str> for EncryptionAlgorithm { fn try_from(value: &str) -> Result { match value { - "rsa" => Ok(EncryptionAlgorithm::Rsa), - "ecc" => Ok(EncryptionAlgorithm::Ecc), + /* Use default key size and curve if not explicitly specified */ + "rsa" => Ok(EncryptionAlgorithm::Rsa2048), + "ecc" => Ok(EncryptionAlgorithm::Ecc256), + "rsa1024" => Ok(EncryptionAlgorithm::Rsa1024), + "rsa2048" => Ok(EncryptionAlgorithm::Rsa2048), + "rsa3072" => Ok(EncryptionAlgorithm::Rsa3072), + "rsa4096" => Ok(EncryptionAlgorithm::Rsa4096), + "ecc192" => Ok(EncryptionAlgorithm::Ecc192), + "ecc_nist_p192" => Ok(EncryptionAlgorithm::Ecc192), + "ecc224" => Ok(EncryptionAlgorithm::Ecc224), + "ecc_nist_p224" => Ok(EncryptionAlgorithm::Ecc224), + "ecc256" => Ok(EncryptionAlgorithm::Ecc256), + "ecc_nist_p256" => Ok(EncryptionAlgorithm::Ecc256), + "ecc384" => Ok(EncryptionAlgorithm::Ecc384), + "ecc_nist_p384" => Ok(EncryptionAlgorithm::Ecc384), + "ecc521" => Ok(EncryptionAlgorithm::Ecc521), + "ecc_nist_p521" => Ok(EncryptionAlgorithm::Ecc521), + "ecc_sm2" => Ok(EncryptionAlgorithm::EccSm2), + "ecc_sm2_p256" => Ok(EncryptionAlgorithm::EccSm2), _ => Err(AlgorithmError::UnsupportedEncryptionAlgorithm( value.into(), )), @@ -119,8 +194,16 @@ impl TryFrom<&str> for EncryptionAlgorithm { impl fmt::Display for EncryptionAlgorithm { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let value = match self { - EncryptionAlgorithm::Rsa => "rsa", - EncryptionAlgorithm::Ecc => "ecc", + EncryptionAlgorithm::Rsa1024 => "rsa1024", + EncryptionAlgorithm::Rsa2048 => "rsa", /* for backwards compatibility */ + EncryptionAlgorithm::Rsa3072 => "rsa3072", + EncryptionAlgorithm::Rsa4096 => "rsa4096", + EncryptionAlgorithm::Ecc192 => "ecc192", + EncryptionAlgorithm::Ecc224 => "ecc224", + EncryptionAlgorithm::Ecc256 => "ecc", /* for backwards compatibility */ + EncryptionAlgorithm::Ecc384 => "ecc384", + EncryptionAlgorithm::Ecc521 => "ecc521", + EncryptionAlgorithm::EccSm2 => "ecc_sm2", }; write!(f, "{value}") } @@ -219,9 +302,13 @@ mod tests { #[test] fn test_encrypt_try_from() { let result = EncryptionAlgorithm::try_from("rsa"); - assert!(result.is_ok()); + assert!(result.is_ok_and(|r| r == EncryptionAlgorithm::Rsa2048)); let result = EncryptionAlgorithm::try_from("ecc"); - assert!(result.is_ok()); + assert!(result.is_ok_and(|r| r == EncryptionAlgorithm::Ecc256)); + let result = EncryptionAlgorithm::try_from("rsa4096"); + assert!(result.is_ok_and(|r| r == EncryptionAlgorithm::Rsa4096)); + let result = EncryptionAlgorithm::try_from("ecc256"); + assert!(result.is_ok_and(|r| r == EncryptionAlgorithm::Ecc256)); } #[test] fn test_unsupported_encrypt_try_from() { diff --git a/keylime/src/tpm.rs b/keylime/src/tpm.rs index 753f96a3..1d971a60 100644 --- a/keylime/src/tpm.rs +++ b/keylime/src/tpm.rs @@ -523,7 +523,7 @@ impl Context { let key_handle = match handle { Some(v) => { if v.is_empty() { - ek::create_ek_object( + ek::create_ek_object_2( &mut self.inner, alg.into(), DefaultKey, @@ -592,6 +592,7 @@ impl Context { /// /// * `handle`: The associated EK handle /// * `hash_alg`: The digest algorithm used for signing with the created AK + /// * `key_alg`: The key type used for signing with the created AK /// * `sign_alg`: The created AK signing algorithm /// /// Returns an `AKResult` structure if successful and a `TPMError` otherwise @@ -599,12 +600,14 @@ impl Context { &mut self, handle: KeyHandle, hash_alg: HashAlgorithm, + key_alg: EncryptionAlgorithm, sign_alg: SignAlgorithm, ) -> Result { - let ak = ak::create_ak( + let ak = ak::create_ak_2( &mut self.inner, handle, hash_alg.into(), + key_alg.into(), sign_alg.into(), None, DefaultKey, @@ -1802,9 +1805,7 @@ pub fn get_idevid_template( "H-4" => (AsymmetricAlgorithm::Ecc, HashingAlgorithm::Sha512), "H-5" => (AsymmetricAlgorithm::Ecc, HashingAlgorithm::Sm3_256), _ => ( - AsymmetricAlgorithm::from(EncryptionAlgorithm::try_from( - asym_alg_str, - )?), + EncryptionAlgorithm::try_from(asym_alg_str)?.into(), HashingAlgorithm::from(HashAlgorithm::try_from(name_alg_str)?), ), }; @@ -2120,7 +2121,8 @@ pub mod testing { #[cfg(feature = "testing")] fn test_create_ek() { let mut ctx = Context::new().unwrap(); //#[allow_ci] - let algs = [EncryptionAlgorithm::Rsa, EncryptionAlgorithm::Ecc]; + let algs = + [EncryptionAlgorithm::Rsa2048, EncryptionAlgorithm::Ecc256]; // TODO: create persistent handle and add to be tested: Some("0x81000000"), let handles = [Some(""), None]; @@ -2137,7 +2139,7 @@ pub mod testing { fn test_create_and_load_ak() { let mut ctx = Context::new().unwrap(); //#[allow_ci] - let r = ctx.create_ek(EncryptionAlgorithm::Rsa, None); + let r = ctx.create_ek(EncryptionAlgorithm::Rsa2048, None); assert!(r.is_ok()); let ek_result = r.unwrap(); //#[allow_ci] @@ -2152,6 +2154,9 @@ pub mod testing { //HashingAlgorithm::Sha3_512, // Not supported by swtpm //HashingAlgorithm::Sha1, // Not supported by swtpm ]; + let eng_algs = + [EncryptionAlgorithm::Rsa1024, EncryptionAlgorithm::Rsa2048]; + let sign_algs = [ SignAlgorithm::RsaSsa, SignAlgorithm::RsaPss, @@ -2163,14 +2168,16 @@ pub mod testing { ]; for sign in sign_algs { - for hash in hash_algs { - let r = ctx.create_ak(ek_handle, hash, sign); - assert!(r.is_ok()); + for enc in eng_algs { + for hash in hash_algs { + let r = ctx.create_ak(ek_handle, hash, enc, sign); + assert!(r.is_ok()); - let ak = r.unwrap(); //#[allow_ci] + let ak = r.unwrap(); //#[allow_ci] - let r = ctx.load_ak(ek_handle, &ak); - assert!(r.is_ok()); + let r = ctx.load_ak(ek_handle, &ak); + assert!(r.is_ok()); + } } } } @@ -2230,7 +2237,7 @@ pub mod testing { // Create EK let ek_result = ctx - .create_ek(EncryptionAlgorithm::Rsa, None) + .create_ek(EncryptionAlgorithm::Rsa2048, None) .expect("failed to create EK"); let ek_handle = ek_result.key_handle; @@ -2239,6 +2246,7 @@ pub mod testing { .create_ak( ek_handle, HashAlgorithm::Sha256, + EncryptionAlgorithm::Rsa2048, SignAlgorithm::RsaSsa, ) .expect("failed to create AK"); @@ -2279,7 +2287,7 @@ pub mod testing { // Create EK let ek_result = ctx - .create_ek(EncryptionAlgorithm::Rsa, None) + .create_ek(EncryptionAlgorithm::Rsa2048, None) .expect("failed to create EK"); let ek_handle = ek_result.key_handle; @@ -2288,6 +2296,7 @@ pub mod testing { .create_ak( ek_handle, HashAlgorithm::Sha256, + EncryptionAlgorithm::Rsa2048, SignAlgorithm::RsaSsa, ) .expect("failed to create ak");