1use crate::{
4 constants::tss::{
5 TPM2_HT_AC, TPM2_HT_HMAC_SESSION, TPM2_HT_NV_INDEX, TPM2_HT_PCR, TPM2_HT_PERMANENT,
6 TPM2_HT_PERSISTENT, TPM2_HT_POLICY_SESSION, TPM2_HT_TRANSIENT,
7 },
8 tss2_esys::TPM2_HANDLE,
9 Error, Result, WrapperErrorKind,
10};
11use log::error;
12use std::convert::{From, TryFrom};
13use std::stringify;
14
15#[derive(Debug, Copy, Clone, Eq, PartialEq)]
27pub enum TpmHandle {
28 Pcr(pcr::PcrTpmHandle),
29 NvIndex(nv_index::NvIndexTpmHandle),
30 HmacSession(hmac_session::HmacSessionTpmHandle),
31 LoadedSession(loaded_session::LoadedSessionTpmHandle),
32 PolicySession(policy_session::PolicySessionTpmHandle),
33 SavedSession(saved_session::SavedSessionTpmHandle),
34 Permanent(permanent::PermanentTpmHandle),
35 Transient(transient::TransientTpmHandle),
36 Persistent(persistent::PersistentTpmHandle),
37 AttachedComponent(attached_component::AttachedComponentTpmHandle),
38}
39
40impl TpmHandle {
41 pub(crate) fn may_be_flushed(&self) -> bool {
44 matches!(
45 self,
46 TpmHandle::HmacSession(_) | TpmHandle::LoadedSession(_) | TpmHandle::Transient(_)
47 )
48 }
49}
50
51impl From<TpmHandle> for TPM2_HANDLE {
52 fn from(tpm_handle: TpmHandle) -> TPM2_HANDLE {
53 match tpm_handle {
54 TpmHandle::Pcr(handle) => handle.into(),
55 TpmHandle::NvIndex(handle) => handle.into(),
56 TpmHandle::HmacSession(handle) => handle.into(),
57 TpmHandle::LoadedSession(handle) => handle.into(),
58 TpmHandle::PolicySession(handle) => handle.into(),
59 TpmHandle::SavedSession(handle) => handle.into(),
60 TpmHandle::Permanent(handle) => handle.into(),
61 TpmHandle::Transient(handle) => handle.into(),
62 TpmHandle::Persistent(handle) => handle.into(),
63 TpmHandle::AttachedComponent(handle) => handle.into(),
64 }
65 }
66}
67
68impl TryFrom<TPM2_HANDLE> for TpmHandle {
69 type Error = Error;
70 fn try_from(tss_tpm_handle: TPM2_HANDLE) -> Result<TpmHandle> {
71 let most_significant_byte = tss_tpm_handle.to_be_bytes()[0];
72 match most_significant_byte {
73 TPM2_HT_PCR => Ok(TpmHandle::Pcr(pcr::PcrTpmHandle::new(tss_tpm_handle)?)),
74 TPM2_HT_NV_INDEX => Ok(TpmHandle::NvIndex(nv_index::NvIndexTpmHandle::new(
75 tss_tpm_handle,
76 )?)),
77 TPM2_HT_HMAC_SESSION => Ok(TpmHandle::HmacSession(
78 hmac_session::HmacSessionTpmHandle::new(tss_tpm_handle)?,
79 )),
80 TPM2_HT_POLICY_SESSION => Ok(TpmHandle::PolicySession(
82 policy_session::PolicySessionTpmHandle::new(tss_tpm_handle)?,
83 )),
84 TPM2_HT_PERMANENT => Ok(TpmHandle::Permanent(permanent::PermanentTpmHandle::new(
86 tss_tpm_handle,
87 )?)),
88 TPM2_HT_TRANSIENT => Ok(TpmHandle::Transient(transient::TransientTpmHandle::new(
89 tss_tpm_handle,
90 )?)),
91 TPM2_HT_PERSISTENT => Ok(TpmHandle::Persistent(persistent::PersistentTpmHandle::new(
92 tss_tpm_handle,
93 )?)),
94 TPM2_HT_AC => Ok(TpmHandle::AttachedComponent(
95 attached_component::AttachedComponentTpmHandle::new(tss_tpm_handle)?,
96 )),
97 _ => {
98 error!("Invalid TPM handle type {}", most_significant_byte);
99 Err(Error::local_error(WrapperErrorKind::InvalidParam))
100 }
101 }
102 }
103}
104
105macro_rules! create_tpm_handle_type {
107 ($handle_type_name:ident, $tpm_handle_kind:path, $tpm_handle_type_id:tt, $tpm_handle_type_first:tt, $tpm_handle_type_last:tt) => {
108 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
109 pub struct $handle_type_name {
110 value: u32,
111 }
112
113 impl $handle_type_name {
114 pub fn new(value: u32) -> Result<$handle_type_name> {
115 if value.to_be_bytes()[0] != $tpm_handle_type_id {
116 error!(
117 "TPM Handle ID of the input value did not match the {} (!={})",
118 stringify!($handle_type_name),
119 $tpm_handle_type_id
120 );
121 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
122 }
123 if !($tpm_handle_type_first..($tpm_handle_type_last + 1)).contains(&value) {
125 error!(
126 "TPM Handle ID is not in range ({}..{})",
127 $tpm_handle_type_first, $tpm_handle_type_last
128 );
129 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
130 }
131 Ok($handle_type_name { value })
132 }
133 }
134
135 impl From<$handle_type_name> for TpmHandle {
136 fn from(specific_tpm_handle: $handle_type_name) -> TpmHandle {
137 $tpm_handle_kind(specific_tpm_handle)
138 }
139 }
140
141 impl TryFrom<TpmHandle> for $handle_type_name {
142 type Error = Error;
143 fn try_from(general_tpm_handle: TpmHandle) -> Result<$handle_type_name> {
144 match general_tpm_handle {
145 $tpm_handle_kind(val) => Ok(val),
146 _ => {
147 error!(
148 "Error: Incorrect tpm handle kind(=={}) when converting to {}",
149 stringify!($tpm_handle_kind),
150 stringify!($handle_type_name)
151 );
152 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
153 }
154 }
155 }
156 }
157
158 impl From<$handle_type_name> for TPM2_HANDLE {
159 fn from(specific_tpm_handle: $handle_type_name) -> TPM2_HANDLE {
160 specific_tpm_handle.value
161 }
162 }
163
164 impl TryFrom<TPM2_HANDLE> for $handle_type_name {
165 type Error = Error;
166 fn try_from(tss_tpm_handle: TPM2_HANDLE) -> Result<$handle_type_name> {
167 $handle_type_name::new(tss_tpm_handle)
168 }
169 }
170 };
171}
172
173macro_rules! add_constant_handle {
176 ($handle_type:ident, $constant_handle_name:ident, $constant_handle_value:ident) => {
177 impl $handle_type {
178 #[allow(non_upper_case_globals)]
179 pub const $constant_handle_name: $handle_type = $handle_type {
180 value: $constant_handle_value,
181 };
182 }
183 };
184}
185
186pub mod pcr {
187 use super::*;
189 use crate::constants::tss::{TPM2_HT_PCR, TPM2_PCR_FIRST, TPM2_PCR_LAST};
190 create_tpm_handle_type!(
192 PcrTpmHandle,
193 TpmHandle::Pcr,
194 TPM2_HT_PCR,
195 TPM2_PCR_FIRST,
196 TPM2_PCR_LAST
197 );
198}
199
200pub mod nv_index {
201 use super::*;
203 use crate::constants::tss::{TPM2_HT_NV_INDEX, TPM2_NV_INDEX_FIRST, TPM2_NV_INDEX_LAST};
204
205 create_tpm_handle_type!(
206 NvIndexTpmHandle,
207 TpmHandle::NvIndex,
208 TPM2_HT_NV_INDEX,
209 TPM2_NV_INDEX_FIRST,
210 TPM2_NV_INDEX_LAST
211 );
212}
213
214pub mod hmac_session {
215 use super::*;
217 use crate::constants::tss::{
218 TPM2_HMAC_SESSION_FIRST, TPM2_HMAC_SESSION_LAST, TPM2_HT_HMAC_SESSION,
219 };
220
221 create_tpm_handle_type!(
222 HmacSessionTpmHandle,
223 TpmHandle::HmacSession,
224 TPM2_HT_HMAC_SESSION,
225 TPM2_HMAC_SESSION_FIRST,
226 TPM2_HMAC_SESSION_LAST
227 );
228}
229
230pub mod loaded_session {
231 use super::*;
233 use crate::constants::tss::{
234 TPM2_HT_LOADED_SESSION, TPM2_LOADED_SESSION_FIRST, TPM2_LOADED_SESSION_LAST,
235 };
236
237 create_tpm_handle_type!(
238 LoadedSessionTpmHandle,
239 TpmHandle::LoadedSession,
240 TPM2_HT_LOADED_SESSION,
241 TPM2_LOADED_SESSION_FIRST,
242 TPM2_LOADED_SESSION_LAST
243 );
244}
245
246pub mod policy_session {
247 use super::*;
249 use crate::constants::tss::{
250 TPM2_HT_POLICY_SESSION, TPM2_POLICY_SESSION_FIRST, TPM2_POLICY_SESSION_LAST,
251 };
252
253 create_tpm_handle_type!(
254 PolicySessionTpmHandle,
255 TpmHandle::PolicySession,
256 TPM2_HT_POLICY_SESSION,
257 TPM2_POLICY_SESSION_FIRST,
258 TPM2_POLICY_SESSION_LAST
259 );
260}
261
262pub mod permanent {
263 use super::*;
264 use crate::constants::tss::{
265 TPM2_HT_PERMANENT, TPM2_PERMANENT_FIRST, TPM2_PERMANENT_LAST, TPM2_RH_ACT_0, TPM2_RH_ACT_F,
266 TPM2_RH_ADMIN, TPM2_RH_AUTH_00, TPM2_RH_AUTH_FF, TPM2_RH_EK, TPM2_RH_ENDORSEMENT,
267 TPM2_RH_FIRST, TPM2_RH_LAST, TPM2_RH_LOCKOUT, TPM2_RH_NULL, TPM2_RH_OPERATOR,
268 TPM2_RH_OWNER, TPM2_RH_PLATFORM, TPM2_RH_PLATFORM_NV, TPM2_RH_REVOKE, TPM2_RH_SRK,
269 TPM2_RH_TRANSPORT, TPM2_RH_UNASSIGNED, TPM2_RS_PW,
270 };
271
272 create_tpm_handle_type!(
273 PermanentTpmHandle,
274 TpmHandle::Permanent,
275 TPM2_HT_PERMANENT,
276 TPM2_PERMANENT_FIRST,
277 TPM2_PERMANENT_LAST
278 );
279
280 add_constant_handle!(PermanentTpmHandle, First, TPM2_RH_FIRST);
281 add_constant_handle!(PermanentTpmHandle, StorageRootKey, TPM2_RH_SRK);
282 add_constant_handle!(PermanentTpmHandle, Owner, TPM2_RH_OWNER);
283 add_constant_handle!(PermanentTpmHandle, Revoke, TPM2_RH_REVOKE);
284 add_constant_handle!(PermanentTpmHandle, Transport, TPM2_RH_TRANSPORT);
285 add_constant_handle!(PermanentTpmHandle, Operator, TPM2_RH_OPERATOR);
286 add_constant_handle!(PermanentTpmHandle, Admin, TPM2_RH_ADMIN);
287 add_constant_handle!(PermanentTpmHandle, EndorsementKey, TPM2_RH_EK);
288 add_constant_handle!(PermanentTpmHandle, Null, TPM2_RH_NULL);
289 add_constant_handle!(PermanentTpmHandle, Unassigned, TPM2_RH_UNASSIGNED);
290 add_constant_handle!(PermanentTpmHandle, PasswordSession, TPM2_RS_PW);
291 add_constant_handle!(PermanentTpmHandle, Lockout, TPM2_RH_LOCKOUT);
292 add_constant_handle!(PermanentTpmHandle, Endorsement, TPM2_RH_ENDORSEMENT);
293 add_constant_handle!(PermanentTpmHandle, Platform, TPM2_RH_PLATFORM);
294 add_constant_handle!(PermanentTpmHandle, PlatformNv, TPM2_RH_PLATFORM_NV);
295 add_constant_handle!(
296 PermanentTpmHandle,
297 VendorSpecificAuthorizationFirst,
298 TPM2_RH_AUTH_00
299 );
300 add_constant_handle!(
301 PermanentTpmHandle,
302 VendorSpecificAuthorizationLast,
303 TPM2_RH_AUTH_FF
304 );
305 add_constant_handle!(PermanentTpmHandle, AuthenticatedTimersFirst, TPM2_RH_ACT_0);
306 add_constant_handle!(PermanentTpmHandle, AuthenticatedTimersLast, TPM2_RH_ACT_F);
307 add_constant_handle!(PermanentTpmHandle, Last, TPM2_RH_LAST);
308}
309
310pub mod saved_session {
311 use super::*;
313 use crate::constants::tss::{
314 TPM2_HT_SAVED_SESSION, TPM2_POLICY_SESSION_FIRST, TPM2_POLICY_SESSION_LAST,
315 };
316
317 create_tpm_handle_type!(
318 SavedSessionTpmHandle,
319 TpmHandle::SavedSession,
320 TPM2_HT_SAVED_SESSION,
321 TPM2_POLICY_SESSION_FIRST, TPM2_POLICY_SESSION_LAST );
324}
325
326pub mod transient {
327 use super::*;
329 use crate::constants::tss::{TPM2_HT_TRANSIENT, TPM2_TRANSIENT_FIRST, TPM2_TRANSIENT_LAST};
330
331 create_tpm_handle_type!(
332 TransientTpmHandle,
333 TpmHandle::Transient,
334 TPM2_HT_TRANSIENT,
335 TPM2_TRANSIENT_FIRST,
336 TPM2_TRANSIENT_LAST
337 );
338}
339
340pub mod persistent {
341 use super::*;
343 use crate::constants::tss::{TPM2_HT_PERSISTENT, TPM2_PERSISTENT_FIRST, TPM2_PERSISTENT_LAST};
344
345 create_tpm_handle_type!(
346 PersistentTpmHandle,
347 TpmHandle::Persistent,
348 TPM2_HT_PERSISTENT,
349 TPM2_PERSISTENT_FIRST,
350 TPM2_PERSISTENT_LAST
351 );
352}
353
354pub mod attached_component {
355 use super::*;
357 use crate::constants::tss::{TPM2_AC_FIRST, TPM2_AC_LAST, TPM2_HT_AC};
358
359 create_tpm_handle_type!(
360 AttachedComponentTpmHandle,
361 TpmHandle::AttachedComponent,
362 TPM2_HT_AC,
363 TPM2_AC_FIRST,
364 TPM2_AC_LAST
365 );
366}