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