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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use crate::{
constants::CommandCode,
tss2_esys::{TPM2_CC, TPMA_CC},
Error, Result, WrapperErrorKind,
};
use bitfield::bitfield;
use log::error;
use std::convert::{TryFrom, TryInto};
bitfield! {
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct CommandCodeAttributes(TPMA_CC);
impl Debug;
pub u16, command_index, _: 15, 0;
u16, _, set_command_index: 15, 0;
u8, reserved, set_reserved: 21, 16; pub nv, _: 22;
_, set_nv: 22;
pub extensive, _: 23;
_, set_extensive: 23;
pub flushed, _: 24;
_, set_flushed: 24;
pub u8, c_handles, _: 27, 25;
u8, _, set_c_handles: 27, 25;
pub r_handle, _: 28;
_, set_r_handle: 28;
pub is_vendor_specific, _: 29;
_, set_vendor_specific: 29;
res, set_res: 31, 30; }
impl CommandCodeAttributes {
pub const fn builder() -> CommandCodeAttributesBuilder {
CommandCodeAttributesBuilder::new()
}
}
impl TryFrom<TPMA_CC> for CommandCodeAttributes {
type Error = Error;
fn try_from(tpma_cc: TPMA_CC) -> Result<Self> {
let command_code_attributes = CommandCodeAttributes(tpma_cc);
if command_code_attributes.reserved() != 0 || command_code_attributes.res() != 0 {
error!(
"Command code attributes from the TPM contained a non zero value in a resrved area"
);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
if !command_code_attributes.is_vendor_specific() {
let tpm_command_code: TPM2_CC = command_code_attributes.command_index().into();
let _ = CommandCode::try_from(tpm_command_code)?;
}
Ok(command_code_attributes)
}
}
impl From<CommandCodeAttributes> for TPMA_CC {
fn from(command_code_attributes: CommandCodeAttributes) -> Self {
command_code_attributes.0
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct CommandCodeAttributesBuilder {
command_code_attributes: CommandCodeAttributes,
}
impl CommandCodeAttributesBuilder {
pub const fn new() -> Self {
CommandCodeAttributesBuilder {
command_code_attributes: CommandCodeAttributes(0),
}
}
pub fn with_command_index(mut self, command_index: u16) -> Self {
self.command_code_attributes
.set_command_index(command_index);
self
}
pub fn with_nv(mut self, set: bool) -> Self {
self.command_code_attributes.set_nv(set);
self
}
pub fn with_extensive(mut self, set: bool) -> Self {
self.command_code_attributes.set_extensive(set);
self
}
pub fn with_flushed(mut self, set: bool) -> Self {
self.command_code_attributes.set_flushed(set);
self
}
pub fn with_c_handles(mut self, value: u8) -> Self {
self.command_code_attributes.set_c_handles(value);
self
}
pub fn with_r_handle(mut self, set: bool) -> Self {
self.command_code_attributes.set_r_handle(set);
self
}
pub fn with_vendor_specific(mut self, set: bool) -> Self {
self.command_code_attributes.set_vendor_specific(set);
self
}
pub fn build(self) -> Result<CommandCodeAttributes> {
self.command_code_attributes.0.try_into()
}
}