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