cli/
print.rs

1// SPDX-License-Identifier: GPL-3-0-or-later
2// Copyright (c) 2025 Opinsys Oy
3// Copyright (c) 2024-2025 Jarkko Sakkinen
4
5use std::{io::Write, vec::Vec};
6use tpm2_protocol::{
7    self,
8    basic::{TpmBuffer, TpmList},
9    data::{
10        self, Tpm2bNvPublic, Tpm2bPublic, Tpm2bSensitiveCreate, TpmAlgId, TpmCap, TpmCc,
11        TpmEccCurve, TpmPt, TpmRh, TpmSe, TpmSt, TpmaAlgorithm, TpmaCc, TpmaLocality, TpmaNv,
12        TpmaObject, TpmaSession, TpmiYesNo, TpmsAlgProperty, TpmsAuthCommand, TpmsCapabilityData,
13        TpmsContext, TpmsCreationData, TpmsEccPoint, TpmsKeyedhashParms, TpmsNvPublic,
14        TpmsPcrSelect, TpmsPcrSelection, TpmsSchemeHash, TpmsSchemeXor, TpmsSensitiveCreate,
15        TpmsSymcipherParms, TpmsTaggedProperty, TpmtEccScheme, TpmtHa, TpmtKdfScheme,
16        TpmtKeyedhashScheme, TpmtPublic, TpmtPublicParms, TpmtRsaScheme, TpmtSymDefObject,
17        TpmtTkAuth, TpmtTkCreation, TpmtTkHashcheck, TpmuAsymScheme, TpmuCapabilities, TpmuHa,
18        TpmuKeyedhashScheme, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite, TpmuSymKeyBits,
19        TpmuSymMode,
20    },
21    message::{
22        TpmCommandBody, TpmContextLoadCommand, TpmContextLoadResponse, TpmContextSaveCommand,
23        TpmContextSaveResponse, TpmCreateCommand, TpmCreatePrimaryCommand,
24        TpmCreatePrimaryResponse, TpmCreateResponse, TpmDictionaryAttackLockResetCommand,
25        TpmDictionaryAttackLockResetResponse, TpmEccParametersCommand, TpmEvictControlCommand,
26        TpmEvictControlResponse, TpmFlushContextCommand, TpmFlushContextResponse,
27        TpmGetCapabilityCommand, TpmGetCapabilityResponse, TpmImportCommand, TpmImportResponse,
28        TpmLoadCommand, TpmLoadResponse, TpmNvReadCommand, TpmNvReadPublicCommand,
29        TpmNvReadPublicResponse, TpmNvReadResponse, TpmPcrEventCommand, TpmPcrEventResponse,
30        TpmPcrReadCommand, TpmPcrReadResponse, TpmPolicyGetDigestCommand,
31        TpmPolicyGetDigestResponse, TpmPolicyOrCommand, TpmPolicyPcrCommand, TpmPolicyPcrResponse,
32        TpmPolicyRestartCommand, TpmPolicyRestartResponse, TpmPolicySecretCommand,
33        TpmPolicySecretResponse, TpmReadPublicCommand, TpmReadPublicResponse, TpmResponseBody,
34        TpmStartAuthSessionCommand, TpmStartAuthSessionResponse, TpmTestParmsCommand,
35        TpmUnsealCommand, TpmUnsealResponse,
36    },
37    TpmHandle,
38};
39
40pub const INDENT: usize = 2;
41
42pub trait TpmPrint {
43    /// # Errors
44    ///
45    /// Returns `std::io::Error` on I/O failure.
46    fn print(
47        &self,
48        writer: &mut dyn Write,
49        name: &str,
50        indent: usize,
51    ) -> Result<(), std::io::Error>;
52}
53
54macro_rules! tpm_print_simple {
55    ($type:ty, $format:literal) => {
56        impl TpmPrint for $type {
57            fn print(
58                &self,
59                writer: &mut dyn Write,
60                name: &str,
61                indent: usize,
62            ) -> Result<(), std::io::Error> {
63                let prefix = " ".repeat(indent * INDENT);
64                writeln!(
65                    writer,
66                    "{prefix}{name}: {value}",
67                    prefix = prefix,
68                    name = name,
69                    value = format_args!($format, self)
70                )
71            }
72        }
73    };
74}
75
76macro_rules! tpm_print_bitflags {
77    ($type:ty) => {
78        impl TpmPrint for $type {
79            fn print(
80                &self,
81                writer: &mut dyn Write,
82                name: &str,
83                indent: usize,
84            ) -> Result<(), std::io::Error> {
85                let prefix = " ".repeat(indent * INDENT);
86                let flags: Vec<&str> = self.flag_names().collect();
87                let flags_str = if flags.is_empty() {
88                    "NONE".to_string()
89                } else {
90                    flags.join(" | ")
91                };
92                writeln!(
93                    writer,
94                    "{prefix}{name}: {flags_str} ({value:#x})",
95                    name = name,
96                    prefix = prefix,
97                    flags_str = flags_str,
98                    value = self.bits()
99                )
100            }
101        }
102    };
103}
104
105tpm_print_simple!(u8, "{:02x}");
106tpm_print_simple!(u16, "{:04x}");
107tpm_print_simple!(u32, "{:08x}");
108tpm_print_simple!(u64, "{:16x}");
109tpm_print_simple!(i32, "{}");
110tpm_print_simple!(TpmHandle, "{:08x}");
111tpm_print_simple!(TpmAlgId, "{}");
112tpm_print_simple!(TpmCc, "{}");
113tpm_print_simple!(TpmPt, "{}");
114tpm_print_simple!(TpmRh, "{}");
115tpm_print_simple!(TpmCap, "{}");
116tpm_print_simple!(TpmSe, "{:?}");
117tpm_print_simple!(TpmSt, "{:?}");
118tpm_print_simple!(TpmEccCurve, "{:?}");
119tpm_print_simple!(TpmiYesNo, "{:?}");
120
121tpm_print_bitflags!(TpmaObject);
122tpm_print_bitflags!(TpmaAlgorithm);
123tpm_print_bitflags!(TpmaSession);
124tpm_print_bitflags!(TpmaLocality);
125tpm_print_bitflags!(TpmaNv);
126tpm_print_bitflags!(TpmaCc);
127
128impl<const CAPACITY: usize> TpmPrint for TpmBuffer<CAPACITY> {
129    fn print(
130        &self,
131        writer: &mut dyn Write,
132        name: &str,
133        indent: usize,
134    ) -> Result<(), std::io::Error> {
135        let prefix = " ".repeat(indent * INDENT);
136        writeln!(
137            writer,
138            "{}{}: (size={}) {}",
139            prefix,
140            name,
141            self.len(),
142            hex::encode(self)
143        )
144    }
145}
146
147impl TpmPrint for TpmsPcrSelect {
148    fn print(
149        &self,
150        writer: &mut dyn Write,
151        name: &str,
152        indent: usize,
153    ) -> Result<(), std::io::Error> {
154        let prefix = " ".repeat(indent * INDENT);
155        writeln!(
156            writer,
157            "{}{}: (size={}) {}",
158            prefix,
159            name,
160            self.len(),
161            hex::encode(self.as_ref())
162        )
163    }
164}
165
166impl<T, const CAPACITY: usize> TpmPrint for TpmList<T, CAPACITY>
167where
168    T: TpmPrint + Copy,
169{
170    fn print(
171        &self,
172        writer: &mut dyn Write,
173        name: &str,
174        indent: usize,
175    ) -> Result<(), std::io::Error> {
176        let prefix = " ".repeat(indent * INDENT);
177        writeln!(writer, "{}{}: (count={})", prefix, name, self.len())?;
178        for item in self.iter() {
179            item.print(writer, "", indent + 1)?;
180        }
181        Ok(())
182    }
183}
184
185macro_rules! tpm_print_struct {
186    ($type:ty, $($field:ident => $name:literal),* $(,)?) => {
187        impl TpmPrint for $type {
188            fn print(
189                &self,
190                writer: &mut dyn Write,
191                name: &str,
192                indent: usize,
193            ) -> Result<(), std::io::Error> {
194                let prefix = " ".repeat(indent * INDENT);
195                if !name.is_empty() {
196                    writeln!(writer, "{}{}:", prefix, name)?;
197                } else if stringify!($($field),*).is_empty() {
198                    return Ok(());
199                }
200
201                #[allow(unused_variables)]
202                let field_indent = if name.is_empty() { indent } else { indent + 1 };
203                $(
204                    self.$field.print(writer, $name, field_indent)?;
205                )*
206                Ok(())
207            }
208        }
209    };
210}
211
212tpm_print_struct!(TpmsAlgProperty, alg => "alg", alg_properties => "algProperties");
213tpm_print_struct!(TpmsTaggedProperty, property => "property", value => "value");
214tpm_print_struct!(TpmsPcrSelection, hash => "hash", pcr_select => "pcrSelect");
215tpm_print_struct!(TpmsKeyedhashParms, scheme => "scheme");
216tpm_print_struct!(TpmsSymcipherParms, sym => "sym");
217tpm_print_struct!(TpmtKdfScheme, scheme => "scheme");
218tpm_print_struct!(TpmsEccPoint, x => "x", y => "y");
219tpm_print_struct!(TpmsContext, sequence => "sequence", saved_handle => "savedHandle", hierarchy => "hierarchy", context_blob => "contextBlob");
220tpm_print_struct!(TpmsAuthCommand, session_handle => "sessionHandle", nonce => "nonce", session_attributes => "sessionAttributes", hmac => "hmac");
221tpm_print_struct!(TpmsSensitiveCreate, user_auth => "userAuth", data => "data");
222tpm_print_struct!(TpmtTkCreation, tag => "tag", hierarchy => "hierarchy", digest => "digest");
223tpm_print_struct!(TpmtTkAuth, tag => "tag", hierarchy => "hierarchy", digest => "digest");
224tpm_print_struct!(TpmtTkHashcheck, tag => "tag", hierarchy => "hierarchy", digest => "digest");
225tpm_print_struct!(TpmsSchemeHash, hash_alg => "hashAlg");
226tpm_print_struct!(TpmsSchemeXor, hash_alg => "hashAlg", kdf => "kdf");
227tpm_print_struct!(TpmtRsaScheme, scheme => "scheme", details => "details");
228tpm_print_struct!(TpmtEccScheme, scheme => "scheme", details => "details");
229tpm_print_struct!(
230    TpmsCreationData,
231    pcr_select => "pcrSelect",
232    pcr_digest => "pcrDigest",
233    locality => "locality",
234    parent_name_alg => "parentNameAlg",
235    parent_name => "parentName",
236    parent_qualified_name => "parentQualifiedName",
237    outside_info => "outsideInfo",
238);
239tpm_print_struct!(Tpm2bPublic, inner => "inner");
240tpm_print_struct!(Tpm2bSensitiveCreate, inner => "inner");
241tpm_print_struct!(data::Tpm2bCreationData, inner => "inner");
242tpm_print_struct!(TpmsNvPublic, nv_index => "nvIndex", name_alg => "nameAlg", attributes => "attributes", auth_policy => "authPolicy", data_size => "dataSize");
243tpm_print_struct!(Tpm2bNvPublic, inner => "inner");
244
245tpm_print_struct!(TpmCreatePrimaryCommand, primary_handle => "primaryHandle", in_sensitive => "inSensitive", in_public => "inPublic", outside_info => "outsideInfo", creation_pcr => "creationPcr");
246tpm_print_struct!(TpmContextSaveCommand, save_handle => "saveHandle");
247tpm_print_struct!(TpmEvictControlCommand, auth => "auth", object_handle => "objectHandle", persistent_handle => "persistentHandle");
248tpm_print_struct!(TpmFlushContextCommand, flush_handle => "flushHandle");
249tpm_print_struct!(TpmReadPublicCommand, object_handle => "objectHandle");
250tpm_print_struct!(TpmImportCommand, parent_handle => "parentHandle", encryption_key => "encryptionKey", object_public => "objectPublic", duplicate => "duplicate", in_sym_seed => "inSymSeed", symmetric_alg => "symmetricAlg");
251tpm_print_struct!(TpmLoadCommand, parent_handle => "parentHandle", in_private => "inPrivate", in_public => "inPublic");
252tpm_print_struct!(TpmNvReadPublicCommand, nv_index => "nvIndex");
253tpm_print_struct!(TpmNvReadCommand, auth_handle => "authHandle", nv_index => "nvIndex", size => "size", offset => "offset");
254tpm_print_struct!(TpmPcrEventCommand, pcr_handle => "pcrHandle", event_data => "eventData");
255tpm_print_struct!(TpmPcrReadCommand, pcr_selection_in => "pcrSelectionIn");
256tpm_print_struct!(TpmPolicyPcrCommand, policy_session => "policySession", pcr_digest => "pcrDigest", pcrs => "pcrs");
257tpm_print_struct!(TpmPolicySecretCommand, auth_handle => "authHandle", policy_session => "policySession", nonce_tpm => "nonceTpm", cp_hash_a => "cpHashA", policy_ref => "policyRef", expiration => "expiration");
258tpm_print_struct!(TpmPolicyOrCommand, policy_session => "policySession", p_hash_list => "pHashList");
259tpm_print_struct!(TpmPolicyGetDigestCommand, policy_session => "policySession");
260tpm_print_struct!(TpmPolicyRestartCommand, session_handle => "sessionHandle");
261tpm_print_struct!(TpmDictionaryAttackLockResetCommand, lock_handle => "lockHandle");
262tpm_print_struct!(TpmCreateCommand, parent_handle => "parentHandle", in_sensitive => "inSensitive", in_public => "inPublic", outside_info => "outsideInfo", creation_pcr => "creationPcr");
263tpm_print_struct!(TpmUnsealCommand, item_handle => "itemHandle");
264tpm_print_struct!(TpmGetCapabilityCommand, cap => "cap", property => "property", property_count => "propertyCount");
265tpm_print_struct!(TpmStartAuthSessionCommand, tpm_key => "tpmKey", bind => "bind", nonce_caller => "nonceCaller", encrypted_salt => "encryptedSalt", session_type => "sessionType", symmetric => "symmetric", auth_hash => "authHash");
266tpm_print_struct!(TpmContextLoadCommand, context => "context");
267tpm_print_struct!(TpmTestParmsCommand, parameters => "parameters");
268tpm_print_struct!(TpmEccParametersCommand, curve_id => "curveId");
269
270tpm_print_struct!(TpmCreatePrimaryResponse, object_handle => "objectHandle", out_public => "outPublic", creation_data => "creationData", creation_hash => "creationHash", creation_ticket => "creationTicket", name => "name");
271tpm_print_struct!(TpmContextSaveResponse, context => "context");
272tpm_print_struct!(TpmEvictControlResponse,);
273tpm_print_struct!(TpmFlushContextResponse,);
274tpm_print_struct!(TpmReadPublicResponse, out_public => "outPublic", name => "name", qualified_name => "qualifiedName");
275tpm_print_struct!(TpmImportResponse, out_private => "outPrivate");
276tpm_print_struct!(TpmLoadResponse, object_handle => "objectHandle", name => "name");
277tpm_print_struct!(TpmNvReadPublicResponse, nv_public => "nvPublic", nv_name => "nvName");
278tpm_print_struct!(TpmNvReadResponse, data => "data");
279tpm_print_struct!(TpmPcrEventResponse, digests => "digests");
280tpm_print_struct!(TpmPolicyPcrResponse,);
281tpm_print_struct!(TpmPolicySecretResponse, timeout => "timeout", policy_ticket => "policyTicket");
282tpm_print_struct!(TpmPolicyGetDigestResponse, policy_digest => "policyDigest");
283tpm_print_struct!(TpmPolicyRestartResponse,);
284tpm_print_struct!(TpmDictionaryAttackLockResetResponse,);
285tpm_print_struct!(TpmCreateResponse, out_private => "outPrivate", out_public => "outPublic", creation_data => "creationData", creation_hash => "creationHash", creation_ticket => "creationTicket");
286tpm_print_struct!(TpmUnsealResponse, out_data => "outData");
287tpm_print_struct!(TpmGetCapabilityResponse, more_data => "moreData", capability_data => "capabilityData");
288tpm_print_struct!(TpmPcrReadResponse, pcr_update_counter => "pcrUpdateCounter", pcr_selection_out => "pcrSelectionOut", pcr_values => "pcrValues");
289tpm_print_struct!(TpmStartAuthSessionResponse, session_handle => "sessionHandle", nonce_tpm => "nonceTpm");
290tpm_print_struct!(TpmContextLoadResponse, loaded_handle => "loadedHandle");
291
292impl TpmPrint for TpmuHa {
293    fn print(
294        &self,
295        writer: &mut dyn Write,
296        name: &str,
297        indent: usize,
298    ) -> Result<(), std::io::Error> {
299        let prefix = " ".repeat(indent * INDENT);
300        let (variant, bytes): (&str, &[u8]) = match self {
301            Self::Null => ("Null", &[]),
302            Self::Digest(d) => ("Digest", d),
303        };
304        writeln!(
305            writer,
306            "{}{}: (size={}) {} ({})",
307            prefix,
308            name,
309            bytes.len(),
310            hex::encode(bytes),
311            variant,
312        )
313    }
314}
315
316impl TpmPrint for TpmtHa {
317    fn print(
318        &self,
319        writer: &mut dyn Write,
320        name: &str,
321        indent: usize,
322    ) -> Result<(), std::io::Error> {
323        let prefix = " ".repeat(indent * INDENT);
324        writeln!(writer, "{prefix}{name}:")?;
325        self.hash_alg.print(writer, "hashAlg", indent + 1)?;
326        self.digest.print(writer, "digest", indent + 1)?;
327        Ok(())
328    }
329}
330
331impl TpmPrint for TpmsCapabilityData {
332    fn print(
333        &self,
334        writer: &mut dyn Write,
335        name: &str,
336        indent: usize,
337    ) -> Result<(), std::io::Error> {
338        let prefix = " ".repeat(indent * INDENT);
339        writeln!(writer, "{prefix}{name}:")?;
340        self.capability.print(writer, "capability", indent + 1)?;
341        self.data.print(writer, "data", indent + 1)?;
342        Ok(())
343    }
344}
345
346impl TpmPrint for TpmuCapabilities {
347    fn print(
348        &self,
349        writer: &mut dyn Write,
350        name: &str,
351        indent: usize,
352    ) -> Result<(), std::io::Error> {
353        match self {
354            Self::Algs(algs) => algs.print(writer, name, indent),
355            Self::Handles(handles) => handles.print(writer, name, indent),
356            Self::Commands(commands) => commands.print(writer, name, indent),
357            Self::Pcrs(pcrs) => pcrs.print(writer, name, indent),
358            Self::EccCurves(curves) => curves.print(writer, name, indent),
359            Self::TpmProperties(props) => props.print(writer, name, indent),
360        }
361    }
362}
363
364impl TpmPrint for TpmtPublic {
365    fn print(
366        &self,
367        writer: &mut dyn Write,
368        name: &str,
369        indent: usize,
370    ) -> Result<(), std::io::Error> {
371        let prefix = " ".repeat(indent * INDENT);
372        writeln!(writer, "{prefix}{name}:")?;
373        self.object_type.print(writer, "type", indent + 1)?;
374        self.name_alg.print(writer, "nameAlg", indent + 1)?;
375        self.object_attributes
376            .print(writer, "objectAttributes", indent + 1)?;
377        self.auth_policy.print(writer, "authPolicy", indent + 1)?;
378        self.parameters.print(writer, "parameters", indent + 1)?;
379        self.unique.print(writer, "unique", indent + 1)?;
380        Ok(())
381    }
382}
383
384impl TpmPrint for TpmuPublicId {
385    fn print(
386        &self,
387        writer: &mut dyn Write,
388        name: &str,
389        indent: usize,
390    ) -> Result<(), std::io::Error> {
391        let prefix = " ".repeat(indent * INDENT);
392        match self {
393            Self::KeyedHash(b) => b.print(writer, &format!("{name} (keyedHash)"), indent),
394            Self::SymCipher(b) => b.print(writer, &format!("{name} (sym)"), indent),
395            Self::Rsa(b) => b.print(writer, &format!("{name} (rsa)"), indent),
396            Self::Ecc(p) => p.print(writer, &format!("{name} (ecc)"), indent),
397            Self::Null => writeln!(writer, "{prefix}{name}: null"),
398        }
399    }
400}
401
402impl TpmPrint for TpmtPublicParms {
403    fn print(
404        &self,
405        writer: &mut dyn Write,
406        name: &str,
407        indent: usize,
408    ) -> Result<(), std::io::Error> {
409        let prefix = " ".repeat(indent * INDENT);
410        writeln!(writer, "{prefix}{name}:")?;
411        self.object_type.print(writer, "type", indent + 1)?;
412        self.parameters.print(writer, "parameters", indent + 1)?;
413        Ok(())
414    }
415}
416
417impl TpmPrint for TpmuPublicParms {
418    fn print(
419        &self,
420        writer: &mut dyn Write,
421        name: &str,
422        indent: usize,
423    ) -> Result<(), std::io::Error> {
424        let prefix = " ".repeat(indent * INDENT);
425        match self {
426            Self::KeyedHash(details) => {
427                details.print(writer, &format!("{name} (keyedHash)"), indent)?;
428            }
429            Self::SymCipher(details) => details.print(writer, &format!("{name} (sym)"), indent)?,
430            Self::Rsa(params) => {
431                writeln!(writer, "{prefix}{name}: (rsa)")?;
432                params.symmetric.print(writer, "symmetric", indent + 1)?;
433                params.scheme.print(writer, "scheme", indent + 1)?;
434                params.key_bits.print(writer, "keyBits", indent + 1)?;
435                params.exponent.print(writer, "exponent", indent + 1)?;
436            }
437            Self::Ecc(params) => {
438                writeln!(writer, "{prefix}{name}: (ecc)")?;
439                params.symmetric.print(writer, "symmetric", indent + 1)?;
440                params.scheme.print(writer, "scheme", indent + 1)?;
441                params.curve_id.print(writer, "curveId", indent + 1)?;
442                params.kdf.print(writer, "kdf", indent + 1)?;
443            }
444            Self::Null => writeln!(writer, "{prefix}{name}: null")?,
445        }
446        Ok(())
447    }
448}
449
450impl TpmPrint for TpmtSymDefObject {
451    fn print(
452        &self,
453        writer: &mut dyn Write,
454        name: &str,
455        indent: usize,
456    ) -> Result<(), std::io::Error> {
457        if self.algorithm == TpmAlgId::Null {
458            self.algorithm.print(writer, name, indent)
459        } else {
460            let prefix = " ".repeat(indent * INDENT);
461            writeln!(writer, "{prefix}{name}:")?;
462            self.algorithm.print(writer, "algorithm", indent + 1)?;
463            self.key_bits.print(writer, "keyBits", indent + 1)?;
464            self.mode.print(writer, "mode", indent + 1)?;
465            Ok(())
466        }
467    }
468}
469
470impl TpmPrint for TpmuSymKeyBits {
471    fn print(
472        &self,
473        writer: &mut dyn Write,
474        name: &str,
475        indent: usize,
476    ) -> Result<(), std::io::Error> {
477        let prefix = " ".repeat(indent * INDENT);
478        match self {
479            Self::Aes(v) => v.print(writer, &format!("{name} (aes)"), indent),
480            Self::Sm4(v) => v.print(writer, &format!("{name} (sm4)"), indent),
481            Self::Camellia(v) => v.print(writer, &format!("{name} (camellia)"), indent),
482            Self::Xor(v) => v.print(writer, &format!("{name} (xor)"), indent),
483            Self::Null => writeln!(writer, "{prefix}{name}: null"),
484        }
485    }
486}
487
488impl TpmPrint for TpmuSymMode {
489    fn print(
490        &self,
491        writer: &mut dyn Write,
492        name: &str,
493        indent: usize,
494    ) -> Result<(), std::io::Error> {
495        let prefix = " ".repeat(indent * INDENT);
496        match self {
497            Self::Aes(v) => v.print(writer, &format!("{name} (aes)"), indent),
498            Self::Sm4(v) => v.print(writer, &format!("{name} (sm4)"), indent),
499            Self::Camellia(v) => v.print(writer, &format!("{name} (camellia)"), indent),
500            Self::Xor(v) => v.print(writer, &format!("{name} (xor)"), indent),
501            Self::Null => writeln!(writer, "{prefix}{name}: null"),
502        }
503    }
504}
505
506impl TpmPrint for TpmuAsymScheme {
507    fn print(
508        &self,
509        writer: &mut dyn Write,
510        name: &str,
511        indent: usize,
512    ) -> Result<(), std::io::Error> {
513        let prefix = " ".repeat(indent * INDENT);
514        match self {
515            Self::Any(s) => s.print(writer, &format!("{name} (any)"), indent),
516            Self::Null => writeln!(writer, "{prefix}{name}: null"),
517        }
518    }
519}
520
521impl TpmPrint for TpmuSensitiveComposite {
522    fn print(
523        &self,
524        writer: &mut dyn Write,
525        name: &str,
526        indent: usize,
527    ) -> Result<(), std::io::Error> {
528        match self {
529            Self::Rsa(b) => b.print(writer, &format!("{name} (rsa)"), indent),
530            Self::Ecc(b) => b.print(writer, &format!("{name} (ecc)"), indent),
531            Self::Bits(b) => b.print(writer, &format!("{name} (bits)"), indent),
532            Self::Sym(b) => b.print(writer, &format!("{name} (sym)"), indent),
533        }
534    }
535}
536
537impl TpmPrint for TpmtKeyedhashScheme {
538    fn print(
539        &self,
540        writer: &mut dyn Write,
541        name: &str,
542        indent: usize,
543    ) -> Result<(), std::io::Error> {
544        let prefix = " ".repeat(indent * INDENT);
545        writeln!(writer, "{prefix}{name}:")?;
546        self.scheme.print(writer, "scheme", indent + 1)?;
547        self.details.print(writer, "details", indent + 1)?;
548        Ok(())
549    }
550}
551
552impl TpmPrint for TpmuKeyedhashScheme {
553    fn print(
554        &self,
555        writer: &mut dyn Write,
556        name: &str,
557        indent: usize,
558    ) -> Result<(), std::io::Error> {
559        let prefix = " ".repeat(indent * INDENT);
560        match self {
561            Self::Hmac(s) => s.print(writer, &format!("{name} (hmac)"), indent),
562            Self::Xor(s) => s.print(writer, &format!("{name} (xor)"), indent),
563            Self::Null => writeln!(writer, "{prefix}{name}: null"),
564        }
565    }
566}
567
568impl TpmPrint for TpmCommandBody {
569    fn print(
570        &self,
571        writer: &mut dyn Write,
572        name: &str,
573        indent: usize,
574    ) -> Result<(), std::io::Error> {
575        match self {
576            Self::CreatePrimary(cmd) => cmd.print(writer, name, indent),
577            Self::ContextSave(cmd) => cmd.print(writer, name, indent),
578            Self::EvictControl(cmd) => cmd.print(writer, name, indent),
579            Self::FlushContext(cmd) => cmd.print(writer, name, indent),
580            Self::ReadPublic(cmd) => cmd.print(writer, name, indent),
581            Self::Import(cmd) => cmd.print(writer, name, indent),
582            Self::Load(cmd) => cmd.print(writer, name, indent),
583            Self::NvRead(cmd) => cmd.print(writer, name, indent),
584            Self::NvReadPublic(cmd) => cmd.print(writer, name, indent),
585            Self::PcrEvent(cmd) => cmd.print(writer, name, indent),
586            Self::PcrRead(cmd) => cmd.print(writer, name, indent),
587            Self::PolicyPcr(cmd) => cmd.print(writer, name, indent),
588            Self::PolicySecret(cmd) => cmd.print(writer, name, indent),
589            Self::PolicyOr(cmd) => cmd.print(writer, name, indent),
590            Self::PolicyGetDigest(cmd) => cmd.print(writer, name, indent),
591            Self::PolicyRestart(cmd) => cmd.print(writer, name, indent),
592            Self::DictionaryAttackLockReset(cmd) => cmd.print(writer, name, indent),
593            Self::Create(cmd) => cmd.print(writer, name, indent),
594            Self::Unseal(cmd) => cmd.print(writer, name, indent),
595            Self::GetCapability(cmd) => cmd.print(writer, name, indent),
596            Self::StartAuthSession(cmd) => cmd.print(writer, name, indent),
597            Self::ContextLoad(cmd) => cmd.print(writer, name, indent),
598            Self::TestParms(cmd) => cmd.print(writer, name, indent),
599            Self::EccParameters(cmd) => cmd.print(writer, name, indent),
600            _ => {
601                let prefix = " ".repeat(indent * INDENT);
602                writeln!(
603                    writer,
604                    "{prefix}{name}: {self:?} (unimplemented pretty trace)"
605                )
606            }
607        }
608    }
609}
610
611impl TpmPrint for TpmResponseBody {
612    fn print(
613        &self,
614        writer: &mut dyn Write,
615        name: &str,
616        indent: usize,
617    ) -> Result<(), std::io::Error> {
618        match self {
619            Self::GetCapability(resp) => resp.print(writer, name, indent),
620            Self::PcrRead(resp) => resp.print(writer, name, indent),
621            Self::StartAuthSession(resp) => resp.print(writer, name, indent),
622            Self::CreatePrimary(resp) => resp.print(writer, name, indent),
623            Self::ContextSave(resp) => resp.print(writer, name, indent),
624            Self::EvictControl(resp) => resp.print(writer, name, indent),
625            Self::FlushContext(resp) => resp.print(writer, name, indent),
626            Self::ReadPublic(resp) => resp.print(writer, name, indent),
627            Self::Import(resp) => resp.print(writer, name, indent),
628            Self::Load(resp) => resp.print(writer, name, indent),
629            Self::NvRead(resp) => resp.print(writer, name, indent),
630            Self::NvReadPublic(resp) => resp.print(writer, name, indent),
631            Self::PcrEvent(resp) => resp.print(writer, name, indent),
632            Self::PolicyPcr(resp) => resp.print(writer, name, indent),
633            Self::PolicySecret(resp) => resp.print(writer, name, indent),
634            Self::PolicyGetDigest(resp) => resp.print(writer, name, indent),
635            Self::PolicyRestart(resp) => resp.print(writer, name, indent),
636            Self::DictionaryAttackLockReset(resp) => resp.print(writer, name, indent),
637            Self::Create(resp) => resp.print(writer, name, indent),
638            Self::Unseal(resp) => resp.print(writer, name, indent),
639            Self::ContextLoad(resp) => resp.print(writer, name, indent),
640            _ => {
641                let prefix = " ".repeat(indent * INDENT);
642                writeln!(
643                    writer,
644                    "{prefix}{name}: {self:?} (unimplemented pretty trace)"
645                )
646            }
647        }
648    }
649}