Skip to main content

tss_esapi/structures/pcr/
select_size.rs

1// Copyright 2022 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{tss2_esys::TPM2_PCR_SELECT_MAX, Error, Result, WrapperErrorKind};
4
5use num_derive::{FromPrimitive, ToPrimitive};
6use num_traits::{FromPrimitive, ToPrimitive};
7
8use log::error;
9use std::convert::TryFrom;
10
11/// Enum with the possible values for sizeofSelect.
12#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
13#[repr(u8)]
14pub enum PcrSelectSize {
15    OneOctet = 1,
16    TwoOctets = 2,
17    ThreeOctets = 3,
18    FourOctets = 4,
19}
20
21impl PcrSelectSize {
22    /// Returns the PcrSelectSize value as u8
23    pub fn as_u8(&self) -> u8 {
24        // The value is well defined so unwrap will
25        // never cause panic.
26        self.to_u8().unwrap()
27    }
28
29    /// Returns the PcrSelectSize value as u32
30    pub fn as_u32(&self) -> u32 {
31        // The value is well defined so unwrap will
32        // never cause panic.
33        self.to_u32().unwrap()
34    }
35
36    /// Returns the PcrSelectSize value as usize
37    pub fn as_usize(&self) -> usize {
38        // The value is well defined so unwrap will
39        // never cause panic.
40        self.to_usize().unwrap()
41    }
42
43    /// Parses the u8 value as PcrSelectSize
44    pub fn try_parse_u8(value: u8) -> Result<Self> {
45        PcrSelectSize::from_u8(value).ok_or_else(|| {
46            error!(
47                "Error converting sizeofSelect to a SelectSize: Invalid value {}",
48                value
49            );
50            Error::local_error(WrapperErrorKind::InvalidParam)
51        })
52    }
53
54    /// Parses the u32 value as PcrSelectSize
55    pub fn try_parse_u32(value: u32) -> Result<Self> {
56        PcrSelectSize::from_u32(value).ok_or_else(|| {
57            error!(
58                "Error converting sizeofSelect to a SelectSize: Invalid value {}",
59                value
60            );
61            Error::local_error(WrapperErrorKind::InvalidParam)
62        })
63    }
64
65    /// Parses the usize value as PcrSelectSize
66    pub fn try_parse_usize(value: usize) -> Result<Self> {
67        PcrSelectSize::from_usize(value).ok_or_else(|| {
68            error!(
69                "Error converting sizeofSelect to a SelectSize: Invalid value {}",
70                value
71            );
72            Error::local_error(WrapperErrorKind::InvalidParam)
73        })
74    }
75}
76
77/// The default for PcrSelectSize is three octets.
78/// A value for the sizeofSelect that works
79/// on most platforms.
80impl Default for PcrSelectSize {
81    fn default() -> PcrSelectSize {
82        match TPM2_PCR_SELECT_MAX {
83            1 => PcrSelectSize::OneOctet,
84            2 => PcrSelectSize::TwoOctets,
85            _ => PcrSelectSize::ThreeOctets,
86        }
87    }
88}
89
90impl TryFrom<u8> for PcrSelectSize {
91    type Error = Error;
92
93    fn try_from(value: u8) -> Result<Self> {
94        if u32::from(value) > TPM2_PCR_SELECT_MAX {
95            error!(
96                "Found size of select value(= {}) that is larger then TPM2_PCR_SELECT_MAX(={}",
97                value, TPM2_PCR_SELECT_MAX
98            );
99            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
100        }
101
102        PcrSelectSize::try_parse_u8(value)
103    }
104}
105
106impl TryFrom<PcrSelectSize> for u8 {
107    type Error = Error;
108
109    fn try_from(pcr_select_size: PcrSelectSize) -> Result<Self> {
110        if pcr_select_size.as_u32() > TPM2_PCR_SELECT_MAX {
111            error!("The number of octets specified by PcrSelectSize value us greater then TPM2_PCR_SELECT_MAX");
112            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
113        }
114        Ok(pcr_select_size.as_u8())
115    }
116}