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