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::{Attribute, Error, ObjHandle, Result, TransientObject};
19 use optee_utee_sys as raw;
20 use std::{mem, ptr};
21 
22 /// Specify one of the available cryptographic operations.
23 #[repr(u32)]
24 pub enum OperationMode {
25     /// Encryption mode
26     Encrypt = 0,
27     /// Decryption mode
28     Decrypt = 1,
29     /// Signature generation mode
30     Sign = 2,
31     /// Signature verfication mode
32     Verify = 3,
33     /// MAC mode
34     Mac = 4,
35     /// Digest mode
36     Digest = 5,
37     /// Key derivation mode
38     Derive = 6,
39     /// Reserve for testing and validation
40     IllegalValue = 0x7fffffff,
41 }
42 
43 /// Represent the information about a crypto information.
44 pub struct OperationInfo {
45     raw: raw::TEE_OperationInfo,
46 }
47 
48 impl OperationInfo {
49     /// Return the `OperationInfo` struct based on the raw struct `TEE_OperationInfo`.
50     ///
51     /// The raw structure contains following fields:
52     ///
53     /// 1) `algorithm`: One of the algorithm of [AlgorithmId](AlgorithmId).
54     /// 2) `mode`: One of the mode of [OperationMode](OperationMode).
55     /// 3) `maxKeySize`: The maximum key sizes of different algorithms as defined in
56     /// [TransientObjectType](../object/enum.TransientObjectType.html).
57     /// 4) `operationClass`: One of the constants from [OperationConstant](OperationConstant).
58     /// 5) `keySize`:
59     /// 5.1) For an operation that makes no use of keys, 0.
60     /// 5.2) For an operation that uses a single key, the actual size of this key.
61     /// 5.3) For an operation that uses multiple keys, 0. (The actual value of `keySize` can be obtained from
62     /// [OperationInfoMultiple](OperationInfoMultiple)).
63     /// 6) `requiredKeyUsage`:
64     /// 6.1) For an operation that makes no use of keys, 0.
65     /// 6.2) For an operation that uses a single key, a bit vector that describes the necessary bits in the object
66     /// usage for `set_key` functions to succeed without panicking.
67     /// 6.3) For an operation that uses multiple keys, 0. (The actual value of `requiredKeyUsage` can be obtained from
68     /// [OperationInfoMultiple](OperationInfoMultiple).
69     /// 7) `digestLength`: For a [Mac](Mac), [AE](AE), or [Digest](Digest), describes the number of bytes in the digest or tag.
70     /// 8) `handleState`: A bit vector describing the current state of the operation. Contains one or more of the
71     /// [HandleFlag](../object/struct.HandleFlag.html).
from_raw(raw: raw::TEE_OperationInfo) -> Self72     pub fn from_raw(raw: raw::TEE_OperationInfo) -> Self {
73         Self { raw }
74     }
75 
76     /// Return the `keySize` field of the raw structure `TEE_OperationInfo`.
key_size(&self) -> u3277     pub fn key_size(&self) -> u32 {
78         self.raw.keySize
79     }
80 
81     /// Return the `maxDataSize` field of the raw structure `TEE_OperationInfo`.
max_key_size(&self) -> u3282     pub fn max_key_size(&self) -> u32 {
83         self.raw.maxKeySize
84     }
85 }
86 
87 /// Every operation of [AE](AE), [Asymmetric](Asymmetric), [Cipher](Cipher),
88 /// [DeriveKey](DeriveKey), [Digest](Digest), [Mac](Mac) can be either one of the two states.
89 #[repr(u32)]
90 pub enum OperationStates {
91     /// Nothing is going on.
92     Initial = 0x00000000,
93     /// An operation is in progress.
94     Active = 0x00000001,
95 }
96 
97 /// Define the supported crypto operation.
98 pub enum OperationConstant {
99     /// [Cipher](Cipher)
100     Cipher = 1,
101     /// [Mac](Mac)
102     Mac = 3,
103     /// [AE](AE)
104     Ae = 4,
105     /// [Digest](Digest)
106     Digest = 5,
107     /// [Asymmetric](Asymmetric)
108     AsymmetricCipher = 6,
109     /// [Asymmetric](Asymmetric)
110     AsymmetricSignature = 7,
111     /// [DeriveKey](DeriveKey)
112     KeyDerivation = 8,
113 }
114 
115 /// Represent the information about a crypto information which uses multiple keys.
116 pub struct OperationInfoMultiple {
117     raw: *mut raw::TEE_OperationInfoMultiple,
118     size: usize,
119 }
120 
121 impl OperationInfoMultiple {
122     /// Return the `OperationInfoMultiple` struct based on the raw struct `TEE_OperationInfo`.
123     ///
124     /// The raw structure contains following fields:
125     ///
126     /// 1) `algorithm`: One of the algorithm of [AlgorithmId](AlgorithmId).
127     /// 2) `mode`: One of the mode of [OperationMode](OperationMode).
128     /// 3) `maxKeySize`: The maximum key sizes of different algorithms as defined in
129     /// [TransientObjectType](../object/enum.TransientObjectType.html).
130     /// 4) `operationClass`: One of the constants from [OperationConstant](OperationConstant).
131     /// 5) `digestLength`: For a [Mac](Mac), [AE](AE), or [Digest](Digest), describes the number of bytes in the digest or tag.
132     /// 6) `handleState`: A bit vector describing the current state of the operation. Contains one or more of the [HandleFlag](../object/struct.HandleFlag.html).
133     /// 7) `operationState`: Every operation has two states which are defined as
134     ///    [OperationStates](OperationStates).
135     /// 8) `numberOfKeys`: This is set to the number of keys required by this operation. May be 0 for an operation which requires no keys.
136     /// 9) `keyInformation`: This array contains numberOfKeys entries, each of which defines the details for one key used by the operation,
137     /// in the order they are defined.
138     /// If the buffer is larger than required to support `numberOfKeys` entries, the additional space is not initialized or modified.
139     /// For each element:
140     /// 9.1) `keySize`: If a key is programmed in the operation, the actual size of this key, otherwise 0.
141     /// 9.2) `requiredKeyUsage`: A bit vector that describes the necessary bits in the object usage for `set_key` or `set_key_2` to succeed without panicking.
from_raw(raw: *mut raw::TEE_OperationInfoMultiple, size: usize) -> Self142     pub fn from_raw(raw: *mut raw::TEE_OperationInfoMultiple, size: usize) -> Self {
143         Self { raw, size }
144     }
145 
146     /// Return the raw struct `TEE_OperationInfoMultiple`.
raw(&self) -> *mut raw::TEE_OperationInfoMultiple147     pub fn raw(&self) -> *mut raw::TEE_OperationInfoMultiple {
148         self.raw
149     }
150 
151     /// Return the `size` field of the raw structure `TEE_OperationInfoMultiple`.
size(&self) -> usize152     pub fn size(&self) -> usize {
153         self.size
154     }
155 }
156 
157 /// An opaque reference that identifies a particular cryptographic operation.
158 pub struct OperationHandle {
159     raw: *mut raw::TEE_OperationHandle,
160 }
161 
162 impl OperationHandle {
from_raw(raw: *mut raw::TEE_OperationHandle) -> OperationHandle163     fn from_raw(raw: *mut raw::TEE_OperationHandle) -> OperationHandle {
164         Self { raw }
165     }
166 
handle(&self) -> raw::TEE_OperationHandle167     fn handle(&self) -> raw::TEE_OperationHandle {
168         unsafe { *(self.raw) }
169     }
170 
null() -> Self171     fn null() -> Self {
172         OperationHandle::from_raw(ptr::null_mut())
173     }
174 
allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self>175     fn allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self> {
176         let raw_handle: *mut raw::TEE_OperationHandle = Box::into_raw(Box::new(ptr::null_mut()));
177         match unsafe {
178             raw::TEE_AllocateOperation(
179                 raw_handle as *mut _,
180                 algo as u32,
181                 mode as u32,
182                 max_key_size as u32,
183             )
184         } {
185             raw::TEE_SUCCESS => Ok(Self::from_raw(raw_handle)),
186             code => Err(Error::from_raw_error(code)),
187         }
188     }
189 
info(&self) -> OperationInfo190     fn info(&self) -> OperationInfo {
191         let mut raw_info: raw::TEE_OperationInfo = unsafe { mem::zeroed() };
192         unsafe { raw::TEE_GetOperationInfo(self.handle(), &mut raw_info) };
193         OperationInfo::from_raw(raw_info)
194     }
195 
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>196     fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
197         let mut tmp_size: u32 = 0;
198         match unsafe {
199             raw::TEE_GetOperationInfoMultiple(self.handle(), info_buf.as_ptr() as _, &mut tmp_size)
200         } {
201             raw::TEE_SUCCESS => Ok(OperationInfoMultiple::from_raw(
202                 info_buf.as_ptr() as _,
203                 tmp_size as usize,
204             )),
205             code => Err(Error::from_raw_error(code)),
206         }
207     }
208 
reset(&mut self)209     fn reset(&mut self) {
210         unsafe {
211             raw::TEE_ResetOperation(self.handle());
212         }
213     }
214 
set_key<T: ObjHandle>(&self, object: &T) -> Result<()>215     fn set_key<T: ObjHandle>(&self, object: &T) -> Result<()> {
216         match unsafe { raw::TEE_SetOperationKey(self.handle(), object.handle()) } {
217             raw::TEE_SUCCESS => return Ok(()),
218             code => Err(Error::from_raw_error(code)),
219         }
220     }
221 
copy<T: OpHandle>(&mut self, src: &T)222     fn copy<T: OpHandle>(&mut self, src: &T) {
223         unsafe {
224             raw::TEE_CopyOperation(self.handle(), src.handle());
225         }
226     }
227 }
228 
229 /// determine whether a combination of algId and element is supported
is_algorithm_supported(alg_id: u32, element: u32) -> Result<()>230 pub fn is_algorithm_supported(alg_id: u32, element: u32) -> Result<()> {
231     match unsafe { raw::TEE_IsAlgorithmSupported(alg_id, element) } {
232         raw::TEE_SUCCESS => Ok(()),
233         code => Err(Error::from_raw_error(code)),
234     }
235 }
236 
237 // free before check it's not null
238 /// Deallocate all resources associated with an operation handle. After this function is called,
239 /// the operation handle is no longer valid. All cryptographic material in the operation is destroyed.
240 impl Drop for OperationHandle {
drop(&mut self)241     fn drop(&mut self) {
242         unsafe {
243             if self.raw != ptr::null_mut() {
244                 raw::TEE_FreeOperation(self.handle());
245             }
246             Box::from_raw(self.raw);
247         }
248     }
249 }
250 
251 /// A trait for a crypto operation to return its handle.
252 pub trait OpHandle {
253     /// Return the handle of an operation.
handle(&self) -> raw::TEE_OperationHandle254     fn handle(&self) -> raw::TEE_OperationHandle;
255 }
256 
257 /// An operation for digest the message.
258 pub struct Digest(OperationHandle);
259 
260 impl Digest {
261     /// Accumulate message data for hashing. The message does not have to be block aligned.
262     /// Subsequent calls to this function are possible. The operation may be in either
263     /// initial or active state and becomes active.
264     ///
265     /// # Parameters
266     ///
267     /// 1) `chunk`: Chunk of data to be hashed
268     ///
269     /// # Panics
270     ///
271     /// 1) If the operation is not allocated with valid algorithms.
272     /// 2) if input data exceeds maximum length for algorithm.
273     /// 3) Hardware or cryptographic algorithm failure.
274     /// 4) If the Implementation detects any other error.
update(&self, chunk: &[u8])275     pub fn update(&self, chunk: &[u8]) {
276         unsafe {
277             raw::TEE_DigestUpdate(self.handle(), chunk.as_ptr() as _, chunk.len() as u32);
278         }
279     }
280 
281     /// Finalize the message digest operation and produces the message hash. Afterwards the
282     /// Message Digest operation is reset to initial state and can be reused.
283     ///
284     /// # Parameters
285     ///
286     /// 1) `chunk`: Last chunk of data to be hashed.
287     /// 2) `hash`: Output buffer filled with the message hash. This buffer should be large enough to
288     ///    hold the hash message. The real used size is returned by this function.
289     ///
290     /// # Example
291     ///
292     /// ```no_run
293     /// let chunk = [0u8;8];
294     /// let chunk = [1u8;8];
295     /// let hash = [0u8;32];
296     /// match Digest::allocate(AlgorithmId::Sha256) {
297     ///     Ok(operation) =>
298     ///     {
299     ///         operation.update(&chunk1);
300     ///         match operation.do_final(&chunk2, hash) {
301     ///             Ok(hash_len) => {
302     ///                 // ...
303     ///                 Ok(())
304     ///             }
305     ///             Err(e) => Err(e),
306     ///         }
307     ///     }
308     ///     Err(e) => Err(e),
309     /// }
310     /// ```
311     ///
312     /// # Errors
313     ///
314     /// 1) `ShortBuffer`: If the `hash` is too small. Operation is not finalized for this error.
315     ///
316     /// # Panics
317     /// 1) If the operation is not allocated with valid algorithms.
318     /// 2) if input data exceeds maximum length for algorithm.
319     /// 3) Hardware or cryptographic algorithm failure.
320     /// 4) If the Implementation detects any other error.
321     //hash size is dynamic changed so we returned it's updated size
do_final(&self, chunk: &[u8], hash: &mut [u8]) -> Result<usize>322     pub fn do_final(&self, chunk: &[u8], hash: &mut [u8]) -> Result<usize> {
323         let mut hash_size: u32 = hash.len() as u32;
324         match unsafe {
325             raw::TEE_DigestDoFinal(
326                 self.handle(),
327                 chunk.as_ptr() as _,
328                 chunk.len() as u32,
329                 hash.as_mut_ptr() as _,
330                 &mut hash_size,
331             )
332         } {
333             raw::TEE_SUCCESS => return Ok(hash_size as usize),
334             code => Err(Error::from_raw_error(code)),
335         }
336     }
337 
338     /// Create a Digest operation without any specific algorithm or other data.
null() -> Self339     pub fn null() -> Self {
340         Self(OperationHandle::null())
341     }
342 
343     /// Allocate a new cryptographic operation and sets the mode and algorithm type.
344     ///
345     /// # Parameters
346     ///
347     /// 1) `algo`: One of the algorithms that support Digest as listed in
348     ///    [AlgorithmId](AlgorithmId).
349     /// 2) `max_key_size`: The maximum key sizes of different algorithms as defined in
350     ///    [TransientObjectType](../object/enum.TransientObjectType.html).
351     ///
352     /// # Example
353     ///
354     /// ```no_run
355     /// match Digest::allocate(AlgorithmId::Sha256) {
356     ///     Ok(operation) =>
357     ///     {
358     ///         // ...
359     ///         Ok(())
360     ///     }
361     ///     Err(e) => Err(e),
362     /// }
363     /// ```
364     ///
365     /// # Errors
366     ///
367     /// 1) `OutOfMemory`: If not enough resources are available to allocate the object handle.
368     /// 2) `NotSupported`: If the key size is not supported or the object type is not supported.
369     ///
370     /// # Panics
371     ///
372     /// 1) If the Implementation detects any error associated with this function which is not
373     /// explicitly associated with a defined return code for this function.
allocate(algo: AlgorithmId) -> Result<Self>374     pub fn allocate(algo: AlgorithmId) -> Result<Self> {
375         match OperationHandle::allocate(algo, OperationMode::Digest, 0) {
376             Ok(handle) => Ok(Self(handle)),
377             Err(e) => Err(e),
378         }
379     }
380 
381     /// Return the characteristics of a Digest operation.
382     ///
383     /// # Example
384     ///
385     /// ```no_run
386     /// match Digest::allocate(AlgorithmId::Md5, 128) {
387     ///     Ok(operation) =>
388     ///     {
389     ///         let info = operation.info();
390     ///         Ok(())
391     ///     }
392     ///     Err(e) => Err(e),
393     /// }
394     /// ```
395     ///
396     /// # Panics
397     /// 1) If the operation is not a valid opened operation.
398     /// 2) if the Implementation detecs any other error.
info(&self) -> OperationInfo399     pub fn info(&self) -> OperationInfo {
400         self.0.info()
401     }
402 
403     /// Return the characteristics of a Digest operation with multiple keys.
404     ///
405     /// # Parameters
406     ///
407     /// 1) `info_buf`: The buffer is supposed to save multiple keys, and its size should be large enough before passed in.
408     /// The number of keys about this operation can be calculated as: OperationInfoMultiple::size -
409     /// size_of([OperationInfoMultiple](OperationInfoMultiple)) / size_of ( raw::TEE_OperationInfoKey)+1.
410     ///
411     /// # Example
412     ///
413     /// ```no_run
414     /// match Digest::allocate(AlgorithmId::Md5, 128) {
415     ///     Ok(operation) =>
416     ///     {
417     ///         let mut buffer = [0u32, 12];
418     ///         match operation.info_multiple(&mut buffer) {
419     ///             Ok(info_multiple) => {
420     ///                 // ...
421     ///                 Ok(())
422     ///             }
423     ///             Err(e) => Err(e),
424     ///         }
425     ///     }
426     ///     Err(e) => Err(e),
427     /// }
428     /// ```
429     ///
430     /// # Errors:
431     ///
432     /// 1) `ShortBuffer`: If the `info_buf` is not large enough to hold an
433     ///    [OperationInfoMultiple](OperationInfoMultiple) and the corresponding keys.
434     ///
435     /// # Panics:
436     ///
437     /// 1) If operation is not a valid opened object.
438     /// 2) If the Implementation detects any other error.
439     // Here the multiple info total size is not sure
440     // Passed in array is supposed to provide enough size for this struct
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>441     pub fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
442         self.0.info_multiple(info_buf)
443     }
444 
445     /// Reset the operation state to the state after initial [allocate](Digest::allocate) with the
446     /// add addition of any keys which were configured subsequent to this so that current operation
447     /// can be reused with the same keys.
448     ///
449     /// # Panics
450     ///
451     /// 1) If operation is not a valid opened object.
452     /// 2) If the key has not been set yet.
453     /// 3) Hardware or cryptographic algorithm failure.
454     /// 4) If the Implementation detects any other error.
reset(&mut self)455     pub fn reset(&mut self) {
456         self.0.reset()
457     }
458 
459     /// Copy an operation state to another operation. This also copies the key material associated
460     /// with the source operation.
461     ///
462     /// # Parameters
463     ///
464     /// 1) `src`: the source operation.
465     /// 1.1) If `src` has no key programmed, then the key of this operation is cleared. If there is a key
466     /// programmed in srcOperation, then the maximum key size of current SHALL be greater than or
467     /// equal to the actual key size of src.
468     ///
469     /// # Example
470     ///
471     /// ```no_run
472     /// match Digest::allocate(AlgorithmId::Sha256) {
473     ///     Ok(operation) =>
474     ///     {
475     ///         match Digest::allocate(AlgorithmId::Sha256) {
476     ///             Ok(operation2) =>
477     ///             {
478     ///                 // ...
479     ///                 operation.copy(operation2);
480     ///                 Ok(())
481     ///             }
482     ///             Err(e) => Err(e),
483     ///         }
484     ///     }
485     ///     Err(e) => Err(e),
486     /// }
487     /// ```
488     ///
489     /// # Panics
490     ///
491     /// 1) If the operation or source operation is not a valid opened operation.
492     /// 2) If the alogirhtm or mode differe in two perations.
493     /// 3) If `src` has akey and its size is greater than the maximum key size of the operation.
494     /// 4) Hardware or cryptographic algorithm failure.
495     /// 5) If the Implementation detects any other error.
copy<T: OpHandle>(&mut self, src: &T)496     pub fn copy<T: OpHandle>(&mut self, src: &T) {
497         self.0.copy(src)
498     }
499 }
500 
501 impl OpHandle for Digest {
handle(&self) -> raw::TEE_OperationHandle502     fn handle(&self) -> raw::TEE_OperationHandle {
503         self.0.handle()
504     }
505 }
506 
507 /// An operation for conducting symmetric cipher encryption / decryption.
508 /// This operation defines the way to perform symmetric cipher operations, such as AES.
509 /// They cover both block ciphers and stream ciphers.
510 pub struct Cipher(OperationHandle);
511 
512 impl Cipher {
513     /// Start the symmetric cipher operation. The function should be called after the
514     /// [set_key](Cipher::set_key) or [set_key_2](Cipher::set_key_2).
515     ///
516     /// After called, if the operation is in active state, it is reset and then initialized.
517     /// If the operation is in initial state, it is moved to active state.
518     ///
519     /// # Parameters
520     ///
521     /// 1) `iv`: buffer contains the operation Initialization Vector, which is used for:
522     /// 1.1) [AesCbcNopad](AlgorithmId::AesCbcNopad): IV;
523     /// 1.2) [AesCtr](AlgorithmId::AesCtr): Initial Counter Value;
524     /// 1.3) [AesCts](AlgorithmId::AesCts): IV;
525     /// 1.4) [AesXts](AlgorithmId::AesXts): Tweak Value;
526     /// 1.5) [AesCcm](AlgorithmId::AesCcm): Nonce Value;
527     /// 1.6) [AesGcm](AlgorithmId::AesGcm): Nonce Value;
528     /// 1.7) [AesCbcNopad](AlgorithmId::AesCbcNopad): IV.
529     ///
530     /// # Panics
531     ///
532     /// 1) If the algorithm is not a valid algorithm for `Cipher`.
533     /// 2) If no key is programmed in the operation.
534     /// 3) If the IV does not have the length required by the algorithm.
535     /// 4) Hardware or cryptographic algorithm failure.
536     /// 5) If the Implementation detects any other error.
init(&self, iv: &[u8])537     pub fn init(&self, iv: &[u8]) {
538         unsafe { raw::TEE_CipherInit(self.handle(), iv.as_ptr() as _, iv.len() as u32) };
539     }
540 
541     /// Encrypt or decrypt the source data.
542     ///
543     /// Input data does not have to be a multiple of block size. Subsequent calls to this function are possible.
544     /// Unless one or more calls of this function have supplied sufficient input data, no output is generated.
545     /// The function should be called after the [init](Cipher::init).
546     ///
547     /// # Parameters
548     ///
549     /// 1) `src`: Input data buffer to be encrypted or decrypted.
550     /// 2) `dest`: Output buffer.
551     ///
552     /// # Example
553     ///
554     /// ```no_run
555     /// let iv = [0u8, 16];
556     /// let key = [0u8, 16];
557     /// let src = [1u8; 4096];
558     /// let mut dest = [0u8; 4096];
559     /// match Cipher::allocate(AlgorithmId::AesCtr, 128) {
560     ///     Ok(operation) =>
561     ///     {
562     ///         match TransientObject::allocate(TransientObjectType::Aes, 128) {
563     ///             Ok(object) =>
564     ///             {
565     ///                 let attr = AttributeMemref::from_ref(AttributeId::SecretValue, &key);
566     ///                 object.populate(&[attr.into()])?;
567     ///                 operation.set_key(&object)?;
568     ///                 operation.init(&iv);
569     ///                 operation.update(&src, &mut dest)?;
570     ///                 Ok(())
571     ///             }
572     ///             Err(e) => Err(e),
573     ///         }
574     ///     }
575     ///     Err(e) => Err(e),
576     /// }
577     /// ```
578     ///
579     /// # Errors
580     ///
581     /// 1) `ShortBuffer`: If the output buffer is not large enough to contain the output.
582     /// In this case, the input is not fed into the algorithm.
583     ///
584     /// # Panics
585     ///
586     /// 1) If the algorithm is not a valid algorithm for `Cipher`.
587     /// 2) If the function is called before [init](Cipher::init) or after
588     ///    [do_final](Cipher::do_final).
589     /// 3) Hardware or cryptographic algorithm failure.
590     /// 4) If the Implementation detects any other error.
update(&self, src: &[u8], dest: &mut [u8]) -> Result<usize>591     pub fn update(&self, src: &[u8], dest: &mut [u8]) -> Result<usize> {
592         let mut dest_size: u32 = dest.len() as u32;
593         match unsafe {
594             raw::TEE_CipherUpdate(
595                 self.handle(),
596                 src.as_ptr() as _,
597                 src.len() as u32,
598                 dest.as_mut_ptr() as _,
599                 &mut dest_size,
600             )
601         } {
602             raw::TEE_SUCCESS => {
603                 return Ok(dest_size as usize);
604             }
605             code => Err(Error::from_raw_error(code)),
606         }
607     }
608 
609     /// Finalize the cipher operation, processing data that has not been processed by previous calls
610     /// to [update](Cipher::update) as well as data supplied in `src`. The operation handle can be reused or re-initialized.
611     ///
612     /// # Parameters
613     ///
614     /// 1) `src`: Input data buffer to be encrypted or decrypted.
615     /// 2) `dest`: Output buffer.
616     ///
617     /// # Errors
618     ///
619     /// 1) `ShortBuffer`: If the output buffer is not large enough to contain the output.
620     ///
621     /// # Panics
622     ///
623     /// 1) If the algorithm is not a valid algorithm for `Cipher`.
624     /// 2) If the function is called before [init](Cipher::init).
625     /// 3) Hardware or cryptographic algorithm failure.
626     /// 4) If the Implementation detects any other error.
do_final(&self, src: &[u8], dest: &mut [u8]) -> Result<usize>627     pub fn do_final(&self, src: &[u8], dest: &mut [u8]) -> Result<usize> {
628         let mut dest_size: u32 = dest.len() as u32;
629         match unsafe {
630             raw::TEE_CipherDoFinal(
631                 self.handle(),
632                 src.as_ptr() as _,
633                 src.len() as u32,
634                 dest.as_mut_ptr() as _,
635                 &mut dest_size,
636             )
637         } {
638             raw::TEE_SUCCESS => return Ok(dest_size as usize),
639             code => Err(Error::from_raw_error(code)),
640         }
641     }
642 
643     /// Create a Cipher operation without any specific algorithm or other data.
null() -> Self644     pub fn null() -> Self {
645         Self(OperationHandle::null())
646     }
647 
648     /// Function usage is similar to [Digest::allocate](Digest::allocate).
allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self>649     pub fn allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self> {
650         match OperationHandle::allocate(algo, mode, max_key_size) {
651             Ok(handle) => Ok(Self(handle)),
652             Err(e) => Err(e),
653         }
654     }
655 
656     /// Function usage is similar to [Digest::info](Digest::info).
info(&self) -> OperationInfo657     pub fn info(&self) -> OperationInfo {
658         self.0.info()
659     }
660 
661     /// Function usage is similar to [Digest::info_multiple](Digest::info_multiple).
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>662     pub fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
663         self.0.info_multiple(info_buf)
664     }
665 
666     /// Program the key of Digest operation. That ids, it associates the operation with a key.
667     ///
668     /// # Parameters
669     ///
670     /// 1) `object`: The object can either be a [Transient](../object/struct.TransientObject.html)
671     ///    or [Persistent](../object/struct.PersistentObject.html). The key material is copied from
672     ///    the key object handle into the operation. After the key has been set, there is no longer
673     ///    any link between the operation and the key object. The object handle can be closed or reset
674     ///    and this will not affect the operation. This copied material exists until the operation is
675     ///    freed or another key is set into the operation.
676     ///
677     /// # Errors
678     ///
679     /// 1) `CorruptObject`: If the object is corrupt. The object handle is closed.
680     /// 2) `StorageNotAvailable`: If the object is stored in a storage area which is
681     ///    currently inaccessible.
682     ///
683     /// # Panics
684     ///
685     /// 1) If operation is not a valid opened object.
686     /// 2) If object is not null and is not a valid key object.
687     /// 3) If object is not initialized.
688     /// 4) If the operation expect two keys as [AesXts](AlgorithmId::AesXts).
689     /// 5) If the type, size, or usage of object is not compatible with the algorithm, mode, or size of the operation.
690     /// 6) If operation is not in initial state.
691     /// 7) Hardware or cryptographic algorithm failure.
692     /// 8) If the Implementation detects any other error.
set_key<T: ObjHandle>(&self, object: &T) -> Result<()>693     pub fn set_key<T: ObjHandle>(&self, object: &T) -> Result<()> {
694         self.0.set_key(object)
695     }
696 
697     /// Initialize an expisting operation with two keys for [AesXts](AlgorithmId::AesXts).
698     ///
699     /// # Parameters:
700     ///
701     /// object1 and object2 SHALL both be non-NULL or both NULL. object1 and object2 SHALL NOT refer to keys with
702     /// bitwise identical [SecretValue](../object/enum.AttributeId.html#variant.SecretValue) attributes.
703     ///
704     /// # Errors
705     ///
706     /// 1) `CorruptObject`: If the object1 is corrupt. The object handle is closed.
707     /// 2) `CorruptObject2`: If the object2 is corrupt. The object handle is closed.
708     /// 3) `StorageNotAvailable`: If the object1 is stored in a storage area which is
709     ///    currently inaccessible.
710     /// 4) `StorageNotAvailable2`: If the object2 is stored in a storage area which is
711     ///    currently inaccessible.
712     ///
713     /// # Panics
714     ///
715     /// 1) If operation is not a valid opened object.
716     /// 2) If object1 and object2 are not both null and object1 or object2 or both are not a valid key object.
717     /// 3) If object1 or object2 is not initialized.
718     /// 4) If the operation algorithm is not [AesXts](AlgorithmId::AesXts).
719     /// 5) If the type, size, or usage of any object is not compatible with the algorithm, mode, or size of the operation.
720     /// 6) If operation is not in initial state.
721     /// 7) Hardware or cryptographic algorithm failure.
722     /// 8) If the Implementation detects any other error.
set_key_2<T: ObjHandle, D: ObjHandle>(&self, object1: &T, object2: &D) -> Result<()>723     pub fn set_key_2<T: ObjHandle, D: ObjHandle>(&self, object1: &T, object2: &D) -> Result<()> {
724         match unsafe {
725             raw::TEE_SetOperationKey2(self.handle(), object1.handle(), object2.handle())
726         } {
727             raw::TEE_SUCCESS => return Ok(()),
728             code => Err(Error::from_raw_error(code)),
729         }
730     }
731 
732     /// Function usage is similar to [Digest::copy](Digest::copy).
copy<T: OpHandle>(&mut self, src: &T)733     pub fn copy<T: OpHandle>(&mut self, src: &T) {
734         self.0.copy(src)
735     }
736 }
737 
738 impl OpHandle for Cipher {
handle(&self) -> raw::TEE_OperationHandle739     fn handle(&self) -> raw::TEE_OperationHandle {
740         self.0.handle()
741     }
742 }
743 
744 /// An operation for performing MAC (Message Authentication Code) operations, such as `HMAC`
745 /// or `AES-CMAC` operations. This operation is not used for Authenticated Encryption algorithms,
746 /// which SHALL use the functions defined in [AE](AE).
747 pub struct Mac(OperationHandle);
748 
749 impl Mac {
750     /// Initialize a MAC opeartion. The The function should be called after the
751     /// [set_key](Mac::set_key).
752     ///
753     /// # Parameters
754     ///
755     /// 1) `iv`: Input buffer containing the operation Initialization Vector, if applicable
756     ///
757     /// # Panics
758     ///
759     /// 1) If the algorithm is not a valid algorithm for `Mac`.
760     /// 2) If no key is programmed in the operation.
761     /// 3) If the Initialization Vector does not have the length required by the algorithm.
762     /// 4) Hardware or cryptographic algorithm failure.
763     /// 5) If the Implementation detects any other error.
init(&self, iv: &[u8])764     pub fn init(&self, iv: &[u8]) {
765         unsafe { raw::TEE_MACInit(self.handle(), iv.as_ptr() as _, iv.len() as u32) };
766     }
767 
768     /// Accumulate data for a MAC calculation.
769     ///
770     /// Input data does not have to be a multiple of block size. Subsequent calls to this function are possible.
771     /// Unless one or more calls of this function have supplied sufficient input data, no output is generated.
772     /// The function should be called after the [init](Mac::init).
773     ///
774     /// # Parameters
775     ///
776     /// 1) `chunk`: Chunk of the message to be MACed.
777     ///
778     /// # Panics
779     ///
780     /// 1) If the algorithm is not a valid algorithm for `Mac`.
781     /// 2) If the function is called before [init](Mac::init) or after
782     ///    [compute_final](Mac::compute_final) or after [compare_final](Mac::compare_final).
783     /// 3) If `chunk` excceds maximum length for algorithm.
784     /// 4) Hardware or cryptographic algorithm failure.
785     /// 5) If the Implementation detects any other error.
update(&self, chunk: &[u8])786     pub fn update(&self, chunk: &[u8]) {
787         unsafe { raw::TEE_MACUpdate(self.handle(), chunk.as_ptr() as _, chunk.len() as u32) };
788     }
789     /// Finalize the MAC operation with a last chunk of message, and computes the MAC.
790     /// Afterwards the operation handle can be reused or re-initialized with a new key.
791     /// The operation SHALL be in active state and moves to initial state afterwards.
792     ///
793     /// # Parameters:
794     ///
795     /// `message`: Input buffer containing a last message chunk to MAC
796     /// `mac`: Output buffer filled with the computed MAC, the size should be allocated enough for
797     /// containing the whole computed MAC
798     ///
799     /// # Example
800     ///
801     /// ```no_run
802     /// let mut key: [u8; 20] = [
803     /// 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
804     /// 0x36, 0x37, 0x38, 0x39, 0x30,];
805     /// let mut out: [u8; 20] = [0u8; 20];
806     /// match Mac::allocate(AlgorithmId::HmacSha1, key.len() * 8) {
807     ///     Err(e) => return Err(e),
808     ///     Ok(mac) => {
809     ///         match TransientObject::allocate(TransientObjectType::HmacSha1, key.len() * 8) {
810     ///         Err(e) => return Err(e),
811     ///         Ok(mut key_object) => {
812     ///             let attr = Attribute::from_ref(AttributeId::SecretValue, &key);
813     ///             key_object.populate(&[attr.into()])?;
814     ///             mac.set_key(&key_object)?;
815     ///         }
816     ///     }
817     ///     mac.init(&[0u8; 0]);
818     ///     mac.update(&[0u8; 8]);
819     ///     mac.compute_final(&[0u8; 0], &mut out)?;
820     /// }
821     /// ```
822     ///
823     /// # Errors
824     ///
825     /// 1) `ShortBuffer`: If the output buffer is not large enough to contain the output.
826     ///
827     /// # Panics
828     ///
829     /// 1) If the algorithm is not a valid algorithm for `Mac`.
830     /// 2) If the function is called before before [init](Mac::init) or after
831     ///    [compute_final](Mac::compute_final) or after [compare_final](Mac::compare_final).
832     /// 3) If input data exceeds maximum length for algorithm.
833     /// 4) Hardware or cryptographic algorithm failure.
834     /// 5) If the Implementation detects any other error.
compute_final(&self, message: &[u8], mac: &mut [u8]) -> Result<usize>835     pub fn compute_final(&self, message: &[u8], mac: &mut [u8]) -> Result<usize> {
836         let mut mac_size: u32 = mac.len() as u32;
837         match unsafe {
838             raw::TEE_MACComputeFinal(
839                 self.handle(),
840                 message.as_ptr() as _,
841                 message.len() as u32,
842                 mac.as_mut_ptr() as _,
843                 &mut mac_size,
844             )
845         } {
846             raw::TEE_SUCCESS => Ok(mac_size as usize),
847             code => Err(Error::from_raw_error(code)),
848         }
849     }
850 
851     /// Finalize the MAC operation and compares the MAC with the buffer passed to the function.
852     /// Afterwards the operation handle can be reused or re-initialized with a new key.
853     /// The operation SHALL be in active state and moves to initial state afterwards.
854     ///
855     /// # Parameters:
856     ///
857     /// `message`: Input buffer containing a last message chunk to MAC
858     /// `mac`: Input buffer containing the MAC to check
859     ///
860     /// # Errors
861     ///
862     /// 1) `MacInvald`: If the computed MAC does not correspond to the value passed in `mac`.
863     ///
864     /// # Panics
865     ///
866     /// 1) If the algorithm is not a valid algorithm for `Mac`.
867     /// 2) If operation is not in active state.
868     /// 3) If input data exceeds maximum length for algorithm.
869     /// 4) Hardware or cryptographic algorithm failure.
870     /// 5) If the Implementation detects any other error.
compare_final(&self, message: &[u8], mac: &[u8]) -> Result<()>871     pub fn compare_final(&self, message: &[u8], mac: &[u8]) -> Result<()> {
872         match unsafe {
873             raw::TEE_MACCompareFinal(
874                 self.handle(),
875                 message.as_ptr() as _,
876                 message.len() as u32,
877                 mac.as_ptr() as _,
878                 mac.len() as u32,
879             )
880         } {
881             raw::TEE_SUCCESS => Ok(()),
882             code => Err(Error::from_raw_error(code)),
883         }
884     }
885 
886     /// Create a Mac operation without any specific algorithm or other data.
null() -> Self887     pub fn null() -> Self {
888         Self(OperationHandle::null())
889     }
890 
891     /// Function usage is similar to [Digest::allocate](Digest::allocate).
allocate(algo: AlgorithmId, max_key_size: usize) -> Result<Self>892     pub fn allocate(algo: AlgorithmId, max_key_size: usize) -> Result<Self> {
893         match OperationHandle::allocate(algo, OperationMode::Mac, max_key_size) {
894             Ok(handle) => Ok(Self(handle)),
895             Err(e) => Err(e),
896         }
897     }
898 
899     /// Function usage is similar to [Digest::info](Digest::info).
info(&self) -> OperationInfo900     pub fn info(&self) -> OperationInfo {
901         self.0.info()
902     }
903 
904     /// Function usage is similar to [Digest::info_multiple](Digest::info_multiple).
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>905     pub fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
906         self.0.info_multiple(info_buf)
907     }
908 
909     /// Function usage is similar to [Digest::reset](Digest::reset).
reset(&mut self)910     pub fn reset(&mut self) {
911         self.0.reset()
912     }
913 
914     /// Function usage is similar to [Cipher::set_key](Cipher::set_key).
set_key<T: ObjHandle>(&self, object: &T) -> Result<()>915     pub fn set_key<T: ObjHandle>(&self, object: &T) -> Result<()> {
916         self.0.set_key(object)
917     }
918 
919     /// Function usage is similar to [Digest::copy](Digest::copy).
copy<T: OpHandle>(&mut self, src: &T)920     pub fn copy<T: OpHandle>(&mut self, src: &T) {
921         self.0.copy(src)
922     }
923 }
924 
925 impl OpHandle for Mac {
handle(&self) -> raw::TEE_OperationHandle926     fn handle(&self) -> raw::TEE_OperationHandle {
927         self.0.handle()
928     }
929 }
930 
931 /// An operation for conducting authenticated encryption / decryption.
932 pub struct AE(OperationHandle);
933 
934 impl AE {
935     /// Initialize an AE opeartion.
936     /// The operation must be in the initial state and remains in the initial state afterwards.
937     ///
938     /// # Parameters
939     ///
940     /// 1) `nonce`: The peration nonce or IV
941     /// 2) `tag_len`: Size in bits of the tag:
942     /// 2.1) for `AES-GCM`, can be 128, 120, 112, 104, or 96;
943     /// 2.2) for `AES-CCM`, can be 128, 112, 96, 80, 64, 48, or 32.
944     /// 3) `aad_len`: length in bytes of the AAD (Used only for AES-CCM. Ignored for AES-GCM).
945     /// 4) `pay_load_len`: Length in bytes of the payload (Used only for AES-CCM. Ignored for AES-GCM).
946     ///
947     /// # Errors
948     ///
949     /// 1) `NotSupported`: If the `tag_len` is not supported by the algorithm.
950     ///
951     /// # Panics
952     ///
953     /// 1) If the algorithm is not a valid algorithm for `AE`.
954     /// 2) If no key is programmed in the operation.
955     /// 3) If the nonce length is not compatible with the length required by the algorithm.
956     /// 4) If operation is not in initial state.
957     /// 5) Hardware or cryptographic algorithm failure.
958     /// 6) If the Implementation detects any other error.
init( &self, nonce: &[u8], tag_len: usize, aad_len: usize, pay_load_len: usize, ) -> Result<()>959     pub fn init(
960         &self,
961         nonce: &[u8],
962         tag_len: usize,
963         aad_len: usize,
964         pay_load_len: usize,
965     ) -> Result<()> {
966         match unsafe {
967             raw::TEE_AEInit(
968                 self.handle(),
969                 nonce.as_ptr() as _,
970                 nonce.len() as u32,
971                 tag_len as u32,
972                 aad_len as u32,
973                 pay_load_len as u32,
974             )
975         } {
976             raw::TEE_SUCCESS => return Ok(()),
977             code => Err(Error::from_raw_error(code)),
978         }
979     }
980 
981     /// Feed a new chunk of Additional Authentication Data (AAD) to the AE operation.
982     /// Subsequent calls to this function are possible.
983     /// The operation SHALL be in initial state and remains in initial state afterwards.
984     ///
985     /// # Parameters
986     ///
987     /// 1) `aad_data`: Input buffer containing the chunk of AAD.
988     ///
989     /// # Panics
990     ///
991     /// 1) If the algorithm is not a valid algorithm for `AE`.
992     /// 2) If the function is called before [init](AE::init) or has been finalized.
993     /// 3) For `AES-CCM`, if the `aad_data.len()` exceeds the requirement.
994     /// 4) If operation is not in initial state.
995     /// 5) Hardware or cryptographic algorithm failure.
996     /// 6) If the Implementation detects any other error.
update_aad(&self, aad_data: &[u8])997     pub fn update_aad(&self, aad_data: &[u8]) {
998         unsafe {
999             raw::TEE_AEUpdateAAD(self.handle(), aad_data.as_ptr() as _, aad_data.len() as u32)
1000         };
1001     }
1002 
1003     /// Accumulate data for an Authentication Encryption operation.
1004     /// Input data does not have to be a multiple of block size. Subsequent calls to this function are possible.
1005     /// Unless one or more calls of this function have supplied sufficient input data, no output is generated.
1006     /// The buffers `src` and `dest` SHALL be either completely disjoint or equal in their starting positions.
1007     /// The operation may be in either initial or active state and enters active state afterwards if `src.len()` != 0.
1008     ///
1009     /// # Parameters
1010     ///
1011     /// 1) `src`: Input data buffer to be encrypted or decrypted.
1012     /// 2) `dest`: Output buffer.
1013     ///
1014     /// # Errors
1015     ///
1016     /// `ShortBuffer`: If the output buffer is not large enough to contain the output.
1017     ///
1018     /// # Panics
1019     ///
1020     /// 1) If the algorithm is not a valid algorithm for `AE`.
1021     /// 2) If the function is called before [init](AE::init) or has been finalized.
1022     /// 3) For `AES-CCM`, if the AAD length exceeds the requirement.
1023     /// 4) For `AES-CCM`, if the payload length is exceeds the requirement.
1024     /// 5) Hardware or cryptographic algorithm failure.
1025     /// 6) If the Implementation detects any other error.
update(&self, src: &[u8], dest: &mut [u8]) -> Result<usize>1026     pub fn update(&self, src: &[u8], dest: &mut [u8]) -> Result<usize> {
1027         let mut dest_size: u32 = dest.len() as u32;
1028         match unsafe {
1029             raw::TEE_AEUpdate(
1030                 self.handle(),
1031                 src.as_ptr() as _,
1032                 src.len() as u32,
1033                 dest.as_mut_ptr() as _,
1034                 &mut dest_size,
1035             )
1036         } {
1037             raw::TEE_SUCCESS => {
1038                 return Ok(dest_size as usize);
1039             }
1040             code => Err(Error::from_raw_error(code)),
1041         }
1042     }
1043     /// Process data that has not been processed by previous calls to [update](AE::update) as well as data supplied in `src`.
1044     /// It completes the AE operation and computes the tag.
1045     /// The buffers `src` and `dest` SHALL be either completely disjoint or equal in their starting positions.
1046     /// The operation may be in either initial or active state and enters initial state afterwards.
1047     ///
1048     /// # Parameters
1049     ///
1050     /// 1) `src`: Reference to final chunk of input data to be encrypted.
1051     /// 2) `dest`: Output buffer. Can be omitted if the output is to be discarded, e.g. because it is known to be empty.
1052     /// 3) `tag`: Output buffer filled with the computed tag.
1053     ///
1054     /// # Example
1055     ///
1056     /// ```no_run
1057     /// let key = [0xa5u8; 16];
1058     /// let nonce = [0x00u8; 16];
1059     /// let aad = [0xffu8; 16];
1060     /// let clear1 = [0x5au8; 19];
1061     /// let clear2 = [0xa5u8; 13];
1062     /// let mut ciph1 = [0x00u8; 16];
1063     /// let mut ciph2 = [0x00u8; 16];
1064     /// let mut tag = [0x00u8; 16];
1065     /// match AE::allocate(AlgorithmId::AesCcm, OperationMode::Encrypt, 128) {
1066     ///     Ok(operation) => {
1067     ///         match TransientObject::allocate(TransientObjectType::Aes, 128) {
1068     ///             Ok(key_object) => {
1069     ///                 let attr = Attributememref::from_ref(Attributeid::SecretValue, &key);
1070     ///                 key_object.populat(&[attr.into()])?;
1071     ///                 operation.set_key(&key_object)?;
1072     ///                 operation.init(&nonce, 128, 16, 32)?;
1073     ///                 operation.update_aad(&aad);
1074     ///                 operation.update(&clear1, &mut ciph1)?;
1075     ///                 match operation.encrypt_final(&clear2, &mut ciph2) {
1076     ///                     Ok((_ciph_len, _tag_len)) => {
1077     ///                         // ...
1078     ///                         Ok(()),
1079     ///                     }
1080     ///                     Err(e) => Err(e),
1081     ///                 }
1082     ///             Err(e) => Err(e),
1083     ///         }
1084     ///     Err(e) => Err(e),
1085     /// }
1086     /// ```
1087     ///
1088     /// # Errors
1089     ///
1090     /// `ShortBuffer`: If the output tag buffer is not large enough to contain the output.
1091     ///
1092     /// # Panics
1093     ///
1094     /// 1) If the algorithm is not a valid algorithm for `AE`.
1095     /// 2) If the function is called before [init](AE::init) or has been finalized.
1096     /// 3) If the required payload length is known but has not been provided.
1097     /// 4) Hardware or cryptographic algorithm failure.
1098     /// 5) If the Implementation detects any other error.
1099     // both dest and tag are updated with different size
encrypt_final( &self, src: &[u8], dest: &mut [u8], tag: &mut [u8], ) -> Result<(usize, usize)>1100     pub fn encrypt_final(
1101         &self,
1102         src: &[u8],
1103         dest: &mut [u8],
1104         tag: &mut [u8],
1105     ) -> Result<(usize, usize)> {
1106         let mut dest_size: u32 = dest.len() as u32;
1107         let mut tag_size: u32 = tag.len() as u32;
1108         match unsafe {
1109             raw::TEE_AEEncryptFinal(
1110                 self.handle(),
1111                 src.as_ptr() as _,
1112                 src.len() as u32,
1113                 dest.as_mut_ptr() as _,
1114                 &mut dest_size,
1115                 tag.as_mut_ptr() as _,
1116                 &mut tag_size,
1117             )
1118         } {
1119             raw::TEE_SUCCESS => {
1120                 return Ok((dest_size as usize, tag_size as usize));
1121             }
1122             code => Err(Error::from_raw_error(code)),
1123         }
1124     }
1125 
1126     /// Process data that has not been processed by previous calls to [update](AE::update) as well as data supplied in `src`.
1127     /// It completes the AE operation and computes the tag.
1128     /// The buffers `src` and `dest` SHALL be either completely disjoint or equal in their starting positions.
1129     /// The operation may be in either initial or active state and enters initial state afterwards.
1130     ///
1131     /// # Parameters
1132     ///
1133     /// 1) `src`: Reference to final chunk of input data to be decrypted.
1134     /// 2) `dest`: Output buffer. Can be omitted if the output is to be discarded, e.g. because it is known to be empty.
1135     /// 3) `tag`: Input buffer containing the tag to compare.
1136     ///
1137     /// # Errors
1138     ///
1139     /// `ShortBuffer`: If the output buffer is not large enough to contain the output.
1140     /// `MacInvalid`: If the computed tag does not match the supplied tag.
1141     ///
1142     /// # Panics
1143     ///
1144     /// 1) If the algorithm is not a valid algorithm for `AE`.
1145     /// 2) If the function is called before [init](AE::init) or has been finalized.
1146     /// 3) If the required payload length is known but has not been provided.
1147     /// 4) Hardware or cryptographic algorithm failure.
1148     /// 5) If the Implementation detects any other error.
decrypt_final(&self, src: &[u8], dest: &mut [u8], tag: &[u8]) -> Result<usize>1149     pub fn decrypt_final(&self, src: &[u8], dest: &mut [u8], tag: &[u8]) -> Result<usize> {
1150         let mut dest_size: u32 = dest.len() as u32;
1151         match unsafe {
1152             raw::TEE_AEDecryptFinal(
1153                 self.handle(),
1154                 src.as_ptr() as _,
1155                 src.len() as u32,
1156                 dest.as_mut_ptr() as _,
1157                 &mut dest_size,
1158                 tag.as_ptr() as _,
1159                 tag.len() as u32,
1160             )
1161         } {
1162             raw::TEE_SUCCESS => {
1163                 return Ok(dest_size as usize);
1164             }
1165             code => Err(Error::from_raw_error(code)),
1166         }
1167     }
1168 
1169     /// Create an AE operation without any specific algorithm or other data.
null() -> Self1170     pub fn null() -> Self {
1171         Self(OperationHandle::null())
1172     }
1173 
1174     /// Function usage is similar to [Digest::allocate](Digest::allocate).
allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self>1175     pub fn allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self> {
1176         match OperationHandle::allocate(algo, mode, max_key_size) {
1177             Ok(handle) => Ok(Self(handle)),
1178             Err(e) => Err(e),
1179         }
1180     }
1181 
1182     /// Function usage is similar to [Digest::info](Digest::info).
info(&self) -> OperationInfo1183     pub fn info(&self) -> OperationInfo {
1184         self.0.info()
1185     }
1186 
1187     /// Function usage is similar to [Digest::info_multiple](Digest::info_multiple).
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>1188     pub fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
1189         self.0.info_multiple(info_buf)
1190     }
1191 
1192     /// Function usage is similar to [Digest::reset](Digest::reset).
reset(&mut self)1193     pub fn reset(&mut self) {
1194         self.0.reset()
1195     }
1196 
1197     /// Function usage is similar to [Cipher::set_key](Cipher::set_key).
set_key<T: ObjHandle>(&self, object: &T) -> Result<()>1198     pub fn set_key<T: ObjHandle>(&self, object: &T) -> Result<()> {
1199         self.0.set_key(object)
1200     }
1201 
1202     /// Function usage is similar to [Digest::copy](Digest::copy).
copy<T: OpHandle>(&mut self, src: &T)1203     pub fn copy<T: OpHandle>(&mut self, src: &T) {
1204         self.0.copy(src)
1205     }
1206 }
1207 
1208 impl OpHandle for AE {
handle(&self) -> raw::TEE_OperationHandle1209     fn handle(&self) -> raw::TEE_OperationHandle {
1210         self.0.handle()
1211     }
1212 }
1213 
1214 /// An operation for conducting asymmetric encryption /decryption or asymmetric sign / verify.
1215 /// Note that asymmetric encryption is always “single-stage”,
1216 /// which differs from [Cipher](Cipher) which are always “multi-stage”.
1217 pub struct Asymmetric(OperationHandle);
1218 
1219 impl Asymmetric {
1220     /// Encrypt a message.
1221     ///
1222     /// # Parameters
1223     ///
1224     /// 1) `params`: Optional operation parameters.
1225     /// 2) `src`: Input plaintext buffer.
1226     ///
1227     /// # Example
1228     /// ```no_run
1229     /// let clear = [1u8; 8];
1230     /// match TransientObject::allocate(TransientObjectType::RsaKeypair, 256) {
1231     ///     Ok(key) => {
1232     ///         key.generate_key(256, &[])?;
1233     ///         match Asymmetric::allocate(
1234     ///             AlgorithmId::RsaesPkcs1V15,
1235     ///             OperationMode::Encrypt,
1236     ///             256) {
1237     ///             Ok(operation) => {
1238     ///                 operation.set_key(&key)?;
1239     ///                 match operation.encrypt(&[], &clear) {
1240     ///                     Ok(ciph_text) => {
1241     ///                         // Get cipher text as a vector
1242     ///                         // ...
1243     ///                         Ok(())
1244     ///                     }
1245     ///                     Err(e) => Err(e),
1246     ///                 }
1247     ///             }
1248     ///             Err(e) => Err(e),
1249     ///         }
1250     ///     }
1251     ///     Err(e) => Err(e),
1252     /// }
1253     /// ```
1254     ///
1255     /// # Errors
1256     ///
1257     /// 1) `ShortBuffer`: If the output buffer is not large enough to hold the result.
1258     /// 2) `BadParameters`: If the length of the input buffer is not consistent with the algorithm or key size.
1259     /// 3) `CiphertextInvalid`: If there is an error in the packing used on the ciphertext.
1260     ///
1261     /// # Panics
1262     ///
1263     /// 1) If the algorithm is not a valid algorithm for [Encrypt](OperationMode::Encrypt] of
1264     ///    `Asymmetric`.
1265     /// 2) If no key is programmed in the operation.
1266     /// 3) Hardware or cryptographic algorithm failure.
1267     /// 4) If the Implementation detects any other error.
1268     // This function can update output size with short buffer error when buffer is too
1269     // short, and example acipher utilizes this feature!
1270     // Define this function as unsafe because we need to return Ok for short buffer error.
encrypt(&self, params: &[Attribute], src: &[u8]) -> Result<Vec<u8>>1271     pub fn encrypt(&self, params: &[Attribute], src: &[u8]) -> Result<Vec<u8>> {
1272         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
1273         let mut res_size: u32 = self.info().key_size();
1274         let mut res_vec: Vec<u8> = vec![0u8; res_size as usize];
1275         match unsafe {
1276             raw::TEE_AsymmetricEncrypt(
1277                 self.handle(),
1278                 p.as_ptr() as _,
1279                 params.len() as u32,
1280                 src.as_ptr() as _,
1281                 src.len() as u32,
1282                 res_vec.as_mut_ptr() as _,
1283                 &mut res_size,
1284             )
1285         } {
1286             raw::TEE_SUCCESS => {
1287                 res_vec.truncate(res_size as usize);
1288                 return Ok(res_vec);
1289             }
1290             code => Err(Error::from_raw_error(code)),
1291         }
1292     }
1293 
1294     /// Decrypt a message.
1295     ///
1296     /// # Parameters
1297     ///
1298     /// 1) `params`: Optional operation parameters.
1299     /// 2) `src`: Input ciphertext buffer.
1300     ///
1301     /// # Errors
1302     ///
1303     /// 1) `ShortBuffer`: If the output buffer is not large enough to hold the result.
1304     /// 2) `BadParameters`: If the length of the input buffer is not consistent with the algorithm or key size.
1305     /// 3) `CiphertextInvalid`: If there is an error in the packing used on the ciphertext.
1306     ///
1307     /// # Panics
1308     ///
1309     /// 1) If the algorithm is not a valid algorithm for [Decrypt](OperationMode::Decrypt] of
1310     ///    `Asymmetric`.
1311     /// 2) If no key is programmed in the operation.
1312     /// 3) Hardware or cryptographic algorithm failure.
1313     /// 4) If the Implementation detects any other error.
decrypt(&self, params: &[Attribute], src: &[u8]) -> Result<Vec<u8>>1314     pub fn decrypt(&self, params: &[Attribute], src: &[u8]) -> Result<Vec<u8>> {
1315         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
1316         let mut res_size: u32 = self.info().key_size();
1317         let mut res_vec: Vec<u8> = vec![0u8; res_size as usize];
1318         match unsafe {
1319             raw::TEE_AsymmetricDecrypt(
1320                 self.handle(),
1321                 p.as_ptr() as _,
1322                 params.len() as u32,
1323                 src.as_ptr() as _,
1324                 src.len() as u32,
1325                 res_vec.as_mut_ptr() as _,
1326                 &mut res_size,
1327             )
1328         } {
1329             raw::TEE_SUCCESS => {
1330                 res_vec.truncate(res_size as usize);
1331                 return Ok(res_vec);
1332             }
1333             code => Err(Error::from_raw_error(code)),
1334         }
1335     }
1336 
1337     /// Sign a message digest.
1338     ///
1339     /// # Parameters
1340     ///
1341     /// 1) `params`: Optional operation parameters.
1342     /// 2) `digest`: Input buffer containing the input message digest.
1343     /// 3) `signature`: Output buffer written with the signature of the digest.
1344     ///
1345     /// # Errors
1346     ///
1347     /// 1) `ShortBuffer`: If `signature` is not large enough to hold the result.
1348     ///
1349     /// # Panics
1350     ///
1351     /// 1) If the algorithm is not a valid algorithm for [Sign](OperationMode::Sign] of
1352     ///    `Asymmetric`.
1353     /// 2) If no key is programmed in the operation.
1354     /// 3) If the mode is not set as [Sign](OperationMode::Sign].
1355     /// 4) If `digest.len()` is not equal to the hash size of the algorithm.
1356     /// 3) Hardware or cryptographic algorithm failure.
1357     /// 4) If the Implementation detects any other error.
sign_digest( &self, params: &[Attribute], digest: &[u8], signature: &mut [u8], ) -> Result<usize>1358     pub fn sign_digest(
1359         &self,
1360         params: &[Attribute],
1361         digest: &[u8],
1362         signature: &mut [u8],
1363     ) -> Result<usize> {
1364         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
1365         let mut signature_size: u32 = signature.len() as u32;
1366         match unsafe {
1367             raw::TEE_AsymmetricSignDigest(
1368                 self.handle(),
1369                 p.as_ptr() as _,
1370                 params.len() as u32,
1371                 digest.as_ptr() as _,
1372                 digest.len() as u32,
1373                 signature.as_mut_ptr() as _,
1374                 &mut signature_size,
1375             )
1376         } {
1377             raw::TEE_SUCCESS => {
1378                 return Ok(signature_size as usize);
1379             }
1380             code => Err(Error::from_raw_error(code)),
1381         }
1382     }
1383 
1384     /// Verify a message digest.
1385     ///
1386     /// # Parameters
1387     ///
1388     /// 1) `params`: Optional operation parameters.
1389     /// 2) `digest`: Input buffer containing the input message digest.
1390     /// 3) `signature`: Input buffer containing the signature to verify.
1391     ///
1392     /// # Errors
1393     ///
1394     /// 1) `SignatureInvalid`: If the signature is invalid.
1395     ///
1396     /// # Panics
1397     ///
1398     /// 1) If the algorithm is not a valid algorithm for [Verify](OperationMode::Verify] of
1399     ///    `Asymmetric`.
1400     /// 2) If no key is programmed in the operation.
1401     /// 3) If the mode is not set as [Verify](OperationMode::Verify].
1402     /// 4) If `digest.len()` is not equal to the hash size of the algorithm.
1403     /// 3) Hardware or cryptographic algorithm failure.
1404     /// 4) If the Implementation detects any other error.
verify_digest( &self, params: &[Attribute], digest: &[u8], signature: &[u8], ) -> Result<()>1405     pub fn verify_digest(
1406         &self,
1407         params: &[Attribute],
1408         digest: &[u8],
1409         signature: &[u8],
1410     ) -> Result<()> {
1411         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
1412         match unsafe {
1413             raw::TEE_AsymmetricVerifyDigest(
1414                 self.handle(),
1415                 p.as_ptr() as _,
1416                 params.len() as u32,
1417                 digest.as_ptr() as _,
1418                 digest.len() as u32,
1419                 signature.as_ptr() as _,
1420                 signature.len() as u32,
1421             )
1422         } {
1423             raw::TEE_SUCCESS => Ok(()),
1424             code => Err(Error::from_raw_error(code)),
1425         }
1426     }
1427 
1428     /// Create an Asymmetric operation without any specific algorithm or other data.
null() -> Self1429     pub fn null() -> Self {
1430         Self(OperationHandle::null())
1431     }
1432 
1433     /// Function usage is similar to [Digest::allocate](Digest::allocate).
allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self>1434     pub fn allocate(algo: AlgorithmId, mode: OperationMode, max_key_size: usize) -> Result<Self> {
1435         match OperationHandle::allocate(algo, mode, max_key_size) {
1436             Ok(handle) => Ok(Self(handle)),
1437             Err(e) => Err(e),
1438         }
1439     }
1440 
1441     /// Function usage is similar to [Digest::info](Digest::info).
info(&self) -> OperationInfo1442     pub fn info(&self) -> OperationInfo {
1443         self.0.info()
1444     }
1445 
1446     /// Function usage is similar to [Digest::info_multiple](Digest::info_multiple).
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>1447     pub fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
1448         self.0.info_multiple(info_buf)
1449     }
1450 
1451     /// Function usage is similar to [Cipher::set_key](Cipher::set_key).
set_key<T: ObjHandle>(&self, object: &T) -> Result<()>1452     pub fn set_key<T: ObjHandle>(&self, object: &T) -> Result<()> {
1453         self.0.set_key(object)
1454     }
1455 
1456     /// Function usage is similar to [Digest::copy](Digest::copy).
copy<T: OpHandle>(&mut self, src: &T)1457     pub fn copy<T: OpHandle>(&mut self, src: &T) {
1458         self.0.copy(src)
1459     }
1460 }
1461 
1462 impl OpHandle for Asymmetric {
handle(&self) -> raw::TEE_OperationHandle1463     fn handle(&self) -> raw::TEE_OperationHandle {
1464         self.0.handle()
1465     }
1466 }
1467 
1468 /// An operation for derive a shared key object.
1469 pub struct DeriveKey(OperationHandle);
1470 
1471 impl DeriveKey {
1472     /// Take one of the Asymmetric Derivation Operation Algorithm that supports this operation as
1473     /// defined in [AlgorithmId](AlgorithmId), and output a key object.
1474     ///
1475     /// # Parameters
1476     ///
1477     /// 1) `params`: For algorithm [DhDeriveSharedSecret][AlgorithmId::DhDeriveSharedSecret],
1478     ///    [DhPublicValue](../object/enum.AttributeId.html#variant.DhPublicValue) is required as
1479     ///    the passed in attribute.
1480     /// 2) `object`: An uninitialized transient object to be filled with the derived key.
1481     ///
1482     /// # Example
1483     ///
1484     /// ```no_run
1485     /// let attr_prime = AttributeMemref::from_ref(AttributeId::DhPrime, &[23u8]);
1486     /// let attr_base = AttributeMemref::from_ref(AttributeId::DhBase, &[5u8]);
1487     /// let mut public_1 = [0u8; 32];
1488     /// match TransientObject::allocate(TransientObjectType::DhKeypair, 256) {
1489     ///     Ok(key_pair_1) => {
1490     ///         key_pair_1.generate_key(256, &[attr_prime.into(), attr_base.into()])?;
1491     ///         key_pair_1.ref_attribute(aTTRIBUTEiD::DhPublicValue, &mut public_1)?;
1492     ///     }
1493     ///     Err(e) => Err(e),
1494     /// }
1495     ///
1496     /// let attr_prime = AttributeMemref::from_ref(AttributeId::DhPrime, &[23u8]);
1497     /// let attr_base = AttributeMemref::from_ref(AttributeId::DhBase, &[5u8]);
1498     /// match TransientObject::allocate(TransientObjectType::DhKeypair, 256) {
1499     ///     Ok(key_pair_2) => {
1500     ///         key_pair_2.generate_key(256, &[attr_prime.into(), attr_base.into()])?;
1501     ///         match DeriveKey::allocate(AlgorithmId::DhDeriveSharedSecret, 256) {
1502     ///             Ok(operation) => {
1503     ///                 operation.set_key(&key_pair_2)?;
1504     ///                 match TransientObject::allocate(TransientObjectType::GenericSecret,
1505     ///                 256) {
1506     ///                     // Derived key is saved as an transient object
1507     ///                     Ok(derived_key) => {
1508     ///                         let attr_public = AttributeMemref::from_ref(AttributeId::DhPublicValue, &public_1);
1509     ///                         operation.derive(&[attr_public.into()], &mut derived_key);
1510     ///                         // ...
1511     ///                         Ok(())
1512     ///                     }
1513     ///                     Err(e) => Err(e),
1514     ///                 }
1515     ///             }
1516     ///             Err(e) => Err(e),
1517     ///         }
1518     ///     }
1519     ///     Err(e) => Err(e),
1520     /// }
1521     /// ```
1522     ///
1523     /// # Panics
1524     ///
1525     /// 1) If the algorithm is not a valid algorithm for `DeriveKey`.
1526     /// 2) If the `object` is too small for generated value.
1527     /// 3) If no key is programmed in the operation.
1528     /// 4) Hardware or cryptographic algorithm failure.
1529     /// 5) If the Implementation detects any other error.
derive(&self, params: &[Attribute], object: &mut TransientObject)1530     pub fn derive(&self, params: &[Attribute], object: &mut TransientObject) {
1531         let p: Vec<raw::TEE_Attribute> = params.iter().map(|p| p.raw()).collect();
1532         unsafe {
1533             raw::TEE_DeriveKey(
1534                 self.handle(),
1535                 p.as_ptr() as _,
1536                 params.len() as u32,
1537                 object.handle(),
1538             )
1539         };
1540     }
1541 
1542     /// Create a DeriveKey operation without any specific algorithm or other data.
null() -> Self1543     pub fn null() -> Self {
1544         Self(OperationHandle::null())
1545     }
1546 
1547     /// Function usage is similar to [Digest::allocate](Digest::allocate).
1548     /// Currently only supports [DhDeriveSharedSecret][AlgorithmId::DhDeriveSharedSecret] as
1549     /// `algo`.
allocate(algo: AlgorithmId, max_key_size: usize) -> Result<Self>1550     pub fn allocate(algo: AlgorithmId, max_key_size: usize) -> Result<Self> {
1551         match OperationHandle::allocate(algo, OperationMode::Derive, max_key_size) {
1552             Ok(handle) => Ok(Self(handle)),
1553             Err(e) => Err(e),
1554         }
1555     }
1556 
1557     /// Function usage is similar to [Digest::info](Digest::info).
info(&self) -> OperationInfo1558     pub fn info(&self) -> OperationInfo {
1559         self.0.info()
1560     }
1561 
1562     /// Function usage is similar to [Digest::info_multiple](Digest::info_multiple).
info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple>1563     pub fn info_multiple(&self, info_buf: &mut [u8]) -> Result<OperationInfoMultiple> {
1564         self.0.info_multiple(info_buf)
1565     }
1566 
1567     /// Function usage is similar to [Cipher::set_key](Cipher::set_key).
set_key<T: ObjHandle>(&self, object: &T) -> Result<()>1568     pub fn set_key<T: ObjHandle>(&self, object: &T) -> Result<()> {
1569         self.0.set_key(object)
1570     }
1571 
1572     /// Function usage is similar to [Digest::copy](Digest::copy).
copy<T: OpHandle>(&mut self, src: &T)1573     pub fn copy<T: OpHandle>(&mut self, src: &T) {
1574         self.0.copy(src)
1575     }
1576 }
1577 
1578 impl OpHandle for DeriveKey {
handle(&self) -> raw::TEE_OperationHandle1579     fn handle(&self) -> raw::TEE_OperationHandle {
1580         self.0.handle()
1581     }
1582 }
1583 
1584 /// An operation for generating random data.
1585 pub struct Random();
1586 
1587 impl Random {
1588     /// Generate random data.
1589     ///
1590     /// # Parameters
1591     ///
1592     /// 1) `res_buffer`: Reference to generated random data
1593     ///
1594     /// # Example
1595     ///
1596     /// ```no_run
1597     /// let mut res = [0u8;16];
1598     /// Random::generate(&mut res);
1599     /// ```
1600     ///
1601     /// # Panics
1602     ///
1603     /// 1) Hardware or cryptographic algorithm failure.
1604     /// 2) If the Implementation detects any other error.
generate(res_buffer: &mut [u8])1605     pub fn generate(res_buffer: &mut [u8]) {
1606         unsafe {
1607             raw::TEE_GenerateRandom(res_buffer.as_mut_ptr() as _, res_buffer.len() as _);
1608         }
1609     }
1610 }
1611 
1612 /// Algorithms that can be allocated as an crypto operation.
1613 #[repr(u32)]
1614 pub enum AlgorithmId {
1615     /// [Cipher](Cipher) supported algorithm.
1616     AesEcbNopad = 0x10000010,
1617     /// [Cipher](Cipher) supported algorithm.
1618     AesCbcNopad = 0x10000110,
1619     /// [Cipher](Cipher) supported algorithm.
1620     AesCtr = 0x10000210,
1621     /// [Cipher](Cipher) supported algorithm.
1622     AesCts = 0x10000310,
1623     /// [Cipher](Cipher) supported algorithm.
1624     AesXts = 0x10000410,
1625     /// [Mac](Mac) supported algorithm.
1626     AesCbcMacNopad = 0x30000110,
1627     /// [Mac](Mac) supported algorithm.
1628     AesCbcMacPkcs5 = 0x30000510,
1629     /// [Mac](Mac) supported algorithm.
1630     AesCmac = 0x30000610,
1631     /// [AE](AE) supported algorithm.
1632     AesCcm = 0x40000710,
1633     /// [AE](AE) supported algorithm.
1634     AesGcm = 0x40000810,
1635     /// [Cipher](Cipher) supported algorithm.
1636     DesEcbNopad = 0x10000011,
1637     /// [Cipher](Cipher) supported algorithm.
1638     DesCbcNopad = 0x10000111,
1639     /// [Mac](Mac) supported algorithm.
1640     DesCbcMacNopad = 0x30000111,
1641     /// [Mac](Mac) supported algorithm.
1642     DesCbcMacPkcs5 = 0x30000511,
1643     /// [Cipher](Cipher) supported algorithm.
1644     Des3EcbNopad = 0x10000013,
1645     /// [Cipher](Cipher) supported algorithm.
1646     Des3CbcNopad = 0x10000113,
1647     /// [Mac](Mac) supported algorithm.
1648     Des3CbcMacNopad = 0x30000113,
1649     /// [Mac](Mac) supported algorithm.
1650     Des3CbcMacPkcs5 = 0x30000513,
1651     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1652     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1653     RsassaPkcs1V15MD5 = 0x70001830,
1654     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1655     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1656     RsassaPkcs1V15Sha1 = 0x70002830,
1657     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1658     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1659     RsassaPkcs1V15Sha224 = 0x70003830,
1660     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1661     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1662     RsassaPkcs1V15Sha256 = 0x70004830,
1663     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1664     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1665     RsassaPkcs1V15Sha384 = 0x70005830,
1666     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1667     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1668     RsassaPkcs1V15Sha512 = 0x70006830,
1669     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1670     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1671     RsassaPkcs1V15MD5Sha1 = 0x7000F830,
1672     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1673     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1674     RsassaPkcs1PssMgf1Sha1 = 0x70212930,
1675     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1676     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1677     RsassaPkcs1PssMgf1Sha224 = 0x70313930,
1678     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1679     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1680     RsassaPkcs1PssMgf1Sha256 = 0x70414930,
1681     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1682     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1683     RsassaPkcs1PssMgf1Sha384 = 0x70515930,
1684     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1685     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1686     RsassaPkcs1PssMgf1Sha512 = 0x70616930,
1687     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1688     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1689     RsaesPkcs1V15 = 0x60000130,
1690     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1691     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1692     RsaesPkcs1OAepMgf1Sha1 = 0x60210230,
1693     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1694     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1695     RsaesPkcs1OAepMgf1Sha224 = 0x60310230,
1696     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1697     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1698     RsaesPkcs1OAepMgf1Sha256 = 0x60410230,
1699     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1700     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1701     RsaesPkcs1OAepMgf1Sha384 = 0x60510230,
1702     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1703     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1704     RsaesPkcs1OAepMgf1Sha512 = 0x60610230,
1705     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1706     /// [Encrypt](OperationMode::Encrypt) or [Decrypt](OperationMode::Decrypt) mode.
1707     RsaNopad = 0x60000030,
1708     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1709     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1710     DSASha1 = 0x70002131,
1711     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1712     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1713     DSASha224 = 0x70003131,
1714     /// [Asymmetric](Asymmetric) supported algorithm, can be applied with
1715     /// [Sign](OperationMode::Sign) or [Verify](OperationMode::Verify) mode.
1716     DSASha256 = 0x70004131,
1717     /// [DeriveKey](DeriveKey) supported algorithm.
1718     DhDeriveSharedSecret = 0x80000032,
1719     /// [Digest](Digest) supported algorithm.
1720     Md5 = 0x50000001,
1721     /// [Digest](Digest) supported algorithm.
1722     Sha1 = 0x50000002,
1723     /// [Digest](Digest) supported algorithm.
1724     Sha224 = 0x50000003,
1725     /// [Digest](Digest) supported algorithm.
1726     Sha256 = 0x50000004,
1727     /// [Digest](Digest) supported algorithm.
1728     Sha384 = 0x50000005,
1729     /// [Digest](Digest) supported algorithm.
1730     Sha512 = 0x50000006,
1731     /// [Mac](Mac) supported algorithm.
1732     Md5Sha1 = 0x5000000F,
1733     /// [Mac](Mac) supported algorithm.
1734     HmacMd5 = 0x30000001,
1735     /// [Mac](Mac) supported algorithm.
1736     HmacSha1 = 0x30000002,
1737     /// [Mac](Mac) supported algorithm.
1738     HmacSha224 = 0x30000003,
1739     /// [Mac](Mac) supported algorithm.
1740     HmacSha256 = 0x30000004,
1741     /// [Mac](Mac) supported algorithm.
1742     HmacSha384 = 0x30000005,
1743     /// [Mac](Mac) supported algorithm.
1744     HmacSha512 = 0x30000006,
1745     /// Reserved for GlobalPlatform compliance test applications.
1746     IllegalValue = 0xefffffff,
1747 }
1748 
1749 /// This specification defines support for optional cryptographic elements.
1750 #[repr(u32)]
1751 pub enum ElementId {
1752     /// Where algId fully defines the required support,
1753     /// the special value TEE_CRYPTO_ELEMENT_NONE should be used
1754     ElementNone = 0x00000000,
1755     /// Source: `NIST`, Generic: `Y`, Size: 192 bits
1756     EccCurveNistP192 = 0x00000001,
1757     /// Source: `NIST`, Generic: `Y`, Size: 224 bits
1758     EccCurveNistP224 = 0x00000002,
1759     /// Source: `NIST`, Generic: `Y`, Size: 256 bits
1760     EccCurveNistP256 = 0x00000003,
1761     /// Source: `NIST`, Generic: `Y`, Size: 384 bits
1762     EccCurveNistP384 = 0x00000004,
1763     /// Source: `NIST`, Generic: `Y`, Size: 521 bits
1764     EccCurveNistP521 = 0x00000005,
1765 }
1766