Skip to content

Commit fb8202d

Browse files
committed
Adds the Attest and AttestInfo type.
- Adds the Attest and AttestInfo types. The Attest type corresponds to the TPMS_ATTEST and the AttestInfo type corresponds somewhat to the TPMU_ATTEST type. Signed-off-by: Jesper Brynolf <jesper.brynolf@gmail.com>
1 parent fa9a755 commit fb8202d

File tree

7 files changed

+836
-4
lines changed

7 files changed

+836
-4
lines changed

tss-esapi/src/structures/attest.rs

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

tss-esapi/src/structures/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,13 @@ pub use nv_certify_info::NvCertifyInfo;
188188
/////////////////////////////////////////////////////////
189189
mod nv_digest_certify_info;
190190
pub use nv_digest_certify_info::NvDigestCertifyInfo;
191+
/////////////////////////////////////////////////////////
192+
/// Attest Info
193+
/////////////////////////////////////////////////////////
194+
mod attest_info;
195+
pub use attest_info::AttestInfo;
196+
/////////////////////////////////////////////////////////
197+
/// Attest
198+
/////////////////////////////////////////////////////////
199+
mod attest;
200+
pub use attest::Attest;

tss-esapi/tests/integration_tests/common/tpms_types_equality_checks.rs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
use tss_esapi::tss2_esys::{
2-
TPMS_CERTIFY_INFO, TPMS_CLOCK_INFO, TPMS_COMMAND_AUDIT_INFO, TPMS_CREATION_INFO,
3-
TPMS_NV_CERTIFY_INFO, TPMS_PCR_SELECTION, TPMS_QUOTE_INFO, TPMS_SESSION_AUDIT_INFO,
4-
TPMS_TIME_ATTEST_INFO, TPMS_TIME_INFO,
1+
use tss_esapi::{
2+
constants::tss::{
3+
TPM2_ST_ATTEST_CERTIFY, TPM2_ST_ATTEST_COMMAND_AUDIT, TPM2_ST_ATTEST_CREATION,
4+
TPM2_ST_ATTEST_NV, TPM2_ST_ATTEST_QUOTE, TPM2_ST_ATTEST_SESSION_AUDIT, TPM2_ST_ATTEST_TIME,
5+
},
6+
tss2_esys::{
7+
TPMS_ATTEST, TPMS_CERTIFY_INFO, TPMS_CLOCK_INFO, TPMS_COMMAND_AUDIT_INFO,
8+
TPMS_CREATION_INFO, TPMS_NV_CERTIFY_INFO, TPMS_PCR_SELECTION, TPMS_QUOTE_INFO,
9+
TPMS_SESSION_AUDIT_INFO, TPMS_TIME_ATTEST_INFO, TPMS_TIME_INFO,
10+
},
511
};
612

713
macro_rules! ensure_sized_buffer_field_equality {
@@ -146,3 +152,58 @@ pub fn ensure_tpms_nv_certify_info_equality(
146152
);
147153
ensure_sized_buffer_field_equality!(expected, actual, nvContents, buffer, TPM2B_MAX_NV_BUFFER);
148154
}
155+
156+
#[allow(dead_code)]
157+
pub fn ensure_tpms_attest_equality(expected: &TPMS_ATTEST, actual: &TPMS_ATTEST) {
158+
assert_eq!(
159+
expected.magic, actual.magic,
160+
"'magic' value in TPMS_ATTEST, mismatch between actual and expected"
161+
);
162+
assert_eq!(
163+
expected.type_, actual.type_,
164+
"'type_' value in TPMS_ATTEST, mismatch between actual and expected",
165+
);
166+
ensure_sized_buffer_field_equality!(expected, actual, qualifiedSigner, name, TPM2B_NAME);
167+
ensure_sized_buffer_field_equality!(expected, actual, extraData, buffer, TPM2B_DATA);
168+
ensure_tpms_clock_info_equality(&expected.clockInfo, &actual.clockInfo);
169+
assert_eq!(
170+
expected.firmwareVersion, actual.firmwareVersion,
171+
"'firmwareVersion' value in TPMS_ATTEST, mismatch between actual and expected",
172+
);
173+
match expected.type_ {
174+
TPM2_ST_ATTEST_CERTIFY => {
175+
ensure_tpms_certify_info_equality(unsafe { &expected.attested.certify }, unsafe {
176+
&actual.attested.certify
177+
});
178+
}
179+
TPM2_ST_ATTEST_QUOTE => {
180+
ensure_tpms_quote_info_equality(unsafe { &expected.attested.quote }, unsafe {
181+
&actual.attested.quote
182+
});
183+
}
184+
TPM2_ST_ATTEST_SESSION_AUDIT => ensure_tpms_session_audit_info_equality(
185+
unsafe { &expected.attested.sessionAudit },
186+
unsafe { &actual.attested.sessionAudit },
187+
),
188+
TPM2_ST_ATTEST_COMMAND_AUDIT => ensure_tpms_command_audit_info_equality(
189+
unsafe { &expected.attested.commandAudit },
190+
unsafe { &actual.attested.commandAudit },
191+
),
192+
TPM2_ST_ATTEST_TIME => {
193+
ensure_tpms_time_attest_info_equality(unsafe { &expected.attested.time }, unsafe {
194+
&actual.attested.time
195+
})
196+
}
197+
TPM2_ST_ATTEST_CREATION => {
198+
ensure_tpms_creation_info_equality(unsafe { &expected.attested.creation }, unsafe {
199+
&actual.attested.creation
200+
})
201+
}
202+
TPM2_ST_ATTEST_NV => {
203+
ensure_tpms_nv_certify_info_equality(unsafe { &expected.attested.nv }, unsafe {
204+
&actual.attested.nv
205+
})
206+
}
207+
_ => panic!("'type_' value in TPMS_ATTEST contained invalid or unsupported value"),
208+
}
209+
}

0 commit comments

Comments
 (0)