1use super::{
6 Tpm2bAuth, Tpm2bDigest, TpmAlgId, TpmHt, TpmRh, TpmSt, TpmaObject, TpmuHa, TpmuKdfScheme,
7 TpmuKeyedhashScheme, TpmuNvPublic2, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite,
8 TpmuSigScheme, TpmuSymKeyBits, TpmuSymMode,
9};
10use crate::{
11 constant::TPM_MAX_COMMAND_SIZE, tpm_struct, TpmMarshal, TpmResult, TpmSized, TpmUnmarshal,
12 TpmUnmarshalTagged, TpmWriter,
13};
14
15macro_rules! tpm_struct_tagged {
16 (
17 $(#[$outer:meta])*
18 $vis:vis struct $name:ident {
19 pub $tag_field:ident: $tag_ty:ty,
20 pub $value_field:ident: $value_ty:ty,
21 }
22 ) => {
23 $(#[$outer])*
24 $vis struct $name {
25 pub $tag_field: $tag_ty,
26 pub $value_field: $value_ty,
27 }
28
29 impl $crate::TpmSized for $name {
30 const SIZE: usize = <$tag_ty>::SIZE + <$value_ty>::SIZE;
31 fn len(&self) -> usize {
32 $crate::TpmSized::len(&self.$tag_field) + $crate::TpmSized::len(&self.$value_field)
33 }
34 }
35
36 impl $crate::TpmMarshal for $name {
37 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
38 $crate::TpmMarshal::marshal(&self.$tag_field, writer)?;
39 $crate::TpmMarshal::marshal(&self.$value_field, writer)
40 }
41 }
42
43 impl $crate::TpmUnmarshal for $name {
44 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
45 let ($tag_field, buf) = <$tag_ty>::unmarshal(buf)?;
46 let ($value_field, buf) =
47 <$value_ty as $crate::TpmUnmarshalTagged>::unmarshal_tagged($tag_field, buf)?;
48 Ok((
49 Self {
50 $tag_field,
51 $value_field,
52 },
53 buf,
54 ))
55 }
56 }
57 };
58}
59
60#[derive(Debug, PartialEq, Eq, Clone)]
61pub struct TpmtPublic {
62 pub object_type: TpmAlgId,
63 pub name_alg: TpmAlgId,
64 pub object_attributes: TpmaObject,
65 pub auth_policy: Tpm2bDigest,
66 pub parameters: TpmuPublicParms,
67 pub unique: TpmuPublicId,
68}
69
70impl TpmSized for TpmtPublic {
71 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
72 fn len(&self) -> usize {
73 self.object_type.len()
74 + self.name_alg.len()
75 + self.object_attributes.len()
76 + self.auth_policy.len()
77 + self.parameters.len()
78 + self.unique.len()
79 }
80}
81
82impl TpmMarshal for TpmtPublic {
83 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
84 self.object_type.marshal(writer)?;
85 self.name_alg.marshal(writer)?;
86 self.object_attributes.marshal(writer)?;
87 self.auth_policy.marshal(writer)?;
88 self.parameters.marshal(writer)?;
89 self.unique.marshal(writer)
90 }
91}
92
93impl TpmUnmarshal for TpmtPublic {
94 fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
95 let (object_type, buf) = TpmAlgId::unmarshal(buf)?;
96 let (name_alg, buf) = TpmAlgId::unmarshal(buf)?;
97 let (object_attributes, buf) = TpmaObject::unmarshal(buf)?;
98 let (auth_policy, buf) = Tpm2bDigest::unmarshal(buf)?;
99 let (parameters, buf) = TpmuPublicParms::unmarshal_tagged(object_type, buf)?;
100 let (unique, buf) = TpmuPublicId::unmarshal_tagged(object_type, buf)?;
101
102 let public_area = Self {
103 object_type,
104 name_alg,
105 object_attributes,
106 auth_policy,
107 parameters,
108 unique,
109 };
110 Ok((public_area, buf))
111 }
112}
113
114impl Default for TpmtPublic {
115 fn default() -> Self {
116 Self {
117 object_type: TpmAlgId::Null,
118 name_alg: TpmAlgId::Null,
119 object_attributes: TpmaObject::empty(),
120 auth_policy: Tpm2bDigest::default(),
121 parameters: TpmuPublicParms::Null,
122 unique: TpmuPublicId::Null,
123 }
124 }
125}
126
127tpm_struct_tagged! {
128 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
129 pub struct TpmtPublicParms {
130 pub object_type: TpmAlgId,
131 pub parameters: TpmuPublicParms,
132 }
133}
134
135tpm_struct_tagged! {
136 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
137 pub struct TpmtKdfScheme {
138 pub scheme: TpmAlgId,
139 pub details: TpmuKdfScheme,
140 }
141}
142
143impl Default for TpmtKdfScheme {
144 fn default() -> Self {
145 Self {
146 scheme: TpmAlgId::Null,
147 details: TpmuKdfScheme::Null,
148 }
149 }
150}
151
152tpm_struct_tagged! {
153 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
154 pub struct TpmtRsaDecrypt {
155 pub scheme: TpmAlgId,
156 pub details: crate::data::tpmu::TpmuAsymScheme,
157 }
158}
159
160impl Default for TpmtRsaDecrypt {
161 fn default() -> Self {
162 Self {
163 scheme: TpmAlgId::Null,
164 details: crate::data::tpmu::TpmuAsymScheme::default(),
165 }
166 }
167}
168
169#[derive(Debug, PartialEq, Eq, Clone, Default)]
170pub struct TpmtSensitive {
171 pub sensitive_type: TpmAlgId,
172 pub auth_value: Tpm2bAuth,
173 pub seed_value: Tpm2bDigest,
174 pub sensitive: TpmuSensitiveComposite,
175}
176
177impl TpmSized for TpmtSensitive {
178 const SIZE: usize =
179 TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
180 fn len(&self) -> usize {
181 self.sensitive_type.len()
182 + self.auth_value.len()
183 + self.seed_value.len()
184 + self.sensitive.len()
185 }
186}
187
188impl TpmMarshal for TpmtSensitive {
189 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
190 self.sensitive_type.marshal(writer)?;
191 self.auth_value.marshal(writer)?;
192 self.seed_value.marshal(writer)?;
193 self.sensitive.marshal(writer)
194 }
195}
196
197impl TpmUnmarshal for TpmtSensitive {
198 fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
199 let (sensitive_type, buf) = TpmAlgId::unmarshal(buf)?;
200 let (auth_value, buf) = Tpm2bAuth::unmarshal(buf)?;
201 let (seed_value, buf) = Tpm2bDigest::unmarshal(buf)?;
202 let (sensitive, buf) = TpmuSensitiveComposite::unmarshal_tagged(sensitive_type, buf)?;
203
204 Ok((
205 Self {
206 sensitive_type,
207 auth_value,
208 seed_value,
209 sensitive,
210 },
211 buf,
212 ))
213 }
214}
215
216#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
217pub struct TpmtSymDef {
218 pub algorithm: TpmAlgId,
219 pub key_bits: TpmuSymKeyBits,
220 pub mode: TpmuSymMode,
221}
222
223impl TpmSized for TpmtSymDef {
224 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
225 fn len(&self) -> usize {
226 if self.algorithm == TpmAlgId::Null {
227 self.algorithm.len()
228 } else {
229 self.algorithm.len() + self.key_bits.len() + self.mode.len()
230 }
231 }
232}
233
234impl TpmMarshal for TpmtSymDef {
235 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
236 self.algorithm.marshal(writer)?;
237 if self.algorithm != TpmAlgId::Null {
238 self.key_bits.marshal(writer)?;
239 self.mode.marshal(writer)?;
240 }
241 Ok(())
242 }
243}
244
245impl TpmUnmarshal for TpmtSymDef {
246 fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
247 let (algorithm, buf) = TpmAlgId::unmarshal(buf)?;
248
249 if algorithm == TpmAlgId::Null {
250 return Ok((
251 Self {
252 algorithm,
253 key_bits: TpmuSymKeyBits::Null,
254 mode: TpmuSymMode::Null,
255 },
256 buf,
257 ));
258 }
259
260 let (key_bits, buf) = TpmuSymKeyBits::unmarshal_tagged(algorithm, buf)?;
261 let (mode, buf) = TpmuSymMode::unmarshal_tagged(algorithm, buf)?;
262
263 Ok((
264 Self {
265 algorithm,
266 key_bits,
267 mode,
268 },
269 buf,
270 ))
271 }
272}
273
274pub type TpmtSymDefObject = TpmtSymDef;
275
276tpm_struct_tagged! {
277 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
278 pub struct TpmtNvPublic2 {
279 pub handle_type: TpmHt,
280 pub public_area: TpmuNvPublic2,
281 }
282}
283
284tpm_struct! {
285 #[derive(Debug, PartialEq, Eq, Clone, Default)]
286 pub struct TpmtTkCreation {
287 pub tag: TpmSt,
288 pub hierarchy: TpmRh,
289 pub digest: Tpm2bDigest,
290 }
291}
292
293tpm_struct! {
294 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
295 pub struct TpmtTkVerified {
296 pub tag: TpmSt,
297 pub hierarchy: TpmRh,
298 pub digest: Tpm2bDigest,
299 }
300}
301
302tpm_struct! {
303 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
304 pub struct TpmtTkAuth {
305 pub tag: TpmSt,
306 pub hierarchy: TpmRh,
307 pub digest: Tpm2bDigest,
308 }
309}
310
311tpm_struct! {
312 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
313 pub struct TpmtTkHashcheck {
314 pub tag: TpmSt,
315 pub hierarchy: TpmRh,
316 pub digest: Tpm2bDigest,
317 }
318}
319
320tpm_struct_tagged! {
321 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
322 pub struct TpmtHa {
323 pub hash_alg: TpmAlgId,
324 pub digest: TpmuHa,
325 }
326}
327
328impl Default for TpmtHa {
329 fn default() -> Self {
330 Self {
331 hash_alg: TpmAlgId::Null,
332 digest: TpmuHa::default(),
333 }
334 }
335}
336
337tpm_struct_tagged! {
338 #[derive(Debug, PartialEq, Eq, Clone)]
339 pub struct TpmtSignature {
340 pub sig_alg: TpmAlgId,
341 pub signature: crate::data::tpmu::TpmuSignature,
342 }
343}
344
345tpm_struct_tagged! {
346 #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
347 pub struct TpmtKeyedhashScheme {
348 pub scheme: TpmAlgId,
349 pub details: TpmuKeyedhashScheme,
350 }
351}
352
353tpm_struct_tagged! {
354 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
355 pub struct TpmtSigScheme {
356 pub scheme: TpmAlgId,
357 pub details: TpmuSigScheme,
358 }
359}
360
361impl Default for TpmtSigScheme {
362 fn default() -> Self {
363 Self {
364 scheme: TpmAlgId::Null,
365 details: TpmuSigScheme::default(),
366 }
367 }
368}
369
370tpm_struct_tagged! {
371 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
372 pub struct TpmtRsaScheme {
373 pub scheme: TpmAlgId,
374 pub details: crate::data::tpmu::TpmuAsymScheme,
375 }
376}
377
378impl Default for TpmtRsaScheme {
379 fn default() -> Self {
380 Self {
381 scheme: TpmAlgId::Null,
382 details: crate::data::tpmu::TpmuAsymScheme::default(),
383 }
384 }
385}
386
387tpm_struct_tagged! {
388 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
389 pub struct TpmtEccScheme {
390 pub scheme: TpmAlgId,
391 pub details: crate::data::tpmu::TpmuAsymScheme,
392 }
393}
394
395impl Default for TpmtEccScheme {
396 fn default() -> Self {
397 Self {
398 scheme: TpmAlgId::Null,
399 details: crate::data::tpmu::TpmuAsymScheme::default(),
400 }
401 }
402}