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 16, 2023
1 parent 21d4263 commit d238b33
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 705 deletions.
1 change: 1 addition & 0 deletions tss-esapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ picky-asn1-x509 = { version = "0.12.0", optional = true }
cfg-if = "1.0.0"
strum = { version = "0.25.0", optional = true }
strum_macros = { version = "0.25.0", optional = true }
paste = "1.0.14"

[dev-dependencies]
env_logger = "0.9.0"
Expand Down
62 changes: 3 additions & 59 deletions tss-esapi/src/constants/command_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
// SPDX-License-Identifier: Apache-2.0
mod structure;

use crate::{
traits::{Marshall, UnMarshall},
tss2_esys::TPM2_CC,
Error, Result, ReturnCode, WrapperErrorKind,
};
use crate::{traits::impl_mu_simple, tss2_esys::TPM2_CC, Error, Result, 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 @@ -155,56 +151,4 @@ 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<()> {
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)
}
}
impl_mu_simple!(CommandCode, TPM2_CC);
63 changes: 59 additions & 4 deletions tss-esapi/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright 2022 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0

pub(crate) mod data_zeroize;
pub 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,61 @@ where
owned_ffi_data
}

pub(crate) fn to_owned_bytes(ffi_bytes_ptr: *mut u8, size: usize) -> Vec<u8> {
/// 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 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
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub 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)
})
}
}
119 changes: 5 additions & 114 deletions tss-esapi/src/interface_types/structure_tags.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0

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,
constants::StructureTag, traits::impl_mu_simple, tss2_esys::TPMI_ST_ATTEST, Error, Result,
WrapperErrorKind,
};
use std::convert::{TryFrom, TryInto};
use std::convert::TryFrom;

/// Type of attestation.
///
Expand Down Expand Up @@ -75,60 +72,7 @@ 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<()> {
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)
}
}
impl_mu_simple!(AttestationType, TPMI_ST_ATTEST, TPM2_ST);

/// Type of command tag.
///
Expand Down Expand Up @@ -175,57 +119,4 @@ 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<()> {
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)
}
}
impl_mu_simple!(CommandTag, TPMI_ST_COMMAND_TAG, TPM2_ST);
2 changes: 0 additions & 2 deletions tss-esapi/src/macros/mod.rs

This file was deleted.

68 changes: 3 additions & 65 deletions tss-esapi/src/structures/algorithm/symmetric/sensitive_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::{
structures::{Auth, SensitiveData},
traits::{Marshall, UnMarshall},
traits::{impl_mu_standard, Marshall},
tss2_esys::{TPM2B_SENSITIVE_CREATE, TPMS_SENSITIVE_CREATE},
Error, Result, ReturnCode, WrapperErrorKind,
};
Expand Down Expand Up @@ -62,70 +62,8 @@ impl TryFrom<TPMS_SENSITIVE_CREATE> for SensitiveCreate {
}
}

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

/// Produce a marshalled [TPMS_SENSITIVE_CREATE]
///
/// Note: for [TPM2B_SENSITIVE_CREATE] marshalling use [SensitiveCreateBuffer][`crate::structures::SensitiveCreateBuffer]
fn marshall(&self) -> Result<Vec<u8>> {
let mut buffer = vec![0; Self::BUFFER_SIZE];
let mut offset = 0;

ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal(
&self.clone().into(),
buffer.as_mut_ptr(),
Self::BUFFER_SIZE.try_into().map_err(|e| {
error!("Failed to convert size of buffer to TSS size_t type: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
&mut offset,
)
},
|ret| {
error!("Failed to marshal SensitiveCreate: {}", ret);
},
)?;

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)
}
}

impl UnMarshall for SensitiveCreate {
/// Unmarshall the structure from [`TPMS_SENSITIVE_CREATE`]
///
/// Note: for [TPM2B_SENSITIVE_CREATE] unmarshalling use [SensitiveCreateBuffer][`crate::structures::SensitiveCreateBuffer]
fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
let mut dest = TPMS_SENSITIVE_CREATE::default();
let mut offset = 0;

ReturnCode::ensure_success(
unsafe {
crate::tss2_esys::Tss2_MU_TPMS_SENSITIVE_CREATE_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)
})?,
&mut offset,
&mut dest,
)
},
|ret| error!("Failed to unmarshal SensitiveCreate: {}", ret),
)?;

SensitiveCreate::try_from(dest)
}
}
// Implement marshalling traits.
impl_mu_standard!(SensitiveCreate, TPMS_SENSITIVE_CREATE);

impl TryFrom<TPM2B_SENSITIVE_CREATE> for SensitiveCreate {
type Error = Error;
Expand Down
Loading

0 comments on commit d238b33

Please sign in to comment.