1use super::{
6 Tpm2bAuth, Tpm2bDigest, Tpm2bEccParameter, Tpm2bPublicKeyRsa, Tpm2bSensitiveData, Tpm2bSymKey,
7 TpmAlgId, TpmHt, TpmRh, TpmSt, TpmaObject, TpmsEccPoint, TpmuHa, TpmuKeyedhashScheme,
8 TpmuNvPublic2, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite, TpmuSigScheme,
9 TpmuSymKeyBits, TpmuSymMode,
10};
11use crate::{
12 constant::TPM_MAX_COMMAND_SIZE, tpm_struct, TpmBuild, TpmErrorKind, TpmParse, TpmParseTagged,
13 TpmResult, TpmSized, TpmWriter,
14};
15
16macro_rules! tpm_struct_tagged {
17 (
18 $(#[$outer:meta])*
19 $vis:vis struct $name:ident {
20 pub $tag_field:ident: $tag_ty:ty,
21 pub $value_field:ident: $value_ty:ty,
22 }
23 ) => {
24 $(#[$outer])*
25 $vis struct $name {
26 pub $tag_field: $tag_ty,
27 pub $value_field: $value_ty,
28 }
29
30 impl $crate::TpmSized for $name {
31 const SIZE: usize = <$tag_ty>::SIZE + <$value_ty>::SIZE;
32 fn len(&self) -> usize {
33 $crate::TpmSized::len(&self.$tag_field) + $crate::TpmSized::len(&self.$value_field)
34 }
35 }
36
37 impl $crate::TpmBuild for $name {
38 fn build(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
39 $crate::TpmBuild::build(&self.$tag_field, writer)?;
40 $crate::TpmBuild::build(&self.$value_field, writer)
41 }
42 }
43
44 impl $crate::TpmParse for $name {
45 fn parse(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
46 let ($tag_field, buf) = <$tag_ty>::parse(buf)?;
47 let ($value_field, buf) =
48 <$value_ty as $crate::TpmParseTagged>::parse_tagged($tag_field, buf)?;
49 Ok((
50 Self {
51 $tag_field,
52 $value_field,
53 },
54 buf,
55 ))
56 }
57 }
58 };
59}
60
61#[derive(Debug, PartialEq, Eq, Clone)]
62pub struct TpmtPublic {
63 pub object_type: TpmAlgId,
64 pub name_alg: TpmAlgId,
65 pub object_attributes: TpmaObject,
66 pub auth_policy: Tpm2bDigest,
67 pub parameters: TpmuPublicParms,
68 pub unique: TpmuPublicId,
69}
70
71impl TpmSized for TpmtPublic {
72 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
73 fn len(&self) -> usize {
74 self.object_type.len()
75 + self.name_alg.len()
76 + self.object_attributes.len()
77 + self.auth_policy.len()
78 + self.parameters.len()
79 + self.unique.len()
80 }
81}
82
83impl TpmBuild for TpmtPublic {
84 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
85 self.object_type.build(writer)?;
86 self.name_alg.build(writer)?;
87 self.object_attributes.build(writer)?;
88 self.auth_policy.build(writer)?;
89 self.parameters.build(writer)?;
90 self.unique.build(writer)
91 }
92}
93
94impl TpmParse for TpmtPublic {
95 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
96 let (object_type, buf) = TpmAlgId::parse(buf)?;
97 let (name_alg, buf) = TpmAlgId::parse(buf)?;
98 let (object_attributes, buf) = TpmaObject::parse(buf)?;
99 let (auth_policy, buf) = Tpm2bDigest::parse(buf)?;
100 let (parameters, buf) = TpmuPublicParms::parse_tagged(object_type, buf)?;
101 let (unique, buf) = match object_type {
102 TpmAlgId::KeyedHash => {
103 let (val, rest) = Tpm2bDigest::parse(buf)?;
104 (TpmuPublicId::KeyedHash(val), rest)
105 }
106 TpmAlgId::SymCipher => {
107 let (val, rest) = Tpm2bSymKey::parse(buf)?;
108 (TpmuPublicId::SymCipher(val), rest)
109 }
110 TpmAlgId::Rsa => {
111 let (val, rest) = Tpm2bPublicKeyRsa::parse(buf)?;
112 (TpmuPublicId::Rsa(val), rest)
113 }
114 TpmAlgId::Ecc => {
115 let (point, rest) = TpmsEccPoint::parse(buf)?;
116 (TpmuPublicId::Ecc(point), rest)
117 }
118 TpmAlgId::Null => (TpmuPublicId::Null, buf),
119 _ => return Err(TpmErrorKind::InvalidValue),
120 };
121 let public_area = Self {
122 object_type,
123 name_alg,
124 object_attributes,
125 auth_policy,
126 parameters,
127 unique,
128 };
129 Ok((public_area, buf))
130 }
131}
132
133impl Default for TpmtPublic {
134 fn default() -> Self {
135 Self {
136 object_type: TpmAlgId::Null,
137 name_alg: TpmAlgId::Null,
138 object_attributes: TpmaObject::empty(),
139 auth_policy: Tpm2bDigest::default(),
140 parameters: TpmuPublicParms::Null,
141 unique: TpmuPublicId::Null,
142 }
143 }
144}
145
146tpm_struct_tagged! {
147 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
148 pub struct TpmtPublicParms {
149 pub object_type: TpmAlgId,
150 pub parameters: TpmuPublicParms,
151 }
152}
153
154tpm_struct! {
155 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
156 pub struct TpmtKdfScheme {
157 pub scheme: TpmAlgId,
158 }
159}
160
161tpm_struct_tagged! {
162 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
163 pub struct TpmtRsaDecrypt {
164 pub scheme: TpmAlgId,
165 pub details: crate::data::tpmu::TpmuAsymScheme,
166 }
167}
168
169impl Default for TpmtRsaDecrypt {
170 fn default() -> Self {
171 Self {
172 scheme: TpmAlgId::Null,
173 details: crate::data::tpmu::TpmuAsymScheme::default(),
174 }
175 }
176}
177
178#[derive(Debug, PartialEq, Eq, Clone, Default)]
179pub struct TpmtSensitive {
180 pub sensitive_type: TpmAlgId,
181 pub auth_value: Tpm2bAuth,
182 pub seed_value: Tpm2bDigest,
183 pub sensitive: TpmuSensitiveComposite,
184}
185
186impl TpmtSensitive {
187 pub fn from_private_bytes(
193 key_alg: TpmAlgId,
194 private_bytes: &[u8],
195 ) -> Result<Self, TpmErrorKind> {
196 let sensitive = match key_alg {
197 TpmAlgId::Rsa => TpmuSensitiveComposite::Rsa(
198 crate::data::Tpm2bPrivateKeyRsa::try_from(private_bytes)?,
199 ),
200 TpmAlgId::Ecc => TpmuSensitiveComposite::Ecc(crate::data::Tpm2bEccParameter::try_from(
201 private_bytes,
202 )?),
203 TpmAlgId::KeyedHash => TpmuSensitiveComposite::Bits(
204 crate::data::Tpm2bSensitiveData::try_from(private_bytes)?,
205 ),
206 TpmAlgId::SymCipher => {
207 TpmuSensitiveComposite::Sym(crate::data::Tpm2bSymKey::try_from(private_bytes)?)
208 }
209 _ => return Err(TpmErrorKind::InvalidValue),
210 };
211 Ok(Self {
212 sensitive_type: key_alg,
213 auth_value: Tpm2bAuth::default(),
214 seed_value: Tpm2bDigest::default(),
215 sensitive,
216 })
217 }
218}
219
220impl TpmSized for TpmtSensitive {
221 const SIZE: usize =
222 TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
223 fn len(&self) -> usize {
224 self.sensitive_type.len()
225 + self.auth_value.len()
226 + self.seed_value.len()
227 + self.sensitive.len()
228 }
229}
230
231impl TpmBuild for TpmtSensitive {
232 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
233 self.sensitive_type.build(writer)?;
234 self.auth_value.build(writer)?;
235 self.seed_value.build(writer)?;
236 self.sensitive.build(writer)
237 }
238}
239
240impl TpmParse for TpmtSensitive {
241 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
242 let (sensitive_type, buf) = TpmAlgId::parse(buf)?;
243 let (auth_value, buf) = Tpm2bAuth::parse(buf)?;
244 let (seed_value, buf) = Tpm2bDigest::parse(buf)?;
245 let (sensitive, buf) = match sensitive_type {
246 TpmAlgId::Rsa => {
247 let (val, buf) = crate::data::Tpm2bPrivateKeyRsa::parse(buf)?;
248 (TpmuSensitiveComposite::Rsa(val), buf)
249 }
250 TpmAlgId::Ecc => {
251 let (val, buf) = Tpm2bEccParameter::parse(buf)?;
252 (TpmuSensitiveComposite::Ecc(val), buf)
253 }
254 TpmAlgId::KeyedHash => {
255 let (val, buf) = Tpm2bSensitiveData::parse(buf)?;
256 (TpmuSensitiveComposite::Bits(val), buf)
257 }
258 TpmAlgId::SymCipher => {
259 let (val, buf) = Tpm2bSymKey::parse(buf)?;
260 (TpmuSensitiveComposite::Sym(val), buf)
261 }
262 _ => return Err(TpmErrorKind::InvalidValue),
263 };
264 Ok((
265 Self {
266 sensitive_type,
267 auth_value,
268 seed_value,
269 sensitive,
270 },
271 buf,
272 ))
273 }
274}
275
276#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
277pub struct TpmtSymDef {
278 pub algorithm: TpmAlgId,
279 pub key_bits: TpmuSymKeyBits,
280 pub mode: TpmuSymMode,
281}
282
283impl TpmSized for TpmtSymDef {
284 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
285 fn len(&self) -> usize {
286 if self.algorithm == TpmAlgId::Null {
287 self.algorithm.len()
288 } else {
289 self.algorithm.len() + self.key_bits.len() + self.mode.len()
290 }
291 }
292}
293
294impl TpmBuild for TpmtSymDef {
295 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
296 self.algorithm.build(writer)?;
297 if self.algorithm != TpmAlgId::Null {
298 self.key_bits.build(writer)?;
299 self.mode.build(writer)?;
300 }
301 Ok(())
302 }
303}
304
305impl TpmParse for TpmtSymDef {
306 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
307 let (algorithm, buf) = TpmAlgId::parse(buf)?;
308 if algorithm == TpmAlgId::Null {
309 return Ok((
310 Self {
311 algorithm,
312 key_bits: TpmuSymKeyBits::Null,
313 mode: TpmuSymMode::Null,
314 },
315 buf,
316 ));
317 }
318 let (key_bits, buf) = match algorithm {
319 TpmAlgId::Aes => {
320 let (val, buf) = u16::parse(buf)?;
321 (TpmuSymKeyBits::Aes(val), buf)
322 }
323 TpmAlgId::Sm4 => {
324 let (val, buf) = u16::parse(buf)?;
325 (TpmuSymKeyBits::Sm4(val), buf)
326 }
327 TpmAlgId::Camellia => {
328 let (val, buf) = u16::parse(buf)?;
329 (TpmuSymKeyBits::Camellia(val), buf)
330 }
331 TpmAlgId::Xor => {
332 let (val, buf) = TpmAlgId::parse(buf)?;
333 (TpmuSymKeyBits::Xor(val), buf)
334 }
335 TpmAlgId::Null => (TpmuSymKeyBits::Null, buf),
336 _ => return Err(TpmErrorKind::InvalidValue),
337 };
338 let (mode, buf) = match algorithm {
339 TpmAlgId::Aes => {
340 let (val, buf) = TpmAlgId::parse(buf)?;
341 (TpmuSymMode::Aes(val), buf)
342 }
343 TpmAlgId::Sm4 => {
344 let (val, buf) = TpmAlgId::parse(buf)?;
345 (TpmuSymMode::Sm4(val), buf)
346 }
347 TpmAlgId::Camellia => {
348 let (val, buf) = TpmAlgId::parse(buf)?;
349 (TpmuSymMode::Camellia(val), buf)
350 }
351 TpmAlgId::Xor => {
352 let (val, buf) = TpmAlgId::parse(buf)?;
353 (TpmuSymMode::Xor(val), buf)
354 }
355 TpmAlgId::Null => (TpmuSymMode::Null, buf),
356 _ => return Err(TpmErrorKind::InvalidValue),
357 };
358 Ok((
359 Self {
360 algorithm,
361 key_bits,
362 mode,
363 },
364 buf,
365 ))
366 }
367}
368
369pub type TpmtSymDefObject = TpmtSymDef;
370
371tpm_struct_tagged! {
372 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
373 pub struct TpmtNvPublic2 {
374 pub handle_type: TpmHt,
375 pub public_area: TpmuNvPublic2,
376 }
377}
378
379tpm_struct! {
380 #[derive(Debug, PartialEq, Eq, Clone, Default)]
381 pub struct TpmtTkCreation {
382 pub tag: TpmSt,
383 pub hierarchy: TpmRh,
384 pub digest: Tpm2bDigest,
385 }
386}
387
388tpm_struct! {
389 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
390 pub struct TpmtTkVerified {
391 pub tag: TpmSt,
392 pub hierarchy: TpmRh,
393 pub digest: Tpm2bDigest,
394 }
395}
396
397tpm_struct! {
398 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
399 pub struct TpmtTkAuth {
400 pub tag: TpmSt,
401 pub hierarchy: TpmRh,
402 pub digest: Tpm2bDigest,
403 }
404}
405
406tpm_struct! {
407 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
408 pub struct TpmtTkHashcheck {
409 pub tag: TpmSt,
410 pub hierarchy: TpmRh,
411 pub digest: Tpm2bDigest,
412 }
413}
414
415tpm_struct_tagged! {
416 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
417 pub struct TpmtHa {
418 pub hash_alg: TpmAlgId,
419 pub digest: TpmuHa,
420 }
421}
422
423impl Default for TpmtHa {
424 fn default() -> Self {
425 Self {
426 hash_alg: TpmAlgId::Null,
427 digest: TpmuHa::default(),
428 }
429 }
430}
431
432tpm_struct_tagged! {
433 #[derive(Debug, PartialEq, Eq, Clone)]
434 pub struct TpmtSignature {
435 pub sig_alg: TpmAlgId,
436 pub signature: crate::data::tpmu::TpmuSignature,
437 }
438}
439
440tpm_struct_tagged! {
441 #[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
442 pub struct TpmtKeyedhashScheme {
443 pub scheme: TpmAlgId,
444 pub details: TpmuKeyedhashScheme,
445 }
446}
447
448tpm_struct_tagged! {
449 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
450 pub struct TpmtSigScheme {
451 pub scheme: TpmAlgId,
452 pub details: TpmuSigScheme,
453 }
454}
455
456impl Default for TpmtSigScheme {
457 fn default() -> Self {
458 Self {
459 scheme: TpmAlgId::Null,
460 details: TpmuSigScheme::default(),
461 }
462 }
463}
464
465tpm_struct_tagged! {
466 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
467 pub struct TpmtRsaScheme {
468 pub scheme: TpmAlgId,
469 pub details: crate::data::tpmu::TpmuAsymScheme,
470 }
471}
472
473impl Default for TpmtRsaScheme {
474 fn default() -> Self {
475 Self {
476 scheme: TpmAlgId::Null,
477 details: crate::data::tpmu::TpmuAsymScheme::default(),
478 }
479 }
480}
481
482tpm_struct_tagged! {
483 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
484 pub struct TpmtEccScheme {
485 pub scheme: TpmAlgId,
486 pub details: crate::data::tpmu::TpmuAsymScheme,
487 }
488}
489
490impl Default for TpmtEccScheme {
491 fn default() -> Self {
492 Self {
493 scheme: TpmAlgId::Null,
494 details: crate::data::tpmu::TpmuAsymScheme::default(),
495 }
496 }
497}