tss_esapi/structures/tagged/
sensitive.rs1use crate::{
4 interface_types::algorithm::PublicAlgorithm,
5 structures::{Auth, Digest, EccParameter, PrivateKeyRsa, SensitiveData, SymmetricKey},
6 traits::{Marshall, UnMarshall},
7 tss2_esys::{TPM2B_SENSITIVE, TPMT_SENSITIVE, TPMU_SENSITIVE_COMPOSITE},
8 Error, Result, WrapperErrorKind,
9};
10use log::error;
11use std::{
12 convert::{TryFrom, TryInto},
13 mem::size_of,
14};
15
16#[derive(Debug, Clone, Eq, PartialEq)]
21pub enum Sensitive {
22 Rsa {
23 auth_value: Auth,
24 seed_value: Digest,
25 sensitive: PrivateKeyRsa,
26 },
27 Ecc {
28 auth_value: Auth,
29 seed_value: Digest,
30 sensitive: EccParameter,
31 },
32 Bits {
33 auth_value: Auth,
34 seed_value: Digest,
35 sensitive: SensitiveData,
36 },
37 Symmetric {
38 auth_value: Auth,
39 seed_value: Digest,
40 sensitive: SymmetricKey,
41 },
42 }
50
51impl Sensitive {
52 pub fn auth_value(&self) -> &Auth {
54 match self {
55 Sensitive::Rsa { auth_value, .. }
56 | Sensitive::Ecc { auth_value, .. }
57 | Sensitive::Bits { auth_value, .. }
58 | Sensitive::Symmetric { auth_value, .. } => auth_value,
59 }
60 }
61
62 pub fn seed_value(&self) -> &Digest {
64 match self {
65 Sensitive::Rsa { seed_value, .. }
66 | Sensitive::Ecc { seed_value, .. }
67 | Sensitive::Bits { seed_value, .. }
68 | Sensitive::Symmetric { seed_value, .. } => seed_value,
69 }
70 }
71
72 pub fn sensitive_type(&self) -> PublicAlgorithm {
73 match self {
74 Sensitive::Rsa { .. } => PublicAlgorithm::Rsa,
75 Sensitive::Ecc { .. } => PublicAlgorithm::Ecc,
76 Sensitive::Bits { .. } => PublicAlgorithm::KeyedHash,
77 Sensitive::Symmetric { .. } => PublicAlgorithm::SymCipher,
78 }
79 }
80}
81
82impl From<Sensitive> for TPMT_SENSITIVE {
83 fn from(sensitive: Sensitive) -> Self {
84 #[allow(non_snake_case)]
85 let sensitiveType = sensitive.sensitive_type().into();
86 match sensitive {
87 Sensitive::Rsa {
88 auth_value,
89 seed_value,
90 sensitive,
91 } => TPMT_SENSITIVE {
92 sensitiveType,
93 authValue: auth_value.into(),
94 seedValue: seed_value.into(),
95 sensitive: TPMU_SENSITIVE_COMPOSITE {
96 rsa: sensitive.into(),
97 },
98 },
99 Sensitive::Ecc {
100 auth_value,
101 seed_value,
102 sensitive,
103 } => TPMT_SENSITIVE {
104 sensitiveType,
105 authValue: auth_value.into(),
106 seedValue: seed_value.into(),
107 sensitive: TPMU_SENSITIVE_COMPOSITE {
108 ecc: sensitive.into(),
109 },
110 },
111 Sensitive::Bits {
112 auth_value,
113 seed_value,
114 sensitive,
115 } => TPMT_SENSITIVE {
116 sensitiveType,
117 authValue: auth_value.into(),
118 seedValue: seed_value.into(),
119 sensitive: TPMU_SENSITIVE_COMPOSITE {
120 bits: sensitive.into(),
121 },
122 },
123 Sensitive::Symmetric {
124 auth_value,
125 seed_value,
126 sensitive,
127 } => TPMT_SENSITIVE {
128 sensitiveType,
129 authValue: auth_value.into(),
130 seedValue: seed_value.into(),
131 sensitive: TPMU_SENSITIVE_COMPOSITE {
132 sym: sensitive.into(),
133 },
134 },
135 }
136 }
137}
138
139impl TryFrom<TPMT_SENSITIVE> for Sensitive {
140 type Error = Error;
141
142 fn try_from(tpmt_sensitive: TPMT_SENSITIVE) -> Result<Sensitive> {
143 let sensitive_type = PublicAlgorithm::try_from(tpmt_sensitive.sensitiveType)?;
144 match sensitive_type {
145 PublicAlgorithm::Rsa => Ok(Sensitive::Rsa {
146 auth_value: tpmt_sensitive.authValue.try_into()?,
147 seed_value: tpmt_sensitive.seedValue.try_into()?,
148 sensitive: unsafe { tpmt_sensitive.sensitive.rsa }.try_into()?,
149 }),
150 PublicAlgorithm::Ecc => Ok(Sensitive::Ecc {
151 auth_value: tpmt_sensitive.authValue.try_into()?,
152 seed_value: tpmt_sensitive.seedValue.try_into()?,
153 sensitive: unsafe { tpmt_sensitive.sensitive.ecc }.try_into()?,
154 }),
155 PublicAlgorithm::KeyedHash => Ok(Sensitive::Bits {
156 auth_value: tpmt_sensitive.authValue.try_into()?,
157 seed_value: tpmt_sensitive.seedValue.try_into()?,
158 sensitive: unsafe { tpmt_sensitive.sensitive.bits }.try_into()?,
159 }),
160 PublicAlgorithm::SymCipher => Ok(Sensitive::Symmetric {
161 auth_value: tpmt_sensitive.authValue.try_into()?,
162 seed_value: tpmt_sensitive.seedValue.try_into()?,
163 sensitive: unsafe { tpmt_sensitive.sensitive.sym }.try_into()?,
164 }),
165 }
166 }
167}
168
169impl Marshall for Sensitive {
170 const BUFFER_SIZE: usize = size_of::<TPMT_SENSITIVE>();
171
172 fn marshall(&self) -> Result<Vec<u8>> {
176 let mut buffer = vec![0; Self::BUFFER_SIZE];
177 let mut offset = 0;
178
179 let ret = Error::from_tss_rc(unsafe {
180 crate::tss2_esys::Tss2_MU_TPMT_SENSITIVE_Marshal(
181 &self.clone().into(),
182 buffer.as_mut_ptr(),
183 Self::BUFFER_SIZE.try_into().map_err(|e| {
184 error!("Failed to convert size of buffer to TSS size_t type: {}", e);
185 Error::local_error(WrapperErrorKind::InvalidParam)
186 })?,
187 &mut offset,
188 )
189 });
190
191 if !ret.is_success() {
192 return Err(ret);
193 }
194
195 let checked_offset = usize::try_from(offset).map_err(|e| {
196 error!("Failed to parse offset as usize: {}", e);
197 Error::local_error(WrapperErrorKind::InvalidParam)
198 })?;
199
200 buffer.truncate(checked_offset);
201
202 Ok(buffer)
203 }
204}
205
206impl UnMarshall for Sensitive {
207 fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
211 let mut dest = TPMT_SENSITIVE::default();
212 let mut offset = 0;
213
214 let ret = Error::from_tss_rc(unsafe {
215 crate::tss2_esys::Tss2_MU_TPMT_SENSITIVE_Unmarshal(
216 marshalled_data.as_ptr(),
217 marshalled_data.len().try_into().map_err(|e| {
218 error!("Failed to convert length of marshalled data: {}", e);
219 Error::local_error(WrapperErrorKind::InvalidParam)
220 })?,
221 &mut offset,
222 &mut dest,
223 )
224 });
225
226 if !ret.is_success() {
227 return Err(ret);
228 }
229
230 Sensitive::try_from(dest)
231 }
232}
233
234impl TryFrom<TPM2B_SENSITIVE> for Sensitive {
235 type Error = Error;
236
237 fn try_from(tpm2b_sensitive: TPM2B_SENSITIVE) -> Result<Self> {
238 Sensitive::try_from(tpm2b_sensitive.sensitiveArea)
239 }
240}
241
242impl TryFrom<Sensitive> for TPM2B_SENSITIVE {
243 type Error = Error;
244
245 fn try_from(sensitive: Sensitive) -> Result<Self> {
246 let mut buffer = vec![0; Sensitive::BUFFER_SIZE];
247 let mut size = 0;
248 let sensitive_area = TPMT_SENSITIVE::from(sensitive);
249
250 let ret = Error::from_tss_rc(unsafe {
251 crate::tss2_esys::Tss2_MU_TPMT_SENSITIVE_Marshal(
252 &sensitive_area,
253 buffer.as_mut_ptr(),
254 Sensitive::BUFFER_SIZE.try_into().map_err(|e| {
255 error!("Failed to convert size of buffer to TSS size_t type: {}", e);
256 Error::local_error(WrapperErrorKind::InvalidParam)
257 })?,
258 &mut size,
259 )
260 });
261
262 if !ret.is_success() {
263 return Err(ret);
264 }
265
266 Ok(TPM2B_SENSITIVE {
267 size: size.try_into().map_err(|e| {
268 error!(
269 "Failed to convert size of buffer from TSS size_t type: {}",
270 e
271 );
272 Error::local_error(WrapperErrorKind::InvalidParam)
273 })?,
274 sensitiveArea: sensitive_area,
275 })
276 }
277}