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_teec_sys as raw; 19 use std::fmt; 20 21 /// A specialized [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html) 22 /// type for TEE operations. 23 /// 24 /// # Examples 25 /// 26 /// ``` no_run 27 /// fn main() -> optee_teec::Result<()> { 28 /// let mut ctx = Context::new()?; 29 /// } 30 /// ```` 31 pub type Result<T> = std::result::Result<T, Error>; 32 33 /// The error type for TEE operations of [`Context`] and [`Session`]. 34 /// 35 /// [`Context`]: struct.Context.html 36 /// [`Session`]: struct.Session.html 37 pub struct Error { 38 code: u32, 39 } 40 41 /// A list specifying general categories of TEE client error and its 42 /// corresponding code in OP-TEE client library. 43 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 44 #[repr(u32)] 45 pub enum ErrorKind { 46 /// Non-specific cause. 47 Generic = 0xFFFF0000, 48 /// Access privileges are not sufficient. 49 AccessDenied = 0xFFFF0001, 50 /// The operation was canceled. 51 Cancel = 0xFFFF0002, 52 /// Concurrent accesses caused conflict. 53 AccessConflict = 0xFFFF0003, 54 /// Too much data for the requested operation was passed. 55 ExcessData = 0xFFFF0004, 56 /// Input data was of invalid format. 57 BadFormat = 0xFFFF0005, 58 /// Input parameters were invalid. 59 BadParameters = 0xFFFF0006, 60 /// Operation is not valid in the current state. 61 BadState = 0xFFFF0007, 62 /// The requested data item is not found. 63 ItemNotFound = 0xFFFF0008, 64 /// The requested operation should exist but is not yet implemented. 65 NotImplemented = 0xFFFF0009, 66 /// The requested operation is valid but is not supported in this implementation. 67 NotSupported = 0xFFFF000A, 68 /// Expected data was missing. 69 NoData = 0xFFFF000B, 70 /// System ran out of resources. 71 OutOfMEmory = 0xFFFF000C, 72 /// The system is busy working on something else. 73 Busy = 0xFFFF000D, 74 /// Communication with a remote party failed. 75 Communication = 0xFFFF000E, 76 /// A security fault was detected. 77 Security = 0xFFFF000F, 78 /// The supplied buffer is too short for the generated output. 79 ShortBuffer = 0xFFFF0010, 80 /// Implementation defined error code. 81 ExternalCancel = 0xFFFF0011, 82 /// Implementation defined error code: trusted Application has panicked during the operation. 83 TargetDead = 0xFFFF3024, 84 /// Unknown error. 85 Unknown, 86 } 87 88 impl ErrorKind { as_str(&self) -> &'static str89 pub(crate) fn as_str(&self) -> &'static str { 90 match *self { 91 ErrorKind::Generic => "Non-specific cause.", 92 ErrorKind::AccessDenied => "Access privileges are not sufficient.", 93 ErrorKind::Cancel => "The operation was canceled.", 94 ErrorKind::AccessConflict => "Concurrent accesses caused conflict.", 95 ErrorKind::ExcessData => "Too much data for the requested operation was passed.", 96 ErrorKind::BadFormat => "Input data was of invalid format.", 97 ErrorKind::BadParameters => "Input parameters were invalid.", 98 ErrorKind::BadState => "Operation is not valid in the current state.", 99 ErrorKind::ItemNotFound => "The requested data item is not found.", 100 ErrorKind::NotImplemented => { 101 "The requested operation should exist but is not yet implemented." 102 } 103 ErrorKind::NotSupported => { 104 "The requested operation is valid but is not supported in this implementation." 105 } 106 ErrorKind::NoData => "Expected data was missing.", 107 ErrorKind::OutOfMEmory => "System ran out of resources.", 108 ErrorKind::Busy => "The system is busy working on something else.", 109 ErrorKind::Communication => "Communication with a remote party failed.", 110 ErrorKind::Security => "A security fault was detected.", 111 ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.", 112 ErrorKind::ExternalCancel => "Undocumented.", 113 ErrorKind::TargetDead => "Trusted Application has panicked during the operation.", 114 ErrorKind::Unknown => "Unknown error.", 115 } 116 } 117 } 118 119 impl Error { new(kind: ErrorKind) -> Error120 pub fn new(kind: ErrorKind) -> Error { 121 Error { code: kind as u32 } 122 } 123 /// Creates a new instance of an `Error` from a particular TEE error code. 124 /// 125 /// # Examples 126 /// 127 /// ``` no_run 128 /// use optee_teec; 129 /// 130 /// let error = optee_teec::Error::from_raw_error(0xFFFF000F); 131 /// assert_eq!(error.kind(), optee_teec::ErrorKind::Security); 132 /// ``` from_raw_error(code: u32) -> Error133 pub fn from_raw_error(code: u32) -> Error { 134 Error { code } 135 } 136 137 /// Returns the corresponding `ErrorKind` for this error. 138 /// 139 /// # Examples 140 /// 141 /// ``` no_run 142 /// use optee_teec; 143 /// 144 /// let error = optee_teec::Error::new(optee_teec::ErrorKind::Security); 145 /// ``` kind(&self) -> ErrorKind146 pub fn kind(&self) -> ErrorKind { 147 match self.code { 148 raw::TEEC_ERROR_GENERIC => ErrorKind::Generic, 149 raw::TEEC_ERROR_ACCESS_DENIED => ErrorKind::AccessDenied, 150 raw::TEEC_ERROR_CANCEL => ErrorKind::Cancel, 151 raw::TEEC_ERROR_ACCESS_CONFLICT => ErrorKind::AccessConflict, 152 raw::TEEC_ERROR_EXCESS_DATA => ErrorKind::ExcessData, 153 raw::TEEC_ERROR_BAD_FORMAT => ErrorKind::BadFormat, 154 raw::TEEC_ERROR_BAD_PARAMETERS => ErrorKind::BadParameters, 155 raw::TEEC_ERROR_BAD_STATE => ErrorKind::BadState, 156 raw::TEEC_ERROR_ITEM_NOT_FOUND => ErrorKind::ItemNotFound, 157 raw::TEEC_ERROR_NOT_IMPLEMENTED => ErrorKind::NotImplemented, 158 raw::TEEC_ERROR_NOT_SUPPORTED => ErrorKind::NotSupported, 159 raw::TEEC_ERROR_NO_DATA => ErrorKind::NoData, 160 raw::TEEC_ERROR_OUT_OF_MEMORY => ErrorKind::OutOfMEmory, 161 raw::TEEC_ERROR_BUSY => ErrorKind::Busy, 162 raw::TEEC_ERROR_COMMUNICATION => ErrorKind::Communication, 163 raw::TEEC_ERROR_SECURITY => ErrorKind::Security, 164 raw::TEEC_ERROR_SHORT_BUFFER => ErrorKind::ShortBuffer, 165 raw::TEEC_ERROR_EXTERNAL_CANCEL => ErrorKind::ExternalCancel, 166 raw::TEEC_ERROR_TARGET_DEAD => ErrorKind::TargetDead, 167 _ => ErrorKind::Unknown, 168 } 169 } 170 171 /// Returns raw code of this error. raw_code(&self) -> u32172 pub fn raw_code(&self) -> u32 { 173 self.code 174 } 175 176 /// Returns corresponding error message of this error. message(&self) -> &str177 pub fn message(&self) -> &str { 178 self.kind().as_str() 179 } 180 } 181 182 impl fmt::Debug for Error { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result183 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 184 write!(fmt, "{} (error code 0x{:x})", self.message(), self.code) 185 } 186 } 187 188 impl fmt::Display for Error { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result189 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 190 write!(fmt, "{} (error code 0x{:x})", self.message(), self.code) 191 } 192 } 193 194 impl std::error::Error for Error { description(&self) -> &str195 fn description(&self) -> &str { 196 self.message() 197 } 198 } 199 200 impl From<ErrorKind> for Error { 201 #[inline] from(kind: ErrorKind) -> Error202 fn from(kind: ErrorKind) -> Error { 203 Error { code: kind as u32 } 204 } 205 } 206