1#[macro_export]
6macro_rules! tpm_struct {
7 (
8 $(#[$meta:meta])*
9 kind: Command,
10 name: $name:ident,
11 cc: $cc:expr,
12 handles: $count:literal,
13 parameters: {
14 $(pub $param_field:ident: $param_type:ty),*
15 $(,)?
16 }
17 ) => {
18 $(#[$meta])*
19 pub struct $name {
20 pub handles: [$crate::basic::TpmHandle; $count],
21 $(pub $param_field: $param_type,)*
22 }
23
24 impl $crate::frame::TpmHeader for $name {
25 const CC: $crate::data::TpmCc = $cc;
26 const HANDLES: usize = $count;
27 }
28
29 impl $name {
30 pub fn cast_frame(buf: &[u8]) -> $crate::TpmResult<&$crate::frame::TpmCommand> {
37 let command = <$crate::frame::TpmCommand>::cast(buf)?;
38
39 let cc = command.cc()?;
40 if cc != Self::CC {
41 return Err($crate::TpmError::InvalidCc(
42 $crate::TpmErrorValue::new(6).value(u64::from(cc.value())),
43 ));
44 }
45
46 Ok(command)
47 }
48
49 pub fn cast_frame_mut(
56 buf: &mut [u8],
57 ) -> $crate::TpmResult<&mut $crate::frame::TpmCommand> {
58 let command = <$crate::frame::TpmCommand>::cast_mut(buf)?;
59
60 let cc = command.cc()?;
61 if cc != Self::CC {
62 return Err($crate::TpmError::InvalidCc(
63 $crate::TpmErrorValue::new(6).value(u64::from(cc.value())),
64 ));
65 }
66
67 Ok(command)
68 }
69 }
70
71 impl $crate::frame::TpmFrame for $name {
72 fn cc(&self) -> $crate::data::TpmCc {
73 Self::CC
74 }
75 fn handles(&self) -> usize {
76 Self::HANDLES
77 }
78 }
79
80 impl $crate::TpmSized for $name {
81 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
82 fn len(&self) -> usize {
83 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
84 }
85 }
86
87 impl $crate::TpmMarshal for $name {
88 #[allow(unused_variables)]
89 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
90 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
91 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
92 }
93 }
94
95 impl $crate::frame::TpmMarshalBody for $name {
96 #[allow(unused_variables)]
97 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
98 for handle in &self.handles {
99 $crate::TpmMarshal::marshal(handle, writer)?;
100 }
101 Ok(())
102 }
103
104 #[allow(unused_variables)]
105 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
106 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
107 Ok(())
108 }
109 }
110
111 impl $crate::frame::TpmUnmarshalCommand for $name {
112 #[allow(unused_mut, unused_variables)]
113 fn unmarshal_body<'a>(
114 handles_buf: &'a [u8],
115 params_buf: &'a [u8],
116 ) -> $crate::TpmResult<(Self, &'a [u8])> {
117 let mut cursor = handles_buf;
118 let mut handles: [$crate::basic::TpmHandle; $count] = ::core::default::Default::default();
119 for handle in &mut handles {
120 let (val, tail) = <$crate::basic::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
121 *handle = val;
122 cursor = tail;
123 }
124
125 if !cursor.is_empty() {
126 return Err($crate::TpmError::TrailingData(
127 $crate::TpmErrorValue::at(handles_buf, cursor).actual(cursor.len()),
128 ));
129 }
130
131 let mut cursor = params_buf;
132 $(
133 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(cursor)?;
134 cursor = tail;
135 )*
136
137 Ok((
138 Self {
139 handles,
140 $($param_field,)*
141 },
142 cursor,
143 ))
144 }
145 }
146 };
147
148 (
149 $(#[$meta:meta])*
150 kind: Response,
151 name: $name:ident,
152 cc: $cc:expr,
153 handles: $count:literal,
154 parameters: {
155 $(pub $param_field:ident: $param_type:ty),*
156 $(,)?
157 }
158 ) => {
159 $(#[$meta])*
160 pub struct $name {
161 pub handles: [$crate::basic::TpmHandle; $count],
162 $(pub $param_field: $param_type,)*
163 }
164
165 impl $crate::frame::TpmHeader for $name {
166 const CC: $crate::data::TpmCc = $cc;
167 const HANDLES: usize = $count;
168 }
169
170 impl $name {
171 pub fn cast_frame(buf: &[u8]) -> $crate::TpmResult<&$crate::frame::TpmResponse> {
177 <$crate::frame::TpmResponse>::cast(buf)
178 }
179
180 pub fn cast_frame_mut(
186 buf: &mut [u8],
187 ) -> $crate::TpmResult<&mut $crate::frame::TpmResponse> {
188 <$crate::frame::TpmResponse>::cast_mut(buf)
189 }
190 }
191
192 impl $crate::frame::TpmFrame for $name {
193 fn cc(&self) -> $crate::data::TpmCc {
194 Self::CC
195 }
196 fn handles(&self) -> usize {
197 Self::HANDLES
198 }
199 }
200
201 impl $crate::frame::TpmMarshalBody for $name {
202 #[allow(unused_variables)]
203 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
204 for handle in &self.handles {
205 $crate::TpmMarshal::marshal(handle, writer)?;
206 }
207 Ok(())
208 }
209 #[allow(unused_variables)]
210 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
211 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
212 Ok(())
213 }
214 }
215
216 impl $crate::TpmSized for $name {
217 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
218 fn len(&self) -> usize {
219 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
220 }
221 }
222
223 impl $crate::TpmMarshal for $name {
224 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
225 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
226 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
227 }
228 }
229
230 impl $crate::frame::TpmUnmarshalResponse for $name {
231 #[allow(unused_mut, unused_variables)]
232 fn unmarshal_body(
233 tag: $crate::data::TpmSt,
234 buf: &[u8],
235 ) -> $crate::TpmResult<(Self, &[u8])> {
236 let mut cursor = buf;
237 let mut handles: [$crate::basic::TpmHandle; $count] = ::core::default::Default::default();
238 for handle in &mut handles {
239 let (val, tail) = <$crate::basic::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
240 *handle = val;
241 cursor = tail;
242 }
243
244 if tag == $crate::data::TpmSt::Sessions {
245 let (size, buf_after_size) =
246 <$crate::basic::TpmUint32 as $crate::TpmUnmarshal>::unmarshal(cursor)?;
247 let size = u32::from(size) as usize;
248 if buf_after_size.len() < size {
249 return Err($crate::TpmError::UnexpectedEnd(
250 $crate::TpmErrorValue::at(buf, buf_after_size).size(size, buf_after_size.len()),
251 ));
252 }
253 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
254
255 $(
256 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
257 params_cursor = tail;
258 )*
259
260 if !params_cursor.is_empty() {
261 return Err($crate::TpmError::TrailingData(
262 $crate::TpmErrorValue::at(buf, params_cursor).actual(params_cursor.len()),
263 ));
264 }
265
266 Ok((
267 Self {
268 handles,
269 $($param_field,)*
270 },
271 final_tail,
272 ))
273 } else {
274 let mut params_cursor = cursor;
275 $(
276 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
277 params_cursor = tail;
278 )*
279
280 Ok((
281 Self {
282 handles,
283 $($param_field,)*
284 },
285 params_cursor,
286 ))
287 }
288 }
289 }
290 };
291
292 (
293 $(#[$meta:meta])*
294 $vis:vis struct $name:ident {
295 $(pub $field_name:ident: $field_type:ty),*
296 $(,)?
297 }
298 ) => {
299 $(#[$meta])*
300 $vis struct $name {
301 $(pub $field_name: $field_type,)*
302 }
303
304 impl $crate::TpmSized for $name {
305 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
306 fn len(&self) -> usize {
307 0 $(+ $crate::TpmSized::len(&self.$field_name))*
308 }
309 }
310
311 impl $crate::TpmMarshal for $name {
312 #[allow(unused_variables)]
313 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
314 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
315 Ok(())
316 }
317 }
318
319 impl $crate::TpmUnmarshal for $name {
320 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
321 $(let ($field_name, buf) = <$field_type>::unmarshal(buf)?;)*
322 Ok((
323 Self {
324 $($field_name,)*
325 },
326 buf,
327 ))
328 }
329 }
330 };
331}
332
333#[macro_export]
334macro_rules! tpm2b {
335 ($name:ident, $capacity:expr) => {
336 pub type $name = $crate::basic::TpmBuffer<$capacity>;
337 };
338}
339
340#[macro_export]
341macro_rules! tpm2b_struct {
342 (
343 $(#[$meta:meta])*
344 $wrapper_ty:ident, $inner_ty:ty) => {
345 $(#[$meta])*
346 pub struct $wrapper_ty {
347 pub inner: $inner_ty,
348 }
349
350 impl $crate::TpmSized for $wrapper_ty {
351 const SIZE: usize = $crate::basic::TpmUint16::SIZE + <$inner_ty>::SIZE;
352 fn len(&self) -> usize {
353 $crate::basic::TpmUint16::SIZE + $crate::TpmSized::len(&self.inner)
354 }
355 }
356
357 impl $crate::TpmMarshal for $wrapper_ty
358 where
359 $inner_ty: $crate::TpmSized,
360 {
361 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
362 let inner_len = $crate::TpmSized::len(&self.inner);
363 let len_field = <$crate::basic::TpmUint16>::try_from(inner_len)
364 .map_err(|_| $crate::TpmError::IntegerTooLarge(
365 $crate::TpmErrorValue::new(writer.len()).value_usize(inner_len),
366 ))?;
367 len_field.marshal(writer)?;
368 $crate::TpmMarshal::marshal(&self.inner, writer)
369 }
370 }
371
372 impl $crate::TpmUnmarshal for $wrapper_ty {
373 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
374 let (size, buf_after_size) = <$crate::basic::TpmUint16 as $crate::TpmUnmarshal>::unmarshal(buf)?;
375 let size = u16::from(size) as usize;
376
377 if buf_after_size.len() < size {
378 return Err($crate::TpmError::UnexpectedEnd(
379 $crate::TpmErrorValue::at(buf, buf_after_size).size(size, buf_after_size.len()),
380 ));
381 }
382 let (inner_bytes, rest) = buf_after_size.split_at(size);
383
384 let (inner_val, tail) = <$inner_ty>::unmarshal(inner_bytes)?;
385
386 if !tail.is_empty() {
387 return Err($crate::TpmError::TrailingData(
388 $crate::TpmErrorValue::at(buf, tail).actual(tail.len()),
389 ));
390 }
391
392 Ok((Self { inner: inner_val }, rest))
393 }
394 }
395
396 impl From<$inner_ty> for $wrapper_ty {
397 fn from(inner: $inner_ty) -> Self {
398 Self { inner }
399 }
400 }
401
402 impl core::ops::Deref for $wrapper_ty {
403 type Target = $inner_ty;
404 fn deref(&self) -> &Self::Target {
405 &self.inner
406 }
407 }
408
409 impl core::ops::DerefMut for $wrapper_ty {
410 fn deref_mut(&mut self) -> &mut Self::Target {
411 &mut self.inner
412 }
413 }
414 };
415}
416
417#[macro_export]
418macro_rules! tpml {
419 ($name:ident, $inner_ty:ty, $capacity:expr) => {
420 pub type $name = $crate::basic::TpmList<$inner_ty, $capacity>;
421 };
422}