1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #if !defined(MBEDTLS_ALLOW_PRIVATE_ACCESS)
8 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
9 #endif
10 
11 #ifdef ESP_PLATFORM
12 #include "esp_system.h"
13 #include "mbedtls/bignum.h"
14 #include "esp_config.h"
15 #endif
16 
17 #include "utils/includes.h"
18 #include "utils/common.h"
19 #include "crypto.h"
20 #include "sha256.h"
21 #include "random.h"
22 
23 #include "mbedtls/ecp.h"
24 #include "mbedtls/entropy.h"
25 #include "mbedtls/ctr_drbg.h"
26 
27 #include "mbedtls/pk.h"
28 #include "mbedtls/ecdh.h"
29 #include "mbedtls/sha256.h"
30 #include "mbedtls/asn1write.h"
31 #include "mbedtls/error.h"
32 #include "mbedtls/oid.h"
33 
34 #define ECP_PRV_DER_MAX_BYTES   29 + 3 * MBEDTLS_ECP_MAX_BYTES
35 
36 /* A context for random number generation (RNG). */
37 struct rng_context {
38 #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
39     unsigned char dummy;
40 #else /* MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
41     mbedtls_entropy_context entropy;
42 #if defined(MBEDTLS_CTR_DRBG_C)
43     mbedtls_ctr_drbg_context drbg;
44 #elif defined(MBEDTLS_HMAC_DRBG_C)
45     mbedtls_hmac_drbg_context drbg;
46 #else
47 #error "No DRBG available"
48 #endif
49 #endif /* MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
50 };
51 
52 #ifdef CONFIG_ECC
53 struct crypto_ec {
54 	mbedtls_ecp_group group;
55 };
56 
crypto_rng_wrapper(void * ctx,unsigned char * buf,size_t len)57 int crypto_rng_wrapper(void *ctx, unsigned char *buf, size_t len)
58 {
59 	return random_get_bytes(buf, len);
60 }
61 
crypto_ec_init(int group)62 struct crypto_ec *crypto_ec_init(int group)
63 {
64 	struct crypto_ec *e;
65 
66 	mbedtls_ecp_group_id  grp_id;
67 
68 	/* IANA registry to mbedtls internal mapping*/
69 	switch (group) {
70 		case IANA_SECP256R1:
71 			/* For now just support NIST-P256.
72 			 * This is of type "short Weierstrass".
73 			 */
74 			grp_id = MBEDTLS_ECP_DP_SECP256R1;
75 			break;
76 		default:
77 			return NULL;
78 
79 	}
80 	e = os_zalloc(sizeof(*e));
81 	if (e == NULL) {
82 		return NULL;
83 	}
84 
85 	mbedtls_ecp_group_init(&e->group);
86 
87 	if (mbedtls_ecp_group_load(&e->group, grp_id)) {
88 		crypto_ec_deinit(e);
89 		e = NULL;
90 	}
91 
92 	return e;
93 }
94 
95 
crypto_ec_deinit(struct crypto_ec * e)96 void crypto_ec_deinit(struct crypto_ec *e)
97 {
98 	if (e == NULL) {
99 		return;
100 	}
101 
102 	mbedtls_ecp_group_free(&e->group);
103 	os_free(e);
104 }
105 
106 
crypto_ec_point_init(struct crypto_ec * e)107 struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e)
108 {
109 	mbedtls_ecp_point *pt;
110 	if (e == NULL) {
111 		return NULL;
112 	}
113 
114 	pt = os_zalloc(sizeof(mbedtls_ecp_point));
115 
116 	if( pt == NULL) {
117 		return NULL;
118 	}
119 
120 	mbedtls_ecp_point_init(pt);
121 
122 	return (struct crypto_ec_point *) pt;
123 }
124 
125 
crypto_ec_prime_len(struct crypto_ec * e)126 size_t crypto_ec_prime_len(struct crypto_ec *e)
127 {
128 	return mbedtls_mpi_size(&e->group.P);
129 }
130 
131 
crypto_ec_prime_len_bits(struct crypto_ec * e)132 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
133 {
134 	return mbedtls_mpi_bitlen(&e->group.P);
135 }
crypto_ec_get_group_byname(const char * name)136 struct crypto_ec_group *crypto_ec_get_group_byname(const char *name)
137 {
138 	struct crypto_ec *e;
139 	const mbedtls_ecp_curve_info *curve = mbedtls_ecp_curve_info_from_name(name);
140 
141 	e = os_zalloc(sizeof(*e));
142 	if (e == NULL) {
143 		return NULL;
144 	}
145 
146 	mbedtls_ecp_group_init( &e->group );
147 
148 	if (mbedtls_ecp_group_load(&e->group, curve->grp_id)) {
149 		crypto_ec_deinit(e);
150 		e = NULL;
151 	}
152 
153 	return (struct crypto_ec_group *) &e->group;
154 }
155 
crypto_ec_get_prime(struct crypto_ec * e)156 const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e)
157 {
158 	return (const struct crypto_bignum *) &e->group.P;
159 }
160 
161 
crypto_ec_get_order(struct crypto_ec * e)162 const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e)
163 {
164 	return (const struct crypto_bignum *) &e->group.N;
165 }
166 
167 
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)168 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
169 {
170 	mbedtls_ecp_point_free((mbedtls_ecp_point *) p);
171 	os_free(p);
172 }
173 
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)174 int crypto_ec_point_to_bin(struct crypto_ec *e,
175 		const struct crypto_ec_point *point, u8 *x, u8 *y)
176 {
177 	int len = mbedtls_mpi_size(&e->group.P);
178 
179 	if (x) {
180 		if(crypto_bignum_to_bin((struct crypto_bignum *) & ((mbedtls_ecp_point *) point)->X,
181 					x, len, len) < 0) {
182 			return -1;
183 		}
184 
185 	}
186 
187 	if (y) {
188 		if(crypto_bignum_to_bin((struct crypto_bignum *) & ((mbedtls_ecp_point *) point)->Y,
189 					y, len, len) < 0) {
190 			return -1;
191 		}
192 	}
193 
194 	return 0;
195 }
196 
crypto_ec_get_affine_coordinates(struct crypto_ec * e,struct crypto_ec_point * pt,struct crypto_bignum * x,struct crypto_bignum * y)197 int crypto_ec_get_affine_coordinates(struct crypto_ec *e, struct crypto_ec_point *pt,
198 		struct crypto_bignum *x, struct crypto_bignum *y)
199 {
200 	int ret = -1;
201 	mbedtls_ecp_point *point = (mbedtls_ecp_point *)pt;
202 
203 	if (!mbedtls_ecp_is_zero(point)  && (mbedtls_mpi_cmp_int( &point->Z, 1 ) == 0 )) {
204 		// Affine coordinates mean that z should be 1,
205 		wpa_printf(MSG_ERROR, "Z coordinate is neither 0 or 1");
206 		return -1;
207 	}
208 
209 	if (x) {
210 		MBEDTLS_MPI_CHK(mbedtls_mpi_copy((mbedtls_mpi*) x, &((mbedtls_ecp_point* )point)->X));
211 	}
212 	if (y) {
213 		MBEDTLS_MPI_CHK(mbedtls_mpi_copy((mbedtls_mpi*) y, &((mbedtls_ecp_point* )point)->Y));
214 	}
215 	return 0;
216 cleanup:
217 	return ret;
218 }
219 
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)220 struct crypto_ec_point *crypto_ec_point_from_bin(struct crypto_ec *e,
221 		const u8 *val)
222 {
223 	mbedtls_ecp_point *pt;
224 	int len, ret;
225 
226 	if (e == NULL) {
227 		return NULL;
228 	}
229 
230 	len = mbedtls_mpi_size(&e->group.P);
231 
232 	pt = os_zalloc(sizeof(mbedtls_ecp_point));
233 	if (!pt) {
234 		return NULL;
235 	}
236 	mbedtls_ecp_point_init(pt);
237 
238 	MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->X, val, len));
239 	MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->Y, val + len, len));
240 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset((&pt->Z), 1));
241 
242 	return (struct crypto_ec_point *) pt;
243 
244 cleanup:
245 	mbedtls_ecp_point_free(pt);
246 	os_free(pt);
247 	return NULL;
248 }
249 
250 
crypto_ec_point_add(struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b,struct crypto_ec_point * c)251 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
252 		const struct crypto_ec_point *b,
253 		struct crypto_ec_point *c)
254 {
255 	int ret;
256 	mbedtls_mpi one;
257 
258 	mbedtls_mpi_init(&one);
259 
260 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset( &one, 1 ));
261 	MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(&e->group, (mbedtls_ecp_point *) c, &one, (const mbedtls_ecp_point *)a , &one, (const mbedtls_ecp_point *)b));
262 
263 cleanup:
264 	mbedtls_mpi_free(&one);
265 	return ret ? -1 : 0;
266 }
267 
268 
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)269 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
270 		const struct crypto_bignum *b,
271 		struct crypto_ec_point *res)
272 {
273 	int ret;
274 	mbedtls_entropy_context entropy;
275 	mbedtls_ctr_drbg_context ctr_drbg;
276 
277 	mbedtls_entropy_init(&entropy);
278 	mbedtls_ctr_drbg_init(&ctr_drbg);
279 
280 	MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
281 				NULL, 0));
282 
283 	MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&e->group,
284 				(mbedtls_ecp_point *) res,
285 				(const mbedtls_mpi *)b,
286 				(const mbedtls_ecp_point *)p,
287 				mbedtls_ctr_drbg_random,
288 				&ctr_drbg));
289 cleanup:
290 	mbedtls_ctr_drbg_free(&ctr_drbg);
291 	mbedtls_entropy_free(&entropy);
292 	return ret ? -1 : 0;
293 }
294 
295 
296 /*  Currently mbedtls does not have any function for inverse
297  *  This function calculates inverse of a point.
298  *  Set R = -P
299  */
ecp_opp(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point * P)300 static int ecp_opp(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P)
301 {
302 	int ret = 0;
303 
304 	/* Copy */
305 	if (R != P) {
306 		MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P));
307 	}
308 
309 	/* In-place opposite */
310 	if (mbedtls_mpi_cmp_int(&R->Y, 0) != 0) {
311 		MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&R->Y, &grp->P, &R->Y));
312 	}
313 
314 cleanup:
315 	return (ret );
316 }
317 
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)318 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
319 {
320 	return ecp_opp(&e->group, (mbedtls_ecp_point *) p, (mbedtls_ecp_point *) p) ? -1 : 0;
321 }
322 
crypto_ec_point_solve_y_coord(struct crypto_ec * e,struct crypto_ec_point * p,const struct crypto_bignum * x,int y_bit)323 int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
324 		struct crypto_ec_point *p,
325 		const struct crypto_bignum *x, int y_bit)
326 {
327 	mbedtls_mpi temp;
328 	mbedtls_mpi *y_sqr, *y;
329 	mbedtls_mpi_init(&temp);
330 	int ret = 0;
331 
332 	y = &((mbedtls_ecp_point *)p)->Y;
333 
334 	/* Faster way to find sqrt
335 	 * Works only with curves having prime p
336 	 * such that p ≡ 3 (mod 4)
337 	 *  y_ = (y2 ^ ((p+1)/4)) mod p
338 	 *
339 	 *  if LSB of both x and y are same: y = y_
340 	 *   else y = p - y_
341 	 * y_bit is LSB of x
342 	 */
343 	y_bit = (y_bit != 0);
344 
345 	y_sqr = (mbedtls_mpi *) crypto_ec_point_compute_y_sqr(e, x);
346 
347 	if (y_sqr) {
348 
349 		MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&temp, &e->group.P, 1));
350 		MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(&temp, NULL, &temp, 4));
351 		MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(y, y_sqr, &temp, &e->group.P, NULL));
352 
353 		if (y_bit != mbedtls_mpi_get_bit(y, 0))
354 			MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(y, &e->group.P, y));
355 
356 		MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&((mbedtls_ecp_point* )p)->X, (const mbedtls_mpi*) x));
357 		MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&((mbedtls_ecp_point *)p)->Z, 1));
358 	} else {
359 		ret = 1;
360 	}
361 cleanup:
362 	mbedtls_mpi_free(&temp);
363 	mbedtls_mpi_free(y_sqr);
364 	os_free(y_sqr);
365 	return ret ? -1 : 0;
366 }
367 
crypto_get_order(struct crypto_ec_group * group,struct crypto_bignum * x)368 int crypto_get_order(struct crypto_ec_group *group, struct crypto_bignum *x)
369 {
370 	return mbedtls_mpi_copy((mbedtls_mpi *) x, &((mbedtls_ecp_group *)group)->N);
371 }
372 
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)373 struct crypto_bignum *crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
374 		const struct crypto_bignum *x)
375 {
376 	mbedtls_mpi temp, temp2, num;
377 	int ret = 0;
378 
379 	mbedtls_mpi *y_sqr = os_zalloc(sizeof(mbedtls_mpi));
380 	if (y_sqr == NULL) {
381 		return NULL;
382 	}
383 
384 	mbedtls_mpi_init(&temp);
385 	mbedtls_mpi_init(&temp2);
386 	mbedtls_mpi_init(&num);
387 	mbedtls_mpi_init(y_sqr);
388 
389 	/* y^2 = x^3 + ax + b  mod  P*/
390 	/* mbedtls does not have mod-add or mod-mul apis.
391 	 *
392 	 */
393 
394 	/* Calculate x^3  mod P*/
395 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&num, 3));
396 	MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&temp, (const mbedtls_mpi *) x, &num, &e->group.P, NULL));
397 
398 	/* Calculate ax  mod P*/
399 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&num, -3));
400 	MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&temp2, (const mbedtls_mpi *) x, &num));
401 	MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp2, &temp2, &e->group.P));
402 
403 	/* Calculate ax + b  mod P. Note that b is already < P*/
404 	MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&temp2, &temp2, &e->group.B));
405 	MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp2, &temp2, &e->group.P));
406 
407 	/* Calculate x^3 + ax + b  mod P*/
408 	MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&temp2, &temp2, &temp));
409 	MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(y_sqr, &temp2, &e->group.P));
410 
411 cleanup:
412 	mbedtls_mpi_free(&temp);
413 	mbedtls_mpi_free(&temp2);
414 	mbedtls_mpi_free(&num);
415 	if (ret) {
416 		mbedtls_mpi_free(y_sqr);
417 		os_free(y_sqr);
418 		return NULL;
419 	} else {
420 		return (struct crypto_bignum *) y_sqr;
421 	}
422 }
423 
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)424 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
425 		const struct crypto_ec_point *p)
426 {
427 	return mbedtls_ecp_is_zero((mbedtls_ecp_point *) p);
428 }
429 
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)430 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
431 		const struct crypto_ec_point *p)
432 {
433 	mbedtls_mpi y_sqr_lhs, *y_sqr_rhs = NULL, two;
434 	int ret = 0, on_curve = 0;
435 
436 	mbedtls_mpi_init(&y_sqr_lhs);
437 	mbedtls_mpi_init(&two);
438 
439 	/* Calculate y^2  mod P*/
440 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&two, 2));
441 	MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&y_sqr_lhs, &((const mbedtls_ecp_point *)p)->Y , &two, &e->group.P, NULL));
442 
443 	y_sqr_rhs = (mbedtls_mpi *) crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *) & ((const mbedtls_ecp_point *)p)->X);
444 
445 	if (y_sqr_rhs && (mbedtls_mpi_cmp_mpi(y_sqr_rhs, &y_sqr_lhs) == 0)) {
446 		on_curve = 1;
447 	}
448 
449 cleanup:
450 	mbedtls_mpi_free(&y_sqr_lhs);
451 	mbedtls_mpi_free(&two);
452 	mbedtls_mpi_free(y_sqr_rhs);
453 	os_free(y_sqr_rhs);
454 	return (ret == 0) && (on_curve == 1);
455 }
456 
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)457 int crypto_ec_point_cmp(const struct crypto_ec *e,
458 		const struct crypto_ec_point *a,
459 		const struct crypto_ec_point *b)
460 {
461 	return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *) a,
462 			(const mbedtls_ecp_point *) b);
463 }
464 
rng_get(void * p_rng,unsigned char * output,size_t output_len)465 int rng_get( void *p_rng, unsigned char *output, size_t output_len )
466 {
467 #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
468     (void) p_rng;
469     return( mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
470                                     output, output_len ) );
471 #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
472     struct rng_context *rng = p_rng;
473 
474 #if defined(MBEDTLS_CTR_DRBG_C)
475     return( mbedtls_ctr_drbg_random( &rng->drbg, output, output_len ) );
476 #elif defined(MBEDTLS_HMAC_DRBG_C)
477     return( mbedtls_hmac_drbg_random( &rng->drbg, output, output_len ) );
478 #else
479 #error "No DRBG available"
480 #endif
481 
482 #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
483 }
484 
485 struct rng_context rng;
486 
crypto_key_compare(struct crypto_key * key1,struct crypto_key * key2)487 int crypto_key_compare(struct crypto_key *key1, struct crypto_key *key2)
488 {
489 	if (mbedtls_pk_check_pair((mbedtls_pk_context *)key1,
490 		(mbedtls_pk_context *)key2, rng_get, &rng) < 0)
491 		return 0;
492 
493 	return 1;
494 }
495 
crypto_debug_print_point(const char * title,struct crypto_ec * e,const struct crypto_ec_point * point)496 void crypto_debug_print_point(const char *title, struct crypto_ec *e,
497 		const struct crypto_ec_point *point)
498 {
499 	u8 x[32], y[32];
500 
501 	if (crypto_ec_point_to_bin(e, point, x, y) < 0) {
502 		wpa_printf(MSG_ERROR, "error: failed to get corrdinates\n");
503 		return;
504 	}
505 
506 	wpa_hexdump(MSG_ERROR, "x:", x, 32);
507 	wpa_hexdump(MSG_ERROR, "y:", y, 32);
508 }
509 
crypto_alloc_key(void)510 static struct crypto_key *crypto_alloc_key(void)
511 {
512 	mbedtls_pk_context *key = os_malloc(sizeof(*key));
513 
514 	if (!key) {
515 		wpa_printf(MSG_ERROR, "%s: memory allocation failed\n", __func__);
516 		return NULL;
517 	}
518 	mbedtls_pk_init(key);
519 
520 	return (struct crypto_key *)key;
521 }
522 
523 
crypto_ec_set_pubkey_point(const struct crypto_ec_group * group,const u8 * buf,size_t len)524 struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *group,
525 		const u8 *buf, size_t len)
526 {
527 	mbedtls_ecp_point *point = NULL;
528 	struct crypto_key *pkey = NULL;
529 	int ret;
530 	mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key();
531 
532 	if (!key) {
533 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
534 		return NULL;
535 	}
536 
537 	point = (mbedtls_ecp_point *)crypto_ec_point_from_bin((struct crypto_ec *)group, buf);
538 	if (!point) {
539 		wpa_printf(MSG_ERROR, "%s: Point initialization failed", __func__);
540 		goto fail;
541 	}
542 	if (crypto_ec_point_is_at_infinity((struct crypto_ec *)group, (struct crypto_ec_point *)point)) {
543 		wpa_printf(MSG_ERROR, "Point is at infinity");
544 		goto fail;
545 	}
546 	if (!crypto_ec_point_is_on_curve((struct crypto_ec *)group, (struct crypto_ec_point *)point)) {
547 		wpa_printf(MSG_ERROR, "Point not on curve");
548 		goto fail;
549 	}
550 
551 	if (mbedtls_ecp_check_pubkey((mbedtls_ecp_group *)group, point) < 0) { //typecast
552 		// ideally should have failed in upper condition, duplicate code??
553 		wpa_printf(MSG_ERROR, "Invalid key");
554 		goto fail;
555 	}
556 	/* Assign values */
557 	if( ( ret = mbedtls_pk_setup( key,
558 					mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ) ) != 0 )
559 		goto fail;
560 	mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->Q, point);
561 	mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->grp, MBEDTLS_ECP_DP_SECP256R1);
562 
563 	pkey = (struct crypto_key *)key;
564 	crypto_ec_point_deinit((struct crypto_ec_point *)point, 0);
565 	return pkey;
566 fail:
567 	if (point)
568 		crypto_ec_point_deinit((struct crypto_ec_point *)point, 0);
569 	if (key)
570 		mbedtls_pk_free(key);
571 	pkey = NULL;
572 	return pkey;
573 }
574 
575 
crypto_ec_free_key(struct crypto_key * key)576 void crypto_ec_free_key(struct crypto_key *key)
577 {
578 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
579 	mbedtls_pk_free(pkey);
580 	os_free(key);
581 }
582 
crypto_ec_get_public_key(struct crypto_key * key)583 struct crypto_ec_point *crypto_ec_get_public_key(struct crypto_key *key)
584 {
585 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
586 
587 	return (struct crypto_ec_point *)&mbedtls_pk_ec(*pkey)->Q;
588 }
589 
590 
crypto_ec_get_priv_key_der(struct crypto_key * key,unsigned char ** key_data,int * key_len)591 int crypto_ec_get_priv_key_der(struct crypto_key *key, unsigned char **key_data, int *key_len)
592 {
593 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
594 	char der_data[ECP_PRV_DER_MAX_BYTES];
595 
596 	*key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES);
597 	if (*key_len <= 0)
598 		return -1;
599 
600 	*key_data = os_malloc(*key_len);
601 
602 	if (!*key_data) {
603 		wpa_printf(MSG_ERROR, "memory allocation failed\n");
604 		return -1;
605 	}
606 	os_memcpy(*key_data, der_data, *key_len);
607 
608 	return 0;
609 }
610 
crypto_ec_get_group_from_key(struct crypto_key * key)611 struct crypto_ec_group *crypto_ec_get_group_from_key(struct crypto_key *key)
612 {
613 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
614 
615 	return (struct crypto_ec_group *)&(mbedtls_pk_ec(*pkey)->grp);
616 }
617 
crypto_ec_get_private_key(struct crypto_key * key)618 struct crypto_bignum *crypto_ec_get_private_key(struct crypto_key *key)
619 {
620 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
621 
622 	return ((struct crypto_bignum *)&(mbedtls_pk_ec(*pkey)->d));
623 }
624 
crypto_ec_get_publickey_buf(struct crypto_key * key,u8 * key_buf,int len)625 int crypto_ec_get_publickey_buf(struct crypto_key *key, u8 *key_buf, int len)
626 {
627 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
628 	unsigned char buf[MBEDTLS_MPI_MAX_SIZE + 10]; /* tag, length + MPI */
629 	unsigned char *c = buf + sizeof(buf );
630 	int pk_len = 0;
631 
632 	memset(buf, 0, sizeof(buf) );
633 	pk_len = mbedtls_pk_write_pubkey( &c, buf, pkey);
634 
635 	if (pk_len < 0)
636 		return -1;
637 
638 	if (len == 0)
639 		return pk_len;
640 
641 	os_memcpy(key_buf, buf + MBEDTLS_MPI_MAX_SIZE + 10 - pk_len, pk_len);
642 
643 	return pk_len;
644 }
645 
crypto_write_pubkey_der(struct crypto_key * key,unsigned char ** key_buf)646 int crypto_write_pubkey_der(struct crypto_key *key, unsigned char **key_buf)
647 {
648 	unsigned char output_buf[1600] = {0};
649 	int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600);
650 	if (len <= 0)
651 		return 0;
652 
653 	*key_buf = os_malloc(len);
654 	if (!*key_buf) {
655 		return 0;
656 	}
657 	os_memcpy(*key_buf, output_buf + 1600 - len, len);
658 
659 	return len;
660 }
661 
crypto_ec_get_key(const u8 * privkey,size_t privkey_len)662 struct crypto_key *crypto_ec_get_key(const u8 *privkey, size_t privkey_len)
663 {
664 	int ret;
665 	mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key();
666 
667 	if (!kctx) {
668 		wpa_printf(MSG_ERROR, "memory allocation failed\n");
669 		return NULL;
670 	}
671 	ret = mbedtls_pk_parse_key(kctx, privkey, privkey_len, NULL, 0, rng_get, &rng);
672 
673 	if (ret < 0) {
674 		//crypto_print_error_string(ret);
675 		goto fail;
676 	}
677 
678 	return (struct crypto_key *)kctx;
679 
680 fail:
681 	mbedtls_pk_free(kctx);
682 	os_free(kctx);
683 	return NULL;
684 }
685 
crypto_ec_get_mbedtls_to_nist_group_id(int id)686 unsigned int crypto_ec_get_mbedtls_to_nist_group_id(int id)
687 {
688 	unsigned int nist_grpid = 0;
689 	switch (id) {
690 		case MBEDTLS_ECP_DP_SECP256R1:
691 			nist_grpid = 19;
692 			break;
693 		case MBEDTLS_ECP_DP_SECP384R1:
694 			nist_grpid = 20;
695 			break;
696 		case MBEDTLS_ECP_DP_SECP521R1:
697 			nist_grpid = 21;
698 			break;
699 		case MBEDTLS_ECP_DP_BP256R1:
700 			nist_grpid = 28;
701 			break;
702 		case MBEDTLS_ECP_DP_BP384R1:
703 			nist_grpid = 29;
704 			break;
705 		case MBEDTLS_ECP_DP_BP512R1:
706 			nist_grpid = 30;
707 			break;
708 		default:
709 			break;
710 	}
711 
712 	return nist_grpid;
713 }
714 
crypto_ec_get_curve_id(const struct crypto_ec_group * group)715 int crypto_ec_get_curve_id(const struct crypto_ec_group *group)
716 {
717 	mbedtls_ecp_group *grp = (mbedtls_ecp_group *)group;
718 	return (crypto_ec_get_mbedtls_to_nist_group_id(grp->id));
719 }
720 
crypto_ecdh(struct crypto_key * key_own,struct crypto_key * key_peer,u8 * secret,size_t * secret_len)721 int crypto_ecdh(struct crypto_key *key_own, struct crypto_key *key_peer,
722 		u8 *secret, size_t *secret_len)
723 {
724 	mbedtls_ecdh_context *ctx;
725 	mbedtls_pk_context *own = (mbedtls_pk_context *)key_own;
726 	mbedtls_pk_context *peer = (mbedtls_pk_context *)key_peer;
727 
728 	int ret = -1;
729 
730 	*secret_len = 0;
731 	ctx = os_malloc(sizeof(*ctx));
732 	if (!ctx) {
733 		wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_CTX_new failed: %s",
734 				__func__);
735 		return -1;
736 	}
737 
738 	mbedtls_ecdh_init(ctx);
739 	/* No need to setup, done through mbedtls_ecdh_get_params */
740 
741 	/* set params from our key */
742 	if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*own), MBEDTLS_ECDH_OURS) < 0) {
743 		wpa_printf(MSG_ERROR, "failed to set our ecdh params\n");
744 		goto fail;
745 	}
746 
747 #ifndef DPP_MAX_SHARED_SECRET_LEN
748 #define DPP_MAX_SHARED_SECRET_LEN 66
749 #endif
750 	/* set params from peers key */
751 	if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*peer), MBEDTLS_ECDH_THEIRS) < 0) {
752 		wpa_printf(MSG_ERROR, "failed to set peer's ecdh params\n");
753 		goto fail;
754 	}
755 
756 	if (mbedtls_ecdh_calc_secret(ctx, secret_len, secret, DPP_MAX_SHARED_SECRET_LEN, NULL, NULL) < 0) {
757 		wpa_printf(MSG_ERROR, "failed to calculate secret\n");
758 		goto fail;
759 	}
760 
761 	if (*secret_len > DPP_MAX_SHARED_SECRET_LEN) {
762 		wpa_printf(MSG_ERROR, "secret len=%d is too big\n", *secret_len);
763 		goto fail;
764 	}
765 
766 	ret = 0;
767 
768 fail:
769 	mbedtls_ecdh_free(ctx);
770 	os_free(ctx);
771 	return ret;
772 }
773 
774 
crypto_ecdsa_get_sign(unsigned char * hash,const struct crypto_bignum * r,const struct crypto_bignum * s,struct crypto_key * csign,int hash_len)775 int crypto_ecdsa_get_sign(unsigned char *hash,
776 		const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_key *csign, int hash_len)
777 {
778 	int ret = -1;
779 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign;
780 
781 	mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx));
782 	if (!ctx) {
783 		wpa_printf(MSG_ERROR,"failed to allcate memory\n");
784 		return -1;
785 	}
786 	mbedtls_ecdsa_init(ctx);
787 
788 	if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0) {
789 		goto fail;
790 	}
791 	ret = mbedtls_ecdsa_sign(&ctx->grp, (mbedtls_mpi *)r, (mbedtls_mpi *)s,
792 			&ctx->d, hash, SHA256_MAC_LEN, crypto_rng_wrapper, NULL);
793 
794 fail:
795 	mbedtls_ecdsa_free(ctx);
796 	os_free(ctx);
797 
798 	return  ret;
799 }
800 
crypto_edcsa_sign_verify(const unsigned char * hash,const struct crypto_bignum * r,const struct crypto_bignum * s,struct crypto_key * csign,int hlen)801 int crypto_edcsa_sign_verify(const unsigned char *hash,
802 		const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_key *csign, int hlen)
803 {
804 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign;
805 	int ret = 0;
806 
807 	mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx));
808 	if (!ctx) {
809 		wpa_printf(MSG_ERROR, "failed to allcate memory\n");
810 		return ret;
811 	}
812 	mbedtls_ecdsa_init(ctx);
813 
814 	if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0)
815 		return ret;
816 
817 	if((ret = mbedtls_ecdsa_verify(&ctx->grp, hash, hlen,
818 					&ctx->Q, (mbedtls_mpi *)r, (mbedtls_mpi *)s)) != 0){
819 		wpa_printf(MSG_ERROR, "ecdsa verification failed\n");
820 		return ret;
821 	}
822 
823 	mbedtls_ecdsa_free(ctx);
824 	os_free(ctx);
825 
826 	return ret;
827 }
828 
crypto_debug_print_ec_key(const char * title,struct crypto_key * key)829 void crypto_debug_print_ec_key(const char *title, struct crypto_key *key)
830 {
831 #ifdef DEBUG_PRINT
832 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
833 	mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pkey );
834 	u8 x[32], y[32], d[32];
835 	wpa_printf(MSG_ERROR, "curve: %s\n",
836 			mbedtls_ecp_curve_info_from_grp_id( ecp->grp.id )->name );
837 	int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key)));
838 
839 	wpa_printf(MSG_ERROR, "prime len is %d\n", len);
840 	crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_get_public_key(key), x, y);
841 	crypto_bignum_to_bin(crypto_ec_get_private_key(key),
842 			d, len, len);
843 	wpa_hexdump(MSG_ERROR, "Q_x:", x, 32);
844 	wpa_hexdump(MSG_ERROR, "Q_y:", y, 32);
845 	wpa_hexdump(MSG_ERROR, "d:     ",  d , 32);
846 #endif
847 }
848 
crypto_ec_parse_subpub_key(const unsigned char * p,size_t len)849 struct crypto_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t len)
850 {
851 	int ret;
852 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)crypto_alloc_key();
853 	ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey);
854 
855 	if (ret < 0) {
856 		os_free(pkey);
857 		return NULL;
858 	}
859 
860 	return (struct crypto_key *)pkey;
861 }
862 
crypto_is_ec_key(struct crypto_key * key)863 int crypto_is_ec_key(struct crypto_key *key)
864 {
865 	int ret = mbedtls_pk_can_do((mbedtls_pk_context *)key, MBEDTLS_PK_ECKEY);
866 	return  ret;
867 }
868 
crypto_ec_gen_keypair(u16 ike_group)869 struct crypto_key * crypto_ec_gen_keypair(u16 ike_group)
870 {
871 	mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key();
872 
873 	if (!kctx) {
874 		wpa_printf(MSG_ERROR, "%s: memory allocation failed\n", __func__);
875 		return NULL;
876 	}
877 
878 	if(mbedtls_pk_setup(kctx,
879 				mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) != 0 )
880 		goto fail;
881 
882 	mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*kctx), //get this from argument
883 			crypto_rng_wrapper, NULL);
884 
885 	return (struct crypto_key *)kctx;
886 fail:
887 	mbedtls_pk_free(kctx);
888 	os_free(kctx);
889 	return NULL;
890 }
891 
892 /*
893  * ECParameters ::= CHOICE {
894  *   namedCurve         OBJECT IDENTIFIER
895  * }
896  */
pk_write_ec_param(unsigned char ** p,unsigned char * start,mbedtls_ecp_keypair * ec)897 static int pk_write_ec_param( unsigned char **p, unsigned char *start,
898 		mbedtls_ecp_keypair *ec )
899 {
900 	int ret;
901 	size_t len = 0;
902 	const char *oid;
903 	size_t oid_len;
904 
905 	if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
906 		return( ret );
907 
908 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
909 
910 	return( (int) len );
911 }
912 
pk_write_ec_pubkey_formatted(unsigned char ** p,unsigned char * start,mbedtls_ecp_keypair * ec,int format)913 static int pk_write_ec_pubkey_formatted( unsigned char **p, unsigned char *start,
914 		mbedtls_ecp_keypair *ec, int format )
915 {
916 	int ret;
917 	size_t len = 0;
918 	unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
919 
920 	if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
921 					format,
922 					&len, buf, sizeof( buf ) ) ) != 0 )
923 	{
924 		return( ret );
925 	}
926 
927 	if( *p < start || (size_t)( *p - start ) < len )
928 		return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
929 
930 	*p -= len;
931 	memcpy( *p, buf, len );
932 
933 	return( (int) len );
934 }
935 
mbedtls_pk_write_pubkey_formatted(unsigned char ** p,unsigned char * start,const mbedtls_pk_context * key,int format)936 int mbedtls_pk_write_pubkey_formatted( unsigned char **p, unsigned char *start,
937 		const mbedtls_pk_context *key, int format )
938 {
939 	int ret;
940 	size_t len = 0;
941 
942 	if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
943 		MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey_formatted( p, start, mbedtls_pk_ec( *key ), format ) );
944 	else
945 		return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
946 
947 	return( (int) len );
948 }
949 
crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context * key,unsigned char * buf,size_t size,int format)950 int crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context *key, unsigned char *buf, size_t size, int format)
951 {
952 	int ret;
953 	unsigned char *c;
954 	size_t len = 0, par_len = 0, oid_len;
955 	const char *oid;
956 
957 	if( size == 0 )
958 		return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
959 
960 	c = buf + size;
961 
962 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey_formatted( &c, buf, key, format) );
963 
964 	if( c - buf < 1 )
965 		return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
966 
967 	/*
968 	 *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
969 	 *       algorithm            AlgorithmIdentifier,
970 	 *       subjectPublicKey     BIT STRING }
971 	 */
972 	*--c = 0;
973 	len += 1;
974 
975 
976 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
977 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
978 
979 	if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
980 					&oid, &oid_len ) ) != 0 )
981 	{
982 		return( ret );
983 	}
984 
985 	if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
986 	{
987 		MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
988 	}
989 
990 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
991 				par_len ) );
992 
993 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
994 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
995 				MBEDTLS_ASN1_SEQUENCE ) );
996 
997 	return( (int) len );
998 }
999 
crypto_ec_write_pub_key(struct crypto_key * key,unsigned char ** key_buf)1000 int crypto_ec_write_pub_key(struct crypto_key *key, unsigned char **key_buf)
1001 {
1002 	unsigned char output_buf[1600] = {0};
1003 	int len = crypto_pk_write_formatted_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600, 1);
1004 	if (len <= 0)
1005 		return 0;
1006 
1007 	*key_buf = os_malloc(len);
1008 	if (!*key_buf) {
1009 		wpa_printf(MSG_ERROR, "%s: memory allocation failed\n", __func__);
1010 		return 0;
1011 	}
1012 	os_memcpy(*key_buf, output_buf + 1600 - len, len);
1013 
1014 	return len;
1015 }
1016 #endif /* CONFIG_ECC */
1017