tss_esapi/context/tpm_commands/integrity_collection_pcr.rs
1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4 Context, Result, ReturnCode,
5 handles::{AuthHandle, PcrHandle},
6 interface_types::algorithm::HashingAlgorithm,
7 structures::{
8 Auth, Digest, DigestList, DigestValues, Event, PcrAllocateResult, PcrSelectionList,
9 },
10 tss2_esys::{
11 Esys_PCR_Allocate, Esys_PCR_Event, Esys_PCR_Extend, Esys_PCR_Read, Esys_PCR_Reset,
12 Esys_PCR_SetAuthPolicy, Esys_PCR_SetAuthValue,
13 },
14};
15use log::error;
16use std::convert::{TryFrom, TryInto};
17use std::ptr::null_mut;
18
19impl Context {
20 /// Extends a PCR with the specified digests.
21 ///
22 /// # Arguments
23 /// * `pcr_handle`- A [PcrHandle] to the PCR slot that is to be extended.
24 /// * `digests` - The [DigestValues] with which the slot shall be extended.
25 ///
26 /// # Details
27 /// This method is used to cause an update to the indicated PCR. The digests param
28 /// contains the digests for specific algorithms that are to be used.
29 ///
30 /// # Example
31 ///
32 /// ```rust
33 /// # use tss_esapi::{
34 /// # Context, TctiNameConf,
35 /// # constants::SessionType,
36 /// # attributes::SessionAttributesBuilder,
37 /// # handles::PcrHandle,
38 /// # structures::{Digest, SymmetricDefinition},
39 /// # };
40 /// # use std::{env, str::FromStr};
41 /// # // Create context
42 /// # let mut context =
43 /// # Context::new(
44 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
45 /// # ).expect("Failed to create Context");
46 /// # // Create session for a pcr
47 /// # let pcr_session = context
48 /// # .start_auth_session(
49 /// # None,
50 /// # None,
51 /// # None,
52 /// # SessionType::Hmac,
53 /// # SymmetricDefinition::AES_256_CFB,
54 /// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
55 /// # )
56 /// # .expect("Failed to create session")
57 /// # .expect("Received invalid handle");
58 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
59 /// # .with_decrypt(true)
60 /// # .with_encrypt(true)
61 /// # .build();
62 /// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
63 /// # .expect("Failed to set attributes on session");
64 /// #
65 /// # let digest_sha1 = Digest::try_from(vec![
66 /// # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
67 /// # ])
68 /// # .expect("Failed to create sha1 Digest from data");
69 /// #
70 /// # let digest_sha256 = Digest::try_from(vec![
71 /// # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
72 /// # 24, 25, 26, 27, 28, 29, 30, 31, 32,
73 /// # ]).expect("Failed to create Sha256 Digest from data");
74 /// use std::convert::TryFrom;
75 /// use tss_esapi::{
76 /// structures::{DigestValues},
77 /// interface_types::algorithm::HashingAlgorithm,
78 /// };
79 /// // Extend both sha256 and sha1
80 /// let mut vals = DigestValues::new();
81 /// vals.set(
82 /// HashingAlgorithm::Sha1,
83 /// digest_sha1,
84 /// );
85 /// vals.set(
86 /// HashingAlgorithm::Sha256,
87 /// digest_sha256,
88 /// );
89 /// // Use pcr_session for authorization when extending
90 /// // PCR 16 with the values for the banks specified in
91 /// // vals.
92 /// context.execute_with_session(Some(pcr_session), |ctx| {
93 /// ctx.pcr_extend(PcrHandle::Pcr16, vals).expect("Call to pcr_extend failed");
94 /// });
95 /// ```
96 pub fn pcr_extend(&mut self, pcr_handle: PcrHandle, digests: DigestValues) -> Result<()> {
97 ReturnCode::ensure_success(
98 unsafe {
99 Esys_PCR_Extend(
100 self.mut_context(),
101 pcr_handle.into(),
102 self.required_session_1()?,
103 self.optional_session_2(),
104 self.optional_session_3(),
105 &digests.try_into()?,
106 )
107 },
108 |ret| {
109 error!("Error when extending PCR: {:#010X}", ret);
110 },
111 )
112 }
113
114 /// Cause an event to be recorded in a PCR.
115 ///
116 /// # Arguments
117 ///
118 /// * `pcr_handle` - A [PcrHandle] of the PCR slot to extend.
119 /// * `event_data` - An [Event] data to be extended.
120 ///
121 /// # Details
122 ///
123 /// *From the specification*
124 /// > This command is used to cause an update to the indicated PCR.
125 /// > The data in eventData is hashed using each of the implemented hash algorithms.
126 /// > For each PCR bank, pcrHandle is extended with the hash of eventData
127 /// > for that bank's algorithm.
128 ///
129 /// # Returns
130 ///
131 /// A [DigestValues] containing the digest of the event data for each implemented algorithm.
132 ///
133 /// # Example
134 ///
135 /// ```rust
136 /// # use tss_esapi::{
137 /// # Context, TctiNameConf,
138 /// # constants::SessionType,
139 /// # attributes::SessionAttributesBuilder,
140 /// # interface_types::algorithm::HashingAlgorithm,
141 /// # structures::{Event, SymmetricDefinition},
142 /// # };
143 /// # // Create context
144 /// # let mut context =
145 /// # Context::new(
146 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
147 /// # ).expect("Failed to create Context");
148 /// # // Create session for a pcr
149 /// # let pcr_session = context
150 /// # .start_auth_session(
151 /// # None,
152 /// # None,
153 /// # None,
154 /// # SessionType::Hmac,
155 /// # SymmetricDefinition::AES_256_CFB,
156 /// # HashingAlgorithm::Sha256,
157 /// # )
158 /// # .expect("Failed to create session")
159 /// # .expect("Received invalid handle");
160 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
161 /// # .with_decrypt(true)
162 /// # .with_encrypt(true)
163 /// # .build();
164 /// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
165 /// # .expect("Failed to set attributes on session");
166 /// use tss_esapi::{handles::PcrHandle, structures::MaxBuffer};
167 /// let event_data = Event::try_from(vec![1, 2, 3, 4])
168 /// .expect("Failed to create event data");
169 /// // Use pcr_session for authorization when recording the event in PCR 16.
170 /// let digests = context.execute_with_session(Some(pcr_session), |ctx| {
171 /// ctx.pcr_event(PcrHandle::Pcr16, event_data)
172 /// .expect("Call to pcr_event failed")
173 /// });
174 /// ```
175 pub fn pcr_event(&mut self, pcr_handle: PcrHandle, event_data: Event) -> Result<DigestValues> {
176 let mut digests_ptr = null_mut();
177 ReturnCode::ensure_success(
178 unsafe {
179 Esys_PCR_Event(
180 self.mut_context(),
181 pcr_handle.into(),
182 self.required_session_1()?,
183 self.optional_session_2(),
184 self.optional_session_3(),
185 &event_data.into(),
186 &mut digests_ptr,
187 )
188 },
189 |ret| {
190 error!("Error when performing PCR event: {:#010X}", ret);
191 },
192 )?;
193 let digests = Context::ffi_data_to_owned(digests_ptr)?;
194 let mut digest_values = DigestValues::new();
195 for i in 0..digests.count as usize {
196 let tpmt_ha = digests.digests[i];
197 let algorithm = HashingAlgorithm::try_from(tpmt_ha.hashAlg)?;
198 let digest = match algorithm {
199 HashingAlgorithm::Sha1 => Digest::from(unsafe { tpmt_ha.digest.sha1 }),
200 HashingAlgorithm::Sha256 => Digest::from(unsafe { tpmt_ha.digest.sha256 }),
201 HashingAlgorithm::Sha384 => Digest::from(unsafe { tpmt_ha.digest.sha384 }),
202 HashingAlgorithm::Sha512 => Digest::from(unsafe { tpmt_ha.digest.sha512 }),
203 HashingAlgorithm::Sm3_256 => Digest::from(unsafe { tpmt_ha.digest.sm3_256 }),
204 _ => {
205 return Err(crate::Error::local_error(
206 crate::WrapperErrorKind::WrongValueFromTpm,
207 ));
208 }
209 };
210 digest_values.set(algorithm, digest);
211 }
212 Ok(digest_values)
213 }
214
215 /// Reads the values of a PCR.
216 ///
217 /// # Arguments
218 /// * `pcr_selection_list` - A [PcrSelectionList] that contains pcr slots in
219 /// different banks that is going to be read.
220 ///
221 /// # Details
222 /// The provided [PcrSelectionList] contains the pcr slots in the different
223 /// banks that is going to be read. It is possible to select more pcr slots
224 /// then what will fit in the returned result so the method returns a [PcrSelectionList]
225 /// that indicates what values were read. The values that were read are returned
226 /// in a [DigestList].
227 ///
228 /// # Errors
229 /// * Several different errors can occur if conversion of return
230 /// data fails.
231 ///
232 /// # Example
233 ///
234 /// ```rust
235 /// # use tss_esapi::{Context, TctiNameConf};
236 /// # use std::{env, str::FromStr};
237 /// # // Create context
238 /// # let mut context =
239 /// # Context::new(
240 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
241 /// # ).expect("Failed to create Context");
242 /// use tss_esapi::{
243 /// interface_types::algorithm::HashingAlgorithm,
244 /// structures::{PcrSelectionListBuilder, PcrSlot},
245 /// };
246 /// // Create PCR selection list with slots in a bank
247 /// // that is going to be read.
248 /// let pcr_selection_list = PcrSelectionListBuilder::new()
249 /// .with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot0, PcrSlot::Slot1])
250 /// .build()
251 /// .expect("Failed to build PcrSelectionList");
252 ///
253 /// let (update_counter, read_pcr_list, digest_list) = context.pcr_read(pcr_selection_list)
254 /// .expect("Call to pcr_read failed");
255 /// ```
256 pub fn pcr_read(
257 &mut self,
258 pcr_selection_list: PcrSelectionList,
259 ) -> Result<(u32, PcrSelectionList, DigestList)> {
260 let mut pcr_update_counter: u32 = 0;
261 let mut pcr_selection_out_ptr = null_mut();
262 let mut pcr_values_ptr = null_mut();
263 ReturnCode::ensure_success(
264 unsafe {
265 Esys_PCR_Read(
266 self.mut_context(),
267 self.optional_session_1(),
268 self.optional_session_2(),
269 self.optional_session_3(),
270 &pcr_selection_list.into(),
271 &mut pcr_update_counter,
272 &mut pcr_selection_out_ptr,
273 &mut pcr_values_ptr,
274 )
275 },
276 |ret| {
277 error!("Error when reading PCR: {:#010X}", ret);
278 },
279 )?;
280
281 Ok((
282 pcr_update_counter,
283 PcrSelectionList::try_from(Context::ffi_data_to_owned(pcr_selection_out_ptr)?)?,
284 DigestList::try_from(Context::ffi_data_to_owned(pcr_values_ptr)?)?,
285 ))
286 }
287
288 /// Allocate PCR banks.
289 ///
290 /// # Arguments
291 ///
292 /// * `auth_handle` - An [AuthHandle] for the platform hierarchy.
293 /// * `pcr_allocation` - A [PcrSelectionList] specifying the requested PCR allocation.
294 ///
295 /// # Details
296 ///
297 /// *From the specification*
298 /// > This command is used to set the desired PCR allocation of PCR and algorithms.
299 ///
300 /// # Returns
301 ///
302 /// A [PcrAllocateResult] consisting of:
303 /// * `allocation_success` - Whether the allocation was successful.
304 /// * `max_pcr` - Maximum number of PCR that may be in a bank.
305 /// * `size_needed` - Number of octets required to satisfy the request.
306 /// * `size_available` - Number of octets available (maximum size of NV).
307 ///
308 /// # Example
309 ///
310 /// ```rust
311 /// # use tss_esapi::{
312 /// # Context, TctiNameConf,
313 /// # constants::SessionType,
314 /// # attributes::SessionAttributesBuilder,
315 /// # interface_types::algorithm::HashingAlgorithm,
316 /// # structures::SymmetricDefinition,
317 /// # };
318 /// # // Create context
319 /// # let mut context =
320 /// # Context::new(
321 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
322 /// # ).expect("Failed to create Context");
323 /// # // Create session for the platform hierarchy
324 /// # let session = context
325 /// # .start_auth_session(
326 /// # None,
327 /// # None,
328 /// # None,
329 /// # SessionType::Hmac,
330 /// # SymmetricDefinition::AES_256_CFB,
331 /// # HashingAlgorithm::Sha256,
332 /// # )
333 /// # .expect("Failed to create session")
334 /// # .expect("Received invalid handle");
335 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
336 /// # .with_decrypt(true)
337 /// # .with_encrypt(true)
338 /// # .build();
339 /// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
340 /// # .expect("Failed to set attributes on session");
341 /// use tss_esapi::{
342 /// handles::AuthHandle,
343 /// structures::{PcrSelectionListBuilder, PcrSlot},
344 /// };
345 /// let pcr_allocation = PcrSelectionListBuilder::new()
346 /// .with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot0, PcrSlot::Slot1])
347 /// .build()
348 /// .expect("Failed to build PcrSelectionList");
349 /// // The platform hierarchy must authorize the allocation.
350 /// let result = context
351 /// .execute_with_session(Some(session), |ctx| {
352 /// ctx.pcr_allocate(AuthHandle::Platform, pcr_allocation)
353 /// .expect("Call to pcr_allocate failed")
354 /// });
355 /// ```
356 pub fn pcr_allocate(
357 &mut self,
358 auth_handle: AuthHandle,
359 pcr_allocation: PcrSelectionList,
360 ) -> Result<PcrAllocateResult> {
361 let mut allocation_success: u8 = 0;
362 let mut max_pcr: u32 = 0;
363 let mut size_needed: u32 = 0;
364 let mut size_available: u32 = 0;
365 ReturnCode::ensure_success(
366 unsafe {
367 Esys_PCR_Allocate(
368 self.mut_context(),
369 auth_handle.into(),
370 self.required_session_1()?,
371 self.optional_session_2(),
372 self.optional_session_3(),
373 &pcr_allocation.into(),
374 &mut allocation_success,
375 &mut max_pcr,
376 &mut size_needed,
377 &mut size_available,
378 )
379 },
380 |ret| {
381 error!("Error when allocating PCR: {:#010X}", ret);
382 },
383 )?;
384 Ok(PcrAllocateResult {
385 allocation_success: (allocation_success != 0).into(),
386 max_pcr,
387 size_needed,
388 size_available,
389 })
390 }
391
392 /// Set the authorization policy for a PCR.
393 ///
394 /// # Arguments
395 ///
396 /// * `auth_handle` - An [AuthHandle] for the platform hierarchy.
397 /// * `auth_policy` - A [Digest] representing the authorization policy.
398 /// * `hash_algorithm` - The [HashingAlgorithm] of the policy.
399 /// * `pcr_handle` - A [PcrHandle] of the PCR to set the policy for.
400 ///
401 /// # Details
402 ///
403 /// *From the specification*
404 /// > This command is used to associate a policy with a PCR or group of PCR.
405 ///
406 /// # Example
407 ///
408 /// <!--
409 /// This example is marked `no_run` because `PCR_SetAuthPolicy` succeeds only
410 /// for PCRs that the TPM platform configuration assigns to a PolicyAuth group.
411 /// swtpm/libtpms assigns no PCRs to such a group.
412 /// Reference: https://github.com/stefanberger/libtpms/blob/521c51073fe6f7c56023db78e56961fcaf7906e8/src/tpm2/TPMCmd/Platform/src/PlatformPcr.c
413 /// -->
414 ///
415 /// ```rust, no_run
416 /// # use tss_esapi::{
417 /// # Context, TctiNameConf,
418 /// # constants::SessionType,
419 /// # attributes::SessionAttributesBuilder,
420 /// # interface_types::algorithm::HashingAlgorithm,
421 /// # structures::SymmetricDefinition,
422 /// # };
423 /// # // Create context
424 /// # let mut context =
425 /// # Context::new(
426 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
427 /// # ).expect("Failed to create Context");
428 /// # // Create session for the platform hierarchy
429 /// # let session = context
430 /// # .start_auth_session(
431 /// # None,
432 /// # None,
433 /// # None,
434 /// # SessionType::Hmac,
435 /// # SymmetricDefinition::AES_256_CFB,
436 /// # HashingAlgorithm::Sha256,
437 /// # )
438 /// # .expect("Failed to create session")
439 /// # .expect("Received invalid handle");
440 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
441 /// # .with_decrypt(true)
442 /// # .with_encrypt(true)
443 /// # .build();
444 /// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
445 /// # .expect("Failed to set attributes on session");
446 /// use tss_esapi::{
447 /// handles::{AuthHandle, PcrHandle},
448 /// structures::Digest,
449 /// };
450 /// context.execute_with_session(Some(session), |ctx| {
451 /// ctx.pcr_set_auth_policy(
452 /// AuthHandle::Platform,
453 /// Digest::default(),
454 /// HashingAlgorithm::Null,
455 /// PcrHandle::Pcr16,
456 /// )
457 /// .expect("Call to pcr_set_auth_policy failed")
458 /// });
459 /// ```
460 pub fn pcr_set_auth_policy(
461 &mut self,
462 auth_handle: AuthHandle,
463 auth_policy: Digest,
464 hash_algorithm: HashingAlgorithm,
465 pcr_handle: PcrHandle,
466 ) -> Result<()> {
467 ReturnCode::ensure_success(
468 unsafe {
469 Esys_PCR_SetAuthPolicy(
470 self.mut_context(),
471 auth_handle.into(),
472 self.required_session_1()?,
473 self.optional_session_2(),
474 self.optional_session_3(),
475 &auth_policy.into(),
476 hash_algorithm.into(),
477 pcr_handle.into(),
478 )
479 },
480 |ret| {
481 error!("Error when setting PCR auth policy: {:#010X}", ret);
482 },
483 )
484 }
485
486 /// Set the authorization value for a PCR.
487 ///
488 /// # Arguments
489 ///
490 /// * `pcr_handle` - A [PcrHandle] of the PCR to set the auth value for.
491 /// * `auth` - An [Auth] value for the PCR.
492 ///
493 /// # Details
494 ///
495 /// *From the specification*
496 /// > This command changes the authValue of a PCR or group of PCR.
497 ///
498 /// # Example
499 ///
500 /// <!--
501 /// This example is marked `no_run` because `PCR_SetAuthValue` succeeds only
502 /// for PCRs that the TPM platform configuration assigns to an AuthValue group.
503 /// swtpm/libtpms assigns no PCRs to such a group.
504 /// Reference: https://github.com/stefanberger/libtpms/blob/521c51073fe6f7c56023db78e56961fcaf7906e8/src/tpm2/TPMCmd/Platform/src/PlatformPcr.c
505 /// -->
506 ///
507 /// ```rust, no_run
508 /// # use tss_esapi::{
509 /// # Context, TctiNameConf,
510 /// # constants::SessionType,
511 /// # attributes::SessionAttributesBuilder,
512 /// # interface_types::algorithm::HashingAlgorithm,
513 /// # structures::SymmetricDefinition,
514 /// # };
515 /// # // Create context
516 /// # let mut context =
517 /// # Context::new(
518 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
519 /// # ).expect("Failed to create Context");
520 /// # // Create session for a pcr
521 /// # let session = context
522 /// # .start_auth_session(
523 /// # None,
524 /// # None,
525 /// # None,
526 /// # SessionType::Hmac,
527 /// # SymmetricDefinition::AES_256_CFB,
528 /// # HashingAlgorithm::Sha256,
529 /// # )
530 /// # .expect("Failed to create session")
531 /// # .expect("Received invalid handle");
532 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
533 /// # .with_decrypt(true)
534 /// # .with_encrypt(true)
535 /// # .build();
536 /// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
537 /// # .expect("Failed to set attributes on session");
538 /// use tss_esapi::{handles::PcrHandle, structures::Auth};
539 /// let auth = Auth::from_bytes(&[1, 2, 3, 4]).expect("Failed to create Auth");
540 /// context.execute_with_session(Some(session), |ctx| {
541 /// ctx.pcr_set_auth_value(PcrHandle::Pcr16, auth)
542 /// .expect("Call to pcr_set_auth_value failed")
543 /// });
544 /// ```
545 pub fn pcr_set_auth_value(&mut self, pcr_handle: PcrHandle, auth: Auth) -> Result<()> {
546 ReturnCode::ensure_success(
547 unsafe {
548 Esys_PCR_SetAuthValue(
549 self.mut_context(),
550 pcr_handle.into(),
551 self.required_session_1()?,
552 self.optional_session_2(),
553 self.optional_session_3(),
554 &auth.into(),
555 )
556 },
557 |ret| {
558 error!("Error when setting PCR auth value: {:#010X}", ret);
559 },
560 )
561 }
562
563 /// Resets the value in a PCR.
564 ///
565 /// # Arguments
566 /// * `pcr_handle` - A [PcrHandle] to the PCR slot that is to be reset.
567 ///
568 /// # Details
569 /// If the attributes of the PCR indicates that it is allowed
570 /// to reset them and the proper authorization is provided then
571 /// this method can be used to set the the specified PCR in all
572 /// banks to 0.
573 ///
574 /// # Example
575 ///
576 /// ```rust
577 /// # use tss_esapi::{
578 /// # Context, TctiNameConf,
579 /// # constants::SessionType,
580 /// # attributes::SessionAttributesBuilder,
581 /// # structures::SymmetricDefinition,
582 /// # interface_types::algorithm::HashingAlgorithm,
583 /// # };
584 /// # use std::{env, str::FromStr};
585 /// # // Create context
586 /// # let mut context =
587 /// # Context::new(
588 /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
589 /// # ).expect("Failed to create Context");
590 /// # // Create session for a pcr
591 /// # let pcr_session = context
592 /// # .start_auth_session(
593 /// # None,
594 /// # None,
595 /// # None,
596 /// # SessionType::Hmac,
597 /// # SymmetricDefinition::AES_256_CFB,
598 /// # HashingAlgorithm::Sha256,
599 /// # )
600 /// # .expect("Failed to create session")
601 /// # .expect("Received invalid handle");
602 /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
603 /// # .with_decrypt(true)
604 /// # .with_encrypt(true)
605 /// # .build();
606 /// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
607 /// # .expect("Failed to set attributes on session");
608 ///
609 /// use tss_esapi::{
610 /// handles::PcrHandle
611 /// };
612 /// context.execute_with_session(Some(pcr_session), |ctx| {
613 /// ctx.pcr_reset(PcrHandle::Pcr16).expect("Call to pcr_reset failed");
614 /// });
615 /// ```
616 pub fn pcr_reset(&mut self, pcr_handle: PcrHandle) -> Result<()> {
617 ReturnCode::ensure_success(
618 unsafe {
619 Esys_PCR_Reset(
620 self.mut_context(),
621 pcr_handle.into(),
622 self.required_session_1()?,
623 self.optional_session_2(),
624 self.optional_session_3(),
625 )
626 },
627 |ret| {
628 error!("Error when resetting PCR: {:#010X}", ret);
629 },
630 )
631 }
632}