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 { offset: 6, value: u64::from(cc.value()) });
70 }
71
72 Ok(command)
73 }
74
75 pub fn cast_frame_mut(
82 buf: &mut [u8],
83 ) -> $crate::TpmResult<&mut $crate::frame::TpmCommand> {
84 let command = <$crate::frame::TpmCommand>::cast_mut(buf)?;
85
86 let cc = command.cc()?;
87 if cc != Self::CC {
88 return Err($crate::TpmError::InvalidCc { offset: 6, value: u64::from(cc.value()) });
89 }
90
91 Ok(command)
92 }
93 }
94
95 impl $crate::frame::TpmFrame for $name {
96 fn cc(&self) -> $crate::data::TpmCc {
97 Self::CC
98 }
99 fn handles(&self) -> usize {
100 Self::HANDLES
101 }
102 }
103
104 impl $crate::TpmSized for $name {
105 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
106 fn len(&self) -> usize {
107 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
108 }
109 }
110
111 impl $crate::TpmMarshal for $name {
112 #[allow(unused_variables)]
113 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
114 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
115 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
116 }
117 }
118
119 impl $crate::frame::TpmMarshalBody for $name {
120 #[allow(unused_variables)]
121 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
122 for handle in &self.handles {
123 $crate::TpmMarshal::marshal(handle, writer)?;
124 }
125 Ok(())
126 }
127
128 #[allow(unused_variables)]
129 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
130 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
131 Ok(())
132 }
133 }
134 };
135
136 (
137 $(#[$meta:meta])*
138 kind: Response,
139 name: $name:ident,
140 cc: $cc:expr,
141 handles: $count:literal,
142 parameters: {
143 $(pub $param_field:ident: $param_type:ty),*
144 $(,)?
145 }
146 ) => {
147 $(#[$meta])*
148 pub struct $name {
149 pub handles: [$crate::basic::TpmHandle; $count],
150 $(pub $param_field: $param_type,)*
151 }
152
153 impl $crate::frame::TpmHeader for $name {
154 const CC: $crate::data::TpmCc = $cc;
155 const HANDLES: usize = $count;
156 }
157
158 impl $name {
159 pub fn cast_frame(buf: &[u8]) -> $crate::TpmResult<&$crate::frame::TpmResponse> {
165 <$crate::frame::TpmResponse>::cast(buf)
166 }
167
168 pub fn cast_frame_mut(
174 buf: &mut [u8],
175 ) -> $crate::TpmResult<&mut $crate::frame::TpmResponse> {
176 <$crate::frame::TpmResponse>::cast_mut(buf)
177 }
178 }
179
180 impl $crate::frame::TpmFrame for $name {
181 fn cc(&self) -> $crate::data::TpmCc {
182 Self::CC
183 }
184 fn handles(&self) -> usize {
185 Self::HANDLES
186 }
187 }
188
189 impl $crate::frame::TpmMarshalBody for $name {
190 #[allow(unused_variables)]
191 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
192 for handle in &self.handles {
193 $crate::TpmMarshal::marshal(handle, writer)?;
194 }
195 Ok(())
196 }
197 #[allow(unused_variables)]
198 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
199 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
200 Ok(())
201 }
202 }
203
204 impl $crate::TpmSized for $name {
205 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
206 fn len(&self) -> usize {
207 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
208 }
209 }
210
211 impl $crate::TpmMarshal for $name {
212 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
213 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
214 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
215 }
216 }
217 };
218
219 (
220 $(#[$meta:meta])*
221 wire: $wire:ident,
222 $vis:vis struct $name:ident {
223 $(pub $field_name:ident: $field_type:ty),*
224 $(,)?
225 }
226 ) => {
227 $(#[$meta])*
228 $vis struct $name {
229 $(pub $field_name: $field_type,)*
230 }
231
232 #[repr(transparent)]
233 $vis struct $wire([u8]);
234
235 impl $wire {
236 pub fn cast(buf: &[u8]) -> $crate::TpmResult<&Self>
243 where
244 $($field_type: for<'a> $crate::TpmField<'a>,)*
245 {
246 Self::validate(buf)?;
247
248 Ok(unsafe { Self::cast_unchecked(buf) })
250 }
251
252 pub fn cast_prefix(buf: &[u8]) -> $crate::TpmResult<(&Self, &[u8])>
259 where
260 $($field_type: for<'a> $crate::TpmField<'a>,)*
261 {
262 let wire_len = Self::validate_prefix(buf)?;
263 if buf.len() < wire_len {
264 return Err($crate::TpmError::UnexpectedEnd { offset: 0, needed: wire_len, available: buf.len() });
265 }
266
267 let (head, tail) = buf.split_at(wire_len);
268
269 Ok((unsafe { Self::cast_unchecked(head) }, tail))
271 }
272
273 #[must_use]
279 pub unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
280 let ptr = core::ptr::from_ref(buf) as *const Self;
281
282 unsafe { &*ptr }
285 }
286
287 #[must_use]
289 pub const fn as_bytes(&self) -> &[u8] {
290 &self.0
291 }
292
293 pub fn validate(buf: &[u8]) -> $crate::TpmResult<()>
300 where
301 $($field_type: for<'a> $crate::TpmField<'a>,)*
302 {
303 let wire_len = Self::validate_prefix(buf)?;
304
305 if buf.len() > wire_len {
306 return Err($crate::TpmError::TrailingData { offset: wire_len, actual: buf.len() - wire_len });
307 }
308
309 Ok(())
310 }
311
312 #[allow(unused_assignments, unused_mut, unused_variables)]
313 pub fn validate_prefix(buf: &[u8]) -> $crate::TpmResult<usize>
320 where
321 $($field_type: for<'a> $crate::TpmField<'a>,)*
322 {
323 let mut cursor = buf;
324 let mut consumed = 0usize;
325
326 $(
327 let before = cursor.len();
328 let (_, tail) = <$field_type as $crate::TpmField>::cast_prefix_field(cursor)?;
329 let field_len = before.checked_sub(tail.len()).ok_or(
330 $crate::TpmError::IntegerTooLarge { offset: consumed, value: $crate::tpm_value(tail.len()) },
331 )?;
332 consumed = consumed.checked_add(field_len).ok_or(
333 $crate::TpmError::IntegerTooLarge { offset: consumed, value: $crate::tpm_value(before) },
334 )?;
335 cursor = tail;
336 )*
337
338 Ok(consumed)
339 }
340
341 $crate::tpm_struct!(@wire_field_methods [], $(pub $field_name: $field_type),*);
342 }
343
344 impl AsRef<[u8]> for $wire {
345 fn as_ref(&self) -> &[u8] {
346 self.as_bytes()
347 }
348 }
349
350 impl<'a> $crate::TpmField<'a> for $name
351 where
352 $($field_type: for<'b> $crate::TpmField<'b>,)*
353 {
354 type View = &'a $wire;
355
356 fn cast_prefix_field(buf: &'a [u8]) -> $crate::TpmResult<(Self::View, &'a [u8])> {
357 $wire::cast_prefix(buf)
358 }
359 }
360
361 impl $crate::TpmSized for $name {
362 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
363 fn len(&self) -> usize {
364 0 $(+ $crate::TpmSized::len(&self.$field_name))*
365 }
366 }
367
368 impl $crate::TpmMarshal for $name {
369 #[allow(unused_variables)]
370 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
371 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
372 Ok(())
373 }
374 }
375
376 };
377}
378
379#[macro_export]
380macro_rules! tpm2b {
381 ($name:ident, $capacity:expr) => {
382 pub type $name = $crate::basic::TpmBuffer<$capacity>;
383 };
384}
385
386#[macro_export]
387macro_rules! tpm2b_struct {
388 (
389 $(#[$meta:meta])*
390 wire: $wire_ty:ident,
391 $wrapper_ty:ident, $inner_ty:ty) => {
392 $(#[$meta])*
393 pub struct $wrapper_ty {
394 pub inner: $inner_ty,
395 }
396
397 #[repr(transparent)]
398 pub struct $wire_ty([u8]);
399
400 impl $wire_ty {
401 pub fn cast(buf: &[u8]) -> $crate::TpmResult<&Self>
408 where
409 $inner_ty: for<'a> $crate::TpmField<'a>,
410 {
411 Self::validate(buf)?;
412
413 Ok(unsafe { Self::cast_unchecked(buf) })
415 }
416
417 pub fn cast_prefix(buf: &[u8]) -> $crate::TpmResult<(&Self, &[u8])>
424 where
425 $inner_ty: for<'a> $crate::TpmField<'a>,
426 {
427 let wire_len = Self::validate_prefix(buf)?;
428 let (head, tail) = buf.split_at(wire_len);
429
430 Ok((unsafe { Self::cast_unchecked(head) }, tail))
432 }
433
434 #[must_use]
441 pub unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
442 let ptr = core::ptr::from_ref(buf) as *const Self;
443
444 unsafe { &*ptr }
447 }
448
449 #[must_use]
451 pub const fn as_bytes(&self) -> &[u8] {
452 &self.0
453 }
454
455 pub fn inner(&self) -> $crate::TpmResult<<$inner_ty as $crate::TpmField<'_>>::View>
462 where
463 $inner_ty: for<'a> $crate::TpmField<'a>,
464 {
465 let inner_bytes = &self.0[<$crate::basic::TpmUint16 as $crate::TpmSized>::SIZE..];
466 let (inner, tail) = <$inner_ty as $crate::TpmField>::cast_prefix_field(inner_bytes)?;
467
468 if !tail.is_empty() {
469 return Err($crate::TpmError::TrailingData { offset: $crate::tpm_offset(&self.0, tail), actual: tail.len() });
470 }
471
472 Ok(inner)
473 }
474
475 pub fn validate(buf: &[u8]) -> $crate::TpmResult<()>
482 where
483 $inner_ty: for<'a> $crate::TpmField<'a>,
484 {
485 let wire_len = Self::validate_prefix(buf)?;
486
487 if buf.len() > wire_len {
488 return Err($crate::TpmError::TrailingData { offset: wire_len, actual: buf.len() - wire_len });
489 }
490
491 Ok(())
492 }
493
494 pub fn validate_prefix(buf: &[u8]) -> $crate::TpmResult<usize>
501 where
502 $inner_ty: for<'a> $crate::TpmField<'a>,
503 {
504 let (size_field, payload) = <$crate::basic::TpmUint16 as $crate::TpmCast>::cast_prefix(buf)?;
505 let payload_len = size_field.value() as usize;
506
507 if payload.len() < payload_len {
508 return Err($crate::TpmError::UnexpectedEnd { offset: $crate::tpm_offset(buf, payload), needed: payload_len, available: payload.len() });
509 }
510
511 let (inner_bytes, _) = payload.split_at(payload_len);
512 let (_, tail) = <$inner_ty as $crate::TpmField>::cast_prefix_field(inner_bytes)?;
513
514 if !tail.is_empty() {
515 return Err($crate::TpmError::TrailingData { offset: $crate::tpm_offset(buf, tail), actual: tail.len() });
516 }
517
518 Ok(<$crate::basic::TpmUint16 as $crate::TpmSized>::SIZE + payload_len)
519 }
520 }
521
522 impl AsRef<[u8]> for $wire_ty {
523 fn as_ref(&self) -> &[u8] {
524 self.as_bytes()
525 }
526 }
527
528 impl<'a> $crate::TpmField<'a> for $wrapper_ty
529 where
530 $inner_ty: for<'b> $crate::TpmField<'b>,
531 {
532 type View = &'a $wire_ty;
533
534 fn cast_prefix_field(buf: &'a [u8]) -> $crate::TpmResult<(Self::View, &'a [u8])> {
535 $wire_ty::cast_prefix(buf)
536 }
537 }
538
539 impl $crate::TpmSized for $wrapper_ty {
540 const SIZE: usize = $crate::basic::TpmUint16::SIZE + <$inner_ty>::SIZE;
541 fn len(&self) -> usize {
542 $crate::basic::TpmUint16::SIZE + $crate::TpmSized::len(&self.inner)
543 }
544 }
545
546 impl $crate::TpmMarshal for $wrapper_ty
547 where
548 $inner_ty: $crate::TpmSized,
549 {
550 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
551 let inner_len = $crate::TpmSized::len(&self.inner);
552 let len_field = <$crate::basic::TpmUint16>::try_from(inner_len)
553 .map_err(|_| $crate::TpmError::IntegerTooLarge { offset: writer.len(), value: $crate::tpm_value(inner_len) })?;
554 len_field.marshal(writer)?;
555 $crate::TpmMarshal::marshal(&self.inner, writer)
556 }
557 }
558
559 impl From<$inner_ty> for $wrapper_ty {
560 fn from(inner: $inner_ty) -> Self {
561 Self { inner }
562 }
563 }
564
565 impl core::ops::Deref for $wrapper_ty {
566 type Target = $inner_ty;
567 fn deref(&self) -> &Self::Target {
568 &self.inner
569 }
570 }
571
572 impl core::ops::DerefMut for $wrapper_ty {
573 fn deref_mut(&mut self) -> &mut Self::Target {
574 &mut self.inner
575 }
576 }
577 };
578}
579
580#[macro_export]
581macro_rules! tpml {
582 ($name:ident, $inner_ty:ty, $capacity:expr) => {
583 pub type $name = $crate::basic::TpmList<$inner_ty, $capacity>;
584 };
585}