tss_esapi/context/tpm_commands/
hierarchy_commands.rs1use crate::{
4 context::handle_manager::HandleDropAction,
5 handles::{AuthHandle, KeyHandle, ObjectHandle},
6 interface_types::{resource_handles::Hierarchy, YesNo},
7 structures::{
8 Auth, CreatePrimaryKeyResult, CreationData, CreationTicket, Data, Digest, PcrSelectionList,
9 Public, SensitiveData,
10 },
11 tss2_esys::{
12 Esys_Clear, Esys_ClearControl, Esys_CreatePrimary, Esys_HierarchyChangeAuth,
13 TPM2B_SENSITIVE_CREATE, TPMS_SENSITIVE_CREATE,
14 },
15 Context, Error, Result,
16};
17use log::error;
18use std::{
19 convert::{TryFrom, TryInto},
20 mem::size_of,
21 ptr::null_mut,
22};
23
24impl Context {
25 #[allow(clippy::too_many_arguments)]
35 pub fn create_primary(
36 &mut self,
37 primary_handle: Hierarchy,
38 public: Public,
39 auth_value: Option<Auth>,
40 initial_data: Option<SensitiveData>,
41 outside_info: Option<Data>,
42 creation_pcrs: Option<PcrSelectionList>,
43 ) -> Result<CreatePrimaryKeyResult> {
44 let sensitive_create = TPM2B_SENSITIVE_CREATE {
45 size: size_of::<TPMS_SENSITIVE_CREATE>().try_into().unwrap(),
46 sensitive: TPMS_SENSITIVE_CREATE {
47 userAuth: auth_value.unwrap_or_default().into(),
48 data: initial_data.unwrap_or_default().into(),
49 },
50 };
51 let creation_pcrs = PcrSelectionList::list_from_option(creation_pcrs);
52
53 let mut out_public_ptr = null_mut();
54 let mut creation_data_ptr = null_mut();
55 let mut creation_hash_ptr = null_mut();
56 let mut creation_ticket_ptr = null_mut();
57 let mut object_handle = ObjectHandle::None.into();
58
59 let ret = unsafe {
60 Esys_CreatePrimary(
61 self.mut_context(),
62 ObjectHandle::from(primary_handle).into(),
63 self.optional_session_1(),
64 self.optional_session_2(),
65 self.optional_session_3(),
66 &sensitive_create,
67 &public.try_into()?,
68 &outside_info.unwrap_or_default().into(),
69 &creation_pcrs.into(),
70 &mut object_handle,
71 &mut out_public_ptr,
72 &mut creation_data_ptr,
73 &mut creation_hash_ptr,
74 &mut creation_ticket_ptr,
75 )
76 };
77 let ret = Error::from_tss_rc(ret);
78
79 if ret.is_success() {
80 let out_public_owned = Context::ffi_data_to_owned(out_public_ptr);
81 let creation_data_owned = Context::ffi_data_to_owned(creation_data_ptr);
82 let creation_hash_owned = Context::ffi_data_to_owned(creation_hash_ptr);
83 let creation_ticket_owned = Context::ffi_data_to_owned(creation_ticket_ptr);
84 let primary_key_handle = KeyHandle::from(object_handle);
85 self.handle_manager
86 .add_handle(primary_key_handle.into(), HandleDropAction::Flush)?;
87
88 Ok(CreatePrimaryKeyResult {
89 key_handle: primary_key_handle,
90 out_public: Public::try_from(out_public_owned)?,
91 creation_data: CreationData::try_from(creation_data_owned)?,
92 creation_hash: Digest::try_from(creation_hash_owned)?,
93 creation_ticket: CreationTicket::try_from(creation_ticket_owned)?,
94 })
95 } else {
96 error!("Error in creating primary key: {}", ret);
97 Err(ret)
98 }
99 }
100
101 pub fn clear(&mut self, auth_handle: AuthHandle) -> Result<()> {
108 let ret = unsafe {
109 Esys_Clear(
110 self.mut_context(),
111 auth_handle.into(),
112 self.required_session_1()?,
113 self.optional_session_2(),
114 self.optional_session_3(),
115 )
116 };
117 let ret = Error::from_tss_rc(ret);
118
119 if ret.is_success() {
120 Ok(())
121 } else {
122 error!("Error in clearing TPM hierarchy: {}", ret);
123 Err(ret)
124 }
125 }
126
127 pub fn clear_control(&mut self, auth_handle: AuthHandle, disable: bool) -> Result<()> {
129 let ret = unsafe {
130 Esys_ClearControl(
131 self.mut_context(),
132 auth_handle.into(),
133 self.required_session_1()?,
134 self.optional_session_2(),
135 self.optional_session_3(),
136 YesNo::from(disable).into(),
137 )
138 };
139 let ret = Error::from_tss_rc(ret);
140
141 if ret.is_success() {
142 Ok(())
143 } else {
144 error!("Error in controlling clear command: {}", ret);
145 Err(ret)
146 }
147 }
148
149 pub fn hierarchy_change_auth(&mut self, auth_handle: AuthHandle, new_auth: Auth) -> Result<()> {
151 let ret = unsafe {
152 Esys_HierarchyChangeAuth(
153 self.mut_context(),
154 auth_handle.into(),
155 self.required_session_1()?,
156 self.optional_session_2(),
157 self.optional_session_3(),
158 &new_auth.into(),
159 )
160 };
161 let ret = Error::from_tss_rc(ret);
162 if ret.is_success() {
163 Ok(())
164 } else {
165 error!("Error changing hierarchy auth: {}", ret);
166 Err(ret)
167 }
168 }
169}