@@ -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