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