xref: /aosp_15_r20/external/mbedtls/tests/suites/test_suite_ecp.function (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1/* BEGIN_HEADER */
2#include "mbedtls/ecp.h"
3#include "ecp_invasive.h"
4#include "mbedtls/ecdsa.h"
5#include "mbedtls/ecdh.h"
6
7#include "bignum_core.h"
8#include "ecp_invasive.h"
9#include "bignum_mod_raw_invasive.h"
10#include "constant_time_internal.h"
11
12#define ECP_PF_UNKNOWN     -1
13
14#define ECP_PT_RESET(x)           \
15    mbedtls_ecp_point_free(x);    \
16    mbedtls_ecp_point_init(x);
17
18/* Auxiliary function to compare two mbedtls_ecp_group objects. */
19inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
20                                        mbedtls_ecp_group *grp2)
21{
22    if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
23        return 1;
24    }
25    if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
26        return 1;
27    }
28    if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
29        return 1;
30    }
31    if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
32        return 1;
33    }
34    if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
35        return 1;
36    }
37    if (grp1->id != grp2->id) {
38        return 1;
39    }
40    if (grp1->pbits != grp2->pbits) {
41        return 1;
42    }
43    if (grp1->nbits != grp2->nbits) {
44        return 1;
45    }
46    if (grp1->h != grp2->h) {
47        return 1;
48    }
49    if (grp1->modp != grp2->modp) {
50        return 1;
51    }
52    if (grp1->t_pre != grp2->t_pre) {
53        return 1;
54    }
55    if (grp1->t_post != grp2->t_post) {
56        return 1;
57    }
58    if (grp1->t_data != grp2->t_data) {
59        return 1;
60    }
61    if (grp1->T_size != grp2->T_size) {
62        return 1;
63    }
64    if (grp1->T != grp2->T) {
65        return 1;
66    }
67
68    return 0;
69}
70
71/* END_HEADER */
72
73/* BEGIN_DEPENDENCIES
74 * depends_on:MBEDTLS_ECP_LIGHT
75 * END_DEPENDENCIES
76 */
77
78/* BEGIN_CASE */
79void ecp_invalid_param()
80{
81    mbedtls_ecp_group grp;
82    mbedtls_ecp_point P;
83    int invalid_fmt = 42;
84    size_t olen;
85    unsigned char buf[42] = { 0 };
86
87    mbedtls_ecp_group_init(&grp);
88    mbedtls_ecp_point_init(&P);
89
90    TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
91               mbedtls_ecp_point_write_binary(&grp, &P,
92                                              invalid_fmt,
93                                              &olen,
94                                              buf, sizeof(buf)));
95    TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
96               mbedtls_ecp_tls_write_point(&grp, &P,
97                                           invalid_fmt,
98                                           &olen,
99                                           buf,
100                                           sizeof(buf)));
101
102exit:
103    return;
104}
105/* END_CASE */
106
107/* BEGIN_CASE */
108void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
109{
110    const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
111
112    by_id   = mbedtls_ecp_curve_info_from_grp_id(id);
113    by_tls  = mbedtls_ecp_curve_info_from_tls_id(tls_id);
114    by_name = mbedtls_ecp_curve_info_from_name(name);
115    TEST_ASSERT(by_id   != NULL);
116    TEST_ASSERT(by_tls  != NULL);
117    TEST_ASSERT(by_name != NULL);
118
119    TEST_ASSERT(by_id == by_tls);
120    TEST_ASSERT(by_id == by_name);
121
122    TEST_ASSERT(by_id->bit_size == size);
123    TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
124    TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
125}
126/* END_CASE */
127
128/* BEGIN_CASE */
129void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
130                   int ret)
131{
132    mbedtls_ecp_group grp;
133    mbedtls_ecp_point P;
134
135    mbedtls_ecp_group_init(&grp);
136    mbedtls_ecp_point_init(&P);
137
138    TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
139
140    TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
141    TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
142    TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
143
144    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
145
146exit:
147    mbedtls_ecp_group_free(&grp);
148    mbedtls_ecp_point_free(&P);
149}
150/* END_CASE */
151
152/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
153void ecp_test_vect_restart(int id,
154                           char *dA_str, char *xA_str, char *yA_str,
155                           char *dB_str,  char *xZ_str, char *yZ_str,
156                           int max_ops, int min_restarts, int max_restarts)
157{
158    /*
159     * Test for early restart. Based on test vectors like ecp_test_vect(),
160     * but for the sake of simplicity only does half of each side. It's
161     * important to test both base point and random point, though, as memory
162     * management is different in each case.
163     *
164     * Don't try using too precise bounds for restarts as the exact number
165     * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
166     * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
167     * change in the future. A factor 2 is a minimum safety margin.
168     *
169     * For reference, with Mbed TLS 2.4 and default settings, for P-256:
170     * - Random point mult:     ~3250M
171     * - Cold base point mult:  ~3300M
172     * - Hot base point mult:   ~1100M
173     * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
174     * - Random point mult:     ~3850M
175     */
176    mbedtls_ecp_restart_ctx ctx;
177    mbedtls_ecp_group grp;
178    mbedtls_ecp_point R, P;
179    mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
180    int cnt_restarts;
181    int ret;
182    mbedtls_test_rnd_pseudo_info rnd_info;
183
184    mbedtls_ecp_restart_init(&ctx);
185    mbedtls_ecp_group_init(&grp);
186    mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
187    mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
188    mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
189    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
190
191    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
192
193    TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
194    TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
195    TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
196
197    TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
198    TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
199    TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
200
201    mbedtls_ecp_set_max_ops((unsigned) max_ops);
202
203    /* Base point case */
204    cnt_restarts = 0;
205    do {
206        ECP_PT_RESET(&R);
207        ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
208                                          &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
209    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
210
211    TEST_ASSERT(ret == 0);
212    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
213    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
214
215    TEST_ASSERT(cnt_restarts >= min_restarts);
216    TEST_ASSERT(cnt_restarts <= max_restarts);
217
218    /* Non-base point case */
219    mbedtls_ecp_copy(&P, &R);
220    cnt_restarts = 0;
221    do {
222        ECP_PT_RESET(&R);
223        ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
224                                          &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
225    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
226
227    TEST_ASSERT(ret == 0);
228    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
229    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
230
231    TEST_ASSERT(cnt_restarts >= min_restarts);
232    TEST_ASSERT(cnt_restarts <= max_restarts);
233
234    /* Do we leak memory when aborting an operation?
235     * This test only makes sense when we actually restart */
236    if (min_restarts > 0) {
237        ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
238                                          &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
239        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
240    }
241
242exit:
243    mbedtls_ecp_restart_free(&ctx);
244    mbedtls_ecp_group_free(&grp);
245    mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
246    mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
247    mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
248}
249/* END_CASE */
250
251/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
252void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
253                        char *u1_str, char *u2_str,
254                        char *xQ_str, char *yQ_str,
255                        int max_ops, int min_restarts, int max_restarts)
256{
257    /*
258     * Compute R = u1 * G + u2 * Q
259     * (test vectors mostly taken from ECDSA intermediate results)
260     *
261     * See comments at the top of ecp_test_vect_restart()
262     */
263    mbedtls_ecp_restart_ctx ctx;
264    mbedtls_ecp_group grp;
265    mbedtls_ecp_point R, Q;
266    mbedtls_mpi u1, u2, xR, yR;
267    int cnt_restarts;
268    int ret;
269
270    mbedtls_ecp_restart_init(&ctx);
271    mbedtls_ecp_group_init(&grp);
272    mbedtls_ecp_point_init(&R);
273    mbedtls_ecp_point_init(&Q);
274    mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
275    mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
276
277    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
278
279    TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
280    TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
281    TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
282    TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
283
284    TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
285    TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
286    TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
287
288    mbedtls_ecp_set_max_ops((unsigned) max_ops);
289
290    cnt_restarts = 0;
291    do {
292        ECP_PT_RESET(&R);
293        ret = mbedtls_ecp_muladd_restartable(&grp, &R,
294                                             &u1, &grp.G, &u2, &Q, &ctx);
295    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
296
297    TEST_ASSERT(ret == 0);
298    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
299    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
300
301    TEST_ASSERT(cnt_restarts >= min_restarts);
302    TEST_ASSERT(cnt_restarts <= max_restarts);
303
304    /* Do we leak memory when aborting an operation?
305     * This test only makes sense when we actually restart */
306    if (min_restarts > 0) {
307        ret = mbedtls_ecp_muladd_restartable(&grp, &R,
308                                             &u1, &grp.G, &u2, &Q, &ctx);
309        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
310    }
311
312exit:
313    mbedtls_ecp_restart_free(&ctx);
314    mbedtls_ecp_group_free(&grp);
315    mbedtls_ecp_point_free(&R);
316    mbedtls_ecp_point_free(&Q);
317    mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
318    mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
319}
320/* END_CASE */
321
322/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
323void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
324                   char *dB_str, char *xB_str, char *yB_str,
325                   char *xZ_str, char *yZ_str)
326{
327    mbedtls_ecp_group grp;
328    mbedtls_ecp_point R;
329    mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
330    mbedtls_test_rnd_pseudo_info rnd_info;
331
332    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
333    mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
334    mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
335    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
336
337    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
338
339    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
340
341    TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
342    TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
343    TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
344    TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
345    TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
346    TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
347    TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
348    TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
349
350    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
351                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
352    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
353    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
354    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
355    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
356                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
357    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
358    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
359    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
360
361    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
362                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
363    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
364    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
365    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
366    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
367                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
368    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
369    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
370    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
371
372exit:
373    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
374    mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
375    mbedtls_mpi_free(&xB); mbedtls_mpi_free(&yB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
376}
377/* END_CASE */
378
379/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
380void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
381                    char *xB_hex, char *xS_hex)
382{
383    mbedtls_ecp_group grp;
384    mbedtls_ecp_point R;
385    mbedtls_mpi dA, xA, dB, xB, xS;
386    mbedtls_test_rnd_pseudo_info rnd_info;
387
388    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
389    mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
390    mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
391    mbedtls_mpi_init(&xS);
392    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
393
394    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
395
396    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
397
398    TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
399    TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
400    TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
401    TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
402    TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
403
404    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
405                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
406    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
407    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
408
409    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
410                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
411    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
412    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
413
414    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
415                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
416    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
417    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
418
419    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
420                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
421    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
422    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
423
424exit:
425    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
426    mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
427    mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
428    mbedtls_mpi_free(&xS);
429}
430/* END_CASE */
431
432/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
433void ecp_test_mul(int id, data_t *n_hex,
434                  data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
435                  data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
436                  int expected_ret)
437{
438    mbedtls_ecp_group grp;
439    mbedtls_ecp_point P, nP, R;
440    mbedtls_mpi n;
441    mbedtls_test_rnd_pseudo_info rnd_info;
442
443    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
444    mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
445    mbedtls_mpi_init(&n);
446    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
447
448    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
449
450    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
451
452    TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
453
454    TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
455    TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
456    TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
457    TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
458                == 0);
459    TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
460                == 0);
461    TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
462                == 0);
463
464    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
465                                &mbedtls_test_rnd_pseudo_rand, &rnd_info)
466                == expected_ret);
467
468    if (expected_ret == 0) {
469        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
470        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
471        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
472    }
473
474exit:
475    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
476    mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
477    mbedtls_mpi_free(&n);
478}
479/* END_CASE */
480
481/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
482void ecp_test_mul_rng(int id, data_t *d_hex)
483{
484    mbedtls_ecp_group grp;
485    mbedtls_mpi d;
486    mbedtls_ecp_point Q;
487
488    mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
489    mbedtls_ecp_point_init(&Q);
490
491    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
492
493    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
494
495    TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
496
497    TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
498                                &mbedtls_test_rnd_zero_rand, NULL)
499                == MBEDTLS_ERR_ECP_RANDOM_FAILED);
500
501exit:
502    mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
503    mbedtls_ecp_point_free(&Q);
504}
505/* END_CASE */
506
507/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED:MBEDTLS_ECP_C */
508void ecp_muladd(int id,
509                data_t *u1_bin, data_t *P1_bin,
510                data_t *u2_bin, data_t *P2_bin,
511                data_t *expected_result)
512{
513    /* Compute R = u1 * P1 + u2 * P2 */
514    mbedtls_ecp_group grp;
515    mbedtls_ecp_point P1, P2, R;
516    mbedtls_mpi u1, u2;
517    uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
518    size_t len;
519
520    mbedtls_ecp_group_init(&grp);
521    mbedtls_ecp_point_init(&P1);
522    mbedtls_ecp_point_init(&P2);
523    mbedtls_ecp_point_init(&R);
524    mbedtls_mpi_init(&u1);
525    mbedtls_mpi_init(&u2);
526
527    TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
528    TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
529    TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
530    TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
531                                                P1_bin->x, P1_bin->len));
532    TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
533                                                P2_bin->x, P2_bin->len));
534
535    TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
536    TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
537                   &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
538                   &len, actual_result, sizeof(actual_result)));
539    TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
540
541    TEST_MEMORY_COMPARE(expected_result->x, expected_result->len,
542                        actual_result, len);
543
544exit:
545    mbedtls_ecp_group_free(&grp);
546    mbedtls_ecp_point_free(&P1);
547    mbedtls_ecp_point_free(&P2);
548    mbedtls_ecp_point_free(&R);
549    mbedtls_mpi_free(&u1);
550    mbedtls_mpi_free(&u2);
551}
552/* END_CASE */
553
554/* BEGIN_CASE */
555void ecp_fast_mod(int id, char *N_str)
556{
557    mbedtls_ecp_group grp;
558    mbedtls_mpi N, R;
559
560    mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
561    mbedtls_ecp_group_init(&grp);
562
563    TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
564    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
565    TEST_ASSERT(grp.modp != NULL);
566
567    /*
568     * Store correct result before we touch N
569     */
570    TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
571
572    TEST_ASSERT(grp.modp(&N) == 0);
573    TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
574
575    /*
576     * Use mod rather than addition/subtraction in case previous test fails
577     */
578    TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
579    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
580
581exit:
582    mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
583    mbedtls_ecp_group_free(&grp);
584}
585/* END_CASE */
586
587/* BEGIN_CASE */
588void ecp_write_binary(int id, char *x, char *y, char *z, int format,
589                      data_t *out, int blen, int ret)
590{
591    mbedtls_ecp_group grp;
592    mbedtls_ecp_point P;
593    unsigned char buf[256];
594    size_t olen;
595
596    memset(buf, 0, sizeof(buf));
597
598    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
599
600    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
601
602    TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
603    TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
604    TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
605
606    TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
607                                               &olen, buf, blen) == ret);
608
609    if (ret == 0) {
610        TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
611        TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
612    }
613
614exit:
615    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
616}
617/* END_CASE */
618
619/* BEGIN_CASE */
620void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
621                     int ret)
622{
623    mbedtls_ecp_group grp;
624    mbedtls_ecp_point P;
625    mbedtls_mpi X, Y, Z;
626
627
628    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
629    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
630
631    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
632
633    TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
634    TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
635    TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
636
637    TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
638
639    if (ret == 0) {
640        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
641        if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
642            TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
643            TEST_ASSERT(P.Y.p == NULL);
644            TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
645            TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
646        } else {
647            TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
648            TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
649
650            if (buf->x[0] == 0x04 &&
651                /* (reading compressed format supported only for
652                 *  Short Weierstrass curves with prime p where p = 3 mod 4) */
653                id != MBEDTLS_ECP_DP_SECP224R1 &&
654                id != MBEDTLS_ECP_DP_SECP224K1) {
655                /* re-encode in compressed format and test read again */
656                mbedtls_mpi_free(&P.Y);
657                buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
658                TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
659                TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
660            }
661        }
662    }
663
664exit:
665    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
666    mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
667}
668/* END_CASE */
669
670/* BEGIN_CASE */
671void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
672                                char *z, int ret)
673{
674    mbedtls_ecp_group grp;
675    mbedtls_ecp_point P;
676    mbedtls_mpi X, Y, Z;
677    const unsigned char *vbuf = buf->x;
678
679
680    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
681    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
682
683    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
684
685    TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
686    TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
687    TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
688
689    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
690
691    if (ret == 0) {
692        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
693        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
694        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
695        TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
696    }
697
698exit:
699    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
700    mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
701}
702/* END_CASE */
703
704/* BEGIN_CASE */
705void ecp_tls_write_read_point(int id)
706{
707    mbedtls_ecp_group grp;
708    mbedtls_ecp_point pt;
709    unsigned char buf[256];
710    const unsigned char *vbuf;
711    size_t olen;
712
713    mbedtls_ecp_group_init(&grp);
714    mbedtls_ecp_point_init(&pt);
715
716    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
717
718    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
719    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
720                                            MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
721    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
722    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
723    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
724    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
725    TEST_ASSERT(vbuf == buf + olen);
726
727    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
728    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
729                                            MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
730    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
731    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
732    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
733    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
734    TEST_ASSERT(vbuf == buf + olen);
735
736    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
737    TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
738    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
739                                            MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
740    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
741    TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
742    TEST_ASSERT(vbuf == buf + olen);
743
744    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
745    TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
746    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
747                                            MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
748    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
749    TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
750    TEST_ASSERT(vbuf == buf + olen);
751
752exit:
753    mbedtls_ecp_group_free(&grp);
754    mbedtls_ecp_point_free(&pt);
755}
756/* END_CASE */
757
758/* BEGIN_CASE */
759void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
760                                int record_len)
761{
762    mbedtls_ecp_group grp;
763    const unsigned char *vbuf = buf->x;
764    int ret;
765
766    mbedtls_ecp_group_init(&grp);
767
768    ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
769
770    TEST_ASSERT(ret == result);
771    if (ret == 0) {
772        TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
773        TEST_ASSERT(vbuf - buf->x ==  record_len);
774    }
775
776exit:
777    mbedtls_ecp_group_free(&grp);
778}
779/* END_CASE */
780
781/* BEGIN_CASE */
782void ecp_tls_write_read_group(int id)
783{
784    mbedtls_ecp_group grp1, grp2;
785    unsigned char buf[10];
786    const unsigned char *vbuf = buf;
787    size_t len;
788    int ret;
789
790    mbedtls_ecp_group_init(&grp1);
791    mbedtls_ecp_group_init(&grp2);
792    memset(buf, 0x00, sizeof(buf));
793
794    TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
795
796    TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
797    ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
798    TEST_ASSERT(ret == 0);
799
800    if (ret == 0) {
801        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
802        TEST_ASSERT(grp1.id == grp2.id);
803    }
804
805exit:
806    mbedtls_ecp_group_free(&grp1);
807    mbedtls_ecp_group_free(&grp2);
808}
809/* END_CASE */
810
811/* BEGIN_CASE */
812void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
813                                char *P, char *A, char *B,
814                                char *G_x, char *G_y, char *N,
815                                int tls_id)
816{
817    mbedtls_ecp_group grp, grp_read, grp_cpy;
818    const mbedtls_ecp_group_id *g_id;
819    mbedtls_ecp_group_id read_g_id;
820    const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
821
822    mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
823
824    unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
825    const unsigned char *vbuf = buf;
826    size_t olen;
827
828    mbedtls_ecp_group_init(&grp);
829    mbedtls_ecp_group_init(&grp_read);
830    mbedtls_ecp_group_init(&grp_cpy);
831
832    mbedtls_mpi_init(&exp_P);
833    mbedtls_mpi_init(&exp_A);
834    mbedtls_mpi_init(&exp_B);
835    mbedtls_mpi_init(&exp_G_x);
836    mbedtls_mpi_init(&exp_G_y);
837    mbedtls_mpi_init(&exp_N);
838
839    // Read expected parameters
840    TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
841    TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
842    TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
843    TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
844    TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
845    TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
846
847    // Convert exp_A to internal representation (A+2)/4
848    if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
849        TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
850        TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
851    }
852
853    // Load group
854    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
855
856    // Compare group with expected parameters
857    // A is NULL for SECPxxxR1 curves
858    // B and G_y are NULL for curve25519 and curve448
859    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
860    if (*A != 0) {
861        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
862    }
863    if (*B != 0) {
864        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
865    }
866    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
867    if (*G_y != 0) {
868        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
869    }
870    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
871
872    // Load curve info and compare with known values
873    crv = mbedtls_ecp_curve_info_from_grp_id(id);
874    TEST_EQUAL(crv->grp_id, id);
875    TEST_EQUAL(crv->bit_size, bit_size);
876    TEST_EQUAL(crv->tls_id, tls_id);
877
878    // Load curve from TLS ID and name, and compare IDs
879    crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
880    crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
881    TEST_EQUAL(crv_tls_id->grp_id, id);
882    TEST_EQUAL(crv_name->grp_id, id);
883
884    // Validate write_group against test data
885    TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
886                                           buf, sizeof(buf)),
887               0);
888    TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
889                                   sizeof(ecparameters)),
890               0);
891
892    // Read group from buffer and compare with expected ID
893    TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
894               0);
895    TEST_EQUAL(read_g_id, id);
896    vbuf = buf;
897    TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
898               0);
899    TEST_EQUAL(grp_read.id, id);
900
901    // Check curve type, and if it can be used for ECDH/ECDSA
902    TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
903#if defined(MBEDTLS_ECDH_C)
904    TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
905#endif
906#if defined(MBEDTLS_ECDSA_C)
907    TEST_EQUAL(mbedtls_ecdsa_can_do(id),
908               crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
909#endif
910
911    // Copy group and compare with original
912    TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
913    TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
914
915    // Check curve is in curve list and group ID list
916    for (crv = mbedtls_ecp_curve_list();
917         crv->grp_id != MBEDTLS_ECP_DP_NONE &&
918         crv->grp_id != (unsigned) id;
919         crv++) {
920        ;
921    }
922    TEST_EQUAL(crv->grp_id, id);
923    for (g_id = mbedtls_ecp_grp_id_list();
924         *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
925         g_id++) {
926        ;
927    }
928    TEST_EQUAL(*g_id, (unsigned) id);
929
930exit:
931    mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
932    mbedtls_ecp_group_free(&grp_read);
933    mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
934    mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
935    mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
936}
937/* END_CASE */
938
939/* BEGIN_CASE */
940void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
941{
942    mbedtls_ecp_group grp;
943    mbedtls_mpi d;
944
945    mbedtls_ecp_group_init(&grp);
946    mbedtls_mpi_init(&d);
947
948    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
949    TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
950
951    TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
952
953exit:
954    mbedtls_ecp_group_free(&grp);
955    mbedtls_mpi_free(&d);
956}
957/* END_CASE */
958
959/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
960void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
961                                int id, char *d, char *Qx, char *Qy,
962                                int ret)
963{
964    mbedtls_ecp_keypair pub, prv;
965    mbedtls_test_rnd_pseudo_info rnd_info;
966
967    mbedtls_ecp_keypair_init(&pub);
968    mbedtls_ecp_keypair_init(&prv);
969    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
970
971    if (id_pub != MBEDTLS_ECP_DP_NONE) {
972        TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
973    }
974    TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
975
976    if (id != MBEDTLS_ECP_DP_NONE) {
977        TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
978    }
979    TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
980    TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
981
982    TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
983                                           &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
984
985exit:
986    mbedtls_ecp_keypair_free(&pub);
987    mbedtls_ecp_keypair_free(&prv);
988}
989/* END_CASE */
990
991/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
992void mbedtls_ecp_gen_keypair(int id)
993{
994    mbedtls_ecp_group grp;
995    mbedtls_ecp_point Q;
996    mbedtls_mpi d;
997    mbedtls_test_rnd_pseudo_info rnd_info;
998
999    mbedtls_ecp_group_init(&grp);
1000    mbedtls_ecp_point_init(&Q);
1001    mbedtls_mpi_init(&d);
1002    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1003
1004    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1005
1006    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1007                                        &mbedtls_test_rnd_pseudo_rand,
1008                                        &rnd_info) == 0);
1009
1010    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1011    TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
1012
1013exit:
1014    mbedtls_ecp_group_free(&grp);
1015    mbedtls_ecp_point_free(&Q);
1016    mbedtls_mpi_free(&d);
1017}
1018/* END_CASE */
1019
1020/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
1021void mbedtls_ecp_gen_key(int id)
1022{
1023    mbedtls_ecp_keypair key;
1024    mbedtls_test_rnd_pseudo_info rnd_info;
1025
1026    mbedtls_ecp_keypair_init(&key);
1027    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1028
1029    TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1030                                    &mbedtls_test_rnd_pseudo_rand,
1031                                    &rnd_info) == 0);
1032
1033    TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1034    TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
1035
1036exit:
1037    mbedtls_ecp_keypair_free(&key);
1038}
1039/* END_CASE */
1040
1041/* BEGIN_CASE */
1042void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
1043{
1044    int ret = 0;
1045    mbedtls_ecp_keypair key;
1046    mbedtls_ecp_keypair key2;
1047
1048    mbedtls_ecp_keypair_init(&key);
1049    mbedtls_ecp_keypair_init(&key2);
1050
1051    ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1052    TEST_ASSERT(ret == expected);
1053
1054    if (expected == 0) {
1055        ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1056        TEST_ASSERT(ret == 0);
1057
1058        if (canonical) {
1059            unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
1060
1061            ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1062            TEST_ASSERT(ret == 0);
1063
1064            TEST_MEMORY_COMPARE(in_key->x, in_key->len,
1065                                buf, in_key->len);
1066        } else {
1067            unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
1068            unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
1069
1070            ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1071            TEST_ASSERT(ret == 0);
1072
1073            ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1074            TEST_ASSERT(ret == expected);
1075
1076            ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1077            TEST_ASSERT(ret == 0);
1078
1079            TEST_MEMORY_COMPARE(export1, in_key->len,
1080                                export2, in_key->len);
1081        }
1082    }
1083
1084exit:
1085    mbedtls_ecp_keypair_free(&key);
1086    mbedtls_ecp_keypair_free(&key2);
1087}
1088/* END_CASE */
1089
1090/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBEDTLS_ECP_LIGHT */
1091void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
1092{
1093    mbedtls_test_rnd_buf_info rnd_info;
1094    mbedtls_mpi d;
1095    int ret;
1096    uint8_t *actual = NULL;
1097
1098    mbedtls_mpi_init(&d);
1099    rnd_info.buf = seed->x;
1100    rnd_info.length = seed->len;
1101    rnd_info.fallback_f_rng = NULL;
1102    rnd_info.fallback_p_rng = NULL;
1103
1104    TEST_CALLOC(actual, expected->len);
1105
1106    ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1107                                     mbedtls_test_rnd_buffer_rand, &rnd_info);
1108
1109    if (expected->len == 0) {
1110        /* Expecting an error (happens if there isn't enough randomness) */
1111        TEST_ASSERT(ret != 0);
1112    } else {
1113        TEST_EQUAL(ret, 0);
1114        TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1115        TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
1116        /* Test the exact result. This assumes that the output of the
1117         * RNG is used in a specific way, which is overly constraining.
1118         * The advantage is that it's easier to test the expected properties
1119         * of the generated key:
1120         * - The most significant bit must be at a specific positions
1121         *   (can be enforced by checking the bit-length).
1122         * - The least significant bits must have specific values
1123         *   (can be enforced by checking these bits).
1124         * - Other bits must be random (by testing with different RNG outputs,
1125         *   we validate that those bits are indeed influenced by the RNG). */
1126        TEST_MEMORY_COMPARE(expected->x, expected->len,
1127                            actual, expected->len);
1128    }
1129
1130exit:
1131    mbedtls_free(actual);
1132    mbedtls_mpi_free(&d);
1133}
1134/* END_CASE */
1135
1136/* BEGIN_CASE */
1137void ecp_set_zero(int id, data_t *P_bin)
1138{
1139    mbedtls_ecp_group grp;
1140    mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1141
1142    mbedtls_ecp_group_init(&grp);
1143    mbedtls_ecp_point_init(&pt);
1144    mbedtls_ecp_point_init(&zero_pt);
1145    mbedtls_ecp_point_init(&nonzero_pt);
1146
1147    // Set zero and non-zero points for comparison
1148    TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1149    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1150    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1151                                             P_bin->x, P_bin->len), 0);
1152    TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1153    TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
1154
1155    // Test initialized point
1156    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1157    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1158    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1159    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1160               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1161
1162    // Test zeroed point
1163    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1164    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1165    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1166    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1167               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1168
1169    // Set point to non-zero value
1170    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1171                                             P_bin->x, P_bin->len), 0);
1172    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1173    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1174               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1175    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
1176
1177    // Test non-zero point
1178    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1179    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1180    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1181    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1182               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1183
1184    // Test freed non-zero point
1185    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1186                                             P_bin->x, P_bin->len), 0);
1187    mbedtls_ecp_point_free(&pt);
1188    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1189    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1190    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1191    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1192               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1193
1194exit:
1195    mbedtls_ecp_group_free(&grp);
1196    mbedtls_ecp_point_free(&pt);
1197    mbedtls_ecp_point_free(&zero_pt);
1198    mbedtls_ecp_point_free(&nonzero_pt);
1199}
1200/* END_CASE */
1201
1202/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
1203void ecp_selftest()
1204{
1205    TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
1206}
1207/* END_CASE */
1208
1209/* BEGIN_CASE */
1210void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
1211{
1212    mbedtls_ecp_keypair key;
1213    mbedtls_ecp_group export_grp;
1214    mbedtls_mpi export_d;
1215    mbedtls_ecp_point export_Q;
1216
1217    mbedtls_ecp_group_init(&export_grp);
1218    mbedtls_ecp_group_init(&key.grp);
1219    mbedtls_mpi_init(&export_d);
1220    mbedtls_ecp_point_init(&export_Q);
1221
1222    mbedtls_ecp_keypair_init(&key);
1223    if (invalid_grp == 0) {
1224        TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1225    }
1226    TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1227    TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
1228
1229    TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1230                                  &export_d, &export_Q), expected_ret);
1231
1232    if (expected_ret == 0) {
1233        TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1234        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1235        TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
1236    }
1237
1238exit:
1239    mbedtls_ecp_keypair_free(&key);
1240    mbedtls_ecp_group_free(&export_grp);
1241    mbedtls_mpi_free(&export_d);
1242    mbedtls_ecp_point_free(&export_Q);
1243}
1244/* END_CASE */
1245
1246/* BEGIN_CASE */
1247void ecp_check_order(int id, char *expected_order_hex)
1248{
1249    mbedtls_ecp_group grp;
1250    mbedtls_mpi expected_n;
1251
1252    mbedtls_ecp_group_init(&grp);
1253    mbedtls_mpi_init(&expected_n);
1254
1255    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1256    TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
1257
1258    // check sign bits are well-formed (i.e. 1 or -1) - see #5810
1259    TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1260    TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
1261
1262    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
1263
1264exit:
1265    mbedtls_ecp_group_free(&grp);
1266    mbedtls_mpi_free(&expected_n);
1267}
1268/* END_CASE */
1269
1270/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1271void ecp_mod_p_generic_raw(int curve_id,
1272                           char *input_N,
1273                           char *input_X,
1274                           char *result)
1275{
1276    mbedtls_mpi_uint *X = NULL;
1277    mbedtls_mpi_uint *N = NULL;
1278    mbedtls_mpi_uint *res = NULL;
1279    size_t limbs_X;
1280    size_t limbs_N;
1281    size_t limbs_res;
1282
1283    size_t bytes;
1284    size_t limbs;
1285    size_t curve_bits;
1286    int (*curve_func)(mbedtls_mpi_uint *X, size_t X_limbs);
1287
1288    mbedtls_mpi_mod_modulus m;
1289    mbedtls_mpi_mod_modulus_init(&m);
1290
1291    TEST_EQUAL(mbedtls_test_read_mpi_core(&X,   &limbs_X,   input_X), 0);
1292    TEST_EQUAL(mbedtls_test_read_mpi_core(&N,   &limbs_N,   input_N), 0);
1293    TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result),  0);
1294    bytes = limbs_N * sizeof(mbedtls_mpi_uint);
1295
1296    switch (curve_id) {
1297#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1298        case MBEDTLS_ECP_DP_SECP192R1:
1299            limbs = BITS_TO_LIMBS(192) * 2;
1300            curve_bits = 192;
1301            curve_func = &mbedtls_ecp_mod_p192_raw;
1302            break;
1303#endif
1304#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1305        case MBEDTLS_ECP_DP_SECP224R1:
1306            limbs = BITS_TO_LIMBS(224) * 2;
1307            curve_bits = 224;
1308            curve_func = &mbedtls_ecp_mod_p224_raw;
1309            break;
1310#endif
1311#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1312        case MBEDTLS_ECP_DP_SECP256R1:
1313            limbs = BITS_TO_LIMBS(256) * 2;
1314            curve_bits = 256;
1315            curve_func = &mbedtls_ecp_mod_p256_raw;
1316            break;
1317#endif
1318#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1319        case MBEDTLS_ECP_DP_SECP384R1:
1320            limbs = BITS_TO_LIMBS(384) * 2;
1321            curve_bits = 384;
1322            curve_func = &mbedtls_ecp_mod_p384_raw;
1323            break;
1324#endif
1325#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1326        case MBEDTLS_ECP_DP_SECP521R1:
1327            limbs = BITS_TO_LIMBS(521) * 2;
1328            curve_bits = 521;
1329            curve_func = &mbedtls_ecp_mod_p521_raw;
1330            break;
1331#endif
1332#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
1333        case MBEDTLS_ECP_DP_SECP192K1:
1334            limbs = BITS_TO_LIMBS(192) * 2;
1335            curve_bits = 192;
1336            curve_func = &mbedtls_ecp_mod_p192k1_raw;
1337            break;
1338#endif
1339#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
1340        case MBEDTLS_ECP_DP_SECP224K1:
1341            limbs = BITS_TO_LIMBS(224) * 2;
1342            curve_bits = 224;
1343            curve_func = &mbedtls_ecp_mod_p224k1_raw;
1344            break;
1345#endif
1346#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1347        case MBEDTLS_ECP_DP_SECP256K1:
1348            limbs = BITS_TO_LIMBS(256) * 2;
1349            curve_bits = 256;
1350            curve_func = &mbedtls_ecp_mod_p256k1_raw;
1351            break;
1352#endif
1353#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
1354        case MBEDTLS_ECP_DP_CURVE25519:
1355            limbs = BITS_TO_LIMBS(255) * 2;
1356            curve_bits = 255;
1357            curve_func = &mbedtls_ecp_mod_p255_raw;
1358            break;
1359#endif
1360#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1361        case MBEDTLS_ECP_DP_CURVE448:
1362            limbs = BITS_TO_LIMBS(448) * 2;
1363            curve_bits = 448;
1364            curve_func = &mbedtls_ecp_mod_p448_raw;
1365            break;
1366#endif
1367        default:
1368            mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__);
1369            goto exit;
1370    }
1371
1372    TEST_EQUAL(limbs_X, limbs);
1373    TEST_EQUAL(limbs_res, limbs_N);
1374
1375    TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1376                   &m, N, limbs_N), 0);
1377
1378    TEST_EQUAL((*curve_func)(X, limbs_X), 0);
1379
1380    mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1381    TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
1382    TEST_MEMORY_COMPARE(X, bytes, res, bytes);
1383
1384exit:
1385    mbedtls_free(X);
1386    mbedtls_free(res);
1387
1388    mbedtls_mpi_mod_modulus_free(&m);
1389    mbedtls_free(N);
1390}
1391/* END_CASE */
1392
1393/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1394void ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1395{
1396    int ret;
1397    mbedtls_mpi_mod_modulus m;
1398    mbedtls_mpi_mod_modulus_init(&m);
1399    mbedtls_mpi_uint *p = NULL;
1400    size_t p_limbs;
1401    size_t bytes;
1402
1403    TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1404
1405    ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1406    TEST_EQUAL(ret, iret);
1407
1408    if (ret == 0) {
1409        TEST_ASSERT(m.int_rep != MBEDTLS_MPI_MOD_REP_INVALID);
1410        /* Test for limb sizes */
1411        TEST_EQUAL(m.limbs, p_limbs);
1412        bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1413
1414        if (m.int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
1415            /* Test for validity of moduli by the presence of Montgomery consts */
1416            TEST_ASSERT(m.rep.mont.mm != 0);
1417            TEST_ASSERT(m.rep.mont.rr != NULL);
1418        } else {
1419            TEST_ASSERT(m.rep.ored.modp != NULL);
1420        }
1421
1422        /* Compare output byte-by-byte */
1423        TEST_MEMORY_COMPARE(p, bytes, m.p, bytes);
1424
1425        /* Test for user free-ing allocated memory */
1426        mbedtls_mpi_mod_modulus_free(&m);
1427    }
1428
1429exit:
1430    mbedtls_mpi_mod_modulus_free(&m);
1431    mbedtls_free(p);
1432}
1433/* END_CASE */
1434
1435/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1436void ecp_mod_mul_inv(char *input_A, int id, int ctype)
1437{
1438    size_t limbs;
1439    mbedtls_mpi_mod_modulus m;
1440    mbedtls_mpi_mod_residue rA; // For input
1441    mbedtls_mpi_mod_residue rA_inverse; // For inverse input
1442    mbedtls_mpi_mod_residue rX; // For result
1443    mbedtls_mpi_uint *rX_raw = NULL;
1444    mbedtls_mpi_uint *A_inverse = NULL;
1445    mbedtls_mpi_uint *A = NULL;
1446    mbedtls_mpi_uint *bufx = NULL;
1447    const mbedtls_mpi_uint one[1] = { 1 };
1448
1449    mbedtls_mpi_mod_modulus_init(&m);
1450
1451    TEST_ASSERT(mbedtls_ecp_modulus_setup(&m, id, ctype) == 0);
1452
1453    TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs, input_A), 0);
1454    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
1455
1456    /* Test for limb sizes */
1457    TEST_EQUAL(m.limbs, limbs);
1458
1459    TEST_CALLOC(A_inverse, limbs);
1460    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA_inverse, &m, A_inverse, limbs));
1461
1462    TEST_CALLOC(rX_raw, limbs);
1463    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1464
1465    /* Get inverse of A mode m, and multiply it with itself,
1466     * to see whether the result equal to '1' */
1467    TEST_EQUAL(0, mbedtls_mpi_mod_inv(&rA_inverse, &rA, &m));
1468    TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA_inverse, &m), 0);
1469
1470    TEST_CALLOC(bufx, limbs);
1471    TEST_EQUAL(mbedtls_mpi_mod_write(&rX, &m, (unsigned char *) bufx,
1472                                     limbs * ciL,
1473                                     MBEDTLS_MPI_MOD_EXT_REP_LE), 0);
1474
1475    TEST_MEMORY_COMPARE(bufx, ciL, one, ciL);
1476    /*Borrow the buffer of A to compare the left lims with 0 */
1477    memset(A, 0, limbs * ciL);
1478    TEST_MEMORY_COMPARE(&bufx[1], (limbs - 1) * ciL, A, (limbs - 1) * ciL);
1479
1480exit:
1481    mbedtls_mpi_mod_modulus_free(&m);
1482    mbedtls_mpi_mod_residue_release(&rA);
1483    mbedtls_mpi_mod_residue_release(&rA_inverse);
1484    mbedtls_mpi_mod_residue_release(&rX);
1485    mbedtls_free(A);
1486    mbedtls_free(A_inverse);
1487    mbedtls_free(rX_raw);
1488    mbedtls_free(bufx);
1489}
1490/* END_CASE */
1491
1492/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1493void ecp_mod_add_sub(char *input_A, char *input_B, int id, int ctype)
1494{
1495    size_t p_A_limbs;
1496    size_t p_B_limbs;
1497    size_t bytes;
1498    mbedtls_mpi_mod_modulus m;
1499    mbedtls_mpi_mod_residue rA;
1500    mbedtls_mpi_mod_residue rB;
1501    mbedtls_mpi_mod_residue rS;
1502    mbedtls_mpi_uint *p_A = NULL;
1503    mbedtls_mpi_uint *p_B = NULL;
1504    mbedtls_mpi_uint *p_S = NULL;
1505
1506    mbedtls_mpi_mod_modulus_init(&m);
1507
1508    TEST_EQUAL(mbedtls_test_read_mpi_core(&p_A, &p_A_limbs, input_A), 0);
1509    TEST_EQUAL(mbedtls_test_read_mpi_core(&p_B, &p_B_limbs, input_B), 0);
1510
1511    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1512
1513    /* Test for limb sizes for two input value and modulus */
1514    TEST_EQUAL(p_A_limbs, p_B_limbs);
1515    TEST_EQUAL(m.limbs, p_A_limbs);
1516    bytes = p_A_limbs * ciL;
1517
1518    TEST_CALLOC(p_S, p_A_limbs);
1519
1520    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rA, &m, p_A, p_A_limbs), 0);
1521    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rB, &m, p_B, p_B_limbs), 0);
1522    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rS, &m, p_S, p_A_limbs), 0);
1523
1524    /* Firstly add A and B to get the sum S, then subtract B,
1525     * the difference should be equal to A*/
1526    TEST_EQUAL(0, mbedtls_mpi_mod_add(&rS, &rA, &rB, &m));
1527    TEST_EQUAL(0, mbedtls_mpi_mod_sub(&rS, &rS, &rB, &m));
1528
1529    /* Compare difference with rA byte-by-byte */
1530    TEST_MEMORY_COMPARE(rA.p, bytes, rS.p, bytes);
1531
1532exit:
1533    mbedtls_mpi_mod_modulus_free(&m);
1534    mbedtls_mpi_mod_residue_release(&rA);
1535    mbedtls_mpi_mod_residue_release(&rB);
1536    mbedtls_mpi_mod_residue_release(&rS);
1537    mbedtls_free(p_A);
1538    mbedtls_free(p_B);
1539    mbedtls_free(p_S);
1540}
1541/* END_CASE */
1542
1543/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1544void ecp_mod_read_write(char *input_A, int id, int ctype)
1545{
1546    size_t limbs;
1547    size_t bytes;
1548    mbedtls_mpi_mod_modulus m;
1549    mbedtls_mpi_mod_residue rA; // For input
1550    mbedtls_mpi_mod_residue rX; // For read back
1551    mbedtls_mpi_uint *rX_raw = NULL;
1552    mbedtls_mpi_uint *A = NULL;
1553    mbedtls_mpi_uint *bufx = NULL;
1554
1555    mbedtls_mpi_mod_modulus_init(&m);
1556
1557    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1558
1559    TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &limbs, input_A));
1560    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
1561
1562    /* Test for limb sizes */
1563    TEST_EQUAL(m.limbs, limbs);
1564
1565    TEST_CALLOC(rX_raw, limbs);
1566    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1567
1568    bytes = limbs * ciL;
1569    TEST_CALLOC(bufx, limbs);
1570    /* Write source mod residue to a buffer, then read it back to
1571     * the destination mod residue, compare the two mod residues.
1572     * Firstly test little endian write and read */
1573    TEST_EQUAL(0, mbedtls_mpi_mod_write(&rA, &m, (unsigned char *) bufx,
1574                                        bytes, MBEDTLS_MPI_MOD_EXT_REP_LE));
1575
1576    TEST_EQUAL(0, mbedtls_mpi_mod_read(&rX, &m, (unsigned char *) bufx,
1577                                       bytes, MBEDTLS_MPI_MOD_EXT_REP_LE));
1578
1579    TEST_EQUAL(limbs, rX.limbs);
1580    TEST_MEMORY_COMPARE(rA.p, bytes, rX.p, bytes);
1581
1582    memset(bufx, 0x00, bytes);
1583    memset(rX_raw, 0x00, bytes);
1584    /* Then test big endian write and read */
1585    TEST_EQUAL(0, mbedtls_mpi_mod_write(&rA, &m, (unsigned char *) bufx,
1586                                        bytes,
1587                                        MBEDTLS_MPI_MOD_EXT_REP_BE));
1588
1589    TEST_EQUAL(0, mbedtls_mpi_mod_read(&rX, &m, (unsigned char *) bufx,
1590                                       bytes,
1591                                       MBEDTLS_MPI_MOD_EXT_REP_BE));
1592
1593    TEST_EQUAL(limbs, rX.limbs);
1594    TEST_MEMORY_COMPARE(rA.p, bytes, rX.p, bytes);
1595
1596exit:
1597    mbedtls_mpi_mod_modulus_free(&m);
1598    mbedtls_mpi_mod_residue_release(&rA);
1599    mbedtls_mpi_mod_residue_release(&rX);
1600    mbedtls_free(A);
1601    mbedtls_free(rX_raw);
1602    mbedtls_free(bufx);
1603}
1604/* END_CASE */
1605
1606/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1607void ecp_mod_random(int id, int ctype)
1608{
1609    size_t limbs;
1610    mbedtls_mpi_mod_modulus m;
1611    mbedtls_mpi_mod_residue rX; // For random data
1612    mbedtls_mpi_uint *rX_raw = NULL;
1613
1614    mbedtls_mpi_mod_modulus_init(&m);
1615    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1616
1617    limbs = m.limbs;
1618
1619    TEST_CALLOC(rX_raw, limbs);
1620    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1621
1622    TEST_EQUAL(0, mbedtls_mpi_mod_random(&rX, 1, &m,
1623                                         mbedtls_test_rnd_std_rand, NULL));
1624
1625    TEST_ASSERT(mbedtls_mpi_core_lt_ct(rX.p, m.p, limbs) == MBEDTLS_CT_TRUE);
1626
1627exit:
1628    mbedtls_mpi_mod_modulus_free(&m);
1629    mbedtls_mpi_mod_residue_release(&rX);
1630    mbedtls_free(rX_raw);
1631}
1632/* END_CASE */
1633
1634/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_LIGHT */
1635void check_variant()
1636{
1637    mbedtls_ecp_variant variant = mbedtls_ecp_get_variant();
1638
1639#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
1640    TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_UINT);
1641#else
1642    TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT);
1643#endif
1644}
1645/* END_CASE */
1646