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