1 /*
2  * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifdef ESP_PLATFORM
8 #include "esp_system.h"
9 #include "mbedtls/bignum.h"
10 #endif
11 
12 #include "utils/includes.h"
13 #include "utils/common.h"
14 #include "crypto.h"
15 #include "sha256.h"
16 #include "random.h"
17 
18 #include "mbedtls/ecp.h"
19 #include "mbedtls/entropy.h"
20 #include "mbedtls/ctr_drbg.h"
21 
22 #include "mbedtls/pk.h"
23 #include "mbedtls/ecdh.h"
24 #include "mbedtls/sha256.h"
25 #include "mbedtls/asn1write.h"
26 #include "mbedtls/error.h"
27 #include "mbedtls/oid.h"
28 
29 #define ECP_PRV_DER_MAX_BYTES   29 + 3 * MBEDTLS_ECP_MAX_BYTES
30 
31 #ifdef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT
32 #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(var)
33 #else
34 #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(mbed_ecdh).MBEDTLS_PRIVATE(var)
35 #endif
36 
37 #ifdef CONFIG_ECC
38 struct crypto_ec {
39 	mbedtls_ecp_group group;
40 };
41 
crypto_rng_wrapper(void * ctx,unsigned char * buf,size_t len)42 static int crypto_rng_wrapper(void *ctx, unsigned char *buf, size_t len)
43 {
44 	return random_get_bytes(buf, len);
45 }
46 
crypto_ec_init(int group)47 struct crypto_ec *crypto_ec_init(int group)
48 {
49 	struct crypto_ec *e;
50 
51 	mbedtls_ecp_group_id  grp_id;
52 
53 	/* IANA registry to mbedtls internal mapping*/
54 	switch (group) {
55 		case IANA_SECP256R1:
56 			/* For now just support NIST-P256.
57 			 * This is of type "short Weierstrass".
58 			 */
59 			grp_id = MBEDTLS_ECP_DP_SECP256R1;
60 			break;
61 		default:
62 			return NULL;
63 
64 	}
65 	e = os_zalloc(sizeof(*e));
66 	if (e == NULL) {
67 		return NULL;
68 	}
69 
70 	mbedtls_ecp_group_init(&e->group);
71 
72 	if (mbedtls_ecp_group_load(&e->group, grp_id)) {
73 		crypto_ec_deinit(e);
74 		e = NULL;
75 	}
76 
77 	return e;
78 }
79 
80 
crypto_ec_deinit(struct crypto_ec * e)81 void crypto_ec_deinit(struct crypto_ec *e)
82 {
83 	if (e == NULL) {
84 		return;
85 	}
86 
87 	mbedtls_ecp_group_free(&e->group);
88 	os_free(e);
89 }
90 
91 
crypto_ec_point_init(struct crypto_ec * e)92 struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e)
93 {
94 	mbedtls_ecp_point *pt;
95 	if (e == NULL) {
96 		return NULL;
97 	}
98 
99 	pt = os_zalloc(sizeof(mbedtls_ecp_point));
100 
101 	if( pt == NULL) {
102 		return NULL;
103 	}
104 
105 	mbedtls_ecp_point_init(pt);
106 
107 	return (struct crypto_ec_point *) pt;
108 }
109 
110 
crypto_ec_prime_len(struct crypto_ec * e)111 size_t crypto_ec_prime_len(struct crypto_ec *e)
112 {
113 	return mbedtls_mpi_size(&e->group.P);
114 }
115 
crypto_ec_order_len(struct crypto_ec * e)116 size_t crypto_ec_order_len(struct crypto_ec *e)
117 {
118 	return mbedtls_mpi_size(&e->group.N);
119 }
120 
121 
crypto_ec_prime_len_bits(struct crypto_ec * e)122 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
123 {
124 	return mbedtls_mpi_bitlen(&e->group.P);
125 }
crypto_ec_get_group_byname(const char * name)126 struct crypto_ec_group *crypto_ec_get_group_byname(const char *name)
127 {
128 	struct crypto_ec *e;
129 	const mbedtls_ecp_curve_info *curve = mbedtls_ecp_curve_info_from_name(name);
130 
131 	e = os_zalloc(sizeof(*e));
132 	if (e == NULL) {
133 		return NULL;
134 	}
135 
136 	mbedtls_ecp_group_init( &e->group );
137 
138 	if (mbedtls_ecp_group_load(&e->group, curve->grp_id)) {
139 		crypto_ec_deinit(e);
140 		e = NULL;
141 	}
142 
143 	return (struct crypto_ec_group *) &e->group;
144 }
145 
crypto_ec_get_prime(struct crypto_ec * e)146 const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e)
147 {
148 	return (const struct crypto_bignum *) &e->group.P;
149 }
150 
151 
crypto_ec_get_order(struct crypto_ec * e)152 const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e)
153 {
154 	return (const struct crypto_bignum *) &e->group.N;
155 }
156 
157 
crypto_ec_get_b(struct crypto_ec * e)158 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
159 {
160 	return (const struct crypto_bignum *) &e->group.B;
161 }
162 
163 
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)164 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
165 {
166 	mbedtls_ecp_point_free((mbedtls_ecp_point *) p);
167 	os_free(p);
168 }
169 
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)170 int crypto_ec_point_to_bin(struct crypto_ec *e,
171 		const struct crypto_ec_point *point, u8 *x, u8 *y)
172 {
173 	int len = mbedtls_mpi_size(&e->group.P);
174 
175 	if (x) {
176 		if(crypto_bignum_to_bin((struct crypto_bignum *) & ((mbedtls_ecp_point *) point)->MBEDTLS_PRIVATE(X),
177 					x, len, len) < 0) {
178 			return -1;
179 		}
180 
181 	}
182 
183 	if (y) {
184 		if(crypto_bignum_to_bin((struct crypto_bignum *) & ((mbedtls_ecp_point *) point)->MBEDTLS_PRIVATE(Y),
185 					y, len, len) < 0) {
186 			return -1;
187 		}
188 	}
189 
190 	return 0;
191 }
192 
crypto_ec_get_affine_coordinates(struct crypto_ec * e,struct crypto_ec_point * pt,struct crypto_bignum * x,struct crypto_bignum * y)193 int crypto_ec_get_affine_coordinates(struct crypto_ec *e, struct crypto_ec_point *pt,
194 		struct crypto_bignum *x, struct crypto_bignum *y)
195 {
196 	int ret = -1;
197 	mbedtls_ecp_point *point = (mbedtls_ecp_point *)pt;
198 
199 	if (!mbedtls_ecp_is_zero(point)  && (mbedtls_mpi_cmp_int( &point->MBEDTLS_PRIVATE(Z), 1 ) == 0 )) {
200 		// Affine coordinates mean that z should be 1,
201 		wpa_printf(MSG_ERROR, "Z coordinate is neither 0 or 1");
202 		return -1;
203 	}
204 
205 	if (x) {
206 		MBEDTLS_MPI_CHK(mbedtls_mpi_copy((mbedtls_mpi*) x, &((mbedtls_ecp_point* )point)->MBEDTLS_PRIVATE(X)));
207 	}
208 	if (y) {
209 		MBEDTLS_MPI_CHK(mbedtls_mpi_copy((mbedtls_mpi*) y, &((mbedtls_ecp_point* )point)->MBEDTLS_PRIVATE(Y)));
210 	}
211 	return 0;
212 cleanup:
213 	return ret;
214 }
215 
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)216 struct crypto_ec_point *crypto_ec_point_from_bin(struct crypto_ec *e,
217 		const u8 *val)
218 {
219 	mbedtls_ecp_point *pt;
220 	int len, ret;
221 
222 	if (e == NULL) {
223 		return NULL;
224 	}
225 
226 	len = mbedtls_mpi_size(&e->group.P);
227 
228 	pt = os_zalloc(sizeof(mbedtls_ecp_point));
229 	if (!pt) {
230 		return NULL;
231 	}
232 	mbedtls_ecp_point_init(pt);
233 
234 	MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->MBEDTLS_PRIVATE(X), val, len));
235 	MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->MBEDTLS_PRIVATE(Y), val + len, len));
236 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset((&pt->MBEDTLS_PRIVATE(Z)), 1));
237 
238 	return (struct crypto_ec_point *) pt;
239 
240 cleanup:
241 	mbedtls_ecp_point_free(pt);
242 	os_free(pt);
243 	return NULL;
244 }
245 
246 
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)247 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
248 		const struct crypto_ec_point *b,
249 		struct crypto_ec_point *c)
250 {
251 	int ret;
252 	mbedtls_mpi one;
253 
254 	mbedtls_mpi_init(&one);
255 
256 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset( &one, 1 ));
257 	MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(&e->group, (mbedtls_ecp_point *) c, &one, (const mbedtls_ecp_point *)a , &one, (const mbedtls_ecp_point *)b));
258 
259 cleanup:
260 	mbedtls_mpi_free(&one);
261 	return ret ? -1 : 0;
262 }
263 
264 
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)265 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
266 		const struct crypto_bignum *b,
267 		struct crypto_ec_point *res)
268 {
269 	int ret;
270 	mbedtls_entropy_context entropy;
271 	mbedtls_ctr_drbg_context ctr_drbg;
272 
273 	mbedtls_entropy_init(&entropy);
274 	mbedtls_ctr_drbg_init(&ctr_drbg);
275 
276 	MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
277 				NULL, 0));
278 
279 	MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&e->group,
280 				(mbedtls_ecp_point *) res,
281 				(const mbedtls_mpi *)b,
282 				(const mbedtls_ecp_point *)p,
283 				mbedtls_ctr_drbg_random,
284 				&ctr_drbg));
285 cleanup:
286 	mbedtls_ctr_drbg_free(&ctr_drbg);
287 	mbedtls_entropy_free(&entropy);
288 	return ret ? -1 : 0;
289 }
290 
291 
292 /*  Currently mbedtls does not have any function for inverse
293  *  This function calculates inverse of a point.
294  *  Set R = -P
295  */
ecp_opp(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_ecp_point * P)296 static int ecp_opp(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P)
297 {
298 	int ret = 0;
299 
300 	/* Copy */
301 	if (R != P) {
302 		MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P));
303 	}
304 
305 	/* In-place opposite */
306 	if (mbedtls_mpi_cmp_int(&R->MBEDTLS_PRIVATE(Y), 0) != 0) {
307 		MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&R->MBEDTLS_PRIVATE(Y), &grp->P, &R->MBEDTLS_PRIVATE(Y)));
308 	}
309 
310 cleanup:
311 	return (ret );
312 }
313 
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)314 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
315 {
316 	return ecp_opp(&e->group, (mbedtls_ecp_point *) p, (mbedtls_ecp_point *) p) ? -1 : 0;
317 }
318 
crypto_ec_point_solve_y_coord(struct crypto_ec * e,struct crypto_ec_point * p,const struct crypto_bignum * x,int y_bit)319 int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
320 		struct crypto_ec_point *p,
321 		const struct crypto_bignum *x, int y_bit)
322 {
323 	mbedtls_mpi temp;
324 	mbedtls_mpi *y_sqr, *y;
325 	mbedtls_mpi_init(&temp);
326 	int ret = 0;
327 
328 	y = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y);
329 
330 	/* Faster way to find sqrt
331 	 * Works only with curves having prime p
332 	 * such that p ≡ 3 (mod 4)
333 	 *  y_ = (y2 ^ ((p+1)/4)) mod p
334 	 *
335 	 *  if LSB of both x and y are same: y = y_
336 	 *   else y = p - y_
337 	 * y_bit is LSB of x
338 	 */
339 	y_bit = (y_bit != 0);
340 
341 	y_sqr = (mbedtls_mpi *) crypto_ec_point_compute_y_sqr(e, x);
342 
343 	if (y_sqr) {
344 
345 		MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&temp, &e->group.P, 1));
346 		MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(&temp, NULL, &temp, 4));
347 		MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(y, y_sqr, &temp, &e->group.P, NULL));
348 
349 		if (y_bit != mbedtls_mpi_get_bit(y, 0))
350 			MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(y, &e->group.P, y));
351 
352 		MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&((mbedtls_ecp_point* )p)->MBEDTLS_PRIVATE(X), (const mbedtls_mpi*) x));
353 		MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z), 1));
354 	} else {
355 		ret = 1;
356 	}
357 cleanup:
358 	mbedtls_mpi_free(&temp);
359 	mbedtls_mpi_free(y_sqr);
360 	os_free(y_sqr);
361 	return ret ? -1 : 0;
362 }
363 
crypto_get_order(struct crypto_ec_group * group,struct crypto_bignum * x)364 int crypto_get_order(struct crypto_ec_group *group, struct crypto_bignum *x)
365 {
366 	return mbedtls_mpi_copy((mbedtls_mpi *) x, &((mbedtls_ecp_group *)group)->N);
367 }
368 
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)369 struct crypto_bignum *crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
370 		const struct crypto_bignum *x)
371 {
372 	mbedtls_mpi temp, temp2, num;
373 	int ret = 0;
374 
375 	mbedtls_mpi *y_sqr = os_zalloc(sizeof(mbedtls_mpi));
376 	if (y_sqr == NULL) {
377 		return NULL;
378 	}
379 
380 	mbedtls_mpi_init(&temp);
381 	mbedtls_mpi_init(&temp2);
382 	mbedtls_mpi_init(&num);
383 	mbedtls_mpi_init(y_sqr);
384 
385 	/* y^2 = x^3 + ax + b  mod  P */
386 	/* X*X*X is faster on esp32 whereas X^3 is faster on other chips */
387 #if CONFIG_IDF_TARGET_ESP32
388 	/* Calculate x*x*x  mod P*/
389 	MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&temp, (const mbedtls_mpi *) x, (const mbedtls_mpi *) x));
390 	MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&temp, &temp, (const mbedtls_mpi *) x));
391 	MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp, &temp, &e->group.P));
392 #else
393 	/* Calculate x^3  mod P*/
394 	MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&num, 3));
395 	MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&temp, (const mbedtls_mpi *) x, &num, &e->group.P, NULL));
396 #endif
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)->MBEDTLS_PRIVATE(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)->MBEDTLS_PRIVATE(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 
crypto_key_compare(struct crypto_key * key1,struct crypto_key * key2)465 int crypto_key_compare(struct crypto_key *key1, struct crypto_key *key2)
466 {
467 	int ret = 0;
468 	mbedtls_entropy_context entropy;
469 	mbedtls_ctr_drbg_context ctr_drbg;
470 
471 	mbedtls_entropy_init(&entropy);
472 	mbedtls_ctr_drbg_init(&ctr_drbg);
473 
474 	MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0));
475 	if (mbedtls_pk_check_pair((mbedtls_pk_context *)key1, (mbedtls_pk_context *)key2, mbedtls_ctr_drbg_random, &ctr_drbg) < 0) {
476 		goto cleanup;
477 	}
478 
479 	ret = 1;
480 cleanup:
481 	mbedtls_ctr_drbg_free(&ctr_drbg);
482 	mbedtls_entropy_free(&entropy);
483 	return ret;
484 }
485 
crypto_debug_print_point(const char * title,struct crypto_ec * e,const struct crypto_ec_point * point)486 void crypto_debug_print_point(const char *title, struct crypto_ec *e,
487 		const struct crypto_ec_point *point)
488 {
489 	u8 x[32], y[32];
490 
491 	if (crypto_ec_point_to_bin(e, point, x, y) < 0) {
492 		wpa_printf(MSG_ERROR, "error: failed to get corrdinates");
493 		return;
494 	}
495 
496 	wpa_hexdump(MSG_ERROR, "x:", x, 32);
497 	wpa_hexdump(MSG_ERROR, "y:", y, 32);
498 }
499 
crypto_alloc_key(void)500 static struct crypto_key *crypto_alloc_key(void)
501 {
502 	mbedtls_pk_context *key = os_malloc(sizeof(*key));
503 
504 	if (!key) {
505 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
506 		return NULL;
507 	}
508 	mbedtls_pk_init(key);
509 
510 	return (struct crypto_key *)key;
511 }
512 
513 
crypto_ec_set_pubkey_point(const struct crypto_ec_group * group,const u8 * buf,size_t len)514 struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *group,
515 		const u8 *buf, size_t len)
516 {
517 	mbedtls_ecp_point *point = NULL;
518 	struct crypto_key *pkey = NULL;
519 	int ret;
520 	mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key();
521 
522 	if (!key) {
523 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
524 		return NULL;
525 	}
526 
527 	point = (mbedtls_ecp_point *)crypto_ec_point_from_bin((struct crypto_ec *)group, buf);
528 	if (!point) {
529 		wpa_printf(MSG_ERROR, "%s: Point initialization failed", __func__);
530 		goto fail;
531 	}
532 	if (crypto_ec_point_is_at_infinity((struct crypto_ec *)group, (struct crypto_ec_point *)point)) {
533 		wpa_printf(MSG_ERROR, "Point is at infinity");
534 		goto fail;
535 	}
536 	if (!crypto_ec_point_is_on_curve((struct crypto_ec *)group, (struct crypto_ec_point *)point)) {
537 		wpa_printf(MSG_ERROR, "Point not on curve");
538 		goto fail;
539 	}
540 
541 	if (mbedtls_ecp_check_pubkey((mbedtls_ecp_group *)group, point) < 0) { //typecast
542 		// ideally should have failed in upper condition, duplicate code??
543 		wpa_printf(MSG_ERROR, "Invalid key");
544 		goto fail;
545 	}
546 	/* Assign values */
547 	if( ( ret = mbedtls_pk_setup( key,
548 					mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ) ) != 0 )
549 		goto fail;
550 	mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(Q), point);
551 	mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
552 
553 	pkey = (struct crypto_key *)key;
554 	crypto_ec_point_deinit((struct crypto_ec_point *)point, 0);
555 	return pkey;
556 fail:
557 	if (point)
558 		crypto_ec_point_deinit((struct crypto_ec_point *)point, 0);
559 	if (key)
560 		mbedtls_pk_free(key);
561 	pkey = NULL;
562 	return pkey;
563 }
564 
565 
crypto_ec_free_key(struct crypto_key * key)566 void crypto_ec_free_key(struct crypto_key *key)
567 {
568 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
569 	mbedtls_pk_free(pkey);
570 	os_free(key);
571 }
572 
crypto_ec_get_public_key(struct crypto_key * key)573 struct crypto_ec_point *crypto_ec_get_public_key(struct crypto_key *key)
574 {
575 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
576 
577 	return (struct crypto_ec_point *)&mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(Q);
578 }
579 
580 
crypto_ec_get_priv_key_der(struct crypto_key * key,unsigned char ** key_data,int * key_len)581 int crypto_ec_get_priv_key_der(struct crypto_key *key, unsigned char **key_data, int *key_len)
582 {
583 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
584 	char der_data[ECP_PRV_DER_MAX_BYTES];
585 
586 	*key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES);
587 	if (*key_len <= 0)
588 		return -1;
589 
590 	*key_data = os_malloc(*key_len);
591 
592 	if (!*key_data) {
593 		wpa_printf(MSG_ERROR, "memory allocation failed");
594 		return -1;
595 	}
596 	os_memcpy(*key_data, der_data, *key_len);
597 
598 	return 0;
599 }
600 
crypto_ec_get_group_from_key(struct crypto_key * key)601 struct crypto_ec_group *crypto_ec_get_group_from_key(struct crypto_key *key)
602 {
603 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
604 
605 	return (struct crypto_ec_group *)&(mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp));
606 }
607 
crypto_ec_key_group(struct crypto_ec_key * key)608 int crypto_ec_key_group(struct crypto_ec_key *key)
609 {
610 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
611 
612 	int iana_group = (int)crypto_ec_get_mbedtls_to_nist_group_id(mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp).id);
613 	return iana_group;
614 }
615 
crypto_ec_get_private_key(struct crypto_key * key)616 struct crypto_bignum *crypto_ec_get_private_key(struct crypto_key *key)
617 {
618 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
619 
620 	return ((struct crypto_bignum *)&(mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(d)));
621 }
622 
crypto_ec_get_publickey_buf(struct crypto_key * key,u8 * key_buf,int len)623 int crypto_ec_get_publickey_buf(struct crypto_key *key, u8 *key_buf, int len)
624 {
625 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
626 	unsigned char buf[MBEDTLS_MPI_MAX_SIZE + 10]; /* tag, length + MPI */
627 	unsigned char *c = buf + sizeof(buf );
628 	int pk_len = 0;
629 
630 	memset(buf, 0, sizeof(buf) );
631 	pk_len = mbedtls_pk_write_pubkey( &c, buf, pkey);
632 
633 	if (pk_len < 0)
634 		return -1;
635 
636 	if (len == 0)
637 		return pk_len;
638 
639 	os_memcpy(key_buf, buf + MBEDTLS_MPI_MAX_SIZE + 10 - pk_len, pk_len);
640 
641 	return pk_len;
642 }
643 
crypto_write_pubkey_der(struct crypto_key * key,unsigned char ** key_buf)644 int crypto_write_pubkey_der(struct crypto_key *key, unsigned char **key_buf)
645 {
646 	unsigned char output_buf[1600] = {0};
647 	int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600);
648 	if (len <= 0)
649 		return 0;
650 
651 	*key_buf = os_malloc(len);
652 	if (!*key_buf) {
653 		return 0;
654 	}
655 	os_memcpy(*key_buf, output_buf + 1600 - len, len);
656 
657 	return len;
658 }
659 
crypto_ec_get_key(const u8 * privkey,size_t privkey_len)660 struct crypto_key *crypto_ec_get_key(const u8 *privkey, size_t privkey_len)
661 {
662 	int ret;
663 	mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key();
664 
665 	if (!kctx) {
666 		wpa_printf(MSG_ERROR, "memory allocation failed");
667 		return NULL;
668 	}
669 	ret = mbedtls_pk_parse_key(kctx, privkey, privkey_len, NULL, 0, crypto_rng_wrapper, NULL);
670 
671 	if (ret < 0) {
672 		//crypto_print_error_string(ret);
673 		goto fail;
674 	}
675 
676 	return (struct crypto_key *)kctx;
677 
678 fail:
679 	mbedtls_pk_free(kctx);
680 	os_free(kctx);
681 	return NULL;
682 }
683 
crypto_ec_get_mbedtls_to_nist_group_id(int id)684 unsigned int crypto_ec_get_mbedtls_to_nist_group_id(int id)
685 {
686 	unsigned int nist_grpid = 0;
687 	switch (id) {
688 		case MBEDTLS_ECP_DP_SECP256R1:
689 			nist_grpid = 19;
690 			break;
691 		case MBEDTLS_ECP_DP_SECP384R1:
692 			nist_grpid = 20;
693 			break;
694 		case MBEDTLS_ECP_DP_SECP521R1:
695 			nist_grpid = 21;
696 			break;
697 		case MBEDTLS_ECP_DP_BP256R1:
698 			nist_grpid = 28;
699 			break;
700 		case MBEDTLS_ECP_DP_BP384R1:
701 			nist_grpid = 29;
702 			break;
703 		case MBEDTLS_ECP_DP_BP512R1:
704 			nist_grpid = 30;
705 			break;
706 		default:
707 			break;
708 	}
709 
710 	return nist_grpid;
711 }
712 
crypto_ec_get_curve_id(const struct crypto_ec_group * group)713 int crypto_ec_get_curve_id(const struct crypto_ec_group *group)
714 {
715 	mbedtls_ecp_group *grp = (mbedtls_ecp_group *)group;
716 	return (crypto_ec_get_mbedtls_to_nist_group_id(grp->id));
717 }
718 
crypto_ecdh(struct crypto_key * key_own,struct crypto_key * key_peer,u8 * secret,size_t * secret_len)719 int crypto_ecdh(struct crypto_key *key_own, struct crypto_key *key_peer,
720 		u8 *secret, size_t *secret_len)
721 {
722 	mbedtls_ecdh_context *ctx = NULL;
723 	mbedtls_pk_context *own = (mbedtls_pk_context *)key_own;
724 	mbedtls_pk_context *peer = (mbedtls_pk_context *)key_peer;
725 	mbedtls_entropy_context entropy;
726 	mbedtls_ctr_drbg_context ctr_drbg;
727 	int ret = -1;
728 
729 	mbedtls_entropy_init(&entropy);
730 	mbedtls_ctr_drbg_init(&ctr_drbg);
731 
732 	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) < 0) {
733 		goto fail;
734 	}
735 
736 	*secret_len = 0;
737 	ctx = os_malloc(sizeof(*ctx));
738 	if (!ctx) {
739 		wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_CTX_new failed: %s",
740 				__func__);
741 		goto fail;
742 	}
743 
744 	mbedtls_ecdh_init(ctx);
745 	/* No need to setup, done through mbedtls_ecdh_get_params */
746 
747 	/* set params from our key */
748 	if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*own), MBEDTLS_ECDH_OURS) < 0) {
749 		wpa_printf(MSG_ERROR, "failed to set our ecdh params");
750 		goto fail;
751 	}
752 
753 #ifndef DPP_MAX_SHARED_SECRET_LEN
754 #define DPP_MAX_SHARED_SECRET_LEN 66
755 #endif
756 	/* set params from peers key */
757 	if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*peer), MBEDTLS_ECDH_THEIRS) < 0) {
758 		wpa_printf(MSG_ERROR, "failed to set peer's ecdh params");
759 		goto fail;
760 	}
761 
762 	if (mbedtls_ecdh_calc_secret(ctx, secret_len, secret, DPP_MAX_SHARED_SECRET_LEN,
763 				     mbedtls_ctr_drbg_random, &ctr_drbg) < 0) {
764 		wpa_printf(MSG_ERROR, "failed to calculate secret");
765 		goto fail;
766 	}
767 
768 	if (*secret_len > DPP_MAX_SHARED_SECRET_LEN) {
769 		wpa_printf(MSG_ERROR, "secret len=%d is too big", *secret_len);
770 		goto fail;
771 	}
772 
773 	ret = 0;
774 
775 fail:
776 	mbedtls_ctr_drbg_free(&ctr_drbg);
777 	mbedtls_entropy_free(&entropy);
778 	if (ctx) {
779 		mbedtls_ecdh_free(ctx);
780 		os_free(ctx);
781 	}
782 	return ret;
783 }
784 
785 
crypto_ecdsa_get_sign(unsigned char * hash,const struct crypto_bignum * r,const struct crypto_bignum * s,struct crypto_key * csign,int hash_len)786 int crypto_ecdsa_get_sign(unsigned char *hash,
787 		const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_key *csign, int hash_len)
788 {
789 	int ret = -1;
790 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign;
791 
792 	mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx));
793 	if (!ctx) {
794 		wpa_printf(MSG_ERROR,"failed to allcate memory");
795 		return -1;
796 	}
797 	mbedtls_ecdsa_init(ctx);
798 
799 	if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0) {
800 		goto fail;
801 	}
802 	ret = mbedtls_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), (mbedtls_mpi *)r, (mbedtls_mpi *)s,
803 			&ctx->MBEDTLS_PRIVATE(d), hash, SHA256_MAC_LEN, crypto_rng_wrapper, NULL);
804 
805 fail:
806 	mbedtls_ecdsa_free(ctx);
807 	os_free(ctx);
808 
809 	return  ret;
810 }
811 
crypto_edcsa_sign_verify(const unsigned char * hash,const struct crypto_bignum * r,const struct crypto_bignum * s,struct crypto_key * csign,int hlen)812 int crypto_edcsa_sign_verify(const unsigned char *hash,
813 		const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_key *csign, int hlen)
814 {
815 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign;
816 	int ret = 0;
817 
818 	mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx));
819 	if (!ctx) {
820 		wpa_printf(MSG_ERROR, "failed to allcate memory");
821 		return ret;
822 	}
823 	mbedtls_ecdsa_init(ctx);
824 
825 	if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0)
826 		return ret;
827 
828 	if((ret = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hash, hlen,
829 					&ctx->MBEDTLS_PRIVATE(Q), (mbedtls_mpi *)r, (mbedtls_mpi *)s)) != 0){
830 		wpa_printf(MSG_ERROR, "ecdsa verification failed");
831 		return ret;
832 	}
833 
834 	mbedtls_ecdsa_free(ctx);
835 	os_free(ctx);
836 
837 	return ret;
838 }
839 
crypto_debug_print_ec_key(const char * title,struct crypto_key * key)840 void crypto_debug_print_ec_key(const char *title, struct crypto_key *key)
841 {
842 #ifdef DEBUG_PRINT
843 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
844 	mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pkey );
845 	u8 x[32], y[32], d[32];
846 	wpa_printf(MSG_ERROR, "curve: %s",
847 			mbedtls_ecp_curve_info_from_grp_id( ecp->MBEDTLS_PRIVATE(grp).id )->name );
848 	int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key)));
849 
850 	wpa_printf(MSG_ERROR, "prime len is %d", len);
851 	crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_get_public_key(key), x, y);
852 	crypto_bignum_to_bin(crypto_ec_get_private_key(key),
853 			d, len, len);
854 	wpa_hexdump(MSG_ERROR, "Q_x:", x, 32);
855 	wpa_hexdump(MSG_ERROR, "Q_y:", y, 32);
856 	wpa_hexdump(MSG_ERROR, "d:     ",  d , 32);
857 #endif
858 }
859 
crypto_ec_parse_subpub_key(const unsigned char * p,size_t len)860 struct crypto_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t len)
861 {
862 	int ret;
863 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)crypto_alloc_key();
864 	ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey);
865 
866 	if (ret < 0) {
867 		os_free(pkey);
868 		return NULL;
869 	}
870 
871 	return (struct crypto_key *)pkey;
872 }
873 
crypto_is_ec_key(struct crypto_key * key)874 int crypto_is_ec_key(struct crypto_key *key)
875 {
876 	int ret = mbedtls_pk_can_do((mbedtls_pk_context *)key, MBEDTLS_PK_ECKEY);
877 	return  ret;
878 }
879 
crypto_ec_gen_keypair(u16 ike_group)880 struct crypto_key * crypto_ec_gen_keypair(u16 ike_group)
881 {
882 	mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key();
883 
884 	if (!kctx) {
885 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
886 		return NULL;
887 	}
888 
889 	if(mbedtls_pk_setup(kctx,
890 				mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) != 0 )
891 		goto fail;
892 
893 	mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*kctx), //get this from argument
894 			crypto_rng_wrapper, NULL);
895 
896 	return (struct crypto_key *)kctx;
897 fail:
898 	mbedtls_pk_free(kctx);
899 	os_free(kctx);
900 	return NULL;
901 }
902 
903 /*
904  * ECParameters ::= CHOICE {
905  *   namedCurve         OBJECT IDENTIFIER
906  * }
907  */
pk_write_ec_param(unsigned char ** p,unsigned char * start,mbedtls_ecp_keypair * ec)908 static int pk_write_ec_param( unsigned char **p, unsigned char *start,
909 		mbedtls_ecp_keypair *ec )
910 {
911 	int ret;
912 	size_t len = 0;
913 	const char *oid;
914 	size_t oid_len;
915 
916 	if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->MBEDTLS_PRIVATE(grp).id, &oid, &oid_len ) ) != 0 )
917 		return( ret );
918 
919 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
920 
921 	return( (int) len );
922 }
923 
pk_write_ec_pubkey_formatted(unsigned char ** p,unsigned char * start,mbedtls_ecp_keypair * ec,int format)924 static int pk_write_ec_pubkey_formatted( unsigned char **p, unsigned char *start,
925 		mbedtls_ecp_keypair *ec, int format )
926 {
927 	int ret;
928 	size_t len = 0;
929 	unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
930 
931 	if( ( ret = mbedtls_ecp_point_write_binary( &ec->MBEDTLS_PRIVATE(grp), &ec->MBEDTLS_PRIVATE(Q),
932 					format,
933 					&len, buf, sizeof( buf ) ) ) != 0 )
934 	{
935 		return( ret );
936 	}
937 
938 	if( *p < start || (size_t)( *p - start ) < len )
939 		return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
940 
941 	*p -= len;
942 	memcpy( *p, buf, len );
943 
944 	return( (int) len );
945 }
946 
mbedtls_pk_write_pubkey_formatted(unsigned char ** p,unsigned char * start,const mbedtls_pk_context * key,int format)947 int mbedtls_pk_write_pubkey_formatted( unsigned char **p, unsigned char *start,
948 		const mbedtls_pk_context *key, int format )
949 {
950 	int ret;
951 	size_t len = 0;
952 
953 	if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
954 		MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey_formatted( p, start, mbedtls_pk_ec( *key ), format ) );
955 	else
956 		return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
957 
958 	return( (int) len );
959 }
960 
crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context * key,unsigned char * buf,size_t size,int format)961 int crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context *key, unsigned char *buf, size_t size, int format)
962 {
963 	int ret;
964 	unsigned char *c;
965 	size_t len = 0, par_len = 0, oid_len;
966 	const char *oid;
967 
968 	if( size == 0 )
969 		return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
970 
971 	c = buf + size;
972 
973 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey_formatted( &c, buf, key, format) );
974 
975 	if( c - buf < 1 )
976 		return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
977 
978 	/*
979 	 *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
980 	 *       algorithm            AlgorithmIdentifier,
981 	 *       subjectPublicKey     BIT STRING }
982 	 */
983 	*--c = 0;
984 	len += 1;
985 
986 
987 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
988 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
989 
990 	if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
991 					&oid, &oid_len ) ) != 0 )
992 	{
993 		return( ret );
994 	}
995 
996 	if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
997 	{
998 		MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
999 	}
1000 
1001 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
1002 				par_len ) );
1003 
1004 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
1005 	MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
1006 				MBEDTLS_ASN1_SEQUENCE ) );
1007 
1008 	return( (int) len );
1009 }
1010 
crypto_ec_write_pub_key(struct crypto_key * key,unsigned char ** key_buf)1011 int crypto_ec_write_pub_key(struct crypto_key *key, unsigned char **key_buf)
1012 {
1013 	unsigned char output_buf[1600] = {0};
1014 	int len = crypto_pk_write_formatted_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600, 1);
1015 	if (len <= 0)
1016 		return 0;
1017 
1018 	*key_buf = os_malloc(len);
1019 	if (!*key_buf) {
1020 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
1021 		return 0;
1022 	}
1023 	os_memcpy(*key_buf, output_buf + 1600 - len, len);
1024 
1025 	return len;
1026 }
1027 
crypto_mbedtls_get_grp_id(int group)1028 int crypto_mbedtls_get_grp_id(int group)
1029 {
1030         switch(group) {
1031         case IANA_SECP256R1:
1032                 return MBEDTLS_ECP_DP_SECP256R1;
1033         case IANA_SECP384R1:
1034                 return MBEDTLS_ECP_DP_SECP384R1;
1035         case IANA_SECP521R1:
1036                 return MBEDTLS_ECP_DP_SECP521R1;
1037         default:
1038                 return MBEDTLS_ECP_DP_NONE;
1039         }
1040 }
1041 
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)1042 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1043 {
1044 	mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh;
1045         if (!ctx) {
1046                 return;
1047         }
1048         mbedtls_ecdh_free(ctx);
1049         os_free(ctx);
1050         ctx = NULL;
1051 }
1052 
crypto_ecdh_init(int group)1053 struct crypto_ecdh * crypto_ecdh_init(int group)
1054 {
1055 	mbedtls_ctr_drbg_context ctr_drbg;
1056 	mbedtls_entropy_context entropy;
1057 	mbedtls_ecdh_context *ctx;
1058 
1059 	ctx = os_zalloc(sizeof(*ctx));
1060 	if (!ctx) {
1061 		wpa_printf(MSG_ERROR, "Memory allocation failed for ecdh context");
1062 		goto fail;
1063 	}
1064 	mbedtls_ecdh_init(ctx);
1065 #ifndef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT
1066 	ctx->MBEDTLS_PRIVATE(var) = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
1067 #endif
1068 
1069 	if ((mbedtls_ecp_group_load(ACCESS_ECDH(&ctx, grp), crypto_mbedtls_get_grp_id(group))) != 0) {
1070                 wpa_printf(MSG_ERROR, "Failed to set up ECDH context with group info");
1071                 goto fail;
1072 	}
1073 
1074 	/* Initialize CTR_DRBG context */
1075 	mbedtls_ctr_drbg_init(&ctr_drbg);
1076 	mbedtls_entropy_init(&entropy);
1077 
1078 	/* Seed and setup CTR_DRBG entropy source for future reseeds */
1079 	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) != 0) {
1080                 wpa_printf(MSG_ERROR, "Seeding entropy source failed");
1081                 goto fail;
1082 	}
1083 
1084 	/* Generates ECDH keypair on elliptic curve */
1085 	if (mbedtls_ecdh_gen_public(ACCESS_ECDH(&ctx, grp), ACCESS_ECDH(&ctx, d), ACCESS_ECDH(&ctx, Q), mbedtls_ctr_drbg_random, &ctr_drbg)!=0) {
1086                 wpa_printf(MSG_ERROR, "ECDH keypair on curve failed");
1087                 goto fail;
1088 	}
1089 
1090 	mbedtls_ctr_drbg_free(&ctr_drbg);
1091 	mbedtls_entropy_free(&entropy);
1092 	return (struct crypto_ecdh *)ctx;
1093 fail:
1094 	if (ctx) {
1095 		mbedtls_ecdh_free(ctx);
1096 		os_free(ctx);
1097 		ctx = NULL;
1098 	}
1099 	mbedtls_ctr_drbg_free(&ctr_drbg);
1100 	mbedtls_entropy_free(&entropy);
1101 	return NULL;
1102 }
1103 
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int y)1104 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int y)
1105 {
1106 	struct wpabuf *public_key = NULL;
1107 	uint8_t *buf = NULL;
1108 	mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh;
1109 	size_t prime_len = ACCESS_ECDH(ctx, grp).pbits/8;
1110 
1111 	buf = os_zalloc(y ? prime_len : 2 * prime_len);
1112         if (!buf) {
1113                 wpa_printf(MSG_ERROR, "Memory allocation failed");
1114                 return NULL;
1115         }
1116 
1117 	/* Export an MPI into unsigned big endian binary data of fixed size */
1118 	mbedtls_mpi_write_binary(ACCESS_ECDH(&ctx, Q).MBEDTLS_PRIVATE(X), buf, prime_len);
1119 	public_key = wpabuf_alloc_copy(buf, 32);
1120 	os_free(buf);
1121 	return public_key;
1122 }
1123 
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)1124 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
1125                                         const u8 *key, size_t len)
1126 {
1127 	uint8_t *secret = 0;
1128 	size_t olen = 0, len_prime = 0;
1129 	struct crypto_bignum *bn_x = NULL;
1130 	struct crypto_ec_point *ec_pt = NULL;
1131 	uint8_t *px = NULL, *py = NULL, *buf = NULL;
1132 	struct crypto_key *pkey = NULL;
1133 	struct wpabuf *sh_secret = NULL;
1134 	int secret_key = 0;
1135 
1136 	mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh;
1137 
1138 	mbedtls_ctr_drbg_context ctr_drbg;
1139 	mbedtls_entropy_context entropy;
1140 
1141 	/* Initialize CTR_DRBG context */
1142 	mbedtls_ctr_drbg_init(&ctr_drbg);
1143 	mbedtls_entropy_init(&entropy);
1144 
1145 	/* Seed and setup CTR_DRBG entropy source for future reseeds */
1146 	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) != 0) {
1147 		wpa_printf(MSG_ERROR, "Seeding entropy source failed");
1148 		goto cleanup;
1149 	}
1150 	len_prime = ACCESS_ECDH(ctx, grp).pbits/8;
1151 	bn_x = crypto_bignum_init_set(key, len);
1152 
1153 	/* Initialize data for EC point */
1154 	ec_pt = crypto_ec_point_init((struct crypto_ec*)ACCESS_ECDH(&ctx, grp));
1155 	if (!ec_pt) {
1156 		wpa_printf(MSG_ERROR,"Initializing for EC point failed");
1157 		goto cleanup;
1158 	}
1159 
1160 	if (crypto_ec_point_solve_y_coord((struct crypto_ec*)ACCESS_ECDH(&ctx, grp), ec_pt, bn_x, inc_y) != 0) {
1161                 wpa_printf(MSG_ERROR,"Failed to solve for y coordinate");
1162                 goto cleanup;
1163 	}
1164 	px = os_zalloc(len);
1165 	py = os_zalloc(len);
1166 	buf = os_zalloc(2*len);
1167 
1168         if (!px || !py || !buf) {
1169                 wpa_printf(MSG_ERROR, "Memory allocation failed");
1170                 goto cleanup;
1171         }
1172 	if (crypto_ec_point_to_bin((struct crypto_ec*)ACCESS_ECDH(&ctx, grp), ec_pt, px, py) != 0) {
1173                 wpa_printf(MSG_ERROR,"Failed to write EC point value as binary data");
1174                 goto cleanup;
1175 	}
1176 
1177 	os_memcpy(buf, px, len);
1178 	os_memcpy(buf+len, py, len);
1179 
1180 	pkey = crypto_ec_set_pubkey_point((struct crypto_ec_group*)ACCESS_ECDH(&ctx, grp), buf, len);
1181         if (!pkey) {
1182                 wpa_printf(MSG_ERROR, "Failed to set point for peer's public key");
1183                 goto cleanup;
1184 	}
1185 
1186 
1187 	mbedtls_pk_context *peer = (mbedtls_pk_context*)pkey;
1188 
1189 	/* Setup ECDH context from EC key */
1190 /* Call to mbedtls_ecdh_get_params() will initialize the context when not LEGACY context */
1191         if (ctx != NULL && peer != NULL) {
1192 				mbedtls_ecp_copy( ACCESS_ECDH(&ctx, Qp), &(mbedtls_pk_ec(*peer))->MBEDTLS_PRIVATE(Q) );
1193 #ifndef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT
1194 				ctx->MBEDTLS_PRIVATE(var) = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
1195 #endif
1196         } else {
1197                 wpa_printf(MSG_ERROR, "Failed to set peer's ECDH context");
1198                 goto cleanup;
1199         }
1200 	int len_secret = inc_y ? 2*len : len;
1201 	secret = os_zalloc(len_secret);
1202 	if (!secret) {
1203 		wpa_printf(MSG_ERROR, "Allocation failed for secret");
1204 		goto cleanup;
1205 	}
1206 
1207 	/* Calculate secret
1208 	z = F(DH(x,Y)) */
1209 	secret_key = mbedtls_ecdh_calc_secret(ctx, &olen, secret, len_prime, mbedtls_ctr_drbg_random, &ctr_drbg);
1210 	if (secret_key != 0) {
1211 		wpa_printf(MSG_ERROR, "Calculation of secret failed");
1212 		goto cleanup;
1213 	}
1214 	sh_secret = wpabuf_alloc_copy(secret, len_secret);
1215 
1216 cleanup:
1217 	os_free(px);
1218 	os_free(py);
1219 	os_free(buf);
1220 	os_free(secret);
1221 	crypto_ec_free_key(pkey);
1222 	crypto_bignum_deinit(bn_x, 1);
1223 	crypto_ec_point_deinit(ec_pt, 1);
1224 	mbedtls_ctr_drbg_free(&ctr_drbg);
1225 	mbedtls_entropy_free(&entropy);
1226 	return sh_secret;
1227 }
1228 
1229 
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)1230 struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
1231 {
1232 	int ret;
1233 	mbedtls_pk_context *pkey = os_zalloc(sizeof(*pkey));
1234 
1235 	if (!pkey) {
1236 		return NULL;
1237 	}
1238 
1239 	mbedtls_pk_init(pkey);
1240 	ret = mbedtls_pk_parse_public_key(pkey, der, der_len);
1241 
1242 	if (ret < 0) {
1243 		wpa_printf(MSG_ERROR, "failed to parse ec public key");
1244 		os_free(pkey);
1245 		return NULL;
1246 	}
1247 	return (struct crypto_ec_key *)pkey;
1248 }
1249 
1250 
crypto_ec_key_deinit(struct crypto_ec_key * key)1251 void crypto_ec_key_deinit(struct crypto_ec_key *key)
1252 {
1253 	mbedtls_pk_free((mbedtls_pk_context *)key);
1254 	os_free(key);
1255 }
1256 
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)1257 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
1258 					size_t len, const u8 *sig, size_t sig_len)
1259 {
1260 	int ret = 0;
1261 
1262 	mbedtls_ecdsa_context *ctx_verify = os_malloc(sizeof(mbedtls_ecdsa_context));
1263 	if (ctx_verify == NULL) {
1264 		return -1;
1265 	}
1266 
1267 	mbedtls_ecdsa_init(ctx_verify);
1268 
1269 	mbedtls_ecp_keypair *ec_key = mbedtls_pk_ec(*((mbedtls_pk_context *)key));
1270 	mbedtls_ecp_group *grp = &ec_key->MBEDTLS_PRIVATE(grp);
1271 
1272 	if ((ret = mbedtls_ecp_group_copy(&ctx_verify->MBEDTLS_PRIVATE(grp),grp)) != 0) {
1273 		goto cleanup;
1274 	}
1275 
1276 	if ((ret = mbedtls_ecp_copy(&ctx_verify->MBEDTLS_PRIVATE(Q), &ec_key->MBEDTLS_PRIVATE(Q))) != 0) {
1277 		goto cleanup;
1278 	}
1279 
1280 	if ((ret = mbedtls_ecdsa_read_signature(ctx_verify,
1281 					data, len,
1282 					sig, sig_len)) != 0) {
1283 		goto cleanup;
1284 	}
1285 	ret = 1;
1286 
1287 cleanup:
1288 	mbedtls_ecdsa_free(ctx_verify);
1289 	os_free(ctx_verify);
1290 	return ret;
1291 }
1292 
1293 
1294 #endif /* CONFIG_ECC */
1295