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 $crate::frame::TpmFrame for $name {
30 fn cc(&self) -> $crate::data::TpmCc {
31 Self::CC
32 }
33 fn handles(&self) -> usize {
34 Self::HANDLES
35 }
36 }
37
38 impl $crate::TpmSized for $name {
39 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
40 fn len(&self) -> usize {
41 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
42 }
43 }
44
45 impl $crate::TpmMarshal for $name {
46 #[allow(unused_variables)]
47 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
48 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
49 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
50 }
51 }
52
53 impl $crate::frame::TpmMarshalBody for $name {
54 #[allow(unused_variables)]
55 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
56 for handle in &self.handles {
57 $crate::TpmMarshal::marshal(handle, writer)?;
58 }
59 Ok(())
60 }
61
62 #[allow(unused_variables)]
63 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
64 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
65 Ok(())
66 }
67 }
68
69 impl $crate::frame::TpmUnmarshalCommand for $name {
70 #[allow(unused_mut, unused_variables)]
71 fn unmarshal_body<'a>(
72 handles_buf: &'a [u8],
73 params_buf: &'a [u8],
74 ) -> $crate::TpmResult<(Self, &'a [u8])> {
75 let mut cursor = handles_buf;
76 let mut handles: [$crate::basic::TpmHandle; $count] = ::core::default::Default::default();
77 for handle in &mut handles {
78 let (val, tail) = <$crate::basic::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
79 *handle = val;
80 cursor = tail;
81 }
82
83 if !cursor.is_empty() {
84 return Err($crate::TpmProtocolError::TrailingData);
85 }
86
87 let mut cursor = params_buf;
88 $(
89 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(cursor)?;
90 cursor = tail;
91 )*
92
93 Ok((
94 Self {
95 handles,
96 $($param_field,)*
97 },
98 cursor,
99 ))
100 }
101 }
102 };
103
104 (
105 $(#[$meta:meta])*
106 kind: Response,
107 name: $name:ident,
108 cc: $cc:expr,
109 handles: $count:literal,
110 parameters: {
111 $(pub $param_field:ident: $param_type:ty),*
112 $(,)?
113 }
114 ) => {
115 $(#[$meta])*
116 pub struct $name {
117 pub handles: [$crate::basic::TpmHandle; $count],
118 $(pub $param_field: $param_type,)*
119 }
120
121 impl $crate::frame::TpmHeader for $name {
122 const CC: $crate::data::TpmCc = $cc;
123 const HANDLES: usize = $count;
124 }
125
126 impl $crate::frame::TpmFrame for $name {
127 fn cc(&self) -> $crate::data::TpmCc {
128 Self::CC
129 }
130 fn handles(&self) -> usize {
131 Self::HANDLES
132 }
133 }
134
135 impl $crate::frame::TpmMarshalBody for $name {
136 #[allow(unused_variables)]
137 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
138 for handle in &self.handles {
139 $crate::TpmMarshal::marshal(handle, writer)?;
140 }
141 Ok(())
142 }
143 #[allow(unused_variables)]
144 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
145 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
146 Ok(())
147 }
148 }
149
150 impl $crate::TpmSized for $name {
151 const SIZE: usize = (Self::HANDLES * <$crate::basic::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
152 fn len(&self) -> usize {
153 (self.handles.len() * <$crate::basic::TpmHandle>::SIZE) $(+ $crate::TpmSized::len(&self.$param_field))*
154 }
155 }
156
157 impl $crate::TpmMarshal for $name {
158 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
159 <Self as $crate::frame::TpmMarshalBody>::marshal_handles(self, writer)?;
160 <Self as $crate::frame::TpmMarshalBody>::marshal_parameters(self, writer)
161 }
162 }
163
164 impl $crate::frame::TpmUnmarshalResponse for $name {
165 #[allow(unused_mut, unused_variables)]
166 fn unmarshal_body(
167 tag: $crate::data::TpmSt,
168 buf: &[u8],
169 ) -> $crate::TpmResult<(Self, &[u8])> {
170 let mut cursor = buf;
171 let mut handles: [$crate::basic::TpmHandle; $count] = ::core::default::Default::default();
172 for handle in &mut handles {
173 let (val, tail) = <$crate::basic::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
174 *handle = val;
175 cursor = tail;
176 }
177
178 if tag == $crate::data::TpmSt::Sessions {
179 let (size, buf_after_size) =
180 <$crate::basic::TpmUint32 as $crate::TpmUnmarshal>::unmarshal(cursor)?;
181 let size = u32::from(size) as usize;
182 if buf_after_size.len() < size {
183 return Err($crate::TpmProtocolError::UnexpectedEnd);
184 }
185 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
186
187 $(
188 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
189 params_cursor = tail;
190 )*
191
192 if !params_cursor.is_empty() {
193 return Err($crate::TpmProtocolError::TrailingData);
194 }
195
196 Ok((
197 Self {
198 handles,
199 $($param_field,)*
200 },
201 final_tail,
202 ))
203 } else {
204 let mut params_cursor = cursor;
205 $(
206 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
207 params_cursor = tail;
208 )*
209
210 Ok((
211 Self {
212 handles,
213 $($param_field,)*
214 },
215 params_cursor,
216 ))
217 }
218 }
219 }
220 };
221
222 (
223 $(#[$meta:meta])*
224 $vis:vis struct $name:ident {
225 $(pub $field_name:ident: $field_type:ty),*
226 $(,)?
227 }
228 ) => {
229 $(#[$meta])*
230 $vis struct $name {
231 $(pub $field_name: $field_type,)*
232 }
233
234 impl $crate::TpmSized for $name {
235 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
236 fn len(&self) -> usize {
237 0 $(+ $crate::TpmSized::len(&self.$field_name))*
238 }
239 }
240
241 impl $crate::TpmMarshal for $name {
242 #[allow(unused_variables)]
243 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
244 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
245 Ok(())
246 }
247 }
248
249 impl $crate::TpmUnmarshal for $name {
250 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
251 $(let ($field_name, buf) = <$field_type>::unmarshal(buf)?;)*
252 Ok((
253 Self {
254 $($field_name,)*
255 },
256 buf,
257 ))
258 }
259 }
260 };
261}
262
263#[macro_export]
264macro_rules! tpm2b {
265 ($name:ident, $capacity:expr) => {
266 pub type $name = $crate::basic::TpmBuffer<$capacity>;
267 };
268}
269
270#[macro_export]
271macro_rules! tpm2b_struct {
272 (
273 $(#[$meta:meta])*
274 $wrapper_ty:ident, $inner_ty:ty) => {
275 $(#[$meta])*
276 pub struct $wrapper_ty {
277 pub inner: $inner_ty,
278 }
279
280 impl $crate::TpmSized for $wrapper_ty {
281 const SIZE: usize = $crate::basic::TpmUint16::SIZE + <$inner_ty>::SIZE;
282 fn len(&self) -> usize {
283 $crate::basic::TpmUint16::SIZE + $crate::TpmSized::len(&self.inner)
284 }
285 }
286
287 impl $crate::TpmMarshal for $wrapper_ty
288 where
289 $inner_ty: $crate::TpmSized,
290 {
291 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
292 let inner_len = $crate::TpmSized::len(&self.inner);
293 let len_field = <$crate::basic::TpmUint16>::try_from(inner_len)
294 .map_err(|_| $crate::TpmProtocolError::IntegerTooLarge)?;
295 len_field.marshal(writer)?;
296 $crate::TpmMarshal::marshal(&self.inner, writer)
297 }
298 }
299
300 impl $crate::TpmUnmarshal for $wrapper_ty {
301 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
302 let (size, buf_after_size) = <$crate::basic::TpmUint16 as $crate::TpmUnmarshal>::unmarshal(buf)?;
303 let size = u16::from(size) as usize;
304
305 if buf_after_size.len() < size {
306 return Err($crate::TpmProtocolError::UnexpectedEnd);
307 }
308 let (inner_bytes, rest) = buf_after_size.split_at(size);
309
310 let (inner_val, tail) = <$inner_ty>::unmarshal(inner_bytes)?;
311
312 if !tail.is_empty() {
313 return Err($crate::TpmProtocolError::TrailingData);
314 }
315
316 Ok((Self { inner: inner_val }, rest))
317 }
318 }
319
320 impl From<$inner_ty> for $wrapper_ty {
321 fn from(inner: $inner_ty) -> Self {
322 Self { inner }
323 }
324 }
325
326 impl core::ops::Deref for $wrapper_ty {
327 type Target = $inner_ty;
328 fn deref(&self) -> &Self::Target {
329 &self.inner
330 }
331 }
332
333 impl core::ops::DerefMut for $wrapper_ty {
334 fn deref_mut(&mut self) -> &mut Self::Target {
335 &mut self.inner
336 }
337 }
338 };
339}
340
341#[macro_export]
342macro_rules! tpml {
343 ($name:ident, $inner_ty:ty, $capacity:expr) => {
344 pub type $name = $crate::basic::TpmList<$inner_ty, $capacity>;
345 };
346}