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, TpmuKdfScheme,
7    TpmuKeyedhashScheme, TpmuNvPublic2, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite,
8    TpmuSigScheme, 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;
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_tagged! {
136    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
137    pub struct TpmtKdfScheme {
138        pub scheme: TpmAlgId,
139        pub details: TpmuKdfScheme,
140    }
141}
142
143impl Default for TpmtKdfScheme {
144    fn default() -> Self {
145        Self {
146            scheme: TpmAlgId::Null,
147            details: TpmuKdfScheme::Null,
148        }
149    }
150}
151
152tpm_struct_tagged! {
153    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
154    pub struct TpmtRsaDecrypt {
155        pub scheme: TpmAlgId,
156        pub details: crate::data::tpmu::TpmuAsymScheme,
157    }
158}
159
160impl Default for TpmtRsaDecrypt {
161    fn default() -> Self {
162        Self {
163            scheme: TpmAlgId::Null,
164            details: crate::data::tpmu::TpmuAsymScheme::default(),
165        }
166    }
167}
168
169#[derive(Debug, PartialEq, Eq, Clone, Default)]
170pub struct TpmtSensitive {
171    pub sensitive_type: TpmAlgId,
172    pub auth_value: Tpm2bAuth,
173    pub seed_value: Tpm2bDigest,
174    pub sensitive: TpmuSensitiveComposite,
175}
176
177impl TpmSized for TpmtSensitive {
178    const SIZE: usize =
179        TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
180    fn len(&self) -> usize {
181        self.sensitive_type.len()
182            + self.auth_value.len()
183            + self.seed_value.len()
184            + self.sensitive.len()
185    }
186}
187
188impl TpmMarshal for TpmtSensitive {
189    fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
190        self.sensitive_type.marshal(writer)?;
191        self.auth_value.marshal(writer)?;
192        self.seed_value.marshal(writer)?;
193        self.sensitive.marshal(writer)
194    }
195}
196
197impl TpmUnmarshal for TpmtSensitive {
198    fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
199        let (sensitive_type, buf) = TpmAlgId::unmarshal(buf)?;
200        let (auth_value, buf) = Tpm2bAuth::unmarshal(buf)?;
201        let (seed_value, buf) = Tpm2bDigest::unmarshal(buf)?;
202        let (sensitive, buf) = TpmuSensitiveComposite::unmarshal_tagged(sensitive_type, buf)?;
203
204        Ok((
205            Self {
206                sensitive_type,
207                auth_value,
208                seed_value,
209                sensitive,
210            },
211            buf,
212        ))
213    }
214}
215
216#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
217pub struct TpmtSymDef {
218    pub algorithm: TpmAlgId,
219    pub key_bits: TpmuSymKeyBits,
220    pub mode: TpmuSymMode,
221}
222
223impl TpmSized for TpmtSymDef {
224    const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
225    fn len(&self) -> usize {
226        if self.algorithm == TpmAlgId::Null {
227            self.algorithm.len()
228        } else {
229            self.algorithm.len() + self.key_bits.len() + self.mode.len()
230        }
231    }
232}
233
234impl TpmMarshal for TpmtSymDef {
235    fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
236        self.algorithm.marshal(writer)?;
237        if self.algorithm != TpmAlgId::Null {
238            self.key_bits.marshal(writer)?;
239            self.mode.marshal(writer)?;
240        }
241        Ok(())
242    }
243}
244
245impl TpmUnmarshal for TpmtSymDef {
246    fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
247        let (algorithm, buf) = TpmAlgId::unmarshal(buf)?;
248
249        if algorithm == TpmAlgId::Null {
250            return Ok((
251                Self {
252                    algorithm,
253                    key_bits: TpmuSymKeyBits::Null,
254                    mode: TpmuSymMode::Null,
255                },
256                buf,
257            ));
258        }
259
260        let (key_bits, buf) = TpmuSymKeyBits::unmarshal_tagged(algorithm, buf)?;
261        let (mode, buf) = TpmuSymMode::unmarshal_tagged(algorithm, buf)?;
262
263        Ok((
264            Self {
265                algorithm,
266                key_bits,
267                mode,
268            },
269            buf,
270        ))
271    }
272}
273
274pub type TpmtSymDefObject = TpmtSymDef;
275
276tpm_struct_tagged! {
277    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
278    pub struct TpmtNvPublic2 {
279        pub handle_type: TpmHt,
280        pub public_area: TpmuNvPublic2,
281    }
282}
283
284tpm_struct! {
285    #[derive(Debug, PartialEq, Eq, Clone, Default)]
286    pub struct TpmtTkCreation {
287        pub tag: TpmSt,
288        pub hierarchy: TpmRh,
289        pub digest: Tpm2bDigest,
290    }
291}
292
293tpm_struct! {
294    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
295    pub struct TpmtTkVerified {
296        pub tag: TpmSt,
297        pub hierarchy: TpmRh,
298        pub digest: Tpm2bDigest,
299    }
300}
301
302tpm_struct! {
303    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
304    pub struct TpmtTkAuth {
305        pub tag: TpmSt,
306        pub hierarchy: TpmRh,
307        pub digest: Tpm2bDigest,
308    }
309}
310
311tpm_struct! {
312    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
313    pub struct TpmtTkHashcheck {
314        pub tag: TpmSt,
315        pub hierarchy: TpmRh,
316        pub digest: Tpm2bDigest,
317    }
318}
319
320tpm_struct_tagged! {
321    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
322    pub struct TpmtHa {
323        pub hash_alg: TpmAlgId,
324        pub digest: TpmuHa,
325    }
326}
327
328impl Default for TpmtHa {
329    fn default() -> Self {
330        Self {
331            hash_alg: TpmAlgId::Null,
332            digest: TpmuHa::default(),
333        }
334    }
335}
336
337tpm_struct_tagged! {
338    #[derive(Debug, PartialEq, Eq, Clone)]
339    pub struct TpmtSignature {
340        pub sig_alg: TpmAlgId,
341        pub signature: crate::data::tpmu::TpmuSignature,
342    }
343}
344
345tpm_struct_tagged! {
346    #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
347    pub struct TpmtKeyedhashScheme {
348        pub scheme: TpmAlgId,
349        pub details: TpmuKeyedhashScheme,
350    }
351}
352
353tpm_struct_tagged! {
354    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
355    pub struct TpmtSigScheme {
356        pub scheme: TpmAlgId,
357        pub details: TpmuSigScheme,
358    }
359}
360
361impl Default for TpmtSigScheme {
362    fn default() -> Self {
363        Self {
364            scheme: TpmAlgId::Null,
365            details: TpmuSigScheme::default(),
366        }
367    }
368}
369
370tpm_struct_tagged! {
371    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
372    pub struct TpmtRsaScheme {
373        pub scheme: TpmAlgId,
374        pub details: crate::data::tpmu::TpmuAsymScheme,
375    }
376}
377
378impl Default for TpmtRsaScheme {
379    fn default() -> Self {
380        Self {
381            scheme: TpmAlgId::Null,
382            details: crate::data::tpmu::TpmuAsymScheme::default(),
383        }
384    }
385}
386
387tpm_struct_tagged! {
388    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
389    pub struct TpmtEccScheme {
390        pub scheme: TpmAlgId,
391        pub details: crate::data::tpmu::TpmuAsymScheme,
392    }
393}
394
395impl Default for TpmtEccScheme {
396    fn default() -> Self {
397        Self {
398            scheme: TpmAlgId::Null,
399            details: crate::data::tpmu::TpmuAsymScheme::default(),
400        }
401    }
402}