use crate::{
handles::{AuthHandle, ObjectHandle, SessionHandle},
interface_types::session_handles::PolicySession,
structures::{
AuthTicket, Digest, DigestList, Name, Nonce, PcrSelectionList, Timeout, VerifiedTicket,
},
tss2_esys::*,
utils::Signature,
Context, Error, Result, WrapperErrorKind as ErrorKind,
};
use log::error;
use mbox::MBox;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
use std::time::Duration;
impl Context {
#[allow(clippy::too_many_arguments)]
pub fn policy_signed(
&mut self,
policy_session: PolicySession,
auth_object: ObjectHandle,
nonce_tpm: Nonce,
cp_hash_a: Digest,
policy_ref: Nonce,
expiration: Option<Duration>,
signature: Signature,
) -> Result<(Timeout, AuthTicket)> {
let mut out_timeout = null_mut();
let mut out_policy_ticket = null_mut();
let expiration = match expiration {
None => 0,
Some(val) => match i32::try_from(val.as_secs()) {
Ok(val) => val,
Err(_) => return Err(Error::local_error(ErrorKind::InvalidParam)),
},
};
let ret = unsafe {
Esys_PolicySigned(
self.mut_context(),
auth_object.into(),
SessionHandle::from(policy_session).into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&nonce_tpm.into(),
&cp_hash_a.into(),
&policy_ref.into(),
expiration,
&signature.try_into()?,
&mut out_timeout,
&mut out_policy_ticket,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let out_timeout = unsafe { MBox::from_raw(out_timeout) };
let out_timeout = Timeout::try_from(*out_timeout)?;
let out_policy_ticket = unsafe { MBox::from_raw(out_policy_ticket) };
let out_policy_ticket = AuthTicket::try_from(*out_policy_ticket)?;
Ok((out_timeout, out_policy_ticket))
} else {
error!("Error when sending policy signed: {}", ret);
Err(ret)
}
}
pub fn policy_secret(
&mut self,
policy_session: PolicySession,
auth_handle: AuthHandle,
nonce_tpm: Nonce,
cp_hash_a: Digest,
policy_ref: Nonce,
expiration: Option<Duration>,
) -> Result<(Timeout, AuthTicket)> {
let mut out_timeout = null_mut();
let mut out_policy_ticket = null_mut();
let expiration = match expiration {
None => 0,
Some(val) => match i32::try_from(val.as_secs()) {
Ok(val) => val,
Err(_) => return Err(Error::local_error(ErrorKind::InvalidParam)),
},
};
let ret = unsafe {
Esys_PolicySecret(
self.mut_context(),
auth_handle.into(),
SessionHandle::from(policy_session).into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&nonce_tpm.into(),
&cp_hash_a.into(),
&policy_ref.into(),
expiration,
&mut out_timeout,
&mut out_policy_ticket,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let out_timeout = unsafe { MBox::from_raw(out_timeout) };
let out_timeout = Timeout::try_from(*out_timeout)?;
let out_policy_ticket = unsafe { MBox::from_raw(out_policy_ticket) };
let out_policy_ticket = AuthTicket::try_from(*out_policy_ticket)?;
Ok((out_timeout, out_policy_ticket))
} else {
error!("Error when sending policy secret: {}", ret);
Err(ret)
}
}
pub fn policy_or(
&mut self,
policy_session: PolicySession,
digest_list: DigestList,
) -> Result<()> {
let digest_list = TPML_DIGEST::try_from(digest_list)?;
let ret = unsafe {
Esys_PolicyOR(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&digest_list,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy OR: {}", ret);
Err(ret)
}
}
pub fn policy_pcr(
&mut self,
policy_session: PolicySession,
pcr_policy_digest: &Digest,
pcr_selection_list: PcrSelectionList,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyPCR(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&pcr_policy_digest.clone().into(),
&pcr_selection_list.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy PCR: {}", ret);
Err(ret)
}
}
pub fn policy_locality(
&mut self,
policy_session: PolicySession,
locality: TPMA_LOCALITY,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyLocality(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
locality,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy locality: {}", ret);
Err(ret)
}
}
pub fn policy_command_code(
&mut self,
policy_session: PolicySession,
code: TPM2_CC,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyCommandCode(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
code,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy command code: {}", ret);
Err(ret)
}
}
pub fn policy_physical_presence(&mut self, policy_session: PolicySession) -> Result<()> {
let ret = unsafe {
Esys_PolicyPhysicalPresence(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy physical presence: {}", ret);
Err(ret)
}
}
pub fn policy_cp_hash(
&mut self,
policy_session: PolicySession,
cp_hash_a: &Digest,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyCpHash(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&cp_hash_a.clone().into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy command parameters: {}", ret);
Err(ret)
}
}
pub fn policy_name_hash(
&mut self,
policy_session: PolicySession,
name_hash: &Digest,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyNameHash(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&name_hash.clone().into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy name hash: {}", ret);
Err(ret)
}
}
pub fn policy_authorize(
&mut self,
policy_session: PolicySession,
approved_policy: &Digest,
policy_ref: &Nonce,
key_sign: &Name,
check_ticket: VerifiedTicket,
) -> Result<()> {
let tss_key_sign = TPM2B_NAME::try_from(key_sign.clone())?;
let check_ticket = TPMT_TK_VERIFIED::try_from(check_ticket)?;
let ret = unsafe {
Esys_PolicyAuthorize(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&approved_policy.clone().into(),
&policy_ref.clone().into(),
&tss_key_sign,
&check_ticket,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy authorize: {}", ret);
Err(ret)
}
}
pub fn policy_auth_value(&mut self, policy_session: PolicySession) -> Result<()> {
let ret = unsafe {
Esys_PolicyAuthValue(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy auth value: {}", ret);
Err(ret)
}
}
pub fn policy_password(&mut self, policy_session: PolicySession) -> Result<()> {
let ret = unsafe {
Esys_PolicyPassword(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy password: {}", ret);
Err(ret)
}
}
pub fn policy_get_digest(&mut self, policy_session: PolicySession) -> Result<Digest> {
let mut policy_digest_ptr = null_mut();
let ret = unsafe {
Esys_PolicyGetDigest(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut policy_digest_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let policy_digest = unsafe { MBox::<TPM2B_DIGEST>::from_raw(policy_digest_ptr) };
Ok(Digest::try_from(*policy_digest)?)
} else {
error!(
"Error failed to peform policy get digest operation: {}.",
ret
);
Err(ret)
}
}
pub fn policy_nv_written(
&mut self,
policy_session: PolicySession,
written_set: bool,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyNvWritten(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
if written_set { 1 } else { 0 },
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy NV written state: {}", ret);
Err(ret)
}
}
pub fn policy_template(
&mut self,
policy_session: PolicySession,
template_hash: &Digest,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyTemplate(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&template_hash.clone().into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!(
"Failed to bind template to a specific creation template: {}",
ret
);
Err(ret)
}
}
}