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