Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions crates/optee-teec/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ pub enum ErrorKind {
ExternalCancel = raw::TEEC_ERROR_EXTERNAL_CANCEL,
/// Implementation defined error code: trusted Application has panicked during the operation.
TargetDead = raw::TEEC_ERROR_TARGET_DEAD,
/// Unknown error.
#[default]
Unknown,
/// Unknown error, holding the original raw code.
#[num_enum(catch_all)]
Unknown(u32),
}

impl ErrorKind {
Expand Down Expand Up @@ -120,7 +120,7 @@ impl ErrorKind {
ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.",
ErrorKind::ExternalCancel => "Undocumented.",
ErrorKind::TargetDead => "Trusted Application has panicked during the operation.",
ErrorKind::Unknown => "Unknown error.",
ErrorKind::Unknown(_) => "Unknown error.",
}
}
}
Expand Down Expand Up @@ -221,3 +221,22 @@ pub enum ErrorOrigin {
#[default]
UNKNOWN,
}

#[cfg(test)]
mod tests {
use super::*;

/// Guarantees: unrecognized codes are preserved in the catch-all variant
/// and round-trip through `Error`.
#[test]
fn unknown_raw_code_round_trips() {
let code = 0x1234_5678;
assert_eq!(ErrorKind::from(code), ErrorKind::Unknown(code));
let back: u32 = ErrorKind::Unknown(code).into();
assert_eq!(back, code);

let err = Error::from_raw_error(code);
assert_eq!(err.kind(), ErrorKind::Unknown(code));
assert_eq!(err.raw_code(), code);
}
}
90 changes: 42 additions & 48 deletions crates/optee-utee/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#[cfg(not(feature = "std"))]
use core::error;
use core::{fmt, result};
use num_enum::{FromPrimitive, IntoPrimitive};
use optee_utee_sys as raw;
#[cfg(feature = "std")]
use std::error;
Expand All @@ -44,7 +45,13 @@ pub struct Error {

/// A list specifying general categories of TEE error and its corresponding code
/// in OP-TEE OS.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
///
/// Unrecognized codes are preserved in the `Unknown` catch-all variant, so
/// `raw_code()` always round-trips the value passed to
/// [`Error::from_raw_error`].
#[derive(
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, FromPrimitive, IntoPrimitive,
)]
#[repr(u32)]
pub enum ErrorKind {
/// Object corruption.
Expand Down Expand Up @@ -107,9 +114,9 @@ pub enum ErrorKind {
/// The persistent time has been set but may have been corrupted and SHALL
/// no longer be trusted.
TimeNeedsReset = raw::TEE_ERROR_TIME_NEEDS_RESET,
/// Unknown error.
#[default]
Unknown,
/// Unknown error, holding the original raw code.
#[num_enum(catch_all)]
Unknown(u32),
}

impl ErrorKind {
Expand Down Expand Up @@ -150,50 +157,7 @@ impl ErrorKind {
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,
ErrorKind::Unknown(_) => "Unknown error.",
}
}
}
Expand Down Expand Up @@ -313,3 +277,33 @@ impl From<u32> for ErrorOrigin {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

/// Guarantees: unrecognized codes are preserved in the catch-all variant
/// and round-trip through `Error`.
#[test]
fn unknown_raw_code_round_trips() {
let code = 0x1234_5678;
assert_eq!(ErrorKind::from(code), ErrorKind::Unknown(code));
let back: u32 = ErrorKind::Unknown(code).into();
assert_eq!(back, code);

let err = Error::from_raw_error(code);
assert_eq!(err.kind(), ErrorKind::Unknown(code));
assert_eq!(err.raw_code(), code);
}

/// Guarantees: known codes still map to their named variants.
#[test]
fn known_codes_still_map() {
assert_eq!(
ErrorKind::from(raw::TEE_ERROR_SECURITY),
ErrorKind::Security
);
let code: u32 = ErrorKind::Security.into();
assert_eq!(code, raw::TEE_ERROR_SECURITY);
}
}
2 changes: 1 addition & 1 deletion crates/optee-utee/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl LoadablePlugin {
/// let mut cmd = plugin.invoke_with_capacity(command_id, subcommand_id, capacity);
/// serde_json::to_writer(Wrapper(&mut cmd), &request_data).map_err(|err| {
/// trace_println!("serde error: {:?}", err);
/// ErrorKind::Unknown
/// ErrorKind::Generic
/// })?;
/// let result = cmd.call()?;
///
Expand Down
Loading