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 TpmError, TpmMarshal, TpmResult, TpmSized, TpmUnmarshal, TpmUnmarshalTagged, TpmWriter,
12 constant::TPM_MAX_COMMAND_SIZE, tpm_struct,
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 if !self.$value_field.matches_tag(self.$tag_field) {
39 return Err($crate::TpmError::VariantNotAvailable {
40 offset: writer.len(),
41 value: u64::from(self.$tag_field.value()),
42 });
43 }
44
45 $crate::TpmMarshal::marshal(&self.$tag_field, writer)?;
46 $crate::TpmMarshal::marshal(&self.$value_field, writer)
47 }
48 }
49
50 impl<'a> $crate::TpmField<'a> for $name
51 where
52 $tag_ty: $crate::TpmField<'a, View = $tag_ty>,
53 $value_ty: $crate::TpmTaggedField<'a, $tag_ty>,
54 {
55 type View = (
56 $tag_ty,
57 <$value_ty as $crate::TpmTaggedField<'a, $tag_ty>>::View,
58 );
59
60 fn cast_prefix_field(buf: &'a [u8]) -> $crate::TpmResult<(Self::View, &'a [u8])> {
61 let ($tag_field, buf) = <$tag_ty as $crate::TpmField>::cast_prefix_field(buf)?;
62 let ($value_field, buf) =
63 <$value_ty as $crate::TpmTaggedField<'a, $tag_ty>>::cast_tagged_prefix_field(
64 $tag_field,
65 buf,
66 )?;
67
68 Ok((($tag_field, $value_field), buf))
69 }
70 }
71
72 impl $crate::TpmUnmarshal for $name
73 where
74 $tag_ty: $crate::TpmUnmarshal,
75 $value_ty: $crate::TpmUnmarshalTagged<$tag_ty>,
76 {
77 fn unmarshal(buffer: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
78 let ($tag_field, rest) = <$tag_ty as $crate::TpmUnmarshal>::unmarshal(buffer)?;
79 let offset = buffer.len() - rest.len();
80 let ($value_field, buffer) =
81 <$value_ty as $crate::TpmUnmarshalTagged<$tag_ty>>::unmarshal_tagged(
82 $tag_field,
83 rest,
84 )
85 .map_err(|e| e.rebase(offset))?;
86
87 Ok((Self { $tag_field, $value_field }, buffer))
88 }
89 }
90 };
91}
92
93#[derive(Debug, PartialEq, Eq, Clone, Default)]
94pub struct TpmtPublic {
95 pub object_type: TpmAlgId,
96 pub name_alg: TpmAlgId,
97 pub object_attributes: TpmaObject,
98 pub auth_policy: Tpm2bDigest,
99 pub parameters: TpmuPublicParms,
100 pub unique: TpmuPublicId,
101}
102
103impl TpmSized for TpmtPublic {
104 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
105 fn len(&self) -> usize {
106 self.object_type.len()
107 + self.name_alg.len()
108 + self.object_attributes.len()
109 + self.auth_policy.len()
110 + self.parameters.len()
111 + self.unique.len()
112 }
113}
114
115impl TpmMarshal for TpmtPublic {
116 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
117 if !self.parameters.matches_tag(self.object_type)
118 || !self.unique.matches_tag(self.object_type)
119 {
120 return Err(TpmError::VariantNotAvailable {
121 offset: writer.len(),
122 value: u64::from(self.object_type.value()),
123 });
124 }
125
126 self.object_type.marshal(writer)?;
127 self.name_alg.marshal(writer)?;
128 self.object_attributes.marshal(writer)?;
129 self.auth_policy.marshal(writer)?;
130 self.parameters.marshal(writer)?;
131 self.unique.marshal(writer)
132 }
133}
134
135impl TpmUnmarshal for TpmtPublic {
136 fn unmarshal(buffer: &[u8]) -> TpmResult<(Self, &[u8])> {
137 let (object_type, buffer) = TpmAlgId::unmarshal(buffer)?;
138 let (name_alg, buffer) = TpmAlgId::unmarshal(buffer)?;
139 let (object_attributes, buffer) = TpmaObject::unmarshal(buffer)?;
140 let (auth_policy, buffer) = Tpm2bDigest::unmarshal(buffer)?;
141 let (parameters, buffer) = TpmuPublicParms::unmarshal_tagged(object_type, buffer)?;
142 let (unique, buffer) = TpmuPublicId::unmarshal_tagged(object_type, buffer)?;
143
144 Ok((
145 Self {
146 object_type,
147 name_alg,
148 object_attributes,
149 auth_policy,
150 parameters,
151 unique,
152 },
153 buffer,
154 ))
155 }
156}
157
158pub struct TpmtPublicView<'a> {
160 pub object_type: TpmAlgId,
161 pub name_alg: TpmAlgId,
162 pub object_attributes: TpmaObject,
163 pub auth_policy: <Tpm2bDigest as crate::TpmField<'a>>::View,
164 pub parameters: <TpmuPublicParms as crate::TpmTaggedField<'a, TpmAlgId>>::View,
165 pub unique: <TpmuPublicId as crate::TpmTaggedField<'a, TpmAlgId>>::View,
166}
167
168impl<'a> crate::TpmField<'a> for TpmtPublic {
169 type View = TpmtPublicView<'a>;
170
171 fn cast_prefix_field(buf: &'a [u8]) -> TpmResult<(Self::View, &'a [u8])> {
172 let (object_type, buf) = <TpmAlgId as crate::TpmField>::cast_prefix_field(buf)?;
173 let (name_alg, buf) = <TpmAlgId as crate::TpmField>::cast_prefix_field(buf)?;
174 let (object_attributes, buf) = <TpmaObject as crate::TpmField>::cast_prefix_field(buf)?;
175 let (auth_policy, buf) = <Tpm2bDigest as crate::TpmField>::cast_prefix_field(buf)?;
176 let (parameters, buf) =
177 <TpmuPublicParms as crate::TpmTaggedField<'a, TpmAlgId>>::cast_tagged_prefix_field(
178 object_type,
179 buf,
180 )?;
181 let (unique, buf) =
182 <TpmuPublicId as crate::TpmTaggedField<'a, TpmAlgId>>::cast_tagged_prefix_field(
183 object_type,
184 buf,
185 )?;
186
187 Ok((
188 TpmtPublicView {
189 object_type,
190 name_alg,
191 object_attributes,
192 auth_policy,
193 parameters,
194 unique,
195 },
196 buf,
197 ))
198 }
199}
200
201tpm_struct_tagged! {
202 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
203 pub struct TpmtPublicParms {
204 pub object_type: TpmAlgId,
205 pub parameters: TpmuPublicParms,
206 }
207}
208
209tpm_struct_tagged! {
210 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
211 pub struct TpmtKdfScheme {
212 pub scheme: TpmAlgId,
213 pub details: TpmuKdfScheme,
214 }
215}
216
217impl Default for TpmtKdfScheme {
218 fn default() -> Self {
219 Self {
220 scheme: TpmAlgId::Null,
221 details: TpmuKdfScheme::Null,
222 }
223 }
224}
225
226tpm_struct_tagged! {
227 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
228 pub struct TpmtRsaDecrypt {
229 pub scheme: TpmAlgId,
230 pub details: crate::data::tpmu::TpmuAsymScheme,
231 }
232}
233
234impl Default for TpmtRsaDecrypt {
235 fn default() -> Self {
236 Self {
237 scheme: TpmAlgId::Null,
238 details: crate::data::tpmu::TpmuAsymScheme::default(),
239 }
240 }
241}
242
243#[derive(Debug, PartialEq, Eq, Clone, Default)]
244pub struct TpmtSensitive {
245 pub sensitive_type: TpmAlgId,
246 pub auth_value: Tpm2bAuth,
247 pub seed_value: Tpm2bDigest,
248 pub sensitive: TpmuSensitiveComposite,
249}
250
251impl TpmSized for TpmtSensitive {
252 const SIZE: usize =
253 TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
254 fn len(&self) -> usize {
255 self.sensitive_type.len()
256 + self.auth_value.len()
257 + self.seed_value.len()
258 + self.sensitive.len()
259 }
260}
261
262impl TpmMarshal for TpmtSensitive {
263 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
264 if !self.sensitive.matches_tag(self.sensitive_type) {
265 return Err(TpmError::VariantNotAvailable {
266 offset: writer.len(),
267 value: u64::from(self.sensitive_type.value()),
268 });
269 }
270
271 self.sensitive_type.marshal(writer)?;
272 self.auth_value.marshal(writer)?;
273 self.seed_value.marshal(writer)?;
274 self.sensitive.marshal(writer)
275 }
276}
277
278impl TpmUnmarshal for TpmtSensitive {
279 fn unmarshal(buffer: &[u8]) -> TpmResult<(Self, &[u8])> {
280 let (sensitive_type, buffer) = TpmAlgId::unmarshal(buffer)?;
281 let (auth_value, buffer) = Tpm2bAuth::unmarshal(buffer)?;
282 let (seed_value, buffer) = Tpm2bDigest::unmarshal(buffer)?;
283 let (sensitive, buffer) = TpmuSensitiveComposite::unmarshal_tagged(sensitive_type, buffer)?;
284
285 Ok((
286 Self {
287 sensitive_type,
288 auth_value,
289 seed_value,
290 sensitive,
291 },
292 buffer,
293 ))
294 }
295}
296
297#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
298pub struct TpmtSymDef {
299 pub algorithm: TpmAlgId,
300 pub key_bits: TpmuSymKeyBits,
301 pub mode: TpmuSymMode,
302}
303
304impl TpmSized for TpmtSymDef {
305 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
306 fn len(&self) -> usize {
307 if self.algorithm == TpmAlgId::Null {
308 self.algorithm.len()
309 } else {
310 self.algorithm.len() + self.key_bits.len() + self.mode.len()
311 }
312 }
313}
314
315impl TpmMarshal for TpmtSymDef {
316 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
317 if self.algorithm != TpmAlgId::Null
318 && (!self.key_bits.matches_tag(self.algorithm)
319 || !self.mode.matches_tag(self.algorithm))
320 {
321 return Err(TpmError::VariantNotAvailable {
322 offset: writer.len(),
323 value: u64::from(self.algorithm.value()),
324 });
325 }
326
327 self.algorithm.marshal(writer)?;
328 if self.algorithm != TpmAlgId::Null {
329 self.key_bits.marshal(writer)?;
330 self.mode.marshal(writer)?;
331 }
332 Ok(())
333 }
334}
335
336impl TpmUnmarshal for TpmtSymDef {
337 fn unmarshal(buffer: &[u8]) -> TpmResult<(Self, &[u8])> {
338 let (algorithm, buffer) = TpmAlgId::unmarshal(buffer)?;
339 if algorithm == TpmAlgId::Null {
340 return Ok((
341 Self {
342 algorithm,
343 key_bits: TpmuSymKeyBits::Null,
344 mode: TpmuSymMode::Null,
345 },
346 buffer,
347 ));
348 }
349
350 let (key_bits, buffer) = TpmuSymKeyBits::unmarshal_tagged(algorithm, buffer)?;
351 let (mode, buffer) = TpmuSymMode::unmarshal_tagged(algorithm, buffer)?;
352 Ok((
353 Self {
354 algorithm,
355 key_bits,
356 mode,
357 },
358 buffer,
359 ))
360 }
361}
362
363pub enum TpmtSymDefView<'a> {
364 Null,
365 Value {
366 algorithm: TpmAlgId,
367 key_bits: <TpmuSymKeyBits as crate::TpmTaggedField<'a, TpmAlgId>>::View,
368 mode: <TpmuSymMode as crate::TpmTaggedField<'a, TpmAlgId>>::View,
369 },
370}
371
372impl<'a> crate::TpmField<'a> for TpmtSymDef {
373 type View = TpmtSymDefView<'a>;
374
375 fn cast_prefix_field(buf: &'a [u8]) -> TpmResult<(Self::View, &'a [u8])> {
376 let (algorithm, buf) = <TpmAlgId as crate::TpmField>::cast_prefix_field(buf)?;
377
378 if algorithm == TpmAlgId::Null {
379 return Ok((TpmtSymDefView::Null, buf));
380 }
381
382 let (key_bits, buf) =
383 <TpmuSymKeyBits as crate::TpmTaggedField<'a, TpmAlgId>>::cast_tagged_prefix_field(
384 algorithm, buf,
385 )?;
386 let (mode, buf) =
387 <TpmuSymMode as crate::TpmTaggedField<'a, TpmAlgId>>::cast_tagged_prefix_field(
388 algorithm, buf,
389 )?;
390
391 Ok((
392 TpmtSymDefView::Value {
393 algorithm,
394 key_bits,
395 mode,
396 },
397 buf,
398 ))
399 }
400}
401
402pub type TpmtSymDefObject = TpmtSymDef;
403
404tpm_struct_tagged! {
405 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
406 pub struct TpmtNvPublic2 {
407 pub handle_type: TpmHt,
408 pub public_area: TpmuNvPublic2,
409 }
410}
411
412tpm_struct! {
413 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
414 wire: TpmtTkCreationWire,
415 pub struct TpmtTkCreation {
416 pub tag: TpmSt,
417 pub hierarchy: TpmRh,
418 pub digest: Tpm2bDigest,
419 }
420}
421
422tpm_struct! {
423 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
424 wire: TpmtTkVerifiedWire,
425 pub struct TpmtTkVerified {
426 pub tag: TpmSt,
427 pub hierarchy: TpmRh,
428 pub digest: Tpm2bDigest,
429 }
430}
431
432tpm_struct! {
433 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
434 wire: TpmtTkAuthWire,
435 pub struct TpmtTkAuth {
436 pub tag: TpmSt,
437 pub hierarchy: TpmRh,
438 pub digest: Tpm2bDigest,
439 }
440}
441
442tpm_struct! {
443 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
444 wire: TpmtTkHashcheckWire,
445 pub struct TpmtTkHashcheck {
446 pub tag: TpmSt,
447 pub hierarchy: TpmRh,
448 pub digest: Tpm2bDigest,
449 }
450}
451
452tpm_struct_tagged! {
453 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
454 pub struct TpmtHa {
455 pub hash_alg: TpmAlgId,
456 pub digest: TpmuHa,
457 }
458}
459
460impl Default for TpmtHa {
461 fn default() -> Self {
462 Self {
463 hash_alg: TpmAlgId::Null,
464 digest: TpmuHa::default(),
465 }
466 }
467}
468
469tpm_struct_tagged! {
470 #[derive(Debug, PartialEq, Eq, Clone)]
471 pub struct TpmtSignature {
472 pub sig_alg: TpmAlgId,
473 pub signature: crate::data::tpmu::TpmuSignature,
474 }
475}
476
477tpm_struct_tagged! {
478 #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
479 pub struct TpmtKeyedhashScheme {
480 pub scheme: TpmAlgId,
481 pub details: TpmuKeyedhashScheme,
482 }
483}
484
485tpm_struct_tagged! {
486 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
487 pub struct TpmtSigScheme {
488 pub scheme: TpmAlgId,
489 pub details: TpmuSigScheme,
490 }
491}
492
493impl Default for TpmtSigScheme {
494 fn default() -> Self {
495 Self {
496 scheme: TpmAlgId::Null,
497 details: TpmuSigScheme::default(),
498 }
499 }
500}
501
502tpm_struct_tagged! {
503 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
504 pub struct TpmtRsaScheme {
505 pub scheme: TpmAlgId,
506 pub details: crate::data::tpmu::TpmuAsymScheme,
507 }
508}
509
510impl Default for TpmtRsaScheme {
511 fn default() -> Self {
512 Self {
513 scheme: TpmAlgId::Null,
514 details: crate::data::tpmu::TpmuAsymScheme::default(),
515 }
516 }
517}
518
519tpm_struct_tagged! {
520 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
521 pub struct TpmtEccScheme {
522 pub scheme: TpmAlgId,
523 pub details: crate::data::tpmu::TpmuAsymScheme,
524 }
525}
526
527impl Default for TpmtEccScheme {
528 fn default() -> Self {
529 Self {
530 scheme: TpmAlgId::Null,
531 details: crate::data::tpmu::TpmuAsymScheme::default(),
532 }
533 }
534}