Skip to main content

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