xref: /optee_os/core/lib/libtomcrypt/ecc.c (revision 5b385b3f835df16fad1922cfbe6dbe112d2047b5)
16644e2f0SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
26644e2f0SJens Wiklander /*
36644e2f0SJens Wiklander  * Copyright (c) 2014-2019, Linaro Limited
46644e2f0SJens Wiklander  */
56644e2f0SJens Wiklander 
66644e2f0SJens Wiklander #include <crypto/crypto.h>
76644e2f0SJens Wiklander #include <stdlib.h>
86644e2f0SJens Wiklander #include <string.h>
96644e2f0SJens Wiklander #include <tee_api_types.h>
106644e2f0SJens Wiklander #include <trace.h>
116644e2f0SJens Wiklander #include <utee_defines.h>
126644e2f0SJens Wiklander 
136644e2f0SJens Wiklander #include "acipher_helpers.h"
146644e2f0SJens Wiklander 
156644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s,
166644e2f0SJens Wiklander 					    size_t key_size_bits __unused)
176644e2f0SJens Wiklander {
186644e2f0SJens Wiklander 	memset(s, 0, sizeof(*s));
196644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->d))
206644e2f0SJens Wiklander 		goto err;
216644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->x))
226644e2f0SJens Wiklander 		goto err;
236644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->y))
246644e2f0SJens Wiklander 		goto err;
256644e2f0SJens Wiklander 	return TEE_SUCCESS;
266644e2f0SJens Wiklander err:
276644e2f0SJens Wiklander 	crypto_bignum_free(s->d);
286644e2f0SJens Wiklander 	crypto_bignum_free(s->x);
296644e2f0SJens Wiklander 	crypto_bignum_free(s->y);
306644e2f0SJens Wiklander 	return TEE_ERROR_OUT_OF_MEMORY;
316644e2f0SJens Wiklander }
326644e2f0SJens Wiklander 
336644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s,
346644e2f0SJens Wiklander 					       size_t key_size_bits __unused)
356644e2f0SJens Wiklander {
366644e2f0SJens Wiklander 	memset(s, 0, sizeof(*s));
376644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->x))
386644e2f0SJens Wiklander 		goto err;
396644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->y))
406644e2f0SJens Wiklander 		goto err;
416644e2f0SJens Wiklander 	return TEE_SUCCESS;
426644e2f0SJens Wiklander err:
436644e2f0SJens Wiklander 	crypto_bignum_free(s->x);
446644e2f0SJens Wiklander 	crypto_bignum_free(s->y);
456644e2f0SJens Wiklander 	return TEE_ERROR_OUT_OF_MEMORY;
466644e2f0SJens Wiklander }
476644e2f0SJens Wiklander 
486644e2f0SJens Wiklander void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s)
496644e2f0SJens Wiklander {
506644e2f0SJens Wiklander 	if (!s)
516644e2f0SJens Wiklander 		return;
526644e2f0SJens Wiklander 
536644e2f0SJens Wiklander 	crypto_bignum_free(s->x);
546644e2f0SJens Wiklander 	crypto_bignum_free(s->y);
556644e2f0SJens Wiklander }
566644e2f0SJens Wiklander 
576644e2f0SJens Wiklander /*
585a913ee7SJerome Forissier  * For a given TEE @curve, return key size and LTC curve name. Also check that
595a913ee7SJerome Forissier  * @algo is compatible with this curve.
605a913ee7SJerome Forissier  * @curve: TEE_ECC_CURVE_NIST_P192, ...
615a913ee7SJerome Forissier  * @algo: TEE_ALG_ECDSA_P192, ...
626644e2f0SJens Wiklander  */
635a913ee7SJerome Forissier static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo,
645a913ee7SJerome Forissier 				     size_t *key_size_bytes,
655a913ee7SJerome Forissier 				     size_t *key_size_bits,
665a913ee7SJerome Forissier 				     const char **curve_name)
676644e2f0SJens Wiklander {
685a913ee7SJerome Forissier 	size_t size_bytes = 0;
695a913ee7SJerome Forissier 	size_t size_bits = 0;
705a913ee7SJerome Forissier 	const char *name = NULL;
715a913ee7SJerome Forissier 
726644e2f0SJens Wiklander 	/*
736644e2f0SJens Wiklander 	 * Excerpt of libtomcrypt documentation:
746644e2f0SJens Wiklander 	 * ecc_make_key(... key_size ...): The keysize is the size of the
756644e2f0SJens Wiklander 	 * modulus in bytes desired. Currently directly supported values
766644e2f0SJens Wiklander 	 * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond
776644e2f0SJens Wiklander 	 * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits
786644e2f0SJens Wiklander 	 * respectively.
796644e2f0SJens Wiklander 	 */
806644e2f0SJens Wiklander 
816644e2f0SJens Wiklander 	/*
826644e2f0SJens Wiklander 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
836644e2f0SJens Wiklander 	 * but defines TEE_ALG_ECDH_P192
846644e2f0SJens Wiklander 	 */
856644e2f0SJens Wiklander 
866644e2f0SJens Wiklander 	switch (curve) {
876644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P192:
885a913ee7SJerome Forissier 		size_bits = 192;
895a913ee7SJerome Forissier 		size_bytes = 24;
905a913ee7SJerome Forissier 		name = "NISTP192";
916644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
926644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P192))
936644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
946644e2f0SJens Wiklander 		break;
956644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P224:
965a913ee7SJerome Forissier 		size_bits = 224;
975a913ee7SJerome Forissier 		size_bytes = 28;
985a913ee7SJerome Forissier 		name = "NISTP224";
996644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
1006644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P224))
1016644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
1026644e2f0SJens Wiklander 		break;
1036644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P256:
1045a913ee7SJerome Forissier 		size_bits = 256;
1055a913ee7SJerome Forissier 		size_bytes = 32;
1065a913ee7SJerome Forissier 		name = "NISTP256";
1076644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
1086644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P256))
1096644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
1106644e2f0SJens Wiklander 		break;
1116644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P384:
1125a913ee7SJerome Forissier 		size_bits = 384;
1135a913ee7SJerome Forissier 		size_bytes = 48;
1145a913ee7SJerome Forissier 		name = "NISTP384";
1156644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
1166644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P384))
1176644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
1186644e2f0SJens Wiklander 		break;
1196644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P521:
1205a913ee7SJerome Forissier 		size_bits = 521;
1215a913ee7SJerome Forissier 		size_bytes = 66;
1225a913ee7SJerome Forissier 		name = "NISTP521";
1236644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
1246644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P521))
1256644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
1266644e2f0SJens Wiklander 		break;
12791fc6bd8SJerome Forissier 	case TEE_ECC_CURVE_SM2:
12891fc6bd8SJerome Forissier 		size_bits = 256;
12991fc6bd8SJerome Forissier 		size_bytes = 32;
13091fc6bd8SJerome Forissier 		name = "SM2";
1310f151943SJerome Forissier 		if ((algo != 0) && (algo != TEE_ALG_SM2_PKE) &&
132*5b385b3fSJerome Forissier 		    (algo != TEE_ALG_SM2_DSA_SM3) &&
133*5b385b3fSJerome Forissier 		    (algo != TEE_ALG_SM2_KEP))
13491fc6bd8SJerome Forissier 			return TEE_ERROR_BAD_PARAMETERS;
13591fc6bd8SJerome Forissier 		break;
1366644e2f0SJens Wiklander 	default:
1376644e2f0SJens Wiklander 		return TEE_ERROR_NOT_SUPPORTED;
1386644e2f0SJens Wiklander 	}
1396644e2f0SJens Wiklander 
1405a913ee7SJerome Forissier 	if (key_size_bytes)
1415a913ee7SJerome Forissier 		*key_size_bytes = size_bytes;
1425a913ee7SJerome Forissier 	if (key_size_bits)
1435a913ee7SJerome Forissier 		*key_size_bits = size_bits;
1445a913ee7SJerome Forissier 	if (curve_name)
1455a913ee7SJerome Forissier 		*curve_name = name;
1466644e2f0SJens Wiklander 	return TEE_SUCCESS;
1476644e2f0SJens Wiklander }
1486644e2f0SJens Wiklander 
1496644e2f0SJens Wiklander TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key)
1506644e2f0SJens Wiklander {
1516644e2f0SJens Wiklander 	TEE_Result res;
1526644e2f0SJens Wiklander 	ecc_key ltc_tmp_key;
1536644e2f0SJens Wiklander 	int ltc_res;
1546644e2f0SJens Wiklander 	size_t key_size_bytes = 0;
1556644e2f0SJens Wiklander 	size_t key_size_bits = 0;
1566644e2f0SJens Wiklander 
1575a913ee7SJerome Forissier 	res = ecc_get_curve_info(key->curve, 0, &key_size_bytes, &key_size_bits,
1585a913ee7SJerome Forissier 				 NULL);
1596644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
1606644e2f0SJens Wiklander 		return res;
1616644e2f0SJens Wiklander 
1626644e2f0SJens Wiklander 	/* Generate the ECC key */
1631f3b1115SJens Wiklander 	ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"),
1646644e2f0SJens Wiklander 			       key_size_bytes, &ltc_tmp_key);
1656644e2f0SJens Wiklander 	if (ltc_res != CRYPT_OK)
1666644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
1676644e2f0SJens Wiklander 
1686644e2f0SJens Wiklander 	/* check the size of the keys */
1696644e2f0SJens Wiklander 	if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) ||
1706644e2f0SJens Wiklander 	    ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) ||
1716644e2f0SJens Wiklander 	    ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) {
1726644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
1736644e2f0SJens Wiklander 		goto exit;
1746644e2f0SJens Wiklander 	}
1756644e2f0SJens Wiklander 
1766644e2f0SJens Wiklander 	/* check LTC is returning z==1 */
1776644e2f0SJens Wiklander 	if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) {
1786644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
1796644e2f0SJens Wiklander 		goto exit;
1806644e2f0SJens Wiklander 	}
1816644e2f0SJens Wiklander 
1826644e2f0SJens Wiklander 	/* Copy the key */
1836644e2f0SJens Wiklander 	ltc_mp.copy(ltc_tmp_key.k, key->d);
1846644e2f0SJens Wiklander 	ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x);
1856644e2f0SJens Wiklander 	ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y);
1866644e2f0SJens Wiklander 
1876644e2f0SJens Wiklander 	res = TEE_SUCCESS;
1886644e2f0SJens Wiklander 
1896644e2f0SJens Wiklander exit:
1906644e2f0SJens Wiklander 	ecc_free(&ltc_tmp_key);		/* Free the temporary key */
1916644e2f0SJens Wiklander 	return res;
1926644e2f0SJens Wiklander }
1936644e2f0SJens Wiklander 
1945a913ee7SJerome Forissier /* Note: this function clears the key before setting the curve */
1955a913ee7SJerome Forissier static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key,
1965a913ee7SJerome Forissier 					  const char *curve_name)
1976644e2f0SJens Wiklander {
1985a913ee7SJerome Forissier 	const ltc_ecc_curve *curve = NULL;
1995a913ee7SJerome Forissier 	int ltc_res = 0;
2006644e2f0SJens Wiklander 
2015a913ee7SJerome Forissier 	ltc_res = ecc_find_curve(curve_name, &curve);
2025a913ee7SJerome Forissier 	if (ltc_res != CRYPT_OK)
2035a913ee7SJerome Forissier 		return TEE_ERROR_NOT_SUPPORTED;
2046644e2f0SJens Wiklander 
2055a913ee7SJerome Forissier 	ltc_res = ecc_set_curve(curve, ltc_key);
2065a913ee7SJerome Forissier 	if (ltc_res != CRYPT_OK)
2075a913ee7SJerome Forissier 		return TEE_ERROR_GENERIC;
2086644e2f0SJens Wiklander 
2096644e2f0SJens Wiklander 	return TEE_SUCCESS;
2106644e2f0SJens Wiklander }
2116644e2f0SJens Wiklander 
2126644e2f0SJens Wiklander /*
2136644e2f0SJens Wiklander  * Given a keypair "key", populate the Libtomcrypt private key "ltc_key"
2146644e2f0SJens Wiklander  * It also returns the key size, in bytes
2156644e2f0SJens Wiklander  */
216c0691130SJerome Forissier TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key,
2176644e2f0SJens Wiklander 					struct ecc_keypair *key,
218c0691130SJerome Forissier 					uint32_t algo, size_t *key_size_bytes)
2196644e2f0SJens Wiklander {
2205a913ee7SJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
2215a913ee7SJerome Forissier 	const char *name = NULL;
2226644e2f0SJens Wiklander 
2235a913ee7SJerome Forissier 	res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name);
2245a913ee7SJerome Forissier 	if (res)
2256644e2f0SJens Wiklander 		return res;
2266644e2f0SJens Wiklander 
2275a913ee7SJerome Forissier 	memset(ltc_key, 0, sizeof(*ltc_key));
2285a913ee7SJerome Forissier 
2295a913ee7SJerome Forissier 	res = ecc_set_curve_from_name(ltc_key, name);
2305a913ee7SJerome Forissier 	if (res)
2315a913ee7SJerome Forissier 		return res;
2325a913ee7SJerome Forissier 
2335a913ee7SJerome Forissier 	ltc_key->type = PK_PRIVATE;
2345a913ee7SJerome Forissier 	mp_copy(key->d, ltc_key->k);
2357ecec894SJerome Forissier 	mp_copy(key->x, ltc_key->pubkey.x);
2367ecec894SJerome Forissier 	mp_copy(key->y, ltc_key->pubkey.y);
2377ecec894SJerome Forissier 	mp_set_int(ltc_key->pubkey.z, 1);
2385a913ee7SJerome Forissier 
2395a913ee7SJerome Forissier 	return TEE_SUCCESS;
2406644e2f0SJens Wiklander }
2416644e2f0SJens Wiklander 
2426644e2f0SJens Wiklander /*
2436644e2f0SJens Wiklander  * Given a public "key", populate the Libtomcrypt public key "ltc_key"
2446644e2f0SJens Wiklander  * It also returns the key size, in bytes
2456644e2f0SJens Wiklander  */
246c0691130SJerome Forissier TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key,
2476644e2f0SJens Wiklander 				       struct ecc_public_key *key,
248c0691130SJerome Forissier 				       uint32_t algo, size_t *key_size_bytes)
2496644e2f0SJens Wiklander {
2505a913ee7SJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
2515a913ee7SJerome Forissier 	const char *name = NULL;
2526644e2f0SJens Wiklander 	uint8_t one[1] = { 1 };
2536644e2f0SJens Wiklander 
2545a913ee7SJerome Forissier 	res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name);
2555a913ee7SJerome Forissier 	if (res)
2566644e2f0SJens Wiklander 		return res;
2576644e2f0SJens Wiklander 
2585a913ee7SJerome Forissier 	memset(ltc_key, 0, sizeof(*ltc_key));
2595a913ee7SJerome Forissier 
2605a913ee7SJerome Forissier 	res = ecc_set_curve_from_name(ltc_key, name);
2615a913ee7SJerome Forissier 	if (res)
2625a913ee7SJerome Forissier 		return res;
2635a913ee7SJerome Forissier 
2645a913ee7SJerome Forissier 	ltc_key->type = PK_PUBLIC;
2655a913ee7SJerome Forissier 
2665a913ee7SJerome Forissier 	mp_copy(key->x, ltc_key->pubkey.x);
2675a913ee7SJerome Forissier 	mp_copy(key->y, ltc_key->pubkey.y);
2685a913ee7SJerome Forissier 	mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one));
2695a913ee7SJerome Forissier 
2705a913ee7SJerome Forissier 	return TEE_SUCCESS;
2716644e2f0SJens Wiklander }
2726644e2f0SJens Wiklander 
2736644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key,
2746644e2f0SJens Wiklander 				   const uint8_t *msg, size_t msg_len,
2756644e2f0SJens Wiklander 				   uint8_t *sig, size_t *sig_len)
2766644e2f0SJens Wiklander {
2775a913ee7SJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
2785a913ee7SJerome Forissier 	int ltc_res = 0;
2795a913ee7SJerome Forissier 	size_t key_size_bytes = 0;
2805a913ee7SJerome Forissier 	ecc_key ltc_key = { };
2815a913ee7SJerome Forissier 	unsigned long ltc_sig_len = 0;
2826644e2f0SJens Wiklander 
2835a913ee7SJerome Forissier 	if (algo == 0)
2845a913ee7SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
2856644e2f0SJens Wiklander 
2866644e2f0SJens Wiklander 	res = ecc_populate_ltc_private_key(&ltc_key, key, algo,
2876644e2f0SJens Wiklander 					   &key_size_bytes);
2886644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
2895a913ee7SJerome Forissier 		return res;
2906644e2f0SJens Wiklander 
2916644e2f0SJens Wiklander 	if (*sig_len < 2 * key_size_bytes) {
2926644e2f0SJens Wiklander 		*sig_len = 2 * key_size_bytes;
2936644e2f0SJens Wiklander 		res = TEE_ERROR_SHORT_BUFFER;
2945a913ee7SJerome Forissier 		goto out;
2956644e2f0SJens Wiklander 	}
2966644e2f0SJens Wiklander 
2975a913ee7SJerome Forissier 	ltc_sig_len = *sig_len;
2985a913ee7SJerome Forissier 	ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, &ltc_sig_len,
2991f3b1115SJens Wiklander 				    NULL, find_prng("prng_crypto"), &ltc_key);
3006644e2f0SJens Wiklander 	if (ltc_res == CRYPT_OK) {
3016644e2f0SJens Wiklander 		res = TEE_SUCCESS;
3026644e2f0SJens Wiklander 	} else {
3036644e2f0SJens Wiklander 		res = TEE_ERROR_GENERIC;
3046644e2f0SJens Wiklander 	}
3055a913ee7SJerome Forissier 	*sig_len = ltc_sig_len;
3066644e2f0SJens Wiklander 
3075a913ee7SJerome Forissier out:
3085a913ee7SJerome Forissier 	ecc_free(&ltc_key);
3096644e2f0SJens Wiklander 	return res;
3106644e2f0SJens Wiklander }
3116644e2f0SJens Wiklander 
3126644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
3136644e2f0SJens Wiklander 				     const uint8_t *msg, size_t msg_len,
3146644e2f0SJens Wiklander 				     const uint8_t *sig, size_t sig_len)
3156644e2f0SJens Wiklander {
3165a913ee7SJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
3175a913ee7SJerome Forissier 	int ltc_stat = 0;
3185a913ee7SJerome Forissier 	int ltc_res = 0;
3195a913ee7SJerome Forissier 	size_t key_size_bytes = 0;
3205a913ee7SJerome Forissier 	ecc_key ltc_key = { };
3216644e2f0SJens Wiklander 
3226644e2f0SJens Wiklander 	if (algo == 0)
3236644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
3246644e2f0SJens Wiklander 
3255a913ee7SJerome Forissier 	res = ecc_populate_ltc_public_key(&ltc_key, key, algo, &key_size_bytes);
3266644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
3276644e2f0SJens Wiklander 		goto out;
3286644e2f0SJens Wiklander 
3296644e2f0SJens Wiklander 	/* check keysize vs sig_len */
3306644e2f0SJens Wiklander 	if ((key_size_bytes * 2) != sig_len) {
3316644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
3326644e2f0SJens Wiklander 		goto out;
3336644e2f0SJens Wiklander 	}
3346644e2f0SJens Wiklander 
3355a913ee7SJerome Forissier 	ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, &ltc_stat,
3365a913ee7SJerome Forissier 					  &ltc_key);
3376644e2f0SJens Wiklander 	res = convert_ltc_verify_status(ltc_res, ltc_stat);
3386644e2f0SJens Wiklander out:
3395a913ee7SJerome Forissier 	ecc_free(&ltc_key);
3406644e2f0SJens Wiklander 	return res;
3416644e2f0SJens Wiklander }
3426644e2f0SJens Wiklander 
3436644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
3446644e2f0SJens Wiklander 					    struct ecc_public_key *public_key,
3456644e2f0SJens Wiklander 					    void *secret,
3466644e2f0SJens Wiklander 					    unsigned long *secret_len)
3476644e2f0SJens Wiklander {
3485a913ee7SJerome Forissier 	TEE_Result res = TEE_ERROR_GENERIC;
3495a913ee7SJerome Forissier 	int ltc_res = 0;
3505a913ee7SJerome Forissier 	ecc_key ltc_private_key = { };
3515a913ee7SJerome Forissier 	ecc_key ltc_public_key = { };
3525a913ee7SJerome Forissier 	size_t key_size_bytes = 0;
3536644e2f0SJens Wiklander 
3546644e2f0SJens Wiklander 	/* Check the curves are the same */
3556644e2f0SJens Wiklander 	if (private_key->curve != public_key->curve)
3566644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
3576644e2f0SJens Wiklander 
3586644e2f0SJens Wiklander 	res = ecc_populate_ltc_private_key(&ltc_private_key, private_key,
3596644e2f0SJens Wiklander 					   0, &key_size_bytes);
3606644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
3616644e2f0SJens Wiklander 		goto out;
3625a913ee7SJerome Forissier 	res = ecc_populate_ltc_public_key(&ltc_public_key, public_key,
3636644e2f0SJens Wiklander 					  0, &key_size_bytes);
3646644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
3656644e2f0SJens Wiklander 		goto out;
3666644e2f0SJens Wiklander 
3676644e2f0SJens Wiklander 	ltc_res = ecc_shared_secret(&ltc_private_key, &ltc_public_key,
3686644e2f0SJens Wiklander 				    secret, secret_len);
3696644e2f0SJens Wiklander 	if (ltc_res == CRYPT_OK)
3706644e2f0SJens Wiklander 		res = TEE_SUCCESS;
3716644e2f0SJens Wiklander 	else
3726644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
3736644e2f0SJens Wiklander 
3746644e2f0SJens Wiklander out:
3755a913ee7SJerome Forissier 	ecc_free(&ltc_private_key);
3765a913ee7SJerome Forissier 	ecc_free(&ltc_public_key);
3776644e2f0SJens Wiklander 	return res;
3786644e2f0SJens Wiklander }
379