1use crate::{
6 TpmError, TpmMarshal, TpmResult, TpmSized, TpmWriter,
7 basic::{TpmHandle, TpmUint8, TpmUint16, TpmUint32, TpmUint64},
8 constant::{TPM_GENERATED_VALUE, TPM_PCR_SELECT_MAX},
9 data::{
10 Tpm2b, Tpm2bAuth, Tpm2bData, Tpm2bDigest, Tpm2bEccParameter, Tpm2bMaxNvBuffer, Tpm2bName,
11 Tpm2bNonce, Tpm2bSensitiveData, TpmAlgId, TpmAt, TpmCap, TpmEccCurve, TpmPt, TpmRh, TpmSt,
12 TpmaAlgorithm, TpmaLocality, TpmaNv, TpmaNvExp, TpmaSession, TpmiAlgHash, TpmiRhNvExpIndex,
13 TpmiYesNo, TpmlPcrSelection, TpmtEccScheme, TpmtKdfScheme, TpmtKeyedhashScheme,
14 TpmtRsaScheme, TpmtSymDefObject, TpmuAttest, TpmuCapabilities,
15 },
16 tpm_struct,
17};
18use core::{
19 convert::TryFrom,
20 fmt::{Debug, Formatter},
21 mem::size_of,
22 ops::Deref,
23};
24
25#[derive(Clone, Copy, PartialEq, Eq)]
27pub struct TpmsPcrSelect {
28 size: TpmUint8,
29 data: [u8; TPM_PCR_SELECT_MAX as usize],
30}
31
32impl TpmsPcrSelect {
33 #[must_use]
35 pub const fn new() -> Self {
36 Self {
37 size: TpmUint8::new(0),
38 data: [0; TPM_PCR_SELECT_MAX as usize],
39 }
40 }
41}
42
43impl Default for TpmsPcrSelect {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49impl Deref for TpmsPcrSelect {
50 type Target = [u8];
51
52 fn deref(&self) -> &Self::Target {
53 &self.data[..u8::from(self.size) as usize]
54 }
55}
56
57impl TryFrom<&[u8]> for TpmsPcrSelect {
58 type Error = TpmError;
59
60 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
61 if slice.len() > TPM_PCR_SELECT_MAX as usize {
62 return Err(TpmError::TooManyItems(
63 crate::TpmErrorValue::new(0).limit(TPM_PCR_SELECT_MAX as usize, slice.len()),
64 ));
65 }
66 let mut pcr_select = Self::new();
67 let len_u8 = u8::try_from(slice.len()).map_err(|_| {
68 TpmError::IntegerTooLarge(crate::TpmErrorValue::new(0).value_usize(slice.len()))
69 })?;
70 pcr_select.size = TpmUint8::from(len_u8);
71 pcr_select.data[..slice.len()].copy_from_slice(slice);
72 Ok(pcr_select)
73 }
74}
75
76impl Debug for TpmsPcrSelect {
77 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
78 write!(f, "TpmsPcrSelect(")?;
79 for byte in self.iter() {
80 write!(f, "{byte:02X}")?;
81 }
82 write!(f, ")")
83 }
84}
85
86impl TpmSized for TpmsPcrSelect {
87 const SIZE: usize = size_of::<TpmUint8>() + TPM_PCR_SELECT_MAX as usize;
88
89 fn len(&self) -> usize {
90 size_of::<TpmUint8>() + u8::from(self.size) as usize
91 }
92}
93
94impl TpmMarshal for TpmsPcrSelect {
95 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
96 self.size.marshal(writer)?;
97 writer.write_bytes(self)
98 }
99}
100
101impl<'a> crate::TpmField<'a> for TpmsPcrSelect {
102 type View = &'a [u8];
103
104 fn cast_prefix_field(buf: &'a [u8]) -> TpmResult<(Self::View, &'a [u8])> {
105 let (size, remainder) = <TpmUint8 as crate::TpmCast>::cast_prefix(buf)?;
106 let size = size.get() as usize;
107
108 if size > TPM_PCR_SELECT_MAX as usize {
109 return Err(TpmError::TooManyItems(
110 crate::TpmErrorValue::new(0).limit(TPM_PCR_SELECT_MAX as usize, size),
111 ));
112 }
113
114 if remainder.len() < size {
115 return Err(TpmError::UnexpectedEnd(
116 crate::TpmErrorValue::new(size_of::<TpmUint8>()).size(size, remainder.len()),
117 ));
118 }
119
120 let (pcr_select, remainder) = remainder.split_at(size);
121 Ok((pcr_select, remainder))
122 }
123}
124
125tpm_struct! {
126 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
127 wire: TpmsAcOutputWire,
128 pub struct TpmsAcOutput {
129 pub tag: TpmAt,
130 pub data: TpmUint32,
131 }
132}
133
134tpm_struct! {
135 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
136 wire: TpmsAlgPropertyWire,
137 pub struct TpmsAlgProperty {
138 pub alg: TpmAlgId,
139 pub alg_properties: TpmaAlgorithm,
140 }
141}
142
143tpm_struct! {
144 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
145 wire: TpmsAuthCommandWire,
146 pub struct TpmsAuthCommand {
147 pub session_handle: TpmHandle,
148 pub nonce: Tpm2bNonce,
149 pub session_attributes: TpmaSession,
150 pub hmac: Tpm2bAuth,
151 }
152}
153
154tpm_struct! {
155 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
156 wire: TpmsAuthResponseWire,
157 pub struct TpmsAuthResponse {
158 pub nonce: Tpm2bNonce,
159 pub session_attributes: TpmaSession,
160 pub hmac: Tpm2bAuth,
161 }
162}
163
164#[derive(Debug, PartialEq, Eq, Clone)]
165pub struct TpmsCapabilityData {
166 pub capability: TpmCap,
167 pub data: TpmuCapabilities,
168}
169
170impl TpmSized for TpmsCapabilityData {
171 const SIZE: usize = size_of::<TpmUint32>() + TpmuCapabilities::SIZE;
172 fn len(&self) -> usize {
173 self.capability.len() + self.data.len()
174 }
175}
176
177impl TpmMarshal for TpmsCapabilityData {
178 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
179 self.capability.marshal(writer)?;
180 self.data.marshal(writer)
181 }
182}
183
184tpm_struct! {
185 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
186 wire: TpmsClockInfoWire,
187 pub struct TpmsClockInfo {
188 pub clock: TpmUint64,
189 pub reset_count: TpmUint32,
190 pub restart_count: TpmUint32,
191 pub safe: TpmiYesNo,
192 }
193}
194
195tpm_struct! {
196 #[derive(Debug, PartialEq, Eq, Clone)]
197 wire: TpmsContextWire,
198 pub struct TpmsContext {
199 pub sequence: TpmUint64,
200 pub saved_handle: TpmHandle,
201 pub hierarchy: TpmRh,
202 pub context_blob: Tpm2b,
203 }
204}
205
206tpm_struct! {
207 #[derive(Debug, PartialEq, Eq, Clone, Default)]
208 wire: TpmsCreationDataWire,
209 pub struct TpmsCreationData {
210 pub pcr_select: TpmlPcrSelection,
211 pub pcr_digest: Tpm2bDigest,
212 pub locality: TpmaLocality,
213 pub parent_name_alg: TpmAlgId,
214 pub parent_name: Tpm2bName,
215 pub parent_qualified_name: Tpm2bName,
216 pub outside_info: Tpm2bData,
217 }
218}
219
220tpm_struct! {
221 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
222 wire: TpmsEccPointWire,
223 pub struct TpmsEccPoint {
224 pub x: Tpm2bEccParameter,
225 pub y: Tpm2bEccParameter,
226 }
227}
228
229tpm_struct! {
230 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
231 wire: TpmsEmptyWire,
232 pub struct TpmsEmpty {}
233}
234
235tpm_struct! {
236 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
237 wire: TpmsKeyedhashParmsWire,
238 pub struct TpmsKeyedhashParms {
239 pub scheme: TpmtKeyedhashScheme,
240 }
241}
242
243tpm_struct! {
244 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
245 wire: TpmsNvPublicWire,
246 pub struct TpmsNvPublic {
247 pub nv_index: TpmHandle,
248 pub name_alg: TpmAlgId,
249 pub attributes: TpmaNv,
250 pub auth_policy: Tpm2bDigest,
251 pub data_size: TpmUint16,
252 }
253}
254
255tpm_struct! {
256 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
257 wire: TpmsNvPublicExpAttrWire,
258 pub struct TpmsNvPublicExpAttr {
259 pub nv_index: TpmiRhNvExpIndex,
260 pub name_alg: TpmAlgId,
261 pub attributes: TpmaNvExp,
262 pub auth_policy: Tpm2bDigest,
263 pub data_size: TpmUint16,
264 }
265}
266
267#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
268pub struct TpmsPcrSelection {
269 pub hash: TpmAlgId,
270 pub pcr_select: TpmsPcrSelect,
271}
272
273impl TpmSized for TpmsPcrSelection {
274 const SIZE: usize = TpmAlgId::SIZE + 1 + TPM_PCR_SELECT_MAX as usize;
275
276 fn len(&self) -> usize {
277 self.hash.len() + self.pcr_select.len()
278 }
279}
280
281impl TpmMarshal for TpmsPcrSelection {
282 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
283 self.hash.marshal(writer)?;
284 self.pcr_select.marshal(writer)
285 }
286}
287
288impl<'a> crate::TpmField<'a> for TpmsPcrSelection {
289 type View = (TpmAlgId, &'a [u8]);
290
291 fn cast_prefix_field(buf: &'a [u8]) -> TpmResult<(Self::View, &'a [u8])> {
292 let (hash, buf) = <TpmAlgId as crate::TpmField>::cast_prefix_field(buf)?;
293 let (pcr_select, buf) = <TpmsPcrSelect as crate::TpmField>::cast_prefix_field(buf)?;
294
295 Ok(((hash, pcr_select), buf))
296 }
297}
298
299tpm_struct! {
300 #[derive(Debug, Default, PartialEq, Eq, Clone)]
301 wire: TpmsSensitiveCreateWire,
302 pub struct TpmsSensitiveCreate {
303 pub user_auth: Tpm2bAuth,
304 pub data: Tpm2bSensitiveData,
305 }
306}
307
308tpm_struct! {
309 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
310 wire: TpmsIdObjectWire,
311 pub struct TpmsIdObject {
312 pub integrity_hmac: Tpm2bDigest,
313 pub enc_identity: Tpm2bDigest,
314 }
315}
316
317tpm_struct! {
318 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
319 wire: TpmsSymcipherParmsWire,
320 pub struct TpmsSymcipherParms {
321 pub sym: TpmtSymDefObject,
322 }
323}
324
325tpm_struct! {
326 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
327 wire: TpmsTaggedPropertyWire,
328 pub struct TpmsTaggedProperty {
329 pub property: TpmPt,
330 pub value: TpmUint32,
331 }
332}
333
334tpm_struct! {
335 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
336 wire: TpmsTimeInfoWire,
337 pub struct TpmsTimeInfo {
338 pub time: TpmUint64,
339 pub clock_info: TpmsClockInfo,
340 }
341}
342
343tpm_struct! {
344 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
345 wire: TpmsSignatureRsaWire,
346 pub struct TpmsSignatureRsa {
347 pub hash: TpmAlgId,
348 pub sig: crate::data::Tpm2bPublicKeyRsa,
349 }
350}
351
352tpm_struct! {
353 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
354 wire: TpmsSignatureEccWire,
355 pub struct TpmsSignatureEcc {
356 pub hash: TpmAlgId,
357 pub signature_r: Tpm2bEccParameter,
358 pub signature_s: Tpm2bEccParameter,
359 }
360}
361
362tpm_struct! {
363 #[derive(Debug, PartialEq, Eq, Clone, Default)]
364 wire: TpmsTimeAttestInfoWire,
365 pub struct TpmsTimeAttestInfo {
366 pub time: TpmsTimeInfo,
367 pub firmware_version: TpmUint64,
368 }
369}
370
371tpm_struct! {
372 #[derive(Debug, PartialEq, Eq, Clone, Default)]
373 wire: TpmsCertifyInfoWire,
374 pub struct TpmsCertifyInfo {
375 pub name: Tpm2bName,
376 pub qualified_name: Tpm2bName,
377 }
378}
379
380tpm_struct! {
381 #[derive(Debug, PartialEq, Eq, Clone, Default)]
382 wire: TpmsQuoteInfoWire,
383 pub struct TpmsQuoteInfo {
384 pub pcr_select: TpmlPcrSelection,
385 pub pcr_digest: Tpm2bDigest,
386 }
387}
388
389tpm_struct! {
390 #[derive(Debug, PartialEq, Eq, Clone, Default)]
391 wire: TpmsCommandAuditInfoWire,
392 pub struct TpmsCommandAuditInfo {
393 pub audit_counter: TpmUint64,
394 pub digest_alg: TpmAlgId,
395 pub audit_digest: Tpm2bDigest,
396 pub command_digest: Tpm2bDigest,
397 }
398}
399
400tpm_struct! {
401 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
402 wire: TpmsSessionAuditInfoWire,
403 pub struct TpmsSessionAuditInfo {
404 pub exclusive_session: TpmiYesNo,
405 pub session_digest: Tpm2bDigest,
406 }
407}
408
409tpm_struct! {
410 #[derive(Debug, PartialEq, Eq, Clone, Default)]
411 wire: TpmsCreationInfoWire,
412 pub struct TpmsCreationInfo {
413 pub object_name: Tpm2bName,
414 pub creation_hash: Tpm2bDigest,
415 }
416}
417
418tpm_struct! {
419 #[derive(Debug, PartialEq, Eq, Clone, Default)]
420 wire: TpmsNvCertifyInfoWire,
421 pub struct TpmsNvCertifyInfo {
422 pub index_name: Tpm2bName,
423 pub offset: TpmUint16,
424 pub nv_contents: Tpm2bMaxNvBuffer,
425 }
426}
427
428tpm_struct! {
429 #[derive(Debug, PartialEq, Eq, Clone, Default)]
430 wire: TpmsNvDigestCertifyInfoWire,
431 pub struct TpmsNvDigestCertifyInfo {
432 pub index_name: Tpm2bName,
433 pub nv_digest: Tpm2bDigest,
434 }
435}
436
437tpm_struct! {
438 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
439 wire: TpmsAlgorithmDetailEccWire,
440 pub struct TpmsAlgorithmDetailEcc {
441 pub curve_id: TpmEccCurve,
442 pub key_size: TpmUint16,
443 pub kdf: TpmtKdfScheme,
444 pub sign: TpmtEccScheme,
445 pub p: Tpm2bEccParameter,
446 pub a: Tpm2bEccParameter,
447 pub b: Tpm2bEccParameter,
448 pub gx: Tpm2bEccParameter,
449 pub gy: Tpm2bEccParameter,
450 pub n: Tpm2bEccParameter,
451 pub h: Tpm2bEccParameter,
452 }
453}
454
455#[derive(Debug, PartialEq, Eq, Clone)]
456pub struct TpmsAttest {
457 pub attest_type: TpmSt,
458 pub qualified_signer: Tpm2bName,
459 pub extra_data: Tpm2bData,
460 pub clock_info: TpmsClockInfo,
461 pub firmware_version: TpmUint64,
462 pub attested: TpmuAttest,
463}
464
465impl TpmSized for TpmsAttest {
466 const SIZE: usize = size_of::<TpmUint32>()
467 + TpmSt::SIZE
468 + Tpm2bName::SIZE
469 + Tpm2bData::SIZE
470 + TpmsClockInfo::SIZE
471 + size_of::<TpmUint64>()
472 + TpmuAttest::SIZE;
473 fn len(&self) -> usize {
474 size_of::<TpmUint32>()
475 + self.attest_type.len()
476 + self.qualified_signer.len()
477 + self.extra_data.len()
478 + self.clock_info.len()
479 + size_of::<TpmUint64>()
480 + self.attested.len()
481 }
482}
483
484impl TpmMarshal for TpmsAttest {
485 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
486 crate::basic::TpmUint32::from(TPM_GENERATED_VALUE).marshal(writer)?;
487 self.attest_type.marshal(writer)?;
488 self.qualified_signer.marshal(writer)?;
489 self.extra_data.marshal(writer)?;
490 self.clock_info.marshal(writer)?;
491 self.firmware_version.marshal(writer)?;
492 self.attested.marshal(writer)
493 }
494}
495
496tpm_struct! {
497 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
498 wire: TpmsSchemeHashWire,
499 pub struct TpmsSchemeHash {
500 pub hash_alg: TpmiAlgHash,
501 }
502}
503
504pub type TpmsSchemeHmac = TpmsSchemeHash;
505
506tpm_struct! {
507 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
508 wire: TpmsSchemeXorWire,
509 pub struct TpmsSchemeXor {
510 pub hash_alg: TpmiAlgHash,
511 pub kdf: TpmtKdfScheme,
512 }
513}
514
515tpm_struct! {
516 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
517 wire: TpmsRsaParmsWire,
518 pub struct TpmsRsaParms {
519 pub symmetric: TpmtSymDefObject,
520 pub scheme: TpmtRsaScheme,
521 pub key_bits: TpmUint16,
522 pub exponent: TpmUint32,
523 }
524}
525
526tpm_struct! {
527 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
528 wire: TpmsEccParmsWire,
529 pub struct TpmsEccParms {
530 pub symmetric: TpmtSymDefObject,
531 pub scheme: TpmtEccScheme,
532 pub curve_id: TpmEccCurve,
533 pub kdf: TpmtKdfScheme,
534 }
535}