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: {
13 $($handle_field:ident),*
14 $(,)?
15 },
16 parameters: {
17 $(pub $param_field:ident: $param_type:ty),*
18 $(,)?
19 }
20 ) => {
21 $(#[$meta])*
22 pub struct $name {
23 $(pub $handle_field: $crate::TpmHandle,)*
24 $(pub $param_field: $param_type,)*
25 }
26
27 impl $crate::frame::TpmHeader for $name {
28 const CC: $crate::data::TpmCc = $cc;
29 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
30 }
31
32 impl $crate::frame::TpmFrame for $name {
33 fn cc(&self) -> $crate::data::TpmCc {
34 Self::CC
35 }
36 fn handles(&self) -> usize {
37 Self::HANDLES
38 }
39 }
40
41 impl $crate::TpmSized for $name {
42 const SIZE: usize = (Self::HANDLES * <$crate::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
43 fn len(&self) -> usize {
44 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
45 }
46 }
47
48 impl $crate::TpmMarshal for $name {
49 #[allow(unused_variables)]
50 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
51 <Self as $crate::frame::TpmBodyMarshal>::marshal_handles(self, writer)?;
52 <Self as $crate::frame::TpmBodyMarshal>::marshal_parameters(self, writer)
53 }
54 }
55
56 impl $crate::frame::TpmBodyMarshal for $name {
57 #[allow(unused_variables)]
58 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
59 $($crate::TpmMarshal::marshal(&self.$handle_field, writer)?;)*
60 Ok(())
61 }
62
63 #[allow(unused_variables)]
64 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
65 $($crate::TpmMarshal::marshal(&self.$param_field, writer)?;)*
66 Ok(())
67 }
68 }
69
70 impl $crate::frame::TpmCommandBodyUnmarshal for $name {
71 #[allow(unused_mut, unused_variables)]
72 fn unmarshal_body<'a>(
73 handles: &'a [u8],
74 params: &'a [u8],
75 ) -> $crate::TpmUnmarshalResult<(Self, &'a [u8])> {
76 let mut cursor = handles;
77 $(
78 let ($handle_field, tail) = <$crate::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
79 cursor = tail;
80 )*
81
82 if !cursor.is_empty() {
83 return Err($crate::TpmUnmarshalError::TrailingData);
84 }
85
86 let mut cursor = params;
87 $(
88 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(cursor)?;
89 cursor = tail;
90 )*
91
92 Ok((
93 Self {
94 $($handle_field,)*
95 $($param_field,)*
96 },
97 cursor,
98 ))
99 }
100 }
101 };
102
103 (
104 $(#[$meta:meta])*
105 kind: Response,
106 name: $name:ident,
107 cc: $cc:expr,
108 handles: {
109 $($handle_field:ident),*
110 $(,)?
111 },
112 parameters: {
113 $(pub $param_field:ident: $param_type:ty),*
114 $(,)?
115 }
116 ) => {
117 $(#[$meta])*
118 pub struct $name {
119 $(pub $handle_field: $crate::TpmHandle,)*
120 $(pub $param_field: $param_type,)*
121 }
122
123 impl $crate::frame::TpmHeader for $name {
124 const CC: $crate::data::TpmCc = $cc;
125 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
126 }
127
128 impl $crate::frame::TpmFrame for $name {
129 fn cc(&self) -> $crate::data::TpmCc {
130 Self::CC
131 }
132 fn handles(&self) -> usize {
133 Self::HANDLES
134 }
135 }
136
137 impl $crate::frame::TpmBodyMarshal for $name {
138 #[allow(unused_variables)]
139 fn marshal_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
140 $($crate::TpmMarshal::marshal(&self.$handle_field, writer)?;)*
141 Ok(())
142 }
143 #[allow(unused_variables)]
144 fn marshal_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
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::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
152 fn len(&self) -> usize {
153 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
154 }
155 }
156
157 impl $crate::TpmMarshal for $name {
158 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
159 <Self as $crate::frame::TpmBodyMarshal>::marshal_handles(self, writer)?;
160 <Self as $crate::frame::TpmBodyMarshal>::marshal_parameters(self, writer)
161 }
162 }
163
164 impl $crate::frame::TpmResponseBodyUnmarshal for $name {
165 #[allow(unused_mut, unused_variables)]
166 fn unmarshal_body(
167 tag: $crate::data::TpmSt,
168 buf: &[u8],
169 ) -> $crate::TpmUnmarshalResult<(Self, &[u8])> {
170 let mut cursor = buf;
171 $(
172 let ($handle_field, tail) = <$crate::TpmHandle as $crate::TpmUnmarshal>::unmarshal(cursor)?;
173 cursor = tail;
174 )*
175
176 if tag == $crate::data::TpmSt::Sessions {
177 let (size, buf_after_size) = <u32 as $crate::TpmUnmarshal>::unmarshal(cursor)?;
178 let size = size as usize;
179 if buf_after_size.len() < size {
180 return Err($crate::TpmUnmarshalError::TruncatedData);
181 }
182 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
183
184 $(
185 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
186 params_cursor = tail;
187 )*
188
189 if !params_cursor.is_empty() {
190 return Err($crate::TpmUnmarshalError::TrailingData);
191 }
192
193 Ok((
194 Self {
195 $($handle_field,)*
196 $($param_field,)*
197 },
198 final_tail,
199 ))
200 } else {
201 let mut params_cursor = cursor;
202 $(
203 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
204 params_cursor = tail;
205 )*
206
207 Ok((
208 Self {
209 $($handle_field,)*
210 $($param_field,)*
211 },
212 params_cursor,
213 ))
214 }
215 }
216 }
217 };
218
219 (
220 $(#[$meta:meta])*
221 $vis:vis struct $name:ident {
222 $(pub $field_name:ident: $field_type:ty),*
223 $(,)?
224 }
225 ) => {
226 $(#[$meta])*
227 $vis struct $name {
228 $(pub $field_name: $field_type,)*
229 }
230
231 impl $crate::TpmSized for $name {
232 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
233 fn len(&self) -> usize {
234 0 $(+ $crate::TpmSized::len(&self.$field_name))*
235 }
236 }
237
238 impl $crate::TpmMarshal for $name {
239 #[allow(unused_variables)]
240 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmMarshalResult<()> {
241 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
242 Ok(())
243 }
244 }
245
246 impl $crate::TpmUnmarshal for $name {
247 fn unmarshal(buf: &[u8]) -> $crate::TpmUnmarshalResult<(Self, &[u8])> {
248 $(let ($field_name, buf) = <$field_type>::unmarshal(buf)?;)*
249 Ok((
250 Self {
251 $($field_name,)*
252 },
253 buf,
254 ))
255 }
256 }
257 };
258}