Skip to content

Commit 3588ba0

Browse files
authored
Merge pull request #378 from Superhepper/ffi-data-zeroizing-v2
Improvement of FFI data zeroizing(version 2).
2 parents 660716e + ead098a commit 3588ba0

File tree

11 files changed

+714
-49
lines changed

11 files changed

+714
-49
lines changed

tss-esapi/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ num-derive = "0.3.2"
2121
num-traits = "0.2.12"
2222
hostname-validator = "1.1.0"
2323
regex = "1.3.9"
24-
zeroize = { version = "1.1.0", features = ["zeroize_derive"] }
24+
zeroize = { version = "1.5.7", features = ["zeroize_derive"] }
2525
tss-esapi-sys = { path = "../tss-esapi-sys", version = "0.3.0" }
2626
oid = "0.2.1"
2727
picky-asn1 = "0.3.0"

tss-esapi/src/context/tpm_commands/object_commands.rs

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
// Copyright 2021 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
3+
mod create_command_input;
4+
mod create_command_output;
5+
36
use crate::{
47
context::handle_manager::HandleDropAction,
58
handles::{KeyHandle, ObjectHandle, TpmHandle},
69
interface_types::resource_handles::Hierarchy,
710
structures::{
8-
Auth, CreateKeyResult, CreationData, CreationTicket, Data, Digest, EncryptedSecret,
9-
IdObject, Name, PcrSelectionList, Private, Public, Sensitive, SensitiveCreate,
10-
SensitiveData,
11+
Auth, CreateKeyResult, Data, Digest, EncryptedSecret, IdObject, Name, PcrSelectionList,
12+
Private, Public, Sensitive, SensitiveData,
1113
},
1214
tss2_esys::{
1315
Esys_ActivateCredential, Esys_Create, Esys_Load, Esys_LoadExternal, Esys_MakeCredential,
1416
Esys_ObjectChangeAuth, Esys_ReadPublic, Esys_Unseal,
1517
},
1618
Context, Result, ReturnCode,
1719
};
20+
use create_command_input::CreateCommandInputHandler;
21+
use create_command_output::CreateCommandOutputHandler;
1822
use log::error;
1923
use std::convert::{TryFrom, TryInto};
2024
use std::ptr::{null, null_mut};
@@ -49,53 +53,42 @@ impl Context {
4953
outside_info: Option<Data>,
5054
creation_pcrs: Option<PcrSelectionList>,
5155
) -> Result<CreateKeyResult> {
52-
let sensitive_create = SensitiveCreate::new(
53-
auth_value.unwrap_or_default(),
54-
sensitive_data.unwrap_or_default(),
55-
);
56-
let creation_pcrs = PcrSelectionList::list_from_option(creation_pcrs);
56+
let input_parameters = CreateCommandInputHandler::create(
57+
parent_handle,
58+
public,
59+
auth_value,
60+
sensitive_data,
61+
outside_info,
62+
creation_pcrs,
63+
)?;
5764

58-
let mut out_public_ptr = null_mut();
59-
let mut out_private_ptr = null_mut();
60-
let mut creation_data_ptr = null_mut();
61-
let mut creation_hash_ptr = null_mut();
62-
let mut creation_ticket_ptr = null_mut();
65+
let mut output_parameters = CreateCommandOutputHandler::new();
6366

6467
ReturnCode::ensure_success(
6568
unsafe {
6669
Esys_Create(
6770
self.mut_context(),
68-
parent_handle.into(),
71+
input_parameters.ffi_in_parent_handle(),
6972
self.optional_session_1(),
7073
self.optional_session_2(),
7174
self.optional_session_3(),
72-
&sensitive_create.try_into()?,
73-
&public.try_into()?,
74-
&outside_info.unwrap_or_default().into(),
75-
&creation_pcrs.into(),
76-
&mut out_private_ptr,
77-
&mut out_public_ptr,
78-
&mut creation_data_ptr,
79-
&mut creation_hash_ptr,
80-
&mut creation_ticket_ptr,
75+
input_parameters.ffi_in_sensitive(),
76+
input_parameters.ffi_in_public(),
77+
input_parameters.ffi_outside_info(),
78+
input_parameters.ffi_creation_pcr(),
79+
output_parameters.ffi_out_private_ptr(),
80+
output_parameters.ffi_out_public_ptr(),
81+
output_parameters.ffi_creation_data_ptr(),
82+
output_parameters.ffi_creation_hash_ptr(),
83+
output_parameters.ffi_creation_ticket_ptr(),
8184
)
8285
},
8386
|ret| {
8487
error!("Error in creating derived key: {:#010X}", ret);
8588
},
8689
)?;
87-
let out_private_owned = Context::ffi_data_to_owned(out_private_ptr);
88-
let out_public_owned = Context::ffi_data_to_owned(out_public_ptr);
89-
let creation_data_owned = Context::ffi_data_to_owned(creation_data_ptr);
90-
let creation_hash_owned = Context::ffi_data_to_owned(creation_hash_ptr);
91-
let creation_ticket_owned = Context::ffi_data_to_owned(creation_ticket_ptr);
92-
Ok(CreateKeyResult {
93-
out_private: Private::try_from(out_private_owned)?,
94-
out_public: Public::try_from(out_public_owned)?,
95-
creation_data: CreationData::try_from(creation_data_owned)?,
96-
creation_hash: Digest::try_from(creation_hash_owned)?,
97-
creation_ticket: CreationTicket::try_from(creation_ticket_owned)?,
98-
})
90+
91+
output_parameters.try_into()
9992
}
10093

10194
/// Load a previously generated key back into the TPM and return its new handle.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright 2022 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::{
5+
ffi::data_zeroize::FfiDataZeroize,
6+
handles::KeyHandle,
7+
structures::{Auth, Data, PcrSelectionList, Public, SensitiveCreate, SensitiveData},
8+
tss2_esys::{ESYS_TR, TPM2B_DATA, TPM2B_PUBLIC, TPM2B_SENSITIVE_CREATE, TPML_PCR_SELECTION},
9+
Result,
10+
};
11+
use std::convert::TryInto;
12+
use zeroize::Zeroize;
13+
14+
/// Struct that handles the input of the
15+
/// to the Esys_Create command and zeroizes
16+
/// the data when it gets dropped.
17+
pub struct CreateCommandInputHandler {
18+
ffi_in_parent_handle: ESYS_TR,
19+
ffi_in_sensitive: TPM2B_SENSITIVE_CREATE,
20+
ffi_in_public: TPM2B_PUBLIC,
21+
ffi_outside_info: TPM2B_DATA,
22+
ffi_creation_pcr: TPML_PCR_SELECTION,
23+
}
24+
25+
impl CreateCommandInputHandler {
26+
/// Creates the CreateCommandInputHandler from the inputs
27+
/// of the 'create' [crate::Context] method.
28+
///
29+
/// # Details
30+
/// Consumes the input parameters and converts them into their
31+
/// TSS counterpart and zeroizes all the data when dropped.
32+
///
33+
/// # Arguments
34+
/// See the input arguments of 'crate' [crate::Context] method.
35+
///
36+
/// # Returns
37+
/// The created CreateCommandInputHandler.
38+
///
39+
/// # Errors
40+
/// WrapperErrors if the conversions to the TSS types fails.
41+
pub(crate) fn create(
42+
parent_handle: KeyHandle,
43+
public: Public,
44+
auth_value: Option<Auth>,
45+
sensitive_data: Option<SensitiveData>,
46+
outside_info: Option<Data>,
47+
creation_pcrs: Option<PcrSelectionList>,
48+
) -> Result<Self> {
49+
Ok(Self {
50+
ffi_in_parent_handle: parent_handle.into(),
51+
ffi_in_sensitive: SensitiveCreate::new(
52+
auth_value.unwrap_or_default(),
53+
sensitive_data.unwrap_or_default(),
54+
)
55+
.try_into()?,
56+
ffi_in_public: public.try_into()?,
57+
ffi_outside_info: outside_info.unwrap_or_default().into(),
58+
ffi_creation_pcr: PcrSelectionList::list_from_option(creation_pcrs).into(),
59+
})
60+
}
61+
62+
/// The 'parentHandle' input parameter
63+
pub const fn ffi_in_parent_handle(&self) -> ESYS_TR {
64+
self.ffi_in_parent_handle
65+
}
66+
67+
/// The 'inSensitive' input parameter.
68+
pub const fn ffi_in_sensitive(&self) -> &TPM2B_SENSITIVE_CREATE {
69+
&self.ffi_in_sensitive
70+
}
71+
72+
/// The 'inPublic' input parameter.
73+
pub const fn ffi_in_public(&self) -> &TPM2B_PUBLIC {
74+
&self.ffi_in_public
75+
}
76+
77+
/// The 'outsideInfo' input parameter.
78+
pub const fn ffi_outside_info(&self) -> &TPM2B_DATA {
79+
&self.ffi_outside_info
80+
}
81+
82+
/// The 'creationPCR' input parameter.
83+
pub const fn ffi_creation_pcr(&self) -> &TPML_PCR_SELECTION {
84+
&self.ffi_creation_pcr
85+
}
86+
}
87+
88+
impl Zeroize for CreateCommandInputHandler {
89+
fn zeroize(&mut self) {
90+
self.ffi_in_parent_handle.zeroize();
91+
self.ffi_in_sensitive.ffi_data_zeroize();
92+
self.ffi_in_public.ffi_data_zeroize();
93+
self.ffi_outside_info.ffi_data_zeroize();
94+
self.ffi_creation_pcr.ffi_data_zeroize();
95+
}
96+
}
97+
98+
impl Drop for CreateCommandInputHandler {
99+
fn drop(&mut self) {
100+
self.zeroize();
101+
}
102+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2022 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::{
5+
structures::{CreateKeyResult, CreationData, CreationTicket, Digest, Private, Public},
6+
tss2_esys::{TPM2B_CREATION_DATA, TPM2B_DIGEST, TPM2B_PRIVATE, TPM2B_PUBLIC, TPMT_TK_CREATION},
7+
Error, Result,
8+
};
9+
use std::convert::TryFrom;
10+
use std::ptr::null_mut;
11+
12+
/// Struct that handles the output of the
13+
/// Create Esys_Create command and zeroizes
14+
/// the FFI data.
15+
pub(crate) struct CreateCommandOutputHandler {
16+
ffi_out_public_ptr: *mut TPM2B_PUBLIC,
17+
ffi_out_private_ptr: *mut TPM2B_PRIVATE,
18+
ffi_creation_data_ptr: *mut TPM2B_CREATION_DATA,
19+
ffi_creation_hash_ptr: *mut TPM2B_DIGEST,
20+
ffi_creation_ticket_ptr: *mut TPMT_TK_CREATION,
21+
}
22+
23+
/// Creates a new CreateCommandOutputHandler
24+
impl CreateCommandOutputHandler {
25+
pub(crate) fn new() -> Self {
26+
Self {
27+
ffi_out_private_ptr: null_mut(),
28+
ffi_out_public_ptr: null_mut(),
29+
ffi_creation_data_ptr: null_mut(),
30+
ffi_creation_hash_ptr: null_mut(),
31+
ffi_creation_ticket_ptr: null_mut(),
32+
}
33+
}
34+
35+
/// A reference to the where 'outPrivate' output parameter pointer shall be stored.
36+
pub fn ffi_out_private_ptr(&mut self) -> &mut *mut TPM2B_PRIVATE {
37+
&mut self.ffi_out_private_ptr
38+
}
39+
40+
/// A reference to the where 'outPublic' output parameter pointer shall be stored.
41+
pub fn ffi_out_public_ptr(&mut self) -> &mut *mut TPM2B_PUBLIC {
42+
&mut self.ffi_out_public_ptr
43+
}
44+
45+
/// A reference to the where 'creationData' output parameter pointer shall be stored.
46+
pub fn ffi_creation_data_ptr(&mut self) -> &mut *mut TPM2B_CREATION_DATA {
47+
&mut self.ffi_creation_data_ptr
48+
}
49+
50+
/// A reference to the where 'creationHash' output parameter pointer shall be stored.
51+
pub fn ffi_creation_hash_ptr(&mut self) -> &mut *mut TPM2B_DIGEST {
52+
&mut self.ffi_creation_hash_ptr
53+
}
54+
55+
/// A reference to the where 'creationTicket' output parameter pointer shall be stored.
56+
pub fn ffi_creation_ticket_ptr(&mut self) -> &mut *mut TPMT_TK_CREATION {
57+
&mut self.ffi_creation_ticket_ptr
58+
}
59+
}
60+
61+
impl TryFrom<CreateCommandOutputHandler> for CreateKeyResult {
62+
type Error = Error;
63+
64+
fn try_from(ffi_data_handler: CreateCommandOutputHandler) -> Result<CreateKeyResult> {
65+
let out_private_owned =
66+
crate::ffi::to_owned_with_zeroized_source(ffi_data_handler.ffi_out_private_ptr);
67+
let out_public_owned =
68+
crate::ffi::to_owned_with_zeroized_source(ffi_data_handler.ffi_out_public_ptr);
69+
let creation_data_owned =
70+
crate::ffi::to_owned_with_zeroized_source(ffi_data_handler.ffi_creation_data_ptr);
71+
let creation_hash_owned =
72+
crate::ffi::to_owned_with_zeroized_source(ffi_data_handler.ffi_creation_hash_ptr);
73+
let creation_ticket_owned =
74+
crate::ffi::to_owned_with_zeroized_source(ffi_data_handler.ffi_creation_ticket_ptr);
75+
Ok(CreateKeyResult {
76+
out_private: Private::try_from(out_private_owned)?,
77+
out_public: Public::try_from(out_public_owned)?,
78+
creation_data: CreationData::try_from(creation_data_owned)?,
79+
creation_hash: Digest::try_from(creation_hash_owned)?,
80+
creation_ticket: CreationTicket::try_from(creation_ticket_owned)?,
81+
})
82+
}
83+
}

tss-esapi/src/ffi.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2022 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
pub(crate) mod data_zeroize;
5+
6+
use crate::ffi::data_zeroize::FfiDataZeroize;
7+
use mbox::MBox;
8+
use std::ops::Deref;
9+
10+
/// Function that takes ownership of data that has been
11+
/// allocated with C memory allocation functions in TSS while also
12+
/// zeroizing the memory before freeing it.
13+
///
14+
/// # Arguments
15+
/// * `ffi_data_ptr` - A pointer to the FFI data.
16+
///
17+
/// # Returns
18+
/// The owned version of the FFI data.
19+
pub(crate) fn to_owned_with_zeroized_source<T>(ffi_data_ptr: *mut T) -> T
20+
where
21+
T: FfiDataZeroize + Copy,
22+
{
23+
let mut ffi_data = unsafe { MBox::from_raw(ffi_data_ptr) };
24+
let owned_ffi_data: T = *ffi_data.deref();
25+
ffi_data.ffi_data_zeroize();
26+
owned_ffi_data
27+
}

0 commit comments

Comments
 (0)