• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4#include "bignum_core.h"
5#include "bignum_mod_raw.h"
6#include "constant_time_internal.h"
7#include "test/constant_flow.h"
8
9/* END_HEADER */
10
11/* BEGIN_DEPENDENCIES
12 * depends_on:MBEDTLS_BIGNUM_C
13 * END_DEPENDENCIES
14 */
15
16/* BEGIN_CASE */
17void mpi_mod_raw_io( data_t *input, int nb_int, int nx_32_int,
18                     int iendian, int iret, int oret )
19{
20    mbedtls_mpi_mod_modulus m;
21    mbedtls_mpi_mod_modulus_init( &m );
22
23    if( iret != 0 )
24        TEST_ASSERT( oret == 0 );
25
26    TEST_LE_S( 0, nb_int );
27    size_t nb = nb_int;
28
29    unsigned char buf[1024];
30    TEST_LE_U( nb, sizeof( buf ) );
31
32    /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
33     * to halve the number of limbs to have the same size. */
34    size_t nx;
35    TEST_LE_S( 0, nx_32_int );
36    if( sizeof( mbedtls_mpi_uint ) == 8 )
37        nx = nx_32_int / 2 + nx_32_int % 2;
38    else
39        nx = nx_32_int;
40
41    mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
42    TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) );
43
44    int endian;
45    if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
46        endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
47    else
48        endian = iendian;
49
50    mbedtls_mpi_uint init[sizeof( X ) / sizeof( X[0] )];
51    memset( init, 0xFF, sizeof( init ) );
52    int ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx,
53                                             MBEDTLS_MPI_MOD_REP_MONTGOMERY );
54    TEST_EQUAL( ret, 0 );
55
56    if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
57       endian = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
58
59    ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len, endian );
60    TEST_EQUAL( ret, iret );
61
62    if( iret == 0 )
63    {
64        if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
65            endian = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
66
67        ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb, endian );
68        TEST_EQUAL( ret, oret );
69    }
70
71    if( ( iret == 0 ) && ( oret == 0 ) )
72    {
73        if( nb > input->len )
74        {
75            if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
76            {
77                size_t leading_zeroes = nb - input->len;
78                TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
79                for( size_t i = 0; i < leading_zeroes; i++ )
80                    TEST_EQUAL( buf[i], 0 );
81            }
82            else
83            {
84                TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
85                for( size_t i = input->len; i < nb; i++ )
86                    TEST_EQUAL( buf[i], 0 );
87            }
88        }
89        else
90        {
91            if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
92            {
93                size_t leading_zeroes = input->len - nb;
94                TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
95                for( size_t i = 0; i < leading_zeroes; i++ )
96                    TEST_EQUAL( input->x[i], 0 );
97            }
98            else
99            {
100                TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
101                for( size_t i = nb; i < input->len; i++ )
102                    TEST_EQUAL( input->x[i], 0 );
103            }
104        }
105    }
106
107exit:
108    mbedtls_mpi_mod_modulus_free( &m );
109}
110/* END_CASE */
111
112/* BEGIN_CASE */
113void mpi_mod_raw_cond_assign( char * input_X,
114                              char * input_Y,
115                              int input_bytes )
116{
117    mbedtls_mpi_uint *X = NULL;
118    mbedtls_mpi_uint *Y = NULL;
119    mbedtls_mpi_uint *buff_m = NULL;
120    size_t limbs_X;
121    size_t limbs_Y;
122
123    mbedtls_mpi_mod_modulus m;
124    mbedtls_mpi_mod_modulus_init( &m );
125
126    TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs_X, input_X ), 0 );
127    TEST_EQUAL( mbedtls_test_read_mpi_core( &Y, &limbs_Y, input_Y ), 0 );
128
129    size_t limbs = limbs_X;
130    size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
131    size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
132    size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
133
134    TEST_EQUAL( limbs_X, limbs_Y );
135    TEST_ASSERT( copy_limbs <= limbs );
136
137    ASSERT_ALLOC( buff_m, copy_limbs );
138    memset( buff_m, 0xFF, copy_limbs );
139    TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
140                        &m, buff_m, copy_limbs,
141                        MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
142
143    /* condition is false */
144    TEST_CF_SECRET( X, bytes );
145    TEST_CF_SECRET( Y, bytes );
146
147    mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 0 );
148
149    TEST_CF_PUBLIC( X, bytes );
150    TEST_CF_PUBLIC( Y, bytes );
151
152    TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
153
154    /* condition is true */
155    TEST_CF_SECRET( X, bytes );
156    TEST_CF_SECRET( Y, bytes );
157
158    mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 1 );
159
160    TEST_CF_PUBLIC( X, bytes );
161    TEST_CF_PUBLIC( Y, bytes );
162
163    /* Check if the given length is copied even it is smaller
164       than the length of the given MPIs. */
165    if( copy_limbs <limbs )
166    {
167        ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
168        TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
169    }
170    else
171        ASSERT_COMPARE( X, bytes, Y, bytes );
172
173exit:
174    mbedtls_free( X );
175    mbedtls_free( Y );
176
177    mbedtls_mpi_mod_modulus_free( &m );
178    mbedtls_free( buff_m );
179}
180/* END_CASE */
181
182/* BEGIN_CASE */
183void mpi_mod_raw_cond_swap( char * input_X,
184                            char * input_Y,
185                            int input_bytes )
186{
187    mbedtls_mpi_uint *tmp_X = NULL;
188    mbedtls_mpi_uint *tmp_Y = NULL;
189    mbedtls_mpi_uint *X = NULL;
190    mbedtls_mpi_uint *Y = NULL;
191    mbedtls_mpi_uint *buff_m = NULL;
192    size_t limbs_X;
193    size_t limbs_Y;
194
195    mbedtls_mpi_mod_modulus m;
196    mbedtls_mpi_mod_modulus_init( &m );
197
198    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_X, &limbs_X, input_X ), 0 );
199    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_Y, &limbs_Y, input_Y ), 0 );
200
201    size_t limbs = limbs_X;
202    size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
203    size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
204    size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
205
206    TEST_EQUAL( limbs_X, limbs_Y );
207    TEST_ASSERT( copy_limbs <= limbs );
208
209    ASSERT_ALLOC( buff_m, copy_limbs );
210    memset( buff_m, 0xFF, copy_limbs );
211    TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
212                        &m, buff_m, copy_limbs,
213                        MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
214
215    ASSERT_ALLOC( X, limbs );
216    memcpy( X, tmp_X, bytes );
217
218    ASSERT_ALLOC( Y, bytes );
219    memcpy( Y, tmp_Y, bytes );
220
221    /* condition is false */
222    TEST_CF_SECRET( X, bytes );
223    TEST_CF_SECRET( Y, bytes );
224
225    mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 0 );
226
227    TEST_CF_PUBLIC( X, bytes );
228    TEST_CF_PUBLIC( Y, bytes );
229
230    ASSERT_COMPARE( X, bytes, tmp_X, bytes );
231    ASSERT_COMPARE( Y, bytes, tmp_Y, bytes );
232
233    /* condition is true */
234    TEST_CF_SECRET( X, bytes );
235    TEST_CF_SECRET( Y, bytes );
236
237    mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 1 );
238
239    TEST_CF_PUBLIC( X, bytes );
240    TEST_CF_PUBLIC( Y, bytes );
241
242    /* Check if the given length is copied even it is smaller
243       than the length of the given MPIs. */
244    if( copy_limbs < limbs )
245    {
246        ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes );
247        ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes );
248        TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 );
249        TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 );
250        TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 );
251        TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 );
252    }
253    else
254    {
255        ASSERT_COMPARE( X, bytes, tmp_Y, bytes );
256        ASSERT_COMPARE( Y, bytes, tmp_X, bytes );
257    }
258
259exit:
260    mbedtls_free( tmp_X );
261    mbedtls_free( tmp_Y );
262    mbedtls_free( X );
263    mbedtls_free( Y );
264
265    mbedtls_mpi_mod_modulus_free( &m );
266    mbedtls_free( buff_m );
267}
268/* END_CASE */
269
270/* BEGIN MERGE SLOT 1 */
271
272/* END MERGE SLOT 1 */
273
274/* BEGIN MERGE SLOT 2 */
275
276/* BEGIN_CASE */
277void mpi_mod_raw_sub( char * input_A,
278                      char * input_B,
279                      char * input_N,
280                      char * result )
281{
282    mbedtls_mpi_uint *A = NULL;
283    mbedtls_mpi_uint *B = NULL;
284    mbedtls_mpi_uint *N = NULL;
285    mbedtls_mpi_uint *X = NULL;
286    mbedtls_mpi_uint *res = NULL;
287    size_t limbs_A;
288    size_t limbs_B;
289    size_t limbs_N;
290    size_t limbs_res;
291
292    mbedtls_mpi_mod_modulus m;
293    mbedtls_mpi_mod_modulus_init( &m );
294
295    TEST_EQUAL( mbedtls_test_read_mpi_core( &A,   &limbs_A,   input_A ), 0 );
296    TEST_EQUAL( mbedtls_test_read_mpi_core( &B,   &limbs_B,   input_B ), 0 );
297    TEST_EQUAL( mbedtls_test_read_mpi_core( &N,   &limbs_N,   input_N ), 0 );
298    TEST_EQUAL( mbedtls_test_read_mpi_core( &res, &limbs_res, result  ), 0 );
299
300    size_t limbs = limbs_N;
301    size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
302
303    TEST_EQUAL( limbs_A,   limbs );
304    TEST_EQUAL( limbs_B,   limbs );
305    TEST_EQUAL( limbs_res, limbs );
306
307    ASSERT_ALLOC( X, limbs );
308
309    TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
310                        &m, N, limbs,
311                        MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
312
313    mbedtls_mpi_mod_raw_sub( X, A, B, &m );
314    ASSERT_COMPARE( X, bytes, res, bytes );
315
316    /* alias X to A */
317    memcpy( X, A, bytes );
318    mbedtls_mpi_mod_raw_sub( X, X, B, &m );
319    ASSERT_COMPARE( X, bytes, res, bytes );
320
321    /* alias X to B */
322    memcpy( X, B, bytes );
323    mbedtls_mpi_mod_raw_sub( X, A, X, &m );
324    ASSERT_COMPARE( X, bytes, res, bytes );
325
326    /* A == B: alias A and B */
327    if( memcmp( A, B, bytes ) == 0 )
328    {
329        mbedtls_mpi_mod_raw_sub( X, A, A, &m );
330        ASSERT_COMPARE( X, bytes, res, bytes );
331
332        /* X, A, B all aliased together */
333        memcpy( X, A, bytes );
334        mbedtls_mpi_mod_raw_sub( X, X, X, &m );
335        ASSERT_COMPARE( X, bytes, res, bytes );
336    }
337exit:
338    mbedtls_free( A );
339    mbedtls_free( B );
340    mbedtls_free( X );
341    mbedtls_free( res );
342
343    mbedtls_mpi_mod_modulus_free( &m );
344    mbedtls_free( N );
345}
346/* END_CASE */
347
348/* END MERGE SLOT 2 */
349
350/* BEGIN MERGE SLOT 3 */
351
352/* END MERGE SLOT 3 */
353
354/* BEGIN MERGE SLOT 4 */
355
356/* END MERGE SLOT 4 */
357
358/* BEGIN MERGE SLOT 5 */
359
360/* BEGIN_CASE */
361void mpi_mod_raw_add( char * input_N,
362                      char * input_A, char * input_B,
363                      char * input_S )
364{
365    mbedtls_mpi_uint *A = NULL;
366    mbedtls_mpi_uint *B = NULL;
367    mbedtls_mpi_uint *S = NULL;
368    mbedtls_mpi_uint *N = NULL;
369    mbedtls_mpi_uint *X = NULL;
370    size_t A_limbs, B_limbs, N_limbs, S_limbs;
371
372    mbedtls_mpi_mod_modulus m;
373    mbedtls_mpi_mod_modulus_init( &m );
374
375    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) );
376    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &B, &B_limbs, input_B ) );
377    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &N_limbs, input_N ) );
378    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &S, &S_limbs, input_S ) );
379
380    /* Modulus gives the number of limbs; all inputs must have the same. */
381    size_t limbs = N_limbs;
382    size_t bytes = limbs * sizeof( *A );
383
384    TEST_EQUAL( A_limbs, limbs );
385    TEST_EQUAL( B_limbs, limbs );
386    TEST_EQUAL( S_limbs, limbs );
387
388    ASSERT_ALLOC( X, limbs );
389
390    TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
391                        &m, N, limbs,
392                        MBEDTLS_MPI_MOD_REP_MONTGOMERY
393                ), 0 );
394
395    /* A + B => Correct result */
396    mbedtls_mpi_mod_raw_add( X, A, B, &m );
397    ASSERT_COMPARE( X, bytes, S, bytes );
398
399    /* A + B: alias X to A => Correct result */
400    memcpy( X, A, bytes );
401    mbedtls_mpi_mod_raw_add( X, X, B, &m );
402    ASSERT_COMPARE( X, bytes, S, bytes );
403
404    /* A + B: alias X to B => Correct result */
405    memcpy( X, B, bytes );
406    mbedtls_mpi_mod_raw_add( X, A, X, &m );
407    ASSERT_COMPARE( X, bytes, S, bytes );
408
409    if ( memcmp(A, B, bytes ) == 0 )
410    {
411        /* A == B: alias A and B */
412
413        /* A + A => Correct result */
414        mbedtls_mpi_mod_raw_add( X, A, A, &m );
415        ASSERT_COMPARE( X, bytes, S, bytes );
416
417        /* A + A: X, A, B all aliased together => Correct result */
418        memcpy( X, A, bytes );
419        mbedtls_mpi_mod_raw_add( X, X, X, &m );
420        ASSERT_COMPARE( X, bytes, S, bytes );
421    }
422    else
423    {
424        /* A != B: test B + A */
425
426        /* B + A => Correct result */
427        mbedtls_mpi_mod_raw_add( X, B, A, &m );
428        ASSERT_COMPARE( X, bytes, S, bytes );
429
430        /* B + A: alias X to A => Correct result */
431        memcpy( X, A, bytes );
432        mbedtls_mpi_mod_raw_add( X, B, X, &m );
433        ASSERT_COMPARE( X, bytes, S, bytes );
434
435        /* B + A: alias X to B => Correct result */
436        memcpy( X, B, bytes );
437        mbedtls_mpi_mod_raw_add( X, X, A, &m );
438        ASSERT_COMPARE( X, bytes, S, bytes );
439    }
440
441exit:
442    mbedtls_mpi_mod_modulus_free( &m );
443
444    mbedtls_free( A );
445    mbedtls_free( B );
446    mbedtls_free( S );
447    mbedtls_free( N );
448    mbedtls_free( X );
449}
450/* END_CASE */
451/* END MERGE SLOT 5 */
452
453/* BEGIN MERGE SLOT 6 */
454
455/* END MERGE SLOT 6 */
456
457/* BEGIN MERGE SLOT 7 */
458/* BEGIN_CASE */
459void mpi_mod_raw_to_mont_rep( char * input_N, char * input_A, char * input_X )
460{
461    mbedtls_mpi_uint *N = NULL;
462    mbedtls_mpi_uint *A = NULL;
463    mbedtls_mpi_uint *X = NULL;
464    size_t n_limbs, a_limbs, x_limbs, x_bytes;
465
466    mbedtls_mpi_mod_modulus m;
467    mbedtls_mpi_mod_modulus_init( &m );
468
469    /* Read inputs */
470    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
471    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) );
472    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) );
473    x_bytes = x_limbs * sizeof(mbedtls_mpi_uint);
474
475    /* Test that input does not require more limbs than modulo */
476    TEST_LE_U(a_limbs, n_limbs);
477
478    TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
479                MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
480
481    /* Convert from cannonical into Montgomery representation */
482    TEST_EQUAL(0, mbedtls_mpi_mod_raw_to_mont_rep( A, &m ) );
483
484    /* The result matches expected value */
485    ASSERT_COMPARE( A, x_bytes, X, x_bytes );
486exit:
487    mbedtls_mpi_mod_modulus_free( &m );
488    mbedtls_free( N );
489    mbedtls_free( A );
490    mbedtls_free( X );
491}
492/* END_CASE */
493
494/* BEGIN_CASE */
495void mpi_mod_raw_from_mont_rep( char * input_N, char * input_A, char * input_X )
496{
497    mbedtls_mpi_uint *N = NULL;
498    mbedtls_mpi_uint *A = NULL;
499    mbedtls_mpi_uint *X = NULL;
500    size_t n_limbs, a_limbs, x_limbs, x_bytes;
501
502    mbedtls_mpi_mod_modulus m;
503    mbedtls_mpi_mod_modulus_init( &m );
504
505    /* Read inputs */
506    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
507    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) );
508    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) );
509    x_bytes = x_limbs * sizeof(mbedtls_mpi_uint);
510
511    /* Test that input does not require more limbs than modulo */
512    TEST_LE_U(a_limbs, n_limbs);
513
514    TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
515                MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
516
517    /* Convert from Montgomery into cannonical representation */
518    TEST_EQUAL(0, mbedtls_mpi_mod_raw_from_mont_rep( A, &m ) );
519
520    /* The result matches expected value */
521    ASSERT_COMPARE( A, x_bytes, X, x_bytes );
522exit:
523    mbedtls_mpi_mod_modulus_free( &m );
524    mbedtls_free( N );
525    mbedtls_free( A );
526    mbedtls_free( X );
527}
528/* END_CASE */
529/* END MERGE SLOT 7 */
530
531/* BEGIN MERGE SLOT 8 */
532
533/* END MERGE SLOT 8 */
534
535/* BEGIN MERGE SLOT 9 */
536
537/* END MERGE SLOT 9 */
538
539/* BEGIN MERGE SLOT 10 */
540
541/* END MERGE SLOT 10 */
542