1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::tss2_esys::TPMS_PCR_SELECT;
use crate::{Error, Result, WrapperErrorKind};
use enumflags2::BitFlags;
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::{From, TryFrom};
#[derive(BitFlags, Hash, Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)]
#[repr(u32)]
pub enum PcrSlot {
Slot0 = 0x0000_0001,
Slot1 = 0x0000_0002,
Slot2 = 0x0000_0004,
Slot3 = 0x0000_0008,
Slot4 = 0x0000_0010,
Slot5 = 0x0000_0020,
Slot6 = 0x0000_0040,
Slot7 = 0x0000_0080,
Slot8 = 0x0000_0100,
Slot9 = 0x0000_0200,
Slot10 = 0x0000_0400,
Slot11 = 0x0000_0800,
Slot12 = 0x0000_1000,
Slot13 = 0x0000_2000,
Slot14 = 0x0000_4000,
Slot15 = 0x0000_8000,
Slot16 = 0x0001_0000,
Slot17 = 0x0002_0000,
Slot18 = 0x0004_0000,
Slot19 = 0x0008_0000,
Slot20 = 0x0010_0000,
Slot21 = 0x0020_0000,
Slot22 = 0x0040_0000,
Slot23 = 0x0080_0000,
}
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum PcrSelectSize {
OneByte = 1,
TwoBytes = 2,
ThreeBytes = 3,
FourBytes = 4,
}
impl Default for PcrSelectSize {
fn default() -> PcrSelectSize {
PcrSelectSize::ThreeBytes
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PcrSelect {
size_of_select: PcrSelectSize,
selected_pcrs: BitFlags<PcrSlot>,
}
impl PcrSelect {
pub fn new(size_of_select: PcrSelectSize, pcr_slots: &[PcrSlot]) -> Self {
PcrSelect {
size_of_select,
selected_pcrs: pcr_slots.iter().cloned().collect(),
}
}
}
impl TryFrom<TPMS_PCR_SELECT> for PcrSelect {
type Error = Error;
fn try_from(tss_pcr_select: TPMS_PCR_SELECT) -> Result<Self> {
Ok(PcrSelect {
size_of_select: PcrSelectSize::from_u8(tss_pcr_select.sizeofSelect).ok_or_else(
|| {
error!(
"Error converting sizeofSelect to a SelectSize: Invalid value {}",
tss_pcr_select.sizeofSelect
);
Error::local_error(WrapperErrorKind::InvalidParam)
},
)?,
selected_pcrs: BitFlags::<PcrSlot>::try_from(u32::from_le_bytes(
tss_pcr_select.pcrSelect,
))
.map_err(|e| {
error!("Error parsing pcrSelect to a BitFlags<PcrSlot>: {}.", e);
Error::local_error(WrapperErrorKind::UnsupportedParam)
})?,
})
}
}
impl From<PcrSelect> for TPMS_PCR_SELECT {
fn from(pcr_select: PcrSelect) -> Self {
TPMS_PCR_SELECT {
sizeofSelect: pcr_select.size_of_select.to_u8().unwrap(),
pcrSelect: pcr_select.selected_pcrs.bits().to_le_bytes(),
}
}
}