Skip to main content

tss_esapi/context/tpm_commands/
hierarchy_commands.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    context::handle_manager::HandleDropAction,
5    handles::{AuthHandle, KeyHandle, ObjectHandle},
6    interface_types::{reserved_handles::Hierarchy, YesNo},
7    structures::{
8        Auth, CreatePrimaryKeyResult, CreationData, CreationTicket, Data, Digest, PcrSelectionList,
9        Public, SensitiveCreate, SensitiveData,
10    },
11    tss2_esys::{Esys_Clear, Esys_ClearControl, Esys_CreatePrimary, Esys_HierarchyChangeAuth},
12    Context, Result, ReturnCode,
13};
14use log::error;
15use std::convert::{TryFrom, TryInto};
16use std::ptr::null_mut;
17
18impl Context {
19    /// Create a primary key and return the handle.
20    ///
21    /// The authentication value, initial data, outside info and creation PCRs are passed as slices
22    /// which are then converted by the method into TSS native structures.
23    ///
24    /// # Errors
25    /// * if either of the slices is larger than the maximum size of the native objects, a
26    ///   `WrongParamSize` wrapper error is returned
27    // TODO: Fix when compacting the arguments into a struct
28    #[allow(clippy::too_many_arguments)]
29    pub fn create_primary(
30        &mut self,
31        primary_handle: Hierarchy,
32        public: Public,
33        auth_value: Option<Auth>,
34        initial_data: Option<SensitiveData>,
35        outside_info: Option<Data>,
36        creation_pcrs: Option<PcrSelectionList>,
37    ) -> Result<CreatePrimaryKeyResult> {
38        let sensitive_create = SensitiveCreate::new(
39            auth_value.unwrap_or_default(),
40            initial_data.unwrap_or_default(),
41        );
42        let creation_pcrs = PcrSelectionList::list_from_option(creation_pcrs);
43
44        let mut out_public_ptr = null_mut();
45        let mut creation_data_ptr = null_mut();
46        let mut creation_hash_ptr = null_mut();
47        let mut creation_ticket_ptr = null_mut();
48        let mut object_handle = ObjectHandle::None.into();
49
50        ReturnCode::ensure_success(
51            unsafe {
52                Esys_CreatePrimary(
53                    self.mut_context(),
54                    ObjectHandle::from(primary_handle).into(),
55                    self.optional_session_1(),
56                    self.optional_session_2(),
57                    self.optional_session_3(),
58                    &sensitive_create.try_into()?,
59                    &public.try_into()?,
60                    &outside_info.unwrap_or_default().into(),
61                    &creation_pcrs.into(),
62                    &mut object_handle,
63                    &mut out_public_ptr,
64                    &mut creation_data_ptr,
65                    &mut creation_hash_ptr,
66                    &mut creation_ticket_ptr,
67                )
68            },
69            |ret| {
70                error!("Error in creating primary key: {:#010X}", ret);
71            },
72        )?;
73        let out_public_owned = Context::ffi_data_to_owned(out_public_ptr)?;
74        let creation_data_owned = Context::ffi_data_to_owned(creation_data_ptr)?;
75        let creation_hash_owned = Context::ffi_data_to_owned(creation_hash_ptr)?;
76        let creation_ticket_owned = Context::ffi_data_to_owned(creation_ticket_ptr)?;
77        let primary_key_handle = KeyHandle::from(object_handle);
78        self.handle_manager
79            .add_handle(primary_key_handle.into(), HandleDropAction::Flush)?;
80
81        Ok(CreatePrimaryKeyResult {
82            key_handle: primary_key_handle,
83            out_public: Public::try_from(out_public_owned)?,
84            creation_data: CreationData::try_from(creation_data_owned)?,
85            creation_hash: Digest::try_from(creation_hash_owned)?,
86            creation_ticket: CreationTicket::try_from(creation_ticket_owned)?,
87        })
88    }
89
90    // Missing function: HierarchyControl
91    // Missing function: SetPrimaryPolicy
92    // Missing function: ChangePPS
93    // Missing function: ChangeEPS
94
95    /// Clear all TPM context associated with a specific Owner
96    pub fn clear(&mut self, auth_handle: AuthHandle) -> Result<()> {
97        ReturnCode::ensure_success(
98            unsafe {
99                Esys_Clear(
100                    self.mut_context(),
101                    auth_handle.into(),
102                    self.required_session_1()?,
103                    self.optional_session_2(),
104                    self.optional_session_3(),
105                )
106            },
107            |ret| {
108                error!("Error in clearing TPM hierarchy: {:#010X}", ret);
109            },
110        )
111    }
112
113    /// Disable or enable the TPM2_CLEAR command
114    pub fn clear_control(&mut self, auth_handle: AuthHandle, disable: bool) -> Result<()> {
115        ReturnCode::ensure_success(
116            unsafe {
117                Esys_ClearControl(
118                    self.mut_context(),
119                    auth_handle.into(),
120                    self.required_session_1()?,
121                    self.optional_session_2(),
122                    self.optional_session_3(),
123                    YesNo::from(disable).into(),
124                )
125            },
126            |ret| {
127                error!("Error in controlling clear command: {:#010X}", ret);
128            },
129        )
130    }
131
132    /// Change authorization for a hierarchy root
133    pub fn hierarchy_change_auth(&mut self, auth_handle: AuthHandle, new_auth: Auth) -> Result<()> {
134        ReturnCode::ensure_success(
135            unsafe {
136                Esys_HierarchyChangeAuth(
137                    self.mut_context(),
138                    auth_handle.into(),
139                    self.required_session_1()?,
140                    self.optional_session_2(),
141                    self.optional_session_3(),
142                    &new_auth.into(),
143                )
144            },
145            |ret| {
146                error!("Error changing hierarchy auth: {:#010X}", ret);
147            },
148        )
149    }
150}