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