Skip to content

Commit ac55b89

Browse files
committed
Add CommandTag
Adding a native implementation of `TPMI_ST_COMMAND_TAG`. Signed-off-by: Ionut Mihalcea <ionut.mihalcea@arm.com>
1 parent c4a78df commit ac55b89

File tree

2 files changed

+247
-2
lines changed

2 files changed

+247
-2
lines changed

tss-esapi/src/interface_types/structure_tags.rs

Lines changed: 189 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
// Copyright 2021 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use crate::{constants::StructureTag, tss2_esys::TPMI_ST_ATTEST, Error, Result, WrapperErrorKind};
5-
use std::convert::TryFrom;
4+
use log::error;
5+
use tss_esapi_sys::TPMI_ST_COMMAND_TAG;
6+
7+
use crate::{
8+
constants::StructureTag,
9+
traits::{Marshall, UnMarshall},
10+
tss2_esys::TPMI_ST_ATTEST,
11+
Error, Result, ReturnCode, WrapperErrorKind,
12+
};
13+
use std::convert::{TryFrom, TryInto};
614

715
/// Type of attestation.
816
///
@@ -66,3 +74,182 @@ impl TryFrom<TPMI_ST_ATTEST> for AttestationType {
6674
AttestationType::try_from(StructureTag::try_from(tpmi_st_attest)?)
6775
}
6876
}
77+
78+
impl Marshall for AttestationType {
79+
const BUFFER_SIZE: usize = std::mem::size_of::<TPMI_ST_ATTEST>();
80+
81+
/// Produce a marshalled [`TPMI_ST_ATTEST`]
82+
fn marshall(&self) -> Result<Vec<u8>> {
83+
let mut buffer = vec![0; Self::BUFFER_SIZE];
84+
let mut offset = 0;
85+
86+
ReturnCode::ensure_success(
87+
unsafe {
88+
crate::tss2_esys::Tss2_MU_TPM2_ST_Marshal(
89+
(*self).into(),
90+
buffer.as_mut_ptr(),
91+
Self::BUFFER_SIZE.try_into().map_err(|e| {
92+
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
93+
Error::local_error(WrapperErrorKind::InvalidParam)
94+
})?,
95+
&mut offset,
96+
)
97+
},
98+
|ret| {
99+
error!("Failed to marshal AttestationType: {}", ret);
100+
},
101+
)?;
102+
103+
let checked_offset = usize::try_from(offset).map_err(|e| {
104+
error!("Failed to parse offset as usize: {}", e);
105+
Error::local_error(WrapperErrorKind::InvalidParam)
106+
})?;
107+
108+
buffer.truncate(checked_offset);
109+
110+
Ok(buffer)
111+
}
112+
}
113+
114+
impl UnMarshall for AttestationType {
115+
/// Unmarshall the structure from [`TPMI_ST_ATTEST`]
116+
fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
117+
AttestationType::unmarshall_offset(marshalled_data, &mut 0)
118+
}
119+
120+
fn unmarshall_offset(
121+
marshalled_data: &[u8],
122+
offset: &mut std::os::raw::c_ulong,
123+
) -> Result<Self> {
124+
let mut dest = TPMI_ST_ATTEST::default();
125+
126+
ReturnCode::ensure_success(
127+
unsafe {
128+
crate::tss2_esys::Tss2_MU_TPM2_ST_Unmarshal(
129+
marshalled_data.as_ptr(),
130+
marshalled_data.len().try_into().map_err(|e| {
131+
error!("Failed to convert length of marshalled data: {}", e);
132+
Error::local_error(WrapperErrorKind::InvalidParam)
133+
})?,
134+
offset,
135+
&mut dest,
136+
)
137+
},
138+
|ret| error!("Failed to unmarshal AttestationType: {}", ret),
139+
)?;
140+
141+
AttestationType::try_from(dest)
142+
}
143+
}
144+
145+
/// Type of command tag.
146+
///
147+
/// # Details
148+
/// Corresponds to `TPMI_ST_COMMAND_TAG`.
149+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
150+
pub enum CommandTag {
151+
Sessions,
152+
NoSessions,
153+
}
154+
155+
impl From<CommandTag> for StructureTag {
156+
fn from(value: CommandTag) -> Self {
157+
match value {
158+
CommandTag::Sessions => StructureTag::Sessions,
159+
CommandTag::NoSessions => StructureTag::NoSessions,
160+
}
161+
}
162+
}
163+
164+
impl TryFrom<StructureTag> for CommandTag {
165+
type Error = Error;
166+
167+
fn try_from(value: StructureTag) -> std::result::Result<Self, Self::Error> {
168+
match value {
169+
StructureTag::Sessions => Ok(CommandTag::Sessions),
170+
StructureTag::NoSessions => Ok(CommandTag::NoSessions),
171+
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
172+
}
173+
}
174+
}
175+
176+
impl From<CommandTag> for TPMI_ST_COMMAND_TAG {
177+
fn from(command_tag: CommandTag) -> Self {
178+
StructureTag::from(command_tag).into()
179+
}
180+
}
181+
182+
impl TryFrom<TPMI_ST_COMMAND_TAG> for CommandTag {
183+
type Error = Error;
184+
185+
fn try_from(tpmi_st_command_tag: TPMI_ST_COMMAND_TAG) -> Result<Self> {
186+
CommandTag::try_from(StructureTag::try_from(tpmi_st_command_tag)?)
187+
}
188+
}
189+
190+
impl Marshall for CommandTag {
191+
const BUFFER_SIZE: usize = std::mem::size_of::<TPMI_ST_COMMAND_TAG>();
192+
193+
/// Produce a marshalled [`TPMI_ST_COMMAND_TAG`]
194+
fn marshall(&self) -> Result<Vec<u8>> {
195+
let mut buffer = vec![0; Self::BUFFER_SIZE];
196+
let mut offset = 0;
197+
198+
ReturnCode::ensure_success(
199+
unsafe {
200+
crate::tss2_esys::Tss2_MU_TPM2_ST_Marshal(
201+
(*self).into(),
202+
buffer.as_mut_ptr(),
203+
Self::BUFFER_SIZE.try_into().map_err(|e| {
204+
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
205+
Error::local_error(WrapperErrorKind::InvalidParam)
206+
})?,
207+
&mut offset,
208+
)
209+
},
210+
|ret| {
211+
error!("Failed to marshal CommandTag: {}", ret);
212+
},
213+
)?;
214+
215+
let checked_offset = usize::try_from(offset).map_err(|e| {
216+
error!("Failed to parse offset as usize: {}", e);
217+
Error::local_error(WrapperErrorKind::InvalidParam)
218+
})?;
219+
220+
buffer.truncate(checked_offset);
221+
222+
Ok(buffer)
223+
}
224+
}
225+
226+
impl UnMarshall for CommandTag {
227+
/// Unmarshall the structure from [`TPMI_ST_COMMAND_TAG`]
228+
fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
229+
CommandTag::unmarshall_offset(marshalled_data, &mut 0)
230+
}
231+
232+
fn unmarshall_offset(
233+
marshalled_data: &[u8],
234+
offset: &mut std::os::raw::c_ulong,
235+
) -> Result<Self> {
236+
let mut dest = TPMI_ST_COMMAND_TAG::default();
237+
238+
ReturnCode::ensure_success(
239+
unsafe {
240+
crate::tss2_esys::Tss2_MU_TPM2_ST_Unmarshal(
241+
marshalled_data.as_ptr(),
242+
marshalled_data.len().try_into().map_err(|e| {
243+
error!("Failed to convert length of marshalled data: {}", e);
244+
Error::local_error(WrapperErrorKind::InvalidParam)
245+
})?,
246+
offset,
247+
&mut dest,
248+
)
249+
},
250+
|ret| error!("Failed to unmarshal CommandTag: {}", ret),
251+
)?;
252+
253+
CommandTag::try_from(dest)
254+
}
255+
}

tss-esapi/tests/integration_tests/interface_types_tests/structure_tags_tests.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ macro_rules! test_valid_conversions {
2222
stringify!($strucutre_tag_item),
2323
);
2424
};
25+
26+
(CommandTag::$attestation_type_item:ident, StructureTag::$strucutre_tag_item:ident) => {
27+
assert_eq!(
28+
CommandTag::$attestation_type_item,
29+
CommandTag::try_from(StructureTag::$strucutre_tag_item).expect(&format!(
30+
"Could not convert StructureTag {}",
31+
stringify!($attestation_type_item)
32+
)),
33+
"StructureTag {} did not convert to the correct CommandTag {}",
34+
stringify!($strucutre_tag_item),
35+
stringify!($attestation_type_item),
36+
);
37+
38+
assert_eq!(
39+
StructureTag::$strucutre_tag_item,
40+
StructureTag::from(CommandTag::$attestation_type_item),
41+
"CommandTag {} did not convert to the correct StructureTag {}",
42+
stringify!($attestation_type_item),
43+
stringify!($strucutre_tag_item),
44+
);
45+
};
2546
}
2647

2748
mod attestation_type_tests {
@@ -57,4 +78,41 @@ mod attestation_type_tests {
5778
"Expected an error when converting StructureTag FuManifest into AttestationType",
5879
)
5980
}
81+
82+
#[test]
83+
fn test_marshall_unmarshall() {
84+
let val = AttestationType::SessionAudit;
85+
crate::common::check_marshall_unmarshall(&val);
86+
crate::common::check_marshall_unmarshall_offset(&val);
87+
}
88+
}
89+
90+
mod command_tag_tests {
91+
use std::convert::TryFrom;
92+
use tss_esapi::{
93+
constants::StructureTag, interface_types::structure_tags::CommandTag, Error,
94+
WrapperErrorKind,
95+
};
96+
97+
#[test]
98+
fn test_conversions() {
99+
test_valid_conversions!(CommandTag::Sessions, StructureTag::Sessions);
100+
test_valid_conversions!(CommandTag::NoSessions, StructureTag::NoSessions);
101+
}
102+
103+
#[test]
104+
fn test_invalid_conversions() {
105+
assert_eq!(
106+
Err(Error::WrapperError(WrapperErrorKind::InvalidParam)),
107+
CommandTag::try_from(StructureTag::FuManifest),
108+
"Expected an error when converting StructureTag FuManifest into CommandTag",
109+
)
110+
}
111+
112+
#[test]
113+
fn test_marshall_unmarshall() {
114+
let val = CommandTag::Sessions;
115+
crate::common::check_marshall_unmarshall(&val);
116+
crate::common::check_marshall_unmarshall_offset(&val);
117+
}
60118
}

0 commit comments

Comments
 (0)