blob: a0042ed34815ebbd6068f9abfc00407690324f12 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/ecp.h"
Werner Lewise54046c2022-08-15 11:43:56 +01003#include "mbedtls/ecdsa.h"
4#include "mbedtls/ecdh.h"
Paul Bakkerdbd443d2013-08-16 13:38:47 +02005
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01006#include "bignum_core.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +02007#include "ecp_invasive.h"
Gabor Mezeid8f67b92023-02-06 15:49:42 +01008#include "bignum_mod_raw_invasive.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +02009
10#if defined(MBEDTLS_TEST_HOOKS) && \
Gilles Peskine449bd832023-01-11 14:50:10 +010011 (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
12 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
13 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED))
Gilles Peskine618be2e2021-04-03 21:47:53 +020014#define HAVE_FIX_NEGATIVE
15#endif
16
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020017#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020018
Gilles Peskine449bd832023-01-11 14:50:10 +010019#define ECP_PT_RESET(x) \
20 mbedtls_ecp_point_free(x); \
21 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020022
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010023/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010024inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
25 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010026{
Gilles Peskine449bd832023-01-11 14:50:10 +010027 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 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->A, &grp2->A) != 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->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010034 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010035 }
36 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010037 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 }
39 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010040 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010041 }
42 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010043 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010044 }
45 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010046 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010047 }
48 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010049 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010050 }
51 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010052 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010053 }
54 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010055 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010056 }
57 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010058 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010059 }
60 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010061 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010062 }
63 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010064 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010065 }
66 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010067 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010068 }
69 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010070 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010071 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010072
73 return 0;
74}
75
Paul Bakker33b43f12013-08-20 11:48:36 +020076/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010077
Paul Bakker33b43f12013-08-20 11:48:36 +020078/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 * depends_on:MBEDTLS_ECP_C
Paul Bakker33b43f12013-08-20 11:48:36 +020080 * END_DEPENDENCIES
81 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010082
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010083/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010084void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000085{
86 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000087 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000088 int invalid_fmt = 42;
89 size_t olen;
90 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000091
Gilles Peskine449bd832023-01-11 14:50:10 +010092 mbedtls_ecp_group_init(&grp);
93 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020094
Gilles Peskine449bd832023-01-11 14:50:10 +010095 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
96 mbedtls_ecp_point_write_binary(&grp, &P,
97 invalid_fmt,
98 &olen,
99 buf, sizeof(buf)));
100 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
101 mbedtls_ecp_tls_write_point(&grp, &P,
102 invalid_fmt,
103 &olen,
104 buf,
105 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000106
107exit:
108 return;
109}
110/* END_CASE */
111
Paul Bakker33b43f12013-08-20 11:48:36 +0200112/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100113void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100114{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
118 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
119 by_name = mbedtls_ecp_curve_info_from_name(name);
120 TEST_ASSERT(by_id != NULL);
121 TEST_ASSERT(by_tls != NULL);
122 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 TEST_ASSERT(by_id == by_tls);
125 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 TEST_ASSERT(by_id->bit_size == size);
128 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
129 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100130}
131/* END_CASE */
132
133/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100134void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
135 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100136{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137 mbedtls_ecp_group grp;
138 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 mbedtls_ecp_group_init(&grp);
141 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100144
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
146 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
147 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100150
Paul Bakkerbd51b262014-07-10 15:26:12 +0200151exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 mbedtls_ecp_group_free(&grp);
153 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100154}
155/* END_CASE */
156
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200157/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100158void ecp_test_vect_restart(int id,
159 char *dA_str, char *xA_str, char *yA_str,
160 char *dB_str, char *xZ_str, char *yZ_str,
161 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100162{
163 /*
164 * Test for early restart. Based on test vectors like ecp_test_vect(),
165 * but for the sake of simplicity only does half of each side. It's
166 * important to test both base point and random point, though, as memory
167 * management is different in each case.
168 *
169 * Don't try using too precise bounds for restarts as the exact number
170 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
171 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
172 * change in the future. A factor 2 is a minimum safety margin.
173 *
174 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100175 * - Random point mult: ~3250M
176 * - Cold base point mult: ~3300M
177 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100178 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100179 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100180 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200181 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100182 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200183 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100184 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
185 int cnt_restarts;
186 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200187 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 mbedtls_ecp_restart_init(&ctx);
190 mbedtls_ecp_group_init(&grp);
191 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
192 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
193 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
194 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
199 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
200 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
203 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
204 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100207
208 /* Base point case */
209 cnt_restarts = 0;
210 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 ECP_PT_RESET(&R);
212 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
213 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
214 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100215
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 TEST_ASSERT(ret == 0);
217 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
218 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 TEST_ASSERT(cnt_restarts >= min_restarts);
221 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100222
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100223 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100225 cnt_restarts = 0;
226 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 ECP_PT_RESET(&R);
228 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
229 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
230 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 TEST_ASSERT(ret == 0);
233 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
234 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 TEST_ASSERT(cnt_restarts >= min_restarts);
237 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100238
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200239 /* Do we leak memory when aborting an operation?
240 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 if (min_restarts > 0) {
242 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
243 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
244 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200245 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100246
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100247exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 mbedtls_ecp_restart_free(&ctx);
249 mbedtls_ecp_group_free(&grp);
250 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
251 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
252 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100253}
254/* END_CASE */
255
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100256/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100257void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
258 char *u1_str, char *u2_str,
259 char *xQ_str, char *yQ_str,
260 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200261{
262 /*
263 * Compute R = u1 * G + u2 * Q
264 * (test vectors mostly taken from ECDSA intermediate results)
265 *
266 * See comments at the top of ecp_test_vect_restart()
267 */
268 mbedtls_ecp_restart_ctx ctx;
269 mbedtls_ecp_group grp;
270 mbedtls_ecp_point R, Q;
271 mbedtls_mpi u1, u2, xR, yR;
272 int cnt_restarts;
273 int ret;
274
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 mbedtls_ecp_restart_init(&ctx);
276 mbedtls_ecp_group_init(&grp);
277 mbedtls_ecp_point_init(&R);
278 mbedtls_ecp_point_init(&Q);
279 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
280 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
285 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
286 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
287 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
290 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
291 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200294
295 cnt_restarts = 0;
296 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 ECP_PT_RESET(&R);
298 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
299 &u1, &grp.G, &u2, &Q, &ctx);
300 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 TEST_ASSERT(ret == 0);
303 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
304 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 TEST_ASSERT(cnt_restarts >= min_restarts);
307 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200308
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200309 /* Do we leak memory when aborting an operation?
310 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 if (min_restarts > 0) {
312 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
313 &u1, &grp.G, &u2, &Q, &ctx);
314 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200315 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200316
317exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 mbedtls_ecp_restart_free(&ctx);
319 mbedtls_ecp_group_free(&grp);
320 mbedtls_ecp_point_free(&R);
321 mbedtls_ecp_point_free(&Q);
322 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
323 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200324}
325/* END_CASE */
326
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100327/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
329 char *dB_str, char *xB_str, char *yB_str,
330 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100331{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 mbedtls_ecp_group grp;
333 mbedtls_ecp_point R;
334 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200335 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
338 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
339 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
340 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
347 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
348 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
349 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
350 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
351 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
352 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
353 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
356 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
357 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
358 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
359 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
360 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
361 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
362 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
363 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
364 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
367 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
368 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
369 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
370 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
371 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
372 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
373 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
374 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
375 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100376
Paul Bakkerbd51b262014-07-10 15:26:12 +0200377exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
379 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
380 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 +0100381}
Paul Bakker33b43f12013-08-20 11:48:36 +0200382/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100383
Paul Bakker33b43f12013-08-20 11:48:36 +0200384/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
386 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100387{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 mbedtls_ecp_group grp;
389 mbedtls_ecp_point R;
390 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200391 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
394 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
395 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
396 mbedtls_mpi_init(&xS);
397 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
404 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
405 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
406 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
407 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
410 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
411 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
412 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
415 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
416 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
417 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
420 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
421 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
422 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
425 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
426 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
427 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100428
Paul Bakkerbd51b262014-07-10 15:26:12 +0200429exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
431 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
432 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
433 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100434}
435/* END_CASE */
436
437/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438void ecp_test_mul(int id, data_t *n_hex,
439 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
440 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
441 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100442{
443 mbedtls_ecp_group grp;
444 mbedtls_ecp_point P, nP, R;
445 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200446 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
449 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
450 mbedtls_mpi_init(&n);
451 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
460 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
461 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
462 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
463 == 0);
464 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
465 == 0);
466 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
467 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
470 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
471 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 if (expected_ret == 0) {
474 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
475 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
476 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100477 }
478
479exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
481 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
482 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100483}
484/* END_CASE */
485
486/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900488{
489 mbedtls_ecp_group grp;
490 mbedtls_mpi d;
491 mbedtls_ecp_point Q;
492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
494 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
503 &mbedtls_test_rnd_zero_rand, NULL)
504 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900505
506exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
508 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900509}
510/* END_CASE */
511
Gilles Peskineca91ee42021-04-03 18:31:01 +0200512/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100513void ecp_muladd(int id,
514 data_t *u1_bin, data_t *P1_bin,
515 data_t *u2_bin, data_t *P2_bin,
516 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200517{
518 /* Compute R = u1 * P1 + u2 * P2 */
519 mbedtls_ecp_group grp;
520 mbedtls_ecp_point P1, P2, R;
521 mbedtls_mpi u1, u2;
522 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
523 size_t len;
524
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 mbedtls_ecp_group_init(&grp);
526 mbedtls_ecp_point_init(&P1);
527 mbedtls_ecp_point_init(&P2);
528 mbedtls_ecp_point_init(&R);
529 mbedtls_mpi_init(&u1);
530 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
533 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
534 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
535 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
536 P1_bin->x, P1_bin->len));
537 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
538 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
541 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
542 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
543 &len, actual_result, sizeof(actual_result)));
544 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 ASSERT_COMPARE(expected_result->x, expected_result->len,
547 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200548
549exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 mbedtls_ecp_group_free(&grp);
551 mbedtls_ecp_point_free(&P1);
552 mbedtls_ecp_point_free(&P2);
553 mbedtls_ecp_point_free(&R);
554 mbedtls_mpi_free(&u1);
555 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200556}
557/* END_CASE */
558
Jonas923d5792020-05-13 14:22:45 +0900559/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100560void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100561{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 mbedtls_ecp_group grp;
563 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
566 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
569 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
570 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100571
572 /*
573 * Store correct result before we touch N
574 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 TEST_ASSERT(grp.modp(&N) == 0);
578 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100579
580 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200581 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100582 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
584 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100585
Paul Bakkerbd51b262014-07-10 15:26:12 +0200586exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
588 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100589}
Paul Bakker33b43f12013-08-20 11:48:36 +0200590/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100591
Paul Bakker33b43f12013-08-20 11:48:36 +0200592/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100593void ecp_write_binary(int id, char *x, char *y, char *z, int format,
594 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100595{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_ecp_group grp;
597 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100598 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100599 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
608 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
609 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
612 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 if (ret == 0) {
615 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
616 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100617 }
618
Paul Bakkerbd51b262014-07-10 15:26:12 +0200619exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100621}
Paul Bakker33b43f12013-08-20 11:48:36 +0200622/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100623
Paul Bakker33b43f12013-08-20 11:48:36 +0200624/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100625void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
626 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100627{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 mbedtls_ecp_group grp;
629 mbedtls_ecp_point P;
630 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100631
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
634 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
639 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
640 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (ret == 0) {
645 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
646 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
647 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
648 TEST_ASSERT(P.Y.p == NULL);
649 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
650 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
651 } else {
652 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
653 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400656 /* (reading compressed format supported only for
657 * Short Weierstrass curves with prime p where p = 3 mod 4) */
658 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400660 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 mbedtls_mpi_free(&P.Y);
662 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
663 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
664 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400665 }
Janos Follath59b813c2019-02-13 10:44:06 +0000666 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100667 }
668
Paul Bakkerbd51b262014-07-10 15:26:12 +0200669exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
671 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100672}
Paul Bakker33b43f12013-08-20 11:48:36 +0200673/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100674
Paul Bakker33b43f12013-08-20 11:48:36 +0200675/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100676void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
677 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100678{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 mbedtls_ecp_group grp;
680 mbedtls_ecp_point P;
681 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100682 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100683
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
686 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
691 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
692 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 if (ret == 0) {
697 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
698 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
699 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
700 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100701 }
702
Paul Bakkerbd51b262014-07-10 15:26:12 +0200703exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
705 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100706}
Paul Bakker33b43f12013-08-20 11:48:36 +0200707/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100708
Paul Bakker33b43f12013-08-20 11:48:36 +0200709/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100710void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100711{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 mbedtls_ecp_group grp;
713 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100714 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100715 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100716 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 mbedtls_ecp_group_init(&grp);
719 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
724 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
725 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
726 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
727 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
728 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
729 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
730 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
733 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
734 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
735 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
736 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
737 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
738 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
739 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
742 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
743 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
744 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
745 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
746 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
747 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
750 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
751 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
752 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
753 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
754 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
755 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100756
Paul Bakkerbd51b262014-07-10 15:26:12 +0200757exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_ecp_group_free(&grp);
759 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100760}
Paul Bakker33b43f12013-08-20 11:48:36 +0200761/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100762
Paul Bakker33b43f12013-08-20 11:48:36 +0200763/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100764void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
765 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100766{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100768 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100769 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100770
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 TEST_ASSERT(ret == result);
776 if (ret == 0) {
777 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
778 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100779 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100780
Paul Bakkerbd51b262014-07-10 15:26:12 +0200781exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100783}
Paul Bakker33b43f12013-08-20 11:48:36 +0200784/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100785
Paul Bakker33b43f12013-08-20 11:48:36 +0200786/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100787void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100788{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100790 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100791 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100792 size_t len;
793 int ret;
794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 mbedtls_ecp_group_init(&grp1);
796 mbedtls_ecp_group_init(&grp2);
797 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
802 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
803 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 if (ret == 0) {
806 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
807 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100808 }
809
Paul Bakkerbd51b262014-07-10 15:26:12 +0200810exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 mbedtls_ecp_group_free(&grp1);
812 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100813}
Paul Bakker33b43f12013-08-20 11:48:36 +0200814/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100815
Valerio Setti46829482023-01-18 13:59:30 +0100816/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100817void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
818 char *P, char *A, char *B,
819 char *G_x, char *G_y, char *N,
820 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100821{
822 mbedtls_ecp_group grp, grp_read, grp_cpy;
823 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100824 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100825 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
826
827 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
828
829 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
830 const unsigned char *vbuf = buf;
831 size_t olen;
832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 mbedtls_ecp_group_init(&grp);
834 mbedtls_ecp_group_init(&grp_read);
835 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100836
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 mbedtls_mpi_init(&exp_P);
838 mbedtls_mpi_init(&exp_A);
839 mbedtls_mpi_init(&exp_B);
840 mbedtls_mpi_init(&exp_G_x);
841 mbedtls_mpi_init(&exp_G_y);
842 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100843
844 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
846 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
847 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
848 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
849 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
850 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100851
Werner Lewisc4afef72022-08-25 10:29:19 +0100852 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
854 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
855 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100856 }
857
Werner Lewise54046c2022-08-15 11:43:56 +0100858 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100860
861 // Compare group with expected parameters
862 // A is NULL for SECPxxxR1 curves
863 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
865 if (*A != 0) {
866 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
867 }
868 if (*B != 0) {
869 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
870 }
871 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
872 if (*G_y != 0) {
873 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
874 }
875 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100876
877 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 crv = mbedtls_ecp_curve_info_from_grp_id(id);
879 TEST_EQUAL(crv->grp_id, id);
880 TEST_EQUAL(crv->bit_size, bit_size);
881 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100882
883 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
885 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
886 TEST_EQUAL(crv_tls_id->grp_id, id);
887 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100888
Werner Lewisccae25b2022-09-20 10:00:07 +0100889 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
891 buf, sizeof(buf)),
892 0);
893 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
894 sizeof(ecparameters)),
895 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100896
897 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
899 0);
900 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100901 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
903 0);
904 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100905
906 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
Valerio Setti46829482023-01-18 13:59:30 +0100908#if defined(MBEDTLS_ECDH_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
Valerio Setti46829482023-01-18 13:59:30 +0100910#endif
911#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
913 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Valerio Setti46829482023-01-18 13:59:30 +0100914#endif
Werner Lewise54046c2022-08-15 11:43:56 +0100915
916 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
918 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100919
920 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 for (crv = mbedtls_ecp_curve_list();
922 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
923 crv->grp_id != (unsigned) id;
924 crv++) {
925 ;
926 }
927 TEST_EQUAL(crv->grp_id, id);
928 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100929 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 g_id++) {
931 ;
932 }
933 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100934
935exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
937 mbedtls_ecp_group_free(&grp_read);
938 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
939 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
940 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100941}
942/* END_CASE */
943
Paul Bakker33b43f12013-08-20 11:48:36 +0200944/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100945void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200946{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 mbedtls_ecp_group grp;
948 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 mbedtls_ecp_group_init(&grp);
951 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
954 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200957
Paul Bakkerbd51b262014-07-10 15:26:12 +0200958exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 mbedtls_ecp_group_free(&grp);
960 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200961}
Paul Bakker33b43f12013-08-20 11:48:36 +0200962/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200963
Paul Bakker33b43f12013-08-20 11:48:36 +0200964/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100965void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
966 int id, char *d, char *Qx, char *Qy,
967 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100968{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200970 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 mbedtls_ecp_keypair_init(&pub);
973 mbedtls_ecp_keypair_init(&prv);
974 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 if (id_pub != MBEDTLS_ECP_DP_NONE) {
977 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
978 }
979 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 if (id != MBEDTLS_ECP_DP_NONE) {
982 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
983 }
984 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
985 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
988 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100989
990exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 mbedtls_ecp_keypair_free(&pub);
992 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100993}
994/* END_CASE */
995
996/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100997void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100998{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 mbedtls_ecp_group grp;
1000 mbedtls_ecp_point Q;
1001 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001002 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 mbedtls_ecp_group_init(&grp);
1005 mbedtls_ecp_point_init(&Q);
1006 mbedtls_mpi_init(&d);
1007 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1012 &mbedtls_test_rnd_pseudo_rand,
1013 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1016 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001017
Paul Bakkerbd51b262014-07-10 15:26:12 +02001018exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 mbedtls_ecp_group_free(&grp);
1020 mbedtls_ecp_point_free(&Q);
1021 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001022}
Paul Bakker33b43f12013-08-20 11:48:36 +02001023/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001024
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001025/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001026void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001027{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001029 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 mbedtls_ecp_keypair_init(&key);
1032 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1035 &mbedtls_test_rnd_pseudo_rand,
1036 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1039 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001040
Paul Bakkerbd51b262014-07-10 15:26:12 +02001041exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001043}
1044/* END_CASE */
1045
Janos Follath171a7ef2019-02-15 16:17:45 +00001046/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001047void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001048{
1049 int ret = 0;
1050 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001051 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 mbedtls_ecp_keypair_init(&key);
1054 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1057 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 if (expected == 0) {
1060 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1061 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001062
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001064 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1067 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 ASSERT_COMPARE(in_key->x, in_key->len,
1070 buf, in_key->len);
1071 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001072 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001073 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1076 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001077
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1079 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1082 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001083
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 ASSERT_COMPARE(export1, in_key->len,
1085 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001086 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001087 }
1088
1089exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 mbedtls_ecp_keypair_free(&key);
1091 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001092}
1093/* END_CASE */
1094
Gilles Peskine618be2e2021-04-03 21:47:53 +02001095/* BEGIN_CASE depends_on:HAVE_FIX_NEGATIVE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001096void fix_negative(data_t *N_bin, int c, int bits)
Gilles Peskine618be2e2021-04-03 21:47:53 +02001097{
1098 mbedtls_mpi C, M, N;
1099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 mbedtls_mpi_init(&C);
1101 mbedtls_mpi_init(&M);
1102 mbedtls_mpi_init(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001103
Gilles Peskine392d1012021-04-09 15:46:51 +02001104 /* C = - c * 2^bits (positive since c is negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 TEST_EQUAL(0, mbedtls_mpi_lset(&C, -c));
1106 TEST_EQUAL(0, mbedtls_mpi_shift_l(&C, bits));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001107
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 TEST_EQUAL(0, mbedtls_mpi_read_binary(&N, N_bin->x, N_bin->len));
1109 TEST_EQUAL(0, mbedtls_mpi_grow(&N, C.n));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001110
Gilles Peskine392d1012021-04-09 15:46:51 +02001111 /* M = N - C = - ( C - N ) (expected result of fix_negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 TEST_EQUAL(0, mbedtls_mpi_sub_mpi(&M, &N, &C));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 mbedtls_ecp_fix_negative(&N, c, bits);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&N, &M));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001117
1118exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 mbedtls_mpi_free(&C);
1120 mbedtls_mpi_free(&M);
1121 mbedtls_mpi_free(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001122}
1123/* END_CASE */
1124
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001125/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +01001126void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001127{
1128 mbedtls_test_rnd_buf_info rnd_info;
1129 mbedtls_mpi d;
1130 int ret;
1131 uint8_t *actual = NULL;
1132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001134 rnd_info.buf = seed->x;
1135 rnd_info.length = seed->len;
1136 rnd_info.fallback_f_rng = NULL;
1137 rnd_info.fallback_p_rng = NULL;
1138
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1142 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001143
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001145 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 TEST_ASSERT(ret != 0);
1147 } else {
1148 TEST_EQUAL(ret, 0);
1149 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1150 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001151 /* Test the exact result. This assumes that the output of the
1152 * RNG is used in a specific way, which is overly constraining.
1153 * The advantage is that it's easier to test the expected properties
1154 * of the generated key:
1155 * - The most significant bit must be at a specific positions
1156 * (can be enforced by checking the bit-length).
1157 * - The least significant bits must have specific values
1158 * (can be enforced by checking these bits).
1159 * - Other bits must be random (by testing with different RNG outputs,
1160 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 ASSERT_COMPARE(expected->x, expected->len,
1162 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001163 }
1164
1165exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 mbedtls_free(actual);
1167 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001168}
1169/* END_CASE */
1170
Werner Lewis3b097392022-08-08 11:53:45 +01001171/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001172void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001173{
1174 mbedtls_ecp_group grp;
1175 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1176
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 mbedtls_ecp_group_init(&grp);
1178 mbedtls_ecp_point_init(&pt);
1179 mbedtls_ecp_point_init(&zero_pt);
1180 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001181
1182 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1184 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1185 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1186 P_bin->x, P_bin->len), 0);
1187 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1188 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001189
1190 // Test initialized 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, &zero_pt),
1195 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001196
1197 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1199 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1200 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1201 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1202 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001203
1204 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001205 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1206 P_bin->x, P_bin->len), 0);
1207 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1208 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1209 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1210 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001211
1212 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1214 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1215 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1216 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1217 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001218
1219 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1221 P_bin->x, P_bin->len), 0);
1222 mbedtls_ecp_point_free(&pt);
1223 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1224 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1225 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1226 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1227 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001228
1229exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 mbedtls_ecp_group_free(&grp);
1231 mbedtls_ecp_point_free(&pt);
1232 mbedtls_ecp_point_free(&zero_pt);
1233 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001234}
1235/* END_CASE */
1236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001238void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001239{
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001241}
Paul Bakker33b43f12013-08-20 11:48:36 +02001242/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001243
1244/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001245void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001246{
1247 mbedtls_ecp_keypair key;
1248 mbedtls_ecp_group export_grp;
1249 mbedtls_mpi export_d;
1250 mbedtls_ecp_point export_Q;
1251
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 mbedtls_ecp_group_init(&export_grp);
1253 mbedtls_ecp_group_init(&key.grp);
1254 mbedtls_mpi_init(&export_d);
1255 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001256
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 mbedtls_ecp_keypair_init(&key);
1258 if (invalid_grp == 0) {
1259 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1260 }
1261 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1262 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001263
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1265 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001266
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 if (expected_ret == 0) {
1268 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1269 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1270 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001271 }
1272
1273exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 mbedtls_ecp_keypair_free(&key);
1275 mbedtls_ecp_group_free(&export_grp);
1276 mbedtls_mpi_free(&export_d);
1277 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001278}
1279/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001280
1281/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001282void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001283{
1284 mbedtls_ecp_group grp;
1285 mbedtls_mpi expected_n;
1286
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 mbedtls_ecp_group_init(&grp);
1288 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1291 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001292
1293 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1295 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001296
Gilles Peskine449bd832023-01-11 14:50:10 +01001297 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001298
1299exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 mbedtls_ecp_group_free(&grp);
1301 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001302}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001303/* END_CASE */
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001304
1305/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1306void ecp_mod_p192_raw(char *input_N,
1307 char *input_X,
1308 char *result)
1309{
1310 mbedtls_mpi_uint *X = NULL;
1311 mbedtls_mpi_uint *N = NULL;
1312 mbedtls_mpi_uint *res = NULL;
1313 size_t limbs_X;
1314 size_t limbs_N;
1315 size_t limbs_res;
1316
1317 mbedtls_mpi_mod_modulus m;
1318 mbedtls_mpi_mod_modulus_init(&m);
1319
1320 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1321 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1322 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1323
1324 size_t limbs = limbs_N;
1325 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1326
1327 TEST_EQUAL(limbs_X, 2 * limbs);
1328 TEST_EQUAL(limbs_res, limbs);
1329
1330 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1331 &m, N, limbs,
1332 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1333
Gabor Mezei2038ce92023-01-31 14:33:12 +01001334 TEST_EQUAL(mbedtls_ecp_mod_p192_raw(X, limbs_X), 0);
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01001335 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 192);
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001336 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1337 ASSERT_COMPARE(X, bytes, res, bytes);
1338
1339exit:
1340 mbedtls_free(X);
1341 mbedtls_free(res);
1342
1343 mbedtls_mpi_mod_modulus_free(&m);
1344 mbedtls_free(N);
1345}
1346/* END_CASE */
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001347
1348/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1349void ecp_mod_p521_raw(char *input_N,
1350 char *input_X,
1351 char *result)
1352{
1353 mbedtls_mpi_uint *X = NULL;
1354 mbedtls_mpi_uint *N = NULL;
1355 mbedtls_mpi_uint *res = NULL;
1356 size_t limbs_X;
1357 size_t limbs_N;
1358 size_t limbs_res;
1359
1360 mbedtls_mpi_mod_modulus m;
1361 mbedtls_mpi_mod_modulus_init(&m);
1362
1363 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1364 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1365 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1366
1367 size_t limbs = limbs_N;
1368 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1369
1370 TEST_EQUAL(limbs_X, 2 * limbs - 1);
1371 TEST_EQUAL(limbs_res, limbs);
1372
1373 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1374 &m, N, limbs,
1375 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1376
Gabor Mezeib62ad5d2023-02-06 17:13:02 +01001377 TEST_EQUAL(mbedtls_ecp_mod_p521_raw(X, limbs_X), 0);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001378 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1379 ASSERT_COMPARE(X, bytes, res, bytes);
1380
1381exit:
1382 mbedtls_free(X);
1383 mbedtls_free(res);
1384
1385 mbedtls_mpi_mod_modulus_free(&m);
1386 mbedtls_free(N);
1387}
1388/* END_CASE */