blob: 9d0fe939f4a6356652ffea40f23763c3256b5c91 [file] [log] [blame]
Tom Rini0344c602024-10-08 13:56:50 -06001/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4#include "bignum_mod.h"
5#include "bignum_mod_raw.h"
6#include "constant_time_internal.h"
7#include "test/constant_flow.h"
8
9#define TEST_COMPARE_MPI_RESIDUES(a, b) \
10 TEST_MEMORY_COMPARE((a).p, (a).limbs * sizeof(mbedtls_mpi_uint), \
11 (b).p, (b).limbs * sizeof(mbedtls_mpi_uint))
12
13static int test_read_residue(mbedtls_mpi_mod_residue *r,
14 const mbedtls_mpi_mod_modulus *m,
15 char *input,
16 int skip_limbs_and_value_checks)
17{
18 mbedtls_mpi_uint *p = NULL;
19 size_t limbs;
20
21 int ret = mbedtls_test_read_mpi_core(&p, &limbs, input);
22 if (ret != 0) {
23 return ret;
24 }
25
26 if (skip_limbs_and_value_checks) {
27 r->p = p;
28 r->limbs = limbs;
29 return 0;
30 }
31
32 /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */
33 return mbedtls_mpi_mod_residue_setup(r, m, p, limbs);
34}
35/* END_HEADER */
36
37/* BEGIN_DEPENDENCIES
38 * depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_ECP_WITH_MPI_UINT
39 * END_DEPENDENCIES
40 */
41
42/* BEGIN_CASE */
43void mpi_mod_setup(int int_rep, int iret)
44{
45 #define MLIMBS 8
46 mbedtls_mpi_uint mp[MLIMBS];
47 mbedtls_mpi_mod_modulus m;
48 int ret;
49
50 memset(mp, 0xFF, sizeof(mp));
51
52 mbedtls_mpi_mod_modulus_init(&m);
53
54 switch (int_rep) {
55 case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
56 ret = mbedtls_mpi_mod_modulus_setup(&m, mp, MLIMBS);
57 break;
58 case MBEDTLS_MPI_MOD_REP_OPT_RED:
59 ret = mbedtls_mpi_mod_optred_modulus_setup(&m, mp, MLIMBS, NULL);
60 break;
61 default:
62 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
63 break;
64 }
65
66 TEST_EQUAL(ret, iret);
67
68 /* Only test if the constants have been set-up */
69 if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
70 /* Test that the consts have been calculated */
71 TEST_ASSERT(m.rep.mont.rr != NULL);
72 TEST_ASSERT(m.rep.mont.mm != 0);
73
74 }
75
76 /* Address sanitiser should catch if we try to free mp */
77 mbedtls_mpi_mod_modulus_free(&m);
78
79 /* Make sure that the modulus doesn't have reference to mp anymore */
80 TEST_ASSERT(m.p != mp);
81
82 /* Only test if the constants have been set-up */
83 if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
84 /* Verify the data and pointers allocated have been properly wiped */
85 TEST_ASSERT(m.rep.mont.rr == NULL);
86 TEST_ASSERT(m.rep.mont.mm == 0);
87 }
88exit:
89 /* It should be safe to call an mbedtls free several times */
90 mbedtls_mpi_mod_modulus_free(&m);
91
92 #undef MLIMBS
93}
94/* END_CASE */
95
96/* BEGIN_CASE */
97void mpi_mod_mul(char *input_A,
98 char *input_B,
99 char *input_N,
100 char *result)
101{
102 mbedtls_mpi_uint *X = NULL;
103
104 mbedtls_mpi_mod_residue rA = { NULL, 0 };
105 mbedtls_mpi_mod_residue rB = { NULL, 0 };
106 mbedtls_mpi_mod_residue rR = { NULL, 0 };
107 mbedtls_mpi_mod_residue rX = { NULL, 0 };
108
109 mbedtls_mpi_mod_modulus m;
110 mbedtls_mpi_mod_modulus_init(&m);
111
112 TEST_EQUAL(mbedtls_test_read_mpi_modulus(&m, input_N,
113 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
114
115 TEST_EQUAL(test_read_residue(&rA, &m, input_A, 0), 0);
116 TEST_EQUAL(test_read_residue(&rB, &m, input_B, 0), 0);
117 TEST_EQUAL(test_read_residue(&rR, &m, result, 0), 0);
118
119 const size_t limbs = m.limbs;
120 const size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
121
122 TEST_EQUAL(rA.limbs, limbs);
123 TEST_EQUAL(rB.limbs, limbs);
124 TEST_EQUAL(rR.limbs, limbs);
125
126 TEST_CALLOC(X, limbs);
127
128 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0);
129
130 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), 0);
131 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
132
133 /* alias X to A */
134 memcpy(rX.p, rA.p, bytes);
135 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rB, &m), 0);
136 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
137
138 /* alias X to B */
139 memcpy(rX.p, rB.p, bytes);
140 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rX, &m), 0);
141 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
142
143 /* A == B: alias A and B */
144 if (memcmp(rA.p, rB.p, bytes) == 0) {
145 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA, &m), 0);
146 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
147
148 /* X, A, B all aliased together */
149 memcpy(rX.p, rA.p, bytes);
150 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rX, &m), 0);
151 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
152 }
153 /* A != B: test B * A */
154 else {
155 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rA, &m), 0);
156 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
157
158 /* B * A: alias X to A */
159 memcpy(rX.p, rA.p, bytes);
160 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rX, &m), 0);
161 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
162
163 /* B + A: alias X to B */
164 memcpy(rX.p, rB.p, bytes);
165 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rA, &m), 0);
166 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes);
167 }
168
169exit:
170 mbedtls_free(rA.p);
171 mbedtls_free(rB.p);
172 mbedtls_free(rR.p);
173 mbedtls_free(X);
174 mbedtls_free((mbedtls_mpi_uint *) m.p);
175
176 mbedtls_mpi_mod_modulus_free(&m);
177}
178/* END_CASE */
179
180/* BEGIN_CASE */
181void mpi_mod_mul_neg(char *input_A,
182 char *input_B,
183 char *input_N,
184 char *result,
185 int exp_ret)
186{
187 mbedtls_mpi_uint *X = NULL;
188
189 mbedtls_mpi_mod_residue rA = { NULL, 0 };
190 mbedtls_mpi_mod_residue rB = { NULL, 0 };
191 mbedtls_mpi_mod_residue rR = { NULL, 0 };
192 mbedtls_mpi_mod_residue rX = { NULL, 0 };
193
194 mbedtls_mpi_mod_modulus m;
195 mbedtls_mpi_mod_modulus_init(&m);
196
197 mbedtls_mpi_mod_modulus fake_m;
198 mbedtls_mpi_mod_modulus_init(&fake_m);
199
200 TEST_EQUAL(mbedtls_test_read_mpi_modulus(&m, input_N,
201 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
202
203 TEST_EQUAL(test_read_residue(&rA, &m, input_A, 1), 0);
204 TEST_EQUAL(test_read_residue(&rB, &m, input_B, 1), 0);
205 TEST_EQUAL(test_read_residue(&rR, &m, result, 1), 0);
206
207 const size_t limbs = m.limbs;
208
209 TEST_CALLOC(X, limbs);
210
211 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0);
212 rX.limbs = rR.limbs;
213
214 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), exp_ret);
215
216 /* Check when m is not initialized */
217 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &fake_m),
218 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
219
220exit:
221 mbedtls_free(rA.p);
222 mbedtls_free(rB.p);
223 mbedtls_free(rR.p);
224 mbedtls_free(X);
225 mbedtls_free((mbedtls_mpi_uint *) m.p);
226
227 mbedtls_mpi_mod_modulus_free(&m);
228 mbedtls_mpi_mod_modulus_free(&fake_m);
229}
230/* END_CASE */
231
232/* BEGIN_CASE */
233void mpi_mod_sub(char *input_N,
234 char *input_A, char *input_B,
235 char *input_D, int expected_ret)
236{
237 mbedtls_mpi_mod_residue a = { NULL, 0 };
238 mbedtls_mpi_mod_residue b = { NULL, 0 };
239 mbedtls_mpi_mod_residue d = { NULL, 0 };
240 mbedtls_mpi_mod_residue x = { NULL, 0 };
241 mbedtls_mpi_uint *X_raw = NULL;
242
243 mbedtls_mpi_mod_modulus m;
244 mbedtls_mpi_mod_modulus_init(&m);
245
246 TEST_EQUAL(0,
247 mbedtls_test_read_mpi_modulus(&m, input_N,
248 MBEDTLS_MPI_MOD_REP_MONTGOMERY));
249
250 /* test_read_residue() normally checks that inputs have the same number of
251 * limbs as the modulus. For negative testing we can ask it to skip this
252 * with a non-zero final parameter. */
253 TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0));
254 TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0));
255 TEST_EQUAL(0, test_read_residue(&d, &m, input_D, expected_ret != 0));
256
257 size_t limbs = m.limbs;
258 size_t bytes = limbs * sizeof(*X_raw);
259
260 if (expected_ret == 0) {
261 /* Negative test with too many limbs in output */
262 TEST_CALLOC(X_raw, limbs + 1);
263
264 x.p = X_raw;
265 x.limbs = limbs + 1;
266 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
267 mbedtls_mpi_mod_sub(&x, &a, &b, &m));
268
269 mbedtls_free(X_raw);
270 X_raw = NULL;
271
272 /* Negative test with too few limbs in output */
273 if (limbs > 1) {
274 TEST_CALLOC(X_raw, limbs - 1);
275
276 x.p = X_raw;
277 x.limbs = limbs - 1;
278 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
279 mbedtls_mpi_mod_sub(&x, &a, &b, &m));
280
281 mbedtls_free(X_raw);
282 X_raw = NULL;
283 }
284
285 /* Negative testing with too many/too few limbs in a and b is covered by
286 * manually-written test cases with expected_ret != 0. */
287 }
288
289 TEST_CALLOC(X_raw, limbs);
290
291 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs));
292
293 /* a - b => Correct result, or expected error */
294 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_sub(&x, &a, &b, &m));
295 if (expected_ret != 0) {
296 goto exit;
297 }
298
299 TEST_COMPARE_MPI_RESIDUES(x, d);
300
301 /* a - b: alias x to a => Correct result */
302 memcpy(x.p, a.p, bytes);
303 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &b, &m));
304 TEST_COMPARE_MPI_RESIDUES(x, d);
305
306 /* a - b: alias x to b => Correct result */
307 memcpy(x.p, b.p, bytes);
308 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &x, &m));
309 TEST_COMPARE_MPI_RESIDUES(x, d);
310
311 if (memcmp(a.p, b.p, bytes) == 0) {
312 /* a == b: alias a and b */
313
314 /* a - a => Correct result */
315 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &a, &m));
316 TEST_COMPARE_MPI_RESIDUES(x, d);
317
318 /* a - a: x, a, b all aliased together => Correct result */
319 memcpy(x.p, a.p, bytes);
320 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &x, &m));
321 TEST_COMPARE_MPI_RESIDUES(x, d);
322 }
323
324exit:
325 mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
326 mbedtls_mpi_mod_modulus_free(&m);
327
328 mbedtls_free(a.p);
329 mbedtls_free(b.p);
330 mbedtls_free(d.p);
331 mbedtls_free(X_raw);
332}
333/* END_CASE */
334
335/* BEGIN_CASE */
336void mpi_mod_inv_mont(char *input_N,
337 char *input_A, char *input_I,
338 int expected_ret)
339{
340 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
341 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
342 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
343 mbedtls_mpi_uint *X_raw = NULL;
344
345 mbedtls_mpi_mod_modulus N;
346 mbedtls_mpi_mod_modulus_init(&N);
347
348 TEST_EQUAL(0,
349 mbedtls_test_read_mpi_modulus(&N, input_N,
350 MBEDTLS_MPI_MOD_REP_MONTGOMERY));
351
352 /* test_read_residue() normally checks that inputs have the same number of
353 * limbs as the modulus. For negative testing we can ask it to skip this
354 * with a non-zero final parameter. */
355 TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0));
356 TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0));
357
358 size_t limbs = N.limbs;
359 size_t bytes = limbs * sizeof(*X_raw);
360
361 TEST_CALLOC(X_raw, limbs);
362
363 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs));
364
365 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N));
366 if (expected_ret == 0) {
367 TEST_COMPARE_MPI_RESIDUES(x, i);
368
369 /* a^-1: alias x to a => Correct result */
370 memcpy(x.p, a.p, bytes);
371 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N));
372 TEST_COMPARE_MPI_RESIDUES(x, i);
373 }
374
375exit:
376 mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
377 mbedtls_mpi_mod_modulus_free(&N);
378
379 mbedtls_free(a.p);
380 mbedtls_free(i.p);
381 mbedtls_free(X_raw);
382}
383/* END_CASE */
384
385/* BEGIN_CASE */
386void mpi_mod_inv_non_mont(char *input_N,
387 char *input_A, char *input_I,
388 int expected_ret)
389{
390 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
391 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
392 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
393 mbedtls_mpi_uint *X_raw = NULL;
394
395 mbedtls_mpi_mod_modulus N;
396 mbedtls_mpi_mod_modulus_init(&N);
397
398 TEST_EQUAL(0,
399 mbedtls_test_read_mpi_modulus(&N, input_N,
400 MBEDTLS_MPI_MOD_REP_OPT_RED));
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 TEST_CALLOC(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 TEST_COMPARE_MPI_RESIDUES(x, i);
418
419 /* a^-1: alias x to a => Correct result */
420 memcpy(x.p, a.p, bytes);
421 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N));
422 TEST_COMPARE_MPI_RESIDUES(x, i);
423 }
424
425exit:
426 mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
427 mbedtls_mpi_mod_modulus_free(&N);
428
429 mbedtls_free(a.p);
430 mbedtls_free(i.p);
431 mbedtls_free(X_raw);
432}
433/* END_CASE */
434
435/* BEGIN_CASE */
436void mpi_mod_add(char *input_N,
437 char *input_A, char *input_B,
438 char *input_S, int expected_ret)
439{
440 mbedtls_mpi_mod_residue a = { NULL, 0 };
441 mbedtls_mpi_mod_residue b = { NULL, 0 };
442 mbedtls_mpi_mod_residue s = { NULL, 0 };
443 mbedtls_mpi_mod_residue x = { NULL, 0 };
444 mbedtls_mpi_uint *X_raw = NULL;
445
446 mbedtls_mpi_mod_modulus m;
447 mbedtls_mpi_mod_modulus_init(&m);
448
449 TEST_EQUAL(0,
450 mbedtls_test_read_mpi_modulus(&m, input_N,
451 MBEDTLS_MPI_MOD_REP_MONTGOMERY));
452
453 /* test_read_residue() normally checks that inputs have the same number of
454 * limbs as the modulus. For negative testing we can ask it to skip this
455 * with a non-zero final parameter. */
456 TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0));
457 TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0));
458 TEST_EQUAL(0, test_read_residue(&s, &m, input_S, expected_ret != 0));
459
460 size_t limbs = m.limbs;
461 size_t bytes = limbs * sizeof(*X_raw);
462
463 if (expected_ret == 0) {
464 /* Negative test with too many limbs in output */
465 TEST_CALLOC(X_raw, limbs + 1);
466
467 x.p = X_raw;
468 x.limbs = limbs + 1;
469 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
470 mbedtls_mpi_mod_add(&x, &a, &b, &m));
471
472 mbedtls_free(X_raw);
473 X_raw = NULL;
474
475 /* Negative test with too few limbs in output */
476 if (limbs > 1) {
477 TEST_CALLOC(X_raw, limbs - 1);
478
479 x.p = X_raw;
480 x.limbs = limbs - 1;
481 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
482 mbedtls_mpi_mod_add(&x, &a, &b, &m));
483
484 mbedtls_free(X_raw);
485 X_raw = NULL;
486 }
487
488 /* Negative testing with too many/too few limbs in a and b is covered by
489 * manually-written test cases with oret != 0. */
490 }
491
492 /* Allocate correct number of limbs for X_raw */
493 TEST_CALLOC(X_raw, limbs);
494
495 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs));
496
497 /* A + B => Correct result or expected error */
498 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_add(&x, &a, &b, &m));
499 if (expected_ret != 0) {
500 goto exit;
501 }
502
503 TEST_COMPARE_MPI_RESIDUES(x, s);
504
505 /* a + b: alias x to a => Correct result */
506 memcpy(x.p, a.p, bytes);
507 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &b, &m));
508 TEST_COMPARE_MPI_RESIDUES(x, s);
509
510 /* a + b: alias x to b => Correct result */
511 memcpy(x.p, b.p, bytes);
512 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &x, &m));
513 TEST_COMPARE_MPI_RESIDUES(x, s);
514
515 if (memcmp(a.p, b.p, bytes) == 0) {
516 /* a == b: alias a and b */
517
518 /* a + a => Correct result */
519 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &a, &m));
520 TEST_COMPARE_MPI_RESIDUES(x, s);
521
522 /* a + a: x, a, b all aliased together => Correct result */
523 memcpy(x.p, a.p, bytes);
524 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &x, &m));
525 TEST_COMPARE_MPI_RESIDUES(x, s);
526 }
527
528exit:
529 mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
530 mbedtls_mpi_mod_modulus_free(&m);
531
532 mbedtls_free(a.p);
533 mbedtls_free(b.p);
534 mbedtls_free(s.p);
535 mbedtls_free(X_raw);
536}
537/* END_CASE */
538
539/* BEGIN_CASE */
540void mpi_residue_setup(char *input_N, char *input_R, int ret)
541{
542 mbedtls_mpi_uint *N = NULL;
543 mbedtls_mpi_uint *R = NULL;
544 size_t n_limbs, r_limbs;
545 mbedtls_mpi_mod_modulus m;
546 mbedtls_mpi_mod_residue r;
547
548 mbedtls_mpi_mod_modulus_init(&m);
549
550 /* Allocate the memory for intermediate data structures */
551 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
552 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&R, &r_limbs, input_R));
553
554 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs));
555
556 TEST_EQUAL(ret, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs));
557
558 if (ret == 0) {
559 TEST_EQUAL(r.limbs, r_limbs);
560 TEST_ASSERT(r.p == R);
561 }
562
563exit:
564 mbedtls_mpi_mod_modulus_free(&m);
565 mbedtls_free(N);
566 mbedtls_free(R);
567}
568/* END_CASE */
569
570/* BEGIN_CASE */
571void mpi_mod_io_neg(char *input_N, data_t *buf, int ret)
572{
573 mbedtls_mpi_uint *N = NULL;
574 mbedtls_mpi_uint *R = NULL;
575
576 mbedtls_mpi_mod_modulus m;
577 mbedtls_mpi_mod_residue r = { NULL, 0 };
578 mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
579
580 mbedtls_mpi_mod_modulus_init(&m);
581
582 size_t n_limbs;
583 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
584 size_t r_limbs = n_limbs;
585 TEST_CALLOC(R, r_limbs);
586
587 /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */
588 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
589 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
590
591 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
592 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
593
594 /* Set up modulus and test with residue->p == NULL */
595 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs));
596
597 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
598 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
599 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
600 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
601
602 /* Do the rest of the tests with a residue set up with the input data */
603 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs));
604
605 /* Fail for r_limbs < m->limbs */
606 r.limbs--;
607 TEST_ASSERT(r.limbs < m.limbs);
608 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
609 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
610 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
611 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
612 r.limbs++;
613
614 /* Fail for r_limbs > m->limbs */
615 m.limbs--;
616 TEST_ASSERT(r.limbs > m.limbs);
617 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
618 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
619 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
620 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
621 m.limbs++;
622
623 /* Test the read */
624 TEST_EQUAL(ret, mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
625
626 /* Test write overflow only when the representation is large and read is successful */
627 if (r.limbs > 1 && ret == 0) {
628 TEST_EQUAL(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL,
629 mbedtls_mpi_mod_write(&r, &m, buf->x, 1, endian));
630 }
631
632exit:
633 mbedtls_mpi_mod_residue_release(&r);
634 mbedtls_mpi_mod_modulus_free(&m);
635 mbedtls_free(N);
636 mbedtls_free(R);
637}
638/* END_CASE */
639
640/* BEGIN_CASE */
641void mpi_mod_io(char *input_N, data_t *input_A, int endian)
642{
643 mbedtls_mpi_uint *N = NULL;
644 mbedtls_mpi_uint *R = NULL;
645 mbedtls_mpi_uint *R_COPY = NULL;
646 unsigned char *obuf = NULL;
647 unsigned char *ref_buf = NULL;
648 mbedtls_mpi_mod_modulus m;
649 mbedtls_mpi_mod_residue r;
650 mbedtls_mpi_mod_residue r_copy;
651 size_t n_limbs, n_bytes, a_bytes;
652
653 mbedtls_mpi_mod_modulus_init(&m);
654
655 /* Read inputs */
656 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
657 n_bytes = n_limbs * sizeof(mbedtls_mpi_uint);
658 a_bytes = input_A->len;
659
660 /* Allocate the memory for intermediate data structures */
661 TEST_CALLOC(R, n_bytes);
662 TEST_CALLOC(R_COPY, n_bytes);
663
664 /* Test that input's size is not greater to modulo's */
665 TEST_LE_U(a_bytes, n_bytes);
666
667 /* Init Structures */
668 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs));
669
670 /* Enforcing p_limbs >= m->limbs */
671 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, n_limbs));
672
673 TEST_EQUAL(0, mbedtls_mpi_mod_read(&r, &m, input_A->x, input_A->len,
674 endian));
675
676 /* Read a copy for checking that writing didn't change the value of r */
677 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r_copy, &m,
678 R_COPY, n_limbs));
679 TEST_EQUAL(0, mbedtls_mpi_mod_read(&r_copy, &m, input_A->x, input_A->len,
680 endian));
681
682 /* Get number of bytes without leading zeroes */
683 size_t a_bytes_trimmed = a_bytes;
684 while (a_bytes_trimmed > 0) {
685 unsigned char *r_byte_array = (unsigned char *) r.p;
686 if (r_byte_array[--a_bytes_trimmed] != 0) {
687 break;
688 }
689 }
690 a_bytes_trimmed++;
691
692 /* Test write with three output buffer sizes: tight, same as input and
693 * longer than the input */
694 size_t obuf_sizes[3];
695 const size_t obuf_sizes_len = sizeof(obuf_sizes) / sizeof(obuf_sizes[0]);
696 obuf_sizes[0] = a_bytes_trimmed;
697 obuf_sizes[1] = a_bytes;
698 obuf_sizes[2] = a_bytes + 8;
699
700 for (size_t i = 0; i < obuf_sizes_len; i++) {
701 TEST_CALLOC(obuf, obuf_sizes[i]);
702 TEST_EQUAL(0, mbedtls_mpi_mod_write(&r, &m, obuf, obuf_sizes[i], endian));
703
704 /* Make sure that writing didn't corrupt the value of r */
705 TEST_MEMORY_COMPARE(r.p, r.limbs, r_copy.p, r_copy.limbs);
706
707 /* Set up reference output for checking the result */
708 TEST_CALLOC(ref_buf, obuf_sizes[i]);
709 switch (endian) {
710 case MBEDTLS_MPI_MOD_EXT_REP_LE:
711 memcpy(ref_buf, input_A->x, a_bytes_trimmed);
712 break;
713 case MBEDTLS_MPI_MOD_EXT_REP_BE:
714 {
715 size_t a_offset = input_A->len - a_bytes_trimmed;
716 size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed;
717 memcpy(ref_buf + ref_offset, input_A->x + a_offset,
718 a_bytes_trimmed);
719 }
720 break;
721 default:
722 TEST_ASSERT(0);
723 }
724
725 /* Check the result */
726 TEST_MEMORY_COMPARE(obuf, obuf_sizes[i], ref_buf, obuf_sizes[i]);
727
728 mbedtls_free(ref_buf);
729 ref_buf = NULL;
730 mbedtls_free(obuf);
731 obuf = NULL;
732 }
733
734exit:
735 mbedtls_mpi_mod_modulus_free(&m);
736 mbedtls_free(N);
737 mbedtls_free(R);
738 mbedtls_free(R_COPY);
739 mbedtls_free(obuf);
740 mbedtls_free(ref_buf);
741}
742/* END_CASE */