1use super::{
6 Tpm2bAuth, Tpm2bDigest, Tpm2bEccParameter, Tpm2bPublicKeyRsa, Tpm2bSensitiveData, Tpm2bSymKey,
7 TpmAlgId, TpmHt, TpmRh, TpmSt, TpmaObject, TpmsEccPoint, TpmuHa, TpmuKeyedhashScheme,
8 TpmuNvPublic2, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite, TpmuSigScheme,
9 TpmuSymKeyBits, TpmuSymMode,
10};
11use crate::{
12 constant::TPM_MAX_COMMAND_SIZE, tpm_struct, TpmBuild, TpmError, TpmParse, TpmParseTagged,
13 TpmResult, TpmSized, TpmWriter,
14};
15
16macro_rules! tpm_struct_tagged {
17 (
18 $(#[$outer:meta])*
19 $vis:vis struct $name:ident {
20 pub $tag_field:ident: $tag_ty:ty,
21 pub $value_field:ident: $value_ty:ty,
22 }
23 ) => {
24 $(#[$outer])*
25 $vis struct $name {
26 pub $tag_field: $tag_ty,
27 pub $value_field: $value_ty,
28 }
29
30 impl $crate::TpmSized for $name {
31 const SIZE: usize = <$tag_ty>::SIZE + <$value_ty>::SIZE;
32 fn len(&self) -> usize {
33 $crate::TpmSized::len(&self.$tag_field) + $crate::TpmSized::len(&self.$value_field)
34 }
35 }
36
37 impl $crate::TpmBuild for $name {
38 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
39 $crate::TpmBuild::build(&self.$tag_field, writer)?;
40 $crate::TpmBuild::build(&self.$value_field, writer)
41 }
42 }
43
44 impl $crate::TpmParse for $name {
45 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
46 let ($tag_field, buf) = <$tag_ty>::parse(buf)?;
47 let ($value_field, buf) =
48 <$value_ty as $crate::TpmParseTagged>::parse_tagged($tag_field, buf)?;
49 Ok((
50 Self {
51 $tag_field,
52 $value_field,
53 },
54 buf,
55 ))
56 }
57 }
58 };
59}
60
61#[derive(Debug, PartialEq, Eq, Clone)]
62pub struct TpmtPublic {
63 pub object_type: TpmAlgId,
64 pub name_alg: TpmAlgId,
65 pub object_attributes: TpmaObject,
66 pub auth_policy: Tpm2bDigest,
67 pub parameters: TpmuPublicParms,
68 pub unique: TpmuPublicId,
69}
70
71impl TpmSized for TpmtPublic {
72 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
73 fn len(&self) -> usize {
74 self.object_type.len()
75 + self.name_alg.len()
76 + self.object_attributes.len()
77 + self.auth_policy.len()
78 + self.parameters.len()
79 + self.unique.len()
80 }
81}
82
83impl TpmBuild for TpmtPublic {
84 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
85 self.object_type.build(writer)?;
86 self.name_alg.build(writer)?;
87 self.object_attributes.build(writer)?;
88 self.auth_policy.build(writer)?;
89 self.parameters.build(writer)?;
90 self.unique.build(writer)
91 }
92}
93
94impl TpmParse for TpmtPublic {
95 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
96 let (object_type, buf) = TpmAlgId::parse(buf)?;
97 let (name_alg, buf) = TpmAlgId::parse(buf)?;
98 let (object_attributes, buf) = TpmaObject::parse(buf)?;
99 let (auth_policy, buf) = Tpm2bDigest::parse(buf)?;
100 let (parameters, buf) = TpmuPublicParms::parse_tagged(object_type, buf)?;
101 let (unique, buf) = match object_type {
102 TpmAlgId::KeyedHash => {
103 let (val, rest) = Tpm2bDigest::parse(buf)?;
104 (TpmuPublicId::KeyedHash(val), rest)
105 }
106 TpmAlgId::SymCipher => {
107 let (val, rest) = Tpm2bSymKey::parse(buf)?;
108 (TpmuPublicId::SymCipher(val), rest)
109 }
110 TpmAlgId::Rsa => {
111 let (val, rest) = Tpm2bPublicKeyRsa::parse(buf)?;
112 (TpmuPublicId::Rsa(val), rest)
113 }
114 TpmAlgId::Ecc => {
115 let (point, rest) = TpmsEccPoint::parse(buf)?;
116 (TpmuPublicId::Ecc(point), rest)
117 }
118 TpmAlgId::Null => (TpmuPublicId::Null, buf),
119 _ => return Err(TpmError::MalformedData),
120 };
121 let public_area = Self {
122 object_type,
123 name_alg,
124 object_attributes,
125 auth_policy,
126 parameters,
127 unique,
128 };
129 Ok((public_area, buf))
130 }
131}
132
133impl Default for TpmtPublic {
134 fn default() -> Self {
135 Self {
136 object_type: TpmAlgId::Null,
137 name_alg: TpmAlgId::Null,
138 object_attributes: TpmaObject::empty(),
139 auth_policy: Tpm2bDigest::default(),
140 parameters: TpmuPublicParms::Null,
141 unique: TpmuPublicId::Null,
142 }
143 }
144}
145
146tpm_struct_tagged! {
147 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
148 pub struct TpmtPublicParms {
149 pub object_type: TpmAlgId,
150 pub parameters: TpmuPublicParms,
151 }
152}
153
154tpm_struct! {
155 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
156 pub struct TpmtKdfScheme {
157 pub scheme: TpmAlgId,
158 }
159}
160
161tpm_struct_tagged! {
162 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
163 pub struct TpmtRsaDecrypt {
164 pub scheme: TpmAlgId,
165 pub details: crate::data::tpmu::TpmuAsymScheme,
166 }
167}
168
169impl Default for TpmtRsaDecrypt {
170 fn default() -> Self {
171 Self {
172 scheme: TpmAlgId::Null,
173 details: crate::data::tpmu::TpmuAsymScheme::default(),
174 }
175 }
176}
177
178#[derive(Debug, PartialEq, Eq, Clone, Default)]
179pub struct TpmtSensitive {
180 pub sensitive_type: TpmAlgId,
181 pub auth_value: Tpm2bAuth,
182 pub seed_value: Tpm2bDigest,
183 pub sensitive: TpmuSensitiveComposite,
184}
185
186impl TpmSized for TpmtSensitive {
187 const SIZE: usize =
188 TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
189 fn len(&self) -> usize {
190 self.sensitive_type.len()
191 + self.auth_value.len()
192 + self.seed_value.len()
193 + self.sensitive.len()
194 }
195}
196
197impl TpmBuild for TpmtSensitive {
198 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
199 self.sensitive_type.build(writer)?;
200 self.auth_value.build(writer)?;
201 self.seed_value.build(writer)?;
202 self.sensitive.build(writer)
203 }
204}
205
206impl TpmParse for TpmtSensitive {
207 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
208 let (sensitive_type, buf) = TpmAlgId::parse(buf)?;
209 let (auth_value, buf) = Tpm2bAuth::parse(buf)?;
210 let (seed_value, buf) = Tpm2bDigest::parse(buf)?;
211 let (sensitive, buf) = match sensitive_type {
212 TpmAlgId::Rsa => {
213 let (val, buf) = crate::data::Tpm2bPrivateKeyRsa::parse(buf)?;
214 (TpmuSensitiveComposite::Rsa(val), buf)
215 }
216 TpmAlgId::Ecc => {
217 let (val, buf) = Tpm2bEccParameter::parse(buf)?;
218 (TpmuSensitiveComposite::Ecc(val), buf)
219 }
220 TpmAlgId::KeyedHash => {
221 let (val, buf) = Tpm2bSensitiveData::parse(buf)?;
222 (TpmuSensitiveComposite::Bits(val), buf)
223 }
224 TpmAlgId::SymCipher => {
225 let (val, buf) = Tpm2bSymKey::parse(buf)?;
226 (TpmuSensitiveComposite::Sym(val), buf)
227 }
228 _ => return Err(TpmError::MalformedData),
229 };
230 Ok((
231 Self {
232 sensitive_type,
233 auth_value,
234 seed_value,
235 sensitive,
236 },
237 buf,
238 ))
239 }
240}
241
242#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
243pub struct TpmtSymDef {
244 pub algorithm: TpmAlgId,
245 pub key_bits: TpmuSymKeyBits,
246 pub mode: TpmuSymMode,
247}
248
249impl TpmSized for TpmtSymDef {
250 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
251 fn len(&self) -> usize {
252 if self.algorithm == TpmAlgId::Null {
253 self.algorithm.len()
254 } else {
255 self.algorithm.len() + self.key_bits.len() + self.mode.len()
256 }
257 }
258}
259
260impl TpmBuild for TpmtSymDef {
261 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
262 self.algorithm.build(writer)?;
263 if self.algorithm != TpmAlgId::Null {
264 self.key_bits.build(writer)?;
265 self.mode.build(writer)?;
266 }
267 Ok(())
268 }
269}
270
271impl TpmParse for TpmtSymDef {
272 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
273 let (algorithm, buf) = TpmAlgId::parse(buf)?;
274 if algorithm == TpmAlgId::Null {
275 return Ok((
276 Self {
277 algorithm,
278 key_bits: TpmuSymKeyBits::Null,
279 mode: TpmuSymMode::Null,
280 },
281 buf,
282 ));
283 }
284 let (key_bits, buf) = match algorithm {
285 TpmAlgId::Aes => {
286 let (val, buf) = u16::parse(buf)?;
287 (TpmuSymKeyBits::Aes(val), buf)
288 }
289 TpmAlgId::Sm4 => {
290 let (val, buf) = u16::parse(buf)?;
291 (TpmuSymKeyBits::Sm4(val), buf)
292 }
293 TpmAlgId::Camellia => {
294 let (val, buf) = u16::parse(buf)?;
295 (TpmuSymKeyBits::Camellia(val), buf)
296 }
297 TpmAlgId::Xor => {
298 let (val, buf) = TpmAlgId::parse(buf)?;
299 (TpmuSymKeyBits::Xor(val), buf)
300 }
301 TpmAlgId::Null => (TpmuSymKeyBits::Null, buf),
302 _ => return Err(TpmError::MalformedData),
303 };
304 let (mode, buf) = match algorithm {
305 TpmAlgId::Aes => {
306 let (val, buf) = TpmAlgId::parse(buf)?;
307 (TpmuSymMode::Aes(val), buf)
308 }
309 TpmAlgId::Sm4 => {
310 let (val, buf) = TpmAlgId::parse(buf)?;
311 (TpmuSymMode::Sm4(val), buf)
312 }
313 TpmAlgId::Camellia => {
314 let (val, buf) = TpmAlgId::parse(buf)?;
315 (TpmuSymMode::Camellia(val), buf)
316 }
317 TpmAlgId::Xor => {
318 let (val, buf) = TpmAlgId::parse(buf)?;
319 (TpmuSymMode::Xor(val), buf)
320 }
321 TpmAlgId::Null => (TpmuSymMode::Null, buf),
322 _ => return Err(TpmError::MalformedData),
323 };
324 Ok((
325 Self {
326 algorithm,
327 key_bits,
328 mode,
329 },
330 buf,
331 ))
332 }
333}
334
335pub type TpmtSymDefObject = TpmtSymDef;
336
337tpm_struct_tagged! {
338 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
339 pub struct TpmtNvPublic2 {
340 pub handle_type: TpmHt,
341 pub public_area: TpmuNvPublic2,
342 }
343}
344
345tpm_struct! {
346 #[derive(Debug, PartialEq, Eq, Clone, Default)]
347 pub struct TpmtTkCreation {
348 pub tag: TpmSt,
349 pub hierarchy: TpmRh,
350 pub digest: Tpm2bDigest,
351 }
352}
353
354tpm_struct! {
355 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
356 pub struct TpmtTkVerified {
357 pub tag: TpmSt,
358 pub hierarchy: TpmRh,
359 pub digest: Tpm2bDigest,
360 }
361}
362
363tpm_struct! {
364 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
365 pub struct TpmtTkAuth {
366 pub tag: TpmSt,
367 pub hierarchy: TpmRh,
368 pub digest: Tpm2bDigest,
369 }
370}
371
372tpm_struct! {
373 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
374 pub struct TpmtTkHashcheck {
375 pub tag: TpmSt,
376 pub hierarchy: TpmRh,
377 pub digest: Tpm2bDigest,
378 }
379}
380
381tpm_struct_tagged! {
382 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
383 pub struct TpmtHa {
384 pub hash_alg: TpmAlgId,
385 pub digest: TpmuHa,
386 }
387}
388
389impl Default for TpmtHa {
390 fn default() -> Self {
391 Self {
392 hash_alg: TpmAlgId::Null,
393 digest: TpmuHa::default(),
394 }
395 }
396}
397
398tpm_struct_tagged! {
399 #[derive(Debug, PartialEq, Eq, Clone)]
400 pub struct TpmtSignature {
401 pub sig_alg: TpmAlgId,
402 pub signature: crate::data::tpmu::TpmuSignature,
403 }
404}
405
406tpm_struct_tagged! {
407 #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
408 pub struct TpmtKeyedhashScheme {
409 pub scheme: TpmAlgId,
410 pub details: TpmuKeyedhashScheme,
411 }
412}
413
414tpm_struct_tagged! {
415 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
416 pub struct TpmtSigScheme {
417 pub scheme: TpmAlgId,
418 pub details: TpmuSigScheme,
419 }
420}
421
422impl Default for TpmtSigScheme {
423 fn default() -> Self {
424 Self {
425 scheme: TpmAlgId::Null,
426 details: TpmuSigScheme::default(),
427 }
428 }
429}
430
431tpm_struct_tagged! {
432 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
433 pub struct TpmtRsaScheme {
434 pub scheme: TpmAlgId,
435 pub details: crate::data::tpmu::TpmuAsymScheme,
436 }
437}
438
439impl Default for TpmtRsaScheme {
440 fn default() -> Self {
441 Self {
442 scheme: TpmAlgId::Null,
443 details: crate::data::tpmu::TpmuAsymScheme::default(),
444 }
445 }
446}
447
448tpm_struct_tagged! {
449 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
450 pub struct TpmtEccScheme {
451 pub scheme: TpmAlgId,
452 pub details: crate::data::tpmu::TpmuAsymScheme,
453 }
454}
455
456impl Default for TpmtEccScheme {
457 fn default() -> Self {
458 Self {
459 scheme: TpmAlgId::Null,
460 details: crate::data::tpmu::TpmuAsymScheme::default(),
461 }
462 }
463}