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 use optee_utee_sys as raw;
19 use std::convert::From;
20 use std::fmt;
21 
22 /// A specialized [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html)
23 /// type for TEE operations.
24 ///
25 /// # Examples
26 ///
27 /// ``` no_run
28 /// fn open_session(params: &mut Parameters) -> Result<()> {
29 ///     Ok(())
30 /// }
31 /// ````
32 pub type Result<T> = std::result::Result<T, Error>;
33 
34 pub struct Error {
35     code: u32,
36 }
37 
38 /// A list specifying general categories of TEE error and its corresponding code
39 /// in OP-TEE OS.
40 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
41 #[repr(u32)]
42 pub enum ErrorKind {
43     /// Object corruption.
44     CorruptObject = 0xF0100001,
45     /// Persistent object corruption.
46     CorruptObject2 = 0xF0100002,
47     /// Object storage is not available.
48     StorageNotAvailable = 0xF0100003,
49     /// Persistent object storage is not available.
50     StorageNotAvailable2 = 0xF0100004,
51     /// Non-specific cause.
52     Generic = 0xFFFF0000,
53     /// Access privileges are not sufficient.
54     AccessDenied = 0xFFFF0001,
55     /// The operation was canceled.
56     Cancel = 0xFFFF0002,
57     /// Concurrent accesses caused conflict.
58     AccessConflict = 0xFFFF0003,
59     /// Too much data for the requested operation was passed.
60     ExcessData = 0xFFFF0004,
61     /// Input data was of invalid format.
62     BadFormat = 0xFFFF0005,
63     /// Input parameters were invalid.
64     BadParameters = 0xFFFF0006,
65     /// Operation is not valid in the current state.
66     BadState = 0xFFFF0007,
67     /// The requested data item is not found.
68     ItemNotFound = 0xFFFF0008,
69     /// The requested operation should exist but is not yet implemented.
70     NotImplemented = 0xFFFF0009,
71     /// The requested operation is valid but is not supported in this implementation.
72     NotSupported = 0xFFFF000A,
73     /// Expected data was missing.
74     NoData = 0xFFFF000B,
75     /// System ran out of resources.
76     OutOfMemory = 0xFFFF000C,
77     /// The system is busy working on something else.
78     Busy = 0xFFFF000D,
79     /// Communication with a remote party failed.
80     Communication = 0xFFFF000E,
81     /// A security fault was detected.
82     Security = 0xFFFF000F,
83     /// The supplied buffer is too short for the generated output.
84     ShortBuffer = 0xFFFF0010,
85     /// The operation has been cancelled by an external event which occurred in
86     /// the REE while the function was in progress.
87     ExternalCancel = 0xFFFF0011,
88     /// Data overflow.
89     Overflow = 0xFFFF300F,
90     /// Trusted Application has panicked during the operation.
91     TargetDead = 0xFFFF3024,
92     /// Insufficient space is available.
93     StorageNoSpace = 0xFFFF3041,
94     /// MAC is invalid.
95     MacInvalid = 0xFFFF3071,
96     /// Signature is invalid.
97     SignatureInvalid = 0xFFFF3072,
98     /// The persistent time has not been set.
99     TimeNotSet = 0xFFFF5000,
100     /// The persistent time has been set but may have been corrupted and SHALL
101     /// no longer be trusted.
102     TimeNeedsReset = 0xFFFF5001,
103     /// Unknown error.
104     Unknown,
105 }
106 
107 impl ErrorKind {
as_str(&self) -> &'static str108     pub(crate) fn as_str(&self) -> &'static str {
109         match *self {
110             ErrorKind::CorruptObject => "Object corruption.",
111             ErrorKind::CorruptObject2 => "Persistent object corruption.",
112             ErrorKind::StorageNotAvailable => "Object storage is not available.",
113             ErrorKind::StorageNotAvailable2 => "Persistent object storage is not available.",
114             ErrorKind::Generic => "Non-specific cause.",
115             ErrorKind::AccessDenied => "Access privileges are not sufficient.",
116             ErrorKind::Cancel => "The operation was canceled.",
117             ErrorKind::AccessConflict => "Concurrent accesses caused conflict.",
118             ErrorKind::ExcessData => "Too much data for the requested operation was passed.",
119             ErrorKind::BadFormat => "Input data was of invalid format.",
120             ErrorKind::BadParameters => "Input parameters were invalid.",
121             ErrorKind::BadState => "Operation is not valid in the current state.",
122             ErrorKind::ItemNotFound => "The requested data item is not found.",
123             ErrorKind::NotImplemented => {
124                 "The requested operation should exist but is not yet implemented."
125             }
126             ErrorKind::NotSupported => {
127                 "The requested operation is valid but is not supported in this implementation."
128             }
129             ErrorKind::NoData => "Expected data was missing.",
130             ErrorKind::OutOfMemory => "System ran out of resources.",
131             ErrorKind::Busy => "The system is busy working on something else.",
132             ErrorKind::Communication => "Communication with a remote party failed.",
133             ErrorKind::Security => "A security fault was detected.",
134             ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.",
135             ErrorKind::ExternalCancel => "Undocumented.",
136             ErrorKind::Overflow => "Data overflow.",
137             ErrorKind::TargetDead => "Trusted Application has panicked during the operation.",
138             ErrorKind::StorageNoSpace => "Insufficient space is available.",
139             ErrorKind::MacInvalid => "MAC is invalid.",
140             ErrorKind::SignatureInvalid => "Signature is invalid.",
141             ErrorKind::TimeNotSet => "The persistent time has not been set.",
142             ErrorKind::TimeNeedsReset => {
143                 "The persistent time has been set but may have been corrupted and SHALL no longer be trusted."
144             },
145             ErrorKind::Unknown => "Unknown error.",
146         }
147     }
148 }
149 
150 impl Error {
new(kind: ErrorKind) -> Error151     pub fn new(kind: ErrorKind) -> Error {
152         Error { code: kind as u32 }
153     }
154 
155     /// Creates a new instance of an `Error` from a particular TEE error code.
156     ///
157     /// # Examples
158     ///
159     /// ``` no_run
160     /// use optee_utee;
161     ///
162     /// let error = optee_utee::Error::from_raw_error(0xFFFF000F);
163     /// assert_eq!(error.kind(), optee_utee::ErrorKind::Security);
164     /// ```
from_raw_error(code: u32) -> Error165     pub fn from_raw_error(code: u32) -> Error {
166         Error { code }
167     }
168 
169     /// Returns the corresponding `ErrorKind` for this error.
170     ///
171     /// # Examples
172     ///
173     /// ``` no_run
174     /// use optee_utee;
175     ///
176     /// let error = optee_utee::Error::new(optee_utee::ErrorKind::Security);
177     /// ```
kind(&self) -> ErrorKind178     pub fn kind(&self) -> ErrorKind {
179         match self.code {
180             raw::TEE_ERROR_CORRUPT_OBJECT => ErrorKind::CorruptObject,
181             raw::TEE_ERROR_CORRUPT_OBJECT_2 => ErrorKind::CorruptObject2,
182             raw::TEE_ERROR_STORAGE_NOT_AVAILABLE => ErrorKind::StorageNotAvailable,
183             raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2 => ErrorKind::StorageNotAvailable2,
184             raw::TEE_ERROR_GENERIC => ErrorKind::Generic,
185             raw::TEE_ERROR_ACCESS_DENIED => ErrorKind::AccessDenied,
186             raw::TEE_ERROR_CANCEL => ErrorKind::Cancel,
187             raw::TEE_ERROR_ACCESS_CONFLICT => ErrorKind::AccessConflict,
188             raw::TEE_ERROR_EXCESS_DATA => ErrorKind::ExcessData,
189             raw::TEE_ERROR_BAD_FORMAT => ErrorKind::BadFormat,
190             raw::TEE_ERROR_BAD_PARAMETERS => ErrorKind::BadParameters,
191             raw::TEE_ERROR_BAD_STATE => ErrorKind::BadState,
192             raw::TEE_ERROR_ITEM_NOT_FOUND => ErrorKind::ItemNotFound,
193             raw::TEE_ERROR_NOT_IMPLEMENTED => ErrorKind::NotImplemented,
194             raw::TEE_ERROR_NOT_SUPPORTED => ErrorKind::NotSupported,
195             raw::TEE_ERROR_NO_DATA => ErrorKind::NoData,
196             raw::TEE_ERROR_OUT_OF_MEMORY => ErrorKind::OutOfMemory,
197             raw::TEE_ERROR_BUSY => ErrorKind::Busy,
198             raw::TEE_ERROR_COMMUNICATION => ErrorKind::Communication,
199             raw::TEE_ERROR_SECURITY => ErrorKind::Security,
200             raw::TEE_ERROR_SHORT_BUFFER => ErrorKind::ShortBuffer,
201             raw::TEE_ERROR_EXTERNAL_CANCEL => ErrorKind::ExternalCancel,
202             raw::TEE_ERROR_OVERFLOW => ErrorKind::Overflow,
203             raw::TEE_ERROR_TARGET_DEAD => ErrorKind::TargetDead,
204             raw::TEE_ERROR_STORAGE_NO_SPACE => ErrorKind::StorageNoSpace,
205             raw::TEE_ERROR_MAC_INVALID => ErrorKind::MacInvalid,
206             raw::TEE_ERROR_SIGNATURE_INVALID => ErrorKind::SignatureInvalid,
207             raw::TEE_ERROR_TIME_NOT_SET => ErrorKind::TimeNotSet,
208             raw::TEE_ERROR_TIME_NEEDS_RESET => ErrorKind::TimeNeedsReset,
209             _ => ErrorKind::Unknown,
210         }
211     }
212 
raw_code(&self) -> u32213     pub fn raw_code(&self) -> u32 {
214         self.code
215     }
216 
message(&self) -> &str217     pub fn message(&self) -> &str {
218         self.kind().as_str()
219     }
220 }
221 
222 impl fmt::Debug for Error {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result223     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
224         write!(fmt, "{} (error code 0x{:x})", self.message(), self.code)
225     }
226 }
227 
228 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result229     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
230         write!(fmt, "{} (error code 0x{:x})", self.message(), self.code)
231     }
232 }
233 
234 impl std::error::Error for Error {
description(&self) -> &str235     fn description(&self) -> &str {
236         self.message()
237     }
238 }
239 
240 impl From<ErrorKind> for Error {
241     #[inline]
from(kind: ErrorKind) -> Error242     fn from(kind: ErrorKind) -> Error {
243         Error { code: kind as u32 }
244     }
245 }
246