tss_esapi/handles/
tpm.rs

1// Copyright 2020 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use 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/// Enum representing the different types of tpm handles
16/// of a TPM handle.
17///
18/// # Details
19/// The TPM handles are used
20/// to reference shielded locations of various
21/// types within the TPM.
22///
23/// N.B:
24/// Do not confuse the TpmHandles with the
25/// ESYS [ObjectHandle](crate::handles::ObjectHandle).
26#[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    /// Method that indicates if the flushing the
42    /// context of the handle is a valid action.
43    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            // HMAC and LOADED has the same type id
81            TPM2_HT_POLICY_SESSION => Ok(TpmHandle::PolicySession(
82                policy_session::PolicySessionTpmHandle::new(tss_tpm_handle)?,
83            )),
84            // POLICY and SAVED has the same type id.
85            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
105/// Macro for creating the specific TPM handle types
106macro_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                // Add +1 to include tpm_handle_type_last in the range
124                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
173/// Macro for making a constant available
174/// for a TPM handle type.
175macro_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    //! Module for the PCR TPM handle.
188    use super::*;
189    use crate::constants::tss::{TPM2_HT_PCR, TPM2_PCR_FIRST, TPM2_PCR_LAST};
190    // Creates the specific handle types
191    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    //! Module for the NV index TPM handle.
202    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    //! Module for the HMAC session TPM handle.
216    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    //! Module for the loaded session TPM handle.
232    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    //! Module for policy session TPM handles.
248    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    //! Module for saved session TPM handles
312    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, // Policy session have the same type as saved session.
322        TPM2_POLICY_SESSION_LAST   // so assuming they have the same valid range makes sense.
323    );
324}
325
326pub mod transient {
327    //! Module for transient TPM handles
328    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    //! Module for persistent TPM handles
342    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    //! Module for attached component TPM handles.
356    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}