Skip to main content

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    handles::PcrHandle,
5    structures::{DigestList, DigestValues, PcrSelectionList},
6    tss2_esys::{Esys_PCR_Extend, Esys_PCR_Read, Esys_PCR_Reset},
7    Context, Error, Result,
8};
9use log::error;
10use std::convert::{TryFrom, TryInto};
11use std::ptr::null_mut;
12
13impl Context {
14    /// Extends a PCR with the specified digests.
15    ///
16    /// # Arguments
17    /// * `pcr_handle`- A [PcrHandle] to the PCR slot that is to be extended.
18    /// * `digests` - The [DigestValues] with which the slot shall be extended.
19    ///
20    /// # Details
21    /// This method is used to cause an update to the indicated PCR. The digests param
22    /// contains the digests for specific algorithms that are to be used.
23    ///
24    /// # Example
25    ///
26    /// ```rust
27    /// # use tss_esapi::{
28    /// #     Context, TctiNameConf,
29    /// #     constants::SessionType,
30    /// #     attributes::SessionAttributesBuilder,
31    /// #     handles::PcrHandle,
32    /// #     structures::{Digest, SymmetricDefinition},
33    /// # };
34    /// # use std::{env, str::FromStr};
35    /// # // Create context
36    /// # let mut context =
37    /// #     Context::new(
38    /// #         TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
39    /// #     ).expect("Failed to create Context");
40    /// # // Create session for a pcr
41    /// # let pcr_session = context
42    /// #     .start_auth_session(
43    /// #         None,
44    /// #         None,
45    /// #         None,
46    /// #         SessionType::Hmac,
47    /// #         SymmetricDefinition::AES_256_CFB,
48    /// #         tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
49    /// #     )
50    /// #     .expect("Failed to create session")
51    /// #     .expect("Received invalid handle");
52    /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
53    /// #     .with_decrypt(true)
54    /// #     .with_encrypt(true)
55    /// #     .build();
56    /// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
57    /// #     .expect("Failed to set attributes on session");
58    /// #
59    /// # let digest_sha1 = Digest::try_from(vec![
60    /// #       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
61    /// #   ])
62    /// #   .expect("Failed to create sha1 Digest from data");
63    /// #
64    /// # let digest_sha256 = Digest::try_from(vec![
65    /// #        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
66    /// #        24, 25, 26, 27, 28, 29, 30, 31, 32,
67    /// #    ]).expect("Failed to create Sha256 Digest from data");
68    /// use std::convert::TryFrom;
69    /// use tss_esapi::{
70    ///     structures::{DigestValues},
71    ///     interface_types::algorithm::HashingAlgorithm,
72    /// };
73    /// // Extend both sha256 and sha1
74    /// let mut vals = DigestValues::new();
75    /// vals.set(
76    ///     HashingAlgorithm::Sha1,
77    ///     digest_sha1,
78    /// );
79    /// vals.set(
80    ///     HashingAlgorithm::Sha256,
81    ///     digest_sha256,
82    /// );
83    /// // Use pcr_session for authorization when extending
84    /// // PCR 16 with the values for the banks specified in
85    /// // vals.
86    /// context.execute_with_session(Some(pcr_session), |ctx| {
87    ///     ctx.pcr_extend(PcrHandle::Pcr16, vals).expect("Call to pcr_extend failed");
88    /// });
89    /// ```
90    pub fn pcr_extend(&mut self, pcr_handle: PcrHandle, digests: DigestValues) -> Result<()> {
91        let ret = unsafe {
92            Esys_PCR_Extend(
93                self.mut_context(),
94                pcr_handle.into(),
95                self.optional_session_1(),
96                self.optional_session_2(),
97                self.optional_session_3(),
98                &digests.try_into()?,
99            )
100        };
101        let ret = Error::from_tss_rc(ret);
102
103        if ret.is_success() {
104            Ok(())
105        } else {
106            error!("Error when extending PCR: {}", ret);
107            Err(ret)
108        }
109    }
110
111    // Missing function: PCR_Event
112
113    /// Reads the values of a PCR.
114    ///
115    /// # Arguments
116    /// * `pcr_selection_list` - A [PcrSelectionList] that contains pcr slots in
117    ///   different banks that is going to be read.
118    ///
119    /// # Details
120    /// The provided [PcrSelectionList] contains the pcr slots in the different
121    /// banks that is going to be read. It is possible to select more pcr slots
122    /// then what will fit in the returned result so the method returns a [PcrSelectionList]
123    /// that indicates what values were read. The values that were read are returned
124    /// in a [DigestList].
125    ///
126    /// # Errors
127    /// * Several different errors can occur if conversion of return
128    ///   data fails.
129    ///
130    /// # Example
131    ///
132    /// ```rust
133    /// # use tss_esapi::{Context, TctiNameConf};
134    /// # use std::{env, str::FromStr};
135    /// # // Create context
136    /// # let mut context =
137    /// #     Context::new(
138    /// #         TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
139    /// #     ).expect("Failed to create Context");
140    /// use tss_esapi::{
141    ///     interface_types::algorithm::HashingAlgorithm,
142    ///     structures::{PcrSelectionListBuilder, PcrSlot},
143    /// };
144    /// // Create PCR selection list with slots in a bank
145    /// // that is going to be read.
146    /// let pcr_selection_list = PcrSelectionListBuilder::new()
147    ///     .with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot0, PcrSlot::Slot1])
148    ///     .build()
149    ///     .expect("Failed to build PcrSelectionList");
150    ///
151    /// let (update_counter, read_pcr_list, digest_list) = context.pcr_read(pcr_selection_list)
152    ///     .expect("Call to pcr_read failed");
153    /// ```
154    pub fn pcr_read(
155        &mut self,
156        pcr_selection_list: PcrSelectionList,
157    ) -> Result<(u32, PcrSelectionList, DigestList)> {
158        let mut pcr_update_counter: u32 = 0;
159        let mut pcr_selection_out_ptr = null_mut();
160        let mut pcr_values_ptr = null_mut();
161        let ret = unsafe {
162            Esys_PCR_Read(
163                self.mut_context(),
164                self.optional_session_1(),
165                self.optional_session_2(),
166                self.optional_session_3(),
167                &pcr_selection_list.into(),
168                &mut pcr_update_counter,
169                &mut pcr_selection_out_ptr,
170                &mut pcr_values_ptr,
171            )
172        };
173        let ret = Error::from_tss_rc(ret);
174
175        if ret.is_success() {
176            Ok((
177                pcr_update_counter,
178                PcrSelectionList::try_from(Context::ffi_data_to_owned(pcr_selection_out_ptr))?,
179                DigestList::try_from(Context::ffi_data_to_owned(pcr_values_ptr))?,
180            ))
181        } else {
182            error!("Error when reading PCR: {}", ret);
183            Err(ret)
184        }
185    }
186
187    // Missing function: PCR_Allocate
188    // Missing function: PCR_SetAuthPolicy
189    // Missing function: PCR_SetAuthValue
190
191    /// Resets the value in a PCR.
192    ///
193    /// # Arguments
194    /// * `pcr_handle` -  A [PcrHandle] to the PCR slot that is to be reset.
195    ///
196    /// # Details
197    /// If the attributes of the PCR indicates that it is allowed
198    /// to reset them and the proper authorization is provided then
199    /// this method can be used to set the the specified PCR in all
200    /// banks to 0.
201    ///
202    /// # Example
203    ///
204    /// ```rust
205    /// # use tss_esapi::{
206    /// #     Context, TctiNameConf,
207    /// #     constants::SessionType,
208    /// #     attributes::SessionAttributesBuilder,
209    /// #     structures::SymmetricDefinition,
210    /// #     interface_types::algorithm::HashingAlgorithm,
211    /// # };
212    /// # use std::{env, str::FromStr};
213    /// # // Create context
214    /// # let mut context =
215    /// #     Context::new(
216    /// #         TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
217    /// #     ).expect("Failed to create Context");
218    /// # // Create session for a pcr
219    /// # let pcr_session = context
220    /// #     .start_auth_session(
221    /// #         None,
222    /// #         None,
223    /// #         None,
224    /// #         SessionType::Hmac,
225    /// #         SymmetricDefinition::AES_256_CFB,
226    /// #         HashingAlgorithm::Sha256,
227    /// #     )
228    /// #     .expect("Failed to create session")
229    /// #     .expect("Received invalid handle");
230    /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
231    /// #     .with_decrypt(true)
232    /// #     .with_encrypt(true)
233    /// #     .build();
234    /// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
235    /// #     .expect("Failed to set attributes on session");
236    ///
237    /// use tss_esapi::{
238    ///      handles::PcrHandle
239    /// };
240    /// context.execute_with_session(Some(pcr_session), |ctx| {
241    ///     ctx.pcr_reset(PcrHandle::Pcr16).expect("Call to pcr_reset failed");
242    /// });
243    /// ```
244    pub fn pcr_reset(&mut self, pcr_handle: PcrHandle) -> Result<()> {
245        let ret = unsafe {
246            Esys_PCR_Reset(
247                self.mut_context(),
248                pcr_handle.into(),
249                self.optional_session_1(),
250                self.optional_session_2(),
251                self.optional_session_3(),
252            )
253        };
254        let ret = Error::from_tss_rc(ret);
255
256        if ret.is_success() {
257            Ok(())
258        } else {
259            error!("Error when resetting PCR: {}", ret);
260            Err(ret)
261        }
262    }
263
264    // Missing function: _TPM_Hash_Start
265    // Missing function: _TPM_Hash_Data
266    // Missing function: _TPM_Hash_End
267}