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