api_impl/
binding_stubs.rs

1// Copyright 2024 The Fuchsia Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file contains forwarding stubs from the C entry points to Rust implementations.
6//
7// Exposed functions TEE_FooBar forwards to api_impl::foo_bar(), where foo_bar deals in the richer
8// bindings exposed top-level from the tee_internal crate.
9
10#![allow(non_snake_case)]
11#![allow(unused_variables)]
12
13use num_traits::FromPrimitive;
14use tee_internal::binding::{
15    TEE_Attribute, TEE_BigInt, TEE_BigIntFMM, TEE_BigIntFMMContext, TEE_Identity,
16    TEE_ObjectEnumHandle, TEE_ObjectHandle, TEE_ObjectInfo, TEE_OperationHandle, TEE_OperationInfo,
17    TEE_OperationInfoMultiple, TEE_Param, TEE_PropSetHandle, TEE_Result, TEE_TASessionHandle,
18    TEE_Time, TEE_Whence, TEE_SUCCESS, TEE_UUID,
19};
20use tee_internal::{
21    to_tee_result, Algorithm, Attribute, AttributeId, EccCurve, Error, HandleFlags, Mode,
22    ObjectEnumHandle, ObjectHandle, OperationHandle, PropSetHandle, Result as TeeResult,
23    Storage as TeeStorage, Type, Usage, ValueFields, Whence, OBJECT_ID_MAX_LEN,
24};
25
26use crate::props::is_propset_pseudo_handle;
27use crate::{context, crypto, mem, storage, time, ErrorWithSize};
28
29// This function returns a list of the C entry point that we want to expose from
30// this program. They need to be referenced from main to ensure that the linker
31// thinks that they are referenced and need to be included in the final binary.
32//
33// Keep in the order as they appear in the spec.
34#[rustfmt::skip]
35pub fn exposed_c_entry_points() -> &'static [*const extern "C" fn()] {
36    &[
37        //
38        // Trusted Core Framework API
39        //
40
41        // Property Access Functions
42        TEE_GetPropertyAsString as *const extern "C" fn(),
43        TEE_GetPropertyAsBool as *const extern "C" fn(),
44        TEE_GetPropertyAsU32 as *const extern "C" fn(),
45        TEE_GetPropertyAsU64 as *const extern "C" fn(),
46        TEE_GetPropertyAsBinaryBlock as *const extern "C" fn(),
47        TEE_GetPropertyAsUUID as *const extern "C" fn(),
48        TEE_GetPropertyAsIdentity as *const extern "C" fn(),
49        TEE_AllocatePropertyEnumerator as *const extern "C" fn(),
50        TEE_FreePropertyEnumerator as *const extern "C" fn(),
51        TEE_StartPropertyEnumerator as *const extern "C" fn(),
52        TEE_ResetPropertyEnumerator as *const extern "C" fn(),
53        TEE_GetPropertyName as *const extern "C" fn(),
54        TEE_GetNextProperty as *const extern "C" fn(),
55
56        // Panics
57        TEE_Panic as *const extern "C" fn(),
58
59        // Internal Client API
60        TEE_OpenTASession as *const extern "C" fn(),
61        TEE_CloseTASession as *const extern "C" fn(),
62        TEE_InvokeTACommand as *const extern "C" fn(),
63
64        // Cancellation Functions
65        TEE_GetCancellationFlag as *const extern "C" fn(),
66        TEE_UnmaskCancellation as *const extern "C" fn(),
67        TEE_MaskCancellation as *const extern "C" fn(),
68
69        // Memory Management Functions
70        TEE_CheckMemoryAccessRights as *const extern "C" fn(),
71        TEE_SetInstanceData as *const extern "C" fn(),
72        TEE_GetInstanceData as *const extern "C" fn(),
73        TEE_Malloc as *const extern "C" fn(),
74        TEE_Realloc as *const extern "C" fn(),
75        TEE_Free as *const extern "C" fn(),
76        TEE_MemMove as *const extern "C" fn(),
77        TEE_MemCompare as *const extern "C" fn(),
78        TEE_MemFill as *const extern "C" fn(),
79
80        //
81        // Trusted Storage API for Data and Keys
82        //
83
84        // Generic Object Functions
85        TEE_GetObjectInfo1 as *const extern "C" fn(),
86        TEE_GetObjectInfo as *const extern "C" fn(),
87        TEE_RestrictObjectUsage1 as *const extern "C" fn(),
88        TEE_RestrictObjectUsage as *const extern "C" fn(),
89        TEE_GetObjectBufferAttribute as *const extern "C" fn(),
90        TEE_GetObjectValueAttribute as *const extern "C" fn(),
91        TEE_CloseObject as *const extern "C" fn(),
92
93        // Transient Object Functions
94        TEE_AllocateTransientObject as *const extern "C" fn(),
95        TEE_FreeTransientObject as *const extern "C" fn(),
96        TEE_ResetTransientObject as *const extern "C" fn(),
97        TEE_PopulateTransientObject as *const extern "C" fn(),
98        TEE_InitRefAttribute as *const extern "C" fn(),
99        TEE_InitValueAttribute as *const extern "C" fn(),
100        TEE_CopyObjectAttributes1 as *const extern "C" fn(),
101        TEE_CopyObjectAttributes as *const extern "C" fn(),
102        TEE_GenerateKey as *const extern "C" fn(),
103
104        // Persistent Object Functions
105        TEE_OpenPersistentObject as *const extern "C" fn(),
106        TEE_CreatePersistentObject as *const extern "C" fn(),
107        TEE_CloseAndDeletePersistentObject1 as *const extern "C" fn(),
108        TEE_CloseAndDeletePersistentObject as *const extern "C" fn(),
109        TEE_RenamePersistentObject as *const extern "C" fn(),
110
111        // Persistent Object Enumeration Functions
112        TEE_AllocatePersistentObjectEnumerator as *const extern "C" fn(),
113        TEE_FreePersistentObjectEnumerator as *const extern "C" fn(),
114        TEE_ResetPersistentObjectEnumerator as *const extern "C" fn(),
115        TEE_StartPersistentObjectEnumerator as *const extern "C" fn(),
116        TEE_GetNextPersistentObject as *const extern "C" fn(),
117
118        // Data Stream Access Functions
119        TEE_ReadObjectData as *const extern "C" fn(),
120        TEE_WriteObjectData as *const extern "C" fn(),
121        TEE_TruncateObjectData as *const extern "C" fn(),
122        TEE_SeekObjectData as *const extern "C" fn(),
123
124        //
125        // Cryptographic Operations API
126        //
127
128        // Generic Options Functions
129        TEE_AllocateOperation as *const extern "C" fn(),
130        TEE_FreeOperation as *const extern "C" fn(),
131        TEE_GetOperationInfo as *const extern "C" fn(),
132        TEE_GetOperationInfoMultiple as *const extern "C" fn(),
133        TEE_ResetOperation as *const extern "C" fn(),
134        TEE_SetOperationKey as *const extern "C" fn(),
135        TEE_SetOperationKey2 as *const extern "C" fn(),
136        TEE_CopyOperation as *const extern "C" fn(),
137        TEE_IsAlgorithmSupported as *const extern "C" fn(),
138
139        // Message Digest Functions
140        TEE_DigestUpdate as *const extern "C" fn(),
141        TEE_DigestDoFinal as *const extern "C" fn(),
142        TEE_DigestExtract as *const extern "C" fn(),
143
144        // Symmetric Cipher Functions
145        TEE_CipherInit as *const extern "C" fn(),
146        TEE_CipherUpdate as *const extern "C" fn(),
147        TEE_CipherDoFinal as *const extern "C" fn(),
148
149        // MAC Functions
150        TEE_MACInit as *const extern "C" fn(),
151        TEE_MACUpdate as *const extern "C" fn(),
152        TEE_MACComputeFinal as *const extern "C" fn(),
153        TEE_MACCompareFinal as *const extern "C" fn(),
154
155        // Authenticated Encryption Functions
156        TEE_AEInit as *const extern "C" fn(),
157        TEE_AEUpdateAAD as *const extern "C" fn(),
158        TEE_AEUpdate as *const extern "C" fn(),
159        TEE_AEEncryptFinal as *const extern "C" fn(),
160        TEE_AEDecryptFinal as *const extern "C" fn(),
161
162        // Asymmetric Functions
163        TEE_AsymmetricEncrypt as *const extern "C" fn(),
164        TEE_AsymmetricDecrypt as *const extern "C" fn(),
165        TEE_AsymmetricSignDigest as *const extern "C" fn(),
166        TEE_AsymmetricVerifyDigest as *const extern "C" fn(),
167
168        // Key Derivation Functions
169        TEE_DeriveKey as *const extern "C" fn(),
170
171        // Random Data Generation Functions
172        TEE_GenerateRandom as *const extern "C" fn(),
173
174        //
175        // Time API
176        //
177
178        // Time Functions
179        TEE_GetSystemTime as *const extern "C" fn(),
180        TEE_Wait as *const extern "C" fn(),
181        TEE_GetTAPersistentTime as *const extern "C" fn(),
182        TEE_SetTAPersistentTime as *const extern "C" fn(),
183        TEE_GetREETime as *const extern "C" fn(),
184
185        //
186        // TEE Arithmetical API
187        //
188
189        // Memory Allocation and Size of Objects
190        TEE_BigIntFMMContextSizeInU32 as *const extern "C" fn(),
191        TEE_BigIntFMMSizeInU32 as *const extern "C" fn(),
192
193        // Initialization Functions
194        TEE_BigIntInit as *const extern "C" fn(),
195        TEE_BigIntInitFMMContext1 as *const extern "C" fn(),
196        TEE_BigIntInitFMM as *const extern "C" fn(),
197
198        // Converter Functions
199        TEE_BigIntConvertFromOctetString as *const extern "C" fn(),
200        TEE_BigIntConvertToOctetString as *const extern "C" fn(),
201        TEE_BigIntConvertFromS32 as *const extern "C" fn(),
202        TEE_BigIntConvertToS32 as *const extern "C" fn(),
203
204        // Logical Operations
205        TEE_BigIntCmp as *const extern "C" fn(),
206        TEE_BigIntCmpS32 as *const extern "C" fn(),
207        TEE_BigIntShiftRight as *const extern "C" fn(),
208        TEE_BigIntGetBit as *const extern "C" fn(),
209        TEE_BigIntGetBitCount as *const extern "C" fn(),
210        TEE_BigIntSetBit as *const extern "C" fn(),
211        TEE_BigIntAssign as *const extern "C" fn(),
212        TEE_BigIntAbs as *const extern "C" fn(),
213
214        // Basic Arithmetic Operations
215        TEE_BigIntAdd as *const extern "C" fn(),
216        TEE_BigIntSub as *const extern "C" fn(),
217        TEE_BigIntNeg as *const extern "C" fn(),
218        TEE_BigIntMul as *const extern "C" fn(),
219        TEE_BigIntSquare as *const extern "C" fn(),
220        TEE_BigIntDiv as *const extern "C" fn(),
221
222        // Modular Arithmetic Operations
223        TEE_BigIntMod as *const extern "C" fn(),
224        TEE_BigIntAddMod as *const extern "C" fn(),
225        TEE_BigIntSubMod as *const extern "C" fn(),
226        TEE_BigIntMulMod as *const extern "C" fn(),
227        TEE_BigIntSquareMod as *const extern "C" fn(),
228        TEE_BigIntInvMod as *const extern "C" fn(),
229        TEE_BigIntExpMod as *const extern "C" fn(),
230
231        // Other Arithmetic Operations
232        TEE_BigIntRelativePrime as *const extern "C" fn(),
233        TEE_BigIntComputeExtendedGcd as *const extern "C" fn(),
234        TEE_BigIntIsProbablePrime as *const extern "C" fn(),
235
236        // Fast Modular Multiplication Operations
237        TEE_BigIntConvertToFMM as *const extern "C" fn(),
238        TEE_BigIntConvertFromFMM as *const extern "C" fn(),
239        TEE_BigIntComputeFMM as *const extern "C" fn(),
240
241        //
242        // Additional
243        //
244
245        // This function is exposed to configure our default heap allocator.
246        mem::__scudo_default_options as *const extern "C" fn(),
247    ]
248}
249
250fn slice_from_raw_parts_mut<'a, Input, Output>(data: *mut Input, size: usize) -> &'a mut [Output] {
251    debug_assert_eq!(align_of::<Input>(), align_of::<Output>());
252    debug_assert_eq!(size_of::<Input>(), size_of::<Output>());
253    if data.is_null() {
254        assert_eq!(size, 0);
255        &mut []
256    } else {
257        // SAFETY: `data` is non-null in this branch, and the library must
258        // assume that it points to valid memory.
259
260        assert!(data.is_aligned());
261        assert!(
262            size * size_of::<Input>() < isize::MAX.try_into().unwrap(),
263            "Size of buf slice is too large and will cause undefined behavior"
264        );
265        // SAFETY: According to the safety concerns for `std::slice::from_raw_parts_mut`:
266        // [1] data must be [valid] for both reads and writes for len * mem::size_of::<T>() many bytes, and it must be properly aligned.
267        // [2] The entire memory range of this slice must be contained within a single allocated object
268        // [3] data must be non-null and aligned even for zero-length slices
269        // [4] data must point to len consecutive properly initialized values of type T.
270        // [5] The memory referenced by the returned slice must not be accessed through any other pointer
271        // [6] The total size len * mem::size_of::<T>() of the slice must be no larger than isize::MAX,
272        //      and adding that size to data must not "wrap around" the address space.
273        //
274        // Nullity, alignment, and size are checked above, satisfying [3] and parts of [1] and [6].
275        // [1] (validity), [2], [4], [5], and [6] (wrap-around) are the responsibility of the caller to uphold.
276        unsafe { std::slice::from_raw_parts_mut(data as *mut Output, size) }
277    }
278}
279
280fn slice_from_raw_parts<'a, Input, Output>(data: *const Input, size: usize) -> &'a [Output] {
281    debug_assert_eq!(align_of::<Input>(), align_of::<Output>());
282    debug_assert_eq!(size_of::<Input>(), size_of::<Output>());
283    if data.is_null() {
284        assert_eq!(size, 0);
285        &mut []
286    } else {
287        assert!(data.is_aligned());
288        assert!(
289            size * size_of::<Input>() < isize::MAX.try_into().unwrap(),
290            "Size of buf slice is too large and will cause undefined behavior"
291        );
292        // SAFETY: According to the safety concerns for `std::slice::from_raw_parts_mut`:
293        // [1] data must be [valid] for reads for len * mem::size_of::<T>() many bytes, and it must be properly aligned.
294        // [2] The entire memory range of this slice must be contained within a single allocated object
295        // [3] data must be non-null and aligned even for zero-length slices
296        // [4] data must point to len consecutive properly initialized values of type T.
297        // [5] The memory referenced by the returned slice  not be mutated for the duration of lifetime 'a, except inside an UnsafeCell.
298        // [6] The total size len * mem::size_of::<T>() of the slice must be no larger than isize::MAX,
299        //      and adding that size to data must not "wrap around" the address space.
300        //
301        // Nullity, alignment, and size are checked above, satisfying [3] and parts of [1] and [6].
302        // [1] (validity), [2], [4], [5], and [6] (wrap-around) are the responsibility of the caller to uphold.
303        unsafe { std::slice::from_raw_parts(data as *const Output, size) }
304    }
305}
306
307fn buffers_overlap<Input>(a: *const Input, a_len: usize, b: *const Input, b_len: usize) -> bool {
308    let a = a.addr();
309    let a_end = a + a_len * size_of::<Input>();
310    let b = b.addr();
311    let b_end = b + b_len * size_of::<Input>();
312    if a < b {
313        a_end > b
314    } else {
315        b_end > a
316    }
317}
318
319// Returns None if a Utf8Error is encountered.
320fn c_str_to_str<'a>(name: *const ::std::os::raw::c_char) -> Option<&'a str> {
321    assert!(!name.is_null());
322    // SAFETY: According to the safety concerns for `CStr::from_ptr`:
323    // [1] The memory pointed to by ptr must contain a valid nul terminator at the end of the string.
324    // [2] ptr must be [valid] for reads of bytes up to and including the nul terminator. This means in particular:
325    //     [2a] The entire memory range of this CStr must be contained within a single allocated object!
326    //     [2b] ptr must be non-null even for a zero-length cstr.
327    // [3] The memory referenced by the returned CStr must not be mutated for the duration of lifetime 'a.
328    // [4] The nul terminator must be within isize::MAX from ptr
329    //
330    // [1], [2a], and [4] are assumed to be upheld by the caller, and not checked here.
331    // [2b] is checked above for nullity, and we do not mutate the memory here, satisfying [3].
332    let name_cstr = unsafe { std::ffi::CStr::from_ptr(name) };
333    name_cstr.to_str().ok()
334}
335
336#[unsafe(no_mangle)]
337extern "C" fn TEE_GetPropertyAsString(
338    propsetOrEnumerator: TEE_PropSetHandle,
339    name: *mut ::std::os::raw::c_char,
340    valueBuffer: *mut ::std::os::raw::c_char,
341    valueBufferLen: *mut usize,
342) -> TEE_Result {
343    assert!(!valueBuffer.is_null());
344    assert!(valueBuffer.is_aligned());
345    assert!(!valueBufferLen.is_null());
346    assert!(valueBufferLen.is_aligned());
347    to_tee_result((|| -> TeeResult {
348        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
349        let name = if is_propset_pseudo_handle(handle) {
350            c_str_to_str(name).ok_or(Error::ItemNotFound)?
351        } else {
352            ""
353        };
354
355        // SAFETY: Nullity and alignment are checked above, but full validity of the memory read
356        // is the responsibility of the caller (e.g. out-of-bounds or freed memory pointers).
357        let initial_buf_len = unsafe { *valueBufferLen };
358        let mut buf = slice_from_raw_parts_mut(valueBuffer, initial_buf_len);
359        let (len, result) = context::with_current(|context| {
360            match context.properties.get_property_as_string(handle, name, &mut buf) {
361                Ok(written) => {
362                    // written.len() does not include the NUL terminator byte, so cases where we
363                    // write the exact buffer length are captured by `<` rather than `<=`.
364                    debug_assert!(written.len() < initial_buf_len);
365                    (written.len(), Ok(()))
366                }
367                Err(err) => {
368                    if err.error == Error::ShortBuffer {
369                        (err.actual_length, Err(err.error))
370                    } else {
371                        (err.written.len(), Err(err.error))
372                    }
373                }
374            }
375        });
376
377        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
378        // other validity concerns for `ptr::write()`.
379        unsafe {
380            // Add 1 for NUL terminator.
381            *valueBufferLen = len + 1;
382        }
383
384        result
385    })())
386}
387
388#[unsafe(no_mangle)]
389extern "C" fn TEE_GetPropertyAsBool(
390    propsetOrEnumerator: TEE_PropSetHandle,
391    name: *mut ::std::os::raw::c_char,
392    value: *mut bool,
393) -> TEE_Result {
394    assert!(!value.is_null());
395    assert!(value.is_aligned());
396
397    to_tee_result((|| -> TeeResult {
398        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
399        let name = if is_propset_pseudo_handle(handle) {
400            c_str_to_str(name).ok_or(Error::ItemNotFound)?
401        } else {
402            ""
403        };
404        let val =
405            context::with_current(|context| context.properties.get_property_as_bool(handle, name))?;
406        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
407        // other validity concerns for `ptr::write()`.
408        unsafe {
409            *value = val;
410        }
411        Ok(())
412    })())
413}
414
415#[unsafe(no_mangle)]
416extern "C" fn TEE_GetPropertyAsU32(
417    propsetOrEnumerator: TEE_PropSetHandle,
418    name: *mut ::std::os::raw::c_char,
419    value: *mut u32,
420) -> TEE_Result {
421    assert!(!value.is_null());
422    assert!(value.is_aligned());
423
424    to_tee_result((|| -> TeeResult {
425        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
426        let name = if is_propset_pseudo_handle(handle) {
427            c_str_to_str(name).ok_or(Error::ItemNotFound)?
428        } else {
429            ""
430        };
431        let val =
432            context::with_current(|context| context.properties.get_property_as_u32(handle, name))?;
433        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
434        // other validity concerns for `ptr::write()`.
435        unsafe {
436            *value = val;
437        }
438        Ok(())
439    })())
440}
441
442#[unsafe(no_mangle)]
443extern "C" fn TEE_GetPropertyAsU64(
444    propsetOrEnumerator: TEE_PropSetHandle,
445    name: *mut ::std::os::raw::c_char,
446    value: *mut u64,
447) -> TEE_Result {
448    assert!(!value.is_null());
449    assert!(value.is_aligned());
450
451    to_tee_result((|| -> TeeResult {
452        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
453        let name = if is_propset_pseudo_handle(handle) {
454            c_str_to_str(name).ok_or(Error::ItemNotFound)?
455        } else {
456            ""
457        };
458        let val =
459            context::with_current(|context| context.properties.get_property_as_u64(handle, name))?;
460        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
461        // other validity concerns for `ptr::write()`.
462        unsafe {
463            *value = val;
464        }
465        Ok(())
466    })())
467}
468
469#[unsafe(no_mangle)]
470extern "C" fn TEE_GetPropertyAsBinaryBlock(
471    propsetOrEnumerator: TEE_PropSetHandle,
472    name: *mut ::std::os::raw::c_char,
473    valueBuffer: *mut ::std::os::raw::c_void,
474    valueBufferLen: *mut usize,
475) -> TEE_Result {
476    assert!(!valueBufferLen.is_null());
477    assert!(valueBufferLen.is_aligned());
478
479    to_tee_result((|| -> TeeResult {
480        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
481        let name = if is_propset_pseudo_handle(handle) {
482            c_str_to_str(name).ok_or(Error::ItemNotFound)?
483        } else {
484            ""
485        };
486        // SAFETY: Nullity and alignment are checked above, but full validity of the memory read
487        // is the responsibility of the caller (e.g. out-of-bounds or freed memory pointers).
488        let initial_buf_len = unsafe { *valueBufferLen };
489        let mut buf = slice_from_raw_parts_mut(valueBuffer as *mut u8, initial_buf_len);
490
491        let (len, result) = context::with_current(|context| {
492            match context.properties.get_property_as_binary_block(handle, name, &mut buf) {
493                Ok(bytes_written) => {
494                    debug_assert!(bytes_written.len() <= initial_buf_len);
495                    (bytes_written.len(), Ok(()))
496                }
497                Err(err) => {
498                    let len = match err.error {
499                        Error::ShortBuffer => err.actual_length,
500                        Error::BadFormat => 0,
501                        _ => err.written.len(),
502                    };
503                    (len, Err(err.error))
504                }
505            }
506        });
507
508        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
509        // other validity concerns for `ptr::write()`.
510        unsafe {
511            *valueBufferLen = len;
512        };
513
514        result
515    })())
516}
517
518#[unsafe(no_mangle)]
519extern "C" fn TEE_GetPropertyAsUUID(
520    propsetOrEnumerator: TEE_PropSetHandle,
521    name: *mut ::std::os::raw::c_char,
522    value: *mut TEE_UUID,
523) -> TEE_Result {
524    assert!(!value.is_null());
525    assert!(value.is_aligned());
526
527    to_tee_result((|| -> TeeResult {
528        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
529        let name = if is_propset_pseudo_handle(handle) {
530            c_str_to_str(name).ok_or(Error::ItemNotFound)?
531        } else {
532            ""
533        };
534        let uuid =
535            context::with_current(|context| context.properties.get_property_as_uuid(handle, name))?;
536        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
537        // other validity concerns for `ptr::write()`.
538        unsafe {
539            *value = *uuid.to_binding();
540        }
541        Ok(())
542    })())
543}
544
545#[unsafe(no_mangle)]
546extern "C" fn TEE_GetPropertyAsIdentity(
547    propsetOrEnumerator: TEE_PropSetHandle,
548    name: *mut ::std::os::raw::c_char,
549    value: *mut TEE_Identity,
550) -> TEE_Result {
551    assert!(!value.is_null());
552    assert!(value.is_aligned());
553
554    to_tee_result((|| -> TeeResult {
555        let handle = *PropSetHandle::from_binding(&propsetOrEnumerator);
556        let name = if is_propset_pseudo_handle(handle) {
557            c_str_to_str(name).ok_or(Error::ItemNotFound)?
558        } else {
559            ""
560        };
561        let identity = context::with_current(|context| {
562            context.properties.get_property_as_identity(handle, name)
563        })?;
564        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
565        // other validity concerns for `ptr::write()`.
566        unsafe {
567            *value = *identity.to_binding();
568        }
569        Ok(())
570    })())
571}
572
573#[unsafe(no_mangle)]
574extern "C" fn TEE_AllocatePropertyEnumerator(enumerator: *mut TEE_PropSetHandle) -> TEE_Result {
575    assert!(!enumerator.is_null());
576    assert!(enumerator.is_aligned());
577    let handle =
578        context::with_current_mut(|context| context.properties.allocate_property_enumerator());
579    // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
580    // other validity concerns for `ptr::write()`.
581    unsafe {
582        *enumerator = handle.to_binding().clone();
583    }
584    TEE_SUCCESS
585}
586
587#[unsafe(no_mangle)]
588extern "C" fn TEE_FreePropertyEnumerator(enumerator: TEE_PropSetHandle) {
589    context::with_current_mut(|context| {
590        context.properties.free_property_enumerator(*PropSetHandle::from_binding(&enumerator))
591    });
592}
593
594#[unsafe(no_mangle)]
595extern "C" fn TEE_StartPropertyEnumerator(
596    enumerator: TEE_PropSetHandle,
597    propSet: TEE_PropSetHandle,
598) {
599    context::with_current_mut(|context| {
600        context.properties.start_property_enumerator(
601            *PropSetHandle::from_binding(&enumerator),
602            *PropSetHandle::from_binding(&propSet),
603        )
604    });
605}
606
607#[unsafe(no_mangle)]
608extern "C" fn TEE_ResetPropertyEnumerator(enumerator: TEE_PropSetHandle) {
609    context::with_current_mut(|context| {
610        context.properties.reset_property_enumerator(*PropSetHandle::from_binding(&enumerator))
611    });
612}
613
614#[unsafe(no_mangle)]
615extern "C" fn TEE_GetPropertyName(
616    enumerator: TEE_PropSetHandle,
617    nameBuffer: *mut ::std::os::raw::c_void,
618    nameBufferLen: *mut usize,
619) -> TEE_Result {
620    assert!(!nameBuffer.is_null());
621    assert!(nameBuffer.is_aligned());
622    assert!(!nameBufferLen.is_null());
623    assert!(nameBufferLen.is_aligned());
624
625    to_tee_result((|| -> TeeResult {
626        let handle = *PropSetHandle::from_binding(&enumerator);
627
628        // SAFETY: Nullity and alignment are checked above, but full validity of the memory read
629        // is the responsibility of the caller (e.g. out-of-bounds or freed memory pointers).
630        let initial_buf_len = unsafe { *nameBufferLen };
631        let mut buf = slice_from_raw_parts_mut(nameBuffer, initial_buf_len);
632
633        let (len, result) = context::with_current(|context| {
634            match context.properties.get_property_name(handle, &mut buf) {
635                Ok(written) => {
636                    // written.len() does not include the NUL terminator byte, so cases where we
637                    // write the exact buffer length are captured by `<` rather than `<=`.
638                    debug_assert!(written.len() < initial_buf_len);
639                    (written.len(), Ok(()))
640                }
641                Err(err) => {
642                    if err.error == Error::ShortBuffer {
643                        (err.actual_length, Err(err.error))
644                    } else {
645                        (err.written.len(), Err(err.error))
646                    }
647                }
648            }
649        });
650
651        // SAFETY: Nullity and alignment are checked above. The caller is responsible for upholding
652        // other validity concerns for `ptr::write()`.
653        unsafe {
654            // Add 1 for NUL terminator.
655            *nameBufferLen = len + 1;
656        }
657
658        result
659    })())
660}
661
662#[unsafe(no_mangle)]
663extern "C" fn TEE_GetNextProperty(enumerator: TEE_PropSetHandle) -> TEE_Result {
664    to_tee_result((|| -> TeeResult {
665        context::with_current_mut(|context| {
666            context.properties.get_next_property(*PropSetHandle::from_binding(&enumerator))
667        })
668    })())
669}
670
671#[unsafe(no_mangle)]
672pub extern "C" fn TEE_Panic(code: u32) {
673    crate::panic(code)
674}
675
676#[unsafe(no_mangle)]
677extern "C" fn TEE_OpenTASession(
678    destination: *mut TEE_UUID,
679    cancellationRequestTimeout: u32,
680    paramTypes: u32,
681    params: *mut TEE_Param,
682    session: *mut TEE_TASessionHandle,
683    returnOrigin: *mut u32,
684) -> TEE_Result {
685    unimplemented!()
686}
687
688#[unsafe(no_mangle)]
689extern "C" fn TEE_CloseTASession(session: TEE_TASessionHandle) {
690    unimplemented!()
691}
692
693#[unsafe(no_mangle)]
694extern "C" fn TEE_InvokeTACommand(
695    session: TEE_TASessionHandle,
696    cancellationRequestTimeout: u32,
697    commandID: u32,
698    paramTypes: u32,
699    params: *mut TEE_Param,
700    returnOrigin: *mut u32,
701) -> TEE_Result {
702    unimplemented!()
703}
704
705#[unsafe(no_mangle)]
706extern "C" fn TEE_GetCancellationFlag() -> bool {
707    unimplemented!()
708}
709
710#[unsafe(no_mangle)]
711extern "C" fn TEE_UnmaskCancellation() -> bool {
712    // TODO(https://fxbug.dev/370103570): Implement Cancellation APIs.
713    return true;
714}
715
716#[unsafe(no_mangle)]
717extern "C" fn TEE_MaskCancellation() -> bool {
718    unimplemented!()
719}
720
721#[unsafe(no_mangle)]
722extern "C" fn TEE_CheckMemoryAccessRights(
723    accessFlags: u32,
724    buffer: *mut ::std::os::raw::c_void,
725    size: usize,
726) -> TEE_Result {
727    context::with_current(|context| {
728        mem::check_memory_access_rights(
729            accessFlags,
730            buffer.addr(),
731            size,
732            &context.mapped_param_ranges,
733        )
734    })
735}
736
737#[unsafe(no_mangle)]
738extern "C" fn TEE_Malloc(size: usize, hint: u32) -> *mut ::std::os::raw::c_void {
739    mem::malloc(size, hint)
740}
741
742#[unsafe(no_mangle)]
743extern "C" fn TEE_Realloc(
744    buffer: *mut ::std::os::raw::c_void,
745    newSize: usize,
746) -> *mut ::std::os::raw::c_void {
747    unsafe { mem::realloc(buffer, newSize) }
748}
749
750#[unsafe(no_mangle)]
751extern "C" fn TEE_Free(buffer: *mut ::std::os::raw::c_void) {
752    unsafe { mem::free(buffer) }
753}
754
755#[unsafe(no_mangle)]
756extern "C" fn TEE_MemMove(
757    dest: *mut ::std::os::raw::c_void,
758    src: *mut ::std::os::raw::c_void,
759    size: usize,
760) {
761    mem::mem_move(dest, src, size)
762}
763
764#[unsafe(no_mangle)]
765extern "C" fn TEE_MemCompare(
766    buffer1: *mut ::std::os::raw::c_void,
767    buffer2: *mut ::std::os::raw::c_void,
768    size: usize,
769) -> i32 {
770    mem::mem_compare(buffer1, buffer2, size)
771}
772
773#[unsafe(no_mangle)]
774extern "C" fn TEE_MemFill(buffer: *mut ::std::os::raw::c_void, x: u8, size: usize) {
775    mem::mem_fill(buffer, x, size)
776}
777
778#[unsafe(no_mangle)]
779extern "C" fn TEE_SetInstanceData(instanceData: *mut ::std::os::raw::c_void) {
780    unimplemented!()
781}
782
783#[unsafe(no_mangle)]
784extern "C" fn TEE_GetInstanceData() -> *mut ::std::os::raw::c_void {
785    unimplemented!()
786}
787
788#[unsafe(no_mangle)]
789extern "C" fn TEE_GetObjectInfo1(
790    object: TEE_ObjectHandle,
791    objectInfo: *mut TEE_ObjectInfo,
792) -> TEE_Result {
793    assert!(!objectInfo.is_null());
794    to_tee_result(|| -> TeeResult {
795        let object = *ObjectHandle::from_binding(&object);
796        let info = context::with_current(|context| context.storage.get_object_info(object));
797        // SAFETY: `objectInfo` nullity checked above.
798        unsafe {
799            *objectInfo = *info.to_binding();
800        }
801        Ok(())
802    }())
803}
804
805#[unsafe(no_mangle)]
806extern "C" fn TEE_GetObjectInfo(object: TEE_ObjectHandle, objectInfo: *mut TEE_ObjectInfo) {
807    assert_eq!(TEE_GetObjectInfo1(object, objectInfo), TEE_SUCCESS);
808}
809
810#[unsafe(no_mangle)]
811extern "C" fn TEE_RestrictObjectUsage1(object: TEE_ObjectHandle, objectUsage: u32) -> TEE_Result {
812    to_tee_result(|| -> TeeResult {
813        let object = *ObjectHandle::from_binding(&object);
814        let usage = Usage::from_bits_retain(objectUsage);
815        context::with_current(|context| context.storage.restrict_object_usage(object, usage));
816        Ok(())
817    }())
818}
819
820#[unsafe(no_mangle)]
821extern "C" fn TEE_RestrictObjectUsage(object: TEE_ObjectHandle, objectUsage: u32) {
822    assert_eq!(TEE_RestrictObjectUsage1(object, objectUsage), TEE_SUCCESS);
823}
824
825#[unsafe(no_mangle)]
826extern "C" fn TEE_GetObjectBufferAttribute(
827    object: TEE_ObjectHandle,
828    attributeID: u32,
829    buffer: *mut ::std::os::raw::c_void,
830    size: *mut usize,
831) -> TEE_Result {
832    assert!(!size.is_null());
833    to_tee_result(|| -> TeeResult {
834        let object = *ObjectHandle::from_binding(&object);
835        let id = AttributeId::from_u32(attributeID).unwrap();
836        // SAFETY: `size` nullity checked above.
837        let initial_size = unsafe { *size };
838        let buffer = slice_from_raw_parts_mut(buffer, initial_size);
839        let (attribute_size, result) = match context::with_current(|context| {
840            context.storage.get_object_buffer_attribute(object, id, buffer)
841        }) {
842            Ok(written) => {
843                debug_assert!(written <= initial_size);
844                (written, Ok(()))
845            }
846            Err(err) => (err.size, Err(err.error)),
847        };
848        // SAFETY: `size` nullity checked above.
849        unsafe {
850            *size = attribute_size;
851        }
852        result
853    }())
854}
855
856#[unsafe(no_mangle)]
857extern "C" fn TEE_GetObjectValueAttribute(
858    object: TEE_ObjectHandle,
859    attributeID: u32,
860    a: *mut u32,
861    b: *mut u32,
862) -> TEE_Result {
863    assert!(!a.is_null());
864    assert!(!b.is_null());
865    to_tee_result(|| -> TeeResult {
866        let object = *ObjectHandle::from_binding(&object);
867        let id = AttributeId::from_u32(attributeID).unwrap();
868        let val = context::with_current(|context| {
869            context.storage.get_object_value_attribute(object, id)
870        })?;
871        // SAFETY: `a` and `b` nullity checked above.
872        unsafe {
873            (*a, *b) = (val.a, val.b);
874        }
875        Ok(())
876    }())
877}
878
879#[unsafe(no_mangle)]
880extern "C" fn TEE_CloseObject(object: TEE_ObjectHandle) {
881    let object = *ObjectHandle::from_binding(&object);
882    context::with_current_mut(|context| context.storage.close_object(object));
883}
884
885#[unsafe(no_mangle)]
886extern "C" fn TEE_AllocateTransientObject(
887    objectType: u32,
888    maxObjectSize: u32,
889    object: *mut TEE_ObjectHandle,
890) -> TEE_Result {
891    assert!(!object.is_null());
892    to_tee_result(|| -> TeeResult {
893        let object_type = Type::from_u32(objectType).ok_or(Error::NotSupported)?;
894        let obj = context::with_current_mut(|context| {
895            context.storage.allocate_transient_object(object_type, maxObjectSize)
896        })?;
897        // SAFETY: `object` nullity checked above.
898        unsafe {
899            *object = *obj.to_binding();
900        }
901        Ok(())
902    }())
903}
904
905#[unsafe(no_mangle)]
906extern "C" fn TEE_FreeTransientObject(object: TEE_ObjectHandle) {
907    let object = *ObjectHandle::from_binding(&object);
908    context::with_current_mut(|context| context.storage.free_transient_object(object));
909}
910
911#[unsafe(no_mangle)]
912extern "C" fn TEE_ResetTransientObject(object: TEE_ObjectHandle) {
913    let object = *ObjectHandle::from_binding(&object);
914    context::with_current_mut(|context| context.storage.reset_transient_object(object));
915}
916
917#[unsafe(no_mangle)]
918extern "C" fn TEE_PopulateTransientObject(
919    object: TEE_ObjectHandle,
920    attrs: *mut TEE_Attribute,
921    attrCount: u32,
922) -> TEE_Result {
923    // SAFETY: check that the TEE_Attribute entries do indeed give
924    // bitwise-valid Atttibute instances before recasting below.
925    for raw_attr in
926        slice_from_raw_parts::<TEE_Attribute, TEE_Attribute>(attrs, attrCount as usize).iter()
927    {
928        assert!(Attribute::from_binding(&raw_attr).is_some());
929    }
930
931    to_tee_result(|| -> TeeResult {
932        let object = *ObjectHandle::from_binding(&object);
933        let attrs = slice_from_raw_parts(attrs, attrCount as usize);
934        context::with_current(|context| {
935            context.storage.populate_transient_object(object, attrs as &[Attribute])
936        })
937    }())
938}
939
940#[unsafe(no_mangle)]
941extern "C" fn TEE_InitRefAttribute(
942    attr: *mut TEE_Attribute,
943    attributeID: u32,
944    buffer: *mut ::std::os::raw::c_void,
945    length: usize,
946) {
947    assert!(!attr.is_null());
948    let id = AttributeId::from_u32(attributeID).unwrap();
949    let buffer = slice_from_raw_parts_mut(buffer, length);
950    let attribute = storage::init_ref_attribute(id, buffer);
951    // SAFETY: `attr` nullity checked above.
952    unsafe { *attr = *attribute.to_binding() };
953}
954
955#[unsafe(no_mangle)]
956extern "C" fn TEE_InitValueAttribute(attr: *mut TEE_Attribute, attributeID: u32, a: u32, b: u32) {
957    assert!(!attr.is_null());
958    let id = AttributeId::from_u32(attributeID).unwrap();
959    let attribute = storage::init_value_attribute(id, ValueFields { a, b });
960    // SAFETY: `attr` nullity checked above.
961    unsafe { *attr = *attribute.to_binding() };
962}
963
964#[unsafe(no_mangle)]
965extern "C" fn TEE_CopyObjectAttributes1(
966    destObject: TEE_ObjectHandle,
967    srcObject: TEE_ObjectHandle,
968) -> TEE_Result {
969    to_tee_result(|| -> TeeResult {
970        let src = *ObjectHandle::from_binding(&srcObject);
971        let dest = *ObjectHandle::from_binding(&destObject);
972        context::with_current_mut(|context| context.storage.copy_object_attributes(src, dest))
973    }())
974}
975
976#[unsafe(no_mangle)]
977extern "C" fn TEE_CopyObjectAttributes(destObject: TEE_ObjectHandle, srcObject: TEE_ObjectHandle) {
978    assert_eq!(TEE_CopyObjectAttributes1(destObject, srcObject), TEE_SUCCESS);
979}
980
981#[unsafe(no_mangle)]
982extern "C" fn TEE_GenerateKey(
983    object: TEE_ObjectHandle,
984    keySize: u32,
985    params: *mut TEE_Attribute,
986    paramCount: u32,
987) -> TEE_Result {
988    to_tee_result(|| -> TeeResult {
989        let object = *ObjectHandle::from_binding(&object);
990        let params = slice_from_raw_parts(params, paramCount as usize);
991        context::with_current_mut(|context| context.storage.generate_key(object, keySize, params))
992    }())
993}
994
995#[unsafe(no_mangle)]
996extern "C" fn TEE_OpenPersistentObject(
997    storageID: u32,
998    objectID: *mut ::std::os::raw::c_void,
999    objectIDLen: usize,
1000    flags: u32,
1001    object: *mut TEE_ObjectHandle,
1002) -> TEE_Result {
1003    assert!(!object.is_null());
1004    to_tee_result(|| -> TeeResult {
1005        let storage = TeeStorage::from_u32(storageID).ok_or(Error::ItemNotFound)?;
1006        let flags = HandleFlags::from_bits_retain(flags);
1007        let id = slice_from_raw_parts(objectID, objectIDLen);
1008        let obj = context::with_current_mut(|context| {
1009            context.storage.open_persistent_object(storage, id, flags)
1010        })?;
1011        // SAFETY: `object` nullity checked above.
1012        unsafe {
1013            *object = *obj.to_binding();
1014        }
1015        Ok(())
1016    }())
1017}
1018
1019#[unsafe(no_mangle)]
1020extern "C" fn TEE_CreatePersistentObject(
1021    storageID: u32,
1022    objectID: *mut ::std::os::raw::c_void,
1023    objectIDLen: usize,
1024    flags: u32,
1025    attributes: TEE_ObjectHandle,
1026    initialData: *mut ::std::os::raw::c_void,
1027    initialDataLen: usize,
1028    object: *mut TEE_ObjectHandle,
1029) -> TEE_Result {
1030    to_tee_result(|| -> TeeResult {
1031        let storage = TeeStorage::from_u32(storageID).ok_or(Error::ItemNotFound)?;
1032        let flags = HandleFlags::from_bits_retain(flags);
1033        let id = slice_from_raw_parts(objectID, objectIDLen);
1034        let attrs = *ObjectHandle::from_binding(&attributes);
1035        let initial_data = slice_from_raw_parts(initialData, initialDataLen);
1036        context::with_current_mut(|context| -> TeeResult {
1037            let obj = context.storage.create_persistent_object(
1038                storage,
1039                id,
1040                flags,
1041                attrs,
1042                initial_data,
1043            )?;
1044            if object.is_null() {
1045                // The user doesn't want a handle, so just close the newly minted one.
1046                context.storage.close_object(obj);
1047            } else {
1048                // SAFETY: `object` is non-null in this branch.
1049                unsafe {
1050                    *object = *obj.to_binding();
1051                }
1052            }
1053            Ok(())
1054        })
1055    }())
1056}
1057
1058#[unsafe(no_mangle)]
1059extern "C" fn TEE_CloseAndDeletePersistentObject1(object: TEE_ObjectHandle) -> TEE_Result {
1060    to_tee_result(|| -> TeeResult {
1061        let object = *ObjectHandle::from_binding(&object);
1062        context::with_current_mut(|context| {
1063            context.storage.close_and_delete_persistent_object(object)
1064        })
1065    }())
1066}
1067
1068#[unsafe(no_mangle)]
1069extern "C" fn TEE_CloseAndDeletePersistentObject(object: TEE_ObjectHandle) {
1070    assert_eq!(TEE_CloseAndDeletePersistentObject1(object), TEE_SUCCESS);
1071}
1072
1073#[unsafe(no_mangle)]
1074extern "C" fn TEE_RenamePersistentObject(
1075    object: TEE_ObjectHandle,
1076    newObjectID: *mut ::std::os::raw::c_void,
1077    newObjectIDLen: usize,
1078) -> TEE_Result {
1079    to_tee_result(|| -> TeeResult {
1080        let object = *ObjectHandle::from_binding(&object);
1081        let new_id = slice_from_raw_parts(newObjectID, newObjectIDLen);
1082        context::with_current_mut(|context| {
1083            context.storage.rename_persistent_object(object, new_id)
1084        })
1085    }())
1086}
1087
1088#[unsafe(no_mangle)]
1089extern "C" fn TEE_AllocatePersistentObjectEnumerator(
1090    objectEnumerator: *mut TEE_ObjectEnumHandle,
1091) -> TEE_Result {
1092    assert!(!objectEnumerator.is_null());
1093    to_tee_result(|| -> TeeResult {
1094        let enumerator = context::with_current_mut(|context| {
1095            context.storage.allocate_persistent_object_enumerator()
1096        });
1097        // SAFETY: `objectEnumerator` nullity checked above.
1098        unsafe {
1099            *objectEnumerator = *enumerator.to_binding();
1100        }
1101        Ok(())
1102    }())
1103}
1104
1105#[unsafe(no_mangle)]
1106extern "C" fn TEE_FreePersistentObjectEnumerator(objectEnumerator: TEE_ObjectEnumHandle) {
1107    let enumerator = *ObjectEnumHandle::from_binding(&objectEnumerator);
1108    context::with_current_mut(|context| {
1109        context.storage.free_persistent_object_enumerator(enumerator)
1110    });
1111}
1112
1113#[unsafe(no_mangle)]
1114extern "C" fn TEE_ResetPersistentObjectEnumerator(objectEnumerator: TEE_ObjectEnumHandle) {
1115    let enumerator = *ObjectEnumHandle::from_binding(&objectEnumerator);
1116    context::with_current_mut(|context| {
1117        context.storage.reset_persistent_object_enumerator(enumerator)
1118    });
1119}
1120
1121#[unsafe(no_mangle)]
1122extern "C" fn TEE_StartPersistentObjectEnumerator(
1123    objectEnumerator: TEE_ObjectEnumHandle,
1124    storageID: u32,
1125) -> TEE_Result {
1126    to_tee_result(|| -> TeeResult {
1127        let enumerator = *ObjectEnumHandle::from_binding(&objectEnumerator);
1128        let storage = TeeStorage::from_u32(storageID).ok_or(Error::ItemNotFound)?;
1129        context::with_current_mut(|context| {
1130            context.storage.start_persistent_object_enumerator(enumerator, storage)
1131        })
1132    }())
1133}
1134
1135#[unsafe(no_mangle)]
1136extern "C" fn TEE_GetNextPersistentObject(
1137    objectEnumerator: TEE_ObjectEnumHandle,
1138    objectInfo: *mut TEE_ObjectInfo,
1139    objectID: *mut ::std::os::raw::c_void,
1140    objectIDLen: *mut usize,
1141) -> TEE_Result {
1142    assert!(!objectID.is_null());
1143    assert!(!objectIDLen.is_null());
1144    to_tee_result(|| -> TeeResult {
1145        let enumerator = *ObjectEnumHandle::from_binding(&objectEnumerator);
1146        let id_buf = slice_from_raw_parts_mut(objectID, OBJECT_ID_MAX_LEN);
1147        let (info, id) = context::with_current(|context| {
1148            context.storage.get_next_persistent_object(enumerator, id_buf)
1149        })?;
1150        // SAFETY: `objectIDLen` nullity checked above.
1151        unsafe {
1152            *objectIDLen = id.len();
1153        }
1154        if !objectInfo.is_null() {
1155            // SAFETY" `objectInfo` is non-null in this branch.
1156            unsafe {
1157                *objectInfo = *info.to_binding();
1158            }
1159        }
1160        Ok(())
1161    }())
1162}
1163
1164#[unsafe(no_mangle)]
1165extern "C" fn TEE_ReadObjectData(
1166    object: TEE_ObjectHandle,
1167    buffer: *mut ::std::os::raw::c_void,
1168    size: usize,
1169    count: *mut usize,
1170) -> TEE_Result {
1171    assert!(!count.is_null());
1172    to_tee_result(|| -> TeeResult {
1173        let object = *ObjectHandle::from_binding(&object);
1174        let buffer = slice_from_raw_parts_mut(buffer, size);
1175        let written =
1176            context::with_current(|context| context.storage.read_object_data(object, buffer))?;
1177        // SAFETY: `count` nullity checked above.
1178        unsafe {
1179            *count = written.len();
1180        }
1181        Ok(())
1182    }())
1183}
1184
1185#[unsafe(no_mangle)]
1186extern "C" fn TEE_WriteObjectData(
1187    object: TEE_ObjectHandle,
1188    buffer: *mut ::std::os::raw::c_void,
1189    size: usize,
1190) -> TEE_Result {
1191    to_tee_result(|| -> TeeResult {
1192        let object = *ObjectHandle::from_binding(&object);
1193        let buffer = slice_from_raw_parts(buffer, size);
1194        context::with_current(|context| context.storage.write_object_data(object, buffer))
1195    }())
1196}
1197
1198#[unsafe(no_mangle)]
1199extern "C" fn TEE_TruncateObjectData(object: TEE_ObjectHandle, size: usize) -> TEE_Result {
1200    to_tee_result(|| -> TeeResult {
1201        let object = *ObjectHandle::from_binding(&object);
1202        context::with_current(|context| context.storage.truncate_object_data(object, size))
1203    }())
1204}
1205
1206#[unsafe(no_mangle)]
1207extern "C" fn TEE_SeekObjectData(
1208    object: TEE_ObjectHandle,
1209    offset: std::os::raw::c_long,
1210    whence: TEE_Whence,
1211) -> TEE_Result {
1212    to_tee_result(|| -> TeeResult {
1213        let object = *ObjectHandle::from_binding(&object);
1214        let whence = Whence::from_u32(whence).unwrap();
1215        context::with_current(|context| {
1216            context.storage.seek_data_object(object, offset.try_into().unwrap(), whence)
1217        })
1218    }())
1219}
1220
1221#[unsafe(no_mangle)]
1222extern "C" fn TEE_AllocateOperation(
1223    operation: *mut TEE_OperationHandle,
1224    algorithm: u32,
1225    mode: u32,
1226    maxKeySize: u32,
1227) -> TEE_Result {
1228    assert!(!operation.is_null());
1229    to_tee_result(|| -> TeeResult {
1230        let algorithm = Algorithm::from_u32(algorithm).ok_or(Error::NotSupported)?;
1231        let mode = Mode::from_u32(mode).ok_or(Error::NotSupported)?;
1232        context::with_current_mut(|context| {
1233            let operation_handle = context.operations.allocate(algorithm, mode, maxKeySize)?;
1234            // Safety: |operation| is checked as non-null above.
1235            unsafe { *operation = *operation_handle.to_binding() };
1236            Ok(())
1237        })
1238    }())
1239}
1240
1241#[unsafe(no_mangle)]
1242extern "C" fn TEE_FreeOperation(operation: TEE_OperationHandle) {
1243    context::with_current_mut(|context| {
1244        context.operations.free(*OperationHandle::from_binding(&operation))
1245    });
1246}
1247
1248#[unsafe(no_mangle)]
1249extern "C" fn TEE_GetOperationInfo(
1250    operation: TEE_OperationHandle,
1251    operationInfo: *mut TEE_OperationInfo,
1252) {
1253    unimplemented!()
1254}
1255
1256#[unsafe(no_mangle)]
1257extern "C" fn TEE_GetOperationInfoMultiple(
1258    operation: TEE_OperationHandle,
1259    operationInfoMultiple: *mut TEE_OperationInfoMultiple,
1260    operationSize: *mut usize,
1261) -> TEE_Result {
1262    unimplemented!()
1263}
1264
1265#[unsafe(no_mangle)]
1266extern "C" fn TEE_ResetOperation(operation: TEE_OperationHandle) {
1267    context::with_current_mut(|context| {
1268        let operation = *OperationHandle::from_binding(&operation);
1269        context.operations.reset(operation)
1270    })
1271}
1272
1273#[unsafe(no_mangle)]
1274extern "C" fn TEE_SetOperationKey(
1275    operation: TEE_OperationHandle,
1276    key: TEE_ObjectHandle,
1277) -> TEE_Result {
1278    to_tee_result(|| -> TeeResult {
1279        context::with_current_mut(|context| {
1280            let operation = *OperationHandle::from_binding(&operation);
1281            let key = *ObjectHandle::from_binding(&key);
1282            if key.is_null() {
1283                context.operations.clear_key(operation)
1284            } else {
1285                let key_object = context.storage.get(key);
1286                context.operations.set_key(operation, key_object)
1287            }
1288        })
1289    }())
1290}
1291
1292#[unsafe(no_mangle)]
1293extern "C" fn TEE_SetOperationKey2(
1294    operation: TEE_OperationHandle,
1295    key1: TEE_ObjectHandle,
1296    key2: TEE_ObjectHandle,
1297) -> TEE_Result {
1298    unimplemented!()
1299}
1300
1301#[unsafe(no_mangle)]
1302extern "C" fn TEE_CopyOperation(
1303    dstOperation: TEE_OperationHandle,
1304    srcOperation: TEE_OperationHandle,
1305) {
1306    unimplemented!()
1307}
1308
1309#[unsafe(no_mangle)]
1310extern "C" fn TEE_IsAlgorithmSupported(algId: u32, element: u32) -> TEE_Result {
1311    to_tee_result(|| -> TeeResult {
1312        let alg = Algorithm::from_u32(algId).ok_or(Error::NotSupported)?;
1313        let element = EccCurve::from_u32(algId).ok_or(Error::NotSupported)?;
1314        if crypto::is_algorithm_supported(alg, element) {
1315            Ok(())
1316        } else {
1317            Err(Error::NotSupported)
1318        }
1319    }())
1320}
1321
1322#[unsafe(no_mangle)]
1323extern "C" fn TEE_DigestUpdate(
1324    operation: TEE_OperationHandle,
1325    chunk: *const ::std::os::raw::c_void,
1326    chunkSize: usize,
1327) {
1328    let operation = *OperationHandle::from_binding(&operation);
1329    let chunk = slice_from_raw_parts(chunk, chunkSize);
1330    context::with_current_mut(|context| context.operations.update_digest(operation, chunk))
1331}
1332
1333#[unsafe(no_mangle)]
1334extern "C" fn TEE_DigestDoFinal(
1335    operation: TEE_OperationHandle,
1336    chunk: *const ::std::os::raw::c_void,
1337    chunkLen: usize,
1338    hash: *mut ::std::os::raw::c_void,
1339    hashLen: *mut usize,
1340) -> TEE_Result {
1341    to_tee_result(|| -> TeeResult {
1342        assert!(!hashLen.is_null());
1343
1344        // SAFETY: hashLen checked as non-null above.
1345        let initialHashLen = unsafe { *hashLen };
1346
1347        // This is a precondition to being to reinterpret `hash` as a mutable
1348        // slice.
1349        assert!(!buffers_overlap(chunk, chunkLen, hash, initialHashLen));
1350
1351        let operation = *OperationHandle::from_binding(&operation);
1352        let chunk = slice_from_raw_parts(chunk, chunkLen);
1353        let hash = slice_from_raw_parts_mut(hash, initialHashLen);
1354        context::with_current_mut(|context| {
1355            context.operations.update_and_finalize_digest_into(operation, chunk, hash).map_err(
1356                |ErrorWithSize { error, size }| {
1357                    debug_assert_eq!(error, Error::ShortBuffer);
1358                    // SAFETY: hashLen checked as non-null above.
1359                    unsafe { *hashLen = size };
1360                    error
1361                },
1362            )
1363        })
1364    }())
1365}
1366
1367#[unsafe(no_mangle)]
1368extern "C" fn TEE_DigestExtract(
1369    operation: TEE_OperationHandle,
1370    hash: *mut ::std::os::raw::c_void,
1371    hashLen: *mut usize,
1372) -> TEE_Result {
1373    to_tee_result(|| -> TeeResult {
1374        let operation = *OperationHandle::from_binding(&operation);
1375        assert!(!hashLen.is_null());
1376        // SAFETY: hashLen checked as non-null above.
1377        let hash = slice_from_raw_parts_mut(hash, unsafe { *hashLen });
1378        context::with_current_mut(|context| {
1379            let written = context.operations.extract_digest(operation, hash);
1380            // SAFETY: hashLen checked as non-null above.
1381            unsafe {
1382                *hashLen -= written;
1383            }
1384        });
1385        Ok(())
1386    }())
1387}
1388
1389#[unsafe(no_mangle)]
1390extern "C" fn TEE_CipherInit(
1391    operation: TEE_OperationHandle,
1392    IV: *mut ::std::os::raw::c_void,
1393    IVLen: usize,
1394) {
1395    let operation = *OperationHandle::from_binding(&operation);
1396    let iv = slice_from_raw_parts(IV, IVLen);
1397    context::with_current_mut(|context| context.operations.init_cipher(operation, iv));
1398}
1399
1400#[unsafe(no_mangle)]
1401extern "C" fn TEE_CipherUpdate(
1402    operation: TEE_OperationHandle,
1403    srcData: *mut ::std::os::raw::c_void,
1404    srcLen: usize,
1405    destData: *mut ::std::os::raw::c_void,
1406    destLen: *mut usize,
1407) -> TEE_Result {
1408    assert!(!destLen.is_null());
1409
1410    to_tee_result(|| -> TeeResult {
1411        let operation = *OperationHandle::from_binding(&operation);
1412
1413        // SAFETY: `destLen` checked as non-null above.
1414        let initialDestLen = unsafe { *destLen };
1415
1416        context::with_current_mut(|context| {
1417            let dest = slice_from_raw_parts_mut(destData, initialDestLen);
1418
1419            if buffers_overlap(srcData, srcLen, destData, initialDestLen) {
1420                assert_eq!(srcData, destData);
1421                context.operations.update_cipher_in_place(operation, dest);
1422                return Ok(());
1423            }
1424            let src = slice_from_raw_parts(srcData, srcLen);
1425            context.operations.update_cipher(operation, src, dest).map_err(
1426                |ErrorWithSize { error, size }| {
1427                    debug_assert_eq!(error, Error::ShortBuffer);
1428                    // SAFETY: destLen checked as non-null above.
1429                    unsafe { *destLen = size };
1430                    error
1431                },
1432            )
1433        })
1434    }())
1435}
1436
1437#[unsafe(no_mangle)]
1438extern "C" fn TEE_CipherDoFinal(
1439    operation: TEE_OperationHandle,
1440    srcData: *mut ::std::os::raw::c_void,
1441    srcLen: usize,
1442    destData: *mut ::std::os::raw::c_void,
1443    destLen: *mut usize,
1444) -> TEE_Result {
1445    assert!(!destLen.is_null());
1446
1447    to_tee_result(|| -> TeeResult {
1448        let operation = *OperationHandle::from_binding(&operation);
1449
1450        // SAFETY: `destLen` checked as non-null above.
1451        let initialDestLen = unsafe { *destLen };
1452
1453        context::with_current_mut(|context| {
1454            let dest = slice_from_raw_parts_mut(destData, initialDestLen);
1455
1456            if buffers_overlap(srcData, srcLen, destData, initialDestLen) {
1457                assert_eq!(srcData, destData);
1458                context.operations.finalize_cipher_in_place(operation, dest);
1459                return Ok(());
1460            }
1461            let src = slice_from_raw_parts(srcData, srcLen);
1462            context.operations.finalize_cipher(operation, src, dest).map_err(
1463                |ErrorWithSize { error, size }| {
1464                    debug_assert_eq!(error, Error::ShortBuffer);
1465                    // SAFETY: destLen checked as non-null above.
1466                    unsafe { *destLen = size };
1467                    error
1468                },
1469            )
1470        })
1471    }())
1472}
1473
1474#[unsafe(no_mangle)]
1475extern "C" fn TEE_MACInit(
1476    operation: TEE_OperationHandle,
1477    IV: *mut ::std::os::raw::c_void,
1478    IVLen: usize,
1479) {
1480    let operation = *OperationHandle::from_binding(&operation);
1481    let iv = slice_from_raw_parts(IV, IVLen);
1482    context::with_current_mut(|context| context.operations.init_mac(operation, iv));
1483}
1484
1485#[unsafe(no_mangle)]
1486extern "C" fn TEE_MACUpdate(
1487    operation: TEE_OperationHandle,
1488    chunk: *mut ::std::os::raw::c_void,
1489    chunkSize: usize,
1490) {
1491    let operation = *OperationHandle::from_binding(&operation);
1492    let chunk = slice_from_raw_parts(chunk, chunkSize);
1493    context::with_current_mut(|context| context.operations.update_mac(operation, chunk));
1494}
1495
1496#[unsafe(no_mangle)]
1497extern "C" fn TEE_MACComputeFinal(
1498    operation: TEE_OperationHandle,
1499    message: *mut ::std::os::raw::c_void,
1500    messageLen: usize,
1501    mac: *mut ::std::os::raw::c_void,
1502    macLen: *mut usize,
1503) -> TEE_Result {
1504    to_tee_result(|| -> TeeResult {
1505        assert!(!macLen.is_null());
1506
1507        // SAFETY: macLen checked as non-null above.
1508        let initialMacLen = unsafe { *macLen };
1509
1510        // This is a precondition to being able to reinterpret `mac` as a
1511        // mutable slice.
1512        assert!(!buffers_overlap(message, messageLen, mac, initialMacLen));
1513
1514        let operation = *OperationHandle::from_binding(&operation);
1515        let message = slice_from_raw_parts(message, messageLen);
1516        let mac = slice_from_raw_parts_mut(mac, initialMacLen);
1517
1518        context::with_current_mut(|context| {
1519            context.operations.compute_final_mac(operation, message, mac).map_err(
1520                |ErrorWithSize { error, size }| {
1521                    debug_assert_eq!(error, Error::ShortBuffer);
1522                    // SAFETY: macLen checked as non-null above.
1523                    unsafe { *macLen = size };
1524                    error
1525                },
1526            )
1527        })
1528    }())
1529}
1530
1531#[unsafe(no_mangle)]
1532extern "C" fn TEE_MACCompareFinal(
1533    operation: TEE_OperationHandle,
1534    message: *mut ::std::os::raw::c_void,
1535    messageLen: usize,
1536    mac: *mut ::std::os::raw::c_void,
1537    macLen: usize,
1538) -> TEE_Result {
1539    unimplemented!()
1540}
1541
1542#[unsafe(no_mangle)]
1543extern "C" fn TEE_AEInit(
1544    operation: TEE_OperationHandle,
1545    nonce: *mut ::std::os::raw::c_void,
1546    nonceLen: usize,
1547    tagLen: u32,
1548    AADLen: usize,
1549    payloadLen: usize,
1550) -> TEE_Result {
1551    unimplemented!()
1552}
1553
1554#[unsafe(no_mangle)]
1555extern "C" fn TEE_AEUpdateAAD(
1556    operation: TEE_OperationHandle,
1557    AADdata: *mut ::std::os::raw::c_void,
1558    AADdataLen: usize,
1559) {
1560    unimplemented!()
1561}
1562
1563#[unsafe(no_mangle)]
1564extern "C" fn TEE_AEUpdate(
1565    operation: TEE_OperationHandle,
1566    srcData: *mut ::std::os::raw::c_void,
1567    srcLen: usize,
1568    destData: *mut ::std::os::raw::c_void,
1569    destLen: *mut usize,
1570) -> TEE_Result {
1571    unimplemented!()
1572}
1573
1574#[unsafe(no_mangle)]
1575extern "C" fn TEE_AEEncryptFinal(
1576    operation: TEE_OperationHandle,
1577    srcData: *mut ::std::os::raw::c_void,
1578    srcLen: usize,
1579    destData: *mut ::std::os::raw::c_void,
1580    destLen: *mut usize,
1581    tag: *mut ::std::os::raw::c_void,
1582    tagLen: *mut usize,
1583) -> TEE_Result {
1584    unimplemented!()
1585}
1586
1587#[unsafe(no_mangle)]
1588extern "C" fn TEE_AEDecryptFinal(
1589    operation: TEE_OperationHandle,
1590    srcData: *mut ::std::os::raw::c_void,
1591    srcLen: usize,
1592    destData: *mut ::std::os::raw::c_void,
1593    destLen: *mut usize,
1594    tag: *mut ::std::os::raw::c_void,
1595    tagLen: usize,
1596) -> TEE_Result {
1597    unimplemented!()
1598}
1599
1600#[unsafe(no_mangle)]
1601extern "C" fn TEE_AsymmetricEncrypt(
1602    operation: TEE_OperationHandle,
1603    params: *mut TEE_Attribute,
1604    paramCount: u32,
1605    srcData: *mut ::std::os::raw::c_void,
1606    srcLen: usize,
1607    destData: *mut ::std::os::raw::c_void,
1608    destLen: *mut usize,
1609) -> TEE_Result {
1610    unimplemented!()
1611}
1612
1613#[unsafe(no_mangle)]
1614extern "C" fn TEE_AsymmetricDecrypt(
1615    operation: TEE_OperationHandle,
1616    params: *mut TEE_Attribute,
1617    paramCount: u32,
1618    srcData: *mut ::std::os::raw::c_void,
1619    srcLen: usize,
1620    destData: *mut ::std::os::raw::c_void,
1621    destLen: *mut usize,
1622) -> TEE_Result {
1623    assert!(!destLen.is_null());
1624
1625    to_tee_result(|| -> TeeResult {
1626        // SAFETY: destLen checked as non-null above.
1627        let initialDestLen = unsafe { *destLen };
1628
1629        // This is a precondition to being able to reinterpret `destData` as a
1630        // mutable slice.
1631        assert!(!buffers_overlap(srcData, srcLen, destData, initialDestLen));
1632
1633        let params = slice_from_raw_parts(params, paramCount as usize);
1634        let src = slice_from_raw_parts(srcData, srcLen);
1635        let dest = slice_from_raw_parts_mut(destData, initialDestLen);
1636        let operation = *OperationHandle::from_binding(&operation);
1637
1638        context::with_current_mut(|context| {
1639            let (output_size, result) =
1640                match context.operations.asymmetric_decrypt(operation, params, src, dest) {
1641                    Ok(written) => {
1642                        debug_assert!(written <= dest.len());
1643                        (written, Ok(()))
1644                    }
1645                    Err(err) => (err.size, Err(err.error)),
1646                };
1647            // SAFETY: destLen checked as non-null above.
1648            unsafe { *destLen = output_size };
1649            result
1650        })
1651    }())
1652}
1653
1654#[unsafe(no_mangle)]
1655extern "C" fn TEE_AsymmetricSignDigest(
1656    operation: TEE_OperationHandle,
1657    params: *mut TEE_Attribute,
1658    paramCount: u32,
1659    digest: *mut ::std::os::raw::c_void,
1660    digestLen: usize,
1661    signature: *mut ::std::os::raw::c_void,
1662    signatureLen: *mut usize,
1663) -> TEE_Result {
1664    assert!(!signatureLen.is_null());
1665
1666    to_tee_result(|| -> TeeResult {
1667        // SAFETY: signatureLen checked as non-null above.
1668        let initialSignatureLen = unsafe { *signatureLen };
1669
1670        // This is a precondition to being anble to reinterpret `signature` as
1671        // a mutable slice.
1672        assert!(!buffers_overlap(digest, digestLen, signature, initialSignatureLen));
1673
1674        let params = slice_from_raw_parts(params, paramCount as usize);
1675        let digest = slice_from_raw_parts(digest, digestLen);
1676        let signature = slice_from_raw_parts_mut(signature, initialSignatureLen);
1677        let operation = *OperationHandle::from_binding(&operation);
1678
1679        context::with_current_mut(|context| {
1680            let (output_size, result) = match context
1681                .operations
1682                .asymmetric_sign_digest(operation, params, digest, signature)
1683            {
1684                Ok(written) => {
1685                    debug_assert!(written <= signature.len());
1686                    (written, Ok(()))
1687                }
1688                Err(err) => (err.size, Err(err.error)),
1689            };
1690            // SAFETY: signatureLen checked as non-null above.
1691            unsafe { *signatureLen = output_size };
1692            result
1693        })
1694    }())
1695}
1696
1697#[unsafe(no_mangle)]
1698extern "C" fn TEE_AsymmetricVerifyDigest(
1699    operation: TEE_OperationHandle,
1700    params: *mut TEE_Attribute,
1701    paramCount: u32,
1702    digest: *mut ::std::os::raw::c_void,
1703    digestLen: usize,
1704    signature: *mut ::std::os::raw::c_void,
1705    signatureLen: usize,
1706) -> TEE_Result {
1707    unimplemented!()
1708}
1709
1710#[unsafe(no_mangle)]
1711extern "C" fn TEE_DeriveKey(
1712    operation: TEE_OperationHandle,
1713    params: *mut TEE_Attribute,
1714    paramCount: u32,
1715    derivedKey: TEE_ObjectHandle,
1716) {
1717    unimplemented!()
1718}
1719
1720#[unsafe(no_mangle)]
1721extern "C" fn TEE_GenerateRandom(
1722    randomBuffer: *mut ::std::os::raw::c_void,
1723    randomBufferLen: usize,
1724) {
1725    let dest_slice = slice_from_raw_parts_mut(randomBuffer, randomBufferLen);
1726    zx::cprng_draw(dest_slice);
1727}
1728
1729#[unsafe(no_mangle)]
1730extern "C" fn TEE_GetSystemTime(time: *mut TEE_Time) {
1731    assert!(!time.is_null());
1732    let now = time::get_system_time();
1733    // SAFETY: `data` is non-null and the library must assume that it points to
1734    // valid memory.
1735    unsafe { *time = now };
1736}
1737
1738#[unsafe(no_mangle)]
1739extern "C" fn TEE_Wait(timeout: u32) -> TEE_Result {
1740    to_tee_result(time::wait(timeout))
1741}
1742
1743#[unsafe(no_mangle)]
1744extern "C" fn TEE_GetTAPersistentTime(time: *mut TEE_Time) -> TEE_Result {
1745    assert!(!time.is_null());
1746    to_tee_result(|| -> TeeResult {
1747        let now = time::get_ta_persistent_time()?;
1748        // SAFETY: `data` is non-null and the library must assume that it points to
1749        // valid memory.
1750        unsafe { *time = now };
1751        Ok(())
1752    }())
1753}
1754
1755#[unsafe(no_mangle)]
1756extern "C" fn TEE_SetTAPersistentTime(time: *mut TEE_Time) -> TEE_Result {
1757    assert!(!time.is_null());
1758    to_tee_result(|| -> TeeResult {
1759        // SAFETY: `data` is non-null and the library must assume that it points to
1760        // valid memory.
1761        let time = unsafe { *time };
1762        time::set_ta_persistent_time(&time)
1763    }())
1764}
1765
1766#[unsafe(no_mangle)]
1767extern "C" fn TEE_GetREETime(time: *mut TEE_Time) {
1768    assert!(!time.is_null());
1769    let now = time::get_ree_time();
1770    // SAFETY: `data` is non-null and the library must assume that it points to
1771    // valid memory.
1772    unsafe { *time = now };
1773}
1774
1775#[unsafe(no_mangle)]
1776extern "C" fn TEE_BigIntFMMContextSizeInU32(modulusSizeInBits: usize) -> usize {
1777    unimplemented!()
1778}
1779
1780#[unsafe(no_mangle)]
1781extern "C" fn TEE_BigIntFMMSizeInU32(modulusSizeInBits: usize) -> usize {
1782    unimplemented!()
1783}
1784
1785#[unsafe(no_mangle)]
1786extern "C" fn TEE_BigIntInit(bigInt: *mut TEE_BigInt, len: usize) {
1787    unimplemented!()
1788}
1789
1790#[unsafe(no_mangle)]
1791extern "C" fn TEE_BigIntInitFMMContext1(
1792    context: *mut TEE_BigIntFMMContext,
1793    len: usize,
1794    modulus: *mut TEE_BigInt,
1795) -> TEE_Result {
1796    unimplemented!()
1797}
1798
1799#[unsafe(no_mangle)]
1800extern "C" fn TEE_BigIntInitFMMContext(
1801    context: *mut TEE_BigIntFMMContext,
1802    len: usize,
1803    modulus: *mut TEE_BigInt,
1804) {
1805    unimplemented!()
1806}
1807
1808#[unsafe(no_mangle)]
1809extern "C" fn TEE_BigIntInitFMM(bigIntFMM: *mut TEE_BigIntFMM, len: usize) {
1810    unimplemented!()
1811}
1812
1813#[unsafe(no_mangle)]
1814extern "C" fn TEE_BigIntConvertFromOctetString(
1815    dest: *mut TEE_BigInt,
1816    buffer: *mut u8,
1817    bufferLen: usize,
1818    sign: i32,
1819) -> TEE_Result {
1820    unimplemented!()
1821}
1822
1823#[unsafe(no_mangle)]
1824extern "C" fn TEE_BigIntConvertToOctetString(
1825    buffer: *mut ::std::os::raw::c_void,
1826    bufferLen: *mut usize,
1827    bigInt: *mut TEE_BigInt,
1828) -> TEE_Result {
1829    unimplemented!()
1830}
1831
1832#[unsafe(no_mangle)]
1833extern "C" fn TEE_BigIntConvertFromS32(dest: *mut TEE_BigInt, shortVal: i32) {
1834    unimplemented!()
1835}
1836
1837#[unsafe(no_mangle)]
1838extern "C" fn TEE_BigIntConvertToS32(dest: *mut i32, src: *mut TEE_BigInt) -> TEE_Result {
1839    unimplemented!()
1840}
1841
1842#[unsafe(no_mangle)]
1843extern "C" fn TEE_BigIntCmp(op1: *mut TEE_BigInt, op2: *mut TEE_BigInt) -> i32 {
1844    unimplemented!()
1845}
1846
1847#[unsafe(no_mangle)]
1848extern "C" fn TEE_BigIntCmpS32(op: *mut TEE_BigInt, shortVal: i32) -> i32 {
1849    unimplemented!()
1850}
1851
1852#[unsafe(no_mangle)]
1853extern "C" fn TEE_BigIntShiftRight(dest: *mut TEE_BigInt, op: *mut TEE_BigInt, bits: usize) {
1854    unimplemented!()
1855}
1856
1857#[unsafe(no_mangle)]
1858extern "C" fn TEE_BigIntGetBit(src: *mut TEE_BigInt, bitIndex: u32) -> bool {
1859    unimplemented!()
1860}
1861
1862#[unsafe(no_mangle)]
1863extern "C" fn TEE_BigIntGetBitCount(src: *mut TEE_BigInt) -> u32 {
1864    unimplemented!()
1865}
1866
1867#[unsafe(no_mangle)]
1868extern "C" fn TEE_BigIntSetBit(op: *mut TEE_BigInt, bitIndex: u32, value: bool) -> TEE_Result {
1869    unimplemented!()
1870}
1871
1872#[unsafe(no_mangle)]
1873extern "C" fn TEE_BigIntAssign(dest: *mut TEE_BigInt, src: *mut TEE_BigInt) -> TEE_Result {
1874    unimplemented!()
1875}
1876
1877#[unsafe(no_mangle)]
1878extern "C" fn TEE_BigIntAbs(dest: *mut TEE_BigInt, src: *mut TEE_BigInt) -> TEE_Result {
1879    unimplemented!()
1880}
1881
1882#[unsafe(no_mangle)]
1883extern "C" fn TEE_BigIntAdd(dest: *mut TEE_BigInt, op1: *mut TEE_BigInt, op2: *mut TEE_BigInt) {
1884    unimplemented!()
1885}
1886
1887#[unsafe(no_mangle)]
1888extern "C" fn TEE_BigIntSub(dest: *mut TEE_BigInt, op1: *mut TEE_BigInt, op2: *mut TEE_BigInt) {
1889    unimplemented!()
1890}
1891
1892#[unsafe(no_mangle)]
1893extern "C" fn TEE_BigIntNeg(dest: *mut TEE_BigInt, op: *mut TEE_BigInt) {
1894    unimplemented!()
1895}
1896
1897#[unsafe(no_mangle)]
1898extern "C" fn TEE_BigIntMul(dest: *mut TEE_BigInt, op1: *mut TEE_BigInt, op2: *mut TEE_BigInt) {
1899    unimplemented!()
1900}
1901
1902#[unsafe(no_mangle)]
1903extern "C" fn TEE_BigIntSquare(dest: *mut TEE_BigInt, op: *mut TEE_BigInt) {
1904    unimplemented!()
1905}
1906
1907#[unsafe(no_mangle)]
1908extern "C" fn TEE_BigIntDiv(
1909    dest_q: *mut TEE_BigInt,
1910    dest_r: *mut TEE_BigInt,
1911    op1: *mut TEE_BigInt,
1912    op2: *mut TEE_BigInt,
1913) {
1914    unimplemented!()
1915}
1916
1917#[unsafe(no_mangle)]
1918extern "C" fn TEE_BigIntMod(dest: *mut TEE_BigInt, op: *mut TEE_BigInt, n: *mut TEE_BigInt) {
1919    unimplemented!()
1920}
1921
1922#[unsafe(no_mangle)]
1923extern "C" fn TEE_BigIntAddMod(
1924    dest: *mut TEE_BigInt,
1925    op1: *mut TEE_BigInt,
1926    op2: *mut TEE_BigInt,
1927    n: *mut TEE_BigInt,
1928) {
1929    unimplemented!()
1930}
1931
1932#[unsafe(no_mangle)]
1933extern "C" fn TEE_BigIntSubMod(
1934    dest: *mut TEE_BigInt,
1935    op1: *mut TEE_BigInt,
1936    op2: *mut TEE_BigInt,
1937    n: *mut TEE_BigInt,
1938) {
1939    unimplemented!()
1940}
1941
1942#[unsafe(no_mangle)]
1943extern "C" fn TEE_BigIntMulMod(
1944    dest: *mut TEE_BigInt,
1945    op1: *mut TEE_BigInt,
1946    op2: *mut TEE_BigInt,
1947    n: *mut TEE_BigInt,
1948) {
1949    unimplemented!()
1950}
1951
1952#[unsafe(no_mangle)]
1953extern "C" fn TEE_BigIntSquareMod(dest: *mut TEE_BigInt, op: *mut TEE_BigInt, n: *mut TEE_BigInt) {
1954    unimplemented!()
1955}
1956
1957#[unsafe(no_mangle)]
1958extern "C" fn TEE_BigIntInvMod(dest: *mut TEE_BigInt, op: *mut TEE_BigInt, n: *mut TEE_BigInt) {
1959    unimplemented!()
1960}
1961
1962#[unsafe(no_mangle)]
1963extern "C" fn TEE_BigIntExpMod(
1964    dest: *mut TEE_BigInt,
1965    op1: *mut TEE_BigInt,
1966    op2: *mut TEE_BigInt,
1967    n: *mut TEE_BigInt,
1968    context: *mut TEE_BigIntFMMContext,
1969) -> TEE_Result {
1970    unimplemented!()
1971}
1972
1973#[unsafe(no_mangle)]
1974extern "C" fn TEE_BigIntRelativePrime(op1: *mut TEE_BigInt, op2: *mut TEE_BigInt) -> bool {
1975    unimplemented!()
1976}
1977
1978#[unsafe(no_mangle)]
1979extern "C" fn TEE_BigIntComputeExtendedGcd(
1980    gcd: *mut TEE_BigInt,
1981    u: *mut TEE_BigInt,
1982    v: *mut TEE_BigInt,
1983    op1: *mut TEE_BigInt,
1984    op2: *mut TEE_BigInt,
1985) {
1986    unimplemented!()
1987}
1988
1989#[unsafe(no_mangle)]
1990extern "C" fn TEE_BigIntIsProbablePrime(op: *mut TEE_BigInt, confidenceLevel: u32) -> i32 {
1991    unimplemented!()
1992}
1993
1994#[unsafe(no_mangle)]
1995extern "C" fn TEE_BigIntConvertToFMM(
1996    dest: *mut TEE_BigIntFMM,
1997    src: *mut TEE_BigInt,
1998    n: *mut TEE_BigInt,
1999    context: *mut TEE_BigIntFMMContext,
2000) {
2001    unimplemented!()
2002}
2003
2004#[unsafe(no_mangle)]
2005extern "C" fn TEE_BigIntConvertFromFMM(
2006    dest: *mut TEE_BigInt,
2007    src: *mut TEE_BigIntFMM,
2008    n: *mut TEE_BigInt,
2009    context: *mut TEE_BigIntFMMContext,
2010) {
2011    unimplemented!()
2012}
2013
2014#[unsafe(no_mangle)]
2015extern "C" fn TEE_BigIntComputeFMM(
2016    dest: *mut TEE_BigIntFMM,
2017    op1: *mut TEE_BigIntFMM,
2018    op2: *mut TEE_BigIntFMM,
2019    n: *mut TEE_BigInt,
2020    context: *mut TEE_BigIntFMMContext,
2021) {
2022    unimplemented!()
2023}