From 4a9cbe70ced7740d887ffa10d86c82c77deec3c1 Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Wed, 25 Oct 2023 14:13:16 +0000 Subject: [PATCH] Implement tr_serialize and tr_deserialize Signed-off-by: Simon Brand --- tss-esapi/src/context/general_esys_tr.rs | 53 ++++++++++++++++--- .../context_tests/general_esys_tr_tests.rs | 28 +++++++++- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/tss-esapi/src/context/general_esys_tr.rs b/tss-esapi/src/context/general_esys_tr.rs index efd7d52c..71dc9393 100644 --- a/tss-esapi/src/context/general_esys_tr.rs +++ b/tss-esapi/src/context/general_esys_tr.rs @@ -1,16 +1,20 @@ // Copyright 2021 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use crate::{ + constants::tss::TPM2_RH_UNASSIGNED, context::handle_manager::HandleDropAction, handles::ObjectHandle, handles::{handle_conversion::TryIntoNotNone, TpmHandle}, structures::Auth, structures::Name, - tss2_esys::{Esys_TR_Close, Esys_TR_FromTPMPublic, Esys_TR_GetName, Esys_TR_SetAuth}, - Context, Result, ReturnCode, + tss2_esys::{ + Esys_TR_Close, Esys_TR_Deserialize, Esys_TR_FromTPMPublic, Esys_TR_GetName, + Esys_TR_Serialize, Esys_TR_SetAuth, + }, + Context, Error, Result, ReturnCode, WrapperErrorKind, }; use log::error; -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; use std::ptr::null_mut; use zeroize::Zeroize; @@ -372,7 +376,7 @@ impl Context { #[cfg(has_esys_tr_get_tpm_handle)] /// Retrieve the `TpmHandle` stored in the given object. pub fn tr_get_tpm_handle(&mut self, object_handle: ObjectHandle) -> Result { - use crate::{constants::tss::TPM2_RH_UNASSIGNED, tss2_esys::Esys_TR_GetTpmHandle}; + use crate::tss2_esys::Esys_TR_GetTpmHandle; let mut tpm_handle = TPM2_RH_UNASSIGNED; ReturnCode::ensure_success( unsafe { @@ -388,6 +392,43 @@ impl Context { TpmHandle::try_from(tpm_handle) } - // Missing function: Esys_TR_Serialize - // Missing function: Esys_TR_Deserialize + /// Store the `ObjectHandle` in a buffer + pub fn tr_serialize(&mut self, handle: ObjectHandle) -> Result> { + let mut len = 0; + let mut buffer: *mut u8 = null_mut(); + let mut result = vec![]; + ReturnCode::ensure_success( + unsafe { Esys_TR_Serialize(self.mut_context(), handle.into(), &mut buffer, &mut len) }, + |ret| { + error!("Error while serializing handle: {}", ret); + }, + )?; + unsafe { + let data = std::slice::from_raw_parts(buffer, len.try_into().unwrap()); + result.extend_from_slice(&data); + }; + Ok(result) + } + + /// Retrieve the `ObjectHandle` stored in a buffer + pub fn tr_deserialize(&mut self, buffer: &Vec) -> Result { + let mut handle = TPM2_RH_UNASSIGNED; + ReturnCode::ensure_success( + unsafe { + Esys_TR_Deserialize( + self.mut_context(), + buffer.as_ptr(), + buffer.len().try_into().map_err(|e| { + error!("Failed to convert buffer len to usize: {}", e); + Error::local_error(WrapperErrorKind::InvalidParam) + })?, + &mut handle, + ) + }, + |ret| { + error!("Error while deserializing buffer: {}", ret); + }, + )?; + Ok(ObjectHandle::from(handle)) + } } diff --git a/tss-esapi/tests/integration_tests/context_tests/general_esys_tr_tests.rs b/tss-esapi/tests/integration_tests/context_tests/general_esys_tr_tests.rs index 3a3c474e..b86812aa 100644 --- a/tss-esapi/tests/integration_tests/context_tests/general_esys_tr_tests.rs +++ b/tss-esapi/tests/integration_tests/context_tests/general_esys_tr_tests.rs @@ -1,12 +1,12 @@ mod test_tr_from_tpm_public { - use crate::common::create_ctx_without_session; + use crate::common::{create_ctx_with_session, create_ctx_without_session, decryption_key_pub}; use tss_esapi::{ attributes::NvIndexAttributesBuilder, constants::{tss::TPM2_NV_INDEX_FIRST, CapabilityType}, handles::{NvIndexHandle, NvIndexTpmHandle, ObjectHandle}, interface_types::{ algorithm::HashingAlgorithm, - resource_handles::{NvAuth, Provision}, + resource_handles::{Hierarchy, NvAuth, Provision}, session_handles::AuthSession, }, structures::{Auth, CapabilityData, MaxNvBuffer, NvPublicBuilder}, @@ -444,4 +444,28 @@ mod test_tr_from_tpm_public { let expected = TpmHandle::NvIndex(nv_index_tpm_handle); assert_eq!(expected, actual); } + + #[test] + fn test_tr_serialize_tr_deserialize() { + let mut context = create_ctx_with_session(); + let random_digest = context.get_random(16).unwrap(); + let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap(); + let key_handle = context + .create_primary( + Hierarchy::Owner, + decryption_key_pub(), + Some(key_auth), + None, + None, + None, + ) + .unwrap() + .key_handle; + let data = context.tr_serialize(key_handle.into()).unwrap(); + let new_handle = context.tr_deserialize(&data).unwrap().into(); + assert_eq!( + context.read_public(key_handle).unwrap(), + context.read_public(new_handle).unwrap() + ); + } }