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