1use crate::{
6 data::{
7 Tpm2bDigest, Tpm2bEccParameter, Tpm2bPublicKeyRsa, Tpm2bSensitiveData, Tpm2bSymKey,
8 TpmAlgId, TpmCap, TpmHt, TpmlAlgProperty, TpmlHandle, TpmlPcrSelection, TpmsCertifyInfo,
9 TpmsCommandAuditInfo, TpmsCreationInfo, TpmsEccParms, TpmsEccPoint, TpmsKeyedhashParms,
10 TpmsNvCertifyInfo, TpmsNvDigestCertifyInfo, TpmsNvPublic, TpmsNvPublicExpAttr,
11 TpmsQuoteInfo, TpmsRsaParms, TpmsSchemeHash, TpmsSchemeXor, TpmsSessionAuditInfo,
12 TpmsSignatureEcc, TpmsSignatureRsa, TpmsSymcipherParms, TpmsTimeAttestInfo, TpmtHa,
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::Unreachable)
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, Copy)]
222pub enum TpmuPublicParms {
223 KeyedHash(TpmsKeyedhashParms),
224 SymCipher(TpmsSymcipherParms),
225 Rsa(TpmsRsaParms),
226 Ecc(TpmsEccParms),
227 Null,
228}
229
230impl TpmTagged for TpmuPublicParms {
231 type Tag = TpmAlgId;
232 type Value = ();
233}
234
235impl TpmSized for TpmuPublicParms {
236 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
237 fn len(&self) -> usize {
238 match self {
239 Self::KeyedHash(d) => d.len(),
240 Self::SymCipher(d) => d.len(),
241 Self::Rsa(d) => d.len(),
242 Self::Ecc(d) => d.len(),
243 Self::Null => 0,
244 }
245 }
246}
247
248impl TpmBuild for TpmuPublicParms {
249 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
250 match self {
251 Self::KeyedHash(d) => d.build(writer),
252 Self::SymCipher(d) => d.build(writer),
253 Self::Rsa(d) => d.build(writer),
254 Self::Ecc(d) => d.build(writer),
255 Self::Null => Ok(()),
256 }
257 }
258}
259
260impl TpmParseTagged for TpmuPublicParms {
261 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
262 match tag {
263 TpmAlgId::KeyedHash => {
264 let (details, buf) = TpmsKeyedhashParms::parse(buf)?;
265 Ok((Self::KeyedHash(details), buf))
266 }
267 TpmAlgId::SymCipher => {
268 let (details, buf) = TpmsSymcipherParms::parse(buf)?;
269 Ok((Self::SymCipher(details), buf))
270 }
271 TpmAlgId::Rsa => {
272 let (details, buf) = TpmsRsaParms::parse(buf)?;
273 Ok((Self::Rsa(details), buf))
274 }
275 TpmAlgId::Ecc => {
276 let (details, buf) = TpmsEccParms::parse(buf)?;
277 Ok((Self::Ecc(details), buf))
278 }
279 TpmAlgId::Null => Ok((Self::Null, buf)),
280 _ => Err(TpmErrorKind::InvalidValue),
281 }
282 }
283}
284
285#[allow(clippy::large_enum_variant)]
286#[derive(Debug, PartialEq, Eq, Clone)]
287pub enum TpmuSensitiveComposite {
288 Rsa(crate::data::Tpm2bSensitiveData),
289 Ecc(Tpm2bEccParameter),
290 Bits(Tpm2bSensitiveData),
291 Sym(Tpm2bSymKey),
292}
293
294impl TpmTagged for TpmuSensitiveComposite {
295 type Tag = TpmAlgId;
296 type Value = ();
297}
298
299impl Default for TpmuSensitiveComposite {
300 fn default() -> Self {
301 Self::Rsa(crate::data::Tpm2bSensitiveData::default())
302 }
303}
304
305impl TpmSized for TpmuSensitiveComposite {
306 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
307 fn len(&self) -> usize {
308 match self {
309 Self::Ecc(val) => val.len(),
310 Self::Sym(val) => val.len(),
311 Self::Rsa(val) | Self::Bits(val) => val.len(),
312 }
313 }
314}
315
316impl TpmBuild for TpmuSensitiveComposite {
317 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
318 match self {
319 Self::Ecc(val) => val.build(writer),
320 Self::Sym(val) => val.build(writer),
321 Self::Rsa(val) | Self::Bits(val) => val.build(writer),
322 }
323 }
324}
325
326impl TpmParseTagged for TpmuSensitiveComposite {
327 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
328 match tag {
329 TpmAlgId::Rsa => {
330 let (val, buf) = crate::data::Tpm2bPrivateKeyRsa::parse(buf)?;
331 Ok((Self::Rsa(val), buf))
332 }
333 TpmAlgId::Ecc => {
334 let (val, buf) = Tpm2bEccParameter::parse(buf)?;
335 Ok((Self::Ecc(val), buf))
336 }
337 TpmAlgId::KeyedHash => {
338 let (val, buf) = Tpm2bSensitiveData::parse(buf)?;
339 Ok((Self::Bits(val), buf))
340 }
341 TpmAlgId::SymCipher => {
342 let (val, buf) = Tpm2bSymKey::parse(buf)?;
343 Ok((Self::Sym(val), buf))
344 }
345 _ => Err(TpmErrorKind::InvalidValue),
346 }
347 }
348}
349
350#[derive(Debug, PartialEq, Eq, Clone, Copy)]
351pub enum TpmuSymKeyBits {
352 Aes(u16),
353 Sm4(u16),
354 Camellia(u16),
355 Xor(TpmAlgId),
356 Null,
357}
358
359impl TpmTagged for TpmuSymKeyBits {
360 type Tag = TpmAlgId;
361 type Value = ();
362}
363
364impl Default for TpmuSymKeyBits {
365 fn default() -> Self {
366 Self::Null
367 }
368}
369
370impl TpmSized for TpmuSymKeyBits {
371 const SIZE: usize = core::mem::size_of::<u16>();
372 fn len(&self) -> usize {
373 match self {
374 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) => val.len(),
375 Self::Xor(val) => val.len(),
376 Self::Null => 0,
377 }
378 }
379}
380
381impl TpmParseTagged for TpmuSymKeyBits {
382 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
383 match tag {
384 TpmAlgId::Aes => {
385 let (val, buf) = u16::parse(buf)?;
386 Ok((Self::Aes(val), buf))
387 }
388 TpmAlgId::Sm4 => {
389 let (val, buf) = u16::parse(buf)?;
390 Ok((Self::Sm4(val), buf))
391 }
392 TpmAlgId::Camellia => {
393 let (val, buf) = u16::parse(buf)?;
394 Ok((Self::Camellia(val), buf))
395 }
396 TpmAlgId::Xor => {
397 let (val, buf) = TpmAlgId::parse(buf)?;
398 Ok((Self::Xor(val), buf))
399 }
400 TpmAlgId::Null => Ok((Self::Null, buf)),
401 _ => Err(TpmErrorKind::InvalidValue),
402 }
403 }
404}
405
406impl TpmBuild for TpmuSymKeyBits {
407 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
408 match self {
409 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) => val.build(writer),
410 Self::Xor(val) => val.build(writer),
411 Self::Null => Ok(()),
412 }
413 }
414}
415
416#[derive(Debug, PartialEq, Eq, Clone, Copy)]
417pub enum TpmuSymMode {
418 Aes(TpmAlgId),
419 Sm4(TpmAlgId),
420 Camellia(TpmAlgId),
421 Xor(TpmAlgId),
422 Null,
423}
424
425impl TpmTagged for TpmuSymMode {
426 type Tag = TpmAlgId;
427 type Value = ();
428}
429
430impl Default for TpmuSymMode {
431 fn default() -> Self {
432 Self::Null
433 }
434}
435
436impl TpmSized for TpmuSymMode {
437 const SIZE: usize = core::mem::size_of::<u16>();
438 fn len(&self) -> usize {
439 match self {
440 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) | Self::Xor(val) => val.len(),
441 Self::Null => 0,
442 }
443 }
444}
445
446impl TpmParseTagged for TpmuSymMode {
447 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
448 match tag {
449 TpmAlgId::Aes => {
450 let (val, buf) = TpmAlgId::parse(buf)?;
451 Ok((Self::Aes(val), buf))
452 }
453 TpmAlgId::Sm4 => {
454 let (val, buf) = TpmAlgId::parse(buf)?;
455 Ok((Self::Sm4(val), buf))
456 }
457 TpmAlgId::Camellia => {
458 let (val, buf) = TpmAlgId::parse(buf)?;
459 Ok((Self::Camellia(val), buf))
460 }
461 TpmAlgId::Xor => {
462 let (val, buf) = TpmAlgId::parse(buf)?;
463 Ok((Self::Xor(val), buf))
464 }
465 TpmAlgId::Null => Ok((Self::Null, buf)),
466 _ => Err(TpmErrorKind::InvalidValue),
467 }
468 }
469}
470
471impl TpmBuild for TpmuSymMode {
472 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
473 match self {
474 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) | Self::Xor(val) => {
475 val.build(writer)
476 }
477 Self::Null => Ok(()),
478 }
479 }
480}
481
482#[derive(Debug, PartialEq, Eq, Clone)]
483pub enum TpmuSignature {
484 Rsassa(TpmsSignatureRsa),
485 Rsapss(TpmsSignatureRsa),
486 Ecdsa(TpmsSignatureEcc),
487 Ecdaa(TpmsSignatureEcc),
488 Sm2(TpmsSignatureEcc),
489 Ecschnorr(TpmsSignatureEcc),
490 Hmac(TpmtHa),
491 Null,
492}
493
494impl TpmTagged for TpmuSignature {
495 type Tag = TpmAlgId;
496 type Value = ();
497}
498
499impl TpmSized for TpmuSignature {
500 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
501 fn len(&self) -> usize {
502 match self {
503 Self::Rsassa(s) | Self::Rsapss(s) => s.len(),
504 Self::Ecdsa(s) | Self::Ecdaa(s) | Self::Sm2(s) | Self::Ecschnorr(s) => s.len(),
505 Self::Hmac(s) => s.len(),
506 Self::Null => 0,
507 }
508 }
509}
510
511impl TpmBuild for TpmuSignature {
512 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
513 match self {
514 Self::Rsassa(s) | Self::Rsapss(s) => s.build(writer),
515 Self::Ecdsa(s) | Self::Ecdaa(s) | Self::Sm2(s) | Self::Ecschnorr(s) => s.build(writer),
516 Self::Hmac(s) => s.build(writer),
517 Self::Null => Ok(()),
518 }
519 }
520}
521
522impl TpmParseTagged for TpmuSignature {
523 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
524 match tag {
525 TpmAlgId::Rsassa => {
526 let (val, buf) = TpmsSignatureRsa::parse(buf)?;
527 Ok((Self::Rsassa(val), buf))
528 }
529 TpmAlgId::Rsapss => {
530 let (val, buf) = TpmsSignatureRsa::parse(buf)?;
531 Ok((Self::Rsapss(val), buf))
532 }
533 TpmAlgId::Ecdsa => {
534 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
535 Ok((Self::Ecdsa(val), buf))
536 }
537 TpmAlgId::Ecdaa => {
538 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
539 Ok((Self::Ecdaa(val), buf))
540 }
541 TpmAlgId::Sm2 => {
542 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
543 Ok((Self::Sm2(val), buf))
544 }
545 TpmAlgId::Ecschnorr => {
546 let (val, buf) = TpmsSignatureEcc::parse(buf)?;
547 Ok((Self::Ecschnorr(val), buf))
548 }
549 TpmAlgId::Hmac => {
550 let (val, buf) = TpmtHa::parse(buf)?;
551 Ok((Self::Hmac(val), buf))
552 }
553 TpmAlgId::Null => Ok((Self::Null, buf)),
554 _ => Err(TpmErrorKind::InvalidValue),
555 }
556 }
557}
558
559#[allow(clippy::large_enum_variant)]
560#[derive(Debug, PartialEq, Eq, Clone)]
561pub enum TpmuAttest {
562 Certify(TpmsCertifyInfo),
563 Creation(TpmsCreationInfo),
564 Quote(TpmsQuoteInfo),
565 CommandAudit(TpmsCommandAuditInfo),
566 SessionAudit(TpmsSessionAuditInfo),
567 Time(TpmsTimeAttestInfo),
568 Nv(TpmsNvCertifyInfo),
569 NvDigest(TpmsNvDigestCertifyInfo),
570}
571
572impl TpmTagged for TpmuAttest {
573 type Tag = crate::data::TpmSt;
574 type Value = ();
575}
576
577impl TpmSized for TpmuAttest {
578 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
579 fn len(&self) -> usize {
580 match self {
581 Self::Certify(i) => i.len(),
582 Self::Creation(i) => i.len(),
583 Self::Quote(i) => i.len(),
584 Self::CommandAudit(i) => i.len(),
585 Self::SessionAudit(i) => i.len(),
586 Self::Time(i) => i.len(),
587 Self::Nv(i) => i.len(),
588 Self::NvDigest(i) => i.len(),
589 }
590 }
591}
592
593impl TpmBuild for TpmuAttest {
594 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
595 match self {
596 Self::Certify(i) => i.build(writer),
597 Self::Creation(i) => i.build(writer),
598 Self::Quote(i) => i.build(writer),
599 Self::CommandAudit(i) => i.build(writer),
600 Self::SessionAudit(i) => i.build(writer),
601 Self::Time(i) => i.build(writer),
602 Self::Nv(i) => i.build(writer),
603 Self::NvDigest(i) => i.build(writer),
604 }
605 }
606}
607
608impl TpmParseTagged for TpmuAttest {
609 fn parse_tagged(tag: crate::data::TpmSt, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
610 match tag {
611 crate::data::TpmSt::AttestCertify => {
612 let (val, buf) = TpmsCertifyInfo::parse(buf)?;
613 Ok((Self::Certify(val), buf))
614 }
615 crate::data::TpmSt::AttestCreation => {
616 let (val, buf) = TpmsCreationInfo::parse(buf)?;
617 Ok((Self::Creation(val), buf))
618 }
619 crate::data::TpmSt::AttestQuote => {
620 let (val, buf) = TpmsQuoteInfo::parse(buf)?;
621 Ok((Self::Quote(val), buf))
622 }
623 crate::data::TpmSt::AttestCommandAudit => {
624 let (val, buf) = TpmsCommandAuditInfo::parse(buf)?;
625 Ok((Self::CommandAudit(val), buf))
626 }
627 crate::data::TpmSt::AttestSessionAudit => {
628 let (val, buf) = TpmsSessionAuditInfo::parse(buf)?;
629 Ok((Self::SessionAudit(val), buf))
630 }
631 crate::data::TpmSt::AttestTime => {
632 let (val, buf) = TpmsTimeAttestInfo::parse(buf)?;
633 Ok((Self::Time(val), buf))
634 }
635 crate::data::TpmSt::AttestNv => {
636 let (val, buf) = TpmsNvCertifyInfo::parse(buf)?;
637 Ok((Self::Nv(val), buf))
638 }
639 crate::data::TpmSt::AttestNvDigest => {
640 let (val, buf) = TpmsNvDigestCertifyInfo::parse(buf)?;
641 Ok((Self::NvDigest(val), buf))
642 }
643 _ => Err(TpmErrorKind::InvalidValue),
644 }
645 }
646}
647
648#[derive(Debug, PartialEq, Eq, Clone, Copy)]
649pub enum TpmuKeyedhashScheme {
650 Hmac(TpmsSchemeHash),
651 Xor(TpmsSchemeXor),
652 Null,
653}
654
655impl TpmTagged for TpmuKeyedhashScheme {
656 type Tag = TpmAlgId;
657 type Value = ();
658}
659
660impl TpmSized for TpmuKeyedhashScheme {
661 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
662 fn len(&self) -> usize {
663 match self {
664 Self::Hmac(s) => s.len(),
665 Self::Xor(s) => s.len(),
666 Self::Null => 0,
667 }
668 }
669}
670
671impl TpmBuild for TpmuKeyedhashScheme {
672 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
673 match self {
674 Self::Hmac(s) => s.build(writer),
675 Self::Xor(s) => s.build(writer),
676 Self::Null => Ok(()),
677 }
678 }
679}
680
681impl TpmParseTagged for TpmuKeyedhashScheme {
682 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
683 match tag {
684 TpmAlgId::Hmac => {
685 let (val, buf) = TpmsSchemeHash::parse(buf)?;
686 Ok((Self::Hmac(val), buf))
687 }
688 TpmAlgId::Xor => {
689 let (val, buf) = TpmsSchemeXor::parse(buf)?;
690 Ok((Self::Xor(val), buf))
691 }
692 TpmAlgId::Null => Ok((Self::Null, buf)),
693 _ => Err(TpmErrorKind::InvalidValue),
694 }
695 }
696}
697
698#[derive(Debug, PartialEq, Eq, Clone, Copy)]
699pub enum TpmuSigScheme {
700 Any(TpmsSchemeHash),
701 Null,
702}
703
704impl TpmTagged for TpmuSigScheme {
705 type Tag = TpmAlgId;
706 type Value = ();
707}
708
709impl TpmSized for TpmuSigScheme {
710 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
711 fn len(&self) -> usize {
712 match self {
713 Self::Any(s) => s.len(),
714 Self::Null => 0,
715 }
716 }
717}
718
719impl TpmBuild for TpmuSigScheme {
720 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
721 match self {
722 Self::Any(s) => s.build(writer),
723 Self::Null => Ok(()),
724 }
725 }
726}
727
728impl TpmParseTagged for TpmuSigScheme {
729 fn parse_tagged(tag: TpmAlgId, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
730 if tag == TpmAlgId::Null {
731 Ok((Self::Null, buf))
732 } else {
733 let (val, buf) = TpmsSchemeHash::parse(buf)?;
734 Ok((Self::Any(val), buf))
735 }
736 }
737}
738
739pub type TpmuAsymScheme = TpmuSigScheme;
740
741#[derive(Debug, PartialEq, Eq, Clone, Copy)]
742pub enum TpmuNvPublic2 {
743 NvIndex(TpmsNvPublic),
744 ExternalNv(TpmsNvPublicExpAttr),
745 PermanentNv(TpmsNvPublic),
746}
747
748impl TpmTagged for TpmuNvPublic2 {
749 type Tag = TpmHt;
750 type Value = ();
751}
752
753#[allow(clippy::match_same_arms)]
754impl TpmSized for TpmuNvPublic2 {
755 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
756 fn len(&self) -> usize {
757 match self {
758 Self::NvIndex(s) => s.len(),
759 Self::ExternalNv(s) => s.len(),
760 Self::PermanentNv(s) => s.len(),
761 }
762 }
763}
764
765impl TpmBuild for TpmuNvPublic2 {
766 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
767 match self {
768 Self::ExternalNv(s) => s.build(writer),
769 Self::NvIndex(s) | Self::PermanentNv(s) => s.build(writer),
770 }
771 }
772}
773
774impl TpmParseTagged for TpmuNvPublic2 {
775 fn parse_tagged(tag: TpmHt, buf: &[u8]) -> TpmResult<(Self, &[u8])> {
776 match tag {
777 TpmHt::NvIndex => {
778 let (val, buf) = TpmsNvPublic::parse(buf)?;
779 Ok((Self::NvIndex(val), buf))
780 }
781 TpmHt::ExternalNv => {
782 let (val, buf) = TpmsNvPublicExpAttr::parse(buf)?;
783 Ok((Self::ExternalNv(val), buf))
784 }
785 TpmHt::PermanentNv => {
786 let (val, buf) = TpmsNvPublic::parse(buf)?;
787 Ok((Self::PermanentNv(val), buf))
788 }
789 _ => Err(TpmErrorKind::InvalidValue),
790 }
791 }
792}