1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <time.h>
11 #include "unity.h"
12 #include <string.h>
13 #include "utils/common.h"
14 #include "utils/includes.h"
15 #include "crypto/crypto.h"
16
17 #include "mbedtls/ecp.h"
18 #include "test_utils.h"
19
20 typedef struct crypto_bignum crypto_bignum;
21
22 TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
23 {
24 {
25
26 uint8_t buf[32], buf2[32];
27
28 /* BN - Init & Deinit*/
29 crypto_bignum *bn = crypto_bignum_init();
30 crypto_bignum_deinit(bn, 1);
31
32 /* BN - Binary to bignum & bignum to binary*/
33 TEST_ASSERT(!os_get_random(buf, 32));
34
35 bn = crypto_bignum_init_set(buf, 32);
36 TEST_ASSERT_NOT_NULL(bn);
37
38
39 TEST_ASSERT(crypto_bignum_to_bin(bn, buf2, 32, 0) == 32);
40
41 TEST_ASSERT(!memcmp(buf, buf2, 32));
42 crypto_bignum_deinit(bn, 1);
43
44 }
45
46 { /** BN summation*/
47 uint8_t buf1[32], buf2[32], buf3[32], buf4[32];
48 crypto_bignum *bn1, *bn2, *sum;
49 uint8_t count;
50
51 sum = crypto_bignum_init();
52
53 for (count = 0; count < 32; count++) {
54 buf1[count] = 0x11;
55 buf2[count] = 0x22;
56 buf3[count] = 0x33; //expected result
57 buf4[count] = 0x0; //Calculated result
58 }
59
60 bn1 = crypto_bignum_init_set(buf1, 32);
61 TEST_ASSERT_NOT_NULL(bn1);
62
63 bn2 = crypto_bignum_init_set(buf2, 32);
64 TEST_ASSERT_NOT_NULL(bn2);
65
66 TEST_ASSERT(crypto_bignum_add(bn1, bn2, sum) == 0);
67
68 TEST_ASSERT(crypto_bignum_to_bin(sum, buf4, 32, 0) == 32);
69
70 TEST_ASSERT(!memcmp(buf3, buf4, 32));
71 crypto_bignum_deinit(bn1, 1);
72 crypto_bignum_deinit(bn2, 1);
73 crypto_bignum_deinit(sum, 1);
74
75 }
76
77 { /** BN mod*/
78 uint8_t buf1[32], buf2[32], buf3[32], buf4[32];
79 crypto_bignum *bn1, *bn2, *mod;
80 uint8_t count;
81
82 mod = crypto_bignum_init();
83
84 for (count = 0; count < 32; count++) {
85 buf1[count] = 0x33;
86 buf2[count] = 0x22;
87 buf3[count] = 0x11; //expected result
88 buf4[count] = 0x0; //Calculated result
89 }
90
91 bn1 = crypto_bignum_init_set(buf1, 32);
92 TEST_ASSERT_NOT_NULL(bn1);
93
94 bn2 = crypto_bignum_init_set(buf2, 32);
95 TEST_ASSERT_NOT_NULL(bn2);
96
97 TEST_ASSERT(crypto_bignum_mod(bn1, bn2, mod) == 0);
98
99 TEST_ASSERT(crypto_bignum_to_bin(mod, buf4, 32, 0) == 32);
100
101 TEST_ASSERT(!memcmp(buf3, buf4, 32));
102 crypto_bignum_deinit(bn1, 1);
103 crypto_bignum_deinit(bn2, 1);
104 crypto_bignum_deinit(mod, 1);
105
106 }
107
108 { /** BN sub*/
109 uint8_t buf1[32], buf2[32], buf3[32], buf4[32];
110 crypto_bignum *bn1, *bn2, *sub;
111 uint8_t count;
112
113 sub = crypto_bignum_init();
114
115 for (count = 0; count < 32; count++) {
116 buf1[count] = 0x44;
117 buf2[count] = 0x11;
118 buf3[count] = 0x33; //expected result
119 buf4[count] = 0x0; //Calculated result
120 }
121
122 bn1 = crypto_bignum_init_set(buf1, 32);
123 TEST_ASSERT_NOT_NULL(bn1);
124
125 bn2 = crypto_bignum_init_set(buf2, 32);
126 TEST_ASSERT_NOT_NULL(bn2);
127
128 TEST_ASSERT(crypto_bignum_sub(bn1, bn2, sub) == 0);
129
130 TEST_ASSERT(crypto_bignum_to_bin(sub, buf4, 32, 0) == 32);
131
132 TEST_ASSERT(!memcmp(buf3, buf4, 32));
133 crypto_bignum_deinit(bn1, 1);
134 crypto_bignum_deinit(bn2, 1);
135 crypto_bignum_deinit(sub, 1);
136
137 }
138
139 { /** BN div*/
140 uint8_t buf1[32], buf2[32], buf3[32], buf4[32];
141 crypto_bignum *bn1, *bn2, *div;
142 uint8_t count;
143
144 div = crypto_bignum_init();
145
146 for (count = 0; count < 32; count++) {
147 buf1[count] = 0x44;
148 buf2[count] = 0x22;
149 buf3[count] = count ? 0 : 0x2; //expected result
150 buf4[count] = 0x0; //Calculated result
151 }
152
153 bn1 = crypto_bignum_init_set(buf1, 32);
154 TEST_ASSERT_NOT_NULL(bn1);
155
156 bn2 = crypto_bignum_init_set(buf2, 32);
157 TEST_ASSERT_NOT_NULL(bn2);
158
159 TEST_ASSERT(crypto_bignum_div(bn1, bn2, div) == 0);
160
161 TEST_ASSERT(crypto_bignum_to_bin(div, buf4, 32, 0) == 1);
162
163 TEST_ASSERT(!memcmp(buf3, buf4, 1));
164 crypto_bignum_deinit(bn1, 1);
165 crypto_bignum_deinit(bn2, 1);
166 crypto_bignum_deinit(div, 1);
167
168 }
169
170 { /** BN mul mod*/
171 uint8_t buf1[32], buf2[32], buf3[32], buf4[32], buf5[32];
172 crypto_bignum *bn1, *bn2, *bn3, *mulmod;
173 uint8_t count;
174
175 for (count = 0; count < 32; count++) {
176 buf1[count] = 0x22;
177 buf2[count] = 0x11;
178 buf3[count] = (count < 4) ? 0x21 : 0;
179 buf4[count] = (count < 4) ? 0x14 : 0;
180 buf5[count] = 0;
181 }
182 mulmod = crypto_bignum_init();
183
184 bn1 = crypto_bignum_init_set(buf1, 32);
185 TEST_ASSERT_NOT_NULL(bn1);
186
187 bn2 = crypto_bignum_init_set(buf2, 32);
188 TEST_ASSERT_NOT_NULL(bn2);
189
190 bn3 = crypto_bignum_init_set(buf3, 4);
191 TEST_ASSERT_NOT_NULL(bn3);
192
193 TEST_ASSERT(crypto_bignum_mulmod(bn1, bn2, bn3, mulmod) == 0);
194
195 TEST_ASSERT(crypto_bignum_to_bin(mulmod, buf5, 32, 0) == 4);
196
197 TEST_ASSERT(!memcmp(buf5, buf4, 4));
198 crypto_bignum_deinit(bn1, 1);
199 crypto_bignum_deinit(bn2, 1);
200 crypto_bignum_deinit(bn3, 1);
201 crypto_bignum_deinit(mulmod, 1);
202
203 }
204
205 { /** BN exp mod*/
206 uint8_t buf1[32], buf2[32], buf3[32], buf4[32], buf5[32];
207
208 crypto_bignum *bn1, *bn2, *bn3, *expmod;
209 uint8_t count;
210
211 expmod = crypto_bignum_init();
212
213 for (count = 0; count < 32; count++) {
214 buf1[count] = 0x22;
215 buf2[count] = (count >= 30) ? 0x11 : 0;
216 buf3[count] = (count >= 31) ? 0xE9 : 0;
217 buf4[count] = count ? 0 : 0x62;
218 buf5[count] = 0;
219 }
220
221 bn1 = crypto_bignum_init_set(buf1, 32);
222 TEST_ASSERT_NOT_NULL(bn1);
223
224 bn2 = crypto_bignum_init_set(buf2, 32);
225 TEST_ASSERT_NOT_NULL(bn2);
226
227 bn3 = crypto_bignum_init_set(buf3, 32);
228 TEST_ASSERT_NOT_NULL(bn3);
229
230 TEST_ASSERT(crypto_bignum_exptmod(bn1, bn2, bn3, expmod) == 0);
231
232 TEST_ASSERT(crypto_bignum_to_bin(expmod, buf5, 32, 0) == 1);
233
234 TEST_ASSERT(!memcmp(buf5, buf4, 1));
235 crypto_bignum_deinit(bn1, 1);
236 crypto_bignum_deinit(bn2, 1);
237 crypto_bignum_deinit(bn3, 1);
238 crypto_bignum_deinit(expmod, 1);
239
240 }
241
242 { /** BN Legendre symbol test*/
243 uint8_t buf1[32], buf2[32];
244 crypto_bignum *bn1, *bn2;
245
246
247 buf1[0] = 0xf;
248 buf2[0] = 0x11;
249
250 bn1 = crypto_bignum_init_set(buf1, 1);
251 TEST_ASSERT_NOT_NULL(bn1);
252
253 bn2 = crypto_bignum_init_set(buf2, 1);
254 TEST_ASSERT_NOT_NULL(bn2);
255
256 TEST_ASSERT(crypto_bignum_legendre(bn1, bn2) == 1);
257
258 crypto_bignum_deinit(bn1, 1);
259 buf1[0] = 0xa;
260 bn1 = crypto_bignum_init_set(buf1, 1);
261 TEST_ASSERT_NOT_NULL(bn1);
262
263 TEST_ASSERT(crypto_bignum_legendre(bn1, bn2) == -1);
264
265 crypto_bignum_deinit(bn1, 1);
266 buf1[0] = 0x11;
267 bn1 = crypto_bignum_init_set(buf1, 1);
268 TEST_ASSERT_NOT_NULL(bn1);
269
270 TEST_ASSERT(crypto_bignum_legendre(bn1, bn2) == 0);
271
272 crypto_bignum_deinit(bn1, 1);
273 crypto_bignum_deinit(bn2, 1);
274
275 }
276 }
277
278
279 /*
280 * Conversion macros for embedded constants:
281 * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
282 */
283 #if defined(MBEDTLS_HAVE_INT32)
284
285 #define BYTES_TO_T_UINT_4( a, b, c, d ) \
286 ( (mbedtls_mpi_uint) a << 0 ) | \
287 ( (mbedtls_mpi_uint) b << 8 ) | \
288 ( (mbedtls_mpi_uint) c << 16 ) | \
289 ( (mbedtls_mpi_uint) d << 24 )
290
291 #define BYTES_TO_T_UINT_2( a, b ) \
292 BYTES_TO_T_UINT_4( a, b, 0, 0 )
293
294 #define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
295 BYTES_TO_T_UINT_4( a, b, c, d ), \
296 BYTES_TO_T_UINT_4( e, f, g, h )
297
298 #else /* 64-bits */
299
300 #define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
301 ( (mbedtls_mpi_uint) a << 0 ) | \
302 ( (mbedtls_mpi_uint) b << 8 ) | \
303 ( (mbedtls_mpi_uint) c << 16 ) | \
304 ( (mbedtls_mpi_uint) d << 24 ) | \
305 ( (mbedtls_mpi_uint) e << 32 ) | \
306 ( (mbedtls_mpi_uint) f << 40 ) | \
307 ( (mbedtls_mpi_uint) g << 48 ) | \
308 ( (mbedtls_mpi_uint) h << 56 )
309
310 #define BYTES_TO_T_UINT_4( a, b, c, d ) \
311 BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
312
313 #define BYTES_TO_T_UINT_2( a, b ) \
314 BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
315
316 #endif /* bits in mbedtls_mpi_uint */
317
318 /*
319 * Create an MPI from embedded constants
320 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
321 * Allocate a new memory as well so that it can be freed.
322 */
ecp_mpi_load(mbedtls_mpi * X,const mbedtls_mpi_uint * p,size_t len)323 static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
324 {
325 X->MBEDTLS_PRIVATE(s) = 1;
326 X->MBEDTLS_PRIVATE(n) = len / sizeof( mbedtls_mpi_uint );
327 X->MBEDTLS_PRIVATE(p) = os_zalloc(len);
328 memcpy(X->MBEDTLS_PRIVATE(p), (void *)p, len);
329 }
330
331
332 TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
333 {
334
335 static const mbedtls_mpi_uint secp256r1_gx[] = {
336 BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
337 BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
338 BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
339 BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
340 };
341 static const mbedtls_mpi_uint secp256r1_gy[] = {
342 BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
343 BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
344 BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
345 BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
346 };
347
348 {
349 /* Check init and deinit APIs*/
350 struct crypto_ec *e = crypto_ec_init(19);
351 struct crypto_ec_point *pt = crypto_ec_point_init(e);
352 crypto_ec_point_deinit(pt, 1);
353 crypto_ec_deinit(e);
354 }
355
356 {
357 uint8_t pt1[64], pt2[64];
358 struct crypto_ec *e = crypto_ec_init(19);
359 struct crypto_ec_point *p;
360
361 TEST_ASSERT_NOT_NULL(e);
362
363 /* Note this is just testing coversion & not whether point is
364 * in the group or not*/
365 TEST_ASSERT(!os_get_random(pt1, 64));
366
367 p = crypto_ec_point_from_bin(e, pt1);
368
369 TEST_ASSERT(crypto_ec_prime_len(e) == 32);
370
371 TEST_ASSERT(crypto_ec_point_to_bin(e, p, pt2, &pt2[32]) == 0);
372 TEST_ASSERT(!memcmp(pt1, pt2, sizeof(pt1)));
373
374 crypto_ec_point_deinit(p, 1);
375 crypto_ec_deinit(e);
376 }
377 {
378 /* Check addition and multiplication APIs
379 * yield the same answer.
380 */
381 struct crypto_ec *e = crypto_ec_init(19);
382
383 struct crypto_ec_point *p = crypto_ec_point_init(e);
384 struct crypto_ec_point *q = crypto_ec_point_init(e);
385 struct crypto_ec_point *r = crypto_ec_point_init(e);
386 mbedtls_mpi num;
387
388 TEST_ASSERT_NOT_NULL(e);
389 TEST_ASSERT_NOT_NULL(p);
390 TEST_ASSERT_NOT_NULL(q);
391 TEST_ASSERT_NOT_NULL(r);
392
393 mbedtls_mpi_init( &num );
394 mbedtls_mpi_lset( &num, 3 );
395
396 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
397 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
398
399 mbedtls_mpi_lset((&((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z)), 1);
400
401 TEST_ASSERT(crypto_ec_point_mul(e, p, (crypto_bignum *) &num, q) == 0); //q = 3p
402
403 TEST_ASSERT(crypto_ec_point_add(e, p, p, r) == 0);
404 TEST_ASSERT(crypto_ec_point_add(e, p, r, r) == 0);
405
406 TEST_ASSERT(crypto_ec_point_cmp(e, q, r) == 0);
407
408 mbedtls_mpi_free( &num );
409 crypto_ec_point_deinit(p, 1);
410 crypto_ec_point_deinit(q, 1);
411 crypto_ec_point_deinit(r, 1);
412 crypto_ec_deinit(e);
413
414 }
415
416 {
417 /* Generate a point using generator and take its inverse
418 * Check that adding point to inverse yields identity
419 */
420 struct crypto_ec *e = crypto_ec_init(19);
421
422 struct crypto_ec_point *p = crypto_ec_point_init(e);
423 struct crypto_ec_point *q = crypto_ec_point_init(e);
424 struct crypto_ec_point *r = crypto_ec_point_init(e);
425 mbedtls_mpi num;
426
427 TEST_ASSERT_NOT_NULL(e);
428 TEST_ASSERT_NOT_NULL(p);
429 TEST_ASSERT_NOT_NULL(q);
430 TEST_ASSERT_NOT_NULL(r);
431
432 mbedtls_mpi_init( &num );
433 mbedtls_mpi_lset( &num, 100 );
434
435 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
436 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
437
438 mbedtls_mpi_lset((&((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z)), 1);
439
440 TEST_ASSERT(crypto_ec_point_mul(e, p, (crypto_bignum *) &num, q) == 0);
441 TEST_ASSERT(crypto_ec_point_mul(e, p, (crypto_bignum *) &num, r) == 0);
442
443 TEST_ASSERT(crypto_ec_point_invert(e, r) == 0);
444 TEST_ASSERT(crypto_ec_point_add(e, q, r, r) == 0);
445
446 TEST_ASSERT(crypto_ec_point_is_at_infinity(e, r));
447
448 mbedtls_mpi_free( &num );
449 crypto_ec_point_deinit(p, 1);
450 crypto_ec_point_deinit(q, 1);
451 crypto_ec_point_deinit(r, 1);
452 crypto_ec_deinit(e);
453
454 }
455 {
456 /* Check y_sqr calculations and other dependent APIs */
457
458 struct crypto_ec *e = crypto_ec_init(19);
459
460 struct crypto_ec_point *p = crypto_ec_point_init(e);
461 struct crypto_ec_point *q = crypto_ec_point_init(e);
462 mbedtls_mpi num;
463
464 TEST_ASSERT_NOT_NULL(e);
465 TEST_ASSERT_NOT_NULL(p);
466 TEST_ASSERT_NOT_NULL(q);
467
468 mbedtls_mpi_init( &num );
469 mbedtls_mpi_lset( &num, 50 );
470
471 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
472 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
473
474 mbedtls_mpi_lset((&((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z)), 1);
475
476 /* Generator should always be on the curve*/
477 TEST_ASSERT(crypto_ec_point_is_on_curve(e, p));
478
479 /* Any point generated using generated should also be on the same curve*/
480 TEST_ASSERT(crypto_ec_point_mul(e, p, (crypto_bignum *) &num, q) == 0);
481 TEST_ASSERT(crypto_ec_point_is_on_curve(e, q));
482
483
484 mbedtls_mpi_free( &num );
485 crypto_ec_point_deinit(p, 1);
486 crypto_ec_point_deinit(q, 1);
487 crypto_ec_deinit(e);
488
489 }
490
491 {
492 /* crypto_ec_point_solve_y_coord APIs*/
493
494 struct crypto_ec *e = crypto_ec_init(19);
495
496 struct crypto_ec_point *p = crypto_ec_point_init(e);
497 struct crypto_ec_point *q = crypto_ec_point_init(e);
498 struct crypto_ec_point *r = crypto_ec_point_init(e);
499 mbedtls_mpi num;
500
501 TEST_ASSERT_NOT_NULL(e);
502 TEST_ASSERT_NOT_NULL(p);
503 TEST_ASSERT_NOT_NULL(q);
504 TEST_ASSERT_NOT_NULL(r);
505
506 mbedtls_mpi_init( &num );
507 mbedtls_mpi_lset( &num, 50 );
508
509 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
510 ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
511
512 mbedtls_mpi_lset((&((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z)), 1);
513
514 mbedtls_mpi_copy(&((mbedtls_ecp_point *)q)->MBEDTLS_PRIVATE(X), &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X));
515 mbedtls_mpi_copy(&((mbedtls_ecp_point *)r)->MBEDTLS_PRIVATE(X), &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X));
516
517 mbedtls_mpi_lset((&((mbedtls_ecp_point *)q)->MBEDTLS_PRIVATE(Z)), 1);
518 mbedtls_mpi_lset((&((mbedtls_ecp_point *)r)->MBEDTLS_PRIVATE(Z)), 1);
519
520 TEST_ASSERT(crypto_ec_point_solve_y_coord(e, q, (crypto_bignum *) & ((mbedtls_ecp_point *)q)->MBEDTLS_PRIVATE(X), 0) == 0);
521 TEST_ASSERT(crypto_ec_point_is_on_curve(e, q));
522
523 TEST_ASSERT(crypto_ec_point_solve_y_coord(e, r, (crypto_bignum *) & ((mbedtls_ecp_point *)q)->MBEDTLS_PRIVATE(X), 1) == 0);
524 TEST_ASSERT(crypto_ec_point_is_on_curve(e, r));
525
526 TEST_ASSERT((crypto_ec_point_cmp(e, p, q) == 0) || (crypto_ec_point_cmp(e, p, r) == 0));
527
528 /* The two roots should be inverse of one another*/
529 TEST_ASSERT(crypto_ec_point_add(e, q, r, r) == 0);
530 TEST_ASSERT(crypto_ec_point_is_at_infinity(e, r));
531
532 mbedtls_mpi_free( &num );
533 crypto_ec_point_deinit(p, 1);
534 crypto_ec_point_deinit(q, 1);
535 crypto_ec_point_deinit(r, 1);
536 crypto_ec_deinit(e);
537
538 }
539
540 }
541