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::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::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
40 fn len(&self) -> usize {
41 (self.handles.len() * <$crate::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::TpmHandle; $count] = ::core::default::Default::default();
77 for handle in &mut handles {
78 let (val, tail) = <$crate::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::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::TpmHandle>::SIZE) $(+ <$param_type>::SIZE)*;
152 fn len(&self) -> usize {
153 (self.handles.len() * <$crate::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::TpmHandle; $count] = ::core::default::Default::default();
172 for handle in &mut handles {
173 let (val, tail) = <$crate::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) = <u32 as $crate::TpmUnmarshal>::unmarshal(cursor)?;
180 let size = size as usize;
181 if buf_after_size.len() < size {
182 return Err($crate::TpmProtocolError::UnexpectedEnd);
183 }
184 let (mut params_cursor, final_tail) = buf_after_size.split_at(size);
185
186 $(
187 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
188 params_cursor = tail;
189 )*
190
191 if !params_cursor.is_empty() {
192 return Err($crate::TpmProtocolError::TrailingData);
193 }
194
195 Ok((
196 Self {
197 handles,
198 $($param_field,)*
199 },
200 final_tail,
201 ))
202 } else {
203 let mut params_cursor = cursor;
204 $(
205 let ($param_field, tail) = <$param_type as $crate::TpmUnmarshal>::unmarshal(params_cursor)?;
206 params_cursor = tail;
207 )*
208
209 Ok((
210 Self {
211 handles,
212 $($param_field,)*
213 },
214 params_cursor,
215 ))
216 }
217 }
218 }
219 };
220
221 (
222 $(#[$meta:meta])*
223 $vis:vis struct $name:ident {
224 $(pub $field_name:ident: $field_type:ty),*
225 $(,)?
226 }
227 ) => {
228 $(#[$meta])*
229 $vis struct $name {
230 $(pub $field_name: $field_type,)*
231 }
232
233 impl $crate::TpmSized for $name {
234 const SIZE: usize = 0 $(+ <$field_type>::SIZE)*;
235 fn len(&self) -> usize {
236 0 $(+ $crate::TpmSized::len(&self.$field_name))*
237 }
238 }
239
240 impl $crate::TpmMarshal for $name {
241 #[allow(unused_variables)]
242 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
243 $( $crate::TpmMarshal::marshal(&self.$field_name, writer)?; )*
244 Ok(())
245 }
246 }
247
248 impl $crate::TpmUnmarshal for $name {
249 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
250 $(let ($field_name, buf) = <$field_type>::unmarshal(buf)?;)*
251 Ok((
252 Self {
253 $($field_name,)*
254 },
255 buf,
256 ))
257 }
258 }
259 };
260}