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