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