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 no_sessions: $no_sessions:expr,
13 with_sessions: $with_sessions:expr,
14 handles: {
15 $(pub $handle_field:ident: $handle_type:ty),*
16 $(,)?
17 },
18 parameters: {
19 $(pub $param_field:ident: $param_type:ty),*
20 $(,)?
21 }
22 ) => {
23 $(#[$meta])*
24 pub struct $name {
25 $(pub $handle_field: $handle_type,)*
26 $(pub $param_field: $param_type,)*
27 }
28
29 impl $name {
30 #[allow(unused_variables)]
31 pub(crate) fn build_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
32 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
33 Ok(())
34 }
35
36 #[allow(unused_variables)]
37 pub(crate) fn build_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
38 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
39 Ok(())
40 }
41 }
42
43 impl $crate::TpmSized for $name {
44 const SIZE: usize = 0 $(+ <$handle_type>::SIZE)* $(+ <$param_type>::SIZE)*;
45 fn len(&self) -> usize {
46 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
47 }
48 }
49
50 impl $crate::TpmBuild for $name {
51 #[allow(unused_variables)]
52 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
53 self.build_handles(writer)?;
54 self.build_parameters(writer)
55 }
56 }
57
58 impl $crate::message::TpmHeaderCommand for $name {
59 #[allow(unused_variables)]
60 fn build_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
61 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
62 Ok(())
63 }
64
65 #[allow(unused_variables)]
66 fn build_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
67 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
68 Ok(())
69 }
70 }
71
72 impl $crate::TpmParse for $name {
73 #[allow(unused_mut)]
74 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
75 let mut cursor = buf;
76 $(
77 let ($handle_field, tail) = <$handle_type>::parse(cursor)?;
78 cursor = tail;
79 )*
80 $(
81 let ($param_field, tail) = <$param_type>::parse(cursor)?;
82 cursor = tail;
83 )*
84 Ok((
85 Self {
86 $($handle_field,)*
87 $($param_field,)*
88 },
89 cursor,
90 ))
91 }
92 }
93
94 impl $crate::message::TpmHeader for $name {
95 const COMMAND: $crate::data::TpmCc = $cc;
96 const NO_SESSIONS: bool = $no_sessions;
97 const WITH_SESSIONS: bool = $with_sessions;
98 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
99 }
100 };
101
102 (
103 $(#[$meta:meta])*
104 kind: Response,
105 name: $name:ident,
106 cc: $cc:expr,
107 no_sessions: $no_sessions:expr,
108 with_sessions: $with_sessions:expr,
109 handles: {
110 $(pub $handle_field:ident: $handle_type:ty),*
111 $(,)?
112 },
113 parameters: {
114 $(pub $param_field:ident: $param_type:ty),*
115 $(,)?
116 }
117 ) => {
118 $(#[$meta])*
119 pub struct $name {
120 $(pub $handle_field: $handle_type,)*
121 $(pub $param_field: $param_type,)*
122 }
123
124 impl $crate::TpmSized for $name {
125 const SIZE: usize = 0 $(+ <$handle_type>::SIZE)* $(+ <$param_type>::SIZE)*;
126 fn len(&self) -> usize {
127 let params_len: usize = 0 $(+ $crate::TpmSized::len(&self.$param_field))*;
128 let handles_len: usize = 0 $(+ $crate::TpmSized::len(&self.$handle_field))*;
129 let parameter_area_size_field_len: usize = if $with_sessions {
130 core::mem::size_of::<u32>()
131 } else {
132 0
133 };
134 handles_len + parameter_area_size_field_len + params_len
135 }
136 }
137
138 impl $crate::TpmBuild for $name {
139 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
140 let params_len: usize = 0 $(+ $crate::TpmSized::len(&self.$param_field))*;
141 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
142 if $with_sessions {
143 let params_len_u32 = u32::try_from(params_len)
144 .map_err(|_| $crate::TpmErrorKind::ValueTooLarge)?;
145 $crate::TpmBuild::build(¶ms_len_u32, writer)?;
146 }
147 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
148 Ok(())
149 }
150 }
151
152 impl $crate::TpmParse for $name {
153 #[allow(unused_mut)]
154 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
155 let mut cursor = buf;
156 $(
157 let ($handle_field, tail) = <$handle_type>::parse(cursor)?;
158 cursor = tail;
159 )*
160
161 if $with_sessions {
162 let (size, buf_after_size) = u32::parse(cursor)?;
163 let size = size as usize;
164 if buf_after_size.len() < size {
165 return Err($crate::TpmErrorKind::Boundary);
166 }
167 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
168
169 $(
170 let ($param_field, tail) = <$param_type>::parse(params_cursor)?;
171 params_cursor = tail;
172 )*
173
174 if !params_cursor.is_empty() {
175 return Err($crate::TpmErrorKind::TrailingData);
176 }
177
178 Ok((
179 Self {
180 $($handle_field,)*
181 $($param_field,)*
182 },
183 final_tail,
184 ))
185 } else {
186 let mut params_cursor = cursor;
187 $(
188 let ($param_field, tail) = <$param_type>::parse(params_cursor)?;
189 params_cursor = tail;
190 )*
191
192 Ok((
193 Self {
194 $($handle_field,)*
195 $($param_field,)*
196 },
197 params_cursor,
198 ))
199 }
200 }
201 }
202
203 impl $crate::message::TpmHeader for $name {
204 const COMMAND: $crate::data::TpmCc = $cc;
205 const NO_SESSIONS: bool = $no_sessions;
206 const WITH_SESSIONS: bool = $with_sessions;
207 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
208 }
209 };
210
211 (
212 $(#[$meta:meta])*
213 $vis:vis struct $name:ident {
214 $(pub $field_name:ident: $field_type:ty),*
215 $(,)?
216 }
217 ) => {
218 $(#[$meta])*
219 $vis struct $name {
220 $(pub $field_name: $field_type,)*
221 }
222
223 impl $crate::TpmSized for $name {
224 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
225 fn len(&self) -> usize {
226 0 $(+ $crate::TpmSized::len(&self.$field_name))*
227 }
228 }
229
230 impl $crate::TpmBuild for $name {
231 #[allow(unused_variables)]
232 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
233 $( $crate::TpmBuild::build(&self.$field_name, writer)?; )*
234 Ok(())
235 }
236 }
237
238 impl $crate::TpmParse for $name {
239 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
240 $(let ($field_name, buf) = <$field_type>::parse(buf)?;)*
241 Ok((
242 Self {
243 $($field_name,)*
244 },
245 buf,
246 ))
247 }
248 }
249 };
250}
251
252#[macro_export]
253macro_rules! tpm_tagged_struct {
254 (
255 $(#[$outer:meta])*
256 $vis:vis struct $name:ident {
257 pub $tag_field:ident: $tag_ty:ty,
258 pub $value_field:ident: $value_ty:ty,
259 }
260 ) => {
261 $(#[$outer])*
262 $vis struct $name {
263 pub $tag_field: $tag_ty,
264 pub $value_field: $value_ty,
265 }
266
267 impl $crate::TpmTagged for $name {
268 type Tag = $tag_ty;
269 type Value = $value_ty;
270 }
271
272 impl $crate::TpmSized for $name {
273 const SIZE: usize = <$tag_ty>::SIZE + <$value_ty>::SIZE;
274 fn len(&self) -> usize {
275 $crate::TpmSized::len(&self.$tag_field) + $crate::TpmSized::len(&self.$value_field)
276 }
277 }
278
279 impl $crate::TpmBuild for $name {
280 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
281 $crate::TpmBuild::build(&self.$tag_field, writer)?;
282 $crate::TpmBuild::build(&self.$value_field, writer)
283 }
284 }
285
286 impl $crate::TpmParse for $name {
287 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
288 let ($tag_field, buf) = <$tag_ty>::parse(buf)?;
289 let ($value_field, buf) =
290 <$value_ty as $crate::TpmParseTagged>::parse_tagged($tag_field, buf)?;
291 Ok((
292 Self {
293 $tag_field,
294 $value_field,
295 },
296 buf,
297 ))
298 }
299 }
300 };
301}