Skip to main content

cc_teec/
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// This file was modified by KylinSoft Co., Ltd. on 2025.
19
20use std::{fmt, sync::PoisonError};
21
22use num_enum::{FromPrimitive, IntoPrimitive};
23
24use crate::raw;
25
26/// TEE Result 类型。
27pub type Result<T> = std::result::Result<T, Error>;
28
29/// TEE 操作错误类型。
30#[derive(Clone)]
31pub struct Error {
32    kind: ErrorKind,
33    origin: Option<ErrorOrigin>,
34}
35
36/// 指定 TEE 客户端错误通用类别及其在 OP-TEE 客户端库中对应代码的列表。
37#[derive(
38    Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, FromPrimitive, IntoPrimitive,
39)]
40#[repr(u32)]
41pub enum ErrorKind {
42    /// 非特定原因。
43    Generic = raw::TEEC_ERROR_GENERIC,
44    /// 访问权限不足。
45    AccessDenied = raw::TEEC_ERROR_ACCESS_DENIED,
46    /// 操作已取消。
47    Cancel = raw::TEEC_ERROR_CANCEL,
48    /// 并发访问导致冲突。
49    AccessConflict = raw::TEEC_ERROR_ACCESS_CONFLICT,
50    /// 为请求的操作传递了过多数据。
51    ExcessData = raw::TEEC_ERROR_EXCESS_DATA,
52    /// 输入数据格式无效。
53    BadFormat = raw::TEEC_ERROR_BAD_FORMAT,
54    /// 输入参数无效。
55    BadParameters = raw::TEEC_ERROR_BAD_PARAMETERS,
56    /// 在当前状态下操作无效。
57    BadState = raw::TEEC_ERROR_BAD_STATE,
58    /// 未找到请求的数据项。
59    ItemNotFound = raw::TEEC_ERROR_ITEM_NOT_FOUND,
60    /// 请求的操作应该存在但尚未实现。
61    NotImplemented = raw::TEEC_ERROR_NOT_IMPLEMENTED,
62    /// 请求的操作有效,但在此实现中不支持。
63    NotSupported = raw::TEEC_ERROR_NOT_SUPPORTED,
64    /// 缺少预期数据。
65    NoData = raw::TEEC_ERROR_NO_DATA,
66    /// 系统资源耗尽。
67    OutOfMemory = raw::TEEC_ERROR_OUT_OF_MEMORY,
68    /// 系统正忙于处理其他任务。
69    Busy = raw::TEEC_ERROR_BUSY,
70    /// 与远程方的通信失败。
71    Communication = raw::TEEC_ERROR_COMMUNICATION,
72    /// 检测到安全故障。
73    Security = raw::TEEC_ERROR_SECURITY,
74    /// 提供的缓冲区对于生成的输出太短。
75    ShortBuffer = raw::TEEC_ERROR_SHORT_BUFFER,
76    /// 实现定义的错误代码。
77    ExternalCancel = raw::TEEC_ERROR_EXTERNAL_CANCEL,
78    /// 实现定义的错误代码:可信应用程序在操作期间发生崩溃。
79    TargetDead = raw::TEEC_ERROR_TARGET_DEAD,
80    /// 未知错误。
81    #[default]
82    Unknown,
83}
84
85impl ErrorKind {
86    pub(crate) fn as_str(&self) -> &'static str {
87        match self {
88            ErrorKind::Generic => "Non-specific cause.",
89            ErrorKind::AccessDenied => "Access privileges are not sufficient.",
90            ErrorKind::Cancel => "The operation was canceled.",
91            ErrorKind::AccessConflict => "Concurrent accesses caused conflict.",
92            ErrorKind::ExcessData => "Too much data for the requested operation was passed.",
93            ErrorKind::BadFormat => "Input data was of invalid format.",
94            ErrorKind::BadParameters => "Input parameters were invalid.",
95            ErrorKind::BadState => "Operation is not valid in the current state.",
96            ErrorKind::ItemNotFound => "The requested data item is not found.",
97            ErrorKind::NotImplemented => {
98                "The requested operation should exist but is not yet implemented."
99            }
100            ErrorKind::NotSupported => {
101                "The requested operation is valid but is not supported in this implementation."
102            }
103            ErrorKind::NoData => "Expected data was missing.",
104            ErrorKind::OutOfMemory => "System ran out of resources.",
105            ErrorKind::Busy => "The system is busy working on something else.",
106            ErrorKind::Communication => "Communication with a remote party failed.",
107            ErrorKind::Security => "A security fault was detected.",
108            ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.",
109            ErrorKind::ExternalCancel => "Undocumented.",
110            ErrorKind::TargetDead => "Trusted Application has panicked during the operation.",
111            ErrorKind::Unknown => "Unknown error.",
112        }
113    }
114}
115
116impl Error {
117    pub fn new(kind: ErrorKind) -> Error {
118        Error { kind, origin: None }
119    }
120
121    /// 从原始 TEE 错误代码创建 Error 实例
122    pub fn from_raw_error(code: u32) -> Error {
123        Error {
124            kind: ErrorKind::from(code),
125            origin: None,
126        }
127    }
128
129    /// 设置错误来源
130    pub fn with_origin(mut self, origin: ErrorOrigin) -> Self {
131        self.origin = Some(origin);
132        self
133    }
134
135    /// 获取错误类型
136    pub fn kind(&self) -> ErrorKind {
137        self.kind
138    }
139
140    /// 获取错误来源
141    pub fn origin(&self) -> Option<ErrorOrigin> {
142        self.origin
143    }
144
145    /// 获取原始错误码(用于 FFI 接口)
146    pub fn raw_code(&self) -> u32 {
147        self.kind.into()
148    }
149
150    /// 获取错误描述信息
151    pub fn message(&self) -> &str {
152        self.kind().as_str()
153    }
154}
155
156impl<T> From<PoisonError<T>> for Error {
157    fn from(_: PoisonError<T>) -> Self {
158        Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API)
159    }
160}
161
162impl fmt::Debug for Error {
163    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
164        write!(
165            fmt,
166            "{} (错误代码 0x{:x}, 来源 0x{:x})",
167            self.message(),
168            self.raw_code(),
169            self.origin().map(|v| v.into()).unwrap_or(0_u32),
170        )
171    }
172}
173
174impl fmt::Display for Error {
175    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
176        fmt::Debug::fmt(self, f)
177    }
178}
179
180impl std::error::Error for Error {
181    fn description(&self) -> &str {
182        self.message()
183    }
184}
185
186impl From<ErrorKind> for Error {
187    #[inline]
188    fn from(kind: ErrorKind) -> Error {
189        Error { kind, origin: None }
190    }
191}
192
193#[derive(Clone, Copy, Debug, Eq, PartialEq, FromPrimitive, IntoPrimitive)]
194#[repr(u32)]
195pub enum ErrorOrigin {
196    API = raw::TEEC_ORIGIN_API,
197    COMMS = raw::TEEC_ORIGIN_COMMS,
198    TEE = raw::TEEC_ORIGIN_TEE,
199    TA = raw::TEEC_ORIGIN_TRUSTED_APP,
200    #[default]
201    UNKNOWN,
202}
203
204#[cfg(test)]
205mod teec_error_tests {
206    use super::*;
207
208    /// 辅助宏:批量测试 ErrorKind 的 as_str 方法
209    macro_rules! test_error_kind_messages {
210        ($($variant:ident => $msg:expr),* $(,)?) => {
211            $(
212                assert_eq!(ErrorKind::$variant.as_str(), $msg);
213            )*
214        };
215    }
216
217    #[test]
218    fn test_error_types_and_methods() {
219        // 使用宏批量测试所有 ErrorKind 变体的消息
220        test_error_kind_messages! {
221            Generic => "Non-specific cause.",
222            AccessDenied => "Access privileges are not sufficient.",
223            Cancel => "The operation was canceled.",
224            AccessConflict => "Concurrent accesses caused conflict.",
225            ExcessData => "Too much data for the requested operation was passed.",
226            BadFormat => "Input data was of invalid format.",
227            BadParameters => "Input parameters were invalid.",
228            BadState => "Operation is not valid in the current state.",
229            ItemNotFound => "The requested data item is not found.",
230            NotImplemented => "The requested operation should exist but is not yet implemented.",
231            NotSupported => "The requested operation is valid but is not supported in this implementation.",
232            NoData => "Expected data was missing.",
233            OutOfMemory => "System ran out of resources.",
234            Busy => "The system is busy working on something else.",
235            Communication => "Communication with a remote party failed.",
236            Security => "A security fault was detected.",
237            ShortBuffer => "The supplied buffer is too short for the generated output.",
238            ExternalCancel => "Undocumented.",
239            TargetDead => "Trusted Application has panicked during the operation.",
240            Unknown => "Unknown error.",
241        }
242
243        // 测试 Error 的创建和访问方法
244        let error = Error::new(ErrorKind::BadParameters);
245        assert_eq!(error.kind(), ErrorKind::BadParameters);
246        assert_eq!(error.origin(), None);
247
248        // 测试 from_raw_error 方法
249        let raw_error = Error::from_raw_error(ErrorKind::Generic.into());
250        assert_eq!(raw_error.kind(), ErrorKind::Generic);
251
252        // 测试 with_origin 方法
253        let error_with_origin = Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API);
254        assert_eq!(error_with_origin.origin(), Some(ErrorOrigin::API));
255
256        // 测试 raw_code 方法
257        assert_eq!(error.raw_code(), u32::from(ErrorKind::BadParameters));
258
259        // 测试 message 方法
260        assert_eq!(error.message(), "Input parameters were invalid.");
261
262        // 测试 Debug 格式化
263        let debug_str = format!("{:?}", error);
264        assert!(debug_str.contains("错误代码"));
265
266        // 测试 Display 格式化
267        let display_str = format!("{}", error);
268        assert!(display_str.contains("错误代码"));
269
270        // 测试 From trait
271        let from_kind: Error = ErrorKind::OutOfMemory.into();
272        assert_eq!(from_kind.kind(), ErrorKind::OutOfMemory);
273
274        // 测试 ErrorOrigin 的转换
275        assert_eq!(u32::from(ErrorOrigin::API), raw::TEEC_ORIGIN_API);
276        assert_eq!(u32::from(ErrorOrigin::COMMS), raw::TEEC_ORIGIN_COMMS);
277        assert_eq!(u32::from(ErrorOrigin::TEE), raw::TEEC_ORIGIN_TEE);
278        assert_eq!(u32::from(ErrorOrigin::TA), raw::TEEC_ORIGIN_TRUSTED_APP);
279    }
280
281    #[test]
282    fn test_error_kind_all_variants_as_str() {
283        // 测试所有 ErrorKind 变体
284        let error_kinds = vec![
285            ErrorKind::Generic,
286            ErrorKind::AccessDenied,
287            ErrorKind::Cancel,
288            ErrorKind::AccessConflict,
289            ErrorKind::ExcessData,
290            ErrorKind::BadFormat,
291            ErrorKind::BadParameters,
292            ErrorKind::BadState,
293            ErrorKind::ItemNotFound,
294            ErrorKind::NotImplemented,
295            ErrorKind::NotSupported,
296            ErrorKind::NoData,
297            ErrorKind::OutOfMemory,
298            ErrorKind::Busy,
299            ErrorKind::Communication,
300            ErrorKind::Security,
301            ErrorKind::ShortBuffer,
302            ErrorKind::ExternalCancel,
303            ErrorKind::TargetDead,
304            ErrorKind::Unknown,
305        ];
306
307        for kind in error_kinds {
308            let error = Error::new(kind);
309            // 调用 kind 方法不应该崩溃
310            let _ = error.kind();
311        }
312    }
313
314    /// 测试 ErrorOrigin 到 u32 的转换
315    #[test]
316    fn test_error_origin_to_u32() {
317        assert_eq!(u32::from(ErrorOrigin::API), raw::TEEC_ORIGIN_API);
318        assert_eq!(u32::from(ErrorOrigin::COMMS), raw::TEEC_ORIGIN_COMMS);
319        assert_eq!(u32::from(ErrorOrigin::TEE), raw::TEEC_ORIGIN_TEE);
320        assert_eq!(u32::from(ErrorOrigin::TA), raw::TEEC_ORIGIN_TRUSTED_APP);
321    }
322}