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