// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 */
#include <stdlib.h>
#include <string.h>
#include <string_ext.h>

#include <tee_api.h>
#include <tee_api_defines_extensions.h>
#include <tee_internal_api_extensions.h>
#include <utee_syscalls.h>
#include <utee_defines.h>
#include <util.h>
#include "tee_api_private.h"

struct __TEE_OperationHandle {
	TEE_OperationInfo info;
	TEE_ObjectHandle key1;
	TEE_ObjectHandle key2;
	uint32_t operationState;/* Operation state : INITIAL or ACTIVE */
	uint8_t *buffer;	/* buffer to collect complete blocks */
	bool buffer_two_blocks;	/* True if two blocks need to be buffered */
	size_t block_size;	/* Block size of cipher */
	size_t buffer_offs;	/* Offset in buffer */
	uint32_t state;		/* Handle to state in TEE Core */
	uint32_t ae_tag_len;	/*
				 * tag_len in bytes for AE operation else unused
				 */
};

/* Cryptographic Operations API - Generic Operation Functions */

TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation,
				 uint32_t algorithm, uint32_t mode,
				 uint32_t maxKeySize)
{
	TEE_Result res;
	TEE_OperationHandle op = TEE_HANDLE_NULL;
	uint32_t handle_state = 0;
	size_t block_size = 1;
	uint32_t req_key_usage;
	bool with_private_key = false;
	bool buffer_two_blocks = false;

	if (!operation)
		TEE_Panic(0);

	if (algorithm == TEE_ALG_AES_XTS)
		handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;

	/* Check algorithm max key size */
	switch (algorithm) {
	case TEE_ALG_DSA_SHA1:
		if (maxKeySize < 512)
			return TEE_ERROR_NOT_SUPPORTED;
		if (maxKeySize > 1024)
			return TEE_ERROR_NOT_SUPPORTED;
		if (maxKeySize % 64 != 0)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_DSA_SHA224:
		if (maxKeySize != 2048)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_DSA_SHA256:
		if (maxKeySize != 2048 && maxKeySize != 3072)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_ECDSA_P192:
	case TEE_ALG_ECDH_P192:
		if (maxKeySize != 192)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_ECDSA_P224:
	case TEE_ALG_ECDH_P224:
		if (maxKeySize != 224)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_ECDSA_P256:
	case TEE_ALG_ECDH_P256:
	case TEE_ALG_SM2_PKE:
	case TEE_ALG_SM2_DSA_SM3:
		if (maxKeySize != 256)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_ECDSA_P384:
	case TEE_ALG_ECDH_P384:
		if (maxKeySize != 384)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	case TEE_ALG_ECDSA_P521:
	case TEE_ALG_ECDH_P521:
		if (maxKeySize != 521)
			return TEE_ERROR_NOT_SUPPORTED;
		break;

	default:
		break;
	}

	/* Check algorithm mode */
	switch (algorithm) {
	case TEE_ALG_AES_CTS:
	case TEE_ALG_AES_XTS:
		buffer_two_blocks = true;
		/* FALLTHROUGH */
	case TEE_ALG_AES_ECB_NOPAD:
	case TEE_ALG_AES_CBC_NOPAD:
	case TEE_ALG_AES_CCM:
	case TEE_ALG_DES_ECB_NOPAD:
	case TEE_ALG_DES_CBC_NOPAD:
	case TEE_ALG_DES3_ECB_NOPAD:
	case TEE_ALG_DES3_CBC_NOPAD:
	case TEE_ALG_SM4_ECB_NOPAD:
	case TEE_ALG_SM4_CBC_NOPAD:
	case TEE_ALG_SM4_CTR:
		if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES)
			block_size = TEE_AES_BLOCK_SIZE;
		else if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_SM4)
			block_size = TEE_SM4_BLOCK_SIZE;
		else
			block_size = TEE_DES_BLOCK_SIZE;
		/* FALLTHROUGH */
	case TEE_ALG_AES_CTR:
	case TEE_ALG_AES_GCM:
		if (mode == TEE_MODE_ENCRYPT)
			req_key_usage = TEE_USAGE_ENCRYPT;
		else if (mode == TEE_MODE_DECRYPT)
			req_key_usage = TEE_USAGE_DECRYPT;
		else
			return TEE_ERROR_NOT_SUPPORTED;
		break;

#if defined(CFG_CRYPTO_RSASSA_NA1)
	case TEE_ALG_RSASSA_PKCS1_V1_5:
#endif
	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
	case TEE_ALG_DSA_SHA1:
	case TEE_ALG_DSA_SHA224:
	case TEE_ALG_DSA_SHA256:
	case TEE_ALG_ECDSA_P192:
	case TEE_ALG_ECDSA_P224:
	case TEE_ALG_ECDSA_P256:
	case TEE_ALG_ECDSA_P384:
	case TEE_ALG_ECDSA_P521:
	case TEE_ALG_SM2_DSA_SM3:
		if (mode == TEE_MODE_SIGN) {
			with_private_key = true;
			req_key_usage = TEE_USAGE_SIGN;
		} else if (mode == TEE_MODE_VERIFY) {
			req_key_usage = TEE_USAGE_VERIFY;
		} else {
			return TEE_ERROR_NOT_SUPPORTED;
		}
		break;

	case TEE_ALG_RSAES_PKCS1_V1_5:
	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
	case TEE_ALG_SM2_PKE:
		if (mode == TEE_MODE_ENCRYPT) {
			req_key_usage = TEE_USAGE_ENCRYPT;
		} else if (mode == TEE_MODE_DECRYPT) {
			with_private_key = true;
			req_key_usage = TEE_USAGE_DECRYPT;
		} else {
			return TEE_ERROR_NOT_SUPPORTED;
		}
		break;

	case TEE_ALG_RSA_NOPAD:
		if (mode == TEE_MODE_ENCRYPT) {
			req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY;
		} else if (mode == TEE_MODE_DECRYPT) {
			with_private_key = true;
			req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN;
		} else {
			return TEE_ERROR_NOT_SUPPORTED;
		}
		break;

	case TEE_ALG_DH_DERIVE_SHARED_SECRET:
	case TEE_ALG_ECDH_P192:
	case TEE_ALG_ECDH_P224:
	case TEE_ALG_ECDH_P256:
	case TEE_ALG_ECDH_P384:
	case TEE_ALG_ECDH_P521:
	case TEE_ALG_HKDF_MD5_DERIVE_KEY:
	case TEE_ALG_HKDF_SHA1_DERIVE_KEY:
	case TEE_ALG_HKDF_SHA224_DERIVE_KEY:
	case TEE_ALG_HKDF_SHA256_DERIVE_KEY:
	case TEE_ALG_HKDF_SHA384_DERIVE_KEY:
	case TEE_ALG_HKDF_SHA512_DERIVE_KEY:
	case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY:
	case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY:
	case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY:
	case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY:
	case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY:
	case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY:
		if (mode != TEE_MODE_DERIVE)
			return TEE_ERROR_NOT_SUPPORTED;
		with_private_key = true;
		req_key_usage = TEE_USAGE_DERIVE;
		break;

	case TEE_ALG_MD5:
	case TEE_ALG_SHA1:
	case TEE_ALG_SHA224:
	case TEE_ALG_SHA256:
	case TEE_ALG_SHA384:
	case TEE_ALG_SHA512:
	case TEE_ALG_SM3:
		if (mode != TEE_MODE_DIGEST)
			return TEE_ERROR_NOT_SUPPORTED;
		/* v1.1: flags always set for digest operations */
		handle_state |= TEE_HANDLE_FLAG_KEY_SET;
		req_key_usage = 0;
		break;

	case TEE_ALG_DES_CBC_MAC_NOPAD:
	case TEE_ALG_AES_CBC_MAC_NOPAD:
	case TEE_ALG_AES_CBC_MAC_PKCS5:
	case TEE_ALG_AES_CMAC:
	case TEE_ALG_DES_CBC_MAC_PKCS5:
	case TEE_ALG_DES3_CBC_MAC_NOPAD:
	case TEE_ALG_DES3_CBC_MAC_PKCS5:
	case TEE_ALG_HMAC_MD5:
	case TEE_ALG_HMAC_SHA1:
	case TEE_ALG_HMAC_SHA224:
	case TEE_ALG_HMAC_SHA256:
	case TEE_ALG_HMAC_SHA384:
	case TEE_ALG_HMAC_SHA512:
	case TEE_ALG_HMAC_SM3:
		if (mode != TEE_MODE_MAC)
			return TEE_ERROR_NOT_SUPPORTED;
		req_key_usage = TEE_USAGE_MAC;
		break;

	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO);
	if (!op)
		return TEE_ERROR_OUT_OF_MEMORY;

	op->info.algorithm = algorithm;
	op->info.operationClass = TEE_ALG_GET_CLASS(algorithm);
#ifdef CFG_CRYPTO_RSASSA_NA1
	if (algorithm == TEE_ALG_RSASSA_PKCS1_V1_5)
		op->info.operationClass = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
#endif
	op->info.mode = mode;
	op->info.maxKeySize = maxKeySize;
	op->info.requiredKeyUsage = req_key_usage;
	op->info.handleState = handle_state;

	if (block_size > 1) {
		size_t buffer_size = block_size;

		if (buffer_two_blocks)
			buffer_size *= 2;

		op->buffer = TEE_Malloc(buffer_size,
					TEE_USER_MEM_HINT_NO_FILL_ZERO);
		if (op->buffer == NULL) {
			res = TEE_ERROR_OUT_OF_MEMORY;
			goto out;
		}
	}
	op->block_size = block_size;
	op->buffer_two_blocks = buffer_two_blocks;

	if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) {
		uint32_t mks = maxKeySize;
		TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm,
						       with_private_key);

		/*
		 * If two keys are expected the max key size is the sum of
		 * the size of both keys.
		 */
		if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS)
			mks /= 2;

		res = TEE_AllocateTransientObject(key_type, mks, &op->key1);
		if (res != TEE_SUCCESS)
			goto out;

		if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) {
			res = TEE_AllocateTransientObject(key_type, mks,
							  &op->key2);
			if (res != TEE_SUCCESS)
				goto out;
		}
	}

	res = utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1,
				    (unsigned long)op->key2, &op->state);
	if (res != TEE_SUCCESS)
		goto out;

	/*
	 * Initialize digest operations
	 * Other multi-stage operations initialized w/ TEE_xxxInit functions
	 * Non-applicable on asymmetric operations
	 */
	if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) {
		res = utee_hash_init(op->state, NULL, 0);
		if (res != TEE_SUCCESS)
			goto out;
		/* v1.1: flags always set for digest operations */
		op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
	}

	op->operationState = TEE_OPERATION_STATE_INITIAL;

	*operation = op;

out:
	if (res != TEE_SUCCESS) {
		if (res != TEE_ERROR_OUT_OF_MEMORY &&
		    res != TEE_ERROR_NOT_SUPPORTED)
			TEE_Panic(res);
		if (op) {
			if (op->state) {
				TEE_FreeOperation(op);
			} else {
				TEE_Free(op->buffer);
				TEE_FreeTransientObject(op->key1);
				TEE_FreeTransientObject(op->key2);
				TEE_Free(op);
			}
		}
	}

	return res;
}

void TEE_FreeOperation(TEE_OperationHandle operation)
{
	TEE_Result res;

	if (operation == TEE_HANDLE_NULL)
		TEE_Panic(0);

	/*
	 * Note that keys should not be freed here, since they are
	 * claimed by the operation they will be freed by
	 * utee_cryp_state_free().
	 */
	res = utee_cryp_state_free(operation->state);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	TEE_Free(operation->buffer);
	TEE_Free(operation);
}

void TEE_GetOperationInfo(TEE_OperationHandle operation,
			  TEE_OperationInfo *operationInfo)
{
	if (operation == TEE_HANDLE_NULL)
		TEE_Panic(0);

	if (!operationInfo)
		TEE_Panic(0);

	*operationInfo = operation->info;
}

TEE_Result TEE_GetOperationInfoMultiple(TEE_OperationHandle operation,
			  TEE_OperationInfoMultiple *operationInfoMultiple,
			  uint32_t *operationSize)
{
	TEE_Result res = TEE_SUCCESS;
	TEE_ObjectInfo key_info1;
	TEE_ObjectInfo key_info2;
	uint32_t num_of_keys;
	size_t n;

	if (operation == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (!operationInfoMultiple) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (!operationSize) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	num_of_keys = (*operationSize-sizeof(TEE_OperationInfoMultiple))/
			sizeof(TEE_OperationInfoKey);

	if (num_of_keys > 2) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* Two keys flag (TEE_ALG_AES_XTS only) */
	if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) !=
	    0 &&
	    (num_of_keys != 2)) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	/* Clear */
	for (n = 0; n < num_of_keys; n++) {
		operationInfoMultiple->keyInformation[n].keySize = 0;
		operationInfoMultiple->keyInformation[n].requiredKeyUsage = 0;
	}

	if (num_of_keys == 2) {
		res = TEE_GetObjectInfo1(operation->key2, &key_info2);
		/* Key2 is not a valid handle */
		if (res != TEE_SUCCESS)
			goto out;

		operationInfoMultiple->keyInformation[1].keySize =
			key_info2.keySize;
		operationInfoMultiple->keyInformation[1].requiredKeyUsage =
			operation->info.requiredKeyUsage;
	}

	if (num_of_keys >= 1) {
		res = TEE_GetObjectInfo1(operation->key1, &key_info1);
		/* Key1 is not a valid handle */
		if (res != TEE_SUCCESS) {
			if (num_of_keys == 2) {
				operationInfoMultiple->keyInformation[1].
							keySize = 0;
				operationInfoMultiple->keyInformation[1].
							requiredKeyUsage = 0;
			}
			goto out;
		}

		operationInfoMultiple->keyInformation[0].keySize =
			key_info1.keySize;
		operationInfoMultiple->keyInformation[0].requiredKeyUsage =
			operation->info.requiredKeyUsage;
	}

	/* No key */
	operationInfoMultiple->algorithm = operation->info.algorithm;
	operationInfoMultiple->operationClass = operation->info.operationClass;
	operationInfoMultiple->mode = operation->info.mode;
	operationInfoMultiple->digestLength = operation->info.digestLength;
	operationInfoMultiple->maxKeySize = operation->info.maxKeySize;
	operationInfoMultiple->handleState = operation->info.handleState;
	operationInfoMultiple->operationState = operation->operationState;
	operationInfoMultiple->numberOfKeys = num_of_keys;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}

void TEE_ResetOperation(TEE_OperationHandle operation)
{
	TEE_Result res;

	if (operation == TEE_HANDLE_NULL)
		TEE_Panic(0);

	if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET))
			TEE_Panic(0);

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

	if (operation->info.operationClass == TEE_OPERATION_DIGEST) {
		res = utee_hash_init(operation->state, NULL, 0);
		if (res != TEE_SUCCESS)
			TEE_Panic(res);
		operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
	} else {
		operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
	}
}

TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation,
			       TEE_ObjectHandle key)
{
	TEE_Result res;
	uint32_t key_size = 0;
	TEE_ObjectInfo key_info;

	if (operation == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_INITIAL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (key == TEE_HANDLE_NULL) {
		/* Operation key cleared */
		TEE_ResetTransientObject(operation->key1);
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* No key for digest operation */
	if (operation->info.operationClass == TEE_OPERATION_DIGEST) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */
	if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) !=
	    0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = TEE_GetObjectInfo1(key, &key_info);
	/* Key is not a valid handle */
	if (res != TEE_SUCCESS)
		goto out;

	/* Supplied key has to meet required usage */
	if ((key_info.objectUsage & operation->info.requiredKeyUsage) !=
	    operation->info.requiredKeyUsage) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.maxKeySize < key_info.keySize) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	key_size = key_info.keySize;

	TEE_ResetTransientObject(operation->key1);
	operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;

	res = TEE_CopyObjectAttributes1(operation->key1, key);
	if (res != TEE_SUCCESS)
		goto out;

	operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;

	operation->info.keySize = key_size;

out:
	if (res != TEE_SUCCESS  &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation,
				TEE_ObjectHandle key1, TEE_ObjectHandle key2)
{
	TEE_Result res;
	uint32_t key_size = 0;
	TEE_ObjectInfo key_info1;
	TEE_ObjectInfo key_info2;

	if (operation == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_INITIAL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * Key1/Key2 and/or are not initialized and
	 * Either both keys are NULL or both are not NULL
	 */
	if (key1 == TEE_HANDLE_NULL || key2 == TEE_HANDLE_NULL) {
		/* Clear operation key1 (if needed) */
		if (key1 == TEE_HANDLE_NULL)
			TEE_ResetTransientObject(operation->key1);
		/* Clear operation key2 (if needed) */
		if (key2 == TEE_HANDLE_NULL)
			TEE_ResetTransientObject(operation->key2);
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* No key for digest operation */
	if (operation->info.operationClass == TEE_OPERATION_DIGEST) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* Two keys flag expected (TEE_ALG_AES_XTS only) */
	if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) ==
	    0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = TEE_GetObjectInfo1(key1, &key_info1);
	/* Key1 is not a valid handle */
	if (res != TEE_SUCCESS)
		goto out;

	/* Supplied key has to meet required usage */
	if ((key_info1.objectUsage & operation->info.
	     requiredKeyUsage) != operation->info.requiredKeyUsage) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = TEE_GetObjectInfo1(key2, &key_info2);
	/* Key2 is not a valid handle */
	if (res != TEE_SUCCESS) {
		if (res == TEE_ERROR_CORRUPT_OBJECT)
			res = TEE_ERROR_CORRUPT_OBJECT_2;
		goto out;
	}

	/* Supplied key has to meet required usage */
	if ((key_info2.objectUsage & operation->info.
	     requiredKeyUsage) != operation->info.requiredKeyUsage) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * AES-XTS (the only multi key algorithm supported, requires the
	 * keys to be of equal size.
	 */
	if (operation->info.algorithm == TEE_ALG_AES_XTS &&
	    key_info1.keySize != key_info2.keySize) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;

	}

	if (operation->info.maxKeySize < key_info1.keySize) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * Odd that only the size of one key should be reported while
	 * size of two key are used when allocating the operation.
	 */
	key_size = key_info1.keySize;

	TEE_ResetTransientObject(operation->key1);
	TEE_ResetTransientObject(operation->key2);
	operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;

	res = TEE_CopyObjectAttributes1(operation->key1, key1);
	if (res != TEE_SUCCESS)
		goto out;

	res = TEE_CopyObjectAttributes1(operation->key2, key2);
	if (res != TEE_SUCCESS) {
		if (res == TEE_ERROR_CORRUPT_OBJECT)
			res = TEE_ERROR_CORRUPT_OBJECT_2;
		goto out;
	}

	operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;

	operation->info.keySize = key_size;

out:
	if (res != TEE_SUCCESS  &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_CORRUPT_OBJECT_2 &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2)
		TEE_Panic(res);

	return res;
}

void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op)
{
	TEE_Result res;

	if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL)
		TEE_Panic(0);
	if (dst_op->info.algorithm != src_op->info.algorithm)
		TEE_Panic(0);
	if (src_op->info.operationClass != TEE_OPERATION_DIGEST) {
		TEE_ObjectHandle key1 = TEE_HANDLE_NULL;
		TEE_ObjectHandle key2 = TEE_HANDLE_NULL;

		if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) {
			key1 = src_op->key1;
			key2 = src_op->key2;
		}

		if ((src_op->info.handleState &
		     TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) {
			TEE_SetOperationKey(dst_op, key1);
		} else {
			TEE_SetOperationKey2(dst_op, key1, key2);
		}
	}
	dst_op->info.handleState = src_op->info.handleState;
	dst_op->info.keySize = src_op->info.keySize;
	dst_op->operationState = src_op->operationState;

	if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks ||
	    dst_op->block_size != src_op->block_size)
		TEE_Panic(0);

	if (dst_op->buffer != NULL) {
		if (src_op->buffer == NULL)
			TEE_Panic(0);

		memcpy(dst_op->buffer, src_op->buffer, src_op->buffer_offs);
		dst_op->buffer_offs = src_op->buffer_offs;
	} else if (src_op->buffer != NULL) {
		TEE_Panic(0);
	}

	res = utee_cryp_state_copy(dst_op->state, src_op->state);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

/* Cryptographic Operations API - Message Digest Functions */

static void init_hash_operation(TEE_OperationHandle operation, const void *IV,
				uint32_t IVLen)
{
	TEE_Result res;

	/*
	 * Note : IV and IVLen are never used in current implementation
	 * This is why coherent values of IV and IVLen are not checked
	 */
	res = utee_hash_init(operation->state, IV, IVLen);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
	operation->buffer_offs = 0;
	operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
}

void TEE_DigestUpdate(TEE_OperationHandle operation,
		      const void *chunk, uint32_t chunkSize)
{
	TEE_Result res = TEE_ERROR_GENERIC;

	if (operation == TEE_HANDLE_NULL ||
	    operation->info.operationClass != TEE_OPERATION_DIGEST)
		TEE_Panic(0);

	operation->operationState = TEE_OPERATION_STATE_ACTIVE;

	res = utee_hash_update(operation->state, chunk, chunkSize);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk,
			     uint32_t chunkLen, void *hash, uint32_t *hashLen)
{
	TEE_Result res;
	uint64_t hl;

	if ((operation == TEE_HANDLE_NULL) ||
	    (!chunk && chunkLen) ||
	    !hash ||
	    !hashLen ||
	    (operation->info.operationClass != TEE_OPERATION_DIGEST)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	hl = *hashLen;
	res = utee_hash_final(operation->state, chunk, chunkLen, hash, &hl);
	*hashLen = hl;
	if (res != TEE_SUCCESS)
		goto out;

	/* Reset operation state */
	init_hash_operation(operation, NULL, 0);

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}

/* Cryptographic Operations API - Symmetric Cipher Functions */

void TEE_CipherInit(TEE_OperationHandle operation, const void *IV,
		    uint32_t IVLen)
{
	TEE_Result res;

	if (operation == TEE_HANDLE_NULL)
		TEE_Panic(0);

	if (operation->info.operationClass != TEE_OPERATION_CIPHER)
		TEE_Panic(0);

	if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) ||
	    !(operation->key1))
		TEE_Panic(0);

	if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
		TEE_ResetOperation(operation);

	operation->operationState = TEE_OPERATION_STATE_ACTIVE;

	res = utee_cipher_init(operation->state, IV, IVLen);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	operation->buffer_offs = 0;
	operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
}

static TEE_Result tee_buffer_update(
		TEE_OperationHandle op,
		TEE_Result(*update_func)(unsigned long state, const void *src,
				size_t slen, void *dst, uint64_t *dlen),
		const void *src_data, size_t src_len,
		void *dest_data, uint64_t *dest_len)
{
	TEE_Result res;
	const uint8_t *src = src_data;
	size_t slen = src_len;
	uint8_t *dst = dest_data;
	size_t dlen = *dest_len;
	size_t acc_dlen = 0;
	uint64_t tmp_dlen;
	size_t l;
	size_t buffer_size;
	size_t buffer_left;

	if (!src) {
		if (slen)
			TEE_Panic(0);
		goto out;
	}

	if (op->buffer_two_blocks) {
		buffer_size = op->block_size * 2;
		buffer_left = 1;
	} else {
		buffer_size = op->block_size;
		buffer_left = 0;
	}

	if (op->buffer_offs > 0) {
		/* Fill up complete block */
		if (op->buffer_offs < op->block_size)
			l = MIN(slen, op->block_size - op->buffer_offs);
		else
			l = MIN(slen, buffer_size - op->buffer_offs);
		memcpy(op->buffer + op->buffer_offs, src, l);
		op->buffer_offs += l;
		src += l;
		slen -= l;
		if ((op->buffer_offs % op->block_size) != 0)
			goto out;	/* Nothing left to do */
	}

	/* If we can feed from buffer */
	if ((op->buffer_offs > 0) &&
	    ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) {
		l = ROUNDUP(op->buffer_offs + slen - buffer_size,
				op->block_size);
		l = MIN(op->buffer_offs, l);
		tmp_dlen = dlen;
		res = update_func(op->state, op->buffer, l, dst, &tmp_dlen);
		if (res != TEE_SUCCESS)
			TEE_Panic(res);
		dst += tmp_dlen;
		dlen -= tmp_dlen;
		acc_dlen += tmp_dlen;
		op->buffer_offs -= l;
		if (op->buffer_offs > 0) {
			/*
			 * Slen is small enough to be contained in rest buffer.
			 */
			memcpy(op->buffer, op->buffer + l, buffer_size - l);
			memcpy(op->buffer + op->buffer_offs, src, slen);
			op->buffer_offs += slen;
			goto out;	/* Nothing left to do */
		}
	}

	if (slen >= (buffer_size + buffer_left)) {
		/* Buffer is empty, feed as much as possible from src */
		if (op->info.algorithm == TEE_ALG_AES_CTS)
			l = ROUNDUP(slen - buffer_size, op->block_size);
		else
			l = ROUNDUP(slen - buffer_size + 1, op->block_size);

		tmp_dlen = dlen;
		res = update_func(op->state, src, l, dst, &tmp_dlen);
		if (res != TEE_SUCCESS)
			TEE_Panic(res);
		src += l;
		slen -= l;
		dst += tmp_dlen;
		dlen -= tmp_dlen;
		acc_dlen += tmp_dlen;
	}

	/* Slen is small enough to be contained in buffer. */
	memcpy(op->buffer + op->buffer_offs, src, slen);
	op->buffer_offs += slen;

out:
	*dest_len = acc_dlen;
	return TEE_SUCCESS;
}

TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData,
			    uint32_t srcLen, void *destData, uint32_t *destLen)
{
	TEE_Result res;
	size_t req_dlen;
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (!srcData && !srcLen) {
		*destLen = 0;
		res = TEE_SUCCESS;
		goto out;
	}

	/* Calculate required dlen */
	if (operation->block_size > 1) {
		req_dlen = ((operation->buffer_offs + srcLen) /
			    operation->block_size) * operation->block_size;
	} else {
		req_dlen = srcLen;
	}
	if (operation->buffer_two_blocks) {
		if (req_dlen > operation->block_size * 2)
			req_dlen -= operation->block_size * 2;
		else
			req_dlen = 0;
	}
	/*
	 * Check that required destLen is big enough before starting to feed
	 * data to the algorithm. Errors during feeding of data are fatal as we
	 * can't restore sync with this API.
	 */
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	dl = *destLen;
	if (operation->block_size > 1) {
		res = tee_buffer_update(operation, utee_cipher_update, srcData,
					srcLen, destData, &dl);
	} else {
		if (srcLen > 0) {
			res = utee_cipher_update(operation->state, srcData,
						 srcLen, destData, &dl);
		} else {
			res = TEE_SUCCESS;
			dl = 0;
		}
	}
	*destLen = dl;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation,
			     const void *srcData, uint32_t srcLen,
			     void *destData, uint32_t *destLen)
{
	TEE_Result res;
	uint8_t *dst = destData;
	size_t acc_dlen = 0;
	uint64_t tmp_dlen;
	size_t req_dlen;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * Check that the final block doesn't require padding for those
	 * algorithms that requires client to supply padding.
	 */
	if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD ||
	    operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD ||
	    operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD ||
	    operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD ||
	    operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD ||
	    operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD ||
	    operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD ||
	    operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) {
		if (((operation->buffer_offs + srcLen) % operation->block_size)
		    != 0) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}
	}

	/*
	 * Check that required destLen is big enough before starting to feed
	 * data to the algorithm. Errors during feeding of data are fatal as we
	 * can't restore sync with this API.
	 */
	if (operation->block_size > 1) {
		req_dlen = operation->buffer_offs + srcLen;
	} else {
		req_dlen = srcLen;
	}
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	tmp_dlen = *destLen - acc_dlen;
	if (operation->block_size > 1) {
		res = tee_buffer_update(operation, utee_cipher_update,
					srcData, srcLen, dst, &tmp_dlen);
		if (res != TEE_SUCCESS)
			goto out;

		dst += tmp_dlen;
		acc_dlen += tmp_dlen;

		tmp_dlen = *destLen - acc_dlen;
		res = utee_cipher_final(operation->state, operation->buffer,
					operation->buffer_offs, dst, &tmp_dlen);
	} else {
		res = utee_cipher_final(operation->state, srcData,
					srcLen, dst, &tmp_dlen);
	}
	if (res != TEE_SUCCESS)
		goto out;

	acc_dlen += tmp_dlen;
	*destLen = acc_dlen;

	operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}

/* Cryptographic Operations API - MAC Functions */

void TEE_MACInit(TEE_OperationHandle operation, const void *IV, uint32_t IVLen)
{
	if (operation == TEE_HANDLE_NULL)
		TEE_Panic(0);

	if (operation->info.operationClass != TEE_OPERATION_MAC)
		TEE_Panic(0);

	if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) ||
	    !(operation->key1))
		TEE_Panic(0);

	if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
		TEE_ResetOperation(operation);

	operation->operationState = TEE_OPERATION_STATE_ACTIVE;

	init_hash_operation(operation, IV, IVLen);
}

void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk,
		   uint32_t chunkSize)
{
	TEE_Result res;

	if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0))
		TEE_Panic(0);

	if (operation->info.operationClass != TEE_OPERATION_MAC)
		TEE_Panic(0);

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		TEE_Panic(0);

	if (operation->operationState != TEE_OPERATION_STATE_ACTIVE)
		TEE_Panic(0);

	res = utee_hash_update(operation->state, chunk, chunkSize);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation,
			       const void *message, uint32_t messageLen,
			       void *mac, uint32_t *macLen)
{
	TEE_Result res;
	uint64_t ml;

	if (operation == TEE_HANDLE_NULL ||
	    (message == NULL && messageLen != 0) ||
	    mac == NULL ||
	    macLen == NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_MAC) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	ml = *macLen;
	res = utee_hash_final(operation->state, message, messageLen, mac, &ml);
	*macLen = ml;
	if (res != TEE_SUCCESS)
		goto out;

	operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation,
			       const void *message, uint32_t messageLen,
			       const void *mac, uint32_t macLen)
{
	TEE_Result res;
	uint8_t computed_mac[TEE_MAX_HASH_SIZE];
	uint32_t computed_mac_size = TEE_MAX_HASH_SIZE;

	if (operation->info.operationClass != TEE_OPERATION_MAC) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac,
				  &computed_mac_size);
	if (res != TEE_SUCCESS)
		goto out;

	if (computed_mac_size != macLen) {
		res = TEE_ERROR_MAC_INVALID;
		goto out;
	}

	if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) {
		res = TEE_ERROR_MAC_INVALID;
		goto out;
	}

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_MAC_INVALID)
		TEE_Panic(res);

	return res;
}

/* Cryptographic Operations API - Authenticated Encryption Functions */

TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce,
		      uint32_t nonceLen, uint32_t tagLen, uint32_t AADLen,
		      uint32_t payloadLen)
{
	TEE_Result res;

	if (operation == TEE_HANDLE_NULL || nonce == NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_AE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_INITIAL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core
	 * in the implementation. But AES-GCM spec doesn't specify the tag len
	 * according to the same principle so we have to check here instead to
	 * be GP compliant.
	 */
	if (operation->info.algorithm == TEE_ALG_AES_GCM) {
		/*
		 * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96
		 */
		if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) {
			res = TEE_ERROR_NOT_SUPPORTED;
			goto out;
		}
	}

	res = utee_authenc_init(operation->state, nonce, nonceLen,
				tagLen / 8, AADLen, payloadLen);
	if (res != TEE_SUCCESS)
		goto out;

	operation->ae_tag_len = tagLen / 8;
	operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_NOT_SUPPORTED)
			TEE_Panic(res);

	return res;
}

void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata,
		     uint32_t AADdataLen)
{
	TEE_Result res;

	if (operation == TEE_HANDLE_NULL ||
	    (AADdata == NULL && AADdataLen != 0))
		TEE_Panic(0);

	if (operation->info.operationClass != TEE_OPERATION_AE)
		TEE_Panic(0);

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		TEE_Panic(0);

	res = utee_authenc_update_aad(operation->state, AADdata, AADdataLen);

	operation->operationState = TEE_OPERATION_STATE_ACTIVE;

	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData,
			uint32_t srcLen, void *destData, uint32_t *destLen)
{
	TEE_Result res;
	size_t req_dlen;
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_AE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (!srcData && !srcLen) {
		*destLen = 0;
		res = TEE_SUCCESS;
		goto out;
	}

	/*
	 * Check that required destLen is big enough before starting to feed
	 * data to the algorithm. Errors during feeding of data are fatal as we
	 * can't restore sync with this API.
	 */
	if (operation->block_size > 1) {
		req_dlen = ROUNDDOWN(operation->buffer_offs + srcLen,
				     operation->block_size);
	} else {
		req_dlen = srcLen;
	}

	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	dl = *destLen;
	if (operation->block_size > 1) {
		res = tee_buffer_update(operation, utee_authenc_update_payload,
					srcData, srcLen, destData, &dl);
	} else {
		if (srcLen > 0) {
			res = utee_authenc_update_payload(operation->state,
							  srcData, srcLen,
							  destData, &dl);
		} else {
			dl = 0;
			res = TEE_SUCCESS;
		}
	}
	if (res != TEE_SUCCESS)
		goto out;

	*destLen = dl;

	operation->operationState = TEE_OPERATION_STATE_ACTIVE;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
			TEE_Panic(res);

	return res;
}

TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation,
			      const void *srcData, uint32_t srcLen,
			      void *destData, uint32_t *destLen, void *tag,
			      uint32_t *tagLen)
{
	TEE_Result res;
	uint8_t *dst = destData;
	size_t acc_dlen = 0;
	uint64_t tmp_dlen;
	size_t req_dlen;
	uint64_t tl;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0) ||
	    tag == NULL || tagLen == NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_AE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * Check that required destLen is big enough before starting to feed
	 * data to the algorithm. Errors during feeding of data are fatal as we
	 * can't restore sync with this API.
	 *
	 * Need to check this before update_payload since sync would be lost if
	 * we return short buffer after that.
	 */
	res = TEE_ERROR_GENERIC;

	req_dlen = operation->buffer_offs + srcLen;
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
	}

	if (*tagLen < operation->ae_tag_len) {
		*tagLen = operation->ae_tag_len;
		res = TEE_ERROR_SHORT_BUFFER;
	}

	if (res == TEE_ERROR_SHORT_BUFFER)
		goto out;

	tl = *tagLen;
	tmp_dlen = *destLen - acc_dlen;
	if (operation->block_size > 1) {
		res = tee_buffer_update(operation, utee_authenc_update_payload,
					srcData, srcLen, dst, &tmp_dlen);
		if (res != TEE_SUCCESS)
			goto out;

		dst += tmp_dlen;
		acc_dlen += tmp_dlen;

		tmp_dlen = *destLen - acc_dlen;
		res = utee_authenc_enc_final(operation->state,
					     operation->buffer,
					     operation->buffer_offs, dst,
					     &tmp_dlen, tag, &tl);
	} else {
		res = utee_authenc_enc_final(operation->state, srcData,
					     srcLen, dst, &tmp_dlen,
					     tag, &tl);
	}
	*tagLen = tl;
	if (res != TEE_SUCCESS)
		goto out;

	acc_dlen += tmp_dlen;
	*destLen = acc_dlen;

	operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
			TEE_Panic(res);

	return res;
}

TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation,
			      const void *srcData, uint32_t srcLen,
			      void *destData, uint32_t *destLen, void *tag,
			      uint32_t tagLen)
{
	TEE_Result res;
	uint8_t *dst = destData;
	size_t acc_dlen = 0;
	uint64_t tmp_dlen;
	size_t req_dlen;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0) ||
	    (tag == NULL && tagLen != 0)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_AE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/*
	 * Check that required destLen is big enough before starting to feed
	 * data to the algorithm. Errors during feeding of data are fatal as we
	 * can't restore sync with this API.
	 */
	req_dlen = operation->buffer_offs + srcLen;
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	tmp_dlen = *destLen - acc_dlen;
	if (operation->block_size > 1) {
		res = tee_buffer_update(operation, utee_authenc_update_payload,
					srcData, srcLen, dst, &tmp_dlen);
		if (res != TEE_SUCCESS)
			goto out;

		dst += tmp_dlen;
		acc_dlen += tmp_dlen;

		tmp_dlen = *destLen - acc_dlen;
		res = utee_authenc_dec_final(operation->state,
					     operation->buffer,
					     operation->buffer_offs, dst,
					     &tmp_dlen, tag, tagLen);
	} else {
		res = utee_authenc_dec_final(operation->state, srcData,
					     srcLen, dst, &tmp_dlen,
					     tag, tagLen);
	}
	if (res != TEE_SUCCESS)
		goto out;

	/* Supplied tagLen should match what we initiated with */
	if (tagLen != operation->ae_tag_len)
		res = TEE_ERROR_MAC_INVALID;

	acc_dlen += tmp_dlen;
	*destLen = acc_dlen;

	operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;

	operation->operationState = TEE_OPERATION_STATE_INITIAL;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER &&
	    res != TEE_ERROR_MAC_INVALID)
			TEE_Panic(res);

	return res;
}

/* Cryptographic Operations API - Asymmetric Functions */

TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation,
				 const TEE_Attribute *params,
				 uint32_t paramCount, const void *srcData,
				 uint32_t srcLen, void *destData,
				 uint32_t *destLen)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
	    destLen == NULL || (destData == NULL && *destLen != 0))
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_ENCRYPT)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	dl = *destLen;
	res = utee_asymm_operate(operation->state, ua, paramCount, srcData,
				 srcLen, destData, &dl);
	*destLen = dl;

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER &&
	    res != TEE_ERROR_BAD_PARAMETERS)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation,
				 const TEE_Attribute *params,
				 uint32_t paramCount, const void *srcData,
				 uint32_t srcLen, void *destData,
				 uint32_t *destLen)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
	    destLen == NULL || (destData == NULL && *destLen != 0))
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_DECRYPT)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	dl = *destLen;
	res = utee_asymm_operate(operation->state, ua, paramCount, srcData,
				 srcLen, destData, &dl);
	*destLen = dl;

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER &&
	    res != TEE_ERROR_BAD_PARAMETERS)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation,
				    const TEE_Attribute *params,
				    uint32_t paramCount, const void *digest,
				    uint32_t digestLen, void *signature,
				    uint32_t *signatureLen)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];
	uint64_t sl;

	if (operation == TEE_HANDLE_NULL ||
	    (digest == NULL && digestLen != 0) ||
	    signature == NULL || signatureLen == NULL)
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.operationClass !=
	    TEE_OPERATION_ASYMMETRIC_SIGNATURE)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_SIGN)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	sl = *signatureLen;
	res = utee_asymm_operate(operation->state, ua, paramCount, digest,
				 digestLen, signature, &sl);
	*signatureLen = sl;

	if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,
				      const TEE_Attribute *params,
				      uint32_t paramCount, const void *digest,
				      uint32_t digestLen,
				      const void *signature,
				      uint32_t signatureLen)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];

	if (operation == TEE_HANDLE_NULL ||
	    (digest == NULL && digestLen != 0) ||
	    (signature == NULL && signatureLen != 0))
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.operationClass !=
	    TEE_OPERATION_ASYMMETRIC_SIGNATURE)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_VERIFY)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	res = utee_asymm_verify(operation->state, ua, paramCount, digest,
				digestLen, signature, signatureLen);

	if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID)
		TEE_Panic(res);

	return res;
}

/* Cryptographic Operations API - Key Derivation Functions */

void TEE_DeriveKey(TEE_OperationHandle operation,
		   const TEE_Attribute *params, uint32_t paramCount,
		   TEE_ObjectHandle derivedKey)
{
	TEE_Result res;
	TEE_ObjectInfo key_info;
	struct utee_attribute ua[paramCount];

	if (operation == TEE_HANDLE_NULL || derivedKey == 0)
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (TEE_ALG_GET_CLASS(operation->info.algorithm) !=
	    TEE_OPERATION_KEY_DERIVATION)
		TEE_Panic(0);

	if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_DERIVE)
		TEE_Panic(0);
	if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0)
		TEE_Panic(0);

	res = utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	if (key_info.objectType != TEE_TYPE_GENERIC_SECRET)
		TEE_Panic(0);
	if ((key_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	res = utee_cryp_derive_key(operation->state, ua, paramCount,
				   (unsigned long)derivedKey);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

/* Cryptographic Operations API - Random Number Generation Functions */

void TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen)
{
	TEE_Result res;

	res = utee_cryp_random_number_generate(randomBuffer, randomBufferLen);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

int rand(void)
{
	int rc;

	TEE_GenerateRandom(&rc, sizeof(rc));

	/*
	 * RAND_MAX is the larges int, INT_MAX which is all bits but the
	 * highest bit set.
	 */
	return rc & RAND_MAX;
}
