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