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