tpm2_protocol/macro/
struct.rs1#[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 if command.cc()? != Self::CC {
40 return Err($crate::TpmProtocolError::InvalidCc);
41 }
42
43 Ok(command)
44 }
45
46 pub fn cast_frame_mut(
53 buf: &mut [u8],
54 ) -> $crate::TpmResult<&mut $crate::frame::TpmCommand> {
55 let command = <$crate::frame::TpmCommand>::cast_mut(buf)?;
56
57 if command.cc()? != Self::CC {
58 return Err($crate::TpmProtocolError::InvalidCc);
59 }
60
61 Ok(command)
62 }
63 }
64
65 impl $crate::frame::TpmFrame for $name {
66 fn cc(&self) -> $crate::data::TpmCc {
67 Self::CC
68 }
69 fn handles(&self) -> usize {
70 Self::HANDLES
71 }
72 }
73
74 impl $crate::TpmSized for $name {
75 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
76 fn len(&self) -> usize {
77 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
78 }
79 }
80
81 impl $crate::TpmMarshal for $name {
82 #[allow(unused_variables)]
83 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
84 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
85 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
86 }
87 }
88
89 impl $crate::frame::TpmMarshalBody for $name {
90 #[allow(unused_variables)]
91 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
92 for handle in &self.handles {
93 $crate::TpmMarshal::marshal(handle, writer)?;
94 }
95 Ok(())
96 }
97
98 #[allow(unused_variables)]
99 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
100 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
101 Ok(())
102 }
103 }
104
105 impl $crate::frame::TpmUnmarshalCommand for $name {
106 #[allow(unused_mut, unused_variables)]
107 fn unmarshal_body<'a>(
108 handles_buf: &'a [u8],
109 params_buf: &'a [u8],
110 ) -> $crate::TpmResult<(Self, &'a [u8])> {
111 let mut cursor = handles_buf;
112 let mut handles: [$crate::basic::TpmHandle; $count] = ::core::default::Default::default();
113 for handle in &mut handles {
114 let (val, tail) = <$crate::basic::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
115 *handle = val;
116 cursor = tail;
117 }
118
119 if !cursor.is_empty() {
120 return Err($crate::TpmProtocolError::TrailingData);
121 }
122
123 let mut cursor = params_buf;
124 $(
125 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(cursor)?;
126 cursor = tail;
127 )*
128
129 Ok((
130 Self {
131 handles,
132 $($param_field,)*
133 },
134 cursor,
135 ))
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 impl $crate::frame::TpmUnmarshalResponse for $name {
223 #[allow(unused_mut, unused_variables)]
224 fn unmarshal_body(
225 tag: $crate::data::TpmSt,
226 buf: &[u8],
227 ) -> $crate::TpmResult<(Self, &[u8])> {
228 let mut cursor = buf;
229 let mut handles: [$crate::basic::TpmHandle; $count] = ::core::default::Default::default();
230 for handle in &mut handles {
231 let (val, tail) = <$crate::basic::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
232 *handle = val;
233 cursor = tail;
234 }
235
236 if tag == $crate::data::TpmSt::Sessions {
237 let (size, buf_after_size) =
238 <$crate::basic::TpmUint32 as $crate::TpmUnmarshal>::unmarshal(cursor)?;
239 let size = u32::from(size) as usize;
240 if buf_after_size.len() < size {
241 return Err($crate::TpmProtocolError::UnexpectedEnd);
242 }
243 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
244
245 $(
246 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
247 params_cursor = tail;
248 )*
249
250 if !params_cursor.is_empty() {
251 return Err($crate::TpmProtocolError::TrailingData);
252 }
253
254 Ok((
255 Self {
256 handles,
257 $($param_field,)*
258 },
259 final_tail,
260 ))
261 } else {
262 let mut params_cursor = cursor;
263 $(
264 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
265 params_cursor = tail;
266 )*
267
268 Ok((
269 Self {
270 handles,
271 $($param_field,)*
272 },
273 params_cursor,
274 ))
275 }
276 }
277 }
278 };
279
280 (
281 $(#[$meta:meta])*
282 $vis:vis struct $name:ident {
283 $(pub $field_name:ident: $field_type:ty),*
284 $(,)?
285 }
286 ) => {
287 $(#[$meta])*
288 $vis struct $name {
289 $(pub $field_name: $field_type,)*
290 }
291
292 impl $crate::TpmSized for $name {
293 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
294 fn len(&self) -> usize {
295 0 $(+ $crate::TpmSized::len(&self.$field_name))*
296 }
297 }
298
299 impl $crate::TpmMarshal for $name {
300 #[allow(unused_variables)]
301 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
302 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
303 Ok(())
304 }
305 }
306
307 impl $crate::TpmUnmarshal for $name {
308 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
309 $(let ($field_name, buf) = <$field_type>::unmarshal(buf)?;)*
310 Ok((
311 Self {
312 $($field_name,)*
313 },
314 buf,
315 ))
316 }
317 }
318 };
319}
320
321#[macro_export]
322macro_rules! tpm2b {
323 ($name:ident, $capacity:expr) => {
324 pub type $name = $crate::basic::TpmBuffer<$capacity>;
325 };
326}
327
328#[macro_export]
329macro_rules! tpm2b_struct {
330 (
331 $(#[$meta:meta])*
332 $wrapper_ty:ident, $inner_ty:ty) => {
333 $(#[$meta])*
334 pub struct $wrapper_ty {
335 pub inner: $inner_ty,
336 }
337
338 impl $crate::TpmSized for $wrapper_ty {
339 const SIZE: usize = $crate::basic::TpmUint16::SIZE + <$inner_ty>::SIZE;
340 fn len(&self) -> usize {
341 $crate::basic::TpmUint16::SIZE + $crate::TpmSized::len(&self.inner)
342 }
343 }
344
345 impl $crate::TpmMarshal for $wrapper_ty
346 where
347 $inner_ty: $crate::TpmSized,
348 {
349 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
350 let inner_len = $crate::TpmSized::len(&self.inner);
351 let len_field = <$crate::basic::TpmUint16>::try_from(inner_len)
352 .map_err(|_| $crate::TpmProtocolError::IntegerTooLarge)?;
353 len_field.marshal(writer)?;
354 $crate::TpmMarshal::marshal(&self.inner, writer)
355 }
356 }
357
358 impl $crate::TpmUnmarshal for $wrapper_ty {
359 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
360 let (size, buf_after_size) = <$crate::basic::TpmUint16 as $crate::TpmUnmarshal>::unmarshal(buf)?;
361 let size = u16::from(size) as usize;
362
363 if buf_after_size.len() < size {
364 return Err($crate::TpmProtocolError::UnexpectedEnd);
365 }
366 let (inner_bytes, rest) = buf_after_size.split_at(size);
367
368 let (inner_val, tail) = <$inner_ty>::unmarshal(inner_bytes)?;
369
370 if !tail.is_empty() {
371 return Err($crate::TpmProtocolError::TrailingData);
372 }
373
374 Ok((Self { inner: inner_val }, rest))
375 }
376 }
377
378 impl From<$inner_ty> for $wrapper_ty {
379 fn from(inner: $inner_ty) -> Self {
380 Self { inner }
381 }
382 }
383
384 impl core::ops::Deref for $wrapper_ty {
385 type Target = $inner_ty;
386 fn deref(&self) -> &Self::Target {
387 &self.inner
388 }
389 }
390
391 impl core::ops::DerefMut for $wrapper_ty {
392 fn deref_mut(&mut self) -> &mut Self::Target {
393 &mut self.inner
394 }
395 }
396 };
397}
398
399#[macro_export]
400macro_rules! tpml {
401 ($name:ident, $inner_ty:ty, $capacity:expr) => {
402 pub type $name = $crate::basic::TpmList<$inner_ty, $capacity>;
403 };
404}