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