Skip to content

Commit 5845840

Browse files
authored
Merge pull request #243 from ionut-arm/fix-pcr-selection
Ensure PcrSelectionList retains order, #2
2 parents 2eadba4 + 382ce82 commit 5845840

File tree

4 files changed

+99
-247
lines changed

4 files changed

+99
-247
lines changed

tss-esapi/src/structures/lists/pcr_selection.rs

Lines changed: 10 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::convert::TryFrom;
1111
/// corresponds to the TSS TPML_PCR_SELECTION.
1212
#[derive(Debug, Clone, PartialEq, Eq)]
1313
pub struct PcrSelectionList {
14-
items: HashMap<HashingAlgorithm, PcrSelection>,
14+
items: Vec<PcrSelection>,
1515
}
1616

1717
impl PcrSelectionList {
@@ -26,94 +26,23 @@ impl PcrSelectionList {
2626
self.items.is_empty()
2727
}
2828

29+
/// Gets the selections
30+
pub fn get_selections(&self) -> &[PcrSelection] {
31+
&self.items
32+
}
33+
2934
/// Function for retrieving the PcrSelectionList from Option<PcrSelectionList>
3035
///
3136
/// This returns an empty list if None is passed
3237
pub fn list_from_option(pcr_list: Option<PcrSelectionList>) -> PcrSelectionList {
3338
pcr_list.unwrap_or_else(|| PcrSelectionListBuilder::new().build())
3439
}
35-
36-
/// Removes items in `other` from `self.
37-
///
38-
/// # Arguments
39-
///
40-
/// * `other` - A PcrSelectionList containing items
41-
/// that will be removed from `self`.
42-
///
43-
///
44-
/// # Constraints
45-
///
46-
/// * Cannot be called with `other` that contains items that
47-
/// are not present in `self`.
48-
///
49-
/// * Cannot be called with `other` that contains pcr selection
50-
/// associated with a hashing algorithm that cannot be subtracted
51-
/// from the pcr selection associated with the same hashing algorithm
52-
/// in `self`.
53-
///
54-
/// # Errors
55-
///
56-
/// * Calling the method with `other` that contains items
57-
/// not present in `self` will result in an InvalidParam error.
58-
///
59-
///
60-
/// # Examples
61-
/// ```
62-
/// use tss_esapi::structures::{PcrSelectionListBuilder, PcrSlot};
63-
/// use tss_esapi::interface_types::algorithm::HashingAlgorithm;
64-
/// // pcr selections
65-
/// let mut pcr_selection_list = PcrSelectionListBuilder::new()
66-
/// .with_size_of_select(Default::default())
67-
/// .with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot0, PcrSlot::Slot8])
68-
/// .build();
69-
///
70-
/// // Another pcr selections
71-
/// let other = PcrSelectionListBuilder::new()
72-
/// .with_size_of_select(Default::default())
73-
/// .with_selection(
74-
/// HashingAlgorithm::Sha256, &[PcrSlot::Slot0],
75-
/// )
76-
/// .build();
77-
/// pcr_selection_list.subtract(&other).unwrap();
78-
/// assert_eq!(pcr_selection_list.len(), 1);
79-
/// ```
80-
pub fn subtract(&mut self, other: &Self) -> Result<()> {
81-
if self == other {
82-
self.items.clear();
83-
return Ok(());
84-
}
85-
86-
if self.is_empty() {
87-
error!("Error: Trying to remove item that did not exist");
88-
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
89-
}
90-
91-
for hashing_algorithm in other.items.keys() {
92-
// Lookup selection in self.
93-
let pcr_selection = match self.items.get_mut(hashing_algorithm) {
94-
Some(val) => val,
95-
None => {
96-
error!("Error: Trying to remove item that did not exist");
97-
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
98-
}
99-
};
100-
// Check if value exists in other and if not then nothing needs to be done
101-
if let Some(val) = other.items.get(hashing_algorithm) {
102-
pcr_selection.subtract(val)?;
103-
104-
if pcr_selection.is_empty() {
105-
let _ = self.items.remove(hashing_algorithm);
106-
}
107-
}
108-
}
109-
Ok(())
110-
}
11140
}
11241

11342
impl From<PcrSelectionList> for TPML_PCR_SELECTION {
11443
fn from(pcr_selections: PcrSelectionList) -> TPML_PCR_SELECTION {
11544
let mut tss_pcr_selection_list: TPML_PCR_SELECTION = Default::default();
116-
for (_, pcr_selection) in pcr_selections.items {
45+
for pcr_selection in pcr_selections.items {
11746
tss_pcr_selection_list.pcrSelections[tss_pcr_selection_list.count as usize] =
11847
pcr_selection.into();
11948
tss_pcr_selection_list.count += 1;
@@ -137,23 +66,12 @@ impl TryFrom<TPML_PCR_SELECTION> for PcrSelectionList {
13766
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
13867
}
13968

140-
let mut items = HashMap::<HashingAlgorithm, PcrSelection>::new();
69+
let mut items = Vec::<PcrSelection>::with_capacity(size);
14170
// Loop over available selections
14271
for tpms_pcr_selection in tpml_pcr_selection.pcrSelections[..size].iter() {
14372
// Parse pcr selection.
14473
let parsed_pcr_selection = PcrSelection::try_from(*tpms_pcr_selection)?;
145-
// Insert the selection into the storage. Or merge with an existing.
146-
match items.get_mut(&parsed_pcr_selection.hashing_algorithm()) {
147-
Some(previously_parsed_pcr_selection) => {
148-
previously_parsed_pcr_selection.merge(&parsed_pcr_selection)?;
149-
}
150-
None => {
151-
let _ = items.insert(
152-
parsed_pcr_selection.hashing_algorithm(),
153-
parsed_pcr_selection,
154-
);
155-
}
156-
}
74+
items.push(parsed_pcr_selection);
15775
}
15876
Ok(PcrSelectionList { items })
15977
}
@@ -222,7 +140,7 @@ impl PcrSelectionListBuilder {
222140
items: self
223141
.items
224142
.iter()
225-
.map(|(k, v)| (*k, PcrSelection::new(*k, size_of_select, v.as_slice())))
143+
.map(|(k, v)| PcrSelection::new(*k, size_of_select, v.as_slice()))
226144
.collect(),
227145
}
228146
}

tss-esapi/src/structures/pcr/selection.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ impl PcrSelection {
3535
self.hashing_algorithm
3636
}
3737

38+
pub fn selected_pcrs(&self) -> &BitFlags<PcrSlot> {
39+
&self.selected_pcrs
40+
}
41+
3842
pub fn merge(&mut self, other: &Self) -> Result<()> {
3943
// Check that the hashing algorithm match
4044
if self.hashing_algorithm != other.hashing_algorithm {

tss-esapi/src/utils/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,6 @@ impl PublicIdUnion {
524524
/// Rust enum representation of `TPMU_PUBLIC_PARMS`.
525525
// Most of the field types are from bindgen which does not implement Debug on them.
526526
#[allow(missing_debug_implementations)]
527-
#[allow(clippy::pub_enum_variant_names)]
528527
#[derive(Copy, Clone)]
529528
pub enum PublicParmsUnion {
530529
KeyedHashDetail(KeyedHashParameters),

0 commit comments

Comments
 (0)