1use crate::{
6 data::{
7 Tpm2bDigest, Tpm2bEccParameter, Tpm2bPublicKeyRsa, Tpm2bSensitiveData, Tpm2bSymKey,
8 TpmAlgId, TpmCap, TpmEccCurve, TpmlAlgProperty, TpmlHandle, TpmlPcrSelection,
9 TpmsCertifyInfo, TpmsCommandAuditInfo, TpmsCreationInfo, TpmsEccPoint, TpmsKeyedhashParms,
10 TpmsNvCertifyInfo, TpmsNvDigestCertifyInfo, TpmsQuoteInfo, TpmsSessionAuditInfo,
11 TpmsSignatureEcc, TpmsSignatureRsa, TpmsSymcipherParms, TpmsTimeAttestInfo, TpmtHa,
12 TpmtKdfScheme,
13 },
14 tpm_hash_size, TpmBuild, TpmErrorKind, TpmParse, TpmParseTagged, TpmResult, TpmSized,
15 TpmTagged, TpmWriter, TPM_MAX_COMMAND_SIZE,
16};
17use core::ops::Deref;
18
19fn slice_to_fixed_array<const N: usize>(slice: &[u8]) -> TpmResult<[u8; N]> {
21 slice.try_into().map_err(|_| TpmErrorKind::InternalError)
22}
23
24#[derive(Debug, PartialEq, Eq, Clone)]
25pub enum TpmuCapabilities {
26 Algs(TpmlAlgProperty),
27 Handles(TpmlHandle),
28 Pcrs(TpmlPcrSelection),
29}
30
31impl TpmTagged for TpmuCapabilities {
32 type Tag = TpmCap;
33 type Value = ();
34}
35
36impl TpmSized for TpmuCapabilities {
37 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
38 fn len(&self) -> usize {
39 match self {
40 Self::Algs(algs) => algs.len(),
41 Self::Handles(handles) => handles.len(),
42 Self::Pcrs(pcrs) => pcrs.len(),
43 }
44 }
45}
46
47impl TpmBuild for TpmuCapabilities {
48 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
49 match self {
50 Self::Algs(algs) => algs.build(writer),
51 Self::Handles(handles) => handles.build(writer),
52 Self::Pcrs(pcrs) => pcrs.build(writer),
53 }
54 }
55}
56
57impl TpmParseTagged for TpmuCapabilities {
58 fn parse_tagged(tag: TpmCap, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
59 match tag {
60 TpmCap::Algs => {
61 let (algs, buf) = TpmlAlgProperty::parse(buf)?;
62 Ok((Self::Algs(algs), buf))
63 }
64 TpmCap::Handles => {
65 let (handles, buf) = TpmlHandle::parse(buf)?;
66 Ok((Self::Handles(handles), buf))
67 }
68 TpmCap::Pcrs => {
69 let (pcrs, buf) = TpmlPcrSelection::parse(buf)?;
70 Ok((Self::Pcrs(pcrs), buf))
71 }
72 TpmCap::Commands => Err(TpmErrorKind::InvalidValue),
73 }
74 }
75}
76
77#[derive(Debug, PartialEq, Eq, Clone, Copy)]
78pub enum TpmuHa {
79 Sha1([u8; 20]),
80 Sha256([u8; 32]),
81 Sha384([u8; 48]),
82 Sha512([u8; 64]),
83 Sm3_256([u8; 32]),
84}
85
86impl TpmTagged for TpmuHa {
87 type Tag = TpmAlgId;
88 type Value = ();
89}
90
91impl TpmBuild for TpmuHa {
92 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
93 writer.write_bytes(self)
94 }
95}
96
97impl TpmParseTagged for TpmuHa {
98 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
99 let digest_size = tpm_hash_size(&tag).ok_or(TpmErrorKind::InvalidValue)?;
100 if buf.len() < digest_size {
101 return Err(TpmErrorKind::Boundary);
102 }
103
104 let (digest_bytes, buf) = buf.split_at(digest_size);
105
106 let digest = match tag {
107 TpmAlgId::Sha1 => Self::Sha1(slice_to_fixed_array(digest_bytes)?),
108 TpmAlgId::Sha256 => Self::Sha256(slice_to_fixed_array(digest_bytes)?),
109 TpmAlgId::Sha384 => Self::Sha384(slice_to_fixed_array(digest_bytes)?),
110 TpmAlgId::Sha512 => Self::Sha512(slice_to_fixed_array(digest_bytes)?),
111 TpmAlgId::Sm3_256 => Self::Sm3_256(slice_to_fixed_array(digest_bytes)?),
112 _ => return Err(TpmErrorKind::InvalidValue),
113 };
114
115 Ok((digest, buf))
116 }
117}
118
119impl Default for TpmuHa {
120 fn default() -> Self {
121 Self::Sha256([0; 32])
122 }
123}
124
125impl TpmSized for TpmuHa {
126 const SIZE: usize = 64;
127 fn len(&self) -> usize {
128 match self {
129 Self::Sha1(d) => d.len(),
130 Self::Sha256(d) | Self::Sm3_256(d) => d.len(),
131 Self::Sha384(d) => d.len(),
132 Self::Sha512(d) => d.len(),
133 }
134 }
135}
136
137impl Deref for TpmuHa {
138 type Target = [u8];
139
140 fn deref(&self) -> &Self::Target {
141 match self {
142 Self::Sha1(d) => d,
143 Self::Sha256(d) | Self::Sm3_256(d) => d,
144 Self::Sha384(d) => d,
145 Self::Sha512(d) => d,
146 }
147 }
148}
149
150#[allow(clippy::large_enum_variant)]
151#[derive(Debug, PartialEq, Eq, Clone)]
152pub enum TpmuPublicId {
153 KeyedHash(Tpm2bDigest),
154 SymCipher(Tpm2bSymKey),
155 Rsa(Tpm2bPublicKeyRsa),
156 Ecc(TpmsEccPoint),
157 Null,
158}
159
160impl TpmTagged for TpmuPublicId {
161 type Tag = TpmAlgId;
162 type Value = ();
163}
164
165impl TpmSized for TpmuPublicId {
166 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
167 fn len(&self) -> usize {
168 match self {
169 Self::KeyedHash(data) => data.len(),
170 Self::SymCipher(data) => data.len(),
171 Self::Rsa(data) => data.len(),
172 Self::Ecc(point) => point.len(),
173 Self::Null => 0,
174 }
175 }
176}
177
178impl TpmBuild for TpmuPublicId {
179 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
180 match self {
181 Self::KeyedHash(data) => data.build(writer),
182 Self::SymCipher(data) => data.build(writer),
183 Self::Rsa(data) => data.build(writer),
184 Self::Ecc(point) => point.build(writer),
185 Self::Null => Ok(()),
186 }
187 }
188}
189
190impl TpmParseTagged for TpmuPublicId {
191 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
192 match tag {
193 TpmAlgId::KeyedHash => {
194 let (val, rest) = Tpm2bDigest::parse(buf)?;
195 Ok((Self::KeyedHash(val), rest))
196 }
197 TpmAlgId::SymCipher => {
198 let (val, rest) = Tpm2bSymKey::parse(buf)?;
199 Ok((Self::SymCipher(val), rest))
200 }
201 TpmAlgId::Rsa => {
202 let (val, rest) = Tpm2bPublicKeyRsa::parse(buf)?;
203 Ok((Self::Rsa(val), rest))
204 }
205 TpmAlgId::Ecc => {
206 let (point, rest) = TpmsEccPoint::parse(buf)?;
207 Ok((Self::Ecc(point), rest))
208 }
209 TpmAlgId::Null => Ok((Self::Null, buf)),
210 _ => Err(TpmErrorKind::InvalidValue),
211 }
212 }
213}
214
215impl Default for TpmuPublicId {
216 fn default() -> Self {
217 Self::Null
218 }
219}
220
221#[derive(Debug, PartialEq, Eq, Clone)]
222pub enum TpmuPublicParms {
223 KeyedHash {
224 details: TpmsKeyedhashParms,
225 },
226 SymCipher {
227 details: TpmsSymcipherParms,
228 },
229 Rsa {
230 symmetric: crate::data::TpmtSymDefObject,
231 scheme: crate::data::TpmtScheme,
232 key_bits: u16,
233 exponent: u32,
234 },
235 Ecc {
236 symmetric: crate::data::TpmtSymDefObject,
237 scheme: crate::data::TpmtScheme,
238 curve_id: TpmEccCurve,
239 kdf: TpmtKdfScheme,
240 },
241 Null,
242}
243
244impl TpmTagged for TpmuPublicParms {
245 type Tag = TpmAlgId;
246 type Value = ();
247}
248
249impl TpmSized for TpmuPublicParms {
250 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
251 fn len(&self) -> usize {
252 match self {
253 Self::KeyedHash { details } => details.len(),
254 Self::SymCipher { details } => details.len(),
255 Self::Rsa {
256 symmetric,
257 scheme,
258 key_bits,
259 exponent,
260 } => symmetric.len() + scheme.len() + key_bits.len() + exponent.len(),
261 Self::Ecc {
262 symmetric,
263 scheme,
264 curve_id,
265 kdf,
266 } => symmetric.len() + scheme.len() + curve_id.len() + kdf.len(),
267 Self::Null => 0,
268 }
269 }
270}
271
272impl TpmBuild for TpmuPublicParms {
273 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
274 match self {
275 Self::KeyedHash { details } => details.build(writer),
276 Self::SymCipher { details } => details.build(writer),
277 Self::Rsa {
278 symmetric,
279 scheme,
280 key_bits,
281 exponent,
282 } => {
283 symmetric.build(writer)?;
284 scheme.build(writer)?;
285 key_bits.build(writer)?;
286 exponent.build(writer)
287 }
288 Self::Ecc {
289 symmetric,
290 scheme,
291 curve_id,
292 kdf,
293 } => {
294 symmetric.build(writer)?;
295 scheme.build(writer)?;
296 (*curve_id as u16).build(writer)?;
297 kdf.build(writer)
298 }
299 Self::Null => Ok(()),
300 }
301 }
302}
303
304impl TpmParseTagged for TpmuPublicParms {
305 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
306 match tag {
307 TpmAlgId::KeyedHash => {
308 let (details, buf) = TpmsKeyedhashParms::parse(buf)?;
309 Ok((Self::KeyedHash { details }, buf))
310 }
311 TpmAlgId::SymCipher => {
312 let (details, buf) = TpmsSymcipherParms::parse(buf)?;
313 Ok((Self::SymCipher { details }, buf))
314 }
315 TpmAlgId::Rsa => {
316 let (symmetric, buf) = crate::data::TpmtSymDefObject::parse(buf)?;
317 let (scheme, buf) = crate::data::TpmtScheme::parse(buf)?;
318 let (key_bits, buf) = u16::parse(buf)?;
319 let (exponent, buf) = u32::parse(buf)?;
320 Ok((
321 Self::Rsa {
322 symmetric,
323 scheme,
324 key_bits,
325 exponent,
326 },
327 buf,
328 ))
329 }
330 TpmAlgId::Ecc => {
331 let (symmetric, buf) = crate::data::TpmtSymDefObject::parse(buf)?;
332 let (scheme, buf) = crate::data::TpmtScheme::parse(buf)?;
333 let (curve_id_raw, buf) = u16::parse(buf)?;
334 let curve_id = TpmEccCurve::try_from(curve_id_raw).map_err(|()| {
335 TpmErrorKind::InvalidDiscriminant {
336 type_name: "TpmEccCurve",
337 value: u64::from(curve_id_raw),
338 }
339 })?;
340 let (kdf, buf) = TpmtKdfScheme::parse(buf)?;
341 Ok((
342 Self::Ecc {
343 symmetric,
344 scheme,
345 curve_id,
346 kdf,
347 },
348 buf,
349 ))
350 }
351 TpmAlgId::Null => Ok((Self::Null, buf)),
352 _ => Err(TpmErrorKind::InvalidValue),
353 }
354 }
355}
356
357#[allow(clippy::large_enum_variant)]
358#[derive(Debug, PartialEq, Eq, Clone)]
359pub enum TpmuSensitiveComposite {
360 Rsa(crate::data::Tpm2bPrivateKeyRsa),
361 Ecc(Tpm2bEccParameter),
362 Bits(Tpm2bSensitiveData),
363 Sym(Tpm2bSymKey),
364}
365
366impl TpmTagged for TpmuSensitiveComposite {
367 type Tag = TpmAlgId;
368 type Value = ();
369}
370
371impl Default for TpmuSensitiveComposite {
372 fn default() -> Self {
373 Self::Rsa(crate::data::Tpm2bPrivateKeyRsa::default())
374 }
375}
376
377impl TpmSized for TpmuSensitiveComposite {
378 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
379 fn len(&self) -> usize {
380 match self {
381 Self::Rsa(val) => val.len(),
382 Self::Ecc(val) => val.len(),
383 Self::Bits(val) => val.len(),
384 Self::Sym(val) => val.len(),
385 }
386 }
387}
388
389impl TpmBuild for TpmuSensitiveComposite {
390 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
391 match self {
392 Self::Rsa(val) => val.build(writer),
393 Self::Ecc(val) => val.build(writer),
394 Self::Bits(val) => val.build(writer),
395 Self::Sym(val) => val.build(writer),
396 }
397 }
398}
399
400impl TpmParseTagged for TpmuSensitiveComposite {
401 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
402 match tag {
403 TpmAlgId::Rsa => {
404 let (val, buf) = crate::data::Tpm2bPrivateKeyRsa::parse(buf)?;
405 Ok((Self::Rsa(val), buf))
406 }
407 TpmAlgId::Ecc => {
408 let (val, buf) = Tpm2bEccParameter::parse(buf)?;
409 Ok((Self::Ecc(val), buf))
410 }
411 TpmAlgId::KeyedHash => {
412 let (val, buf) = Tpm2bSensitiveData::parse(buf)?;
413 Ok((Self::Bits(val), buf))
414 }
415 TpmAlgId::SymCipher => {
416 let (val, buf) = Tpm2bSymKey::parse(buf)?;
417 Ok((Self::Sym(val), buf))
418 }
419 _ => Err(TpmErrorKind::InvalidValue),
420 }
421 }
422}
423
424#[derive(Debug, PartialEq, Eq, Clone, Copy)]
425pub enum TpmuSymKeyBits {
426 Aes(u16),
427 Sm4(u16),
428 Camellia(u16),
429 Xor(TpmAlgId),
430 Null,
431}
432
433impl TpmTagged for TpmuSymKeyBits {
434 type Tag = TpmAlgId;
435 type Value = ();
436}
437
438impl Default for TpmuSymKeyBits {
439 fn default() -> Self {
440 Self::Null
441 }
442}
443
444impl TpmSized for TpmuSymKeyBits {
445 const SIZE: usize = core::mem::size_of::<u16>();
446 fn len(&self) -> usize {
447 match self {
448 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) => val.len(),
449 Self::Xor(val) => val.len(),
450 Self::Null => 0,
451 }
452 }
453}
454
455impl TpmParseTagged for TpmuSymKeyBits {
456 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
457 match tag {
458 TpmAlgId::Aes => {
459 let (val, buf) = u16::parse(buf)?;
460 Ok((Self::Aes(val), buf))
461 }
462 TpmAlgId::Sm4 => {
463 let (val, buf) = u16::parse(buf)?;
464 Ok((Self::Sm4(val), buf))
465 }
466 TpmAlgId::Camellia => {
467 let (val, buf) = u16::parse(buf)?;
468 Ok((Self::Camellia(val), buf))
469 }
470 TpmAlgId::Xor => {
471 let (val, buf) = TpmAlgId::parse(buf)?;
472 Ok((Self::Xor(val), buf))
473 }
474 TpmAlgId::Null => Ok((Self::Null, buf)),
475 _ => Err(TpmErrorKind::InvalidValue),
476 }
477 }
478}
479
480impl TpmBuild for TpmuSymKeyBits {
481 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
482 match self {
483 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) => val.build(writer),
484 Self::Xor(val) => val.build(writer),
485 Self::Null => Ok(()),
486 }
487 }
488}
489
490#[derive(Debug, PartialEq, Eq, Clone, Copy)]
491pub enum TpmuSymMode {
492 Aes(TpmAlgId),
493 Sm4(TpmAlgId),
494 Camellia(TpmAlgId),
495 Xor(TpmAlgId),
496 Null,
497}
498
499impl TpmTagged for TpmuSymMode {
500 type Tag = TpmAlgId;
501 type Value = ();
502}
503
504impl Default for TpmuSymMode {
505 fn default() -> Self {
506 Self::Null
507 }
508}
509
510impl TpmSized for TpmuSymMode {
511 const SIZE: usize = core::mem::size_of::<u16>();
512 fn len(&self) -> usize {
513 match self {
514 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) | Self::Xor(val) => val.len(),
515 Self::Null => 0,
516 }
517 }
518}
519
520impl TpmParseTagged for TpmuSymMode {
521 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
522 match tag {
523 TpmAlgId::Aes => {
524 let (val, buf) = TpmAlgId::parse(buf)?;
525 Ok((Self::Aes(val), buf))
526 }
527 TpmAlgId::Sm4 => {
528 let (val, buf) = TpmAlgId::parse(buf)?;
529 Ok((Self::Sm4(val), buf))
530 }
531 TpmAlgId::Camellia => {
532 let (val, buf) = TpmAlgId::parse(buf)?;
533 Ok((Self::Camellia(val), buf))
534 }
535 TpmAlgId::Xor => {
536 let (val, buf) = TpmAlgId::parse(buf)?;
537 Ok((Self::Xor(val), buf))
538 }
539 TpmAlgId::Null => Ok((Self::Null, buf)),
540 _ => Err(TpmErrorKind::InvalidValue),
541 }
542 }
543}
544
545impl TpmBuild for TpmuSymMode {
546 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
547 match self {
548 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) | Self::Xor(val) => {
549 val.build(writer)
550 }
551 Self::Null => Ok(()),
552 }
553 }
554}
555
556#[derive(Debug, PartialEq, Eq, Clone)]
557pub enum TpmuSignature {
558 Rsassa(TpmsSignatureRsa),
559 Rsapss(TpmsSignatureRsa),
560 Ecdsa(TpmsSignatureEcc),
561 Ecdaa(TpmsSignatureEcc),
562 Sm2(TpmsSignatureEcc),
563 Ecschnorr(TpmsSignatureEcc),
564 Hmac(TpmtHa),
565 Null,
566}
567
568impl TpmTagged for TpmuSignature {
569 type Tag = TpmAlgId;
570 type Value = ();
571}
572
573impl TpmSized for TpmuSignature {
574 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
575 fn len(&self) -> usize {
576 match self {
577 Self::Rsassa(s) | Self::Rsapss(s) => s.len(),
578 Self::Ecdsa(s) | Self::Ecdaa(s) | Self::Sm2(s) | Self::Ecschnorr(s) => s.len(),
579 Self::Hmac(s) => s.len(),
580 Self::Null => 0,
581 }
582 }
583}
584
585impl TpmBuild for TpmuSignature {
586 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
587 match self {
588 Self::Rsassa(s) | Self::Rsapss(s) => s.build(writer),
589 Self::Ecdsa(s) | Self::Ecdaa(s) | Self::Sm2(s) | Self::Ecschnorr(s) => s.build(writer),
590 Self::Hmac(s) => s.build(writer),
591 Self::Null => Ok(()),
592 }
593 }
594}
595
596impl TpmParseTagged for TpmuSignature {
597 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
598 match tag {
599 TpmAlgId::Rsassa => {
600 let (val, buf) = TpmsSignatureRsa::parse(buf)?;
601 Ok((Self::Rsassa(val), buf))
602 }
603 TpmAlgId::Rsapss => {
604 let (val, buf) = TpmsSignatureRsa::parse(buf)?;
605 Ok((Self::Rsapss(val), buf))
606 }
607 TpmAlgId::Ecdsa => {
608 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
609 Ok((Self::Ecdsa(val), buf))
610 }
611 TpmAlgId::Ecdaa => {
612 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
613 Ok((Self::Ecdaa(val), buf))
614 }
615 TpmAlgId::Sm2 => {
616 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
617 Ok((Self::Sm2(val), buf))
618 }
619 TpmAlgId::Ecschnorr => {
620 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
621 Ok((Self::Ecschnorr(val), buf))
622 }
623 TpmAlgId::Hmac => {
624 let (val, buf) = TpmtHa::parse(buf)?;
625 Ok((Self::Hmac(val), buf))
626 }
627 TpmAlgId::Null => Ok((Self::Null, buf)),
628 _ => Err(TpmErrorKind::InvalidValue),
629 }
630 }
631}
632
633#[allow(clippy::large_enum_variant)]
634#[derive(Debug, PartialEq, Eq, Clone)]
635pub enum TpmuAttest {
636 Certify(TpmsCertifyInfo),
637 Creation(TpmsCreationInfo),
638 Quote(TpmsQuoteInfo),
639 CommandAudit(TpmsCommandAuditInfo),
640 SessionAudit(TpmsSessionAuditInfo),
641 Time(TpmsTimeAttestInfo),
642 Nv(TpmsNvCertifyInfo),
643 NvDigest(TpmsNvDigestCertifyInfo),
644}
645
646impl TpmTagged for TpmuAttest {
647 type Tag = crate::data::TpmSt;
648 type Value = ();
649}
650
651impl TpmSized for TpmuAttest {
652 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
653 fn len(&self) -> usize {
654 match self {
655 Self::Certify(i) => i.len(),
656 Self::Creation(i) => i.len(),
657 Self::Quote(i) => i.len(),
658 Self::CommandAudit(i) => i.len(),
659 Self::SessionAudit(i) => i.len(),
660 Self::Time(i) => i.len(),
661 Self::Nv(i) => i.len(),
662 Self::NvDigest(i) => i.len(),
663 }
664 }
665}
666
667impl TpmBuild for TpmuAttest {
668 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
669 match self {
670 Self::Certify(i) => i.build(writer),
671 Self::Creation(i) => i.build(writer),
672 Self::Quote(i) => i.build(writer),
673 Self::CommandAudit(i) => i.build(writer),
674 Self::SessionAudit(i) => i.build(writer),
675 Self::Time(i) => i.build(writer),
676 Self::Nv(i) => i.build(writer),
677 Self::NvDigest(i) => i.build(writer),
678 }
679 }
680}
681
682impl TpmParseTagged for TpmuAttest {
683 fn parse_tagged(tag: crate::data::TpmSt, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
684 match tag {
685 crate::data::TpmSt::AttestCertify => {
686 let (val, buf) = TpmsCertifyInfo::parse(buf)?;
687 Ok((Self::Certify(val), buf))
688 }
689 crate::data::TpmSt::AttestCreation => {
690 let (val, buf) = TpmsCreationInfo::parse(buf)?;
691 Ok((Self::Creation(val), buf))
692 }
693 crate::data::TpmSt::AttestQuote => {
694 let (val, buf) = TpmsQuoteInfo::parse(buf)?;
695 Ok((Self::Quote(val), buf))
696 }
697 crate::data::TpmSt::AttestCommandAudit => {
698 let (val, buf) = TpmsCommandAuditInfo::parse(buf)?;
699 Ok((Self::CommandAudit(val), buf))
700 }
701 crate::data::TpmSt::AttestSessionAudit => {
702 let (val, buf) = TpmsSessionAuditInfo::parse(buf)?;
703 Ok((Self::SessionAudit(val), buf))
704 }
705 crate::data::TpmSt::AttestTime => {
706 let (val, buf) = TpmsTimeAttestInfo::parse(buf)?;
707 Ok((Self::Time(val), buf))
708 }
709 crate::data::TpmSt::AttestNv => {
710 let (val, buf) = TpmsNvCertifyInfo::parse(buf)?;
711 Ok((Self::Nv(val), buf))
712 }
713 crate::data::TpmSt::AttestNvDigest => {
714 let (val, buf) = TpmsNvDigestCertifyInfo::parse(buf)?;
715 Ok((Self::NvDigest(val), buf))
716 }
717 _ => Err(TpmErrorKind::InvalidTag {
718 type_name: "TpmuAttest",
719 expected: 0,
720 got: tag as u16,
721 }),
722 }
723 }
724}