tss_esapi/context/tpm_commands/enhanced_authorization_ea_commands.rs
1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4 attributes::LocalityAttributes,
5 constants::CommandCode,
6 handles::{AuthHandle, NvIndexHandle, ObjectHandle, SessionHandle},
7 interface_types::{reserved_handles::NvAuth, session_handles::PolicySession, YesNo},
8 structures::{
9 AuthTicket, Digest, DigestList, Name, Nonce, PcrSelectionList, Signature, Timeout,
10 VerifiedTicket,
11 },
12 tss2_esys::{
13 Esys_PolicyAuthValue, Esys_PolicyAuthorize, Esys_PolicyAuthorizeNV, Esys_PolicyCommandCode,
14 Esys_PolicyCpHash, Esys_PolicyDuplicationSelect, Esys_PolicyGetDigest, Esys_PolicyLocality,
15 Esys_PolicyNameHash, Esys_PolicyNvWritten, Esys_PolicyOR, Esys_PolicyPCR,
16 Esys_PolicyPassword, Esys_PolicyPhysicalPresence, Esys_PolicySecret, Esys_PolicySigned,
17 Esys_PolicyTemplate,
18 },
19 Context, Error, Result, ReturnCode, WrapperErrorKind as ErrorKind,
20};
21use log::error;
22use std::convert::{TryFrom, TryInto};
23use std::ptr::null_mut;
24use std::time::Duration;
25
26impl Context {
27 /// Cause the policy to include a signed authorization
28 #[allow(clippy::too_many_arguments)]
29 pub fn policy_signed(
30 &mut self,
31 policy_session: PolicySession,
32 auth_object: ObjectHandle,
33 nonce_tpm: Nonce,
34 cp_hash_a: Digest,
35 policy_ref: Nonce,
36 expiration: Option<Duration>,
37 signature: Signature,
38 ) -> Result<(Timeout, AuthTicket)> {
39 let mut out_timeout_ptr = null_mut();
40 let mut out_policy_ticket_ptr = null_mut();
41 ReturnCode::ensure_success(
42 unsafe {
43 Esys_PolicySigned(
44 self.mut_context(),
45 auth_object.into(),
46 SessionHandle::from(policy_session).into(),
47 self.required_session_1()?,
48 self.optional_session_2(),
49 self.optional_session_3(),
50 &nonce_tpm.into(),
51 &cp_hash_a.into(),
52 &policy_ref.into(),
53 i32::try_from(expiration.map_or(0, |v| v.as_secs())).map_err(|e| {
54 error!("Unable to convert duration to i32: {}", e);
55 Error::local_error(ErrorKind::InvalidParam)
56 })?,
57 &signature.try_into()?,
58 &mut out_timeout_ptr,
59 &mut out_policy_ticket_ptr,
60 )
61 },
62 |ret| {
63 error!("Error when sending policy signed: {:#010X}", ret);
64 },
65 )?;
66 Ok((
67 Timeout::try_from(Context::ffi_data_to_owned(out_timeout_ptr)?)?,
68 AuthTicket::try_from(Context::ffi_data_to_owned(out_policy_ticket_ptr)?)?,
69 ))
70 }
71
72 /// Cause the policy to require a secret in authValue
73 pub fn policy_secret(
74 &mut self,
75 policy_session: PolicySession,
76 auth_handle: AuthHandle,
77 nonce_tpm: Nonce,
78 cp_hash_a: Digest,
79 policy_ref: Nonce,
80 expiration: Option<Duration>,
81 ) -> Result<(Timeout, AuthTicket)> {
82 let mut out_timeout_ptr = null_mut();
83 let mut out_policy_ticket_ptr = null_mut();
84 ReturnCode::ensure_success(
85 unsafe {
86 Esys_PolicySecret(
87 self.mut_context(),
88 auth_handle.into(),
89 SessionHandle::from(policy_session).into(),
90 self.required_session_1()?,
91 self.optional_session_2(),
92 self.optional_session_3(),
93 &nonce_tpm.into(),
94 &cp_hash_a.into(),
95 &policy_ref.into(),
96 i32::try_from(expiration.map_or(0, |v| v.as_secs())).map_err(|e| {
97 error!("Unable to convert duration to i32: {}", e);
98 Error::local_error(ErrorKind::InvalidParam)
99 })?,
100 &mut out_timeout_ptr,
101 &mut out_policy_ticket_ptr,
102 )
103 },
104 |ret| {
105 error!("Error when sending policy secret: {:#010X}", ret);
106 },
107 )?;
108 Ok((
109 Timeout::try_from(Context::ffi_data_to_owned(out_timeout_ptr)?)?,
110 AuthTicket::try_from(Context::ffi_data_to_owned(out_policy_ticket_ptr)?)?,
111 ))
112 }
113
114 // Missing function: PolicyTicket
115
116 /// Cause conditional gating of a policy based on an OR'd condition.
117 ///
118 /// The TPM will ensure that the current policy digest equals at least
119 /// one of the digests.
120 /// If this is the case, the policyDigest of the policy session is replaced
121 /// by the value of the different hashes.
122 ///
123 /// # Constraints
124 /// * `digest_list` must be at least 2 and at most 8 elements long
125 ///
126 /// # Errors
127 /// * if the hash list provided is too short or too long, a `WrongParamSize` wrapper error will be returned
128 pub fn policy_or(
129 &mut self,
130 policy_session: PolicySession,
131 digest_list: DigestList,
132 ) -> Result<()> {
133 if digest_list.len() < 2 {
134 error!(
135 "The digest list only contains {} digests, it must contain at least 2",
136 digest_list.len()
137 );
138 return Err(Error::local_error(ErrorKind::WrongParamSize));
139 }
140
141 ReturnCode::ensure_success(
142 unsafe {
143 Esys_PolicyOR(
144 self.mut_context(),
145 SessionHandle::from(policy_session).into(),
146 self.optional_session_1(),
147 self.optional_session_2(),
148 self.optional_session_3(),
149 &digest_list.try_into()?,
150 )
151 },
152 |ret| {
153 error!("Error when computing policy OR: {:#010X}", ret);
154 },
155 )
156 }
157
158 /// Cause conditional gating of a policy based on PCR.
159 ///
160 /// # Details
161 /// The TPM will use the hash algorithm of the policy_session
162 /// to calculate a digest from the values of the pcr slots
163 /// specified in the pcr_selections.
164 /// This is then compared to pcr_policy_digest if they match then
165 /// the policyDigest of the policy session is extended.
166 ///
167 /// # Errors
168 /// * if the pcr policy digest provided is too long, a `WrongParamSize` wrapper error will be returned
169 pub fn policy_pcr(
170 &mut self,
171 policy_session: PolicySession,
172 pcr_policy_digest: Digest,
173 pcr_selection_list: PcrSelectionList,
174 ) -> Result<()> {
175 ReturnCode::ensure_success(
176 unsafe {
177 Esys_PolicyPCR(
178 self.mut_context(),
179 SessionHandle::from(policy_session).into(),
180 self.optional_session_1(),
181 self.optional_session_2(),
182 self.optional_session_3(),
183 &pcr_policy_digest.into(),
184 &pcr_selection_list.into(),
185 )
186 },
187 |ret| {
188 error!("Error when computing policy PCR: {:#010X}", ret);
189 },
190 )
191 }
192
193 /// Cause conditional gating of a policy based on locality.
194 ///
195 /// The TPM will ensure that the current policy can only complete in the specified
196 /// locality (extended) or any of the specified localities (non-extended).
197 pub fn policy_locality(
198 &mut self,
199 policy_session: PolicySession,
200 locality: LocalityAttributes,
201 ) -> Result<()> {
202 ReturnCode::ensure_success(
203 unsafe {
204 Esys_PolicyLocality(
205 self.mut_context(),
206 SessionHandle::from(policy_session).into(),
207 self.optional_session_1(),
208 self.optional_session_2(),
209 self.optional_session_3(),
210 locality.into(),
211 )
212 },
213 |ret| {
214 error!("Error when computing policy locality: {:#010X}", ret);
215 },
216 )
217 }
218
219 // Missing function: PolicyNV
220 // Missing function: PolicyCounterTimer
221
222 /// Cause conditional gating of a policy based on command code of authorized command.
223 ///
224 /// The TPM will ensure that the current policy can only be used to complete the command
225 /// indicated by code.
226 pub fn policy_command_code(
227 &mut self,
228 policy_session: PolicySession,
229 code: CommandCode,
230 ) -> Result<()> {
231 ReturnCode::ensure_success(
232 unsafe {
233 Esys_PolicyCommandCode(
234 self.mut_context(),
235 SessionHandle::from(policy_session).into(),
236 self.optional_session_1(),
237 self.optional_session_2(),
238 self.optional_session_3(),
239 code.into(),
240 )
241 },
242 |ret| {
243 error!("Error when computing policy command code: {:#010X}", ret);
244 },
245 )
246 }
247
248 /// Cause conditional gating of a policy based on physical presence.
249 ///
250 /// The TPM will ensure that the current policy can only complete when physical
251 /// presence is asserted. The way this is done is implementation-specific.
252 pub fn policy_physical_presence(&mut self, policy_session: PolicySession) -> Result<()> {
253 ReturnCode::ensure_success(
254 unsafe {
255 Esys_PolicyPhysicalPresence(
256 self.mut_context(),
257 SessionHandle::from(policy_session).into(),
258 self.optional_session_1(),
259 self.optional_session_2(),
260 self.optional_session_3(),
261 )
262 },
263 |ret| {
264 error!(
265 "Error when computing policy physical presence: {:#010X}",
266 ret
267 );
268 },
269 )
270 }
271
272 /// Cause conditional gating of a policy based on command parameters.
273 ///
274 /// The TPM will ensure that the current policy can only be used to authorize
275 /// a command where the parameters are hashed into cp_hash_a.
276 pub fn policy_cp_hash(
277 &mut self,
278 policy_session: PolicySession,
279 cp_hash_a: Digest,
280 ) -> Result<()> {
281 ReturnCode::ensure_success(
282 unsafe {
283 Esys_PolicyCpHash(
284 self.mut_context(),
285 SessionHandle::from(policy_session).into(),
286 self.optional_session_1(),
287 self.optional_session_2(),
288 self.optional_session_3(),
289 &cp_hash_a.into(),
290 )
291 },
292 |ret| {
293 error!(
294 "Error when computing policy command parameters: {:#010X}",
295 ret
296 );
297 },
298 )
299 }
300
301 /// Cause conditional gating of a policy based on name hash.
302 ///
303 /// The TPM will ensure that the current policy can only be used to authorize
304 /// a command acting on an object whose name hashes to name_hash.
305 pub fn policy_name_hash(
306 &mut self,
307 policy_session: PolicySession,
308 name_hash: Digest,
309 ) -> Result<()> {
310 ReturnCode::ensure_success(
311 unsafe {
312 Esys_PolicyNameHash(
313 self.mut_context(),
314 SessionHandle::from(policy_session).into(),
315 self.optional_session_1(),
316 self.optional_session_2(),
317 self.optional_session_3(),
318 &name_hash.into(),
319 )
320 },
321 |ret| {
322 error!("Error when computing policy name hash: {:#010X}", ret);
323 },
324 )
325 }
326
327 /// Cause conditional gating of a policy based on duplication parent's name.
328 ///
329 /// # Arguments
330 /// * `policy_session` - The [policy session][PolicySession] being extended.
331 /// * `object_name` - The [name][Name] of the object being duplicated.
332 /// * `new_parent_name` - The [name][Name] of the new parent.
333 /// * `include_object` - Flag indicating if `object_name` will be included in policy
334 /// calculation.
335 ///
336 /// # Details
337 /// Set `include_object` only when this command is used in conjunction with
338 /// [`policy_authorize`][Context::policy_authorize].
339 ///
340 /// # Example
341 ///
342 /// ```rust
343 /// # use std::convert::{TryFrom, TryInto};
344 /// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
345 /// # use tss_esapi::constants::{CommandCode, SessionType};
346 /// # use tss_esapi::handles::ObjectHandle;
347 /// # use tss_esapi::interface_types::{
348 /// # algorithm::{HashingAlgorithm, PublicAlgorithm},
349 /// # key_bits::RsaKeyBits,
350 /// # reserved_handles::Hierarchy,
351 /// # session_handles::PolicySession,
352 /// # };
353 /// # use tss_esapi::structures::SymmetricDefinition;
354 /// # use tss_esapi::structures::{
355 /// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
356 /// # RsaExponent, Name,
357 /// # };
358 /// # use tss_esapi::structures::SymmetricDefinitionObject;
359 /// # use tss_esapi::abstraction::cipher::Cipher;
360 /// # use tss_esapi::{Context, TctiNameConf};
361 /// #
362 /// # let mut context = // ...
363 /// # Context::new(
364 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
365 /// # ).expect("Failed to create Context");
366 /// #
367 /// # let trial_session = context
368 /// # .start_auth_session(
369 /// # None,
370 /// # None,
371 /// # None,
372 /// # SessionType::Trial,
373 /// # SymmetricDefinition::AES_256_CFB,
374 /// # HashingAlgorithm::Sha256,
375 /// # )
376 /// # .expect("Start auth session failed")
377 /// # .expect("Start auth session returned a NONE handle");
378 /// #
379 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
380 /// # SessionAttributesBuilder::new()
381 /// # .with_decrypt(true)
382 /// # .with_encrypt(true)
383 /// # .build();
384 /// # context
385 /// # .tr_sess_set_attributes(
386 /// # trial_session,
387 /// # policy_auth_session_attributes,
388 /// # policy_auth_session_attributes_mask,
389 /// # )
390 /// # .expect("tr_sess_set_attributes call failed");
391 /// #
392 /// # let policy_session = PolicySession::try_from(trial_session)
393 /// # .expect("Failed to convert auth session into policy session");
394 /// #
395 /// # let object_name: Name = Vec::<u8>::new().try_into().unwrap();
396 /// # let parent_name = object_name.clone();
397 /// #
398 /// context
399 /// .policy_duplication_select(policy_session, object_name, parent_name, false)
400 /// .expect("Policy command code");
401 /// #
402 /// # /// Digest of the policy that allows duplication
403 /// # let digest = context
404 /// # .policy_get_digest(policy_session)
405 /// # .expect("Could retrieve digest");
406 /// ```
407 pub fn policy_duplication_select(
408 &mut self,
409 policy_session: PolicySession,
410 object_name: Name,
411 new_parent_name: Name,
412 include_object: bool,
413 ) -> Result<()> {
414 ReturnCode::ensure_success(
415 unsafe {
416 Esys_PolicyDuplicationSelect(
417 self.mut_context(),
418 SessionHandle::from(policy_session).into(),
419 self.optional_session_1(),
420 self.optional_session_2(),
421 self.optional_session_3(),
422 &object_name.into(),
423 &new_parent_name.into(),
424 YesNo::from(include_object).into(),
425 )
426 },
427 |ret| {
428 error!(
429 "Error when computing policy duplication select: {:#010X}",
430 ret
431 );
432 },
433 )
434 }
435
436 /// Cause conditional gating of a policy based on an authorized policy
437 ///
438 /// The TPM will ensure that the current policy digest is correctly signed
439 /// by the ticket in check_ticket and that check_ticket is signed by the key
440 /// named in key_sign.
441 /// If this is the case, the policyDigest of the policy session is replaced
442 /// by the value of the key_sign and policy_ref values.
443 pub fn policy_authorize(
444 &mut self,
445 policy_session: PolicySession,
446 approved_policy: Digest,
447 policy_ref: Nonce,
448 key_sign: &Name,
449 check_ticket: VerifiedTicket,
450 ) -> Result<()> {
451 ReturnCode::ensure_success(
452 unsafe {
453 Esys_PolicyAuthorize(
454 self.mut_context(),
455 SessionHandle::from(policy_session).into(),
456 self.optional_session_1(),
457 self.optional_session_2(),
458 self.optional_session_3(),
459 &approved_policy.into(),
460 &policy_ref.into(),
461 key_sign.as_ref(),
462 &check_ticket.try_into()?,
463 )
464 },
465 |ret| {
466 error!("Error when computing policy authorize: {:#010X}", ret);
467 },
468 )
469 }
470
471 /// Cause conditional gating of a policy based on authValue.
472 ///
473 /// The TPM will ensure that the current policy requires the user to know the authValue
474 /// used when creating the object.
475 pub fn policy_auth_value(&mut self, policy_session: PolicySession) -> Result<()> {
476 ReturnCode::ensure_success(
477 unsafe {
478 Esys_PolicyAuthValue(
479 self.mut_context(),
480 SessionHandle::from(policy_session).into(),
481 self.optional_session_1(),
482 self.optional_session_2(),
483 self.optional_session_3(),
484 )
485 },
486 |ret| {
487 error!("Error when computing policy auth value: {:#010X}", ret);
488 },
489 )
490 }
491
492 /// Cause conditional gating of a policy based on password.
493 ///
494 /// The TPM will ensure that the current policy requires the user to know the password
495 /// used when creating the object.
496 pub fn policy_password(&mut self, policy_session: PolicySession) -> Result<()> {
497 ReturnCode::ensure_success(
498 unsafe {
499 Esys_PolicyPassword(
500 self.mut_context(),
501 SessionHandle::from(policy_session).into(),
502 self.optional_session_1(),
503 self.optional_session_2(),
504 self.optional_session_3(),
505 )
506 },
507 |ret| {
508 error!("Error when computing policy password: {:#010X}", ret);
509 },
510 )
511 }
512
513 /// Function for retrieving the current policy digest for
514 /// the session.
515 pub fn policy_get_digest(&mut self, policy_session: PolicySession) -> Result<Digest> {
516 let mut policy_digest_ptr = null_mut();
517 ReturnCode::ensure_success(
518 unsafe {
519 Esys_PolicyGetDigest(
520 self.mut_context(),
521 SessionHandle::from(policy_session).into(),
522 self.optional_session_1(),
523 self.optional_session_2(),
524 self.optional_session_3(),
525 &mut policy_digest_ptr,
526 )
527 },
528 |ret| {
529 error!(
530 "Error failed to perform policy get digest operation: {:#010X}.",
531 ret
532 );
533 },
534 )?;
535
536 Digest::try_from(Context::ffi_data_to_owned(policy_digest_ptr)?)
537 }
538
539 /// Cause conditional gating of a policy based on NV written state.
540 ///
541 /// The TPM will ensure that the NV index that is used has a specific written state.
542 pub fn policy_nv_written(
543 &mut self,
544 policy_session: PolicySession,
545 written_set: bool,
546 ) -> Result<()> {
547 ReturnCode::ensure_success(
548 unsafe {
549 Esys_PolicyNvWritten(
550 self.mut_context(),
551 SessionHandle::from(policy_session).into(),
552 self.optional_session_1(),
553 self.optional_session_2(),
554 self.optional_session_3(),
555 written_set.into(),
556 )
557 },
558 |ret| {
559 error!(
560 "Error when computing policy NV written state: {:#010X}",
561 ret
562 );
563 },
564 )
565 }
566
567 /// Bind policy to a specific creation template.
568 ///
569 /// # Arguments
570 /// * `policy_session` - The [policy session][PolicySession] being extended.
571 /// * `template_hash` - The [digest][Digest] to be added to the policy.
572 pub fn policy_template(
573 &mut self,
574 policy_session: PolicySession,
575 template_hash: Digest,
576 ) -> Result<()> {
577 ReturnCode::ensure_success(
578 unsafe {
579 Esys_PolicyTemplate(
580 self.mut_context(),
581 SessionHandle::from(policy_session).into(),
582 self.optional_session_1(),
583 self.optional_session_2(),
584 self.optional_session_3(),
585 &template_hash.into(),
586 )
587 },
588 |ret| {
589 error!(
590 "Failed to bind template to a specific creation template: {:#010X}",
591 ret
592 );
593 },
594 )
595 }
596
597 /// Cause conditional gating of a policy based on an authorized policy
598 /// stored in non-volatile memory.
599 ///
600 /// # Arguments
601 /// * `policy_session` - The [policy session][PolicySession] being extended.
602 /// * `auth_handle` - Handle indicating the source of authorization value.
603 /// * `nv_index_handle` - The [NvIndexHandle] associated with NV memory
604 /// where the policy is stored.
605 ///
606 /// # Example
607 /// ```rust
608 /// # use std::convert::TryFrom;
609 /// # use tss_esapi::attributes::{NvIndexAttributes, SessionAttributes};
610 /// # use tss_esapi::constants::SessionType;
611 /// # use tss_esapi::handles::NvIndexTpmHandle;
612 /// # use tss_esapi::interface_types::{
613 /// # algorithm::HashingAlgorithm,
614 /// # reserved_handles::{NvAuth, Provision},
615 /// # session_handles::PolicySession,
616 /// # };
617 /// # use tss_esapi::structures::{NvPublic, SymmetricDefinition};
618 /// # use tss_esapi::{Context, TctiNameConf};
619 /// #
620 /// # let mut context = // ...
621 /// # Context::new(
622 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
623 /// # ).expect("Failed to create Context");
624 /// #
625 /// # // Set owner session for NV space definition
626 /// # let owner_auth_session = context
627 /// # .start_auth_session(
628 /// # None,
629 /// # None,
630 /// # None,
631 /// # SessionType::Hmac,
632 /// # SymmetricDefinition::AES_256_CFB,
633 /// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
634 /// # )
635 /// # .expect("Failed to create session")
636 /// # .expect("Received invalid handle");
637 /// # let (session_attributes, session_attributes_mask) = SessionAttributes::builder()
638 /// # .with_decrypt(true)
639 /// # .with_encrypt(true)
640 /// # .build();
641 /// # context.tr_sess_set_attributes(owner_auth_session, session_attributes, session_attributes_mask)
642 /// # .expect("Failed to set attributes on session");
643 /// # context.set_sessions((Some(owner_auth_session), None, None));
644 /// #
645 /// # let trial_session = context
646 /// # .start_auth_session(
647 /// # None,
648 /// # None,
649 /// # None,
650 /// # SessionType::Trial,
651 /// # SymmetricDefinition::AES_256_CFB,
652 /// # HashingAlgorithm::Sha256,
653 /// # )
654 /// # .expect("Start auth session failed")
655 /// # .expect("Start auth session returned a NONE handle");
656 /// #
657 /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
658 /// # SessionAttributes::builder()
659 /// # .with_decrypt(true)
660 /// # .with_encrypt(true)
661 /// # .build();
662 /// # context
663 /// # .tr_sess_set_attributes(
664 /// # trial_session,
665 /// # policy_auth_session_attributes,
666 /// # policy_auth_session_attributes_mask,
667 /// # )
668 /// # .expect("tr_sess_set_attributes call failed");
669 /// #
670 /// # let policy_session = PolicySession::try_from(trial_session)
671 /// # .expect("Failed to convert auth session into policy session");
672 /// #
673 /// # let nv_index = NvIndexTpmHandle::new(0x01500600)
674 /// # .expect("Failed to create NV index tpm handle");
675 /// #
676 /// # // Create NV index attributes
677 /// # let owner_nv_index_attributes = NvIndexAttributes::builder()
678 /// # .with_owner_write(true)
679 /// # .with_owner_read(true)
680 /// # .build()
681 /// # .expect("Failed to create owner nv index attributes");
682 /// #
683 /// # // Create owner nv public.
684 /// # let owner_nv_public = NvPublic::builder()
685 /// # .with_nv_index(nv_index)
686 /// # .with_index_name_algorithm(HashingAlgorithm::Sha256)
687 /// # .with_index_attributes(owner_nv_index_attributes)
688 /// # .with_data_area_size(32)
689 /// # .build()
690 /// # .expect("Failed to build NvPublic for owner");
691 /// #
692 /// let nv_index_handle = context
693 /// .nv_define_space(Provision::Owner, None, owner_nv_public)
694 /// .expect("Call to nv_define_space failed");
695 ///
696 /// context.policy_authorize_nv(
697 /// policy_session,
698 /// NvAuth::Owner,
699 /// nv_index_handle,
700 /// ).expect("failed to extend policy with policy_authorize_nv");;
701 /// #
702 /// # context
703 /// # .nv_undefine_space(Provision::Owner, nv_index_handle)
704 /// # .expect("Call to nv_undefine_space failed");
705 /// ```
706 pub fn policy_authorize_nv(
707 &mut self,
708 policy_session: PolicySession,
709 auth_handle: NvAuth,
710 nv_index_handle: NvIndexHandle,
711 ) -> Result<()> {
712 ReturnCode::ensure_success(
713 unsafe {
714 Esys_PolicyAuthorizeNV(
715 self.mut_context(),
716 AuthHandle::from(auth_handle).into(),
717 nv_index_handle.into(),
718 SessionHandle::from(policy_session).into(),
719 self.optional_session_1(),
720 self.optional_session_2(),
721 self.optional_session_3(),
722 )
723 },
724 |ret| {
725 error!("Error when computing policy authorize NV: {:#010X}", ret);
726 },
727 )
728 }
729}