// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 */

#include <assert.h>
#include <compiler.h>
#include <crypto/crypto.h>
#include <kernel/tee_ta_manager.h>
#include <mm/tee_mmu.h>
#include <stdlib_ext.h>
#include <string_ext.h>
#include <string.h>
#include <sys/queue.h>
#include <tee_api_types.h>
#include <tee/tee_cryp_utl.h>
#include <tee/tee_obj.h>
#include <tee/tee_svc_cryp.h>
#include <tee/tee_svc.h>
#include <trace.h>
#include <utee_defines.h>
#include <util.h>
#include <tee_api_defines_extensions.h>
#if defined(CFG_CRYPTO_HKDF)
#include <tee/tee_cryp_hkdf.h>
#endif
#if defined(CFG_CRYPTO_CONCAT_KDF)
#include <tee/tee_cryp_concat_kdf.h>
#endif
#if defined(CFG_CRYPTO_PBKDF2)
#include <tee/tee_cryp_pbkdf2.h>
#endif

enum cryp_state {
	CRYP_STATE_INITIALIZED = 0,
	CRYP_STATE_UNINITIALIZED
};

typedef void (*tee_cryp_ctx_finalize_func_t) (void *ctx);
struct tee_cryp_state {
	TAILQ_ENTRY(tee_cryp_state) link;
	uint32_t algo;
	uint32_t mode;
	vaddr_t key1;
	vaddr_t key2;
	void *ctx;
	tee_cryp_ctx_finalize_func_t ctx_finalize;
	enum cryp_state state;
};

struct tee_cryp_obj_secret {
	uint32_t key_size;
	uint32_t alloc_size;

	/*
	 * Pseudo code visualize layout of structure
	 * Next follows data, such as:
	 *	uint8_t data[alloc_size]
	 * key_size must never exceed alloc_size
	 */
};

#define TEE_TYPE_ATTR_OPTIONAL       0x0
#define TEE_TYPE_ATTR_REQUIRED       0x1
#define TEE_TYPE_ATTR_OPTIONAL_GROUP 0x2
#define TEE_TYPE_ATTR_SIZE_INDICATOR 0x4
#define TEE_TYPE_ATTR_GEN_KEY_OPT    0x8
#define TEE_TYPE_ATTR_GEN_KEY_REQ    0x10

    /* Handle storing of generic secret keys of varying lengths */
#define ATTR_OPS_INDEX_SECRET     0
    /* Convert to/from big-endian byte array and provider-specific bignum */
#define ATTR_OPS_INDEX_BIGNUM     1
    /* Convert to/from value attribute depending on direction */
#define ATTR_OPS_INDEX_VALUE      2

struct tee_cryp_obj_type_attrs {
	uint32_t attr_id;
	uint16_t flags;
	uint16_t ops_index;
	uint16_t raw_offs;
	uint16_t raw_size;
};

#define RAW_DATA(_x, _y)	\
	.raw_offs = offsetof(_x, _y), .raw_size = MEMBER_SIZE(_x, _y)

static const struct tee_cryp_obj_type_attrs
	tee_cryp_obj_secret_value_attrs[] = {
	{
	.attr_id = TEE_ATTR_SECRET_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_SECRET,
	.raw_offs = 0,
	.raw_size = 0
	},
};

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_rsa_pub_key_attrs[] = {
	{
	.attr_id = TEE_ATTR_RSA_MODULUS,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_public_key, n)
	},

	{
	.attr_id = TEE_ATTR_RSA_PUBLIC_EXPONENT,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_public_key, e)
	},
};

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_rsa_keypair_attrs[] = {
	{
	.attr_id = TEE_ATTR_RSA_MODULUS,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, n)
	},

	{
	.attr_id = TEE_ATTR_RSA_PUBLIC_EXPONENT,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, e)
	},

	{
	.attr_id = TEE_ATTR_RSA_PRIVATE_EXPONENT,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, d)
	},

	{
	.attr_id = TEE_ATTR_RSA_PRIME1,
	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, p)
	},

	{
	.attr_id = TEE_ATTR_RSA_PRIME2,
	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, q)
	},

	{
	.attr_id = TEE_ATTR_RSA_EXPONENT1,
	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, dp)
	},

	{
	.attr_id = TEE_ATTR_RSA_EXPONENT2,
	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, dq)
	},

	{
	.attr_id = TEE_ATTR_RSA_COEFFICIENT,
	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct rsa_keypair, qp)
	},
};

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dsa_pub_key_attrs[] = {
	{
	.attr_id = TEE_ATTR_DSA_PRIME,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_public_key, p)
	},

	{
	.attr_id = TEE_ATTR_DSA_SUBPRIME,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_public_key, q)
	},

	{
	.attr_id = TEE_ATTR_DSA_BASE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_public_key, g)
	},

	{
	.attr_id = TEE_ATTR_DSA_PUBLIC_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_public_key, y)
	},
};

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dsa_keypair_attrs[] = {
	{
	.attr_id = TEE_ATTR_DSA_PRIME,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_keypair, p)
	},

	{
	.attr_id = TEE_ATTR_DSA_SUBPRIME,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR |
		 TEE_TYPE_ATTR_GEN_KEY_REQ,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_keypair, q)
	},

	{
	.attr_id = TEE_ATTR_DSA_BASE,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_keypair, g)
	},

	{
	.attr_id = TEE_ATTR_DSA_PRIVATE_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_keypair, x)
	},

	{
	.attr_id = TEE_ATTR_DSA_PUBLIC_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dsa_keypair, y)
	},
};

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dh_keypair_attrs[] = {
	{
	.attr_id = TEE_ATTR_DH_PRIME,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR |
		 TEE_TYPE_ATTR_GEN_KEY_REQ,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dh_keypair, p)
	},

	{
	.attr_id = TEE_ATTR_DH_BASE,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dh_keypair, g)
	},

	{
	.attr_id = TEE_ATTR_DH_PUBLIC_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dh_keypair, y)
	},

	{
	.attr_id = TEE_ATTR_DH_PRIVATE_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dh_keypair, x)
	},

	{
	.attr_id = TEE_ATTR_DH_SUBPRIME,
	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP |	 TEE_TYPE_ATTR_GEN_KEY_OPT,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct dh_keypair, q)
	},

	{
	.attr_id = TEE_ATTR_DH_X_BITS,
	.flags = TEE_TYPE_ATTR_GEN_KEY_OPT,
	.ops_index = ATTR_OPS_INDEX_VALUE,
	RAW_DATA(struct dh_keypair, xbits)
	},
};

#if defined(CFG_CRYPTO_HKDF)
static const struct tee_cryp_obj_type_attrs
	tee_cryp_obj_hkdf_ikm_attrs[] = {
	{
	.attr_id = TEE_ATTR_HKDF_IKM,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_SECRET,
	.raw_offs = 0,
	.raw_size = 0
	},
};
#endif

#if defined(CFG_CRYPTO_CONCAT_KDF)
static const struct tee_cryp_obj_type_attrs
	tee_cryp_obj_concat_kdf_z_attrs[] = {
	{
	.attr_id = TEE_ATTR_CONCAT_KDF_Z,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_SECRET,
	.raw_offs = 0,
	.raw_size = 0
	},
};
#endif

#if defined(CFG_CRYPTO_PBKDF2)
static const struct tee_cryp_obj_type_attrs
	tee_cryp_obj_pbkdf2_passwd_attrs[] = {
	{
	.attr_id = TEE_ATTR_PBKDF2_PASSWORD,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_SECRET,
	.raw_offs = 0,
	.raw_size = 0
	},
};
#endif

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_ecc_pub_key_attrs[] = {
	{
	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_X,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct ecc_public_key, x)
	},

	{
	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_Y,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct ecc_public_key, y)
	},

	{
	.attr_id = TEE_ATTR_ECC_CURVE,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_VALUE,
	RAW_DATA(struct ecc_public_key, curve)
	},
};

static const struct tee_cryp_obj_type_attrs tee_cryp_obj_ecc_keypair_attrs[] = {
	{
	.attr_id = TEE_ATTR_ECC_PRIVATE_VALUE,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct ecc_keypair, d)
	},

	{
	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_X,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct ecc_keypair, x)
	},

	{
	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_Y,
	.flags = TEE_TYPE_ATTR_REQUIRED,
	.ops_index = ATTR_OPS_INDEX_BIGNUM,
	RAW_DATA(struct ecc_keypair, y)
	},

	{
	.attr_id = TEE_ATTR_ECC_CURVE,
	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
	.ops_index = ATTR_OPS_INDEX_VALUE,
	RAW_DATA(struct ecc_keypair, curve)
	},
};

struct tee_cryp_obj_type_props {
	TEE_ObjectType obj_type;
	uint16_t min_size;	/* may not be smaller than this */
	uint16_t max_size;	/* may not be larger than this */
	uint16_t alloc_size;	/* this many bytes are allocated to hold data */
	uint8_t quanta;		/* may only be an multiple of this */

	uint8_t num_type_attrs;
	const struct tee_cryp_obj_type_attrs *type_attrs;
};

#define PROP(obj_type, quanta, min_size, max_size, alloc_size, type_attrs) \
		{ (obj_type), (min_size), (max_size), (alloc_size), (quanta), \
		  ARRAY_SIZE(type_attrs), (type_attrs) }

static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = {
	PROP(TEE_TYPE_AES, 64, 128, 256,	/* valid sizes 128, 192, 256 */
		256 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_DES, 56, 56, 56,
		/*
		* Valid size 56 without parity, note that we still allocate
		* for 64 bits since the key is supplied with parity.
		*/
		64 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_DES3, 56, 112, 168,
		/*
		* Valid sizes 112, 168 without parity, note that we still
		* allocate for with space for the parity since the key is
		* supplied with parity.
		*/
		192 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_SM4, 128, 128, 128,
		128 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_MD5, 8, 64, 512,
		512 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_SHA1, 8, 80, 512,
		512 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_SHA224, 8, 112, 512,
		512 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_SHA256, 8, 192, 1024,
		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_SHA384, 8, 256, 1024,
		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_SHA512, 8, 256, 1024,
		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_HMAC_SM3, 8, 80, 1024,
		512 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
	PROP(TEE_TYPE_GENERIC_SECRET, 8, 0, 4096,
		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_secret_value_attrs),
#if defined(CFG_CRYPTO_HKDF)
	PROP(TEE_TYPE_HKDF_IKM, 8, 0, 4096,
		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_hkdf_ikm_attrs),
#endif
#if defined(CFG_CRYPTO_CONCAT_KDF)
	PROP(TEE_TYPE_CONCAT_KDF_Z, 8, 0, 4096,
		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_concat_kdf_z_attrs),
#endif
#if defined(CFG_CRYPTO_PBKDF2)
	PROP(TEE_TYPE_PBKDF2_PASSWORD, 8, 0, 4096,
		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
		tee_cryp_obj_pbkdf2_passwd_attrs),
#endif
	PROP(TEE_TYPE_RSA_PUBLIC_KEY, 1, 256, CFG_CORE_BIGNUM_MAX_BITS,
		sizeof(struct rsa_public_key),
		tee_cryp_obj_rsa_pub_key_attrs),

	PROP(TEE_TYPE_RSA_KEYPAIR, 1, 256, CFG_CORE_BIGNUM_MAX_BITS,
		sizeof(struct rsa_keypair),
		tee_cryp_obj_rsa_keypair_attrs),

	PROP(TEE_TYPE_DSA_PUBLIC_KEY, 64, 512, 3072,
		sizeof(struct dsa_public_key),
		tee_cryp_obj_dsa_pub_key_attrs),

	PROP(TEE_TYPE_DSA_KEYPAIR, 64, 512, 3072,
		sizeof(struct dsa_keypair),
		tee_cryp_obj_dsa_keypair_attrs),

	PROP(TEE_TYPE_DH_KEYPAIR, 1, 256, 2048,
		sizeof(struct dh_keypair),
		tee_cryp_obj_dh_keypair_attrs),

	PROP(TEE_TYPE_ECDSA_PUBLIC_KEY, 1, 192, 521,
		sizeof(struct ecc_public_key),
		tee_cryp_obj_ecc_pub_key_attrs),

	PROP(TEE_TYPE_ECDSA_KEYPAIR, 1, 192, 521,
		sizeof(struct ecc_keypair),
		tee_cryp_obj_ecc_keypair_attrs),

	PROP(TEE_TYPE_ECDH_PUBLIC_KEY, 1, 192, 521,
		sizeof(struct ecc_public_key),
		tee_cryp_obj_ecc_pub_key_attrs),

	PROP(TEE_TYPE_ECDH_KEYPAIR, 1, 192, 521,
		sizeof(struct ecc_keypair),
		tee_cryp_obj_ecc_keypair_attrs),

	PROP(TEE_TYPE_SM2_DSA_PUBLIC_KEY, 1, 256, 256,
	     sizeof(struct ecc_public_key),
	     tee_cryp_obj_ecc_pub_key_attrs),

	PROP(TEE_TYPE_SM2_DSA_KEYPAIR, 1, 256, 256,
	     sizeof(struct ecc_keypair),
	     tee_cryp_obj_ecc_keypair_attrs),

	PROP(TEE_TYPE_SM2_PKE_PUBLIC_KEY, 1, 256, 256,
	     sizeof(struct ecc_public_key),
	     tee_cryp_obj_ecc_pub_key_attrs),

	PROP(TEE_TYPE_SM2_PKE_KEYPAIR, 1, 256, 256,
	     sizeof(struct ecc_keypair),
	     tee_cryp_obj_ecc_keypair_attrs),

	PROP(TEE_TYPE_SM2_KEP_PUBLIC_KEY, 1, 256, 256,
	     sizeof(struct ecc_public_key),
	     tee_cryp_obj_ecc_pub_key_attrs),

	PROP(TEE_TYPE_SM2_KEP_KEYPAIR, 1, 256, 256,
	     sizeof(struct ecc_keypair),
	     tee_cryp_obj_ecc_keypair_attrs),
};

struct attr_ops {
	TEE_Result (*from_user)(void *attr, const void *buffer, size_t size);
	TEE_Result (*to_user)(void *attr, struct tee_ta_session *sess,
			      void *buffer, uint64_t *size);
	TEE_Result (*to_binary)(void *attr, void *data, size_t data_len,
			    size_t *offs);
	bool (*from_binary)(void *attr, const void *data, size_t data_len,
			    size_t *offs);
	TEE_Result (*from_obj)(void *attr, void *src_attr);
	void (*free)(void *attr);
	void (*clear)(void *attr);
};

static TEE_Result op_u32_to_binary_helper(uint32_t v, uint8_t *data,
				    size_t data_len, size_t *offs)
{
	uint32_t field;
	size_t next_offs;

	if (ADD_OVERFLOW(*offs, sizeof(field), &next_offs))
		return TEE_ERROR_OVERFLOW;

	if (data && next_offs <= data_len) {
		field = TEE_U32_TO_BIG_ENDIAN(v);
		memcpy(data + *offs, &field, sizeof(field));
	}
	(*offs) = next_offs;

	return TEE_SUCCESS;
}

static bool op_u32_from_binary_helper(uint32_t *v, const uint8_t *data,
				      size_t data_len, size_t *offs)
{
	uint32_t field;

	if (!data || (*offs + sizeof(field)) > data_len)
		return false;

	memcpy(&field, data + *offs, sizeof(field));
	*v = TEE_U32_FROM_BIG_ENDIAN(field);
	(*offs) += sizeof(field);
	return true;
}

static TEE_Result op_attr_secret_value_from_user(void *attr, const void *buffer,
						 size_t size)
{
	struct tee_cryp_obj_secret *key = attr;

	/* Data size has to fit in allocated buffer */
	if (size > key->alloc_size)
		return TEE_ERROR_SECURITY;
	memcpy(key + 1, buffer, size);
	key->key_size = size;
	return TEE_SUCCESS;
}

static TEE_Result op_attr_secret_value_to_user(void *attr,
			struct tee_ta_session *sess __unused,
			void *buffer, uint64_t *size)
{
	TEE_Result res;
	struct tee_cryp_obj_secret *key = attr;
	uint64_t s;
	uint64_t key_size;

	res = tee_svc_copy_from_user(&s, size, sizeof(s));
	if (res != TEE_SUCCESS)
		return res;

	key_size = key->key_size;
	res = tee_svc_copy_to_user(size, &key_size, sizeof(key_size));
	if (res != TEE_SUCCESS)
		return res;

	if (s < key->key_size || !buffer)
		return TEE_ERROR_SHORT_BUFFER;

	return tee_svc_copy_to_user(buffer, key + 1, key->key_size);
}

static TEE_Result op_attr_secret_value_to_binary(void *attr, void *data,
					   size_t data_len, size_t *offs)
{
	TEE_Result res;
	struct tee_cryp_obj_secret *key = attr;
	size_t next_offs;

	res = op_u32_to_binary_helper(key->key_size, data, data_len, offs);
	if (res != TEE_SUCCESS)
		return res;

	if (ADD_OVERFLOW(*offs, key->key_size, &next_offs))
		return TEE_ERROR_OVERFLOW;

	if (data && next_offs <= data_len)
		memcpy((uint8_t *)data + *offs, key + 1, key->key_size);
	(*offs) = next_offs;

	return TEE_SUCCESS;
}

static bool op_attr_secret_value_from_binary(void *attr, const void *data,
					     size_t data_len, size_t *offs)
{
	struct tee_cryp_obj_secret *key = attr;
	uint32_t s;

	if (!op_u32_from_binary_helper(&s, data, data_len, offs))
		return false;

	if ((*offs + s) > data_len)
		return false;

	/* Data size has to fit in allocated buffer */
	if (s > key->alloc_size)
		return false;
	key->key_size = s;
	memcpy(key + 1, (const uint8_t *)data + *offs, s);
	(*offs) += s;
	return true;
}


static TEE_Result op_attr_secret_value_from_obj(void *attr, void *src_attr)
{
	struct tee_cryp_obj_secret *key = attr;
	struct tee_cryp_obj_secret *src_key = src_attr;

	if (src_key->key_size > key->alloc_size)
		return TEE_ERROR_BAD_STATE;
	memcpy(key + 1, src_key + 1, src_key->key_size);
	key->key_size = src_key->key_size;
	return TEE_SUCCESS;
}

static void op_attr_secret_value_clear(void *attr)
{
	struct tee_cryp_obj_secret *key = attr;

	key->key_size = 0;
	memset(key + 1, 0, key->alloc_size);
}

static TEE_Result op_attr_bignum_from_user(void *attr, const void *buffer,
					   size_t size)
{
	struct bignum **bn = attr;

	return crypto_bignum_bin2bn(buffer, size, *bn);
}

static TEE_Result op_attr_bignum_to_user(void *attr,
					 struct tee_ta_session *sess,
					 void *buffer, uint64_t *size)
{
	TEE_Result res = TEE_SUCCESS;
	struct bignum **bn = attr;
	uint64_t req_size = 0;
	uint64_t s = 0;

	res = tee_svc_copy_from_user(&s, size, sizeof(s));
	if (res != TEE_SUCCESS)
		return res;

	req_size = crypto_bignum_num_bytes(*bn);
	res = tee_svc_copy_to_user(size, &req_size, sizeof(req_size));
	if (res != TEE_SUCCESS)
		return res;
	if (!req_size)
		return TEE_SUCCESS;
	if (s < req_size || !buffer)
		return TEE_ERROR_SHORT_BUFFER;

	/* Check we can access data using supplied user mode pointer */
	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)buffer, req_size);
	if (res != TEE_SUCCESS)
		return res;
	/*
	* Write the bignum (wich raw data points to) into an array of
	* bytes (stored in buffer)
	*/
	crypto_bignum_bn2bin(*bn, buffer);
	return TEE_SUCCESS;
}

static TEE_Result op_attr_bignum_to_binary(void *attr, void *data,
					   size_t data_len, size_t *offs)
{
	TEE_Result res;
	struct bignum **bn = attr;
	uint32_t n = crypto_bignum_num_bytes(*bn);
	size_t next_offs;

	res = op_u32_to_binary_helper(n, data, data_len, offs);
	if (res != TEE_SUCCESS)
		return res;

	if (ADD_OVERFLOW(*offs, n, &next_offs))
		return TEE_ERROR_OVERFLOW;

	if (data && next_offs <= data_len)
		crypto_bignum_bn2bin(*bn, (uint8_t *)data + *offs);
	(*offs) = next_offs;

	return TEE_SUCCESS;
}

static bool op_attr_bignum_from_binary(void *attr, const void *data,
				       size_t data_len, size_t *offs)
{
	struct bignum **bn = attr;
	uint32_t n;

	if (!op_u32_from_binary_helper(&n, data, data_len, offs))
		return false;

	if ((*offs + n) > data_len)
		return false;
	if (crypto_bignum_bin2bn((const uint8_t *)data + *offs, n, *bn))
		return false;
	(*offs) += n;
	return true;
}

static TEE_Result op_attr_bignum_from_obj(void *attr, void *src_attr)
{
	struct bignum **bn = attr;
	struct bignum **src_bn = src_attr;

	crypto_bignum_copy(*bn, *src_bn);
	return TEE_SUCCESS;
}

static void op_attr_bignum_clear(void *attr)
{
	struct bignum **bn = attr;

	crypto_bignum_clear(*bn);
}

static void op_attr_bignum_free(void *attr)
{
	struct bignum **bn = attr;

	crypto_bignum_free(*bn);
	*bn = NULL;
}

static TEE_Result op_attr_value_from_user(void *attr, const void *buffer,
					  size_t size)
{
	uint32_t *v = attr;

	if (size != sizeof(uint32_t) * 2)
		return TEE_ERROR_GENERIC; /* "can't happen */

	/* Note that only the first value is copied */
	memcpy(v, buffer, sizeof(uint32_t));
	return TEE_SUCCESS;
}

static TEE_Result op_attr_value_to_user(void *attr,
					struct tee_ta_session *sess __unused,
					void *buffer, uint64_t *size)
{
	TEE_Result res;
	uint32_t *v = attr;
	uint64_t s;
	uint32_t value[2] = { *v };
	uint64_t req_size = sizeof(value);

	res = tee_svc_copy_from_user(&s, size, sizeof(s));
	if (res != TEE_SUCCESS)
		return res;

	if (s < req_size || !buffer)
		return TEE_ERROR_SHORT_BUFFER;

	return tee_svc_copy_to_user(buffer, value, req_size);
}

static TEE_Result op_attr_value_to_binary(void *attr, void *data,
					  size_t data_len, size_t *offs)
{
	uint32_t *v = attr;

	return op_u32_to_binary_helper(*v, data, data_len, offs);
}

static bool op_attr_value_from_binary(void *attr, const void *data,
				      size_t data_len, size_t *offs)
{
	uint32_t *v = attr;

	return op_u32_from_binary_helper(v, data, data_len, offs);
}

static TEE_Result op_attr_value_from_obj(void *attr, void *src_attr)
{
	uint32_t *v = attr;
	uint32_t *src_v = src_attr;

	*v = *src_v;
	return TEE_SUCCESS;
}

static void op_attr_value_clear(void *attr)
{
	uint32_t *v = attr;

	*v = 0;
}

static const struct attr_ops attr_ops[] = {
	[ATTR_OPS_INDEX_SECRET] = {
		.from_user = op_attr_secret_value_from_user,
		.to_user = op_attr_secret_value_to_user,
		.to_binary = op_attr_secret_value_to_binary,
		.from_binary = op_attr_secret_value_from_binary,
		.from_obj = op_attr_secret_value_from_obj,
		.free = op_attr_secret_value_clear, /* not a typo */
		.clear = op_attr_secret_value_clear,
	},
	[ATTR_OPS_INDEX_BIGNUM] = {
		.from_user = op_attr_bignum_from_user,
		.to_user = op_attr_bignum_to_user,
		.to_binary = op_attr_bignum_to_binary,
		.from_binary = op_attr_bignum_from_binary,
		.from_obj = op_attr_bignum_from_obj,
		.free = op_attr_bignum_free,
		.clear = op_attr_bignum_clear,
	},
	[ATTR_OPS_INDEX_VALUE] = {
		.from_user = op_attr_value_from_user,
		.to_user = op_attr_value_to_user,
		.to_binary = op_attr_value_to_binary,
		.from_binary = op_attr_value_from_binary,
		.from_obj = op_attr_value_from_obj,
		.free = op_attr_value_clear, /* not a typo */
		.clear = op_attr_value_clear,
	},
};

static TEE_Result get_user_u64_as_size_t(size_t *dst, uint64_t *src)
{
	uint64_t d = 0;
	TEE_Result res = tee_svc_copy_from_user(&d, src, sizeof(d));

	/*
	 * On 32-bit systems a size_t can't hold a uint64_t so we need to
	 * check that the value isn't too large.
	 */
	if (!res && ADD_OVERFLOW(0, d, dst))
		return TEE_ERROR_OVERFLOW;

	return res;
}

static TEE_Result put_user_u64(uint64_t *dst, size_t value)
{
	uint64_t v = value;

	return tee_svc_copy_to_user(dst, &v, sizeof(v));
}

TEE_Result syscall_cryp_obj_get_info(unsigned long obj, TEE_ObjectInfo *info)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		goto exit;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		goto exit;

	res = tee_svc_copy_to_user(info, &o->info, sizeof(o->info));

exit:
	return res;
}

TEE_Result syscall_cryp_obj_restrict_usage(unsigned long obj,
			unsigned long usage)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		goto exit;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		goto exit;

	o->info.objectUsage &= usage;

exit:
	return res;
}

static int tee_svc_cryp_obj_find_type_attr_idx(
		uint32_t attr_id,
		const struct tee_cryp_obj_type_props *type_props)
{
	size_t n;

	for (n = 0; n < type_props->num_type_attrs; n++) {
		if (attr_id == type_props->type_attrs[n].attr_id)
			return n;
	}
	return -1;
}

static const struct tee_cryp_obj_type_props *tee_svc_find_type_props(
		TEE_ObjectType obj_type)
{
	size_t n;

	for (n = 0; n < ARRAY_SIZE(tee_cryp_obj_props); n++) {
		if (tee_cryp_obj_props[n].obj_type == obj_type)
			return tee_cryp_obj_props + n;
	}

	return NULL;
}

/* Set an attribute on an object */
static void set_attribute(struct tee_obj *o,
			  const struct tee_cryp_obj_type_props *props,
			  uint32_t attr)
{
	int idx = tee_svc_cryp_obj_find_type_attr_idx(attr, props);

	if (idx < 0)
		return;
	o->have_attrs |= BIT(idx);
}

/* Get an attribute on an object */
static uint32_t get_attribute(const struct tee_obj *o,
			      const struct tee_cryp_obj_type_props *props,
			      uint32_t attr)
{
	int idx = tee_svc_cryp_obj_find_type_attr_idx(attr, props);

	if (idx < 0)
		return 0;
	return o->have_attrs & BIT(idx);
}

TEE_Result syscall_cryp_obj_get_attr(unsigned long obj, unsigned long attr_id,
			void *buffer, uint64_t *size)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;
	const struct tee_cryp_obj_type_props *type_props;
	int idx;
	const struct attr_ops *ops;
	void *attr;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		return TEE_ERROR_ITEM_NOT_FOUND;

	/* Check that the object is initialized */
	if (!(o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
		return TEE_ERROR_BAD_PARAMETERS;

	/* Check that getting the attribute is allowed */
	if (!(attr_id & TEE_ATTR_BIT_PROTECTED) &&
	    !(o->info.objectUsage & TEE_USAGE_EXTRACTABLE))
		return TEE_ERROR_BAD_PARAMETERS;

	type_props = tee_svc_find_type_props(o->info.objectType);
	if (!type_props) {
		/* Unknown object type, "can't happen" */
		return TEE_ERROR_BAD_STATE;
	}

	idx = tee_svc_cryp_obj_find_type_attr_idx(attr_id, type_props);
	if ((idx < 0) || ((o->have_attrs & (1 << idx)) == 0))
		return TEE_ERROR_ITEM_NOT_FOUND;

	ops = attr_ops + type_props->type_attrs[idx].ops_index;
	attr = (uint8_t *)o->attr + type_props->type_attrs[idx].raw_offs;
	return ops->to_user(attr, sess, buffer, size);
}

void tee_obj_attr_free(struct tee_obj *o)
{
	const struct tee_cryp_obj_type_props *tp;
	size_t n;

	if (!o->attr)
		return;
	tp = tee_svc_find_type_props(o->info.objectType);
	if (!tp)
		return;

	for (n = 0; n < tp->num_type_attrs; n++) {
		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;

		attr_ops[ta->ops_index].free((uint8_t *)o->attr + ta->raw_offs);
	}
}

void tee_obj_attr_clear(struct tee_obj *o)
{
	const struct tee_cryp_obj_type_props *tp;
	size_t n;

	if (!o->attr)
		return;
	tp = tee_svc_find_type_props(o->info.objectType);
	if (!tp)
		return;

	for (n = 0; n < tp->num_type_attrs; n++) {
		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;

		attr_ops[ta->ops_index].clear((uint8_t *)o->attr +
					      ta->raw_offs);
	}
}

TEE_Result tee_obj_attr_to_binary(struct tee_obj *o, void *data,
				  size_t *data_len)
{
	const struct tee_cryp_obj_type_props *tp;
	size_t n;
	size_t offs = 0;
	size_t len = data ? *data_len : 0;
	TEE_Result res;

	if (o->info.objectType == TEE_TYPE_DATA) {
		*data_len = 0;
		return TEE_SUCCESS; /* pure data object */
	}
	if (!o->attr)
		return TEE_ERROR_BAD_STATE;
	tp = tee_svc_find_type_props(o->info.objectType);
	if (!tp)
		return TEE_ERROR_BAD_STATE;

	for (n = 0; n < tp->num_type_attrs; n++) {
		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;
		void *attr = (uint8_t *)o->attr + ta->raw_offs;

		res = attr_ops[ta->ops_index].to_binary(attr, data, len, &offs);
		if (res != TEE_SUCCESS)
			return res;
	}

	*data_len = offs;
	if (data && offs > len)
		return TEE_ERROR_SHORT_BUFFER;
	return TEE_SUCCESS;
}

TEE_Result tee_obj_attr_from_binary(struct tee_obj *o, const void *data,
				    size_t data_len)
{
	const struct tee_cryp_obj_type_props *tp;
	size_t n;
	size_t offs = 0;

	if (o->info.objectType == TEE_TYPE_DATA)
		return TEE_SUCCESS; /* pure data object */
	if (!o->attr)
		return TEE_ERROR_BAD_STATE;
	tp = tee_svc_find_type_props(o->info.objectType);
	if (!tp)
		return TEE_ERROR_BAD_STATE;

	for (n = 0; n < tp->num_type_attrs; n++) {
		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;
		void *attr = (uint8_t *)o->attr + ta->raw_offs;

		if (!attr_ops[ta->ops_index].from_binary(attr, data, data_len,
							 &offs))
			return TEE_ERROR_CORRUPT_OBJECT;
	}
	return TEE_SUCCESS;
}

TEE_Result tee_obj_attr_copy_from(struct tee_obj *o, const struct tee_obj *src)
{
	TEE_Result res;
	const struct tee_cryp_obj_type_props *tp;
	const struct tee_cryp_obj_type_attrs *ta;
	size_t n;
	uint32_t have_attrs = 0;
	void *attr;
	void *src_attr;

	if (o->info.objectType == TEE_TYPE_DATA)
		return TEE_SUCCESS; /* pure data object */
	if (!o->attr)
		return TEE_ERROR_BAD_STATE;
	tp = tee_svc_find_type_props(o->info.objectType);
	if (!tp)
		return TEE_ERROR_BAD_STATE;

	if (o->info.objectType == src->info.objectType) {
		have_attrs = src->have_attrs;
		for (n = 0; n < tp->num_type_attrs; n++) {
			ta = tp->type_attrs + n;
			attr = (uint8_t *)o->attr + ta->raw_offs;
			src_attr = (uint8_t *)src->attr + ta->raw_offs;
			res = attr_ops[ta->ops_index].from_obj(attr, src_attr);
			if (res != TEE_SUCCESS)
				return res;
		}
	} else {
		const struct tee_cryp_obj_type_props *tp_src;
		int idx;

		if (o->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_RSA_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else if (o->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_DSA_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else if (o->info.objectType == TEE_TYPE_ECDSA_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_ECDSA_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else if (o->info.objectType == TEE_TYPE_ECDH_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_ECDH_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else if (o->info.objectType == TEE_TYPE_SM2_DSA_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_SM2_DSA_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else if (o->info.objectType == TEE_TYPE_SM2_PKE_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_SM2_PKE_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else if (o->info.objectType == TEE_TYPE_SM2_KEP_PUBLIC_KEY) {
			if (src->info.objectType != TEE_TYPE_SM2_KEP_KEYPAIR)
				return TEE_ERROR_BAD_PARAMETERS;
		} else {
			return TEE_ERROR_BAD_PARAMETERS;
		}

		tp_src = tee_svc_find_type_props(src->info.objectType);
		if (!tp_src)
			return TEE_ERROR_BAD_STATE;

		have_attrs = BIT32(tp->num_type_attrs) - 1;
		for (n = 0; n < tp->num_type_attrs; n++) {
			ta = tp->type_attrs + n;

			idx = tee_svc_cryp_obj_find_type_attr_idx(ta->attr_id,
								  tp_src);
			if (idx < 0)
				return TEE_ERROR_BAD_STATE;

			attr = (uint8_t *)o->attr + ta->raw_offs;
			src_attr = (uint8_t *)src->attr +
				   tp_src->type_attrs[idx].raw_offs;
			res = attr_ops[ta->ops_index].from_obj(attr, src_attr);
			if (res != TEE_SUCCESS)
				return res;
		}
	}

	o->have_attrs = have_attrs;
	return TEE_SUCCESS;
}

TEE_Result tee_obj_set_type(struct tee_obj *o, uint32_t obj_type,
			    size_t max_key_size)
{
	TEE_Result res = TEE_SUCCESS;
	const struct tee_cryp_obj_type_props *type_props;

	/* Can only set type for newly allocated objs */
	if (o->attr)
		return TEE_ERROR_BAD_STATE;

	/*
	 * Verify that maxKeySize is supported and find out how
	 * much should be allocated.
	 */

	if (obj_type == TEE_TYPE_DATA) {
		if (max_key_size)
			return TEE_ERROR_NOT_SUPPORTED;
	} else {
		/* Find description of object */
		type_props = tee_svc_find_type_props(obj_type);
		if (!type_props)
			return TEE_ERROR_NOT_SUPPORTED;

		/* Check that maxKeySize follows restrictions */
		if (max_key_size % type_props->quanta != 0)
			return TEE_ERROR_NOT_SUPPORTED;
		if (max_key_size < type_props->min_size)
			return TEE_ERROR_NOT_SUPPORTED;
		if (max_key_size > type_props->max_size)
			return TEE_ERROR_NOT_SUPPORTED;

		o->attr = calloc(1, type_props->alloc_size);
		if (!o->attr)
			return TEE_ERROR_OUT_OF_MEMORY;
	}

	/* If we have a key structure, pre-allocate the bignums inside */
	switch (obj_type) {
	case TEE_TYPE_RSA_PUBLIC_KEY:
		res = crypto_acipher_alloc_rsa_public_key(o->attr,
							  max_key_size);
		break;
	case TEE_TYPE_RSA_KEYPAIR:
		res = crypto_acipher_alloc_rsa_keypair(o->attr, max_key_size);
		break;
	case TEE_TYPE_DSA_PUBLIC_KEY:
		res = crypto_acipher_alloc_dsa_public_key(o->attr,
							  max_key_size);
		break;
	case TEE_TYPE_DSA_KEYPAIR:
		res = crypto_acipher_alloc_dsa_keypair(o->attr, max_key_size);
		break;
	case TEE_TYPE_DH_KEYPAIR:
		res = crypto_acipher_alloc_dh_keypair(o->attr, max_key_size);
		break;
	case TEE_TYPE_ECDSA_PUBLIC_KEY:
	case TEE_TYPE_ECDH_PUBLIC_KEY:
	case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
	case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
	case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
		res = crypto_acipher_alloc_ecc_public_key(o->attr,
							  max_key_size);
		break;
	case TEE_TYPE_ECDSA_KEYPAIR:
	case TEE_TYPE_ECDH_KEYPAIR:
	case TEE_TYPE_SM2_DSA_KEYPAIR:
	case TEE_TYPE_SM2_PKE_KEYPAIR:
	case TEE_TYPE_SM2_KEP_KEYPAIR:
		res = crypto_acipher_alloc_ecc_keypair(o->attr, max_key_size);
		break;
	default:
		if (obj_type != TEE_TYPE_DATA) {
			struct tee_cryp_obj_secret *key = o->attr;

			key->alloc_size = type_props->alloc_size -
					  sizeof(*key);
		}
		break;
	}

	if (res != TEE_SUCCESS)
		return res;

	o->info.objectType = obj_type;
	o->info.maxKeySize = max_key_size;
	o->info.objectUsage = TEE_USAGE_DEFAULT;

	return TEE_SUCCESS;
}

TEE_Result syscall_cryp_obj_alloc(unsigned long obj_type,
			unsigned long max_key_size, uint32_t *obj)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;

	if (obj_type == TEE_TYPE_DATA)
		return TEE_ERROR_NOT_SUPPORTED;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	o = tee_obj_alloc();
	if (!o)
		return TEE_ERROR_OUT_OF_MEMORY;

	res = tee_obj_set_type(o, obj_type, max_key_size);
	if (res != TEE_SUCCESS) {
		tee_obj_free(o);
		return res;
	}

	tee_obj_add(to_user_ta_ctx(sess->ctx), o);

	res = tee_svc_copy_kaddr_to_uref(obj, o);
	if (res != TEE_SUCCESS)
		tee_obj_close(to_user_ta_ctx(sess->ctx), o);
	return res;
}

TEE_Result syscall_cryp_obj_close(unsigned long obj)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		return res;

	/*
	 * If it's busy it's used by an operation, a client should never have
	 * this handle.
	 */
	if (o->busy)
		return TEE_ERROR_ITEM_NOT_FOUND;

	tee_obj_close(to_user_ta_ctx(sess->ctx), o);
	return TEE_SUCCESS;
}

TEE_Result syscall_cryp_obj_reset(unsigned long obj)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		return res;

	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) == 0) {
		tee_obj_attr_clear(o);
		o->info.keySize = 0;
		o->info.objectUsage = TEE_USAGE_DEFAULT;
	} else {
		return TEE_ERROR_BAD_PARAMETERS;
	}

	/* the object is no more initialized */
	o->info.handleFlags &= ~TEE_HANDLE_FLAG_INITIALIZED;

	return TEE_SUCCESS;
}

static TEE_Result copy_in_attrs(struct user_ta_ctx *utc,
			const struct utee_attribute *usr_attrs,
			uint32_t attr_count, TEE_Attribute *attrs)
{
	TEE_Result res = TEE_SUCCESS;
	size_t size = 0;
	uint32_t n = 0;

	if (MUL_OVERFLOW(sizeof(struct utee_attribute), attr_count, &size))
		return TEE_ERROR_OVERFLOW;

	res = tee_mmu_check_access_rights(&utc->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)usr_attrs, size);
	if (res != TEE_SUCCESS)
		return res;

	for (n = 0; n < attr_count; n++) {
		attrs[n].attributeID = usr_attrs[n].attribute_id;
		if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
			attrs[n].content.value.a = usr_attrs[n].a;
			attrs[n].content.value.b = usr_attrs[n].b;
		} else {
			uintptr_t buf = usr_attrs[n].a;
			size_t len = usr_attrs[n].b;
			uint32_t flags = TEE_MEMORY_ACCESS_READ |
					 TEE_MEMORY_ACCESS_ANY_OWNER;

			res = tee_mmu_check_access_rights(&utc->uctx, flags,
							  buf, len);
			if (res != TEE_SUCCESS)
				return res;
			attrs[n].content.ref.buffer = (void *)buf;
			attrs[n].content.ref.length = len;
		}
	}

	return TEE_SUCCESS;
}

enum attr_usage {
	ATTR_USAGE_POPULATE,
	ATTR_USAGE_GENERATE_KEY
};

static TEE_Result tee_svc_cryp_check_attr(enum attr_usage usage,
					  const struct tee_cryp_obj_type_props
						*type_props,
					  const TEE_Attribute *attrs,
					  uint32_t attr_count)
{
	uint32_t required_flag;
	uint32_t opt_flag;
	bool all_opt_needed;
	uint32_t req_attrs = 0;
	uint32_t opt_grp_attrs = 0;
	uint32_t attrs_found = 0;
	size_t n;
	uint32_t bit;
	uint32_t flags;
	int idx;

	if (usage == ATTR_USAGE_POPULATE) {
		required_flag = TEE_TYPE_ATTR_REQUIRED;
		opt_flag = TEE_TYPE_ATTR_OPTIONAL_GROUP;
		all_opt_needed = true;
	} else {
		required_flag = TEE_TYPE_ATTR_GEN_KEY_REQ;
		opt_flag = TEE_TYPE_ATTR_GEN_KEY_OPT;
		all_opt_needed = false;
	}

	/*
	 * First find out which attributes are required and which belong to
	 * the optional group
	 */
	for (n = 0; n < type_props->num_type_attrs; n++) {
		bit = 1 << n;
		flags = type_props->type_attrs[n].flags;

		if (flags & required_flag)
			req_attrs |= bit;
		else if (flags & opt_flag)
			opt_grp_attrs |= bit;
	}

	/*
	 * Verify that all required attributes are in place and
	 * that the same attribute isn't repeated.
	 */
	for (n = 0; n < attr_count; n++) {
		idx = tee_svc_cryp_obj_find_type_attr_idx(
							attrs[n].attributeID,
							type_props);

		/* attribute not defined in current object type */
		if (idx < 0)
			return TEE_ERROR_ITEM_NOT_FOUND;

		bit = 1 << idx;

		/* attribute not repeated */
		if ((attrs_found & bit) != 0)
			return TEE_ERROR_ITEM_NOT_FOUND;

		attrs_found |= bit;
	}
	/* Required attribute missing */
	if ((attrs_found & req_attrs) != req_attrs)
		return TEE_ERROR_ITEM_NOT_FOUND;

	/*
	 * If the flag says that "if one of the optional attributes are included
	 * all of them has to be included" this must be checked.
	 */
	if (all_opt_needed && (attrs_found & opt_grp_attrs) != 0 &&
	    (attrs_found & opt_grp_attrs) != opt_grp_attrs)
		return TEE_ERROR_ITEM_NOT_FOUND;

	return TEE_SUCCESS;
}

static TEE_Result get_ec_key_size(uint32_t curve, size_t *key_size)
{
	switch (curve) {
	case TEE_ECC_CURVE_NIST_P192:
		*key_size = 192;
		break;
	case TEE_ECC_CURVE_NIST_P224:
		*key_size = 224;
		break;
	case TEE_ECC_CURVE_NIST_P256:
		*key_size = 256;
		break;
	case TEE_ECC_CURVE_NIST_P384:
		*key_size = 384;
		break;
	case TEE_ECC_CURVE_NIST_P521:
		*key_size = 521;
		break;
	case TEE_ECC_CURVE_SM2:
		*key_size = 256;
		break;
	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	return TEE_SUCCESS;
}

static TEE_Result tee_svc_cryp_obj_populate_type(
		struct tee_obj *o,
		const struct tee_cryp_obj_type_props *type_props,
		const TEE_Attribute *attrs,
		uint32_t attr_count)
{
	TEE_Result res;
	uint32_t have_attrs = 0;
	size_t obj_size = 0;
	size_t n;
	int idx;
	const struct attr_ops *ops;
	void *attr;

	for (n = 0; n < attr_count; n++) {
		idx = tee_svc_cryp_obj_find_type_attr_idx(
							attrs[n].attributeID,
							type_props);
		/* attribute not defined in current object type */
		if (idx < 0)
			return TEE_ERROR_ITEM_NOT_FOUND;

		have_attrs |= BIT32(idx);
		ops = attr_ops + type_props->type_attrs[idx].ops_index;
		attr = (uint8_t *)o->attr +
		       type_props->type_attrs[idx].raw_offs;
		if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE)
			res = ops->from_user(attr, &attrs[n].content.value,
					     sizeof(attrs[n].content.value));
		else
			res = ops->from_user(attr, attrs[n].content.ref.buffer,
					     attrs[n].content.ref.length);
		if (res != TEE_SUCCESS)
			return res;

		/*
		 * First attr_idx signifies the attribute that gives the size
		 * of the object
		 */
		if (type_props->type_attrs[idx].flags &
		    TEE_TYPE_ATTR_SIZE_INDICATOR) {
			/*
			 * For ECDSA/ECDH we need to translate curve into
			 * object size
			 */
			if (attrs[n].attributeID == TEE_ATTR_ECC_CURVE) {
				res = get_ec_key_size(attrs[n].content.value.a,
						      &obj_size);
				if (res != TEE_SUCCESS)
					return res;
			} else {
				obj_size += (attrs[n].content.ref.length * 8);
			}
		}
	}

	/*
	 * We have to do it like this because the parity bits aren't counted
	 * when telling the size of the key in bits.
	 */
	if (o->info.objectType == TEE_TYPE_DES ||
	    o->info.objectType == TEE_TYPE_DES3)
		obj_size -= obj_size / 8; /* Exclude parity in size of key */

	o->have_attrs = have_attrs;
	o->info.keySize = obj_size;

	return TEE_SUCCESS;
}

TEE_Result syscall_cryp_obj_populate(unsigned long obj,
			struct utee_attribute *usr_attrs,
			unsigned long attr_count)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *o;
	const struct tee_cryp_obj_type_props *type_props;
	TEE_Attribute *attrs = NULL;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		return res;

	/* Must be a transient object */
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
		return TEE_ERROR_BAD_PARAMETERS;

	/* Must not be initialized already */
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
		return TEE_ERROR_BAD_PARAMETERS;

	type_props = tee_svc_find_type_props(o->info.objectType);
	if (!type_props)
		return TEE_ERROR_NOT_IMPLEMENTED;

	size_t alloc_size = 0;

	if (MUL_OVERFLOW(sizeof(TEE_Attribute), attr_count, &alloc_size))
		return TEE_ERROR_OVERFLOW;

	attrs = malloc(alloc_size);
	if (!attrs)
		return TEE_ERROR_OUT_OF_MEMORY;

	res = copy_in_attrs(to_user_ta_ctx(sess->ctx), usr_attrs, attr_count,
			    attrs);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_svc_cryp_check_attr(ATTR_USAGE_POPULATE, type_props,
				      attrs, attr_count);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_svc_cryp_obj_populate_type(o, type_props, attrs, attr_count);
	if (res == TEE_SUCCESS)
		o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;

out:
	free_wipe(attrs);
	return res;
}

TEE_Result syscall_cryp_obj_copy(unsigned long dst, unsigned long src)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	struct tee_obj *dst_o;
	struct tee_obj *src_o;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(dst), &dst_o);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(src), &src_o);
	if (res != TEE_SUCCESS)
		return res;

	if ((src_o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		return TEE_ERROR_BAD_PARAMETERS;
	if ((dst_o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
		return TEE_ERROR_BAD_PARAMETERS;
	if ((dst_o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
		return TEE_ERROR_BAD_PARAMETERS;

	res = tee_obj_attr_copy_from(dst_o, src_o);
	if (res != TEE_SUCCESS)
		return res;

	dst_o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
	dst_o->info.keySize = src_o->info.keySize;
	dst_o->info.objectUsage = src_o->info.objectUsage;
	return TEE_SUCCESS;
}

static TEE_Result tee_svc_obj_generate_key_rsa(
	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
	uint32_t key_size,
	const TEE_Attribute *params, uint32_t param_count)
{
	TEE_Result res;
	struct rsa_keypair *key = o->attr;
	uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537);

	/* Copy the present attributes into the obj before starting */
	res = tee_svc_cryp_obj_populate_type(o, type_props, params,
					     param_count);
	if (res != TEE_SUCCESS)
		return res;
	if (!get_attribute(o, type_props, TEE_ATTR_RSA_PUBLIC_EXPONENT))
		crypto_bignum_bin2bn((const uint8_t *)&e, sizeof(e), key->e);
	res = crypto_acipher_gen_rsa_key(key, key_size);
	if (res != TEE_SUCCESS)
		return res;

	/* Set bits for all known attributes for this object type */
	o->have_attrs = (1 << type_props->num_type_attrs) - 1;

	return TEE_SUCCESS;
}

static TEE_Result tee_svc_obj_generate_key_dsa(
	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
	uint32_t key_size)
{
	TEE_Result res;

	res = crypto_acipher_gen_dsa_key(o->attr, key_size);
	if (res != TEE_SUCCESS)
		return res;

	/* Set bits for all known attributes for this object type */
	o->have_attrs = (1 << type_props->num_type_attrs) - 1;

	return TEE_SUCCESS;
}

static TEE_Result tee_svc_obj_generate_key_dh(
	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
	uint32_t key_size __unused,
	const TEE_Attribute *params, uint32_t param_count)
{
	TEE_Result res;
	struct dh_keypair *tee_dh_key;
	struct bignum *dh_q = NULL;
	uint32_t dh_xbits = 0;

	/* Copy the present attributes into the obj before starting */
	res = tee_svc_cryp_obj_populate_type(o, type_props, params,
					     param_count);
	if (res != TEE_SUCCESS)
		return res;

	tee_dh_key = (struct dh_keypair *)o->attr;

	if (get_attribute(o, type_props, TEE_ATTR_DH_SUBPRIME))
		dh_q = tee_dh_key->q;
	if (get_attribute(o, type_props, TEE_ATTR_DH_X_BITS))
		dh_xbits = tee_dh_key->xbits;
	res = crypto_acipher_gen_dh_key(tee_dh_key, dh_q, dh_xbits);
	if (res != TEE_SUCCESS)
		return res;

	/* Set bits for the generated public and private key */
	set_attribute(o, type_props, TEE_ATTR_DH_PUBLIC_VALUE);
	set_attribute(o, type_props, TEE_ATTR_DH_PRIVATE_VALUE);
	set_attribute(o, type_props, TEE_ATTR_DH_X_BITS);
	return TEE_SUCCESS;
}

static TEE_Result tee_svc_obj_generate_key_ecc(
	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
	uint32_t key_size __unused,
	const TEE_Attribute *params, uint32_t param_count)
{
	TEE_Result res;
	struct ecc_keypair *tee_ecc_key;

	/* Copy the present attributes into the obj before starting */
	res = tee_svc_cryp_obj_populate_type(o, type_props, params,
					     param_count);
	if (res != TEE_SUCCESS)
		return res;

	tee_ecc_key = (struct ecc_keypair *)o->attr;

	res = crypto_acipher_gen_ecc_key(tee_ecc_key);
	if (res != TEE_SUCCESS)
		return res;

	/* Set bits for the generated public and private key */
	set_attribute(o, type_props, TEE_ATTR_ECC_PRIVATE_VALUE);
	set_attribute(o, type_props, TEE_ATTR_ECC_PUBLIC_VALUE_X);
	set_attribute(o, type_props, TEE_ATTR_ECC_PUBLIC_VALUE_Y);
	set_attribute(o, type_props, TEE_ATTR_ECC_CURVE);
	return TEE_SUCCESS;
}

TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size,
			const struct utee_attribute *usr_params,
			unsigned long param_count)
{
	TEE_Result res;
	struct tee_ta_session *sess;
	const struct tee_cryp_obj_type_props *type_props;
	struct tee_obj *o;
	struct tee_cryp_obj_secret *key;
	size_t byte_size;
	TEE_Attribute *params = NULL;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
			  tee_svc_uref_to_vaddr(obj), &o);
	if (res != TEE_SUCCESS)
		return res;

	/* Must be a transient object */
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
		return TEE_ERROR_BAD_STATE;

	/* Must not be initialized already */
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
		return TEE_ERROR_BAD_STATE;

	/* Find description of object */
	type_props = tee_svc_find_type_props(o->info.objectType);
	if (!type_props)
		return TEE_ERROR_NOT_SUPPORTED;

	/* Check that maxKeySize follows restrictions */
	if (key_size % type_props->quanta != 0)
		return TEE_ERROR_NOT_SUPPORTED;
	if (key_size < type_props->min_size)
		return TEE_ERROR_NOT_SUPPORTED;
	if (key_size > type_props->max_size)
		return TEE_ERROR_NOT_SUPPORTED;

	size_t alloc_size = 0;

	if (MUL_OVERFLOW(sizeof(TEE_Attribute), param_count, &alloc_size))
		return TEE_ERROR_OVERFLOW;

	params = malloc(alloc_size);
	if (!params)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = copy_in_attrs(to_user_ta_ctx(sess->ctx), usr_params, param_count,
			    params);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_svc_cryp_check_attr(ATTR_USAGE_GENERATE_KEY, type_props,
				      params, param_count);
	if (res != TEE_SUCCESS)
		goto out;

	switch (o->info.objectType) {
	case TEE_TYPE_AES:
	case TEE_TYPE_DES:
	case TEE_TYPE_DES3:
	case TEE_TYPE_SM4:
	case TEE_TYPE_HMAC_MD5:
	case TEE_TYPE_HMAC_SHA1:
	case TEE_TYPE_HMAC_SHA224:
	case TEE_TYPE_HMAC_SHA256:
	case TEE_TYPE_HMAC_SHA384:
	case TEE_TYPE_HMAC_SHA512:
	case TEE_TYPE_HMAC_SM3:
	case TEE_TYPE_GENERIC_SECRET:
		byte_size = key_size / 8;

		/*
		 * We have to do it like this because the parity bits aren't
		 * counted when telling the size of the key in bits.
		 */
		if (o->info.objectType == TEE_TYPE_DES ||
		    o->info.objectType == TEE_TYPE_DES3) {
			byte_size = (key_size + key_size / 7) / 8;
		}

		key = (struct tee_cryp_obj_secret *)o->attr;
		if (byte_size > key->alloc_size) {
			res = TEE_ERROR_EXCESS_DATA;
			goto out;
		}

		res = crypto_rng_read((void *)(key + 1), byte_size);
		if (res != TEE_SUCCESS)
			goto out;

		key->key_size = byte_size;

		/* Set bits for all known attributes for this object type */
		o->have_attrs = (1 << type_props->num_type_attrs) - 1;

		break;

	case TEE_TYPE_RSA_KEYPAIR:
		res = tee_svc_obj_generate_key_rsa(o, type_props, key_size,
						   params, param_count);
		if (res != TEE_SUCCESS)
			goto out;
		break;

	case TEE_TYPE_DSA_KEYPAIR:
		res = tee_svc_obj_generate_key_dsa(o, type_props, key_size);
		if (res != TEE_SUCCESS)
			goto out;
		break;

	case TEE_TYPE_DH_KEYPAIR:
		res = tee_svc_obj_generate_key_dh(o, type_props, key_size,
						  params, param_count);
		if (res != TEE_SUCCESS)
			goto out;
		break;

	case TEE_TYPE_ECDSA_KEYPAIR:
	case TEE_TYPE_ECDH_KEYPAIR:
	case TEE_TYPE_SM2_PKE_KEYPAIR:
		res = tee_svc_obj_generate_key_ecc(o, type_props, key_size,
						  params, param_count);
		if (res != TEE_SUCCESS)
			goto out;
		break;

	default:
		res = TEE_ERROR_BAD_FORMAT;
	}

out:
	free_wipe(params);
	if (res == TEE_SUCCESS) {
		o->info.keySize = key_size;
		o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
	}
	return res;
}

static TEE_Result tee_svc_cryp_get_state(struct tee_ta_session *sess,
					 uint32_t state_id,
					 struct tee_cryp_state **state)
{
	struct tee_cryp_state *s;
	struct user_ta_ctx *utc = to_user_ta_ctx(sess->ctx);

	TAILQ_FOREACH(s, &utc->cryp_states, link) {
		if (state_id == (vaddr_t)s) {
			*state = s;
			return TEE_SUCCESS;
		}
	}
	return TEE_ERROR_BAD_PARAMETERS;
}

static void cryp_state_free(struct user_ta_ctx *utc, struct tee_cryp_state *cs)
{
	struct tee_obj *o;

	if (tee_obj_get(utc, cs->key1, &o) == TEE_SUCCESS)
		tee_obj_close(utc, o);
	if (tee_obj_get(utc, cs->key2, &o) == TEE_SUCCESS)
		tee_obj_close(utc, o);

	TAILQ_REMOVE(&utc->cryp_states, cs, link);
	if (cs->ctx_finalize != NULL)
		cs->ctx_finalize(cs->ctx);

	switch (TEE_ALG_GET_CLASS(cs->algo)) {
	case TEE_OPERATION_CIPHER:
		crypto_cipher_free_ctx(cs->ctx);
		break;
	case TEE_OPERATION_AE:
		crypto_authenc_free_ctx(cs->ctx);
		break;
	case TEE_OPERATION_DIGEST:
		crypto_hash_free_ctx(cs->ctx);
		break;
	case TEE_OPERATION_MAC:
		crypto_mac_free_ctx(cs->ctx);
		break;
	default:
		assert(!cs->ctx);
	}

	free(cs);
}

static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o,
					      uint32_t algo,
					      TEE_OperationMode mode)
{
	uint32_t req_key_type;
	uint32_t req_key_type2 = 0;

	switch (TEE_ALG_GET_MAIN_ALG(algo)) {
	case TEE_MAIN_ALGO_MD5:
		req_key_type = TEE_TYPE_HMAC_MD5;
		break;
	case TEE_MAIN_ALGO_SHA1:
		req_key_type = TEE_TYPE_HMAC_SHA1;
		break;
	case TEE_MAIN_ALGO_SHA224:
		req_key_type = TEE_TYPE_HMAC_SHA224;
		break;
	case TEE_MAIN_ALGO_SHA256:
		req_key_type = TEE_TYPE_HMAC_SHA256;
		break;
	case TEE_MAIN_ALGO_SHA384:
		req_key_type = TEE_TYPE_HMAC_SHA384;
		break;
	case TEE_MAIN_ALGO_SHA512:
		req_key_type = TEE_TYPE_HMAC_SHA512;
		break;
	case TEE_MAIN_ALGO_SM3:
		req_key_type = TEE_TYPE_HMAC_SM3;
		break;
	case TEE_MAIN_ALGO_AES:
		req_key_type = TEE_TYPE_AES;
		break;
	case TEE_MAIN_ALGO_DES:
		req_key_type = TEE_TYPE_DES;
		break;
	case TEE_MAIN_ALGO_DES3:
		req_key_type = TEE_TYPE_DES3;
		break;
	case TEE_MAIN_ALGO_SM4:
		req_key_type = TEE_TYPE_SM4;
		break;
	case TEE_MAIN_ALGO_RSA:
		req_key_type = TEE_TYPE_RSA_KEYPAIR;
		if (mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY)
			req_key_type2 = TEE_TYPE_RSA_PUBLIC_KEY;
		break;
	case TEE_MAIN_ALGO_DSA:
		req_key_type = TEE_TYPE_DSA_KEYPAIR;
		if (mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY)
			req_key_type2 = TEE_TYPE_DSA_PUBLIC_KEY;
		break;
	case TEE_MAIN_ALGO_DH:
		req_key_type = TEE_TYPE_DH_KEYPAIR;
		break;
	case TEE_MAIN_ALGO_ECDSA:
		req_key_type = TEE_TYPE_ECDSA_KEYPAIR;
		if (mode == TEE_MODE_VERIFY)
			req_key_type2 = TEE_TYPE_ECDSA_PUBLIC_KEY;
		break;
	case TEE_MAIN_ALGO_ECDH:
		req_key_type = TEE_TYPE_ECDH_KEYPAIR;
		break;
	case TEE_MAIN_ALGO_SM2_PKE:
		if (mode == TEE_MODE_ENCRYPT)
			req_key_type = TEE_TYPE_SM2_PKE_PUBLIC_KEY;
		else
			req_key_type = TEE_TYPE_SM2_PKE_KEYPAIR;
		break;
	case TEE_MAIN_ALGO_SM2_DSA_SM3:
		if (mode == TEE_MODE_VERIFY)
			req_key_type = TEE_TYPE_SM2_DSA_PUBLIC_KEY;
		else
			req_key_type = TEE_TYPE_SM2_DSA_KEYPAIR;
		break;
#if defined(CFG_CRYPTO_SM2_KEP)
	case TEE_MAIN_ALGO_SM2_KEP:
		req_key_type = TEE_TYPE_SM2_KEP_KEYPAIR;
		req_key_type2 = TEE_TYPE_SM2_KEP_PUBLIC_KEY;
		break;
#endif
#if defined(CFG_CRYPTO_HKDF)
	case TEE_MAIN_ALGO_HKDF:
		req_key_type = TEE_TYPE_HKDF_IKM;
		break;
#endif
#if defined(CFG_CRYPTO_CONCAT_KDF)
	case TEE_MAIN_ALGO_CONCAT_KDF:
		req_key_type = TEE_TYPE_CONCAT_KDF_Z;
		break;
#endif
#if defined(CFG_CRYPTO_PBKDF2)
	case TEE_MAIN_ALGO_PBKDF2:
		req_key_type = TEE_TYPE_PBKDF2_PASSWORD;
		break;
#endif
	default:
		return TEE_ERROR_BAD_PARAMETERS;
	}

	if (req_key_type != o->info.objectType &&
	    req_key_type2 != o->info.objectType)
		return TEE_ERROR_BAD_PARAMETERS;
	return TEE_SUCCESS;
}

TEE_Result syscall_cryp_state_alloc(unsigned long algo, unsigned long mode,
			unsigned long key1, unsigned long key2,
			uint32_t *state)
{
	TEE_Result res;
	struct tee_cryp_state *cs;
	struct tee_ta_session *sess;
	struct tee_obj *o1 = NULL;
	struct tee_obj *o2 = NULL;
	struct user_ta_ctx *utc;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	if (key1 != 0) {
		res = tee_obj_get(utc, tee_svc_uref_to_vaddr(key1), &o1);
		if (res != TEE_SUCCESS)
			return res;
		if (o1->busy)
			return TEE_ERROR_BAD_PARAMETERS;
		res = tee_svc_cryp_check_key_type(o1, algo, mode);
		if (res != TEE_SUCCESS)
			return res;
	}
	if (key2 != 0) {
		res = tee_obj_get(utc, tee_svc_uref_to_vaddr(key2), &o2);
		if (res != TEE_SUCCESS)
			return res;
		if (o2->busy)
			return TEE_ERROR_BAD_PARAMETERS;
		res = tee_svc_cryp_check_key_type(o2, algo, mode);
		if (res != TEE_SUCCESS)
			return res;
	}

	cs = calloc(1, sizeof(struct tee_cryp_state));
	if (!cs)
		return TEE_ERROR_OUT_OF_MEMORY;
	TAILQ_INSERT_TAIL(&utc->cryp_states, cs, link);
	cs->algo = algo;
	cs->mode = mode;
	cs->state = CRYP_STATE_UNINITIALIZED;

	switch (TEE_ALG_GET_CLASS(algo)) {
	case TEE_OPERATION_EXTENSION:
#ifdef CFG_CRYPTO_RSASSA_NA1
		if (algo == TEE_ALG_RSASSA_PKCS1_V1_5)
			goto rsassa_na1;
#endif
		res = TEE_ERROR_NOT_SUPPORTED;
		break;
	case TEE_OPERATION_CIPHER:
		if ((algo == TEE_ALG_AES_XTS && (key1 == 0 || key2 == 0)) ||
		    (algo != TEE_ALG_AES_XTS && (key1 == 0 || key2 != 0))) {
			res = TEE_ERROR_BAD_PARAMETERS;
		} else {
			res = crypto_cipher_alloc_ctx(&cs->ctx, algo);
			if (res != TEE_SUCCESS)
				break;
		}
		break;
	case TEE_OPERATION_AE:
		if (key1 == 0 || key2 != 0) {
			res = TEE_ERROR_BAD_PARAMETERS;
		} else {
			res = crypto_authenc_alloc_ctx(&cs->ctx, algo);
			if (res != TEE_SUCCESS)
				break;
		}
		break;
	case TEE_OPERATION_MAC:
		if (key1 == 0 || key2 != 0) {
			res = TEE_ERROR_BAD_PARAMETERS;
		} else {
			res = crypto_mac_alloc_ctx(&cs->ctx, algo);
			if (res != TEE_SUCCESS)
				break;
		}
		break;
	case TEE_OPERATION_DIGEST:
		if (key1 != 0 || key2 != 0) {
			res = TEE_ERROR_BAD_PARAMETERS;
		} else {
			res = crypto_hash_alloc_ctx(&cs->ctx, algo);
			if (res != TEE_SUCCESS)
				break;
		}
		break;
	case TEE_OPERATION_ASYMMETRIC_CIPHER:
	case TEE_OPERATION_ASYMMETRIC_SIGNATURE:
rsassa_na1: __maybe_unused
		if (key1 == 0 || key2 != 0)
			res = TEE_ERROR_BAD_PARAMETERS;
		break;
	case TEE_OPERATION_KEY_DERIVATION:
		if (algo == TEE_ALG_SM2_KEP) {
			if (key1 == 0 || key2 == 0)
				res = TEE_ERROR_BAD_PARAMETERS;
		} else {
			if (key1 == 0 || key2 != 0)
				res = TEE_ERROR_BAD_PARAMETERS;
		}
		break;
	default:
		res = TEE_ERROR_NOT_SUPPORTED;
		break;
	}
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_svc_copy_kaddr_to_uref(state, cs);
	if (res != TEE_SUCCESS)
		goto out;

	/* Register keys */
	if (o1 != NULL) {
		o1->busy = true;
		cs->key1 = (vaddr_t)o1;
	}
	if (o2 != NULL) {
		o2->busy = true;
		cs->key2 = (vaddr_t)o2;
	}

out:
	if (res != TEE_SUCCESS)
		cryp_state_free(utc, cs);
	return res;
}

TEE_Result syscall_cryp_state_copy(unsigned long dst, unsigned long src)
{
	TEE_Result res;
	struct tee_cryp_state *cs_dst;
	struct tee_cryp_state *cs_src;
	struct tee_ta_session *sess;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(dst), &cs_dst);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(src), &cs_src);
	if (res != TEE_SUCCESS)
		return res;
	if (cs_dst->algo != cs_src->algo || cs_dst->mode != cs_src->mode)
		return TEE_ERROR_BAD_PARAMETERS;

	switch (TEE_ALG_GET_CLASS(cs_src->algo)) {
	case TEE_OPERATION_CIPHER:
		crypto_cipher_copy_state(cs_dst->ctx, cs_src->ctx);
		break;
	case TEE_OPERATION_AE:
		crypto_authenc_copy_state(cs_dst->ctx, cs_src->ctx);
		break;
	case TEE_OPERATION_DIGEST:
		crypto_hash_copy_state(cs_dst->ctx, cs_src->ctx);
		break;
	case TEE_OPERATION_MAC:
		crypto_mac_copy_state(cs_dst->ctx, cs_src->ctx);
		break;
	default:
		return TEE_ERROR_BAD_STATE;
	}

	cs_dst->state = cs_src->state;

	return TEE_SUCCESS;
}

void tee_svc_cryp_free_states(struct user_ta_ctx *utc)
{
	struct tee_cryp_state_head *states = &utc->cryp_states;

	while (!TAILQ_EMPTY(states))
		cryp_state_free(utc, TAILQ_FIRST(states));
}

TEE_Result syscall_cryp_state_free(unsigned long state)
{
	TEE_Result res;
	struct tee_cryp_state *cs;
	struct tee_ta_session *sess;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;
	cryp_state_free(to_user_ta_ctx(sess->ctx), cs);
	return TEE_SUCCESS;
}

TEE_Result syscall_hash_init(unsigned long state,
			     const void *iv __maybe_unused,
			     size_t iv_len __maybe_unused)
{
	TEE_Result res;
	struct tee_cryp_state *cs;
	struct tee_ta_session *sess;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	switch (TEE_ALG_GET_CLASS(cs->algo)) {
	case TEE_OPERATION_DIGEST:
		res = crypto_hash_init(cs->ctx);
		if (res != TEE_SUCCESS)
			return res;
		break;
	case TEE_OPERATION_MAC:
		{
			struct tee_obj *o;
			struct tee_cryp_obj_secret *key;

			res = tee_obj_get(to_user_ta_ctx(sess->ctx),
					  cs->key1, &o);
			if (res != TEE_SUCCESS)
				return res;
			if ((o->info.handleFlags &
			     TEE_HANDLE_FLAG_INITIALIZED) == 0)
				return TEE_ERROR_BAD_PARAMETERS;

			key = (struct tee_cryp_obj_secret *)o->attr;
			res = crypto_mac_init(cs->ctx, (void *)(key + 1),
					      key->key_size);
			if (res != TEE_SUCCESS)
				return res;
			break;
		}
	default:
		return TEE_ERROR_BAD_PARAMETERS;
	}

	cs->state = CRYP_STATE_INITIALIZED;

	return TEE_SUCCESS;
}

TEE_Result syscall_hash_update(unsigned long state, const void *chunk,
			size_t chunk_size)
{
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res = TEE_SUCCESS;

	/* No data, but size provided isn't valid parameters. */
	if (!chunk && chunk_size)
		return TEE_ERROR_BAD_PARAMETERS;

	/* Zero length hash is valid, but nothing we need to do. */
	if (!chunk_size)
		return TEE_SUCCESS;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)chunk, chunk_size);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	switch (TEE_ALG_GET_CLASS(cs->algo)) {
	case TEE_OPERATION_DIGEST:
		res = crypto_hash_update(cs->ctx, chunk, chunk_size);
		if (res != TEE_SUCCESS)
			return res;
		break;
	case TEE_OPERATION_MAC:
		res = crypto_mac_update(cs->ctx, chunk, chunk_size);
		if (res != TEE_SUCCESS)
			return res;
		break;
	default:
		return TEE_ERROR_BAD_PARAMETERS;
	}

	return TEE_SUCCESS;
}

TEE_Result syscall_hash_final(unsigned long state, const void *chunk,
			size_t chunk_size, void *hash, uint64_t *hash_len)
{
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res2 = TEE_SUCCESS;
	TEE_Result res = TEE_SUCCESS;
	size_t hash_size = 0;
	size_t hlen = 0;

	/* No data, but size provided isn't valid parameters. */
	if (!chunk && chunk_size)
		return TEE_ERROR_BAD_PARAMETERS;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)chunk, chunk_size);
	if (res != TEE_SUCCESS)
		return res;

	res = get_user_u64_as_size_t(&hlen, hash_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)hash, hlen);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	switch (TEE_ALG_GET_CLASS(cs->algo)) {
	case TEE_OPERATION_DIGEST:
		res = tee_hash_get_digest_size(cs->algo, &hash_size);
		if (res != TEE_SUCCESS)
			return res;
		if (hlen < hash_size) {
			res = TEE_ERROR_SHORT_BUFFER;
			goto out;
		}

		if (chunk_size) {
			res = crypto_hash_update(cs->ctx, chunk, chunk_size);
			if (res != TEE_SUCCESS)
				return res;
		}

		res = crypto_hash_final(cs->ctx, hash, hash_size);
		if (res != TEE_SUCCESS)
			return res;
		break;

	case TEE_OPERATION_MAC:
		res = tee_mac_get_digest_size(cs->algo, &hash_size);
		if (res != TEE_SUCCESS)
			return res;
		if (hlen < hash_size) {
			res = TEE_ERROR_SHORT_BUFFER;
			goto out;
		}

		if (chunk_size) {
			res = crypto_mac_update(cs->ctx, chunk, chunk_size);
			if (res != TEE_SUCCESS)
				return res;
		}

		res = crypto_mac_final(cs->ctx, hash, hash_size);
		if (res != TEE_SUCCESS)
			return res;
		break;

	default:
		return TEE_ERROR_BAD_PARAMETERS;
	}
out:
	res2 = put_user_u64(hash_len, hash_size);
	if (res2 != TEE_SUCCESS)
		return res2;
	return res;
}

TEE_Result syscall_cipher_init(unsigned long state, const void *iv,
			size_t iv_len)
{
	struct tee_cryp_obj_secret *key1 = NULL;
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	struct user_ta_ctx *utc = NULL;
	TEE_Result res = TEE_SUCCESS;
	struct tee_obj *o = NULL;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (TEE_ALG_GET_CLASS(cs->algo) != TEE_OPERATION_CIPHER)
		return TEE_ERROR_BAD_STATE;

	res = tee_mmu_check_access_rights(&utc->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)iv, iv_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(utc, cs->key1, &o);
	if (res != TEE_SUCCESS)
		return res;
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		return TEE_ERROR_BAD_PARAMETERS;

	key1 = o->attr;

	if (tee_obj_get(utc, cs->key2, &o) == TEE_SUCCESS) {
		struct tee_cryp_obj_secret *key2 = o->attr;

		if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
			return TEE_ERROR_BAD_PARAMETERS;

		res = crypto_cipher_init(cs->ctx, cs->mode,
					 (uint8_t *)(key1 + 1), key1->key_size,
					 (uint8_t *)(key2 + 1), key2->key_size,
					 iv, iv_len);
	} else {
		res = crypto_cipher_init(cs->ctx, cs->mode,
					 (uint8_t *)(key1 + 1), key1->key_size,
					 NULL, 0, iv, iv_len);
	}
	if (res != TEE_SUCCESS)
		return res;

	cs->ctx_finalize = crypto_cipher_final;
	cs->state = CRYP_STATE_INITIALIZED;

	return TEE_SUCCESS;
}

static TEE_Result tee_svc_cipher_update_helper(unsigned long state,
			bool last_block, const void *src, size_t src_len,
			void *dst, uint64_t *dst_len)
{
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res = TEE_SUCCESS;
	size_t dlen = 0;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)src, src_len);
	if (res != TEE_SUCCESS)
		return res;

	if (!dst_len) {
		dlen = 0;
	} else {
		struct user_mode_ctx *uctx = &to_user_ta_ctx(sess->ctx)->uctx;
		uint32_t flags = TEE_MEMORY_ACCESS_READ |
				 TEE_MEMORY_ACCESS_WRITE |
				 TEE_MEMORY_ACCESS_ANY_OWNER;

		res = get_user_u64_as_size_t(&dlen, dst_len);
		if (res != TEE_SUCCESS)
			return res;

		res = tee_mmu_check_access_rights(uctx, flags, (uaddr_t)dst,
						  dlen);
		if (res != TEE_SUCCESS)
			return res;
	}

	if (dlen < src_len) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	if (src_len > 0) {
		/* Permit src_len == 0 to finalize the operation */
		res = tee_do_cipher_update(cs->ctx, cs->algo, cs->mode,
					   last_block, src, src_len, dst);
	}

	if (last_block && cs->ctx_finalize != NULL) {
		cs->ctx_finalize(cs->ctx);
		cs->ctx_finalize = NULL;
	}

out:
	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
	    dst_len != NULL) {
		TEE_Result res2;

		res2 = put_user_u64(dst_len, src_len);
		if (res2 != TEE_SUCCESS)
			res = res2;
	}

	return res;
}

TEE_Result syscall_cipher_update(unsigned long state, const void *src,
			size_t src_len, void *dst, uint64_t *dst_len)
{
	return tee_svc_cipher_update_helper(state, false /* last_block */,
					    src, src_len, dst, dst_len);
}

TEE_Result syscall_cipher_final(unsigned long state, const void *src,
			size_t src_len, void *dst, uint64_t *dst_len)
{
	return tee_svc_cipher_update_helper(state, true /* last_block */,
					    src, src_len, dst, dst_len);
}

#if defined(CFG_CRYPTO_HKDF)
static TEE_Result get_hkdf_params(const TEE_Attribute *params,
				  uint32_t param_count,
				  void **salt, size_t *salt_len, void **info,
				  size_t *info_len, size_t *okm_len)
{
	size_t n;
	enum { SALT = 0x1, LENGTH = 0x2, INFO = 0x4 };
	uint8_t found = 0;

	*salt = *info = NULL;
	*salt_len = *info_len = *okm_len = 0;

	for (n = 0; n < param_count; n++) {
		switch (params[n].attributeID) {
		case TEE_ATTR_HKDF_SALT:
			if (!(found & SALT)) {
				*salt = params[n].content.ref.buffer;
				*salt_len = params[n].content.ref.length;
				found |= SALT;
			}
			break;
		case TEE_ATTR_HKDF_OKM_LENGTH:
			if (!(found & LENGTH)) {
				*okm_len = params[n].content.value.a;
				found |= LENGTH;
			}
			break;
		case TEE_ATTR_HKDF_INFO:
			if (!(found & INFO)) {
				*info = params[n].content.ref.buffer;
				*info_len = params[n].content.ref.length;
				found |= INFO;
			}
			break;
		default:
			/* Unexpected attribute */
			return TEE_ERROR_BAD_PARAMETERS;
		}

	}

	if (!(found & LENGTH))
		return TEE_ERROR_BAD_PARAMETERS;

	return TEE_SUCCESS;
}
#endif

#if defined(CFG_CRYPTO_CONCAT_KDF)
static TEE_Result get_concat_kdf_params(const TEE_Attribute *params,
					uint32_t param_count,
					void **other_info,
					size_t *other_info_len,
					size_t *derived_key_len)
{
	size_t n;
	enum { LENGTH = 0x1, INFO = 0x2 };
	uint8_t found = 0;

	*other_info = NULL;
	*other_info_len = *derived_key_len = 0;

	for (n = 0; n < param_count; n++) {
		switch (params[n].attributeID) {
		case TEE_ATTR_CONCAT_KDF_OTHER_INFO:
			if (!(found & INFO)) {
				*other_info = params[n].content.ref.buffer;
				*other_info_len = params[n].content.ref.length;
				found |= INFO;
			}
			break;
		case TEE_ATTR_CONCAT_KDF_DKM_LENGTH:
			if (!(found & LENGTH)) {
				*derived_key_len = params[n].content.value.a;
				found |= LENGTH;
			}
			break;
		default:
			/* Unexpected attribute */
			return TEE_ERROR_BAD_PARAMETERS;
		}
	}

	if (!(found & LENGTH))
		return TEE_ERROR_BAD_PARAMETERS;

	return TEE_SUCCESS;
}
#endif

#if defined(CFG_CRYPTO_PBKDF2)
static TEE_Result get_pbkdf2_params(const TEE_Attribute *params,
				   uint32_t param_count, void **salt,
				   size_t *salt_len, size_t *derived_key_len,
				   size_t *iteration_count)
{
	size_t n;
	enum { SALT = 0x1, LENGTH = 0x2, COUNT = 0x4 };
	uint8_t found = 0;

	*salt = NULL;
	*salt_len = *derived_key_len = *iteration_count = 0;

	for (n = 0; n < param_count; n++) {
		switch (params[n].attributeID) {
		case TEE_ATTR_PBKDF2_SALT:
			if (!(found & SALT)) {
				*salt = params[n].content.ref.buffer;
				*salt_len = params[n].content.ref.length;
				found |= SALT;
			}
			break;
		case TEE_ATTR_PBKDF2_DKM_LENGTH:
			if (!(found & LENGTH)) {
				*derived_key_len = params[n].content.value.a;
				found |= LENGTH;
			}
			break;
		case TEE_ATTR_PBKDF2_ITERATION_COUNT:
			if (!(found & COUNT)) {
				*iteration_count = params[n].content.value.a;
				found |= COUNT;
			}
			break;
		default:
			/* Unexpected attribute */
			return TEE_ERROR_BAD_PARAMETERS;
		}
	}

	if ((found & (LENGTH|COUNT)) != (LENGTH|COUNT))
		return TEE_ERROR_BAD_PARAMETERS;

	return TEE_SUCCESS;
}
#endif

#if defined(CFG_CRYPTO_SM2_KEP)
static TEE_Result get_sm2_kep_params(const TEE_Attribute *params,
				     uint32_t param_count,
				     struct ecc_public_key *peer_key,
				     struct ecc_public_key *peer_eph_key,
				     struct sm2_kep_parms *kep_parms)
{
	TEE_Result res = TEE_ERROR_GENERIC;
	size_t n;
	enum {
		IS_INITIATOR,
		PEER_KEY_X,
		PEER_KEY_Y,
		PEER_EPH_KEY_X,
		PEER_EPH_KEY_Y,
		INITIATOR_ID,
		RESPONDER_ID,
	};
	uint8_t mandatory = BIT(IS_INITIATOR) | BIT(PEER_KEY_X) |
		BIT(PEER_KEY_Y) | BIT(PEER_EPH_KEY_X) | BIT(PEER_EPH_KEY_Y) |
		BIT(INITIATOR_ID) | BIT(RESPONDER_ID);
	uint8_t found = 0;

	res = crypto_acipher_alloc_ecc_public_key(peer_key, 256);
	if (res)
		goto out;

	res = crypto_acipher_alloc_ecc_public_key(peer_eph_key, 256);
	if (res)
		goto out;

	peer_key->curve = TEE_ECC_CURVE_SM2;
	peer_eph_key->curve = TEE_ECC_CURVE_SM2;

	for (n = 0; n < param_count; n++) {
		const TEE_Attribute *p = &params[n];

		switch (p->attributeID) {
		case TEE_ATTR_SM2_KEP_USER:
			kep_parms->is_initiator = !p->content.value.a;
			found |= BIT(IS_INITIATOR);
			break;
		case TEE_ATTR_ECC_PUBLIC_VALUE_X:
			crypto_bignum_bin2bn(p->content.ref.buffer,
					     p->content.ref.length,
					     peer_key->x);
			found |= BIT(PEER_KEY_X);
			break;
		case TEE_ATTR_ECC_PUBLIC_VALUE_Y:
			crypto_bignum_bin2bn(p->content.ref.buffer,
					     p->content.ref.length,
					     peer_key->y);
			found |= BIT(PEER_KEY_Y);
			break;
		case TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_X:
			crypto_bignum_bin2bn(p->content.ref.buffer,
					     p->content.ref.length,
					     peer_eph_key->x);
			found |= BIT(PEER_EPH_KEY_X);
			break;
		case TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_Y:
			crypto_bignum_bin2bn(p->content.ref.buffer,
					     p->content.ref.length,
					     peer_eph_key->y);
			found |= BIT(PEER_EPH_KEY_Y);
			break;
		case TEE_ATTR_SM2_ID_INITIATOR:
			kep_parms->initiator_id = p->content.ref.buffer;
			kep_parms->initiator_id_len = p->content.ref.length;
			found |= BIT(INITIATOR_ID);
			break;
		case TEE_ATTR_SM2_ID_RESPONDER:
			kep_parms->responder_id = p->content.ref.buffer;
			kep_parms->responder_id_len = p->content.ref.length;
			found |= BIT(RESPONDER_ID);
			break;
		case TEE_ATTR_SM2_KEP_CONFIRMATION_IN:
			kep_parms->conf_in = p->content.ref.buffer;
			kep_parms->conf_in_len = p->content.ref.length;
			break;
		case TEE_ATTR_SM2_KEP_CONFIRMATION_OUT:
			kep_parms->conf_out = p->content.ref.buffer;
			kep_parms->conf_out_len = p->content.ref.length;
			break;
		default:
			/* Unexpected attribute */
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}
	}

	if ((found & mandatory) != mandatory) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	return TEE_SUCCESS;
out:
	crypto_acipher_free_ecc_public_key(peer_key);
	crypto_acipher_free_ecc_public_key(peer_eph_key);
	return res;
}
#endif

TEE_Result syscall_cryp_derive_key(unsigned long state,
			const struct utee_attribute *usr_params,
			unsigned long param_count, unsigned long derived_key)
{
	TEE_Result res = TEE_ERROR_NOT_SUPPORTED;
	struct tee_ta_session *sess;
	struct tee_obj *ko;
	struct tee_obj *so;
	struct tee_cryp_state *cs;
	struct tee_cryp_obj_secret *sk;
	const struct tee_cryp_obj_type_props *type_props;
	TEE_Attribute *params = NULL;
	struct user_ta_ctx *utc;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	size_t alloc_size = 0;

	if (MUL_OVERFLOW(sizeof(TEE_Attribute), param_count, &alloc_size))
		return TEE_ERROR_OVERFLOW;

	params = malloc(alloc_size);
	if (!params)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = copy_in_attrs(utc, usr_params, param_count, params);
	if (res != TEE_SUCCESS)
		goto out;

	/* Get key set in operation */
	res = tee_obj_get(utc, cs->key1, &ko);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_obj_get(utc, tee_svc_uref_to_vaddr(derived_key), &so);
	if (res != TEE_SUCCESS)
		goto out;

	/* Find information needed about the object to initialize */
	sk = so->attr;

	/* Find description of object */
	type_props = tee_svc_find_type_props(so->info.objectType);
	if (!type_props) {
		res = TEE_ERROR_NOT_SUPPORTED;
		goto out;
	}

	if (cs->algo == TEE_ALG_DH_DERIVE_SHARED_SECRET) {
		struct bignum *pub;
		struct bignum *ss;

		if (param_count != 1 ||
		    params[0].attributeID != TEE_ATTR_DH_PUBLIC_VALUE) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}

		size_t bin_size = params[0].content.ref.length;

		if (MUL_OVERFLOW(bin_size, 8, &alloc_size)) {
			res = TEE_ERROR_OVERFLOW;
			goto out;
		}

		pub = crypto_bignum_allocate(alloc_size);
		ss = crypto_bignum_allocate(alloc_size);
		if (pub && ss) {
			crypto_bignum_bin2bn(params[0].content.ref.buffer,
					     bin_size, pub);
			res = crypto_acipher_dh_shared_secret(ko->attr,
							      pub, ss);
			if (res == TEE_SUCCESS) {
				sk->key_size = crypto_bignum_num_bytes(ss);
				crypto_bignum_bn2bin(ss, (uint8_t *)(sk + 1));
				so->info.handleFlags |=
						TEE_HANDLE_FLAG_INITIALIZED;
				set_attribute(so, type_props,
					      TEE_ATTR_SECRET_VALUE);
			}
		} else {
			res = TEE_ERROR_OUT_OF_MEMORY;
		}
		crypto_bignum_free(pub);
		crypto_bignum_free(ss);
	} else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_ECDH) {
		struct ecc_public_key key_public;
		uint8_t *pt_secret;
		unsigned long pt_secret_len;

		if (param_count != 2 ||
		    params[0].attributeID != TEE_ATTR_ECC_PUBLIC_VALUE_X ||
		    params[1].attributeID != TEE_ATTR_ECC_PUBLIC_VALUE_Y) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}

		switch (cs->algo) {
		case TEE_ALG_ECDH_P192:
			alloc_size = 192;
			break;
		case TEE_ALG_ECDH_P224:
			alloc_size = 224;
			break;
		case TEE_ALG_ECDH_P256:
			alloc_size = 256;
			break;
		case TEE_ALG_ECDH_P384:
			alloc_size = 384;
			break;
		case TEE_ALG_ECDH_P521:
			alloc_size = 521;
			break;
		default:
			res = TEE_ERROR_NOT_IMPLEMENTED;
			goto out;
		}

		/* Create the public key */
		res = crypto_acipher_alloc_ecc_public_key(&key_public,
							  alloc_size);
		if (res != TEE_SUCCESS)
			goto out;
		key_public.curve = ((struct ecc_keypair *)ko->attr)->curve;
		crypto_bignum_bin2bn(params[0].content.ref.buffer,
				     params[0].content.ref.length,
				     key_public.x);
		crypto_bignum_bin2bn(params[1].content.ref.buffer,
				     params[1].content.ref.length,
				     key_public.y);

		pt_secret = (uint8_t *)(sk + 1);
		pt_secret_len = sk->alloc_size;
		res = crypto_acipher_ecc_shared_secret(ko->attr, &key_public,
						       pt_secret,
						       &pt_secret_len);

		if (res == TEE_SUCCESS) {
			sk->key_size = pt_secret_len;
			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
		}

		/* free the public key */
		crypto_acipher_free_ecc_public_key(&key_public);
	}
#if defined(CFG_CRYPTO_HKDF)
	else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_HKDF) {
		void *salt, *info;
		size_t salt_len, info_len, okm_len;
		uint32_t hash_id = TEE_ALG_GET_DIGEST_HASH(cs->algo);
		struct tee_cryp_obj_secret *ik = ko->attr;
		const uint8_t *ikm = (const uint8_t *)(ik + 1);

		res = get_hkdf_params(params, param_count, &salt, &salt_len,
				      &info, &info_len, &okm_len);
		if (res != TEE_SUCCESS)
			goto out;

		/* Requested size must fit into the output object's buffer */
		if (okm_len > ik->alloc_size) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}

		res = tee_cryp_hkdf(hash_id, ikm, ik->key_size, salt, salt_len,
				    info, info_len, (uint8_t *)(sk + 1),
				    okm_len);
		if (res == TEE_SUCCESS) {
			sk->key_size = okm_len;
			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
		}
	}
#endif
#if defined(CFG_CRYPTO_CONCAT_KDF)
	else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_CONCAT_KDF) {
		void *info;
		size_t info_len, derived_key_len;
		uint32_t hash_id = TEE_ALG_GET_DIGEST_HASH(cs->algo);
		struct tee_cryp_obj_secret *ss = ko->attr;
		const uint8_t *shared_secret = (const uint8_t *)(ss + 1);

		res = get_concat_kdf_params(params, param_count, &info,
					    &info_len, &derived_key_len);
		if (res != TEE_SUCCESS)
			goto out;

		/* Requested size must fit into the output object's buffer */
		if (derived_key_len > ss->alloc_size) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}

		res = tee_cryp_concat_kdf(hash_id, shared_secret, ss->key_size,
					  info, info_len, (uint8_t *)(sk + 1),
					  derived_key_len);
		if (res == TEE_SUCCESS) {
			sk->key_size = derived_key_len;
			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
		}
	}
#endif
#if defined(CFG_CRYPTO_PBKDF2)
	else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_PBKDF2) {
		void *salt;
		size_t salt_len, iteration_count, derived_key_len;
		uint32_t hash_id = TEE_ALG_GET_DIGEST_HASH(cs->algo);
		struct tee_cryp_obj_secret *ss = ko->attr;
		const uint8_t *password = (const uint8_t *)(ss + 1);

		res = get_pbkdf2_params(params, param_count, &salt, &salt_len,
					&derived_key_len, &iteration_count);
		if (res != TEE_SUCCESS)
			goto out;

		/* Requested size must fit into the output object's buffer */
		if (derived_key_len > ss->alloc_size) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto out;
		}

		res = tee_cryp_pbkdf2(hash_id, password, ss->key_size, salt,
				      salt_len, iteration_count,
				      (uint8_t *)(sk + 1), derived_key_len);
		if (res == TEE_SUCCESS) {
			sk->key_size = derived_key_len;
			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
		}
	}
#endif
#if defined(CFG_CRYPTO_SM2_KEP)
	else if (cs->algo == TEE_ALG_SM2_KEP) {
		struct ecc_public_key peer_eph_key = { };
		struct ecc_public_key peer_key = { };
		struct sm2_kep_parms kep_parms = {
			.out = (uint8_t *)(sk + 1),
			.out_len = so->info.maxKeySize,
		};
		struct tee_obj *ko2 = NULL;

		res = tee_obj_get(utc, cs->key2, &ko2);
		if (res != TEE_SUCCESS)
			goto out;

		res = get_sm2_kep_params(params, param_count, &peer_key,
					 &peer_eph_key, &kep_parms);
		if (res != TEE_SUCCESS)
			goto out;

		/*
		 * key1 is our private keypair, key2 is our ephemeral public key
		 */
		res = crypto_acipher_sm2_kep_derive(ko->attr, /* key1 */
						    ko2->attr, /* key2 */
						    &peer_key, &peer_eph_key,
						    &kep_parms);

		if (res == TEE_SUCCESS) {
			sk->key_size = kep_parms.out_len;
			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
		}
		crypto_acipher_free_ecc_public_key(&peer_key);
		crypto_acipher_free_ecc_public_key(&peer_eph_key);
	}
#endif
	else
		res = TEE_ERROR_NOT_SUPPORTED;

out:
	free_wipe(params);
	return res;
}

TEE_Result syscall_cryp_random_number_generate(void *buf, size_t blen)
{
	struct tee_ta_session *sess = NULL;
	TEE_Result res = TEE_SUCCESS;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)buf, blen);
	if (res != TEE_SUCCESS)
		return res;

	res = crypto_rng_read(buf, blen);
	if (res != TEE_SUCCESS)
		return res;

	return res;
}

TEE_Result syscall_authenc_init(unsigned long state, const void *nonce,
				size_t nonce_len, size_t tag_len,
				size_t aad_len, size_t payload_len)
{
	struct tee_cryp_obj_secret *key = NULL;
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res = TEE_SUCCESS;
	struct tee_obj *o = NULL;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)nonce, nonce_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_obj_get(to_user_ta_ctx(sess->ctx), cs->key1, &o);
	if (res != TEE_SUCCESS)
		return res;
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		return TEE_ERROR_BAD_PARAMETERS;

	key = o->attr;
	res = crypto_authenc_init(cs->ctx, cs->mode, (uint8_t *)(key + 1),
				  key->key_size, nonce, nonce_len, tag_len,
				  aad_len, payload_len);
	if (res != TEE_SUCCESS)
		return res;

	cs->ctx_finalize = crypto_authenc_final;
	cs->state = CRYP_STATE_INITIALIZED;

	return TEE_SUCCESS;
}

TEE_Result syscall_authenc_update_aad(unsigned long state,
				      const void *aad_data, size_t aad_data_len)
{
	TEE_Result res = TEE_SUCCESS;
	struct tee_cryp_state *cs;
	struct tee_ta_session *sess;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t) aad_data,
					  aad_data_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	if (TEE_ALG_GET_CLASS(cs->algo) != TEE_OPERATION_AE)
		return TEE_ERROR_BAD_STATE;

	res = crypto_authenc_update_aad(cs->ctx, cs->mode, aad_data,
					aad_data_len);
	if (res != TEE_SUCCESS)
		return res;

	return TEE_SUCCESS;
}

TEE_Result syscall_authenc_update_payload(unsigned long state,
					  const void *src_data,
					  size_t src_len, void *dst_data,
					  uint64_t *dst_len)
{
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res = TEE_SUCCESS;
	size_t dlen = 0;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	if (TEE_ALG_GET_CLASS(cs->algo) != TEE_OPERATION_AE)
		return TEE_ERROR_BAD_STATE;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)src_data, src_len);
	if (res != TEE_SUCCESS)
		return res;

	res = get_user_u64_as_size_t(&dlen, dst_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&to_user_ta_ctx(sess->ctx)->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)dst_data, dlen);
	if (res != TEE_SUCCESS)
		return res;

	if (dlen < src_len) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	res = crypto_authenc_update_payload(cs->ctx, cs->mode, src_data,
					    src_len, dst_data, &dlen);
out:
	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
		TEE_Result res2 = put_user_u64(dst_len, dlen);

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

	return res;
}

TEE_Result syscall_authenc_enc_final(unsigned long state, const void *src_data,
				     size_t src_len, void *dst_data,
				     uint64_t *dst_len, void *tag,
				     uint64_t *tag_len)
{
	struct tee_ta_session *sess = NULL;
	struct user_mode_ctx *uctx = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res = TEE_SUCCESS;
	size_t dlen = 0;
	size_t tlen = 0;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	uctx = &to_user_ta_ctx(sess->ctx)->uctx;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	if (cs->mode != TEE_MODE_ENCRYPT)
		return TEE_ERROR_BAD_PARAMETERS;

	if (TEE_ALG_GET_CLASS(cs->algo) != TEE_OPERATION_AE)
		return TEE_ERROR_BAD_STATE;

	res = tee_mmu_check_access_rights(uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)src_data, src_len);
	if (res != TEE_SUCCESS)
		return res;

	if (!dst_len) {
		dlen = 0;
	} else {
		res = get_user_u64_as_size_t(&dlen, dst_len);
		if (res != TEE_SUCCESS)
			return res;

		res = tee_mmu_check_access_rights(uctx,
						  TEE_MEMORY_ACCESS_READ |
						  TEE_MEMORY_ACCESS_WRITE |
						  TEE_MEMORY_ACCESS_ANY_OWNER,
						  (uaddr_t)dst_data, dlen);
		if (res != TEE_SUCCESS)
			return res;
	}

	if (dlen < src_len) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	res = get_user_u64_as_size_t(&tlen, tag_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)tag, tlen);
	if (res != TEE_SUCCESS)
		return res;

	res = crypto_authenc_enc_final(cs->ctx, src_data, src_len, dst_data,
				       &dlen, tag, &tlen);

out:
	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
		TEE_Result res2 = TEE_SUCCESS;

		if (dst_len != NULL) {
			res2 = put_user_u64(dst_len, dlen);
			if (res2 != TEE_SUCCESS)
				return res2;
		}

		res2 = put_user_u64(tag_len, tlen);
		if (res2 != TEE_SUCCESS)
			return res2;
	}

	return res;
}

TEE_Result syscall_authenc_dec_final(unsigned long state,
			const void *src_data, size_t src_len, void *dst_data,
			uint64_t *dst_len, const void *tag, size_t tag_len)
{
	struct tee_ta_session *sess = NULL;
	struct user_mode_ctx *uctx = NULL;
	struct tee_cryp_state *cs = NULL;
	TEE_Result res = TEE_SUCCESS;
	size_t dlen = 0;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;

	uctx = &to_user_ta_ctx(sess->ctx)->uctx;

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->state != CRYP_STATE_INITIALIZED)
		return TEE_ERROR_BAD_STATE;

	if (cs->mode != TEE_MODE_DECRYPT)
		return TEE_ERROR_BAD_PARAMETERS;

	if (TEE_ALG_GET_CLASS(cs->algo) != TEE_OPERATION_AE)
		return TEE_ERROR_BAD_STATE;

	res = tee_mmu_check_access_rights(uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)src_data, src_len);
	if (res != TEE_SUCCESS)
		return res;

	if (!dst_len) {
		dlen = 0;
	} else {
		res = get_user_u64_as_size_t(&dlen, dst_len);
		if (res != TEE_SUCCESS)
			return res;

		res = tee_mmu_check_access_rights(uctx,
						  TEE_MEMORY_ACCESS_READ |
						  TEE_MEMORY_ACCESS_WRITE |
						  TEE_MEMORY_ACCESS_ANY_OWNER,
						  (uaddr_t)dst_data, dlen);
		if (res != TEE_SUCCESS)
			return res;
	}

	if (dlen < src_len) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	res = tee_mmu_check_access_rights(uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)tag, tag_len);
	if (res != TEE_SUCCESS)
		return res;

	res = crypto_authenc_dec_final(cs->ctx, src_data, src_len, dst_data,
				       &dlen, tag, tag_len);

out:
	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
	    dst_len != NULL) {
		TEE_Result res2 = put_user_u64(dst_len, dlen);

		if (res2 != TEE_SUCCESS)
			return res2;
	}

	return res;
}

static int pkcs1_get_salt_len(const TEE_Attribute *params, uint32_t num_params,
			      size_t default_len)
{
	size_t n;

	assert(default_len < INT_MAX);

	for (n = 0; n < num_params; n++) {
		if (params[n].attributeID == TEE_ATTR_RSA_PSS_SALT_LENGTH) {
			if (params[n].content.value.a < INT_MAX)
				return params[n].content.value.a;
			break;
		}
	}
	/*
	 * If salt length isn't provided use the default value which is
	 * the length of the digest.
	 */
	return default_len;
}

TEE_Result syscall_asymm_operate(unsigned long state,
			const struct utee_attribute *usr_params,
			size_t num_params, const void *src_data, size_t src_len,
			void *dst_data, uint64_t *dst_len)
{
	TEE_Result res;
	struct tee_cryp_state *cs;
	struct tee_ta_session *sess;
	size_t dlen;
	struct tee_obj *o;
	void *label = NULL;
	size_t label_len = 0;
	size_t n;
	int salt_len;
	TEE_Attribute *params = NULL;
	struct user_ta_ctx *utc;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&utc->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)src_data, src_len);
	if (res != TEE_SUCCESS)
		return res;

	res = get_user_u64_as_size_t(&dlen, dst_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&utc->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)dst_data, dlen);
	if (res != TEE_SUCCESS)
		return res;

	size_t alloc_size = 0;

	if (MUL_OVERFLOW(sizeof(TEE_Attribute), num_params, &alloc_size))
		return TEE_ERROR_OVERFLOW;

	params = malloc(alloc_size);
	if (!params)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = copy_in_attrs(utc, usr_params, num_params, params);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_obj_get(utc, cs->key1, &o);
	if (res != TEE_SUCCESS)
		goto out;
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_GENERIC;
		goto out;
	}

	switch (cs->algo) {
	case TEE_ALG_RSA_NOPAD:
		if (cs->mode == TEE_MODE_ENCRYPT) {
			res = crypto_acipher_rsanopad_encrypt(o->attr, src_data,
							      src_len, dst_data,
							      &dlen);
		} else if (cs->mode == TEE_MODE_DECRYPT) {
			res = crypto_acipher_rsanopad_decrypt(o->attr, src_data,
							      src_len, dst_data,
							      &dlen);
		} else {
			/*
			 * We will panic because "the mode is not compatible
			 * with the function"
			 */
			res = TEE_ERROR_GENERIC;
		}
		break;

	case TEE_ALG_SM2_PKE:
		if (cs->mode == TEE_MODE_ENCRYPT) {
			res = crypto_acipher_sm2_pke_encrypt(o->attr, src_data,
							     src_len, dst_data,
							     &dlen);
		} else if (cs->mode == TEE_MODE_DECRYPT) {
			res = crypto_acipher_sm2_pke_decrypt(o->attr, src_data,
							     src_len, dst_data,
							     &dlen);
		} else {
			res = TEE_ERROR_GENERIC;
		}
		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:
		for (n = 0; n < num_params; n++) {
			if (params[n].attributeID == TEE_ATTR_RSA_OAEP_LABEL) {
				label = params[n].content.ref.buffer;
				label_len = params[n].content.ref.length;
				break;
			}
		}

		if (cs->mode == TEE_MODE_ENCRYPT) {
			res = crypto_acipher_rsaes_encrypt(cs->algo, o->attr,
							   label, label_len,
							   src_data, src_len,
							   dst_data, &dlen);
		} else if (cs->mode == TEE_MODE_DECRYPT) {
			res = crypto_acipher_rsaes_decrypt(
					cs->algo, o->attr, label, label_len,
					src_data, src_len, dst_data, &dlen);
		} else {
			res = TEE_ERROR_BAD_PARAMETERS;
		}
		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:
		if (cs->mode != TEE_MODE_SIGN) {
			res = TEE_ERROR_BAD_PARAMETERS;
			break;
		}
		salt_len = pkcs1_get_salt_len(params, num_params, src_len);
		res = crypto_acipher_rsassa_sign(cs->algo, o->attr, salt_len,
						 src_data, src_len, dst_data,
						 &dlen);
		break;

	case TEE_ALG_DSA_SHA1:
	case TEE_ALG_DSA_SHA224:
	case TEE_ALG_DSA_SHA256:
		res = crypto_acipher_dsa_sign(cs->algo, o->attr, src_data,
					      src_len, dst_data, &dlen);
		break;
	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:
		res = crypto_acipher_ecc_sign(cs->algo, o->attr, src_data,
					      src_len, dst_data, &dlen);
		break;
	case TEE_ALG_SM2_DSA_SM3:
		res = crypto_acipher_sm2_dsa_sign(cs->algo, o->attr, src_data,
						  src_len, dst_data, &dlen);
		break;

	default:
		res = TEE_ERROR_BAD_PARAMETERS;
		break;
	}

out:
	free_wipe(params);

	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
		TEE_Result res2 = put_user_u64(dst_len, dlen);

		if (res2 != TEE_SUCCESS)
			return res2;
	}

	return res;
}

TEE_Result syscall_asymm_verify(unsigned long state,
			const struct utee_attribute *usr_params,
			size_t num_params, const void *data, size_t data_len,
			const void *sig, size_t sig_len)
{
	struct tee_ta_session *sess = NULL;
	struct tee_cryp_state *cs = NULL;
	struct user_ta_ctx *utc = NULL;
	TEE_Result res = TEE_SUCCESS;
	TEE_Attribute *params = NULL;
	struct tee_obj *o = NULL;
	size_t hash_size = 0;
	uint32_t hash_algo = 0;
	int salt_len = 0;

	res = tee_ta_get_current_session(&sess);
	if (res != TEE_SUCCESS)
		return res;
	utc = to_user_ta_ctx(sess->ctx);

	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
	if (res != TEE_SUCCESS)
		return res;

	if (cs->mode != TEE_MODE_VERIFY)
		return TEE_ERROR_BAD_PARAMETERS;

	res = tee_mmu_check_access_rights(&utc->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)data, data_len);
	if (res != TEE_SUCCESS)
		return res;

	res = tee_mmu_check_access_rights(&utc->uctx,
					  TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)sig, sig_len);
	if (res != TEE_SUCCESS)
		return res;

	size_t alloc_size = 0;

	if (MUL_OVERFLOW(sizeof(TEE_Attribute), num_params, &alloc_size))
		return TEE_ERROR_OVERFLOW;

	params = malloc(alloc_size);
	if (!params)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = copy_in_attrs(utc, usr_params, num_params, params);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_obj_get(utc, cs->key1, &o);
	if (res != TEE_SUCCESS)
		goto out;
	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	switch (TEE_ALG_GET_MAIN_ALG(cs->algo)) {
	case TEE_MAIN_ALGO_RSA:
		if (cs->algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
			hash_algo = TEE_DIGEST_HASH_TO_ALGO(cs->algo);
			res = tee_hash_get_digest_size(hash_algo, &hash_size);
			if (res != TEE_SUCCESS)
				break;
			if (data_len != hash_size) {
				res = TEE_ERROR_BAD_PARAMETERS;
				break;
			}
			salt_len = pkcs1_get_salt_len(params, num_params,
						      hash_size);
		}
		res = crypto_acipher_rsassa_verify(cs->algo, o->attr, salt_len,
						   data, data_len, sig,
						   sig_len);
		break;

	case TEE_MAIN_ALGO_DSA:
		hash_algo = TEE_DIGEST_HASH_TO_ALGO(cs->algo);
		res = tee_hash_get_digest_size(hash_algo, &hash_size);
		if (res != TEE_SUCCESS)
			break;
		/*
		 * Depending on the DSA algorithm (NIST), the digital signature
		 * output size may be truncated to the size of a key pair
		 * (Q prime size). Q prime size must be less or equal than the
		 * hash output length of the hash algorithm involved.
		 */
		if (data_len > hash_size) {
			res = TEE_ERROR_BAD_PARAMETERS;
			break;
		}
		res = crypto_acipher_dsa_verify(cs->algo, o->attr, data,
						data_len, sig, sig_len);
		break;

	case TEE_MAIN_ALGO_ECDSA:
		res = crypto_acipher_ecc_verify(cs->algo, o->attr, data,
						data_len, sig, sig_len);
		break;

	case TEE_MAIN_ALGO_SM2_DSA_SM3:
		res = crypto_acipher_sm2_dsa_verify(cs->algo, o->attr, data,
						    data_len, sig, sig_len);
		break;

	default:
		res = TEE_ERROR_NOT_SUPPORTED;
	}

out:
	free_wipe(params);
	return res;
}
