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)]
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 TpmtScheme {
157 pub scheme: TpmAlgId,
158 }
159}
160
161tpm_struct! {
162 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
163 pub struct TpmtKdfScheme {
164 pub scheme: TpmAlgId,
165 }
166}
167
168tpm_struct_tagged! {
169 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
170 pub struct TpmtRsaDecrypt {
171 pub scheme: TpmAlgId,
172 pub details: crate::data::tpmu::TpmuAsymScheme,
173 }
174}
175
176impl Default for TpmtRsaDecrypt {
177 fn default() -> Self {
178 Self {
179 scheme: TpmAlgId::Null,
180 details: crate::data::tpmu::TpmuAsymScheme::Null,
181 }
182 }
183}
184
185#[derive(Debug, PartialEq, Eq, Clone, Default)]
186pub struct TpmtSensitive {
187 pub sensitive_type: TpmAlgId,
188 pub auth_value: Tpm2bAuth,
189 pub seed_value: Tpm2bDigest,
190 pub sensitive: TpmuSensitiveComposite,
191}
192
193impl TpmtSensitive {
194 pub fn from_private_bytes(
200 key_alg: TpmAlgId,
201 private_bytes: &[u8],
202 ) -> Result<Self, TpmErrorKind> {
203 let sensitive = match key_alg {
204 TpmAlgId::Rsa => TpmuSensitiveComposite::Rsa(
205 crate::data::Tpm2bPrivateKeyRsa::try_from(private_bytes)?,
206 ),
207 TpmAlgId::Ecc => TpmuSensitiveComposite::Ecc(crate::data::Tpm2bEccParameter::try_from(
208 private_bytes,
209 )?),
210 TpmAlgId::KeyedHash => TpmuSensitiveComposite::Bits(
211 crate::data::Tpm2bSensitiveData::try_from(private_bytes)?,
212 ),
213 TpmAlgId::SymCipher => {
214 TpmuSensitiveComposite::Sym(crate::data::Tpm2bSymKey::try_from(private_bytes)?)
215 }
216 _ => return Err(TpmErrorKind::InvalidValue),
217 };
218 Ok(Self {
219 sensitive_type: key_alg,
220 auth_value: Tpm2bAuth::default(),
221 seed_value: Tpm2bDigest::default(),
222 sensitive,
223 })
224 }
225}
226
227impl TpmSized for TpmtSensitive {
228 const SIZE: usize =
229 TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
230 fn len(&self) -> usize {
231 self.sensitive_type.len()
232 + self.auth_value.len()
233 + self.seed_value.len()
234 + self.sensitive.len()
235 }
236}
237
238impl TpmBuild for TpmtSensitive {
239 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
240 self.sensitive_type.build(writer)?;
241 self.auth_value.build(writer)?;
242 self.seed_value.build(writer)?;
243 self.sensitive.build(writer)
244 }
245}
246
247impl TpmParse for TpmtSensitive {
248 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
249 let (sensitive_type, buf) = TpmAlgId::parse(buf)?;
250 let (auth_value, buf) = Tpm2bAuth::parse(buf)?;
251 let (seed_value, buf) = Tpm2bDigest::parse(buf)?;
252 let (sensitive, buf) = match sensitive_type {
253 TpmAlgId::Rsa => {
254 let (val, buf) = crate::data::Tpm2bPrivateKeyRsa::parse(buf)?;
255 (TpmuSensitiveComposite::Rsa(val), buf)
256 }
257 TpmAlgId::Ecc => {
258 let (val, buf) = Tpm2bEccParameter::parse(buf)?;
259 (TpmuSensitiveComposite::Ecc(val), buf)
260 }
261 TpmAlgId::KeyedHash => {
262 let (val, buf) = Tpm2bSensitiveData::parse(buf)?;
263 (TpmuSensitiveComposite::Bits(val), buf)
264 }
265 TpmAlgId::SymCipher => {
266 let (val, buf) = Tpm2bSymKey::parse(buf)?;
267 (TpmuSensitiveComposite::Sym(val), buf)
268 }
269 _ => return Err(TpmErrorKind::InvalidValue),
270 };
271 Ok((
272 Self {
273 sensitive_type,
274 auth_value,
275 seed_value,
276 sensitive,
277 },
278 buf,
279 ))
280 }
281}
282
283#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
284pub struct TpmtSymDef {
285 pub algorithm: TpmAlgId,
286 pub key_bits: TpmuSymKeyBits,
287 pub mode: TpmuSymMode,
288}
289
290impl TpmSized for TpmtSymDef {
291 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
292 fn len(&self) -> usize {
293 if self.algorithm == TpmAlgId::Null {
294 self.algorithm.len()
295 } else {
296 self.algorithm.len() + self.key_bits.len() + self.mode.len()
297 }
298 }
299}
300
301impl TpmBuild for TpmtSymDef {
302 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
303 self.algorithm.build(writer)?;
304 if self.algorithm != TpmAlgId::Null {
305 self.key_bits.build(writer)?;
306 self.mode.build(writer)?;
307 }
308 Ok(())
309 }
310}
311
312impl TpmParse for TpmtSymDef {
313 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
314 let (algorithm, buf) = TpmAlgId::parse(buf)?;
315 if algorithm == TpmAlgId::Null {
316 return Ok((
317 Self {
318 algorithm,
319 key_bits: TpmuSymKeyBits::Null,
320 mode: TpmuSymMode::Null,
321 },
322 buf,
323 ));
324 }
325 let (key_bits, buf) = match algorithm {
326 TpmAlgId::Aes => {
327 let (val, buf) = u16::parse(buf)?;
328 (TpmuSymKeyBits::Aes(val), buf)
329 }
330 TpmAlgId::Sm4 => {
331 let (val, buf) = u16::parse(buf)?;
332 (TpmuSymKeyBits::Sm4(val), buf)
333 }
334 TpmAlgId::Camellia => {
335 let (val, buf) = u16::parse(buf)?;
336 (TpmuSymKeyBits::Camellia(val), buf)
337 }
338 TpmAlgId::Xor => {
339 let (val, buf) = TpmAlgId::parse(buf)?;
340 (TpmuSymKeyBits::Xor(val), buf)
341 }
342 TpmAlgId::Null => (TpmuSymKeyBits::Null, buf),
343 _ => return Err(TpmErrorKind::InvalidValue),
344 };
345 let (mode, buf) = match algorithm {
346 TpmAlgId::Aes => {
347 let (val, buf) = TpmAlgId::parse(buf)?;
348 (TpmuSymMode::Aes(val), buf)
349 }
350 TpmAlgId::Sm4 => {
351 let (val, buf) = TpmAlgId::parse(buf)?;
352 (TpmuSymMode::Sm4(val), buf)
353 }
354 TpmAlgId::Camellia => {
355 let (val, buf) = TpmAlgId::parse(buf)?;
356 (TpmuSymMode::Camellia(val), buf)
357 }
358 TpmAlgId::Xor => {
359 let (val, buf) = TpmAlgId::parse(buf)?;
360 (TpmuSymMode::Xor(val), buf)
361 }
362 TpmAlgId::Null => (TpmuSymMode::Null, buf),
363 _ => return Err(TpmErrorKind::InvalidValue),
364 };
365 Ok((
366 Self {
367 algorithm,
368 key_bits,
369 mode,
370 },
371 buf,
372 ))
373 }
374}
375
376pub type TpmtSymDefObject = TpmtSymDef;
377
378tpm_struct_tagged! {
379 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
380 pub struct TpmtNvPublic2 {
381 pub handle_type: TpmHt,
382 pub public_area: TpmuNvPublic2,
383 }
384}
385
386tpm_struct! {
387 #[derive(Debug, PartialEq, Eq, Clone, Default)]
388 pub struct TpmtTkCreation {
389 pub tag: TpmSt,
390 pub hierarchy: TpmRh,
391 pub digest: Tpm2bDigest,
392 }
393}
394
395tpm_struct! {
396 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
397 pub struct TpmtTkVerified {
398 pub tag: TpmSt,
399 pub hierarchy: TpmRh,
400 pub digest: Tpm2bDigest,
401 }
402}
403
404tpm_struct! {
405 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
406 pub struct TpmtTkAuth {
407 pub tag: TpmSt,
408 pub hierarchy: TpmRh,
409 pub digest: Tpm2bDigest,
410 }
411}
412
413tpm_struct! {
414 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
415 pub struct TpmtTkHashcheck {
416 pub tag: TpmSt,
417 pub hierarchy: TpmRh,
418 pub digest: Tpm2bDigest,
419 }
420}
421
422tpm_struct_tagged! {
423 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
424 pub struct TpmtHa {
425 pub hash_alg: TpmAlgId,
426 pub digest: TpmuHa,
427 }
428}
429
430impl Default for TpmtHa {
431 fn default() -> Self {
432 Self {
433 hash_alg: TpmAlgId::Null,
434 digest: TpmuHa::default(),
435 }
436 }
437}
438
439tpm_struct_tagged! {
440 #[derive(Debug, PartialEq, Eq, Clone)]
441 pub struct TpmtSignature {
442 pub sig_alg: TpmAlgId,
443 pub signature: crate::data::tpmu::TpmuSignature,
444 }
445}
446
447tpm_struct_tagged! {
448 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
449 pub struct TpmtKeyedhashScheme {
450 pub scheme: TpmAlgId,
451 pub details: TpmuKeyedhashScheme,
452 }
453}
454
455tpm_struct_tagged! {
456 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
457 pub struct TpmtSigScheme {
458 pub scheme: TpmAlgId,
459 pub details: TpmuSigScheme,
460 }
461}