xref: /optee_os/lib/libmbedtls/core/ecc.c (revision 2f4d97e7664270c92f4fd9d35fcddcfa4fd5f667)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2018, ARM Limited
4  * Copyright (C) 2019, Linaro Limited
5  */
6 
7 #include <assert.h>
8 #include <config.h>
9 #include <crypto/crypto_impl.h>
10 #include <mbedtls/ctr_drbg.h>
11 #include <mbedtls/ecdh.h>
12 #include <mbedtls/ecdsa.h>
13 #include <mbedtls/ecp.h>
14 #include <mbedtls/entropy.h>
15 #include <mbedtls/pk.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "mbed_helpers.h"
20 #include "sm2-dsa.h"
21 #include "sm2-pke.h"
22 
23 /* Translate mbedtls result to TEE result */
24 static TEE_Result get_tee_result(int lmd_res)
25 {
26 	switch (lmd_res) {
27 	case 0:
28 		return TEE_SUCCESS;
29 	case MBEDTLS_ERR_ECP_VERIFY_FAILED:
30 		return TEE_ERROR_SIGNATURE_INVALID;
31 	case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
32 		return TEE_ERROR_SHORT_BUFFER;
33 	default:
34 		return TEE_ERROR_BAD_STATE;
35 	}
36 }
37 
38 static void ecc_free_public_key(struct ecc_public_key *s)
39 {
40 	if (!s)
41 		return;
42 
43 	crypto_bignum_free(s->x);
44 	crypto_bignum_free(s->y);
45 }
46 
47 /*
48  * curve is part of TEE_ECC_CURVE_NIST_P192,...
49  * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it
50  */
51 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo,
52 				  size_t *key_size_bytes, size_t *key_size_bits)
53 {
54 	/*
55 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
56 	 * but defines TEE_ALG_ECDH_P192
57 	 */
58 	switch (curve) {
59 	case TEE_ECC_CURVE_NIST_P192:
60 		*key_size_bits = 192;
61 		*key_size_bytes = 24;
62 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
63 		    (algo != TEE_ALG_ECDH_P192))
64 			return TEE_ERROR_BAD_PARAMETERS;
65 		break;
66 	case TEE_ECC_CURVE_NIST_P224:
67 		*key_size_bits = 224;
68 		*key_size_bytes = 28;
69 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
70 		    (algo != TEE_ALG_ECDH_P224))
71 			return TEE_ERROR_BAD_PARAMETERS;
72 		break;
73 	case TEE_ECC_CURVE_NIST_P256:
74 		*key_size_bits = 256;
75 		*key_size_bytes = 32;
76 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
77 		    (algo != TEE_ALG_ECDH_P256))
78 			return TEE_ERROR_BAD_PARAMETERS;
79 		break;
80 	case TEE_ECC_CURVE_NIST_P384:
81 		*key_size_bits = 384;
82 		*key_size_bytes = 48;
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 		*key_size_bits = 521;
89 		*key_size_bytes = 66;
90 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
91 		    (algo != TEE_ALG_ECDH_P521))
92 			return TEE_ERROR_BAD_PARAMETERS;
93 		break;
94 	case TEE_ECC_CURVE_SM2:
95 		*key_size_bits = 256;
96 		*key_size_bytes = 32;
97 		if (algo != 0 && algo != TEE_ALG_SM2_DSA_SM3 &&
98 		    algo != TEE_ALG_SM2_KEP && algo != TEE_ALG_SM2_PKE)
99 			return TEE_ERROR_BAD_PARAMETERS;
100 		break;
101 	default:
102 		*key_size_bits = 0;
103 		*key_size_bytes = 0;
104 		return TEE_ERROR_NOT_SUPPORTED;
105 	}
106 
107 	return TEE_SUCCESS;
108 }
109 
110 /*
111  * Clear some memory that was used to prepare the context
112  */
113 static void ecc_clear_precomputed(mbedtls_ecp_group *grp)
114 {
115 	size_t i = 0;
116 
117 	if (grp->T) {
118 		for (i = 0; i < grp->T_size; i++)
119 			mbedtls_ecp_point_free(&grp->T[i]);
120 		free(grp->T);
121 	}
122 	grp->T = NULL;
123 	grp->T_size = 0;
124 }
125 
126 static mbedtls_ecp_group_id curve_to_group_id(uint32_t curve)
127 {
128 	switch (curve) {
129 	case TEE_ECC_CURVE_NIST_P192:
130 		return MBEDTLS_ECP_DP_SECP192R1;
131 	case TEE_ECC_CURVE_NIST_P224:
132 		return MBEDTLS_ECP_DP_SECP224R1;
133 	case TEE_ECC_CURVE_NIST_P256:
134 		return MBEDTLS_ECP_DP_SECP256R1;
135 	case TEE_ECC_CURVE_NIST_P384:
136 		return MBEDTLS_ECP_DP_SECP384R1;
137 	case TEE_ECC_CURVE_NIST_P521:
138 		return MBEDTLS_ECP_DP_SECP521R1;
139 	case TEE_ECC_CURVE_SM2:
140 		return MBEDTLS_ECP_DP_SM2;
141 	default:
142 		return MBEDTLS_ECP_DP_NONE;
143 	}
144 }
145 
146 static TEE_Result ecc_generate_keypair(struct ecc_keypair *key, size_t key_size)
147 {
148 	TEE_Result res = TEE_SUCCESS;
149 	int lmd_res = 0;
150 	mbedtls_ecdsa_context ecdsa;
151 	mbedtls_ecp_group_id gid;
152 	size_t key_size_bytes = 0;
153 	size_t key_size_bits = 0;
154 
155 	memset(&ecdsa, 0, sizeof(ecdsa));
156 	memset(&gid, 0, sizeof(gid));
157 
158 	res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
159 	if (res != TEE_SUCCESS)
160 		return res;
161 
162 	if (key_size != key_size_bits)
163 		return TEE_ERROR_BAD_PARAMETERS;
164 
165 	mbedtls_ecdsa_init(&ecdsa);
166 
167 	/* Generate the ECC key */
168 	gid = curve_to_group_id(key->curve);
169 	lmd_res = mbedtls_ecdsa_genkey(&ecdsa, gid, mbd_rand, NULL);
170 	if (lmd_res != 0) {
171 		res = TEE_ERROR_BAD_PARAMETERS;
172 		FMSG("mbedtls_ecdsa_genkey failed.");
173 		goto exit;
174 	}
175 	ecc_clear_precomputed(&ecdsa.grp);
176 
177 	/* check the size of the keys */
178 	if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
179 	    (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
180 	    (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
181 		res = TEE_ERROR_BAD_PARAMETERS;
182 		FMSG("Check the size of the keys failed.");
183 		goto exit;
184 	}
185 
186 	/* check LMD is returning z==1 */
187 	if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
188 		res = TEE_ERROR_BAD_PARAMETERS;
189 		FMSG("Check LMD failed.");
190 		goto exit;
191 	}
192 
193 	/* Copy the key */
194 	crypto_bignum_copy(key->d, (void *)&ecdsa.d);
195 	crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
196 	crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);
197 
198 	res = TEE_SUCCESS;
199 exit:
200 	mbedtls_ecdsa_free(&ecdsa);		/* Free the temporary key */
201 	return res;
202 }
203 
204 static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key,
205 			   const uint8_t *msg, size_t msg_len, uint8_t *sig,
206 			   size_t *sig_len)
207 {
208 	TEE_Result res = TEE_SUCCESS;
209 	int lmd_res = 0;
210 	const mbedtls_pk_info_t *pk_info = NULL;
211 	mbedtls_ecdsa_context ecdsa;
212 	mbedtls_ecp_group_id gid;
213 	size_t key_size_bytes = 0;
214 	size_t key_size_bits = 0;
215 	mbedtls_mpi r;
216 	mbedtls_mpi s;
217 
218 	memset(&ecdsa, 0, sizeof(ecdsa));
219 	memset(&gid, 0, sizeof(gid));
220 	memset(&r, 0, sizeof(r));
221 	memset(&s, 0, sizeof(s));
222 
223 	if (algo == 0)
224 		return TEE_ERROR_BAD_PARAMETERS;
225 
226 	mbedtls_mpi_init(&r);
227 	mbedtls_mpi_init(&s);
228 
229 	mbedtls_ecdsa_init(&ecdsa);
230 
231 	gid = curve_to_group_id(key->curve);
232 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, gid);
233 	if (lmd_res != 0) {
234 		res = TEE_ERROR_NOT_SUPPORTED;
235 		goto out;
236 	}
237 
238 	ecdsa.d = *(mbedtls_mpi *)key->d;
239 
240 	res = ecc_get_keysize(key->curve, algo, &key_size_bytes,
241 			      &key_size_bits);
242 	if (res != TEE_SUCCESS)
243 		goto out;
244 
245 	if (*sig_len < 2 * key_size_bytes) {
246 		*sig_len = 2 * key_size_bytes;
247 		res = TEE_ERROR_SHORT_BUFFER;
248 		goto out;
249 	}
250 
251 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
252 	if (pk_info == NULL) {
253 		res = TEE_ERROR_NOT_SUPPORTED;
254 		goto out;
255 	}
256 
257 	lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
258 				     msg_len, mbd_rand, NULL);
259 	if (lmd_res == 0) {
260 		*sig_len = 2 * key_size_bytes;
261 		memset(sig, 0, *sig_len);
262 		mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
263 					 mbedtls_mpi_size(&r),
264 					 mbedtls_mpi_size(&r));
265 
266 		mbedtls_mpi_write_binary(&s, sig + *sig_len -
267 					 mbedtls_mpi_size(&s),
268 					 mbedtls_mpi_size(&s));
269 		res = TEE_SUCCESS;
270 	} else {
271 		FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res);
272 		res = TEE_ERROR_GENERIC;
273 	}
274 out:
275 	mbedtls_mpi_free(&r);
276 	mbedtls_mpi_free(&s);
277 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
278 	mbedtls_mpi_init(&ecdsa.d);
279 	mbedtls_ecdsa_free(&ecdsa);
280 	return res;
281 }
282 
283 static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key,
284 			     const uint8_t *msg, size_t msg_len,
285 			     const uint8_t *sig, size_t sig_len)
286 {
287 	TEE_Result res = TEE_SUCCESS;
288 	int lmd_res = 0;
289 	mbedtls_ecdsa_context ecdsa;
290 	mbedtls_ecp_group_id gid;
291 	size_t key_size_bytes, key_size_bits = 0;
292 	uint8_t one[1] = { 1 };
293 	mbedtls_mpi r;
294 	mbedtls_mpi s;
295 
296 	memset(&ecdsa, 0, sizeof(ecdsa));
297 	memset(&gid, 0, sizeof(gid));
298 	memset(&r, 0, sizeof(r));
299 	memset(&s, 0, sizeof(s));
300 
301 	if (algo == 0)
302 		return TEE_ERROR_BAD_PARAMETERS;
303 
304 	mbedtls_mpi_init(&r);
305 	mbedtls_mpi_init(&s);
306 
307 	mbedtls_ecdsa_init(&ecdsa);
308 
309 	gid = curve_to_group_id(key->curve);
310 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, gid);
311 	if (lmd_res != 0) {
312 		res = TEE_ERROR_NOT_SUPPORTED;
313 		goto out;
314 	}
315 
316 	ecdsa.Q.X = *(mbedtls_mpi *)key->x;
317 	ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
318 	mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));
319 
320 	res = ecc_get_keysize(key->curve, algo,
321 			      &key_size_bytes, &key_size_bits);
322 	if (res != TEE_SUCCESS) {
323 		res = TEE_ERROR_BAD_PARAMETERS;
324 		goto out;
325 	}
326 
327 	/* check keysize vs sig_len */
328 	if ((key_size_bytes * 2) != sig_len) {
329 		res = TEE_ERROR_BAD_PARAMETERS;
330 		goto out;
331 	}
332 
333 	mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
334 	mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
335 
336 	lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
337 				       &r, &s);
338 	if (lmd_res != 0) {
339 		FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
340 		res = get_tee_result(lmd_res);
341 	}
342 out:
343 	mbedtls_mpi_free(&r);
344 	mbedtls_mpi_free(&s);
345 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
346 	mbedtls_mpi_init(&ecdsa.Q.X);
347 	mbedtls_mpi_init(&ecdsa.Q.Y);
348 	mbedtls_ecdsa_free(&ecdsa);
349 	return res;
350 }
351 
352 static TEE_Result ecc_shared_secret(struct ecc_keypair *private_key,
353 				    struct ecc_public_key *public_key,
354 				    void *secret, unsigned long *secret_len)
355 {
356 	TEE_Result res = TEE_SUCCESS;
357 	int lmd_res = 0;
358 	uint8_t one[1] = { 1 };
359 	mbedtls_ecdh_context ecdh;
360 	mbedtls_ecp_group_id gid;
361 	size_t out_len = 0;
362 
363 	memset(&ecdh, 0, sizeof(ecdh));
364 	memset(&gid, 0, sizeof(gid));
365 	mbedtls_ecdh_init(&ecdh);
366 	gid = curve_to_group_id(private_key->curve);
367 	lmd_res = mbedtls_ecp_group_load(&ecdh.grp, gid);
368 	if (lmd_res != 0) {
369 		res = TEE_ERROR_NOT_SUPPORTED;
370 		goto out;
371 	}
372 
373 	ecdh.d = *(mbedtls_mpi *)private_key->d;
374 	ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
375 	ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
376 	mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one));
377 
378 	lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
379 					   *secret_len, mbd_rand, NULL);
380 	if (lmd_res != 0) {
381 		res = get_tee_result(lmd_res);
382 		goto out;
383 	}
384 	*secret_len = out_len;
385 out:
386 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
387 	mbedtls_mpi_init(&ecdh.d);
388 	mbedtls_mpi_init(&ecdh.Qp.X);
389 	mbedtls_mpi_init(&ecdh.Qp.Y);
390 	mbedtls_ecdh_free(&ecdh);
391 	return res;
392 }
393 
394 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = {
395 	.generate = ecc_generate_keypair,
396 	.sign = ecc_sign,
397 	.shared_secret = ecc_shared_secret,
398 };
399 
400 static const struct crypto_ecc_keypair_ops sm2_pke_keypair_ops = {
401 	.generate = ecc_generate_keypair,
402 	.decrypt = sm2_mbedtls_pke_decrypt,
403 };
404 
405 static const struct crypto_ecc_keypair_ops sm2_kep_keypair_ops = {
406 	.generate = ecc_generate_keypair,
407 };
408 
409 static const struct crypto_ecc_keypair_ops sm2_dsa_keypair_ops = {
410 	.generate = ecc_generate_keypair,
411 	.sign = sm2_mbedtls_dsa_sign,
412 };
413 
414 TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s,
415 					 uint32_t key_type,
416 					 size_t key_size_bits)
417 {
418 	memset(s, 0, sizeof(*s));
419 
420 	switch (key_type) {
421 	case TEE_TYPE_ECDSA_KEYPAIR:
422 	case TEE_TYPE_ECDH_KEYPAIR:
423 		s->ops = &ecc_keypair_ops;
424 		break;
425 	case TEE_TYPE_SM2_DSA_KEYPAIR:
426 		if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
427 			return TEE_ERROR_NOT_IMPLEMENTED;
428 
429 		s->curve = TEE_ECC_CURVE_SM2;
430 		s->ops = &sm2_dsa_keypair_ops;
431 		break;
432 	case TEE_TYPE_SM2_PKE_KEYPAIR:
433 		if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
434 			return TEE_ERROR_NOT_IMPLEMENTED;
435 
436 		s->curve = TEE_ECC_CURVE_SM2;
437 		s->ops = &sm2_pke_keypair_ops;
438 		break;
439 	case TEE_TYPE_SM2_KEP_KEYPAIR:
440 		if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
441 			return TEE_ERROR_NOT_IMPLEMENTED;
442 
443 		s->curve = TEE_ECC_CURVE_SM2;
444 		s->ops = &sm2_kep_keypair_ops;
445 		break;
446 	default:
447 		return TEE_ERROR_NOT_IMPLEMENTED;
448 	}
449 
450 	s->d = crypto_bignum_allocate(key_size_bits);
451 	if (!s->d)
452 		goto err;
453 	s->x = crypto_bignum_allocate(key_size_bits);
454 	if (!s->x)
455 		goto err;
456 	s->y = crypto_bignum_allocate(key_size_bits);
457 	if (!s->y)
458 		goto err;
459 
460 	return TEE_SUCCESS;
461 
462 err:
463 	crypto_bignum_free(s->d);
464 	crypto_bignum_free(s->x);
465 
466 	return TEE_ERROR_OUT_OF_MEMORY;
467 }
468 
469 static const struct crypto_ecc_public_ops ecc_public_key_ops = {
470 	.free = ecc_free_public_key,
471 	.verify = ecc_verify,
472 };
473 
474 static const struct crypto_ecc_public_ops sm2_pke_public_key_ops = {
475 	.free = ecc_free_public_key,
476 	.encrypt = sm2_mbedtls_pke_encrypt,
477 };
478 
479 static const struct crypto_ecc_public_ops sm2_kep_public_key_ops = {
480 	.free = ecc_free_public_key,
481 };
482 
483 static const struct crypto_ecc_public_ops sm2_dsa_public_key_ops = {
484 	.free = ecc_free_public_key,
485 	.verify = sm2_mbedtls_dsa_verify,
486 };
487 
488 TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s,
489 					    uint32_t key_type,
490 					    size_t key_size_bits)
491 {
492 	memset(s, 0, sizeof(*s));
493 
494 	switch (key_type) {
495 	case TEE_TYPE_ECDSA_PUBLIC_KEY:
496 	case TEE_TYPE_ECDH_PUBLIC_KEY:
497 		s->ops = &ecc_public_key_ops;
498 		break;
499 	case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
500 		if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
501 			return TEE_ERROR_NOT_IMPLEMENTED;
502 
503 		s->curve = TEE_ECC_CURVE_SM2;
504 		s->ops = &sm2_dsa_public_key_ops;
505 		break;
506 	case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
507 		if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
508 			return TEE_ERROR_NOT_IMPLEMENTED;
509 
510 		s->curve = TEE_ECC_CURVE_SM2;
511 		s->ops = &sm2_pke_public_key_ops;
512 		break;
513 	case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
514 		if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
515 			return TEE_ERROR_NOT_IMPLEMENTED;
516 
517 		s->curve = TEE_ECC_CURVE_SM2;
518 		s->ops = &sm2_kep_public_key_ops;
519 		break;
520 	default:
521 		return TEE_ERROR_NOT_IMPLEMENTED;
522 	}
523 
524 	s->x = crypto_bignum_allocate(key_size_bits);
525 	if (!s->x)
526 		goto err;
527 	s->y = crypto_bignum_allocate(key_size_bits);
528 	if (!s->y)
529 		goto err;
530 
531 	return TEE_SUCCESS;
532 
533 err:
534 	crypto_bignum_free(s->x);
535 
536 	return TEE_ERROR_OUT_OF_MEMORY;
537 }
538