1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 use crate::{Error, Result};
19 use bitflags::bitflags;
20 use optee_utee_sys as raw;
21 use core::{marker, mem, ptr};
22 #[cfg(not(feature = "std"))]
23 use alloc::boxed::Box;
24 #[cfg(not(feature = "std"))]
25 use alloc::vec::Vec;
26 
27 /// A general attribute (buffer or value) that can be used to populate an object or to specify
28 /// opeation parameters.
29 pub struct Attribute {
30     raw: raw::TEE_Attribute,
31 }
32 
33 impl Attribute {
34     /// Return the raw struct `TEE_Attribute`.
raw(&self) -> raw::TEE_Attribute35     pub fn raw(&self) -> raw::TEE_Attribute {
36         self.raw
37     }
38 }
39 
40 /// Convert the buffer attribute [AttributeMemref](AttributeMemref) to the general attribute.
41 impl<'attrref> From<AttributeMemref<'attrref>> for Attribute {
from(attr: AttributeMemref) -> Self42     fn from(attr: AttributeMemref) -> Self {
43         Self { raw: attr.raw() }
44     }
45 }
46 
47 /// Convert the value attribute [AttributeValue](AttributeValue) to the general attribute.
48 impl From<AttributeValue> for Attribute {
from(attr: AttributeValue) -> Self49     fn from(attr: AttributeValue) -> Self {
50         Self { raw: attr.raw() }
51     }
52 }
53 
54 /// A buffer attribute.
55 #[derive(Clone, Copy)]
56 pub struct AttributeMemref<'attrref> {
57     raw: raw::TEE_Attribute,
58     _marker: marker::PhantomData<&'attrref mut [u8]>,
59 }
60 
61 impl<'attrref> AttributeMemref<'attrref> {
62     /// Return the raw struct TEE_Attribute.
raw(&self) -> raw::TEE_Attribute63     pub fn raw(&self) -> raw::TEE_Attribute {
64         self.raw
65     }
66 
new_ref() -> Self67     fn new_ref() -> Self {
68         let raw = raw::TEE_Attribute {
69             attributeID: 0,
70             content: raw::content {
71                 memref: raw::Memref {
72                     buffer: 0 as *mut _,
73                     size: 0,
74                 },
75             },
76         };
77         Self {
78             raw: raw,
79             _marker: marker::PhantomData,
80         }
81     }
82 
83     /// Populate a single attribute with a reference to a buffer.
84     ///
85     /// # Parameters
86     ///
87     /// 1) `id`: The AttributeId[AttributeId] is an identifier of the attribute to populate.
88     /// 2) `buffer`: Input buffer that holds the content of the attribute.
89     ///
90     /// # Example
91     ///
92     /// ```no_run
93     /// let mut attr = AttributeMemref::from_ref(AttributeId::SecretValue, &mut [0u8;1]);
94     /// ```
from_ref(id: AttributeId, buffer: &'attrref [u8]) -> Self95     pub fn from_ref(id: AttributeId, buffer: &'attrref [u8]) -> Self {
96         let mut res = AttributeMemref::new_ref();
97         unsafe {
98             raw::TEE_InitRefAttribute(
99                 &mut res.raw,
100                 id as u32,
101                 buffer.as_ptr() as *mut _,
102                 buffer.len(),
103             );
104         }
105         res
106     }
107 }
108 
109 /// A value attribute.
110 pub struct AttributeValue {
111     raw: raw::TEE_Attribute,
112 }
113 
114 impl AttributeValue {
115     /// Return the raw struct TEE_Attribute.
raw(&self) -> raw::TEE_Attribute116     pub fn raw(&self) -> raw::TEE_Attribute {
117         self.raw
118     }
119 
new_value() -> Self120     fn new_value() -> Self {
121         let raw = raw::TEE_Attribute {
122             attributeID: 0,
123             content: raw::content {
124                 value: raw::Value { a: 0, b: 0 },
125             },
126         };
127         Self { raw }
128     }
129 
130     /// Populate a single attribute with two u32 values.
131     ///
132     /// # Parameters
133     ///
134     /// 1) `id`: The AttributeId[AttributeId] is an identifier of the attribute to populate.
135     /// 2) `a`, `b`: u32 values to assign to the members of the a value attribute.
136     ///
137     /// # Example
138     ///
139     /// ```no_run
140     /// let mut attr = AttributeValue::from_value(AttributeId::SecretValue, 0, 0);
141     /// ```
from_value(id: AttributeId, a: u32, b: u32) -> Self142     pub fn from_value(id: AttributeId, a: u32, b: u32) -> Self {
143         let mut res = AttributeValue::new_value();
144         unsafe {
145             raw::TEE_InitValueAttribute(&mut res.raw, id as u32, a, b);
146         }
147         res
148     }
149 }
150 
151 /// Represent the characteristics of an object.
152 /// This info can be returned by [TransientObject](TransientObject) function
153 /// [info](TransientObject::info)
154 /// or [PersistentObject](PersistentObject) function
155 /// [info](PersistentObject::info).
156 pub struct ObjectInfo {
157     raw: raw::TEE_ObjectInfo,
158 }
159 
160 // Since raw struct is not implemented Copy attribute yet, every item in raw struct needs a function to extract.
161 impl ObjectInfo {
162     /// Return an [ObjectInfo](ObjectInfo) struct based on the raw structrure `TEE_ObjectInfo`.
163     /// The raw structure contains following fields:
164     ///
165     /// 1) `objectType`: The parameter represents one of the
166     ///    [TransientObjectType](TransientObjectType).
167     /// 2) `objectSize`: The current size in bits of the object as determined by its attributes.
168     /// This will always be less than or equal to maxObjectSize. Set to 0 for uninitialized and data only objects.
169     /// 3) `maxObjectSize`: The maximum objectSize which this object can represent.
170     /// 3.1) For a [PersistentObject](PersistentObject), set to `objectSize`.
171     /// 3.2) For a [TransientObject](TransientObject), set to the parameter `maxObjectSize` passed to
172     /// [allocate](TransientObject::allocate).
173     /// 4) `objectUsage`: A bit vector of UsageFlag.
174     /// 5) `dataSize`:
175     /// 5.1) For a [PersistentObject](PersistentObject), set to the current size of the data associated with the object.
176     /// 5.2) For a [TransientObject](TransientObject), always set to 0.
177     /// 6) `dataPosition`:
178     /// 6.1) For a [PersistentObject](PersistentObject), set to the current position in the data for this handle.
179     /// Data positions for different handles on the same object may differ.
180     /// 6.2) For a [TransientObject](TransientObject), set to 0.
181     /// 7) `handleFlags`: A bit vector containing one or more [HandleFlag](HandleFlag) or [DataFlag](DataFlag).
from_raw(raw: raw::TEE_ObjectInfo) -> Self182     pub fn from_raw(raw: raw::TEE_ObjectInfo) -> Self {
183         Self { raw }
184     }
185 
186     /// Return the `dataSize` field of the raw structrure `TEE_ObjectInfo`.
data_size(&self) -> usize187     pub fn data_size(&self) -> usize {
188         self.raw.dataSize as usize
189     }
190 
191     /// Return the `objectSize` field of the raw structrure `TEE_ObjectInfo`.
object_size(&self) -> usize192     pub fn object_size(&self) -> usize {
193         self.raw.objectSize as usize
194     }
195 }
196 
197 /// Indicate the possible start offset when moving a data position in the data stream associated with a [PersistentObject](PersistentObject).
198 pub enum Whence {
199     /// The data position is set to offset bytes from the beginning of the data stream.
200     DataSeekSet,
201     /// The data position is set to its current position plus offset.
202     DataSeekCur,
203     /// The data position is set to the size of the object data plus offset.
204     DataSeekEnd,
205 }
206 
207 impl Into<raw::TEE_Whence> for Whence {
into(self) -> raw::TEE_Whence208     fn into(self) -> raw::TEE_Whence {
209         match self {
210             Whence::DataSeekSet => raw::TEE_Whence::TEE_DATA_SEEK_SET,
211             Whence::DataSeekCur => raw::TEE_Whence::TEE_DATA_SEEK_CUR,
212             Whence::DataSeekEnd => raw::TEE_Whence::TEE_DATA_SEEK_END,
213         }
214     }
215 }
216 
217 /// An opaque handle on an object.
218 pub struct ObjectHandle {
219     raw: *mut raw::TEE_ObjectHandle,
220 }
221 
222 impl ObjectHandle {
handle(&self) -> raw::TEE_ObjectHandle223     fn handle(&self) -> raw::TEE_ObjectHandle {
224         unsafe { *(self.raw) }
225     }
226 
from_raw(raw: *mut raw::TEE_ObjectHandle) -> ObjectHandle227     fn from_raw(raw: *mut raw::TEE_ObjectHandle) -> ObjectHandle {
228         Self { raw }
229     }
230 
info(&self) -> Result<ObjectInfo>231     fn info(&self) -> Result<ObjectInfo> {
232         let mut raw_info: raw::TEE_ObjectInfo = unsafe { mem::zeroed() };
233         match unsafe { raw::TEE_GetObjectInfo1(self.handle(), &mut raw_info) } {
234             raw::TEE_SUCCESS => Ok(ObjectInfo::from_raw(raw_info)),
235             code => Err(Error::from_raw_error(code)),
236         }
237     }
238 
restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()>239     fn restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()> {
240         match unsafe { raw::TEE_RestrictObjectUsage1(self.handle(), obj_usage.bits()) } {
241             raw::TEE_SUCCESS => Ok(()),
242             code => Err(Error::from_raw_error(code)),
243         }
244     }
245 
ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize>246     fn ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize> {
247         let mut size = buffer.len();
248         match unsafe {
249             raw::TEE_GetObjectBufferAttribute(
250                 self.handle(),
251                 id as u32,
252                 buffer as *mut _ as _,
253                 &mut size,
254             )
255         } {
256             raw::TEE_SUCCESS => Ok(size),
257             code => Err(Error::from_raw_error(code)),
258         }
259     }
260 
value_attribute(&self, id: u32) -> Result<(u32, u32)>261     fn value_attribute(&self, id: u32) -> Result<(u32, u32)> {
262         let mut value_a: u32 = 0;
263         let mut value_b: u32 = 0;
264         match unsafe {
265             raw::TEE_GetObjectValueAttribute(
266                 self.handle(),
267                 id,
268                 &mut value_a as *mut _,
269                 &mut value_b as *mut _,
270             )
271         } {
272             raw::TEE_SUCCESS => Ok((value_a, value_b)),
273             code => Err(Error::from_raw_error(code)),
274         }
275     }
276 }
277 
278 #[repr(u32)]
279 pub enum ObjectStorageConstants {
280     Private = 0x00000001,
281     IllegalValue = 0x7FFFFFFF,
282 }
283 
284 bitflags! {
285     /// A set of flags that controls the access rights and sharing permissions
286     /// with which the object handle is opened.
287     pub struct DataFlag: u32 {
288         /// The object is opened with the read access right. This allows the
289         /// Trusted Application to call the function `TEE_ReadObjectData`.
290         const ACCESS_READ = 0x00000001;
291         /// The object is opened with the write access right. This allows the
292         /// Trusted Application to call the functions `TEE_WriteObjectData` and
293         /// `TEE_TruncateObjectData`.
294         const ACCESS_WRITE = 0x00000002;
295         /// The object is opened with the write-meta access right. This allows
296         /// the Trusted Application to call the functions
297         /// `TEE_CloseAndDeletePersistentObject1` and `TEE_RenamePersistentObject`.
298         const ACCESS_WRITE_META = 0x00000004;
299         /// The caller allows another handle on the object to be created with
300         /// read access.
301         const SHARE_READ = 0x00000010;
302         /// The caller allows another handle on the object to be created with
303         /// write access.
304         const SHARE_WRITE = 0x00000020;
305         /// * If this flag is present and the object exists, then the object is
306         ///   deleted and re-created as an atomic operation: that is, the TA sees
307         ///   either the old object or the new one.
308         /// * If the flag is absent and the object exists, then the function
309         ///   SHALL return `TEE_ERROR_ACCESS_CONFLICT`.
310         const OVERWRITE = 0x00000400;
311     }
312 }
313 
314 bitflags! {
315     /// A set of flags that defines usages of data in TEE secure storage.
316     pub struct UsageFlag: u32 {
317         /// The object [Attribute](Attribute) can be extracted.
318         const EXTRACTABLE = 0x00000001;
319         /// The object can be used for encrytpion.
320         const ENCRYPT = 0x00000002;
321         /// The object can be used for decrption.
322         const DECRYPT = 0x00000004;
323         /// The object can be used for mac operation.
324         const MAC = 0x00000008;
325         /// The ojbect can be used for signature.
326         const SIGN = 0x00000010;
327         /// The object can be used for verification of a signature.
328         const VERIFY = 0x00000020;
329         /// The object can be used for deriving a key.
330         const DERIVE = 0x00000040;
331     }
332 }
333 
334 /// Miscellaneous constants.
335 #[repr(u32)]
336 pub enum MiscellaneousConstants {
337     /// Maximum offset of a data object.
338     TeeDataMaxPosition = 0xFFFFFFFF,
339     /// Maximum length of an object id.
340     TeeObjectIdMaxLen = 64,
341 }
342 
343 bitflags! {
344     /// A set of flags that defines Handle features.
345     pub struct HandleFlag: u32{
346         /// Set for a [PersistentObject](PersistentObject).
347         const PERSISTENT = 0x00010000;
348         /// 1) For a [PersistentObject](PersistentObject), always set.
349         /// 2) For a [TransientObject](TransientObject), initially cleared, then set when the object becomes initialized.
350         const INITIALIZED = 0x00020000;
351         /// Following two flags are for crypto operation handles:
352         /// 1) Set if the required operation key has been set.
353         /// 2) Always set for digest operations.
354         const KEY_SET = 0x00040000;
355         /// Set if the algorithm expects two keys to be set, using `TEE_SetOperationKey2`.
356         /// This happens only if algorithm is set to [AesXts](../crypto_op/enum.AlgorithmId.html#variant.AesXts)
357         /// or `TEE_ALG_SM2_KEP`(not supported now).
358         const EXPECT_TWO_KEYS = 0x00080000;
359     }
360 }
361 
362 #[repr(u32)]
363 pub enum AttributeId {
364     /// Used for all secret keys for symmetric ciphers, MACs, and HMACs
365     SecretValue = 0xC0000000,
366     /// RSA modulus: `n`
367     RsaModulus = 0xD0000130,
368     /// RSA public key exponent: `e`
369     RsaPublicExponent = 0xD0000230,
370     /// RSA private key exponent: `d`
371     RsaPrivateExponent = 0xC0000330,
372     /// RSA prime number: `p`
373     RsaPrime1 = 0xC0000430,
374     /// RSA prime number: `q`
375     RsaPrime2 = 0xC0000530,
376     /// RSA exponent: `dp`
377     RsaExponent1 = 0xC0000630,
378     /// RSA exponent: `dq`
379     RsaExponent2 = 0xC0000730,
380     /// RSA coefficient: `iq`
381     RsaCoefficient = 0xC0000830,
382     /// DSA prime number: `p`
383     DsaPrime = 0xD0001031,
384     /// DSA sub prime number: `q`
385     DsaSubprime = 0xD0001131,
386     /// DSA base: `g`
387     DsaBase = 0xD0001231,
388     /// DSA public value: `y`
389     DsaPublicValue = 0xD0000131,
390     /// DSA private value: `x`
391     DsaPrivateValue = 0xC0000231,
392     /// Diffie-Hellman prime number: `p`
393     DhPrime = 0xD0001032,
394     /// Diffie-Hellman sub prime number: `q`
395     DhSubprime = 0xD0001132,
396     /// Diffie-Hellman base: `g`
397     DhBase = 0xD0001232,
398     /// Diffie-Hellman x bits: `l`
399     DhXBits = 0xF0001332,
400     /// Diffie-Hellman public value: `y`
401     DhPublicValue = 0xD0000132,
402     /// Diffie-Hellman public value: `x`
403     DhPrivateValue = 0xC0000232,
404     RsaOaepLabel = 0xD0000930,
405     RsaPssSaltLength = 0xF0000A30,
406     EccPublicValueX = 0xD0000141,
407     EccPublicValueY = 0xD0000241,
408     /// ECC private value: `d`
409     EccPrivateValue = 0xC0000341,
410     /// ECC Curve algorithm
411     EccCurve = 0xF0000441,
412     BitProtected = (1 << 28),
413     BitValue = (1 << 29),
414 }
415 
416 /// Define types of [TransientObject](TransientObject) with predefined maximum sizes.
417 #[repr(u32)]
418 pub enum TransientObjectType {
419     /// 128, 192, or 256 bits
420     Aes = 0xA0000010,
421     /// Always 64 bits including the parity bits. This gives an effective key size of 56 bits
422     Des = 0xA0000011,
423     /// 128 or 192 bits including the parity bits. This gives effective key sizes of 112 or 168 bits
424     Des3 = 0xA0000013,
425     /// Between 64 and 512 bits, multiple of 8 bits
426     HmacMd5 = 0xA0000001,
427     /// Between 80 and 512 bits, multiple of 8 bits
428     HmacSha1 = 0xA0000002,
429     /// Between 112 and 512 bits, multiple of 8 bits
430     HmacSha224 = 0xA0000003,
431     /// Between 192 and 1024 bits, multiple of 8 bits
432     HmacSha256 = 0xA0000004,
433     /// Between 256 and 1024 bits, multiple of 8 bits
434     HmacSha384 = 0xA0000005,
435     /// Between 256 and 1024 bits, multiple of 8 bits
436     HmacSha512 = 0xA0000006,
437     /// The number of bits in the modulus. 256, 512, 768, 1024, 1536 and 2048 bit keys SHALL be supported.
438     /// Support for other key sizes including bigger key sizes is
439     /// implementation-dependent. Minimum key size is 256 bits
440     RsaPublicKey = 0xA0000030,
441     /// Same as [RsaPublicKey](TransientObjectType::RsaPublicKey) key size.
442     RsaKeypair = 0xA1000030,
443     /// Depends on Algorithm:
444     /// 1) [DsaSha1](../crypto_op/enum.AlgorithmId.html#variant.DsaSha1):
445     /// Between 512 and 1024 bits, multiple of 64 bits
446     /// 2) [DsaSha224](../crypto_op/enum.AlgorithmId.html#variant.DsaSha224): 2048 bits
447     /// 3) [DsaSha256](../crypto_op/enum.AlgorithmId.html#variant.DsaSha256): 2048 or 3072 bits
448     DsaPublicKey = 0xA0000031,
449     /// Same as [DsaPublicKey](TransientObjectType::DsaPublicKey) key size.
450     DsaKeypair = 0xA1000031,
451     /// From 256 to 2048 bits, multiple of 8 bits.
452     DhKeypair = 0xA1000032,
453     /// Between 160 and 521 bits. Conditional: Available only if at least
454     /// one of the ECC the curves defined in Table 6-14 with "generic"
455     /// equal to "Y" is supported.
456     EcdsaPublicKey = 0xA0000041,
457     /// Between 160 and 521 bits. Conditional: Available only if at least
458     /// one of the ECC curves defined in Table 6-14 with "generic" equal to
459     /// "Y" is supported. SHALL be same value as for ECDSA public key size.
460     EcdsaKeypair = 0xA1000041,
461     /// Between 160 and 521 bits. Conditional: Available only if at least
462     /// one of the ECC curves defined in Table 6-14 with "generic" equal to
463     /// "Y" is supported.
464     EcdhPublicKey = 0xA0000042,
465     /// Between 160 and 521 bits. Conditional: Available only if at least
466     /// one of the ECC curves defined in Table 6-14 with "generic" equal to
467     /// "Y" is supported. SHALL be same value as for ECDH public key size
468     EcdhKeypair = 0xA1000042,
469     /// Multiple of 8 bits, up to 4096 bits. This type is intended for secret
470     /// data that has been derived from a key derivation scheme.
471     GenericSecret = 0xA0000000,
472     /// Object is corrupted.
473     CorruptedObject = 0xA00000BE,
474     /// 0 – All data is in the associated data stream.
475     Data = 0xA00000BF,
476 }
477 
478 /// A trait for an object (trasient or persistent) to return its handle.
479 pub trait ObjHandle {
480     /// Return the handle of an object.
handle(&self) -> raw::TEE_ObjectHandle481     fn handle(&self) -> raw::TEE_ObjectHandle;
482 }
483 
484 /// An object containing attributes but no data stream, which is reclaimed
485 /// when closed or when the TA instance is destroyed.
486 /// Transient objects are used to hold a cryptographic object (key or key-pair).
487 ///
488 /// Contrast [PersistentObject](PersistentObject).
489 pub struct TransientObject(ObjectHandle);
490 
491 impl TransientObject {
492     /// Create a [TransientObject](TransientObject) with a null handle which points to nothing.
null_object() -> Self493     pub fn null_object() -> Self {
494         Self(ObjectHandle::from_raw(ptr::null_mut()))
495     }
496 
497     /// Allocate an uninitialized [TransientObject](TransientObject), i.e. a container for attributes.
498     ///
499     /// As allocated, the object is uninitialized.
500     /// It can be initialized by subsequently importing the object material, generating an object,
501     /// deriving an object, or loading an object from the Trusted Storage.
502     ///
503     /// # Parameters
504     ///
505     /// 1) `object_type`: Type of uninitialized object container to be created as defined in
506     /// [TransientObjectType](TransientObjectType).
507     /// 2) `max_object_size`: Key Size of the object. Valid values depend on the object type and are
508     ///    defined in [TransientObjectType](TransientObjectType).
509     ///
510     /// # Example
511     ///
512     /// ```no_run
513     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
514     ///     Ok(object) =>
515     ///     {
516     ///         // ...
517     ///         Ok(())
518     ///     }
519     ///     Err(e) => Err(e),
520     /// }
521     /// ```
522     ///
523     /// # Errors
524     ///
525     /// 1) `OutOfMemory`: If not enough resources are available to allocate the object handle.
526     /// 2) `NotSupported`: If the key size is not supported or the object type is not supported.
527     ///
528     /// # Panics
529     ///
530     /// 1) If the Implementation detects any error associated with this function which is not
531     ///    explicitly associated with a defined return code for this function.
allocate(object_type: TransientObjectType, max_object_size: usize) -> Result<Self>532     pub fn allocate(object_type: TransientObjectType, max_object_size: usize) -> Result<Self> {
533         let raw_handle: *mut raw::TEE_ObjectHandle = Box::into_raw(Box::new(ptr::null_mut()));
534         match unsafe {
535             raw::TEE_AllocateTransientObject(object_type as u32, max_object_size as u32, raw_handle)
536         } {
537             raw::TEE_SUCCESS => {
538                 let handle = ObjectHandle::from_raw(raw_handle);
539                 Ok(Self(handle))
540             }
541             code => Err(Error::from_raw_error(code)),
542         }
543     }
544 
545     ///Reset a [TransientObject](TransientObject) to its initial state after allocation.
546     ///If the object is currently initialized, the function clears the object of all its material.
547     ///The object is then uninitialized again.
reset(&mut self)548     pub fn reset(&mut self) {
549         unsafe {
550             raw::TEE_ResetTransientObject(self.handle());
551         }
552     }
553 
554     /// Populate an uninitialized object container with object attributes passed by the TA in the `attrs` parameter.
555     /// When this function is called, the object SHALL be uninitialized.
556     /// If the object is initialized, the caller SHALL first clear it using the function reset.
557     /// Note that if the object type is a key-pair, then this function sets both the private and public attributes of the keypair.
558     ///
559     /// # Parameters
560     ///
561     /// 1) `attrs`: Array of object attributes.
562     ///
563     /// # Example
564     ///
565     /// ```no_run
566     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
567     ///     Ok(object) =>
568     ///     {
569     ///         let attrs = [AttributeMemref::from_ref(AttributeId::SecretValue, &[0u8;1])];
570     ///         object.populate(&attrs);
571     ///         Ok(())
572     ///     }
573     ///     Err(e) => Err(e),
574     /// }
575     /// ```
576     ///
577     /// # Errors
578     ///
579     /// 1) `BadParameters`: If an incorrect or inconsistent attribute value is detected. In this case,
580     /// the content of the object SHALL remain uninitialized.
581     ///
582     /// # Panics
583     ///
584     /// 1) If object is not a valid opened object that is transient and uninitialized.
585     /// 2) If some mandatory attribute is missing.
586     /// 3) If an attribute which is not defined for the object’s type is present in attrs.
587     /// 4) If an attribute value is too big to fit within the maximum object size specified when the object was created.
588     /// 5) If the Implementation detects any other error associated with this function which is not
589     ///    explicitly associated with a defined return code for this function.
populate(&mut self, attrs: &[Attribute]) -> Result<()>590     pub fn populate(&mut self, attrs: &[Attribute]) -> Result<()> {
591         let p: Vec<raw::TEE_Attribute> = attrs.iter().map(|p| p.raw()).collect();
592         match unsafe {
593             raw::TEE_PopulateTransientObject(self.0.handle(), p.as_ptr() as _, attrs.len() as u32)
594         } {
595             raw::TEE_SUCCESS => Ok(()),
596             code => return Err(Error::from_raw_error(code)),
597         }
598     }
599 
600     /// Return the characteristics of an object.
601     ///
602     /// # Example
603     ///
604     /// ```no_run
605     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
606     ///     Ok(object) => {
607     ///         match object.info() {
608     ///             Ok(info) => {
609     ///                 // ...
610     ///                 Ok(())
611     ///             }
612     ///         Err(e) => Err(e),
613     ///     }
614     ///     Err(e) => Err(e),
615     /// }
616     /// ```
617     ///
618     /// # Panics
619     ///
620     /// 1) If object is not a valid opened object.
621     /// 2) If the Implementation detects any other error associated with this function which is not
622     ///    explicitly associated with a defined return code for this function.
info(&self) -> Result<ObjectInfo>623     pub fn info(&self) -> Result<ObjectInfo> {
624         self.0.info()
625     }
626 
627     /// Restrict the object usage flags of an object handle to contain at most the flags passed in the obj_usage parameter.
628     ///
629     /// The initial value of the key usage contains all usage flags.
630     ///
631     /// # Parameters
632     ///
633     /// 1) `obj_usage`: New object usage, an OR comination of one or more of the [UsageFlag](UsageFlag).
634     ///
635     /// # Example
636     ///
637     /// ```no_run
638     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
639     ///     Ok(object) =>
640     ///     {
641     ///         object.restrict_usage(UsageFlag::ENCRYPT)?;
642     ///         Ok(())
643     ///     }
644     ///     Err(e) => Err(e),
645     /// }
646     /// ```
647     ///
648     /// # Panics
649     ///
650     /// 1) If object is not a valid opened object.
651     /// 2) If the Implementation detects any other error associated with this function which is not
652     ///    explicitly associated with a defined return code for this function.
restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()>653     pub fn restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()> {
654         self.0.restrict_usage(obj_usage)
655     }
656 
657     /// Extract one buffer attribute from an object. The attribute is identified by the argument id.
658     ///
659     /// # Parameters
660     ///
661     /// 1) `id`: Identifier of the attribute to retrieve.
662     /// 2) `ref_attr`: Output buffer to get the content of the attribute.
663     ///
664     /// # Example
665     ///
666     /// ```no_run
667     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
668     ///     Ok(object) => {
669     ///         let mut attr = [0u8; 16];
670     ///         match object.ref_attribute(id, &mut attr) {
671     ///             Ok(size) => {
672     ///                 // ...
673     ///                 Ok(())
674     ///             }
675     ///             Err(e) => Err(e),
676     ///         }
677     ///     }
678     ///     Err(e) => Err(e),
679     /// }
680     /// ```
681     ///
682     /// # Errors
683     ///
684     /// 1) `ItemNotFound`: If the attribute is not found on this object.
685     /// 2) `ShortBuffer`: If buffer is NULL or too small to contain the key part.
686     ///
687     /// # Panics
688     ///
689     /// 1) If object is not a valid opened object.
690     /// 2) If the object is not initialized.
691     /// 3) If the Attribute is not a buffer attribute.
ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize>692     pub fn ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize> {
693         self.0.ref_attribute(id, buffer)
694     }
695 
696     /// Extract one value attribute from an object. The attribute is identified by the argument id.
697     ///
698     /// # Parameters
699     ///
700     /// 1) `id`: Identifier of the attribute to retrieve.
701     /// 2) `value_attr`: Two value placeholders to get the content of the attribute.
702     ///
703     /// # Example
704     ///
705     /// ```no_run
706     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
707     ///     Ok(object) => {
708     ///         match object.value_attribute(id) {
709     ///             Ok(a,b) => {
710     ///                 // ...
711     ///                 Ok(())
712     ///             }
713     ///             Err(e) => Err(e),
714     ///         }
715     ///     }
716     ///     Err(e) => Err(e),
717     /// }
718     /// ```
719     ///
720     /// # Errors
721     ///
722     /// 1) `ItemNotFound`: If the attribute is not found on this object.
723     ///
724     /// # Panics
725     ///
726     /// 1) If object is not a valid opened object.
727     /// 2) If the object is not initialized.
728     /// 3) If the Attribute is not a value attribute.
value_attribute(&self, id: u32) -> Result<(u32, u32)>729     pub fn value_attribute(&self, id: u32) -> Result<(u32, u32)> {
730         self.0.value_attribute(id)
731     }
732 
733     /// Populates an uninitialized object handle with the attributes of another object handle;
734     /// that is, it populates the attributes of this handle with the attributes of src_handle.
735     /// It is most useful in the following situations:
736     /// 1) To extract the public key attributes from a key-pair object.
737     /// 2) To copy the attributes from a [PersistentObject](PersistentObject) into a [TransientObject](TransientObject).
738     ///
739     /// # Parameters
740     ///
741     /// 1) `src_object`: Can be either a [TransientObject](TransientObject) or [PersistentObject](PersistentObject).
742     ///
743     /// # Example
744     ///
745     /// ```no_run
746     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
747     ///     Ok(object1) =>
748     ///     {
749     ///         match TransientObject::allocate(TransientObjectType::Aes, 256) {
750     ///             Ok(object2) => {
751     ///                 object1.copy_attribute_from(object2);
752     ///                 Ok(())
753     ///             }
754     ///             Err(e) => Err(e),
755     ///         }
756     ///     }
757     ///     Err(e) => Err(e),
758     /// }
759     /// ```
760     ///
761     /// # Errors
762     ///
763     /// 1) `CorruptObject`: If the persistentd` object is corrupt. The object handle is closed.
764     /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
765     ///    currently inaccessible.
766     ///
767     /// # Panics
768     ///
769     /// 1) If src_object is not initialized.
770     /// 2) If self is initialized.
771     /// 3) If the type and size of src_object and self are not compatible.
772     /// 4) If the Implementation detects any other error associated with this function which is not
773     ///    explicitly associated with a defined return code for this function.
copy_attribute_from<T: ObjHandle>(&mut self, src_object: &T) -> Result<()>774     pub fn copy_attribute_from<T: ObjHandle>(&mut self, src_object: &T) -> Result<()> {
775         match unsafe { raw::TEE_CopyObjectAttributes1(self.handle(), src_object.handle()) } {
776             raw::TEE_SUCCESS => Ok(()),
777             code => Err(Error::from_raw_error(code)),
778         }
779     }
780 
781     /// Generates a random key or a key-pair and populates a transient key object with the generated key material.
782     ///
783     /// # Parameters
784     ///
785     /// 1) `key_size`: the size of the desired key. It SHALL be less than or equal to
786     /// the maximum key size specified when the [TransientObject](TransientObject) was created.
787     ///
788     /// # Example
789     ///
790     /// ```no_run
791     /// match TransientObject::allocate(TransientObjectType::Aes, 128) {
792     ///     Ok(object) =>
793     ///     {
794     ///         object.generate_key(128, &[])?;
795     ///         Ok(())
796     ///     }
797     ///     Err(e) => Err(e),
798     /// }
799     /// ```
800     ///
801     /// # Errors
802     ///
803     /// 1) `BadParameters`: If an incorrect or inconsistent attribute value is detected. In this
804     ///    case, the content of the object SHALL remain uninitialized.
805     ///
806     /// # Panics
807     ///
808     /// 1) If object is not a valid opened object.
809     /// 2) If some mandatory attribute is missing.
810     /// 3) If an attribute which is not defined for the object’s type is present in attrs.
811     /// 4) If an attribute value is too big to fit within the maximum object size specified when
812     /// the object was created.
813     /// 5) If the Implementation detects any other error associated with this function which is not
814     ///    explicitly associated with a defined return code for this function.
generate_key(&self, key_size: usize, params: &[Attribute]) -> Result<()>815     pub fn generate_key(&self, key_size: usize, params: &[Attribute]) -> Result<()> {
816         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
817         unsafe {
818             match raw::TEE_GenerateKey(
819                 self.handle(),
820                 key_size as u32,
821                 p.as_slice().as_ptr() as _,
822                 p.len() as u32,
823             ) {
824                 raw::TEE_SUCCESS => Ok(()),
825                 code => Err(Error::from_raw_error(code)),
826             }
827         }
828     }
829 }
830 
831 impl ObjHandle for TransientObject {
handle(&self) -> raw::TEE_ObjectHandle832     fn handle(&self) -> raw::TEE_ObjectHandle {
833         self.0.handle()
834     }
835 }
836 
837 impl Drop for TransientObject {
838     /// Deallocates a [TransientObject](TransientObject) previously allocated.
839     /// After this function has been called, the object handle is no longer valid and all resources
840     /// associated with the [TransientObject](TransientObject) SHALL have been reclaimed.
841     ///
842     /// # Panics
843     ///
844     /// 1) If object is not a valid opened object.
845     /// 2) If the Implementation detects any other error associated with this function which is not
846     ///    explicitly associated with a defined return code for this function.
drop(&mut self)847     fn drop(&mut self) {
848         unsafe {
849             if self.0.raw != ptr::null_mut() {
850                 raw::TEE_FreeTransientObject(self.0.handle());
851             }
852             drop(Box::from_raw(self.0.raw));
853         }
854     }
855 }
856 
857 /// An object identified by an Object Identifier and including a Data Stream.
858 ///
859 /// Contrast [TransientObject](TransientObject).
860 pub struct PersistentObject(ObjectHandle);
861 
862 impl PersistentObject {
863     /// Open an existing [PersistentObject](PersistentObject).
864     ///
865     /// # Parameters
866     ///
867     /// 1) `storage_id`: The storaget to use which is defined in
868     ///    [ObjectStorageConstants](ObjectStorageConstants).
869     /// 2) `object_id`: The object identifier. Note that this buffer cannot reside in shared memory.
870     /// 3) `flags`: The [DataFlag](DataFlag) which determine the settings under which the object is opened.
871     ///
872     /// # Example
873     ///
874     /// ```no_run
875     /// let obj_id = [1u8;1];
876     /// match PersistentObject::open (
877     ///         ObjectStorageConstants::Private,
878     ///         &obj_id,
879     ///         DataFlag::ACCESS_READ) {
880     ///     Ok(object) =>
881     ///     {
882     ///         // ...
883     ///         Ok(())
884     ///     }
885     ///     Err(e) => Err(e),
886     /// }
887     /// ```
888     ///
889     /// # Errors
890     ///
891     /// 1) `ItemNotFound`: If the storage denoted by storage_id does not exist or if the object
892     ///    identifier cannot be found in the storage.
893     /// 2) `Access_Conflict`: If an access right conflict was detected while opening the object.
894     /// 3) `OutOfMemory`: If there is not enough memory to complete the operation.
895     /// 4) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
896     /// 5) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
897     ///    currently inaccessible.
898     ///
899     /// # Panics
900     ///
901     /// 1) If object_id.len() >
902     ///    [MiscellaneousConstants::TeeObjectIdMaxLen](MiscellaneousConstants::TeeObjectIdMaxLen)
903     /// 2) If the Implementation detects any other error associated with this function which is not
904     ///    explicitly associated with a defined return code for this function.
open( storage_id: ObjectStorageConstants, object_id: &[u8], flags: DataFlag, ) -> Result<Self>905     pub fn open(
906         storage_id: ObjectStorageConstants,
907         object_id: &[u8],
908         flags: DataFlag,
909     ) -> Result<Self> {
910         let raw_handle: *mut raw::TEE_ObjectHandle = Box::into_raw(Box::new(ptr::null_mut()));
911         match unsafe {
912             raw::TEE_OpenPersistentObject(
913                 storage_id as u32,
914                 object_id.as_ptr() as _,
915                 object_id.len(),
916                 flags.bits(),
917                 raw_handle as *mut _,
918             )
919         } {
920             raw::TEE_SUCCESS => {
921                 let handle = ObjectHandle::from_raw(raw_handle);
922                 Ok(Self(handle))
923             }
924             code => {
925                 unsafe {
926                     drop(Box::from_raw(raw_handle));
927                 }
928                 Err(Error::from_raw_error(code))
929             }
930         }
931     }
932 
933     /// Create a [PersistentObject](PersistentObject) with initial attributes and an initial data stream content.
934     ///
935     /// # Parameters
936     ///
937     /// 1) `storage_id`: The storaget to use which is defined in
938     ///    [ObjectStorageConstants](ObjectStorageConstants).
939     /// 2) `object_id`: The object identifier. Note that this buffer cannot reside in shared memory.
940     /// 3) `flags`: The [DataFlag](DataFlag) which determine the settings under which the object is opened.
941     /// 4) `attributes`: A handle on a [PersistentObject](PersistentObject) or an initialized [TransientObject](TransientObject)
942     /// from which to take the [PersistentObject](PersistentObject) attributes.
943     /// Can be NONE if the [PersistentObject](PersistentObject) contains no attribute.
944     /// For example,if  it is a pure data object.
945     ///
946     /// # Example
947     ///
948     /// ```no_run
949     /// let obj_id = [1u8;1];
950     /// let mut init_data: [u8; 0] = [0; 0];
951     /// match PersistentObject::open (
952     ///         ObjectStorageConstants::Private,
953     ///         &obj_id,
954     ///         DataFlag::ACCESS_READ | DataFlag::ACCESS_WRITE
955     ///         None,
956     ///         &mut init_data) {
957     ///     Ok(object) =>
958     ///     {
959     ///         // ...
960     ///         Ok(())
961     ///     }
962     ///     Err(e) => Err(e),
963     /// }
964     /// ```
965     ///
966     /// # Errors
967     ///
968     /// 1) `ItemNotFound`: If the storage denoted by storage_id does not exist or if the object
969     ///    identifier cannot be found in the storage.
970     /// 2) `Access_Conflict`: If an access right conflict was detected while opening the object.
971     /// 3) `OutOfMemory`: If there is not enough memory to complete the operation.
972     /// 4) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
973     /// 5) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
974     ///    currently inaccessible.
975     ///
976     /// # Panics
977     ///
978     /// 1) If object_id.len() >
979     ///    [MiscellaneousConstants::TeeObjectIdMaxLen](MiscellaneousConstants::TeeObjectIdMaxLen).
980     /// 2) If attributes is not NONE and is not a valid handle on an initialized object containing
981     ///    the type and attributes of the [PersistentObject](PersistentObject) to create.
982     /// 3) If the Implementation detects any other error associated with this function which is not
983     ///    explicitly associated with a defined return code for this function.
create( storage_id: ObjectStorageConstants, object_id: &[u8], flags: DataFlag, attributes: Option<ObjectHandle>, initial_data: &[u8], ) -> Result<Self>984     pub fn create(
985         storage_id: ObjectStorageConstants,
986         object_id: &[u8],
987         flags: DataFlag,
988         attributes: Option<ObjectHandle>,
989         initial_data: &[u8],
990     ) -> Result<Self> {
991         let raw_handle: *mut raw::TEE_ObjectHandle = Box::into_raw(Box::new(ptr::null_mut()));
992         let attributes = match attributes {
993             Some(a) => a.handle(),
994             None => ptr::null_mut(),
995         };
996         match unsafe {
997             raw::TEE_CreatePersistentObject(
998                 storage_id as u32,
999                 object_id.as_ptr() as _,
1000                 object_id.len(),
1001                 flags.bits(),
1002                 attributes,
1003                 initial_data.as_ptr() as _,
1004                 initial_data.len(),
1005                 raw_handle as *mut _,
1006             )
1007         } {
1008             raw::TEE_SUCCESS => {
1009                 let handle = ObjectHandle::from_raw(raw_handle);
1010                 Ok(Self(handle))
1011             }
1012             code => {
1013                 unsafe {
1014                     drop(Box::from_raw(raw_handle));
1015                 }
1016                 Err(Error::from_raw_error(code))
1017             }
1018         }
1019     }
1020 
1021     /// Marks an object for deletion and closes the object.
1022     ///
1023     /// # Example
1024     ///
1025     /// ```no_run
1026     /// let obj_id = [1u8;1];
1027     /// match PersistentObject::open (
1028     ///         ObjectStorageConstants::Private,
1029     ///         &obj_id,
1030     ///         DataFlag::ACCESS_READ) {
1031     ///     Ok(object) =>
1032     ///     {
1033     ///         object.close_and_delete()?;
1034     ///         std::mem::forget(object);
1035     ///         Ok(())
1036     ///     }
1037     ///     Err(e) => Err(e),
1038     /// }
1039     /// ```
1040     ///
1041     /// # Errors
1042     ///
1043     /// 1) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1044     ///    currently inaccessible.
1045     ///
1046     /// # Panics
1047     ///
1048     /// 1) If object is not a valid opened object.
1049     /// 2) If the Implementation detects any other error associated with this function which is not
1050     ///    explicitly associated with a defined return code for this function.
1051     // this function is conflicted with Drop implementation, when use this one to avoid panic:
1052     // Call `mem::forget` for this structure to avoid double drop the object
close_and_delete(&mut self) -> Result<()>1053     pub fn close_and_delete(&mut self) -> Result<()> {
1054         match unsafe { raw::TEE_CloseAndDeletePersistentObject1(self.0.handle()) } {
1055             raw::TEE_SUCCESS => {
1056                 unsafe {
1057                     drop(Box::from_raw(self.0.raw));
1058                 }
1059                 return Ok(());
1060             }
1061             code => Err(Error::from_raw_error(code)),
1062         }
1063     }
1064 
1065     /// Changes the identifier of an object.
1066     /// The object SHALL have been opened with the [DataFlag::ACCESS_WRITE_META](DataFlag::ACCESS_WRITE_META) right, which means access to the object is exclusive.
1067     ///
1068     /// # Example
1069     ///
1070     /// ```no_run
1071     /// let obj_id = [1u8;1];
1072     /// let new_obj_id = [2u8;1];
1073     /// match PersistentObject::open (
1074     ///         ObjectStorageConstants::Private,
1075     ///         &obj_id,
1076     ///         DataFlag::ACCESS_WRITE_META) {
1077     ///     Ok(object) =>
1078     ///     {
1079     ///         object.rename(&new_obj_id)?;
1080     ///         Ok(())
1081     ///     }
1082     ///     Err(e) => Err(e),
1083     /// }
1084     /// ```
1085     ///
1086     /// # Errors
1087     ///
1088     /// 1) `Access_Conflict`: If an access right conflict was detected while opening the object.
1089     /// 2) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1090     /// 3) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1091     ///    currently inaccessible.
1092     ///
1093     /// # Panics
1094     ///
1095     /// 1) If object is not a valid opened object.
1096     /// 2) If new_object_id resides in shared memory.
1097     /// 3) If new_object_id.len() >
1098     ///    [MiscellaneousConstants::TeeObjectIdMaxLen](MiscellaneousConstants::TeeObjectIdMaxLen).
1099     /// 4) If the Implementation detects any other error associated with this function which is not
1100     ///    explicitly associated with a defined return code for this function.
rename(&mut self, new_object_id: &[u8]) -> Result<()>1101     pub fn rename(&mut self, new_object_id: &[u8]) -> Result<()> {
1102         match unsafe {
1103             raw::TEE_RenamePersistentObject(
1104                 self.0.handle(),
1105                 new_object_id.as_ptr() as _,
1106                 new_object_id.len(),
1107             )
1108         } {
1109             raw::TEE_SUCCESS => Ok(()),
1110             code => Err(Error::from_raw_error(code)),
1111         }
1112     }
1113     /// Return the characteristics of an object.
1114     /// Function is similar to [TransientObject::info](TransientObject::info) besides extra errors.
1115     ///
1116     /// # Errors
1117     ///
1118     /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1119     /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1120     ///    currently inaccessible.
info(&self) -> Result<ObjectInfo>1121     pub fn info(&self) -> Result<ObjectInfo> {
1122         self.0.info()
1123     }
1124 
1125     /// Restrict the object usage flags of an object handle to contain at most the flags passed in the obj_usage parameter.
1126     /// Function is similar to [TransientObject::restrict_usage](TransientObject::restrict_usage) besides extra errors.
1127     ///
1128     /// # Errors
1129     ///
1130     /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1131     /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1132     ///    currently inaccessible.
restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()>1133     pub fn restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()> {
1134         self.0.restrict_usage(obj_usage)
1135     }
1136 
1137     /// Extract one buffer attribute from an object. The attribute is identified by the argument id.
1138     /// Function is similar to [TransientObject::ref_attribute](TransientObject::ref_attribute) besides extra errors.
1139     ///
1140     /// # Errors
1141     ///
1142     /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1143     /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1144     ///    currently inaccessible.
ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize>1145     pub fn ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize> {
1146         self.0.ref_attribute(id, buffer)
1147     }
1148 
1149     /// Extract one value attribute from an object. The attribute is identified by the argument id.
1150     /// Function is similar to [TransientObject::value_attribute](TransientObject::value_attribute) besides extra errors.
1151     ///
1152     /// # Errors
1153     ///
1154     /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1155     /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1156     ///    currently inaccessible.
value_attribute(&self, id: u32) -> Result<(u32, u32)>1157     pub fn value_attribute(&self, id: u32) -> Result<(u32, u32)> {
1158         self.0.value_attribute(id)
1159     }
1160 
1161     /// Read requested size from the data stream assoicate with the object into the buffer.
1162     ///
1163     /// # Parameters
1164     ///
1165     /// 1) `buffer`: A pre-allocated buffer for saving the object's data stream.
1166     /// 2) `count`: The returned value contains the number of bytes read.
1167     /// # Example
1168     ///
1169     /// ```no_run
1170     /// let obj_id = [1u8;1];
1171     /// match PersistentObject::open (
1172     ///         ObjectStorageConstants::Private,
1173     ///         &obj_id,
1174     ///         DataFlag::ACCESS_READ) {
1175     ///     Ok(object) =>
1176     ///     {
1177     ///         let read_buf = [0u8;16];
1178     ///         object.read(&mut read_buf)?;
1179     ///         Ok(())
1180     ///     }
1181     ///     Err(e) => Err(e),
1182     /// }
1183     /// ```
1184     ///
1185     /// # Errors
1186     ///
1187     /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1188     /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1189     ///    currently inaccessible.
1190     ///
1191     /// # Panics
1192     ///
1193     /// 1) If object is not a valid opened object.
1194     /// 2) If the Implementation detects any other error associated with this function which is not
1195     ///    explicitly associated with a defined return code for this function.
read(&self, buf: &mut [u8]) -> Result<u32>1196     pub fn read(&self, buf: &mut [u8]) -> Result<u32> {
1197         let mut count: usize = 0;
1198         match unsafe {
1199             raw::TEE_ReadObjectData(
1200                 self.handle(),
1201                 buf.as_mut_ptr() as _,
1202                 buf.len(),
1203                 &mut count,
1204             )
1205         } {
1206             raw::TEE_SUCCESS => Ok(count as u32),
1207             code => Err(Error::from_raw_error(code)),
1208         }
1209     }
1210 
1211     /// Write the passed in buffer data into from the data stream assoicate with the object.
1212     ///
1213     /// # Parameters
1214     ///
1215     /// 1) `buffer`: A pre-allocated buffer for saving the object's data stream.
1216     ///
1217     /// # Example
1218     ///
1219     /// ```no_run
1220     /// let obj_id = [1u8;1];
1221     /// match PersistentObject::open (
1222     ///         ObjectStorageConstants::Private,
1223     ///         &obj_id,
1224     ///         DataFlag::ACCESS_WRITE) {
1225     ///     Ok(object) =>
1226     ///     {
1227     ///         let write_buf = [1u8;16];
1228     ///         object.write(& write_buf)?;
1229     ///         Ok(())
1230     ///     }
1231     ///     Err(e) => Err(e),
1232     /// }
1233     /// ```
1234     ///
1235     /// # Errors
1236     ///
1237     /// 1) `StorageNoSpace`: If insufficient storage space is available.
1238     /// 2) `Overflow`: If the value of the data position indicator resulting from this operation
1239     ///    would be greater than
1240     ///    [MiscellaneousConstants::TeeDataMaxPosition](MiscellaneousConstants::TeeDataMaxPosition).
1241     /// 3) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1242     /// 4) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1243     ///    currently inaccessible.
1244     ///
1245     /// # Panics
1246     ///
1247     /// 1) If object is not a valid opened object.
1248     /// 2) If the Implementation detects any other error associated with this function which is not
1249     ///    explicitly associated with a defined return code for this function.
write(&mut self, buf: &[u8]) -> Result<()>1250     pub fn write(&mut self, buf: &[u8]) -> Result<()> {
1251         match unsafe {
1252             raw::TEE_WriteObjectData(self.handle(), buf.as_ptr() as _, buf.len())
1253         } {
1254             raw::TEE_SUCCESS => Ok(()),
1255             code => Err(Error::from_raw_error(code)),
1256         }
1257     }
1258 
1259     /// Change the size of a data stream associate with the object.
1260     ///
1261     /// # Example
1262     ///
1263     /// ```no_run
1264     /// let obj_id = [1u8;1];
1265     /// match PersistentObject::open (
1266     ///         ObjectStorageConstants::Private,
1267     ///         &obj_id,
1268     ///         DataFlag::ACCESS_WRITE) {
1269     ///     Ok(object) =>
1270     ///     {
1271     ///         object.truncate(1u32)?;
1272     ///         Ok(())
1273     ///     }
1274     ///     Err(e) => Err(e),
1275     /// }
1276     /// ```
1277     ///
1278     /// # Errors
1279     ///
1280     /// 1) `StorageNoSpace`: If insufficient storage space is available.
1281     ///    would be greater than
1282     ///    [MiscellaneousConstants::TeeDataMaxPosition](MiscellaneousConstants::TeeDataMaxPosition).
1283     /// 2) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1284     /// 3) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1285     ///    currently inaccessible.
1286     ///
1287     /// # Panics
1288     ///
1289     /// 1) If object is not a valid opened object.
1290     /// 2) If the Implementation detects any other error associated with this function which is not
1291     ///    explicitly associated with a defined return code for this function.
truncate(&self, size: u32) -> Result<()>1292     pub fn truncate(&self, size: u32) -> Result<()> {
1293         match unsafe { raw::TEE_TruncateObjectData(self.handle(), size as usize) } {
1294             raw::TEE_SUCCESS => Ok(()),
1295             code => Err(Error::from_raw_error(code)),
1296         }
1297     }
1298 
1299     /// Set the data position indicator associate with the object.
1300     ///
1301     /// # Parameters
1302     /// 1) `whence`: Defined in [Whence](Whence).
1303     /// 2) `offset`: The bytes shifted based on `whence`.
1304     ///
1305     /// # Example
1306     ///
1307     /// ```no_run
1308     /// let obj_id = [1u8;1];
1309     /// match PersistentObject::open(
1310     ///         ObjectStorageConstants::Private,
1311     ///         &obj_id,
1312     ///         DataFlag::ACCESS_WRITE) {
1313     ///     Ok(object) =>
1314     ///     {
1315     ///         object.seek(0i32, Whence::DataSeekSet)?;
1316     ///         Ok(())
1317     ///     }
1318     ///     Err(e) => Err(e),
1319     /// }
1320     /// ```
1321     ///
1322     /// # Errors
1323     ///
1324     /// 1) `Overflow`: If data position indicator is greater than
1325     ///    [MiscellaneousConstants::TeeDataMaxPosition](MiscellaneousConstants::TeeDataMaxPosition).
1326     /// 2) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed.
1327     /// 3) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is
1328     ///    currently inaccessible.
1329     ///
1330     /// # Panics
1331     ///
1332     /// 1) If object is not a valid opened object.
1333     /// 2) If the Implementation detects any other error associated with this function which is not
1334     ///    explicitly associated with a defined return code for this function.
seek(&self, offset: i32, whence: Whence) -> Result<()>1335     pub fn seek(&self, offset: i32, whence: Whence) -> Result<()> {
1336         match unsafe { raw::TEE_SeekObjectData(self.handle(), offset, whence.into()) } {
1337             raw::TEE_SUCCESS => Ok(()),
1338             code => Err(Error::from_raw_error(code)),
1339         }
1340     }
1341 }
1342 
1343 impl ObjHandle for PersistentObject {
handle(&self) -> raw::TEE_ObjectHandle1344     fn handle(&self) -> raw::TEE_ObjectHandle {
1345         self.0.handle()
1346     }
1347 }
1348 
1349 impl Drop for PersistentObject {
1350     /// Close an opened [PersistentObject](PersistentObject).
1351     ///
1352     /// # Panics
1353     ///
1354     /// 1) If object is not a valid opened object.
1355     /// 2) If the Implementation detects any other error associated with this function which is not
1356     ///    explicitly associated with a defined return code for this function.
drop(&mut self)1357     fn drop(&mut self) {
1358         unsafe {
1359             if self.0.raw != Box::into_raw(Box::new(ptr::null_mut())) {
1360                 raw::TEE_CloseObject(self.0.handle());
1361             }
1362             drop(Box::from_raw(self.0.raw));
1363         }
1364     }
1365 }
1366 
1367 // The examples and detailed function explanation will be added after we test this struct and its
1368 // functions.
1369 /// An enumerator for [PersistentObject](PersistentObject)s.
1370 pub struct ObjectEnumHandle {
1371     raw: *mut raw::TEE_ObjectEnumHandle,
1372 }
1373 
1374 impl ObjectEnumHandle {
1375     /// Allocate an object enumerator.
1376     /// Once an object enumerator has been allocated, it can be reused for multiple enumerations.
allocate() -> Result<Self>1377     pub fn allocate() -> Result<Self> {
1378         let raw_handle: *mut raw::TEE_ObjectEnumHandle = Box::into_raw(Box::new(ptr::null_mut()));
1379         match unsafe { raw::TEE_AllocatePersistentObjectEnumerator(raw_handle) } {
1380             raw::TEE_SUCCESS => Ok(Self { raw: raw_handle }),
1381             code => {
1382                 unsafe {
1383                     drop(Box::from_raw(raw_handle));
1384                 }
1385                 Err(Error::from_raw_error(code))
1386             }
1387         }
1388     }
1389 
1390     /// Reset an object enumerator handle to its initial state after allocation.
1391     /// If an enumeration has been started, it is stopped.
reset(&mut self)1392     pub fn reset(&mut self) {
1393         unsafe {
1394             raw::TEE_ResetPersistentObjectEnumerator(*self.raw);
1395         }
1396     }
1397 
1398     /// Start the enumeration of all the [PersistentObject](PersistentObject)s in a given Trusted Storage.
1399     /// The object information can be retrieved by calling the function
1400     /// [ObjectEnumHandle::get_next](ObjectEnumHandle::get_next) repeatedly.
start(&mut self, storage_id: u32) -> Result<()>1401     pub fn start(&mut self, storage_id: u32) -> Result<()> {
1402         match unsafe { raw::TEE_StartPersistentObjectEnumerator(*self.raw, storage_id) } {
1403             raw::TEE_SUCCESS => Ok(()),
1404             code => Err(Error::from_raw_error(code)),
1405         }
1406     }
1407 
1408     /// Get the next object in an enumeration and returns information about the object: type, size, identifier, etc.
get_next<T>( &mut self, object_info: &mut ObjectInfo, object_id: &mut [u8], ) -> Result<u32>1409     pub fn get_next<T>(
1410         &mut self,
1411         object_info: &mut ObjectInfo,
1412         object_id: &mut [u8],
1413     ) -> Result<u32> {
1414         let mut object_id_len: usize = 0;
1415         match unsafe {
1416             raw::TEE_GetNextPersistentObject(
1417                 *self.raw,
1418                 &mut object_info.raw,
1419                 object_id.as_mut_ptr() as _,
1420                 &mut object_id_len,
1421             )
1422         } {
1423             raw::TEE_SUCCESS => Ok(object_id_len as u32),
1424             code => Err(Error::from_raw_error(code)),
1425         }
1426     }
1427 }
1428 
1429 impl Drop for ObjectEnumHandle {
1430     /// Deallocates all resources associated with an object enumerator handle. After this function is called, the handle is no longer valid.
1431     ///
1432     /// # Panics
1433     ///
1434     /// 1) If object is not a valid opened object.
1435     /// 2) If the Implementation detects any other error.
drop(&mut self)1436     fn drop(&mut self) {
1437         unsafe {
1438             raw::TEE_FreePersistentObjectEnumerator(*self.raw);
1439             drop(Box::from_raw(self.raw));
1440         }
1441     }
1442 }
1443