Skip to content

Commit 50e0db9

Browse files
author
Nathan Rossi
committed
Add definition for UndefineSpaceSpecial
Add a implementation for the UndefineSpaceSpecial function which is used to delete an NV index that has the TPMA_NV_POLICY_DELETE attribute set. An example and test are included for this function, setting up the NV index and deleting it requires additional initialization of a policy digest as well as a policy session in order to perform the delete due to the policy requiring the NvUndefineSpaceSpecial command code defined. Signed-off-by: Nathan Rossi <nathan.rossi@digi.com>
1 parent f025684 commit 50e0db9

File tree

1 file changed

+144
-2
lines changed

1 file changed

+144
-2
lines changed

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

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
structures::{Auth, MaxNvBuffer, Name, NvPublic},
88
tss2_esys::{
99
Esys_NV_DefineSpace, Esys_NV_Increment, Esys_NV_Read, Esys_NV_ReadPublic,
10-
Esys_NV_UndefineSpace, Esys_NV_Write,
10+
Esys_NV_UndefineSpace, Esys_NV_UndefineSpaceSpecial, Esys_NV_Write,
1111
},
1212
Context, Result, ReturnCode,
1313
};
@@ -226,7 +226,149 @@ impl Context {
226226
self.handle_manager.set_as_closed(nv_index_handle.into())
227227
}
228228

229-
// Missing function: UndefineSpaceSpecial
229+
/// Deletes an index in the non volatile storage.
230+
///
231+
/// # Details
232+
/// The method will instruct the TPM to remove a
233+
/// nv index that was defined with TPMA_NV_POLICY_DELETE.
234+
///
235+
/// Please beware that this method requires both a policy and
236+
/// authorization session handle to be present.
237+
///
238+
/// # Arguments
239+
/// * `nv_auth` - The [Provision] used for authorization.
240+
/// * `nv_index_handle`- The [NvIndexHandle] associated with
241+
/// the nv area that is to be removed.
242+
///
243+
/// # Example
244+
/// ```rust
245+
/// # use tss_esapi::{
246+
/// # Context, TctiNameConf, attributes::SessionAttributes, constants::SessionType,
247+
/// # structures::SymmetricDefinition, constants::CommandCode,
248+
/// # handles::NvIndexTpmHandle, attributes::NvIndexAttributes, structures::NvPublic,
249+
/// # interface_types::algorithm::HashingAlgorithm, structures::Digest,
250+
/// # interface_types::session_handles::PolicySession,
251+
/// # };
252+
/// # use std::convert::TryFrom;
253+
/// use tss_esapi::interface_types::resource_handles::Provision;
254+
/// use tss_esapi::interface_types::session_handles::AuthSession;
255+
/// # // Create context
256+
/// # let mut context =
257+
/// # Context::new(
258+
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
259+
/// # ).expect("Failed to create Context");
260+
/// #
261+
/// # // Create a trial session to generate policy digest
262+
/// # let session = context
263+
/// # .start_auth_session(
264+
/// # None,
265+
/// # None,
266+
/// # None,
267+
/// # SessionType::Trial,
268+
/// # SymmetricDefinition::AES_256_CFB,
269+
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
270+
/// # )
271+
/// # .expect("Failed to create session")
272+
/// # .expect("Received invalid handle");
273+
/// # let (session_attributes, session_attributes_mask) = SessionAttributes::builder()
274+
/// # .with_decrypt(true)
275+
/// # .with_encrypt(true)
276+
/// # .build();
277+
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
278+
/// # .expect("Failed to set attributes on session");
279+
/// #
280+
/// # // Create a trial policy session that allows undefine with NvUndefineSpaceSpecial
281+
/// # let policy_session = PolicySession::try_from(session).expect("Failed to get policy session");
282+
/// # context.policy_command_code(policy_session, CommandCode::NvUndefineSpaceSpecial).expect("Failed to create trial policy");
283+
/// # let digest = context.policy_get_digest(policy_session).expect("Failed to get policy digest");
284+
/// #
285+
/// # let nv_index = NvIndexTpmHandle::new(0x01500023)
286+
/// # .expect("Failed to create NV index tpm handle");
287+
/// #
288+
/// # // Create NV index attributes
289+
/// # let nv_index_attributes = NvIndexAttributes::builder()
290+
/// # .with_pp_read(true)
291+
/// # .with_platform_create(true)
292+
/// # .with_policy_delete(true)
293+
/// # .with_policy_write(true)
294+
/// # .build()
295+
/// # .expect("Failed to create nv index attributes");
296+
/// #
297+
/// # // Create nv public.
298+
/// # let nv_public = NvPublic::builder()
299+
/// # .with_nv_index(nv_index)
300+
/// # .with_index_name_algorithm(HashingAlgorithm::Sha256)
301+
/// # .with_index_attributes(nv_index_attributes)
302+
/// # .with_index_auth_policy(digest)
303+
/// # .with_data_area_size(32)
304+
/// # .build()
305+
/// # .expect("Failed to build NvPublic");
306+
/// #
307+
/// // Define the NV space.
308+
/// let index_handle = context.execute_with_session(Some(AuthSession::Password), |context| {
309+
/// context
310+
/// .nv_define_space(Provision::Platform, None, nv_public)
311+
/// .expect("Call to nv_define_space failed")
312+
/// });
313+
///
314+
/// # // Setup auth policy session
315+
/// # let session = context
316+
/// # .start_auth_session(
317+
/// # None,
318+
/// # None,
319+
/// # None,
320+
/// # SessionType::Policy,
321+
/// # SymmetricDefinition::AES_256_CFB,
322+
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
323+
/// # )
324+
/// # .expect("Failed to create policy session")
325+
/// # .expect("Received invalid handle");
326+
/// # let (session_attributes, session_attributes_mask) = SessionAttributes::builder()
327+
/// # .with_decrypt(true)
328+
/// # .with_encrypt(true)
329+
/// # .build();
330+
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
331+
/// # .expect("Failed to set attributes on session");
332+
/// #
333+
/// # // Define a policy command code that allows undefine with NvUndefineSpaceSpecial
334+
/// # let policy_session = PolicySession::try_from(session).expect("Failed to get policy session");
335+
/// # context.policy_command_code(policy_session, CommandCode::NvUndefineSpaceSpecial).expect("Failed to create policy");
336+
/// #
337+
/// // Undefine the NV space with a policy session and default auth session
338+
/// context.execute_with_sessions((
339+
/// Some(session),
340+
/// Some(AuthSession::Password),
341+
/// None,
342+
/// ), |context| {
343+
/// context
344+
/// .nv_undefine_space_special(Provision::Platform, index_handle)
345+
/// .expect("Call to nv_undefine_space_special failed");
346+
/// }
347+
/// );
348+
/// ```
349+
pub fn nv_undefine_space_special(
350+
&mut self,
351+
nv_auth: Provision,
352+
nv_index_handle: NvIndexHandle,
353+
) -> Result<()> {
354+
ReturnCode::ensure_success(
355+
unsafe {
356+
Esys_NV_UndefineSpaceSpecial(
357+
self.mut_context(),
358+
nv_index_handle.into(),
359+
AuthHandle::from(nv_auth).into(),
360+
self.required_session_1()?,
361+
self.optional_session_2(),
362+
self.optional_session_3(),
363+
)
364+
},
365+
|ret| {
366+
error!("Error when undefining NV space: {:#010X}", ret);
367+
},
368+
)?;
369+
370+
self.handle_manager.set_as_closed(nv_index_handle.into())
371+
}
230372

231373
/// Reads the public part of an nv index.
232374
///

0 commit comments

Comments
 (0)