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    /// 从特定的 TEE 错误代码创建新的 `Error` 实例。
121    pub fn from_raw_error(code: u32) -> Error {
122        Error {
123            kind: ErrorKind::from(code),
124            origin: None,
125        }
126    }
127
128    pub fn with_origin(mut self, origin: ErrorOrigin) -> Self {
129        self.origin = Some(origin);
130        self
131    }
132
133    /// 返回此错误对应的 `ErrorKind`。
134    pub fn kind(&self) -> ErrorKind {
135        self.kind
136    }
137
138    /// 返回此错误的来源。
139    pub fn origin(&self) -> Option<ErrorOrigin> {
140        self.origin.clone()
141    }
142
143    /// 返回此错误的原始代码。
144    pub fn raw_code(&self) -> u32 {
145        self.kind.into()
146    }
147
148    /// 返回此错误对应的错误信息。
149    pub fn message(&self) -> &str {
150        self.kind().as_str()
151    }
152}
153
154impl<T> From<PoisonError<T>> for Error {
155    fn from(_: PoisonError<T>) -> Self {
156        Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API)
157    }
158}
159
160impl fmt::Debug for Error {
161    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
162        write!(
163            fmt,
164            "{} (错误代码 0x{:x}, 来源 0x{:x})",
165            self.message(),
166            self.raw_code(),
167            self.origin().map(|v| v.into()).unwrap_or(0_u32),
168        )
169    }
170}
171
172impl fmt::Display for Error {
173    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174        fmt::Debug::fmt(self, f)
175    }
176}
177
178impl std::error::Error for Error {
179    fn description(&self) -> &str {
180        self.message()
181    }
182}
183
184impl From<ErrorKind> for Error {
185    #[inline]
186    fn from(kind: ErrorKind) -> Error {
187        Error { kind, origin: None }
188    }
189}
190
191#[derive(Clone, Debug, Eq, PartialEq, FromPrimitive, IntoPrimitive)]
192#[repr(u32)]
193pub enum ErrorOrigin {
194    API = raw::TEEC_ORIGIN_API,
195    COMMS = raw::TEEC_ORIGIN_COMMS,
196    TEE = raw::TEEC_ORIGIN_TEE,
197    TA = raw::TEEC_ORIGIN_TRUSTED_APP,
198    #[default]
199    UNKNOWN,
200}
201
202#[cfg(test)]
203mod teec_error_tests {
204    use super::*;
205
206    #[test]
207    fn test_error_types_and_methods() {
208        // 测试 ErrorKind 的 as_str 方法
209        assert_eq!(ErrorKind::Generic.as_str(), "Non-specific cause.");
210        assert_eq!(
211            ErrorKind::AccessDenied.as_str(),
212            "Access privileges are not sufficient."
213        );
214        assert_eq!(ErrorKind::Cancel.as_str(), "The operation was canceled.");
215        assert_eq!(
216            ErrorKind::AccessConflict.as_str(),
217            "Concurrent accesses caused conflict."
218        );
219        assert_eq!(
220            ErrorKind::ExcessData.as_str(),
221            "Too much data for the requested operation was passed."
222        );
223        assert_eq!(
224            ErrorKind::BadFormat.as_str(),
225            "Input data was of invalid format."
226        );
227        assert_eq!(
228            ErrorKind::BadParameters.as_str(),
229            "Input parameters were invalid."
230        );
231        assert_eq!(
232            ErrorKind::BadState.as_str(),
233            "Operation is not valid in the current state."
234        );
235        assert_eq!(
236            ErrorKind::ItemNotFound.as_str(),
237            "The requested data item is not found."
238        );
239        assert_eq!(
240            ErrorKind::NotImplemented.as_str(),
241            "The requested operation should exist but is not yet implemented."
242        );
243        assert_eq!(
244            ErrorKind::NotSupported.as_str(),
245            "The requested operation is valid but is not supported in this implementation."
246        );
247        assert_eq!(ErrorKind::NoData.as_str(), "Expected data was missing.");
248        assert_eq!(
249            ErrorKind::OutOfMemory.as_str(),
250            "System ran out of resources."
251        );
252        assert_eq!(
253            ErrorKind::Busy.as_str(),
254            "The system is busy working on something else."
255        );
256        assert_eq!(
257            ErrorKind::Communication.as_str(),
258            "Communication with a remote party failed."
259        );
260        assert_eq!(
261            ErrorKind::Security.as_str(),
262            "A security fault was detected."
263        );
264        assert_eq!(
265            ErrorKind::ShortBuffer.as_str(),
266            "The supplied buffer is too short for the generated output."
267        );
268        assert_eq!(ErrorKind::ExternalCancel.as_str(), "Undocumented.");
269        assert_eq!(
270            ErrorKind::TargetDead.as_str(),
271            "Trusted Application has panicked during the operation."
272        );
273        assert_eq!(ErrorKind::Unknown.as_str(), "Unknown error.");
274
275        // 测试 Error 的创建和访问方法
276        let error = Error::new(ErrorKind::BadParameters);
277        assert_eq!(error.kind(), ErrorKind::BadParameters);
278        assert_eq!(error.origin(), None);
279
280        // 测试 from_raw_error 方法
281        let raw_error = Error::from_raw_error(ErrorKind::Generic.into());
282        assert_eq!(raw_error.kind(), ErrorKind::Generic);
283
284        // 测试 with_origin 方法
285        let error_with_origin = Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API);
286        assert_eq!(error_with_origin.origin(), Some(ErrorOrigin::API));
287
288        // 测试 raw_code 方法
289        assert_eq!(error.raw_code(), ErrorKind::BadParameters.into());
290
291        // 测试 message 方法
292        assert_eq!(error.message(), "Input parameters were invalid.");
293
294        // 测试 Debug 格式化
295        let debug_str = format!("{:?}", error);
296        assert!(debug_str.contains("错误代码"));
297
298        // 测试 Display 格式化
299        let display_str = format!("{}", error);
300        assert!(display_str.contains("错误代码"));
301
302        // 测试 From trait
303        let from_kind: Error = ErrorKind::OutOfMemory.into();
304        assert_eq!(from_kind.kind(), ErrorKind::OutOfMemory);
305
306        // 测试 ErrorOrigin 的转换
307        assert_eq!(u32::from(ErrorOrigin::API), raw::TEEC_ORIGIN_API);
308        assert_eq!(u32::from(ErrorOrigin::COMMS), raw::TEEC_ORIGIN_COMMS);
309        assert_eq!(u32::from(ErrorOrigin::TEE), raw::TEEC_ORIGIN_TEE);
310        assert_eq!(u32::from(ErrorOrigin::TA), raw::TEEC_ORIGIN_TRUSTED_APP);
311    }
312
313    #[test]
314    fn test_error_kind_all_variants_as_str() {
315        // 测试所有 ErrorKind 变体
316        let error_kinds = vec![
317            ErrorKind::Generic,
318            ErrorKind::AccessDenied,
319            ErrorKind::Cancel,
320            ErrorKind::AccessConflict,
321            ErrorKind::ExcessData,
322            ErrorKind::BadFormat,
323            ErrorKind::BadParameters,
324            ErrorKind::BadState,
325            ErrorKind::ItemNotFound,
326            ErrorKind::NotImplemented,
327            ErrorKind::NotSupported,
328            ErrorKind::NoData,
329            ErrorKind::OutOfMemory,
330            ErrorKind::Busy,
331            ErrorKind::Communication,
332            ErrorKind::Security,
333            ErrorKind::ShortBuffer,
334            ErrorKind::ExternalCancel,
335            ErrorKind::TargetDead,
336            ErrorKind::Unknown,
337        ];
338
339        for kind in error_kinds {
340            let error = Error::new(kind);
341            // 调用 kind 方法不应该崩溃
342            let _ = error.kind();
343        }
344    }
345
346    /// 测试 ErrorOrigin 到 u32 的转换
347    #[test]
348    fn test_error_origin_to_u32() {
349        assert_eq!(u32::from(ErrorOrigin::API), raw::TEEC_ORIGIN_API);
350        assert_eq!(u32::from(ErrorOrigin::COMMS), raw::TEEC_ORIGIN_COMMS);
351        assert_eq!(u32::from(ErrorOrigin::TEE), raw::TEEC_ORIGIN_TEE);
352        assert_eq!(u32::from(ErrorOrigin::TA), raw::TEEC_ORIGIN_TRUSTED_APP);
353    }
354}