Skip to main content

tss_esapi/context/tpm_commands/
session_commands.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    constants::SessionType,
5    context::handle_manager::HandleDropAction,
6    handles::{KeyHandle, ObjectHandle, SessionHandle},
7    interface_types::{
8        algorithm::HashingAlgorithm,
9        session_handles::{AuthSession, PolicySession},
10    },
11    structures::{Nonce, SymmetricDefinition},
12    tss2_esys::{Esys_PolicyRestart, Esys_StartAuthSession},
13    Context, Error, Result,
14};
15use log::error;
16use std::{convert::TryInto, ptr::null};
17impl Context {
18    /// Start new authentication session and return the Session object
19    /// associated with the session.
20    ///
21    /// If the returned session handle from ESYS api is ESYS_TR_NONE then
22    /// the value of the option in the result will be None.
23    ///
24    /// # Example
25    ///
26    /// ```rust
27    /// # use tss_esapi::{Context, Tcti,
28    /// #     constants::SessionType,
29    /// #     interface_types::algorithm::HashingAlgorithm,
30    /// #     structures::SymmetricDefinition,
31    /// # };
32    /// # // Create context
33    /// # let mut context =
34    /// #     Context::new(
35    /// #         Tcti::from_environment_variable().expect("Failed to get TCTI"),
36    /// #     ).expect("Failed to create Context");
37    /// // Create auth session without key_handle, bind_handle
38    /// // and Nonce
39    /// let session = context
40    ///     .start_auth_session(
41    ///         None,
42    ///         None,
43    ///         None,
44    ///         SessionType::Hmac,
45    ///         SymmetricDefinition::AES_256_CFB,
46    ///         HashingAlgorithm::Sha256,
47    ///     )
48    ///     .expect("Failed to create session")
49    ///     .expect("Received invalid handle");
50    /// ```
51    #[allow(clippy::too_many_arguments)]
52    pub fn start_auth_session(
53        &mut self,
54        tpm_key: Option<KeyHandle>,
55        bind: Option<ObjectHandle>,
56        nonce: Option<Nonce>,
57        session_type: SessionType,
58        symmetric: SymmetricDefinition,
59        auth_hash: HashingAlgorithm,
60    ) -> Result<Option<AuthSession>> {
61        let mut session_handle = ObjectHandle::None.into();
62        let potential_tpm2b_nonce = nonce.map(|v| v.into());
63        let ret = unsafe {
64            Esys_StartAuthSession(
65                self.mut_context(),
66                tpm_key
67                    .map(ObjectHandle::from)
68                    .unwrap_or(ObjectHandle::None)
69                    .into(),
70                bind.unwrap_or(ObjectHandle::None).into(),
71                self.optional_session_1(),
72                self.optional_session_2(),
73                self.optional_session_3(),
74                potential_tpm2b_nonce
75                    .as_ref()
76                    .map_or(null(), std::ptr::from_ref),
77                session_type.into(),
78                &symmetric.try_into()?,
79                auth_hash.into(),
80                &mut session_handle,
81            )
82        };
83
84        let ret = Error::from_tss_rc(ret);
85        if ret.is_success() {
86            self.handle_manager
87                .add_handle(session_handle.into(), HandleDropAction::Flush)?;
88            Ok(AuthSession::create(
89                session_type,
90                session_handle.into(),
91                auth_hash,
92            ))
93        } else {
94            error!("Error when creating a session: {}", ret);
95            Err(ret)
96        }
97    }
98
99    /// Restart the TPM Policy
100    pub fn policy_restart(&mut self, policy_session: PolicySession) -> Result<()> {
101        let ret = unsafe {
102            Esys_PolicyRestart(
103                self.mut_context(),
104                SessionHandle::from(policy_session).into(),
105                self.optional_session_1(),
106                self.optional_session_2(),
107                self.optional_session_3(),
108            )
109        };
110        let ret = Error::from_tss_rc(ret);
111
112        if ret.is_success() {
113            Ok(())
114        } else {
115            error!("Error restarting policy: {}", ret);
116            Err(ret)
117        }
118    }
119}