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