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