blob: ded4c0cb4c8fadd3074c785517e7dd4157637c14 [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
Gilles Peskine449bd832023-01-11 14:50:10 +01009#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))
Tom Cosgrove62b20482022-12-01 14:27:37 +000012
Gilles Peskine449bd832023-01-11 14:50:10 +010013static 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
Gilles Peskine449bd832023-01-11 14:50:10 +010020 int ret = mbedtls_test_read_mpi_core(&p, &limbs, input);
21 if (ret != 0) {
22 return ret;
23 }
Tom Cosgrove62b20482022-12-01 14:27:37 +000024
Gilles Peskine449bd832023-01-11 14:50:10 +010025 return mbedtls_mpi_mod_modulus_setup(m, p, limbs, int_rep);
Tom Cosgrove62b20482022-12-01 14:27:37 +000026}
27
Gilles Peskine449bd832023-01-11 14:50:10 +010028static int test_read_residue(mbedtls_mpi_mod_residue *r,
29 const mbedtls_mpi_mod_modulus *m,
30 char *input,
31 int skip_limbs_and_value_checks)
Tom Cosgrove62b20482022-12-01 14:27:37 +000032{
33 mbedtls_mpi_uint *p = NULL;
34 size_t limbs;
35
Gilles Peskine449bd832023-01-11 14:50:10 +010036 int ret = mbedtls_test_read_mpi_core(&p, &limbs, input);
37 if (ret != 0) {
38 return ret;
39 }
Tom Cosgrove62b20482022-12-01 14:27:37 +000040
Gilles Peskine449bd832023-01-11 14:50:10 +010041 if (skip_limbs_and_value_checks) {
Tom Cosgrove62b20482022-12-01 14:27:37 +000042 r->p = p;
43 r->limbs = limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +010044 return 0;
Tom Cosgrove62b20482022-12-01 14:27:37 +000045 }
46
47 /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */
Gilles Peskine449bd832023-01-11 14:50:10 +010048 return mbedtls_mpi_mod_residue_setup(r, m, p, limbs);
Tom Cosgrove62b20482022-12-01 14:27:37 +000049}
Werner Lewis0c6ea122022-09-30 13:02:16 +010050/* END_HEADER */
51
52/* BEGIN_DEPENDENCIES
53 * depends_on:MBEDTLS_BIGNUM_C
54 * END_DEPENDENCIES
55 */
56
57/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010058void mpi_mod_setup(int int_rep, int iret)
Werner Lewis0c6ea122022-09-30 13:02:16 +010059{
60 #define MLIMBS 8
61 mbedtls_mpi_uint mp[MLIMBS];
62 mbedtls_mpi_mod_modulus m;
63 int ret;
64
Gilles Peskine449bd832023-01-11 14:50:10 +010065 memset(mp, 0xFF, sizeof(mp));
Werner Lewis0c6ea122022-09-30 13:02:16 +010066
Gilles Peskine449bd832023-01-11 14:50:10 +010067 mbedtls_mpi_mod_modulus_init(&m);
68 ret = mbedtls_mpi_mod_modulus_setup(&m, mp, MLIMBS, int_rep);
69 TEST_EQUAL(ret, iret);
Werner Lewis0c6ea122022-09-30 13:02:16 +010070
Minos Galanakisdd365a52022-10-19 01:48:32 +010071 /* Only test if the constants have been set-up */
Gilles Peskine449bd832023-01-11 14:50:10 +010072 if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
Minos Galanakisdd365a52022-10-19 01:48:32 +010073 /* Test that the consts have been calculated */
Gilles Peskine449bd832023-01-11 14:50:10 +010074 TEST_ASSERT(m.rep.mont.rr != NULL);
75 TEST_ASSERT(m.rep.mont.mm != 0);
Minos Galanakisdd365a52022-10-19 01:48:32 +010076
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 */
Gilles Peskine449bd832023-01-11 14:50:10 +010080 mbedtls_mpi_mod_modulus_free(&m);
Werner Lewis0c6ea122022-09-30 13:02:16 +010081
82 /* Make sure that the modulus doesn't have reference to mp anymore */
Gilles Peskine449bd832023-01-11 14:50:10 +010083 TEST_ASSERT(m.p != mp);
Werner Lewis0c6ea122022-09-30 13:02:16 +010084
Minos Galanakisdd365a52022-10-19 01:48:32 +010085 /* Only test if the constants have been set-up */
Gilles Peskine449bd832023-01-11 14:50:10 +010086 if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
Minos Galanakisdd365a52022-10-19 01:48:32 +010087 /* Verify the data and pointers allocated have been properly wiped */
Gilles Peskine449bd832023-01-11 14:50:10 +010088 TEST_ASSERT(m.rep.mont.rr == NULL);
89 TEST_ASSERT(m.rep.mont.mm == 0);
Minos Galanakisdd365a52022-10-19 01:48:32 +010090 }
Werner Lewis0c6ea122022-09-30 13:02:16 +010091exit:
92 /* It should be safe to call an mbedtls free several times */
Gilles Peskine449bd832023-01-11 14:50:10 +010093 mbedtls_mpi_mod_modulus_free(&m);
Werner Lewis0c6ea122022-09-30 13:02:16 +010094
95 #undef MLIMBS
96}
97/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +000098
99/* BEGIN MERGE SLOT 1 */
100
101/* END MERGE SLOT 1 */
102
103/* BEGIN MERGE SLOT 2 */
104
Gabor Mezeieca74662022-12-13 10:53:50 +0100105/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100106void mpi_mod_mul(char *input_A,
107 char *input_B,
108 char *input_N,
109 char *result)
Gabor Mezeieca74662022-12-13 10:53:50 +0100110{
Gabor Mezeieca74662022-12-13 10:53:50 +0100111 mbedtls_mpi_uint *X = NULL;
Gabor Mezeieca74662022-12-13 10:53:50 +0100112
Gabor Mezei78c4fb42022-12-20 18:09:49 +0100113 mbedtls_mpi_mod_residue rA = { NULL, 0 };
114 mbedtls_mpi_mod_residue rB = { NULL, 0 };
115 mbedtls_mpi_mod_residue rR = { NULL, 0 };
116 mbedtls_mpi_mod_residue rX = { NULL, 0 };
117
Gabor Mezeieca74662022-12-13 10:53:50 +0100118 mbedtls_mpi_mod_modulus m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 mbedtls_mpi_mod_modulus_init(&m);
Gabor Mezeieca74662022-12-13 10:53:50 +0100120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 TEST_EQUAL(test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N),
122 0);
Gabor Mezeieca74662022-12-13 10:53:50 +0100123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 TEST_EQUAL(test_read_residue(&rA, &m, input_A, 0), 0);
125 TEST_EQUAL(test_read_residue(&rB, &m, input_B, 0), 0);
126 TEST_EQUAL(test_read_residue(&rR, &m, result, 0), 0);
Gabor Mezei809baef2022-12-16 16:31:59 +0100127
128 const size_t limbs = m.limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 const size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
Gabor Mezei809baef2022-12-16 16:31:59 +0100130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 TEST_EQUAL(rA.limbs, limbs);
132 TEST_EQUAL(rB.limbs, limbs);
133 TEST_EQUAL(rR.limbs, limbs);
Gabor Mezei809baef2022-12-16 16:31:59 +0100134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 ASSERT_ALLOC(X, limbs);
Gabor Mezeieca74662022-12-13 10:53:50 +0100136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0);
Gabor Mezeieca74662022-12-13 10:53:50 +0100138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), 0);
140 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100141
142 /* alias X to A */
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 memcpy(rX.p, rA.p, bytes);
144 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rB, &m), 0);
145 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100146
147 /* alias X to B */
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 memcpy(rX.p, rB.p, bytes);
149 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rX, &m), 0);
150 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100151
152 /* A == B: alias A and B */
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 if (memcmp(rA.p, rB.p, bytes) == 0) {
154 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA, &m), 0);
155 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100156
157 /* X, A, B all aliased together */
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 memcpy(rX.p, rA.p, bytes);
159 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rX, &m), 0);
160 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100161 }
Gabor Mezeieca74662022-12-13 10:53:50 +0100162 /* A != B: test B * A */
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 else {
164 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rA, &m), 0);
165 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100166
167 /* B * A: alias X to A */
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 memcpy(rX.p, rA.p, bytes);
169 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rX, &m), 0);
170 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100171
172 /* B + A: alias X to B */
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 memcpy(rX.p, rB.p, bytes);
174 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rA, &m), 0);
175 ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
Gabor Mezeieca74662022-12-13 10:53:50 +0100176 }
177
178exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 mbedtls_free(rA.p);
180 mbedtls_free(rB.p);
181 mbedtls_free(rR.p);
182 mbedtls_free(X);
183 mbedtls_free((mbedtls_mpi_uint *) m.p);
Gabor Mezeif9728132022-12-20 13:55:37 +0100184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 mbedtls_mpi_mod_modulus_free(&m);
Gabor Mezeieca74662022-12-13 10:53:50 +0100186}
187/* END_CASE */
188
189/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100190void mpi_mod_mul_neg(char *input_A,
191 char *input_B,
192 char *input_N,
193 char *result,
194 int exp_ret)
Gabor Mezeieca74662022-12-13 10:53:50 +0100195{
Gabor Mezeieca74662022-12-13 10:53:50 +0100196 mbedtls_mpi_uint *X = NULL;
Gabor Mezeieca74662022-12-13 10:53:50 +0100197
Gabor Mezei78c4fb42022-12-20 18:09:49 +0100198 mbedtls_mpi_mod_residue rA = { NULL, 0 };
199 mbedtls_mpi_mod_residue rB = { NULL, 0 };
200 mbedtls_mpi_mod_residue rR = { NULL, 0 };
201 mbedtls_mpi_mod_residue rX = { NULL, 0 };
202
Gabor Mezeieca74662022-12-13 10:53:50 +0100203 mbedtls_mpi_mod_modulus m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 mbedtls_mpi_mod_modulus_init(&m);
Gabor Mezeieca74662022-12-13 10:53:50 +0100205
Gabor Mezeif65c71f2022-12-21 11:54:22 +0100206 mbedtls_mpi_mod_modulus fake_m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 mbedtls_mpi_mod_modulus_init(&fake_m);
Gabor Mezeif65c71f2022-12-21 11:54:22 +0100208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 TEST_EQUAL(test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N),
210 0);
Gabor Mezeieca74662022-12-13 10:53:50 +0100211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 TEST_EQUAL(test_read_residue(&rA, &m, input_A, 1), 0);
213 TEST_EQUAL(test_read_residue(&rB, &m, input_B, 1), 0);
214 TEST_EQUAL(test_read_residue(&rR, &m, result, 1), 0);
Gabor Mezei809baef2022-12-16 16:31:59 +0100215
216 const size_t limbs = m.limbs;
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 ASSERT_ALLOC(X, limbs);
Gabor Mezeieca74662022-12-13 10:53:50 +0100219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0);
Gabor Mezei809baef2022-12-16 16:31:59 +0100221 rX.limbs = rR.limbs;
Gabor Mezeieca74662022-12-13 10:53:50 +0100222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), exp_ret);
Gabor Mezeieca74662022-12-13 10:53:50 +0100224
225 /* Check when m is not initialized */
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &fake_m),
227 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gabor Mezeieca74662022-12-13 10:53:50 +0100228
229exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 mbedtls_free(rA.p);
231 mbedtls_free(rB.p);
232 mbedtls_free(rR.p);
233 mbedtls_free(X);
234 mbedtls_free((mbedtls_mpi_uint *) m.p);
Gabor Mezeif9728132022-12-20 13:55:37 +0100235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 mbedtls_mpi_mod_modulus_free(&m);
237 mbedtls_mpi_mod_modulus_free(&fake_m);
Gabor Mezeieca74662022-12-13 10:53:50 +0100238}
239/* END_CASE */
240
Janos Follath5933f692022-11-02 14:35:17 +0000241/* END MERGE SLOT 2 */
242
243/* BEGIN MERGE SLOT 3 */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000244/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100245void mpi_mod_sub(char *input_N,
246 char *input_A, char *input_B,
247 char *input_D, int expected_ret)
Tom Cosgrove62b20482022-12-01 14:27:37 +0000248{
249 mbedtls_mpi_mod_residue a = { NULL, 0 };
250 mbedtls_mpi_mod_residue b = { NULL, 0 };
251 mbedtls_mpi_mod_residue d = { NULL, 0 };
252 mbedtls_mpi_mod_residue x = { NULL, 0 };
253 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000254
Tom Cosgrove62b20482022-12-01 14:27:37 +0000255 mbedtls_mpi_mod_modulus m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 mbedtls_mpi_mod_modulus_init(&m);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 TEST_EQUAL(0,
259 test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N));
Tom Cosgrove62b20482022-12-01 14:27:37 +0000260
261 /* test_read_residue() normally checks that inputs have the same number of
262 * limbs as the modulus. For negative testing we can ask it to skip this
263 * with a non-zero final parameter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0));
265 TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0));
266 TEST_EQUAL(0, test_read_residue(&d, &m, input_D, expected_ret != 0));
Tom Cosgrove62b20482022-12-01 14:27:37 +0000267
268 size_t limbs = m.limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 size_t bytes = limbs * sizeof(*X_raw);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000270
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 if (expected_ret == 0) {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000272 /* Negative test with too many limbs in output */
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 ASSERT_ALLOC(X_raw, limbs + 1);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000274
Tom Cosgrove62b20482022-12-01 14:27:37 +0000275 x.p = X_raw;
276 x.limbs = limbs + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
278 mbedtls_mpi_mod_sub(&x, &a, &b, &m));
Tom Cosgrove62b20482022-12-01 14:27:37 +0000279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 mbedtls_free(X_raw);
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000281 X_raw = NULL;
282
283 /* Negative test with too few limbs in output */
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 if (limbs > 1) {
285 ASSERT_ALLOC(X_raw, limbs - 1);
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000286
Tom Cosgrove62b20482022-12-01 14:27:37 +0000287 x.p = X_raw;
288 x.limbs = limbs - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
290 mbedtls_mpi_mod_sub(&x, &a, &b, &m));
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 mbedtls_free(X_raw);
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000293 X_raw = NULL;
Tom Cosgrove62b20482022-12-01 14:27:37 +0000294 }
295
296 /* Negative testing with too many/too few limbs in a and b is covered by
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000297 * manually-written test cases with expected_ret != 0. */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000298 }
299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 ASSERT_ALLOC(X_raw, limbs);
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs));
Tom Cosgrove62b20482022-12-01 14:27:37 +0000303
304 /* a - b => Correct result, or expected error */
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_sub(&x, &a, &b, &m));
306 if (expected_ret != 0) {
Tom Cosgrove62b20482022-12-01 14:27:37 +0000307 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 }
Tom Cosgrove62b20482022-12-01 14:27:37 +0000309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 TEST_COMPARE_MPI_RESIDUES(x, d);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000311
312 /* a - b: alias x to a => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 memcpy(x.p, a.p, bytes);
314 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &b, &m));
315 TEST_COMPARE_MPI_RESIDUES(x, d);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000316
317 /* a - b: alias x to b => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 memcpy(x.p, b.p, bytes);
319 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &x, &m));
320 TEST_COMPARE_MPI_RESIDUES(x, d);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 if (memcmp(a.p, b.p, bytes) == 0) {
Tom Cosgrove62b20482022-12-01 14:27:37 +0000323 /* a == b: alias a and b */
324
325 /* a - a => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &a, &m));
327 TEST_COMPARE_MPI_RESIDUES(x, d);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000328
329 /* a - a: x, a, b all aliased together => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 memcpy(x.p, a.p, bytes);
331 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &x, &m));
332 TEST_COMPARE_MPI_RESIDUES(x, d);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000333 }
334
335exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
337 mbedtls_mpi_mod_modulus_free(&m);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 mbedtls_free(a.p);
340 mbedtls_free(b.p);
341 mbedtls_free(d.p);
342 mbedtls_free(X_raw);
Tom Cosgrove62b20482022-12-01 14:27:37 +0000343}
344/* END_CASE */
Tom Cosgrovedc197592022-12-15 16:59:40 +0000345
346/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100347void mpi_mod_inv_mont(char *input_N,
348 char *input_A, char *input_I,
349 int expected_ret)
Tom Cosgrovedc197592022-12-15 16:59:40 +0000350{
351 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
352 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
353 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
354 mbedtls_mpi_uint *X_raw = NULL;
355
356 mbedtls_mpi_mod_modulus N;
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 mbedtls_mpi_mod_modulus_init(&N);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 TEST_EQUAL(0,
360 test_read_modulus(&N, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N));
Tom Cosgrovedc197592022-12-15 16:59:40 +0000361
362 /* test_read_residue() normally checks that inputs have the same number of
363 * limbs as the modulus. For negative testing we can ask it to skip this
364 * with a non-zero final parameter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0));
366 TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0));
Tom Cosgrovedc197592022-12-15 16:59:40 +0000367
368 size_t limbs = N.limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 size_t bytes = limbs * sizeof(*X_raw);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 ASSERT_ALLOC(X_raw, limbs);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs));
Tom Cosgrovedc197592022-12-15 16:59:40 +0000374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N));
376 if (expected_ret == 0) {
377 TEST_COMPARE_MPI_RESIDUES(x, i);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000378
379 /* a^-1: alias x to a => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 memcpy(x.p, a.p, bytes);
381 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N));
382 TEST_COMPARE_MPI_RESIDUES(x, i);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000383 }
384
385exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
387 mbedtls_mpi_mod_modulus_free(&N);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 mbedtls_free(a.p);
390 mbedtls_free(i.p);
391 mbedtls_free(X_raw);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000392}
393/* END_CASE */
394
395/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100396void mpi_mod_inv_non_mont(char *input_N,
397 char *input_A, char *input_I,
398 int expected_ret)
Tom Cosgrovedc197592022-12-15 16:59:40 +0000399{
400 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
401 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
402 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
403 mbedtls_mpi_uint *X_raw = NULL;
404
405 mbedtls_mpi_mod_modulus N;
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 mbedtls_mpi_mod_modulus_init(&N);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 TEST_EQUAL(0,
409 test_read_modulus(&N, MBEDTLS_MPI_MOD_REP_OPT_RED, input_N));
Tom Cosgrovedc197592022-12-15 16:59:40 +0000410
411 /* test_read_residue() normally checks that inputs have the same number of
412 * limbs as the modulus. For negative testing we can ask it to skip this
413 * with a non-zero final parameter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0));
415 TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0));
Tom Cosgrovedc197592022-12-15 16:59:40 +0000416
417 size_t limbs = N.limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 size_t bytes = limbs * sizeof(*X_raw);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 ASSERT_ALLOC(X_raw, limbs);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs));
Tom Cosgrovedc197592022-12-15 16:59:40 +0000423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N));
425 if (expected_ret == 0) {
426 TEST_COMPARE_MPI_RESIDUES(x, i);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000427
428 /* a^-1: alias x to a => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 memcpy(x.p, a.p, bytes);
430 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N));
431 TEST_COMPARE_MPI_RESIDUES(x, i);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000432 }
433
434exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
436 mbedtls_mpi_mod_modulus_free(&N);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 mbedtls_free(a.p);
439 mbedtls_free(i.p);
440 mbedtls_free(X_raw);
Tom Cosgrovedc197592022-12-15 16:59:40 +0000441}
442/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000443/* END MERGE SLOT 3 */
444
445/* BEGIN MERGE SLOT 4 */
446
447/* END MERGE SLOT 4 */
448
449/* BEGIN MERGE SLOT 5 */
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000450/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451void mpi_mod_add(char *input_N,
452 char *input_A, char *input_B,
453 char *input_S, int expected_ret)
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000454{
455 mbedtls_mpi_mod_residue a = { NULL, 0 };
456 mbedtls_mpi_mod_residue b = { NULL, 0 };
457 mbedtls_mpi_mod_residue s = { NULL, 0 };
458 mbedtls_mpi_mod_residue x = { NULL, 0 };
459 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000460
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000461 mbedtls_mpi_mod_modulus m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 mbedtls_mpi_mod_modulus_init(&m);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 TEST_EQUAL(0,
465 test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N));
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000466
467 /* test_read_residue() normally checks that inputs have the same number of
468 * limbs as the modulus. For negative testing we can ask it to skip this
469 * with a non-zero final parameter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0));
471 TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0));
472 TEST_EQUAL(0, test_read_residue(&s, &m, input_S, expected_ret != 0));
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000473
474 size_t limbs = m.limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 size_t bytes = limbs * sizeof(*X_raw);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 if (expected_ret == 0) {
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000478 /* Negative test with too many limbs in output */
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 ASSERT_ALLOC(X_raw, limbs + 1);
Werner Lewis79341a42022-12-13 17:19:01 +0000480
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000481 x.p = X_raw;
482 x.limbs = limbs + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
484 mbedtls_mpi_mod_add(&x, &a, &b, &m));
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 mbedtls_free(X_raw);
Werner Lewis79341a42022-12-13 17:19:01 +0000487 X_raw = NULL;
488
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000489 /* Negative test with too few limbs in output */
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 if (limbs > 1) {
491 ASSERT_ALLOC(X_raw, limbs - 1);
Werner Lewis79341a42022-12-13 17:19:01 +0000492
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000493 x.p = X_raw;
494 x.limbs = limbs - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
496 mbedtls_mpi_mod_add(&x, &a, &b, &m));
Werner Lewis79341a42022-12-13 17:19:01 +0000497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 mbedtls_free(X_raw);
Werner Lewis79341a42022-12-13 17:19:01 +0000499 X_raw = NULL;
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000500 }
501
502 /* Negative testing with too many/too few limbs in a and b is covered by
503 * manually-written test cases with oret != 0. */
504 }
505
Werner Lewis79341a42022-12-13 17:19:01 +0000506 /* Allocate correct number of limbs for X_raw */
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 ASSERT_ALLOC(X_raw, limbs);
Werner Lewis79341a42022-12-13 17:19:01 +0000508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs));
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000510
511 /* A + B => Correct result or expected error */
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_add(&x, &a, &b, &m));
513 if (expected_ret != 0) {
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000514 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 }
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 TEST_COMPARE_MPI_RESIDUES(x, s);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000518
519 /* a + b: alias x to a => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 memcpy(x.p, a.p, bytes);
521 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &b, &m));
522 TEST_COMPARE_MPI_RESIDUES(x, s);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000523
524 /* a + b: alias x to b => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 memcpy(x.p, b.p, bytes);
526 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &x, &m));
527 TEST_COMPARE_MPI_RESIDUES(x, s);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (memcmp(a.p, b.p, bytes) == 0) {
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000530 /* a == b: alias a and b */
531
532 /* a + a => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &a, &m));
534 TEST_COMPARE_MPI_RESIDUES(x, s);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000535
536 /* a + a: x, a, b all aliased together => Correct result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 memcpy(x.p, a.p, bytes);
538 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &x, &m));
539 TEST_COMPARE_MPI_RESIDUES(x, s);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000540 }
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000541
542exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
544 mbedtls_mpi_mod_modulus_free(&m);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 mbedtls_free(a.p);
547 mbedtls_free(b.p);
548 mbedtls_free(s.p);
549 mbedtls_free(X_raw);
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000550}
551/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000552/* END MERGE SLOT 5 */
553
554/* BEGIN MERGE SLOT 6 */
555
556/* END MERGE SLOT 6 */
557
558/* BEGIN MERGE SLOT 7 */
Minos Galanakis8f242702022-11-10 16:56:02 +0000559/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100560void mpi_residue_setup(char *input_N, char *input_R, int ret)
Minos Galanakisa17ad482022-11-16 16:29:15 +0000561{
Minos Galanakisa17ad482022-11-16 16:29:15 +0000562 mbedtls_mpi_uint *N = NULL;
563 mbedtls_mpi_uint *R = NULL;
Minos Galanakisaed832a2022-11-24 09:09:47 +0000564 size_t n_limbs, r_limbs;
Minos Galanakisa17ad482022-11-16 16:29:15 +0000565 mbedtls_mpi_mod_modulus m;
566 mbedtls_mpi_mod_residue r;
567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 mbedtls_mpi_mod_modulus_init(&m);
Minos Galanakisa17ad482022-11-16 16:29:15 +0000569
Minos Galanakisaed832a2022-11-24 09:09:47 +0000570 /* Allocate the memory for intermediate data structures */
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
572 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&R, &r_limbs, input_R));
Minos Galanakisaed832a2022-11-24 09:09:47 +0000573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs,
575 MBEDTLS_MPI_MOD_REP_MONTGOMERY));
Minos Galanakisa17ad482022-11-16 16:29:15 +0000576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 TEST_EQUAL(ret, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs));
Minos Galanakisa17ad482022-11-16 16:29:15 +0000578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (ret == 0) {
580 TEST_EQUAL(r.limbs, r_limbs);
581 TEST_ASSERT(r.p == R);
Janos Follath91f3abd2022-11-26 11:47:14 +0000582 }
583
Minos Galanakisa17ad482022-11-16 16:29:15 +0000584exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 mbedtls_mpi_mod_modulus_free(&m);
586 mbedtls_free(N);
587 mbedtls_free(R);
Minos Galanakisa17ad482022-11-16 16:29:15 +0000588}
589/* END_CASE */
Minos Galanakisaed832a2022-11-24 09:09:47 +0000590
Minos Galanakisa17ad482022-11-16 16:29:15 +0000591/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592void mpi_mod_io_neg(char *input_N, data_t *buf, int ret)
Minos Galanakis8f242702022-11-10 16:56:02 +0000593{
Minos Galanakis8f242702022-11-10 16:56:02 +0000594 mbedtls_mpi_uint *N = NULL;
595 mbedtls_mpi_uint *R = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000596
597 mbedtls_mpi_mod_modulus m;
Janos Follathe7190a22022-11-26 18:46:54 +0000598 mbedtls_mpi_mod_residue r = { NULL, 0 };
Minos Galanakis96070a52022-11-25 19:32:10 +0000599 mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
Minos Galanakis8f242702022-11-10 16:56:02 +0000600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 mbedtls_mpi_mod_modulus_init(&m);
Janos Follath799eaee2022-11-25 15:57:04 +0000602
Janos Follath339b4392022-11-26 12:20:41 +0000603 size_t n_limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
Janos Follath339b4392022-11-26 12:20:41 +0000605 size_t r_limbs = n_limbs;
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 ASSERT_ALLOC(R, r_limbs);
Minos Galanakis8f242702022-11-10 16:56:02 +0000607
Janos Follathe7190a22022-11-26 18:46:54 +0000608 /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
610 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
Minos Galanakis8f242702022-11-10 16:56:02 +0000611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
613 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
Minos Galanakis8f242702022-11-10 16:56:02 +0000614
Janos Follathe7190a22022-11-26 18:46:54 +0000615 /* Set up modulus and test with residue->p == NULL */
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs,
617 MBEDTLS_MPI_MOD_REP_MONTGOMERY));
Minos Galanakis96070a52022-11-25 19:32:10 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
620 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
621 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
622 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
Janos Follathe7190a22022-11-26 18:46:54 +0000623
624 /* Do the rest of the tests with a residue set up with the input data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs));
Minos Galanakis96070a52022-11-25 19:32:10 +0000626
Janos Follathd7bb3522022-11-26 14:59:27 +0000627 /* Fail for r_limbs < m->limbs */
628 r.limbs--;
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 TEST_ASSERT(r.limbs < m.limbs);
630 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
631 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
632 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
633 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
Janos Follathd7bb3522022-11-26 14:59:27 +0000634 r.limbs++;
635
636 /* Fail for r_limbs > m->limbs */
637 m.limbs--;
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 TEST_ASSERT(r.limbs > m.limbs);
639 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
640 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
641 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
642 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
Janos Follathd7bb3522022-11-26 14:59:27 +0000643 m.limbs++;
Minos Galanakis96070a52022-11-25 19:32:10 +0000644
645 /* Test the read */
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 TEST_EQUAL(ret, mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
Minos Galanakis96070a52022-11-25 19:32:10 +0000647
648 /* Test write overflow only when the representation is large and read is successful */
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (r.limbs > 1 && ret == 0) {
650 TEST_EQUAL(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL,
651 mbedtls_mpi_mod_write(&r, &m, buf->x, 1, endian));
652 }
Janos Follathd7bb3522022-11-26 14:59:27 +0000653
Minos Galanakis8f242702022-11-10 16:56:02 +0000654exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 mbedtls_mpi_mod_residue_release(&r);
656 mbedtls_mpi_mod_modulus_free(&m);
657 mbedtls_free(N);
658 mbedtls_free(R);
Minos Galanakis8f242702022-11-10 16:56:02 +0000659}
660/* END_CASE */
661
662/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100663void mpi_mod_io(char *input_N, data_t *input_A, int endian)
Minos Galanakis8f242702022-11-10 16:56:02 +0000664{
665 mbedtls_mpi_uint *N = NULL;
666 mbedtls_mpi_uint *R = NULL;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000667 mbedtls_mpi_uint *R_COPY = NULL;
Janos Follath0020df92022-11-26 17:23:16 +0000668 unsigned char *obuf = NULL;
669 unsigned char *ref_buf = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000670 mbedtls_mpi_mod_modulus m;
671 mbedtls_mpi_mod_residue r;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000672 mbedtls_mpi_mod_residue r_copy;
Minos Galanakis8f242702022-11-10 16:56:02 +0000673 size_t n_limbs, n_bytes, a_bytes;
674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 mbedtls_mpi_mod_modulus_init(&m);
Janos Follath799eaee2022-11-25 15:57:04 +0000676
Minos Galanakis8f242702022-11-10 16:56:02 +0000677 /* Read inputs */
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
679 n_bytes = n_limbs * sizeof(mbedtls_mpi_uint);
Janos Follath6ef582f2022-11-26 14:19:02 +0000680 a_bytes = input_A->len;
Minos Galanakis8f242702022-11-10 16:56:02 +0000681
682 /* Allocate the memory for intermediate data structures */
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 ASSERT_ALLOC(R, n_bytes);
684 ASSERT_ALLOC(R_COPY, n_bytes);
Minos Galanakis8f242702022-11-10 16:56:02 +0000685
686 /* Test that input's size is not greater to modulo's */
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 TEST_LE_U(a_bytes, n_bytes);
Minos Galanakis8f242702022-11-10 16:56:02 +0000688
689 /* Init Structures */
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs,
691 MBEDTLS_MPI_MOD_REP_MONTGOMERY));
Minos Galanakis8f242702022-11-10 16:56:02 +0000692
693 /* Enforcing p_limbs >= m->limbs */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, n_limbs));
Minos Galanakis8f242702022-11-10 16:56:02 +0000695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 TEST_EQUAL(0, mbedtls_mpi_mod_read(&r, &m, input_A->x, input_A->len,
697 endian));
Minos Galanakis8f242702022-11-10 16:56:02 +0000698
Janos Follath0020df92022-11-26 17:23:16 +0000699 /* Read a copy for checking that writing didn't change the value of r */
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r_copy, &m,
701 R_COPY, n_limbs));
702 TEST_EQUAL(0, mbedtls_mpi_mod_read(&r_copy, &m, input_A->x, input_A->len,
703 endian));
Janos Follath8dfc8c42022-11-26 15:39:02 +0000704
Janos Follath0020df92022-11-26 17:23:16 +0000705 /* Get number of bytes without leading zeroes */
706 size_t a_bytes_trimmed = a_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 while (a_bytes_trimmed > 0) {
708 unsigned char *r_byte_array = (unsigned char *) r.p;
709 if (r_byte_array[--a_bytes_trimmed] != 0) {
Janos Follath0020df92022-11-26 17:23:16 +0000710 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 }
Janos Follath0020df92022-11-26 17:23:16 +0000712 }
713 a_bytes_trimmed++;
714
715 /* Test write with three output buffer sizes: tight, same as input and
716 * longer than the input */
717 size_t obuf_sizes[3];
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 const size_t obuf_sizes_len = sizeof(obuf_sizes) / sizeof(obuf_sizes[0]);
Janos Follath0020df92022-11-26 17:23:16 +0000719 obuf_sizes[0] = a_bytes_trimmed;
720 obuf_sizes[1] = a_bytes;
721 obuf_sizes[2] = a_bytes + 8;
722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 for (size_t i = 0; i < obuf_sizes_len; i++) {
724 ASSERT_ALLOC(obuf, obuf_sizes[i]);
725 TEST_EQUAL(0, mbedtls_mpi_mod_write(&r, &m, obuf, obuf_sizes[i], endian));
Janos Follath0020df92022-11-26 17:23:16 +0000726
727 /* Make sure that writing didn't corrupt the value of r */
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 ASSERT_COMPARE(r.p, r.limbs, r_copy.p, r_copy.limbs);
Janos Follath0020df92022-11-26 17:23:16 +0000729
730 /* Set up reference output for checking the result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 ASSERT_ALLOC(ref_buf, obuf_sizes[i]);
732 switch (endian) {
Janos Follath0020df92022-11-26 17:23:16 +0000733 case MBEDTLS_MPI_MOD_EXT_REP_LE:
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 memcpy(ref_buf, input_A->x, a_bytes_trimmed);
Janos Follath0020df92022-11-26 17:23:16 +0000735 break;
736 case MBEDTLS_MPI_MOD_EXT_REP_BE:
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 {
738 size_t a_offset = input_A->len - a_bytes_trimmed;
739 size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed;
740 memcpy(ref_buf + ref_offset, input_A->x + a_offset,
741 a_bytes_trimmed);
742 }
743 break;
Janos Follath0020df92022-11-26 17:23:16 +0000744 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 TEST_ASSERT(0);
Janos Follath0020df92022-11-26 17:23:16 +0000746 }
747
748 /* Check the result */
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 ASSERT_COMPARE(obuf, obuf_sizes[i], ref_buf, obuf_sizes[i]);
Janos Follath0020df92022-11-26 17:23:16 +0000750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 mbedtls_free(ref_buf);
Janos Follath0020df92022-11-26 17:23:16 +0000752 ref_buf = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 mbedtls_free(obuf);
Janos Follath0020df92022-11-26 17:23:16 +0000754 obuf = NULL;
755 }
756
Minos Galanakis8f242702022-11-10 16:56:02 +0000757exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_mpi_mod_modulus_free(&m);
759 mbedtls_free(N);
760 mbedtls_free(R);
761 mbedtls_free(R_COPY);
762 mbedtls_free(obuf);
Minos Galanakis8f242702022-11-10 16:56:02 +0000763}
764/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000765/* END MERGE SLOT 7 */
766
767/* BEGIN MERGE SLOT 8 */
768
769/* END MERGE SLOT 8 */
770
771/* BEGIN MERGE SLOT 9 */
772
773/* END MERGE SLOT 9 */
774
775/* BEGIN MERGE SLOT 10 */
776
777/* END MERGE SLOT 10 */