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