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::message::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::TpmSized for $name {
33 const SIZE: usize = (Self::HANDLES * <$crate::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
34 fn len(&self) -> usize {
35 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
36 }
37 }
38
39 impl $crate::TpmBuild for $name {
40 #[allow(unused_variables)]
41 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
42 <Self as $crate::message::TpmBodyBuild>::build_handles(self, writer)?;
43 <Self as $crate::message::TpmBodyBuild>::build_parameters(self, writer)
44 }
45 }
46
47 impl $crate::message::TpmBodyBuild for $name {
48 #[allow(unused_variables)]
49 fn build_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
50 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
51 Ok(())
52 }
53
54 #[allow(unused_variables)]
55 fn build_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
56 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
57 Ok(())
58 }
59 }
60
61 impl $crate::message::TpmCommandBodyParse for $name {
62 #[allow(unused_mut, unused_variables)]
63 fn parse_body<'a>(
64 handles: &'a [u8],
65 params: &'a [u8],
66 ) -> $crate::TpmResult<(Self, &'a [u8])> {
67 let mut cursor = handles;
68 $(
69 let ($handle_field, tail) = <$crate::TpmHandle as $crate::TpmParse>::parse(cursor)?;
70 cursor = tail;
71 )*
72
73 if !cursor.is_empty() {
74 return Err($crate::TpmError::TrailingData);
75 }
76
77 let mut cursor = params;
78 $(
79 let ($param_field, tail) = <$param_type as $crate::TpmParse>::parse(cursor)?;
80 cursor = tail;
81 )*
82
83 Ok((
84 Self {
85 $($handle_field,)*
86 $($param_field,)*
87 },
88 cursor,
89 ))
90 }
91 }
92 };
93
94 (
95 $(#[$meta:meta])*
96 kind: Response,
97 name: $name:ident,
98 cc: $cc:expr,
99 handles: {
100 $($handle_field:ident),*
101 $(,)?
102 },
103 parameters: {
104 $(pub $param_field:ident: $param_type:ty),*
105 $(,)?
106 }
107 ) => {
108 $(#[$meta])*
109 pub struct $name {
110 $(pub $handle_field: $crate::TpmHandle,)*
111 $(pub $param_field: $param_type,)*
112 }
113
114 impl $crate::message::TpmHeader for $name {
115 const CC: $crate::data::TpmCc = $cc;
116 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
117 }
118
119 impl $crate::message::TpmBodyBuild for $name {
120 #[allow(unused_variables)]
121 fn build_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
122 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
123 Ok(())
124 }
125 #[allow(unused_variables)]
126 fn build_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
127 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
128 Ok(())
129 }
130 }
131
132 impl $crate::TpmSized for $name {
133 const SIZE: usize = (Self::HANDLES * <$crate::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
134 fn len(&self) -> usize {
135 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
136 }
137 }
138
139 impl $crate::TpmBuild for $name {
140 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
141 <Self as $crate::message::TpmBodyBuild>::build_handles(self, writer)?;
142 <Self as $crate::message::TpmBodyBuild>::build_parameters(self, writer)
143 }
144 }
145
146 impl $crate::message::TpmResponseBodyParse for $name {
147 #[allow(unused_mut, unused_variables)]
148 fn parse_body(
149 tag: $crate::data::TpmSt,
150 buf: &[u8],
151 ) -> $crate::TpmResult<(Self, &[u8])> {
152 let mut cursor = buf;
153 $(
154 let ($handle_field, tail) = <$crate::TpmHandle as $crate::TpmParse>::parse(cursor)?;
155 cursor = tail;
156 )*
157
158 if tag == $crate::data::TpmSt::Sessions {
159 let (size, buf_after_size) = <u32 as $crate::TpmParse>::parse(cursor)?;
160 let size = size as usize;
161 if buf_after_size.len() < size {
162 return Err($crate::TpmError::Truncated);
163 }
164 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
165
166 $(
167 let ($param_field, tail) = <$param_type as $crate::TpmParse>::parse(params_cursor)?;
168 params_cursor = tail;
169 )*
170
171 if !params_cursor.is_empty() {
172 return Err($crate::TpmError::TrailingData);
173 }
174
175 Ok((
176 Self {
177 $($handle_field,)*
178 $($param_field,)*
179 },
180 final_tail,
181 ))
182 } else {
183 let mut params_cursor = cursor;
184 $(
185 let ($param_field, tail) = <$param_type as $crate::TpmParse>::parse(params_cursor)?;
186 params_cursor = tail;
187 )*
188
189 Ok((
190 Self {
191 $($handle_field,)*
192 $($param_field,)*
193 },
194 params_cursor,
195 ))
196 }
197 }
198 }
199 };
200
201 (
202 $(#[$meta:meta])*
203 $vis:vis struct $name:ident {
204 $(pub $field_name:ident: $field_type:ty),*
205 $(,)?
206 }
207 ) => {
208 $(#[$meta])*
209 $vis struct $name {
210 $(pub $field_name: $field_type,)*
211 }
212
213 impl $crate::TpmSized for $name {
214 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
215 fn len(&self) -> usize {
216 0 $(+ $crate::TpmSized::len(&self.$field_name))*
217 }
218 }
219
220 impl $crate::TpmBuild for $name {
221 #[allow(unused_variables)]
222 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
223 $( $crate::TpmBuild::build(&self.$field_name, writer)?; )*
224 Ok(())
225 }
226 }
227
228 impl $crate::TpmParse for $name {
229 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
230 $(let ($field_name, buf) = <$field_type>::parse(buf)?;)*
231 Ok((
232 Self {
233 $($field_name,)*
234 },
235 buf,
236 ))
237 }
238 }
239 };
240}