Skip to main content

tss_esapi/structures/attestation/
attest.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    constants::tss::TPM2_GENERATED_VALUE,
6    interface_types::structure_tags::AttestationType,
7    structures::{AttestInfo, ClockInfo, Data, Name},
8    traits::impl_mu_standard,
9    tss2_esys::TPMS_ATTEST,
10    Error, Result, WrapperErrorKind,
11};
12use log::error;
13use std::convert::{TryFrom, TryInto};
14
15/// Type for holding attestation data
16///
17/// # Details
18/// Corresponds to `TPMS_ATTEST`.
19#[derive(Debug, Clone)]
20pub struct Attest {
21    attestation_type: AttestationType,
22    qualified_signer: Name,
23    extra_data: Data,
24    clock_info: ClockInfo,
25    firmware_version: u64,
26    attested: AttestInfo,
27}
28
29impl Attest {
30    /// Returns attestation type
31    pub const fn attestation_type(&self) -> AttestationType {
32        self.attestation_type
33    }
34
35    /// Returns the qualified name of the signing object.
36    pub const fn qualified_signer(&self) -> &Name {
37        &self.qualified_signer
38    }
39
40    /// Returns the extra data specified by the caller.
41    pub const fn extra_data(&self) -> &Data {
42        &self.extra_data
43    }
44
45    /// Returns the internal TPM clock data.
46    pub const fn clock_info(&self) -> &ClockInfo {
47        &self.clock_info
48    }
49
50    /// Returns TPM firmware version number.
51    pub const fn firmware_version(&self) -> u64 {
52        self.firmware_version
53    }
54
55    /// Returns types specific attestation information
56    pub const fn attested(&self) -> &AttestInfo {
57        &self.attested
58    }
59}
60
61impl From<Attest> for TPMS_ATTEST {
62    fn from(attest: Attest) -> Self {
63        TPMS_ATTEST {
64            magic: TPM2_GENERATED_VALUE,
65            type_: attest.attestation_type.into(),
66            qualifiedSigner: attest.qualified_signer.into(),
67            extraData: attest.extra_data.into(),
68            clockInfo: attest.clock_info.into(),
69            firmwareVersion: attest.firmware_version,
70            attested: attest.attested.into(),
71        }
72    }
73}
74
75impl TryFrom<TPMS_ATTEST> for Attest {
76    type Error = Error;
77
78    fn try_from(tpms_attest: TPMS_ATTEST) -> Result<Self> {
79        if tpms_attest.magic != TPM2_GENERATED_VALUE {
80            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
81        }
82
83        let attestation_type = AttestationType::try_from(tpms_attest.type_)?;
84        Ok(Attest {
85            attestation_type,
86            qualified_signer: Name::try_from(tpms_attest.qualifiedSigner)?,
87            extra_data: Data::try_from(tpms_attest.extraData)?,
88            clock_info: ClockInfo::try_from(tpms_attest.clockInfo)?,
89            firmware_version: tpms_attest.firmwareVersion,
90            attested: match attestation_type {
91                AttestationType::Certify => AttestInfo::Certify {
92                    info: unsafe { tpms_attest.attested.certify }.try_into()?,
93                },
94                AttestationType::Quote => AttestInfo::Quote {
95                    info: unsafe { tpms_attest.attested.quote }.try_into()?,
96                },
97                AttestationType::SessionAudit => AttestInfo::SessionAudit {
98                    info: unsafe { tpms_attest.attested.sessionAudit }.try_into()?,
99                },
100                AttestationType::CommandAudit => AttestInfo::CommandAudit {
101                    info: unsafe { tpms_attest.attested.commandAudit }.try_into()?,
102                },
103                AttestationType::Time => AttestInfo::Time {
104                    info: unsafe { tpms_attest.attested.time }.try_into()?,
105                },
106                AttestationType::Creation => AttestInfo::Creation {
107                    info: unsafe { tpms_attest.attested.creation }.try_into()?,
108                },
109                AttestationType::Nv => AttestInfo::Nv {
110                    info: unsafe { tpms_attest.attested.nv }.try_into()?,
111                },
112                AttestationType::NvDigest => {
113                    error!("NvDigest attestation type is currently not supported");
114                    return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
115                }
116            },
117        })
118    }
119}
120
121impl_mu_standard!(Attest, TPMS_ATTEST);