blob: c8a0a828447461b7a81ec2380a5cc64982be6421 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/ecp.h"
Werner Lewise54046c2022-08-15 11:43:56 +01003#include "mbedtls/ecdsa.h"
4#include "mbedtls/ecdh.h"
Paul Bakkerdbd443d2013-08-16 13:38:47 +02005
Gilles Peskine618be2e2021-04-03 21:47:53 +02006#include "ecp_invasive.h"
7
8#if defined(MBEDTLS_TEST_HOOKS) && \
Gilles Peskine449bd832023-01-11 14:50:10 +01009 (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
10 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
11 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED))
Gilles Peskine618be2e2021-04-03 21:47:53 +020012#define HAVE_FIX_NEGATIVE
13#endif
14
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020015#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020016
Gilles Peskine449bd832023-01-11 14:50:10 +010017#define ECP_PT_RESET(x) \
18 mbedtls_ecp_point_free(x); \
19 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020020
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010021/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010022inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
23 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010024{
Gilles Peskine449bd832023-01-11 14:50:10 +010025 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010026 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010027 }
28 if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010029 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010030 }
31 if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010032 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010033 }
34 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010035 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010036 }
37 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010038 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010039 }
40 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010041 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010042 }
43 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010044 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010045 }
46 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010047 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010048 }
49 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010050 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010051 }
52 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010053 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010054 }
55 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010056 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010057 }
58 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010059 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010060 }
61 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010062 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010063 }
64 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010065 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010066 }
67 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010068 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010069 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010070
71 return 0;
72}
73
Paul Bakker33b43f12013-08-20 11:48:36 +020074/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010075
Paul Bakker33b43f12013-08-20 11:48:36 +020076/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077 * depends_on:MBEDTLS_ECP_C
Paul Bakker33b43f12013-08-20 11:48:36 +020078 * END_DEPENDENCIES
79 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010080
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010081/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010082void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000083{
84 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000085 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000086 int invalid_fmt = 42;
87 size_t olen;
88 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000089
Gilles Peskine449bd832023-01-11 14:50:10 +010090 mbedtls_ecp_group_init(&grp);
91 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020092
Gilles Peskine449bd832023-01-11 14:50:10 +010093 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
94 mbedtls_ecp_point_write_binary(&grp, &P,
95 invalid_fmt,
96 &olen,
97 buf, sizeof(buf)));
98 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
99 mbedtls_ecp_tls_write_point(&grp, &P,
100 invalid_fmt,
101 &olen,
102 buf,
103 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000104
105exit:
106 return;
107}
108/* END_CASE */
109
Paul Bakker33b43f12013-08-20 11:48:36 +0200110/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100111void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100112{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
116 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
117 by_name = mbedtls_ecp_curve_info_from_name(name);
118 TEST_ASSERT(by_id != NULL);
119 TEST_ASSERT(by_tls != NULL);
120 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 TEST_ASSERT(by_id == by_tls);
123 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 TEST_ASSERT(by_id->bit_size == size);
126 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
127 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100128}
129/* END_CASE */
130
131/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100132void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
133 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100134{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200135 mbedtls_ecp_group grp;
136 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 mbedtls_ecp_group_init(&grp);
139 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
144 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
145 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100148
Paul Bakkerbd51b262014-07-10 15:26:12 +0200149exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 mbedtls_ecp_group_free(&grp);
151 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100152}
153/* END_CASE */
154
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200155/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100156void ecp_test_vect_restart(int id,
157 char *dA_str, char *xA_str, char *yA_str,
158 char *dB_str, char *xZ_str, char *yZ_str,
159 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100160{
161 /*
162 * Test for early restart. Based on test vectors like ecp_test_vect(),
163 * but for the sake of simplicity only does half of each side. It's
164 * important to test both base point and random point, though, as memory
165 * management is different in each case.
166 *
167 * Don't try using too precise bounds for restarts as the exact number
168 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
169 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
170 * change in the future. A factor 2 is a minimum safety margin.
171 *
172 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100173 * - Random point mult: ~3250M
174 * - Cold base point mult: ~3300M
175 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100176 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100177 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100178 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200179 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100180 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200181 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100182 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
183 int cnt_restarts;
184 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200185 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 mbedtls_ecp_restart_init(&ctx);
188 mbedtls_ecp_group_init(&grp);
189 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
190 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
191 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
192 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
197 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
198 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
201 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
202 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100205
206 /* Base point case */
207 cnt_restarts = 0;
208 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 ECP_PT_RESET(&R);
210 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
211 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
212 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 TEST_ASSERT(ret == 0);
215 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
216 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 TEST_ASSERT(cnt_restarts >= min_restarts);
219 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100220
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100221 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100223 cnt_restarts = 0;
224 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 ECP_PT_RESET(&R);
226 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
227 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
228 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 TEST_ASSERT(ret == 0);
231 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
232 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 TEST_ASSERT(cnt_restarts >= min_restarts);
235 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100236
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200237 /* Do we leak memory when aborting an operation?
238 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 if (min_restarts > 0) {
240 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
241 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
242 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200243 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100244
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100245exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 mbedtls_ecp_restart_free(&ctx);
247 mbedtls_ecp_group_free(&grp);
248 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
249 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
250 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100251}
252/* END_CASE */
253
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100254/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
256 char *u1_str, char *u2_str,
257 char *xQ_str, char *yQ_str,
258 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200259{
260 /*
261 * Compute R = u1 * G + u2 * Q
262 * (test vectors mostly taken from ECDSA intermediate results)
263 *
264 * See comments at the top of ecp_test_vect_restart()
265 */
266 mbedtls_ecp_restart_ctx ctx;
267 mbedtls_ecp_group grp;
268 mbedtls_ecp_point R, Q;
269 mbedtls_mpi u1, u2, xR, yR;
270 int cnt_restarts;
271 int ret;
272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 mbedtls_ecp_restart_init(&ctx);
274 mbedtls_ecp_group_init(&grp);
275 mbedtls_ecp_point_init(&R);
276 mbedtls_ecp_point_init(&Q);
277 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
278 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
283 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
284 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
285 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
288 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
289 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200292
293 cnt_restarts = 0;
294 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 ECP_PT_RESET(&R);
296 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
297 &u1, &grp.G, &u2, &Q, &ctx);
298 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 TEST_ASSERT(ret == 0);
301 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
302 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 TEST_ASSERT(cnt_restarts >= min_restarts);
305 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200306
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200307 /* Do we leak memory when aborting an operation?
308 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 if (min_restarts > 0) {
310 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
311 &u1, &grp.G, &u2, &Q, &ctx);
312 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200313 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200314
315exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 mbedtls_ecp_restart_free(&ctx);
317 mbedtls_ecp_group_free(&grp);
318 mbedtls_ecp_point_free(&R);
319 mbedtls_ecp_point_free(&Q);
320 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
321 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200322}
323/* END_CASE */
324
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100325/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
327 char *dB_str, char *xB_str, char *yB_str,
328 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100329{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330 mbedtls_ecp_group grp;
331 mbedtls_ecp_point R;
332 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200333 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
336 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
337 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
338 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
345 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
346 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
347 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
348 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
349 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
350 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
351 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
354 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
355 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
356 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
357 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
358 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
359 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
360 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
361 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
362 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
365 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
366 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
367 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
368 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
369 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
370 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
371 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
372 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
373 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100374
Paul Bakkerbd51b262014-07-10 15:26:12 +0200375exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
377 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
378 mbedtls_mpi_free(&xB); mbedtls_mpi_free(&yB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100379}
Paul Bakker33b43f12013-08-20 11:48:36 +0200380/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100381
Paul Bakker33b43f12013-08-20 11:48:36 +0200382/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
384 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100385{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 mbedtls_ecp_group grp;
387 mbedtls_ecp_point R;
388 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200389 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
392 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
393 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
394 mbedtls_mpi_init(&xS);
395 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
402 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
403 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
404 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
405 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
408 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
409 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
410 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
413 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
414 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
415 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
418 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
419 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
420 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
423 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
424 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
425 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100426
Paul Bakkerbd51b262014-07-10 15:26:12 +0200427exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
429 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
430 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
431 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100432}
433/* END_CASE */
434
435/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100436void ecp_test_mul(int id, data_t *n_hex,
437 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
438 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
439 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100440{
441 mbedtls_ecp_group grp;
442 mbedtls_ecp_point P, nP, R;
443 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200444 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
447 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
448 mbedtls_mpi_init(&n);
449 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
458 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
459 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
460 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
461 == 0);
462 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
463 == 0);
464 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
465 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
468 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
469 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 if (expected_ret == 0) {
472 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
473 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
474 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100475 }
476
477exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
479 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
480 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100481}
482/* END_CASE */
483
484/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100485void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900486{
487 mbedtls_ecp_group grp;
488 mbedtls_mpi d;
489 mbedtls_ecp_point Q;
490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
492 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
501 &mbedtls_test_rnd_zero_rand, NULL)
502 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900503
504exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
506 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900507}
508/* END_CASE */
509
Gilles Peskineca91ee42021-04-03 18:31:01 +0200510/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100511void ecp_muladd(int id,
512 data_t *u1_bin, data_t *P1_bin,
513 data_t *u2_bin, data_t *P2_bin,
514 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200515{
516 /* Compute R = u1 * P1 + u2 * P2 */
517 mbedtls_ecp_group grp;
518 mbedtls_ecp_point P1, P2, R;
519 mbedtls_mpi u1, u2;
520 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
521 size_t len;
522
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 mbedtls_ecp_group_init(&grp);
524 mbedtls_ecp_point_init(&P1);
525 mbedtls_ecp_point_init(&P2);
526 mbedtls_ecp_point_init(&R);
527 mbedtls_mpi_init(&u1);
528 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
531 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
532 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
533 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
534 P1_bin->x, P1_bin->len));
535 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
536 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
539 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
540 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
541 &len, actual_result, sizeof(actual_result)));
542 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200543
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 ASSERT_COMPARE(expected_result->x, expected_result->len,
545 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200546
547exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_ecp_group_free(&grp);
549 mbedtls_ecp_point_free(&P1);
550 mbedtls_ecp_point_free(&P2);
551 mbedtls_ecp_point_free(&R);
552 mbedtls_mpi_free(&u1);
553 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200554}
555/* END_CASE */
556
Jonas923d5792020-05-13 14:22:45 +0900557/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100558void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100559{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 mbedtls_ecp_group grp;
561 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
564 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
567 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
568 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100569
570 /*
571 * Store correct result before we touch N
572 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 TEST_ASSERT(grp.modp(&N) == 0);
576 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100577
578 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200579 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100580 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
582 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100583
Paul Bakkerbd51b262014-07-10 15:26:12 +0200584exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
586 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100587}
Paul Bakker33b43f12013-08-20 11:48:36 +0200588/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100589
Paul Bakker33b43f12013-08-20 11:48:36 +0200590/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100591void ecp_write_binary(int id, char *x, char *y, char *z, int format,
592 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100593{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 mbedtls_ecp_group grp;
595 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100596 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100597 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
606 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
607 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100608
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
610 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 if (ret == 0) {
613 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
614 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100615 }
616
Paul Bakkerbd51b262014-07-10 15:26:12 +0200617exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100619}
Paul Bakker33b43f12013-08-20 11:48:36 +0200620/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100621
Paul Bakker33b43f12013-08-20 11:48:36 +0200622/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100623void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
624 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100625{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 mbedtls_ecp_group grp;
627 mbedtls_ecp_point P;
628 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100629
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
632 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
637 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
638 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 if (ret == 0) {
643 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
644 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
645 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
646 TEST_ASSERT(P.Y.p == NULL);
647 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
648 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
649 } else {
650 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
651 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400652
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400654 /* (reading compressed format supported only for
655 * Short Weierstrass curves with prime p where p = 3 mod 4) */
656 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400658 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 mbedtls_mpi_free(&P.Y);
660 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
661 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
662 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400663 }
Janos Follath59b813c2019-02-13 10:44:06 +0000664 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100665 }
666
Paul Bakkerbd51b262014-07-10 15:26:12 +0200667exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
669 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100670}
Paul Bakker33b43f12013-08-20 11:48:36 +0200671/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100672
Paul Bakker33b43f12013-08-20 11:48:36 +0200673/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100674void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
675 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100676{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 mbedtls_ecp_group grp;
678 mbedtls_ecp_point P;
679 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100680 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100681
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
684 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
689 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
690 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 if (ret == 0) {
695 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
696 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
697 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
698 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100699 }
700
Paul Bakkerbd51b262014-07-10 15:26:12 +0200701exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
703 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100704}
Paul Bakker33b43f12013-08-20 11:48:36 +0200705/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100706
Paul Bakker33b43f12013-08-20 11:48:36 +0200707/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100708void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100709{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 mbedtls_ecp_group grp;
711 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100712 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100713 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100714 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 mbedtls_ecp_group_init(&grp);
717 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
722 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
723 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
724 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
725 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
726 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
727 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
728 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
731 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
732 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
733 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
734 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
735 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
736 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
737 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
740 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
741 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
742 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
743 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
744 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
745 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
748 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
749 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
750 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
751 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
752 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
753 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100754
Paul Bakkerbd51b262014-07-10 15:26:12 +0200755exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 mbedtls_ecp_group_free(&grp);
757 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100758}
Paul Bakker33b43f12013-08-20 11:48:36 +0200759/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100760
Paul Bakker33b43f12013-08-20 11:48:36 +0200761/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100762void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
763 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100764{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100766 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100767 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100770
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 TEST_ASSERT(ret == result);
774 if (ret == 0) {
775 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
776 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100777 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100778
Paul Bakkerbd51b262014-07-10 15:26:12 +0200779exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100781}
Paul Bakker33b43f12013-08-20 11:48:36 +0200782/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100783
Paul Bakker33b43f12013-08-20 11:48:36 +0200784/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100785void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100786{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100788 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100789 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100790 size_t len;
791 int ret;
792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 mbedtls_ecp_group_init(&grp1);
794 mbedtls_ecp_group_init(&grp2);
795 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
800 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
801 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 if (ret == 0) {
804 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
805 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100806 }
807
Paul Bakkerbd51b262014-07-10 15:26:12 +0200808exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 mbedtls_ecp_group_free(&grp1);
810 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100811}
Paul Bakker33b43f12013-08-20 11:48:36 +0200812/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100813
Valerio Setti46829482023-01-18 13:59:30 +0100814/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100815void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
816 char *P, char *A, char *B,
817 char *G_x, char *G_y, char *N,
818 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100819{
820 mbedtls_ecp_group grp, grp_read, grp_cpy;
821 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100822 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100823 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
824
825 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
826
827 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
828 const unsigned char *vbuf = buf;
829 size_t olen;
830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 mbedtls_ecp_group_init(&grp);
832 mbedtls_ecp_group_init(&grp_read);
833 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 mbedtls_mpi_init(&exp_P);
836 mbedtls_mpi_init(&exp_A);
837 mbedtls_mpi_init(&exp_B);
838 mbedtls_mpi_init(&exp_G_x);
839 mbedtls_mpi_init(&exp_G_y);
840 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100841
842 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
844 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
845 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
846 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
847 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
848 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100849
Werner Lewisc4afef72022-08-25 10:29:19 +0100850 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
852 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
853 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100854 }
855
Werner Lewise54046c2022-08-15 11:43:56 +0100856 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100858
859 // Compare group with expected parameters
860 // A is NULL for SECPxxxR1 curves
861 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
863 if (*A != 0) {
864 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
865 }
866 if (*B != 0) {
867 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
868 }
869 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
870 if (*G_y != 0) {
871 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
872 }
873 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100874
875 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 crv = mbedtls_ecp_curve_info_from_grp_id(id);
877 TEST_EQUAL(crv->grp_id, id);
878 TEST_EQUAL(crv->bit_size, bit_size);
879 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100880
881 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
883 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
884 TEST_EQUAL(crv_tls_id->grp_id, id);
885 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100886
Werner Lewisccae25b2022-09-20 10:00:07 +0100887 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
889 buf, sizeof(buf)),
890 0);
891 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
892 sizeof(ecparameters)),
893 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100894
895 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
897 0);
898 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100899 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
901 0);
902 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100903
904 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
Valerio Setti46829482023-01-18 13:59:30 +0100906#if defined(MBEDTLS_ECDH_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
Valerio Setti46829482023-01-18 13:59:30 +0100908#endif
909#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
911 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Valerio Setti46829482023-01-18 13:59:30 +0100912#endif
Werner Lewise54046c2022-08-15 11:43:56 +0100913
914 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
916 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100917
918 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 for (crv = mbedtls_ecp_curve_list();
920 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
921 crv->grp_id != (unsigned) id;
922 crv++) {
923 ;
924 }
925 TEST_EQUAL(crv->grp_id, id);
926 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100927 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 g_id++) {
929 ;
930 }
931 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100932
933exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
935 mbedtls_ecp_group_free(&grp_read);
936 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
937 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
938 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100939}
940/* END_CASE */
941
Paul Bakker33b43f12013-08-20 11:48:36 +0200942/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100943void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200944{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 mbedtls_ecp_group grp;
946 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 mbedtls_ecp_group_init(&grp);
949 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
952 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200955
Paul Bakkerbd51b262014-07-10 15:26:12 +0200956exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 mbedtls_ecp_group_free(&grp);
958 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200959}
Paul Bakker33b43f12013-08-20 11:48:36 +0200960/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200961
Paul Bakker33b43f12013-08-20 11:48:36 +0200962/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100963void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
964 int id, char *d, char *Qx, char *Qy,
965 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100966{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200968 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 mbedtls_ecp_keypair_init(&pub);
971 mbedtls_ecp_keypair_init(&prv);
972 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 if (id_pub != MBEDTLS_ECP_DP_NONE) {
975 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
976 }
977 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if (id != MBEDTLS_ECP_DP_NONE) {
980 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
981 }
982 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
983 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
986 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100987
988exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 mbedtls_ecp_keypair_free(&pub);
990 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100991}
992/* END_CASE */
993
994/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100995void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100996{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 mbedtls_ecp_group grp;
998 mbedtls_ecp_point Q;
999 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001000 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 mbedtls_ecp_group_init(&grp);
1003 mbedtls_ecp_point_init(&Q);
1004 mbedtls_mpi_init(&d);
1005 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1010 &mbedtls_test_rnd_pseudo_rand,
1011 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1014 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001015
Paul Bakkerbd51b262014-07-10 15:26:12 +02001016exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 mbedtls_ecp_group_free(&grp);
1018 mbedtls_ecp_point_free(&Q);
1019 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001020}
Paul Bakker33b43f12013-08-20 11:48:36 +02001021/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001022
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001023/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001024void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001025{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001027 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 mbedtls_ecp_keypair_init(&key);
1030 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1033 &mbedtls_test_rnd_pseudo_rand,
1034 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1037 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001038
Paul Bakkerbd51b262014-07-10 15:26:12 +02001039exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001041}
1042/* END_CASE */
1043
Janos Follath171a7ef2019-02-15 16:17:45 +00001044/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001045void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001046{
1047 int ret = 0;
1048 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001049 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 mbedtls_ecp_keypair_init(&key);
1052 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1055 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 if (expected == 0) {
1058 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1059 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001062 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001063
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1065 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001066
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 ASSERT_COMPARE(in_key->x, in_key->len,
1068 buf, in_key->len);
1069 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001070 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001071 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001072
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1074 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1077 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001078
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1080 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001081
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 ASSERT_COMPARE(export1, in_key->len,
1083 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001084 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001085 }
1086
1087exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 mbedtls_ecp_keypair_free(&key);
1089 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001090}
1091/* END_CASE */
1092
Gilles Peskine618be2e2021-04-03 21:47:53 +02001093/* BEGIN_CASE depends_on:HAVE_FIX_NEGATIVE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001094void fix_negative(data_t *N_bin, int c, int bits)
Gilles Peskine618be2e2021-04-03 21:47:53 +02001095{
1096 mbedtls_mpi C, M, N;
1097
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 mbedtls_mpi_init(&C);
1099 mbedtls_mpi_init(&M);
1100 mbedtls_mpi_init(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001101
Gilles Peskine392d1012021-04-09 15:46:51 +02001102 /* C = - c * 2^bits (positive since c is negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 TEST_EQUAL(0, mbedtls_mpi_lset(&C, -c));
1104 TEST_EQUAL(0, mbedtls_mpi_shift_l(&C, bits));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001105
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 TEST_EQUAL(0, mbedtls_mpi_read_binary(&N, N_bin->x, N_bin->len));
1107 TEST_EQUAL(0, mbedtls_mpi_grow(&N, C.n));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001108
Gilles Peskine392d1012021-04-09 15:46:51 +02001109 /* M = N - C = - ( C - N ) (expected result of fix_negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 TEST_EQUAL(0, mbedtls_mpi_sub_mpi(&M, &N, &C));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001111
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 mbedtls_ecp_fix_negative(&N, c, bits);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&N, &M));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001115
1116exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 mbedtls_mpi_free(&C);
1118 mbedtls_mpi_free(&M);
1119 mbedtls_mpi_free(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001120}
1121/* END_CASE */
1122
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001123/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +01001124void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001125{
1126 mbedtls_test_rnd_buf_info rnd_info;
1127 mbedtls_mpi d;
1128 int ret;
1129 uint8_t *actual = NULL;
1130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001132 rnd_info.buf = seed->x;
1133 rnd_info.length = seed->len;
1134 rnd_info.fallback_f_rng = NULL;
1135 rnd_info.fallback_p_rng = NULL;
1136
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001138
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1140 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001143 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 TEST_ASSERT(ret != 0);
1145 } else {
1146 TEST_EQUAL(ret, 0);
1147 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1148 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001149 /* Test the exact result. This assumes that the output of the
1150 * RNG is used in a specific way, which is overly constraining.
1151 * The advantage is that it's easier to test the expected properties
1152 * of the generated key:
1153 * - The most significant bit must be at a specific positions
1154 * (can be enforced by checking the bit-length).
1155 * - The least significant bits must have specific values
1156 * (can be enforced by checking these bits).
1157 * - Other bits must be random (by testing with different RNG outputs,
1158 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 ASSERT_COMPARE(expected->x, expected->len,
1160 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001161 }
1162
1163exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 mbedtls_free(actual);
1165 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001166}
1167/* END_CASE */
1168
Werner Lewis3b097392022-08-08 11:53:45 +01001169/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001170void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001171{
1172 mbedtls_ecp_group grp;
1173 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1174
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 mbedtls_ecp_group_init(&grp);
1176 mbedtls_ecp_point_init(&pt);
1177 mbedtls_ecp_point_init(&zero_pt);
1178 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001179
1180 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1182 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1183 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1184 P_bin->x, P_bin->len), 0);
1185 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1186 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001187
1188 // Test initialized point
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1190 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1191 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1192 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1193 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001194
1195 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001196 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1197 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1198 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1199 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1200 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001201
1202 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1204 P_bin->x, P_bin->len), 0);
1205 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1206 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1207 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1208 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001209
1210 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001211 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1212 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1213 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1214 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1215 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001216
1217 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1219 P_bin->x, P_bin->len), 0);
1220 mbedtls_ecp_point_free(&pt);
1221 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1222 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1223 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1224 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1225 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001226
1227exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 mbedtls_ecp_group_free(&grp);
1229 mbedtls_ecp_point_free(&pt);
1230 mbedtls_ecp_point_free(&zero_pt);
1231 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001232}
1233/* END_CASE */
1234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001235/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001236void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001237{
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001239}
Paul Bakker33b43f12013-08-20 11:48:36 +02001240/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001241
1242/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001243void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001244{
1245 mbedtls_ecp_keypair key;
1246 mbedtls_ecp_group export_grp;
1247 mbedtls_mpi export_d;
1248 mbedtls_ecp_point export_Q;
1249
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 mbedtls_ecp_group_init(&export_grp);
1251 mbedtls_ecp_group_init(&key.grp);
1252 mbedtls_mpi_init(&export_d);
1253 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001254
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 mbedtls_ecp_keypair_init(&key);
1256 if (invalid_grp == 0) {
1257 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1258 }
1259 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1260 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001261
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1263 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001264
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 if (expected_ret == 0) {
1266 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1267 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1268 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001269 }
1270
1271exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 mbedtls_ecp_keypair_free(&key);
1273 mbedtls_ecp_group_free(&export_grp);
1274 mbedtls_mpi_free(&export_d);
1275 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001276}
1277/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001278
1279/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001280void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001281{
1282 mbedtls_ecp_group grp;
1283 mbedtls_mpi expected_n;
1284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 mbedtls_ecp_group_init(&grp);
1286 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001287
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1289 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001290
1291 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1293 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001296
1297exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 mbedtls_ecp_group_free(&grp);
1299 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001300}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001301/* END_CASE */