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 $(pub $handle_field:ident: $handle_type:ty),*
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: $handle_type,)*
24 $(pub $param_field: $param_type,)*
25 }
26
27 impl $crate::TpmSized for $name {
28 const SIZE: usize = 0 $(+ <$handle_type>::SIZE)* $(+ <$param_type>::SIZE)*;
29 fn len(&self) -> usize {
30 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
31 }
32 }
33
34 impl $crate::TpmBuild for $name {
35 #[allow(unused_variables)]
36 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
37 <Self as $crate::message::TpmBodyBuild>::build_handles(self, writer)?;
38 <Self as $crate::message::TpmBodyBuild>::build_parameters(self, writer)
39 }
40 }
41
42 impl $crate::message::TpmBodyBuild for $name {
43 #[allow(unused_variables)]
44 fn build_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
45 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
46 Ok(())
47 }
48
49 #[allow(unused_variables)]
50 fn build_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
51 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
52 Ok(())
53 }
54 }
55
56 impl $crate::message::TpmCommandBodyParse for $name {
57 #[allow(unused_mut)]
58 fn parse_body<'a>(
59 handles: &'a [u8],
60 params: &'a [u8],
61 ) -> $crate::TpmResult<(Self, &'a [u8])> {
62 let mut cursor = handles;
63 $(
64 let ($handle_field, tail) = <$handle_type as $crate::TpmParse>::parse(cursor)?;
65 cursor = tail;
66 )*
67
68 if !cursor.is_empty() {
69 return Err($crate::TpmErrorKind::TrailingData);
70 }
71
72 let mut cursor = params;
73 $(
74 let ($param_field, tail) = <$param_type as $crate::TpmParse>::parse(cursor)?;
75 cursor = tail;
76 )*
77
78 Ok((
79 Self {
80 $($handle_field,)*
81 $($param_field,)*
82 },
83 cursor,
84 ))
85 }
86 }
87
88 impl $crate::message::TpmHeader for $name {
89 const CC: $crate::data::TpmCc = $cc;
90 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
91 }
92 };
93
94 (
95 $(#[$meta:meta])*
96 kind: Response,
97 name: $name:ident,
98 cc: $cc:expr,
99 handles: {
100 $(pub $handle_field:ident: $handle_type:ty),*
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: $handle_type,)*
111 $(pub $param_field: $param_type,)*
112 }
113
114 impl $crate::message::TpmBodyBuild for $name {
115 #[allow(unused_variables)]
116 fn build_handles(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
117 $($crate::TpmBuild::build(&self.$handle_field, writer)?;)*
118 Ok(())
119 }
120 #[allow(unused_variables)]
121 fn build_parameters(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
122 $($crate::TpmBuild::build(&self.$param_field, writer)?;)*
123 Ok(())
124 }
125 }
126
127 impl $crate::TpmSized for $name {
128 const SIZE: usize = 0 $(+ <$handle_type>::SIZE)* $(+ <$param_type>::SIZE)*;
129 fn len(&self) -> usize {
130 0 $(+ $crate::TpmSized::len(&self.$handle_field))* $(+ $crate::TpmSized::len(&self.$param_field))*
131 }
132 }
133
134 impl $crate::TpmBuild for $name {
135 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
136 <Self as $crate::message::TpmBodyBuild>::build_handles(self, writer)?;
137 <Self as $crate::message::TpmBodyBuild>::build_parameters(self, writer)
138 }
139 }
140
141 impl $crate::message::TpmResponseBodyParse for $name {
142 #[allow(unused_mut)]
143 fn parse_body(
144 tag: $crate::data::TpmSt,
145 buf: &[u8],
146 ) -> $crate::TpmResult<(Self, &[u8])> {
147 let mut cursor = buf;
148 $(
149 let ($handle_field, tail) = <$handle_type as $crate::TpmParse>::parse(cursor)?;
150 cursor = tail;
151 )*
152
153 if tag == $crate::data::TpmSt::Sessions {
154 let (size, buf_after_size) = <u32 as $crate::TpmParse>::parse(cursor)?;
155 let size = size as usize;
156 if buf_after_size.len() < size {
157 return Err($crate::TpmErrorKind::Underflow);
158 }
159 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
160
161 $(
162 let ($param_field, tail) = <$param_type as $crate::TpmParse>::parse(params_cursor)?;
163 params_cursor = tail;
164 )*
165
166 if !params_cursor.is_empty() {
167 return Err($crate::TpmErrorKind::TrailingData);
168 }
169
170 Ok((
171 Self {
172 $($handle_field,)*
173 $($param_field,)*
174 },
175 final_tail,
176 ))
177 } else {
178 let mut params_cursor = cursor;
179 $(
180 let ($param_field, tail) = <$param_type as $crate::TpmParse>::parse(params_cursor)?;
181 params_cursor = tail;
182 )*
183
184 Ok((
185 Self {
186 $($handle_field,)*
187 $($param_field,)*
188 },
189 params_cursor,
190 ))
191 }
192 }
193 }
194
195 impl $crate::message::TpmHeader for $name {
196 const CC: $crate::data::TpmCc = $cc;
197 const HANDLES: usize = 0 $(+ {let _ = stringify!($handle_field); 1})*;
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}