blob: 51a910fd1d6a32d54dd5b203fe718cfe259b96e9 [file] [log] [blame]
Werner Lewis0c6ea122022-09-30 13:02:16 +01001/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4#include "bignum_mod.h"
Gabor Mezeieca74662022-12-13 10:53:50 +01005#include "bignum_mod_raw.h"
Werner Lewis0c6ea122022-09-30 13:02:16 +01006#include "constant_time_internal.h"
7#include "test/constant_flow.h"
Tom Cosgrove62b20482022-12-01 14:27:37 +00008
9#define TEST_COMPARE_MPI_RESIDUES( a, b ) \
10 ASSERT_COMPARE( (a).p, (a).limbs * sizeof(mbedtls_mpi_uint), \
11 (b).p, (b).limbs * sizeof(mbedtls_mpi_uint) )
12
Tom Cosgrovef51f9722022-12-05 15:47:40 +000013static int test_read_modulus( mbedtls_mpi_mod_modulus *m,
14 mbedtls_mpi_mod_rep_selector int_rep,
15 char *input )
Tom Cosgrove62b20482022-12-01 14:27:37 +000016{
17 mbedtls_mpi_uint *p = NULL;
18 size_t limbs;
19
20 int ret = mbedtls_test_read_mpi_core( &p, &limbs, input );
21 if( ret != 0 )
22 return( ret );
23
24 return( mbedtls_mpi_mod_modulus_setup( m, p, limbs, int_rep ) );
25}
26
Tom Cosgrovef51f9722022-12-05 15:47:40 +000027static int test_read_residue( mbedtls_mpi_mod_residue *r,
28 const mbedtls_mpi_mod_modulus *m,
29 char *input,
30 int skip_limbs_and_value_checks )
Tom Cosgrove62b20482022-12-01 14:27:37 +000031{
32 mbedtls_mpi_uint *p = NULL;
33 size_t limbs;
34
35 int ret = mbedtls_test_read_mpi_core( &p, &limbs, input );
36 if( ret != 0 )
37 return( ret );
38
39 if( skip_limbs_and_value_checks )
40 {
41 r->p = p;
42 r->limbs = limbs;
43 return( 0 );
44 }
45
46 /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */
47 return( mbedtls_mpi_mod_residue_setup( r, m, p, limbs ) );
48}
Werner Lewis0c6ea122022-09-30 13:02:16 +010049/* END_HEADER */
50
51/* BEGIN_DEPENDENCIES
52 * depends_on:MBEDTLS_BIGNUM_C
53 * END_DEPENDENCIES
54 */
55
56/* BEGIN_CASE */
Janos Follath91295d22022-11-24 18:20:26 +000057void mpi_mod_setup( int int_rep, int iret )
Werner Lewis0c6ea122022-09-30 13:02:16 +010058{
59 #define MLIMBS 8
60 mbedtls_mpi_uint mp[MLIMBS];
61 mbedtls_mpi_mod_modulus m;
62 int ret;
63
Minos Galanakis4d4c98b2022-10-27 15:58:02 +010064 memset( mp, 0xFF, sizeof(mp) );
Werner Lewis0c6ea122022-09-30 13:02:16 +010065
66 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath91295d22022-11-24 18:20:26 +000067 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, int_rep );
Werner Lewis0c6ea122022-09-30 13:02:16 +010068 TEST_EQUAL( ret, iret );
69
Minos Galanakisdd365a52022-10-19 01:48:32 +010070 /* Only test if the constants have been set-up */
71 if ( ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
72 {
73 /* Test that the consts have been calculated */
74 TEST_ASSERT( m.rep.mont.rr != NULL );
75 TEST_ASSERT( m.rep.mont.mm != 0 );
76
Minos Galanakisdd365a52022-10-19 01:48:32 +010077 }
78
Werner Lewis0c6ea122022-09-30 13:02:16 +010079 /* Address sanitiser should catch if we try to free mp */
80 mbedtls_mpi_mod_modulus_free( &m );
81
82 /* Make sure that the modulus doesn't have reference to mp anymore */
83 TEST_ASSERT( m.p != mp );
84
Minos Galanakisdd365a52022-10-19 01:48:32 +010085 /* Only test if the constants have been set-up */
86 if ( ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
87 {
Minos Galanakisdd365a52022-10-19 01:48:32 +010088 /* Verify the data and pointers allocated have been properly wiped */
89 TEST_ASSERT( m.rep.mont.rr == NULL );
90 TEST_ASSERT( m.rep.mont.mm == 0 );
Minos Galanakisdd365a52022-10-19 01:48:32 +010091 }
Werner Lewis0c6ea122022-09-30 13:02:16 +010092exit:
93 /* It should be safe to call an mbedtls free several times */
94 mbedtls_mpi_mod_modulus_free( &m );
95
96 #undef MLIMBS
97}
98/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +000099
100/* BEGIN MERGE SLOT 1 */
101
102/* END MERGE SLOT 1 */
103
104/* BEGIN MERGE SLOT 2 */
105
Gabor Mezeieca74662022-12-13 10:53:50 +0100106/* BEGIN_CASE */
107void mpi_mod_mul( char * input_A,
108 char * input_B,
109 char * input_N,
110 char * result )
111{
112 mbedtls_mpi_uint *A = NULL;
113 mbedtls_mpi_uint *B = NULL;
114 mbedtls_mpi_uint *N = NULL;
115 mbedtls_mpi_uint *X = NULL;
116 mbedtls_mpi_uint *R = NULL;
117 size_t limbs_A;
118 size_t limbs_B;
119 size_t limbs_N;
120 size_t limbs_R;
121
122 mbedtls_mpi_mod_modulus m;
123 mbedtls_mpi_mod_modulus_init( &m );
124
125 TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &limbs_A, input_A ), 0 );
126 TEST_EQUAL( mbedtls_test_read_mpi_core( &B, &limbs_B, input_B ), 0 );
127 TEST_EQUAL( mbedtls_test_read_mpi_core( &N, &limbs_N, input_N ), 0 );
128 TEST_EQUAL( mbedtls_test_read_mpi_core( &R, &limbs_R, result ), 0 );
129
130 const size_t limbs = limbs_N;
131 const size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
132
133 TEST_EQUAL( limbs_A, limbs );
134 TEST_EQUAL( limbs_B, limbs );
135 TEST_EQUAL( limbs_R, limbs );
136
137 ASSERT_ALLOC( X, limbs );
138
139 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
140 &m, N, limbs,
141 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
142
143 mbedtls_mpi_mod_residue rA;
144 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rA, &m, A, limbs ), 0 );
145
146 mbedtls_mpi_mod_residue rB;
147 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rB, &m, B, limbs ), 0 );
148
149 mbedtls_mpi_mod_residue rX;
150 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rX, &m, X, limbs ), 0 );
151
Gabor Mezeieca74662022-12-13 10:53:50 +0100152 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100153 ASSERT_COMPARE( rX.p, bytes, R, bytes );
154
155 /* alias X to A */
156 memcpy( rX.p, rA.p, bytes );
157 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rB, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100158 ASSERT_COMPARE( rX.p, bytes, R, bytes );
159
160 /* alias X to B */
161 memcpy( rX.p, rB.p, bytes );
162 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rX, &m ), 0);
Gabor Mezeieca74662022-12-13 10:53:50 +0100163 ASSERT_COMPARE( rX.p, bytes, R, bytes );
164
165 /* A == B: alias A and B */
166 if( memcmp( rA.p, rB.p, bytes ) == 0 )
167 {
168 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rA, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100169 ASSERT_COMPARE( rX.p, bytes, R, bytes );
170
171 /* X, A, B all aliased together */
172 memcpy( rX.p, rA.p, bytes );
173 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rX, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100174 ASSERT_COMPARE( rX.p, bytes, R, bytes );
175 }
176
177 /* A != B: test B * A */
178 else
179 {
180 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rB, &rA, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100181 ASSERT_COMPARE( rX.p, bytes, R, bytes );
182
183 /* B * A: alias X to A */
184 memcpy( rX.p, rA.p, bytes );
185 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rB, &rX, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100186 ASSERT_COMPARE( rX.p, bytes, R, bytes );
187
188 /* B + A: alias X to B */
189 memcpy( rX.p, rB.p, bytes );
190 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rA, &m ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100191 ASSERT_COMPARE( rX.p, bytes, R, bytes );
192 }
193
194exit:
195 mbedtls_mpi_mod_residue_release( &rA );
196 mbedtls_mpi_mod_residue_release( &rB );
197 mbedtls_mpi_mod_residue_release( &rX );
198 mbedtls_mpi_mod_modulus_free( &m );
199
200 mbedtls_free( A );
201 mbedtls_free( B );
202 mbedtls_free( N );
203 mbedtls_free( X );
204 mbedtls_free( R );
205}
206/* END_CASE */
207
208/* BEGIN_CASE */
209void mpi_mod_mul_neg( char * input_A,
210 char * input_B,
211 char * input_N,
212 char * result,
213 int exp_ret )
214{
215 mbedtls_mpi_uint *A = NULL;
216 mbedtls_mpi_uint *B = NULL;
217 mbedtls_mpi_uint *N = NULL;
218 mbedtls_mpi_uint *X = NULL;
219 mbedtls_mpi_uint *R = NULL;
220 size_t limbs_A = 0;
221 size_t limbs_B = 0;
222 size_t limbs_N = 0;
223 size_t limbs_X = 0;
224
225 mbedtls_mpi_mod_modulus m;
226 mbedtls_mpi_mod_modulus_init( &m );
227
228 mbedtls_mpi_mod_modulus fake_m;
229 mbedtls_mpi_mod_modulus_init( &fake_m );
230
231 TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &limbs_A, input_A ), 0 );
232 TEST_EQUAL( mbedtls_test_read_mpi_core( &B, &limbs_B, input_B ), 0 );
233 TEST_EQUAL( mbedtls_test_read_mpi_core( &N, &limbs_N, input_N ), 0 );
234 TEST_EQUAL( mbedtls_test_read_mpi_core( &R, &limbs_X, result ), 0 );
235
236 ASSERT_ALLOC( X, limbs_X );
237
238 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
239 &m, N, limbs_N,
240 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
241
242 mbedtls_mpi_mod_residue rA;
243 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rA, &m, A, limbs_N ), 0 );
244 rA.limbs = limbs_A;
245
246 mbedtls_mpi_mod_residue rB;
247 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rB, &m, B, limbs_N ), 0 );
248 rB.limbs = limbs_B;
249
250 mbedtls_mpi_mod_residue rX;
251 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rX, &m, X, limbs_N ), 0 );
252 rX.limbs = limbs_X;
253
254 /* Convert to Montgomery representation */
255 TEST_EQUAL( mbedtls_mpi_mod_raw_to_mont_rep( rA.p, &m ), 0 );
256 TEST_EQUAL( mbedtls_mpi_mod_raw_to_mont_rep( rB.p, &m ), 0 );
257
258 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &m ), exp_ret );
259
260 /* Check when m is not initialized */
261 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &fake_m ),
262 MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
263
264exit:
265 mbedtls_mpi_mod_residue_release( &rA );
266 mbedtls_mpi_mod_residue_release( &rB );
267 mbedtls_mpi_mod_residue_release( &rX );
268 mbedtls_mpi_mod_modulus_free( &m );
269 mbedtls_mpi_mod_modulus_free( &fake_m );
270
271 mbedtls_free( A );
272 mbedtls_free( B );
273 mbedtls_free( N );
274 mbedtls_free( X );
275 mbedtls_free( R );
276}
277/* END_CASE */
278
Janos Follath5933f692022-11-02 14:35:17 +0000279/* END MERGE SLOT 2 */
280
281/* BEGIN MERGE SLOT 3 */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000282/* BEGIN_CASE */
283void mpi_mod_sub( char * input_N,
284 char * input_A, char * input_B,
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000285 char * input_D, int expected_ret )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000286{
287 mbedtls_mpi_mod_residue a = { NULL, 0 };
288 mbedtls_mpi_mod_residue b = { NULL, 0 };
289 mbedtls_mpi_mod_residue d = { NULL, 0 };
290 mbedtls_mpi_mod_residue x = { NULL, 0 };
291 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000292
Tom Cosgrove62b20482022-12-01 14:27:37 +0000293 mbedtls_mpi_mod_modulus m;
294 mbedtls_mpi_mod_modulus_init( &m );
295
296 TEST_EQUAL( 0,
297 test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
298
299 /* test_read_residue() normally checks that inputs have the same number of
300 * limbs as the modulus. For negative testing we can ask it to skip this
301 * with a non-zero final parameter. */
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000302 TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
303 TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
304 TEST_EQUAL( 0, test_read_residue( &d, &m, input_D, expected_ret != 0 ) );
Tom Cosgrove62b20482022-12-01 14:27:37 +0000305
306 size_t limbs = m.limbs;
307 size_t bytes = limbs * sizeof( *X_raw );
308
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000309 if( expected_ret == 0 )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000310 {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000311 /* Negative test with too many limbs in output */
312 ASSERT_ALLOC( X_raw, limbs + 1 );
Tom Cosgrove62b20482022-12-01 14:27:37 +0000313
Tom Cosgrove62b20482022-12-01 14:27:37 +0000314 x.p = X_raw;
315 x.limbs = limbs + 1;
316 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
317 mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
318
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000319 mbedtls_free( X_raw );
320 X_raw = NULL;
321
322 /* Negative test with too few limbs in output */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000323 if( limbs > 1 )
324 {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000325 ASSERT_ALLOC( X_raw, limbs - 1 );
326
Tom Cosgrove62b20482022-12-01 14:27:37 +0000327 x.p = X_raw;
328 x.limbs = limbs - 1;
329 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
330 mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000331
332 mbedtls_free( X_raw );
333 X_raw = NULL;
Tom Cosgrove62b20482022-12-01 14:27:37 +0000334 }
335
336 /* Negative testing with too many/too few limbs in a and b is covered by
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000337 * manually-written test cases with expected_ret != 0. */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000338 }
339
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000340 ASSERT_ALLOC( X_raw, limbs );
341
Tom Cosgrove62b20482022-12-01 14:27:37 +0000342 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
343
344 /* a - b => Correct result, or expected error */
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000345 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
346 if( expected_ret != 0 )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000347 goto exit;
348
349 TEST_COMPARE_MPI_RESIDUES( x, d );
350
351 /* a - b: alias x to a => Correct result */
352 memcpy( x.p, a.p, bytes );
353 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &b, &m ) );
354 TEST_COMPARE_MPI_RESIDUES( x, d );
355
356 /* a - b: alias x to b => Correct result */
357 memcpy( x.p, b.p, bytes );
358 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &x, &m ) );
359 TEST_COMPARE_MPI_RESIDUES( x, d );
360
361 if ( memcmp( a.p, b.p, bytes ) == 0 )
362 {
363 /* a == b: alias a and b */
364
365 /* a - a => Correct result */
366 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &a, &m ) );
367 TEST_COMPARE_MPI_RESIDUES( x, d );
368
369 /* a - a: x, a, b all aliased together => Correct result */
370 memcpy( x.p, a.p, bytes );
371 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &x, &m ) );
372 TEST_COMPARE_MPI_RESIDUES( x, d );
373 }
374
375exit:
376 mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
377 mbedtls_mpi_mod_modulus_free( &m );
378
379 mbedtls_free( a.p );
380 mbedtls_free( b.p );
381 mbedtls_free( d.p );
382 mbedtls_free( X_raw );
383}
384/* END_CASE */
Tom Cosgrovedc197592022-12-15 16:59:40 +0000385
386/* BEGIN_CASE */
387void mpi_mod_inv_mont( char * input_N,
388 char * input_A, char * input_I,
389 int expected_ret )
390{
391 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
392 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
393 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
394 mbedtls_mpi_uint *X_raw = NULL;
395
396 mbedtls_mpi_mod_modulus N;
397 mbedtls_mpi_mod_modulus_init( &N );
398
399 TEST_EQUAL( 0,
400 test_read_modulus( &N, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
401
402 /* test_read_residue() normally checks that inputs have the same number of
403 * limbs as the modulus. For negative testing we can ask it to skip this
404 * with a non-zero final parameter. */
405 TEST_EQUAL( 0, test_read_residue( &a, &N, input_A, expected_ret != 0 ) );
406 TEST_EQUAL( 0, test_read_residue( &i, &N, input_I, expected_ret != 0 ) );
407
408 size_t limbs = N.limbs;
409 size_t bytes = limbs * sizeof( *X_raw );
410
411 ASSERT_ALLOC( X_raw, limbs );
412
413 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &N, X_raw, limbs ) );
414
415 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_inv( &x, &a, &N ) );
416 if( expected_ret == 0 )
417 {
418 TEST_COMPARE_MPI_RESIDUES( x, i );
419
420 /* a^-1: alias x to a => Correct result */
421 memcpy( x.p, a.p, bytes );
422 TEST_EQUAL( 0, mbedtls_mpi_mod_inv( &x, &x, &N ) );
423 TEST_COMPARE_MPI_RESIDUES( x, i );
424 }
425
426exit:
427 mbedtls_free( (void *)N.p ); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
428 mbedtls_mpi_mod_modulus_free( &N );
429
430 mbedtls_free( a.p );
431 mbedtls_free( i.p );
432 mbedtls_free( X_raw );
433}
434/* END_CASE */
435
436/* BEGIN_CASE */
437void mpi_mod_inv_non_mont( char * input_N,
438 char * input_A, char * input_I,
439 int expected_ret )
440{
441 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
442 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
443 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
444 mbedtls_mpi_uint *X_raw = NULL;
445
446 mbedtls_mpi_mod_modulus N;
447 mbedtls_mpi_mod_modulus_init( &N );
448
449 TEST_EQUAL( 0,
450 test_read_modulus( &N, MBEDTLS_MPI_MOD_REP_OPT_RED, input_N ) );
451
452 /* test_read_residue() normally checks that inputs have the same number of
453 * limbs as the modulus. For negative testing we can ask it to skip this
454 * with a non-zero final parameter. */
455 TEST_EQUAL( 0, test_read_residue( &a, &N, input_A, expected_ret != 0 ) );
456 TEST_EQUAL( 0, test_read_residue( &i, &N, input_I, expected_ret != 0 ) );
457
458 size_t limbs = N.limbs;
459 size_t bytes = limbs * sizeof( *X_raw );
460
461 ASSERT_ALLOC( X_raw, limbs );
462
463 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &N, X_raw, limbs ) );
464
465 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_inv( &x, &a, &N ) );
466 if( expected_ret == 0 )
467 {
468 TEST_COMPARE_MPI_RESIDUES( x, i );
469
470 /* a^-1: alias x to a => Correct result */
471 memcpy( x.p, a.p, bytes );
472 TEST_EQUAL( 0, mbedtls_mpi_mod_inv( &x, &x, &N ) );
473 TEST_COMPARE_MPI_RESIDUES( x, i );
474 }
475
476exit:
477 mbedtls_free( (void *)N.p ); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
478 mbedtls_mpi_mod_modulus_free( &N );
479
480 mbedtls_free( a.p );
481 mbedtls_free( i.p );
482 mbedtls_free( X_raw );
483}
484/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000485/* END MERGE SLOT 3 */
486
487/* BEGIN MERGE SLOT 4 */
488
489/* END MERGE SLOT 4 */
490
491/* BEGIN MERGE SLOT 5 */
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000492/* BEGIN_CASE */
493void mpi_mod_add( char * input_N,
494 char * input_A, char * input_B,
Werner Lewis25690a92022-12-13 17:17:34 +0000495 char * input_S, int expected_ret )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000496{
497 mbedtls_mpi_mod_residue a = { NULL, 0 };
498 mbedtls_mpi_mod_residue b = { NULL, 0 };
499 mbedtls_mpi_mod_residue s = { NULL, 0 };
500 mbedtls_mpi_mod_residue x = { NULL, 0 };
501 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000502
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000503 mbedtls_mpi_mod_modulus m;
504 mbedtls_mpi_mod_modulus_init( &m );
505
506 TEST_EQUAL( 0,
507 test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
508
509 /* test_read_residue() normally checks that inputs have the same number of
510 * limbs as the modulus. For negative testing we can ask it to skip this
511 * with a non-zero final parameter. */
Werner Lewis25690a92022-12-13 17:17:34 +0000512 TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
513 TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
514 TEST_EQUAL( 0, test_read_residue( &s, &m, input_S, expected_ret != 0 ) );
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000515
516 size_t limbs = m.limbs;
517 size_t bytes = limbs * sizeof( *X_raw );
518
Werner Lewis25690a92022-12-13 17:17:34 +0000519 if( expected_ret == 0 )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000520 {
521 /* Negative test with too many limbs in output */
Werner Lewis79341a42022-12-13 17:19:01 +0000522 ASSERT_ALLOC( X_raw, limbs + 1 );
523
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000524 x.p = X_raw;
525 x.limbs = limbs + 1;
526 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
527 mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
528
Werner Lewis79341a42022-12-13 17:19:01 +0000529 mbedtls_free( X_raw );
530 X_raw = NULL;
531
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000532 /* Negative test with too few limbs in output */
533 if( limbs > 1 )
534 {
Werner Lewis79341a42022-12-13 17:19:01 +0000535 ASSERT_ALLOC( X_raw, limbs - 1 );
536
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000537 x.p = X_raw;
538 x.limbs = limbs - 1;
539 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
540 mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
Werner Lewis79341a42022-12-13 17:19:01 +0000541
542 mbedtls_free( X_raw );
543 X_raw = NULL;
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000544 }
545
546 /* Negative testing with too many/too few limbs in a and b is covered by
547 * manually-written test cases with oret != 0. */
548 }
549
Werner Lewis79341a42022-12-13 17:19:01 +0000550 /* Allocate correct number of limbs for X_raw */
551 ASSERT_ALLOC( X_raw, limbs );
552
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000553 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
554
555 /* A + B => Correct result or expected error */
Werner Lewis25690a92022-12-13 17:17:34 +0000556 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
557 if( expected_ret != 0 )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000558 goto exit;
559
560 TEST_COMPARE_MPI_RESIDUES( x, s );
561
562 /* a + b: alias x to a => Correct result */
563 memcpy( x.p, a.p, bytes );
564 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &b, &m ) );
565 TEST_COMPARE_MPI_RESIDUES( x, s );
566
567 /* a + b: alias x to b => Correct result */
568 memcpy( x.p, b.p, bytes );
569 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &x, &m ) );
570 TEST_COMPARE_MPI_RESIDUES( x, s );
571
572 if ( memcmp( a.p, b.p, bytes ) == 0 )
573 {
574 /* a == b: alias a and b */
575
576 /* a + a => Correct result */
577 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &a, &m ) );
578 TEST_COMPARE_MPI_RESIDUES( x, s );
579
580 /* a + a: x, a, b all aliased together => Correct result */
581 memcpy( x.p, a.p, bytes );
582 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &x, &m ) );
583 TEST_COMPARE_MPI_RESIDUES( x, s );
584 }
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000585
586exit:
587 mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
588 mbedtls_mpi_mod_modulus_free( &m );
589
590 mbedtls_free( a.p );
591 mbedtls_free( b.p );
592 mbedtls_free( s.p );
593 mbedtls_free( X_raw );
594}
595/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000596/* END MERGE SLOT 5 */
597
598/* BEGIN MERGE SLOT 6 */
599
600/* END MERGE SLOT 6 */
601
602/* BEGIN MERGE SLOT 7 */
Minos Galanakis8f242702022-11-10 16:56:02 +0000603/* BEGIN_CASE */
Janos Follath91f3abd2022-11-26 11:47:14 +0000604void mpi_residue_setup( char * input_N, char * input_R, int ret )
Minos Galanakisa17ad482022-11-16 16:29:15 +0000605{
Minos Galanakisa17ad482022-11-16 16:29:15 +0000606 mbedtls_mpi_uint *N = NULL;
607 mbedtls_mpi_uint *R = NULL;
Minos Galanakisaed832a2022-11-24 09:09:47 +0000608 size_t n_limbs, r_limbs;
Minos Galanakisa17ad482022-11-16 16:29:15 +0000609 mbedtls_mpi_mod_modulus m;
610 mbedtls_mpi_mod_residue r;
611
Minos Galanakisa17ad482022-11-16 16:29:15 +0000612 mbedtls_mpi_mod_modulus_init( &m );
613
Minos Galanakisaed832a2022-11-24 09:09:47 +0000614 /* Allocate the memory for intermediate data structures */
Janos Follath91f3abd2022-11-26 11:47:14 +0000615 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
616 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &R, &r_limbs, input_R ) );
Minos Galanakisaed832a2022-11-24 09:09:47 +0000617
Minos Galanakisa17ad482022-11-16 16:29:15 +0000618 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
Janos Follath91295d22022-11-24 18:20:26 +0000619 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000620
Minos Galanakisaed832a2022-11-24 09:09:47 +0000621 TEST_EQUAL( ret, mbedtls_mpi_mod_residue_setup( &r, &m, R , r_limbs ) );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000622
Janos Follath91f3abd2022-11-26 11:47:14 +0000623 if ( ret == 0 )
624 {
625 TEST_EQUAL( r.limbs, r_limbs );
626 TEST_ASSERT( r.p == R );
627 }
628
Minos Galanakisa17ad482022-11-16 16:29:15 +0000629exit:
630 mbedtls_mpi_mod_modulus_free( &m );
631 mbedtls_free( N );
632 mbedtls_free( R );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000633}
634/* END_CASE */
Minos Galanakisaed832a2022-11-24 09:09:47 +0000635
Minos Galanakisa17ad482022-11-16 16:29:15 +0000636/* BEGIN_CASE */
Janos Follath339b4392022-11-26 12:20:41 +0000637void mpi_mod_io_neg( char * input_N, data_t * buf, int ret )
Minos Galanakis8f242702022-11-10 16:56:02 +0000638{
Minos Galanakis8f242702022-11-10 16:56:02 +0000639 mbedtls_mpi_uint *N = NULL;
640 mbedtls_mpi_uint *R = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000641
642 mbedtls_mpi_mod_modulus m;
Janos Follathe7190a22022-11-26 18:46:54 +0000643 mbedtls_mpi_mod_residue r = { NULL, 0 };
Minos Galanakis96070a52022-11-25 19:32:10 +0000644 mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
Minos Galanakis8f242702022-11-10 16:56:02 +0000645
Janos Follath799eaee2022-11-25 15:57:04 +0000646 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath799eaee2022-11-25 15:57:04 +0000647
Janos Follath339b4392022-11-26 12:20:41 +0000648 size_t n_limbs;
Minos Galanakis96070a52022-11-25 19:32:10 +0000649 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
Janos Follath339b4392022-11-26 12:20:41 +0000650 size_t r_limbs = n_limbs;
651 ASSERT_ALLOC( R, r_limbs );
Minos Galanakis8f242702022-11-10 16:56:02 +0000652
Janos Follathe7190a22022-11-26 18:46:54 +0000653 /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */
Janos Follath3e3fc912022-11-24 18:02:46 +0000654 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000655 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000656
Minos Galanakis96070a52022-11-25 19:32:10 +0000657 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000658 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000659
Janos Follathe7190a22022-11-26 18:46:54 +0000660 /* Set up modulus and test with residue->p == NULL */
Minos Galanakis96070a52022-11-25 19:32:10 +0000661 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
662 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000663
Minos Galanakis96070a52022-11-25 19:32:10 +0000664 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follathe7190a22022-11-26 18:46:54 +0000665 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000666 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follathe7190a22022-11-26 18:46:54 +0000667 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
668
669 /* Do the rest of the tests with a residue set up with the input data */
670 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R , r_limbs ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000671
Janos Follathd7bb3522022-11-26 14:59:27 +0000672 /* Fail for r_limbs < m->limbs */
673 r.limbs--;
674 TEST_ASSERT( r.limbs < m.limbs );
Minos Galanakis96070a52022-11-25 19:32:10 +0000675 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000676 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000677 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000678 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
Janos Follathd7bb3522022-11-26 14:59:27 +0000679 r.limbs++;
680
681 /* Fail for r_limbs > m->limbs */
682 m.limbs--;
683 TEST_ASSERT( r.limbs > m.limbs );
684 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
685 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
686 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
687 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
688 m.limbs++;
Minos Galanakis96070a52022-11-25 19:32:10 +0000689
690 /* Test the read */
Janos Follath566c91d2022-11-26 12:05:50 +0000691 TEST_EQUAL( ret, mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000692
693 /* Test write overflow only when the representation is large and read is successful */
Janos Follath6ef582f2022-11-26 14:19:02 +0000694 if ( r.limbs > 1 && ret == 0 )
Minos Galanakis96070a52022-11-25 19:32:10 +0000695 TEST_EQUAL( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL,
Janos Follath566c91d2022-11-26 12:05:50 +0000696 mbedtls_mpi_mod_write( &r, &m, buf->x, 1, endian ) );
Janos Follathd7bb3522022-11-26 14:59:27 +0000697
Minos Galanakis8f242702022-11-10 16:56:02 +0000698exit:
Janos Follathd7bb3522022-11-26 14:59:27 +0000699 mbedtls_mpi_mod_residue_release( &r );
Minos Galanakis8f242702022-11-10 16:56:02 +0000700 mbedtls_mpi_mod_modulus_free( &m );
Minos Galanakis8f242702022-11-10 16:56:02 +0000701 mbedtls_free( N );
702 mbedtls_free( R );
Minos Galanakis8f242702022-11-10 16:56:02 +0000703}
704/* END_CASE */
705
706/* BEGIN_CASE */
Janos Follath3e3fc912022-11-24 18:02:46 +0000707void mpi_mod_io( char * input_N, data_t * input_A, int endian )
Minos Galanakis8f242702022-11-10 16:56:02 +0000708{
709 mbedtls_mpi_uint *N = NULL;
710 mbedtls_mpi_uint *R = NULL;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000711 mbedtls_mpi_uint *R_COPY = NULL;
Janos Follath0020df92022-11-26 17:23:16 +0000712 unsigned char *obuf = NULL;
713 unsigned char *ref_buf = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000714 mbedtls_mpi_mod_modulus m;
715 mbedtls_mpi_mod_residue r;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000716 mbedtls_mpi_mod_residue r_copy;
Minos Galanakis8f242702022-11-10 16:56:02 +0000717 size_t n_limbs, n_bytes, a_bytes;
718
Janos Follath799eaee2022-11-25 15:57:04 +0000719 mbedtls_mpi_mod_modulus_init( &m );
720
Minos Galanakis8f242702022-11-10 16:56:02 +0000721 /* Read inputs */
722 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
723 n_bytes = n_limbs * sizeof( mbedtls_mpi_uint );
Janos Follath6ef582f2022-11-26 14:19:02 +0000724 a_bytes = input_A->len;
Minos Galanakis8f242702022-11-10 16:56:02 +0000725
726 /* Allocate the memory for intermediate data structures */
727 ASSERT_ALLOC( R, n_bytes );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000728 ASSERT_ALLOC( R_COPY, n_bytes );
Minos Galanakis8f242702022-11-10 16:56:02 +0000729
730 /* Test that input's size is not greater to modulo's */
Janos Follath6ef582f2022-11-26 14:19:02 +0000731 TEST_LE_U( a_bytes, n_bytes );
Minos Galanakis8f242702022-11-10 16:56:02 +0000732
733 /* Init Structures */
Janos Follath91295d22022-11-24 18:20:26 +0000734 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
Minos Galanakis8f242702022-11-10 16:56:02 +0000735 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
736
737 /* Enforcing p_limbs >= m->limbs */
Janos Follath3e3fc912022-11-24 18:02:46 +0000738 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R, n_limbs ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000739
Janos Follath3e3fc912022-11-24 18:02:46 +0000740 TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r, &m, input_A->x, input_A->len,
741 endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000742
Janos Follath0020df92022-11-26 17:23:16 +0000743 /* Read a copy for checking that writing didn't change the value of r */
744 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r_copy, &m,
745 R_COPY, n_limbs ) );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000746 TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r_copy, &m, input_A->x, input_A->len,
747 endian ) );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000748
Janos Follath0020df92022-11-26 17:23:16 +0000749 /* Get number of bytes without leading zeroes */
750 size_t a_bytes_trimmed = a_bytes;
751 while( a_bytes_trimmed > 0 )
752 {
753 unsigned char* r_byte_array = (unsigned char*) r.p;
754 if( r_byte_array[--a_bytes_trimmed] != 0 )
755 break;
756 }
757 a_bytes_trimmed++;
758
759 /* Test write with three output buffer sizes: tight, same as input and
760 * longer than the input */
761 size_t obuf_sizes[3];
762 const size_t obuf_sizes_len = sizeof( obuf_sizes ) / sizeof( obuf_sizes[0] );
763 obuf_sizes[0] = a_bytes_trimmed;
764 obuf_sizes[1] = a_bytes;
765 obuf_sizes[2] = a_bytes + 8;
766
767 for( size_t i = 0; i < obuf_sizes_len; i++ )
768 {
769 ASSERT_ALLOC( obuf, obuf_sizes[i] );
770 TEST_EQUAL( 0, mbedtls_mpi_mod_write( &r, &m, obuf, obuf_sizes[i], endian ) );
771
772 /* Make sure that writing didn't corrupt the value of r */
773 ASSERT_COMPARE( r.p, r.limbs, r_copy.p, r_copy.limbs );
774
775 /* Set up reference output for checking the result */
776 ASSERT_ALLOC( ref_buf, obuf_sizes[i] );
777 switch( endian )
778 {
779 case MBEDTLS_MPI_MOD_EXT_REP_LE:
780 memcpy( ref_buf, input_A->x, a_bytes_trimmed );
781 break;
782 case MBEDTLS_MPI_MOD_EXT_REP_BE:
783 {
784 size_t a_offset = input_A->len - a_bytes_trimmed;
785 size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed;
786 memcpy( ref_buf + ref_offset, input_A->x + a_offset,
787 a_bytes_trimmed );
788 }
789 break;
790 default:
791 TEST_ASSERT( 0 );
792 }
793
794 /* Check the result */
795 ASSERT_COMPARE( obuf, obuf_sizes[i], ref_buf, obuf_sizes[i] );
796
797 mbedtls_free( ref_buf );
798 ref_buf = NULL;
799 mbedtls_free( obuf );
800 obuf = NULL;
801 }
802
Minos Galanakis8f242702022-11-10 16:56:02 +0000803exit:
804 mbedtls_mpi_mod_modulus_free( &m );
805 mbedtls_free( N );
806 mbedtls_free( R );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000807 mbedtls_free( R_COPY );
Janos Follath0020df92022-11-26 17:23:16 +0000808 mbedtls_free( obuf );
Minos Galanakis8f242702022-11-10 16:56:02 +0000809}
810/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000811/* END MERGE SLOT 7 */
812
813/* BEGIN MERGE SLOT 8 */
814
815/* END MERGE SLOT 8 */
816
817/* BEGIN MERGE SLOT 9 */
818
819/* END MERGE SLOT 9 */
820
821/* BEGIN MERGE SLOT 10 */
822
823/* END MERGE SLOT 10 */