xref: /optee_os/core/lib/libtomcrypt/ecc.c (revision c44d734b6366cbf4d12610310e809872db65f89d)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014-2019, Linaro Limited
4  */
5 
6 #include <config.h>
7 #include <crypto/crypto_impl.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <tee_api_types.h>
11 #include <trace.h>
12 #include <utee_defines.h>
13 
14 #include "acipher_helpers.h"
15 
16 static void _ltc_ecc_free_public_key(struct ecc_public_key *s)
17 {
18 	if (!s)
19 		return;
20 
21 	crypto_bignum_free(s->x);
22 	crypto_bignum_free(s->y);
23 }
24 
25 /*
26  * For a given TEE @curve, return key size and LTC curve name. Also check that
27  * @algo is compatible with this curve.
28  * @curve: TEE_ECC_CURVE_NIST_P192, ...
29  * @algo: TEE_ALG_ECDSA_P192, ...
30  */
31 static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo,
32 				     size_t *key_size_bytes,
33 				     size_t *key_size_bits,
34 				     const char **curve_name)
35 {
36 	size_t size_bytes = 0;
37 	size_t size_bits = 0;
38 	const char *name = NULL;
39 
40 	/*
41 	 * Excerpt of libtomcrypt documentation:
42 	 * ecc_make_key(... key_size ...): The keysize is the size of the
43 	 * modulus in bytes desired. Currently directly supported values
44 	 * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond
45 	 * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits
46 	 * respectively.
47 	 */
48 
49 	/*
50 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
51 	 * but defines TEE_ALG_ECDH_P192
52 	 */
53 
54 	switch (curve) {
55 	case TEE_ECC_CURVE_NIST_P192:
56 		size_bits = 192;
57 		size_bytes = 24;
58 		name = "NISTP192";
59 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
60 		    (algo != TEE_ALG_ECDH_P192))
61 			return TEE_ERROR_BAD_PARAMETERS;
62 		break;
63 	case TEE_ECC_CURVE_NIST_P224:
64 		size_bits = 224;
65 		size_bytes = 28;
66 		name = "NISTP224";
67 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
68 		    (algo != TEE_ALG_ECDH_P224))
69 			return TEE_ERROR_BAD_PARAMETERS;
70 		break;
71 	case TEE_ECC_CURVE_NIST_P256:
72 		size_bits = 256;
73 		size_bytes = 32;
74 		name = "NISTP256";
75 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
76 		    (algo != TEE_ALG_ECDH_P256))
77 			return TEE_ERROR_BAD_PARAMETERS;
78 		break;
79 	case TEE_ECC_CURVE_NIST_P384:
80 		size_bits = 384;
81 		size_bytes = 48;
82 		name = "NISTP384";
83 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
84 		    (algo != TEE_ALG_ECDH_P384))
85 			return TEE_ERROR_BAD_PARAMETERS;
86 		break;
87 	case TEE_ECC_CURVE_NIST_P521:
88 		size_bits = 521;
89 		size_bytes = 66;
90 		name = "NISTP521";
91 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
92 		    (algo != TEE_ALG_ECDH_P521))
93 			return TEE_ERROR_BAD_PARAMETERS;
94 		break;
95 	case TEE_ECC_CURVE_SM2:
96 		size_bits = 256;
97 		size_bytes = 32;
98 		name = "SM2";
99 		if ((algo != 0) && (algo != TEE_ALG_SM2_PKE) &&
100 		    (algo != TEE_ALG_SM2_DSA_SM3) &&
101 		    (algo != TEE_ALG_SM2_KEP))
102 			return TEE_ERROR_BAD_PARAMETERS;
103 		break;
104 	default:
105 		return TEE_ERROR_NOT_SUPPORTED;
106 	}
107 
108 	if (key_size_bytes)
109 		*key_size_bytes = size_bytes;
110 	if (key_size_bits)
111 		*key_size_bits = size_bits;
112 	if (curve_name)
113 		*curve_name = name;
114 	return TEE_SUCCESS;
115 }
116 
117 /* Note: this function clears the key before setting the curve */
118 static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key,
119 					  const char *curve_name)
120 {
121 	const ltc_ecc_curve *curve = NULL;
122 	int ltc_res = 0;
123 
124 	ltc_res = ecc_find_curve(curve_name, &curve);
125 	if (ltc_res != CRYPT_OK)
126 		return TEE_ERROR_NOT_SUPPORTED;
127 
128 	ltc_res = ecc_set_curve(curve, ltc_key);
129 	if (ltc_res != CRYPT_OK)
130 		return TEE_ERROR_GENERIC;
131 
132 	return TEE_SUCCESS;
133 }
134 
135 static TEE_Result _ltc_ecc_generate_keypair(struct ecc_keypair *key,
136 					    size_t key_size)
137 {
138 	TEE_Result res;
139 	ecc_key ltc_tmp_key;
140 	int ltc_res;
141 	size_t key_size_bytes = 0;
142 	size_t key_size_bits = 0;
143 	const char *name = NULL;
144 
145 	res = ecc_get_curve_info(key->curve, 0, &key_size_bytes, &key_size_bits,
146 				 &name);
147 	if (res != TEE_SUCCESS)
148 		return res;
149 
150 	if (key_size != key_size_bits)
151 		return TEE_ERROR_BAD_PARAMETERS;
152 
153 	res = ecc_set_curve_from_name(&ltc_tmp_key, name);
154 	if (res)
155 		return res;
156 
157 	/* Generate the ECC key */
158 	ltc_res = ecc_generate_key(NULL, find_prng("prng_crypto"),
159 				   &ltc_tmp_key);
160 	if (ltc_res != CRYPT_OK)
161 		return TEE_ERROR_BAD_PARAMETERS;
162 
163 	/* check the size of the keys */
164 	if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) ||
165 	    ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) ||
166 	    ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) {
167 		res = TEE_ERROR_BAD_PARAMETERS;
168 		goto exit;
169 	}
170 
171 	/* check LTC is returning z==1 */
172 	if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) {
173 		res = TEE_ERROR_BAD_PARAMETERS;
174 		goto exit;
175 	}
176 
177 	/* Copy the key */
178 	ltc_mp.copy(ltc_tmp_key.k, key->d);
179 	ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x);
180 	ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y);
181 
182 	res = TEE_SUCCESS;
183 
184 exit:
185 	ecc_free(&ltc_tmp_key);		/* Free the temporary key */
186 	return res;
187 }
188 
189 /*
190  * Given a keypair "key", populate the Libtomcrypt private key "ltc_key"
191  * It also returns the key size, in bytes
192  */
193 TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key,
194 					struct ecc_keypair *key,
195 					uint32_t algo, size_t *key_size_bytes)
196 {
197 	TEE_Result res = TEE_ERROR_GENERIC;
198 	const char *name = NULL;
199 
200 	res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name);
201 	if (res)
202 		return res;
203 
204 	memset(ltc_key, 0, sizeof(*ltc_key));
205 
206 	res = ecc_set_curve_from_name(ltc_key, name);
207 	if (res)
208 		return res;
209 
210 	ltc_key->type = PK_PRIVATE;
211 	mp_copy(key->d, ltc_key->k);
212 	mp_copy(key->x, ltc_key->pubkey.x);
213 	mp_copy(key->y, ltc_key->pubkey.y);
214 	mp_set_int(ltc_key->pubkey.z, 1);
215 
216 	return TEE_SUCCESS;
217 }
218 
219 /*
220  * Given a public "key", populate the Libtomcrypt public key "ltc_key"
221  * It also returns the key size, in bytes
222  */
223 TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key,
224 				       struct ecc_public_key *key,
225 				       uint32_t algo, size_t *key_size_bytes)
226 {
227 	TEE_Result res = TEE_ERROR_GENERIC;
228 	const char *name = NULL;
229 	uint8_t one[1] = { 1 };
230 
231 	res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name);
232 	if (res)
233 		return res;
234 
235 	memset(ltc_key, 0, sizeof(*ltc_key));
236 
237 	res = ecc_set_curve_from_name(ltc_key, name);
238 	if (res)
239 		return res;
240 
241 	ltc_key->type = PK_PUBLIC;
242 
243 	mp_copy(key->x, ltc_key->pubkey.x);
244 	mp_copy(key->y, ltc_key->pubkey.y);
245 	mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one));
246 
247 	return TEE_SUCCESS;
248 }
249 
250 static TEE_Result _ltc_ecc_sign(uint32_t algo, struct ecc_keypair *key,
251 				const uint8_t *msg, size_t msg_len,
252 				uint8_t *sig, size_t *sig_len)
253 {
254 	TEE_Result res = TEE_ERROR_GENERIC;
255 	int ltc_res = 0;
256 	size_t key_size_bytes = 0;
257 	ecc_key ltc_key = { };
258 	unsigned long ltc_sig_len = 0;
259 
260 	if (algo == 0)
261 		return TEE_ERROR_BAD_PARAMETERS;
262 
263 	res = ecc_populate_ltc_private_key(&ltc_key, key, algo,
264 					   &key_size_bytes);
265 	if (res != TEE_SUCCESS)
266 		return res;
267 
268 	if (*sig_len < 2 * key_size_bytes) {
269 		*sig_len = 2 * key_size_bytes;
270 		res = TEE_ERROR_SHORT_BUFFER;
271 		goto out;
272 	}
273 
274 	ltc_sig_len = *sig_len;
275 	ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, &ltc_sig_len,
276 				    NULL, find_prng("prng_crypto"), &ltc_key);
277 	if (ltc_res == CRYPT_OK) {
278 		res = TEE_SUCCESS;
279 	} else {
280 		res = TEE_ERROR_GENERIC;
281 	}
282 	*sig_len = ltc_sig_len;
283 
284 out:
285 	ecc_free(&ltc_key);
286 	return res;
287 }
288 
289 static TEE_Result _ltc_ecc_verify(uint32_t algo, struct ecc_public_key *key,
290 				  const uint8_t *msg, size_t msg_len,
291 				  const uint8_t *sig, size_t sig_len)
292 {
293 	TEE_Result res = TEE_ERROR_GENERIC;
294 	int ltc_stat = 0;
295 	int ltc_res = 0;
296 	size_t key_size_bytes = 0;
297 	ecc_key ltc_key = { };
298 
299 	if (algo == 0)
300 		return TEE_ERROR_BAD_PARAMETERS;
301 
302 	res = ecc_populate_ltc_public_key(&ltc_key, key, algo, &key_size_bytes);
303 	if (res != TEE_SUCCESS)
304 		goto out;
305 
306 	/* check keysize vs sig_len */
307 	if ((key_size_bytes * 2) != sig_len) {
308 		res = TEE_ERROR_BAD_PARAMETERS;
309 		goto out;
310 	}
311 
312 	ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, &ltc_stat,
313 					  &ltc_key);
314 	res = convert_ltc_verify_status(ltc_res, ltc_stat);
315 out:
316 	ecc_free(&ltc_key);
317 	return res;
318 }
319 
320 static TEE_Result _ltc_ecc_shared_secret(struct ecc_keypair *private_key,
321 					 struct ecc_public_key *public_key,
322 					 void *secret,
323 					 unsigned long *secret_len)
324 {
325 	TEE_Result res = TEE_ERROR_GENERIC;
326 	int ltc_res = 0;
327 	ecc_key ltc_private_key = { };
328 	ecc_key ltc_public_key = { };
329 	size_t key_size_bytes = 0;
330 
331 	/* Check the curves are the same */
332 	if (private_key->curve != public_key->curve)
333 		return TEE_ERROR_BAD_PARAMETERS;
334 
335 	res = ecc_populate_ltc_private_key(&ltc_private_key, private_key,
336 					   0, &key_size_bytes);
337 	if (res != TEE_SUCCESS)
338 		goto out;
339 	res = ecc_populate_ltc_public_key(&ltc_public_key, public_key,
340 					  0, &key_size_bytes);
341 	if (res != TEE_SUCCESS)
342 		goto out;
343 
344 	ltc_res = ecc_shared_secret(&ltc_private_key, &ltc_public_key,
345 				    secret, secret_len);
346 	if (ltc_res == CRYPT_OK)
347 		res = TEE_SUCCESS;
348 	else
349 		res = TEE_ERROR_BAD_PARAMETERS;
350 
351 out:
352 	ecc_free(&ltc_private_key);
353 	ecc_free(&ltc_public_key);
354 	return res;
355 }
356 
357 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = {
358 	.generate = _ltc_ecc_generate_keypair,
359 	.sign = _ltc_ecc_sign,
360 	.shared_secret = _ltc_ecc_shared_secret,
361 };
362 
363 static const struct crypto_ecc_public_ops ecc_public_key_ops = {
364 	.free = _ltc_ecc_free_public_key,
365 	.verify = _ltc_ecc_verify,
366 };
367 
368 static const struct crypto_ecc_keypair_ops sm2_dsa_keypair_ops = {
369 	.generate = _ltc_ecc_generate_keypair,
370 	.sign = sm2_ltc_dsa_sign,
371 };
372 
373 static const struct crypto_ecc_public_ops sm2_dsa_public_key_ops = {
374 	.free = _ltc_ecc_free_public_key,
375 	.verify = sm2_ltc_dsa_verify,
376 };
377 
378 static const struct crypto_ecc_keypair_ops sm2_pke_keypair_ops = {
379 	.generate = _ltc_ecc_generate_keypair,
380 	.decrypt = sm2_ltc_pke_decrypt,
381 };
382 
383 static const struct crypto_ecc_public_ops sm2_pke_public_key_ops = {
384 	.free = _ltc_ecc_free_public_key,
385 	.encrypt = sm2_ltc_pke_encrypt,
386 };
387 
388 static const struct crypto_ecc_keypair_ops sm2_kep_keypair_ops = {
389 	.generate = _ltc_ecc_generate_keypair,
390 };
391 
392 static const struct crypto_ecc_public_ops sm2_kep_public_key_ops = {
393 	.free = _ltc_ecc_free_public_key,
394 };
395 
396 TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s,
397 					 uint32_t key_type,
398 					 size_t key_size_bits __unused)
399 {
400 	memset(s, 0, sizeof(*s));
401 
402 	switch (key_type) {
403 	case TEE_TYPE_ECDSA_KEYPAIR:
404 	case TEE_TYPE_ECDH_KEYPAIR:
405 		s->ops = &ecc_keypair_ops;
406 		break;
407 	case TEE_TYPE_SM2_DSA_KEYPAIR:
408 		if (!IS_ENABLED(_CFG_CORE_LTC_SM2_DSA))
409 			return TEE_ERROR_NOT_IMPLEMENTED;
410 
411 		s->curve = TEE_ECC_CURVE_SM2;
412 		s->ops = &sm2_dsa_keypair_ops;
413 		break;
414 	case TEE_TYPE_SM2_PKE_KEYPAIR:
415 		if (!IS_ENABLED(_CFG_CORE_LTC_SM2_PKE))
416 			return TEE_ERROR_NOT_IMPLEMENTED;
417 
418 		s->curve = TEE_ECC_CURVE_SM2;
419 		s->ops = &sm2_pke_keypair_ops;
420 		break;
421 	case TEE_TYPE_SM2_KEP_KEYPAIR:
422 		if (!IS_ENABLED(_CFG_CORE_LTC_SM2_KEP))
423 			return TEE_ERROR_NOT_IMPLEMENTED;
424 
425 		s->curve = TEE_ECC_CURVE_SM2;
426 		s->ops = &sm2_kep_keypair_ops;
427 		break;
428 	default:
429 		return TEE_ERROR_NOT_IMPLEMENTED;
430 	}
431 
432 	if (!bn_alloc_max(&s->d))
433 		goto err;
434 	if (!bn_alloc_max(&s->x))
435 		goto err;
436 	if (!bn_alloc_max(&s->y))
437 		goto err;
438 
439 	return TEE_SUCCESS;
440 
441 err:
442 	s->ops = NULL;
443 
444 	crypto_bignum_free(s->d);
445 	crypto_bignum_free(s->x);
446 
447 	return TEE_ERROR_OUT_OF_MEMORY;
448 }
449 
450 TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s,
451 					    uint32_t key_type,
452 					    size_t key_size_bits __unused)
453 {
454 	memset(s, 0, sizeof(*s));
455 
456 	switch (key_type) {
457 	case TEE_TYPE_ECDSA_PUBLIC_KEY:
458 	case TEE_TYPE_ECDH_PUBLIC_KEY:
459 		s->ops = &ecc_public_key_ops;
460 		break;
461 	case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
462 		if (!IS_ENABLED(_CFG_CORE_LTC_SM2_DSA))
463 			return TEE_ERROR_NOT_IMPLEMENTED;
464 
465 		s->curve = TEE_ECC_CURVE_SM2;
466 		s->ops = &sm2_dsa_public_key_ops;
467 		break;
468 	case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
469 		if (!IS_ENABLED(_CFG_CORE_LTC_SM2_PKE))
470 			return TEE_ERROR_NOT_IMPLEMENTED;
471 
472 		s->curve = TEE_ECC_CURVE_SM2;
473 		s->ops = &sm2_pke_public_key_ops;
474 		break;
475 	case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
476 		if (!IS_ENABLED(_CFG_CORE_LTC_SM2_KEP))
477 			return TEE_ERROR_NOT_IMPLEMENTED;
478 
479 		s->curve = TEE_ECC_CURVE_SM2;
480 		s->ops = &sm2_kep_public_key_ops;
481 		break;
482 	default:
483 		return TEE_ERROR_NOT_IMPLEMENTED;
484 	}
485 
486 	if (!bn_alloc_max(&s->x))
487 		goto err;
488 	if (!bn_alloc_max(&s->y))
489 		goto err;
490 
491 	return TEE_SUCCESS;
492 
493 err:
494 	s->ops = NULL;
495 
496 	crypto_bignum_free(s->x);
497 
498 	return TEE_ERROR_OUT_OF_MEMORY;
499 }
500