1mod base;
5mod esapi;
6mod fapi;
7mod muapi;
8mod sapi;
9mod tcti;
10mod tpm;
11
12use crate::{
13 constants::{return_code::ReturnCodeLayer, tss::TSS2_RC_SUCCESS},
14 tss2_esys::TSS2_RC,
15 Error, Result,
16};
17pub use base::BaseReturnCode;
18use bitfield::bitfield;
19pub use esapi::EsapiReturnCode;
20pub use fapi::FapiReturnCode;
21pub use muapi::MuapiReturnCode;
22pub use sapi::SapiReturnCode;
23use std::convert::TryFrom;
24pub use tcti::TctiReturnCode;
25pub use tpm::{
26 ArgumentNumber, TpmFormatOneResponseCode, TpmFormatZeroErrorResponseCode,
27 TpmFormatZeroResponseCode, TpmFormatZeroWarningResponseCode, TpmResponseCode,
28};
29
30#[derive(Debug, Copy, Clone, PartialEq, Eq)]
33pub enum ReturnCode {
34 Tpm(TpmResponseCode),
35 Fapi(FapiReturnCode),
36 Esapi(EsapiReturnCode),
37 Sapi(SapiReturnCode),
38 Mu(MuapiReturnCode),
39 Tcti(TctiReturnCode),
40 ResourceManager(BaseReturnCode),
41 TpmResourceManager(TpmResponseCode),
42}
43
44impl ReturnCode {
45 pub(crate) fn ensure_success<F>(tss2_rc: TSS2_RC, f: F) -> Result<()>
54 where
55 F: FnOnce(TSS2_RC),
56 {
57 if ReturnCodeStructure(tss2_rc).is_success() {
58 Ok(())
59 } else {
60 f(tss2_rc);
61 Err(Error::tss_error(ReturnCode::try_from(tss2_rc)?))
62 }
63 }
64}
65
66impl TryFrom<TSS2_RC> for ReturnCode {
67 type Error = Error;
68 fn try_from(tss2_rc: TSS2_RC) -> Result<Self> {
69 let structure = ReturnCodeStructure(tss2_rc);
70 match structure.return_code_layer()? {
71 ReturnCodeLayer::Tpm => {
72 TpmResponseCode::try_from(structure.return_code_data()).map(ReturnCode::Tpm)
73 }
74 ReturnCodeLayer::Feature => {
75 FapiReturnCode::try_from(structure.return_code_data()).map(ReturnCode::Fapi)
76 }
77 ReturnCodeLayer::Esys => {
78 EsapiReturnCode::try_from(structure.return_code_data()).map(ReturnCode::Esapi)
79 }
80 ReturnCodeLayer::Sys => {
81 SapiReturnCode::try_from(structure.return_code_data()).map(ReturnCode::Sapi)
82 }
83 ReturnCodeLayer::Mu => {
84 MuapiReturnCode::try_from(structure.return_code_data()).map(ReturnCode::Mu)
85 }
86 ReturnCodeLayer::Tcti => {
87 TctiReturnCode::try_from(structure.return_code_data()).map(ReturnCode::Tcti)
88 }
89 ReturnCodeLayer::ResMgr => BaseReturnCode::try_from(structure.return_code_data())
90 .map(ReturnCode::ResourceManager),
91 ReturnCodeLayer::ResMgrTpm => TpmResponseCode::try_from(structure.return_code_data())
92 .map(ReturnCode::TpmResourceManager),
93 }
94 }
95}
96
97impl From<ReturnCode> for TSS2_RC {
98 fn from(return_code: ReturnCode) -> Self {
99 let mut return_code_structure = ReturnCodeStructure(0);
100 match return_code {
101 ReturnCode::Tpm(rc) => {
102 return_code_structure.set_layer_data(ReturnCodeLayer::Tpm.into());
103 return_code_structure.set_return_code_data(rc.into());
104 }
105 ReturnCode::Fapi(rc) => {
106 return_code_structure.set_layer_data(ReturnCodeLayer::Feature.into());
107 return_code_structure.set_return_code_data(rc.into());
108 }
109 ReturnCode::Esapi(rc) => {
110 return_code_structure.set_layer_data(ReturnCodeLayer::Esys.into());
111 return_code_structure.set_return_code_data(rc.into());
112 }
113 ReturnCode::Sapi(rc) => {
114 return_code_structure.set_layer_data(ReturnCodeLayer::Sys.into());
115 return_code_structure.set_return_code_data(rc.into());
116 }
117 ReturnCode::Mu(rc) => {
118 return_code_structure.set_layer_data(ReturnCodeLayer::Mu.into());
119 return_code_structure.set_return_code_data(rc.into());
120 }
121 ReturnCode::Tcti(rc) => {
122 return_code_structure.set_layer_data(ReturnCodeLayer::Tcti.into());
123 return_code_structure.set_return_code_data(rc.into());
124 }
125 ReturnCode::ResourceManager(rc) => {
126 return_code_structure.set_layer_data(ReturnCodeLayer::ResMgr.into());
127 return_code_structure.set_return_code_data(rc.into());
128 }
129 ReturnCode::TpmResourceManager(rc) => {
130 return_code_structure.set_layer_data(ReturnCodeLayer::ResMgrTpm.into());
131 return_code_structure.set_return_code_data(rc.into());
132 }
133 }
134 return_code_structure.0
135 }
136}
137
138impl std::error::Error for ReturnCode {
139 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
140 match self {
141 ReturnCode::Tpm(rc) => Some(rc),
142 ReturnCode::Fapi(rc) => Some(rc),
143 ReturnCode::Esapi(rc) => Some(rc),
144 ReturnCode::Sapi(rc) => Some(rc),
145 ReturnCode::Mu(rc) => Some(rc),
146 ReturnCode::Tcti(rc) => Some(rc),
147 ReturnCode::ResourceManager(rc) => Some(rc),
148 ReturnCode::TpmResourceManager(rc) => Some(rc),
149 }
150 }
151}
152
153impl std::fmt::Display for ReturnCode {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 match self {
156 ReturnCode::Tpm(e) => write!(
157 f,
158 "TSS Layer: TPM, Code: 0x{:08X}, Message: {}",
159 TSS2_RC::from(*self),
160 e
161 ),
162 ReturnCode::Fapi(e) => write!(
163 f,
164 "TSS Layer: FAPI, Code: 0x{:08X}, Message: {}",
165 TSS2_RC::from(*self),
166 e
167 ),
168 ReturnCode::Esapi(e) => write!(
169 f,
170 "TSS Layer: ESAPI, Code: 0x{:08X}, Message: {}",
171 TSS2_RC::from(*self),
172 e
173 ),
174 ReturnCode::Sapi(e) => write!(
175 f,
176 "TSS Layer: SAPI, Code: 0x{:08X}, Message: {}",
177 TSS2_RC::from(*self),
178 e
179 ),
180 ReturnCode::Mu(e) => write!(
181 f,
182 "TSS Layer: MUAPI, Code: 0x{:08X}, Message: {}",
183 TSS2_RC::from(*self),
184 e
185 ),
186 ReturnCode::Tcti(e) => write!(
187 f,
188 "TSS Layer: TCTI, Code: 0x{:08X}, Message: {}",
189 TSS2_RC::from(*self),
190 e
191 ),
192 ReturnCode::ResourceManager(e) => write!(
193 f,
194 "TSS Layer: RESOURCE MANAGER, Code: 0x{:08X}, Message: {}",
195 TSS2_RC::from(*self),
196 e
197 ),
198 ReturnCode::TpmResourceManager(e) => {
199 write!(
200 f,
201 "TSS Layer: TPM RESOURCE MANAGER, Code: 0x{:08X}, Message: {}",
202 TSS2_RC::from(*self),
203 e
204 )
205 }
206 }
207 }
208}
209
210bitfield! {
211 #[derive(PartialEq, Copy, Clone)]
213 struct ReturnCodeStructure(TSS2_RC);
214 impl Debug;
215 u8, layer_data, set_layer_data: 23, 16;
216 u16, return_code_data, set_return_code_data: 15, 0;
217}
218
219impl ReturnCodeStructure {
220 fn return_code_layer(&self) -> Result<ReturnCodeLayer> {
226 ReturnCodeLayer::try_from(self.layer_data())
227 }
228
229 const fn is_success(&self) -> bool {
231 self.0 == TSS2_RC_SUCCESS
232 }
233}