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