blob: 4914e1d89a0e7dca0405edf1abc51196416bbf5a [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{
Gabor Mezeieca74662022-12-13 10:53:50 +0100112 mbedtls_mpi_uint *X = NULL;
Gabor Mezeieca74662022-12-13 10:53:50 +0100113
114 mbedtls_mpi_mod_modulus m;
115 mbedtls_mpi_mod_modulus_init( &m );
116
Gabor Mezei809baef2022-12-16 16:31:59 +0100117 TEST_EQUAL( test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ),
118 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100119
120 mbedtls_mpi_mod_residue rA;
Gabor Mezei809baef2022-12-16 16:31:59 +0100121 TEST_EQUAL( test_read_residue( &rA, &m, input_A, 0 ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100122
123 mbedtls_mpi_mod_residue rB;
Gabor Mezei809baef2022-12-16 16:31:59 +0100124 TEST_EQUAL( test_read_residue( &rB, &m, input_B, 0 ), 0 );
125
126 mbedtls_mpi_mod_residue rR;
127 TEST_EQUAL( test_read_residue( &rR, &m, result, 0 ), 0 );
128
129 const size_t limbs = m.limbs;
130 const size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
131
132 TEST_EQUAL( rA.limbs, limbs );
133 TEST_EQUAL( rB.limbs, limbs );
134 TEST_EQUAL( rR.limbs, limbs );
135
136 ASSERT_ALLOC( X, limbs );
Gabor Mezeieca74662022-12-13 10:53:50 +0100137
138 mbedtls_mpi_mod_residue rX;
139 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rX, &m, X, limbs ), 0 );
140
Gabor Mezeieca74662022-12-13 10:53:50 +0100141 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100142 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100143
144 /* alias X to A */
145 memcpy( rX.p, rA.p, bytes );
146 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rB, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100147 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100148
149 /* alias X to B */
150 memcpy( rX.p, rB.p, bytes );
151 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rX, &m ), 0);
Gabor Mezei809baef2022-12-16 16:31:59 +0100152 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100153
154 /* A == B: alias A and B */
155 if( memcmp( rA.p, rB.p, bytes ) == 0 )
156 {
157 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rA, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100158 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100159
160 /* X, A, B all aliased together */
161 memcpy( rX.p, rA.p, bytes );
162 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rX, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100163 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100164 }
165
166 /* A != B: test B * A */
167 else
168 {
169 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rB, &rA, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100170 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100171
172 /* B * A: alias X to A */
173 memcpy( rX.p, rA.p, bytes );
174 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rB, &rX, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100175 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100176
177 /* B + A: alias X to B */
178 memcpy( rX.p, rB.p, bytes );
179 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rA, &m ), 0 );
Gabor Mezei809baef2022-12-16 16:31:59 +0100180 ASSERT_COMPARE( rX.p, bytes, rR.p, bytes );
Gabor Mezeieca74662022-12-13 10:53:50 +0100181 }
182
183exit:
Gabor Mezei809baef2022-12-16 16:31:59 +0100184 mbedtls_free( rA.p );
185 mbedtls_free( rB.p );
186 mbedtls_free( rR.p );
Gabor Mezeieca74662022-12-13 10:53:50 +0100187 mbedtls_free( X );
Gabor Mezei809baef2022-12-16 16:31:59 +0100188 mbedtls_free( (mbedtls_mpi_uint *) m.p );
Gabor Mezeif9728132022-12-20 13:55:37 +0100189
190 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezeieca74662022-12-13 10:53:50 +0100191}
192/* END_CASE */
193
194/* BEGIN_CASE */
195void mpi_mod_mul_neg( char * input_A,
196 char * input_B,
197 char * input_N,
198 char * result,
199 int exp_ret )
200{
Gabor Mezeieca74662022-12-13 10:53:50 +0100201 mbedtls_mpi_uint *X = NULL;
Gabor Mezeieca74662022-12-13 10:53:50 +0100202
203 mbedtls_mpi_mod_modulus m;
204 mbedtls_mpi_mod_modulus_init( &m );
205
Gabor Mezei809baef2022-12-16 16:31:59 +0100206 TEST_EQUAL( test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ),
207 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100208
209 mbedtls_mpi_mod_residue rA;
Gabor Mezei809baef2022-12-16 16:31:59 +0100210 TEST_EQUAL( test_read_residue( &rA, &m, input_A, 1 ), 0 );
Gabor Mezeieca74662022-12-13 10:53:50 +0100211
212 mbedtls_mpi_mod_residue rB;
Gabor Mezei809baef2022-12-16 16:31:59 +0100213 TEST_EQUAL( test_read_residue( &rB, &m, input_B, 1 ), 0 );
214
215 mbedtls_mpi_mod_residue rR;
216 TEST_EQUAL( test_read_residue( &rR, &m, result, 1 ), 0 );
217
218 const size_t limbs = m.limbs;
219
220 ASSERT_ALLOC( X, limbs );
Gabor Mezeieca74662022-12-13 10:53:50 +0100221
222 mbedtls_mpi_mod_residue rX;
Gabor Mezei809baef2022-12-16 16:31:59 +0100223 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rX, &m, X, limbs ), 0 );
224 rX.limbs = rR.limbs;
Gabor Mezeieca74662022-12-13 10:53:50 +0100225
226 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &m ), exp_ret );
227
Gabor Mezei809baef2022-12-16 16:31:59 +0100228 mbedtls_mpi_mod_modulus fake_m;
229 mbedtls_mpi_mod_modulus_init( &fake_m );
230
Gabor Mezeieca74662022-12-13 10:53:50 +0100231 /* Check when m is not initialized */
232 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &fake_m ),
233 MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
234
235exit:
Gabor Mezei809baef2022-12-16 16:31:59 +0100236 mbedtls_free( rA.p );
237 mbedtls_free( rB.p );
238 mbedtls_free( rR.p );
Gabor Mezeieca74662022-12-13 10:53:50 +0100239 mbedtls_free( X );
Gabor Mezei809baef2022-12-16 16:31:59 +0100240 mbedtls_free( (mbedtls_mpi_uint *) m.p );
Gabor Mezeif9728132022-12-20 13:55:37 +0100241
242 mbedtls_mpi_mod_modulus_free( &m );
243 mbedtls_mpi_mod_modulus_free( &fake_m );
Gabor Mezeieca74662022-12-13 10:53:50 +0100244}
245/* END_CASE */
246
Janos Follath5933f692022-11-02 14:35:17 +0000247/* END MERGE SLOT 2 */
248
249/* BEGIN MERGE SLOT 3 */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000250/* BEGIN_CASE */
251void mpi_mod_sub( char * input_N,
252 char * input_A, char * input_B,
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000253 char * input_D, int expected_ret )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000254{
255 mbedtls_mpi_mod_residue a = { NULL, 0 };
256 mbedtls_mpi_mod_residue b = { NULL, 0 };
257 mbedtls_mpi_mod_residue d = { NULL, 0 };
258 mbedtls_mpi_mod_residue x = { NULL, 0 };
259 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000260
Tom Cosgrove62b20482022-12-01 14:27:37 +0000261 mbedtls_mpi_mod_modulus m;
262 mbedtls_mpi_mod_modulus_init( &m );
263
264 TEST_EQUAL( 0,
265 test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
266
267 /* test_read_residue() normally checks that inputs have the same number of
268 * limbs as the modulus. For negative testing we can ask it to skip this
269 * with a non-zero final parameter. */
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000270 TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
271 TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
272 TEST_EQUAL( 0, test_read_residue( &d, &m, input_D, expected_ret != 0 ) );
Tom Cosgrove62b20482022-12-01 14:27:37 +0000273
274 size_t limbs = m.limbs;
275 size_t bytes = limbs * sizeof( *X_raw );
276
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000277 if( expected_ret == 0 )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000278 {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000279 /* Negative test with too many limbs in output */
280 ASSERT_ALLOC( X_raw, limbs + 1 );
Tom Cosgrove62b20482022-12-01 14:27:37 +0000281
Tom Cosgrove62b20482022-12-01 14:27:37 +0000282 x.p = X_raw;
283 x.limbs = limbs + 1;
284 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
285 mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
286
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000287 mbedtls_free( X_raw );
288 X_raw = NULL;
289
290 /* Negative test with too few limbs in output */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000291 if( limbs > 1 )
292 {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000293 ASSERT_ALLOC( X_raw, limbs - 1 );
294
Tom Cosgrove62b20482022-12-01 14:27:37 +0000295 x.p = X_raw;
296 x.limbs = limbs - 1;
297 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
298 mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000299
300 mbedtls_free( X_raw );
301 X_raw = NULL;
Tom Cosgrove62b20482022-12-01 14:27:37 +0000302 }
303
304 /* Negative testing with too many/too few limbs in a and b is covered by
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000305 * manually-written test cases with expected_ret != 0. */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000306 }
307
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000308 ASSERT_ALLOC( X_raw, limbs );
309
Tom Cosgrove62b20482022-12-01 14:27:37 +0000310 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
311
312 /* a - b => Correct result, or expected error */
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000313 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
314 if( expected_ret != 0 )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000315 goto exit;
316
317 TEST_COMPARE_MPI_RESIDUES( x, d );
318
319 /* a - b: alias x to a => Correct result */
320 memcpy( x.p, a.p, bytes );
321 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &b, &m ) );
322 TEST_COMPARE_MPI_RESIDUES( x, d );
323
324 /* a - b: alias x to b => Correct result */
325 memcpy( x.p, b.p, bytes );
326 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &x, &m ) );
327 TEST_COMPARE_MPI_RESIDUES( x, d );
328
329 if ( memcmp( a.p, b.p, bytes ) == 0 )
330 {
331 /* a == b: alias a and b */
332
333 /* a - a => Correct result */
334 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &a, &m ) );
335 TEST_COMPARE_MPI_RESIDUES( x, d );
336
337 /* a - a: x, a, b all aliased together => Correct result */
338 memcpy( x.p, a.p, bytes );
339 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &x, &m ) );
340 TEST_COMPARE_MPI_RESIDUES( x, d );
341 }
342
343exit:
344 mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
345 mbedtls_mpi_mod_modulus_free( &m );
346
347 mbedtls_free( a.p );
348 mbedtls_free( b.p );
349 mbedtls_free( d.p );
350 mbedtls_free( X_raw );
351}
352/* END_CASE */
Tom Cosgrovedc197592022-12-15 16:59:40 +0000353
354/* BEGIN_CASE */
355void mpi_mod_inv_mont( char * input_N,
356 char * input_A, char * input_I,
357 int expected_ret )
358{
359 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
360 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
361 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
362 mbedtls_mpi_uint *X_raw = NULL;
363
364 mbedtls_mpi_mod_modulus N;
365 mbedtls_mpi_mod_modulus_init( &N );
366
367 TEST_EQUAL( 0,
368 test_read_modulus( &N, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
369
370 /* test_read_residue() normally checks that inputs have the same number of
371 * limbs as the modulus. For negative testing we can ask it to skip this
372 * with a non-zero final parameter. */
373 TEST_EQUAL( 0, test_read_residue( &a, &N, input_A, expected_ret != 0 ) );
374 TEST_EQUAL( 0, test_read_residue( &i, &N, input_I, expected_ret != 0 ) );
375
376 size_t limbs = N.limbs;
377 size_t bytes = limbs * sizeof( *X_raw );
378
379 ASSERT_ALLOC( X_raw, limbs );
380
381 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &N, X_raw, limbs ) );
382
383 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_inv( &x, &a, &N ) );
384 if( expected_ret == 0 )
385 {
386 TEST_COMPARE_MPI_RESIDUES( x, i );
387
388 /* a^-1: alias x to a => Correct result */
389 memcpy( x.p, a.p, bytes );
390 TEST_EQUAL( 0, mbedtls_mpi_mod_inv( &x, &x, &N ) );
391 TEST_COMPARE_MPI_RESIDUES( x, i );
392 }
393
394exit:
395 mbedtls_free( (void *)N.p ); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
396 mbedtls_mpi_mod_modulus_free( &N );
397
398 mbedtls_free( a.p );
399 mbedtls_free( i.p );
400 mbedtls_free( X_raw );
401}
402/* END_CASE */
403
404/* BEGIN_CASE */
405void mpi_mod_inv_non_mont( char * input_N,
406 char * input_A, char * input_I,
407 int expected_ret )
408{
409 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
410 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
411 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
412 mbedtls_mpi_uint *X_raw = NULL;
413
414 mbedtls_mpi_mod_modulus N;
415 mbedtls_mpi_mod_modulus_init( &N );
416
417 TEST_EQUAL( 0,
418 test_read_modulus( &N, MBEDTLS_MPI_MOD_REP_OPT_RED, input_N ) );
419
420 /* test_read_residue() normally checks that inputs have the same number of
421 * limbs as the modulus. For negative testing we can ask it to skip this
422 * with a non-zero final parameter. */
423 TEST_EQUAL( 0, test_read_residue( &a, &N, input_A, expected_ret != 0 ) );
424 TEST_EQUAL( 0, test_read_residue( &i, &N, input_I, expected_ret != 0 ) );
425
426 size_t limbs = N.limbs;
427 size_t bytes = limbs * sizeof( *X_raw );
428
429 ASSERT_ALLOC( X_raw, limbs );
430
431 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &N, X_raw, limbs ) );
432
433 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_inv( &x, &a, &N ) );
434 if( expected_ret == 0 )
435 {
436 TEST_COMPARE_MPI_RESIDUES( x, i );
437
438 /* a^-1: alias x to a => Correct result */
439 memcpy( x.p, a.p, bytes );
440 TEST_EQUAL( 0, mbedtls_mpi_mod_inv( &x, &x, &N ) );
441 TEST_COMPARE_MPI_RESIDUES( x, i );
442 }
443
444exit:
445 mbedtls_free( (void *)N.p ); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
446 mbedtls_mpi_mod_modulus_free( &N );
447
448 mbedtls_free( a.p );
449 mbedtls_free( i.p );
450 mbedtls_free( X_raw );
451}
452/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000453/* END MERGE SLOT 3 */
454
455/* BEGIN MERGE SLOT 4 */
456
457/* END MERGE SLOT 4 */
458
459/* BEGIN MERGE SLOT 5 */
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000460/* BEGIN_CASE */
461void mpi_mod_add( char * input_N,
462 char * input_A, char * input_B,
Werner Lewis25690a92022-12-13 17:17:34 +0000463 char * input_S, int expected_ret )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000464{
465 mbedtls_mpi_mod_residue a = { NULL, 0 };
466 mbedtls_mpi_mod_residue b = { NULL, 0 };
467 mbedtls_mpi_mod_residue s = { NULL, 0 };
468 mbedtls_mpi_mod_residue x = { NULL, 0 };
469 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000470
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000471 mbedtls_mpi_mod_modulus m;
472 mbedtls_mpi_mod_modulus_init( &m );
473
474 TEST_EQUAL( 0,
475 test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
476
477 /* test_read_residue() normally checks that inputs have the same number of
478 * limbs as the modulus. For negative testing we can ask it to skip this
479 * with a non-zero final parameter. */
Werner Lewis25690a92022-12-13 17:17:34 +0000480 TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
481 TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
482 TEST_EQUAL( 0, test_read_residue( &s, &m, input_S, expected_ret != 0 ) );
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000483
484 size_t limbs = m.limbs;
485 size_t bytes = limbs * sizeof( *X_raw );
486
Werner Lewis25690a92022-12-13 17:17:34 +0000487 if( expected_ret == 0 )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000488 {
489 /* Negative test with too many limbs in output */
Werner Lewis79341a42022-12-13 17:19:01 +0000490 ASSERT_ALLOC( X_raw, limbs + 1 );
491
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000492 x.p = X_raw;
493 x.limbs = limbs + 1;
494 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
495 mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
496
Werner Lewis79341a42022-12-13 17:19:01 +0000497 mbedtls_free( X_raw );
498 X_raw = NULL;
499
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000500 /* Negative test with too few limbs in output */
501 if( limbs > 1 )
502 {
Werner Lewis79341a42022-12-13 17:19:01 +0000503 ASSERT_ALLOC( X_raw, limbs - 1 );
504
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000505 x.p = X_raw;
506 x.limbs = limbs - 1;
507 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
508 mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
Werner Lewis79341a42022-12-13 17:19:01 +0000509
510 mbedtls_free( X_raw );
511 X_raw = NULL;
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000512 }
513
514 /* Negative testing with too many/too few limbs in a and b is covered by
515 * manually-written test cases with oret != 0. */
516 }
517
Werner Lewis79341a42022-12-13 17:19:01 +0000518 /* Allocate correct number of limbs for X_raw */
519 ASSERT_ALLOC( X_raw, limbs );
520
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000521 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
522
523 /* A + B => Correct result or expected error */
Werner Lewis25690a92022-12-13 17:17:34 +0000524 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
525 if( expected_ret != 0 )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000526 goto exit;
527
528 TEST_COMPARE_MPI_RESIDUES( x, s );
529
530 /* a + b: alias x to a => Correct result */
531 memcpy( x.p, a.p, bytes );
532 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &b, &m ) );
533 TEST_COMPARE_MPI_RESIDUES( x, s );
534
535 /* a + b: alias x to b => Correct result */
536 memcpy( x.p, b.p, bytes );
537 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &x, &m ) );
538 TEST_COMPARE_MPI_RESIDUES( x, s );
539
540 if ( memcmp( a.p, b.p, bytes ) == 0 )
541 {
542 /* a == b: alias a and b */
543
544 /* a + a => Correct result */
545 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &a, &m ) );
546 TEST_COMPARE_MPI_RESIDUES( x, s );
547
548 /* a + a: x, a, b all aliased together => Correct result */
549 memcpy( x.p, a.p, bytes );
550 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &x, &m ) );
551 TEST_COMPARE_MPI_RESIDUES( x, s );
552 }
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000553
554exit:
555 mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
556 mbedtls_mpi_mod_modulus_free( &m );
557
558 mbedtls_free( a.p );
559 mbedtls_free( b.p );
560 mbedtls_free( s.p );
561 mbedtls_free( X_raw );
562}
563/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000564/* END MERGE SLOT 5 */
565
566/* BEGIN MERGE SLOT 6 */
567
568/* END MERGE SLOT 6 */
569
570/* BEGIN MERGE SLOT 7 */
Minos Galanakis8f242702022-11-10 16:56:02 +0000571/* BEGIN_CASE */
Janos Follath91f3abd2022-11-26 11:47:14 +0000572void mpi_residue_setup( char * input_N, char * input_R, int ret )
Minos Galanakisa17ad482022-11-16 16:29:15 +0000573{
Minos Galanakisa17ad482022-11-16 16:29:15 +0000574 mbedtls_mpi_uint *N = NULL;
575 mbedtls_mpi_uint *R = NULL;
Minos Galanakisaed832a2022-11-24 09:09:47 +0000576 size_t n_limbs, r_limbs;
Minos Galanakisa17ad482022-11-16 16:29:15 +0000577 mbedtls_mpi_mod_modulus m;
578 mbedtls_mpi_mod_residue r;
579
Minos Galanakisa17ad482022-11-16 16:29:15 +0000580 mbedtls_mpi_mod_modulus_init( &m );
581
Minos Galanakisaed832a2022-11-24 09:09:47 +0000582 /* Allocate the memory for intermediate data structures */
Janos Follath91f3abd2022-11-26 11:47:14 +0000583 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
584 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &R, &r_limbs, input_R ) );
Minos Galanakisaed832a2022-11-24 09:09:47 +0000585
Minos Galanakisa17ad482022-11-16 16:29:15 +0000586 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
Janos Follath91295d22022-11-24 18:20:26 +0000587 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000588
Minos Galanakisaed832a2022-11-24 09:09:47 +0000589 TEST_EQUAL( ret, mbedtls_mpi_mod_residue_setup( &r, &m, R , r_limbs ) );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000590
Janos Follath91f3abd2022-11-26 11:47:14 +0000591 if ( ret == 0 )
592 {
593 TEST_EQUAL( r.limbs, r_limbs );
594 TEST_ASSERT( r.p == R );
595 }
596
Minos Galanakisa17ad482022-11-16 16:29:15 +0000597exit:
598 mbedtls_mpi_mod_modulus_free( &m );
599 mbedtls_free( N );
600 mbedtls_free( R );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000601}
602/* END_CASE */
Minos Galanakisaed832a2022-11-24 09:09:47 +0000603
Minos Galanakisa17ad482022-11-16 16:29:15 +0000604/* BEGIN_CASE */
Janos Follath339b4392022-11-26 12:20:41 +0000605void mpi_mod_io_neg( char * input_N, data_t * buf, int ret )
Minos Galanakis8f242702022-11-10 16:56:02 +0000606{
Minos Galanakis8f242702022-11-10 16:56:02 +0000607 mbedtls_mpi_uint *N = NULL;
608 mbedtls_mpi_uint *R = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000609
610 mbedtls_mpi_mod_modulus m;
Janos Follathe7190a22022-11-26 18:46:54 +0000611 mbedtls_mpi_mod_residue r = { NULL, 0 };
Minos Galanakis96070a52022-11-25 19:32:10 +0000612 mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
Minos Galanakis8f242702022-11-10 16:56:02 +0000613
Janos Follath799eaee2022-11-25 15:57:04 +0000614 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath799eaee2022-11-25 15:57:04 +0000615
Janos Follath339b4392022-11-26 12:20:41 +0000616 size_t n_limbs;
Minos Galanakis96070a52022-11-25 19:32:10 +0000617 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
Janos Follath339b4392022-11-26 12:20:41 +0000618 size_t r_limbs = n_limbs;
619 ASSERT_ALLOC( R, r_limbs );
Minos Galanakis8f242702022-11-10 16:56:02 +0000620
Janos Follathe7190a22022-11-26 18:46:54 +0000621 /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */
Janos Follath3e3fc912022-11-24 18:02:46 +0000622 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000623 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000624
Minos Galanakis96070a52022-11-25 19:32:10 +0000625 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000626 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000627
Janos Follathe7190a22022-11-26 18:46:54 +0000628 /* Set up modulus and test with residue->p == NULL */
Minos Galanakis96070a52022-11-25 19:32:10 +0000629 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
630 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000631
Minos Galanakis96070a52022-11-25 19:32:10 +0000632 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follathe7190a22022-11-26 18:46:54 +0000633 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000634 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follathe7190a22022-11-26 18:46:54 +0000635 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
636
637 /* Do the rest of the tests with a residue set up with the input data */
638 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R , r_limbs ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000639
Janos Follathd7bb3522022-11-26 14:59:27 +0000640 /* Fail for r_limbs < m->limbs */
641 r.limbs--;
642 TEST_ASSERT( r.limbs < m.limbs );
Minos Galanakis96070a52022-11-25 19:32:10 +0000643 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000644 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000645 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000646 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
Janos Follathd7bb3522022-11-26 14:59:27 +0000647 r.limbs++;
648
649 /* Fail for r_limbs > m->limbs */
650 m.limbs--;
651 TEST_ASSERT( r.limbs > m.limbs );
652 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
653 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
654 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
655 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
656 m.limbs++;
Minos Galanakis96070a52022-11-25 19:32:10 +0000657
658 /* Test the read */
Janos Follath566c91d2022-11-26 12:05:50 +0000659 TEST_EQUAL( ret, mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000660
661 /* Test write overflow only when the representation is large and read is successful */
Janos Follath6ef582f2022-11-26 14:19:02 +0000662 if ( r.limbs > 1 && ret == 0 )
Minos Galanakis96070a52022-11-25 19:32:10 +0000663 TEST_EQUAL( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL,
Janos Follath566c91d2022-11-26 12:05:50 +0000664 mbedtls_mpi_mod_write( &r, &m, buf->x, 1, endian ) );
Janos Follathd7bb3522022-11-26 14:59:27 +0000665
Minos Galanakis8f242702022-11-10 16:56:02 +0000666exit:
Janos Follathd7bb3522022-11-26 14:59:27 +0000667 mbedtls_mpi_mod_residue_release( &r );
Minos Galanakis8f242702022-11-10 16:56:02 +0000668 mbedtls_mpi_mod_modulus_free( &m );
Minos Galanakis8f242702022-11-10 16:56:02 +0000669 mbedtls_free( N );
670 mbedtls_free( R );
Minos Galanakis8f242702022-11-10 16:56:02 +0000671}
672/* END_CASE */
673
674/* BEGIN_CASE */
Janos Follath3e3fc912022-11-24 18:02:46 +0000675void mpi_mod_io( char * input_N, data_t * input_A, int endian )
Minos Galanakis8f242702022-11-10 16:56:02 +0000676{
677 mbedtls_mpi_uint *N = NULL;
678 mbedtls_mpi_uint *R = NULL;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000679 mbedtls_mpi_uint *R_COPY = NULL;
Janos Follath0020df92022-11-26 17:23:16 +0000680 unsigned char *obuf = NULL;
681 unsigned char *ref_buf = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000682 mbedtls_mpi_mod_modulus m;
683 mbedtls_mpi_mod_residue r;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000684 mbedtls_mpi_mod_residue r_copy;
Minos Galanakis8f242702022-11-10 16:56:02 +0000685 size_t n_limbs, n_bytes, a_bytes;
686
Janos Follath799eaee2022-11-25 15:57:04 +0000687 mbedtls_mpi_mod_modulus_init( &m );
688
Minos Galanakis8f242702022-11-10 16:56:02 +0000689 /* Read inputs */
690 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
691 n_bytes = n_limbs * sizeof( mbedtls_mpi_uint );
Janos Follath6ef582f2022-11-26 14:19:02 +0000692 a_bytes = input_A->len;
Minos Galanakis8f242702022-11-10 16:56:02 +0000693
694 /* Allocate the memory for intermediate data structures */
695 ASSERT_ALLOC( R, n_bytes );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000696 ASSERT_ALLOC( R_COPY, n_bytes );
Minos Galanakis8f242702022-11-10 16:56:02 +0000697
698 /* Test that input's size is not greater to modulo's */
Janos Follath6ef582f2022-11-26 14:19:02 +0000699 TEST_LE_U( a_bytes, n_bytes );
Minos Galanakis8f242702022-11-10 16:56:02 +0000700
701 /* Init Structures */
Janos Follath91295d22022-11-24 18:20:26 +0000702 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
Minos Galanakis8f242702022-11-10 16:56:02 +0000703 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
704
705 /* Enforcing p_limbs >= m->limbs */
Janos Follath3e3fc912022-11-24 18:02:46 +0000706 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R, n_limbs ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000707
Janos Follath3e3fc912022-11-24 18:02:46 +0000708 TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r, &m, input_A->x, input_A->len,
709 endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000710
Janos Follath0020df92022-11-26 17:23:16 +0000711 /* Read a copy for checking that writing didn't change the value of r */
712 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r_copy, &m,
713 R_COPY, n_limbs ) );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000714 TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r_copy, &m, input_A->x, input_A->len,
715 endian ) );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000716
Janos Follath0020df92022-11-26 17:23:16 +0000717 /* Get number of bytes without leading zeroes */
718 size_t a_bytes_trimmed = a_bytes;
719 while( a_bytes_trimmed > 0 )
720 {
721 unsigned char* r_byte_array = (unsigned char*) r.p;
722 if( r_byte_array[--a_bytes_trimmed] != 0 )
723 break;
724 }
725 a_bytes_trimmed++;
726
727 /* Test write with three output buffer sizes: tight, same as input and
728 * longer than the input */
729 size_t obuf_sizes[3];
730 const size_t obuf_sizes_len = sizeof( obuf_sizes ) / sizeof( obuf_sizes[0] );
731 obuf_sizes[0] = a_bytes_trimmed;
732 obuf_sizes[1] = a_bytes;
733 obuf_sizes[2] = a_bytes + 8;
734
735 for( size_t i = 0; i < obuf_sizes_len; i++ )
736 {
737 ASSERT_ALLOC( obuf, obuf_sizes[i] );
738 TEST_EQUAL( 0, mbedtls_mpi_mod_write( &r, &m, obuf, obuf_sizes[i], endian ) );
739
740 /* Make sure that writing didn't corrupt the value of r */
741 ASSERT_COMPARE( r.p, r.limbs, r_copy.p, r_copy.limbs );
742
743 /* Set up reference output for checking the result */
744 ASSERT_ALLOC( ref_buf, obuf_sizes[i] );
745 switch( endian )
746 {
747 case MBEDTLS_MPI_MOD_EXT_REP_LE:
748 memcpy( ref_buf, input_A->x, a_bytes_trimmed );
749 break;
750 case MBEDTLS_MPI_MOD_EXT_REP_BE:
751 {
752 size_t a_offset = input_A->len - a_bytes_trimmed;
753 size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed;
754 memcpy( ref_buf + ref_offset, input_A->x + a_offset,
755 a_bytes_trimmed );
756 }
757 break;
758 default:
759 TEST_ASSERT( 0 );
760 }
761
762 /* Check the result */
763 ASSERT_COMPARE( obuf, obuf_sizes[i], ref_buf, obuf_sizes[i] );
764
765 mbedtls_free( ref_buf );
766 ref_buf = NULL;
767 mbedtls_free( obuf );
768 obuf = NULL;
769 }
770
Minos Galanakis8f242702022-11-10 16:56:02 +0000771exit:
772 mbedtls_mpi_mod_modulus_free( &m );
773 mbedtls_free( N );
774 mbedtls_free( R );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000775 mbedtls_free( R_COPY );
Janos Follath0020df92022-11-26 17:23:16 +0000776 mbedtls_free( obuf );
Minos Galanakis8f242702022-11-10 16:56:02 +0000777}
778/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000779/* END MERGE SLOT 7 */
780
781/* BEGIN MERGE SLOT 8 */
782
783/* END MERGE SLOT 8 */
784
785/* BEGIN MERGE SLOT 9 */
786
787/* END MERGE SLOT 9 */
788
789/* BEGIN MERGE SLOT 10 */
790
791/* END MERGE SLOT 10 */