From 3811bffc6701242eb39dba04ddc07a617e34fc2d Mon Sep 17 00:00:00 2001 From: Patrick Uiterwijk Date: Wed, 3 Nov 2021 10:24:38 +0100 Subject: [PATCH] fix: use hash for name oject hash alg This makes sure we actually use the correct hash algorithm for name alg. Fixes: #9 Signed-off-by: Patrick Uiterwijk --- src/cli.rs | 8 +++++++- src/main.rs | 11 ++++++----- src/tpm_objects.rs | 8 ++++++-- src/utils.rs | 2 +- tests/test_pcr | 5 +++++ 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index a82264c..d0c6b93 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -72,7 +72,13 @@ impl TPM2Config { pub(super) fn get_pcr_hash_alg( &self, ) -> tss_esapi::interface_types::algorithm::HashingAlgorithm { - crate::utils::get_pcr_hash_alg_from_name(self.pcr_bank.as_ref()) + crate::utils::get_hash_alg_from_name(self.pcr_bank.as_ref()) + } + + pub(super) fn get_name_hash_alg( + &self, + ) -> tss_esapi::interface_types::algorithm::HashingAlgorithm { + crate::utils::get_hash_alg_from_name(self.hash.as_ref()) } pub(super) fn get_pcr_ids(&self) -> Option> { diff --git a/src/main.rs b/src/main.rs index b32ef06..638b626 100644 --- a/src/main.rs +++ b/src/main.rs @@ -146,7 +146,7 @@ fn perform_encrypt(cfg: TPM2Config, input: Vec) -> Result<(), PinError> { None => "ecc", Some(key_type) => key_type, }; - let key_public = tpm_objects::get_key_public(&key_type)?; + let key_public = tpm_objects::get_key_public(&key_type, cfg.get_name_hash_alg())?; let mut ctx = utils::get_tpm2_ctx()?; let key_handle = utils::get_tpm2_primary_key(&mut ctx, &key_public)?; @@ -206,7 +206,7 @@ fn perform_encrypt(cfg: TPM2Config, input: Vec) -> Result<(), PinError> { clevis: ClevisInner { pin: pin_type.to_string(), tpm2: Tpm2Inner { - hash: "sha256".to_string(), + hash: cfg.hash.as_ref().unwrap_or(&"sha256".to_string()).clone(), key: key_type.to_string(), jwk_pub, jwk_priv, @@ -282,7 +282,7 @@ impl TryFrom<&Tpm2Inner> for TPMPolicyStep { if cfg.pcr_ids.is_some() && cfg.policy_pubkey_path.is_some() { Ok(TPMPolicyStep::Or([ Box::new(TPMPolicyStep::PCRs( - utils::get_pcr_hash_alg_from_name(cfg.pcr_bank.as_ref()), + utils::get_hash_alg_from_name(cfg.pcr_bank.as_ref()), cfg.get_pcr_ids().unwrap(), Box::new(TPMPolicyStep::NoStep), )), @@ -300,7 +300,7 @@ impl TryFrom<&Tpm2Inner> for TPMPolicyStep { ])) } else if cfg.pcr_ids.is_some() { Ok(TPMPolicyStep::PCRs( - utils::get_pcr_hash_alg_from_name(cfg.pcr_bank.as_ref()), + utils::get_hash_alg_from_name(cfg.pcr_bank.as_ref()), cfg.get_pcr_ids().unwrap(), Box::new(TPMPolicyStep::NoStep), )) @@ -345,7 +345,8 @@ fn perform_decrypt(input: Vec) -> Result<(), PinError> { let policy = TPMPolicyStep::try_from(&hdr.private.clevis.tpm2)?; - let key_public = tpm_objects::get_key_public(hdr.private.clevis.tpm2.key.as_str())?; + let name_alg = crate::utils::get_hash_alg_from_name(Some(&hdr.private.clevis.tpm2.hash)); + let key_public = tpm_objects::get_key_public(hdr.private.clevis.tpm2.key.as_str(), name_alg)?; let mut ctx = utils::get_tpm2_ctx()?; let key_handle = utils::get_tpm2_primary_key(&mut ctx, &key_public)?; diff --git a/src/tpm_objects.rs b/src/tpm_objects.rs index aa84ba8..ed1acc5 100644 --- a/src/tpm_objects.rs +++ b/src/tpm_objects.rs @@ -1,11 +1,11 @@ use std::convert::TryFrom; -use tss_esapi::abstraction::cipher::Cipher; use tss_esapi::attributes::object::ObjectAttributesBuilder; use tss_esapi::constants::tss as tss_constants; use tss_esapi::interface_types::ecc::EccCurve; use tss_esapi::structures::Digest; use tss_esapi::utils::{PublicParmsUnion, Tpm2BPublicBuilder, TpmsEccParmsBuilder}; +use tss_esapi::{abstraction::cipher::Cipher, interface_types::algorithm::HashingAlgorithm}; #[cfg(target_pointer_width = "64")] type Sizedu = u64; @@ -16,6 +16,7 @@ use crate::PinError; pub(super) fn get_key_public( key_type: &str, + name_alg: HashingAlgorithm, ) -> Result { match key_type { "ecc" => Ok(create_restricted_ecc_public()), @@ -25,7 +26,10 @@ pub(super) fn get_key_public( 0, )?), _ => Err(PinError::Text("Unsupported key type used")), - } + }.map(|mut public| { + public.publicArea.nameAlg = name_alg.into(); + public + }) } pub(super) fn create_tpm2b_public_sealed_object( diff --git a/src/utils.rs b/src/utils.rs index 4e271b4..cbc6b15 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -45,7 +45,7 @@ pub(crate) fn get_authorized_policy_step( }) } -pub(crate) fn get_pcr_hash_alg_from_name(name: Option<&String>) -> HashingAlgorithm { +pub(crate) fn get_hash_alg_from_name(name: Option<&String>) -> HashingAlgorithm { match name { None => HashingAlgorithm::Sha256, Some(val) => match val.to_lowercase().as_str() { diff --git a/tests/test_pcr b/tests/test_pcr index c5a86bb..bb46104 100755 --- a/tests/test_pcr +++ b/tests/test_pcr @@ -13,6 +13,11 @@ echo "Working: no sealing (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 enc echo "Working: no sealing (clevis encrypt)" | clevis encrypt tpm2 '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing (clevis encrypt)"; exit 1) echo "Working: no sealing (renamed encrypt)" | ./target/debug/clevis-encrypt-tpm2plus '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1) echo "Working: no sealing (renamed decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' | ./target/debug/clevis-decrypt-tpm2plus || (echo "Failed: no sealing (clevis decrypt)"; exit 1) +name_alg_out=$(echo "Working: with name alg" | ./target/debug/clevis-pin-tpm2 encrypt '{"hash": "sha1"}') +echo $name_alg_out | cut -d'.' -f1 | jose b64 dec -i- | grep "\"hash\":\"sha1\"" || (echo "Failed: with name alg: not using sha1"; exit 1) +echo $name_alg_out | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with name alg"; exit 1) +echo "Working: with name alg (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"hash": "sha1"}' | clevis decrypt || (echo "Failed: with name alg (clevis decrypt)"; exit 1) +echo "Working: with name alg (clevis encrypt)" | clevis encrypt tpm2 '{"hash": "sha1"}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with name alg (clevis encrypt)"; exit 1) echo "Working: with PCRs" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs"; exit 1) echo "Working: with PCRs (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_ids":[23]}' | clevis decrypt || (echo "Failed: with PCRs (clevis decrypt)"; exit 1) echo "Working: with PCRs (clevis encrypt)" | clevis encrypt tpm2 '{"pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs (clevis encrypt)"; exit 1)