From cde261e4812553b4ac96be749e516d03196a140a 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 | 35 +++++---- 5 files changed, 126 insertions(+), 27 deletions(-) diff --git a/keylime-agent/src/agent_handler.rs b/keylime-agent/src/agent_handler.rs index 11d021864..c83b288dc 100644 --- a/keylime-agent/src/agent_handler.rs +++ b/keylime-agent/src/agent_handler.rs @@ -49,7 +49,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 a6cb0702e..e3ce9e281 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 7b3db34b6..fedda4627 100644 --- a/keylime-agent/src/main.rs +++ b/keylime-agent/src/main.rs @@ -540,6 +540,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)?; @@ -1148,6 +1149,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)?; @@ -1216,7 +1218,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 9c461954e..4b4205a5d 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 => "rsa2048", + EncryptionAlgorithm::Rsa3072 => "rsa3072", + EncryptionAlgorithm::Rsa4096 => "rsa4096", + EncryptionAlgorithm::Ecc192 => "ecc192", + EncryptionAlgorithm::Ecc224 => "ecc224", + EncryptionAlgorithm::Ecc256 => "ecc256", + 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 54913424c..69690e347 100644 --- a/keylime/src/tpm.rs +++ b/keylime/src/tpm.rs @@ -574,6 +574,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 @@ -581,12 +582,14 @@ impl Context { &mut self, handle: KeyHandle, hash_alg: HashAlgorithm, + key_alg: EncryptionAlgorithm, sign_alg: SignAlgorithm, ) -> Result { let ak = ak::create_ak( &mut self.inner, handle, hash_alg.into(), + key_alg.into(), sign_alg.into(), None, DefaultKey, @@ -1784,9 +1787,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)?), ), }; @@ -2102,7 +2103,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]; @@ -2119,7 +2121,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] @@ -2134,6 +2136,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, @@ -2145,14 +2150,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()); + } } } } @@ -2212,7 +2219,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; @@ -2221,6 +2228,7 @@ pub mod testing { .create_ak( ek_handle, HashAlgorithm::Sha256, + EncryptionAlgorithm::Rsa2048, SignAlgorithm::RsaSsa, ) .expect("failed to create AK"); @@ -2261,7 +2269,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; @@ -2270,6 +2278,7 @@ pub mod testing { .create_ak( ek_handle, HashAlgorithm::Sha256, + EncryptionAlgorithm::Rsa2048, SignAlgorithm::RsaSsa, ) .expect("failed to create ak");