tss_esapi/abstraction/pcr/
data.rs1use crate::{
5 abstraction::pcr::PcrBank,
6 interface_types::algorithm::HashingAlgorithm,
7 structures::{Digest, DigestList, PcrSelectionList},
8 tss2_esys::TPML_DIGEST,
9 Error, Result, WrapperErrorKind,
10};
11use log::error;
12#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct PcrData {
16 data: Vec<(HashingAlgorithm, PcrBank)>,
17}
18
19impl PcrData {
20 pub const fn new() -> Self {
22 PcrData { data: Vec::new() }
23 }
24
25 pub fn create(
27 pcr_selection_list: &PcrSelectionList,
28 digest_list: &DigestList,
29 ) -> Result<PcrData> {
30 Ok(PcrData {
31 data: Self::create_data(pcr_selection_list, digest_list.value().to_vec())?,
32 })
33 }
34
35 pub fn add(
37 &mut self,
38 pcr_selection_list: &PcrSelectionList,
39 digest_list: &DigestList,
40 ) -> Result<()> {
41 Self::create_data(pcr_selection_list, digest_list.value().to_vec())?
42 .drain(..)
43 .try_for_each(|(hashing_algorithm, pcr_bank)| {
44 if let Some(existing_pcr_bank) = self.pcr_bank_mut(hashing_algorithm) {
45 existing_pcr_bank.try_extend(pcr_bank)?;
46 } else {
47 self.data.push((hashing_algorithm, pcr_bank));
48 }
49 Ok(())
50 })
51 }
52
53 fn create_data(
56 pcr_selection_list: &PcrSelectionList,
57 mut digests: Vec<Digest>,
58 ) -> Result<Vec<(HashingAlgorithm, PcrBank)>> {
59 pcr_selection_list
60 .get_selections()
61 .iter()
62 .map(|pcr_selection| {
63 let pcr_slots = pcr_selection.selected();
64 if pcr_slots.len() > digests.len() {
65 error!("More pcr slots in selection then available digests");
66 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
67 }
68 let digests_in_bank = digests.drain(..pcr_slots.len()).collect();
69 Ok((
70 pcr_selection.hashing_algorithm(),
71 PcrBank::create(pcr_slots, digests_in_bank)?,
72 ))
73 })
74 .collect()
75 }
76
77 pub fn pcr_bank(&self, hashing_algorithm: HashingAlgorithm) -> Option<&PcrBank> {
79 self.data
80 .iter()
81 .find(|(alg, _)| *alg == hashing_algorithm)
82 .map(|(_, bank)| bank)
83 }
84
85 pub fn len(&self) -> usize {
87 self.data.len()
88 }
89
90 pub fn is_empty(&self) -> bool {
92 self.data.is_empty()
93 }
94
95 fn pcr_bank_mut(&mut self, hashing_algorithm: HashingAlgorithm) -> Option<&mut PcrBank> {
97 self.data
98 .iter_mut()
99 .find(|(alg, _)| *alg == hashing_algorithm)
100 .map(|(_, bank)| bank)
101 }
102}
103
104impl Default for PcrData {
105 fn default() -> Self {
106 Self::new()
107 }
108}
109
110impl IntoIterator for PcrData {
111 type Item = (HashingAlgorithm, PcrBank);
112 type IntoIter = ::std::vec::IntoIter<(HashingAlgorithm, PcrBank)>;
113
114 fn into_iter(self) -> Self::IntoIter {
115 self.data.into_iter()
116 }
117}
118
119impl From<PcrData> for Vec<TPML_DIGEST> {
120 fn from(pcr_data: PcrData) -> Self {
121 pcr_data
122 .data
123 .iter()
124 .flat_map(|(_, pcr_bank)| pcr_bank.into_iter())
125 .map(|(_, digest)| digest)
126 .collect::<Vec<&Digest>>()
127 .chunks(DigestList::MAX_SIZE)
128 .map(|digests| {
129 let mut tpml_digest: TPML_DIGEST = Default::default();
130 for (index, digest) in digests.iter().enumerate() {
131 tpml_digest.count += 1;
132 tpml_digest.digests[index].size = digest.len() as u16;
133 tpml_digest.digests[index].buffer[..digest.len()]
134 .copy_from_slice(digest.value());
135 }
136 tpml_digest
137 })
138 .collect()
139 }
140}