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 <jesper.brynolf@gmail.com>
  • Loading branch information
Superhepper committed Nov 8, 2023
1 parent 21d4263 commit 901a813
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 94 deletions.
30 changes: 14 additions & 16 deletions tss-esapi/src/constants/command_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ mod structure;
use crate::{
traits::{Marshall, UnMarshall},
tss2_esys::TPM2_CC,
Error, Result, ReturnCode, WrapperErrorKind,
Error, Result, ReturnCode, WrapperErrorKind, ffi::FfiSizeType
};
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 @@ -161,50 +161,48 @@ impl Marshall for CommandCode {
fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
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,
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, WrapperErrorKind, Result};
use log::error;
use mbox::MBox;
use std::ops::Deref;
use std::{ops::Deref, convert::TryFrom};

/// 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(|value| FfiSizeType(value))
.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)
})
}
}
58 changes: 26 additions & 32 deletions tss-esapi/src/interface_types/structure_tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use crate::{
constants::StructureTag,
traits::{Marshall, UnMarshall},
tss2_esys::TPMI_ST_ATTEST,
Error, Result, ReturnCode, WrapperErrorKind,
Error, Result, ReturnCode, WrapperErrorKind, ffi::FfiSizeType,
};
use std::convert::{TryFrom, TryInto};
use std::convert::TryFrom;

/// Type of attestation.
///
Expand Down Expand Up @@ -81,51 +81,48 @@ impl Marshall for AttestationType {
fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
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,
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 @@ -181,51 +178,48 @@ impl Marshall for CommandTag {
fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
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,
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)
}
}
27 changes: 13 additions & 14 deletions tss-esapi/src/structures/buffers/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::{
traits::{Marshall, UnMarshall},
ReturnCode,
ReturnCode, ffi::FfiSizeType,
};
use std::convert::TryInto;
use tss_esapi_sys::_PRIVATE;
Expand All @@ -17,8 +17,10 @@ impl Marshall for Private {
fn marshall_offset(
&self,
marshalled_data: &mut [u8],
offset: &mut std::os::raw::c_ulong,
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,18 +29,15 @@ 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(())
}
}
Expand All @@ -47,23 +46,23 @@ impl UnMarshall for Private {
/// Unmarshall the structure from [`TPM2B_PRIVATE`]
fn unmarshall_offset(
marshalled_data: &[u8],
offset: &mut std::os::raw::c_ulong,
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 901a813

Please sign in to comment.