// 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:
	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:
		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:
	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;
}
