Skip to main content

rust_utee/api/
tee_api_objects.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2025 KylinSoft Co., Ltd. <https://www.kylinos.cn/>
3// See LICENSES for license details.
4//
5// This file has been modified by KylinSoft on 2025.
6
7use crate::api::tee_api_mm::TEE_CheckMemoryAccessRights;
8use crate::api::tee_api_panic::TEE_Panic;
9use crate::syscalls::syscall_table::{
10    _utee_cryp_obj_alloc, _utee_cryp_obj_close, _utee_cryp_obj_copy, _utee_cryp_obj_generate_key,
11    _utee_cryp_obj_get_attr, _utee_cryp_obj_get_info, _utee_cryp_obj_populate,
12    _utee_cryp_obj_reset, _utee_cryp_obj_restrict_usage, _utee_storage_alloc_enum,
13    _utee_storage_free_enum, _utee_storage_next_enum, _utee_storage_obj_create,
14    _utee_storage_obj_del, _utee_storage_obj_open, _utee_storage_obj_read, _utee_storage_obj_seek,
15    _utee_storage_obj_trunc, _utee_storage_obj_write, _utee_storage_reset_enum,
16    _utee_storage_start_enum,
17};
18use crate::tee_api_defines::*;
19use crate::tee_api_types::{
20    TEE_Attribute, TEE_ObjectEnumHandle, TEE_ObjectHandle, TEE_ObjectInfo, TEE_Result, TEE_Whence,
21};
22use crate::utee_types::utee_attribute;
23
24/// 默认使用标志
25pub const TEE_USAGE_DEFAULT: u32 = 0xffffffff;
26
27/// 将TEE属性转换为utee属性
28pub unsafe fn __utee_from_attr(
29    ua: *mut utee_attribute,
30    attrs: *const TEE_Attribute,
31    attr_count: u32,
32) {
33    unsafe {
34        for n in 0..attr_count as usize {
35            let ua_ptr = ua.add(n);
36            let attr_ptr = attrs.add(n);
37
38            (*ua_ptr).attribute_id = (*attr_ptr).attributeID;
39
40            if (*attr_ptr).attributeID & TEE_ATTR_FLAG_VALUE != 0 {
41                // 处理值类型属性
42                (*ua_ptr).a = (*attr_ptr).content.value.a as u64;
43                (*ua_ptr).b = (*attr_ptr).content.value.b as u64;
44            } else {
45                // 处理引用类型属性
46                (*ua_ptr).a = (*attr_ptr).content.memref.buffer as u64;
47                (*ua_ptr).b = (*attr_ptr).content.memref.size as u64;
48            }
49        }
50    }
51}
52
53/// 获取对象信息(已弃用)
54///
55/// 注意:此函数已弃用,新代码应使用 [TEE_GetObjectInfo1] 函数
56#[unsafe(no_mangle)]
57pub extern "C" fn TEE_GetObjectInfo(object: TEE_ObjectHandle, object_info: &mut TEE_ObjectInfo) {
58    let mut info = unsafe { std::mem::zeroed() }; // 使用 zeroed 替代 default
59    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) };
60
61    if res != TEE_SUCCESS as usize {
62        TEE_Panic(res as u32);
63    }
64
65    if info.obj_type == TEE_TYPE_CORRUPTED_OBJECT {
66        // 对于损坏的对象,设置默认值
67        object_info.objectSize = 0;
68        object_info.maxObjectSize = 0;
69        object_info.objectUsage = 0;
70        object_info.dataSize = 0;
71        object_info.dataPosition = 0;
72        object_info.handleFlags = 0;
73    } else {
74        // 复制对象信息
75        object_info.objectType = info.obj_type;
76        object_info.objectSize = info.obj_size;
77        object_info.maxObjectSize = info.max_obj_size;
78        object_info.objectUsage = info.obj_usage;
79        object_info.dataSize = info.data_size as usize;
80        object_info.dataPosition = info.data_pos as usize;
81        object_info.handleFlags = info.handle_flags;
82    }
83}
84
85/// 获取对象信息
86///
87/// 此函数返回操作结果而不是 panic
88#[unsafe(no_mangle)]
89pub extern "C" fn TEE_GetObjectInfo1(
90    object: TEE_ObjectHandle,
91    object_info: &mut TEE_ObjectInfo,
92) -> TEE_Result {
93    let mut info = unsafe { std::mem::zeroed() };
94    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
95
96    // 检查是否为非预期错误
97    if res != TEE_SUCCESS
98        && res != TEE_ERROR_CORRUPT_OBJECT
99        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
100    {
101        TEE_Panic(res as u32);
102    }
103
104    // 总是复制对象信息,即使对象已损坏或存储不可用
105    object_info.objectType = info.obj_type;
106    object_info.objectSize = info.obj_size;
107    object_info.maxObjectSize = info.max_obj_size;
108    object_info.objectUsage = info.obj_usage;
109    object_info.dataSize = info.data_size as usize;
110    object_info.dataPosition = info.data_pos as usize;
111    object_info.handleFlags = info.handle_flags;
112
113    res
114}
115
116/// 限制对象使用(已弃用)
117///
118/// 注意:此函数已弃用,新代码应使用 [TEE_RestrictObjectUsage1] 函数
119#[unsafe(no_mangle)]
120pub extern "C" fn TEE_RestrictObjectUsage(object: TEE_ObjectHandle, object_usage: u32) {
121    let mut info = unsafe { std::mem::zeroed() };
122    unsafe {
123        _utee_cryp_obj_get_info(object as u64, &mut info);
124    }
125
126    // 如果对象已损坏,则直接返回
127    if info.obj_type == TEE_TYPE_CORRUPTED_OBJECT {
128        return;
129    }
130
131    let res = TEE_RestrictObjectUsage1(object, object_usage);
132
133    if res != TEE_SUCCESS {
134        TEE_Panic(res as u32);
135    }
136}
137
138/// 限制对象使用
139///
140/// 设置对象的使用限制,返回操作结果
141#[unsafe(no_mangle)]
142pub extern "C" fn TEE_RestrictObjectUsage1(
143    object: TEE_ObjectHandle,
144    object_usage: u32,
145) -> TEE_Result {
146    let res =
147        unsafe { _utee_cryp_obj_restrict_usage(object as u64, object_usage as u64) } as TEE_Result;
148
149    // 检查是否为非预期错误
150    if res != TEE_SUCCESS
151        && res != TEE_ERROR_CORRUPT_OBJECT
152        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
153    {
154        TEE_Panic(res as u32);
155    }
156
157    res
158}
159
160/// 获取对象的缓冲区属性(已弃用)
161///
162/// 返回对象的缓冲区属性,将数据写入提供的缓冲区
163#[unsafe(no_mangle)]
164pub extern "C" fn TEE_GetObjectBufferAttribute(
165    object: TEE_ObjectHandle,
166    attribute_id: u32,
167    buffer: *mut core::ffi::c_void,
168    size: *mut usize,
169) -> TEE_Result {
170    // 检查参数有效性
171    if cfg!(feature = "strict_annotation_checks") {
172        let res = TEE_CheckMemoryAccessRights(
173            TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
174            size as *mut core::ffi::c_void,
175            std::mem::size_of::<usize>(),
176        );
177        if res != 0 {
178            eprintln!("[inout] size: error {:#010x}", res);
179            TEE_Panic(0);
180        }
181    }
182
183    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
184    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
185
186    if res != TEE_SUCCESS {
187        return check_result_and_panic(res);
188    }
189
190    // 此函数仅支持引用类型属性
191    if attribute_id & TEE_ATTR_FLAG_VALUE != 0 {
192        return check_result_and_panic(TEE_ERROR_BAD_PARAMETERS);
193    }
194
195    let mut buffer_size: u64 = 0;
196    unsafe {
197        if !size.is_null() {
198            buffer_size = *size as u64;
199        }
200    }
201
202    let res = unsafe {
203        _utee_cryp_obj_get_attr(object as u64, attribute_id as u64, buffer, &mut buffer_size)
204    } as TEE_Result;
205
206    unsafe {
207        if !size.is_null() {
208            *size = buffer_size as usize;
209        }
210    }
211
212    check_result_and_panic(res)
213}
214
215/// 获取对象的缓冲区属性
216///
217/// 返回对象的缓冲区属性,将数据写入提供的缓冲区
218#[unsafe(no_mangle)]
219pub extern "C" fn TEE_GetObjectBufferAttribute1(
220    object: TEE_ObjectHandle,
221    attribute_id: u32,
222    buffer: *mut core::ffi::c_void,
223    size: *mut usize,
224) -> TEE_Result {
225    // 检查参数有效性
226    if size.is_null() {
227        return TEE_ERROR_BAD_PARAMETERS;
228    }
229
230    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
231    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
232
233    if res != TEE_SUCCESS {
234        return check_result_and_panic(res);
235    }
236
237    // 此函数仅支持引用类型属性
238    if attribute_id & TEE_ATTR_FLAG_VALUE != 0 {
239        return TEE_ERROR_BAD_PARAMETERS;
240    }
241
242    // 首先获取所需缓冲区大小
243    let mut required_size: u64 = 0;
244    let res = unsafe {
245        _utee_cryp_obj_get_attr(
246            object as u64,
247            attribute_id as u64,
248            core::ptr::null_mut(),
249            &mut required_size,
250        ) as TEE_Result
251    };
252
253    if res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER {
254        unsafe {
255            *size = required_size as usize;
256        }
257    } else {
258        return check_result_and_panic(res);
259    }
260
261    // 如果提供了缓冲区且大小足够,获取实际数据
262    if !buffer.is_null() && unsafe { *size } >= required_size as usize {
263        let res = unsafe {
264            _utee_cryp_obj_get_attr(
265                object as u64,
266                attribute_id as u64,
267                buffer,
268                &mut required_size,
269            ) as TEE_Result
270        };
271
272        if res != TEE_SUCCESS {
273            return check_result_and_panic(res);
274        }
275
276        unsafe {
277            *size = required_size as usize;
278        }
279    }
280
281    TEE_SUCCESS
282}
283
284/// 检查结果并对非预期错误进行 panic
285fn check_result_and_panic(res: TEE_Result) -> TEE_Result {
286    if res != TEE_SUCCESS
287        && res != TEE_ERROR_ITEM_NOT_FOUND
288        && res != TEE_ERROR_SHORT_BUFFER
289        && res != TEE_ERROR_CORRUPT_OBJECT
290        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
291    {
292        TEE_Panic(res as u32);
293    }
294    res
295}
296
297/// 处理结果并返回
298fn handle_result_and_return(
299    res: TEE_Result,
300    a: *mut u32,
301    b: *mut u32,
302    value_a: u32,
303    value_b: u32,
304) -> TEE_Result {
305    if res != TEE_SUCCESS
306        && res != TEE_ERROR_ITEM_NOT_FOUND
307        && res != TEE_ERROR_CORRUPT_OBJECT
308        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
309    {
310        TEE_Panic(res);
311    }
312
313    if res == TEE_SUCCESS {
314        if !a.is_null() {
315            unsafe { *a = value_a };
316        }
317        if !b.is_null() {
318            unsafe { *b = value_b };
319        }
320    }
321
322    res
323}
324
325/// 获取对象值属性
326///
327/// 此函数仅支持值类型属性(由TEE_ATTR_FLAG_VALUE标识)
328#[unsafe(no_mangle)]
329pub extern "C" fn TEE_GetObjectValueAttribute(
330    object: TEE_ObjectHandle,
331    attribute_id: u32,
332    a: *mut u32,
333    b: *mut u32,
334) -> TEE_Result {
335    // 检查输出参数的有效性(如果非空)
336    if cfg!(feature = "strict_annotation_checks") {
337        if !a.is_null() {
338            let res = TEE_CheckMemoryAccessRights(
339                TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
340                a as *mut core::ffi::c_void,
341                std::mem::size_of::<u32>(),
342            );
343            if res != 0 {
344                eprintln!("[inout] a: error {:#010x}", res);
345                TEE_Panic(0);
346            }
347        }
348        if !b.is_null() {
349            let res = TEE_CheckMemoryAccessRights(
350                TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
351                b as *mut core::ffi::c_void,
352                std::mem::size_of::<u32>(),
353            );
354            if res != 0 {
355                eprintln!("[inout] b: error {:#010x}", res);
356                TEE_Panic(0);
357            }
358        }
359    }
360
361    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
362    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
363
364    if res != TEE_SUCCESS {
365        return handle_result_and_return(res, a, b, 0, 0);
366    }
367
368    // 此函数仅支持值类型属性
369    if attribute_id & TEE_ATTR_FLAG_VALUE == 0 {
370        let res = TEE_ERROR_BAD_PARAMETERS;
371        return handle_result_and_return(res, a, b, 0, 0);
372    }
373
374    // 创建缓冲区来存储属性值
375    let mut buf = [0u32; 2];
376    let mut size = std::mem::size_of_val(&buf) as u64;
377
378    let res = unsafe {
379        _utee_cryp_obj_get_attr(
380            object as u64,
381            attribute_id as u64,
382            buf.as_mut_ptr() as *mut core::ffi::c_void,
383            &mut size,
384        ) as TEE_Result
385    };
386
387    // 检查返回结果是否为非预期错误
388    if res != TEE_SUCCESS
389        && res != TEE_ERROR_ITEM_NOT_FOUND
390        && res != TEE_ERROR_CORRUPT_OBJECT
391        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
392    {
393        TEE_Panic(res);
394    }
395
396    // 验证返回的大小是否正确
397    if size != std::mem::size_of_val(&buf) as u64 {
398        TEE_Panic(0);
399    }
400
401    // 如果成功,将值写入输出参数
402    if res == TEE_SUCCESS {
403        if !a.is_null() {
404            unsafe { *a = buf[0] };
405        }
406        if !b.is_null() {
407            unsafe { *b = buf[1] };
408        }
409    }
410
411    res
412}
413
414/// 关闭对象
415///
416/// 关闭并释放指定的TEE对象句柄
417#[unsafe(no_mangle)]
418pub extern "C" fn TEE_CloseObject(object: TEE_ObjectHandle) {
419    // 检查是否为NULL句柄
420    if object.is_null() {
421        return;
422    }
423
424    let res = unsafe { _utee_cryp_obj_close(object as u64) } as TEE_Result;
425
426    // 检查返回结果,如果不是成功则panic
427    if res != TEE_SUCCESS {
428        TEE_Panic(res as u32);
429    }
430}
431
432/// 分配临时对象
433///
434/// 分配一个新的临时对象句柄
435#[unsafe(no_mangle)]
436pub extern "C" fn TEE_AllocateTransientObject(
437    object_type: u32, // TEE_ObjectType
438    max_object_size: u32,
439    object: *mut TEE_ObjectHandle,
440) -> TEE_Result {
441    // 数据类型对象不支持
442    if object_type == TEE_TYPE_DATA {
443        return TEE_ERROR_NOT_SUPPORTED;
444    }
445
446    // 检查输出参数的有效性
447    if cfg!(feature = "strict_annotation_checks") {
448        let res = TEE_CheckMemoryAccessRights(
449            TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
450            object as *mut core::ffi::c_void,
451            std::mem::size_of::<TEE_ObjectHandle>(),
452        );
453        if res != 0 {
454            eprintln!("[inout] object: error {:#010x}", res);
455            TEE_Panic(0);
456        }
457    }
458
459    let mut obj: u32 = 0;
460
461    let res = unsafe { _utee_cryp_obj_alloc(object_type as u64, max_object_size as u64, &mut obj) }
462        as TEE_Result;
463
464    // 检查返回结果是否为非预期错误
465    if res != TEE_SUCCESS && res != TEE_ERROR_OUT_OF_MEMORY && res != TEE_ERROR_NOT_SUPPORTED {
466        TEE_Panic(res as u32);
467    }
468
469    // 如果成功,将对象句柄写入输出参数
470    if res == TEE_SUCCESS {
471        unsafe {
472            *object = obj as TEE_ObjectHandle;
473        }
474    }
475
476    res
477}
478
479/// 释放临时对象
480///
481/// 释放指定的临时对象句柄,仅当对象不是持久化对象时
482#[unsafe(no_mangle)]
483pub extern "C" fn TEE_FreeTransientObject(object: TEE_ObjectHandle) {
484    // 检查是否为NULL句柄
485    if object.is_null() {
486        return;
487    }
488
489    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
490    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
491
492    if res != TEE_SUCCESS {
493        TEE_Panic(res as u32);
494    }
495
496    // 检查对象是否为持久化对象,如果是则panic
497    if (info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0 {
498        TEE_Panic(0);
499    }
500
501    let res = unsafe { _utee_cryp_obj_close(object as u64) } as TEE_Result;
502
503    if res != TEE_SUCCESS {
504        TEE_Panic(res as u32);
505    }
506}
507
508/// 重置临时对象
509///
510/// 重置指定的临时对象,仅当对象不是持久化对象时
511#[unsafe(no_mangle)]
512pub extern "C" fn TEE_ResetTransientObject(object: TEE_ObjectHandle) {
513    // 检查是否为NULL句柄
514    if object.is_null() {
515        return;
516    }
517
518    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
519    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
520
521    if res != TEE_SUCCESS {
522        TEE_Panic(res as u32);
523    }
524
525    // 检查对象是否为持久化对象,如果是则panic
526    if (info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0 {
527        TEE_Panic(0);
528    }
529
530    let res = unsafe { _utee_cryp_obj_reset(object as u64) } as TEE_Result;
531
532    if res != TEE_SUCCESS {
533        TEE_Panic(res as u32);
534    }
535}
536
537/// 填充临时对象
538///
539/// 使用指定的属性填充临时对象
540#[unsafe(no_mangle)]
541pub extern "C" fn TEE_PopulateTransientObject(
542    object: TEE_ObjectHandle,
543    attrs: *const TEE_Attribute,
544    attr_count: u32,
545) -> TEE_Result {
546    // 检查属性数组的有效性
547    // 注意:这里简化处理,不进行详细的属性检查
548
549    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
550    let res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) } as TEE_Result;
551
552    if res != TEE_SUCCESS {
553        TEE_Panic(res as u32);
554    }
555
556    // 必须是临时对象(不能是持久化对象)
557    if (info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0 {
558        TEE_Panic(0);
559    }
560
561    // 对象不能已经被初始化
562    if (info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0 {
563        TEE_Panic(0);
564    }
565
566    // 创建临时属性数组并转换属性
567    let mut ua = vec![utee_attribute::default(); attr_count as usize];
568
569    unsafe {
570        __utee_from_attr(ua.as_mut_ptr(), attrs, attr_count);
571    }
572
573    let res = unsafe {
574        _utee_cryp_obj_populate(object as u64, ua.as_mut_ptr(), attr_count as u64) as TEE_Result
575    };
576
577    if res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS {
578        TEE_Panic(res as u32);
579    }
580
581    res
582}
583
584/// 初始化引用属性
585///
586/// 初始化一个引用类型的TEE属性
587#[unsafe(no_mangle)]
588pub extern "C" fn TEE_InitRefAttribute(
589    attr: *mut TEE_Attribute,
590    attribute_id: u32,
591    buffer: *const core::ffi::c_void,
592    length: usize,
593) {
594    // 检查输出参数的有效性
595    if cfg!(feature = "strict_annotation_checks") {
596        let res = TEE_CheckMemoryAccessRights(
597            TEE_MEMORY_ACCESS_WRITE,
598            attr as *mut core::ffi::c_void,
599            std::mem::size_of::<TEE_Attribute>(),
600        );
601        if res != 0 {
602            eprintln!("[out] attr: error {:#010x}", res);
603            TEE_Panic(0);
604        }
605    }
606
607    // 检查属性ID是否为引用类型(不能是值类型)
608    if (attribute_id & TEE_ATTR_FLAG_VALUE) != 0 {
609        TEE_Panic(0);
610    }
611
612    // 初始化属性
613    unsafe {
614        if !attr.is_null() {
615            (*attr).attributeID = attribute_id;
616            (*attr).content.memref.buffer = buffer as *mut core::ffi::c_void;
617            (*attr).content.memref.size = length;
618        }
619    }
620}
621
622/// 初始化值属性
623///
624/// 初始化一个值类型的TEE属性
625#[unsafe(no_mangle)]
626pub extern "C" fn TEE_InitValueAttribute(
627    attr: *mut TEE_Attribute,
628    attribute_id: u32,
629    a: u32,
630    b: u32,
631) {
632    // 检查输出参数的有效性
633    if cfg!(feature = "strict_annotation_checks") {
634        let res = TEE_CheckMemoryAccessRights(
635            TEE_MEMORY_ACCESS_WRITE,
636            attr as *mut core::ffi::c_void,
637            std::mem::size_of::<TEE_Attribute>(),
638        );
639        if res != 0 {
640            eprintln!("[out] attr: error {:#010x}", res);
641            TEE_Panic(0);
642        }
643    }
644
645    // 检查属性ID是否为值类型(必须是值类型)
646    if (attribute_id & TEE_ATTR_FLAG_VALUE) == 0 {
647        TEE_Panic(0);
648    }
649
650    // 初始化属性
651    unsafe {
652        if !attr.is_null() {
653            (*attr).attributeID = attribute_id;
654            (*attr).content.value.a = a;
655            (*attr).content.value.b = b;
656        }
657    }
658}
659
660/// 复制对象属性(已弃用)
661///
662/// 注意:此函数已弃用,新代码应使用 [TEE_CopyObjectAttributes1] 函数
663#[unsafe(no_mangle)]
664pub extern "C" fn TEE_CopyObjectAttributes(
665    dest_object: TEE_ObjectHandle,
666    src_object: TEE_ObjectHandle,
667) {
668    let mut src_info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
669    let _res = unsafe { _utee_cryp_obj_get_info(src_object as u64, &mut src_info) } as TEE_Result;
670
671    // 如果源对象已损坏,则直接返回
672    if src_info.obj_type == TEE_TYPE_CORRUPTED_OBJECT {
673        return;
674    }
675
676    let res = TEE_CopyObjectAttributes1(dest_object, src_object);
677
678    if res != TEE_SUCCESS {
679        TEE_Panic(res as u32);
680    }
681}
682
683/// 复制对象属性
684///
685/// 将源对象的属性复制到目标对象
686#[unsafe(no_mangle)]
687pub extern "C" fn TEE_CopyObjectAttributes1(
688    dest_object: TEE_ObjectHandle,
689    src_object: TEE_ObjectHandle,
690) -> TEE_Result {
691    let mut dst_info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
692    let mut src_info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
693
694    // 获取目标对象信息
695    let mut res =
696        unsafe { _utee_cryp_obj_get_info(dest_object as u64, &mut dst_info) } as TEE_Result;
697
698    if res != TEE_SUCCESS {
699        return check_copy_object_attributes_result(res);
700    }
701
702    // 获取源对象信息
703    res = unsafe { _utee_cryp_obj_get_info(src_object as u64, &mut src_info) } as TEE_Result;
704
705    if res != TEE_SUCCESS {
706        return check_copy_object_attributes_result(res);
707    }
708
709    // 源对象必须已初始化
710    if (src_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
711        TEE_Panic(0);
712    }
713
714    // 目标对象不能是持久化对象
715    if (dst_info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0 {
716        TEE_Panic(0);
717    }
718
719    // 目标对象不能已经被初始化
720    if (dst_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0 {
721        TEE_Panic(0);
722    }
723
724    // 执行对象属性复制
725    res = unsafe { _utee_cryp_obj_copy(dest_object as u64, src_object as u64) } as TEE_Result;
726
727    check_copy_object_attributes_result(res)
728}
729
730/// 检查复制对象属性的结果
731fn check_copy_object_attributes_result(res: TEE_Result) -> TEE_Result {
732    if res != TEE_SUCCESS
733        && res != TEE_ERROR_CORRUPT_OBJECT
734        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
735    {
736        TEE_Panic(res as u32);
737    }
738
739    res
740}
741
742/// 生成密钥
743///
744/// 为指定对象生成密钥
745#[unsafe(no_mangle)]
746pub extern "C" fn TEE_GenerateKey(
747    object: TEE_ObjectHandle,
748    key_size: u32,
749    params: *const TEE_Attribute,
750    param_count: u32,
751) -> TEE_Result {
752    // 检查属性参数的有效性
753    if cfg!(feature = "strict_annotation_checks") && param_count > 0 {
754        let res = TEE_CheckMemoryAccessRights(
755            TEE_MEMORY_ACCESS_READ,
756            params as *mut core::ffi::c_void,
757            std::mem::size_of::<TEE_Attribute>() * param_count as usize,
758        );
759        if res != 0 {
760            eprintln!("[in] attrs: error {:#010x}", res);
761            TEE_Panic(0);
762        }
763    }
764
765    // 创建临时属性数组并转换属性
766    let mut ua = vec![utee_attribute::default(); param_count as usize];
767
768    unsafe {
769        __utee_from_attr(ua.as_mut_ptr(), params, param_count);
770    }
771
772    let res = unsafe {
773        _utee_cryp_obj_generate_key(
774            object as u64,
775            key_size as u64,
776            ua.as_ptr(),
777            param_count as u64,
778        )
779    } as TEE_Result;
780
781    if res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS {
782        TEE_Panic(res as u32);
783    }
784
785    res
786}
787
788/// 打开持久化对象
789///
790/// 打开一个持久化存储对象
791#[unsafe(no_mangle)]
792pub extern "C" fn TEE_OpenPersistentObject(
793    storage_id: u32,
794    object_id: *const core::ffi::c_void,
795    object_id_len: usize,
796    flags: u32,
797    object: *mut TEE_ObjectHandle,
798) -> TEE_Result {
799    // 检查输出参数的有效性
800    if cfg!(feature = "strict_annotation_checks") {
801        let res = TEE_CheckMemoryAccessRights(
802            TEE_MEMORY_ACCESS_WRITE,
803            object as *mut core::ffi::c_void,
804            std::mem::size_of::<TEE_ObjectHandle>(),
805        );
806        if res != 0 {
807            eprintln!("[out] object: error {:#010x}", res);
808            TEE_Panic(0);
809        }
810    }
811
812    let mut obj: u32 = 0;
813
814    let res = unsafe {
815        _utee_storage_obj_open(
816            storage_id as u64,
817            object_id,
818            object_id_len,
819            flags as u64,
820            &mut obj,
821        )
822    } as TEE_Result;
823
824    // 如果成功,将对象句柄写入输出参数
825    if res == TEE_SUCCESS {
826        unsafe {
827            *object = obj as TEE_ObjectHandle;
828        }
829    } else {
830        // 如果失败,将对象句柄设置为NULL
831        unsafe {
832            *object = core::ptr::null_mut();
833        }
834    }
835
836    // 检查返回结果是否为非预期错误
837    if res != TEE_SUCCESS
838        && res != TEE_ERROR_ITEM_NOT_FOUND
839        && res != TEE_ERROR_ACCESS_CONFLICT
840        && res != TEE_ERROR_OUT_OF_MEMORY
841        && res != TEE_ERROR_CORRUPT_OBJECT
842        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
843    {
844        TEE_Panic(res as u32);
845    }
846
847    res
848}
849
850/// 创建持久化对象
851///
852/// 创建一个持久化存储对象
853#[unsafe(no_mangle)]
854pub extern "C" fn TEE_CreatePersistentObject(
855    storage_id: u32,
856    object_id: *const core::ffi::c_void,
857    object_id_len: usize,
858    flags: u32,
859    attributes: TEE_ObjectHandle,
860    initial_data: *const core::ffi::c_void,
861    initial_data_len: usize,
862    object: *mut TEE_ObjectHandle,
863) -> TEE_Result {
864    let mut obj: u32 = 0;
865    let obj_ptr: *mut u32;
866
867    // 检查输出参数的有效性
868    if !object.is_null() {
869        if cfg!(feature = "strict_annotation_checks") {
870            let res = TEE_CheckMemoryAccessRights(
871                TEE_MEMORY_ACCESS_WRITE,
872                object as *mut core::ffi::c_void,
873                std::mem::size_of::<TEE_ObjectHandle>(),
874            );
875            if res != 0 {
876                eprintln!("[out] object: error {:#010x}", res);
877                TEE_Panic(0);
878            }
879        }
880        obj_ptr = &mut obj;
881    } else {
882        obj_ptr = core::ptr::null_mut();
883    }
884
885    let res = unsafe {
886        _utee_storage_obj_create(
887            storage_id as u64,
888            object_id,
889            object_id_len,
890            flags as u64,
891            attributes as u64,
892            initial_data,
893            initial_data_len,
894            obj_ptr,
895        )
896    } as TEE_Result;
897
898    // 如果成功且输出参数不为空,将对象句柄写入输出参数
899    if res == TEE_SUCCESS && !object.is_null() {
900        unsafe {
901            *object = obj as TEE_ObjectHandle;
902        }
903    } else if res != TEE_SUCCESS && !object.is_null() {
904        // 如果失败且输出参数不为空,将对象句柄设置为NULL
905        unsafe {
906            *object = core::ptr::null_mut();
907        }
908    }
909
910    // 检查返回结果是否为非预期错误
911    if res != TEE_SUCCESS
912        && res != TEE_ERROR_ITEM_NOT_FOUND
913        && res != TEE_ERROR_ACCESS_CONFLICT
914        && res != TEE_ERROR_OUT_OF_MEMORY
915        && res != TEE_ERROR_STORAGE_NO_SPACE
916        && res != TEE_ERROR_CORRUPT_OBJECT
917        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
918    {
919        TEE_Panic(res as u32);
920    }
921
922    res
923}
924
925/// 关闭并删除持久化对象(已弃用)
926///
927/// 注意:此函数已弃用,新代码应使用 [TEE_CloseAndDeletePersistentObject1] 函数
928#[unsafe(no_mangle)]
929pub extern "C" fn TEE_CloseAndDeletePersistentObject(object: TEE_ObjectHandle) {
930    // 检查是否为NULL句柄
931    if object.is_null() {
932        return;
933    }
934
935    let res = TEE_CloseAndDeletePersistentObject1(object);
936
937    if res != TEE_SUCCESS {
938        TEE_Panic(0);
939    }
940}
941
942/// 关闭并删除持久化对象
943///
944/// 关闭并删除指定的持久化对象
945#[unsafe(no_mangle)]
946pub extern "C" fn TEE_CloseAndDeletePersistentObject1(object: TEE_ObjectHandle) -> TEE_Result {
947    // 检查是否为NULL句柄
948    if object.is_null() {
949        return TEE_SUCCESS;
950    }
951
952    let res = unsafe { _utee_storage_obj_del(object as u64) } as TEE_Result;
953
954    // 检查返回结果是否为非预期错误
955    if res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE {
956        TEE_Panic(res as u32);
957    }
958
959    res
960}
961
962/// 重命名持久化对象
963///
964/// 将指定的持久化对象重命名
965#[unsafe(no_mangle)]
966pub extern "C" fn TEE_RenamePersistentObject(
967    object: TEE_ObjectHandle,
968    _new_object_id: *const core::ffi::c_void,
969    _new_object_id_len: usize,
970) -> TEE_Result {
971    // 检查对象句柄是否为空
972    let res = if object.is_null() {
973        TEE_ERROR_ITEM_NOT_FOUND
974    } else {
975        // 调用底层系统调用进行重命名
976        // unsafe {
977        //     _utee_storage_obj_rename(object as u64, new_object_id, new_object_id_len) as TEE_Result
978        // }
979        TEE_ERROR_ITEM_NOT_FOUND
980    };
981
982    // 检查返回结果,如果不是预期的错误类型则panic
983    if res != TEE_SUCCESS
984        && res != TEE_ERROR_ACCESS_CONFLICT
985        && res != TEE_ERROR_CORRUPT_OBJECT
986        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
987    {
988        TEE_Panic(res as u32);
989    }
990
991    res
992}
993
994/// 分配持久化对象枚举器
995///
996/// 分配一个新的持久化对象枚举器句柄
997#[unsafe(no_mangle)]
998pub extern "C" fn TEE_AllocatePersistentObjectEnumerator(
999    object_enumerator: *mut TEE_ObjectEnumHandle,
1000) -> TEE_Result {
1001    // 检查输出参数的有效性
1002    if cfg!(feature = "strict_annotation_checks") {
1003        let res = TEE_CheckMemoryAccessRights(
1004            TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
1005            object_enumerator as *mut core::ffi::c_void,
1006            std::mem::size_of::<TEE_ObjectEnumHandle>(),
1007        );
1008        if res != 0 {
1009            eprintln!("[out] objectEnumerator: error {:#010x}", res);
1010            TEE_Panic(0);
1011        }
1012    }
1013
1014    let mut oe: u32 = 0;
1015
1016    let res = unsafe { _utee_storage_alloc_enum(&mut oe) } as TEE_Result;
1017
1018    // 如果失败,将枚举器句柄设置为NULL
1019    if res != TEE_SUCCESS {
1020        oe = TEE_HANDLE_NULL as u32;
1021    }
1022
1023    // 将枚举器句柄写入输出参数
1024    unsafe {
1025        *object_enumerator = oe as TEE_ObjectEnumHandle;
1026    }
1027
1028    // 检查返回结果,如果不是预期的错误类型则panic
1029    if res != TEE_SUCCESS && res != TEE_ERROR_ACCESS_CONFLICT {
1030        TEE_Panic(res as u32);
1031    }
1032
1033    res
1034}
1035
1036/// 释放持久化对象枚举器
1037///
1038/// 释放指定的持久化对象枚举器句柄
1039#[unsafe(no_mangle)]
1040pub extern "C" fn TEE_FreePersistentObjectEnumerator(object_enumerator: TEE_ObjectEnumHandle) {
1041    // 检查枚举器句柄是否为空
1042    if object_enumerator.is_null() {
1043        return;
1044    }
1045
1046    let res = unsafe { _utee_storage_free_enum(object_enumerator as u64) } as TEE_Result;
1047
1048    // 检查返回结果,如果不是成功则panic
1049    if res != TEE_SUCCESS {
1050        TEE_Panic(res as u32);
1051    }
1052}
1053
1054/// 重置持久化对象枚举器
1055///
1056/// 重置指定的持久化对象枚举器句柄
1057#[unsafe(no_mangle)]
1058pub extern "C" fn TEE_ResetPersistentObjectEnumerator(object_enumerator: TEE_ObjectEnumHandle) {
1059    // 检查枚举器句柄是否为空
1060    if object_enumerator.is_null() {
1061        return;
1062    }
1063
1064    let res = unsafe { _utee_storage_reset_enum(object_enumerator as u64) } as TEE_Result;
1065
1066    // 检查返回结果,如果不是成功则panic
1067    if res != TEE_SUCCESS {
1068        TEE_Panic(res as u32);
1069    }
1070}
1071
1072/// 开始持久化对象枚举
1073///
1074/// 开始枚举指定存储空间中的持久化对象
1075#[unsafe(no_mangle)]
1076pub extern "C" fn TEE_StartPersistentObjectEnumerator(
1077    object_enumerator: TEE_ObjectEnumHandle,
1078    storage_id: u32,
1079) -> TEE_Result {
1080    let res = unsafe {
1081        _utee_storage_start_enum(object_enumerator as u64, storage_id as u64) as TEE_Result
1082    };
1083
1084    // 检查返回结果,如果不是预期的错误类型则panic
1085    if res != TEE_SUCCESS
1086        && res != TEE_ERROR_ITEM_NOT_FOUND
1087        && res != TEE_ERROR_CORRUPT_OBJECT
1088        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
1089    {
1090        TEE_Panic(res);
1091    }
1092
1093    res
1094}
1095
1096/// 获取下一个持久化对象
1097///
1098/// 从枚举器中获取下一个持久化对象的信息和ID
1099#[unsafe(no_mangle)]
1100pub extern "C" fn TEE_GetNextPersistentObject(
1101    object_enumerator: TEE_ObjectEnumHandle,
1102    object_info: *mut TEE_ObjectInfo,
1103    object_id: *mut core::ffi::c_void,
1104    object_id_len: *mut usize,
1105) -> TEE_Result {
1106    // 检查参数有效性
1107    if cfg!(feature = "strict_annotation_checks") {
1108        // 检查 object_info 参数(如果非空)
1109        if !object_info.is_null() {
1110            let res = TEE_CheckMemoryAccessRights(
1111                TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
1112                object_info as *mut core::ffi::c_void,
1113                std::mem::size_of::<TEE_ObjectInfo>(),
1114            );
1115            if res != 0 {
1116                eprintln!("[out] objectInfo: error {:#010x}", res);
1117                TEE_Panic(0);
1118            }
1119        }
1120
1121        // 检查 object_id_len 参数
1122        let res = TEE_CheckMemoryAccessRights(
1123            TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
1124            object_id_len as *mut core::ffi::c_void,
1125            std::mem::size_of::<usize>(),
1126        );
1127        if res != 0 {
1128            eprintln!("[out] objectIDLen: error {:#010x}", res);
1129            TEE_Panic(0);
1130        }
1131    }
1132
1133    // 检查必要参数是否为空
1134    if object_id.is_null() {
1135        return TEE_ERROR_BAD_PARAMETERS;
1136    }
1137
1138    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
1139    let mut len: u64 = 0;
1140
1141    unsafe {
1142        if !object_id_len.is_null() {
1143            len = *object_id_len as u64;
1144        }
1145    }
1146
1147    let res = unsafe {
1148        _utee_storage_next_enum(object_enumerator as u64, &mut info, object_id, &mut len)
1149    } as TEE_Result;
1150
1151    // 如果提供了object_info参数,复制对象信息
1152    if !object_info.is_null() {
1153        unsafe {
1154            (*object_info).objectType = info.obj_type;
1155            (*object_info).objectSize = info.obj_size;
1156            (*object_info).maxObjectSize = info.max_obj_size;
1157            (*object_info).objectUsage = info.obj_usage;
1158            (*object_info).dataSize = info.data_size as usize;
1159            (*object_info).dataPosition = info.data_pos as usize;
1160            (*object_info).handleFlags = info.handle_flags;
1161        }
1162    }
1163
1164    // 更新objectIDLen
1165    unsafe {
1166        if !object_id_len.is_null() {
1167            *object_id_len = len as usize;
1168        }
1169    }
1170
1171    // 检查返回结果,如果不是预期的错误类型则panic
1172    if res != TEE_SUCCESS
1173        && res != TEE_ERROR_ITEM_NOT_FOUND
1174        && res != TEE_ERROR_CORRUPT_OBJECT
1175        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
1176    {
1177        TEE_Panic(res as u32);
1178    }
1179
1180    res
1181}
1182
1183/// 读取对象数据
1184///
1185/// 从持久化对象中读取数据
1186#[unsafe(no_mangle)]
1187pub extern "C" fn TEE_ReadObjectData(
1188    object: TEE_ObjectHandle,
1189    buffer: *mut core::ffi::c_void,
1190    size: usize,
1191    count: *mut usize,
1192) -> TEE_Result {
1193    // 检查对象句柄是否为空
1194    if object.is_null() {
1195        return TEE_ERROR_BAD_PARAMETERS;
1196    }
1197
1198    // 检查参数有效性
1199    if cfg!(feature = "strict_annotation_checks") {
1200        let res = TEE_CheckMemoryAccessRights(
1201            TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
1202            count as *mut core::ffi::c_void,
1203            std::mem::size_of::<usize>(),
1204        );
1205        if res != 0 {
1206            eprintln!("[out] count: error {:#010x}", res);
1207            TEE_Panic(0);
1208        }
1209    }
1210
1211    let mut cnt64: u64 = 0;
1212    unsafe {
1213        if !count.is_null() {
1214            cnt64 = *count as u64;
1215        }
1216    }
1217
1218    let res =
1219        unsafe { _utee_storage_obj_read(object as u64, buffer, size, &mut cnt64) } as TEE_Result;
1220
1221    // 更新count值
1222    unsafe {
1223        if !count.is_null() {
1224            *count = cnt64 as usize;
1225        }
1226    }
1227
1228    // 检查返回结果,如果不是预期的错误类型则panic
1229    if res != TEE_SUCCESS
1230        && res != TEE_ERROR_CORRUPT_OBJECT
1231        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
1232    {
1233        TEE_Panic(res as u32);
1234    }
1235
1236    res
1237}
1238
1239/// 写入对象数据
1240///
1241/// 向持久化对象写入数据
1242#[unsafe(no_mangle)]
1243pub extern "C" fn TEE_WriteObjectData(
1244    object: TEE_ObjectHandle,
1245    buffer: *const core::ffi::c_void,
1246    size: usize,
1247) -> TEE_Result {
1248    // 检查对象句柄是否为空
1249    if object.is_null() {
1250        return TEE_ERROR_BAD_PARAMETERS;
1251    }
1252
1253    // 检查数据大小是否超过最大限制
1254    if size > TEE_DATA_MAX_POSITION as usize {
1255        return TEE_ERROR_OVERFLOW;
1256    }
1257
1258    // 检查参数有效性
1259    if cfg!(feature = "strict_annotation_checks") && size > 0 && !buffer.is_null() {
1260        let res = TEE_CheckMemoryAccessRights(
1261            TEE_MEMORY_ACCESS_READ,
1262            buffer as *mut core::ffi::c_void,
1263            size,
1264        );
1265        if res != 0 {
1266            eprintln!("[in] buffer: error {:#010x}", res);
1267            TEE_Panic(0);
1268        }
1269    }
1270
1271    let res = unsafe { _utee_storage_obj_write(object as u64, buffer, size) } as TEE_Result;
1272
1273    // 检查返回结果,如果不是预期的错误类型则panic
1274    if res != TEE_SUCCESS
1275        && res != TEE_ERROR_STORAGE_NO_SPACE
1276        && res != TEE_ERROR_OVERFLOW
1277        && res != TEE_ERROR_CORRUPT_OBJECT
1278        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
1279    {
1280        TEE_Panic(res as u32);
1281    }
1282
1283    res
1284}
1285
1286/// 截断对象数据
1287///
1288/// 截断持久化对象的数据到指定大小
1289#[unsafe(no_mangle)]
1290pub extern "C" fn TEE_TruncateObjectData(object: TEE_ObjectHandle, size: usize) -> TEE_Result {
1291    // 检查对象句柄是否为空
1292    if object.is_null() {
1293        return TEE_ERROR_BAD_PARAMETERS;
1294    }
1295
1296    let res = unsafe {
1297        _utee_storage_obj_trunc(
1298            object as u64,
1299            size, // 直接使用 usize,不需要转换为 u64
1300        )
1301    } as TEE_Result;
1302
1303    // 检查返回结果,如果不是预期的错误类型则panic
1304    if res != TEE_SUCCESS
1305        && res != TEE_ERROR_STORAGE_NO_SPACE
1306        && res != TEE_ERROR_CORRUPT_OBJECT
1307        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
1308    {
1309        TEE_Panic(res as u32);
1310    }
1311
1312    res
1313}
1314
1315/// 寻找对象数据
1316///
1317/// 设置持久化对象的数据访问位置
1318/// 寻找对象数据
1319///
1320/// 设置持久化对象的数据访问位置
1321#[unsafe(no_mangle)]
1322pub extern "C" fn TEE_SeekObjectData(
1323    object: TEE_ObjectHandle,
1324    offset: i64, // intmax_t 对应 i64
1325    whence: TEE_Whence,
1326) -> TEE_Result {
1327    // 检查对象句柄是否为空
1328    if object.is_null() {
1329        return TEE_ERROR_BAD_PARAMETERS;
1330    }
1331
1332    // 获取对象信息
1333    let mut info = unsafe { std::mem::zeroed::<crate::utee_types::utee_object_info>() };
1334    let mut res = unsafe { _utee_cryp_obj_get_info(object as u64, &mut info) as TEE_Result };
1335
1336    if res != TEE_SUCCESS {
1337        return res;
1338    }
1339
1340    // 保存whence的转换值,避免移动错误
1341    let whence_u32 = whence as u32;
1342    let whence_u64 = whence as u64;
1343
1344    // 检查偏移量和寻址方式
1345    match whence_u32 {
1346        TEE_DATA_SEEK_SET => {
1347            if offset > 0 && offset as u32 > TEE_DATA_MAX_POSITION {
1348                return TEE_ERROR_OVERFLOW;
1349            }
1350        }
1351        TEE_DATA_SEEK_CUR => {
1352            if offset > 0
1353                && (offset as u32 + info.data_pos > TEE_DATA_MAX_POSITION as u32
1354                    || offset as u32 + info.data_pos < info.data_pos)
1355            {
1356                return TEE_ERROR_OVERFLOW;
1357            }
1358        }
1359        TEE_DATA_SEEK_END => {
1360            if offset > 0
1361                && (offset as u32 + info.data_size > TEE_DATA_MAX_POSITION as u32
1362                    || offset as u32 + info.data_size < info.data_size)
1363            {
1364                return TEE_ERROR_OVERFLOW;
1365            }
1366        }
1367        _ => {
1368            return TEE_ERROR_ITEM_NOT_FOUND;
1369        }
1370    }
1371
1372    // 执行寻址操作
1373    res = unsafe { _utee_storage_obj_seek(object as u64, offset as i32, whence_u64) as TEE_Result };
1374
1375    // 检查返回结果,如果不是预期的错误类型则panic
1376    if res != TEE_SUCCESS
1377        && res != TEE_ERROR_OVERFLOW
1378        && res != TEE_ERROR_CORRUPT_OBJECT
1379        && res != TEE_ERROR_STORAGE_NOT_AVAILABLE
1380    {
1381        TEE_Panic(res as u32);
1382    }
1383
1384    res
1385}