Skip to main content

tss_esapi/structures/lists/
algorithm_property.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    Error, Result, WrapperErrorKind,
6    constants::AlgorithmIdentifier,
7    structures::AlgorithmProperty,
8    tss2_esys::{TPML_ALG_PROPERTY, TPMS_ALG_PROPERTY},
9};
10use log::error;
11use std::{convert::TryFrom, iter::IntoIterator, ops::Deref};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct AlgorithmPropertyList {
15    algorithm_properties: Vec<AlgorithmProperty>,
16}
17
18impl AlgorithmPropertyList {
19    pub const MAX_SIZE: usize = Self::calculate_max_size();
20
21    /// Finds an [AlgorithmProperty] in the list that matches
22    /// the provided ´algorithm_identifier´.
23    pub fn find(&self, algorithm_identifier: AlgorithmIdentifier) -> Option<&AlgorithmProperty> {
24        self.algorithm_properties
25            .iter()
26            .find(|ap| ap.algorithm_identifier() == algorithm_identifier)
27    }
28
29    /// Private function that calculates the maximum number
30    /// elements allowed in internal storage.
31    const fn calculate_max_size() -> usize {
32        crate::structures::capability_data::max_cap_size::<TPMS_ALG_PROPERTY>()
33    }
34}
35
36impl Deref for AlgorithmPropertyList {
37    type Target = Vec<AlgorithmProperty>;
38
39    fn deref(&self) -> &Self::Target {
40        &self.algorithm_properties
41    }
42}
43
44impl AsRef<[AlgorithmProperty]> for AlgorithmPropertyList {
45    fn as_ref(&self) -> &[AlgorithmProperty] {
46        self.algorithm_properties.as_slice()
47    }
48}
49
50impl IntoIterator for AlgorithmPropertyList {
51    type Item = AlgorithmProperty;
52    type IntoIter = std::vec::IntoIter<Self::Item>;
53
54    fn into_iter(self) -> Self::IntoIter {
55        self.algorithm_properties.into_iter()
56    }
57}
58
59impl TryFrom<Vec<AlgorithmProperty>> for AlgorithmPropertyList {
60    type Error = Error;
61
62    fn try_from(algorithm_properties: Vec<AlgorithmProperty>) -> Result<Self> {
63        if algorithm_properties.len() > Self::MAX_SIZE {
64            error!(
65                "Failed to convert Vec<AlgorithmProperty> into AlgorithmPropertyList, to many items (> {})",
66                Self::MAX_SIZE
67            );
68            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
69        }
70        Ok(AlgorithmPropertyList {
71            algorithm_properties,
72        })
73    }
74}
75
76impl From<AlgorithmPropertyList> for Vec<AlgorithmProperty> {
77    fn from(algorithm_property_list: AlgorithmPropertyList) -> Self {
78        algorithm_property_list.algorithm_properties
79    }
80}
81
82impl TryFrom<TPML_ALG_PROPERTY> for AlgorithmPropertyList {
83    type Error = Error;
84
85    fn try_from(tpml_alg_property: TPML_ALG_PROPERTY) -> Result<Self> {
86        let count = usize::try_from(tpml_alg_property.count).map_err(|e| {
87            error!("Failed to parse count in TPML_ALG_PROPERTY as usize: {}", e);
88            Error::local_error(WrapperErrorKind::InvalidParam)
89        })?;
90
91        if count > Self::MAX_SIZE {
92            error!(
93                "Invalid size value in TPML_ALG_PROPERTY (> {})",
94                Self::MAX_SIZE,
95            );
96            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
97        }
98
99        tpml_alg_property.algProperties[..count]
100            .iter()
101            .map(|&tp| AlgorithmProperty::try_from(tp))
102            .collect::<Result<Vec<AlgorithmProperty>>>()
103            .map(|algorithm_properties| AlgorithmPropertyList {
104                algorithm_properties,
105            })
106    }
107}
108
109impl From<AlgorithmPropertyList> for TPML_ALG_PROPERTY {
110    fn from(algorithm_property_list: AlgorithmPropertyList) -> Self {
111        let mut tpml_alg_property: TPML_ALG_PROPERTY = Default::default();
112        for algorithm_property in algorithm_property_list {
113            tpml_alg_property.algProperties[tpml_alg_property.count as usize] =
114                algorithm_property.into();
115            tpml_alg_property.count += 1;
116        }
117        tpml_alg_property
118    }
119}