1#[cfg(not(feature = "std"))]
19use core::error;
20use core::{fmt, result};
21use optee_utee_sys as raw;
22#[cfg(feature = "std")]
23use std::error;
24
25pub type Result<T> = result::Result<T, Error>;
38
39#[derive(Clone)]
40pub struct Error {
41 kind: ErrorKind,
42 origin: Option<ErrorOrigin>,
43}
44
45#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
48#[repr(u32)]
49pub enum ErrorKind {
50 CorruptObject = raw::TEE_ERROR_CORRUPT_OBJECT,
52 CorruptObject2 = raw::TEE_ERROR_CORRUPT_OBJECT_2,
54 StorageNotAvailable = raw::TEE_ERROR_STORAGE_NOT_AVAILABLE,
56 StorageNotAvailable2 = raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2,
58 Generic = raw::TEE_ERROR_GENERIC,
60 AccessDenied = raw::TEE_ERROR_ACCESS_DENIED,
62 Cancel = raw::TEE_ERROR_CANCEL,
64 AccessConflict = raw::TEE_ERROR_ACCESS_CONFLICT,
66 ExcessData = raw::TEE_ERROR_EXCESS_DATA,
68 BadFormat = raw::TEE_ERROR_BAD_FORMAT,
70 BadParameters = raw::TEE_ERROR_BAD_PARAMETERS,
72 BadState = raw::TEE_ERROR_BAD_STATE,
74 ItemNotFound = raw::TEE_ERROR_ITEM_NOT_FOUND,
76 NotImplemented = raw::TEE_ERROR_NOT_IMPLEMENTED,
78 NotSupported = raw::TEE_ERROR_NOT_SUPPORTED,
80 NoData = raw::TEE_ERROR_NO_DATA,
82 OutOfMemory = raw::TEE_ERROR_OUT_OF_MEMORY,
84 Busy = raw::TEE_ERROR_BUSY,
86 Communication = raw::TEE_ERROR_COMMUNICATION,
88 Security = raw::TEE_ERROR_SECURITY,
90 ShortBuffer = raw::TEE_ERROR_SHORT_BUFFER,
92 ExternalCancel = raw::TEE_ERROR_EXTERNAL_CANCEL,
95 Overflow = raw::TEE_ERROR_OVERFLOW,
97 TargetDead = raw::TEE_ERROR_TARGET_DEAD,
99 StorageNoSpace = raw::TEE_ERROR_STORAGE_NO_SPACE,
101 MacInvalid = raw::TEE_ERROR_MAC_INVALID,
103 SignatureInvalid = raw::TEE_ERROR_SIGNATURE_INVALID,
105 TimeNotSet = raw::TEE_ERROR_TIME_NOT_SET,
107 TimeNeedsReset = raw::TEE_ERROR_TIME_NEEDS_RESET,
110 #[default]
112 Unknown,
113}
114
115impl ErrorKind {
116 pub(crate) fn as_str(&self) -> &'static str {
117 match *self {
118 ErrorKind::CorruptObject => "Object corruption.",
119 ErrorKind::CorruptObject2 => "Persistent object corruption.",
120 ErrorKind::StorageNotAvailable => "Object storage is not available.",
121 ErrorKind::StorageNotAvailable2 => "Persistent object storage is not available.",
122 ErrorKind::Generic => "Non-specific cause.",
123 ErrorKind::AccessDenied => "Access privileges are not sufficient.",
124 ErrorKind::Cancel => "The operation was canceled.",
125 ErrorKind::AccessConflict => "Concurrent accesses caused conflict.",
126 ErrorKind::ExcessData => "Too much data for the requested operation was passed.",
127 ErrorKind::BadFormat => "Input data was of invalid format.",
128 ErrorKind::BadParameters => "Input parameters were invalid.",
129 ErrorKind::BadState => "Operation is not valid in the current state.",
130 ErrorKind::ItemNotFound => "The requested data item is not found.",
131 ErrorKind::NotImplemented => {
132 "The requested operation should exist but is not yet implemented."
133 }
134 ErrorKind::NotSupported => {
135 "The requested operation is valid but is not supported in this implementation."
136 }
137 ErrorKind::NoData => "Expected data was missing.",
138 ErrorKind::OutOfMemory => "System ran out of resources.",
139 ErrorKind::Busy => "The system is busy working on something else.",
140 ErrorKind::Communication => "Communication with a remote party failed.",
141 ErrorKind::Security => "A security fault was detected.",
142 ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.",
143 ErrorKind::ExternalCancel => "Undocumented.",
144 ErrorKind::Overflow => "Data overflow.",
145 ErrorKind::TargetDead => "Trusted Application has panicked during the operation.",
146 ErrorKind::StorageNoSpace => "Insufficient space is available.",
147 ErrorKind::MacInvalid => "MAC is invalid.",
148 ErrorKind::SignatureInvalid => "Signature is invalid.",
149 ErrorKind::TimeNotSet => "The persistent time has not been set.",
150 ErrorKind::TimeNeedsReset => {
151 "The persistent time has been set but may have been corrupted and SHALL no longer be trusted."
152 }
153 ErrorKind::Unknown => "Unknown error.",
154 }
155 }
156}
157
158impl From<ErrorKind> for u32 {
159 fn from(kind: ErrorKind) -> u32 {
160 kind as u32
161 }
162}
163
164impl From<u32> for ErrorKind {
165 fn from(code: u32) -> ErrorKind {
166 match code {
167 raw::TEE_ERROR_CORRUPT_OBJECT => ErrorKind::CorruptObject,
168 raw::TEE_ERROR_CORRUPT_OBJECT_2 => ErrorKind::CorruptObject2,
169 raw::TEE_ERROR_STORAGE_NOT_AVAILABLE => ErrorKind::StorageNotAvailable,
170 raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2 => ErrorKind::StorageNotAvailable2,
171 raw::TEE_ERROR_GENERIC => ErrorKind::Generic,
172 raw::TEE_ERROR_ACCESS_DENIED => ErrorKind::AccessDenied,
173 raw::TEE_ERROR_CANCEL => ErrorKind::Cancel,
174 raw::TEE_ERROR_ACCESS_CONFLICT => ErrorKind::AccessConflict,
175 raw::TEE_ERROR_EXCESS_DATA => ErrorKind::ExcessData,
176 raw::TEE_ERROR_BAD_FORMAT => ErrorKind::BadFormat,
177 raw::TEE_ERROR_BAD_PARAMETERS => ErrorKind::BadParameters,
178 raw::TEE_ERROR_BAD_STATE => ErrorKind::BadState,
179 raw::TEE_ERROR_ITEM_NOT_FOUND => ErrorKind::ItemNotFound,
180 raw::TEE_ERROR_NOT_IMPLEMENTED => ErrorKind::NotImplemented,
181 raw::TEE_ERROR_NOT_SUPPORTED => ErrorKind::NotSupported,
182 raw::TEE_ERROR_NO_DATA => ErrorKind::NoData,
183 raw::TEE_ERROR_OUT_OF_MEMORY => ErrorKind::OutOfMemory,
184 raw::TEE_ERROR_BUSY => ErrorKind::Busy,
185 raw::TEE_ERROR_COMMUNICATION => ErrorKind::Communication,
186 raw::TEE_ERROR_SECURITY => ErrorKind::Security,
187 raw::TEE_ERROR_SHORT_BUFFER => ErrorKind::ShortBuffer,
188 raw::TEE_ERROR_EXTERNAL_CANCEL => ErrorKind::ExternalCancel,
189 raw::TEE_ERROR_OVERFLOW => ErrorKind::Overflow,
190 raw::TEE_ERROR_TARGET_DEAD => ErrorKind::TargetDead,
191 raw::TEE_ERROR_STORAGE_NO_SPACE => ErrorKind::StorageNoSpace,
192 raw::TEE_ERROR_MAC_INVALID => ErrorKind::MacInvalid,
193 raw::TEE_ERROR_SIGNATURE_INVALID => ErrorKind::SignatureInvalid,
194 raw::TEE_ERROR_TIME_NOT_SET => ErrorKind::TimeNotSet,
195 raw::TEE_ERROR_TIME_NEEDS_RESET => ErrorKind::TimeNeedsReset,
196 _ => ErrorKind::Unknown,
197 }
198 }
199}
200
201impl Error {
202 pub fn new(kind: ErrorKind) -> Error {
203 Error { kind, origin: None }
204 }
205
206 pub fn from_raw_error(code: u32) -> Error {
217 Error {
218 kind: ErrorKind::from(code),
219 origin: None,
220 }
221 }
222
223 pub fn with_origin(mut self, origin: ErrorOrigin) -> Self {
224 self.origin = Some(origin);
225 self
226 }
227
228 pub fn kind(&self) -> ErrorKind {
238 self.kind
239 }
240
241 pub fn origin(&self) -> Option<ErrorOrigin> {
243 self.origin.clone()
244 }
245
246 pub fn raw_code(&self) -> u32 {
248 self.kind.into()
249 }
250
251 pub fn message(&self) -> &str {
253 self.kind().as_str()
254 }
255}
256
257impl fmt::Debug for Error {
258 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
259 write!(
260 fmt,
261 "{} (error code 0x{:x}, origin 0x{:x})",
262 self.message(),
263 self.raw_code(),
264 self.origin().map(|v| v.into()).unwrap_or(0_u32),
265 )
266 }
267}
268
269impl fmt::Display for Error {
270 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271 fmt::Debug::fmt(self, f)
272 }
273}
274
275impl error::Error for Error {
276 fn description(&self) -> &str {
277 self.message()
278 }
279}
280
281impl From<ErrorKind> for Error {
282 #[inline]
283 fn from(kind: ErrorKind) -> Error {
284 Error { kind, origin: None }
285 }
286}
287
288#[derive(Clone, Debug, Default, Eq, PartialEq)]
289#[repr(u32)]
290pub enum ErrorOrigin {
291 Api = raw::TEE_ORIGIN_API,
292 Comms = raw::TEE_ORIGIN_COMMS,
293 Tee = raw::TEE_ORIGIN_TEE,
294 Ta = raw::TEE_ORIGIN_TRUSTED_APP,
295 #[default]
296 Unknown,
297}
298
299impl From<ErrorOrigin> for u32 {
300 fn from(origin: ErrorOrigin) -> u32 {
301 origin as u32
302 }
303}
304
305impl From<u32> for ErrorOrigin {
306 fn from(code: u32) -> ErrorOrigin {
307 match code {
308 raw::TEE_ORIGIN_API => ErrorOrigin::Api,
309 raw::TEE_ORIGIN_COMMS => ErrorOrigin::Comms,
310 raw::TEE_ORIGIN_TEE => ErrorOrigin::Tee,
311 raw::TEE_ORIGIN_TRUSTED_APP => ErrorOrigin::Ta,
312 _ => ErrorOrigin::Unknown,
313 }
314 }
315}