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