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    mbedtls_ecp_keypair key;
594    unsigned char buf[256];
595    size_t olen;
596
597    memset(buf, 0, sizeof(buf));
598
599    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
600    mbedtls_ecp_keypair_init(&key);
601
602    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
603
604    TEST_EQUAL(mbedtls_test_read_mpi(&P.X, x), 0);
605    TEST_EQUAL(mbedtls_test_read_mpi(&P.Y, y), 0);
606    TEST_EQUAL(mbedtls_test_read_mpi(&P.Z, z), 0);
607
608    TEST_EQUAL(mbedtls_ecp_point_write_binary(&grp, &P, format,
609                                              &olen, buf, blen), ret);
610    if (ret == 0) {
611        TEST_LE_U(olen, MBEDTLS_ECP_MAX_PT_LEN);
612        ASSERT_COMPARE(buf, olen,
613                       out->x, out->len);
614    }
615
616    memset(buf, 0, blen);
617    TEST_EQUAL(mbedtls_ecp_set_public_key(grp.id, &key, &P), 0);
618    TEST_EQUAL(mbedtls_ecp_write_public_key(&key, format,
619                                            &olen, buf, blen), ret);
620    if (ret == 0) {
621        ASSERT_COMPARE(buf, olen,
622                       out->x, out->len);
623    }
624
625exit:
626    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
627    mbedtls_ecp_keypair_free(&key);
628}
629/* END_CASE */
630
631/* BEGIN_CASE */
632void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
633                     int ret)
634{
635    mbedtls_ecp_group grp;
636    mbedtls_ecp_point P;
637    mbedtls_mpi X, Y, Z;
638
639
640    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
641    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
642
643    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
644
645    TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
646    TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
647    TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
648
649    TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
650
651    if (ret == 0) {
652        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
653        if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
654            TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
655            TEST_ASSERT(P.Y.p == NULL);
656            TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
657            TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
658        } else {
659            TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
660            TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
661
662            if (buf->x[0] == 0x04 &&
663                /* (reading compressed format supported only for
664                 *  Short Weierstrass curves with prime p where p = 3 mod 4) */
665                id != MBEDTLS_ECP_DP_SECP224R1 &&
666                id != MBEDTLS_ECP_DP_SECP224K1) {
667                /* re-encode in compressed format and test read again */
668                mbedtls_mpi_free(&P.Y);
669                buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
670                TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
671                TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
672            }
673        }
674    }
675
676exit:
677    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
678    mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
679}
680/* END_CASE */
681
682/* BEGIN_CASE */
683void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
684                                char *z, int ret)
685{
686    mbedtls_ecp_group grp;
687    mbedtls_ecp_point P;
688    mbedtls_mpi X, Y, Z;
689    const unsigned char *vbuf = buf->x;
690
691
692    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
693    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
694
695    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
696
697    TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
698    TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
699    TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
700
701    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
702
703    if (ret == 0) {
704        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
705        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
706        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
707        TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
708    }
709
710exit:
711    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
712    mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
713}
714/* END_CASE */
715
716/* BEGIN_CASE */
717void ecp_tls_write_read_point(int id)
718{
719    mbedtls_ecp_group grp;
720    mbedtls_ecp_point pt;
721    unsigned char buf[256];
722    const unsigned char *vbuf;
723    size_t olen;
724
725    mbedtls_ecp_group_init(&grp);
726    mbedtls_ecp_point_init(&pt);
727
728    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
729
730    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
731    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
732                                            MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
733    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
734    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
735    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
736    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
737    TEST_ASSERT(vbuf == buf + olen);
738
739    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
740    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
741                                            MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
742    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
743    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
744    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
745    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
746    TEST_ASSERT(vbuf == buf + olen);
747
748    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
749    TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
750    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
751                                            MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
752    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
753    TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
754    TEST_ASSERT(vbuf == buf + olen);
755
756    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
757    TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
758    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
759                                            MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
760    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
761    TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
762    TEST_ASSERT(vbuf == buf + olen);
763
764exit:
765    mbedtls_ecp_group_free(&grp);
766    mbedtls_ecp_point_free(&pt);
767}
768/* END_CASE */
769
770/* BEGIN_CASE */
771void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
772                                int record_len)
773{
774    mbedtls_ecp_group grp;
775    const unsigned char *vbuf = buf->x;
776    int ret;
777
778    mbedtls_ecp_group_init(&grp);
779
780    ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
781
782    TEST_ASSERT(ret == result);
783    if (ret == 0) {
784        TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
785        TEST_ASSERT(vbuf - buf->x ==  record_len);
786    }
787
788exit:
789    mbedtls_ecp_group_free(&grp);
790}
791/* END_CASE */
792
793/* BEGIN_CASE */
794void ecp_tls_write_read_group(int id)
795{
796    mbedtls_ecp_group grp1, grp2;
797    unsigned char buf[10];
798    const unsigned char *vbuf = buf;
799    size_t len;
800    int ret;
801
802    mbedtls_ecp_group_init(&grp1);
803    mbedtls_ecp_group_init(&grp2);
804    memset(buf, 0x00, sizeof(buf));
805
806    TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
807
808    TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
809    ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
810    TEST_ASSERT(ret == 0);
811
812    if (ret == 0) {
813        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
814        TEST_ASSERT(grp1.id == grp2.id);
815    }
816
817exit:
818    mbedtls_ecp_group_free(&grp1);
819    mbedtls_ecp_group_free(&grp2);
820}
821/* END_CASE */
822
823/* BEGIN_CASE */
824void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
825                                char *P, char *A, char *B,
826                                char *G_x, char *G_y, char *N,
827                                int tls_id)
828{
829    mbedtls_ecp_group grp, grp_read, grp_cpy;
830    const mbedtls_ecp_group_id *g_id;
831    mbedtls_ecp_group_id read_g_id;
832    const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
833
834    mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
835
836    unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
837    const unsigned char *vbuf = buf;
838    size_t olen;
839
840    mbedtls_ecp_group_init(&grp);
841    mbedtls_ecp_group_init(&grp_read);
842    mbedtls_ecp_group_init(&grp_cpy);
843
844    mbedtls_mpi_init(&exp_P);
845    mbedtls_mpi_init(&exp_A);
846    mbedtls_mpi_init(&exp_B);
847    mbedtls_mpi_init(&exp_G_x);
848    mbedtls_mpi_init(&exp_G_y);
849    mbedtls_mpi_init(&exp_N);
850
851    // Read expected parameters
852    TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
853    TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
854    TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
855    TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
856    TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
857    TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
858
859    // Convert exp_A to internal representation (A+2)/4
860    if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
861        TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
862        TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
863    }
864
865    // Load group
866    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
867
868    // Compare group with expected parameters
869    // A is NULL for SECPxxxR1 curves
870    // B and G_y are NULL for curve25519 and curve448
871    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
872    if (*A != 0) {
873        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
874    }
875    if (*B != 0) {
876        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
877    }
878    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
879    if (*G_y != 0) {
880        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
881    }
882    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
883
884    // Load curve info and compare with known values
885    crv = mbedtls_ecp_curve_info_from_grp_id(id);
886    TEST_EQUAL(crv->grp_id, id);
887    TEST_EQUAL(crv->bit_size, bit_size);
888    TEST_EQUAL(crv->tls_id, tls_id);
889
890    // Load curve from TLS ID and name, and compare IDs
891    crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
892    crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
893    TEST_EQUAL(crv_tls_id->grp_id, id);
894    TEST_EQUAL(crv_name->grp_id, id);
895
896    // Validate write_group against test data
897    TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
898                                           buf, sizeof(buf)),
899               0);
900    TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
901                                   sizeof(ecparameters)),
902               0);
903
904    // Read group from buffer and compare with expected ID
905    TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
906               0);
907    TEST_EQUAL(read_g_id, id);
908    vbuf = buf;
909    TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
910               0);
911    TEST_EQUAL(grp_read.id, id);
912
913    // Check curve type, and if it can be used for ECDH/ECDSA
914    TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
915#if defined(MBEDTLS_ECDH_C)
916    TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
917#endif
918#if defined(MBEDTLS_ECDSA_C)
919    TEST_EQUAL(mbedtls_ecdsa_can_do(id),
920               crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
921#endif
922
923    // Copy group and compare with original
924    TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
925    TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
926
927    // Check curve is in curve list and group ID list
928    for (crv = mbedtls_ecp_curve_list();
929         crv->grp_id != MBEDTLS_ECP_DP_NONE &&
930         crv->grp_id != (unsigned) id;
931         crv++) {
932        ;
933    }
934    TEST_EQUAL(crv->grp_id, id);
935    for (g_id = mbedtls_ecp_grp_id_list();
936         *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
937         g_id++) {
938        ;
939    }
940    TEST_EQUAL(*g_id, (unsigned) id);
941
942exit:
943    mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
944    mbedtls_ecp_group_free(&grp_read);
945    mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
946    mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
947    mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
948}
949/* END_CASE */
950
951/* BEGIN_CASE */
952void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
953{
954    mbedtls_ecp_group grp;
955    mbedtls_mpi d;
956
957    mbedtls_ecp_group_init(&grp);
958    mbedtls_mpi_init(&d);
959
960    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
961    TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
962
963    TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
964
965exit:
966    mbedtls_ecp_group_free(&grp);
967    mbedtls_mpi_free(&d);
968}
969/* END_CASE */
970
971/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
972void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
973                                int id, char *d, char *Qx, char *Qy,
974                                int ret)
975{
976    mbedtls_ecp_keypair pub, prv;
977    mbedtls_test_rnd_pseudo_info rnd_info;
978
979    mbedtls_ecp_keypair_init(&pub);
980    mbedtls_ecp_keypair_init(&prv);
981    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
982
983    if (id_pub != MBEDTLS_ECP_DP_NONE) {
984        TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
985    }
986    TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
987
988    if (id != MBEDTLS_ECP_DP_NONE) {
989        TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
990    }
991    TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
992    TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
993
994    TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
995                                           &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
996
997exit:
998    mbedtls_ecp_keypair_free(&pub);
999    mbedtls_ecp_keypair_free(&prv);
1000}
1001/* END_CASE */
1002
1003/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
1004void ecp_calc_public(int grp_id, data_t *private_data,
1005                     int expected_ret, data_t *expected_public)
1006{
1007    mbedtls_ecp_keypair key;
1008    mbedtls_ecp_keypair_init(&key);
1009    mbedtls_test_rnd_pseudo_info rnd_info;
1010    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1011
1012    TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0);
1013    TEST_EQUAL(mbedtls_mpi_read_binary(&key.d,
1014                                       private_data->x, private_data->len), 0);
1015
1016    TEST_EQUAL(mbedtls_ecp_keypair_calc_public(&key,
1017                                               &mbedtls_test_rnd_pseudo_rand, &rnd_info),
1018               expected_ret);
1019
1020    if (expected_ret == 0) {
1021        TEST_EQUAL(mbedtls_ecp_check_pub_priv(&key, &key,
1022                                              &mbedtls_test_rnd_pseudo_rand, &rnd_info),
1023                   0);
1024        unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
1025        size_t length;
1026        TEST_EQUAL(mbedtls_ecp_point_write_binary(&key.grp, &key.Q,
1027                                                  MBEDTLS_ECP_PF_UNCOMPRESSED,
1028                                                  &length, buf, sizeof(buf)),
1029                   0);
1030        ASSERT_COMPARE(expected_public->x, expected_public->len, buf, length);
1031    }
1032
1033exit:
1034    mbedtls_ecp_keypair_free(&key);
1035}
1036/* END_CASE */
1037
1038/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
1039void mbedtls_ecp_gen_keypair(int id)
1040{
1041    mbedtls_ecp_group grp;
1042    mbedtls_ecp_point Q;
1043    mbedtls_mpi d;
1044    mbedtls_test_rnd_pseudo_info rnd_info;
1045
1046    mbedtls_ecp_group_init(&grp);
1047    mbedtls_ecp_point_init(&Q);
1048    mbedtls_mpi_init(&d);
1049    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1050
1051    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1052
1053    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1054                                        &mbedtls_test_rnd_pseudo_rand,
1055                                        &rnd_info) == 0);
1056
1057    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1058    TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
1059
1060exit:
1061    mbedtls_ecp_group_free(&grp);
1062    mbedtls_ecp_point_free(&Q);
1063    mbedtls_mpi_free(&d);
1064}
1065/* END_CASE */
1066
1067/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
1068void mbedtls_ecp_gen_key(int id)
1069{
1070    mbedtls_ecp_keypair key;
1071    mbedtls_test_rnd_pseudo_info rnd_info;
1072
1073    mbedtls_ecp_keypair_init(&key);
1074    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1075
1076    TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1077                                    &mbedtls_test_rnd_pseudo_rand,
1078                                    &rnd_info) == 0);
1079
1080    TEST_EQUAL(mbedtls_ecp_keypair_get_group_id(&key), id);
1081    TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1082    TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
1083
1084exit:
1085    mbedtls_ecp_keypair_free(&key);
1086}
1087/* END_CASE */
1088
1089/* BEGIN_CASE */
1090void ecp_set_public_key_group_check(int grp_id, int expected_ret)
1091{
1092    mbedtls_ecp_keypair key;
1093    mbedtls_ecp_keypair_init(&key);
1094    mbedtls_ecp_point Q;
1095    mbedtls_ecp_point_init(&Q);
1096
1097    TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q),
1098               expected_ret);
1099
1100exit:
1101    mbedtls_ecp_keypair_free(&key);
1102    mbedtls_ecp_point_free(&Q);
1103}
1104/* END_CASE */
1105
1106/* BEGIN_CASE */
1107void ecp_set_public_key_good(int grp_id, data_t *public_data)
1108{
1109    mbedtls_ecp_keypair key;
1110    mbedtls_ecp_keypair_init(&key);
1111    mbedtls_ecp_group grp;
1112    mbedtls_ecp_group_init(&grp);
1113    mbedtls_ecp_point Q;
1114    mbedtls_ecp_point_init(&Q);
1115
1116    TEST_EQUAL(mbedtls_ecp_group_load(&grp, grp_id), 0);
1117    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q,
1118                                             public_data->x, public_data->len),
1119               0);
1120
1121    /* Freshly initialized key */
1122    TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0);
1123    TEST_EQUAL(key.grp.id, grp_id);
1124    TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0);
1125
1126    /* Key with a public key already set to a different value */
1127    TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.X, &key.Q.X, 1), 0);
1128    TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Y, &key.Q.Y, 1), 0);
1129    TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Z, &key.Q.Z, 1), 0);
1130    TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0);
1131    TEST_EQUAL(key.grp.id, grp_id);
1132    TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0);
1133
1134exit:
1135    mbedtls_ecp_keypair_free(&key);
1136    mbedtls_ecp_group_free(&grp);
1137    mbedtls_ecp_point_free(&Q);
1138}
1139/* END_CASE */
1140
1141/* BEGIN_CASE */
1142void ecp_set_public_key_after_private(int private_grp_id, data_t *private_data,
1143                                      int public_grp_id, data_t *public_data)
1144{
1145    mbedtls_ecp_keypair key;
1146    mbedtls_ecp_keypair_init(&key);
1147    mbedtls_ecp_group grp;
1148    mbedtls_ecp_group_init(&grp);
1149    mbedtls_ecp_point Q;
1150    mbedtls_ecp_point_init(&Q);
1151    mbedtls_mpi d;
1152    mbedtls_mpi_init(&d);
1153
1154    TEST_EQUAL(mbedtls_ecp_group_load(&grp, public_grp_id), 0);
1155    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q,
1156                                             public_data->x, public_data->len),
1157               0);
1158    TEST_EQUAL(mbedtls_ecp_read_key(private_grp_id, &key,
1159                                    private_data->x, private_data->len),
1160               0);
1161    TEST_EQUAL(mbedtls_mpi_copy(&d, &key.d), 0);
1162
1163    int ret = mbedtls_ecp_set_public_key(public_grp_id, &key, &Q);
1164
1165    if (private_grp_id == public_grp_id) {
1166        TEST_EQUAL(ret, 0);
1167        TEST_EQUAL(key.grp.id, public_grp_id);
1168        TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0);
1169        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&d, &key.d), 0);
1170    } else {
1171        TEST_EQUAL(ret, MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1172    }
1173
1174exit:
1175    mbedtls_ecp_keypair_free(&key);
1176    mbedtls_ecp_group_free(&grp);
1177    mbedtls_ecp_point_free(&Q);
1178    mbedtls_mpi_free(&d);
1179}
1180/* END_CASE */
1181
1182/* BEGIN_CASE */
1183void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
1184{
1185    int ret = 0;
1186    mbedtls_ecp_keypair key;
1187    mbedtls_ecp_keypair_init(&key);
1188    mbedtls_ecp_keypair key2;
1189    mbedtls_ecp_keypair_init(&key2);
1190
1191    TEST_EQUAL(mbedtls_mpi_lset(&key.Q.X, 1), 0);
1192    TEST_EQUAL(mbedtls_mpi_lset(&key.Q.Y, 2), 0);
1193    TEST_EQUAL(mbedtls_mpi_lset(&key.Q.Z, 3), 0);
1194
1195    ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1196    TEST_ASSERT(ret == expected);
1197
1198    if (expected == 0) {
1199        TEST_EQUAL(mbedtls_ecp_keypair_get_group_id(&key), grp_id);
1200        ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1201        TEST_ASSERT(ret == 0);
1202
1203        TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.X, 1), 0);
1204        TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Y, 2), 0);
1205        TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Z, 3), 0);
1206
1207        if (canonical && in_key->len == (key.grp.nbits + 7) / 8) {
1208            unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
1209            size_t length = 0xdeadbeef;
1210
1211            TEST_EQUAL(mbedtls_ecp_write_key_ext(&key,
1212                                                 &length, buf, in_key->len), 0);
1213            TEST_MEMORY_COMPARE(in_key->x, in_key->len,
1214                                buf, length);
1215
1216#if defined(MBEDTLS_TEST_DEPRECATED)
1217            memset(buf, 0, sizeof(buf));
1218            TEST_EQUAL(mbedtls_ecp_write_key(&key, buf, in_key->len), 0);
1219            TEST_MEMORY_COMPARE(in_key->x, in_key->len,
1220                                buf, in_key->len);
1221#endif /* MBEDTLS_TEST_DEPRECATED */
1222        } else {
1223            unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
1224            unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
1225
1226            size_t length1 = 0xdeadbeef;
1227            TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &length1,
1228                                                 export1, sizeof(export1)), 0);
1229            TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, length1),
1230                       expected);
1231            size_t length2 = 0xdeadbeef;
1232            TEST_EQUAL(mbedtls_ecp_write_key_ext(&key2, &length2,
1233                                                 export2, sizeof(export2)), 0);
1234            TEST_MEMORY_COMPARE(export1, length1,
1235                                export2, length2);
1236
1237#if defined(MBEDTLS_TEST_DEPRECATED)
1238            memset(export1, 0, sizeof(export1));
1239            memset(export2, 0, sizeof(export2));
1240            TEST_EQUAL(mbedtls_ecp_write_key(&key, export1, in_key->len), 0);
1241            TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len),
1242                       expected);
1243            TEST_EQUAL(mbedtls_ecp_write_key(&key2, export2, in_key->len), 0);
1244            TEST_MEMORY_COMPARE(export1, in_key->len,
1245                                export2, in_key->len);
1246#endif /* MBEDTLS_TEST_DEPRECATED */
1247        }
1248    }
1249
1250exit:
1251    mbedtls_ecp_keypair_free(&key);
1252    mbedtls_ecp_keypair_free(&key2);
1253}
1254/* END_CASE */
1255
1256/* BEGIN_CASE depends_on:MBEDTLS_TEST_DEPRECATED */
1257void ecp_write_key(int grp_id, data_t *in_key,
1258                   int exported_size, int expected_ret)
1259{
1260    mbedtls_ecp_keypair key;
1261    mbedtls_ecp_keypair_init(&key);
1262    unsigned char *exported = NULL;
1263
1264    TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len), 0);
1265
1266    TEST_CALLOC(exported, exported_size);
1267    TEST_EQUAL(mbedtls_ecp_write_key(&key, exported, exported_size),
1268               expected_ret);
1269
1270    if (expected_ret == 0) {
1271        size_t length = (key.grp.nbits + 7) / 8;
1272        const unsigned char *key_start = NULL;
1273        const unsigned char *zeros_start = NULL;
1274        switch (mbedtls_ecp_get_type(&key.grp)) {
1275            case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS:
1276                if ((size_t) exported_size < length) {
1277                    length = exported_size;
1278                }
1279                key_start = exported + exported_size - length;
1280                zeros_start = exported;
1281                break;
1282            case MBEDTLS_ECP_TYPE_MONTGOMERY:
1283                TEST_LE_U(length, exported_size);
1284                key_start = exported;
1285                zeros_start = exported + length;
1286                break;
1287            default:
1288                TEST_FAIL("Unknown ECP curve type");
1289                break;
1290        }
1291
1292        if (length < in_key->len) {
1293            /* Shorter output (only possible with Weierstrass keys) */
1294            for (size_t i = 0; i < in_key->len - length; i++) {
1295                mbedtls_test_set_step(i);
1296                TEST_EQUAL(in_key->x[i], 0);
1297            }
1298            TEST_MEMORY_COMPARE(in_key->x + in_key->len - length, length,
1299                                key_start, length);
1300        } else {
1301            TEST_MEMORY_COMPARE(in_key->x, in_key->len,
1302                                key_start, length);
1303            for (size_t i = 0; i < exported_size - length; i++) {
1304                mbedtls_test_set_step(i);
1305                TEST_EQUAL(zeros_start[i], 0);
1306            }
1307        }
1308    }
1309
1310exit:
1311    mbedtls_ecp_keypair_free(&key);
1312    mbedtls_free(exported);
1313}
1314/* END_CASE */
1315
1316/* BEGIN_CASE */
1317void ecp_write_key_ext(int grp_id, data_t *in_key,
1318                       int exported_size, int expected_ret)
1319{
1320    mbedtls_ecp_keypair key;
1321    mbedtls_ecp_keypair_init(&key);
1322    unsigned char *exported = NULL;
1323
1324    if (in_key->len != 0) {
1325        TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len), 0);
1326    } else if (grp_id != MBEDTLS_ECP_DP_NONE) {
1327        TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0);
1328    }
1329
1330    TEST_CALLOC(exported, exported_size);
1331    size_t olen = 0xdeadbeef;
1332    TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &olen, exported, exported_size),
1333               expected_ret);
1334
1335    if (expected_ret == 0) {
1336        TEST_EQUAL(olen, (key.grp.nbits + 7) / 8);
1337        TEST_LE_U(olen, MBEDTLS_ECP_MAX_BYTES);
1338        TEST_MEMORY_COMPARE(in_key->x, in_key->len,
1339                            exported, olen);
1340    } else {
1341        /* Robustness check: even in the error case, insist that olen is less
1342         * than the buffer size. */
1343        TEST_LE_U(olen, exported_size);
1344    }
1345
1346exit:
1347    mbedtls_ecp_keypair_free(&key);
1348    mbedtls_free(exported);
1349}
1350/* END_CASE */
1351
1352/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBEDTLS_ECP_LIGHT */
1353void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
1354{
1355    mbedtls_test_rnd_buf_info rnd_info;
1356    mbedtls_mpi d;
1357    int ret;
1358    uint8_t *actual = NULL;
1359
1360    mbedtls_mpi_init(&d);
1361    rnd_info.buf = seed->x;
1362    rnd_info.length = seed->len;
1363    rnd_info.fallback_f_rng = NULL;
1364    rnd_info.fallback_p_rng = NULL;
1365
1366    TEST_CALLOC(actual, expected->len);
1367
1368    ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1369                                     mbedtls_test_rnd_buffer_rand, &rnd_info);
1370
1371    if (expected->len == 0) {
1372        /* Expecting an error (happens if there isn't enough randomness) */
1373        TEST_ASSERT(ret != 0);
1374    } else {
1375        TEST_EQUAL(ret, 0);
1376        TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1377        TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
1378        /* Test the exact result. This assumes that the output of the
1379         * RNG is used in a specific way, which is overly constraining.
1380         * The advantage is that it's easier to test the expected properties
1381         * of the generated key:
1382         * - The most significant bit must be at a specific positions
1383         *   (can be enforced by checking the bit-length).
1384         * - The least significant bits must have specific values
1385         *   (can be enforced by checking these bits).
1386         * - Other bits must be random (by testing with different RNG outputs,
1387         *   we validate that those bits are indeed influenced by the RNG). */
1388        TEST_MEMORY_COMPARE(expected->x, expected->len,
1389                            actual, expected->len);
1390    }
1391
1392exit:
1393    mbedtls_free(actual);
1394    mbedtls_mpi_free(&d);
1395}
1396/* END_CASE */
1397
1398/* BEGIN_CASE */
1399void ecp_set_zero(int id, data_t *P_bin)
1400{
1401    mbedtls_ecp_group grp;
1402    mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1403
1404    mbedtls_ecp_group_init(&grp);
1405    mbedtls_ecp_point_init(&pt);
1406    mbedtls_ecp_point_init(&zero_pt);
1407    mbedtls_ecp_point_init(&nonzero_pt);
1408
1409    // Set zero and non-zero points for comparison
1410    TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1411    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1412    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1413                                             P_bin->x, P_bin->len), 0);
1414    TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1415    TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
1416
1417    // Test initialized point
1418    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1419    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1420    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1421    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1422               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1423
1424    // Test zeroed point
1425    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1426    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1427    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1428    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1429               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1430
1431    // Set point to non-zero value
1432    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1433                                             P_bin->x, P_bin->len), 0);
1434    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1435    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1436               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1437    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
1438
1439    // Test non-zero point
1440    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1441    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1442    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1443    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1444               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1445
1446    // Test freed non-zero point
1447    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1448                                             P_bin->x, P_bin->len), 0);
1449    mbedtls_ecp_point_free(&pt);
1450    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1451    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1452    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1453    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1454               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1455
1456exit:
1457    mbedtls_ecp_group_free(&grp);
1458    mbedtls_ecp_point_free(&pt);
1459    mbedtls_ecp_point_free(&zero_pt);
1460    mbedtls_ecp_point_free(&nonzero_pt);
1461}
1462/* END_CASE */
1463
1464/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
1465void ecp_selftest()
1466{
1467    TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
1468}
1469/* END_CASE */
1470
1471/* BEGIN_CASE */
1472void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
1473{
1474    mbedtls_ecp_keypair key;
1475    mbedtls_ecp_group export_grp;
1476    mbedtls_mpi export_d;
1477    mbedtls_ecp_point export_Q;
1478
1479    mbedtls_ecp_group_init(&export_grp);
1480    mbedtls_ecp_group_init(&key.grp);
1481    mbedtls_mpi_init(&export_d);
1482    mbedtls_ecp_point_init(&export_Q);
1483
1484    mbedtls_ecp_keypair_init(&key);
1485    if (invalid_grp == 0) {
1486        TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1487    }
1488    TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1489    TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
1490
1491    TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1492                                  &export_d, &export_Q), expected_ret);
1493
1494    if (expected_ret == 0) {
1495        TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1496        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1497        TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
1498
1499        /* Check consistency with the group id */
1500        TEST_EQUAL(export_grp.id,
1501                   mbedtls_ecp_keypair_get_group_id(&key));
1502
1503        /* Test null arguments: grp only */
1504        mbedtls_ecp_group_free(&export_grp);
1505        mbedtls_ecp_group_init(&export_grp);
1506        TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp, NULL, NULL), 0);
1507        TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
1508
1509        /* Test null arguments: d only */
1510        mbedtls_mpi_free(&export_d);
1511        mbedtls_mpi_init(&export_d);
1512        TEST_EQUAL(mbedtls_ecp_export(&key, NULL, &export_d, NULL), 0);
1513        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1514
1515        /* Test null arguments: Q only */
1516        mbedtls_ecp_point_free(&export_Q);
1517        mbedtls_ecp_point_init(&export_Q);
1518        TEST_EQUAL(mbedtls_ecp_export(&key, NULL, NULL, &export_Q), 0);
1519        TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1520    }
1521
1522exit:
1523    mbedtls_ecp_keypair_free(&key);
1524    mbedtls_ecp_group_free(&export_grp);
1525    mbedtls_mpi_free(&export_d);
1526    mbedtls_ecp_point_free(&export_Q);
1527}
1528/* END_CASE */
1529
1530/* BEGIN_CASE */
1531void ecp_check_order(int id, char *expected_order_hex)
1532{
1533    mbedtls_ecp_group grp;
1534    mbedtls_mpi expected_n;
1535
1536    mbedtls_ecp_group_init(&grp);
1537    mbedtls_mpi_init(&expected_n);
1538
1539    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1540    TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
1541
1542    // check sign bits are well-formed (i.e. 1 or -1) - see #5810
1543    TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1544    TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
1545
1546    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
1547
1548exit:
1549    mbedtls_ecp_group_free(&grp);
1550    mbedtls_mpi_free(&expected_n);
1551}
1552/* END_CASE */
1553
1554/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1555void ecp_mod_p_generic_raw(int curve_id,
1556                           char *input_N,
1557                           char *input_X,
1558                           char *result)
1559{
1560    mbedtls_mpi_uint *X = NULL;
1561    mbedtls_mpi_uint *N = NULL;
1562    mbedtls_mpi_uint *res = NULL;
1563    size_t limbs_X;
1564    size_t limbs_N;
1565    size_t limbs_res;
1566
1567    size_t bytes;
1568    size_t limbs;
1569    size_t curve_bits;
1570    int (*curve_func)(mbedtls_mpi_uint *X, size_t X_limbs);
1571
1572    mbedtls_mpi_mod_modulus m;
1573    mbedtls_mpi_mod_modulus_init(&m);
1574
1575    TEST_EQUAL(mbedtls_test_read_mpi_core(&X,   &limbs_X,   input_X), 0);
1576    TEST_EQUAL(mbedtls_test_read_mpi_core(&N,   &limbs_N,   input_N), 0);
1577    TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result),  0);
1578    bytes = limbs_N * sizeof(mbedtls_mpi_uint);
1579
1580    switch (curve_id) {
1581#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1582        case MBEDTLS_ECP_DP_SECP192R1:
1583            limbs = BITS_TO_LIMBS(192) * 2;
1584            curve_bits = 192;
1585            curve_func = &mbedtls_ecp_mod_p192_raw;
1586            break;
1587#endif
1588#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1589        case MBEDTLS_ECP_DP_SECP224R1:
1590            limbs = BITS_TO_LIMBS(224) * 2;
1591            curve_bits = 224;
1592            curve_func = &mbedtls_ecp_mod_p224_raw;
1593            break;
1594#endif
1595#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1596        case MBEDTLS_ECP_DP_SECP256R1:
1597            limbs = BITS_TO_LIMBS(256) * 2;
1598            curve_bits = 256;
1599            curve_func = &mbedtls_ecp_mod_p256_raw;
1600            break;
1601#endif
1602#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1603        case MBEDTLS_ECP_DP_SECP384R1:
1604            limbs = BITS_TO_LIMBS(384) * 2;
1605            curve_bits = 384;
1606            curve_func = &mbedtls_ecp_mod_p384_raw;
1607            break;
1608#endif
1609#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1610        case MBEDTLS_ECP_DP_SECP521R1:
1611            limbs = BITS_TO_LIMBS(521) * 2;
1612            curve_bits = 521;
1613            curve_func = &mbedtls_ecp_mod_p521_raw;
1614            break;
1615#endif
1616#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
1617        case MBEDTLS_ECP_DP_SECP192K1:
1618            limbs = BITS_TO_LIMBS(192) * 2;
1619            curve_bits = 192;
1620            curve_func = &mbedtls_ecp_mod_p192k1_raw;
1621            break;
1622#endif
1623#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
1624        case MBEDTLS_ECP_DP_SECP224K1:
1625            limbs = BITS_TO_LIMBS(224) * 2;
1626            curve_bits = 224;
1627            curve_func = &mbedtls_ecp_mod_p224k1_raw;
1628            break;
1629#endif
1630#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1631        case MBEDTLS_ECP_DP_SECP256K1:
1632            limbs = BITS_TO_LIMBS(256) * 2;
1633            curve_bits = 256;
1634            curve_func = &mbedtls_ecp_mod_p256k1_raw;
1635            break;
1636#endif
1637#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
1638        case MBEDTLS_ECP_DP_CURVE25519:
1639            limbs = BITS_TO_LIMBS(255) * 2;
1640            curve_bits = 255;
1641            curve_func = &mbedtls_ecp_mod_p255_raw;
1642            break;
1643#endif
1644#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1645        case MBEDTLS_ECP_DP_CURVE448:
1646            limbs = BITS_TO_LIMBS(448) * 2;
1647            curve_bits = 448;
1648            curve_func = &mbedtls_ecp_mod_p448_raw;
1649            break;
1650#endif
1651        default:
1652            mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__);
1653            goto exit;
1654    }
1655
1656    TEST_EQUAL(limbs_X, limbs);
1657    TEST_EQUAL(limbs_res, limbs_N);
1658
1659    TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1660                   &m, N, limbs_N), 0);
1661
1662    TEST_EQUAL((*curve_func)(X, limbs_X), 0);
1663
1664    mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1665    TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
1666    TEST_MEMORY_COMPARE(X, bytes, res, bytes);
1667
1668exit:
1669    mbedtls_free(X);
1670    mbedtls_free(res);
1671
1672    mbedtls_mpi_mod_modulus_free(&m);
1673    mbedtls_free(N);
1674}
1675/* END_CASE */
1676
1677/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1678void ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1679{
1680    int ret;
1681    mbedtls_mpi_mod_modulus m;
1682    mbedtls_mpi_mod_modulus_init(&m);
1683    mbedtls_mpi_uint *p = NULL;
1684    size_t p_limbs;
1685    size_t bytes;
1686
1687    TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1688
1689    ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1690    TEST_EQUAL(ret, iret);
1691
1692    if (ret == 0) {
1693        TEST_ASSERT(m.int_rep != MBEDTLS_MPI_MOD_REP_INVALID);
1694        /* Test for limb sizes */
1695        TEST_EQUAL(m.limbs, p_limbs);
1696        bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1697
1698        if (m.int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
1699            /* Test for validity of moduli by the presence of Montgomery consts */
1700            TEST_ASSERT(m.rep.mont.mm != 0);
1701            TEST_ASSERT(m.rep.mont.rr != NULL);
1702        } else {
1703            TEST_ASSERT(m.rep.ored.modp != NULL);
1704        }
1705
1706        /* Compare output byte-by-byte */
1707        TEST_MEMORY_COMPARE(p, bytes, m.p, bytes);
1708
1709        /* Test for user free-ing allocated memory */
1710        mbedtls_mpi_mod_modulus_free(&m);
1711    }
1712
1713exit:
1714    mbedtls_mpi_mod_modulus_free(&m);
1715    mbedtls_free(p);
1716}
1717/* END_CASE */
1718
1719/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1720void ecp_mod_mul_inv(char *input_A, int id, int ctype)
1721{
1722    size_t limbs;
1723    mbedtls_mpi_mod_modulus m;
1724    mbedtls_mpi_mod_residue rA; // For input
1725    mbedtls_mpi_mod_residue rA_inverse; // For inverse input
1726    mbedtls_mpi_mod_residue rX; // For result
1727    mbedtls_mpi_uint *rX_raw = NULL;
1728    mbedtls_mpi_uint *A_inverse = NULL;
1729    mbedtls_mpi_uint *A = NULL;
1730    mbedtls_mpi_uint *bufx = NULL;
1731    const mbedtls_mpi_uint one[1] = { 1 };
1732
1733    mbedtls_mpi_mod_modulus_init(&m);
1734
1735    TEST_ASSERT(mbedtls_ecp_modulus_setup(&m, id, ctype) == 0);
1736
1737    TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs, input_A), 0);
1738    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
1739
1740    /* Test for limb sizes */
1741    TEST_EQUAL(m.limbs, limbs);
1742
1743    TEST_CALLOC(A_inverse, limbs);
1744    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA_inverse, &m, A_inverse, limbs));
1745
1746    TEST_CALLOC(rX_raw, limbs);
1747    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1748
1749    /* Get inverse of A mode m, and multiply it with itself,
1750     * to see whether the result equal to '1' */
1751    TEST_EQUAL(0, mbedtls_mpi_mod_inv(&rA_inverse, &rA, &m));
1752    TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA_inverse, &m), 0);
1753
1754    TEST_CALLOC(bufx, limbs);
1755    TEST_EQUAL(mbedtls_mpi_mod_write(&rX, &m, (unsigned char *) bufx,
1756                                     limbs * ciL,
1757                                     MBEDTLS_MPI_MOD_EXT_REP_LE), 0);
1758
1759    TEST_MEMORY_COMPARE(bufx, ciL, one, ciL);
1760    /*Borrow the buffer of A to compare the left lims with 0 */
1761    memset(A, 0, limbs * ciL);
1762    TEST_MEMORY_COMPARE(&bufx[1], (limbs - 1) * ciL, A, (limbs - 1) * ciL);
1763
1764exit:
1765    mbedtls_mpi_mod_modulus_free(&m);
1766    mbedtls_mpi_mod_residue_release(&rA);
1767    mbedtls_mpi_mod_residue_release(&rA_inverse);
1768    mbedtls_mpi_mod_residue_release(&rX);
1769    mbedtls_free(A);
1770    mbedtls_free(A_inverse);
1771    mbedtls_free(rX_raw);
1772    mbedtls_free(bufx);
1773}
1774/* END_CASE */
1775
1776/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1777void ecp_mod_add_sub(char *input_A, char *input_B, int id, int ctype)
1778{
1779    size_t p_A_limbs;
1780    size_t p_B_limbs;
1781    size_t bytes;
1782    mbedtls_mpi_mod_modulus m;
1783    mbedtls_mpi_mod_residue rA;
1784    mbedtls_mpi_mod_residue rB;
1785    mbedtls_mpi_mod_residue rS;
1786    mbedtls_mpi_uint *p_A = NULL;
1787    mbedtls_mpi_uint *p_B = NULL;
1788    mbedtls_mpi_uint *p_S = NULL;
1789
1790    mbedtls_mpi_mod_modulus_init(&m);
1791
1792    TEST_EQUAL(mbedtls_test_read_mpi_core(&p_A, &p_A_limbs, input_A), 0);
1793    TEST_EQUAL(mbedtls_test_read_mpi_core(&p_B, &p_B_limbs, input_B), 0);
1794
1795    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1796
1797    /* Test for limb sizes for two input value and modulus */
1798    TEST_EQUAL(p_A_limbs, p_B_limbs);
1799    TEST_EQUAL(m.limbs, p_A_limbs);
1800    bytes = p_A_limbs * ciL;
1801
1802    TEST_CALLOC(p_S, p_A_limbs);
1803
1804    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rA, &m, p_A, p_A_limbs), 0);
1805    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rB, &m, p_B, p_B_limbs), 0);
1806    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rS, &m, p_S, p_A_limbs), 0);
1807
1808    /* Firstly add A and B to get the sum S, then subtract B,
1809     * the difference should be equal to A*/
1810    TEST_EQUAL(0, mbedtls_mpi_mod_add(&rS, &rA, &rB, &m));
1811    TEST_EQUAL(0, mbedtls_mpi_mod_sub(&rS, &rS, &rB, &m));
1812
1813    /* Compare difference with rA byte-by-byte */
1814    TEST_MEMORY_COMPARE(rA.p, bytes, rS.p, bytes);
1815
1816exit:
1817    mbedtls_mpi_mod_modulus_free(&m);
1818    mbedtls_mpi_mod_residue_release(&rA);
1819    mbedtls_mpi_mod_residue_release(&rB);
1820    mbedtls_mpi_mod_residue_release(&rS);
1821    mbedtls_free(p_A);
1822    mbedtls_free(p_B);
1823    mbedtls_free(p_S);
1824}
1825/* END_CASE */
1826
1827/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1828void ecp_mod_read_write(char *input_A, int id, int ctype)
1829{
1830    size_t limbs;
1831    size_t bytes;
1832    mbedtls_mpi_mod_modulus m;
1833    mbedtls_mpi_mod_residue rA; // For input
1834    mbedtls_mpi_mod_residue rX; // For read back
1835    mbedtls_mpi_uint *rX_raw = NULL;
1836    mbedtls_mpi_uint *A = NULL;
1837    mbedtls_mpi_uint *bufx = NULL;
1838
1839    mbedtls_mpi_mod_modulus_init(&m);
1840
1841    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1842
1843    TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &limbs, input_A));
1844    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
1845
1846    /* Test for limb sizes */
1847    TEST_EQUAL(m.limbs, limbs);
1848
1849    TEST_CALLOC(rX_raw, limbs);
1850    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1851
1852    bytes = limbs * ciL;
1853    TEST_CALLOC(bufx, limbs);
1854    /* Write source mod residue to a buffer, then read it back to
1855     * the destination mod residue, compare the two mod residues.
1856     * Firstly test little endian write and read */
1857    TEST_EQUAL(0, mbedtls_mpi_mod_write(&rA, &m, (unsigned char *) bufx,
1858                                        bytes, MBEDTLS_MPI_MOD_EXT_REP_LE));
1859
1860    TEST_EQUAL(0, mbedtls_mpi_mod_read(&rX, &m, (unsigned char *) bufx,
1861                                       bytes, MBEDTLS_MPI_MOD_EXT_REP_LE));
1862
1863    TEST_EQUAL(limbs, rX.limbs);
1864    TEST_MEMORY_COMPARE(rA.p, bytes, rX.p, bytes);
1865
1866    memset(bufx, 0x00, bytes);
1867    memset(rX_raw, 0x00, bytes);
1868    /* Then test big endian write and read */
1869    TEST_EQUAL(0, mbedtls_mpi_mod_write(&rA, &m, (unsigned char *) bufx,
1870                                        bytes,
1871                                        MBEDTLS_MPI_MOD_EXT_REP_BE));
1872
1873    TEST_EQUAL(0, mbedtls_mpi_mod_read(&rX, &m, (unsigned char *) bufx,
1874                                       bytes,
1875                                       MBEDTLS_MPI_MOD_EXT_REP_BE));
1876
1877    TEST_EQUAL(limbs, rX.limbs);
1878    TEST_MEMORY_COMPARE(rA.p, bytes, rX.p, bytes);
1879
1880exit:
1881    mbedtls_mpi_mod_modulus_free(&m);
1882    mbedtls_mpi_mod_residue_release(&rA);
1883    mbedtls_mpi_mod_residue_release(&rX);
1884    mbedtls_free(A);
1885    mbedtls_free(rX_raw);
1886    mbedtls_free(bufx);
1887}
1888/* END_CASE */
1889
1890/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1891void ecp_mod_random(int id, int ctype)
1892{
1893    size_t limbs;
1894    mbedtls_mpi_mod_modulus m;
1895    mbedtls_mpi_mod_residue rX; // For random data
1896    mbedtls_mpi_uint *rX_raw = NULL;
1897
1898    mbedtls_mpi_mod_modulus_init(&m);
1899    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1900
1901    limbs = m.limbs;
1902
1903    TEST_CALLOC(rX_raw, limbs);
1904    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1905
1906    TEST_EQUAL(0, mbedtls_mpi_mod_random(&rX, 1, &m,
1907                                         mbedtls_test_rnd_std_rand, NULL));
1908
1909    TEST_ASSERT(mbedtls_mpi_core_lt_ct(rX.p, m.p, limbs) == MBEDTLS_CT_TRUE);
1910
1911exit:
1912    mbedtls_mpi_mod_modulus_free(&m);
1913    mbedtls_mpi_mod_residue_release(&rX);
1914    mbedtls_free(rX_raw);
1915}
1916/* END_CASE */
1917
1918/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_LIGHT */
1919void check_variant()
1920{
1921    mbedtls_ecp_variant variant = mbedtls_ecp_get_variant();
1922
1923#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
1924    TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_UINT);
1925#else
1926    TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT);
1927#endif
1928}
1929/* END_CASE */
1930