#![allow(unused_assignments)]
use crate::api::tee_api_mm::{TEE_CheckMemoryAccessRights, TEE_Free, TEE_Malloc, TEE_MemFill};
use crate::api::tee_api_objects::{
__utee_from_attr, TEE_AllocateTransientObject, TEE_CopyObjectAttributes1,
TEE_FreeTransientObject, TEE_GetObjectInfo1, TEE_ResetTransientObject,
};
use crate::api::tee_api_panic::TEE_Panic;
use crate::syscalls::syscall_table::{
_utee_asymm_operate, _utee_asymm_verify, _utee_authenc_dec_final, _utee_authenc_enc_final,
_utee_authenc_init, _utee_authenc_update_aad, _utee_authenc_update_payload, _utee_cipher_final,
_utee_cipher_init, _utee_cipher_update, _utee_cryp_derive_key, _utee_cryp_obj_get_info,
_utee_cryp_random_number_generate, _utee_cryp_state_alloc, _utee_cryp_state_copy,
_utee_cryp_state_free, _utee_hash_final, _utee_hash_init, _utee_hash_update,
};
use crate::tee_api_defines::*;
use crate::tee_api_types::{
TEE_Attribute, TEE_ObjectHandle, TEE_ObjectInfo, TEE_OperationHandle, TEE_OperationInfo,
TEE_OperationInfoKey, TEE_OperationInfoMultiple, TEE_Result,
};
use std::ptr;
pub fn TEE_ALG_GET_CLASS(alg: u32) -> u32 {
(alg >> 24) & 0xFF
}
pub(crate) fn TEE_ALG_GET_MAIN_ALG(algo: u32) -> u32 {
match algo {
TEE_ALG_SM2_PKE => TEE_MAIN_ALGO_SM2_PKE,
TEE_ALG_SM2_KEP => TEE_MAIN_ALGO_SM2_KEP,
TEE_ALG_X25519 => TEE_MAIN_ALGO_X25519,
TEE_ALG_ED25519 => TEE_MAIN_ALGO_ED25519,
TEE_ALG_ECDSA_SHA1 | TEE_ALG_ECDSA_SHA224 | TEE_ALG_ECDSA_SHA256 | TEE_ALG_ECDSA_SHA384
| TEE_ALG_ECDSA_SHA512 => TEE_MAIN_ALGO_ECDSA,
TEE_ALG_HKDF => TEE_MAIN_ALGO_HKDF,
TEE_ALG_SHAKE128 => TEE_MAIN_ALGO_SHAKE128,
TEE_ALG_SHAKE256 => TEE_MAIN_ALGO_SHAKE256,
TEE_ALG_X448 => TEE_MAIN_ALGO_X448,
_ => algo & 0xff,
}
}
pub fn TEE_ALG_GET_KEY_TYPE(alg: u32, mode: u32) -> Result<(u32, u32), u32> {
let req_key_type;
let mut req_key_type2: u32 = 0;
match TEE_ALG_GET_MAIN_ALG(alg) {
TEE_MAIN_ALGO_MD5 => {
req_key_type = TEE_TYPE_HMAC_MD5;
}
TEE_MAIN_ALGO_SHA1 => {
req_key_type = TEE_TYPE_HMAC_SHA1;
}
TEE_MAIN_ALGO_SHA224 => {
req_key_type = TEE_TYPE_HMAC_SHA224;
}
TEE_MAIN_ALGO_SHA256 => {
req_key_type = TEE_TYPE_HMAC_SHA256;
}
TEE_MAIN_ALGO_SHA384 => {
req_key_type = TEE_TYPE_HMAC_SHA384;
}
TEE_MAIN_ALGO_SHA512 => {
req_key_type = TEE_TYPE_HMAC_SHA512;
}
TEE_MAIN_ALGO_SHA3_224 => {
req_key_type = TEE_TYPE_HMAC_SHA3_224;
}
TEE_MAIN_ALGO_SHA3_256 => {
req_key_type = TEE_TYPE_HMAC_SHA3_256;
}
TEE_MAIN_ALGO_SHA3_384 => {
req_key_type = TEE_TYPE_HMAC_SHA3_384;
}
TEE_MAIN_ALGO_SHA3_512 => {
req_key_type = TEE_TYPE_HMAC_SHA3_512;
}
TEE_MAIN_ALGO_SM3 => {
req_key_type = TEE_TYPE_HMAC_SM3;
}
TEE_MAIN_ALGO_AES => {
req_key_type = TEE_TYPE_AES;
}
TEE_MAIN_ALGO_DES => {
req_key_type = TEE_TYPE_DES;
}
TEE_MAIN_ALGO_DES3 => {
req_key_type = TEE_TYPE_DES3;
}
TEE_MAIN_ALGO_SM4 => {
req_key_type = TEE_TYPE_SM4;
}
TEE_MAIN_ALGO_RSA => {
req_key_type = TEE_TYPE_RSA_KEYPAIR;
if mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY {
req_key_type2 = TEE_TYPE_RSA_PUBLIC_KEY;
}
}
TEE_MAIN_ALGO_DSA => {
req_key_type = TEE_TYPE_DSA_KEYPAIR;
if mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY {
req_key_type2 = TEE_TYPE_DSA_PUBLIC_KEY;
}
}
TEE_MAIN_ALGO_DH => {
req_key_type = TEE_TYPE_DH_KEYPAIR;
}
TEE_MAIN_ALGO_ECDSA => {
req_key_type = TEE_TYPE_ECDSA_KEYPAIR;
if mode == TEE_MODE_VERIFY {
req_key_type2 = TEE_TYPE_ECDSA_PUBLIC_KEY;
}
}
TEE_MAIN_ALGO_ECDH => {
req_key_type = TEE_TYPE_ECDH_KEYPAIR;
}
TEE_MAIN_ALGO_ED25519 => {
req_key_type = TEE_TYPE_ED25519_KEYPAIR;
if mode == TEE_MODE_VERIFY {
req_key_type2 = TEE_TYPE_ED25519_PUBLIC_KEY;
}
}
TEE_MAIN_ALGO_SM2_PKE => {
if mode == TEE_MODE_ENCRYPT {
req_key_type = TEE_TYPE_SM2_PKE_PUBLIC_KEY;
} else {
req_key_type = TEE_TYPE_SM2_PKE_KEYPAIR;
}
}
TEE_MAIN_ALGO_SM2_DSA_SM3 => {
if mode == TEE_MODE_VERIFY {
req_key_type = TEE_TYPE_SM2_DSA_PUBLIC_KEY;
} else {
req_key_type = TEE_TYPE_SM2_DSA_KEYPAIR;
}
}
TEE_MAIN_ALGO_SM2_KEP => {
req_key_type = TEE_TYPE_SM2_KEP_KEYPAIR;
req_key_type2 = TEE_TYPE_SM2_KEP_PUBLIC_KEY;
}
TEE_MAIN_ALGO_HKDF => {
req_key_type = TEE_TYPE_HKDF_IKM;
}
TEE_MAIN_ALGO_CONCAT_KDF => {
req_key_type = TEE_TYPE_CONCAT_KDF_Z;
}
TEE_MAIN_ALGO_PBKDF2 => {
req_key_type = TEE_TYPE_PBKDF2_PASSWORD;
}
TEE_MAIN_ALGO_X25519 => {
req_key_type = TEE_TYPE_X25519_KEYPAIR;
}
TEE_MAIN_ALGO_X448 => {
req_key_type = TEE_TYPE_X448_KEYPAIR;
}
_ => return Err(TEE_ERROR_BAD_PARAMETERS),
}
Ok((req_key_type, req_key_type2))
}
impl TEE_OperationHandle {
pub fn new(
info: TEE_OperationInfo,
key1: TEE_ObjectHandle,
key2: TEE_ObjectHandle,
operation_state: u32,
block_size: usize,
state: u32,
) -> Self {
TEE_OperationHandle {
info,
key1,
key2,
operation_state,
buffer: core::ptr::null_mut(),
buffer_two_blocks: false,
block_size,
buffer_offs: 0,
state,
}
}
pub fn free_buffer(&mut self) {
if !self.buffer.is_null() {
TEE_Free(self.buffer as *mut core::ffi::c_void);
self.buffer = ptr::null_mut();
self.buffer_offs = 0;
}
}
}
impl Drop for TEE_OperationHandle {
fn drop(&mut self) {
self.free_buffer();
}
}
#[derive(Debug, PartialEq)]
pub enum BufferError {
BufferNotAllocated,
InsufficientSpace,
AllocationFailed,
}
impl std::fmt::Display for BufferError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BufferError::BufferNotAllocated => write!(f, "Buffer not allocated"),
BufferError::InsufficientSpace => write!(f, "Insufficient space in buffer"),
BufferError::AllocationFailed => write!(f, "Memory allocation failed"),
}
}
}
impl std::error::Error for BufferError {}
impl TEE_OperationHandle {
pub fn allocate_buffer_v2(&mut self, size: usize) -> std::result::Result<(), BufferError> {
let new_buffer = TEE_Malloc(size, TEE_MALLOC_FILL_ZERO);
if new_buffer.is_null() {
return Err(BufferError::AllocationFailed);
}
if !self.buffer.is_null() {
TEE_Free(self.buffer as *mut core::ffi::c_void);
}
self.buffer = new_buffer as *mut u8;
self.buffer_offs = 0;
Ok(())
}
}
#[derive(Debug, PartialEq)]
enum OperationConfig {
Digest {
block_size: usize,
},
Cipher {
block_size: usize,
buffer_two_blocks: bool,
req_key_usage: u32,
with_private_key: bool,
},
AsymmetricSignature {
req_key_usage: u32,
with_private_key: bool,
},
AsymmetricEncryption {
req_key_usage: u32,
with_private_key: bool,
},
KeyDerivation {
req_key_usage: u32,
},
Mac {
req_key_usage: u32,
},
}
fn validate_algorithm_params(
algorithm: u32,
mode: u32,
max_key_size: u32,
) -> Result<OperationConfig, TEE_Result> {
use crate::tee_api_defines::*;
match algorithm {
TEE_ALG_DSA_SHA1 => {
if max_key_size < 512 || max_key_size > 1024 || max_key_size % 64 != 0 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_DSA_SHA224 => {
if max_key_size != 2048 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_DSA_SHA256 => {
if max_key_size != 2048 && max_key_size != 3072 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_ECDSA_P192 | TEE_ALG_ECDH_P192 => {
if max_key_size != 192 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_ECDSA_P224 | TEE_ALG_ECDH_P224 => {
if max_key_size != 224 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_ECDSA_P256 | TEE_ALG_ECDH_P256 | TEE_ALG_SM2_PKE | TEE_ALG_SM2_DSA_SM3 => {
if max_key_size != 256 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_SM2_KEP => {
if max_key_size != 512 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_ECDSA_P384 | TEE_ALG_ECDH_P384 => {
if max_key_size != 384 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
TEE_ALG_ECDSA_P521 | TEE_ALG_ECDH_P521 => {
if max_key_size != 521 {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
}
_ => {}
}
match algorithm {
TEE_ALG_MD5 | TEE_ALG_SHA1 | TEE_ALG_SHA224 | TEE_ALG_SHA256 | TEE_ALG_SHA384
| TEE_ALG_SHA512 | TEE_ALG_SM3 => {
if mode != TEE_MODE_DIGEST {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
let digest_length = match algorithm & 0x000000FF {
0x01 => 16, 0x02 => 20, 0x03 => 28, 0x04 => 32, 0x05 => 48, 0x06 => 64, 0x10 => 32, _ => 0,
};
Ok(OperationConfig::Digest {
block_size: digest_length,
})
}
TEE_ALG_DES_CBC_MAC_NOPAD
| TEE_ALG_AES_CBC_MAC_NOPAD
| TEE_ALG_AES_CBC_MAC_PKCS5
| TEE_ALG_AES_CMAC
| TEE_ALG_DES_CBC_MAC_PKCS5
| TEE_ALG_DES3_CBC_MAC_NOPAD
| TEE_ALG_DES3_CBC_MAC_PKCS5
| TEE_ALG_HMAC_MD5
| TEE_ALG_HMAC_SHA1
| TEE_ALG_HMAC_SHA224
| TEE_ALG_HMAC_SHA256
| TEE_ALG_HMAC_SHA384
| TEE_ALG_HMAC_SHA512
| TEE_ALG_HMAC_SM3 => {
if mode != TEE_MODE_MAC {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
Ok(OperationConfig::Mac {
req_key_usage: TEE_USAGE_MAC,
})
}
TEE_ALG_AES_ECB_NOPAD
| TEE_ALG_AES_CBC_NOPAD
| TEE_ALG_AES_CCM
| TEE_ALG_DES_ECB_NOPAD
| TEE_ALG_DES_CBC_NOPAD
| TEE_ALG_DES3_ECB_NOPAD
| TEE_ALG_DES3_CBC_NOPAD
| TEE_ALG_SM4_ECB_NOPAD
| TEE_ALG_SM4_CBC_NOPAD
| TEE_ALG_SM4_CTR => {
let main_alg = (algorithm & 0x00FF0000) >> 16;
let block_size = match main_alg {
0x1000 => 16, 0x4000 => 16, _ => 8,
};
Ok(OperationConfig::Cipher {
block_size,
buffer_two_blocks: false,
req_key_usage: 0, with_private_key: false, })
}
TEE_ALG_AES_CTS => {
let main_alg = (algorithm & 0x00FF0000) >> 16;
let block_size = match main_alg {
0x1000 => 16, 0x4000 => 16, _ => return Err(TEE_ERROR_NOT_SUPPORTED),
};
Ok(OperationConfig::Cipher {
block_size,
buffer_two_blocks: true,
req_key_usage: 0,
with_private_key: false,
})
}
TEE_ALG_AES_CTR | TEE_ALG_AES_GCM | TEE_ALG_SM4_GCM => {
let block_size = 16;
match mode {
TEE_MODE_ENCRYPT => Ok(OperationConfig::Cipher {
block_size,
buffer_two_blocks: false,
req_key_usage: TEE_USAGE_ENCRYPT,
with_private_key: false,
}),
TEE_MODE_DECRYPT => Ok(OperationConfig::Cipher {
block_size,
buffer_two_blocks: false,
req_key_usage: TEE_USAGE_DECRYPT,
with_private_key: true,
}),
_ => Err(TEE_ERROR_NOT_SUPPORTED),
}
}
TEE_ALG_ECDSA_P192 | TEE_ALG_ECDSA_P224 | TEE_ALG_ECDSA_P256 | TEE_ALG_ECDSA_P384
| TEE_ALG_ECDSA_P521 | TEE_ALG_SM2_DSA_SM3 => match mode {
TEE_MODE_SIGN => Ok(OperationConfig::AsymmetricSignature {
req_key_usage: TEE_USAGE_SIGN,
with_private_key: true,
}),
TEE_MODE_VERIFY => Ok(OperationConfig::AsymmetricSignature {
req_key_usage: TEE_USAGE_VERIFY,
with_private_key: false,
}),
_ => Err(TEE_ERROR_NOT_SUPPORTED),
},
TEE_ALG_RSAES_PKCS1_V1_5
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512
| TEE_ALG_SM2_PKE => match mode {
TEE_MODE_ENCRYPT => Ok(OperationConfig::AsymmetricEncryption {
req_key_usage: TEE_USAGE_ENCRYPT,
with_private_key: false,
}),
TEE_MODE_DECRYPT => Ok(OperationConfig::AsymmetricEncryption {
req_key_usage: TEE_USAGE_DECRYPT,
with_private_key: true,
}),
_ => Err(TEE_ERROR_NOT_SUPPORTED),
},
TEE_ALG_RSA_NOPAD => match mode {
TEE_MODE_ENCRYPT => Ok(OperationConfig::AsymmetricEncryption {
req_key_usage: TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY,
with_private_key: false,
}),
TEE_MODE_DECRYPT => Ok(OperationConfig::AsymmetricEncryption {
req_key_usage: TEE_USAGE_DECRYPT | TEE_USAGE_SIGN,
with_private_key: true,
}),
_ => Err(TEE_ERROR_NOT_SUPPORTED),
},
TEE_ALG_DH_DERIVE_SHARED_SECRET
| TEE_ALG_ECDH_P192
| TEE_ALG_ECDH_P224
| TEE_ALG_ECDH_P256
| TEE_ALG_ECDH_P384
| TEE_ALG_ECDH_P521
| TEE_ALG_SM2_KEP => {
if mode != TEE_MODE_DERIVE {
return Err(TEE_ERROR_NOT_SUPPORTED);
}
Ok(OperationConfig::KeyDerivation {
req_key_usage: TEE_USAGE_DERIVE,
})
}
_ => Err(TEE_ERROR_NOT_SUPPORTED),
}
}
pub fn tee_alg_get_class(algo: u32) -> u32 {
match algo {
TEE_ALG_SM2_PKE => TEE_OPERATION_ASYMMETRIC_CIPHER,
TEE_ALG_SM2_KEP => TEE_OPERATION_KEY_DERIVATION,
TEE_ALG_RSASSA_PKCS1_V1_5_MD5
| TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1
| TEE_ALG_RSASSA_PKCS1_V1_5_SHA1
| TEE_ALG_RSASSA_PKCS1_V1_5_SHA224
| TEE_ALG_RSASSA_PKCS1_V1_5_SHA256
| TEE_ALG_RSASSA_PKCS1_V1_5_SHA384
| TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 => TEE_OPERATION_ASYMMETRIC_SIGNATURE,
TEE_ALG_DES3_CBC_MAC_NOPAD | TEE_ALG_DES3_CBC_MAC_PKCS5 => TEE_OPERATION_MAC,
TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1
| TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224
| TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256
| TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384
| TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 => TEE_OPERATION_ASYMMETRIC_SIGNATURE,
TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384
| TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512 => TEE_OPERATION_ASYMMETRIC_CIPHER,
_ => (algo >> 28) & 0xF,
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AllocateOperation(
operation: *mut *mut TEE_OperationHandle,
algorithm: u32,
mode: u32,
max_key_size: u32,
) -> TEE_Result {
use crate::tee_api_defines::*;
if operation.is_null() {
TEE_Panic(0);
return TEE_ERROR_GENERIC;
}
let config = match validate_algorithm_params(algorithm, mode, max_key_size) {
Ok(c) => c,
Err(e) => return e,
};
let operation_class = tee_alg_get_class(algorithm);
let digest_length = match algorithm & 0x000000FF {
0x01 => 16, 0x02 => 20, 0x03 => 28, 0x04 => 32, 0x05 => 48, 0x06 => 64, 0x10 => 32, _ => 0,
};
let _main_alg = (algorithm & 0x00FF0000) >> 16;
let mut handle_state = 0u32;
if algorithm == TEE_ALG_SM2_KEP {
handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
}
let (block_size, buffer_two_blocks, req_key_usage, _) = match config {
OperationConfig::Digest { block_size } => {
handle_state |= TEE_HANDLE_FLAG_KEY_SET;
(block_size, false, 0, false)
}
OperationConfig::Cipher {
block_size,
buffer_two_blocks,
req_key_usage,
with_private_key,
} => (
block_size,
buffer_two_blocks,
req_key_usage,
with_private_key,
),
OperationConfig::AsymmetricSignature {
req_key_usage,
with_private_key,
} => (1, false, req_key_usage, with_private_key),
OperationConfig::AsymmetricEncryption {
req_key_usage,
with_private_key,
} => (1, false, req_key_usage, with_private_key),
OperationConfig::KeyDerivation { req_key_usage } => (1, false, req_key_usage, true),
OperationConfig::Mac { req_key_usage } => (1, false, req_key_usage, false),
};
let op_info = TEE_OperationInfo {
algorithm,
operationClass: operation_class,
mode,
digestLength: digest_length,
maxKeySize: max_key_size,
keySize: 0,
requiredKeyUsage: req_key_usage,
handleState: handle_state,
};
let operation_ptr = TEE_Malloc(
core::mem::size_of::<TEE_OperationHandle>(),
TEE_MALLOC_FILL_ZERO,
);
if operation_ptr.is_null() {
return TEE_ERROR_OUT_OF_MEMORY;
}
let op_handle = unsafe { &mut *(operation_ptr as *mut TEE_OperationHandle) };
*op_handle = TEE_OperationHandle::new(
op_info,
ptr::null_mut(),
ptr::null_mut(),
TEE_OPERATION_STATE_INITIAL,
block_size,
0,
);
if block_size > 1 {
let buffer_size = if buffer_two_blocks {
block_size * 2
} else {
block_size
};
if op_handle.allocate_buffer_v2(buffer_size).is_err() {
TEE_Free(operation_ptr);
return TEE_ERROR_OUT_OF_MEMORY;
}
}
op_handle.buffer_two_blocks = buffer_two_blocks;
if operation_class != TEE_OPERATION_DIGEST {
let mut mks = max_key_size;
let res = TEE_ALG_GET_KEY_TYPE(algorithm, mode);
let (key_type, key_type2) = match res {
Ok(res) => res,
Err(e) => return e,
};
if handle_state & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS != 0 {
mks /= 2;
}
let mut key1_ptr = core::ptr::null_mut();
let res = TEE_AllocateTransientObject(key_type, mks, &mut key1_ptr);
if res != TEE_SUCCESS {
TEE_Free(operation_ptr);
return res;
}
op_handle.key1 = key1_ptr;
if handle_state & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS != 0 {
let mut key2_ptr = core::ptr::null_mut();
let res = TEE_AllocateTransientObject(key_type2, mks, &mut key2_ptr);
if res != TEE_SUCCESS {
TEE_FreeTransientObject(op_handle.key1);
TEE_Free(operation_ptr);
return res;
}
op_handle.key2 = key2_ptr;
}
}
let mut state = 0u32;
let res = unsafe {
_utee_cryp_state_alloc(
algorithm as u64,
mode as u64,
op_handle.key1 as u64,
op_handle.key2 as u64,
&mut state,
)
};
if res != TEE_SUCCESS as usize {
TEE_FreeTransientObject(op_handle.key1);
TEE_FreeTransientObject(op_handle.key2);
TEE_Free(operation_ptr);
return res as TEE_Result;
}
op_handle.state = state;
if operation_class == TEE_OPERATION_DIGEST {
let res = unsafe { _utee_hash_init(state as u64, core::ptr::null(), 0) };
if res != TEE_SUCCESS as usize {
TEE_FreeTransientObject(op_handle.key1);
TEE_FreeTransientObject(op_handle.key2);
TEE_Free(operation_ptr);
return res as TEE_Result;
}
op_handle.operation_state |= TEE_HANDLE_FLAG_INITIALIZED;
}
op_handle.operation_state = TEE_OPERATION_STATE_INITIAL;
unsafe {
*operation = operation_ptr as *mut TEE_OperationHandle;
}
TEE_SUCCESS
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_FreeOperation(operation: *mut TEE_OperationHandle) {
use crate::tee_api_defines::*;
if operation.is_null() {
return;
}
let op_handle = unsafe { &*operation };
if !op_handle.buffer.is_null() {
TEE_Free(op_handle.buffer as *mut core::ffi::c_void);
}
let res = unsafe { _utee_cryp_state_free(op_handle.state as u64) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_GetOperationInfo(
operation: *mut TEE_OperationHandle,
operationInfo: *mut TEE_OperationInfo,
) {
use crate::tee_api_defines::*;
if operation.is_null() {
TEE_Panic(0);
}
if operationInfo.is_null() {
TEE_Panic(0);
}
if cfg!(feature = "strict_annotation_checks") {
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
operationInfo as *mut core::ffi::c_void,
std::mem::size_of::<TEE_OperationInfo>(),
);
if res != 0 {
eprintln!("[out] operationInfo: error {:#010x}", res);
TEE_Panic(0);
}
}
let op_handle = unsafe { &*operation };
unsafe {
*operationInfo = op_handle.info;
}
unsafe {
if (*operationInfo).handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS != 0 {
(*operationInfo).keySize = 0;
(*operationInfo).requiredKeyUsage = 0;
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_GetOperationInfoMultiple(
operation: *mut TEE_OperationHandle,
op_info: *mut TEE_OperationInfoMultiple,
size: *mut usize,
) -> TEE_Result {
use crate::tee_api_defines::*;
if operation.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_info.is_null() || size.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if cfg!(feature = "strict_annotation_checks") {
let buffer_size = unsafe { *size };
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
op_info as *mut core::ffi::c_void,
buffer_size,
);
if res != 0 {
eprintln!("[out] op_info: error {:#010x}", res);
TEE_Panic(0);
}
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
size as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if res != 0 {
eprintln!("[out] size: error {:#010x}", res);
TEE_Panic(0);
}
}
let op_info_size = std::mem::size_of::<TEE_OperationInfoMultiple>();
let buffer_size = unsafe { *size };
if buffer_size < op_info_size {
return TEE_ERROR_BAD_PARAMETERS;
}
let key_info_size = std::mem::size_of::<TEE_OperationInfoKey>();
let max_key_count = (buffer_size - op_info_size) / key_info_size;
TEE_MemFill(op_info as *mut core::ffi::c_void, 0, buffer_size);
let op_handle = unsafe { &mut *operation };
let two_keys = (op_handle.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 0;
let result = if op_handle.info.mode == TEE_MODE_DIGEST {
unsafe {
(*op_info).numberOfKeys = 0;
}
TEE_SUCCESS
} else if !two_keys {
if max_key_count < 1 {
return TEE_ERROR_SHORT_BUFFER;
}
let mut kinfo = TEE_ObjectInfo {
objectType: 0,
objectSize: 0,
maxObjectSize: 0,
objectUsage: 0,
dataSize: 0,
dataPosition: 0,
handleFlags: 0,
};
let res = TEE_GetObjectInfo1(op_handle.key1, &mut kinfo);
if res != TEE_SUCCESS {
return check_operation_info_multiple_result(res);
}
unsafe {
(*op_info)
.keyInformation
.add(0)
.write(TEE_OperationInfoKey {
keySize: kinfo.objectSize,
requiredKeyUsage: op_handle.info.requiredKeyUsage,
});
(*op_info).numberOfKeys = 1;
}
TEE_SUCCESS
} else {
if max_key_count < 2 {
return TEE_ERROR_SHORT_BUFFER;
}
let mut kinfo = TEE_ObjectInfo {
objectType: 0,
objectSize: 0,
maxObjectSize: 0,
objectUsage: 0,
dataSize: 0,
dataPosition: 0,
handleFlags: 0,
};
let res = TEE_GetObjectInfo1(op_handle.key1, &mut kinfo);
if res != TEE_SUCCESS {
return check_operation_info_multiple_result(res);
}
unsafe {
(*op_info)
.keyInformation
.add(0)
.write(TEE_OperationInfoKey {
keySize: kinfo.objectSize,
requiredKeyUsage: op_handle.info.requiredKeyUsage,
});
}
let res = TEE_GetObjectInfo1(op_handle.key2, &mut kinfo);
if res != TEE_SUCCESS {
return check_operation_info_multiple_result(res);
}
unsafe {
(*op_info)
.keyInformation
.add(1)
.write(TEE_OperationInfoKey {
keySize: kinfo.objectSize,
requiredKeyUsage: op_handle.info.requiredKeyUsage,
});
(*op_info).numberOfKeys = 2;
}
TEE_SUCCESS
};
if result == TEE_SUCCESS {
unsafe {
(*op_info).algorithm = op_handle.info.algorithm;
(*op_info).operationClass = op_handle.info.operationClass;
(*op_info).mode = op_handle.info.mode;
(*op_info).digestLength = op_handle.info.digestLength;
(*op_info).maxKeySize = op_handle.info.maxKeySize;
(*op_info).handleState = op_handle.info.handleState;
(*op_info).operationState = op_handle.operation_state;
}
}
check_operation_info_multiple_result(result)
}
fn check_operation_info_multiple_result(res: TEE_Result) -> TEE_Result {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
res
}
fn reset_operation_state(operation: &mut TEE_OperationHandle) {
operation.operation_state = TEE_OPERATION_STATE_INITIAL;
operation.buffer_offs = 0;
if operation.info.operationClass == TEE_OPERATION_DIGEST {
let res = unsafe { _utee_hash_init(operation.state as u64, core::ptr::null(), 0) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
operation.info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
} else {
operation.info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_ResetOperation(operation: *mut TEE_OperationHandle) {
if operation.is_null() {
TEE_Panic(TEE_PANIC_ID_TEE_RESETOPERATION);
}
let op_handle = unsafe { &*operation };
if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) != 0 {
TEE_Panic(0);
}
unsafe {
reset_operation_state(&mut *operation);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_SetOperationKey(
operation: *mut TEE_OperationHandle,
key: TEE_ObjectHandle,
) -> TEE_Result {
if operation.is_null() {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &mut *operation };
if key.is_null() {
TEE_ResetTransientObject(op_handle.key1);
op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
reset_operation_state(op_handle);
}
return TEE_SUCCESS;
}
if op_handle.info.operationClass == TEE_OPERATION_DIGEST {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_BAD_PARAMETERS;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 0 {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_BAD_PARAMETERS;
}
let mut key_info = TEE_ObjectInfo {
objectType: 0,
objectSize: 0,
maxObjectSize: 0,
objectUsage: 0,
dataSize: 0,
dataPosition: 0,
handleFlags: 0,
};
let res = TEE_GetObjectInfo1(key, &mut key_info);
if res != TEE_SUCCESS {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_BAD_PARAMETERS;
}
if (key_info.objectUsage & op_handle.info.requiredKeyUsage) != op_handle.info.requiredKeyUsage {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_SECURITY;
}
if op_handle.info.maxKeySize < key_info.objectSize {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_BAD_PARAMETERS;
}
TEE_ResetTransientObject(op_handle.key1);
op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
let res = TEE_CopyObjectAttributes1(op_handle.key1, key);
if res != TEE_SUCCESS {
TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
return TEE_ERROR_BAD_PARAMETERS;
}
op_handle.info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
op_handle.info.keySize = key_info.objectSize;
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
reset_operation_state(op_handle);
}
TEE_SUCCESS
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_SetOperationKey2(
operation: *mut TEE_OperationHandle,
key1: TEE_ObjectHandle,
key2: TEE_ObjectHandle,
) -> TEE_Result {
if operation.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &mut *operation };
if !operation.is_null() && !key1.is_null() && !key2.is_null() && key1 == key2 {
return TEE_ERROR_SECURITY;
}
if key1.is_null() && key2.is_null() {
TEE_ResetTransientObject(op_handle.key1);
TEE_ResetTransientObject(op_handle.key2);
op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
reset_operation_state(op_handle);
}
return TEE_SUCCESS;
} else if key1.is_null() || key2.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.operationClass == TEE_OPERATION_DIGEST {
return TEE_ERROR_BAD_PARAMETERS;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
let mut key_info1 = TEE_ObjectInfo {
objectType: 0,
objectSize: 0,
maxObjectSize: 0,
objectUsage: 0,
dataSize: 0,
dataPosition: 0,
handleFlags: 0,
};
let mut res = TEE_GetObjectInfo1(key1, &mut key_info1);
if res != TEE_SUCCESS {
return handle_result_error(res);
}
if (key_info1.objectUsage & op_handle.info.requiredKeyUsage) != op_handle.info.requiredKeyUsage
{
return TEE_ERROR_BAD_PARAMETERS;
}
let mut key_info2 = TEE_ObjectInfo {
objectType: 0,
objectSize: 0,
maxObjectSize: 0,
objectUsage: 0,
dataSize: 0,
dataPosition: 0,
handleFlags: 0,
};
res = TEE_GetObjectInfo1(key2, &mut key_info2);
if res != TEE_SUCCESS {
return if res == TEE_ERROR_CORRUPT_OBJECT {
TEE_ERROR_CORRUPT_OBJECT_2
} else {
handle_result_error(res)
};
}
if (key_info2.objectUsage & op_handle.info.requiredKeyUsage) != op_handle.info.requiredKeyUsage
{
return TEE_ERROR_BAD_PARAMETERS;
}
if key_info1.objectSize != key_info2.objectSize {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.maxKeySize < key_info1.objectSize {
return TEE_ERROR_BAD_PARAMETERS;
}
TEE_ResetTransientObject(op_handle.key1);
TEE_ResetTransientObject(op_handle.key2);
op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
res = TEE_CopyObjectAttributes1(op_handle.key1, key1);
if res != TEE_SUCCESS {
return handle_result_error(res);
}
res = TEE_CopyObjectAttributes1(op_handle.key2, key2);
if res != TEE_SUCCESS {
return if res == TEE_ERROR_CORRUPT_OBJECT {
TEE_ERROR_CORRUPT_OBJECT_2
} else {
handle_result_error(res)
};
}
op_handle.info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
op_handle.info.keySize = key_info1.objectSize;
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
reset_operation_state(op_handle);
}
TEE_SUCCESS
}
fn handle_result_error(res: TEE_Result) -> TEE_Result {
match res {
TEE_SUCCESS => TEE_SUCCESS,
TEE_ERROR_CORRUPT_OBJECT => TEE_ERROR_CORRUPT_OBJECT,
TEE_ERROR_CORRUPT_OBJECT_2 => TEE_ERROR_CORRUPT_OBJECT_2,
TEE_ERROR_STORAGE_NOT_AVAILABLE => TEE_ERROR_STORAGE_NOT_AVAILABLE,
TEE_ERROR_STORAGE_NOT_AVAILABLE_2 => TEE_ERROR_STORAGE_NOT_AVAILABLE_2,
_ => {
TEE_Panic(res as u32);
res
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_CopyOperation(
dst_op: *mut TEE_OperationHandle,
src_op: *mut TEE_OperationHandle,
) {
if dst_op.is_null() || src_op.is_null() {
TEE_Panic(0);
}
let (dst_ref, src_ref) = unsafe { (&mut *dst_op, &*src_op) };
if dst_ref.info.algorithm != src_ref.info.algorithm {
TEE_Panic(0);
}
if dst_ref.info.mode != src_ref.info.mode {
TEE_Panic(0);
}
if src_ref.info.operationClass != TEE_OPERATION_DIGEST {
let (key1, key2) = if (src_ref.info.handleState & TEE_HANDLE_FLAG_KEY_SET) != 0 {
(src_ref.key1, src_ref.key2)
} else {
(ptr::null_mut(), ptr::null_mut())
};
if (src_ref.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0 {
TEE_SetOperationKey(dst_op, key1);
} else {
let res = TEE_SetOperationKey2(dst_op, key1, key2);
if res != TEE_SUCCESS {
TEE_Panic(res as u32);
}
}
}
dst_ref.info.handleState = src_ref.info.handleState;
dst_ref.info.keySize = src_ref.info.keySize;
dst_ref.info.digestLength = src_ref.info.digestLength;
dst_ref.operation_state = src_ref.operation_state;
if dst_ref.buffer_two_blocks != src_ref.buffer_two_blocks
|| dst_ref.block_size != src_ref.block_size
{
TEE_Panic(0);
}
if !dst_ref.buffer.is_null() {
if src_ref.buffer.is_null() {
TEE_Panic(0);
}
let sz = if src_ref.buffer_two_blocks {
src_ref.block_size * 2
} else {
src_ref.block_size
};
unsafe {
std::ptr::copy_nonoverlapping(src_ref.buffer, dst_ref.buffer, sz);
}
dst_ref.buffer_offs = src_ref.buffer_offs;
} else if !src_ref.buffer.is_null() {
TEE_Panic(0);
}
let res = unsafe { _utee_cryp_state_copy(dst_ref.state as u64, src_ref.state as u64) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
fn init_hash_operation(
operation: *mut TEE_OperationHandle,
iv: *const core::ffi::c_void,
iv_len: u32,
) {
if operation.is_null() {
TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
return;
}
let res = unsafe { _utee_hash_init((*operation).state as u64, iv, iv_len as usize) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
unsafe {
(*operation).buffer_offs = 0;
(*operation).info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_DigestUpdate(
operation: *mut TEE_OperationHandle,
chunk: *const core::ffi::c_void,
chunk_size: usize,
) {
if operation.is_null() {
TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
return;
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_DIGEST {
TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
return;
}
op_handle.operation_state = TEE_OPERATION_STATE_ACTIVE;
let res = unsafe { _utee_hash_update(op_handle.state as u64, chunk, chunk_size) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_DigestDoFinal(
operation: *mut TEE_OperationHandle,
chunk: *const core::ffi::c_void,
chunk_len: usize,
hash: *mut core::ffi::c_void,
hash_len: *mut usize,
) -> TEE_Result {
if operation.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
if chunk.is_null() && chunk_len > 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_DIGEST {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.operation_state == TEE_OPERATION_STATE_EXTRACTING && chunk_len > 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
if hash_len.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if cfg!(feature = "strict_annotation_checks") {
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
hash_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if res != 0 {
eprintln!("[inout] hash_len: error {:#010x}", res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
let res = if op_handle.operation_state == TEE_OPERATION_STATE_EXTRACTING
&& !op_handle.buffer.is_null()
{
let len = std::cmp::min(op_handle.block_size - op_handle.buffer_offs, unsafe {
*hash_len
});
unsafe {
std::ptr::copy_nonoverlapping(
op_handle.buffer.add(op_handle.buffer_offs),
hash as *mut u8,
len,
);
*hash_len = len;
}
TEE_SUCCESS
} else {
let mut hl = unsafe { *hash_len as u64 };
let res =
unsafe { _utee_hash_final(op_handle.state as u64, chunk, chunk_len, hash, &mut hl) };
unsafe {
*hash_len = hl as usize;
}
if res != TEE_SUCCESS as usize {
return res as TEE_Result;
}
TEE_SUCCESS
};
init_hash_operation(operation, core::ptr::null(), 0);
unsafe {
(*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
}
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_DigestExtract(
operation: *mut TEE_OperationHandle,
hash: *mut core::ffi::c_void,
hash_len: *mut usize,
) -> TEE_Result {
if operation.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &mut *operation };
if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 {
TEE_Panic(0);
}
unsafe {
reset_operation_state(&mut *operation);
}
if op_handle.info.operationClass != TEE_OPERATION_DIGEST {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if hash_len.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if cfg!(feature = "strict_annotation_checks") {
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
hash_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if res != 0 {
eprintln!("[inout] hash_len: error {:#010x}", res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
if op_handle.buffer.is_null() {
unsafe {
(*operation).info.handleState |= TEE_HANDLE_FLAG_EXTRACTING;
(*operation).operation_state = TEE_OPERATION_STATE_EXTRACTING;
}
let mut hl = unsafe { *hash_len as u64 };
let res = unsafe {
_utee_hash_final(op_handle.state as u64, core::ptr::null(), 0, hash, &mut hl)
};
if res != TEE_SUCCESS as usize {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
unsafe {
*hash_len = hl as usize;
}
return TEE_SUCCESS;
}
if op_handle.operation_state != TEE_OPERATION_STATE_EXTRACTING {
let mut hl = op_handle.block_size as u64;
let res = unsafe {
_utee_hash_final(
op_handle.state as u64,
core::ptr::null(),
0,
op_handle.buffer as *mut core::ffi::c_void,
&mut hl,
)
};
if res != TEE_SUCCESS as usize {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if hl as usize != op_handle.block_size {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
debug_assert!(op_handle.buffer_offs == 0, "buffer_offs should be 0");
unsafe {
(*operation).info.handleState |= TEE_HANDLE_FLAG_EXTRACTING;
(*operation).operation_state = TEE_OPERATION_STATE_EXTRACTING;
}
}
let len = std::cmp::min(op_handle.block_size - op_handle.buffer_offs, unsafe {
*hash_len
});
unsafe {
std::ptr::copy_nonoverlapping(
op_handle.buffer.add(op_handle.buffer_offs),
hash as *mut u8,
len,
);
*hash_len = len;
}
unsafe {
(*operation).buffer_offs += len;
}
TEE_SUCCESS
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_CipherInit(
operation: *mut TEE_OperationHandle,
iv: *const core::ffi::c_void,
iv_len: usize,
) {
use crate::tee_api_defines::*;
if operation.is_null() {
TEE_Panic(0);
return;
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_CIPHER {
TEE_Panic(0);
return;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 || op_handle.key1.is_null() {
TEE_Panic(0);
return;
}
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
TEE_ResetOperation(operation);
}
if !iv.is_null() && iv_len > 0 {
match op_handle.info.algorithm {
TEE_ALG_AES_ECB_NOPAD
| TEE_ALG_DES_ECB_NOPAD
| TEE_ALG_DES3_ECB_NOPAD
| TEE_ALG_SM4_ECB_NOPAD => {
TEE_Panic(0);
return;
}
_ => {}
}
}
unsafe {
(*operation).operation_state = TEE_OPERATION_STATE_ACTIVE;
}
let res = unsafe { _utee_cipher_init(op_handle.state as u64, iv, iv_len) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
return;
}
unsafe {
(*operation).buffer_offs = 0;
(*operation).info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
}
}
const fn roundup2(v: usize, r: usize) -> usize {
(v + r - 1) & !(r - 1)
}
type UpdateFunc = unsafe extern "C" fn(
state: u64,
src: *const core::ffi::c_void,
slen: usize,
dst: *mut core::ffi::c_void,
dlen: *mut u64,
) -> usize;
fn tee_buffer_update(
op: &mut TEE_OperationHandle,
update_func: UpdateFunc,
src_data: *const core::ffi::c_void,
mut src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut u64,
) -> TEE_Result {
use crate::tee_api_defines::*;
if src_data.is_null() {
if src_len > 0 {
TEE_Panic(0);
}
unsafe {
*dest_len = 0;
}
return TEE_SUCCESS;
}
let mut src = src_data as *const u8;
let mut dst = dest_data as *mut u8;
let mut dlen = unsafe { *dest_len } as usize;
let mut acc_dlen = 0usize;
let (buffer_size, buffer_left) = if op.buffer_two_blocks {
(op.block_size * 2, 1usize)
} else {
(op.block_size, 0usize)
};
if op.buffer_offs > 0 {
let l = if op.buffer_offs < op.block_size {
std::cmp::min(src_len, op.block_size - op.buffer_offs)
} else {
std::cmp::min(src_len, buffer_size - op.buffer_offs)
};
unsafe {
std::ptr::copy_nonoverlapping(src, op.buffer.add(op.buffer_offs), l);
}
op.buffer_offs += l;
src = unsafe { src.add(l) };
src_len -= l;
if op.buffer_offs % op.block_size != 0 {
unsafe {
*dest_len = acc_dlen as u64;
}
return TEE_SUCCESS;
}
}
if op.buffer_offs > 0 && op.buffer_offs + src_len >= buffer_size + buffer_left {
let mut l = roundup2(op.buffer_offs + src_len - buffer_size, op.block_size);
l = std::cmp::min(op.buffer_offs, l);
if !op.buffer_two_blocks {
l = op.block_size;
}
let mut tmp_dlen = dlen as u64;
let res = unsafe {
update_func(
op.state as u64,
op.buffer as *const core::ffi::c_void,
l,
dst as *mut core::ffi::c_void,
&mut tmp_dlen,
)
};
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
let tmp_dlen = tmp_dlen as usize;
unsafe {
dst = dst.add(tmp_dlen);
}
dlen -= tmp_dlen;
acc_dlen += tmp_dlen;
op.buffer_offs -= l;
if op.buffer_offs > 0 {
unsafe {
std::ptr::copy(op.buffer.add(l), op.buffer, buffer_size - l);
std::ptr::copy_nonoverlapping(src, op.buffer.add(op.buffer_offs), src_len);
}
op.buffer_offs += src_len;
unsafe {
*dest_len = acc_dlen as u64;
}
return TEE_SUCCESS;
}
}
if src_len >= buffer_size + buffer_left {
let l = if op.buffer_two_blocks {
roundup2(src_len - buffer_size, op.block_size)
} else {
roundup2(src_len - buffer_size + 1, op.block_size)
};
let mut tmp_dlen = dlen as u64;
let res = unsafe {
update_func(
op.state as u64,
src as *const core::ffi::c_void,
l,
dst as *mut core::ffi::c_void,
&mut tmp_dlen,
)
};
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
let tmp_dlen = tmp_dlen as usize;
unsafe {
src = src.add(l);
}
src_len -= l;
acc_dlen += tmp_dlen;
}
unsafe {
std::ptr::copy_nonoverlapping(src, op.buffer.add(op.buffer_offs), src_len);
}
op.buffer_offs += src_len;
unsafe {
*dest_len = acc_dlen as u64;
}
TEE_SUCCESS
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_CipherUpdate(
operation: *mut TEE_OperationHandle,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
) -> TEE_Result {
if operation.is_null() || (src_data.is_null() && src_len > 0) {
return TEE_ERROR_BAD_PARAMETERS;
}
if cfg!(feature = "strict_annotation_checks") {
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if res != 0 {
eprintln!("[inout] destLen: error {:#010x}", res);
return TEE_ERROR_BAD_PARAMETERS;
}
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_CIPHER {
return TEE_ERROR_BAD_PARAMETERS;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
return TEE_ERROR_BAD_PARAMETERS;
}
if src_data.is_null() && src_len == 0 {
unsafe {
*dest_len = 0;
}
return TEE_SUCCESS;
}
let req_dlen = if op_handle.block_size > 1 {
let base =
((op_handle.buffer_offs + src_len) / op_handle.block_size) * op_handle.block_size;
if op_handle.buffer_two_blocks {
if op_handle.buffer_offs + src_len > op_handle.block_size * 2 {
let req = op_handle.buffer_offs + src_len - op_handle.block_size * 2;
roundup2(req, op_handle.block_size)
} else {
0
}
} else {
base
}
} else {
src_len
};
unsafe {
if *dest_len < req_dlen {
*dest_len = req_dlen;
let res = TEE_ERROR_SHORT_BUFFER;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
}
let mut dl = unsafe { *dest_len } as u64;
let res = if op_handle.block_size > 1 {
tee_buffer_update(
op_handle,
_utee_cipher_update,
src_data,
src_len,
dest_data,
&mut dl,
)
} else {
if src_len > 0 {
unsafe {
_utee_cipher_update(
op_handle.state as u64,
src_data,
src_len,
dest_data,
&mut dl,
) as TEE_Result
}
} else {
dl = 0;
TEE_SUCCESS
}
};
unsafe {
*dest_len = dl as usize;
}
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_CipherDoFinal(
operation: *mut TEE_OperationHandle,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
) -> TEE_Result {
if operation.is_null() || (src_data.is_null() && src_len > 0) {
return TEE_ERROR_BAD_PARAMETERS;
}
if !dest_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] destLen: error {:#010x}", check_res);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_CIPHER {
return TEE_ERROR_BAD_PARAMETERS;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
return TEE_ERROR_BAD_PARAMETERS;
}
match op_handle.info.algorithm {
TEE_ALG_AES_ECB_NOPAD
| TEE_ALG_AES_CBC_NOPAD
| TEE_ALG_DES_ECB_NOPAD
| TEE_ALG_DES_CBC_NOPAD
| TEE_ALG_DES3_ECB_NOPAD
| TEE_ALG_DES3_CBC_NOPAD
| TEE_ALG_SM4_ECB_NOPAD
| TEE_ALG_SM4_CBC_NOPAD => {
if (op_handle.buffer_offs + src_len) % op_handle.block_size != 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
}
_ => {}
}
let req_dlen = if op_handle.block_size > 1 {
op_handle.buffer_offs + src_len
} else {
src_len
};
let mut tmp_dlen = if !dest_len.is_null() {
unsafe { *dest_len as u64 }
} else {
0u64
};
if tmp_dlen < req_dlen as u64 {
if !dest_len.is_null() {
unsafe {
*dest_len = req_dlen;
}
}
let res = TEE_ERROR_SHORT_BUFFER;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
let mut res = TEE_SUCCESS;
let mut dst = dest_data as *mut u8;
let mut acc_dlen = 0usize;
if op_handle.block_size > 1 {
if src_len > 0 {
res = tee_buffer_update(
unsafe { &mut *operation },
_utee_cipher_update,
src_data,
src_len,
dest_data,
&mut tmp_dlen,
);
if res != TEE_SUCCESS {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
let tmp_dlen_usize = tmp_dlen as usize;
unsafe {
dst = dst.add(tmp_dlen_usize);
}
acc_dlen += tmp_dlen_usize;
if !dest_len.is_null() {
unsafe {
tmp_dlen = *dest_len as u64 - acc_dlen as u64;
}
}
}
res = unsafe {
_utee_cipher_final(
op_handle.state as u64,
src_data,
src_len,
dest_data,
dest_len as _,
) as TEE_Result
};
} else {
res = unsafe {
_utee_cipher_final(
op_handle.state as u64,
src_data,
src_len,
dest_data,
dest_len as _,
) as TEE_Result
};
}
if res != TEE_SUCCESS {
if res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
unsafe {
(*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
(*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MACInit(
operation: *mut TEE_OperationHandle,
iv: *const core::ffi::c_void,
iv_len: usize,
) {
if operation.is_null() {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
let op_handle = unsafe { &*operation };
if op_handle.info.operationClass != TEE_OPERATION_MAC {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 || op_handle.key1.is_null() {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
TEE_ResetOperation(operation);
}
unsafe {
(*operation).operation_state = TEE_OPERATION_STATE_ACTIVE;
}
init_hash_operation(operation, iv, iv_len as u32);
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MACUpdate(
operation: *mut TEE_OperationHandle,
chunk: *const core::ffi::c_void,
chunk_size: usize,
) {
if operation.is_null() {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
if chunk.is_null() && chunk_size > 0 {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
let op_handle = unsafe { &*operation };
if op_handle.info.operationClass != TEE_OPERATION_MAC {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
return;
}
let res = unsafe { _utee_hash_update(op_handle.state as u64, chunk, chunk_size) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MACComputeFinal(
operation: *mut TEE_OperationHandle,
message: *const core::ffi::c_void,
message_len: usize,
mac: *mut core::ffi::c_void,
mac_len: *mut usize,
) -> TEE_Result {
if operation.is_null()
|| (!message.is_null() && message_len == 0)
|| (message.is_null() && message_len > 0)
{
return TEE_ERROR_BAD_PARAMETERS;
}
if cfg!(feature = "strict_annotation_checks") {
let res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
mac_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if res != 0 {
eprintln!("[inout] mac_len: error {:#010x}", res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_MAC {
return TEE_ERROR_BAD_PARAMETERS;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
return TEE_ERROR_BAD_PARAMETERS;
}
let mut ml = unsafe { *mac_len as u64 };
let res =
unsafe { _utee_hash_final(op_handle.state as u64, message, message_len, mac, &mut ml) };
unsafe {
*mac_len = ml as usize;
}
if res != TEE_SUCCESS as usize {
let result = res as TEE_Result;
if result != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(result as u32);
}
return result;
}
unsafe {
(*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
(*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
}
TEE_SUCCESS as TEE_Result
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MACCompareFinal(
operation: *mut TEE_OperationHandle,
message: *const core::ffi::c_void,
message_len: usize,
mac: *const core::ffi::c_void,
mac_len: usize,
) -> TEE_Result {
if operation.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_MAC {
return TEE_ERROR_BAD_PARAMETERS;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
return TEE_ERROR_BAD_PARAMETERS;
}
let mut computed_mac = [0u8; TEE_MAX_HASH_SIZE as usize];
let mut computed_mac_size = TEE_MAX_HASH_SIZE as usize;
let res = TEE_MACComputeFinal(
operation,
message,
message_len,
computed_mac.as_mut_ptr() as *mut core::ffi::c_void,
&mut computed_mac_size,
);
if res != TEE_SUCCESS {
if res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
if computed_mac_size != mac_len {
return TEE_ERROR_MAC_INVALID;
}
let provided_mac = unsafe { std::slice::from_raw_parts(mac as *const u8, mac_len) };
if !consttime_memcmp(provided_mac, &computed_mac[..computed_mac_size]) {
return TEE_ERROR_MAC_INVALID;
}
unsafe {
(*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
}
TEE_SUCCESS
}
fn consttime_memcmp(a: &[u8], b: &[u8]) -> bool {
if a.len() != b.len() {
return false;
}
let mut result = 0u8;
for (x, y) in a.iter().zip(b.iter()) {
result |= x ^ y;
}
result == 0
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AEInit(
operation: *mut TEE_OperationHandle,
nonce: *const core::ffi::c_void,
nonce_len: usize,
tag_len: u32,
aad_len: usize,
payload_len: usize,
) -> TEE_Result {
if operation.is_null() || nonce.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &mut *operation };
if op_handle.info.operationClass != TEE_OPERATION_AE {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.algorithm == TEE_ALG_AES_GCM {
if tag_len < 96 || tag_len > 128 || (tag_len % 8 != 0) {
return TEE_ERROR_NOT_SUPPORTED;
}
}
let res = unsafe {
_utee_authenc_init(
op_handle.state as u64,
nonce,
nonce_len,
tag_len as usize / 8, aad_len,
payload_len,
)
};
if res != TEE_SUCCESS as usize {
let result = res as TEE_Result;
if result != TEE_ERROR_NOT_SUPPORTED {
TEE_Panic(result as u32);
}
return result;
}
unsafe {
(*operation).info.digestLength = (tag_len / 8) as u32; (*operation).buffer_offs = 0;
(*operation).info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
}
TEE_SUCCESS
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AEUpdateAAD(
operation: *mut TEE_OperationHandle,
aad_data: *const core::ffi::c_void,
aad_data_len: usize,
) {
if operation.is_null() || (aad_data.is_null() && aad_data_len > 0) {
TEE_Panic(0);
return;
}
let op_handle = unsafe { &*operation };
if op_handle.info.operationClass != TEE_OPERATION_AE {
TEE_Panic(0);
return;
}
if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
TEE_Panic(0);
return;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
TEE_Panic(0);
return;
}
let res = unsafe { _utee_authenc_update_aad(op_handle.state as u64, aad_data, aad_data_len) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
fn ae_update_helper(
operation: *mut TEE_OperationHandle,
src: *const core::ffi::c_void,
slen: usize,
dst: *mut core::ffi::c_void,
dlen: *mut usize,
) -> TEE_Result {
use crate::tee_api_defines::*;
if src.is_null() && slen == 0 {
unsafe {
*dlen = 0;
}
return TEE_SUCCESS;
}
if operation.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &*operation };
if dlen.is_null() {
return TEE_ERROR_BAD_PARAMETERS;
}
let req_dlen = if op_handle.block_size > 1 {
let total_size = op_handle.buffer_offs + slen;
roundup2(total_size, op_handle.block_size)
} else {
slen
};
let provided_dlen = unsafe { *dlen };
if provided_dlen < req_dlen {
unsafe {
*dlen = req_dlen;
}
return TEE_ERROR_SHORT_BUFFER;
}
let mut dl = provided_dlen as u64;
let res = if op_handle.block_size > 1 {
tee_buffer_update(
unsafe { &mut *operation },
_utee_authenc_update_payload,
src,
slen,
dst,
&mut dl,
)
} else {
if slen > 0 {
unsafe {
_utee_authenc_update_payload(op_handle.state as u64, src, slen, dst, &mut dl)
as TEE_Result
}
} else {
dl = 0;
TEE_SUCCESS
}
};
if res == TEE_SUCCESS {
unsafe {
*dlen = dl as usize;
}
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AEUpdate(
operation: *mut TEE_OperationHandle,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
) -> TEE_Result {
if operation.is_null() || (src_data.is_null() && src_len > 0) {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
if !dest_data.is_null() && !dest_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] destLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
let op_handle = unsafe { &*operation };
if op_handle.info.operationClass != TEE_OPERATION_AE {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
let res = ae_update_helper(operation, src_data, src_len, dest_data, dest_len);
if res != TEE_ERROR_SHORT_BUFFER && src_len > 0 {
unsafe {
(*operation).operation_state = TEE_OPERATION_STATE_ACTIVE;
}
}
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AEEncryptFinal(
operation: *mut TEE_OperationHandle,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
tag: *mut core::ffi::c_void,
tag_len: *mut usize,
) -> TEE_Result {
let mut res = TEE_SUCCESS;
if operation.is_null() || (src_data.is_null() && src_len > 0) {
res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
if !dest_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] destLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
if !tag_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
tag_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] tagLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
let op_handle = unsafe { &*operation };
if op_handle.info.operationClass != TEE_OPERATION_AE {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
if dest_len.is_null() || tag_len.is_null() {
res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
let dest_len_val = unsafe { *dest_len };
let tag_len_val = unsafe { *tag_len };
let req_dlen = op_handle.buffer_offs + src_len;
if dest_len_val < req_dlen {
unsafe {
*dest_len = req_dlen;
}
res = TEE_ERROR_SHORT_BUFFER;
}
if tag_len_val < op_handle.info.digestLength as usize {
unsafe {
*tag_len = op_handle.info.digestLength as usize;
}
res = TEE_ERROR_SHORT_BUFFER;
}
if res == TEE_ERROR_SHORT_BUFFER {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
let mut acc_dlen = 0usize;
let mut tl = tag_len_val as u64;
let mut tmp_dlen = (dest_len_val - acc_dlen) as u64;
let dst = dest_data as *mut u8;
if op_handle.block_size > 1 {
res = tee_buffer_update(
unsafe { &mut *operation },
_utee_authenc_update_payload,
src_data,
src_len,
dest_data,
&mut tmp_dlen,
);
if res != TEE_SUCCESS {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
acc_dlen += tmp_dlen as usize;
tmp_dlen = (dest_len_val - acc_dlen) as u64;
let buffer_ptr = op_handle.buffer as *const core::ffi::c_void;
res = unsafe {
_utee_authenc_enc_final(
op_handle.state as u64,
buffer_ptr,
op_handle.buffer_offs,
dst.add(acc_dlen) as *mut core::ffi::c_void,
&mut tmp_dlen,
tag,
&mut tl,
) as TEE_Result
};
} else {
res = unsafe {
_utee_authenc_enc_final(
op_handle.state as u64,
src_data,
src_len,
dst as *mut core::ffi::c_void,
&mut tmp_dlen,
tag,
&mut tl,
) as TEE_Result
};
}
unsafe {
*tag_len = tl as usize;
}
if res != TEE_SUCCESS {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
return res;
}
acc_dlen += tmp_dlen as usize;
unsafe {
*dest_len = acc_dlen;
}
unsafe {
(*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
(*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
}
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AEDecryptFinal(
operation: *mut TEE_OperationHandle,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
tag: *const core::ffi::c_void,
tag_len: usize,
) -> TEE_Result {
let mut res = TEE_SUCCESS;
if operation.is_null() || (src_data.is_null() && src_len > 0) {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
if !dest_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] destLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
} else {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
let op_handle = unsafe { &*operation };
if op_handle.info.operationClass != TEE_OPERATION_AE {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
let res = TEE_ERROR_BAD_PARAMETERS;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
let req_dlen = op_handle.buffer_offs + src_len;
let dest_len_val = unsafe { *dest_len };
if dest_len_val < req_dlen {
unsafe {
*dest_len = req_dlen;
}
let res = TEE_ERROR_SHORT_BUFFER;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
let mut acc_dlen = 0usize;
let mut tmp_dlen = (dest_len_val - acc_dlen) as u64;
let dst = dest_data as *mut u8;
if op_handle.block_size > 1 {
res = tee_buffer_update(
unsafe { &mut *operation },
_utee_authenc_update_payload,
src_data,
src_len,
dest_data,
&mut tmp_dlen,
);
if res != TEE_SUCCESS {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
acc_dlen += tmp_dlen as usize;
tmp_dlen = (dest_len_val - acc_dlen) as u64;
let buffer_ptr = op_handle.buffer as *const core::ffi::c_void;
res = unsafe {
_utee_authenc_dec_final(
op_handle.state as u64,
buffer_ptr,
op_handle.buffer_offs,
dst.add(acc_dlen) as *mut core::ffi::c_void,
&mut tmp_dlen,
tag,
tag_len,
) as TEE_Result
};
} else {
res = unsafe {
_utee_authenc_dec_final(
op_handle.state as u64,
src_data,
src_len,
dst as *mut core::ffi::c_void,
&mut tmp_dlen,
tag,
tag_len,
) as TEE_Result
};
}
if res != TEE_SUCCESS {
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
return res;
}
acc_dlen += tmp_dlen as usize;
unsafe {
*dest_len = acc_dlen;
}
unsafe {
(*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
(*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
}
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AsymmetricEncrypt(
operation: *mut TEE_OperationHandle,
params: *const TEE_Attribute,
param_count: u32,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
) -> TEE_Result {
let mut res = TEE_SUCCESS;
if operation.is_null() || (src_data.is_null() && src_len > 0) {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if !params.is_null() && param_count > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
params as *mut core::ffi::c_void,
(param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
);
if check_res != 0 {
eprintln!("[in] params: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
if !dest_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] destLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
} else {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &*operation };
if op_handle.key1.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.mode != TEE_MODE_ENCRYPT {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let mut dl = unsafe { *dest_len as u64 };
let mut ua = Vec::with_capacity(param_count as usize);
ua.resize(
param_count as usize,
crate::utee_types::utee_attribute::default(),
);
unsafe {
__utee_from_attr(ua.as_mut_ptr(), params, param_count);
}
let syscall_res = unsafe {
_utee_asymm_operate(
op_handle.state as u64,
ua.as_ptr(),
param_count as u64,
src_data,
src_len,
dest_data,
&mut dl,
)
};
unsafe {
*dest_len = dl as usize;
}
res = syscall_res as TEE_Result;
if res != TEE_SUCCESS
&& res != TEE_ERROR_SHORT_BUFFER
&& res != TEE_ERROR_BAD_PARAMETERS
&& res != TEE_ERROR_CIPHERTEXT_INVALID
&& res != TEE_ERROR_NOT_SUPPORTED
{
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AsymmetricDecrypt(
operation: *mut TEE_OperationHandle,
params: *const TEE_Attribute,
param_count: u32,
src_data: *const core::ffi::c_void,
src_len: usize,
dest_data: *mut core::ffi::c_void,
dest_len: *mut usize,
) -> TEE_Result {
let mut res = TEE_SUCCESS;
if operation.is_null() || (src_data.is_null() && src_len > 0) {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if !params.is_null() && param_count > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
params as *mut core::ffi::c_void,
(param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
);
if check_res != 0 {
eprintln!("[in] params: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
if !dest_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
dest_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] destLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
} else {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &*operation };
if op_handle.key1.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.mode != TEE_MODE_DECRYPT {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let mut dl = unsafe { *dest_len as u64 };
let mut ua = Vec::with_capacity(param_count as usize);
ua.resize(
param_count as usize,
crate::utee_types::utee_attribute::default(),
);
unsafe {
__utee_from_attr(ua.as_mut_ptr(), params, param_count);
}
let syscall_res = unsafe {
_utee_asymm_operate(
op_handle.state as u64,
ua.as_ptr(),
param_count as u64,
src_data,
src_len,
dest_data,
&mut dl,
)
};
unsafe {
*dest_len = dl as usize;
}
res = syscall_res as TEE_Result;
if res != TEE_SUCCESS
&& res != TEE_ERROR_SHORT_BUFFER
&& res != TEE_ERROR_BAD_PARAMETERS
&& res != TEE_ERROR_CIPHERTEXT_INVALID
&& res != TEE_ERROR_NOT_SUPPORTED
{
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AsymmetricSignDigest(
operation: *mut TEE_OperationHandle,
params: *const TEE_Attribute,
param_count: u32,
digest: *const core::ffi::c_void,
digest_len: usize,
signature: *mut core::ffi::c_void,
signature_len: *mut usize,
) -> TEE_Result {
let mut res = TEE_SUCCESS;
if operation.is_null() || (digest.is_null() && digest_len > 0) {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if !params.is_null() && param_count > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
params as *mut core::ffi::c_void,
(param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
);
if check_res != 0 {
eprintln!("[in] params: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
if !signature_len.is_null() {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
signature_len as *mut core::ffi::c_void,
std::mem::size_of::<usize>(),
);
if check_res != 0 {
eprintln!("[inout] signatureLen: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
} else {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let op_handle = unsafe { &*operation };
if op_handle.key1.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.mode != TEE_MODE_SIGN {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let mut sl = unsafe { *signature_len as u64 };
let mut ua = Vec::with_capacity(param_count as usize);
ua.resize(
param_count as usize,
crate::utee_types::utee_attribute::default(),
);
unsafe {
__utee_from_attr(ua.as_mut_ptr(), params, param_count);
}
let syscall_res = unsafe {
_utee_asymm_operate(
op_handle.state as u64,
ua.as_ptr(),
param_count as u64,
digest,
digest_len,
signature,
&mut sl,
)
};
unsafe {
*signature_len = sl as usize;
}
res = syscall_res as TEE_Result;
if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_AsymmetricVerifyDigest(
operation: *mut TEE_OperationHandle,
params: *const TEE_Attribute,
param_count: u32,
digest: *const core::ffi::c_void,
digest_len: usize,
signature: *const core::ffi::c_void,
signature_len: usize,
) -> TEE_Result {
let mut res = TEE_SUCCESS;
if operation.is_null()
|| (digest.is_null() && digest_len != 0)
|| (signature.is_null() && signature_len != 0)
{
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if !params.is_null() && param_count > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
params as *mut core::ffi::c_void,
(param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
);
if check_res != 0 {
eprintln!("[in] params: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
if !digest.is_null() && digest_len > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
digest as *mut core::ffi::c_void,
digest_len,
);
if check_res != 0 {
eprintln!("[in] digest: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
if !signature.is_null() && signature_len > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
signature as *mut core::ffi::c_void,
signature_len,
);
if check_res != 0 {
eprintln!("[in] signature: error {:#010x}", check_res);
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
}
}
let op_handle = unsafe { &*operation };
if op_handle.key1.is_null() {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
if op_handle.info.mode != TEE_MODE_VERIFY {
TEE_Panic(0);
return TEE_ERROR_BAD_PARAMETERS;
}
let mut ua = Vec::with_capacity(param_count as usize);
ua.resize(
param_count as usize,
crate::utee_types::utee_attribute::default(),
);
unsafe {
__utee_from_attr(ua.as_mut_ptr(), params, param_count);
}
let syscall_res = unsafe {
_utee_asymm_verify(
op_handle.state as u64,
ua.as_ptr(),
param_count as u64,
digest,
digest_len,
signature,
signature_len,
)
};
res = syscall_res as TEE_Result;
if res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID {
TEE_Panic(res as u32);
}
res
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_DeriveKey(
operation: *mut TEE_OperationHandle,
params: *const TEE_Attribute,
param_count: u32,
derived_key: TEE_ObjectHandle,
) {
if operation.is_null() || derived_key.is_null() {
TEE_Panic(0);
return;
}
if !params.is_null() && param_count > 0 {
if cfg!(feature = "strict_annotation_checks") {
let check_res = TEE_CheckMemoryAccessRights(
TEE_MEMORY_ACCESS_READ,
params as *mut core::ffi::c_void,
(param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
);
if check_res != 0 {
eprintln!("[in] params: error {:#010x}", check_res);
TEE_Panic(0);
return;
}
}
}
let op_handle = unsafe { &*operation };
if TEE_ALG_GET_CLASS(op_handle.info.algorithm) != TEE_OPERATION_KEY_DERIVATION {
TEE_Panic(0);
return;
}
if op_handle.info.operationClass != TEE_OPERATION_KEY_DERIVATION {
TEE_Panic(0);
return;
}
if op_handle.key1.is_null() {
TEE_Panic(0);
return;
}
if op_handle.info.mode != TEE_MODE_DERIVE {
TEE_Panic(0);
return;
}
if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 {
TEE_Panic(0);
return;
}
let mut key_info = crate::utee_types::utee_object_info::default();
let res = unsafe { _utee_cryp_obj_get_info(derived_key as u64, &mut key_info) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
return;
}
if key_info.obj_type != TEE_TYPE_GENERIC_SECRET {
TEE_Panic(0);
return;
}
if (key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0 {
TEE_Panic(0);
return;
}
let mut ua = Vec::with_capacity(param_count as usize);
ua.resize(
param_count as usize,
crate::utee_types::utee_attribute::default(),
);
unsafe {
__utee_from_attr(ua.as_mut_ptr(), params, param_count);
}
let res = unsafe {
_utee_cryp_derive_key(
op_handle.state as u64,
ua.as_ptr(),
param_count as u64,
derived_key as u64,
)
};
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_GenerateRandom(
random_buffer: *mut core::ffi::c_void,
random_buffer_len: usize,
) {
if random_buffer.is_null() && random_buffer_len > 0 {
TEE_Panic(TEE_ERROR_BAD_PARAMETERS as u32);
return;
}
let res = unsafe { _utee_cryp_random_number_generate(random_buffer, random_buffer_len) };
if res != TEE_SUCCESS as usize {
TEE_Panic(res as u32);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_IsAlgorithmSupported(alg: u32, element: u32) -> TEE_Result {
use crate::tee_api_defines::*;
if alg == TEE_ALG_AES_ECB_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_CBC_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_CTR {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_CTS {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_XTS {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_CBC_MAC_NOPAD || alg == TEE_ALG_AES_CBC_MAC_PKCS5 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_CMAC {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_CCM {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_AES_GCM {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DES_ECB_NOPAD || alg == TEE_ALG_DES3_ECB_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DES_CBC_NOPAD || alg == TEE_ALG_DES3_CBC_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DES_CBC_MAC_NOPAD
|| alg == TEE_ALG_DES_CBC_MAC_PKCS5
|| alg == TEE_ALG_DES3_CBC_MAC_NOPAD
|| alg == TEE_ALG_DES3_CBC_MAC_PKCS5
{
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_MD5 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SHA1 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SHA224 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SHA256 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SHA384 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SHA512 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_MD5SHA1 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_MD5 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_SHA1 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_SHA224 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_SHA256 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_SHA384 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_SHA512 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_HMAC_SM3 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SM3 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SM4_ECB_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SM4_CBC_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_SM4_CTR {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1
|| alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1
|| alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1
{
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224
|| alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224
|| alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224
{
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256
|| alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256
|| alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256
{
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384
|| alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384
|| alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384
{
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512
|| alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512
|| alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512
{
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_RSA_NOPAD {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DSA_SHA1 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DSA_SHA224 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DSA_SHA256 {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if alg == TEE_ALG_DH_DERIVE_SHARED_SECRET {
if element == TEE_CRYPTO_ELEMENT_NONE {
return TEE_SUCCESS;
}
}
if (alg == TEE_ALG_ECDH_P192
|| alg == TEE_ALG_ECDSA_P192
|| alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
&& element == TEE_ECC_CURVE_NIST_P192
{
return TEE_SUCCESS;
}
if (alg == TEE_ALG_ECDH_P224
|| alg == TEE_ALG_ECDSA_P224
|| alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
&& element == TEE_ECC_CURVE_NIST_P224
{
return TEE_SUCCESS;
}
if (alg == TEE_ALG_ECDH_P256
|| alg == TEE_ALG_ECDSA_P256
|| alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
&& element == TEE_ECC_CURVE_NIST_P256
{
return TEE_SUCCESS;
}
if (alg == TEE_ALG_ECDH_P384
|| alg == TEE_ALG_ECDSA_P384
|| alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
&& element == TEE_ECC_CURVE_NIST_P384
{
return TEE_SUCCESS;
}
if (alg == TEE_ALG_ECDH_P521
|| alg == TEE_ALG_ECDSA_P521
|| alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
&& element == TEE_ECC_CURVE_NIST_P521
{
return TEE_SUCCESS;
}
if alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2 {
return TEE_SUCCESS;
}
if alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2 {
return TEE_SUCCESS;
}
if alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2 {
return TEE_SUCCESS;
}
TEE_ERROR_NOT_SUPPORTED
}