optee_utee/
crypto_op.rs

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