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