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