Skip to content

Commit

Permalink
Merge pull request #410 from ionut-arm/unmarshall-plus
Browse files Browse the repository at this point in the history
Expanding UnMarshall + a few additions
  • Loading branch information
Superhepper authored Aug 6, 2023
2 parents 750f1d9 + 0e27599 commit 4c9b7a7
Show file tree
Hide file tree
Showing 8 changed files with 427 additions and 7 deletions.
62 changes: 60 additions & 2 deletions tss-esapi/src/constants/command_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
mod structure;

use crate::{tss2_esys::TPM2_CC, Error, Result, WrapperErrorKind};
use crate::{
traits::{Marshall, UnMarshall},
tss2_esys::TPM2_CC,
Error, Result, ReturnCode, WrapperErrorKind,
};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};
use structure::CommandCodeStructure;

/// Enum representing the command code constants.
Expand Down Expand Up @@ -150,3 +154,57 @@ impl From<CommandCode> for TPM2_CC {
command_code.to_u32().unwrap()
}
}

impl Marshall for CommandCode {
const BUFFER_SIZE: usize = std::mem::size_of::<TPM2_CC>();

fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<()> {
ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2_CC_Marshal(
(*self).into(),
marshalled_data.as_mut_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
)
},
|ret| {
error!("Failed to marshal CommandCode: {}", ret);
},
)?;
Ok(())
}
}

impl UnMarshall for CommandCode {
fn unmarshall_offset(
marshalled_data: &[u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<Self> {
let mut dest = TPM2_CC::default();

ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2_CC_Unmarshal(
marshalled_data.as_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert length of marshalled data: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
&mut dest,
)
},
|ret| error!("Failed to unmarshal SensitiveCreate: {}", ret),
)?;

CommandCode::try_from(dest)
}
}
167 changes: 165 additions & 2 deletions tss-esapi/src/interface_types/structure_tags.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0

use crate::{constants::StructureTag, tss2_esys::TPMI_ST_ATTEST, Error, Result, WrapperErrorKind};
use std::convert::TryFrom;
use log::error;
use tss_esapi_sys::TPMI_ST_COMMAND_TAG;

use crate::{
constants::StructureTag,
traits::{Marshall, UnMarshall},
tss2_esys::TPMI_ST_ATTEST,
Error, Result, ReturnCode, WrapperErrorKind,
};
use std::convert::{TryFrom, TryInto};

/// Type of attestation.
///
Expand Down Expand Up @@ -66,3 +74,158 @@ impl TryFrom<TPMI_ST_ATTEST> for AttestationType {
AttestationType::try_from(StructureTag::try_from(tpmi_st_attest)?)
}
}

impl Marshall for AttestationType {
const BUFFER_SIZE: usize = std::mem::size_of::<TPMI_ST_ATTEST>();

fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<()> {
ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2_ST_Marshal(
(*self).into(),
marshalled_data.as_mut_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
)
},
|ret| {
error!("Failed to marshal AttestationType: {}", ret);
},
)?;

Ok(())
}
}

impl UnMarshall for AttestationType {
fn unmarshall_offset(
marshalled_data: &[u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<Self> {
let mut dest = TPMI_ST_ATTEST::default();

ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2_ST_Unmarshal(
marshalled_data.as_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert length of marshalled data: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
&mut dest,
)
},
|ret| error!("Failed to unmarshal AttestationType: {}", ret),
)?;

AttestationType::try_from(dest)
}
}

/// Type of command tag.
///
/// # Details
/// Corresponds to `TPMI_ST_COMMAND_TAG`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CommandTag {
Sessions,
NoSessions,
}

impl From<CommandTag> for StructureTag {
fn from(value: CommandTag) -> Self {
match value {
CommandTag::Sessions => StructureTag::Sessions,
CommandTag::NoSessions => StructureTag::NoSessions,
}
}
}

impl TryFrom<StructureTag> for CommandTag {
type Error = Error;

fn try_from(value: StructureTag) -> std::result::Result<Self, Self::Error> {
match value {
StructureTag::Sessions => Ok(CommandTag::Sessions),
StructureTag::NoSessions => Ok(CommandTag::NoSessions),
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
}
}
}

impl From<CommandTag> for TPMI_ST_COMMAND_TAG {
fn from(command_tag: CommandTag) -> Self {
StructureTag::from(command_tag).into()
}
}

impl TryFrom<TPMI_ST_COMMAND_TAG> for CommandTag {
type Error = Error;

fn try_from(tpmi_st_command_tag: TPMI_ST_COMMAND_TAG) -> Result<Self> {
CommandTag::try_from(StructureTag::try_from(tpmi_st_command_tag)?)
}
}

impl Marshall for CommandTag {
const BUFFER_SIZE: usize = std::mem::size_of::<TPMI_ST_COMMAND_TAG>();

fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<()> {
ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2_ST_Marshal(
(*self).into(),
marshalled_data.as_mut_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
)
},
|ret| {
error!("Failed to marshal CommandTag: {}", ret);
},
)?;

Ok(())
}
}

impl UnMarshall for CommandTag {
fn unmarshall_offset(
marshalled_data: &[u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<Self> {
let mut dest = TPMI_ST_COMMAND_TAG::default();

ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2_ST_Unmarshal(
marshalled_data.as_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert length of marshalled data: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
&mut dest,
)
},
|ret| error!("Failed to unmarshal CommandTag: {}", ret),
)?;

CommandTag::try_from(dest)
}
}
103 changes: 100 additions & 3 deletions tss-esapi/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,115 @@
use std::convert::{TryFrom, TryInto};

use log::error;
use tss_esapi_sys::UINT32;

// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Result;
use crate::{Error, Result, ReturnCode, WrapperErrorKind};

/// Trait for types that can be converted into
/// TPM marshalled data.
pub trait Marshall: Sized {
const BUFFER_SIZE: usize;
/// Returns the type in the form of marshalled data
fn marshall(&self) -> Result<Vec<u8>>;
fn marshall(&self) -> Result<Vec<u8>> {
let mut buffer = vec![0; Self::BUFFER_SIZE];
let mut offset = 0;

self.marshall_offset(&mut buffer, &mut offset)?;

let checked_offset = usize::try_from(offset).map_err(|e| {
error!("Failed to parse offset as usize: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?;

buffer.truncate(checked_offset);

Ok(buffer)
}

/// Writes the type in the form of marshalled data to `marshalled_data`,
/// and modifies the `offset` to point to the first byte in the buffer
/// which was not written in the conversion.
fn marshall_offset(
&self,
_marshalled_data: &mut [u8],
_offset: &mut std::os::raw::c_ulong,
) -> Result<()> {
unimplemented!();
}
}

/// Trait for types that can be created from
/// TPM marshalled data.
pub trait UnMarshall: Sized {
/// Creates the type from marshalled data.
fn unmarshall(marshalled_data: &[u8]) -> Result<Self>;
fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
Self::unmarshall_offset(marshalled_data, &mut 0)
}

/// Creates the type from the marshalled data, and modifies
/// the `offset` to point to the first byte in the `marshalled_data`
/// buffer which was not used in the conversion.
fn unmarshall_offset(
_marshalled_data: &[u8],
_offset: &mut std::os::raw::c_ulong,
) -> Result<Self> {
unimplemented!();
}
}

impl Marshall for u32 {
const BUFFER_SIZE: usize = std::mem::size_of::<UINT32>();

fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<()> {
ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_UINT32_Marshal(
*self,
marshalled_data.as_mut_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
)
},
|ret| {
error!("Failed to marshall u32: {}", ret);
},
)?;

Ok(())
}
}

impl UnMarshall for u32 {
fn unmarshall_offset(
marshalled_data: &[u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<Self> {
let mut dest = 0_u32;

ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_UINT32_Unmarshal(
marshalled_data.as_ptr(),
marshalled_data.len().try_into().map_err(|e| {
error!("Failed to convert length of marshalled data: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
offset,
&mut dest,
)
},
|ret| error!("Failed to unmarshal SensitiveCreate: {}", ret),
)?;

Ok(dest)
}
}
Loading

0 comments on commit 4c9b7a7

Please sign in to comment.