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