Skip to content

Commit 5fcf5c8

Browse files
authored
Merge pull request #293 from Superhepper/attest_structures
Adds the attest structures
2 parents 0185a7d + 0185a3c commit 5fcf5c8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2637
-23
lines changed

tss-esapi/src/context.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub struct Context {
5656
),
5757
/// TCTI context handle associated with the ESYS context.
5858
/// As with the ESYS context, an optional Mbox wrapper allows the context to be deallocated.
59-
tcti_context: TctiContext,
59+
_tcti_context: TctiContext,
6060
/// Handle manager that keep tracks of the state of the handles and how they are to be
6161
/// disposed.
6262
handle_manager: HandleManager,
@@ -91,12 +91,12 @@ impl Context {
9191
pub fn new(tcti_name_conf: TctiNameConf) -> Result<Self> {
9292
let mut esys_context = null_mut();
9393

94-
let mut tcti_context = TctiContext::initialize(tcti_name_conf)?;
94+
let mut _tcti_context = TctiContext::initialize(tcti_name_conf)?;
9595

9696
let ret = unsafe {
9797
Esys_Initialize(
9898
&mut esys_context,
99-
tcti_context.tcti_context_ptr(),
99+
_tcti_context.tcti_context_ptr(),
100100
null_mut(),
101101
)
102102
};
@@ -107,7 +107,7 @@ impl Context {
107107
let context = Context {
108108
esys_context,
109109
sessions: (None, None, None),
110-
tcti_context,
110+
_tcti_context,
111111
handle_manager: HandleManager::new(),
112112
cached_tpm_properties: HashMap::new(),
113113
};

tss-esapi/src/context/tpm_commands/attestation_commands.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
use crate::{
44
handles::KeyHandle,
5-
structures::{Data, PcrSelectionList, Signature, SignatureScheme},
5+
structures::{Attest, AttestBuffer, Data, PcrSelectionList, Signature, SignatureScheme},
66
tss2_esys::*,
77
Context, Error, Result,
88
};
@@ -25,7 +25,7 @@ impl Context {
2525
qualifying_data: &Data,
2626
signing_scheme: SignatureScheme,
2727
pcr_selection_list: PcrSelectionList,
28-
) -> Result<(TPM2B_ATTEST, Signature)> {
28+
) -> Result<(Attest, Signature)> {
2929
let mut quoted = null_mut();
3030
let mut signature = null_mut();
3131
let ret = unsafe {
@@ -45,9 +45,12 @@ impl Context {
4545
let ret = Error::from_tss_rc(ret);
4646

4747
if ret.is_success() {
48-
let quoted = unsafe { MBox::<TPM2B_ATTEST>::from_raw(quoted) };
48+
let quoted = unsafe { MBox::from_raw(quoted) };
4949
let signature = unsafe { MBox::from_raw(signature) };
50-
Ok((*quoted, Signature::try_from(*signature)?))
50+
Ok((
51+
Attest::try_from(AttestBuffer::try_from(*quoted)?)?,
52+
Signature::try_from(*signature)?,
53+
))
5154
} else {
5255
error!("Error in quoting PCR: {}", ret);
5356
Err(ret)

tss-esapi/src/interface_types/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33

44
//! This module contains the different interface types defined in
55
//! the TPM 2.0 specification.
6+
mod yes_no;
7+
68
pub mod algorithm;
79
pub mod dynamic_handles;
810
pub mod ecc;
911
pub mod key_bits;
1012
pub mod resource_handles;
1113
pub mod session_handles;
14+
pub mod structure_tags;
15+
16+
pub use yes_no::YesNo;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::{constants::StructureTag, tss2_esys::TPMI_ST_ATTEST, Error, Result, WrapperErrorKind};
5+
use std::convert::TryFrom;
6+
7+
/// Type of attestation.
8+
///
9+
/// # Details
10+
/// Corresponds to `TPMI_ST_ATTEST`.
11+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12+
pub enum AttestationType {
13+
Certify,
14+
Quote,
15+
SessionAudit,
16+
CommandAudit,
17+
Time,
18+
Creation,
19+
Nv,
20+
NvDigest,
21+
}
22+
23+
impl From<AttestationType> for StructureTag {
24+
fn from(native: AttestationType) -> Self {
25+
match native {
26+
AttestationType::Certify => StructureTag::AttestCertify,
27+
AttestationType::Quote => StructureTag::AttestQuote,
28+
AttestationType::SessionAudit => StructureTag::AttestSessionAudit,
29+
AttestationType::CommandAudit => StructureTag::AttestCommandAudit,
30+
AttestationType::Time => StructureTag::AttestTime,
31+
AttestationType::Creation => StructureTag::AttestCreation,
32+
AttestationType::Nv => StructureTag::AttestNv,
33+
AttestationType::NvDigest => StructureTag::AttestNvDigest,
34+
}
35+
}
36+
}
37+
38+
impl TryFrom<StructureTag> for AttestationType {
39+
type Error = Error;
40+
41+
fn try_from(structure_tag: StructureTag) -> Result<AttestationType> {
42+
match structure_tag {
43+
StructureTag::AttestCertify => Ok(AttestationType::Certify),
44+
StructureTag::AttestQuote => Ok(AttestationType::Quote),
45+
StructureTag::AttestSessionAudit => Ok(AttestationType::SessionAudit),
46+
StructureTag::AttestCommandAudit => Ok(AttestationType::CommandAudit),
47+
StructureTag::AttestTime => Ok(AttestationType::Time),
48+
StructureTag::AttestCreation => Ok(AttestationType::Creation),
49+
StructureTag::AttestNv => Ok(AttestationType::Nv),
50+
StructureTag::AttestNvDigest => Ok(AttestationType::NvDigest),
51+
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
52+
}
53+
}
54+
}
55+
56+
impl From<AttestationType> for TPMI_ST_ATTEST {
57+
fn from(attestation_type: AttestationType) -> Self {
58+
StructureTag::from(attestation_type).into()
59+
}
60+
}
61+
62+
impl TryFrom<TPMI_ST_ATTEST> for AttestationType {
63+
type Error = Error;
64+
65+
fn try_from(tpmi_st_attest: TPMI_ST_ATTEST) -> Result<Self> {
66+
AttestationType::try_from(StructureTag::try_from(tpmi_st_attest)?)
67+
}
68+
}
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
use crate::{tss2_esys::TPMI_YES_NO, Error, Result, WrapperErrorKind};
4+
use std::convert::TryFrom;
5+
6+
/// Enum representing a yes or no.
7+
///
8+
/// # Details
9+
/// This corresponds to the TPMI_YES_NO interface type.
10+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11+
pub enum YesNo {
12+
Yes,
13+
No,
14+
}
15+
16+
impl From<bool> for YesNo {
17+
fn from(value: bool) -> Self {
18+
if value {
19+
YesNo::Yes
20+
} else {
21+
YesNo::No
22+
}
23+
}
24+
}
25+
26+
impl From<YesNo> for bool {
27+
fn from(yes_no: YesNo) -> Self {
28+
match yes_no {
29+
YesNo::Yes => true,
30+
YesNo::No => false,
31+
}
32+
}
33+
}
34+
35+
impl From<YesNo> for TPMI_YES_NO {
36+
fn from(yes_no: YesNo) -> Self {
37+
match yes_no {
38+
YesNo::Yes => 1,
39+
YesNo::No => 0,
40+
}
41+
}
42+
}
43+
44+
impl TryFrom<TPMI_YES_NO> for YesNo {
45+
type Error = Error;
46+
47+
fn try_from(tpmi_yes_no: TPMI_YES_NO) -> Result<Self> {
48+
match tpmi_yes_no {
49+
0 => Ok(YesNo::No),
50+
1 => Ok(YesNo::Yes),
51+
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
52+
}
53+
}
54+
}

tss-esapi/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,5 @@ pub mod interface_types;
113113
pub mod nv;
114114
pub mod structures;
115115
pub mod tcti_ldr;
116+
pub mod traits;
116117
pub mod utils;

tss-esapi/src/structures/attest.rs

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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+
traits::{Marshall, UnMarshall},
9+
tss2_esys::TPMS_ATTEST,
10+
Error, Result, WrapperErrorKind,
11+
};
12+
use log::error;
13+
use std::convert::{TryFrom, TryInto};
14+
15+
/// Type for holding attestation data
16+
///
17+
/// # Details
18+
/// Corresponds to `TPMS_ATTEST`.
19+
#[derive(Debug, Clone)]
20+
pub 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+
29+
impl Attest {
30+
/// Returns ttestation 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+
/// Retirns 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+
61+
impl 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+
75+
impl 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+
121+
impl Marshall for Attest {
122+
const BUFFER_SIZE: usize = std::mem::size_of::<TPMS_ATTEST>();
123+
124+
fn marshall(&self) -> Result<Vec<u8>> {
125+
let mut buffer = vec![0; Self::BUFFER_SIZE];
126+
let mut offset = 0;
127+
128+
let ret = Error::from_tss_rc(unsafe {
129+
crate::tss2_esys::Tss2_MU_TPMS_ATTEST_Marshal(
130+
&self.clone().into(),
131+
buffer.as_mut_ptr(),
132+
Self::BUFFER_SIZE.try_into().map_err(|e| {
133+
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
134+
Error::local_error(WrapperErrorKind::InvalidParam)
135+
})?,
136+
&mut offset,
137+
)
138+
});
139+
140+
if !ret.is_success() {
141+
return Err(ret);
142+
}
143+
144+
let checked_offset = usize::try_from(offset).map_err(|e| {
145+
error!("Failed to parse offset as usize: {}", e);
146+
Error::local_error(WrapperErrorKind::InvalidParam)
147+
})?;
148+
149+
buffer.truncate(checked_offset);
150+
151+
Ok(buffer)
152+
}
153+
}
154+
155+
impl UnMarshall for Attest {
156+
fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
157+
let mut dest = TPMS_ATTEST::default();
158+
let mut offset = 0;
159+
160+
let ret = Error::from_tss_rc(unsafe {
161+
crate::tss2_esys::Tss2_MU_TPMS_ATTEST_Unmarshal(
162+
marshalled_data.as_ptr(),
163+
marshalled_data.len().try_into().map_err(|e| {
164+
error!("Failed to convert length of marshalled data: {}", e);
165+
Error::local_error(WrapperErrorKind::InvalidParam)
166+
})?,
167+
&mut offset,
168+
&mut dest,
169+
)
170+
});
171+
172+
if !ret.is_success() {
173+
return Err(ret);
174+
}
175+
176+
Attest::try_from(dest)
177+
}
178+
}

0 commit comments

Comments
 (0)