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