Skip to main content

rust_utee/api/
tee_api_property.rs

1use crate::api::tee_api_mm::TEE_Free;
2use crate::api::tee_api_mm::TEE_Malloc;
3use crate::tee_api_defines::*;
4use crate::tee_api_types::*;
5use core::ffi::c_void;
6use core::ffi::*;
7use libc::strlen;
8use mbedtls_sys_auto::base64_decode;
9use mbedtls_sys_auto::base64_encode;
10use std::ptr;
11use std::ptr::null_mut;
12
13use crate::api::tee_api_panic::TEE_Panic;
14use crate::syscalls::syscall_table::{_utee_get_property, _utee_get_property_name_to_index};
15use core::mem;
16
17#[repr(C)]
18#[derive(Copy, Clone, PartialEq, Debug)]
19pub enum UserTaPropType {
20    USER_TA_PROP_TYPE_BOOL,         /* bool */
21    USER_TA_PROP_TYPE_U32,          /* uint32_t */
22    USER_TA_PROP_TYPE_UUID,         /* TEE_UUID */
23    USER_TA_PROP_TYPE_IDENTITY,     /* TEE_Identity */
24    USER_TA_PROP_TYPE_STRING,       /* zero terminated string of char */
25    USER_TA_PROP_TYPE_BINARY_BLOCK, /* zero terminated base64 coded string */
26    USER_TA_PROP_TYPE_U64,          /* uint64_t */
27    USER_TA_PROP_TYPE_INVALID,      /* invalid value */
28}
29
30#[repr(C)]
31pub struct UserTaProperty {
32    pub name: *const c_char,
33    pub prop_type: UserTaPropType,
34    pub value: *mut c_void,
35}
36
37unsafe impl Sync for UserTaProperty {}
38
39#[cfg(feature = "ta_props_empty_impl")]
40#[unsafe(no_mangle)]
41pub static ta_num_props: usize = 0;
42#[cfg(feature = "ta_props_empty_impl")]
43#[unsafe(no_mangle)]
44pub static ta_props: UserTaProperty = UserTaProperty {
45    name: core::ptr::null(),
46    prop_type: UserTaPropType::USER_TA_PROP_TYPE_INVALID,
47    value: core::ptr::null_mut(),
48};
49
50// Defined by the final TA crate (link-time symbols), not by rust-libutee.
51#[cfg(not(feature = "ta_props_empty_impl"))]
52unsafe extern "C" {
53    static ta_num_props: usize;
54    static ta_props: UserTaProperty;
55}
56
57#[repr(C)]
58struct PropEnumerator {
59    idx: u32,
60    prop_set: TEE_PropSetHandle,
61}
62
63//TODO: this need to be a config option
64pub const CFG_TA_BIGNUM_MAX_BITS: u32 = 2048;
65pub const TEE_ISOCKET_VERSION: u32 = 0x01000000;
66pub const PROP_ENUMERATOR_NOT_STARTED: u32 = 0xffffffff;
67pub const TEE_USER_MEM_HINT_NO_FILL_ZERO: u32 = 0x80000000;
68
69pub const TEE_CORE_API_MAJOR_VERSION: u32 = 1;
70pub const TEE_CORE_API_MINOR_VERSION: u32 = 3;
71pub const TEE_CORE_API_MAINTENANCE_VERSION: u32 = 1;
72pub const MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL: i32 = -0x002A_i32;
73
74pub const TEE_CORE_API_VERSION: u32 = (TEE_CORE_API_MAJOR_VERSION << 24)
75    | (TEE_CORE_API_MINOR_VERSION << 16)
76    | (TEE_CORE_API_MAINTENANCE_VERSION << 8);
77
78#[unsafe(no_mangle)]
79pub static tee_props: [UserTaProperty; 4usize] = [
80    UserTaProperty {
81        name: "gpd.tee.arith.maxBigIntSize\0".as_ptr() as _,
82        prop_type: UserTaPropType::USER_TA_PROP_TYPE_U32,
83        value: &CFG_TA_BIGNUM_MAX_BITS as *const u32 as *mut _,
84    },
85    UserTaProperty {
86        name: "gpd.tee.sockets.version\0".as_ptr() as _,
87        prop_type: UserTaPropType::USER_TA_PROP_TYPE_U32,
88        value: &TEE_ISOCKET_VERSION as *const u32 as *mut _,
89    },
90    UserTaProperty {
91        name: "gpd.tee.sockets.tcp.version\0".as_ptr() as _,
92        prop_type: UserTaPropType::USER_TA_PROP_TYPE_U32,
93        value: &TEE_ISOCKET_VERSION as *const u32 as *mut _,
94    },
95    UserTaProperty {
96        name: "gpd.tee.internalCore.version\0".as_ptr() as _,
97        prop_type: UserTaPropType::USER_TA_PROP_TYPE_U32,
98        value: &TEE_CORE_API_VERSION as *const u32 as *mut _,
99    },
100];
101
102fn is_propset_pseudo_handle(h: TEE_PropSetHandle) -> bool {
103    h == TEE_PROPSET_CURRENT_TA
104        || h == TEE_PROPSET_CURRENT_CLIENT
105        || h == TEE_PROPSET_TEE_IMPLEMENTATION
106}
107
108fn propset_get(
109    h: TEE_PropSetHandle,
110    eps: *mut *const UserTaProperty,
111    eps_len: *mut usize,
112) -> TEE_Result {
113    unsafe {
114        match h {
115            TEE_PROPSET_CURRENT_TA => {
116                *eps = core::ptr::addr_of!(ta_props);
117                *eps_len = ta_num_props;
118            }
119            TEE_PROPSET_CURRENT_CLIENT => {
120                *eps = core::ptr::null();
121                *eps_len = 0;
122            }
123            TEE_PROPSET_TEE_IMPLEMENTATION => {
124                *eps = tee_props.as_ptr();
125                *eps_len = tee_props.len();
126            }
127            _ => {
128                return TEE_ERROR_ITEM_NOT_FOUND;
129            }
130        }
131    }
132    TEE_SUCCESS
133}
134
135#[inline]
136pub unsafe fn base64_dec(
137    src: *const libc::c_char,
138    src_len: usize,
139    dst: *mut u8,
140    dst_len: &mut usize,
141) -> bool {
142    let mut out_len: usize = 0;
143
144    let ret = unsafe { base64_decode(dst, *dst_len, &mut out_len, src as *const u8, src_len) };
145
146    *dst_len = out_len;
147
148    ret == 0 || ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
149}
150
151#[inline]
152pub unsafe fn base64_enc(
153    src: *const c_char,
154    src_len: usize,
155    dst: *mut u8,
156    dst_len: &mut usize,
157) -> bool {
158    let mut out_len: usize = 0;
159
160    let ret = unsafe { base64_encode(dst, *dst_len, &mut out_len, src as *const u8, src_len) };
161
162    *dst_len = out_len;
163
164    ret == 0 || ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
165}
166
167unsafe fn propget_get_ext_prop(
168    prop: *const UserTaProperty,
169    prop_type: *mut UserTaPropType,
170    buf: *mut c_void,
171    len: *mut c_uint,
172) -> TEE_Result {
173    let prop = unsafe { &*prop };
174    unsafe { *prop_type = prop.prop_type };
175    let l: usize = match prop.prop_type {
176        UserTaPropType::USER_TA_PROP_TYPE_BOOL => mem::size_of::<bool>(),
177        UserTaPropType::USER_TA_PROP_TYPE_U32 => mem::size_of::<u32>(),
178        UserTaPropType::USER_TA_PROP_TYPE_UUID => mem::size_of::<TEE_UUID>(),
179        UserTaPropType::USER_TA_PROP_TYPE_U64 => mem::size_of::<u64>(),
180        UserTaPropType::USER_TA_PROP_TYPE_IDENTITY => mem::size_of::<TEE_Identity>(),
181        UserTaPropType::USER_TA_PROP_TYPE_STRING => unsafe {
182            strlen(prop.value as *const c_char) + 1
183        },
184        UserTaPropType::USER_TA_PROP_TYPE_BINARY_BLOCK => {
185            let mut out_len = unsafe { *len as usize };
186            let ok = unsafe {
187                base64_dec(
188                    prop.value as *const c_char,
189                    strlen(prop.value as *const c_char),
190                    buf as *mut u8,
191                    &mut out_len,
192                )
193            };
194            if !ok && out_len <= unsafe { *len as usize } {
195                return TEE_ERROR_GENERIC;
196            }
197            if unsafe { *len as usize } < out_len {
198                unsafe { *len = out_len as u32 };
199                return TEE_ERROR_SHORT_BUFFER;
200            }
201            unsafe { *len = out_len as u32 };
202            TEE_SUCCESS as usize
203        }
204        _ => TEE_ERROR_GENERIC as usize,
205    };
206    if unsafe { *len as usize } < l {
207        unsafe { *len = l as u32 };
208        return TEE_ERROR_SHORT_BUFFER;
209    }
210
211    unsafe { ptr::copy(prop.value as *const u8, buf as *mut u8, l) };
212
213    TEE_SUCCESS
214}
215
216unsafe fn propget_get_property(
217    h: TEE_PropSetHandle,
218    name: *const c_char,
219    prop_type_out: *mut UserTaPropType,
220    buf: *mut c_void,
221    len: *mut c_uint,
222) -> TEE_Result {
223    let mut eps: *const UserTaProperty = core::ptr::null();
224    let mut eps_len: usize = 0;
225    let mut prop_type: u32 = 0;
226    let mut index: u32 = 0;
227
228    if is_propset_pseudo_handle(h) {
229        let res = propset_get(h, &mut eps, &mut eps_len);
230        if res != TEE_SUCCESS {
231            return res;
232        }
233        for n in 0..eps_len {
234            let prop = unsafe { &*eps.add(n) };
235            let s1 = unsafe { CStr::from_ptr(name).to_str().ok().unwrap() };
236            let s2 = unsafe { CStr::from_ptr(prop.name).to_str().ok().unwrap() };
237            if s1 == s2 {
238                return unsafe { propget_get_ext_prop(prop, prop_type_out, buf, len) };
239            }
240        }
241
242        let res = unsafe {
243            _utee_get_property_name_to_index(
244                h as u64,
245                name as *const c_void,
246                strlen(name) as u64 + 1,
247                &mut index,
248            )
249        };
250        if res != (TEE_SUCCESS as usize) {
251            return res as u32;
252        }
253
254        let res = unsafe {
255            _utee_get_property(
256                h as u64,
257                index as u64,
258                null_mut(),
259                null_mut(),
260                buf,
261                len,
262                &mut prop_type,
263            )
264        };
265
266        if prop_type_out.is_null() {
267            return res as u32;
268        }
269
270        unsafe { *prop_type_out = core::mem::transmute(prop_type) };
271        return res as u32;
272    }
273
274    let pe = unsafe { &*(h as *const PropEnumerator) };
275    let mut idx = pe.idx;
276    if idx == PROP_ENUMERATOR_NOT_STARTED {
277        return TEE_ERROR_ITEM_NOT_FOUND;
278    }
279
280    let res = propset_get(pe.prop_set, &mut eps, &mut eps_len);
281    if res != TEE_SUCCESS {
282        return res;
283    }
284
285    if (idx as usize) < eps_len {
286        return unsafe { propget_get_ext_prop(&*eps.add(idx as usize), prop_type_out, buf, len) };
287    }
288    idx -= eps_len as u32;
289
290    let res = unsafe {
291        _utee_get_property(
292            pe.prop_set as u64,
293            idx as u64,
294            null_mut(),
295            null_mut(),
296            buf,
297            len,
298            &mut prop_type,
299        )
300    };
301
302    let res = if res == (TEE_ERROR_ITEM_NOT_FOUND as usize) {
303        TEE_ERROR_BAD_PARAMETERS
304    } else {
305        res as u32
306    };
307
308    if !prop_type_out.is_null() {
309        unsafe { *prop_type_out = core::mem::transmute(prop_type) };
310    }
311
312    res
313}
314
315fn handle_result(res: TEE_Result, tmp_buf: *mut c_void) -> TEE_Result {
316    if !tmp_buf.is_null() {
317        TEE_Free(tmp_buf);
318    }
319    if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_ITEM_NOT_FOUND {
320        TEE_Panic(0);
321    }
322    res
323}
324fn base64_enc_len(n: usize) -> usize {
325    let enc = ((n + 2) / 3) * 4;
326    enc + 1
327}
328
329fn copy_string(src: &str, dst: *mut u8) -> Result<usize, ()> {
330    unsafe {
331        core::ptr::copy_nonoverlapping(src.as_ptr(), dst, src.len());
332    }
333
334    Ok(src.len())
335}
336
337fn copy_constu8_string(src: *const u8, dst: *mut u8) -> Result<usize, ()> {
338    let c_str = unsafe { core::ffi::CStr::from_ptr(src as _) };
339    unsafe {
340        core::ptr::copy_nonoverlapping(src, dst, c_str.to_bytes().len());
341    }
342
343    Ok(c_str.to_bytes().len())
344}
345#[unsafe(no_mangle)]
346pub extern "C" fn TEE_GetPropertyAsString(
347    propset_or_enumerator: TEE_PropSetHandle,
348    name: *const c_char,
349    value: *mut c_char,
350    value_len: *mut usize,
351) -> TEE_Result {
352    let mut res;
353    let tmp_len = if unsafe { *value_len } < mem::size_of::<TEE_Identity>() {
354        mem::size_of::<TEE_Identity>()
355    } else {
356        unsafe { *value_len }
357    };
358    let tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO);
359    if tmp_buf.is_null() {
360        res = TEE_ERROR_OUT_OF_MEMORY;
361        return handle_result(res, tmp_buf);
362    }
363
364    let mut tmp_len_var: u32 = tmp_len as u32;
365    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_INVALID;
366    res = unsafe {
367        propget_get_property(
368            propset_or_enumerator,
369            name,
370            &mut prop_type,
371            tmp_buf,
372            &mut tmp_len_var,
373        )
374    };
375    if res != TEE_SUCCESS {
376        if res == TEE_ERROR_SHORT_BUFFER {
377            if prop_type == UserTaPropType::USER_TA_PROP_TYPE_BINARY_BLOCK {
378                unsafe { *value_len = base64_enc_len(tmp_len_var as usize) };
379            } else {
380                unsafe { *value_len = tmp_len_var as usize };
381            }
382        }
383        return handle_result(res, tmp_buf);
384    }
385
386    let l = match prop_type {
387        UserTaPropType::USER_TA_PROP_TYPE_BOOL => {
388            let bool_value = unsafe { *(tmp_buf as *const bool) };
389            let s = if bool_value { "true" } else { "false" };
390            copy_string(s, value as _).unwrap()
391        }
392        UserTaPropType::USER_TA_PROP_TYPE_U32 => {
393            let u32_value = unsafe { *(tmp_buf as *const u32) };
394            copy_string(&format!("{}", u32_value), value as _).unwrap()
395        }
396        UserTaPropType::USER_TA_PROP_TYPE_UUID => {
397            let uuid_value = unsafe { *(tmp_buf as *const TEE_UUID) };
398            copy_string(&format!("{}", uuid_value), value as _).unwrap()
399        }
400        UserTaPropType::USER_TA_PROP_TYPE_IDENTITY => {
401            let identity_value = unsafe { *(tmp_buf as *const TEE_Identity) };
402            copy_string(
403                &format!("{}:{}", identity_value.login, identity_value.uuid),
404                value as _,
405            )
406            .unwrap()
407        }
408        UserTaPropType::USER_TA_PROP_TYPE_STRING => {
409            let string_value = tmp_buf as *const c_char;
410            let c_string_value = unsafe { CStr::from_ptr(string_value).to_str().unwrap() };
411
412            copy_string(c_string_value, value as _).unwrap()
413        }
414        UserTaPropType::USER_TA_PROP_TYPE_BINARY_BLOCK => {
415            let mut tmp_l = unsafe { *value_len };
416            if unsafe {
417                !base64_enc(tmp_buf as *mut c_char, tmp_len, value as _, &mut tmp_l)
418                    && tmp_l <= *value_len
419            } {
420                res = TEE_ERROR_GENERIC;
421                return handle_result(res, tmp_buf);
422            }
423            tmp_l
424        }
425        _ => {
426            res = TEE_ERROR_BAD_FORMAT;
427            return handle_result(res, tmp_buf);
428        }
429    };
430
431    if l > unsafe { *value_len } {
432        res = TEE_ERROR_SHORT_BUFFER;
433    }
434    unsafe { *value_len = l };
435    handle_result(res, tmp_buf)
436}
437
438#[unsafe(no_mangle)]
439pub extern "C" fn TEE_GetPropertyAsBool(
440    propset_or_enumerator: TEE_PropSetHandle,
441    name: *const c_char,
442    value: *mut bool,
443) -> TEE_Result {
444    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_BOOL;
445    let mut bool_len = mem::size_of::<bool>() as u32;
446    let mut res = unsafe {
447        propget_get_property(
448            propset_or_enumerator,
449            name,
450            &mut prop_type,
451            value as *mut c_void,
452            &mut bool_len,
453        )
454    };
455    if prop_type != UserTaPropType::USER_TA_PROP_TYPE_BOOL {
456        res = TEE_ERROR_BAD_FORMAT;
457    }
458    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_BAD_FORMAT {
459        TEE_Panic(0);
460    }
461    res
462}
463
464#[unsafe(no_mangle)]
465pub extern "C" fn TEE_GetPropertyAsU32(
466    propset_or_enumerator: TEE_PropSetHandle,
467    name: *const c_char,
468    value: *mut u32,
469) -> TEE_Result {
470    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_U32;
471    let mut u32_len = mem::size_of::<u32>() as u32;
472    let mut res = unsafe {
473        propget_get_property(
474            propset_or_enumerator,
475            name,
476            &mut prop_type,
477            value as *mut c_void,
478            &mut u32_len,
479        )
480    };
481    if prop_type != UserTaPropType::USER_TA_PROP_TYPE_U32 {
482        res = TEE_ERROR_BAD_FORMAT;
483    }
484    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_BAD_FORMAT {
485        TEE_Panic(0);
486    }
487    res
488}
489#[unsafe(no_mangle)]
490pub extern "C" fn TEE_GetPropertyAsU64(
491    propset_or_enumerator: TEE_PropSetHandle,
492    name: *const c_char,
493    value: *mut u64,
494) -> TEE_Result {
495    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_U64;
496    let mut u64_len = mem::size_of::<u64>() as u32;
497    let mut res = unsafe {
498        propget_get_property(
499            propset_or_enumerator,
500            name,
501            &mut prop_type,
502            value as *mut c_void,
503            &mut u64_len,
504        )
505    };
506    if prop_type != UserTaPropType::USER_TA_PROP_TYPE_U64 {
507        res = TEE_ERROR_BAD_FORMAT;
508    }
509    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_BAD_FORMAT {
510        TEE_Panic(0);
511    }
512    res
513}
514
515#[unsafe(no_mangle)]
516pub extern "C" fn TEE_GetPropertyAsBinaryBlock(
517    propset_or_enumerator: TEE_PropSetHandle,
518    name: *const c_char,
519    value: *mut c_void,
520    value_len: *mut usize,
521) -> TEE_Result {
522    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_BINARY_BLOCK;
523    let mut tmp_len = unsafe { *value_len } as u32;
524    let mut res = unsafe {
525        propget_get_property(
526            propset_or_enumerator,
527            name,
528            &mut prop_type,
529            value,
530            &mut tmp_len,
531        )
532    };
533    if prop_type != UserTaPropType::USER_TA_PROP_TYPE_BINARY_BLOCK {
534        res = TEE_ERROR_BAD_FORMAT;
535    }
536    if res != TEE_SUCCESS
537        && res != TEE_ERROR_ITEM_NOT_FOUND
538        && res != TEE_ERROR_BAD_FORMAT
539        && res != TEE_ERROR_SHORT_BUFFER
540    {
541        TEE_Panic(0);
542    }
543    unsafe { *value_len = tmp_len as usize };
544    res
545}
546
547#[unsafe(no_mangle)]
548pub extern "C" fn TEE_GetPropertyAsUUID(
549    propset_or_enumerator: TEE_PropSetHandle,
550    name: *const c_char,
551    value: *mut TEE_UUID,
552) -> TEE_Result {
553    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_UUID;
554    let mut uuid_len = mem::size_of::<TEE_UUID>() as u32;
555    let mut res = unsafe {
556        propget_get_property(
557            propset_or_enumerator,
558            name,
559            &mut prop_type,
560            value as *mut c_void,
561            &mut uuid_len,
562        )
563    };
564    if prop_type != UserTaPropType::USER_TA_PROP_TYPE_UUID {
565        res = TEE_ERROR_BAD_FORMAT;
566    }
567    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_BAD_FORMAT {
568        TEE_Panic(0);
569    }
570    res
571}
572
573#[unsafe(no_mangle)]
574pub extern "C" fn TEE_GetPropertyAsIdentity(
575    propset_or_enumerator: TEE_PropSetHandle,
576    name: *const c_char,
577    value: *mut TEE_Identity,
578) -> TEE_Result {
579    let mut prop_type = UserTaPropType::USER_TA_PROP_TYPE_IDENTITY;
580    let mut identity_len = mem::size_of::<TEE_Identity>() as u32;
581    let mut res = unsafe {
582        propget_get_property(
583            propset_or_enumerator,
584            name,
585            &mut prop_type,
586            value as *mut c_void,
587            &mut identity_len,
588        )
589    };
590    if prop_type != UserTaPropType::USER_TA_PROP_TYPE_IDENTITY {
591        res = TEE_ERROR_BAD_FORMAT;
592    }
593    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_BAD_FORMAT {
594        TEE_Panic(0);
595    }
596    res
597}
598
599#[unsafe(no_mangle)]
600pub extern "C" fn TEE_AllocatePropertyEnumerator(enumerator: *mut TEE_PropSetHandle) -> TEE_Result {
601    let pe = TEE_Malloc(
602        mem::size_of::<PropEnumerator>() as usize,
603        TEE_USER_MEM_HINT_NO_FILL_ZERO,
604    );
605    if pe.is_null() {
606        return TEE_ERROR_OUT_OF_MEMORY;
607    }
608    unsafe { ptr::write(enumerator, pe as TEE_PropSetHandle) };
609    unsafe { TEE_ResetPropertyEnumerator(*enumerator) };
610    TEE_SUCCESS
611}
612
613#[unsafe(no_mangle)]
614pub extern "C" fn TEE_FreePropertyEnumerator(enumerator: TEE_PropSetHandle) {
615    let pe = enumerator as *mut PropEnumerator;
616    TEE_Free(pe as *mut c_void);
617}
618#[unsafe(no_mangle)]
619pub extern "C" fn TEE_StartPropertyEnumerator(
620    enumerator: TEE_PropSetHandle,
621    prop_set: TEE_PropSetHandle,
622) {
623    let pe = enumerator as *mut PropEnumerator;
624    if pe.is_null() {
625        return;
626    }
627    unsafe { (*pe).idx = 0 };
628    unsafe { (*pe).prop_set = prop_set };
629}
630
631#[unsafe(no_mangle)]
632pub extern "C" fn TEE_ResetPropertyEnumerator(enumerator: TEE_PropSetHandle) {
633    let pe = enumerator as *mut PropEnumerator;
634    unsafe { (*pe).idx = PROP_ENUMERATOR_NOT_STARTED };
635}
636
637#[unsafe(no_mangle)]
638pub extern "C" fn TEE_GetPropertyName(
639    enumerator: TEE_PropSetHandle,
640    name: *mut c_void,
641    name_len: *mut usize,
642) -> TEE_Result {
643    let pe = enumerator as *mut PropEnumerator;
644    let tmp_name_len = name_len;
645    let mut eps: *const UserTaProperty = core::ptr::null();
646    let mut eps_len: usize = 0;
647    if pe.is_null() {
648        TEE_Panic(0);
649    }
650    let mut res = unsafe { propset_get((*pe).prop_set, &mut eps, &mut eps_len) };
651    if res != TEE_SUCCESS {
652        if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_SHORT_BUFFER {
653            TEE_Panic(0);
654        }
655        return res;
656    }
657    if unsafe { (*pe).idx } < (eps_len as u32) {
658        let str = unsafe { &*eps.offset((*pe).idx as isize) }.name;
659        let buffer_len = copy_constu8_string(str as _, name as *mut u8).unwrap() + 1;
660        if buffer_len > unsafe { *tmp_name_len } {
661            res = TEE_ERROR_SHORT_BUFFER;
662        }
663        unsafe { *tmp_name_len = buffer_len as usize };
664    } else {
665        res = unsafe {
666            _utee_get_property(
667                (*pe).prop_set as u64,
668                ((*pe).idx - eps_len as u32) as u64,
669                name,
670                tmp_name_len as *mut u32,
671                null_mut(),
672                null_mut(),
673                null_mut(),
674            )
675        } as u32;
676    }
677    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND && res != TEE_ERROR_SHORT_BUFFER {
678        TEE_Panic(0);
679    }
680    res
681}
682#[unsafe(no_mangle)]
683pub extern "C" fn TEE_GetNextProperty(enumerator: TEE_PropSetHandle) -> TEE_Result {
684    let pe = enumerator as *mut PropEnumerator;
685    let mut eps: *const UserTaProperty = core::ptr::null();
686    let mut eps_len: usize = 0;
687    if pe.is_null() {
688        TEE_Panic(0);
689    }
690    if unsafe { (*pe).idx } == PROP_ENUMERATOR_NOT_STARTED {
691        return TEE_ERROR_ITEM_NOT_FOUND;
692    }
693    let mut res = unsafe { propset_get((*pe).prop_set, &mut eps, &mut eps_len) };
694    if res != TEE_SUCCESS {
695        if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND {
696            TEE_Panic(0);
697        }
698        return res;
699    }
700    let next_idx = unsafe { (*pe).idx + 1 };
701    unsafe { (*pe).idx = next_idx };
702    if next_idx < (eps_len as u32) {
703        res = TEE_SUCCESS;
704    } else {
705        res = unsafe {
706            _utee_get_property(
707                (*pe).prop_set as u64,
708                (next_idx - eps_len as u32) as u64,
709                null_mut(),
710                null_mut(),
711                null_mut(),
712                null_mut(),
713                null_mut(),
714            )
715        } as u32;
716    }
717    if res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND {
718        TEE_Panic(0);
719    }
720    res
721}