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