1use super::{PolicyError, PolicySession};
7use crate::device::Device;
8use crate::session;
9use tpm2_protocol::{
10 data::{Tpm2bDigest, Tpm2bName, Tpm2bNonce, TpmAlgId, TpmCc, TpmlDigest, TpmlPcrSelection},
11 message::{
12 TpmPolicyGetDigestCommand, TpmPolicyOrCommand, TpmPolicyPcrCommand, TpmPolicySecretCommand,
13 },
14 TpmHandle,
15};
16
17pub struct TpmPolicySession<'a> {
19 device: &'a mut Device,
20 handle: TpmHandle,
21 hash_alg: TpmAlgId,
22}
23
24impl<'a> TpmPolicySession<'a> {
25 #[must_use]
27 pub fn new(device: &'a mut Device, handle: TpmHandle, hash_alg: TpmAlgId) -> Self {
28 Self {
29 device,
30 handle,
31 hash_alg,
32 }
33 }
34}
35
36impl PolicySession for TpmPolicySession<'_> {
37 fn device(&mut self) -> &mut Device {
38 self.device
39 }
40
41 fn policy_pcr(
42 &mut self,
43 pcr_digest: &Tpm2bDigest,
44 pcrs: TpmlPcrSelection,
45 ) -> Result<(), PolicyError> {
46 let cmd = TpmPolicyPcrCommand {
47 policy_session: self.handle.0.into(),
48 pcr_digest: *pcr_digest,
49 pcrs,
50 };
51 self.device.execute(&cmd, &[])?;
52 Ok(())
53 }
54
55 fn policy_or(&mut self, p_hash_list: &TpmlDigest) -> Result<(), PolicyError> {
56 let cmd = TpmPolicyOrCommand {
57 policy_session: self.handle.0.into(),
58 p_hash_list: *p_hash_list,
59 };
60 self.device.execute(&cmd, &[])?;
61 Ok(())
62 }
63
64 fn policy_secret(
65 &mut self,
66 auth_handle: u32,
67 _auth_handle_name: &Tpm2bName,
68 password: Option<&[u8]>,
69 cp_hash: Option<Tpm2bDigest>,
70 ) -> Result<(), PolicyError> {
71 let cmd = TpmPolicySecretCommand {
72 auth_handle: auth_handle.into(),
73 policy_session: self.handle.0.into(),
74 nonce_tpm: Tpm2bNonce::default(),
75 cp_hash_a: cp_hash.unwrap_or_default(),
76 policy_ref: Tpm2bNonce::default(),
77 expiration: 0,
78 };
79
80 let password_auth = session::build_password_session(password.unwrap_or_default())?;
81 let sessions = vec![password_auth];
82
83 self.device.execute(&cmd, &sessions)?;
84 Ok(())
85 }
86
87 fn get_digest(&mut self) -> Result<Tpm2bDigest, PolicyError> {
88 let cmd = TpmPolicyGetDigestCommand {
89 policy_session: self.handle.0.into(),
90 };
91 let (resp, _) = self.device.execute(&cmd, &[])?;
92 let digest_resp = resp
93 .PolicyGetDigest()
94 .map_err(|_| crate::device::DeviceError::ResponseMismatch(TpmCc::PolicyGetDigest))?;
95 Ok(digest_resp.policy_digest)
96 }
97
98 fn hash_alg(&self) -> TpmAlgId {
99 self.hash_alg
100 }
101}