From dd8fc41d1fec2e43bf47c61b8aa5b6bfe5efc330 Mon Sep 17 00:00:00 2001 From: Anderson Toshiyuki Sasaki Date: Tue, 27 May 2025 08:24:40 +0200 Subject: [PATCH 1/5] Update to tss-esapi v7.6.0 Signed-off-by: Thore Sommer Signed-off-by: Anderson Toshiyuki Sasaki --- Cargo.lock | 54 +++++++++++++++++++----------------------------------- Cargo.toml | 2 +- 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63378793..a9e2bd6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -932,6 +932,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.3.2" @@ -1553,12 +1564,11 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "mbox" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f88d5c34d63aad11aa4321ef55ccb064af58b3ad8091079ae22bf83e5eb75d6" +checksum = "26d142aeadbc4e8c679fc6d93fbe7efe1c021fa7d80629e615915b519e3bc6de" dependencies = [ "libc", - "rustc_version", "stable_deref_trait", ] @@ -2023,7 +2033,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom", + "getrandom 0.3.2", ] [[package]] @@ -2116,15 +2126,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "1.0.7" @@ -2203,24 +2204,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.219" @@ -2441,7 +2424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.52.0", @@ -2651,12 +2634,13 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tss-esapi" -version = "7.4.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de234df360c349f78ecd33f0816ab3842db635732212b5cfad67f2638336864e" +checksum = "78ea9ccde878b029392ac97b5be1f470173d06ea41d18ad0bb3c92794c16a0f2" dependencies = [ "bitfield", "enumflags2", + "getrandom 0.2.16", "hostname-validator", "log", "mbox", @@ -2741,7 +2725,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "getrandom", + "getrandom 0.3.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e6d94cf4..815771b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,6 @@ static_assertions = "1" tempfile = "3.4.0" thiserror = "2.0" tokio = {version = "1", features = ["rt", "sync", "macros"]} -tss-esapi = {version = "7.4.0", features = ["generate-bindings"]} +tss-esapi = {version = "7.6.0", features = ["generate-bindings"]} uuid = {version = "1.3", features = ["v4"]} zip = {version = "0.6", default-features = false, features= ["deflate"]} From d526499044d7821e182165c42338db058f72eb81 Mon Sep 17 00:00:00 2001 From: Anderson Toshiyuki Sasaki Date: Tue, 27 May 2025 08:38:01 +0200 Subject: [PATCH 2/5] config: Use next_back() instead of last() for iterators This fixes a warning generated by clippy. Signed-off-by: Anderson Toshiyuki Sasaki --- keylime-agent/src/config.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/keylime-agent/src/config.rs b/keylime-agent/src/config.rs index c4755034..b7ccdbba 100644 --- a/keylime-agent/src/config.rs +++ b/keylime-agent/src/config.rs @@ -548,8 +548,10 @@ fn config_translate_keywords( .collect::>() .join(", "), "latest" => { - if let Some(version) = - SUPPORTED_API_VERSIONS.iter().map(|&s| s.to_string()).last() + if let Some(version) = SUPPORTED_API_VERSIONS + .iter() + .map(|&s| s.to_string()) + .next_back() { version } else { @@ -914,7 +916,7 @@ mod tests { let expected = SUPPORTED_API_VERSIONS .iter() .map(|e| e.to_string()) - .last() + .next_back() .unwrap(); //#[allow_ci] assert_eq!(version, expected); } From 6fd02debe42ffdd60500835ee226c86418984742 Mon Sep 17 00:00:00 2001 From: Thore Sommer Date: Tue, 1 Oct 2024 22:28:41 +0200 Subject: [PATCH 3/5] Enable non standard key sizes and curves for EK and AK Add the missing argument when calling create_ak() to the push model prototype Signed-off-by: Thore Sommer Signed-off-by: Anderson Toshiyuki Sasaki --- keylime-agent/src/agent_handler.rs | 2 +- keylime-agent/src/common.rs | 1 + keylime-agent/src/main.rs | 5 +- keylime-push-model-agent/src/registration.rs | 8 +- keylime/src/algorithms.rs | 111 +++++++++++++++++-- keylime/src/tpm.rs | 53 +++++---- 6 files changed, 142 insertions(+), 38 deletions(-) diff --git a/keylime-agent/src/agent_handler.rs b/keylime-agent/src/agent_handler.rs index 44228c12..13bcc375 100644 --- a/keylime-agent/src/agent_handler.rs +++ b/keylime-agent/src/agent_handler.rs @@ -88,7 +88,7 @@ mod tests { async fn test_agent_info() { let (mut quotedata, mutex) = QuoteData::fixture().await.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 76942eb8..338a4540 100644 --- a/keylime-agent/src/common.rs +++ b/keylime-agent/src/common.rs @@ -126,6 +126,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 68308961..c01413ea 100644 --- a/keylime-agent/src/main.rs +++ b/keylime-agent/src/main.rs @@ -423,6 +423,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)?; @@ -980,6 +981,7 @@ mod testing { .create_ak( ek_result.key_handle, tpm_hash_alg, + tpm_encryption_alg, tpm_signing_alg, ) .unwrap(); //#[allow_ci] @@ -1057,7 +1059,8 @@ 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-push-model-agent/src/registration.rs b/keylime-push-model-agent/src/registration.rs index 72050eac..ed6bea46 100644 --- a/keylime-push-model-agent/src/registration.rs +++ b/keylime-push-model-agent/src/registration.rs @@ -34,8 +34,12 @@ pub async fn register_agent( let mut ctx = tpm::Context::new()?; let ek_result = ctx.create_ek(tpm_encryption_alg, None)?; let ek_hash = hash_ek::hash_ek_pubkey(ek_result.public.clone())?; - let ak = - ctx.create_ak(ek_result.key_handle, tpm_hash_alg, tpm_signing_alg)?; + let 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, &ak)?; AgentData::create( 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 a717f373..0369b64b 100644 --- a/keylime/src/tpm.rs +++ b/keylime/src/tpm.rs @@ -599,7 +599,7 @@ impl Context<'_> { let key_handle: KeyHandle = match handle { Some(v) => { if v.is_empty() { - ek::create_ek_object(&mut ctx, alg.into(), DefaultKey) + ek::create_ek_object_2(&mut ctx, alg.into(), DefaultKey) .map_err(|source| TpmError::TSSCreateEKError { source, })? @@ -628,7 +628,7 @@ impl Context<'_> { .into() } } - None => ek::create_ek_object(&mut ctx, alg.into(), DefaultKey) + None => ek::create_ek_object_2(&mut ctx, alg.into(), DefaultKey) .map_err(|source| TpmError::TSSCreateEKError { source })?, }; @@ -677,6 +677,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 @@ -684,12 +685,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.lock().unwrap(), //#[allow_ci] handle, hash_alg.into(), + key_alg.into(), sign_alg.into(), None, DefaultKey, @@ -1973,9 +1976,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)?), ), }; @@ -2583,7 +2584,8 @@ pub mod tests { async fn test_create_ek() { let _mutex = testing::lock_tests().await; 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]; @@ -2606,12 +2608,15 @@ pub mod tests { let _mutex = testing::lock_tests().await; 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(), "Result: {r:?}"); let ek_result = r.unwrap(); //#[allow_ci] let ek_handle = ek_result.key_handle; + let eng_algs = + [EncryptionAlgorithm::Rsa1024, EncryptionAlgorithm::Rsa2048]; + let hash_algs = [ HashAlgorithm::Sha256, HashAlgorithm::Sha384, @@ -2632,18 +2637,20 @@ pub mod tests { ]; for sign in sign_algs { - for hash in hash_algs { - let r = ctx.create_ak(ek_handle, hash, sign); - assert!(r.is_ok(), "Result: {r:?}"); - let ak = r.unwrap(); //#[allow_ci] - - let r = ctx.load_ak(ek_handle, &ak); - assert!(r.is_ok(), "Result: {r:?}"); - let handle = r.unwrap(); //#[allow_ci] - - // Flush context to free TPM memory - let r = ctx.flush_context(handle.into()); - assert!(r.is_ok(), "Result: {r:?}"); + for enc in eng_algs { + for hash in hash_algs { + let r = ctx.create_ak(ek_handle, hash, enc, sign); + assert!(r.is_ok(), "Result: {r:?}"); + let ak = r.unwrap(); //#[allow_ci] + + let r = ctx.load_ak(ek_handle, &ak); + assert!(r.is_ok(), "Result: {r:?}"); + let handle = r.unwrap(); //#[allow_ci] + + // Flush context to free TPM memory + let r = ctx.flush_context(handle.into()); + assert!(r.is_ok(), "Result: {r:?}"); + } } } @@ -2724,7 +2731,7 @@ pub mod tests { // 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; @@ -2733,6 +2740,7 @@ pub mod tests { .create_ak( ek_handle, HashAlgorithm::Sha256, + EncryptionAlgorithm::Rsa2048, SignAlgorithm::RsaSsa, ) .expect("failed to create AK"); @@ -2780,7 +2788,7 @@ pub mod tests { // 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; @@ -2789,6 +2797,7 @@ pub mod tests { .create_ak( ek_handle, HashAlgorithm::Sha256, + EncryptionAlgorithm::Rsa2048, SignAlgorithm::RsaSsa, ) .expect("failed to create ak"); From 88884a58129b7392d2cac01d0744aad3f5de5051 Mon Sep 17 00:00:00 2001 From: Thore Sommer Date: Tue, 12 Nov 2024 10:07:58 +0100 Subject: [PATCH 4/5] tpm: add policy auth for EK to activate crendential Signed-off-by: Thore Sommer Signed-off-by: Anderson Toshiyuki Sasaki --- keylime/src/tpm.rs | 151 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 118 insertions(+), 33 deletions(-) diff --git a/keylime/src/tpm.rs b/keylime/src/tpm.rs index 0369b64b..87c796e0 100644 --- a/keylime/src/tpm.rs +++ b/keylime/src/tpm.rs @@ -16,6 +16,9 @@ use std::{ sync::{Arc, Mutex, OnceLock}, }; use thiserror::Error; +use tss_esapi::handles::SessionHandle; +use tss_esapi::interface_types::session_handles::PolicySession; +use tss_esapi::structures::{DigestList, SymmetricDefinition}; use openssl::{ hash::{Hasher, MessageDigest}, @@ -26,9 +29,7 @@ use openssl::{ use tss_esapi::{ abstraction::{ - ak, - cipher::Cipher, - ek, nv, + ak, ek, nv, pcr::{read_all, PcrData}, DefaultKey, }, @@ -41,7 +42,7 @@ use tss_esapi::{ }, handles::{ AuthHandle, KeyHandle, ObjectHandle, PcrHandle, PersistentTpmHandle, - SessionHandle, TpmHandle, + TpmHandle, }, interface_types::{ algorithm::{AsymmetricAlgorithm, HashingAlgorithm, PublicAlgorithm}, @@ -120,6 +121,47 @@ const UNIQUE_IAK: [u8; 3] = [0x49, 0x41, 0x4b]; const RSA_EK_CERTIFICATE_CHAIN_START: u32 = 0x01c00100; const RSA_EK_CERTIFICATE_CHAIN_END: u32 = 0x01c001ff; +// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.5 Revision 2 +// Section B.6 +const POLICY_A_SHA384: [u8; 48] = [ + 0x8b, 0xbf, 0x22, 0x66, 0x53, 0x7c, 0x17, 0x1c, 0xb5, 0x6e, 0x40, 0x3c, + 0x4d, 0xc1, 0xd4, 0xb6, 0x4f, 0x43, 0x26, 0x11, 0xdc, 0x38, 0x6e, 0x6f, + 0x53, 0x20, 0x50, 0xc3, 0x27, 0x8c, 0x93, 0x0e, 0x14, 0x3e, 0x8b, 0xb1, + 0x13, 0x38, 0x24, 0xcc, 0xb4, 0x31, 0x05, 0x38, 0x71, 0xc6, 0xdb, 0x53, +]; +const POLICY_A_SHA512: [u8; 64] = [ + 0x1e, 0x3b, 0x76, 0x50, 0x2c, 0x8a, 0x14, 0x25, 0xaa, 0x0b, 0x7b, 0x3f, + 0xc6, 0x46, 0xa1, 0xb0, 0xfa, 0xe0, 0x63, 0xb0, 0x3b, 0x53, 0x68, 0xf9, + 0xc4, 0xcd, 0xde, 0xca, 0xff, 0x08, 0x91, 0xdd, 0x68, 0x2b, 0xac, 0x1a, + 0x85, 0xd4, 0xd8, 0x32, 0xb7, 0x81, 0xea, 0x45, 0x19, 0x15, 0xde, 0x5f, + 0xc5, 0xbf, 0x0d, 0xc4, 0xa1, 0x91, 0x7c, 0xd4, 0x2f, 0xa0, 0x41, 0xe3, + 0xf9, 0x98, 0xe0, 0xee, +]; +const POLICY_A_SM3_256: [u8; 32] = [ + 0xc6, 0x7f, 0x7d, 0x35, 0xf6, 0x6f, 0x3b, 0xec, 0x13, 0xc8, 0x9f, 0xe8, + 0x98, 0x92, 0x1c, 0x65, 0x1b, 0x0c, 0xb5, 0xa3, 0x8a, 0x92, 0x69, 0x0a, + 0x62, 0xa4, 0x3c, 0x00, 0x12, 0xe4, 0xfb, 0x8b, +]; +const POLICY_C_SHA384: [u8; 48] = [ + 0xd6, 0x03, 0x2c, 0xe6, 0x1f, 0x2f, 0xb3, 0xc2, 0x40, 0xeb, 0x3c, 0xf6, + 0xa3, 0x32, 0x37, 0xef, 0x2b, 0x6a, 0x16, 0xf4, 0x29, 0x3c, 0x22, 0xb4, + 0x55, 0xe2, 0x61, 0xcf, 0xfd, 0x21, 0x7a, 0xd5, 0xb4, 0x94, 0x7c, 0x2d, + 0x73, 0xe6, 0x30, 0x05, 0xee, 0xd2, 0xdc, 0x2b, 0x35, 0x93, 0xd1, 0x65, +]; +const POLICY_C_SHA512: [u8; 64] = [ + 0x58, 0x9e, 0xe1, 0xe1, 0x46, 0x54, 0x47, 0x16, 0xe8, 0xde, 0xaf, 0xe6, + 0xdb, 0x24, 0x7b, 0x01, 0xb8, 0x1e, 0x9f, 0x9c, 0x7d, 0xd1, 0x6b, 0x81, + 0x4a, 0xa1, 0x59, 0x13, 0x87, 0x49, 0x10, 0x5f, 0xba, 0x53, 0x88, 0xdd, + 0x1d, 0xea, 0x70, 0x2f, 0x35, 0x24, 0x0c, 0x18, 0x49, 0x33, 0x12, 0x1e, + 0x2c, 0x61, 0xb8, 0xf5, 0x0d, 0x3e, 0xf9, 0x13, 0x93, 0xa4, 0x9a, 0x38, + 0xc3, 0xf7, 0x3f, 0xc8, +]; +const POLICY_C_SM3_256: [u8; 32] = [ + 0x2d, 0x4e, 0x81, 0x57, 0x8c, 0x35, 0x31, 0xd9, 0xbd, 0x1c, 0xdd, 0x7d, + 0x02, 0xba, 0x29, 0x8d, 0x56, 0x99, 0xa3, 0xe3, 0x9f, 0xc3, 0x55, 0x1b, + 0xfe, 0xff, 0xcf, 0x13, 0x2b, 0x49, 0xe1, 0x1d, +]; + /// TpmError wraps all possible errors raised in tpm.rs #[derive(Error, Debug)] pub enum TpmError { @@ -1267,19 +1309,14 @@ impl Context<'_> { /// Creates an empty authentication session fn create_empty_session( &mut self, + ctx: &mut tss_esapi::Context, ses_type: SessionType, + symmetric: SymmetricDefinition, + hash_alg: HashingAlgorithm, ) -> Result { - let mut ctx = self.inner.lock().unwrap(); //#[allow_ci] let Some(session) = ctx .start_auth_session( - None, - None, - None, - ses_type, - Cipher::aes_128_cfb().try_into().map_err(|source| { - TpmError::TSSSymmetricDefinitionFromCipher { source } - })?, - HashingAlgorithm::Sha256, + None, None, None, ses_type, symmetric, hash_alg, ) .map_err(|source| { TpmError::TSSStartAuthenticationSessionError { source } @@ -1307,35 +1344,83 @@ impl Context<'_> { ak: KeyHandle, ek: KeyHandle, ) -> Result { - let (credential, secret) = parse_cred_and_secret(keyblob)?; - - let ek_auth = self.create_empty_session(SessionType::Policy)?; - let mut ctx = self.inner.lock().unwrap(); //#[allow_ci] - // We authorize ses2 with PolicySecret(ENDORSEMENT) as per PolicyA - let _ = ctx.execute_with_nullauth_session(|context| { - context.policy_secret( - ek_auth.try_into()?, - AuthHandle::Endorsement, - Default::default(), - Default::default(), - Default::default(), - None, - ) - })?; + let (credential, secret) = parse_cred_and_secret(keyblob)?; + let mut policy_digests = DigestList::new(); + let (parent_public, _, _) = ctx.read_public(ek)?; + let ek_hash_alg = parent_public.name_hashing_algorithm(); + let ek_symmetric = + parent_public.symmetric_algorithm().ok_or_else(|| { + TpmError::TSSReadPublicError { + source: tss_esapi::Error::WrapperError( + tss_esapi::WrapperErrorKind::InvalidParam, + ), + } + })?; + match ek_hash_alg { + HashingAlgorithm::Sha384 => { + policy_digests + .add(Digest::try_from(POLICY_A_SHA384.as_slice())?)?; + policy_digests + .add(Digest::try_from(POLICY_C_SHA384.as_slice())?)?; + } + HashingAlgorithm::Sha512 => { + policy_digests + .add(Digest::try_from(POLICY_A_SHA512.as_slice())?)?; + policy_digests + .add(Digest::try_from(POLICY_C_SHA512.as_slice())?)?; + } + HashingAlgorithm::Sm3_256 => { + policy_digests + .add(Digest::try_from(POLICY_A_SM3_256.as_slice())?)?; + policy_digests + .add(Digest::try_from(POLICY_C_SM3_256.as_slice())?)?; + } + _ => (), + }; + + let ek_auth = self.create_empty_session( + &mut ctx, + SessionType::Policy, + ek_symmetric.into(), + ek_hash_alg, + )?; + // We authorize session according to the EK profile spec let result = ctx - .execute_with_sessions( - (Some(AuthSession::Password), Some(ek_auth), None), - |context| { - context.activate_credential(ak, ek, credential, secret) + .execute_with_temporary_object( + SessionHandle::from(ek_auth).into(), + |ctx, _| { + let _ = ctx.execute_with_nullauth_session(|ctx| { + ctx.policy_secret( + PolicySession::try_from(ek_auth)?, + AuthHandle::Endorsement, + Default::default(), + Default::default(), + Default::default(), + None, + ) + })?; + if !policy_digests.is_empty() { + ctx.policy_or( + PolicySession::try_from(ek_auth)?, + policy_digests, + )? + } + ctx.execute_with_sessions( + (Some(AuthSession::Password), Some(ek_auth), None), + |ctx| { + ctx.activate_credential( + ak, ek, credential, secret, + ) + }, + ) }, ) .map_err(TpmError::from); // Clear sessions after use - ctx.flush_context(SessionHandle::from(ek_auth).into())?; ctx.clear_sessions(); result From a99bb40119b9da3036d38bb0dc3144e329643b9b Mon Sep 17 00:00:00 2001 From: Thore Sommer Date: Thu, 19 Dec 2024 14:40:58 +0100 Subject: [PATCH 5/5] keylime-agent.conf: add all accepted TPM encryption algs Signed-off-by: Thore Sommer --- keylime-agent.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keylime-agent.conf b/keylime-agent.conf index 28b2c266..d8b95559 100644 --- a/keylime-agent.conf +++ b/keylime-agent.conf @@ -217,7 +217,7 @@ allow_payload_revocation_actions = true # # Currently accepted values include: # - hashing: sha512, sha384, sha256 or sha1 -# - encryption: ecc or rsa +# - encryption: rsa (alias for rsa2048), rsa1024, rsa2048, rsa3072, rsa4096, ecc (alias for ecc256), ecc192, ecc224, ecc256, ecc384, ecc521 or ecc_sm2. # - signing: rsassa or ecdsa # # To override tpm_hash_alg, set KEYLIME_AGENT_TPM_HASH_ALG environment variable.