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