tss_esapi/attributes/
command_code.rs1use crate::{
5 constants::CommandCode,
6 tss2_esys::{TPM2_CC, TPMA_CC},
7 Error, Result, WrapperErrorKind,
8};
9use bitfield::bitfield;
10use log::error;
11use std::convert::{TryFrom, TryInto};
12
13bitfield! {
14 #[derive(Copy, Clone, Eq, PartialEq)]
19 pub struct CommandCodeAttributes(TPMA_CC);
20 impl Debug;
21 pub u16, command_index, _: 15, 0;
22 u16, _, set_command_index: 15, 0;
23 u8, reserved, set_reserved: 21, 16; pub nv, _: 22;
25 _, set_nv: 22;
26 pub extensive, _: 23;
27 _, set_extensive: 23;
28 pub flushed, _: 24;
29 _, set_flushed: 24;
30 pub u8, c_handles, _: 27, 25;
31 u8, _, set_c_handles: 27, 25;
32 pub r_handle, _: 28;
33 _, set_r_handle: 28;
34 pub is_vendor_specific, _: 29;
35 _, set_vendor_specific: 29;
36 res, set_res: 31, 30; }
38
39impl CommandCodeAttributes {
40 pub const fn builder() -> CommandCodeAttributesBuilder {
42 CommandCodeAttributesBuilder::new()
43 }
44}
45
46impl TryFrom<TPMA_CC> for CommandCodeAttributes {
47 type Error = Error;
48
49 fn try_from(tpma_cc: TPMA_CC) -> Result<Self> {
50 let command_code_attributes = CommandCodeAttributes(tpma_cc);
51 if command_code_attributes.reserved() != 0 || command_code_attributes.res() != 0 {
52 error!(
53 "Command code attributes from the TPM contained a non zero value in a resrved area"
54 );
55 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
56 }
57
58 if !command_code_attributes.is_vendor_specific() {
59 let tpm_command_code: TPM2_CC = command_code_attributes.command_index().into();
62 let _ = CommandCode::try_from(tpm_command_code)?;
63 }
64 Ok(command_code_attributes)
65 }
66}
67
68impl From<CommandCodeAttributes> for TPMA_CC {
69 fn from(command_code_attributes: CommandCodeAttributes) -> Self {
70 command_code_attributes.0
71 }
72}
73
74#[derive(Copy, Clone, Eq, PartialEq, Debug)]
76pub struct CommandCodeAttributesBuilder {
77 command_code_attributes: CommandCodeAttributes,
78}
79
80impl CommandCodeAttributesBuilder {
81 pub const fn new() -> Self {
83 CommandCodeAttributesBuilder {
84 command_code_attributes: CommandCodeAttributes(0),
85 }
86 }
87
88 pub fn with_command_index(mut self, command_index: u16) -> Self {
91 self.command_code_attributes
92 .set_command_index(command_index);
93 self
94 }
95
96 pub fn with_nv(mut self, set: bool) -> Self {
98 self.command_code_attributes.set_nv(set);
99 self
100 }
101
102 pub fn with_extensive(mut self, set: bool) -> Self {
104 self.command_code_attributes.set_extensive(set);
105 self
106 }
107
108 pub fn with_flushed(mut self, set: bool) -> Self {
110 self.command_code_attributes.set_flushed(set);
111 self
112 }
113
114 pub fn with_c_handles(mut self, value: u8) -> Self {
120 self.command_code_attributes.set_c_handles(value);
121 self
122 }
123
124 pub fn with_r_handle(mut self, set: bool) -> Self {
126 self.command_code_attributes.set_r_handle(set);
127 self
128 }
129
130 pub fn with_vendor_specific(mut self, set: bool) -> Self {
132 self.command_code_attributes.set_vendor_specific(set);
133 self
134 }
135
136 pub fn build(self) -> Result<CommandCodeAttributes> {
143 self.command_code_attributes.0.try_into()
144 }
145}
146
147impl Default for CommandCodeAttributesBuilder {
148 fn default() -> Self {
149 Self::new()
150 }
151}