Skip to content

Commit

Permalink
Add policy_duplication_select to Context
Browse files Browse the repository at this point in the history
This function causes conditional gating based on duplication parent's
name (and optionally on the name of the object being duplicated).

The duplication tests have been adjusted to utilize this policy
function. The old code based on `policy_command_code` is still being
tested in `Context::duplicate` doctests.

Signed-off-by: Wiktor Kwapisiewicz <[email protected]>
  • Loading branch information
wiktor-k committed Oct 15, 2021
1 parent c45d4d4 commit bc7bd32
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,113 @@ impl Context {
}
}

// Missing function: PolicyDuplicationSelect
/// Cause conditional gating of a policy based on duplication parent's name.
///
/// # Arguments
/// * `policy_session` - The [policy session][PolicySession] being extended.
/// * `object_name` - The [name][Name] of the object being duplicated.
/// * `new_parent_name` - The [name][Name] of the new parent.
/// * `include_object` - Flag indicating if `object_name` will be included in policy
/// calculation.
///
/// # Details
/// Set `include_object` only when this commend is used in conjunction with
/// [`policy_authorize`][Context::policy_authorize].
///
/// # Example
///
/// ```rust
/// # use std::convert::{TryFrom, TryInto};
/// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
/// # use tss_esapi::constants::{tss::TPM2_CC_Duplicate, SessionType};
/// # use tss_esapi::handles::ObjectHandle;
/// # use tss_esapi::interface_types::{
/// # algorithm::{HashingAlgorithm, PublicAlgorithm},
/// # key_bits::RsaKeyBits,
/// # resource_handles::Hierarchy,
/// # session_handles::PolicySession,
/// # };
/// # use tss_esapi::structures::SymmetricDefinition;
/// # use tss_esapi::structures::{
/// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
/// # RsaExponent, Name,
/// # };
/// # use tss_esapi::structures::SymmetricDefinitionObject;
/// # use tss_esapi::abstraction::cipher::Cipher;
/// # use tss_esapi::{Context, TctiNameConf};
/// #
/// # let mut context = // ...
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let trial_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Trial,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
/// # SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context
/// # .tr_sess_set_attributes(
/// # trial_session,
/// # policy_auth_session_attributes,
/// # policy_auth_session_attributes_mask,
/// # )
/// # .expect("tr_sess_set_attributes call failed");
/// #
/// # let policy_session = PolicySession::try_from(trial_session)
/// # .expect("Failed to convert auth session into policy session");
/// #
/// # let object_name: Name = Vec::<u8>::new().try_into().unwrap();
/// # let parent_name = object_name.clone();
/// #
/// context
/// .policy_duplication_select(policy_session, object_name, parent_name, false)
/// .expect("Policy command code");
/// #
/// # /// Digest of the policy that allows duplication
/// # let digest = context
/// # .policy_get_digest(policy_session)
/// # .expect("Could retrieve digest");
/// ```
pub fn policy_duplication_select(
&mut self,
policy_session: PolicySession,
object_name: Name,
new_parent_name: Name,
include_object: bool,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyDuplicationSelect(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&object_name.try_into()?,
&new_parent_name.try_into()?,
if include_object { 1 } else { 0 },
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy duplication select: {}", ret);
Err(ret)
}
}

/// Cause conditional gating of a policy based on an authorized policy
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
mod test_duplicate {
use crate::common::{create_ctx_with_session, create_ctx_without_session};
use std::convert::TryFrom;
use std::convert::TryInto;
use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
use tss_esapi::constants::{tss::TPM2_CC_Duplicate, SessionType};
use tss_esapi::handles::ObjectHandle;
use tss_esapi::constants::SessionType;
use tss_esapi::handles::{ObjectHandle, PersistentTpmHandle, TpmHandle};
use tss_esapi::interface_types::dynamic_handles::Persistent;
use tss_esapi::interface_types::{
algorithm::{HashingAlgorithm, PublicAlgorithm},
ecc::EccCurve,
resource_handles::Hierarchy,
resource_handles::{Hierarchy, Provision},
session_handles::PolicySession,
};
use tss_esapi::structures::SymmetricDefinition;
Expand All @@ -20,6 +22,55 @@ mod test_duplicate {

#[test]
fn test_duplicate_and_import() {
let mut context = create_ctx_with_session();

let parent_object_attributes = ObjectAttributesBuilder::new()
.with_fixed_tpm(true)
.with_fixed_parent(true)
.with_sensitive_data_origin(true)
.with_user_with_auth(true)
.with_decrypt(true)
.with_sign_encrypt(false)
.with_restricted(true)
.build()
.expect("Attributes to be valid");

let public_parent = PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(parent_object_attributes)
.with_ecc_parameters(
PublicEccParametersBuilder::new()
.with_ecc_scheme(EccScheme::Null)
.with_curve(EccCurve::NistP256)
.with_is_signing_key(false)
.with_is_decryption_key(true)
.with_restricted(true)
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.build()
.expect("Params to be valid"),
)
.with_ecc_unique_identifier(&EccPoint::default())
.build()
.expect("public to be valid");

let new_parent_handle = context
.create_primary(Hierarchy::Owner, &public_parent, None, None, None, None)
.unwrap()
.key_handle;

let parent_name = context.read_public(new_parent_handle).unwrap().1;

let handle = 0x81000027;

let persistent = Persistent::Persistent(PersistentTpmHandle::new(handle).unwrap());

context
.evict_control(Provision::Owner, new_parent_handle.into(), persistent)
.unwrap();

drop(context);
let mut context = create_ctx_without_session();

let trial_session = context
Expand Down Expand Up @@ -51,12 +102,13 @@ mod test_duplicate {
.expect("Failed to convert auth session into policy session");

context
.policy_auth_value(policy_session)
.expect("Policy auth value");

context
.policy_command_code(policy_session, TPM2_CC_Duplicate)
.expect("Policy command code");
.policy_duplication_select(
policy_session,
Vec::<u8>::new().try_into().unwrap(),
parent_name.clone(),
false,
)
.expect("Policy duplication select");

let digest = context
.policy_get_digest(policy_session)
Expand All @@ -65,42 +117,6 @@ mod test_duplicate {
drop(context);
let mut context = create_ctx_with_session();

let parent_object_attributes = ObjectAttributesBuilder::new()
.with_fixed_tpm(true)
.with_fixed_parent(true)
.with_sensitive_data_origin(true)
.with_user_with_auth(true)
.with_decrypt(true)
.with_sign_encrypt(false)
.with_restricted(true)
.build()
.expect("Attributes to be valid");

let public_parent = PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(parent_object_attributes)
.with_ecc_parameters(
PublicEccParametersBuilder::new()
.with_ecc_scheme(EccScheme::Null)
.with_curve(EccCurve::NistP256)
.with_is_signing_key(false)
.with_is_decryption_key(true)
.with_restricted(true)
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.build()
.expect("Params to be valid"),
)
.with_ecc_unique_identifier(&EccPoint::default())
.build()
.expect("public to be valid");

let parent_of_object_to_duplicate_handle = context
.create_primary(Hierarchy::Owner, &public_parent, None, None, None, None)
.unwrap()
.key_handle;

// Fixed TPM and Fixed Parent should be "false" for an object
// to be elligible for duplication
let object_attributes = ObjectAttributesBuilder::new()
Expand Down Expand Up @@ -134,6 +150,18 @@ mod test_duplicate {
.build()
.expect("public to be valid");

let persistent_tpm_handle = PersistentTpmHandle::new(handle).unwrap();

let new_parent_handle = context.execute_without_session(|ctx| {
ctx.tr_from_tpm_public(TpmHandle::Persistent(persistent_tpm_handle))
.expect("Need handle")
});

let parent_of_object_to_duplicate_handle = context
.create_primary(Hierarchy::Owner, &public_parent, None, None, None, None)
.unwrap()
.key_handle;

let result = context
.create(
parent_of_object_to_duplicate_handle,
Expand All @@ -154,11 +182,10 @@ mod test_duplicate {
.unwrap()
.into();

let new_parent_handle: ObjectHandle = context
.create_primary(Hierarchy::Owner, &public_parent, None, None, None, None)
let object_name = context
.read_public(object_to_duplicate_handle.into())
.unwrap()
.key_handle
.into();
.1;

context.set_sessions((None, None, None));

Expand Down Expand Up @@ -190,11 +217,7 @@ mod test_duplicate {
.expect("Failed to convert auth session into policy session");

context
.policy_auth_value(policy_session)
.expect("Policy auth value works");

context
.policy_command_code(policy_session, TPM2_CC_Duplicate)
.policy_duplication_select(policy_session, object_name, parent_name, false)
.unwrap();
context.set_sessions((Some(policy_auth_session), None, None));

Expand Down

0 comments on commit bc7bd32

Please sign in to comment.