optee_utee/
error.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#[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
25/// A specialized [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html)
26/// type for TEE operations.
27///
28/// # Examples
29///
30/// ``` rust,no_run
31/// # use optee_utee::Parameters;
32/// use optee_utee::Result;
33/// fn open_session(params: &mut Parameters) -> Result<()> {
34///     Ok(())
35/// }
36/// ````
37pub type Result<T> = result::Result<T, Error>;
38
39#[derive(Clone)]
40pub struct Error {
41    kind: ErrorKind,
42    origin: Option<ErrorOrigin>,
43}
44
45/// A list specifying general categories of TEE error and its corresponding code
46/// in OP-TEE OS.
47#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
48#[repr(u32)]
49pub enum ErrorKind {
50    /// Object corruption.
51    CorruptObject = raw::TEE_ERROR_CORRUPT_OBJECT,
52    /// Persistent object corruption.
53    CorruptObject2 = raw::TEE_ERROR_CORRUPT_OBJECT_2,
54    /// Object storage is not available.
55    StorageNotAvailable = raw::TEE_ERROR_STORAGE_NOT_AVAILABLE,
56    /// Persistent object storage is not available.
57    StorageNotAvailable2 = raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2,
58    /// Non-specific cause.
59    Generic = raw::TEE_ERROR_GENERIC,
60    /// Access privileges are not sufficient.
61    AccessDenied = raw::TEE_ERROR_ACCESS_DENIED,
62    /// The operation was canceled.
63    Cancel = raw::TEE_ERROR_CANCEL,
64    /// Concurrent accesses caused conflict.
65    AccessConflict = raw::TEE_ERROR_ACCESS_CONFLICT,
66    /// Too much data for the requested operation was passed.
67    ExcessData = raw::TEE_ERROR_EXCESS_DATA,
68    /// Input data was of invalid format.
69    BadFormat = raw::TEE_ERROR_BAD_FORMAT,
70    /// Input parameters were invalid.
71    BadParameters = raw::TEE_ERROR_BAD_PARAMETERS,
72    /// Operation is not valid in the current state.
73    BadState = raw::TEE_ERROR_BAD_STATE,
74    /// The requested data item is not found.
75    ItemNotFound = raw::TEE_ERROR_ITEM_NOT_FOUND,
76    /// The requested operation should exist but is not yet implemented.
77    NotImplemented = raw::TEE_ERROR_NOT_IMPLEMENTED,
78    /// The requested operation is valid but is not supported in this implementation.
79    NotSupported = raw::TEE_ERROR_NOT_SUPPORTED,
80    /// Expected data was missing.
81    NoData = raw::TEE_ERROR_NO_DATA,
82    /// System ran out of resources.
83    OutOfMemory = raw::TEE_ERROR_OUT_OF_MEMORY,
84    /// The system is busy working on something else.
85    Busy = raw::TEE_ERROR_BUSY,
86    /// Communication with a remote party failed.
87    Communication = raw::TEE_ERROR_COMMUNICATION,
88    /// A security fault was detected.
89    Security = raw::TEE_ERROR_SECURITY,
90    /// The supplied buffer is too short for the generated output.
91    ShortBuffer = raw::TEE_ERROR_SHORT_BUFFER,
92    /// The operation has been cancelled by an external event which occurred in
93    /// the REE while the function was in progress.
94    ExternalCancel = raw::TEE_ERROR_EXTERNAL_CANCEL,
95    /// Data overflow.
96    Overflow = raw::TEE_ERROR_OVERFLOW,
97    /// Trusted Application has panicked during the operation.
98    TargetDead = raw::TEE_ERROR_TARGET_DEAD,
99    /// Insufficient space is available.
100    StorageNoSpace = raw::TEE_ERROR_STORAGE_NO_SPACE,
101    /// MAC is invalid.
102    MacInvalid = raw::TEE_ERROR_MAC_INVALID,
103    /// Signature is invalid.
104    SignatureInvalid = raw::TEE_ERROR_SIGNATURE_INVALID,
105    /// The persistent time has not been set.
106    TimeNotSet = raw::TEE_ERROR_TIME_NOT_SET,
107    /// The persistent time has been set but may have been corrupted and SHALL
108    /// no longer be trusted.
109    TimeNeedsReset = raw::TEE_ERROR_TIME_NEEDS_RESET,
110    /// Unknown error.
111    #[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    /// Creates a new instance of an `Error` from a particular TEE error code.
207    ///
208    /// # Examples
209    ///
210    /// ``` no_run
211    /// use optee_utee;
212    ///
213    /// let error = optee_utee::Error::from_raw_error(0xFFFF000F);
214    /// assert_eq!(error.kind(), optee_utee::ErrorKind::Security);
215    /// ```
216    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    /// Returns the corresponding `ErrorKind` for this error.
229    ///
230    /// # Examples
231    ///
232    /// ``` no_run
233    /// use optee_utee;
234    ///
235    /// let error = optee_utee::Error::new(optee_utee::ErrorKind::Security);
236    /// ```
237    pub fn kind(&self) -> ErrorKind {
238        self.kind
239    }
240
241    /// Returns the origin of this error.
242    pub fn origin(&self) -> Option<ErrorOrigin> {
243        self.origin.clone()
244    }
245
246    /// Returns raw code of this error.
247    pub fn raw_code(&self) -> u32 {
248        self.kind.into()
249    }
250
251    /// Returns corresponding error message of this error.
252    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}