tee_internal/
lib.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
5use bitflags::bitflags;
6use num_derive::FromPrimitive;
7use num_traits::FromPrimitive;
8use std::hash::Hash;
9use std::ops::{Deref, DerefMut};
10
11pub mod binding;
12
13//
14// As described in the crate README, here we define and export the richer, more
15// conventional/ergonomic, layout-compatible bindings for the TEE internal API.
16//
17// To conveniently translate between these types and the bindgen-generated
18// ones, non-integral types Foo that correspond to input parameters in the API
19// should admit a zero-copy
20// ```
21// fn from_binding<'a>(foo: &'a TEE_Foo) -> &'a Foo { ... }
22// ```
23// constructor, while those that correspond to output parameters should admit a
24// zero-copy
25// ```
26// fn to_binding<'a>(&'a self) -> &'a TEE_Foo { ... }
27// ```
28// method. The input_parameter!, output_parameter!, and inout_parameter! macros
29// can be used to automatically define these.
30//
31// Types below are listed in the order they appear in the spec.
32//
33// Layout-compatibility and zero-copy translation are verified in the tests below.
34//
35
36macro_rules! input_parameter {
37    ($name:ident, $tee_name:path) => {
38        impl $name {
39            pub fn from_binding<'a>(input: &'a $tee_name) -> &'a Self {
40                // SAFETY: ABI-compatibility checked below.
41                unsafe { &*((input as *const $tee_name) as *const Self) }
42            }
43        }
44    };
45}
46
47macro_rules! output_parameter {
48    ($name:ident, $tee_name:path) => {
49        impl $name {
50            pub fn to_binding<'a>(&'a self) -> &'a $tee_name {
51                // SAFETY:  ABI-compatibility checked below.
52                unsafe { &*((self as *const Self) as *const $tee_name) }
53            }
54        }
55    };
56}
57
58macro_rules! inout_parameter {
59    ($name:ident, $tee_name:path) => {
60        input_parameter!($name, $tee_name);
61        output_parameter!($name, $tee_name);
62    };
63}
64
65macro_rules! handle {
66    ($name:ident, $tee_name:path) => {
67        #[repr(C)]
68        #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
69        pub struct $name(u64);
70
71        impl $name {
72            pub fn from_value(value: u64) -> Self {
73                Self(value)
74            }
75
76            pub fn is_null(&self) -> bool {
77                self.0 == binding::TEE_HANDLE_NULL.into()
78            }
79        }
80
81        inout_parameter!($name, $tee_name);
82
83        impl Deref for $name {
84            type Target = u64;
85
86            fn deref(&self) -> &Self::Target {
87                &self.0
88            }
89        }
90
91        impl DerefMut for $name {
92            fn deref_mut(&mut self) -> &mut Self::Target {
93                &mut self.0
94            }
95        }
96    };
97}
98
99//
100// Common data types
101//
102
103handle!(TaSessionHandle, binding::TEE_TASessionHandle);
104handle!(PropSetHandle, binding::TEE_PropSetHandle);
105handle!(ObjectHandle, binding::TEE_ObjectHandle);
106handle!(ObjectEnumHandle, binding::TEE_ObjectEnumHandle);
107handle!(OperationHandle, binding::TEE_OperationHandle);
108
109// Bindgen didn't carry these values into the generated Rust bindings.
110pub const TEE_PROPSET_TEE_IMPLEMENTATION: PropSetHandle = PropSetHandle(0xfffffffd);
111pub const TEE_PROPSET_CURRENT_CLIENT: PropSetHandle = PropSetHandle(0xfffffffe);
112pub const TEE_PROPSET_CURRENT_TA: PropSetHandle = PropSetHandle(0xffffffff);
113
114#[repr(u32)]
115#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq, thiserror::Error)]
116pub enum Error {
117    #[error("Corrupt object")]
118    CorruptObject = binding::TEE_ERROR_CORRUPT_OBJECT,
119    #[error("Corrupt object")]
120    CorruptObject2 = binding::TEE_ERROR_CORRUPT_OBJECT_2,
121    #[error("Not available")]
122    NotAvailable = binding::TEE_ERROR_STORAGE_NOT_AVAILABLE,
123    #[error("Not available")]
124    NotAvailable2 = binding::TEE_ERROR_STORAGE_NOT_AVAILABLE_2,
125    #[error("Unsupported version")]
126    UnsupportedVersion = binding::TEE_ERROR_UNSUPPORTED_VERSION,
127    #[error("Invalid ciphertext")]
128    CiphertextInvalid = binding::TEE_ERROR_CIPHERTEXT_INVALID,
129    #[error("Generic error")]
130    Generic = binding::TEE_ERROR_GENERIC,
131    #[error("Access denied")]
132    AccessDenied = binding::TEE_ERROR_ACCESS_DENIED,
133    #[error("Canceled")]
134    Cancel = binding::TEE_ERROR_CANCEL,
135    #[error("Access conflict")]
136    AccessConflict = binding::TEE_ERROR_ACCESS_CONFLICT,
137    #[error("Excess data")]
138    ExcessData = binding::TEE_ERROR_EXCESS_DATA,
139    #[error("Bad format")]
140    BadFormat = binding::TEE_ERROR_BAD_FORMAT,
141    #[error("Bad parameters")]
142    BadParameters = binding::TEE_ERROR_BAD_PARAMETERS,
143    #[error("Bad state")]
144    BadState = binding::TEE_ERROR_BAD_STATE,
145    #[error("Item not found")]
146    ItemNotFound = binding::TEE_ERROR_ITEM_NOT_FOUND,
147    #[error("Not implemented")]
148    NotImplemented = binding::TEE_ERROR_NOT_IMPLEMENTED,
149    #[error("Not supported")]
150    NotSupported = binding::TEE_ERROR_NOT_SUPPORTED,
151    #[error("No data")]
152    NoData = binding::TEE_ERROR_NO_DATA,
153    #[error("Out of memory")]
154    OutOfMemory = binding::TEE_ERROR_OUT_OF_MEMORY,
155    #[error("Busy")]
156    Busy = binding::TEE_ERROR_BUSY,
157    #[error("Communication error")]
158    Communication = binding::TEE_ERROR_COMMUNICATION,
159    #[error("Security error")]
160    Security = binding::TEE_ERROR_SECURITY,
161    #[error("Buffer too small")]
162    ShortBuffer = binding::TEE_ERROR_SHORT_BUFFER,
163    #[error("Externally canceled")]
164    ExternalCancel = binding::TEE_ERROR_EXTERNAL_CANCEL,
165    #[error("Timeout")]
166    Timeout = binding::TEE_ERROR_TIMEOUT,
167    #[error("Overflow")]
168    Overflow = binding::TEE_ERROR_OVERFLOW,
169    #[error("Target is dead")]
170    TargetDead = binding::TEE_ERROR_TARGET_DEAD,
171    #[error("Out of storage space")]
172    StorageNoSpace = binding::TEE_ERROR_STORAGE_NO_SPACE,
173    #[error("Invalid MAC")]
174    MacInvalid = binding::TEE_ERROR_MAC_INVALID,
175    #[error("Invalid signature")]
176    SignatureInvalid = binding::TEE_ERROR_SIGNATURE_INVALID,
177    #[error("Time is not set")]
178    TimeNotSet = binding::TEE_ERROR_TIME_NOT_SET,
179    #[error("Time needs to be reset")]
180    TimeNeedsReset = binding::TEE_ERROR_TIME_NEEDS_RESET,
181}
182
183impl Error {
184    pub fn from_tee_result(result: binding::TEE_Result) -> Option<Self> {
185        match result {
186            binding::TEE_SUCCESS => None,
187            error => Some(Error::from_u32(error).unwrap_or(Error::Generic)),
188        }
189    }
190}
191
192pub type Result<T = ()> = std::result::Result<T, Error>;
193
194pub fn to_tee_result(result: crate::Result) -> binding::TEE_Result {
195    match result {
196        Ok(()) => binding::TEE_SUCCESS,
197        Err(error) => error as binding::TEE_Result,
198    }
199}
200
201#[repr(C)]
202#[derive(Clone, Copy, Debug, Default, PartialEq)]
203pub struct Uuid {
204    pub time_low: u32,
205    pub time_mid: u16,
206    pub time_hi_and_version: u16,
207    pub clock_seq_and_node: [u8; 8],
208}
209
210inout_parameter!(Uuid, binding::TEE_UUID);
211
212#[repr(C)]
213#[derive(Clone, Copy, Debug, PartialEq)]
214pub struct ValueFields {
215    pub a: u32,
216    pub b: u32,
217}
218
219#[repr(C)]
220#[derive(Clone, Copy, Debug, PartialEq)]
221pub struct MemRef {
222    pub buffer: *mut u8,
223    pub size: usize,
224}
225
226impl MemRef {
227    pub fn from_mut_slice(slice: &mut [u8]) -> Self {
228        MemRef { buffer: slice.as_mut_ptr(), size: slice.len() }
229    }
230
231    pub fn as_slice(&self) -> &[u8] {
232        self.assert_as_slice_preconditions();
233        // SAFETY: preconditions asserted above.
234        unsafe { std::slice::from_raw_parts(self.buffer, self.size) }
235    }
236
237    pub fn as_mut_slice(&mut self) -> &mut [u8] {
238        self.assert_as_slice_preconditions();
239        // SAFETY: preconditions asserted above.
240        unsafe { std::slice::from_raw_parts_mut(self.buffer, self.size) }
241    }
242
243    // Asserts that the preconditions to std::slice::from_raw_parts(_mut)? are
244    // met.
245    fn assert_as_slice_preconditions(&self) {
246        assert!(!self.buffer.is_null());
247        assert!(self.buffer.is_aligned());
248        assert!(self.size * size_of::<u8>() < isize::MAX.try_into().unwrap());
249    }
250}
251
252#[repr(C)]
253#[derive(Clone, Copy)]
254pub union BufferOrValue {
255    pub memref: MemRef,
256    pub value: ValueFields,
257}
258
259//
260// Trusted Core Framework data types
261//
262
263#[repr(C)]
264#[derive(Clone, Copy, Debug, PartialEq)]
265pub struct Identity {
266    pub login: Login,
267    pub uuid: Uuid,
268}
269
270output_parameter!(Identity, binding::TEE_Identity);
271
272pub type Param = BufferOrValue;
273
274inout_parameter!(Param, binding::TEE_Param);
275
276pub fn param_list_to_binding_mut<'a>(
277    params: &'a mut [Param; 4],
278) -> &'a mut [binding::TEE_Param; 4] {
279    // SAFETY: By virtue of Param-TEE_Param ABI compatibility.
280    unsafe {
281        &mut *(((params as *mut Param) as *mut binding::TEE_Param) as *mut [binding::TEE_Param; 4])
282    }
283}
284
285#[repr(u8)]
286#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
287pub enum ParamType {
288    None = binding::TEE_PARAM_TYPE_NONE as u8,
289    ValueInput = binding::TEE_PARAM_TYPE_VALUE_INPUT as u8,
290    ValueOutput = binding::TEE_PARAM_TYPE_VALUE_OUTPUT as u8,
291    ValueInout = binding::TEE_PARAM_TYPE_VALUE_INOUT as u8,
292    MemrefInput = binding::TEE_PARAM_TYPE_MEMREF_INPUT as u8,
293    MemrefOutput = binding::TEE_PARAM_TYPE_MEMREF_OUTPUT as u8,
294    MemrefInout = binding::TEE_PARAM_TYPE_MEMREF_INOUT as u8,
295}
296
297#[repr(C)]
298#[derive(Clone, Copy, Debug, Eq, PartialEq)]
299pub struct ParamTypes(u32);
300
301impl ParamTypes {
302    pub fn as_u32(&self) -> u32 {
303        self.0
304    }
305
306    pub fn get(&self, idx: usize) -> ParamType {
307        if idx >= 4 {
308            panic!("ParamTypes::get({}) too big; must be < 4", idx);
309        }
310        // We only expose a constructor that deals in valid ParamType values,
311        // so this cannot panic.
312        ParamType::from_u32((self.0 >> 4 * idx) & 0xf).unwrap()
313    }
314
315    pub fn from_types(types: [ParamType; 4]) -> Self {
316        let t0 = types[0] as u32;
317        let t1 = types[1] as u32;
318        let t2 = types[2] as u32;
319        let t3 = types[3] as u32;
320        Self(t0 | (t1 << 4) | (t2 << 8) | (t3 << 12))
321    }
322}
323
324#[repr(u32)]
325#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
326pub enum Login {
327    Public = binding::TEE_LOGIN_PUBLIC,
328    User = binding::TEE_LOGIN_USER,
329    Group = binding::TEE_LOGIN_GROUP,
330    Application = binding::TEE_LOGIN_APPLICATION,
331    ApplicationUser = binding::TEE_LOGIN_APPLICATION_USER,
332    ApplicationGroup = binding::TEE_LOGIN_APPLICATION_GROUP,
333    TrustedApp = binding::TEE_LOGIN_TRUSTED_APP,
334}
335
336#[repr(u32)]
337#[derive(Clone, Copy, Debug, Eq, PartialEq)]
338pub enum Origin {
339    Api = binding::TEE_ORIGIN_API,
340    Comms = binding::TEE_ORIGIN_COMMS,
341    Tee = binding::TEE_ORIGIN_TEE,
342    TrustedApp = binding::TEE_ORIGIN_TRUSTED_APP,
343}
344
345#[repr(C)]
346#[derive(Clone, Copy, Debug, Eq, PartialEq)]
347pub struct MemoryAccess(u32);
348
349bitflags! {
350    impl MemoryAccess : u32 {
351        const READ = binding::TEE_MEMORY_ACCESS_READ;
352        const WRITE = binding::TEE_MEMORY_ACCESS_WRITE;
353        const ANY_OWNER = binding::TEE_MEMORY_ACCESS_ANY_OWNER;
354  }
355}
356
357// Handle-like in practice if not one technically.
358handle!(SessionContext, usize);
359
360//
361// Trusted Storage data types
362//
363
364pub const OBJECT_ID_MAX_LEN: usize = binding::TEE_OBJECT_ID_MAX_LEN as usize;
365pub const DATA_MAX_POSITION: usize = binding::TEE_DATA_MAX_POSITION as usize;
366
367#[repr(C)]
368#[derive(Clone, Copy)]
369pub struct Attribute {
370    pub id: AttributeId,
371    pub content: BufferOrValue,
372}
373
374output_parameter!(Attribute, binding::TEE_Attribute);
375
376impl Attribute {
377    // A fallible version that checks for a valid attribute ID.
378    pub fn from_binding<'a>(attr: &'a binding::TEE_Attribute) -> Option<&'a Self> {
379        // Check for valid attribute ID.
380        let _ = AttributeId::from_u32(attr.attributeID)?;
381
382        // SAFETY:  ABI-compatibility checked below.
383        unsafe { Some(&*((attr as *const binding::TEE_Attribute) as *const Self)) }
384    }
385
386    // Whether the attribute is public (i.e., can be extracted from an object
387    // regardless of its defined usage).
388    pub fn is_public(&self) -> bool {
389        self.id.public()
390    }
391
392    // Whether the attribute is given by value fields.
393    pub fn is_value(&self) -> bool {
394        self.id.value()
395    }
396
397    // Whether the attribute is given by a memory reference.
398    pub fn is_memory_reference(&self) -> bool {
399        self.id.memory_reference()
400    }
401
402    pub fn as_value(&self) -> &ValueFields {
403        assert!(self.is_value());
404        // SAFETY: The above assertion ensures that this variant is what is
405        // 'live'.
406        unsafe { &self.content.value }
407    }
408
409    pub fn as_memory_reference(&self) -> &MemRef {
410        assert!(self.is_memory_reference());
411        // SAFETY: The above assertion ensures that this variant is what is
412        // 'live'.
413        unsafe { &self.content.memref }
414    }
415}
416
417#[repr(C)]
418#[derive(Clone, Copy, Debug, PartialEq)]
419pub struct ObjectInfo {
420    pub object_type: Type,
421    pub object_size: u32,
422    pub max_object_size: u32,
423    pub object_usage: Usage,
424    pub data_size: usize,
425    pub data_position: usize,
426    pub handle_flags: HandleFlags,
427}
428
429output_parameter!(ObjectInfo, binding::TEE_ObjectInfo);
430
431#[repr(u32)]
432#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
433pub enum Whence {
434    DataSeekSet = binding::TEE_DATA_SEEK_SET,
435    DataSeekCur = binding::TEE_DATA_SEEK_CUR,
436    DataSeekEnd = binding::TEE_DATA_SEEK_END,
437}
438
439#[repr(u32)]
440#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
441pub enum Storage {
442    Private = binding::TEE_STORAGE_PRIVATE,
443    Perso = binding::TEE_STORAGE_PERSO,
444    Protected = binding::TEE_STORAGE_PROTECTED,
445}
446
447#[repr(C)]
448#[derive(Clone, Copy, Debug, PartialEq, Eq)]
449pub struct Usage(u32);
450
451bitflags! {
452    impl Usage : u32 {
453        const EXTRACTABLE = binding::TEE_USAGE_EXTRACTABLE;
454        const ENCRYPT = binding::TEE_USAGE_ENCRYPT;
455        const DECRYPT = binding::TEE_USAGE_DECRYPT;
456        const MAC = binding::TEE_USAGE_MAC;
457        const SIGN = binding::TEE_USAGE_SIGN;
458        const VERIFY = binding::TEE_USAGE_VERIFY;
459        const DERIVE = binding::TEE_USAGE_DERIVE;
460  }
461}
462
463impl Usage {
464    pub fn default() -> Usage {
465        Usage::from_bits_retain(0xffffffff)
466    }
467}
468
469#[repr(C)]
470#[derive(Clone, Copy, Debug, PartialEq, Eq)]
471pub struct HandleFlags(u32);
472
473bitflags! {
474    impl HandleFlags : u32 {
475        const PERSISTENT = binding::TEE_HANDLE_FLAG_PERSISTENT;
476        const INITIALIZED = binding::TEE_HANDLE_FLAG_INITIALIZED;
477        const KEY_SET = binding::TEE_HANDLE_FLAG_KEY_SET;
478        const EXPECT_TWO_KEYS = binding::TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
479        const EXTRACTING = binding::TEE_HANDLE_FLAG_EXTRACTING;
480
481        // Only valid for persistent objects.
482        const DATA_ACCESS_READ = binding::TEE_DATA_FLAG_ACCESS_READ;
483        const DATA_ACCESS_WRITE = binding::TEE_DATA_FLAG_ACCESS_WRITE;
484        const DATA_ACCESS_WRITE_META = binding::TEE_DATA_FLAG_ACCESS_WRITE_META;
485        const DATA_SHARE_READ = binding::TEE_DATA_FLAG_SHARE_READ;
486        const DATA_SHARE_WRITE = binding::TEE_DATA_FLAG_SHARE_WRITE;
487        const DATA_FLAG_OVERWRITE = binding::TEE_DATA_FLAG_OVERWRITE;
488  }
489}
490
491#[repr(u32)]
492#[derive(Clone, Copy, Debug, Eq, PartialEq)]
493pub enum Operation {
494    Cipher = binding::TEE_OPERATION_CIPHER,
495    Mac = binding::TEE_OPERATION_MAC,
496    Ae = binding::TEE_OPERATION_AE,
497    Digest = binding::TEE_OPERATION_DIGEST,
498    AsymmetricCipher = binding::TEE_OPERATION_ASYMMETRIC_CIPHER,
499    AsymmetricSignature = binding::TEE_OPERATION_ASYMMETRIC_SIGNATURE,
500    KeyDerivation = binding::TEE_OPERATION_KEY_DERIVATION,
501}
502
503#[repr(u32)]
504#[derive(Clone, Copy, Debug, Eq, PartialEq)]
505pub enum OperationState {
506    Initial = binding::TEE_OPERATION_STATE_INITIAL,
507    Active = binding::TEE_OPERATION_STATE_ACTIVE,
508    Extracting = binding::TEE_OPERATION_STATE_EXTRACTING,
509}
510
511#[repr(u32)]
512#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
513pub enum Type {
514    Aes = binding::TEE_TYPE_AES,
515    Des = binding::TEE_TYPE_DES,
516    Des3 = binding::TEE_TYPE_DES3,
517    Md5 = binding::TEE_TYPE_HMAC_MD5,
518    HmacSha1 = binding::TEE_TYPE_HMAC_SHA1,
519    HmacSha224 = binding::TEE_TYPE_HMAC_SHA224,
520    HmacSha256 = binding::TEE_TYPE_HMAC_SHA256,
521    HmacSha384 = binding::TEE_TYPE_HMAC_SHA384,
522    HmacSha512 = binding::TEE_TYPE_HMAC_SHA512,
523    HmacSm3 = binding::TEE_TYPE_HMAC_SM3,
524    HmacSha3_224 = binding::TEE_TYPE_HMAC_SHA3_224,
525    HmacSha3_256 = binding::TEE_TYPE_HMAC_SHA3_256,
526    HmacSha3_384 = binding::TEE_TYPE_HMAC_SHA3_384,
527    HmacSha3_512 = binding::TEE_TYPE_HMAC_SHA3_512,
528    RsaPublicKey = binding::TEE_TYPE_RSA_PUBLIC_KEY,
529    RsaKeypair = binding::TEE_TYPE_RSA_KEYPAIR,
530    DsaPublicKey = binding::TEE_TYPE_DSA_PUBLIC_KEY,
531    DsaKeypair = binding::TEE_TYPE_DSA_KEYPAIR,
532    DhKeypair = binding::TEE_TYPE_DH_KEYPAIR,
533    EcdsaPublicKey = binding::TEE_TYPE_ECDSA_PUBLIC_KEY,
534    EcdsaKeypair = binding::TEE_TYPE_ECDSA_KEYPAIR,
535    EcdhPublicKey = binding::TEE_TYPE_ECDH_PUBLIC_KEY,
536    EcdhKeypair = binding::TEE_TYPE_ECDH_KEYPAIR,
537    Ed25519PublicKey = binding::TEE_TYPE_ED25519_PUBLIC_KEY,
538    Ed25519Keypair = binding::TEE_TYPE_ED25519_KEYPAIR,
539    X25519PublicKey = binding::TEE_TYPE_X25519_PUBLIC_KEY,
540    X25519Keypair = binding::TEE_TYPE_X25519_KEYPAIR,
541    Sm2DsaPublicKey = binding::TEE_TYPE_SM2_DSA_PUBLIC_KEY,
542    Sm2DsaKeypair = binding::TEE_TYPE_SM2_DSA_KEYPAIR,
543    Sm2KepPublicKey = binding::TEE_TYPE_SM2_KEP_PUBLIC_KEY,
544    Sm2KepKeypair = binding::TEE_TYPE_SM2_KEP_KEYPAIR,
545    Sm2PkePublicKey = binding::TEE_TYPE_SM2_PKE_PUBLIC_KEY,
546    Sm2PkeKeypair = binding::TEE_TYPE_SM2_PKE_KEYPAIR,
547    Sm4 = binding::TEE_TYPE_SM4,
548    Hkdf = binding::TEE_TYPE_HKDF,
549    GenericSecret = binding::TEE_TYPE_GENERIC_SECRET,
550    CorruptedObject = binding::TEE_TYPE_CORRUPTED_OBJECT,
551    Data = binding::TEE_TYPE_DATA,
552}
553
554//
555// Cryptographic data types
556//
557
558#[repr(u32)]
559#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
560pub enum Mode {
561    Encrypt = binding::TEE_MODE_ENCRYPT,
562    Decrypt = binding::TEE_MODE_DECRYPT,
563    Sign = binding::TEE_MODE_SIGN,
564    Verify = binding::TEE_MODE_VERIFY,
565    Mac = binding::TEE_MODE_MAC,
566    Digest = binding::TEE_MODE_DIGEST,
567    Derive = binding::TEE_MODE_DERIVE,
568}
569
570#[repr(C)]
571#[derive(Clone, Copy, Debug, PartialEq)]
572pub struct OperationInfo {
573    pub algorithm: Algorithm,
574    pub operation_class: Operation,
575    pub mode: Mode,
576    pub digest_length: u32,
577    pub max_key_size: u32,
578    pub key_size: u32,
579    pub required_key_usage: Usage,
580    pub handle_state: HandleFlags,
581}
582
583output_parameter!(OperationInfo, binding::TEE_OperationInfo);
584
585#[repr(C)]
586#[derive(Clone, Copy, Debug, PartialEq)]
587pub struct OperationInfoKey {
588    pub key_size: u32,
589    pub required_key_usage: Usage,
590}
591
592output_parameter!(OperationInfoKey, binding::TEE_OperationInfoKey);
593
594#[repr(C)]
595#[derive(Debug)]
596pub struct OperationInfoMultiple {
597    pub algorithm: Algorithm,
598    pub operation_class: Operation,
599    pub mode: Mode,
600    pub digest_length: u32,
601    pub max_key_size: u32,
602    pub handle_state: HandleFlags,
603    pub operation_state: OperationState,
604    pub number_of_keys: u32,
605    pub key_information: binding::__IncompleteArrayField<OperationInfoKey>,
606}
607
608output_parameter!(OperationInfoMultiple, binding::TEE_OperationInfoMultiple);
609
610#[repr(u32)]
611#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
612pub enum Algorithm {
613    AesEcbNopad = binding::TEE_ALG_AES_ECB_NOPAD,
614    AesCbcNopad = binding::TEE_ALG_AES_CBC_NOPAD,
615    AesCtr = binding::TEE_ALG_AES_CTR,
616    AesCts = binding::TEE_ALG_AES_CTS,
617    AesXts = binding::TEE_ALG_AES_XTS,
618    AesCbcMacNopad = binding::TEE_ALG_AES_CBC_MAC_NOPAD,
619    AesCbcMacPkcs5 = binding::TEE_ALG_AES_CBC_MAC_PKCS5,
620    AesCmac = binding::TEE_ALG_AES_CMAC,
621    AesCcm = binding::TEE_ALG_AES_CCM,
622    AesGcm = binding::TEE_ALG_AES_GCM,
623    DesEcbNopad = binding::TEE_ALG_DES_ECB_NOPAD,
624    DesCbcNopad = binding::TEE_ALG_DES_CBC_NOPAD,
625    DesCbcMacNopad = binding::TEE_ALG_DES_CBC_MAC_NOPAD,
626    DesCbcMacPkcs5 = binding::TEE_ALG_DES_CBC_MAC_PKCS5,
627    Des3EcbNopad = binding::TEE_ALG_DES3_ECB_NOPAD,
628    Des3CbcNopad = binding::TEE_ALG_DES3_CBC_NOPAD,
629    Des3CbcMacNopad = binding::TEE_ALG_DES3_CBC_MAC_NOPAD,
630    Des3CbcMacPkcs5 = binding::TEE_ALG_DES3_CBC_MAC_PKCS5,
631    RsassaPkcs1V1_5Md5 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_MD5,
632    RsassaPkcs1V1_5Sha1 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA1,
633    RsassaPkcs1V1_5Sha224 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA224,
634    RsassaPkcs1V1_5Sha256 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA256,
635    RsassaPkcs1V1_5Sha384 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA384,
636    RsassaPkcs1V1_5Sha512 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA512,
637    RsassaPkcs1V1_5Sha3_224 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA3_224,
638    RsassaPkcs1V1_5Sha3_256 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA3_256,
639    RsassaPkcs1V1_5Sha3_384 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA3_384,
640    RsassaPkcs1V1_5Sha3_512 = binding::TEE_ALG_RSASSA_PKCS1_V1_5_SHA3_512,
641    RsassaPkcs1PssMgf1Sha1 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1,
642    RsassaPkcs1PssMgf1Sha224 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224,
643    RsassaPkcs1PssMgf1Sha256 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256,
644    RsassaPkcs1PssMgf1Sha384 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384,
645    RsassaPkcs1PssMgf1Sha512 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512,
646    RsassaPkcs1PssMgf1Sha3_224 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA3_224,
647    RsassaPkcs1PssMgf1Sha3_256 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA3_256,
648    RsassaPkcs1PssMgf1Sha3_384 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA3_384,
649    RsassaPkcs1PssMgf1Sha3_512 = binding::TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA3_512,
650    RsaesPkcs1V1_5 = binding::TEE_ALG_RSAES_PKCS1_V1_5,
651    RsaesPkcs1OaepMgf1Sha1 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1,
652    RsaesPkcs1OaepMgf1Sha224 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224,
653    RsaesPkcs1OaepMgf1Sha256 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256,
654    RsaesPkcs1OaepMgf1Sha384 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384,
655    RsaesPkcs1OaepMgf1Sha512 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512,
656    RsaesPkcs1OaepMgf1Sha3_224 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA3_224,
657    RsaesPkcs1OaepMgf1Sha3_256 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA3_256,
658    RsaesPkcs1OaepMgf1Sha3_384 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA3_384,
659    RsaesPkcs1OaepMgf1Sha3_512 = binding::TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA3_512,
660    RsaNopad = binding::TEE_ALG_RSA_NOPAD,
661    DsaSha1 = binding::TEE_ALG_DSA_SHA1,
662    DsaSha224 = binding::TEE_ALG_DSA_SHA224,
663    DsaSha256 = binding::TEE_ALG_DSA_SHA256,
664    DsaSha3_224 = binding::TEE_ALG_DSA_SHA3_224,
665    DsaSha3_256 = binding::TEE_ALG_DSA_SHA3_256,
666    DsaSha3_384 = binding::TEE_ALG_DSA_SHA3_384,
667    DsaSha3_512 = binding::TEE_ALG_DSA_SHA3_512,
668    DhDeriveSharedSecret = binding::TEE_ALG_DH_DERIVE_SHARED_SECRET,
669    Md5 = binding::TEE_ALG_MD5,
670    Sha1 = binding::TEE_ALG_SHA1,
671    Sha224 = binding::TEE_ALG_SHA224,
672    Sha256 = binding::TEE_ALG_SHA256,
673    Sha384 = binding::TEE_ALG_SHA384,
674    Sha512 = binding::TEE_ALG_SHA512,
675    Sha3_224 = binding::TEE_ALG_SHA3_224,
676    Sha3_256 = binding::TEE_ALG_SHA3_256,
677    Sha3_384 = binding::TEE_ALG_SHA3_384,
678    Sha3_512 = binding::TEE_ALG_SHA3_512,
679    HmacMd5 = binding::TEE_ALG_HMAC_MD5,
680    HmacSha1 = binding::TEE_ALG_HMAC_SHA1,
681    HmacSha224 = binding::TEE_ALG_HMAC_SHA224,
682    HmacSha256 = binding::TEE_ALG_HMAC_SHA256,
683    HmacSha384 = binding::TEE_ALG_HMAC_SHA384,
684    HmacSha512 = binding::TEE_ALG_HMAC_SHA512,
685    HmacSha3_224 = binding::TEE_ALG_HMAC_SHA3_224,
686    HmacSha3_256 = binding::TEE_ALG_HMAC_SHA3_256,
687    HmacSha3_384 = binding::TEE_ALG_HMAC_SHA3_384,
688    HmacSha3_512 = binding::TEE_ALG_HMAC_SHA3_512,
689    Hkdf = binding::TEE_ALG_HKDF,
690    Shake128 = binding::TEE_ALG_SHAKE128,
691    Shake256 = binding::TEE_ALG_SHAKE256,
692}
693
694#[repr(u32)]
695#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
696pub enum EccCurve {
697    None = binding::TEE_CRYPTO_ELEMENT_NONE,
698    NistP192 = binding::TEE_ECC_CURVE_NIST_P192,
699    NistP224 = binding::TEE_ECC_CURVE_NIST_P224,
700    NistP256 = binding::TEE_ECC_CURVE_NIST_P256,
701    NistP384 = binding::TEE_ECC_CURVE_NIST_P384,
702    NistP521 = binding::TEE_ECC_CURVE_NIST_P521,
703    BsiP160r1 = binding::TEE_ECC_CURVE_BSI_P160r1,
704    BsiP192r1 = binding::TEE_ECC_CURVE_BSI_P192r1,
705    BsiP224r1 = binding::TEE_ECC_CURVE_BSI_P224r1,
706    BsiP256r1 = binding::TEE_ECC_CURVE_BSI_P256r1,
707    BsiP320r1 = binding::TEE_ECC_CURVE_BSI_P320r1,
708    BsiP384r1 = binding::TEE_ECC_CURVE_BSI_P384r1,
709    BsiP512r1 = binding::TEE_ECC_CURVE_BSI_P512r1,
710    BsiP160t1 = binding::TEE_ECC_CURVE_BSI_P160t1,
711    BsiP192t1 = binding::TEE_ECC_CURVE_BSI_P192t1,
712    BsiP224t1 = binding::TEE_ECC_CURVE_BSI_P224t1,
713    BsiP256t1 = binding::TEE_ECC_CURVE_BSI_P256t1,
714    BsiP320t1 = binding::TEE_ECC_CURVE_BSI_P320t1,
715    BsiP384t1 = binding::TEE_ECC_CURVE_BSI_P384t1,
716    BsiP512t1 = binding::TEE_ECC_CURVE_BSI_P512t1,
717    _448 = binding::TEE_ECC_CURVE_448,
718    Sm2 = binding::TEE_ECC_CURVE_SM2,
719}
720
721#[repr(u32)]
722#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
723pub enum AttributeId {
724    SecretValue = binding::TEE_ATTR_SECRET_VALUE,
725    RsaModulus = binding::TEE_ATTR_RSA_MODULUS,
726    RsaPublicExponent = binding::TEE_ATTR_RSA_PUBLIC_EXPONENT,
727    RsaPrivateExponent = binding::TEE_ATTR_RSA_PRIVATE_EXPONENT,
728    RsaPrime1 = binding::TEE_ATTR_RSA_PRIME1,
729    RsaPrime2 = binding::TEE_ATTR_RSA_PRIME2,
730    RsaExponent1 = binding::TEE_ATTR_RSA_EXPONENT1,
731    RsaExponent2 = binding::TEE_ATTR_RSA_EXPONENT2,
732    RsaCoefficient = binding::TEE_ATTR_RSA_COEFFICIENT,
733    DsaPrime = binding::TEE_ATTR_DSA_PRIME,
734    DsaSubprimme = binding::TEE_ATTR_DSA_SUBPRIME,
735    DsaBase = binding::TEE_ATTR_DSA_BASE,
736    DsaPublicValue = binding::TEE_ATTR_DSA_PUBLIC_VALUE,
737    DsaPrivateValue = binding::TEE_ATTR_DSA_PRIVATE_VALUE,
738    DhPrime = binding::TEE_ATTR_DH_PRIME,
739    DhSubprime = binding::TEE_ATTR_DH_SUBPRIME,
740    DhBase = binding::TEE_ATTR_DH_BASE,
741    DhXBits = binding::TEE_ATTR_DH_X_BITS,
742    DhPublicValue = binding::TEE_ATTR_DH_PUBLIC_VALUE,
743    DhPrivateValue = binding::TEE_ATTR_DH_PRIVATE_VALUE,
744    RsaOaepLabel = binding::TEE_ATTR_RSA_OAEP_LABEL,
745    RsaOaepMgfHash = binding::TEE_ATTR_RSA_OAEP_MGF_HASH,
746    RsaPssSaltLength = binding::TEE_ATTR_RSA_PSS_SALT_LENGTH,
747    EccPublicValueX = binding::TEE_ATTR_ECC_PUBLIC_VALUE_X,
748    EccPublicValueY = binding::TEE_ATTR_ECC_PUBLIC_VALUE_Y,
749    EccPrivateValue = binding::TEE_ATTR_ECC_PRIVATE_VALUE,
750    EccEphemeralPublicValueX = binding::TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_X,
751    EccEphemeralPublicValueY = binding::TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_Y,
752    EccCurve = binding::TEE_ATTR_ECC_CURVE,
753    EddsaCtx = binding::TEE_ATTR_EDDSA_CTX,
754    Ed25519PublicValue = binding::TEE_ATTR_ED25519_PUBLIC_VALUE,
755    Ed25519PrivateValue = binding::TEE_ATTR_ED25519_PRIVATE_VALUE,
756    X25519PublicValue = binding::TEE_ATTR_X25519_PUBLIC_VALUE,
757    X25519PrivateValue = binding::TEE_ATTR_X25519_PRIVATE_VALUE,
758    Ed448PublicValue = binding::TEE_ATTR_ED448_PUBLIC_VALUE,
759    Ed448PrivateValue = binding::TEE_ATTR_ED448_PRIVATE_VALUE,
760    EddsaPrehash = binding::TEE_ATTR_EDDSA_PREHASH,
761    X448PublicValue = binding::TEE_ATTR_X448_PUBLIC_VALUE,
762    X448PrivateValue = binding::TEE_ATTR_X448_PRIVATE_VALUE,
763    Sm2IdInitiator = binding::TEE_ATTR_SM2_ID_INITIATOR,
764    Sm2IdResponder = binding::TEE_ATTR_SM2_ID_RESPONDER,
765    Sm2KepUser = binding::TEE_ATTR_SM2_KEP_USER,
766    Sm2KepConfirmationIn = binding::TEE_ATTR_SM2_KEP_CONFIRMATION_IN,
767    Sm2KepConfirmationOut = binding::TEE_ATTR_SM2_KEP_CONFIRMATION_OUT,
768    HkdfSalt = binding::TEE_ATTR_HKDF_SALT,
769    HkdfInfo = binding::TEE_ATTR_HKDF_INFO,
770    HkdfHashAlgorithm = binding::TEE_ATTR_HKDF_HASH_ALGORITHM,
771    KdfKeySize = binding::TEE_ATTR_KDF_KEY_SIZE,
772}
773
774impl AttributeId {
775    // Whether the ID represents an attribute that is public (i.e., can be
776    // extracted from an object regardless of its defined usage).
777    pub fn public(self) -> bool {
778        (self as u32) & binding::TEE_ATTR_FLAG_PUBLIC != 0
779    }
780
781    // Whether the ID represents a value attribute.
782    pub fn value(self) -> bool {
783        (self as u32) & binding::TEE_ATTR_FLAG_VALUE != 0
784    }
785
786    // Whether the ID represents a memory reference attribute.
787    pub fn memory_reference(self) -> bool {
788        !self.value()
789    }
790}
791
792//
793// Time data types
794//
795
796pub type Time = binding::TEE_Time;
797
798#[cfg(test)]
799pub mod tests {
800    use super::*;
801
802    use binding::{
803        TEE_Attribute, TEE_Attribute__bindgen_ty_1, TEE_Attribute__bindgen_ty_1__bindgen_ty_1,
804        TEE_Attribute__bindgen_ty_1__bindgen_ty_2, TEE_Identity, TEE_ObjectEnumHandle,
805        TEE_ObjectHandle, TEE_ObjectInfo, TEE_OperationHandle, TEE_OperationInfo,
806        TEE_OperationInfoKey, TEE_OperationInfoMultiple, TEE_Param, TEE_Param__bindgen_ty_1,
807        TEE_Param__bindgen_ty_2, TEE_PropSetHandle, TEE_Result, TEE_TASessionHandle, TEE_UUID,
808    };
809    use std::mem::{align_of, align_of_val, offset_of, size_of, size_of_val};
810    use std::ptr::addr_of;
811
812    const EMPTY_TEE_UUID: TEE_UUID =
813        TEE_UUID { timeLow: 0, timeMid: 0, timeHiAndVersion: 0, clockSeqAndNode: [0; 8] };
814
815    #[test]
816    pub fn test_param_types() {
817        let types = ParamTypes::from_types([
818            ParamType::ValueInout,
819            ParamType::MemrefInput,
820            ParamType::None,
821            ParamType::ValueOutput,
822        ]);
823        assert_eq!(types.get(0), ParamType::ValueInout);
824        assert_eq!(types.get(1), ParamType::MemrefInput);
825        assert_eq!(types.get(2), ParamType::None);
826        assert_eq!(types.get(3), ParamType::ValueOutput);
827
828        assert_eq!(3u32 | 5u32 << 4 | 2u32 << 12, types.as_u32());
829    }
830
831    #[test]
832    pub fn test_abi_compat_ta_session_handle() {
833        assert_eq!(size_of::<TaSessionHandle>(), size_of::<TEE_TASessionHandle>());
834        assert_eq!(align_of::<TaSessionHandle>(), align_of::<TEE_TASessionHandle>());
835
836        let new = TaSessionHandle::from_value(0);
837        let old: TEE_TASessionHandle = std::ptr::null_mut();
838
839        // Verify zero-copy translation.
840        assert_eq!(addr_of!(*TaSessionHandle::from_binding(&old)) as usize, addr_of!(old) as usize);
841        assert_eq!(addr_of!(*TaSessionHandle::to_binding(&new)) as usize, addr_of!(new) as usize);
842    }
843
844    #[test]
845    pub fn test_abi_compat_prop_set_handle() {
846        assert_eq!(size_of::<PropSetHandle>(), size_of::<TEE_PropSetHandle>());
847        assert_eq!(align_of::<PropSetHandle>(), align_of::<TEE_PropSetHandle>());
848
849        let new = PropSetHandle::from_value(0);
850        let old: TEE_PropSetHandle = std::ptr::null_mut();
851
852        // Verify zero-copy translation.
853        assert_eq!(addr_of!(*PropSetHandle::from_binding(&old)) as usize, addr_of!(old) as usize);
854        assert_eq!(addr_of!(*PropSetHandle::to_binding(&new)) as usize, addr_of!(new) as usize);
855    }
856
857    #[test]
858    pub fn test_abi_compat_object_handle() {
859        assert_eq!(size_of::<ObjectHandle>(), size_of::<TEE_ObjectHandle>());
860        assert_eq!(align_of::<ObjectHandle>(), align_of::<TEE_ObjectHandle>());
861
862        let new = ObjectHandle::from_value(0);
863        let old: TEE_ObjectHandle = std::ptr::null_mut();
864
865        // Verify zero-copy translation.
866        assert_eq!(addr_of!(*ObjectHandle::from_binding(&old)) as usize, addr_of!(old) as usize);
867        assert_eq!(addr_of!(*ObjectHandle::to_binding(&new)) as usize, addr_of!(new) as usize);
868    }
869
870    #[test]
871    pub fn test_abi_compat_object_enum_handle() {
872        assert_eq!(size_of::<ObjectEnumHandle>(), size_of::<TEE_ObjectEnumHandle>());
873        assert_eq!(align_of::<ObjectEnumHandle>(), align_of::<TEE_ObjectEnumHandle>());
874
875        let new = ObjectEnumHandle::from_value(0);
876        let old: TEE_ObjectEnumHandle = std::ptr::null_mut();
877
878        // Verify zero-copy translation.
879        assert_eq!(
880            addr_of!(*ObjectEnumHandle::from_binding(&old)) as usize,
881            addr_of!(old) as usize
882        );
883        assert_eq!(addr_of!(*ObjectEnumHandle::to_binding(&new)) as usize, addr_of!(new) as usize);
884    }
885
886    #[test]
887    pub fn test_abi_compat_operation_handle() {
888        assert_eq!(size_of::<OperationHandle>(), size_of::<TEE_OperationHandle>());
889        assert_eq!(align_of::<OperationHandle>(), align_of::<TEE_OperationHandle>());
890
891        let new = OperationHandle::from_value(0);
892        let old: TEE_OperationHandle = std::ptr::null_mut();
893
894        // Verify zero-copy translation.
895        assert_eq!(addr_of!(*OperationHandle::from_binding(&old)) as usize, addr_of!(old) as usize);
896        assert_eq!(addr_of!(*OperationHandle::to_binding(&new)) as usize, addr_of!(new) as usize);
897    }
898
899    #[test]
900    pub fn test_abi_compat_result() {
901        assert_eq!(size_of::<Error>(), size_of::<TEE_Result>());
902        assert_eq!(align_of::<Error>(), align_of::<TEE_Result>());
903    }
904
905    #[test]
906    pub fn test_abi_compat_uuid() {
907        assert_eq!(size_of::<Uuid>(), size_of::<TEE_UUID>());
908        assert_eq!(align_of::<Uuid>(), align_of::<TEE_UUID>());
909
910        let new = Uuid::default();
911        let old = EMPTY_TEE_UUID;
912
913        assert_eq!(offset_of!(Uuid, time_low), offset_of!(TEE_UUID, timeLow));
914        assert_eq!(size_of_val(&new.time_low), size_of_val(&old.timeLow));
915        assert_eq!(align_of_val(&new.time_low), align_of_val(&old.timeLow));
916
917        assert_eq!(offset_of!(Uuid, time_mid), offset_of!(TEE_UUID, timeMid));
918        assert_eq!(size_of_val(&new.time_mid), size_of_val(&old.timeMid));
919        assert_eq!(align_of_val(&new.time_mid), align_of_val(&old.timeMid));
920
921        assert_eq!(offset_of!(Uuid, time_hi_and_version), offset_of!(TEE_UUID, timeHiAndVersion));
922        assert_eq!(size_of_val(&new.time_hi_and_version), size_of_val(&old.timeHiAndVersion));
923        assert_eq!(align_of_val(&new.time_hi_and_version), align_of_val(&old.timeHiAndVersion));
924
925        // Verify zero-copy translation.
926        assert_eq!(addr_of!(*Uuid::from_binding(&old)) as usize, addr_of!(old) as usize);
927        assert_eq!(addr_of!(*Uuid::to_binding(&new)) as usize, addr_of!(new) as usize);
928    }
929
930    #[test]
931    pub fn test_abi_compat_identity() {
932        assert_eq!(size_of::<Identity>(), size_of::<TEE_Identity>());
933        assert_eq!(align_of::<Identity>(), align_of::<TEE_Identity>());
934
935        let new = Identity { login: Login::TrustedApp, uuid: Uuid::default() };
936        let old = TEE_Identity { login: 0, uuid: EMPTY_TEE_UUID };
937
938        assert_eq!(offset_of!(Identity, login), offset_of!(TEE_Identity, login));
939        assert_eq!(size_of_val(&new.login), size_of_val(&old.login));
940        assert_eq!(align_of_val(&new.login), align_of_val(&old.login));
941
942        assert_eq!(offset_of!(Identity, uuid), offset_of!(TEE_Identity, uuid));
943        assert_eq!(size_of_val(&new.uuid), size_of_val(&old.uuid));
944        assert_eq!(align_of_val(&new.uuid), align_of_val(&old.uuid));
945
946        // Verify zero-copy translation.
947        assert_eq!(addr_of!(*Identity::to_binding(&new)) as usize, addr_of!(new) as usize);
948    }
949
950    #[test]
951    pub fn test_abi_compat_param() {
952        assert_eq!(size_of::<Param>(), size_of::<TEE_Param>());
953        assert_eq!(align_of::<Param>(), align_of::<TEE_Param>());
954
955        assert_eq!(size_of::<MemRef>(), size_of::<TEE_Param__bindgen_ty_1>());
956        assert_eq!(align_of::<MemRef>(), align_of::<TEE_Param__bindgen_ty_1>());
957
958        assert_eq!(size_of::<ValueFields>(), size_of::<TEE_Param__bindgen_ty_2>());
959        assert_eq!(align_of::<ValueFields>(), align_of::<TEE_Param__bindgen_ty_2>());
960
961        let new = Param { value: ValueFields { a: 0, b: 0 } };
962        let old = TEE_Param { value: TEE_Param__bindgen_ty_2 { a: 0, b: 0 } };
963
964        // SAFETY:  Accessing the fields of a repr(C) union is unsafe.
965        let new_memref = unsafe { new.memref };
966        let old_memref = unsafe { old.memref };
967
968        assert_eq!(offset_of!(MemRef, buffer), offset_of!(TEE_Param__bindgen_ty_1, buffer));
969        assert_eq!(size_of_val(&new_memref.buffer), size_of_val(&old_memref.buffer));
970        assert_eq!(align_of_val(&new_memref.buffer), align_of_val(&old_memref.buffer));
971
972        assert_eq!(offset_of!(MemRef, size), offset_of!(TEE_Param__bindgen_ty_1, size));
973        assert_eq!(size_of_val(&new_memref.size), size_of_val(&old_memref.size));
974        assert_eq!(align_of_val(&new_memref.size), align_of_val(&old_memref.size));
975
976        // SAFETY:  Accessing the fields of a repr(C) union is unsafe.
977        let new_value = unsafe { new.value };
978        let old_value = unsafe { old.value };
979
980        assert_eq!(offset_of!(ValueFields, a), offset_of!(TEE_Param__bindgen_ty_2, a));
981        assert_eq!(size_of_val(&new_value.a), size_of_val(&old_value.a));
982        assert_eq!(align_of_val(&new_value.a), align_of_val(&old_value.a));
983
984        assert_eq!(offset_of!(ValueFields, b), offset_of!(TEE_Param__bindgen_ty_2, b));
985        assert_eq!(size_of_val(&new_value.b), size_of_val(&old_value.b));
986        assert_eq!(align_of_val(&new_value.b), align_of_val(&old_value.b));
987
988        // Verify zero-copy translation.
989        assert_eq!(addr_of!(*Param::from_binding(&old)) as usize, addr_of!(old) as usize);
990        assert_eq!(addr_of!(*Param::to_binding(&new)) as usize, addr_of!(new) as usize);
991    }
992
993    #[test]
994    pub fn test_abi_compat_param_types() {
995        assert_eq!(size_of::<ParamTypes>(), size_of::<u32>());
996        assert_eq!(align_of::<ParamTypes>(), align_of::<u32>());
997    }
998
999    #[test]
1000    pub fn test_abi_compat_login() {
1001        assert_eq!(size_of::<Login>(), size_of::<u32>());
1002        assert_eq!(align_of::<Login>(), align_of::<u32>());
1003    }
1004
1005    #[test]
1006    pub fn test_abi_compat_origin() {
1007        assert_eq!(size_of::<Origin>(), size_of::<u32>());
1008        assert_eq!(align_of::<Origin>(), align_of::<u32>());
1009    }
1010
1011    #[test]
1012    pub fn test_abi_compat_memory_access() {
1013        assert_eq!(size_of::<MemoryAccess>(), size_of::<u32>());
1014        assert_eq!(align_of::<MemoryAccess>(), align_of::<u32>());
1015    }
1016
1017    #[test]
1018    pub fn test_abi_compat_session_context() {
1019        assert_eq!(size_of::<SessionContext>(), size_of::<usize>());
1020        assert_eq!(align_of::<SessionContext>(), align_of::<usize>());
1021
1022        let new = SessionContext::from_value(0);
1023        let old: usize = 0;
1024
1025        // Verify zero-copy translation.
1026        assert_eq!(addr_of!(*SessionContext::from_binding(&old)) as usize, addr_of!(old) as usize);
1027        assert_eq!(addr_of!(*SessionContext::to_binding(&new)) as usize, addr_of!(new) as usize);
1028    }
1029
1030    #[test]
1031    pub fn test_abi_compat_attribute() {
1032        assert_eq!(size_of::<Attribute>(), size_of::<TEE_Attribute>());
1033        assert_eq!(align_of::<Attribute>(), align_of::<TEE_Attribute>());
1034
1035        let new = Attribute {
1036            id: AttributeId::SecretValue,
1037            content: BufferOrValue { value: ValueFields { a: 0, b: 0 } },
1038        };
1039        let old = TEE_Attribute {
1040            attributeID: AttributeId::SecretValue as u32,
1041            __bindgen_padding_0: [0; 4],
1042            content: TEE_Attribute__bindgen_ty_1 {
1043                value: TEE_Attribute__bindgen_ty_1__bindgen_ty_2 { a: 0, b: 0 },
1044            },
1045        };
1046
1047        assert_eq!(offset_of!(Attribute, id), offset_of!(TEE_Attribute, attributeID));
1048        assert_eq!(size_of_val(&new.id), size_of_val(&old.attributeID));
1049        assert_eq!(align_of_val(&new.id), align_of_val(&old.attributeID));
1050
1051        assert_eq!(offset_of!(Attribute, content), offset_of!(TEE_Attribute, content));
1052        assert_eq!(size_of_val(&new.content), size_of_val(&old.content));
1053        assert_eq!(align_of_val(&new.content), align_of_val(&old.content));
1054
1055        // SAFETY:  Accessing the fields of a repr(C) union is unsafe.
1056        let new_memref = unsafe { new.content.memref };
1057        let old_content_memref = unsafe { old.content.ref_ };
1058
1059        assert_eq!(
1060            offset_of!(MemRef, buffer),
1061            offset_of!(TEE_Attribute__bindgen_ty_1__bindgen_ty_1, buffer)
1062        );
1063        assert_eq!(size_of_val(&new_memref.buffer), size_of_val(&old_content_memref.buffer));
1064        assert_eq!(align_of_val(&new_memref.buffer), align_of_val(&old_content_memref.buffer));
1065
1066        assert_eq!(
1067            offset_of!(MemRef, size),
1068            offset_of!(TEE_Attribute__bindgen_ty_1__bindgen_ty_1, length)
1069        );
1070        assert_eq!(size_of_val(&new_memref.size), size_of_val(&old_content_memref.length));
1071        assert_eq!(align_of_val(&new_memref.size), align_of_val(&old_content_memref.length));
1072
1073        // SAFETY:  Accessing the fields of a repr(C) union is unsafe.
1074        let new_value = unsafe { new.content.value };
1075        let old_value = unsafe { old.content.value };
1076
1077        assert_eq!(
1078            offset_of!(ValueFields, a),
1079            offset_of!(TEE_Attribute__bindgen_ty_1__bindgen_ty_2, a)
1080        );
1081        assert_eq!(size_of_val(&new_value.a), size_of_val(&old_value.a));
1082        assert_eq!(align_of_val(&new_value.a), align_of_val(&old_value.a));
1083
1084        assert_eq!(
1085            offset_of!(ValueFields, b),
1086            offset_of!(TEE_Attribute__bindgen_ty_1__bindgen_ty_2, b)
1087        );
1088        assert_eq!(size_of_val(&new_value.b), size_of_val(&old_value.b));
1089        assert_eq!(align_of_val(&new_value.b), align_of_val(&old_value.b));
1090
1091        // Verify zero-copy translation.
1092        assert_eq!(
1093            addr_of!(*Attribute::from_binding(&old).unwrap()) as usize,
1094            addr_of!(old) as usize
1095        );
1096        assert_eq!(addr_of!(*Attribute::to_binding(&new)) as usize, addr_of!(new) as usize);
1097    }
1098
1099    #[test]
1100    pub fn test_abi_compat_object_info() {
1101        assert_eq!(size_of::<ObjectInfo>(), size_of::<TEE_ObjectInfo>());
1102        assert_eq!(align_of::<ObjectInfo>(), align_of::<TEE_ObjectInfo>());
1103
1104        let new = ObjectInfo {
1105            object_type: Type::Aes,
1106            object_size: 0,
1107            max_object_size: 0,
1108            object_usage: Usage::empty(),
1109            data_size: 0,
1110            data_position: 0,
1111            handle_flags: HandleFlags::empty(),
1112        };
1113        let old = TEE_ObjectInfo {
1114            objectType: 0,
1115            objectSize: 0,
1116            maxObjectSize: 0,
1117            objectUsage: 0,
1118            dataSize: 0,
1119            dataPosition: 0,
1120            handleFlags: 0,
1121            __bindgen_padding_0: [0; 4],
1122        };
1123
1124        assert_eq!(offset_of!(ObjectInfo, object_type), offset_of!(TEE_ObjectInfo, objectType));
1125        assert_eq!(size_of_val(&new.object_type), size_of_val(&old.objectType));
1126        assert_eq!(align_of_val(&new.object_type), align_of_val(&old.objectType));
1127
1128        assert_eq!(offset_of!(ObjectInfo, object_size), offset_of!(TEE_ObjectInfo, objectSize));
1129        assert_eq!(size_of_val(&new.object_size), size_of_val(&old.objectSize));
1130        assert_eq!(align_of_val(&new.object_size), align_of_val(&old.objectSize));
1131
1132        assert_eq!(
1133            offset_of!(ObjectInfo, max_object_size),
1134            offset_of!(TEE_ObjectInfo, maxObjectSize)
1135        );
1136        assert_eq!(size_of_val(&new.max_object_size), size_of_val(&old.maxObjectSize));
1137        assert_eq!(align_of_val(&new.max_object_size), align_of_val(&old.maxObjectSize));
1138
1139        assert_eq!(offset_of!(ObjectInfo, object_usage), offset_of!(TEE_ObjectInfo, objectUsage));
1140        assert_eq!(size_of_val(&new.object_usage), size_of_val(&old.objectUsage));
1141        assert_eq!(align_of_val(&new.object_usage), align_of_val(&old.objectUsage));
1142
1143        assert_eq!(offset_of!(ObjectInfo, data_size), offset_of!(TEE_ObjectInfo, dataSize));
1144        assert_eq!(size_of_val(&new.data_size), size_of_val(&old.dataSize));
1145        assert_eq!(align_of_val(&new.data_size), align_of_val(&old.dataSize));
1146
1147        assert_eq!(offset_of!(ObjectInfo, data_position), offset_of!(TEE_ObjectInfo, dataPosition));
1148        assert_eq!(size_of_val(&new.data_position), size_of_val(&old.dataPosition));
1149        assert_eq!(align_of_val(&new.data_position), align_of_val(&old.dataPosition));
1150
1151        assert_eq!(offset_of!(ObjectInfo, handle_flags), offset_of!(TEE_ObjectInfo, handleFlags));
1152        assert_eq!(size_of_val(&new.handle_flags), size_of_val(&old.handleFlags));
1153        assert_eq!(align_of_val(&new.handle_flags), align_of_val(&old.handleFlags));
1154
1155        // Verify zero-copy translation.
1156        assert_eq!(addr_of!(*ObjectInfo::to_binding(&new)) as usize, addr_of!(new) as usize);
1157    }
1158
1159    #[test]
1160    pub fn test_abi_compat_whence() {
1161        assert_eq!(size_of::<Whence>(), size_of::<u32>());
1162        assert_eq!(align_of::<Whence>(), align_of::<u32>());
1163    }
1164
1165    #[test]
1166    pub fn test_abi_compat_storage() {
1167        assert_eq!(size_of::<Storage>(), size_of::<u32>());
1168        assert_eq!(align_of::<Storage>(), align_of::<u32>());
1169    }
1170
1171    #[test]
1172    pub fn test_abi_compat_usage() {
1173        assert_eq!(size_of::<Usage>(), size_of::<u32>());
1174        assert_eq!(align_of::<Usage>(), align_of::<u32>());
1175    }
1176
1177    #[test]
1178    pub fn test_abi_compat_handle_flags() {
1179        assert_eq!(size_of::<HandleFlags>(), size_of::<u32>());
1180        assert_eq!(align_of::<HandleFlags>(), align_of::<u32>());
1181    }
1182
1183    #[test]
1184    pub fn test_abi_compat_operation() {
1185        assert_eq!(size_of::<Operation>(), size_of::<u32>());
1186        assert_eq!(align_of::<Operation>(), align_of::<u32>());
1187    }
1188
1189    #[test]
1190    pub fn test_abi_compat_operation_state() {
1191        assert_eq!(size_of::<OperationState>(), size_of::<u32>());
1192        assert_eq!(align_of::<OperationState>(), align_of::<u32>());
1193    }
1194
1195    #[test]
1196    pub fn test_abi_compat_type() {
1197        assert_eq!(size_of::<Type>(), size_of::<u32>());
1198        assert_eq!(align_of::<Type>(), align_of::<u32>());
1199    }
1200
1201    #[test]
1202    pub fn test_abi_compat_mode() {
1203        assert_eq!(size_of::<Mode>(), size_of::<u32>());
1204        assert_eq!(align_of::<Mode>(), align_of::<u32>());
1205    }
1206
1207    #[test]
1208    pub fn test_abi_compat_operation_info() {
1209        assert_eq!(size_of::<OperationInfo>(), size_of::<TEE_OperationInfo>());
1210        assert_eq!(align_of::<OperationInfo>(), align_of::<TEE_OperationInfo>());
1211
1212        let new = OperationInfo {
1213            algorithm: Algorithm::AesEcbNopad,
1214            operation_class: Operation::Ae,
1215            mode: Mode::Decrypt,
1216            digest_length: 0,
1217            max_key_size: 0,
1218            key_size: 0,
1219            required_key_usage: Usage::empty(),
1220            handle_state: HandleFlags::empty(),
1221        };
1222        let old = TEE_OperationInfo {
1223            algorithm: 0,
1224            operationClass: 0,
1225            mode: 0,
1226            digestLength: 0,
1227            maxKeySize: 0,
1228            keySize: 0,
1229            requiredKeyUsage: 0,
1230            handleState: 0,
1231        };
1232
1233        assert_eq!(offset_of!(OperationInfo, algorithm), offset_of!(TEE_OperationInfo, algorithm));
1234        assert_eq!(size_of_val(&new.algorithm), size_of_val(&old.algorithm));
1235        assert_eq!(align_of_val(&new.algorithm), align_of_val(&old.algorithm));
1236
1237        assert_eq!(
1238            offset_of!(OperationInfo, operation_class),
1239            offset_of!(TEE_OperationInfo, operationClass)
1240        );
1241        assert_eq!(size_of_val(&new.operation_class), size_of_val(&old.operationClass));
1242        assert_eq!(align_of_val(&new.operation_class), align_of_val(&old.operationClass));
1243
1244        assert_eq!(offset_of!(OperationInfo, mode), offset_of!(TEE_OperationInfo, mode));
1245        assert_eq!(size_of_val(&new.mode), size_of_val(&old.mode));
1246        assert_eq!(align_of_val(&new.mode), align_of_val(&old.mode));
1247
1248        assert_eq!(
1249            offset_of!(OperationInfo, digest_length),
1250            offset_of!(TEE_OperationInfo, digestLength)
1251        );
1252        assert_eq!(size_of_val(&new.digest_length), size_of_val(&old.digestLength));
1253        assert_eq!(align_of_val(&new.digest_length), align_of_val(&old.digestLength));
1254
1255        assert_eq!(
1256            offset_of!(OperationInfo, max_key_size),
1257            offset_of!(TEE_OperationInfo, maxKeySize)
1258        );
1259        assert_eq!(size_of_val(&new.max_key_size), size_of_val(&old.maxKeySize));
1260        assert_eq!(align_of_val(&new.max_key_size), align_of_val(&old.maxKeySize));
1261
1262        assert_eq!(offset_of!(OperationInfo, key_size), offset_of!(TEE_OperationInfo, keySize));
1263        assert_eq!(size_of_val(&new.key_size), size_of_val(&old.keySize));
1264        assert_eq!(align_of_val(&new.key_size), align_of_val(&old.keySize));
1265
1266        assert_eq!(
1267            offset_of!(OperationInfo, required_key_usage),
1268            offset_of!(TEE_OperationInfo, requiredKeyUsage)
1269        );
1270        assert_eq!(size_of_val(&new.required_key_usage), size_of_val(&old.requiredKeyUsage));
1271        assert_eq!(align_of_val(&new.required_key_usage), align_of_val(&old.requiredKeyUsage));
1272
1273        assert_eq!(
1274            offset_of!(OperationInfo, handle_state),
1275            offset_of!(TEE_OperationInfo, handleState)
1276        );
1277        assert_eq!(size_of_val(&new.handle_state), size_of_val(&old.handleState));
1278        assert_eq!(align_of_val(&new.handle_state), align_of_val(&old.handleState));
1279
1280        // Verify zero-copy translation.
1281        assert_eq!(addr_of!(*OperationInfo::to_binding(&new)) as usize, addr_of!(new) as usize);
1282    }
1283
1284    #[test]
1285    pub fn test_abi_compat_operation_info_key() {
1286        assert_eq!(size_of::<OperationInfoKey>(), size_of::<TEE_OperationInfoKey>());
1287        assert_eq!(align_of::<OperationInfoKey>(), align_of::<TEE_OperationInfoKey>());
1288
1289        let new = OperationInfoKey { key_size: 0, required_key_usage: Usage::empty() };
1290        let old = TEE_OperationInfoKey { keySize: 0, requiredKeyUsage: 0 };
1291
1292        assert_eq!(
1293            offset_of!(OperationInfoKey, key_size),
1294            offset_of!(TEE_OperationInfoKey, keySize)
1295        );
1296        assert_eq!(size_of_val(&new.key_size), size_of_val(&old.keySize));
1297        assert_eq!(align_of_val(&new.key_size), align_of_val(&old.keySize));
1298
1299        assert_eq!(
1300            offset_of!(OperationInfoKey, required_key_usage),
1301            offset_of!(TEE_OperationInfoKey, requiredKeyUsage)
1302        );
1303        assert_eq!(size_of_val(&new.required_key_usage), size_of_val(&old.requiredKeyUsage));
1304        assert_eq!(align_of_val(&new.required_key_usage), align_of_val(&old.requiredKeyUsage));
1305
1306        // Verify zero-copy translation.
1307        assert_eq!(addr_of!(*OperationInfoKey::to_binding(&new)) as usize, addr_of!(new) as usize);
1308    }
1309
1310    #[test]
1311    pub fn test_abi_compat_operation_info_multiple() {
1312        assert_eq!(size_of::<OperationInfoMultiple>(), size_of::<TEE_OperationInfoMultiple>());
1313        assert_eq!(align_of::<OperationInfoMultiple>(), align_of::<TEE_OperationInfoMultiple>());
1314
1315        let new = OperationInfoMultiple {
1316            algorithm: Algorithm::AesEcbNopad,
1317            operation_class: Operation::Ae,
1318            mode: Mode::Decrypt,
1319            digest_length: 0,
1320            max_key_size: 0,
1321            handle_state: HandleFlags::empty(),
1322            operation_state: OperationState::Active,
1323            number_of_keys: 0,
1324            key_information: binding::__IncompleteArrayField::<OperationInfoKey>::new(),
1325        };
1326        let old = TEE_OperationInfoMultiple {
1327            algorithm: 0,
1328            operationClass: 0,
1329            mode: 0,
1330            digestLength: 0,
1331            maxKeySize: 0,
1332            handleState: 0,
1333            operationState: 0,
1334            numberOfKeys: 0,
1335            keyInformation: binding::__IncompleteArrayField::<TEE_OperationInfoKey>::new(),
1336        };
1337
1338        assert_eq!(
1339            offset_of!(OperationInfoMultiple, algorithm),
1340            offset_of!(TEE_OperationInfoMultiple, algorithm)
1341        );
1342        assert_eq!(size_of_val(&new.algorithm), size_of_val(&old.algorithm));
1343        assert_eq!(align_of_val(&new.algorithm), align_of_val(&old.algorithm));
1344
1345        assert_eq!(
1346            offset_of!(OperationInfoMultiple, operation_class),
1347            offset_of!(TEE_OperationInfoMultiple, operationClass)
1348        );
1349        assert_eq!(size_of_val(&new.operation_class), size_of_val(&old.operationClass));
1350        assert_eq!(align_of_val(&new.operation_class), align_of_val(&old.operationClass));
1351
1352        assert_eq!(
1353            offset_of!(OperationInfoMultiple, mode),
1354            offset_of!(TEE_OperationInfoMultiple, mode)
1355        );
1356        assert_eq!(size_of_val(&new.mode), size_of_val(&old.mode));
1357        assert_eq!(align_of_val(&new.mode), align_of_val(&old.mode));
1358
1359        assert_eq!(
1360            offset_of!(OperationInfoMultiple, digest_length),
1361            offset_of!(TEE_OperationInfoMultiple, digestLength)
1362        );
1363        assert_eq!(size_of_val(&new.digest_length), size_of_val(&old.digestLength));
1364        assert_eq!(align_of_val(&new.digest_length), align_of_val(&old.digestLength));
1365
1366        assert_eq!(
1367            offset_of!(OperationInfoMultiple, max_key_size),
1368            offset_of!(TEE_OperationInfoMultiple, maxKeySize)
1369        );
1370        assert_eq!(size_of_val(&new.max_key_size), size_of_val(&old.maxKeySize));
1371        assert_eq!(align_of_val(&new.max_key_size), align_of_val(&old.maxKeySize));
1372
1373        assert_eq!(
1374            offset_of!(OperationInfoMultiple, handle_state),
1375            offset_of!(TEE_OperationInfoMultiple, handleState)
1376        );
1377        assert_eq!(size_of_val(&new.handle_state), size_of_val(&old.handleState));
1378        assert_eq!(align_of_val(&new.handle_state), align_of_val(&old.handleState));
1379
1380        assert_eq!(
1381            offset_of!(OperationInfoMultiple, operation_state),
1382            offset_of!(TEE_OperationInfoMultiple, operationState)
1383        );
1384        assert_eq!(size_of_val(&new.operation_state), size_of_val(&old.operationState));
1385        assert_eq!(align_of_val(&new.operation_state), align_of_val(&old.operationState));
1386
1387        assert_eq!(
1388            offset_of!(OperationInfoMultiple, number_of_keys),
1389            offset_of!(TEE_OperationInfoMultiple, numberOfKeys)
1390        );
1391        assert_eq!(size_of_val(&new.number_of_keys), size_of_val(&old.numberOfKeys));
1392        assert_eq!(align_of_val(&new.number_of_keys), align_of_val(&old.numberOfKeys));
1393
1394        assert_eq!(
1395            offset_of!(OperationInfoMultiple, key_information),
1396            offset_of!(TEE_OperationInfoMultiple, keyInformation)
1397        );
1398        assert_eq!(size_of_val(&new.key_information), size_of_val(&old.keyInformation));
1399        assert_eq!(align_of_val(&new.key_information), align_of_val(&old.keyInformation));
1400
1401        // Verify zero-copy translation.
1402        assert_eq!(
1403            addr_of!(*OperationInfoMultiple::to_binding(&new)) as usize,
1404            addr_of!(new) as usize
1405        );
1406    }
1407
1408    #[test]
1409    pub fn test_abi_compat_algorithm() {
1410        assert_eq!(size_of::<Algorithm>(), size_of::<u32>());
1411        assert_eq!(align_of::<Algorithm>(), align_of::<u32>());
1412    }
1413
1414    #[test]
1415    pub fn test_abi_compat_ecc_curve() {
1416        assert_eq!(size_of::<EccCurve>(), size_of::<u32>());
1417        assert_eq!(align_of::<EccCurve>(), align_of::<u32>());
1418    }
1419
1420    #[test]
1421    pub fn test_abi_compat_attribute_id() {
1422        assert_eq!(size_of::<AttributeId>(), size_of::<u32>());
1423        assert_eq!(align_of::<AttributeId>(), align_of::<u32>());
1424    }
1425}