tpm2_protocol/data/
tpmt.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2025 Opinsys Oy
3// Copyright (c) 2024-2025 Jarkko Sakkinen
4
5use super::{
6    Tpm2bAuth, Tpm2bDigest, TpmAlgId, TpmHt, TpmRh, TpmSt, TpmaObject, TpmuHa, TpmuKeyedhashScheme,
7    TpmuNvPublic2, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite, TpmuSigScheme,
8    TpmuSymKeyBits, TpmuSymMode,
9};
10use crate::{
11    constant::TPM_MAX_COMMAND_SIZE, tpm_struct, TpmMarshal, TpmResult, TpmSized, TpmUnmarshal,
12    TpmUnmarshalTagged, TpmWriter,
13};
14
15macro_rules! tpm_struct_tagged {
16    (
17        $(#[$outer:meta])*
18        $vis:vis struct $name:ident {
19            pub $tag_field:ident: $tag_ty:ty,
20            pub $value_field:ident: $value_ty:ty,
21        }
22    ) => {
23        $(#[$outer])*
24        $vis struct $name {
25            pub $tag_field: $tag_ty,
26            pub $value_field: $value_ty,
27        }
28
29        impl $crate::TpmSized for $name {
30            const SIZE: usize = <$tag_ty>::SIZE + <$value_ty>::SIZE;
31            fn len(&self) -> usize {
32                $crate::TpmSized::len(&self.$tag_field) + $crate::TpmSized::len(&self.$value_field)
33            }
34        }
35
36        impl $crate::TpmMarshal for $name {
37            fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
38                $crate::TpmMarshal::marshal(&self.$tag_field, writer)?;
39                $crate::TpmMarshal::marshal(&self.$value_field, writer)
40            }
41        }
42
43        impl $crate::TpmUnmarshal for $name {
44            fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
45                let ($tag_field, buf) = <$tag_ty>::unmarshal(buf)?;
46                let ($value_field, buf) =
47                    <$value_ty as $crate::TpmUnmarshalTagged>::unmarshal_tagged($tag_field, buf)?;
48                Ok((
49                    Self {
50                        $tag_field,
51                        $value_field,
52                    },
53                    buf,
54                ))
55            }
56        }
57    };
58}
59
60#[derive(Debug, PartialEq, Eq, Clone)]
61pub struct TpmtPublic {
62    pub object_type: TpmAlgId,
63    pub name_alg: TpmAlgId,
64    pub object_attributes: TpmaObject,
65    pub auth_policy: Tpm2bDigest,
66    pub parameters: TpmuPublicParms,
67    pub unique: TpmuPublicId,
68}
69
70impl TpmSized for TpmtPublic {
71    const SIZE: usize = TPM_MAX_COMMAND_SIZE as usize;
72    fn len(&self) -> usize {
73        self.object_type.len()
74            + self.name_alg.len()
75            + self.object_attributes.len()
76            + self.auth_policy.len()
77            + self.parameters.len()
78            + self.unique.len()
79    }
80}
81
82impl TpmMarshal for TpmtPublic {
83    fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
84        self.object_type.marshal(writer)?;
85        self.name_alg.marshal(writer)?;
86        self.object_attributes.marshal(writer)?;
87        self.auth_policy.marshal(writer)?;
88        self.parameters.marshal(writer)?;
89        self.unique.marshal(writer)
90    }
91}
92
93impl TpmUnmarshal for TpmtPublic {
94    fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
95        let (object_type, buf) = TpmAlgId::unmarshal(buf)?;
96        let (name_alg, buf) = TpmAlgId::unmarshal(buf)?;
97        let (object_attributes, buf) = TpmaObject::unmarshal(buf)?;
98        let (auth_policy, buf) = Tpm2bDigest::unmarshal(buf)?;
99        let (parameters, buf) = TpmuPublicParms::unmarshal_tagged(object_type, buf)?;
100        let (unique, buf) = TpmuPublicId::unmarshal_tagged(object_type, buf)?;
101
102        let public_area = Self {
103            object_type,
104            name_alg,
105            object_attributes,
106            auth_policy,
107            parameters,
108            unique,
109        };
110        Ok((public_area, buf))
111    }
112}
113
114impl Default for TpmtPublic {
115    fn default() -> Self {
116        Self {
117            object_type: TpmAlgId::Null,
118            name_alg: TpmAlgId::Null,
119            object_attributes: TpmaObject::empty(),
120            auth_policy: Tpm2bDigest::default(),
121            parameters: TpmuPublicParms::Null,
122            unique: TpmuPublicId::Null,
123        }
124    }
125}
126
127tpm_struct_tagged! {
128    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
129    pub struct TpmtPublicParms {
130        pub object_type: TpmAlgId,
131        pub parameters: TpmuPublicParms,
132    }
133}
134
135tpm_struct! {
136    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
137    pub struct TpmtKdfScheme {
138        pub scheme: TpmAlgId,
139    }
140}
141
142tpm_struct_tagged! {
143    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
144    pub struct TpmtRsaDecrypt {
145        pub scheme: TpmAlgId,
146        pub details: crate::data::tpmu::TpmuAsymScheme,
147    }
148}
149
150impl Default for TpmtRsaDecrypt {
151    fn default() -> Self {
152        Self {
153            scheme: TpmAlgId::Null,
154            details: crate::data::tpmu::TpmuAsymScheme::default(),
155        }
156    }
157}
158
159#[derive(Debug, PartialEq, Eq, Clone, Default)]
160pub struct TpmtSensitive {
161    pub sensitive_type: TpmAlgId,
162    pub auth_value: Tpm2bAuth,
163    pub seed_value: Tpm2bDigest,
164    pub sensitive: TpmuSensitiveComposite,
165}
166
167impl TpmSized for TpmtSensitive {
168    const SIZE: usize =
169        TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
170    fn len(&self) -> usize {
171        self.sensitive_type.len()
172            + self.auth_value.len()
173            + self.seed_value.len()
174            + self.sensitive.len()
175    }
176}
177
178impl TpmMarshal for TpmtSensitive {
179    fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
180        self.sensitive_type.marshal(writer)?;
181        self.auth_value.marshal(writer)?;
182        self.seed_value.marshal(writer)?;
183        self.sensitive.marshal(writer)
184    }
185}
186
187impl TpmUnmarshal for TpmtSensitive {
188    fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
189        let (sensitive_type, buf) = TpmAlgId::unmarshal(buf)?;
190        let (auth_value, buf) = Tpm2bAuth::unmarshal(buf)?;
191        let (seed_value, buf) = Tpm2bDigest::unmarshal(buf)?;
192        let (sensitive, buf) = TpmuSensitiveComposite::unmarshal_tagged(sensitive_type, buf)?;
193
194        Ok((
195            Self {
196                sensitive_type,
197                auth_value,
198                seed_value,
199                sensitive,
200            },
201            buf,
202        ))
203    }
204}
205
206#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
207pub struct TpmtSymDef {
208    pub algorithm: TpmAlgId,
209    pub key_bits: TpmuSymKeyBits,
210    pub mode: TpmuSymMode,
211}
212
213impl TpmSized for TpmtSymDef {
214    const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
215    fn len(&self) -> usize {
216        if self.algorithm == TpmAlgId::Null {
217            self.algorithm.len()
218        } else {
219            self.algorithm.len() + self.key_bits.len() + self.mode.len()
220        }
221    }
222}
223
224impl TpmMarshal for TpmtSymDef {
225    fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
226        self.algorithm.marshal(writer)?;
227        if self.algorithm != TpmAlgId::Null {
228            self.key_bits.marshal(writer)?;
229            self.mode.marshal(writer)?;
230        }
231        Ok(())
232    }
233}
234
235impl TpmUnmarshal for TpmtSymDef {
236    fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
237        let (algorithm, buf) = TpmAlgId::unmarshal(buf)?;
238
239        if algorithm == TpmAlgId::Null {
240            return Ok((
241                Self {
242                    algorithm,
243                    key_bits: TpmuSymKeyBits::Null,
244                    mode: TpmuSymMode::Null,
245                },
246                buf,
247            ));
248        }
249
250        let (key_bits, buf) = TpmuSymKeyBits::unmarshal_tagged(algorithm, buf)?;
251        let (mode, buf) = TpmuSymMode::unmarshal_tagged(algorithm, buf)?;
252
253        Ok((
254            Self {
255                algorithm,
256                key_bits,
257                mode,
258            },
259            buf,
260        ))
261    }
262}
263
264pub type TpmtSymDefObject = TpmtSymDef;
265
266tpm_struct_tagged! {
267    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
268    pub struct TpmtNvPublic2 {
269        pub handle_type: TpmHt,
270        pub public_area: TpmuNvPublic2,
271    }
272}
273
274tpm_struct! {
275    #[derive(Debug, PartialEq, Eq, Clone, Default)]
276    pub struct TpmtTkCreation {
277        pub tag: TpmSt,
278        pub hierarchy: TpmRh,
279        pub digest: Tpm2bDigest,
280    }
281}
282
283tpm_struct! {
284    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
285    pub struct TpmtTkVerified {
286        pub tag: TpmSt,
287        pub hierarchy: TpmRh,
288        pub digest: Tpm2bDigest,
289    }
290}
291
292tpm_struct! {
293    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
294    pub struct TpmtTkAuth {
295        pub tag: TpmSt,
296        pub hierarchy: TpmRh,
297        pub digest: Tpm2bDigest,
298    }
299}
300
301tpm_struct! {
302    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
303    pub struct TpmtTkHashcheck {
304        pub tag: TpmSt,
305        pub hierarchy: TpmRh,
306        pub digest: Tpm2bDigest,
307    }
308}
309
310tpm_struct_tagged! {
311    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
312    pub struct TpmtHa {
313        pub hash_alg: TpmAlgId,
314        pub digest: TpmuHa,
315    }
316}
317
318impl Default for TpmtHa {
319    fn default() -> Self {
320        Self {
321            hash_alg: TpmAlgId::Null,
322            digest: TpmuHa::default(),
323        }
324    }
325}
326
327tpm_struct_tagged! {
328    #[derive(Debug, PartialEq, Eq, Clone)]
329    pub struct TpmtSignature {
330        pub sig_alg: TpmAlgId,
331        pub signature: crate::data::tpmu::TpmuSignature,
332    }
333}
334
335tpm_struct_tagged! {
336    #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
337    pub struct TpmtKeyedhashScheme {
338        pub scheme: TpmAlgId,
339        pub details: TpmuKeyedhashScheme,
340    }
341}
342
343tpm_struct_tagged! {
344    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
345    pub struct TpmtSigScheme {
346        pub scheme: TpmAlgId,
347        pub details: TpmuSigScheme,
348    }
349}
350
351impl Default for TpmtSigScheme {
352    fn default() -> Self {
353        Self {
354            scheme: TpmAlgId::Null,
355            details: TpmuSigScheme::default(),
356        }
357    }
358}
359
360tpm_struct_tagged! {
361    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
362    pub struct TpmtRsaScheme {
363        pub scheme: TpmAlgId,
364        pub details: crate::data::tpmu::TpmuAsymScheme,
365    }
366}
367
368impl Default for TpmtRsaScheme {
369    fn default() -> Self {
370        Self {
371            scheme: TpmAlgId::Null,
372            details: crate::data::tpmu::TpmuAsymScheme::default(),
373        }
374    }
375}
376
377tpm_struct_tagged! {
378    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
379    pub struct TpmtEccScheme {
380        pub scheme: TpmAlgId,
381        pub details: crate::data::tpmu::TpmuAsymScheme,
382    }
383}
384
385impl Default for TpmtEccScheme {
386    fn default() -> Self {
387        Self {
388            scheme: TpmAlgId::Null,
389            details: crate::data::tpmu::TpmuAsymScheme::default(),
390        }
391    }
392}