xref: /optee_os/core/lib/libtomcrypt/ecc.c (revision 6644e2f01fac173544c60c7b67ec0b185fa1ae78)
1*6644e2f0SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2*6644e2f0SJens Wiklander /*
3*6644e2f0SJens Wiklander  * Copyright (c) 2014-2019, Linaro Limited
4*6644e2f0SJens Wiklander  */
5*6644e2f0SJens Wiklander 
6*6644e2f0SJens Wiklander #include <crypto/crypto.h>
7*6644e2f0SJens Wiklander #include <stdlib.h>
8*6644e2f0SJens Wiklander #include <string.h>
9*6644e2f0SJens Wiklander #include <tee_api_types.h>
10*6644e2f0SJens Wiklander #include <tomcrypt.h>
11*6644e2f0SJens Wiklander #include <trace.h>
12*6644e2f0SJens Wiklander #include <utee_defines.h>
13*6644e2f0SJens Wiklander 
14*6644e2f0SJens Wiklander #include "acipher_helpers.h"
15*6644e2f0SJens Wiklander 
16*6644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s,
17*6644e2f0SJens Wiklander 					    size_t key_size_bits __unused)
18*6644e2f0SJens Wiklander {
19*6644e2f0SJens Wiklander 	memset(s, 0, sizeof(*s));
20*6644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->d))
21*6644e2f0SJens Wiklander 		goto err;
22*6644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->x))
23*6644e2f0SJens Wiklander 		goto err;
24*6644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->y))
25*6644e2f0SJens Wiklander 		goto err;
26*6644e2f0SJens Wiklander 	return TEE_SUCCESS;
27*6644e2f0SJens Wiklander err:
28*6644e2f0SJens Wiklander 	crypto_bignum_free(s->d);
29*6644e2f0SJens Wiklander 	crypto_bignum_free(s->x);
30*6644e2f0SJens Wiklander 	crypto_bignum_free(s->y);
31*6644e2f0SJens Wiklander 	return TEE_ERROR_OUT_OF_MEMORY;
32*6644e2f0SJens Wiklander }
33*6644e2f0SJens Wiklander 
34*6644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s,
35*6644e2f0SJens Wiklander 					       size_t key_size_bits __unused)
36*6644e2f0SJens Wiklander {
37*6644e2f0SJens Wiklander 	memset(s, 0, sizeof(*s));
38*6644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->x))
39*6644e2f0SJens Wiklander 		goto err;
40*6644e2f0SJens Wiklander 	if (!bn_alloc_max(&s->y))
41*6644e2f0SJens Wiklander 		goto err;
42*6644e2f0SJens Wiklander 	return TEE_SUCCESS;
43*6644e2f0SJens Wiklander err:
44*6644e2f0SJens Wiklander 	crypto_bignum_free(s->x);
45*6644e2f0SJens Wiklander 	crypto_bignum_free(s->y);
46*6644e2f0SJens Wiklander 	return TEE_ERROR_OUT_OF_MEMORY;
47*6644e2f0SJens Wiklander }
48*6644e2f0SJens Wiklander 
49*6644e2f0SJens Wiklander void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s)
50*6644e2f0SJens Wiklander {
51*6644e2f0SJens Wiklander 	if (!s)
52*6644e2f0SJens Wiklander 		return;
53*6644e2f0SJens Wiklander 
54*6644e2f0SJens Wiklander 	crypto_bignum_free(s->x);
55*6644e2f0SJens Wiklander 	crypto_bignum_free(s->y);
56*6644e2f0SJens Wiklander }
57*6644e2f0SJens Wiklander 
58*6644e2f0SJens Wiklander /*
59*6644e2f0SJens Wiklander  * curve is part of TEE_ECC_CURVE_NIST_P192,...
60*6644e2f0SJens Wiklander  * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it
61*6644e2f0SJens Wiklander  */
62*6644e2f0SJens Wiklander static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo,
63*6644e2f0SJens Wiklander 				  size_t *key_size_bytes, size_t *key_size_bits)
64*6644e2f0SJens Wiklander {
65*6644e2f0SJens Wiklander 	/*
66*6644e2f0SJens Wiklander 	 * Excerpt of libtomcrypt documentation:
67*6644e2f0SJens Wiklander 	 * ecc_make_key(... key_size ...): The keysize is the size of the
68*6644e2f0SJens Wiklander 	 * modulus in bytes desired. Currently directly supported values
69*6644e2f0SJens Wiklander 	 * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond
70*6644e2f0SJens Wiklander 	 * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits
71*6644e2f0SJens Wiklander 	 * respectively.
72*6644e2f0SJens Wiklander 	 */
73*6644e2f0SJens Wiklander 
74*6644e2f0SJens Wiklander 	/*
75*6644e2f0SJens Wiklander 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
76*6644e2f0SJens Wiklander 	 * but defines TEE_ALG_ECDH_P192
77*6644e2f0SJens Wiklander 	 */
78*6644e2f0SJens Wiklander 
79*6644e2f0SJens Wiklander 	switch (curve) {
80*6644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P192:
81*6644e2f0SJens Wiklander 		*key_size_bits = 192;
82*6644e2f0SJens Wiklander 		*key_size_bytes = 24;
83*6644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
84*6644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P192))
85*6644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
86*6644e2f0SJens Wiklander 		break;
87*6644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P224:
88*6644e2f0SJens Wiklander 		*key_size_bits = 224;
89*6644e2f0SJens Wiklander 		*key_size_bytes = 28;
90*6644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
91*6644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P224))
92*6644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
93*6644e2f0SJens Wiklander 		break;
94*6644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P256:
95*6644e2f0SJens Wiklander 		*key_size_bits = 256;
96*6644e2f0SJens Wiklander 		*key_size_bytes = 32;
97*6644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
98*6644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P256))
99*6644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
100*6644e2f0SJens Wiklander 		break;
101*6644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P384:
102*6644e2f0SJens Wiklander 		*key_size_bits = 384;
103*6644e2f0SJens Wiklander 		*key_size_bytes = 48;
104*6644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
105*6644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P384))
106*6644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
107*6644e2f0SJens Wiklander 		break;
108*6644e2f0SJens Wiklander 	case TEE_ECC_CURVE_NIST_P521:
109*6644e2f0SJens Wiklander 		*key_size_bits = 521;
110*6644e2f0SJens Wiklander 		/*
111*6644e2f0SJens Wiklander 		 * set 66 instead of 65 wrt to Libtomcrypt documentation as
112*6644e2f0SJens Wiklander 		 * if it the real key size
113*6644e2f0SJens Wiklander 		 */
114*6644e2f0SJens Wiklander 		*key_size_bytes = 66;
115*6644e2f0SJens Wiklander 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
116*6644e2f0SJens Wiklander 		    (algo != TEE_ALG_ECDH_P521))
117*6644e2f0SJens Wiklander 			return TEE_ERROR_BAD_PARAMETERS;
118*6644e2f0SJens Wiklander 		break;
119*6644e2f0SJens Wiklander 	default:
120*6644e2f0SJens Wiklander 		*key_size_bits = 0;
121*6644e2f0SJens Wiklander 		*key_size_bytes = 0;
122*6644e2f0SJens Wiklander 		return TEE_ERROR_NOT_SUPPORTED;
123*6644e2f0SJens Wiklander 	}
124*6644e2f0SJens Wiklander 
125*6644e2f0SJens Wiklander 	return TEE_SUCCESS;
126*6644e2f0SJens Wiklander }
127*6644e2f0SJens Wiklander 
128*6644e2f0SJens Wiklander TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key)
129*6644e2f0SJens Wiklander {
130*6644e2f0SJens Wiklander 	TEE_Result res;
131*6644e2f0SJens Wiklander 	ecc_key ltc_tmp_key;
132*6644e2f0SJens Wiklander 	int ltc_res;
133*6644e2f0SJens Wiklander 	size_t key_size_bytes = 0;
134*6644e2f0SJens Wiklander 	size_t key_size_bits = 0;
135*6644e2f0SJens Wiklander 
136*6644e2f0SJens Wiklander 	res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
137*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
138*6644e2f0SJens Wiklander 		return res;
139*6644e2f0SJens Wiklander 
140*6644e2f0SJens Wiklander 	/* Generate the ECC key */
141*6644e2f0SJens Wiklander 	ltc_res = ecc_make_key(NULL, find_prng("prng_mpa"),
142*6644e2f0SJens Wiklander 			       key_size_bytes, &ltc_tmp_key);
143*6644e2f0SJens Wiklander 	if (ltc_res != CRYPT_OK)
144*6644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
145*6644e2f0SJens Wiklander 
146*6644e2f0SJens Wiklander 	/* check the size of the keys */
147*6644e2f0SJens Wiklander 	if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) ||
148*6644e2f0SJens Wiklander 	    ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) ||
149*6644e2f0SJens Wiklander 	    ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) {
150*6644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
151*6644e2f0SJens Wiklander 		goto exit;
152*6644e2f0SJens Wiklander 	}
153*6644e2f0SJens Wiklander 
154*6644e2f0SJens Wiklander 	/* check LTC is returning z==1 */
155*6644e2f0SJens Wiklander 	if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) {
156*6644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
157*6644e2f0SJens Wiklander 		goto exit;
158*6644e2f0SJens Wiklander 	}
159*6644e2f0SJens Wiklander 
160*6644e2f0SJens Wiklander 	/* Copy the key */
161*6644e2f0SJens Wiklander 	ltc_mp.copy(ltc_tmp_key.k, key->d);
162*6644e2f0SJens Wiklander 	ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x);
163*6644e2f0SJens Wiklander 	ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y);
164*6644e2f0SJens Wiklander 
165*6644e2f0SJens Wiklander 	res = TEE_SUCCESS;
166*6644e2f0SJens Wiklander 
167*6644e2f0SJens Wiklander exit:
168*6644e2f0SJens Wiklander 	ecc_free(&ltc_tmp_key);		/* Free the temporary key */
169*6644e2f0SJens Wiklander 	return res;
170*6644e2f0SJens Wiklander }
171*6644e2f0SJens Wiklander 
172*6644e2f0SJens Wiklander static TEE_Result ecc_compute_key_idx(ecc_key *ltc_key, size_t keysize)
173*6644e2f0SJens Wiklander {
174*6644e2f0SJens Wiklander 	size_t x;
175*6644e2f0SJens Wiklander 
176*6644e2f0SJens Wiklander 	for (x = 0; ((int)keysize > ltc_ecc_sets[x].size) &&
177*6644e2f0SJens Wiklander 		    (ltc_ecc_sets[x].size != 0);
178*6644e2f0SJens Wiklander 	     x++)
179*6644e2f0SJens Wiklander 		;
180*6644e2f0SJens Wiklander 	keysize = (size_t)ltc_ecc_sets[x].size;
181*6644e2f0SJens Wiklander 
182*6644e2f0SJens Wiklander 	if ((keysize > ECC_MAXSIZE) || (ltc_ecc_sets[x].size == 0))
183*6644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
184*6644e2f0SJens Wiklander 
185*6644e2f0SJens Wiklander 	ltc_key->idx = -1;
186*6644e2f0SJens Wiklander 	ltc_key->dp  = &ltc_ecc_sets[x];
187*6644e2f0SJens Wiklander 
188*6644e2f0SJens Wiklander 	return TEE_SUCCESS;
189*6644e2f0SJens Wiklander }
190*6644e2f0SJens Wiklander 
191*6644e2f0SJens Wiklander /*
192*6644e2f0SJens Wiklander  * Given a keypair "key", populate the Libtomcrypt private key "ltc_key"
193*6644e2f0SJens Wiklander  * It also returns the key size, in bytes
194*6644e2f0SJens Wiklander  */
195*6644e2f0SJens Wiklander static TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key,
196*6644e2f0SJens Wiklander 					       struct ecc_keypair *key,
197*6644e2f0SJens Wiklander 					       uint32_t algo,
198*6644e2f0SJens Wiklander 					       size_t *key_size_bytes)
199*6644e2f0SJens Wiklander {
200*6644e2f0SJens Wiklander 	TEE_Result res;
201*6644e2f0SJens Wiklander 	size_t key_size_bits;
202*6644e2f0SJens Wiklander 
203*6644e2f0SJens Wiklander 	memset(ltc_key, 0, sizeof(*ltc_key));
204*6644e2f0SJens Wiklander 	ltc_key->type = PK_PRIVATE;
205*6644e2f0SJens Wiklander 	ltc_key->k = key->d;
206*6644e2f0SJens Wiklander 
207*6644e2f0SJens Wiklander 	/* compute the index of the ecc curve */
208*6644e2f0SJens Wiklander 	res = ecc_get_keysize(key->curve, algo,
209*6644e2f0SJens Wiklander 			      key_size_bytes, &key_size_bits);
210*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
211*6644e2f0SJens Wiklander 		return res;
212*6644e2f0SJens Wiklander 
213*6644e2f0SJens Wiklander 	return ecc_compute_key_idx(ltc_key, *key_size_bytes);
214*6644e2f0SJens Wiklander }
215*6644e2f0SJens Wiklander 
216*6644e2f0SJens Wiklander /*
217*6644e2f0SJens Wiklander  * Given a public "key", populate the Libtomcrypt public key "ltc_key"
218*6644e2f0SJens Wiklander  * It also returns the key size, in bytes
219*6644e2f0SJens Wiklander  */
220*6644e2f0SJens Wiklander static TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key,
221*6644e2f0SJens Wiklander 					      struct ecc_public_key *key,
222*6644e2f0SJens Wiklander 					      void *key_z,
223*6644e2f0SJens Wiklander 					      uint32_t algo,
224*6644e2f0SJens Wiklander 					      size_t *key_size_bytes)
225*6644e2f0SJens Wiklander {
226*6644e2f0SJens Wiklander 	TEE_Result res;
227*6644e2f0SJens Wiklander 	size_t key_size_bits;
228*6644e2f0SJens Wiklander 	uint8_t one[1] = { 1 };
229*6644e2f0SJens Wiklander 
230*6644e2f0SJens Wiklander 
231*6644e2f0SJens Wiklander 	memset(ltc_key, 0, sizeof(*ltc_key));
232*6644e2f0SJens Wiklander 	ltc_key->type = PK_PUBLIC;
233*6644e2f0SJens Wiklander 	ltc_key->pubkey.x = key->x;
234*6644e2f0SJens Wiklander 	ltc_key->pubkey.y = key->y;
235*6644e2f0SJens Wiklander 	ltc_key->pubkey.z = key_z;
236*6644e2f0SJens Wiklander 	mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one));
237*6644e2f0SJens Wiklander 
238*6644e2f0SJens Wiklander 	/* compute the index of the ecc curve */
239*6644e2f0SJens Wiklander 	res = ecc_get_keysize(key->curve, algo,
240*6644e2f0SJens Wiklander 			      key_size_bytes, &key_size_bits);
241*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
242*6644e2f0SJens Wiklander 		return res;
243*6644e2f0SJens Wiklander 
244*6644e2f0SJens Wiklander 	return ecc_compute_key_idx(ltc_key, *key_size_bytes);
245*6644e2f0SJens Wiklander }
246*6644e2f0SJens Wiklander 
247*6644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key,
248*6644e2f0SJens Wiklander 				   const uint8_t *msg, size_t msg_len,
249*6644e2f0SJens Wiklander 				   uint8_t *sig, size_t *sig_len)
250*6644e2f0SJens Wiklander {
251*6644e2f0SJens Wiklander 	TEE_Result res;
252*6644e2f0SJens Wiklander 	int ltc_res;
253*6644e2f0SJens Wiklander 	void *r, *s;
254*6644e2f0SJens Wiklander 	size_t key_size_bytes;
255*6644e2f0SJens Wiklander 	ecc_key ltc_key;
256*6644e2f0SJens Wiklander 
257*6644e2f0SJens Wiklander 	if (algo == 0) {
258*6644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
259*6644e2f0SJens Wiklander 		goto err;
260*6644e2f0SJens Wiklander 	}
261*6644e2f0SJens Wiklander 
262*6644e2f0SJens Wiklander 	res = ecc_populate_ltc_private_key(&ltc_key, key, algo,
263*6644e2f0SJens Wiklander 					   &key_size_bytes);
264*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
265*6644e2f0SJens Wiklander 		goto err;
266*6644e2f0SJens Wiklander 
267*6644e2f0SJens Wiklander 	if (*sig_len < 2 * key_size_bytes) {
268*6644e2f0SJens Wiklander 		*sig_len = 2 * key_size_bytes;
269*6644e2f0SJens Wiklander 		res = TEE_ERROR_SHORT_BUFFER;
270*6644e2f0SJens Wiklander 		goto err;
271*6644e2f0SJens Wiklander 	}
272*6644e2f0SJens Wiklander 
273*6644e2f0SJens Wiklander 	ltc_res = mp_init_multi(&r, &s, NULL);
274*6644e2f0SJens Wiklander 	if (ltc_res != CRYPT_OK) {
275*6644e2f0SJens Wiklander 		res = TEE_ERROR_OUT_OF_MEMORY;
276*6644e2f0SJens Wiklander 		goto err;
277*6644e2f0SJens Wiklander 	}
278*6644e2f0SJens Wiklander 
279*6644e2f0SJens Wiklander 	ltc_res = ecc_sign_hash_raw(msg, msg_len, r, s,
280*6644e2f0SJens Wiklander 				    NULL, find_prng("prng_mpa"), &ltc_key);
281*6644e2f0SJens Wiklander 
282*6644e2f0SJens Wiklander 	if (ltc_res == CRYPT_OK) {
283*6644e2f0SJens Wiklander 		*sig_len = 2 * key_size_bytes;
284*6644e2f0SJens Wiklander 		memset(sig, 0, *sig_len);
285*6644e2f0SJens Wiklander 		mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 -
286*6644e2f0SJens Wiklander 				   mp_unsigned_bin_size(r));
287*6644e2f0SJens Wiklander 		mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len -
288*6644e2f0SJens Wiklander 				   mp_unsigned_bin_size(s));
289*6644e2f0SJens Wiklander 		res = TEE_SUCCESS;
290*6644e2f0SJens Wiklander 	} else {
291*6644e2f0SJens Wiklander 		res = TEE_ERROR_GENERIC;
292*6644e2f0SJens Wiklander 	}
293*6644e2f0SJens Wiklander 
294*6644e2f0SJens Wiklander 	mp_clear_multi(r, s, NULL);
295*6644e2f0SJens Wiklander 
296*6644e2f0SJens Wiklander err:
297*6644e2f0SJens Wiklander 	return res;
298*6644e2f0SJens Wiklander }
299*6644e2f0SJens Wiklander 
300*6644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
301*6644e2f0SJens Wiklander 				     const uint8_t *msg, size_t msg_len,
302*6644e2f0SJens Wiklander 				     const uint8_t *sig, size_t sig_len)
303*6644e2f0SJens Wiklander {
304*6644e2f0SJens Wiklander 	TEE_Result res;
305*6644e2f0SJens Wiklander 	int ltc_stat;
306*6644e2f0SJens Wiklander 	int ltc_res;
307*6644e2f0SJens Wiklander 	void *r;
308*6644e2f0SJens Wiklander 	void *s;
309*6644e2f0SJens Wiklander 	void *key_z;
310*6644e2f0SJens Wiklander 	size_t key_size_bytes;
311*6644e2f0SJens Wiklander 	ecc_key ltc_key;
312*6644e2f0SJens Wiklander 
313*6644e2f0SJens Wiklander 	if (algo == 0)
314*6644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
315*6644e2f0SJens Wiklander 
316*6644e2f0SJens Wiklander 	ltc_res = mp_init_multi(&key_z, &r, &s, NULL);
317*6644e2f0SJens Wiklander 	if (ltc_res != CRYPT_OK)
318*6644e2f0SJens Wiklander 		return TEE_ERROR_OUT_OF_MEMORY;
319*6644e2f0SJens Wiklander 
320*6644e2f0SJens Wiklander 	res = ecc_populate_ltc_public_key(&ltc_key, key, key_z, algo,
321*6644e2f0SJens Wiklander 					  &key_size_bytes);
322*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
323*6644e2f0SJens Wiklander 		goto out;
324*6644e2f0SJens Wiklander 
325*6644e2f0SJens Wiklander 	/* check keysize vs sig_len */
326*6644e2f0SJens Wiklander 	if ((key_size_bytes * 2) != sig_len) {
327*6644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
328*6644e2f0SJens Wiklander 		goto out;
329*6644e2f0SJens Wiklander 	}
330*6644e2f0SJens Wiklander 
331*6644e2f0SJens Wiklander 	mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2);
332*6644e2f0SJens Wiklander 	mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2);
333*6644e2f0SJens Wiklander 
334*6644e2f0SJens Wiklander 	ltc_res = ecc_verify_hash_raw(r, s, msg, msg_len, &ltc_stat, &ltc_key);
335*6644e2f0SJens Wiklander 	res = convert_ltc_verify_status(ltc_res, ltc_stat);
336*6644e2f0SJens Wiklander out:
337*6644e2f0SJens Wiklander 	mp_clear_multi(key_z, r, s, NULL);
338*6644e2f0SJens Wiklander 	return res;
339*6644e2f0SJens Wiklander }
340*6644e2f0SJens Wiklander 
341*6644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
342*6644e2f0SJens Wiklander 					    struct ecc_public_key *public_key,
343*6644e2f0SJens Wiklander 					    void *secret,
344*6644e2f0SJens Wiklander 					    unsigned long *secret_len)
345*6644e2f0SJens Wiklander {
346*6644e2f0SJens Wiklander 	TEE_Result res;
347*6644e2f0SJens Wiklander 	int ltc_res;
348*6644e2f0SJens Wiklander 	ecc_key ltc_private_key;
349*6644e2f0SJens Wiklander 	ecc_key ltc_public_key;
350*6644e2f0SJens Wiklander 	size_t key_size_bytes;
351*6644e2f0SJens Wiklander 	void *key_z;
352*6644e2f0SJens Wiklander 
353*6644e2f0SJens Wiklander 	/* Check the curves are the same */
354*6644e2f0SJens Wiklander 	if (private_key->curve != public_key->curve)
355*6644e2f0SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
356*6644e2f0SJens Wiklander 
357*6644e2f0SJens Wiklander 	ltc_res = mp_init_multi(&key_z, NULL);
358*6644e2f0SJens Wiklander 	if (ltc_res != CRYPT_OK)
359*6644e2f0SJens Wiklander 		return TEE_ERROR_OUT_OF_MEMORY;
360*6644e2f0SJens Wiklander 
361*6644e2f0SJens Wiklander 	res = ecc_populate_ltc_private_key(&ltc_private_key, private_key,
362*6644e2f0SJens Wiklander 					   0, &key_size_bytes);
363*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
364*6644e2f0SJens Wiklander 		goto out;
365*6644e2f0SJens Wiklander 	res = ecc_populate_ltc_public_key(&ltc_public_key, public_key, key_z,
366*6644e2f0SJens Wiklander 					  0, &key_size_bytes);
367*6644e2f0SJens Wiklander 	if (res != TEE_SUCCESS)
368*6644e2f0SJens Wiklander 		goto out;
369*6644e2f0SJens Wiklander 
370*6644e2f0SJens Wiklander 	ltc_res = ecc_shared_secret(&ltc_private_key, &ltc_public_key,
371*6644e2f0SJens Wiklander 				    secret, secret_len);
372*6644e2f0SJens Wiklander 	if (ltc_res == CRYPT_OK)
373*6644e2f0SJens Wiklander 		res = TEE_SUCCESS;
374*6644e2f0SJens Wiklander 	else
375*6644e2f0SJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
376*6644e2f0SJens Wiklander 
377*6644e2f0SJens Wiklander out:
378*6644e2f0SJens Wiklander 	mp_clear_multi(key_z, NULL);
379*6644e2f0SJens Wiklander 	return res;
380*6644e2f0SJens Wiklander }
381