blob: eb55f01c4d8d10c5896dc79911e9ac7299a149d7 [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"
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00003#include "ecp_invasive.h"
Werner Lewise54046c2022-08-15 11:43:56 +01004#include "mbedtls/ecdsa.h"
5#include "mbedtls/ecdh.h"
Paul Bakkerdbd443d2013-08-16 13:38:47 +02006
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01007#include "bignum_core.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +02008#include "ecp_invasive.h"
Gabor Mezeid8f67b92023-02-06 15:49:42 +01009#include "bignum_mod_raw_invasive.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +020010
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020011#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020012
Gilles Peskine449bd832023-01-11 14:50:10 +010013#define ECP_PT_RESET(x) \
14 mbedtls_ecp_point_free(x); \
15 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020016
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010017/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010018inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
19 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010020{
Gilles Peskine449bd832023-01-11 14:50:10 +010021 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010022 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010023 }
24 if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010025 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010026 }
27 if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010028 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010029 }
30 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010031 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010032 }
33 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010034 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010035 }
36 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010037 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 }
39 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010040 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010041 }
42 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010043 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010044 }
45 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010046 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010047 }
48 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010049 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010050 }
51 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010052 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010053 }
54 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010055 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010056 }
57 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010058 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010059 }
60 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010061 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010062 }
63 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010064 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010065 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010066
67 return 0;
68}
69
Minos Galanakis92278dc2023-03-29 11:41:21 +010070#if defined(MBEDTLS_TEST_HOOKS) && \
71 (defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
72 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
73 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
74 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
75 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED))
76#define MBEDTLS_ECP_DP_SECP_GENERIC_ENABLED
77#endif
78
Paul Bakker33b43f12013-08-20 11:48:36 +020079/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010080
Paul Bakker33b43f12013-08-20 11:48:36 +020081/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082 * depends_on:MBEDTLS_ECP_C
Paul Bakker33b43f12013-08-20 11:48:36 +020083 * END_DEPENDENCIES
84 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010085
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010086/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010087void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000088{
89 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000090 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000091 int invalid_fmt = 42;
92 size_t olen;
93 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000094
Gilles Peskine449bd832023-01-11 14:50:10 +010095 mbedtls_ecp_group_init(&grp);
96 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020097
Gilles Peskine449bd832023-01-11 14:50:10 +010098 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
99 mbedtls_ecp_point_write_binary(&grp, &P,
100 invalid_fmt,
101 &olen,
102 buf, sizeof(buf)));
103 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
104 mbedtls_ecp_tls_write_point(&grp, &P,
105 invalid_fmt,
106 &olen,
107 buf,
108 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000109
110exit:
111 return;
112}
113/* END_CASE */
114
Paul Bakker33b43f12013-08-20 11:48:36 +0200115/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100116void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100117{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
121 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
122 by_name = mbedtls_ecp_curve_info_from_name(name);
123 TEST_ASSERT(by_id != NULL);
124 TEST_ASSERT(by_tls != NULL);
125 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 TEST_ASSERT(by_id == by_tls);
128 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100129
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 TEST_ASSERT(by_id->bit_size == size);
131 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
132 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100133}
134/* END_CASE */
135
136/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100137void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
138 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100139{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 mbedtls_ecp_group grp;
141 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 mbedtls_ecp_group_init(&grp);
144 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
149 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
150 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100153
Paul Bakkerbd51b262014-07-10 15:26:12 +0200154exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 mbedtls_ecp_group_free(&grp);
156 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100157}
158/* END_CASE */
159
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200160/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100161void ecp_test_vect_restart(int id,
162 char *dA_str, char *xA_str, char *yA_str,
163 char *dB_str, char *xZ_str, char *yZ_str,
164 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100165{
166 /*
167 * Test for early restart. Based on test vectors like ecp_test_vect(),
168 * but for the sake of simplicity only does half of each side. It's
169 * important to test both base point and random point, though, as memory
170 * management is different in each case.
171 *
172 * Don't try using too precise bounds for restarts as the exact number
173 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
174 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
175 * change in the future. A factor 2 is a minimum safety margin.
176 *
177 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100178 * - Random point mult: ~3250M
179 * - Cold base point mult: ~3300M
180 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100181 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100182 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100183 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200184 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100185 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200186 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100187 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
188 int cnt_restarts;
189 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200190 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 mbedtls_ecp_restart_init(&ctx);
193 mbedtls_ecp_group_init(&grp);
194 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
195 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
196 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
197 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
202 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
203 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
206 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
207 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100210
211 /* Base point case */
212 cnt_restarts = 0;
213 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 ECP_PT_RESET(&R);
215 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
216 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
217 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 TEST_ASSERT(ret == 0);
220 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
221 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 TEST_ASSERT(cnt_restarts >= min_restarts);
224 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100225
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100226 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100228 cnt_restarts = 0;
229 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 ECP_PT_RESET(&R);
231 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
232 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
233 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 TEST_ASSERT(ret == 0);
236 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
237 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 TEST_ASSERT(cnt_restarts >= min_restarts);
240 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100241
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200242 /* Do we leak memory when aborting an operation?
243 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if (min_restarts > 0) {
245 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
246 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
247 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200248 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100249
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100250exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 mbedtls_ecp_restart_free(&ctx);
252 mbedtls_ecp_group_free(&grp);
253 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
254 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
255 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100256}
257/* END_CASE */
258
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100259/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100260void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
261 char *u1_str, char *u2_str,
262 char *xQ_str, char *yQ_str,
263 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200264{
265 /*
266 * Compute R = u1 * G + u2 * Q
267 * (test vectors mostly taken from ECDSA intermediate results)
268 *
269 * See comments at the top of ecp_test_vect_restart()
270 */
271 mbedtls_ecp_restart_ctx ctx;
272 mbedtls_ecp_group grp;
273 mbedtls_ecp_point R, Q;
274 mbedtls_mpi u1, u2, xR, yR;
275 int cnt_restarts;
276 int ret;
277
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 mbedtls_ecp_restart_init(&ctx);
279 mbedtls_ecp_group_init(&grp);
280 mbedtls_ecp_point_init(&R);
281 mbedtls_ecp_point_init(&Q);
282 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
283 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 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(&u1, u1_str) == 0);
288 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
289 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
290 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
293 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
294 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200297
298 cnt_restarts = 0;
299 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 ECP_PT_RESET(&R);
301 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
302 &u1, &grp.G, &u2, &Q, &ctx);
303 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 TEST_ASSERT(ret == 0);
306 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
307 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 TEST_ASSERT(cnt_restarts >= min_restarts);
310 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200311
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200312 /* Do we leak memory when aborting an operation?
313 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 if (min_restarts > 0) {
315 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
316 &u1, &grp.G, &u2, &Q, &ctx);
317 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200318 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200319
320exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 mbedtls_ecp_restart_free(&ctx);
322 mbedtls_ecp_group_free(&grp);
323 mbedtls_ecp_point_free(&R);
324 mbedtls_ecp_point_free(&Q);
325 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
326 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200327}
328/* END_CASE */
329
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100330/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100331void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
332 char *dB_str, char *xB_str, char *yB_str,
333 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100334{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 mbedtls_ecp_group grp;
336 mbedtls_ecp_point R;
337 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200338 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
341 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
342 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
343 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
350 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
351 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
352 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
353 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
354 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
355 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
356 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
359 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
360 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
361 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
362 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
363 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
364 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
365 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
366 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
367 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
370 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
371 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
372 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
373 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
374 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
375 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
376 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
377 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
378 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100379
Paul Bakkerbd51b262014-07-10 15:26:12 +0200380exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
382 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
383 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 +0100384}
Paul Bakker33b43f12013-08-20 11:48:36 +0200385/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100386
Paul Bakker33b43f12013-08-20 11:48:36 +0200387/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
389 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100390{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_ecp_group grp;
392 mbedtls_ecp_point R;
393 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200394 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
397 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
398 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
399 mbedtls_mpi_init(&xS);
400 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100403
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
407 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
408 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
409 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
410 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 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, &dA, &grp.G,
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, &xA) == 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, &R,
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, &xS) == 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, &dB, &grp.G,
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, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
428 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
429 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
430 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100431
Paul Bakkerbd51b262014-07-10 15:26:12 +0200432exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
434 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
435 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
436 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100437}
438/* END_CASE */
439
440/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100441void ecp_test_mul(int id, data_t *n_hex,
442 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
443 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
444 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100445{
446 mbedtls_ecp_group grp;
447 mbedtls_ecp_point P, nP, R;
448 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200449 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
452 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
453 mbedtls_mpi_init(&n);
454 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
463 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
464 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
465 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
466 == 0);
467 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
468 == 0);
469 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
470 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
473 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
474 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (expected_ret == 0) {
477 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
478 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
479 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100480 }
481
482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
484 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
485 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100486}
487/* END_CASE */
488
489/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100490void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900491{
492 mbedtls_ecp_group grp;
493 mbedtls_mpi d;
494 mbedtls_ecp_point Q;
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
497 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900500
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900504
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
506 &mbedtls_test_rnd_zero_rand, NULL)
507 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900508
509exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
511 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900512}
513/* END_CASE */
514
Gilles Peskineca91ee42021-04-03 18:31:01 +0200515/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100516void ecp_muladd(int id,
517 data_t *u1_bin, data_t *P1_bin,
518 data_t *u2_bin, data_t *P2_bin,
519 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200520{
521 /* Compute R = u1 * P1 + u2 * P2 */
522 mbedtls_ecp_group grp;
523 mbedtls_ecp_point P1, P2, R;
524 mbedtls_mpi u1, u2;
525 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
526 size_t len;
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 mbedtls_ecp_group_init(&grp);
529 mbedtls_ecp_point_init(&P1);
530 mbedtls_ecp_point_init(&P2);
531 mbedtls_ecp_point_init(&R);
532 mbedtls_mpi_init(&u1);
533 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
536 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
537 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
538 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
539 P1_bin->x, P1_bin->len));
540 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
541 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
544 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
545 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
546 &len, actual_result, sizeof(actual_result)));
547 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 ASSERT_COMPARE(expected_result->x, expected_result->len,
550 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200551
552exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 mbedtls_ecp_group_free(&grp);
554 mbedtls_ecp_point_free(&P1);
555 mbedtls_ecp_point_free(&P2);
556 mbedtls_ecp_point_free(&R);
557 mbedtls_mpi_free(&u1);
558 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200559}
560/* END_CASE */
561
Jonas923d5792020-05-13 14:22:45 +0900562/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100563void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100564{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 mbedtls_ecp_group grp;
566 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
569 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
572 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
573 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100574
575 /*
576 * Store correct result before we touch N
577 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 TEST_ASSERT(grp.modp(&N) == 0);
581 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100582
583 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200584 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100585 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
587 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100588
Paul Bakkerbd51b262014-07-10 15:26:12 +0200589exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
591 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100592}
Paul Bakker33b43f12013-08-20 11:48:36 +0200593/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100594
Paul Bakker33b43f12013-08-20 11:48:36 +0200595/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100596void ecp_write_binary(int id, char *x, char *y, char *z, int format,
597 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100598{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 mbedtls_ecp_group grp;
600 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100601 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100602 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
611 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
612 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
615 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (ret == 0) {
618 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
619 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100620 }
621
Paul Bakkerbd51b262014-07-10 15:26:12 +0200622exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100624}
Paul Bakker33b43f12013-08-20 11:48:36 +0200625/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100626
Paul Bakker33b43f12013-08-20 11:48:36 +0200627/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100628void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
629 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100630{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_ecp_group grp;
632 mbedtls_ecp_point P;
633 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100634
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
637 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
642 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
643 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (ret == 0) {
648 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
649 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
650 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
651 TEST_ASSERT(P.Y.p == NULL);
652 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
653 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
654 } else {
655 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
656 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400659 /* (reading compressed format supported only for
660 * Short Weierstrass curves with prime p where p = 3 mod 4) */
661 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400663 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 mbedtls_mpi_free(&P.Y);
665 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
666 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
667 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400668 }
Janos Follath59b813c2019-02-13 10:44:06 +0000669 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100670 }
671
Paul Bakkerbd51b262014-07-10 15:26:12 +0200672exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
674 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100675}
Paul Bakker33b43f12013-08-20 11:48:36 +0200676/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100677
Paul Bakker33b43f12013-08-20 11:48:36 +0200678/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100679void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
680 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100681{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 mbedtls_ecp_group grp;
683 mbedtls_ecp_point P;
684 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100685 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100686
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
689 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
694 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
695 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 if (ret == 0) {
700 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
701 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
702 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
703 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100704 }
705
Paul Bakkerbd51b262014-07-10 15:26:12 +0200706exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
708 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100709}
Paul Bakker33b43f12013-08-20 11:48:36 +0200710/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100711
Paul Bakker33b43f12013-08-20 11:48:36 +0200712/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100713void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100714{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200715 mbedtls_ecp_group grp;
716 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100717 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100718 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100719 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 mbedtls_ecp_group_init(&grp);
722 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
727 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
728 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
729 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
730 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
731 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
732 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
733 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
736 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
737 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
738 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
739 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
740 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
741 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
742 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
745 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
746 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
747 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
748 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
749 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
750 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
753 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
754 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
755 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
756 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
757 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
758 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100759
Paul Bakkerbd51b262014-07-10 15:26:12 +0200760exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 mbedtls_ecp_group_free(&grp);
762 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100763}
Paul Bakker33b43f12013-08-20 11:48:36 +0200764/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100765
Paul Bakker33b43f12013-08-20 11:48:36 +0200766/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100767void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
768 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100769{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100771 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100772 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 TEST_ASSERT(ret == result);
779 if (ret == 0) {
780 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
781 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100782 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100783
Paul Bakkerbd51b262014-07-10 15:26:12 +0200784exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100786}
Paul Bakker33b43f12013-08-20 11:48:36 +0200787/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100788
Paul Bakker33b43f12013-08-20 11:48:36 +0200789/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100790void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100791{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100793 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100794 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100795 size_t len;
796 int ret;
797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 mbedtls_ecp_group_init(&grp1);
799 mbedtls_ecp_group_init(&grp2);
800 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
805 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
806 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 if (ret == 0) {
809 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
810 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100811 }
812
Paul Bakkerbd51b262014-07-10 15:26:12 +0200813exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 mbedtls_ecp_group_free(&grp1);
815 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100816}
Paul Bakker33b43f12013-08-20 11:48:36 +0200817/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100818
Valerio Setti46829482023-01-18 13:59:30 +0100819/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100820void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
821 char *P, char *A, char *B,
822 char *G_x, char *G_y, char *N,
823 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100824{
825 mbedtls_ecp_group grp, grp_read, grp_cpy;
826 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100827 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100828 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
829
830 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
831
832 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
833 const unsigned char *vbuf = buf;
834 size_t olen;
835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 mbedtls_ecp_group_init(&grp);
837 mbedtls_ecp_group_init(&grp_read);
838 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 mbedtls_mpi_init(&exp_P);
841 mbedtls_mpi_init(&exp_A);
842 mbedtls_mpi_init(&exp_B);
843 mbedtls_mpi_init(&exp_G_x);
844 mbedtls_mpi_init(&exp_G_y);
845 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100846
847 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
849 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
850 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
851 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
852 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
853 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100854
Werner Lewisc4afef72022-08-25 10:29:19 +0100855 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
857 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
858 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100859 }
860
Werner Lewise54046c2022-08-15 11:43:56 +0100861 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100863
864 // Compare group with expected parameters
865 // A is NULL for SECPxxxR1 curves
866 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
868 if (*A != 0) {
869 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
870 }
871 if (*B != 0) {
872 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
873 }
874 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
875 if (*G_y != 0) {
876 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
877 }
878 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100879
880 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 crv = mbedtls_ecp_curve_info_from_grp_id(id);
882 TEST_EQUAL(crv->grp_id, id);
883 TEST_EQUAL(crv->bit_size, bit_size);
884 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100885
886 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
888 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
889 TEST_EQUAL(crv_tls_id->grp_id, id);
890 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100891
Werner Lewisccae25b2022-09-20 10:00:07 +0100892 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
894 buf, sizeof(buf)),
895 0);
896 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
897 sizeof(ecparameters)),
898 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100899
900 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
902 0);
903 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100904 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
906 0);
907 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100908
909 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
Valerio Setti46829482023-01-18 13:59:30 +0100911#if defined(MBEDTLS_ECDH_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
Valerio Setti46829482023-01-18 13:59:30 +0100913#endif
914#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
916 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Valerio Setti46829482023-01-18 13:59:30 +0100917#endif
Werner Lewise54046c2022-08-15 11:43:56 +0100918
919 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
921 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100922
923 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 for (crv = mbedtls_ecp_curve_list();
925 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
926 crv->grp_id != (unsigned) id;
927 crv++) {
928 ;
929 }
930 TEST_EQUAL(crv->grp_id, id);
931 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100932 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 g_id++) {
934 ;
935 }
936 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100937
938exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
940 mbedtls_ecp_group_free(&grp_read);
941 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
942 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
943 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100944}
945/* END_CASE */
946
Paul Bakker33b43f12013-08-20 11:48:36 +0200947/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100948void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200949{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 mbedtls_ecp_group grp;
951 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 mbedtls_ecp_group_init(&grp);
954 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
957 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200960
Paul Bakkerbd51b262014-07-10 15:26:12 +0200961exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 mbedtls_ecp_group_free(&grp);
963 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200964}
Paul Bakker33b43f12013-08-20 11:48:36 +0200965/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200966
Paul Bakker33b43f12013-08-20 11:48:36 +0200967/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100968void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
969 int id, char *d, char *Qx, char *Qy,
970 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100971{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200973 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 mbedtls_ecp_keypair_init(&pub);
976 mbedtls_ecp_keypair_init(&prv);
977 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if (id_pub != MBEDTLS_ECP_DP_NONE) {
980 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
981 }
982 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (id != MBEDTLS_ECP_DP_NONE) {
985 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
986 }
987 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
988 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100989
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
991 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100992
993exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 mbedtls_ecp_keypair_free(&pub);
995 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100996}
997/* END_CASE */
998
999/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001000void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001001{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 mbedtls_ecp_group grp;
1003 mbedtls_ecp_point Q;
1004 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001005 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 mbedtls_ecp_group_init(&grp);
1008 mbedtls_ecp_point_init(&Q);
1009 mbedtls_mpi_init(&d);
1010 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1015 &mbedtls_test_rnd_pseudo_rand,
1016 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1019 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001020
Paul Bakkerbd51b262014-07-10 15:26:12 +02001021exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 mbedtls_ecp_group_free(&grp);
1023 mbedtls_ecp_point_free(&Q);
1024 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001025}
Paul Bakker33b43f12013-08-20 11:48:36 +02001026/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001027
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001028/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001029void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001030{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001032 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 mbedtls_ecp_keypair_init(&key);
1035 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1038 &mbedtls_test_rnd_pseudo_rand,
1039 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1042 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001043
Paul Bakkerbd51b262014-07-10 15:26:12 +02001044exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001046}
1047/* END_CASE */
1048
Janos Follath171a7ef2019-02-15 16:17:45 +00001049/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001050void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001051{
1052 int ret = 0;
1053 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001054 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 mbedtls_ecp_keypair_init(&key);
1057 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1060 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 if (expected == 0) {
1063 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1064 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001067 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1070 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001071
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 ASSERT_COMPARE(in_key->x, in_key->len,
1073 buf, in_key->len);
1074 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001075 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001076 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001077
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1079 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1082 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001083
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1085 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001086
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 ASSERT_COMPARE(export1, in_key->len,
1088 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001089 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001090 }
1091
1092exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 mbedtls_ecp_keypair_free(&key);
1094 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001095}
1096/* END_CASE */
1097
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001098/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +01001099void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001100{
1101 mbedtls_test_rnd_buf_info rnd_info;
1102 mbedtls_mpi d;
1103 int ret;
1104 uint8_t *actual = NULL;
1105
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001107 rnd_info.buf = seed->x;
1108 rnd_info.length = seed->len;
1109 rnd_info.fallback_f_rng = NULL;
1110 rnd_info.fallback_p_rng = NULL;
1111
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1115 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001116
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001118 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 TEST_ASSERT(ret != 0);
1120 } else {
1121 TEST_EQUAL(ret, 0);
1122 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1123 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001124 /* Test the exact result. This assumes that the output of the
1125 * RNG is used in a specific way, which is overly constraining.
1126 * The advantage is that it's easier to test the expected properties
1127 * of the generated key:
1128 * - The most significant bit must be at a specific positions
1129 * (can be enforced by checking the bit-length).
1130 * - The least significant bits must have specific values
1131 * (can be enforced by checking these bits).
1132 * - Other bits must be random (by testing with different RNG outputs,
1133 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 ASSERT_COMPARE(expected->x, expected->len,
1135 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001136 }
1137
1138exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 mbedtls_free(actual);
1140 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001141}
1142/* END_CASE */
1143
Werner Lewis3b097392022-08-08 11:53:45 +01001144/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001145void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001146{
1147 mbedtls_ecp_group grp;
1148 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1149
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 mbedtls_ecp_group_init(&grp);
1151 mbedtls_ecp_point_init(&pt);
1152 mbedtls_ecp_point_init(&zero_pt);
1153 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001154
1155 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1157 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1158 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1159 P_bin->x, P_bin->len), 0);
1160 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1161 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001162
1163 // Test initialized point
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1165 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1166 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1167 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1168 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001169
1170 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1172 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1173 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1174 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1175 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001176
1177 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1179 P_bin->x, P_bin->len), 0);
1180 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1181 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1182 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1183 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001184
1185 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1187 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1188 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1189 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1190 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001191
1192 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1194 P_bin->x, P_bin->len), 0);
1195 mbedtls_ecp_point_free(&pt);
1196 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
1202exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 mbedtls_ecp_group_free(&grp);
1204 mbedtls_ecp_point_free(&pt);
1205 mbedtls_ecp_point_free(&zero_pt);
1206 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001207}
1208/* END_CASE */
1209
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001210/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001211void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001212{
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001214}
Paul Bakker33b43f12013-08-20 11:48:36 +02001215/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001216
1217/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001219{
1220 mbedtls_ecp_keypair key;
1221 mbedtls_ecp_group export_grp;
1222 mbedtls_mpi export_d;
1223 mbedtls_ecp_point export_Q;
1224
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 mbedtls_ecp_group_init(&export_grp);
1226 mbedtls_ecp_group_init(&key.grp);
1227 mbedtls_mpi_init(&export_d);
1228 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001229
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 mbedtls_ecp_keypair_init(&key);
1231 if (invalid_grp == 0) {
1232 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1233 }
1234 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1235 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001236
Gilles Peskine449bd832023-01-11 14:50:10 +01001237 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1238 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001239
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 if (expected_ret == 0) {
1241 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1242 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1243 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001244 }
1245
1246exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 mbedtls_ecp_keypair_free(&key);
1248 mbedtls_ecp_group_free(&export_grp);
1249 mbedtls_mpi_free(&export_d);
1250 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001251}
1252/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001253
1254/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001255void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001256{
1257 mbedtls_ecp_group grp;
1258 mbedtls_mpi expected_n;
1259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 mbedtls_ecp_group_init(&grp);
1261 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1264 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001265
1266 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1268 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001269
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001271
1272exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 mbedtls_ecp_group_free(&grp);
1274 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001275}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001276/* END_CASE */
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001277
Minos Galanakis92278dc2023-03-29 11:41:21 +01001278/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP_GENERIC_ENABLED */
Minos Galanakis13586482023-03-21 12:08:37 +00001279void ecp_mod_p_generic_raw(int curve_id,
1280 char *input_N,
1281 char *input_X,
1282 char *result)
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001283{
1284 mbedtls_mpi_uint *X = NULL;
1285 mbedtls_mpi_uint *N = NULL;
1286 mbedtls_mpi_uint *res = NULL;
1287 size_t limbs_X;
1288 size_t limbs_N;
1289 size_t limbs_res;
1290
Minos Galanakis13586482023-03-21 12:08:37 +00001291 size_t bytes;
1292 size_t limbs;
1293 size_t curve_bits;
1294 int (*curve_func)(mbedtls_mpi_uint *X, size_t X_limbs);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001295
1296 mbedtls_mpi_mod_modulus m;
1297 mbedtls_mpi_mod_modulus_init(&m);
1298
1299 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1300 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1301 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
Minos Galanakis13586482023-03-21 12:08:37 +00001302 bytes = limbs_N * sizeof(mbedtls_mpi_uint);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001303
Minos Galanakis13586482023-03-21 12:08:37 +00001304 switch (curve_id) {
1305#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
1306 case MBEDTLS_ECP_DP_SECP192R1:
1307 limbs = 2 * limbs_N;
1308 curve_bits = 192;
1309 curve_func = &mbedtls_ecp_mod_p192_raw;
1310 break;
1311#endif
1312#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
1313 case MBEDTLS_ECP_DP_SECP224R1:
1314 limbs = 448 / biL;
1315 curve_bits = 224;
1316 curve_func = &mbedtls_ecp_mod_p224_raw;
1317 break;
1318#endif
1319#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
1320 case MBEDTLS_ECP_DP_SECP256R1:
1321 limbs = 2 * limbs_N;
1322 curve_bits = 256;
1323 curve_func = &mbedtls_ecp_mod_p256_raw;
1324 break;
1325#endif
1326#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
1327 case MBEDTLS_ECP_DP_SECP384R1:
1328 limbs = 2 * limbs_N;
1329 curve_bits = 384;
1330 curve_func = &mbedtls_ecp_mod_p384_raw;
1331 break;
1332#endif
1333#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
1334 case MBEDTLS_ECP_DP_SECP521R1:
1335 limbs = 2 * limbs_N;
1336 curve_bits = 522;
1337 curve_func = &mbedtls_ecp_mod_p521_raw;
1338 break;
1339#endif
1340 default:
1341 mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__);
1342 goto exit;
1343 }
Gabor Mezeif65a0592023-02-14 18:26:36 +01001344
Minos Galanakis13586482023-03-21 12:08:37 +00001345 TEST_EQUAL(limbs_X, limbs);
1346 TEST_EQUAL(limbs_res, limbs_N);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001347
1348 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
Minos Galanakis13586482023-03-21 12:08:37 +00001349 &m, N, limbs_N,
Gabor Mezeif65a0592023-02-14 18:26:36 +01001350 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1351
Minos Galanakis13586482023-03-21 12:08:37 +00001352 TEST_EQUAL((*curve_func)(X, limbs_X), 0);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001353
Minos Galanakis13586482023-03-21 12:08:37 +00001354 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001355 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1356 ASSERT_COMPARE(X, bytes, res, bytes);
1357
1358exit:
1359 mbedtls_free(X);
1360 mbedtls_free(res);
1361
1362 mbedtls_mpi_mod_modulus_free(&m);
1363 mbedtls_free(N);
1364}
1365/* END_CASE */
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00001366
1367/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1368void ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1369{
1370 int ret;
1371 mbedtls_mpi_mod_modulus m;
1372 mbedtls_mpi_mod_modulus_init(&m);
1373 mbedtls_mpi_uint *p = NULL;
1374 size_t p_limbs;
1375 size_t bytes;
1376
1377 TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1378
1379 ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1380 TEST_EQUAL(ret, iret);
1381
1382 if (ret == 0) {
1383
1384 /* Test for limb sizes */
1385 TEST_EQUAL(m.limbs, p_limbs);
1386 bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1387
1388 /* Test for validity of moduli by the presence of Montgomery consts */
1389
1390 TEST_ASSERT(m.rep.mont.mm != 0);
1391 TEST_ASSERT(m.rep.mont.rr != NULL);
1392
1393
1394 /* Compare output byte-by-byte */
1395 ASSERT_COMPARE(p, bytes, m.p, bytes);
1396
1397 /* Test for user free-ing allocated memory */
1398 mbedtls_mpi_mod_modulus_free(&m);
1399 }
1400
1401exit:
1402 mbedtls_mpi_mod_modulus_free(&m);
1403 mbedtls_free(p);
1404}
1405/* END_CASE */