| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| use crate::{Error, Result}; |
| use bitflags::bitflags; |
| use optee_utee_sys as raw; |
| use std::{marker, mem, ptr}; |
| |
| /// A general attribute (buffer or value) that can be used to populate an object or to specify |
| /// opeation parameters. |
| pub struct Attribute { |
| raw: raw::TEE_Attribute, |
| } |
| |
| impl Attribute { |
| /// Return the raw struct `TEE_Attribute`. |
| pub fn raw(&self) -> raw::TEE_Attribute { |
| self.raw |
| } |
| } |
| |
| /// Convert the buffer attribute [AttributeMemref](AttributeMemref) to the general attribute. |
| impl<'attrref> From<AttributeMemref<'attrref>> for Attribute { |
| fn from(attr: AttributeMemref) -> Self { |
| Self { raw: attr.raw() } |
| } |
| } |
| |
| /// Convert the value attribute [AttributeValue](AttributeValue) to the general attribute. |
| impl From<AttributeValue> for Attribute { |
| fn from(attr: AttributeValue) -> Self { |
| Self { raw: attr.raw() } |
| } |
| } |
| |
| /// A buffer attribute. |
| #[derive(Clone, Copy)] |
| pub struct AttributeMemref<'attrref> { |
| raw: raw::TEE_Attribute, |
| _marker: marker::PhantomData<&'attrref mut [u8]>, |
| } |
| |
| impl<'attrref> AttributeMemref<'attrref> { |
| /// Return the raw struct TEE_Attribute. |
| pub fn raw(&self) -> raw::TEE_Attribute { |
| self.raw |
| } |
| |
| fn new_ref() -> Self { |
| let raw = raw::TEE_Attribute { |
| attributeID: 0, |
| content: raw::content { |
| memref: raw::Memref { |
| buffer: 0 as *mut _, |
| size: 0, |
| }, |
| }, |
| }; |
| Self { |
| raw: raw, |
| _marker: marker::PhantomData, |
| } |
| } |
| |
| /// Populate a single attribute with a reference to a buffer. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `id`: The AttributeId[AttributeId] is an identifier of the attribute to populate. |
| /// 2) `buffer`: Input buffer that holds the content of the attribute. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let mut attr = AttributeMemref::from_ref(AttributeId::SecretValue, &mut [0u8;1]); |
| /// ``` |
| pub fn from_ref(id: AttributeId, buffer: &'attrref [u8]) -> Self { |
| let mut res = AttributeMemref::new_ref(); |
| unsafe { |
| raw::TEE_InitRefAttribute( |
| &mut res.raw, |
| id as u32, |
| buffer.as_ptr() as *mut _, |
| buffer.len(), |
| ); |
| } |
| res |
| } |
| } |
| |
| /// A value attribute. |
| pub struct AttributeValue { |
| raw: raw::TEE_Attribute, |
| } |
| |
| impl AttributeValue { |
| /// Return the raw struct TEE_Attribute. |
| pub fn raw(&self) -> raw::TEE_Attribute { |
| self.raw |
| } |
| |
| fn new_value() -> Self { |
| let raw = raw::TEE_Attribute { |
| attributeID: 0, |
| content: raw::content { |
| value: raw::Value { a: 0, b: 0 }, |
| }, |
| }; |
| Self { raw } |
| } |
| |
| /// Populate a single attribute with two u32 values. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `id`: The AttributeId[AttributeId] is an identifier of the attribute to populate. |
| /// 2) `a`, `b`: u32 values to assign to the members of the a value attribute. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let mut attr = AttributeValue::from_value(AttributeId::SecretValue, 0, 0); |
| /// ``` |
| pub fn from_value(id: AttributeId, a: u32, b: u32) -> Self { |
| let mut res = AttributeValue::new_value(); |
| unsafe { |
| raw::TEE_InitValueAttribute(&mut res.raw, id as u32, a, b); |
| } |
| res |
| } |
| } |
| |
| /// Represent the characteristics of an object. |
| /// This info can be returned by [TransientObject](TransientObject) function |
| /// [info](TransientObject::info) |
| /// or [PersistentObject](PersistentObject) function |
| /// [info](PersistentObject::info). |
| pub struct ObjectInfo { |
| raw: raw::TEE_ObjectInfo, |
| } |
| |
| // Since raw struct is not implemented Copy attribute yet, every item in raw struct needs a function to extract. |
| impl ObjectInfo { |
| /// Return an [ObjectInfo](ObjectInfo) struct based on the raw structrure `TEE_ObjectInfo`. |
| /// The raw structure contains following fields: |
| /// |
| /// 1) `objectType`: The parameter represents one of the |
| /// [TransientObjectType](TransientObjectType). |
| /// 2) `objectSize`: The current size in bits of the object as determined by its attributes. |
| /// This will always be less than or equal to maxObjectSize. Set to 0 for uninitialized and data only objects. |
| /// 3) `maxObjectSize`: The maximum objectSize which this object can represent. |
| /// 3.1) For a [PersistentObject](PersistentObject), set to `objectSize`. |
| /// 3.2) For a [TransientObject](TransientObject), set to the parameter `maxObjectSize` passed to |
| /// [allocate](TransientObject::allocate). |
| /// 4) `objectUsage`: A bit vector of UsageFlag. |
| /// 5) `dataSize`: |
| /// 5.1) For a [PersistentObject](PersistentObject), set to the current size of the data associated with the object. |
| /// 5.2) For a [TransientObject](TransientObject), always set to 0. |
| /// 6) `dataPosition`: |
| /// 6.1) For a [PersistentObject](PersistentObject), set to the current position in the data for this handle. |
| /// Data positions for different handles on the same object may differ. |
| /// 6.2) For a [TransientObject](TransientObject), set to 0. |
| /// 7) `handleFlags`: A bit vector containing one or more [HandleFlag](HandleFlag) or [DataFlag](DataFlag). |
| pub fn from_raw(raw: raw::TEE_ObjectInfo) -> Self { |
| Self { raw } |
| } |
| |
| /// Return the `dataSize` field of the raw structrure `TEE_ObjectInfo`. |
| pub fn data_size(&self) -> usize { |
| self.raw.dataSize as usize |
| } |
| |
| /// Return the `objectSize` field of the raw structrure `TEE_ObjectInfo`. |
| pub fn object_size(&self) -> usize { |
| self.raw.objectSize as usize |
| } |
| } |
| |
| /// Indicate the possible start offset when moving a data position in the data stream associated with a [PersistentObject](PersistentObject). |
| pub enum Whence { |
| /// The data position is set to offset bytes from the beginning of the data stream. |
| DataSeekSet, |
| /// The data position is set to its current position plus offset. |
| DataSeekCur, |
| /// The data position is set to the size of the object data plus offset. |
| DataSeekEnd, |
| } |
| |
| impl Into<raw::TEE_Whence> for Whence { |
| fn into(self) -> raw::TEE_Whence { |
| match self { |
| Whence::DataSeekSet => raw::TEE_Whence::TEE_DATA_SEEK_SET, |
| Whence::DataSeekCur => raw::TEE_Whence::TEE_DATA_SEEK_CUR, |
| Whence::DataSeekEnd => raw::TEE_Whence::TEE_DATA_SEEK_END, |
| } |
| } |
| } |
| |
| /// An opaque handle on an object. |
| pub struct ObjectHandle { |
| raw: *mut raw::TEE_ObjectHandle, |
| } |
| |
| impl ObjectHandle { |
| fn handle(&self) -> raw::TEE_ObjectHandle { |
| unsafe { *(self.raw) } |
| } |
| |
| fn from_raw(raw: *mut raw::TEE_ObjectHandle) -> ObjectHandle { |
| Self { raw } |
| } |
| |
| fn info(&self) -> Result<ObjectInfo> { |
| let mut raw_info: raw::TEE_ObjectInfo = unsafe { mem::zeroed() }; |
| match unsafe { raw::TEE_GetObjectInfo1(self.handle(), &mut raw_info) } { |
| raw::TEE_SUCCESS => Ok(ObjectInfo::from_raw(raw_info)), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| fn restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()> { |
| match unsafe { raw::TEE_RestrictObjectUsage1(self.handle(), obj_usage.bits()) } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| fn ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize> { |
| let mut size = buffer.len(); |
| match unsafe { |
| raw::TEE_GetObjectBufferAttribute( |
| self.handle(), |
| id as u32, |
| buffer as *mut _ as _, |
| &mut size, |
| ) |
| } { |
| raw::TEE_SUCCESS => Ok(size), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| fn value_attribute(&self, id: u32) -> Result<(u32, u32)> { |
| let mut value_a: u32 = 0; |
| let mut value_b: u32 = 0; |
| match unsafe { |
| raw::TEE_GetObjectValueAttribute( |
| self.handle(), |
| id, |
| &mut value_a as *mut _, |
| &mut value_b as *mut _, |
| ) |
| } { |
| raw::TEE_SUCCESS => Ok((value_a, value_b)), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| } |
| |
| #[repr(u32)] |
| pub enum ObjectStorageConstants { |
| Private = 0x00000001, |
| IllegalValue = 0x7FFFFFFF, |
| } |
| |
| bitflags! { |
| /// A set of flags that controls the access rights and sharing permissions |
| /// with which the object handle is opened. |
| pub struct DataFlag: u32 { |
| /// The object is opened with the read access right. This allows the |
| /// Trusted Application to call the function `TEE_ReadObjectData`. |
| const ACCESS_READ = 0x00000001; |
| /// The object is opened with the write access right. This allows the |
| /// Trusted Application to call the functions `TEE_WriteObjectData` and |
| /// `TEE_TruncateObjectData`. |
| const ACCESS_WRITE = 0x00000002; |
| /// The object is opened with the write-meta access right. This allows |
| /// the Trusted Application to call the functions |
| /// `TEE_CloseAndDeletePersistentObject1` and `TEE_RenamePersistentObject`. |
| const ACCESS_WRITE_META = 0x00000004; |
| /// The caller allows another handle on the object to be created with |
| /// read access. |
| const SHARE_READ = 0x00000010; |
| /// The caller allows another handle on the object to be created with |
| /// write access. |
| const SHARE_WRITE = 0x00000020; |
| /// * If this flag is present and the object exists, then the object is |
| /// deleted and re-created as an atomic operation: that is, the TA sees |
| /// either the old object or the new one. |
| /// * If the flag is absent and the object exists, then the function |
| /// SHALL return `TEE_ERROR_ACCESS_CONFLICT`. |
| const OVERWRITE = 0x00000400; |
| } |
| } |
| |
| bitflags! { |
| /// A set of flags that defines usages of data in TEE secure storage. |
| pub struct UsageFlag: u32 { |
| /// The object [Attribute](Attribute) can be extracted. |
| const EXTRACTABLE = 0x00000001; |
| /// The object can be used for encrytpion. |
| const ENCRYPT = 0x00000002; |
| /// The object can be used for decrption. |
| const DECRYPT = 0x00000004; |
| /// The object can be used for mac operation. |
| const MAC = 0x00000008; |
| /// The ojbect can be used for signature. |
| const SIGN = 0x00000010; |
| /// The object can be used for verification of a signature. |
| const VERIFY = 0x00000020; |
| /// The object can be used for deriving a key. |
| const DERIVE = 0x00000040; |
| } |
| } |
| |
| /// Miscellaneous constants. |
| #[repr(u32)] |
| pub enum MiscellaneousConstants { |
| /// Maximum offset of a data object. |
| TeeDataMaxPosition = 0xFFFFFFFF, |
| /// Maximum length of an object id. |
| TeeObjectIdMaxLen = 64, |
| } |
| |
| bitflags! { |
| /// A set of flags that defines Handle features. |
| pub struct HandleFlag: u32{ |
| /// Set for a [PersistentObject](PersistentObject). |
| const PERSISTENT = 0x00010000; |
| /// 1) For a [PersistentObject](PersistentObject), always set. |
| /// 2) For a [TransientObject](TransientObject), initially cleared, then set when the object becomes initialized. |
| const INITIALIZED = 0x00020000; |
| /// Following two flags are for crypto operation handles: |
| /// 1) Set if the required operation key has been set. |
| /// 2) Always set for digest operations. |
| const KEY_SET = 0x00040000; |
| /// Set if the algorithm expects two keys to be set, using `TEE_SetOperationKey2`. |
| /// This happens only if algorithm is set to [AesXts](../crypto_op/enum.AlgorithmId.html#variant.AesXts) |
| /// or `TEE_ALG_SM2_KEP`(not supported now). |
| const EXPECT_TWO_KEYS = 0x00080000; |
| } |
| } |
| |
| #[repr(u32)] |
| pub enum AttributeId { |
| /// Used for all secret keys for symmetric ciphers, MACs, and HMACs |
| SecretValue = 0xC0000000, |
| /// RSA modulus: `n` |
| RsaModulus = 0xD0000130, |
| /// RSA public key exponent: `e` |
| RsaPublicExponent = 0xD0000230, |
| /// RSA private key exponent: `d` |
| RsaPrivateExponent = 0xC0000330, |
| /// RSA prime number: `p` |
| RsaPrime1 = 0xC0000430, |
| /// RSA prime number: `q` |
| RsaPrime2 = 0xC0000530, |
| /// RSA exponent: `dp` |
| RsaExponent1 = 0xC0000630, |
| /// RSA exponent: `dq` |
| RsaExponent2 = 0xC0000730, |
| /// RSA coefficient: `iq` |
| RsaCoefficient = 0xC0000830, |
| /// DSA prime number: `p` |
| DsaPrime = 0xD0001031, |
| /// DSA sub prime number: `q` |
| DsaSubprime = 0xD0001131, |
| /// DSA base: `g` |
| DsaBase = 0xD0001231, |
| /// DSA public value: `y` |
| DsaPublicValue = 0xD0000131, |
| /// DSA private value: `x` |
| DsaPrivateValue = 0xC0000231, |
| /// Diffie-Hellman prime number: `p` |
| DhPrime = 0xD0001032, |
| /// Diffie-Hellman sub prime number: `q` |
| DhSubprime = 0xD0001132, |
| /// Diffie-Hellman base: `g` |
| DhBase = 0xD0001232, |
| /// Diffie-Hellman x bits: `l` |
| DhXBits = 0xF0001332, |
| /// Diffie-Hellman public value: `y` |
| DhPublicValue = 0xD0000132, |
| /// Diffie-Hellman public value: `x` |
| DhPrivateValue = 0xC0000232, |
| RsaOaepLabel = 0xD0000930, |
| RsaOaepMgf1Hash = 0xD0000931, |
| RsaPssSaltLength = 0xF0000A30, |
| /// ECC public value: `x` |
| EccPublicValueX = 0xD0000141, |
| /// ECC public value: `y` |
| EccPublicValueY = 0xD0000241, |
| /// ECC private value: `d` |
| EccPrivateValue = 0xC0000341, |
| /// Ed25519 public value |
| Ed25519PublicValue = 0xD0000743, |
| /// Ed25519 private value |
| Ed25519PrivateValue = 0xC0000843, |
| /// X25519 public value |
| X25519PublicValue = 0xD0000944, |
| /// X25519 private value |
| X25519PrivateValue = 0xC0000A44, |
| /// ECC Curve algorithm |
| EccCurve = 0xF0000441, |
| BitProtected = (1 << 28), |
| BitValue = (1 << 29), |
| } |
| |
| /// Define types of [TransientObject](TransientObject) with predefined maximum sizes. |
| #[repr(u32)] |
| pub enum TransientObjectType { |
| /// 128, 192, or 256 bits |
| Aes = 0xA0000010, |
| /// Always 64 bits including the parity bits. This gives an effective key size of 56 bits |
| Des = 0xA0000011, |
| /// 128 or 192 bits including the parity bits. This gives effective key sizes of 112 or 168 bits |
| Des3 = 0xA0000013, |
| /// Between 64 and 512 bits, multiple of 8 bits |
| HmacMd5 = 0xA0000001, |
| /// Between 80 and 512 bits, multiple of 8 bits |
| HmacSha1 = 0xA0000002, |
| /// Between 112 and 512 bits, multiple of 8 bits |
| HmacSha224 = 0xA0000003, |
| /// Between 192 and 1024 bits, multiple of 8 bits |
| HmacSha256 = 0xA0000004, |
| /// Between 256 and 1024 bits, multiple of 8 bits |
| HmacSha384 = 0xA0000005, |
| /// Between 256 and 1024 bits, multiple of 8 bits |
| HmacSha512 = 0xA0000006, |
| /// The number of bits in the modulus. 256, 512, 768, 1024, 1536 and 2048 bit keys SHALL be supported. |
| /// Support for other key sizes including bigger key sizes is |
| /// implementation-dependent. Minimum key size is 256 bits |
| RsaPublicKey = 0xA0000030, |
| /// Same as [RsaPublicKey](TransientObjectType::RsaPublicKey) key size. |
| RsaKeypair = 0xA1000030, |
| /// Depends on Algorithm: |
| /// 1) [DsaSha1](../crypto_op/enum.AlgorithmId.html#variant.DsaSha1): |
| /// Between 512 and 1024 bits, multiple of 64 bits |
| /// 2) [DsaSha224](../crypto_op/enum.AlgorithmId.html#variant.DsaSha224): 2048 bits |
| /// 3) [DsaSha256](../crypto_op/enum.AlgorithmId.html#variant.DsaSha256): 2048 or 3072 bits |
| DsaPublicKey = 0xA0000031, |
| /// Same as [DsaPublicKey](TransientObjectType::DsaPublicKey) key size. |
| DsaKeypair = 0xA1000031, |
| /// From 256 to 2048 bits, multiple of 8 bits. |
| DhKeypair = 0xA1000032, |
| /// Between 160 and 521 bits. Conditional: Available only if at least |
| /// one of the ECC the curves defined in Table 6-14 with "generic" |
| /// equal to "Y" is supported. |
| EcdsaPublicKey = 0xA0000041, |
| /// Between 160 and 521 bits. Conditional: Available only if at least |
| /// one of the ECC curves defined in Table 6-14 with "generic" equal to |
| /// "Y" is supported. SHALL be same value as for ECDSA public key size. |
| EcdsaKeypair = 0xA1000041, |
| /// Between 160 and 521 bits. Conditional: Available only if at least |
| /// one of the ECC curves defined in Table 6-14 with "generic" equal to |
| /// "Y" is supported. |
| EcdhPublicKey = 0xA0000042, |
| /// Between 160 and 521 bits. Conditional: Available only if at least |
| /// one of the ECC curves defined in Table 6-14 with "generic" equal to |
| /// "Y" is supported. SHALL be same value as for ECDH public key size |
| EcdhKeypair = 0xA1000042, |
| /// 256 bits. Conditional: Available only if TEE_ECC_CURVE_25519 |
| /// defined in Table 6-14 is supported. |
| Ed25519PublicKey = 0xA0000043, |
| /// 256 bits. Conditional: Available only if TEE_ECC_CURVE_25519 |
| /// defined in Table 6-14 is supported. |
| Ed25519Keypair = 0xA1000043, |
| /// 256 bits. Conditional: Available only if TEE_ECC_CURVE_25519 |
| /// defined in Table 6-14 is supported. |
| X25519PublicKey = 0xA0000044, |
| /// 256 bits. Conditional: Available only if TEE_ECC_CURVE_25519 |
| /// defined in Table 6-14 is supported. |
| X25519Keypair = 0xA1000044, |
| /// Multiple of 8 bits, up to 4096 bits. This type is intended for secret |
| /// data that has been derived from a key derivation scheme. |
| GenericSecret = 0xA0000000, |
| /// Object is corrupted. |
| CorruptedObject = 0xA00000BE, |
| /// 0 – All data is in the associated data stream. |
| Data = 0xA00000BF, |
| } |
| |
| /// A trait for an object (trasient or persistent) to return its handle. |
| pub trait ObjHandle { |
| /// Return the handle of an object. |
| fn handle(&self) -> raw::TEE_ObjectHandle; |
| } |
| |
| /// An object containing attributes but no data stream, which is reclaimed |
| /// when closed or when the TA instance is destroyed. |
| /// Transient objects are used to hold a cryptographic object (key or key-pair). |
| /// |
| /// Contrast [PersistentObject](PersistentObject). |
| pub struct TransientObject(ObjectHandle); |
| |
| impl TransientObject { |
| /// Create a [TransientObject](TransientObject) with a null handle which points to nothing. |
| pub fn null_object() -> Self { |
| Self(ObjectHandle::from_raw(ptr::null_mut())) |
| } |
| |
| /// Allocate an uninitialized [TransientObject](TransientObject), i.e. a container for attributes. |
| /// |
| /// As allocated, the object is uninitialized. |
| /// It can be initialized by subsequently importing the object material, generating an object, |
| /// deriving an object, or loading an object from the Trusted Storage. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `object_type`: Type of uninitialized object container to be created as defined in |
| /// [TransientObjectType](TransientObjectType). |
| /// 2) `max_object_size`: Key Size of the object. Valid values depend on the object type and are |
| /// defined in [TransientObjectType](TransientObjectType). |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => |
| /// { |
| /// // ... |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `OutOfMemory`: If not enough resources are available to allocate the object handle. |
| /// 2) `NotSupported`: If the key size is not supported or the object type is not supported. |
| /// |
| /// # Panics |
| /// |
| /// 1) If the Implementation detects any error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn allocate(object_type: TransientObjectType, max_object_size: usize) -> Result<Self> { |
| let raw_handle: *mut raw::TEE_ObjectHandle = Box::into_raw(Box::new(ptr::null_mut())); |
| match unsafe { |
| raw::TEE_AllocateTransientObject(object_type as u32, max_object_size as u32, raw_handle) |
| } { |
| raw::TEE_SUCCESS => { |
| let handle = ObjectHandle::from_raw(raw_handle); |
| Ok(Self(handle)) |
| } |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| ///Reset a [TransientObject](TransientObject) to its initial state after allocation. |
| ///If the object is currently initialized, the function clears the object of all its material. |
| ///The object is then uninitialized again. |
| pub fn reset(&mut self) { |
| unsafe { |
| raw::TEE_ResetTransientObject(self.handle()); |
| } |
| } |
| |
| /// Populate an uninitialized object container with object attributes passed by the TA in the `attrs` parameter. |
| /// When this function is called, the object SHALL be uninitialized. |
| /// If the object is initialized, the caller SHALL first clear it using the function reset. |
| /// Note that if the object type is a key-pair, then this function sets both the private and public attributes of the keypair. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `attrs`: Array of object attributes. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => |
| /// { |
| /// let attrs = [AttributeMemref::from_ref(AttributeId::SecretValue, &[0u8;1])]; |
| /// object.populate(&attrs); |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `BadParameters`: If an incorrect or inconsistent attribute value is detected. In this case, |
| /// the content of the object SHALL remain uninitialized. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object that is transient and uninitialized. |
| /// 2) If some mandatory attribute is missing. |
| /// 3) If an attribute which is not defined for the object’s type is present in attrs. |
| /// 4) If an attribute value is too big to fit within the maximum object size specified when the object was created. |
| /// 5) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn populate(&mut self, attrs: &[Attribute]) -> Result<()> { |
| let p: Vec<raw::TEE_Attribute> = attrs.iter().map(|p| p.raw()).collect(); |
| match unsafe { |
| raw::TEE_PopulateTransientObject(self.0.handle(), p.as_ptr() as _, attrs.len() as u32) |
| } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => return Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Return the characteristics of an object. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => { |
| /// match object.info() { |
| /// Ok(info) => { |
| /// // ... |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn info(&self) -> Result<ObjectInfo> { |
| self.0.info() |
| } |
| |
| /// Restrict the object usage flags of an object handle to contain at most the flags passed in the obj_usage parameter. |
| /// |
| /// The initial value of the key usage contains all usage flags. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `obj_usage`: New object usage, an OR comination of one or more of the [UsageFlag](UsageFlag). |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => |
| /// { |
| /// object.restrict_usage(UsageFlag::ENCRYPT)?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()> { |
| self.0.restrict_usage(obj_usage) |
| } |
| |
| /// Extract one buffer attribute from an object. The attribute is identified by the argument id. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `id`: Identifier of the attribute to retrieve. |
| /// 2) `ref_attr`: Output buffer to get the content of the attribute. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => { |
| /// let mut attr = [0u8; 16]; |
| /// match object.ref_attribute(id, &mut attr) { |
| /// Ok(size) => { |
| /// // ... |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `ItemNotFound`: If the attribute is not found on this object. |
| /// 2) `ShortBuffer`: If buffer is NULL or too small to contain the key part. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the object is not initialized. |
| /// 3) If the Attribute is not a buffer attribute. |
| pub fn ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize> { |
| self.0.ref_attribute(id, buffer) |
| } |
| |
| /// Extract one value attribute from an object. The attribute is identified by the argument id. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `id`: Identifier of the attribute to retrieve. |
| /// 2) `value_attr`: Two value placeholders to get the content of the attribute. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => { |
| /// match object.value_attribute(id) { |
| /// Ok(a,b) => { |
| /// // ... |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `ItemNotFound`: If the attribute is not found on this object. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the object is not initialized. |
| /// 3) If the Attribute is not a value attribute. |
| pub fn value_attribute(&self, id: u32) -> Result<(u32, u32)> { |
| self.0.value_attribute(id) |
| } |
| |
| /// Populates an uninitialized object handle with the attributes of another object handle; |
| /// that is, it populates the attributes of this handle with the attributes of src_handle. |
| /// It is most useful in the following situations: |
| /// 1) To extract the public key attributes from a key-pair object. |
| /// 2) To copy the attributes from a [PersistentObject](PersistentObject) into a [TransientObject](TransientObject). |
| /// |
| /// # Parameters |
| /// |
| /// 1) `src_object`: Can be either a [TransientObject](TransientObject) or [PersistentObject](PersistentObject). |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object1) => |
| /// { |
| /// match TransientObject::allocate(TransientObjectType::Aes, 256) { |
| /// Ok(object2) => { |
| /// object1.copy_attribute_from(object2); |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `CorruptObject`: If the persistentd` object is corrupt. The object handle is closed. |
| /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If src_object is not initialized. |
| /// 2) If self is initialized. |
| /// 3) If the type and size of src_object and self are not compatible. |
| /// 4) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn copy_attribute_from<T: ObjHandle>(&mut self, src_object: &T) -> Result<()> { |
| match unsafe { raw::TEE_CopyObjectAttributes1(self.handle(), src_object.handle()) } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Generates a random key or a key-pair and populates a transient key object with the generated key material. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `key_size`: the size of the desired key. It SHALL be less than or equal to |
| /// the maximum key size specified when the [TransientObject](TransientObject) was created. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// match TransientObject::allocate(TransientObjectType::Aes, 128) { |
| /// Ok(object) => |
| /// { |
| /// object.generate_key(128, &[])?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `BadParameters`: If an incorrect or inconsistent attribute value is detected. In this |
| /// case, the content of the object SHALL remain uninitialized. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If some mandatory attribute is missing. |
| /// 3) If an attribute which is not defined for the object’s type is present in attrs. |
| /// 4) If an attribute value is too big to fit within the maximum object size specified when |
| /// the object was created. |
| /// 5) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn generate_key(&self, key_size: usize, params: &[Attribute]) -> Result<()> { |
| let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect(); |
| unsafe { |
| match raw::TEE_GenerateKey( |
| self.handle(), |
| key_size as u32, |
| p.as_slice().as_ptr() as _, |
| p.len() as u32, |
| ) { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| } |
| } |
| |
| impl ObjHandle for TransientObject { |
| fn handle(&self) -> raw::TEE_ObjectHandle { |
| self.0.handle() |
| } |
| } |
| |
| impl Drop for TransientObject { |
| /// Deallocates a [TransientObject](TransientObject) previously allocated. |
| /// After this function has been called, the object handle is no longer valid and all resources |
| /// associated with the [TransientObject](TransientObject) SHALL have been reclaimed. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| fn drop(&mut self) { |
| unsafe { |
| if self.0.raw != ptr::null_mut() { |
| raw::TEE_FreeTransientObject(self.0.handle()); |
| } |
| Box::from_raw(self.0.raw); |
| } |
| } |
| } |
| |
| /// An object identified by an Object Identifier and including a Data Stream. |
| /// |
| /// Contrast [TransientObject](TransientObject). |
| pub struct PersistentObject(ObjectHandle); |
| |
| impl PersistentObject { |
| /// Open an existing [PersistentObject](PersistentObject). |
| /// |
| /// # Parameters |
| /// |
| /// 1) `storage_id`: The storaget to use which is defined in |
| /// [ObjectStorageConstants](ObjectStorageConstants). |
| /// 2) `object_id`: The object identifier. Note that this buffer cannot reside in shared memory. |
| /// 3) `flags`: The [DataFlag](DataFlag) which determine the settings under which the object is opened. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_READ) { |
| /// Ok(object) => |
| /// { |
| /// // ... |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `ItemNotFound`: If the storage denoted by storage_id does not exist or if the object |
| /// identifier cannot be found in the storage. |
| /// 2) `Access_Conflict`: If an access right conflict was detected while opening the object. |
| /// 3) `OutOfMemory`: If there is not enough memory to complete the operation. |
| /// 4) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 5) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object_id.len() > |
| /// [MiscellaneousConstants::TeeObjectIdMaxLen](MiscellaneousConstants::TeeObjectIdMaxLen) |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn open( |
| storage_id: ObjectStorageConstants, |
| object_id: &[u8], |
| flags: DataFlag, |
| ) -> Result<Self> { |
| let raw_handle: *mut raw::TEE_ObjectHandle = Box::into_raw(Box::new(ptr::null_mut())); |
| match unsafe { |
| raw::TEE_OpenPersistentObject( |
| storage_id as u32, |
| object_id.as_ptr() as _, |
| object_id.len(), |
| flags.bits(), |
| raw_handle as *mut _, |
| ) |
| } { |
| raw::TEE_SUCCESS => { |
| let handle = ObjectHandle::from_raw(raw_handle); |
| Ok(Self(handle)) |
| } |
| code => { |
| unsafe { |
| Box::from_raw(raw_handle); |
| } |
| Err(Error::from_raw_error(code)) |
| } |
| } |
| } |
| |
| /// Create a [PersistentObject](PersistentObject) with initial attributes and an initial data stream content. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `storage_id`: The storaget to use which is defined in |
| /// [ObjectStorageConstants](ObjectStorageConstants). |
| /// 2) `object_id`: The object identifier. Note that this buffer cannot reside in shared memory. |
| /// 3) `flags`: The [DataFlag](DataFlag) which determine the settings under which the object is opened. |
| /// 4) `attributes`: A handle on a [PersistentObject](PersistentObject) or an initialized [TransientObject](TransientObject) |
| /// from which to take the [PersistentObject](PersistentObject) attributes. |
| /// Can be NONE if the [PersistentObject](PersistentObject) contains no attribute. |
| /// For example,if it is a pure data object. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// let mut init_data: [u8; 0] = [0; 0]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_READ | DataFlag::ACCESS_WRITE |
| /// None, |
| /// &mut init_data) { |
| /// Ok(object) => |
| /// { |
| /// // ... |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `ItemNotFound`: If the storage denoted by storage_id does not exist or if the object |
| /// identifier cannot be found in the storage. |
| /// 2) `Access_Conflict`: If an access right conflict was detected while opening the object. |
| /// 3) `OutOfMemory`: If there is not enough memory to complete the operation. |
| /// 4) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 5) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object_id.len() > |
| /// [MiscellaneousConstants::TeeObjectIdMaxLen](MiscellaneousConstants::TeeObjectIdMaxLen). |
| /// 2) If attributes is not NONE and is not a valid handle on an initialized object containing |
| /// the type and attributes of the [PersistentObject](PersistentObject) to create. |
| /// 3) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn create( |
| storage_id: ObjectStorageConstants, |
| object_id: &[u8], |
| flags: DataFlag, |
| attributes: Option<ObjectHandle>, |
| initial_data: &[u8], |
| ) -> Result<Self> { |
| let raw_handle: *mut raw::TEE_ObjectHandle = Box::into_raw(Box::new(ptr::null_mut())); |
| let attributes = match attributes { |
| Some(a) => a.handle(), |
| None => ptr::null_mut(), |
| }; |
| match unsafe { |
| raw::TEE_CreatePersistentObject( |
| storage_id as u32, |
| object_id.as_ptr() as _, |
| object_id.len(), |
| flags.bits(), |
| attributes, |
| initial_data.as_ptr() as _, |
| initial_data.len(), |
| raw_handle as *mut _, |
| ) |
| } { |
| raw::TEE_SUCCESS => { |
| let handle = ObjectHandle::from_raw(raw_handle); |
| Ok(Self(handle)) |
| } |
| code => { |
| unsafe { |
| Box::from_raw(raw_handle); |
| } |
| Err(Error::from_raw_error(code)) |
| } |
| } |
| } |
| |
| /// Marks an object for deletion and closes the object. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_READ) { |
| /// Ok(object) => |
| /// { |
| /// object.close_and_delete()?; |
| /// std::mem::forget(object); |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| // this function is conflicted with Drop implementation, when use this one to avoid panic: |
| // Call `mem::forget` for this structure to avoid double drop the object |
| pub fn close_and_delete(&mut self) -> Result<()> { |
| match unsafe { raw::TEE_CloseAndDeletePersistentObject1(self.0.handle()) } { |
| raw::TEE_SUCCESS => { |
| unsafe { |
| Box::from_raw(self.0.raw); |
| } |
| return Ok(()); |
| } |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Changes the identifier of an object. |
| /// 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. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// let new_obj_id = [2u8;1]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_WRITE_META) { |
| /// Ok(object) => |
| /// { |
| /// object.rename(&new_obj_id)?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `Access_Conflict`: If an access right conflict was detected while opening the object. |
| /// 2) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 3) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If new_object_id resides in shared memory. |
| /// 3) If new_object_id.len() > |
| /// [MiscellaneousConstants::TeeObjectIdMaxLen](MiscellaneousConstants::TeeObjectIdMaxLen). |
| /// 4) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn rename(&mut self, new_object_id: &[u8]) -> Result<()> { |
| match unsafe { |
| raw::TEE_RenamePersistentObject( |
| self.0.handle(), |
| new_object_id.as_ptr() as _, |
| new_object_id.len(), |
| ) |
| } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| /// Return the characteristics of an object. |
| /// Function is similar to [TransientObject::info](TransientObject::info) besides extra errors. |
| /// |
| /// # Errors |
| /// |
| /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| pub fn info(&self) -> Result<ObjectInfo> { |
| self.0.info() |
| } |
| |
| /// Restrict the object usage flags of an object handle to contain at most the flags passed in the obj_usage parameter. |
| /// Function is similar to [TransientObject::restrict_usage](TransientObject::restrict_usage) besides extra errors. |
| /// |
| /// # Errors |
| /// |
| /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| pub fn restrict_usage(&mut self, obj_usage: UsageFlag) -> Result<()> { |
| self.0.restrict_usage(obj_usage) |
| } |
| |
| /// Extract one buffer attribute from an object. The attribute is identified by the argument id. |
| /// Function is similar to [TransientObject::ref_attribute](TransientObject::ref_attribute) besides extra errors. |
| /// |
| /// # Errors |
| /// |
| /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| pub fn ref_attribute(&self, id: AttributeId, buffer: &mut [u8]) -> Result<usize> { |
| self.0.ref_attribute(id, buffer) |
| } |
| |
| /// Extract one value attribute from an object. The attribute is identified by the argument id. |
| /// Function is similar to [TransientObject::value_attribute](TransientObject::value_attribute) besides extra errors. |
| /// |
| /// # Errors |
| /// |
| /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| pub fn value_attribute(&self, id: u32) -> Result<(u32, u32)> { |
| self.0.value_attribute(id) |
| } |
| |
| /// Read requested size from the data stream assoicate with the object into the buffer. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `buffer`: A pre-allocated buffer for saving the object's data stream. |
| /// 2) `count`: The returned value contains the number of bytes read. |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_READ) { |
| /// Ok(object) => |
| /// { |
| /// let read_buf = [0u8;16]; |
| /// object.read(&mut read_buf)?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 2) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn read(&self, buf: &mut [u8]) -> Result<u32> { |
| let mut count: usize = 0; |
| match unsafe { |
| raw::TEE_ReadObjectData( |
| self.handle(), |
| buf.as_mut_ptr() as _, |
| buf.len(), |
| &mut count, |
| ) |
| } { |
| raw::TEE_SUCCESS => Ok(count as u32), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Write the passed in buffer data into from the data stream assoicate with the object. |
| /// |
| /// # Parameters |
| /// |
| /// 1) `buffer`: A pre-allocated buffer for saving the object's data stream. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_WRITE) { |
| /// Ok(object) => |
| /// { |
| /// let write_buf = [1u8;16]; |
| /// object.write(& write_buf)?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `StorageNoSpace`: If insufficient storage space is available. |
| /// 2) `Overflow`: If the value of the data position indicator resulting from this operation |
| /// would be greater than |
| /// [MiscellaneousConstants::TeeDataMaxPosition](MiscellaneousConstants::TeeDataMaxPosition). |
| /// 3) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 4) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn write(&mut self, buf: &[u8]) -> Result<()> { |
| match unsafe { |
| raw::TEE_WriteObjectData(self.handle(), buf.as_ptr() as _, buf.len()) |
| } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Change the size of a data stream associate with the object. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// match PersistentObject::open ( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_WRITE) { |
| /// Ok(object) => |
| /// { |
| /// object.truncate(1u32)?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `StorageNoSpace`: If insufficient storage space is available. |
| /// would be greater than |
| /// [MiscellaneousConstants::TeeDataMaxPosition](MiscellaneousConstants::TeeDataMaxPosition). |
| /// 2) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 3) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn truncate(&self, size: u32) -> Result<()> { |
| match unsafe { raw::TEE_TruncateObjectData(self.handle(), size as usize) } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Set the data position indicator associate with the object. |
| /// |
| /// # Parameters |
| /// 1) `whence`: Defined in [Whence](Whence). |
| /// 2) `offset`: The bytes shifted based on `whence`. |
| /// |
| /// # Example |
| /// |
| /// ```no_run |
| /// let obj_id = [1u8;1]; |
| /// match PersistentObject::open( |
| /// ObjectStorageConstants::Private, |
| /// &obj_id, |
| /// DataFlag::ACCESS_WRITE) { |
| /// Ok(object) => |
| /// { |
| /// object.seek(0i32, Whence::DataSeekSet)?; |
| /// Ok(()) |
| /// } |
| /// Err(e) => Err(e), |
| /// } |
| /// ``` |
| /// |
| /// # Errors |
| /// |
| /// 1) `Overflow`: If data position indicator is greater than |
| /// [MiscellaneousConstants::TeeDataMaxPosition](MiscellaneousConstants::TeeDataMaxPosition). |
| /// 2) `CorruptObject`: If the [PersistentObject](PersistentObject) is corrupt. The object handle is closed. |
| /// 3) `StorageNotAvailable`: If the [PersistentObject](PersistentObject) is stored in a storage area which is |
| /// currently inaccessible. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| pub fn seek(&self, offset: i32, whence: Whence) -> Result<()> { |
| match unsafe { raw::TEE_SeekObjectData(self.handle(), offset, whence.into()) } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| } |
| |
| impl ObjHandle for PersistentObject { |
| fn handle(&self) -> raw::TEE_ObjectHandle { |
| self.0.handle() |
| } |
| } |
| |
| impl Drop for PersistentObject { |
| /// Close an opened [PersistentObject](PersistentObject). |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error associated with this function which is not |
| /// explicitly associated with a defined return code for this function. |
| fn drop(&mut self) { |
| unsafe { |
| if self.0.raw != Box::into_raw(Box::new(ptr::null_mut())) { |
| raw::TEE_CloseObject(self.0.handle()); |
| } |
| Box::from_raw(self.0.raw); |
| } |
| } |
| } |
| |
| // The examples and detailed function explanation will be added after we test this struct and its |
| // functions. |
| /// An enumerator for [PersistentObject](PersistentObject)s. |
| pub struct ObjectEnumHandle { |
| raw: *mut raw::TEE_ObjectEnumHandle, |
| } |
| |
| impl ObjectEnumHandle { |
| /// Allocate an object enumerator. |
| /// Once an object enumerator has been allocated, it can be reused for multiple enumerations. |
| pub fn allocate() -> Result<Self> { |
| let raw_handle: *mut raw::TEE_ObjectEnumHandle = Box::into_raw(Box::new(ptr::null_mut())); |
| match unsafe { raw::TEE_AllocatePersistentObjectEnumerator(raw_handle) } { |
| raw::TEE_SUCCESS => Ok(Self { raw: raw_handle }), |
| code => { |
| unsafe { |
| Box::from_raw(raw_handle); |
| } |
| Err(Error::from_raw_error(code)) |
| } |
| } |
| } |
| |
| /// Reset an object enumerator handle to its initial state after allocation. |
| /// If an enumeration has been started, it is stopped. |
| pub fn reset(&mut self) { |
| unsafe { |
| raw::TEE_ResetPersistentObjectEnumerator(*self.raw); |
| } |
| } |
| |
| /// Start the enumeration of all the [PersistentObject](PersistentObject)s in a given Trusted Storage. |
| /// The object information can be retrieved by calling the function |
| /// [ObjectEnumHandle::get_next](ObjectEnumHandle::get_next) repeatedly. |
| pub fn start(&mut self, storage_id: u32) -> Result<()> { |
| match unsafe { raw::TEE_StartPersistentObjectEnumerator(*self.raw, storage_id) } { |
| raw::TEE_SUCCESS => Ok(()), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| |
| /// Get the next object in an enumeration and returns information about the object: type, size, identifier, etc. |
| pub fn get_next<T>( |
| &mut self, |
| object_info: &mut ObjectInfo, |
| object_id: &mut [u8], |
| ) -> Result<u32> { |
| let mut object_id_len: usize = 0; |
| match unsafe { |
| raw::TEE_GetNextPersistentObject( |
| *self.raw, |
| &mut object_info.raw, |
| object_id.as_mut_ptr() as _, |
| &mut object_id_len, |
| ) |
| } { |
| raw::TEE_SUCCESS => Ok(object_id_len as u32), |
| code => Err(Error::from_raw_error(code)), |
| } |
| } |
| } |
| |
| impl Drop for ObjectEnumHandle { |
| /// Deallocates all resources associated with an object enumerator handle. After this function is called, the handle is no longer valid. |
| /// |
| /// # Panics |
| /// |
| /// 1) If object is not a valid opened object. |
| /// 2) If the Implementation detects any other error. |
| fn drop(&mut self) { |
| unsafe { |
| raw::TEE_FreePersistentObjectEnumerator(*self.raw); |
| Box::from_raw(self.raw); |
| } |
| } |
| } |