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