From 387826aef7a4d65e96585e4e33210169e613419b Mon Sep 17 00:00:00 2001 From: Patrick Uiterwijk Date: Mon, 3 Aug 2020 16:47:21 +0200 Subject: [PATCH] Move tpm_objects functions to other module Signed-off-by: Patrick Uiterwijk --- src/main.rs | 151 +++------------------------------------------ src/tpm_objects.rs | 142 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 143 deletions(-) create mode 100644 src/tpm_objects.rs diff --git a/src/main.rs b/src/main.rs index 191a1db..b7f3e43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,6 @@ use std::io::{self, Read, Write}; use biscuit::jwe; use biscuit::CompactJson; -use tss_esapi::constants; use tss_esapi::tss2_esys::{ESYS_TR, ESYS_TR_NONE, ESYS_TR_RH_OWNER}; use tss_esapi::utils; use tss_esapi::utils::tcti; @@ -41,6 +40,8 @@ use serde::{Deserialize, Serialize}; use tpm2_policy::{TPMPolicyStep, SignedPolicyList, PublicKey}; +mod tpm_objects; + fn serialize_as_base64_url_no_pad(bytes: &[u8], serializer: S) -> Result where S: serde::Serializer, @@ -430,39 +431,6 @@ fn get_mode_and_cfg(args: &[String]) -> Result<(ActionMode, Option), Ok((mode, cfg)) } -fn create_tpm2b_public_sealed_object( - policy: Option, -) -> Result { - let mut object_attributes = utils::ObjectAttributes(0); - object_attributes.set_fixed_tpm(true); - object_attributes.set_fixed_parent(true); - object_attributes.set_no_da(true); - object_attributes.set_admin_with_policy(true); - - if policy.is_none() { - object_attributes.set_user_with_auth(true); - } - let policy = match policy { - Some(p) => p, - None => tss_esapi::utils::Digest::try_from(vec![])?, - }; - - let mut params: tss_esapi::tss2_esys::TPMU_PUBLIC_PARMS = Default::default(); - params.keyedHashDetail.scheme.scheme = tss_esapi::constants::TPM2_ALG_NULL; - - Ok(tss_esapi::tss2_esys::TPM2B_PUBLIC { - size: std::mem::size_of::() as u16, - publicArea: tss_esapi::tss2_esys::TPMT_PUBLIC { - type_: tss_esapi::constants::TPM2_ALG_KEYEDHASH, - nameAlg: tss_esapi::constants::TPM2_ALG_SHA256, - objectAttributes: object_attributes.0, - authPolicy: tss_esapi::tss2_esys::TPM2B_DIGEST::try_from(policy)?, - parameters: params, - unique: Default::default(), - }, - }) -} - fn perform_encrypt(cfg: TPM2Config, input: &str) -> Result<(), PinError> { let key_type = match &cfg.key { None => "ecc", @@ -494,13 +462,13 @@ fn perform_encrypt(cfg: TPM2Config, input: &str) -> Result<(), PinError> { ]); let jwk_str = serde_json::to_string(&jwk)?; - let public = create_tpm2b_public_sealed_object(policy_digest)?; + let public = tpm_objects::create_tpm2b_public_sealed_object(policy_digest)?; let (jwk_priv, jwk_pub) = ctx.create_key(key_handle, &public, &[], jwk_str.as_bytes(), &[], &[])?; - let jwk_priv = get_tpm2b_private(jwk_priv)?; + let jwk_priv = tpm_objects::get_tpm2b_private(jwk_priv)?; - let jwk_pub = get_tpm2b_public(jwk_pub)?; + let jwk_pub = tpm_objects::get_tpm2b_public(jwk_pub)?; let hdr: biscuit::jwe::Header = biscuit::jwe::Header { registered: biscuit::jwe::RegisteredHeader { @@ -648,112 +616,9 @@ impl CompactJson for Tpm2Inner {} impl CompactJson for ClevisHeader {} impl CompactJson for ClevisInner {} -fn get_tpm2b_public(val: tss_esapi::tss2_esys::TPM2B_PUBLIC) -> Result, PinError> { - let mut offset = 0 as u64; - let mut resp = Vec::with_capacity((val.size + 4) as usize); - - unsafe { - let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Marshal( - &val, - resp.as_mut_ptr(), - resp.capacity() as u64, - &mut offset, - ); - if res != 0 { - return Err(PinError::Text("Marshalling tpm2b_public failed")); - } - resp.set_len(offset as usize); - } - - Ok(resp) -} - -fn get_tpm2b_private(val: tss_esapi::tss2_esys::TPM2B_PRIVATE) -> Result, PinError> { - let mut offset = 0 as u64; - let mut resp = Vec::with_capacity((val.size + 4) as usize); - - unsafe { - let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Marshal( - &val, - resp.as_mut_ptr(), - resp.capacity() as u64, - &mut offset, - ); - if res != 0 { - return Err(PinError::Text("Marshalling tpm2b_private failed")); - } - resp.set_len(offset as usize); - } - - Ok(resp) -} - -fn build_tpm2b_private(val: &[u8]) -> Result { - let mut resp = tss_esapi::tss2_esys::TPM2B_PRIVATE::default(); - let mut offset = 0 as u64; - - unsafe { - let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Unmarshal( - val[..].as_ptr(), - val.len() as u64, - &mut offset, - &mut resp, - ); - if res != 0 { - return Err(PinError::Text("Unmarshalling tpm2b_private failed")); - } - } - - Ok(resp) -} - -fn build_tpm2b_public(val: &[u8]) -> Result { - let mut resp = tss_esapi::tss2_esys::TPM2B_PUBLIC::default(); - let mut offset = 0 as u64; - - unsafe { - let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Unmarshal( - val[..].as_ptr(), - val.len() as u64, - &mut offset, - &mut resp, - ); - if res != 0 { - return Err(PinError::Text("Unmarshalling tpm2b_public failed")); - } - } - - Ok(resp) -} - -fn create_restricted_ecc_public() -> tss_esapi::tss2_esys::TPM2B_PUBLIC { - let ecc_params = utils::TpmsEccParmsBuilder::new_restricted_decryption_key( - utils::algorithm_specifiers::Cipher::aes_128_cfb(), - utils::algorithm_specifiers::EllipticCurve::NistP256, - ) - .build() - .unwrap(); - let mut object_attributes = utils::ObjectAttributes(0); - object_attributes.set_fixed_tpm(true); - object_attributes.set_fixed_parent(true); - object_attributes.set_sensitive_data_origin(true); - object_attributes.set_user_with_auth(true); - object_attributes.set_decrypt(true); - object_attributes.set_sign_encrypt(false); - object_attributes.set_restricted(true); - - utils::Tpm2BPublicBuilder::new() - .with_type(constants::TPM2_ALG_ECC) - .with_name_alg(constants::TPM2_ALG_SHA256) - .with_object_attributes(object_attributes) - .with_parms(utils::PublicParmsUnion::EccDetail(ecc_params)) - .build() - .unwrap() -} - fn get_key_public(key_type: &str) -> Result { match key_type { - "ecc" => Ok(create_restricted_ecc_public()), + "ecc" => Ok(tpm_objects::create_restricted_ecc_public()), "rsa" => Ok(tss_esapi::utils::create_restricted_decryption_rsa_public( utils::algorithm_specifiers::Cipher::aes_128_cfb(), 2048, @@ -771,8 +636,8 @@ fn perform_decrypt(input: &str) -> Result<(), PinError> { return Err(PinError::Text("JWE pin mismatch")); } - let jwkpub = build_tpm2b_public(&hdr.private.clevis.tpm2.jwk_pub)?; - let jwkpriv = build_tpm2b_private(&hdr.private.clevis.tpm2.jwk_priv)?; + let jwkpub = tpm_objects::build_tpm2b_public(&hdr.private.clevis.tpm2.jwk_pub)?; + let jwkpriv = tpm_objects::build_tpm2b_private(&hdr.private.clevis.tpm2.jwk_priv)?; let policy = TPMPolicyStep::try_from(&hdr.private.clevis.tpm2)?; diff --git a/src/tpm_objects.rs b/src/tpm_objects.rs new file mode 100644 index 0000000..e0e70fb --- /dev/null +++ b/src/tpm_objects.rs @@ -0,0 +1,142 @@ +use std::convert::TryFrom; + +use tss_esapi::constants; +use tss_esapi::utils; + +use crate::PinError; + +pub(super) fn create_tpm2b_public_sealed_object( + policy: Option, +) -> Result { + let mut object_attributes = utils::ObjectAttributes(0); + object_attributes.set_fixed_tpm(true); + object_attributes.set_fixed_parent(true); + object_attributes.set_no_da(true); + object_attributes.set_admin_with_policy(true); + + if policy.is_none() { + object_attributes.set_user_with_auth(true); + } + let policy = match policy { + Some(p) => p, + None => tss_esapi::utils::Digest::try_from(vec![])?, + }; + + let mut params: tss_esapi::tss2_esys::TPMU_PUBLIC_PARMS = Default::default(); + params.keyedHashDetail.scheme.scheme = tss_esapi::constants::TPM2_ALG_NULL; + + Ok(tss_esapi::tss2_esys::TPM2B_PUBLIC { + size: std::mem::size_of::() as u16, + publicArea: tss_esapi::tss2_esys::TPMT_PUBLIC { + type_: tss_esapi::constants::TPM2_ALG_KEYEDHASH, + nameAlg: tss_esapi::constants::TPM2_ALG_SHA256, + objectAttributes: object_attributes.0, + authPolicy: tss_esapi::tss2_esys::TPM2B_DIGEST::try_from(policy)?, + parameters: params, + unique: Default::default(), + }, + }) +} + +pub(super) fn get_tpm2b_public(val: tss_esapi::tss2_esys::TPM2B_PUBLIC) -> Result, PinError> { + let mut offset = 0 as u64; + let mut resp = Vec::with_capacity((val.size + 4) as usize); + + unsafe { + let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Marshal( + &val, + resp.as_mut_ptr(), + resp.capacity() as u64, + &mut offset, + ); + if res != 0 { + return Err(PinError::Text("Marshalling tpm2b_public failed")); + } + resp.set_len(offset as usize); + } + + Ok(resp) +} + +pub(super) fn get_tpm2b_private(val: tss_esapi::tss2_esys::TPM2B_PRIVATE) -> Result, PinError> { + let mut offset = 0 as u64; + let mut resp = Vec::with_capacity((val.size + 4) as usize); + + unsafe { + let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Marshal( + &val, + resp.as_mut_ptr(), + resp.capacity() as u64, + &mut offset, + ); + if res != 0 { + return Err(PinError::Text("Marshalling tpm2b_private failed")); + } + resp.set_len(offset as usize); + } + + Ok(resp) +} + +pub(super) fn build_tpm2b_private(val: &[u8]) -> Result { + let mut resp = tss_esapi::tss2_esys::TPM2B_PRIVATE::default(); + let mut offset = 0 as u64; + + unsafe { + let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Unmarshal( + val[..].as_ptr(), + val.len() as u64, + &mut offset, + &mut resp, + ); + if res != 0 { + return Err(PinError::Text("Unmarshalling tpm2b_private failed")); + } + } + + Ok(resp) +} + +pub(super) fn build_tpm2b_public(val: &[u8]) -> Result { + let mut resp = tss_esapi::tss2_esys::TPM2B_PUBLIC::default(); + let mut offset = 0 as u64; + + unsafe { + let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Unmarshal( + val[..].as_ptr(), + val.len() as u64, + &mut offset, + &mut resp, + ); + if res != 0 { + return Err(PinError::Text("Unmarshalling tpm2b_public failed")); + } + } + + Ok(resp) +} + +pub(super) fn create_restricted_ecc_public() -> tss_esapi::tss2_esys::TPM2B_PUBLIC { + let ecc_params = utils::TpmsEccParmsBuilder::new_restricted_decryption_key( + utils::algorithm_specifiers::Cipher::aes_128_cfb(), + utils::algorithm_specifiers::EllipticCurve::NistP256, + ) + .build() + .unwrap(); + let mut object_attributes = utils::ObjectAttributes(0); + object_attributes.set_fixed_tpm(true); + object_attributes.set_fixed_parent(true); + object_attributes.set_sensitive_data_origin(true); + object_attributes.set_user_with_auth(true); + object_attributes.set_decrypt(true); + object_attributes.set_sign_encrypt(false); + object_attributes.set_restricted(true); + + utils::Tpm2BPublicBuilder::new() + .with_type(constants::TPM2_ALG_ECC) + .with_name_alg(constants::TPM2_ALG_SHA256) + .with_object_attributes(object_attributes) + .with_parms(utils::PublicParmsUnion::EccDetail(ecc_params)) + .build() + .unwrap() +}