Skip to content

Commit

Permalink
Implement tr_serialize and tr_deserialize
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Brand <[email protected]>
  • Loading branch information
brandsimon committed Oct 26, 2023
1 parent d942908 commit 48c1046
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 22 deletions.
55 changes: 49 additions & 6 deletions tss-esapi/src/context/general_esys_tr.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::TPM2_RH_UNASSIGNED,
context::handle_manager::HandleDropAction,
ffi::to_owned_bytes,
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;

Expand Down Expand Up @@ -372,7 +377,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<TpmHandle> {
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 {
Expand All @@ -388,6 +393,44 @@ 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<Vec<u8>> {
let mut len = 0;
let mut buffer: *mut u8 = null_mut();
ReturnCode::ensure_success(
unsafe { Esys_TR_Serialize(self.mut_context(), handle.into(), &mut buffer, &mut len) },
|ret| {
error!("Error while serializing handle: {}", ret);
},
)?;
Ok(to_owned_bytes(
buffer,
len.try_into().map_err(|e| {
error!("Failed to convert buffer len to usize: {}", e);
Error::local_error(WrapperErrorKind::InvalidParam)
})?,
))
}

/// Retrieve the `ObjectHandle` stored in a buffer
pub fn tr_deserialize(&mut self, buffer: &Vec<u8>) -> Result<ObjectHandle> {
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))
}
}
5 changes: 5 additions & 0 deletions tss-esapi/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ where
ffi_data.ffi_data_zeroize();
owned_ffi_data
}

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());
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
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, PersistentTpmHandle, TpmHandle},
interface_types::{
algorithm::HashingAlgorithm,
dynamic_handles::Persistent,
resource_handles::{Hierarchy, NvAuth, Provision},
session_handles::AuthSession,
},
structures::{Auth, CapabilityData, MaxNvBuffer, NvPublicBuilder},
tss2_esys::TPM2_HANDLE,
Context, Error,
};

use std::convert::TryFrom;

mod test_tr_from_tpm_public {
use crate::common::create_ctx_without_session;
use tss_esapi::{
attributes::NvIndexAttributesBuilder,
constants::{tss::TPM2_NV_INDEX_FIRST, CapabilityType},
handles::{NvIndexHandle, NvIndexTpmHandle, ObjectHandle},
interface_types::{
algorithm::HashingAlgorithm,
resource_handles::{NvAuth, Provision},
session_handles::AuthSession,
},
structures::{Auth, CapabilityData, MaxNvBuffer, NvPublicBuilder},
tss2_esys::TPM2_HANDLE,
Context,
};

use std::convert::TryFrom;
use super::*;

fn remove_nv_index_handle_from_tpm(nv_index_tpm_handle: NvIndexTpmHandle, nv_auth: Provision) {
let mut context = create_ctx_without_session();
Expand Down Expand Up @@ -445,3 +448,45 @@ mod test_tr_from_tpm_public {
assert_eq!(expected, actual);
}
}

mod test_tr_serialize_tr_deserialize {
use super::*;

#[test]
fn test_tr_serialize_tr_deserialize() -> Result<(), Error> {
let persistent_addr =
PersistentTpmHandle::new(u32::from_be_bytes([0x81, 0x00, 0x00, 0x05]))?;
let persistent = Persistent::Persistent(persistent_addr);
let mut context = create_ctx_with_session();

// Make sure the handle is not already persistent
if let Ok(clear_handle) =
context.tr_from_tpm_public(TpmHandle::Persistent(persistent.into()))
{
context.evict_control(Provision::Owner, clear_handle, persistent)?;
}

let key_handle = context
.create_primary(
Hierarchy::Owner,
decryption_key_pub(),
None,
None,
None,
None,
)?
.key_handle;
let public = context.read_public(key_handle)?;
let persistent_handle =
context.evict_control(Provision::Owner, key_handle.into(), persistent)?;
let data = context.tr_serialize(persistent_handle)?;

std::mem::drop(context);
// Load handle in a new context
let mut new_context = create_ctx_without_session();
let new_handle = new_context.tr_deserialize(&data)?.into();
// Check it is the same key via the public key included in Public
assert_eq!(public, new_context.read_public(new_handle)?);
Ok(())
}
}

0 comments on commit 48c1046

Please sign in to comment.