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