Skip to content

Commit 314f4c1

Browse files
committed
Makes sensitive part in load_external optional.
The TPM2 specification specifies that the sensitive portion of the key is optional. This changes the API of the `load_external` context method in order to better reflect this fact. This in turn makes the `load_external_public` context method unnecessary and there for it has been removed. Signed-off-by: Jesper Brynolf <jesper.brynolf@gmail.com>
1 parent 8f906d6 commit 314f4c1

File tree

7 files changed

+132
-108
lines changed

7 files changed

+132
-108
lines changed

tss-esapi/examples/certify.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ fn main() {
267267
// challenge encryption.
268268
let (_public, ak_name, _qualified_name) = context_2
269269
.execute_with_nullauth_session(|ctx| {
270-
let ak_handle = ctx.load_external_public(ak_public.clone(), Hierarchy::Null)?;
270+
let ak_handle = ctx.load_external(None, ak_public.clone(), Hierarchy::Null)?;
271271
let r = ctx.read_public(ak_handle);
272272
ctx.flush_context(ak_handle.into())?;
273273
r
@@ -291,7 +291,7 @@ fn main() {
291291
// Now we load the ek_public, and create our encrypted challenge.
292292
let (idobject, encrypted_secret) = context_2
293293
.execute_with_nullauth_session(|ctx| {
294-
let ek_handle = ctx.load_external_public(ek_public, Hierarchy::Null)?;
294+
let ek_handle = ctx.load_external(None, ek_public, Hierarchy::Null)?;
295295
let r = ctx.make_credential(ek_handle, challenge.clone(), ak_name);
296296
ctx.flush_context(ek_handle.into())?;
297297
r
@@ -510,7 +510,8 @@ fn main() {
510510
// First, load the public from the aik
511511
let ak_handle = context_2
512512
.execute_with_nullauth_session(|ctx| {
513-
ctx.load_external_public(
513+
ctx.load_external(
514+
None,
514515
ak_public,
515516
// We put it into the null hierarchy as this is ephemeral.
516517
Hierarchy::Null,

tss-esapi/examples/duplication.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ fn main() {
303303
.execute_without_session(|ctx| {
304304
// Ensure we load the new parent handle before we start
305305
let new_parent_handle = ctx
306-
.load_external_public(primary_key_2_public, Hierarchy::Null)
306+
.load_external(None, primary_key_2_public, Hierarchy::Null)
307307
.unwrap();
308308

309309
// IMPORTANT! After you start the policy session, you can't do *anything* else except

tss-esapi/examples/rsa_oaep.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn main() {
9090
let encrypted_data = context
9191
.execute_with_nullauth_session(|ctx| {
9292
let rsa_pub_key = ctx
93-
.load_external_public(public.clone(), Hierarchy::Null)
93+
.load_external(None, public.clone(), Hierarchy::Null)
9494
.unwrap();
9595

9696
ctx.rsa_encrypt(

tss-esapi/src/abstraction/transient/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,7 @@ impl TransientKeyContext {
194194
) -> Result<KeyMaterial> {
195195
let public = TransientKeyContext::get_public_from_params(params, Some(public_key.clone()))?;
196196
self.set_session_attrs()?;
197-
let key_handle = self
198-
.context
199-
.load_external_public(public, Hierarchy::Owner)?;
197+
let key_handle = self.context.load_external(None, public, Hierarchy::Owner)?;
200198
self.context.flush_context(key_handle.into())?;
201199
Ok(KeyMaterial {
202200
public: public_key,
@@ -522,8 +520,7 @@ impl TransientKeyContext {
522520

523521
self.set_session_attrs()?;
524522
let key_handle = if material.private.is_empty() {
525-
self.context
526-
.load_external_public(public, Hierarchy::Owner)?
523+
self.context.load_external(None, public, Hierarchy::Owner)?
527524
} else {
528525
self.context
529526
.load(self.root_key_handle, material.private.try_into()?, public)?

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

Lines changed: 108 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
Esys_ActivateCredential, Esys_Create, Esys_Load, Esys_LoadExternal, Esys_MakeCredential,
1616
Esys_ObjectChangeAuth, Esys_ReadPublic, Esys_Unseal,
1717
},
18-
Context, Result, ReturnCode,
18+
Context, Error, Result, ReturnCode, WrapperErrorKind,
1919
};
2020
use create_command_input::CreateCommandInputHandler;
2121
use create_command_output::CreateCommandOutputHandler;
@@ -123,22 +123,126 @@ impl Context {
123123
}
124124

125125
/// Load an external key into the TPM and return its new handle.
126+
///
127+
/// # Details
128+
/// This command is used to load an object that is not a Protected Object into the TPM. The command allows
129+
/// loading of a public area or both a public and sensitive area.
130+
///
131+
/// # Arguments
132+
/// * `private` - The optional sensitive portion of the object.
133+
/// * `public` - The public portion of the object.
134+
/// * `hierarchy` - The hierarchy with which the object area is associated.
135+
///
136+
/// # Returns
137+
/// The handle to the loaded key.
138+
///
139+
/// # Example
140+
///
141+
/// ```rust
142+
/// # use tss_esapi::{
143+
/// # Context, TctiNameConf,
144+
/// # attributes::ObjectAttributesBuilder,
145+
/// # constants::SessionType,
146+
/// # interface_types::{
147+
/// # algorithm::{HashingAlgorithm, PublicAlgorithm, RsaSchemeAlgorithm},
148+
/// # key_bits::RsaKeyBits,
149+
/// # reserved_handles::Hierarchy,
150+
/// # },
151+
/// # structures::{
152+
/// # Public, PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
153+
/// # SymmetricDefinition,
154+
/// # },
155+
/// # };
156+
/// #
157+
/// # const KEY: [u8; 256] = [
158+
/// # 231, 97, 201, 180, 0, 1, 185, 150, 85, 90, 174, 188, 105, 133, 188, 3, 206, 5, 222, 71, 185, 1,
159+
/// # 209, 243, 36, 130, 250, 116, 17, 0, 24, 4, 25, 225, 250, 198, 245, 210, 140, 23, 139, 169, 15,
160+
/// # 193, 4, 145, 52, 138, 149, 155, 238, 36, 74, 152, 179, 108, 200, 248, 250, 100, 115, 214, 166,
161+
/// # 165, 1, 27, 51, 11, 11, 244, 218, 157, 3, 174, 171, 142, 45, 8, 9, 36, 202, 171, 165, 43, 208,
162+
/// # 186, 232, 15, 241, 95, 81, 174, 189, 30, 213, 47, 86, 115, 239, 49, 214, 235, 151, 9, 189, 174,
163+
/// # 144, 238, 200, 201, 241, 157, 43, 37, 6, 96, 94, 152, 159, 205, 54, 9, 181, 14, 35, 246, 49,
164+
/// # 150, 163, 118, 242, 59, 54, 42, 221, 215, 248, 23, 18, 223, 179, 229, 0, 204, 65, 69, 166, 180,
165+
/// # 11, 49, 131, 96, 163, 96, 158, 7, 109, 119, 208, 17, 237, 125, 187, 121, 94, 65, 2, 86, 105,
166+
/// # 68, 51, 197, 73, 108, 185, 231, 126, 199, 81, 1, 251, 211, 45, 47, 15, 113, 135, 197, 152, 239,
167+
/// # 180, 111, 18, 192, 136, 222, 11, 99, 41, 248, 205, 253, 209, 56, 214, 32, 225, 3, 49, 161, 58,
168+
/// # 57, 190, 69, 86, 95, 185, 184, 155, 76, 8, 122, 104, 81, 222, 234, 246, 40, 98, 182, 90, 160,
169+
/// # 111, 74, 102, 36, 148, 99, 69, 207, 214, 104, 87, 128, 238, 26, 121, 107, 166, 4, 64, 5, 210,
170+
/// # 164, 162, 189,
171+
/// # ];
172+
/// #
173+
/// # // Create context
174+
/// # let mut context =
175+
/// # Context::new(
176+
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
177+
/// # ).expect("Failed to create Context");
178+
/// #
179+
/// # let session = context
180+
/// # .start_auth_session(
181+
/// # None,
182+
/// # None,
183+
/// # None,
184+
/// # SessionType::Hmac,
185+
/// # SymmetricDefinition::AES_256_CFB,
186+
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
187+
/// # )
188+
/// # .expect("Failed to create session")
189+
/// # .expect("Received invalid handle");
190+
/// #
191+
/// let object_attributes = ObjectAttributesBuilder::new()
192+
/// .with_user_with_auth(true)
193+
/// .with_decrypt(false)
194+
/// .with_sign_encrypt(true)
195+
/// .with_restricted(false)
196+
/// .build()
197+
/// .expect("Failed to build object attributes");
198+
///
199+
/// let public = PublicBuilder::new()
200+
/// .with_public_algorithm(PublicAlgorithm::Rsa)
201+
/// .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
202+
/// .with_object_attributes(object_attributes)
203+
/// .with_rsa_parameters(
204+
/// PublicRsaParametersBuilder::new_unrestricted_signing_key(
205+
/// RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256))
206+
/// .expect("Failed to create rsa scheme"),
207+
/// RsaKeyBits::Rsa2048,
208+
/// Default::default(),
209+
/// )
210+
/// .build()
211+
/// .expect("Failed to create rsa parameters for public structure"),
212+
/// )
213+
/// .with_rsa_unique_identifier(
214+
/// PublicKeyRsa::from_bytes(&KEY[..256])
215+
/// .expect("Failed to create Public RSA key from buffer"),
216+
/// )
217+
/// .build()
218+
/// .expect("Failed to build Public structure");
219+
///
220+
/// // Load public key into Owner hierarchy.
221+
/// let key_handle = context.load_external(None, public, Hierarchy::Owner)
222+
/// .expect("The load_external should have returned a valid key handle.");
223+
/// ```
126224
pub fn load_external(
127225
&mut self,
128-
private: Sensitive,
226+
private: Option<Sensitive>,
129227
public: Public,
130228
hierarchy: Hierarchy,
131229
) -> Result<KeyHandle> {
230+
if (hierarchy != Hierarchy::Null) && private.is_some() {
231+
error!("Only NULL hierarchy is valid in load_external when loading both private and public part.");
232+
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
233+
}
132234
let mut object_handle = ObjectHandle::None.into();
235+
let potential_private_in = private.map(|v| v.try_into()).transpose()?;
236+
let public_in = public.try_into()?;
133237
ReturnCode::ensure_success(
134238
unsafe {
135239
Esys_LoadExternal(
136240
self.mut_context(),
137241
self.optional_session_1(),
138242
self.optional_session_2(),
139243
self.optional_session_3(),
140-
&private.try_into()?,
141-
&public.try_into()?,
244+
potential_private_in.as_ref().map_or_else(null, |v| v),
245+
&public_in,
142246
if cfg!(hierarchy_is_esys_tr) {
143247
ObjectHandle::from(hierarchy).into()
144248
} else {
@@ -158,41 +262,6 @@ impl Context {
158262
Ok(key_handle)
159263
}
160264

161-
/// Load the public part of an external key and return its new handle.
162-
pub fn load_external_public(
163-
&mut self,
164-
public: Public,
165-
hierarchy: Hierarchy,
166-
) -> Result<KeyHandle> {
167-
let mut object_handle = ObjectHandle::None.into();
168-
ReturnCode::ensure_success(
169-
unsafe {
170-
Esys_LoadExternal(
171-
self.mut_context(),
172-
self.optional_session_1(),
173-
self.optional_session_2(),
174-
self.optional_session_3(),
175-
null(),
176-
&public.try_into()?,
177-
if cfg!(hierarchy_is_esys_tr) {
178-
ObjectHandle::from(hierarchy).into()
179-
} else {
180-
TpmHandle::from(hierarchy).into()
181-
},
182-
&mut object_handle,
183-
)
184-
},
185-
|ret| {
186-
error!("Error in loading external public object: {:#010X}", ret);
187-
},
188-
)?;
189-
190-
let key_handle = KeyHandle::from(object_handle);
191-
self.handle_manager
192-
.add_handle(key_handle.into(), HandleDropAction::Flush)?;
193-
Ok(key_handle)
194-
}
195-
196265
/// Read the public part of a key currently in the TPM and return it.
197266
pub fn read_public(&mut self, key_handle: KeyHandle) -> Result<(Public, Name, Name)> {
198267
let mut out_public_ptr = null_mut();

tss-esapi/tests/integration_tests/abstraction_tests/transient_key_context_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ fn ctx_migration_test() {
558558
let key_context = basic_ctx.context_save(key_handle.into()).unwrap();
559559

560560
let pub_key_handle = basic_ctx
561-
.load_external_public(result.out_public.clone(), Hierarchy::Owner)
561+
.load_external(None, result.out_public.clone(), Hierarchy::Owner)
562562
.unwrap();
563563
let pub_key_context = basic_ctx.context_save(pub_key_handle.into()).unwrap();
564564

@@ -672,7 +672,7 @@ fn activate_credential() {
672672
panic!("Wrong Public type");
673673
};
674674
let pub_handle = basic_ctx
675-
.load_external_public(key_pub, Hierarchy::Owner)
675+
.load_external(None, key_pub, Hierarchy::Owner)
676676
.unwrap();
677677

678678
// Credential to expect back as proof for attestation
@@ -799,7 +799,7 @@ fn activate_credential_wrong_key() {
799799
panic!("Wrong Public type");
800800
};
801801
let pub_handle = basic_ctx
802-
.load_external_public(key_pub, Hierarchy::Owner)
802+
.load_external(None, key_pub, Hierarchy::Owner)
803803
.unwrap();
804804

805805
// Credential to expect back as proof for attestation

tss-esapi/tests/integration_tests/context_tests/tpm_commands/object_commands_tests.rs

Lines changed: 13 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -76,60 +76,6 @@ mod test_load {
7676
}
7777
}
7878

79-
mod test_load_external_public {
80-
use crate::common::{create_ctx_with_session, KEY};
81-
use tss_esapi::{
82-
attributes::ObjectAttributesBuilder,
83-
interface_types::{
84-
algorithm::{HashingAlgorithm, PublicAlgorithm, RsaSchemeAlgorithm},
85-
key_bits::RsaKeyBits,
86-
reserved_handles::Hierarchy,
87-
},
88-
structures::{Public, PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme},
89-
};
90-
91-
pub fn get_ext_rsa_pub() -> Public {
92-
let object_attributes = ObjectAttributesBuilder::new()
93-
.with_user_with_auth(true)
94-
.with_decrypt(false)
95-
.with_sign_encrypt(true)
96-
.with_restricted(false)
97-
.build()
98-
.expect("Failed to build object attributes");
99-
100-
PublicBuilder::new()
101-
.with_public_algorithm(PublicAlgorithm::Rsa)
102-
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
103-
.with_object_attributes(object_attributes)
104-
.with_rsa_parameters(
105-
PublicRsaParametersBuilder::new_unrestricted_signing_key(
106-
RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256))
107-
.expect("Failed to create rsa scheme"),
108-
RsaKeyBits::Rsa2048,
109-
Default::default(),
110-
)
111-
.build()
112-
.expect("Failed to create rsa parameters for public structure"),
113-
)
114-
.with_rsa_unique_identifier(
115-
PublicKeyRsa::from_bytes(&KEY[..256])
116-
.expect("Failed to create Public RSA key from buffer"),
117-
)
118-
.build()
119-
.expect("Failed to build Public structure")
120-
}
121-
122-
#[test]
123-
fn test_load_external_public() {
124-
let mut context = create_ctx_with_session();
125-
let pub_key = get_ext_rsa_pub();
126-
127-
context
128-
.load_external_public(pub_key, Hierarchy::Owner)
129-
.unwrap();
130-
}
131-
}
132-
13379
mod test_load_external {
13480
use crate::common::create_ctx_with_session;
13581
use std::convert::TryInto;
@@ -218,13 +164,24 @@ mod test_load_external {
218164
}
219165

220166
#[test]
221-
fn test_load_external() {
167+
fn test_load_external_private_and_public_parts() {
222168
let mut context = create_ctx_with_session();
223169
let pub_key = get_ext_rsa_pub();
224170
let priv_key = get_ext_rsa_priv();
225171

226172
let key_handle = context
227-
.load_external(priv_key, pub_key, Hierarchy::Null)
173+
.load_external(Some(priv_key), pub_key, Hierarchy::Null)
174+
.unwrap();
175+
context.flush_context(key_handle.into()).unwrap();
176+
}
177+
178+
#[test]
179+
fn test_load_external_only_public_part() {
180+
let mut context = create_ctx_with_session();
181+
let pub_key = get_ext_rsa_pub();
182+
183+
let key_handle = context
184+
.load_external(None, pub_key, Hierarchy::Null)
228185
.unwrap();
229186
context.flush_context(key_handle.into()).unwrap();
230187
}

0 commit comments

Comments
 (0)