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