diff --git a/tss-esapi/Cargo.toml b/tss-esapi/Cargo.toml index df11168f..27390df4 100644 --- a/tss-esapi/Cargo.toml +++ b/tss-esapi/Cargo.toml @@ -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" diff --git a/tss-esapi/src/constants/command_code.rs b/tss-esapi/src/constants/command_code.rs index fb2b072b..33442af8 100644 --- a/tss-esapi/src/constants/command_code.rs +++ b/tss-esapi/src/constants/command_code.rs @@ -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. @@ -155,56 +151,4 @@ impl From for TPM2_CC { } } -impl Marshall for CommandCode { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - 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 { - 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); diff --git a/tss-esapi/src/ffi.rs b/tss-esapi/src/ffi.rs index f51313f1..ce61b241 100644 --- a/tss-esapi/src/ffi.rs +++ b/tss-esapi/src/ffi.rs @@ -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 @@ -26,7 +27,61 @@ where owned_ffi_data } -pub(crate) fn to_owned_bytes(ffi_bytes_ptr: *mut u8, size: usize) -> Vec { +/// 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` object. +pub fn to_owned_bytes(ffi_bytes_ptr: *mut u8, size: usize) -> Vec { let ffi_bytes = unsafe { MBox::<[u8]>::from_raw_parts(ffi_bytes_ptr, size) }; return Vec::::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 for FfiSizeType { + fn from(value: crate::tss2_esys::size_t) -> Self { + Self(value) + } +} + +impl From for crate::tss2_esys::size_t { + fn from(ffi: FfiSizeType) -> crate::tss2_esys::size_t { + ffi.0 + } +} + +impl TryFrom for FfiSizeType { + type Error = Error; + fn try_from(native: usize) -> Result { + 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 for usize { + type Error = Error; + fn try_from(ffi: FfiSizeType) -> Result { + usize::try_from(ffi.0).map_err(|err| { + error!("Failed to convert `size_t` to `usize`: {}", err); + Error::local_error(WrapperErrorKind::UnsupportedParam) + }) + } +} diff --git a/tss-esapi/src/interface_types/structure_tags.rs b/tss-esapi/src/interface_types/structure_tags.rs index 0f28d587..a04408a7 100644 --- a/tss-esapi/src/interface_types/structure_tags.rs +++ b/tss-esapi/src/interface_types/structure_tags.rs @@ -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. /// @@ -75,60 +72,7 @@ impl TryFrom for AttestationType { } } -impl Marshall for AttestationType { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - 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 { - 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. /// @@ -175,57 +119,4 @@ impl TryFrom for CommandTag { } } -impl Marshall for CommandTag { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - 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 { - 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); diff --git a/tss-esapi/src/lib.rs b/tss-esapi/src/lib.rs index 9d0aed88..68fdca37 100644 --- a/tss-esapi/src/lib.rs +++ b/tss-esapi/src/lib.rs @@ -29,6 +29,7 @@ missing_copy_implementations, rustdoc::broken_intra_doc_links, )] + //! # TSS 2.0 Rust Wrapper over Enhanced System API //! This crate exposes the functionality of the TCG Software Stack Enhanced System API to //! Rust developers, both directly through FFI bindings and through more Rust-tailored interfaces diff --git a/tss-esapi/src/macros/mod.rs b/tss-esapi/src/macros/mod.rs deleted file mode 100644 index fffe2d55..00000000 --- a/tss-esapi/src/macros/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright 2020 Contributors to the Parsec project. -// SPDX-License-Identifier: Apache-2.0 diff --git a/tss-esapi/src/structures/algorithm/symmetric/sensitive_create.rs b/tss-esapi/src/structures/algorithm/symmetric/sensitive_create.rs index 3f7d30d7..1a511329 100644 --- a/tss-esapi/src/structures/algorithm/symmetric/sensitive_create.rs +++ b/tss-esapi/src/structures/algorithm/symmetric/sensitive_create.rs @@ -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, }; @@ -62,70 +62,8 @@ impl TryFrom for SensitiveCreate { } } -impl Marshall for SensitiveCreate { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [TPMS_SENSITIVE_CREATE] - /// - /// Note: for [TPM2B_SENSITIVE_CREATE] marshalling use [SensitiveCreateBuffer][`crate::structures::SensitiveCreateBuffer] - fn marshall(&self) -> Result> { - 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 { - 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 for SensitiveCreate { type Error = Error; diff --git a/tss-esapi/src/structures/attestation/attest.rs b/tss-esapi/src/structures/attestation/attest.rs index c046e7cb..65f8f597 100644 --- a/tss-esapi/src/structures/attestation/attest.rs +++ b/tss-esapi/src/structures/attestation/attest.rs @@ -5,9 +5,9 @@ use crate::{ constants::tss::TPM2_GENERATED_VALUE, interface_types::structure_tags::AttestationType, structures::{AttestInfo, ClockInfo, Data, Name}, - traits::{Marshall, UnMarshall}, + traits::impl_mu_standard, tss2_esys::TPMS_ATTEST, - Error, Result, ReturnCode, WrapperErrorKind, + Error, Result, WrapperErrorKind, }; use log::error; use std::convert::{TryFrom, TryInto}; @@ -118,59 +118,4 @@ impl TryFrom for Attest { } } -impl Marshall for Attest { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [`TPMS_ATTEST`] - fn marshall(&self) -> Result> { - let mut buffer = vec![0; Self::BUFFER_SIZE]; - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPMS_ATTEST_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 Attest: {}", 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 Attest { - /// Unmarshall the structure from [`TPMS_ATTEST`] - fn unmarshall(marshalled_data: &[u8]) -> Result { - let mut dest = TPMS_ATTEST::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPMS_ATTEST_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 Attest: {}", ret), - )?; - - Attest::try_from(dest) - } -} +impl_mu_standard!(Attest, TPMS_ATTEST); diff --git a/tss-esapi/src/structures/buffers/private.rs b/tss-esapi/src/structures/buffers/private.rs index 62ee5054..321e898b 100644 --- a/tss-esapi/src/structures/buffers/private.rs +++ b/tss-esapi/src/structures/buffers/private.rs @@ -1,69 +1,9 @@ // Copyright 2023 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 -use crate::{ - traits::{Marshall, UnMarshall}, - ReturnCode, -}; -use std::convert::TryInto; +use crate::traits::impl_mu_standard; use tss_esapi_sys::_PRIVATE; buffer_type!(Private, ::std::mem::size_of::<_PRIVATE>(), TPM2B_PRIVATE); -impl Marshall for Private { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [`TPM2B_PRIVATE`] - 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_TPM2B_PRIVATE_Marshal( - &self.clone().try_into().map_err(|e| { - error!("Failed to convert Private to TPM2B_PRIVATE: {}", e); - 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, - ) - }, - |ret| { - error!("Failed to marshal Private: {}", ret); - }, - )?; - - 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 { - let mut dest = TPM2B_PRIVATE::default(); - 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, - &mut dest, - ) - }, - |ret| error!("Failed to unmarshal Private: {}", ret), - )?; - Private::try_from(dest) - } -} +impl_mu_standard!(Private, TPM2B_PRIVATE); diff --git a/tss-esapi/src/structures/buffers/public.rs b/tss-esapi/src/structures/buffers/public.rs index 98ee0d3e..4d6b7c09 100644 --- a/tss-esapi/src/structures/buffers/public.rs +++ b/tss-esapi/src/structures/buffers/public.rs @@ -3,9 +3,9 @@ use crate::{ structures::Public, - traits::{Marshall, UnMarshall}, + traits::{impl_mu_complex, Marshall, UnMarshall}, tss2_esys::{TPM2B_PUBLIC, TPMT_PUBLIC}, - Error, Result, ReturnCode, WrapperErrorKind, + Error, Result, WrapperErrorKind, }; use log::error; use std::{ @@ -108,61 +108,4 @@ impl TryFrom for PublicBuffer { } } -impl Marshall for PublicBuffer { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [`TPM2B_PUBLIC`] - fn marshall(&self) -> Result> { - let mut buffer = vec![0; Self::BUFFER_SIZE]; - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Marshal( - &self.clone().try_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 PublicBuffer: {}", 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 PublicBuffer { - /// Unmarshall the structure from [`TPM2B_PUBLIC`] - fn unmarshall(marshalled_data: &[u8]) -> Result { - let mut dest = TPM2B_PUBLIC::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPM2B_PUBLIC_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 PublicBuffer: {}", ret), - )?; - - PublicBuffer::try_from(dest) - } -} +impl_mu_complex!(PublicBuffer, TPM2B_PUBLIC); diff --git a/tss-esapi/src/structures/buffers/sensitive.rs b/tss-esapi/src/structures/buffers/sensitive.rs index 25328efb..5de1c93f 100644 --- a/tss-esapi/src/structures/buffers/sensitive.rs +++ b/tss-esapi/src/structures/buffers/sensitive.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ structures::Sensitive, - traits::{Marshall, UnMarshall}, + traits::{impl_mu_complex, Marshall, UnMarshall}, tss2_esys::{TPM2B_SENSITIVE, TPMT_SENSITIVE}, - Error, Result, ReturnCode, WrapperErrorKind, + Error, Result, WrapperErrorKind, }; use log::error; use std::{ @@ -107,61 +107,4 @@ impl TryFrom for SensitiveBuffer { } } -impl Marshall for SensitiveBuffer { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [`TPM2B_SENSITIVE`] - fn marshall(&self) -> Result> { - let mut buffer = vec![0; Self::BUFFER_SIZE]; - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPM2B_SENSITIVE_Marshal( - &self.clone().try_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 SensitiveBuffer: {}", 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 SensitiveBuffer { - /// Unmarshall the structure from [`TPM2B_SENSITIVE`] - fn unmarshall(marshalled_data: &[u8]) -> Result { - let mut dest = TPM2B_SENSITIVE::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPM2B_SENSITIVE_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 SensitiveBuffer: {}", ret), - )?; - - SensitiveBuffer::try_from(dest) - } -} +impl_mu_complex!(SensitiveBuffer, TPM2B_SENSITIVE); diff --git a/tss-esapi/src/structures/buffers/sensitive_create.rs b/tss-esapi/src/structures/buffers/sensitive_create.rs index 5f71ce15..45272d70 100644 --- a/tss-esapi/src/structures/buffers/sensitive_create.rs +++ b/tss-esapi/src/structures/buffers/sensitive_create.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ structures::SensitiveCreate, - traits::{Marshall, UnMarshall}, + traits::{impl_mu_complex, Marshall, UnMarshall}, tss2_esys::{TPM2B_SENSITIVE_CREATE, TPMS_SENSITIVE_CREATE}, - Error, Result, ReturnCode, WrapperErrorKind, + Error, Result, WrapperErrorKind, }; use log::error; use std::{ @@ -112,61 +112,4 @@ impl TryFrom for SensitiveCreateBuffer { } } -impl Marshall for SensitiveCreateBuffer { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [TPM2B_SENSITIVE_CREATE] - fn marshall(&self) -> Result> { - let mut buffer = vec![0; Self::BUFFER_SIZE]; - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal( - &self.clone().try_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 SensitiveCreateBuffer: {}", 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 SensitiveCreateBuffer { - /// Unmarshall the structure from [TPM2B_SENSITIVE_CREATE] - fn unmarshall(marshalled_data: &[u8]) -> Result { - let mut dest = TPM2B_SENSITIVE_CREATE::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPM2B_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 SensitiveCreateBuffer: {}", ret), - )?; - - SensitiveCreateBuffer::try_from(dest) - } -} +impl_mu_complex!(SensitiveCreateBuffer, TPM2B_SENSITIVE_CREATE); diff --git a/tss-esapi/src/structures/tagged/public.rs b/tss-esapi/src/structures/tagged/public.rs index e0883dff..3a6ac8b0 100644 --- a/tss-esapi/src/structures/tagged/public.rs +++ b/tss-esapi/src/structures/tagged/public.rs @@ -8,7 +8,7 @@ use crate::{ attributes::ObjectAttributes, interface_types::algorithm::{HashingAlgorithm, PublicAlgorithm}, structures::{Digest, EccPoint, PublicKeyRsa, SymmetricCipherParameters}, - traits::{Marshall, UnMarshall}, + traits::{impl_mu_standard, Marshall}, tss2_esys::{TPM2B_PUBLIC, TPMT_PUBLIC}, Error, Result, ReturnCode, WrapperErrorKind, }; @@ -491,66 +491,7 @@ impl TryFrom for Public { } } -impl Marshall for Public { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [TPMT_PUBLIC] - /// - /// Note: for [TPM2B_PUBLIC] marshalling use [PublicBuffer][`crate::structures::PublicBuffer] - fn marshall(&self) -> Result> { - let mut buffer = vec![0; Self::BUFFER_SIZE]; - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPMT_PUBLIC_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 Public: {}", 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 Public { - /// Unmarshall the structure from [`TPMT_PUBLIC`] - /// - /// Note: for [TPM2B_PUBLIC] unmarshalling use [PublicBuffer][`crate::structures::PublicBuffer] - fn unmarshall(marshalled_data: &[u8]) -> Result { - let mut dest = TPMT_PUBLIC::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPMT_PUBLIC_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 Public: {}", ret), - )?; - - Public::try_from(dest) - } -} +impl_mu_standard!(Public, TPMT_PUBLIC); impl TryFrom for Public { type Error = Error; diff --git a/tss-esapi/src/structures/tagged/sensitive.rs b/tss-esapi/src/structures/tagged/sensitive.rs index 3c1a58c8..06f220ea 100644 --- a/tss-esapi/src/structures/tagged/sensitive.rs +++ b/tss-esapi/src/structures/tagged/sensitive.rs @@ -3,7 +3,7 @@ use crate::{ interface_types::algorithm::PublicAlgorithm, structures::{Auth, Digest, EccParameter, PrivateKeyRsa, SensitiveData, SymmetricKey}, - traits::{Marshall, UnMarshall}, + traits::{impl_mu_standard, Marshall}, tss2_esys::{TPM2B_SENSITIVE, TPMT_SENSITIVE, TPMU_SENSITIVE_COMPOSITE}, Error, Result, ReturnCode, WrapperErrorKind, }; @@ -163,66 +163,7 @@ impl TryFrom for Sensitive { } } -impl Marshall for Sensitive { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [`TPMT_SENSITIVE`] - /// - /// Note: for [TPM2B_SENSITIVE] marshalling use [SensitiveBuffer][`crate::structures::SensitiveBuffer] - fn marshall(&self) -> Result> { - let mut buffer = vec![0; Self::BUFFER_SIZE]; - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPMT_SENSITIVE_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 Sensitive: {}", 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 Sensitive { - /// Unmarshall the structure from [`TPMT_SENSITIVE`] - /// - /// Note: for [TPM2B_SENSITIVE] marshalling use [SensitiveBuffer][`crate::structures::SensitiveBuffer] - fn unmarshall(marshalled_data: &[u8]) -> Result { - let mut dest = TPMT_SENSITIVE::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - crate::tss2_esys::Tss2_MU_TPMT_SENSITIVE_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 Sensitive: {}", ret), - )?; - - Sensitive::try_from(dest) - } -} +impl_mu_standard!(Sensitive, TPMT_SENSITIVE); impl TryFrom for Sensitive { type Error = Error; diff --git a/tss-esapi/src/structures/tagged/signature.rs b/tss-esapi/src/structures/tagged/signature.rs index b3022906..cd5daf91 100644 --- a/tss-esapi/src/structures/tagged/signature.rs +++ b/tss-esapi/src/structures/tagged/signature.rs @@ -3,13 +3,11 @@ use crate::{ interface_types::algorithm::SignatureSchemeAlgorithm, structures::{EccSignature, HashAgile, RsaSignature}, - traits::{Marshall, UnMarshall}, + traits::impl_mu_complex, tss2_esys::{TPMT_SIGNATURE, TPMU_SIGNATURE}, - Error, Result, ReturnCode, WrapperErrorKind, + Error, Result, }; -use log::error; use std::convert::{TryFrom, TryInto}; -use tss_esapi_sys::{Tss2_MU_TPMT_SIGNATURE_Marshal, Tss2_MU_TPMT_SIGNATURE_Unmarshal}; /// Enum representing a Signature /// @@ -129,59 +127,4 @@ impl TryFrom for Signature { } } -impl Marshall for Signature { - const BUFFER_SIZE: usize = std::mem::size_of::(); - - /// Produce a marshalled [`TPMT_SIGNATURE`] - fn marshall(&self) -> Result> { - let tpmt_sig = TPMT_SIGNATURE::try_from(self.clone())?; - let mut offset = 0; - let mut buffer = vec![0; Self::BUFFER_SIZE]; - - ReturnCode::ensure_success( - unsafe { - Tss2_MU_TPMT_SIGNATURE_Marshal( - &tpmt_sig, - buffer.as_mut_ptr(), - buffer.capacity().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 Signature: {}", 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 Signature { - /// Unmarshall the structure from [`TPMT_SIGNATURE`] - fn unmarshall(public_buffer: &[u8]) -> Result { - let mut tpmt_sig = TPMT_SIGNATURE::default(); - let mut offset = 0; - - ReturnCode::ensure_success( - unsafe { - Tss2_MU_TPMT_SIGNATURE_Unmarshal( - public_buffer.as_ptr(), - public_buffer.len().try_into().map_err(|e| { - error!("Failed to convert length of marshalled data: {}", e); - Error::local_error(WrapperErrorKind::InvalidParam) - })?, - &mut offset, - &mut tpmt_sig, - ) - }, - |ret| error!("Failed to unmarshal Sensitive: {}", ret), - )?; - tpmt_sig.try_into() - } -} +impl_mu_complex!(Signature, TPMT_SIGNATURE); diff --git a/tss-esapi/src/traits.rs b/tss-esapi/src/traits.rs index 1e5b4a04..98ef7c57 100644 --- a/tss-esapi/src/traits.rs +++ b/tss-esapi/src/traits.rs @@ -1,11 +1,7 @@ -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::{Error, Result, ReturnCode, WrapperErrorKind}; +use crate::{tss2_esys::UINT32, Result}; +use std::convert::TryFrom; /// Trait for types that can be converted into /// TPM marshalled data. @@ -18,12 +14,7 @@ pub trait Marshall: Sized { 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); + buffer.truncate(offset); Ok(buffer) } @@ -31,11 +22,7 @@ pub trait Marshall: Sized { /// 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<()> { + fn marshall_offset(&self, _marshalled_data: &mut [u8], _offset: &mut usize) -> Result<()> { unimplemented!(); } } @@ -51,65 +38,151 @@ pub trait UnMarshall: Sized { /// 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 { + fn unmarshall_offset(_marshalled_data: &[u8], _offset: &mut usize) -> Result { unimplemented!(); } } -impl Marshall for u32 { - const BUFFER_SIZE: usize = std::mem::size_of::(); +/// A macro for implementing the Marshall trait +/// for a specific TSS type. +macro_rules! impl_marshall_trait { + ($native_type:ident, $tss_type:ident, $tss_mu_type:ident, $convert_expression:stmt, $( $ref_sign:tt )?) => { + paste::item! { + impl $crate::traits::Marshall for $native_type { + const BUFFER_SIZE: usize = std::mem::size_of::<$tss_type>(); + + fn marshall_offset( + &self, + marshalled_data: &mut [u8], + offset: &mut usize, + ) -> $crate::Result<()> { + let ffi_object = self.clone().$convert_expression; + let ffi_buffer_size = $crate::ffi::FfiSizeType::try_from(marshalled_data.len())?; + let mut ffi_offset = $crate::ffi::FfiSizeType::try_from(*offset)?; + $crate::ReturnCode::ensure_success( + unsafe { + $crate::tss2_esys::[< Tss2_MU_ $tss_mu_type _Marshal >]( + $( $ref_sign )?ffi_object, + marshalled_data.as_mut_ptr(), + ffi_buffer_size.into(), + ffi_offset.as_mut_ptr(), + ) + }, + |ret| { + log::error!( + "Failed to marshall {}: {}", + std::stringify!($native_type), + ret + ); + }, + )?; + *offset = usize::try_from(ffi_offset)?; + Ok(()) + } + } + } + }; +} - 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); - }, - )?; +/// A macro for implementing the Unmarshall trait +/// for a specific TSS type. +macro_rules! impl_unmarshall_trait { + ($native_type:ident, $tss_type:ident, $tss_mu_type:ident, $convert_expression:expr) => { + paste::item! { + impl $crate::traits::UnMarshall for $native_type { + fn unmarshall_offset(marshalled_data: &[u8], offset: &mut usize) -> Result { + let mut dest = $tss_type::default(); + let ffi_buffer_size = $crate::ffi::FfiSizeType::try_from(marshalled_data.len())?; + let mut ffi_offset = $crate::ffi::FfiSizeType::try_from(*offset)?; + crate::ReturnCode::ensure_success( + unsafe { + crate::tss2_esys::[ < Tss2_MU_ $tss_mu_type _Unmarshal >]( + marshalled_data.as_ptr(), + ffi_buffer_size.into(), + ffi_offset.as_mut_ptr(), + &mut dest, + ) + }, + |ret| log::error!("Failed to unmarshal {}: {}", std::stringify!($native_type), ret), + )?; + *offset = usize::try_from(ffi_offset)?; + $convert_expression(dest) + } + } + } + }; +} - Ok(()) - } +/// Macro used to implement Marshall and Unmarshall for types +/// that are just a type aliases of native types and are passed +/// to MUAPI by value. +macro_rules! impl_mu_aliases { + ($tss_type:ident) => { + $crate::traits::impl_marshall_trait!($tss_type, $tss_type, $tss_type, into(),); + $crate::traits::impl_unmarshall_trait!($tss_type, $tss_type, $tss_type, Ok); + }; } -impl UnMarshall for u32 { - fn unmarshall_offset( - marshalled_data: &[u8], - offset: &mut std::os::raw::c_ulong, - ) -> Result { - let mut dest = 0_u32; +/// Macro used to implement Marshall and Unmarshall for types that +/// can be converted from native to TSS i.e. it cannot fail and are +/// passed to MUAPI by value. +macro_rules! impl_mu_simple { + ($native_type:ident, $tss_type:ident, $tss_mu_type:ident) => { + $crate::traits::impl_marshall_trait!($native_type, $tss_type, $tss_mu_type, into(),); + $crate::traits::impl_unmarshall_trait!( + $native_type, + $tss_type, + $tss_mu_type, + $native_type::try_from + ); + }; + ($native_type:ident, $tss_type:ident) => { + $crate::traits::impl_mu_simple!($native_type, $tss_type, $tss_type); + }; +} - 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), - )?; +/// Macro used to implement Marshall and Unmarshall for types that +/// can be converted from native to TSS without failing and are +/// passed to MUAPI by reference(i.e. pointer). +macro_rules! impl_mu_standard { + ($native_type:ident, $tss_type:ident, $tss_mu_type:ident) => { + $crate::traits::impl_marshall_trait!($native_type, $tss_type, $tss_mu_type, into(), &); + $crate::traits::impl_unmarshall_trait!( + $native_type, + $tss_type, + $tss_mu_type, + $native_type::try_from + ); + }; + ($native_type:ident, $tss_type:ident) => { + $crate::traits::impl_mu_standard!($native_type, $tss_type, $tss_type); + }; +} - Ok(dest) - } +/// Macro used to implement Marshall and Unmarshall for types that +/// can be converted from native to TSS with the possibility of failing +/// and are passed to MUAPI by reference(i.e. pointer). +macro_rules! impl_mu_complex { + ($native_type:ident, $tss_type:ident, $tss_mu_type:ident) => { + $crate::traits::impl_marshall_trait!($native_type, $tss_type, $tss_mu_type, try_into()?, &); + $crate::traits::impl_unmarshall_trait!( + $native_type, + $tss_type, + $tss_mu_type, + $native_type::try_from + ); + }; + ($native_type:ident, $tss_type:ident) => { + $crate::traits::impl_mu_complex!($native_type, $tss_type, $tss_type); + }; } + +// Make the macros usable outside of the module. +pub(crate) use impl_marshall_trait; +pub(crate) use impl_mu_aliases; +pub(crate) use impl_mu_complex; +pub(crate) use impl_mu_simple; +pub(crate) use impl_mu_standard; +pub(crate) use impl_unmarshall_trait; +// Implementation of Marshall and UnMarshall macro for base TSS types. +impl_mu_aliases!(UINT32); diff --git a/tss-esapi/tests/integration_tests/common/marshall.rs b/tss-esapi/tests/integration_tests/common/marshall.rs index 749fb915..dfde5b9b 100644 --- a/tss-esapi/tests/integration_tests/common/marshall.rs +++ b/tss-esapi/tests/integration_tests/common/marshall.rs @@ -19,20 +19,20 @@ pub fn check_marshall_unmarshall_offset