// 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:
		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:
		if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES)
			block_size = TEE_AES_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:
		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:
		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:
		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:
		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) {
		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;
}
