#[cfg(not(target_os = "optee"))]
use core::error;
use core::{fmt, result};
use optee_utee_sys as raw;
#[cfg(target_os = "optee")]
use std::error;
pub type Result<T> = result::Result<T, Error>;
#[derive(Clone)]
pub struct Error {
kind: ErrorKind,
origin: Option<ErrorOrigin>,
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(u32)]
pub enum ErrorKind {
CorruptObject = raw::TEE_ERROR_CORRUPT_OBJECT,
CorruptObject2 = raw::TEE_ERROR_CORRUPT_OBJECT_2,
StorageNotAvailable = raw::TEE_ERROR_STORAGE_NOT_AVAILABLE,
StorageNotAvailable2 = raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2,
Generic = raw::TEE_ERROR_GENERIC,
AccessDenied = raw::TEE_ERROR_ACCESS_DENIED,
Cancel = raw::TEE_ERROR_CANCEL,
AccessConflict = raw::TEE_ERROR_ACCESS_CONFLICT,
ExcessData = raw::TEE_ERROR_EXCESS_DATA,
BadFormat = raw::TEE_ERROR_BAD_FORMAT,
BadParameters = raw::TEE_ERROR_BAD_PARAMETERS,
BadState = raw::TEE_ERROR_BAD_STATE,
ItemNotFound = raw::TEE_ERROR_ITEM_NOT_FOUND,
NotImplemented = raw::TEE_ERROR_NOT_IMPLEMENTED,
NotSupported = raw::TEE_ERROR_NOT_SUPPORTED,
NoData = raw::TEE_ERROR_NO_DATA,
OutOfMemory = raw::TEE_ERROR_OUT_OF_MEMORY,
Busy = raw::TEE_ERROR_BUSY,
Communication = raw::TEE_ERROR_COMMUNICATION,
Security = raw::TEE_ERROR_SECURITY,
ShortBuffer = raw::TEE_ERROR_SHORT_BUFFER,
ExternalCancel = raw::TEE_ERROR_EXTERNAL_CANCEL,
Overflow = raw::TEE_ERROR_OVERFLOW,
TargetDead = raw::TEE_ERROR_TARGET_DEAD,
StorageNoSpace = raw::TEE_ERROR_STORAGE_NO_SPACE,
MacInvalid = raw::TEE_ERROR_MAC_INVALID,
SignatureInvalid = raw::TEE_ERROR_SIGNATURE_INVALID,
TimeNotSet = raw::TEE_ERROR_TIME_NOT_SET,
TimeNeedsReset = raw::TEE_ERROR_TIME_NEEDS_RESET,
#[default]
Unknown,
}
impl ErrorKind {
pub(crate) fn as_str(&self) -> &'static str {
match *self {
ErrorKind::CorruptObject => "Object corruption.",
ErrorKind::CorruptObject2 => "Persistent object corruption.",
ErrorKind::StorageNotAvailable => "Object storage is not available.",
ErrorKind::StorageNotAvailable2 => "Persistent object storage is not available.",
ErrorKind::Generic => "Non-specific cause.",
ErrorKind::AccessDenied => "Access privileges are not sufficient.",
ErrorKind::Cancel => "The operation was canceled.",
ErrorKind::AccessConflict => "Concurrent accesses caused conflict.",
ErrorKind::ExcessData => "Too much data for the requested operation was passed.",
ErrorKind::BadFormat => "Input data was of invalid format.",
ErrorKind::BadParameters => "Input parameters were invalid.",
ErrorKind::BadState => "Operation is not valid in the current state.",
ErrorKind::ItemNotFound => "The requested data item is not found.",
ErrorKind::NotImplemented => {
"The requested operation should exist but is not yet implemented."
}
ErrorKind::NotSupported => {
"The requested operation is valid but is not supported in this implementation."
}
ErrorKind::NoData => "Expected data was missing.",
ErrorKind::OutOfMemory => "System ran out of resources.",
ErrorKind::Busy => "The system is busy working on something else.",
ErrorKind::Communication => "Communication with a remote party failed.",
ErrorKind::Security => "A security fault was detected.",
ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.",
ErrorKind::ExternalCancel => "Undocumented.",
ErrorKind::Overflow => "Data overflow.",
ErrorKind::TargetDead => "Trusted Application has panicked during the operation.",
ErrorKind::StorageNoSpace => "Insufficient space is available.",
ErrorKind::MacInvalid => "MAC is invalid.",
ErrorKind::SignatureInvalid => "Signature is invalid.",
ErrorKind::TimeNotSet => "The persistent time has not been set.",
ErrorKind::TimeNeedsReset => {
"The persistent time has been set but may have been corrupted and SHALL no longer be trusted."
},
ErrorKind::Unknown => "Unknown error.",
}
}
}
impl From<ErrorKind> for u32 {
fn from(kind: ErrorKind) -> u32 {
kind as u32
}
}
impl From<u32> for ErrorKind {
fn from(code: u32) -> ErrorKind {
match code {
raw::TEE_ERROR_CORRUPT_OBJECT => ErrorKind::CorruptObject,
raw::TEE_ERROR_CORRUPT_OBJECT_2 => ErrorKind::CorruptObject2,
raw::TEE_ERROR_STORAGE_NOT_AVAILABLE => ErrorKind::StorageNotAvailable,
raw::TEE_ERROR_STORAGE_NOT_AVAILABLE_2 => ErrorKind::StorageNotAvailable2,
raw::TEE_ERROR_GENERIC => ErrorKind::Generic,
raw::TEE_ERROR_ACCESS_DENIED => ErrorKind::AccessDenied,
raw::TEE_ERROR_CANCEL => ErrorKind::Cancel,
raw::TEE_ERROR_ACCESS_CONFLICT => ErrorKind::AccessConflict,
raw::TEE_ERROR_EXCESS_DATA => ErrorKind::ExcessData,
raw::TEE_ERROR_BAD_FORMAT => ErrorKind::BadFormat,
raw::TEE_ERROR_BAD_PARAMETERS => ErrorKind::BadParameters,
raw::TEE_ERROR_BAD_STATE => ErrorKind::BadState,
raw::TEE_ERROR_ITEM_NOT_FOUND => ErrorKind::ItemNotFound,
raw::TEE_ERROR_NOT_IMPLEMENTED => ErrorKind::NotImplemented,
raw::TEE_ERROR_NOT_SUPPORTED => ErrorKind::NotSupported,
raw::TEE_ERROR_NO_DATA => ErrorKind::NoData,
raw::TEE_ERROR_OUT_OF_MEMORY => ErrorKind::OutOfMemory,
raw::TEE_ERROR_BUSY => ErrorKind::Busy,
raw::TEE_ERROR_COMMUNICATION => ErrorKind::Communication,
raw::TEE_ERROR_SECURITY => ErrorKind::Security,
raw::TEE_ERROR_SHORT_BUFFER => ErrorKind::ShortBuffer,
raw::TEE_ERROR_EXTERNAL_CANCEL => ErrorKind::ExternalCancel,
raw::TEE_ERROR_OVERFLOW => ErrorKind::Overflow,
raw::TEE_ERROR_TARGET_DEAD => ErrorKind::TargetDead,
raw::TEE_ERROR_STORAGE_NO_SPACE => ErrorKind::StorageNoSpace,
raw::TEE_ERROR_MAC_INVALID => ErrorKind::MacInvalid,
raw::TEE_ERROR_SIGNATURE_INVALID => ErrorKind::SignatureInvalid,
raw::TEE_ERROR_TIME_NOT_SET => ErrorKind::TimeNotSet,
raw::TEE_ERROR_TIME_NEEDS_RESET => ErrorKind::TimeNeedsReset,
_ => ErrorKind::Unknown,
}
}
}
impl Error {
pub fn new(kind: ErrorKind) -> Error {
Error { kind, origin: None }
}
pub fn from_raw_error(code: u32) -> Error {
Error {
kind: ErrorKind::from(code),
origin: None,
}
}
pub fn with_origin(mut self, origin: ErrorOrigin) -> Self {
self.origin = Some(origin);
self
}
pub fn kind(&self) -> ErrorKind {
self.kind
}
pub fn origin(&self) -> Option<ErrorOrigin> {
self.origin.clone()
}
pub fn raw_code(&self) -> u32 {
self.kind.into()
}
pub fn message(&self) -> &str {
self.kind().as_str()
}
}
impl fmt::Debug for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(
fmt,
"{} (error code 0x{:x}, origin 0x{:x})",
self.message(),
self.raw_code(),
self.origin().map(|v| v.into()).unwrap_or(0_u32),
)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
impl error::Error for Error {
fn description(&self) -> &str {
self.message()
}
}
impl From<ErrorKind> for Error {
#[inline]
fn from(kind: ErrorKind) -> Error {
Error { kind, origin: None }
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[repr(u32)]
pub enum ErrorOrigin {
API = raw::TEE_ORIGIN_API,
COMMS = raw::TEE_ORIGIN_COMMS,
TEE = raw::TEE_ORIGIN_TEE,
TA = raw::TEE_ORIGIN_TRUSTED_APP,
#[default]
UNKNOWN,
}
impl From<ErrorOrigin> for u32 {
fn from(origin: ErrorOrigin) -> u32 {
origin as u32
}
}
impl From<u32> for ErrorOrigin {
fn from(code: u32) -> ErrorOrigin {
match code {
raw::TEE_ORIGIN_API => ErrorOrigin::API,
raw::TEE_ORIGIN_COMMS => ErrorOrigin::COMMS,
raw::TEE_ORIGIN_TEE => ErrorOrigin::TEE,
raw::TEE_ORIGIN_TRUSTED_APP => ErrorOrigin::TA,
_ => ErrorOrigin::UNKNOWN,
}
}
}