blob: f5b5811581606a454a5afdf1f7c62de0a3905a7a [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"
Gabor Mezei65fc9f72023-01-16 16:51:12 +01005#include "ecp_internal.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +02006
7#if defined(MBEDTLS_TEST_HOOKS) && \
Gilles Peskine449bd832023-01-11 14:50:10 +01008 (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
9 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
10 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED))
Gilles Peskine618be2e2021-04-03 21:47:53 +020011#define HAVE_FIX_NEGATIVE
12#endif
13
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020014#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020015
Gilles Peskine449bd832023-01-11 14:50:10 +010016#define ECP_PT_RESET(x) \
17 mbedtls_ecp_point_free(x); \
18 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020019
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010020/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010021inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
22 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010023{
Gilles Peskine449bd832023-01-11 14:50:10 +010024 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 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->A, &grp2->A) != 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->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010031 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010032 }
33 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010034 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010035 }
36 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010037 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 }
39 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010040 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010041 }
42 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010043 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010044 }
45 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010046 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010047 }
48 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010049 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010050 }
51 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010052 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010053 }
54 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010055 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010056 }
57 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010058 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010059 }
60 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010061 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010062 }
63 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010064 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010065 }
66 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010067 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010068 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010069
70 return 0;
71}
72
Paul Bakker33b43f12013-08-20 11:48:36 +020073/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010074
Paul Bakker33b43f12013-08-20 11:48:36 +020075/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 * depends_on:MBEDTLS_ECP_C
Paul Bakker33b43f12013-08-20 11:48:36 +020077 * END_DEPENDENCIES
78 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010079
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010080/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010081void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000082{
83 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000084 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000085 int invalid_fmt = 42;
86 size_t olen;
87 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000088
Gilles Peskine449bd832023-01-11 14:50:10 +010089 mbedtls_ecp_group_init(&grp);
90 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020091
Gilles Peskine449bd832023-01-11 14:50:10 +010092 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
93 mbedtls_ecp_point_write_binary(&grp, &P,
94 invalid_fmt,
95 &olen,
96 buf, sizeof(buf)));
97 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
98 mbedtls_ecp_tls_write_point(&grp, &P,
99 invalid_fmt,
100 &olen,
101 buf,
102 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000103
104exit:
105 return;
106}
107/* END_CASE */
108
Paul Bakker33b43f12013-08-20 11:48:36 +0200109/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100110void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100111{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100113
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
115 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
116 by_name = mbedtls_ecp_curve_info_from_name(name);
117 TEST_ASSERT(by_id != NULL);
118 TEST_ASSERT(by_tls != NULL);
119 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 TEST_ASSERT(by_id == by_tls);
122 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 TEST_ASSERT(by_id->bit_size == size);
125 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
126 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100127}
128/* END_CASE */
129
130/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
132 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100133{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 mbedtls_ecp_group grp;
135 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 mbedtls_ecp_group_init(&grp);
138 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100141
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
143 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
144 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100147
Paul Bakkerbd51b262014-07-10 15:26:12 +0200148exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 mbedtls_ecp_group_free(&grp);
150 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100151}
152/* END_CASE */
153
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200154/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100155void ecp_test_vect_restart(int id,
156 char *dA_str, char *xA_str, char *yA_str,
157 char *dB_str, char *xZ_str, char *yZ_str,
158 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100159{
160 /*
161 * Test for early restart. Based on test vectors like ecp_test_vect(),
162 * but for the sake of simplicity only does half of each side. It's
163 * important to test both base point and random point, though, as memory
164 * management is different in each case.
165 *
166 * Don't try using too precise bounds for restarts as the exact number
167 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
168 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
169 * change in the future. A factor 2 is a minimum safety margin.
170 *
171 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100172 * - Random point mult: ~3250M
173 * - Cold base point mult: ~3300M
174 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100175 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100176 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100177 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200178 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100179 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200180 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100181 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
182 int cnt_restarts;
183 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200184 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 mbedtls_ecp_restart_init(&ctx);
187 mbedtls_ecp_group_init(&grp);
188 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
189 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
190 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
191 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
196 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
197 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
200 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
201 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100204
205 /* Base point case */
206 cnt_restarts = 0;
207 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 ECP_PT_RESET(&R);
209 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
210 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
211 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 TEST_ASSERT(ret == 0);
214 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
215 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 TEST_ASSERT(cnt_restarts >= min_restarts);
218 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100219
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100220 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100222 cnt_restarts = 0;
223 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 ECP_PT_RESET(&R);
225 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
226 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
227 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 TEST_ASSERT(ret == 0);
230 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
231 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 TEST_ASSERT(cnt_restarts >= min_restarts);
234 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100235
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200236 /* Do we leak memory when aborting an operation?
237 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 if (min_restarts > 0) {
239 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
240 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
241 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200242 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100243
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100244exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 mbedtls_ecp_restart_free(&ctx);
246 mbedtls_ecp_group_free(&grp);
247 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
248 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
249 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100250}
251/* END_CASE */
252
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100253/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100254void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
255 char *u1_str, char *u2_str,
256 char *xQ_str, char *yQ_str,
257 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200258{
259 /*
260 * Compute R = u1 * G + u2 * Q
261 * (test vectors mostly taken from ECDSA intermediate results)
262 *
263 * See comments at the top of ecp_test_vect_restart()
264 */
265 mbedtls_ecp_restart_ctx ctx;
266 mbedtls_ecp_group grp;
267 mbedtls_ecp_point R, Q;
268 mbedtls_mpi u1, u2, xR, yR;
269 int cnt_restarts;
270 int ret;
271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 mbedtls_ecp_restart_init(&ctx);
273 mbedtls_ecp_group_init(&grp);
274 mbedtls_ecp_point_init(&R);
275 mbedtls_ecp_point_init(&Q);
276 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
277 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
282 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
283 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
284 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
287 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
288 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200291
292 cnt_restarts = 0;
293 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 ECP_PT_RESET(&R);
295 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
296 &u1, &grp.G, &u2, &Q, &ctx);
297 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 TEST_ASSERT(ret == 0);
300 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
301 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 TEST_ASSERT(cnt_restarts >= min_restarts);
304 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200305
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200306 /* Do we leak memory when aborting an operation?
307 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 if (min_restarts > 0) {
309 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
310 &u1, &grp.G, &u2, &Q, &ctx);
311 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200312 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200313
314exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 mbedtls_ecp_restart_free(&ctx);
316 mbedtls_ecp_group_free(&grp);
317 mbedtls_ecp_point_free(&R);
318 mbedtls_ecp_point_free(&Q);
319 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
320 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200321}
322/* END_CASE */
323
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100324/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
326 char *dB_str, char *xB_str, char *yB_str,
327 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100328{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 mbedtls_ecp_group grp;
330 mbedtls_ecp_point R;
331 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200332 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100333
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
335 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
336 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
337 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
344 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
345 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
346 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
347 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
348 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
349 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
350 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
353 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
354 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
355 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
356 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
357 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
358 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
359 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
360 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
361 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
364 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
365 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
366 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
367 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
368 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
369 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
370 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
371 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
372 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100373
Paul Bakkerbd51b262014-07-10 15:26:12 +0200374exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
376 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
377 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 +0100378}
Paul Bakker33b43f12013-08-20 11:48:36 +0200379/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100380
Paul Bakker33b43f12013-08-20 11:48:36 +0200381/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
383 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100384{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 mbedtls_ecp_group grp;
386 mbedtls_ecp_point R;
387 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200388 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
391 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
392 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
393 mbedtls_mpi_init(&xS);
394 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
401 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
402 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
403 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
404 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
407 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
408 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
409 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
412 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
413 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
414 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
417 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
418 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
419 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
422 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
423 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
424 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100425
Paul Bakkerbd51b262014-07-10 15:26:12 +0200426exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
428 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
429 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
430 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100431}
432/* END_CASE */
433
434/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435void ecp_test_mul(int id, data_t *n_hex,
436 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
437 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
438 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100439{
440 mbedtls_ecp_group grp;
441 mbedtls_ecp_point P, nP, R;
442 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200443 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
446 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
447 mbedtls_mpi_init(&n);
448 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
457 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
458 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
459 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
460 == 0);
461 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
462 == 0);
463 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
464 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
467 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
468 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 if (expected_ret == 0) {
471 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
472 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
473 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100474 }
475
476exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
478 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
479 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100480}
481/* END_CASE */
482
483/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100484void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900485{
486 mbedtls_ecp_group grp;
487 mbedtls_mpi d;
488 mbedtls_ecp_point Q;
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
491 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
500 &mbedtls_test_rnd_zero_rand, NULL)
501 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900502
503exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
505 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900506}
507/* END_CASE */
508
Gilles Peskineca91ee42021-04-03 18:31:01 +0200509/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100510void ecp_muladd(int id,
511 data_t *u1_bin, data_t *P1_bin,
512 data_t *u2_bin, data_t *P2_bin,
513 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200514{
515 /* Compute R = u1 * P1 + u2 * P2 */
516 mbedtls_ecp_group grp;
517 mbedtls_ecp_point P1, P2, R;
518 mbedtls_mpi u1, u2;
519 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
520 size_t len;
521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 mbedtls_ecp_group_init(&grp);
523 mbedtls_ecp_point_init(&P1);
524 mbedtls_ecp_point_init(&P2);
525 mbedtls_ecp_point_init(&R);
526 mbedtls_mpi_init(&u1);
527 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
530 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
531 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
532 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
533 P1_bin->x, P1_bin->len));
534 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
535 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
538 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
539 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
540 &len, actual_result, sizeof(actual_result)));
541 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 ASSERT_COMPARE(expected_result->x, expected_result->len,
544 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200545
546exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 mbedtls_ecp_group_free(&grp);
548 mbedtls_ecp_point_free(&P1);
549 mbedtls_ecp_point_free(&P2);
550 mbedtls_ecp_point_free(&R);
551 mbedtls_mpi_free(&u1);
552 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200553}
554/* END_CASE */
555
Jonas923d5792020-05-13 14:22:45 +0900556/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100557void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100558{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_ecp_group grp;
560 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
563 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
566 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
567 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100568
569 /*
570 * Store correct result before we touch N
571 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 TEST_ASSERT(grp.modp(&N) == 0);
575 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100576
577 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200578 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100579 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
581 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100582
Paul Bakkerbd51b262014-07-10 15:26:12 +0200583exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
585 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100586}
Paul Bakker33b43f12013-08-20 11:48:36 +0200587/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100588
Paul Bakker33b43f12013-08-20 11:48:36 +0200589/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100590void ecp_write_binary(int id, char *x, char *y, char *z, int format,
591 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100592{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_ecp_group grp;
594 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100595 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100596 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
605 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
606 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
609 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if (ret == 0) {
612 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
613 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100614 }
615
Paul Bakkerbd51b262014-07-10 15:26:12 +0200616exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100618}
Paul Bakker33b43f12013-08-20 11:48:36 +0200619/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100620
Paul Bakker33b43f12013-08-20 11:48:36 +0200621/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100622void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
623 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100624{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 mbedtls_ecp_group grp;
626 mbedtls_ecp_point P;
627 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100628
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
631 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
636 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
637 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 if (ret == 0) {
642 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
643 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
644 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
645 TEST_ASSERT(P.Y.p == NULL);
646 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
647 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
648 } else {
649 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
650 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400653 /* (reading compressed format supported only for
654 * Short Weierstrass curves with prime p where p = 3 mod 4) */
655 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400657 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 mbedtls_mpi_free(&P.Y);
659 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
660 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
661 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400662 }
Janos Follath59b813c2019-02-13 10:44:06 +0000663 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100664 }
665
Paul Bakkerbd51b262014-07-10 15:26:12 +0200666exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
668 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100669}
Paul Bakker33b43f12013-08-20 11:48:36 +0200670/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100671
Paul Bakker33b43f12013-08-20 11:48:36 +0200672/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100673void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
674 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100675{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 mbedtls_ecp_group grp;
677 mbedtls_ecp_point P;
678 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100679 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100680
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
683 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
688 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
689 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 if (ret == 0) {
694 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
695 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
696 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
697 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100698 }
699
Paul Bakkerbd51b262014-07-10 15:26:12 +0200700exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
702 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100703}
Paul Bakker33b43f12013-08-20 11:48:36 +0200704/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100705
Paul Bakker33b43f12013-08-20 11:48:36 +0200706/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100707void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100708{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_ecp_group grp;
710 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100711 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100712 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100713 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 mbedtls_ecp_group_init(&grp);
716 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
721 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
722 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
723 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
724 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
725 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
726 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
727 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
730 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
731 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
732 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
733 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
734 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
735 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
736 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
739 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
740 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
741 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
742 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
743 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
744 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
747 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
748 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
749 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
750 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
751 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
752 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100753
Paul Bakkerbd51b262014-07-10 15:26:12 +0200754exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 mbedtls_ecp_group_free(&grp);
756 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100757}
Paul Bakker33b43f12013-08-20 11:48:36 +0200758/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100759
Paul Bakker33b43f12013-08-20 11:48:36 +0200760/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100761void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
762 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100763{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100765 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100766 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100769
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 TEST_ASSERT(ret == result);
773 if (ret == 0) {
774 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
775 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100776 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100777
Paul Bakkerbd51b262014-07-10 15:26:12 +0200778exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100780}
Paul Bakker33b43f12013-08-20 11:48:36 +0200781/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100782
Paul Bakker33b43f12013-08-20 11:48:36 +0200783/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100784void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100785{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100787 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100788 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100789 size_t len;
790 int ret;
791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 mbedtls_ecp_group_init(&grp1);
793 mbedtls_ecp_group_init(&grp2);
794 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
799 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
800 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 if (ret == 0) {
803 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
804 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100805 }
806
Paul Bakkerbd51b262014-07-10 15:26:12 +0200807exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 mbedtls_ecp_group_free(&grp1);
809 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100810}
Paul Bakker33b43f12013-08-20 11:48:36 +0200811/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100812
Werner Lewise54046c2022-08-15 11:43:56 +0100813/* BEGIN_CASE depends_on:MBEDTLS_ECDH_C:MBEDTLS_ECDSA_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100814void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
815 char *P, char *A, char *B,
816 char *G_x, char *G_y, char *N,
817 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100818{
819 mbedtls_ecp_group grp, grp_read, grp_cpy;
820 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100821 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100822 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
823
824 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
825
826 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
827 const unsigned char *vbuf = buf;
828 size_t olen;
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 mbedtls_ecp_group_init(&grp);
831 mbedtls_ecp_group_init(&grp_read);
832 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 mbedtls_mpi_init(&exp_P);
835 mbedtls_mpi_init(&exp_A);
836 mbedtls_mpi_init(&exp_B);
837 mbedtls_mpi_init(&exp_G_x);
838 mbedtls_mpi_init(&exp_G_y);
839 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100840
841 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
843 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
844 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
845 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
846 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
847 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100848
Werner Lewisc4afef72022-08-25 10:29:19 +0100849 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
851 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
852 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100853 }
854
Werner Lewise54046c2022-08-15 11:43:56 +0100855 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100857
858 // Compare group with expected parameters
859 // A is NULL for SECPxxxR1 curves
860 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
862 if (*A != 0) {
863 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
864 }
865 if (*B != 0) {
866 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
867 }
868 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
869 if (*G_y != 0) {
870 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
871 }
872 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100873
874 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 crv = mbedtls_ecp_curve_info_from_grp_id(id);
876 TEST_EQUAL(crv->grp_id, id);
877 TEST_EQUAL(crv->bit_size, bit_size);
878 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100879
880 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
882 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
883 TEST_EQUAL(crv_tls_id->grp_id, id);
884 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100885
Werner Lewisccae25b2022-09-20 10:00:07 +0100886 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
888 buf, sizeof(buf)),
889 0);
890 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
891 sizeof(ecparameters)),
892 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100893
894 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
896 0);
897 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100898 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
900 0);
901 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100902
903 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
905 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
906 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
907 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Werner Lewise54046c2022-08-15 11:43:56 +0100908
909 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
911 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100912
913 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 for (crv = mbedtls_ecp_curve_list();
915 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
916 crv->grp_id != (unsigned) id;
917 crv++) {
918 ;
919 }
920 TEST_EQUAL(crv->grp_id, id);
921 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100922 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 g_id++) {
924 ;
925 }
926 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100927
928exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
930 mbedtls_ecp_group_free(&grp_read);
931 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
932 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
933 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100934}
935/* END_CASE */
936
Paul Bakker33b43f12013-08-20 11:48:36 +0200937/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100938void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200939{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940 mbedtls_ecp_group grp;
941 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 mbedtls_ecp_group_init(&grp);
944 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
947 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200950
Paul Bakkerbd51b262014-07-10 15:26:12 +0200951exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 mbedtls_ecp_group_free(&grp);
953 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200954}
Paul Bakker33b43f12013-08-20 11:48:36 +0200955/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200956
Paul Bakker33b43f12013-08-20 11:48:36 +0200957/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100958void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
959 int id, char *d, char *Qx, char *Qy,
960 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100961{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200963 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 mbedtls_ecp_keypair_init(&pub);
966 mbedtls_ecp_keypair_init(&prv);
967 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 if (id_pub != MBEDTLS_ECP_DP_NONE) {
970 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
971 }
972 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 if (id != MBEDTLS_ECP_DP_NONE) {
975 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
976 }
977 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
978 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
981 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100982
983exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 mbedtls_ecp_keypair_free(&pub);
985 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100986}
987/* END_CASE */
988
989/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100990void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100991{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 mbedtls_ecp_group grp;
993 mbedtls_ecp_point Q;
994 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200995 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 mbedtls_ecp_group_init(&grp);
998 mbedtls_ecp_point_init(&Q);
999 mbedtls_mpi_init(&d);
1000 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1005 &mbedtls_test_rnd_pseudo_rand,
1006 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1009 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001010
Paul Bakkerbd51b262014-07-10 15:26:12 +02001011exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 mbedtls_ecp_group_free(&grp);
1013 mbedtls_ecp_point_free(&Q);
1014 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001015}
Paul Bakker33b43f12013-08-20 11:48:36 +02001016/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001017
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001018/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001019void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001020{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001022 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 mbedtls_ecp_keypair_init(&key);
1025 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1028 &mbedtls_test_rnd_pseudo_rand,
1029 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1032 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001033
Paul Bakkerbd51b262014-07-10 15:26:12 +02001034exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001036}
1037/* END_CASE */
1038
Janos Follath171a7ef2019-02-15 16:17:45 +00001039/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001040void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001041{
1042 int ret = 0;
1043 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001044 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 mbedtls_ecp_keypair_init(&key);
1047 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1050 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 if (expected == 0) {
1053 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1054 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001057 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1060 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 ASSERT_COMPARE(in_key->x, in_key->len,
1063 buf, in_key->len);
1064 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001065 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001066 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1069 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001070
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1072 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1075 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001076
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 ASSERT_COMPARE(export1, in_key->len,
1078 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001079 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001080 }
1081
1082exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 mbedtls_ecp_keypair_free(&key);
1084 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001085}
1086/* END_CASE */
1087
Gilles Peskine618be2e2021-04-03 21:47:53 +02001088/* BEGIN_CASE depends_on:HAVE_FIX_NEGATIVE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001089void fix_negative(data_t *N_bin, int c, int bits)
Gilles Peskine618be2e2021-04-03 21:47:53 +02001090{
1091 mbedtls_mpi C, M, N;
1092
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 mbedtls_mpi_init(&C);
1094 mbedtls_mpi_init(&M);
1095 mbedtls_mpi_init(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001096
Gilles Peskine392d1012021-04-09 15:46:51 +02001097 /* C = - c * 2^bits (positive since c is negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 TEST_EQUAL(0, mbedtls_mpi_lset(&C, -c));
1099 TEST_EQUAL(0, mbedtls_mpi_shift_l(&C, bits));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001100
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 TEST_EQUAL(0, mbedtls_mpi_read_binary(&N, N_bin->x, N_bin->len));
1102 TEST_EQUAL(0, mbedtls_mpi_grow(&N, C.n));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001103
Gilles Peskine392d1012021-04-09 15:46:51 +02001104 /* M = N - C = - ( C - N ) (expected result of fix_negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 TEST_EQUAL(0, mbedtls_mpi_sub_mpi(&M, &N, &C));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 mbedtls_ecp_fix_negative(&N, c, bits);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001108
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&N, &M));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001110
1111exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 mbedtls_mpi_free(&C);
1113 mbedtls_mpi_free(&M);
1114 mbedtls_mpi_free(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001115}
1116/* END_CASE */
1117
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001118/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +01001119void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001120{
1121 mbedtls_test_rnd_buf_info rnd_info;
1122 mbedtls_mpi d;
1123 int ret;
1124 uint8_t *actual = NULL;
1125
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001127 rnd_info.buf = seed->x;
1128 rnd_info.length = seed->len;
1129 rnd_info.fallback_f_rng = NULL;
1130 rnd_info.fallback_p_rng = NULL;
1131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1135 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001136
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001138 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 TEST_ASSERT(ret != 0);
1140 } else {
1141 TEST_EQUAL(ret, 0);
1142 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1143 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001144 /* Test the exact result. This assumes that the output of the
1145 * RNG is used in a specific way, which is overly constraining.
1146 * The advantage is that it's easier to test the expected properties
1147 * of the generated key:
1148 * - The most significant bit must be at a specific positions
1149 * (can be enforced by checking the bit-length).
1150 * - The least significant bits must have specific values
1151 * (can be enforced by checking these bits).
1152 * - Other bits must be random (by testing with different RNG outputs,
1153 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 ASSERT_COMPARE(expected->x, expected->len,
1155 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001156 }
1157
1158exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 mbedtls_free(actual);
1160 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001161}
1162/* END_CASE */
1163
Werner Lewis3b097392022-08-08 11:53:45 +01001164/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001165void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001166{
1167 mbedtls_ecp_group grp;
1168 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 mbedtls_ecp_group_init(&grp);
1171 mbedtls_ecp_point_init(&pt);
1172 mbedtls_ecp_point_init(&zero_pt);
1173 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001174
1175 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1177 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1178 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1179 P_bin->x, P_bin->len), 0);
1180 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1181 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001182
1183 // Test initialized point
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1185 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1186 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1187 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1188 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001189
1190 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1192 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1193 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1194 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1195 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001196
1197 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1199 P_bin->x, P_bin->len), 0);
1200 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1201 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1202 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1203 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001204
1205 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1207 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1208 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1209 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1210 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001211
1212 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1214 P_bin->x, P_bin->len), 0);
1215 mbedtls_ecp_point_free(&pt);
1216 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1217 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1218 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1219 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1220 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001221
1222exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 mbedtls_ecp_group_free(&grp);
1224 mbedtls_ecp_point_free(&pt);
1225 mbedtls_ecp_point_free(&zero_pt);
1226 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001227}
1228/* END_CASE */
1229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001231void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001232{
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001234}
Paul Bakker33b43f12013-08-20 11:48:36 +02001235/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001236
1237/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001238void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001239{
1240 mbedtls_ecp_keypair key;
1241 mbedtls_ecp_group export_grp;
1242 mbedtls_mpi export_d;
1243 mbedtls_ecp_point export_Q;
1244
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 mbedtls_ecp_group_init(&export_grp);
1246 mbedtls_ecp_group_init(&key.grp);
1247 mbedtls_mpi_init(&export_d);
1248 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001249
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 mbedtls_ecp_keypair_init(&key);
1251 if (invalid_grp == 0) {
1252 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1253 }
1254 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1255 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001256
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1258 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 if (expected_ret == 0) {
1261 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1262 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1263 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001264 }
1265
1266exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 mbedtls_ecp_keypair_free(&key);
1268 mbedtls_ecp_group_free(&export_grp);
1269 mbedtls_mpi_free(&export_d);
1270 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001271}
1272/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001273
1274/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001275void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001276{
1277 mbedtls_ecp_group grp;
1278 mbedtls_mpi expected_n;
1279
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 mbedtls_ecp_group_init(&grp);
1281 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1284 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001285
1286 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1288 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001291
1292exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 mbedtls_ecp_group_free(&grp);
1294 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001295}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001296/* END_CASE */
Gabor Mezei65fc9f72023-01-16 16:51:12 +01001297
1298/* BEGIN_CASE */
1299void ecp_quasi_reduction(char *input_N,
1300 char *input_A,
1301 char *result)
1302{
1303 mbedtls_mpi_uint *A = NULL;
1304 mbedtls_mpi_uint *N = NULL;
1305 mbedtls_mpi_uint *res = NULL;
1306 size_t limbs_A;
1307 size_t limbs_N;
1308 size_t limbs_res;
1309
1310 mbedtls_mpi_mod_modulus m;
1311 mbedtls_mpi_mod_modulus_init(&m);
1312
1313 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
1314 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1315 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1316
1317 size_t limbs = limbs_N;
1318 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1319
1320 TEST_EQUAL(limbs_A, limbs);
1321 TEST_EQUAL(limbs_res, limbs);
1322
1323 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1324 &m, N, limbs,
1325 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1326
1327 TEST_EQUAL(mbedtls_ecp_quasi_reduction(A, &m), 0);
1328 ASSERT_COMPARE(A, bytes, res, bytes);
1329
1330exit:
1331 mbedtls_free(A);
1332 mbedtls_free(res);
1333
1334 mbedtls_mpi_mod_modulus_free(&m);
1335 mbedtls_free(N);
1336}
1337/* END_CASE */
1338
1339/* BEGIN_CASE */
1340void ecp_quasi_reduction_neg(char *input_N,
1341 char *input_A,
1342 char *result)
1343{
1344 mbedtls_mpi_uint *A = NULL;
1345 mbedtls_mpi_uint *N = NULL;
1346 mbedtls_mpi_uint *res = NULL;
1347 size_t limbs_A;
1348 size_t limbs_N;
1349 size_t limbs_res;
1350
1351 mbedtls_mpi_mod_modulus m;
1352 mbedtls_mpi_mod_modulus_init(&m);
1353
1354 mbedtls_mpi_mod_modulus fake_m;
1355 mbedtls_mpi_mod_modulus_init(&fake_m);
1356
1357 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
1358 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1359 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1360
1361 size_t limbs = limbs_N;
1362 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1363
1364 TEST_EQUAL(limbs_A, limbs);
1365 TEST_EQUAL(limbs_res, limbs);
1366
1367 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1368 &m, N, limbs,
1369 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1370
1371 TEST_EQUAL(mbedtls_ecp_quasi_reduction(A, &m), 0);
1372 ASSERT_COMPARE(A, bytes, res, bytes);
1373
1374 /* Check when m is not initialized */
1375 TEST_EQUAL(mbedtls_ecp_quasi_reduction(A, &fake_m),
1376 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1377
1378exit:
1379 mbedtls_free(A);
1380 mbedtls_free(res);
1381
1382 mbedtls_mpi_mod_modulus_free(&fake_m);
1383 mbedtls_mpi_mod_modulus_free(&m);
1384 mbedtls_free(N);
1385}
1386/* END_CASE */