Skip to main content

tss_esapi/structures/
tpm_context.rs

1// Copyright 2024 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    handles::TpmHandle,
5    interface_types::{data_handles::Saved, reserved_handles::Hierarchy},
6    structures::TpmContextData,
7    traits::impl_mu_standard,
8    tss2_esys::TPMS_CONTEXT,
9    Error, Result,
10};
11use std::convert::TryFrom;
12
13/// Structure holding the content of a TPM context.
14///
15/// # Details
16/// This object can be serialized and deserialized
17/// using serde if the `serde` feature is enabled.
18#[derive(Debug, Clone)]
19pub struct SavedTpmContext {
20    sequence: u64,
21    saved_handle: Saved,
22    hierarchy: Hierarchy,
23    context_blob: TpmContextData,
24}
25
26impl SavedTpmContext {
27    /// The sequence parameter
28    ///
29    /// # Details
30    /// "The sequence parameter is used to differentiate the contexts and to allow the TPM to create a different
31    ///  encryption key for each context."
32    pub const fn sequence(&self) -> u64 {
33        self.sequence
34    }
35
36    /// The saved handle.
37    pub const fn saved_handle(&self) -> Saved {
38        self.saved_handle
39    }
40
41    /// The hierarchy for the saved context.
42    pub const fn hierarchy(&self) -> Hierarchy {
43        self.hierarchy
44    }
45
46    /// The context blob.
47    ///
48    /// # Details
49    /// "This is the hierarchy ([Hierarchy]) for the saved context and determines the proof value used
50    ///  in the construction of the encryption and integrity values for the context. For session and sequence
51    ///  contexts, the hierarchy is [Hierarchy::Null]. The hierarchy for a transient object may be [Hierarchy::Null]
52    ///  but it is not required."
53    pub fn context_blob(&self) -> &TpmContextData {
54        &self.context_blob
55    }
56}
57
58impl TryFrom<TPMS_CONTEXT> for SavedTpmContext {
59    type Error = Error;
60
61    fn try_from(tss: TPMS_CONTEXT) -> Result<SavedTpmContext> {
62        Ok(SavedTpmContext {
63            sequence: tss.sequence,
64            saved_handle: Saved::try_from(tss.savedHandle)?,
65            hierarchy: TpmHandle::try_from(tss.hierarchy).and_then(Hierarchy::try_from)?,
66            context_blob: TpmContextData::try_from(tss.contextBlob)?,
67        })
68    }
69}
70
71impl From<SavedTpmContext> for TPMS_CONTEXT {
72    fn from(native: SavedTpmContext) -> TPMS_CONTEXT {
73        TPMS_CONTEXT {
74            sequence: native.sequence,
75            savedHandle: native.saved_handle.into(),
76            hierarchy: TpmHandle::from(native.hierarchy).into(),
77            contextBlob: native.context_blob.into(),
78        }
79    }
80}
81
82impl_mu_standard!(SavedTpmContext, TPMS_CONTEXT);
83
84cfg_if::cfg_if! {
85    if #[cfg(feature = "serde")] {
86        use crate::traits::{Marshall, UnMarshall};
87        impl serde::Serialize for SavedTpmContext {
88            /// Serialize the [SavedTpmContext] data into it's bytes representation of the TCG
89            /// TPMS_CONTEXT structure.
90            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
91            where
92                S: serde::Serializer,
93            {
94                let bytes = self.marshall().map_err(serde::ser::Error::custom)?;
95                serializer.serialize_bytes(&bytes)
96            }
97        }
98
99        impl<'de> serde::Deserialize<'de> for SavedTpmContext {
100            /// Deserialize the [SavedTpmContext] data from it's bytes representation of the TCG
101            /// TPMS_CONTEXT structure.
102            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
103            where
104                D: serde::Deserializer<'de>,
105            {
106                let bytes = <Vec<u8>>::deserialize(deserializer)?;
107                Self::unmarshall(&bytes).map_err(serde::de::Error::custom)
108            }
109        }
110    }
111}