1#[macro_export]
6macro_rules! tpm_struct {
7 (@wire_field_methods [$($prev_type:ty,)*],) => {};
8
9 (@wire_field_methods [$($prev_type:ty,)*], pub $field_name:ident: $field_type:ty $(, pub $rest_field:ident: $rest_type:ty)* $(,)?) => {
10 #[allow(unused_mut)]
16 pub fn $field_name(&self) -> $crate::TpmResult<&$field_type>
17 where
18 $($prev_type: for<'a> $crate::TpmField<'a>,)*
19 $field_type: for<'a> $crate::TpmField<'a, View = &'a $field_type>,
20 {
21 let mut cursor = &self.0;
22 $(
23 let (_, tail) = <$prev_type as $crate::TpmField>::cast_prefix_field(cursor)?;
24 cursor = tail;
25 )*
26
27 let (value, _) = <$field_type as $crate::TpmField>::cast_prefix_field(cursor)?;
28
29 Ok(value)
30 }
31
32 $crate::tpm_struct!(@wire_field_methods [$($prev_type,)* $field_type,], $(pub $rest_field: $rest_type),*);
33 };
34
35 (
36 $(#[$meta:meta])*
37 kind: Command,
38 name: $name:ident,
39 cc: $cc:expr,
40 handles: $count:literal,
41 parameters: {
42 $(pub $param_field:ident: $param_type:ty),*
43 $(,)?
44 }
45 ) => {
46 $(#[$meta])*
47 pub struct $name {
48 pub handles: [$crate::basic::TpmHandle; $count],
49 $(pub $param_field: $param_type,)*
50 }
51
52 impl $crate::frame::TpmHeader for $name {
53 const CC: $crate::data::TpmCc = $cc;
54 const HANDLES: usize = $count;
55 }
56
57 impl $name {
58 pub fn cast_frame(buf: &[u8]) -> $crate::TpmResult<&$crate::frame::TpmCommand> {
65 let command = <$crate::frame::TpmCommand>::cast(buf)?;
66
67 let cc = command.cc()?;
68 if cc != Self::CC {
69 return Err($crate::TpmError::InvalidCc(
70 $crate::TpmErrorValue::new(6).value(u64::from(cc.value())),
71 ));
72 }
73
74 Ok(command)
75 }
76
77 pub fn cast_frame_mut(
84 buf: &mut [u8],
85 ) -> $crate::TpmResult<&mut $crate::frame::TpmCommand> {
86 let command = <$crate::frame::TpmCommand>::cast_mut(buf)?;
87
88 let cc = command.cc()?;
89 if cc != Self::CC {
90 return Err($crate::TpmError::InvalidCc(
91 $crate::TpmErrorValue::new(6).value(u64::from(cc.value())),
92 ));
93 }
94
95 Ok(command)
96 }
97 }
98
99 impl $crate::frame::TpmFrame for $name {
100 fn cc(&self) -> $crate::data::TpmCc {
101 Self::CC
102 }
103 fn handles(&self) -> usize {
104 Self::HANDLES
105 }
106 }
107
108 impl $crate::TpmSized for $name {
109 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
110 fn len(&self) -> usize {
111 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
112 }
113 }
114
115 impl $crate::TpmMarshal for $name {
116 #[allow(unused_variables)]
117 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
118 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
119 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
120 }
121 }
122
123 impl $crate::frame::TpmMarshalBody for $name {
124 #[allow(unused_variables)]
125 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
126 for handle in &self.handles {
127 $crate::TpmMarshal::marshal(handle, writer)?;
128 }
129 Ok(())
130 }
131
132 #[allow(unused_variables)]
133 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
134 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
135 Ok(())
136 }
137 }
138 };
139
140 (
141 $(#[$meta:meta])*
142 kind: Response,
143 name: $name:ident,
144 cc: $cc:expr,
145 handles: $count:literal,
146 parameters: {
147 $(pub $param_field:ident: $param_type:ty),*
148 $(,)?
149 }
150 ) => {
151 $(#[$meta])*
152 pub struct $name {
153 pub handles: [$crate::basic::TpmHandle; $count],
154 $(pub $param_field: $param_type,)*
155 }
156
157 impl $crate::frame::TpmHeader for $name {
158 const CC: $crate::data::TpmCc = $cc;
159 const HANDLES: usize = $count;
160 }
161
162 impl $name {
163 pub fn cast_frame(buf: &[u8]) -> $crate::TpmResult<&$crate::frame::TpmResponse> {
169 <$crate::frame::TpmResponse>::cast(buf)
170 }
171
172 pub fn cast_frame_mut(
178 buf: &mut [u8],
179 ) -> $crate::TpmResult<&mut $crate::frame::TpmResponse> {
180 <$crate::frame::TpmResponse>::cast_mut(buf)
181 }
182 }
183
184 impl $crate::frame::TpmFrame for $name {
185 fn cc(&self) -> $crate::data::TpmCc {
186 Self::CC
187 }
188 fn handles(&self) -> usize {
189 Self::HANDLES
190 }
191 }
192
193 impl $crate::frame::TpmMarshalBody for $name {
194 #[allow(unused_variables)]
195 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
196 for handle in &self.handles {
197 $crate::TpmMarshal::marshal(handle, writer)?;
198 }
199 Ok(())
200 }
201 #[allow(unused_variables)]
202 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
203 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
204 Ok(())
205 }
206 }
207
208 impl $crate::TpmSized for $name {
209 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
210 fn len(&self) -> usize {
211 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
212 }
213 }
214
215 impl $crate::TpmMarshal for $name {
216 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
217 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
218 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
219 }
220 }
221 };
222
223 (
224 $(#[$meta:meta])*
225 wire: $wire:ident,
226 $vis:vis struct $name:ident {
227 $(pub $field_name:ident: $field_type:ty),*
228 $(,)?
229 }
230 ) => {
231 $(#[$meta])*
232 $vis struct $name {
233 $(pub $field_name: $field_type,)*
234 }
235
236 #[repr(transparent)]
237 $vis struct $wire([u8]);
238
239 impl $wire {
240 pub fn cast(buf: &[u8]) -> $crate::TpmResult<&Self>
247 where
248 $($field_type: for<'a> $crate::TpmField<'a>,)*
249 {
250 Self::validate(buf)?;
251
252 Ok(unsafe { Self::cast_unchecked(buf) })
254 }
255
256 pub fn cast_prefix(buf: &[u8]) -> $crate::TpmResult<(&Self, &[u8])>
263 where
264 $($field_type: for<'a> $crate::TpmField<'a>,)*
265 {
266 let wire_len = Self::validate_prefix(buf)?;
267 if buf.len() < wire_len {
268 return Err($crate::TpmError::UnexpectedEnd(
269 $crate::TpmErrorValue::new(0).size(wire_len, buf.len()),
270 ));
271 }
272
273 let (head, tail) = buf.split_at(wire_len);
274
275 Ok((unsafe { Self::cast_unchecked(head) }, tail))
277 }
278
279 #[must_use]
285 pub unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
286 let ptr = core::ptr::from_ref(buf) as *const Self;
287
288 unsafe { &*ptr }
291 }
292
293 #[must_use]
295 pub const fn as_bytes(&self) -> &[u8] {
296 &self.0
297 }
298
299 pub fn validate(buf: &[u8]) -> $crate::TpmResult<()>
306 where
307 $($field_type: for<'a> $crate::TpmField<'a>,)*
308 {
309 let wire_len = Self::validate_prefix(buf)?;
310
311 if buf.len() > wire_len {
312 return Err($crate::TpmError::TrailingData(
313 $crate::TpmErrorValue::new(wire_len).actual(buf.len() - wire_len),
314 ));
315 }
316
317 Ok(())
318 }
319
320 #[allow(unused_assignments, unused_mut, unused_variables)]
321 pub fn validate_prefix(buf: &[u8]) -> $crate::TpmResult<usize>
328 where
329 $($field_type: for<'a> $crate::TpmField<'a>,)*
330 {
331 let mut cursor = buf;
332 let mut consumed = 0usize;
333
334 $(
335 let before = cursor.len();
336 let (_, tail) = <$field_type as $crate::TpmField>::cast_prefix_field(cursor)?;
337 let field_len = before.checked_sub(tail.len()).ok_or(
338 $crate::TpmError::IntegerTooLarge(
339 $crate::TpmErrorValue::new(consumed).value_usize(tail.len()),
340 ),
341 )?;
342 consumed = consumed.checked_add(field_len).ok_or(
343 $crate::TpmError::IntegerTooLarge(
344 $crate::TpmErrorValue::new(consumed).value_usize(before),
345 ),
346 )?;
347 cursor = tail;
348 )*
349
350 Ok(consumed)
351 }
352
353 $crate::tpm_struct!(@wire_field_methods [], $(pub $field_name: $field_type),*);
354 }
355
356 impl AsRef<[u8]> for $wire {
357 fn as_ref(&self) -> &[u8] {
358 self.as_bytes()
359 }
360 }
361
362 impl<'a> $crate::TpmField<'a> for $name
363 where
364 $($field_type: for<'b> $crate::TpmField<'b>,)*
365 {
366 type View = &'a $wire;
367
368 fn cast_prefix_field(buf: &'a [u8]) -> $crate::TpmResult<(Self::View, &'a [u8])> {
369 $wire::cast_prefix(buf)
370 }
371 }
372
373 impl $crate::TpmSized for $name {
374 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
375 fn len(&self) -> usize {
376 0 $(+ $crate::TpmSized::len(&self.$field_name))*
377 }
378 }
379
380 impl $crate::TpmMarshal for $name {
381 #[allow(unused_variables)]
382 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
383 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
384 Ok(())
385 }
386 }
387
388 };
389}
390
391#[macro_export]
392macro_rules! tpm2b {
393 ($name:ident, $capacity:expr) => {
394 pub type $name = $crate::basic::TpmBuffer<$capacity>;
395 };
396}
397
398#[macro_export]
399macro_rules! tpm2b_struct {
400 (
401 $(#[$meta:meta])*
402 wire: $wire_ty:ident,
403 $wrapper_ty:ident, $inner_ty:ty) => {
404 $(#[$meta])*
405 pub struct $wrapper_ty {
406 pub inner: $inner_ty,
407 }
408
409 #[repr(transparent)]
410 pub struct $wire_ty([u8]);
411
412 impl $wire_ty {
413 pub fn cast(buf: &[u8]) -> $crate::TpmResult<&Self>
420 where
421 $inner_ty: for<'a> $crate::TpmField<'a>,
422 {
423 Self::validate(buf)?;
424
425 Ok(unsafe { Self::cast_unchecked(buf) })
427 }
428
429 pub fn cast_prefix(buf: &[u8]) -> $crate::TpmResult<(&Self, &[u8])>
436 where
437 $inner_ty: for<'a> $crate::TpmField<'a>,
438 {
439 let wire_len = Self::validate_prefix(buf)?;
440 let (head, tail) = buf.split_at(wire_len);
441
442 Ok((unsafe { Self::cast_unchecked(head) }, tail))
444 }
445
446 #[must_use]
453 pub unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
454 let ptr = core::ptr::from_ref(buf) as *const Self;
455
456 unsafe { &*ptr }
459 }
460
461 #[must_use]
463 pub const fn as_bytes(&self) -> &[u8] {
464 &self.0
465 }
466
467 pub fn inner(&self) -> $crate::TpmResult<<$inner_ty as $crate::TpmField<'_>>::View>
474 where
475 $inner_ty: for<'a> $crate::TpmField<'a>,
476 {
477 let inner_bytes = &self.0[<$crate::basic::TpmUint16 as $crate::TpmSized>::SIZE..];
478 let (inner, tail) = <$inner_ty as $crate::TpmField>::cast_prefix_field(inner_bytes)?;
479
480 if !tail.is_empty() {
481 return Err($crate::TpmError::TrailingData(
482 $crate::TpmErrorValue::at(&self.0, tail).actual(tail.len()),
483 ));
484 }
485
486 Ok(inner)
487 }
488
489 pub fn validate(buf: &[u8]) -> $crate::TpmResult<()>
496 where
497 $inner_ty: for<'a> $crate::TpmField<'a>,
498 {
499 let wire_len = Self::validate_prefix(buf)?;
500
501 if buf.len() > wire_len {
502 return Err($crate::TpmError::TrailingData(
503 $crate::TpmErrorValue::new(wire_len).actual(buf.len() - wire_len),
504 ));
505 }
506
507 Ok(())
508 }
509
510 pub fn validate_prefix(buf: &[u8]) -> $crate::TpmResult<usize>
517 where
518 $inner_ty: for<'a> $crate::TpmField<'a>,
519 {
520 let (size_field, payload) = <$crate::basic::TpmUint16 as $crate::TpmCast>::cast_prefix(buf)?;
521 let payload_len = size_field.get() as usize;
522
523 if payload.len() < payload_len {
524 return Err($crate::TpmError::UnexpectedEnd(
525 $crate::TpmErrorValue::at(buf, payload).size(payload_len, payload.len()),
526 ));
527 }
528
529 let (inner_bytes, _) = payload.split_at(payload_len);
530 let (_, tail) = <$inner_ty as $crate::TpmField>::cast_prefix_field(inner_bytes)?;
531
532 if !tail.is_empty() {
533 return Err($crate::TpmError::TrailingData(
534 $crate::TpmErrorValue::at(buf, tail).actual(tail.len()),
535 ));
536 }
537
538 Ok(<$crate::basic::TpmUint16 as $crate::TpmSized>::SIZE + payload_len)
539 }
540 }
541
542 impl AsRef<[u8]> for $wire_ty {
543 fn as_ref(&self) -> &[u8] {
544 self.as_bytes()
545 }
546 }
547
548 impl<'a> $crate::TpmField<'a> for $wrapper_ty
549 where
550 $inner_ty: for<'b> $crate::TpmField<'b>,
551 {
552 type View = &'a $wire_ty;
553
554 fn cast_prefix_field(buf: &'a [u8]) -> $crate::TpmResult<(Self::View, &'a [u8])> {
555 $wire_ty::cast_prefix(buf)
556 }
557 }
558
559 impl $crate::TpmSized for $wrapper_ty {
560 const SIZE: usize = $crate::basic::TpmUint16::SIZE + <$inner_ty>::SIZE;
561 fn len(&self) -> usize {
562 $crate::basic::TpmUint16::SIZE + $crate::TpmSized::len(&self.inner)
563 }
564 }
565
566 impl $crate::TpmMarshal for $wrapper_ty
567 where
568 $inner_ty: $crate::TpmSized,
569 {
570 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
571 let inner_len = $crate::TpmSized::len(&self.inner);
572 let len_field = <$crate::basic::TpmUint16>::try_from(inner_len)
573 .map_err(|_| $crate::TpmError::IntegerTooLarge(
574 $crate::TpmErrorValue::new(writer.len()).value_usize(inner_len),
575 ))?;
576 len_field.marshal(writer)?;
577 $crate::TpmMarshal::marshal(&self.inner, writer)
578 }
579 }
580
581 impl From<$inner_ty> for $wrapper_ty {
582 fn from(inner: $inner_ty) -> Self {
583 Self { inner }
584 }
585 }
586
587 impl core::ops::Deref for $wrapper_ty {
588 type Target = $inner_ty;
589 fn deref(&self) -> &Self::Target {
590 &self.inner
591 }
592 }
593
594 impl core::ops::DerefMut for $wrapper_ty {
595 fn deref_mut(&mut self) -> &mut Self::Target {
596 &mut self.inner
597 }
598 }
599 };
600}
601
602#[macro_export]
603macro_rules! tpml {
604 ($name:ident, $inner_ty:ty, $capacity:expr) => {
605 pub type $name = $crate::basic::TpmList<$inner_ty, $capacity>;
606 };
607}