Skip to content

Commit

Permalink
Improves handling size_t FFI values.
Browse files Browse the repository at this point in the history
- The size_t type that is used in all the MU APIs will
  be dependent on the compiler that ```bindgen``` uses to
  generate the bindings for the library. This attempts to
  make the crate less dependant on that value in the
  public APIs.

- Changes the Marshall and Unmarshall traits to use usize as
  input.

Signed-off-by: Jesper Brynolf <[email protected]>
  • Loading branch information
Superhepper committed Nov 9, 2023
1 parent 21d4263 commit 4a6e638
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 136 deletions.
36 changes: 14 additions & 22 deletions tss-esapi/src/constants/command_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
mod structure;

use crate::{
ffi::FfiSizeType,
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, TryInto};
use std::convert::TryFrom;
use structure::CommandCodeStructure;

/// Enum representing the command code constants.
Expand Down Expand Up @@ -158,53 +159,44 @@ impl From<CommandCode> for TPM2_CC {
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<()> {
fn marshall_offset(&self, marshalled_data: &mut [u8], offset: &mut usize) -> Result<()> {
let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
)
},
|ret| {
error!("Failed to marshal CommandCode: {}", ret);
},
)?;
*offset = usize::try_from(ffi_offset)?;
Ok(())
}
}

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

let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
&mut dest,
)
},
|ret| error!("Failed to unmarshal SensitiveCreate: {}", ret),
)?;

*offset = usize::try_from(ffi_offset)?;
CommandCode::try_from(dest)
}
}
58 changes: 56 additions & 2 deletions tss-esapi/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

pub(crate) mod data_zeroize;

use crate::ffi::data_zeroize::FfiDataZeroize;
use crate::{ffi::data_zeroize::FfiDataZeroize, Error, Result, WrapperErrorKind};
use log::error;
use mbox::MBox;
use std::ops::Deref;
use std::{convert::TryFrom, ops::Deref};

/// Function that takes ownership of data that has been
/// allocated with C memory allocation functions in TSS while also
Expand All @@ -26,7 +27,60 @@ where
owned_ffi_data
}

/// Function that takes ownership of bytes that are stored in a
/// buffer that has been allocated with C memory allocation functions in TSS.
///
/// # Arguments
/// * `ffi_bytes_ptr` - A pointer to the FFI buffer.
/// * `size` - The number of bytes to read from the buffer.
///
/// # Returns
/// The owned bytes in the form of a `Vec<u8>` object.
pub(crate) fn to_owned_bytes(ffi_bytes_ptr: *mut u8, size: usize) -> Vec<u8> {
let ffi_bytes = unsafe { MBox::<[u8]>::from_raw_parts(ffi_bytes_ptr, size) };
return Vec::<u8>::from(ffi_bytes.as_ref());
}

/// Type used for handling `size_t` variables
pub(crate) struct FfiSizeType(crate::tss2_esys::size_t);

impl FfiSizeType {
/// Returns an unsafe mutable pointer to the `size_t` value.
pub(crate) fn as_mut_ptr(&mut self) -> *mut crate::tss2_esys::size_t {
&mut self.0
}
}

impl From<crate::tss2_esys::size_t> for FfiSizeType {
fn from(value: crate::tss2_esys::size_t) -> Self {
Self(value)
}
}

impl From<FfiSizeType> for crate::tss2_esys::size_t {
fn from(ffi: FfiSizeType) -> crate::tss2_esys::size_t {
ffi.0
}
}

impl TryFrom<usize> for FfiSizeType {
type Error = Error;
fn try_from(native: usize) -> Result<Self> {
crate::tss2_esys::size_t::try_from(native)
.map(FfiSizeType)
.map_err(|err| {
error!("Failed to convert `usize` to `size_t`: {}", err);
Error::local_error(WrapperErrorKind::UnsupportedParam)
})
}
}

impl TryFrom<FfiSizeType> for usize {
type Error = Error;
fn try_from(ffi: FfiSizeType) -> Result<usize> {
usize::try_from(ffi.0).map_err(|err| {
error!("Failed to convert `size_t` to `usize`: {}", err);
Error::local_error(WrapperErrorKind::UnsupportedParam)
})
}
}
71 changes: 26 additions & 45 deletions tss-esapi/src/interface_types/structure_tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use tss_esapi_sys::TPMI_ST_COMMAND_TAG;

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

/// Type of attestation.
///
Expand Down Expand Up @@ -78,54 +79,44 @@ impl TryFrom<TPMI_ST_ATTEST> for AttestationType {
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<()> {
fn marshall_offset(&self, marshalled_data: &mut [u8], offset: &mut usize) -> Result<()> {
let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
)
},
|ret| {
error!("Failed to marshal AttestationType: {}", ret);
},
)?;

*offset = usize::try_from(ffi_offset)?;
Ok(())
}
}

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

let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
&mut dest,
)
},
|ret| error!("Failed to unmarshal AttestationType: {}", ret),
)?;

*offset = usize::try_from(ffi_offset)?;
AttestationType::try_from(dest)
}
}
Expand Down Expand Up @@ -178,54 +169,44 @@ impl TryFrom<TPMI_ST_COMMAND_TAG> for CommandTag {
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<()> {
fn marshall_offset(&self, marshalled_data: &mut [u8], offset: &mut usize) -> Result<()> {
let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
)
},
|ret| {
error!("Failed to marshal CommandTag: {}", ret);
},
)?;

*offset = usize::try_from(ffi_offset)?;
Ok(())
}
}

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

let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
&mut dest,
)
},
|ret| error!("Failed to unmarshal CommandTag: {}", ret),
)?;

*offset = usize::try_from(ffi_offset)?;
CommandTag::try_from(dest)
}
}
33 changes: 13 additions & 20 deletions tss-esapi/src/structures/buffers/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use crate::{
ffi::FfiSizeType,
traits::{Marshall, UnMarshall},
ReturnCode,
};
Expand All @@ -14,11 +15,9 @@ impl Marshall for Private {
const BUFFER_SIZE: usize = std::mem::size_of::<TPM2B_PRIVATE>();

/// Produce a marshalled [`TPM2B_PRIVATE`]
fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<()> {
fn marshall_offset(&self, marshalled_data: &mut [u8], offset: &mut usize) -> Result<()> {
let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Marshal(
Expand All @@ -27,43 +26,37 @@ impl Marshall for Private {
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
)
},
|ret| {
error!("Failed to marshal Private: {}", ret);
},
)?;

*offset = usize::try_from(ffi_offset)?;
Ok(())
}
}

impl UnMarshall for Private {
/// Unmarshall the structure from [`TPM2B_PRIVATE`]
fn unmarshall_offset(
marshalled_data: &[u8],
offset: &mut std::os::raw::c_ulong,
) -> Result<Self> {
fn unmarshall_offset(marshalled_data: &[u8], offset: &mut usize) -> Result<Self> {
let mut dest = TPM2B_PRIVATE::default();
let ffi_buffer_size = FfiSizeType::try_from(marshalled_data.len())?;
let mut ffi_offset = FfiSizeType::try_from(*offset)?;
ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPM2B_PRIVATE_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,
ffi_buffer_size.into(),
ffi_offset.as_mut_ptr(),
&mut dest,
)
},
|ret| error!("Failed to unmarshal Private: {}", ret),
)?;
*offset = usize::try_from(ffi_offset)?;
Private::try_from(dest)
}
}
Loading

0 comments on commit 4a6e638

Please sign in to comment.