blob: 96537c2b3bc3c4e6130fb5e6177efaab27648fa1 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/ecp.h"
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00003#include "ecp_invasive.h"
Werner Lewise54046c2022-08-15 11:43:56 +01004#include "mbedtls/ecdsa.h"
5#include "mbedtls/ecdh.h"
Paul Bakkerdbd443d2013-08-16 13:38:47 +02006
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01007#include "bignum_core.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +02008#include "ecp_invasive.h"
Gabor Mezeid8f67b92023-02-06 15:49:42 +01009#include "bignum_mod_raw_invasive.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +020010
11#if defined(MBEDTLS_TEST_HOOKS) && \
Gilles Peskine449bd832023-01-11 14:50:10 +010012 (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
13 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
14 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED))
Gilles Peskine618be2e2021-04-03 21:47:53 +020015#define HAVE_FIX_NEGATIVE
16#endif
17
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020018#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020019
Gilles Peskine449bd832023-01-11 14:50:10 +010020#define ECP_PT_RESET(x) \
21 mbedtls_ecp_point_free(x); \
22 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020023
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010024/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010025inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
26 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010027{
Gilles Peskine449bd832023-01-11 14:50:10 +010028 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010029 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010030 }
31 if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010032 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010033 }
34 if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010035 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010036 }
37 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010038 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010039 }
40 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010041 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010042 }
43 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010044 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010045 }
46 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010047 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010048 }
49 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010050 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010051 }
52 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010053 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010054 }
55 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010056 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010057 }
58 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010059 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010060 }
61 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010062 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010063 }
64 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010065 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010066 }
67 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010068 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010069 }
70 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010071 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010072 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010073
74 return 0;
75}
76
Paul Bakker33b43f12013-08-20 11:48:36 +020077/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010078
Paul Bakker33b43f12013-08-20 11:48:36 +020079/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080 * depends_on:MBEDTLS_ECP_C
Paul Bakker33b43f12013-08-20 11:48:36 +020081 * END_DEPENDENCIES
82 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010083
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010084/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010085void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000086{
87 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000088 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000089 int invalid_fmt = 42;
90 size_t olen;
91 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000092
Gilles Peskine449bd832023-01-11 14:50:10 +010093 mbedtls_ecp_group_init(&grp);
94 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020095
Gilles Peskine449bd832023-01-11 14:50:10 +010096 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
97 mbedtls_ecp_point_write_binary(&grp, &P,
98 invalid_fmt,
99 &olen,
100 buf, sizeof(buf)));
101 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
102 mbedtls_ecp_tls_write_point(&grp, &P,
103 invalid_fmt,
104 &olen,
105 buf,
106 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000107
108exit:
109 return;
110}
111/* END_CASE */
112
Paul Bakker33b43f12013-08-20 11:48:36 +0200113/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100114void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100115{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100117
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
119 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
120 by_name = mbedtls_ecp_curve_info_from_name(name);
121 TEST_ASSERT(by_id != NULL);
122 TEST_ASSERT(by_tls != NULL);
123 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 TEST_ASSERT(by_id == by_tls);
126 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100127
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 TEST_ASSERT(by_id->bit_size == size);
129 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
130 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100131}
132/* END_CASE */
133
134/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100135void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
136 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100137{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 mbedtls_ecp_group grp;
139 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 mbedtls_ecp_group_init(&grp);
142 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
147 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
148 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100151
Paul Bakkerbd51b262014-07-10 15:26:12 +0200152exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 mbedtls_ecp_group_free(&grp);
154 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100155}
156/* END_CASE */
157
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200158/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100159void ecp_test_vect_restart(int id,
160 char *dA_str, char *xA_str, char *yA_str,
161 char *dB_str, char *xZ_str, char *yZ_str,
162 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100163{
164 /*
165 * Test for early restart. Based on test vectors like ecp_test_vect(),
166 * but for the sake of simplicity only does half of each side. It's
167 * important to test both base point and random point, though, as memory
168 * management is different in each case.
169 *
170 * Don't try using too precise bounds for restarts as the exact number
171 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
172 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
173 * change in the future. A factor 2 is a minimum safety margin.
174 *
175 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100176 * - Random point mult: ~3250M
177 * - Cold base point mult: ~3300M
178 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100179 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100180 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100181 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200182 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100183 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200184 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100185 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
186 int cnt_restarts;
187 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200188 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 mbedtls_ecp_restart_init(&ctx);
191 mbedtls_ecp_group_init(&grp);
192 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
193 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
194 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
195 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 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(&dA, dA_str) == 0);
200 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
201 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
204 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
205 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100208
209 /* Base point case */
210 cnt_restarts = 0;
211 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 ECP_PT_RESET(&R);
213 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
214 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
215 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 TEST_ASSERT(ret == 0);
218 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
219 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 TEST_ASSERT(cnt_restarts >= min_restarts);
222 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100223
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100224 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100226 cnt_restarts = 0;
227 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 ECP_PT_RESET(&R);
229 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
230 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
231 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 TEST_ASSERT(ret == 0);
234 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
235 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 TEST_ASSERT(cnt_restarts >= min_restarts);
238 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100239
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200240 /* Do we leak memory when aborting an operation?
241 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if (min_restarts > 0) {
243 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
244 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
245 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200246 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100247
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100248exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 mbedtls_ecp_restart_free(&ctx);
250 mbedtls_ecp_group_free(&grp);
251 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
252 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
253 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100254}
255/* END_CASE */
256
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100257/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100258void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
259 char *u1_str, char *u2_str,
260 char *xQ_str, char *yQ_str,
261 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200262{
263 /*
264 * Compute R = u1 * G + u2 * Q
265 * (test vectors mostly taken from ECDSA intermediate results)
266 *
267 * See comments at the top of ecp_test_vect_restart()
268 */
269 mbedtls_ecp_restart_ctx ctx;
270 mbedtls_ecp_group grp;
271 mbedtls_ecp_point R, Q;
272 mbedtls_mpi u1, u2, xR, yR;
273 int cnt_restarts;
274 int ret;
275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 mbedtls_ecp_restart_init(&ctx);
277 mbedtls_ecp_group_init(&grp);
278 mbedtls_ecp_point_init(&R);
279 mbedtls_ecp_point_init(&Q);
280 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
281 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
286 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
287 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
288 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
291 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
292 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200295
296 cnt_restarts = 0;
297 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 ECP_PT_RESET(&R);
299 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
300 &u1, &grp.G, &u2, &Q, &ctx);
301 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 TEST_ASSERT(ret == 0);
304 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
305 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 TEST_ASSERT(cnt_restarts >= min_restarts);
308 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200309
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200310 /* Do we leak memory when aborting an operation?
311 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 if (min_restarts > 0) {
313 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
314 &u1, &grp.G, &u2, &Q, &ctx);
315 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200316 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200317
318exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 mbedtls_ecp_restart_free(&ctx);
320 mbedtls_ecp_group_free(&grp);
321 mbedtls_ecp_point_free(&R);
322 mbedtls_ecp_point_free(&Q);
323 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
324 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200325}
326/* END_CASE */
327
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100328/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100329void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
330 char *dB_str, char *xB_str, char *yB_str,
331 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100332{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_ecp_group grp;
334 mbedtls_ecp_point R;
335 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200336 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
339 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
340 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
341 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
348 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
349 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
350 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
351 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
352 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
353 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
354 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
357 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
358 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
359 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
360 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
361 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
362 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
363 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
364 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
365 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
368 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
369 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
370 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
371 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
372 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
373 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
374 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
375 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
376 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100377
Paul Bakkerbd51b262014-07-10 15:26:12 +0200378exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
380 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
381 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 +0100382}
Paul Bakker33b43f12013-08-20 11:48:36 +0200383/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100384
Paul Bakker33b43f12013-08-20 11:48:36 +0200385/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100386void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
387 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100388{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_ecp_group grp;
390 mbedtls_ecp_point R;
391 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200392 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
395 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
396 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
397 mbedtls_mpi_init(&xS);
398 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100403
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
405 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
406 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
407 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
408 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
411 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
412 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
413 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
416 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
417 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
418 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
421 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
422 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
423 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
426 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
427 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
428 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100429
Paul Bakkerbd51b262014-07-10 15:26:12 +0200430exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
432 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
433 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
434 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100435}
436/* END_CASE */
437
438/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100439void ecp_test_mul(int id, data_t *n_hex,
440 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
441 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
442 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100443{
444 mbedtls_ecp_group grp;
445 mbedtls_ecp_point P, nP, R;
446 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200447 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
450 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
451 mbedtls_mpi_init(&n);
452 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
461 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
462 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
463 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
464 == 0);
465 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
466 == 0);
467 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
468 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
471 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
472 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (expected_ret == 0) {
475 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
476 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
477 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100478 }
479
480exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
482 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
483 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100484}
485/* END_CASE */
486
487/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100488void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900489{
490 mbedtls_ecp_group grp;
491 mbedtls_mpi d;
492 mbedtls_ecp_point Q;
493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
495 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900500
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
504 &mbedtls_test_rnd_zero_rand, NULL)
505 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900506
507exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
509 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900510}
511/* END_CASE */
512
Gilles Peskineca91ee42021-04-03 18:31:01 +0200513/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100514void ecp_muladd(int id,
515 data_t *u1_bin, data_t *P1_bin,
516 data_t *u2_bin, data_t *P2_bin,
517 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200518{
519 /* Compute R = u1 * P1 + u2 * P2 */
520 mbedtls_ecp_group grp;
521 mbedtls_ecp_point P1, P2, R;
522 mbedtls_mpi u1, u2;
523 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
524 size_t len;
525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 mbedtls_ecp_group_init(&grp);
527 mbedtls_ecp_point_init(&P1);
528 mbedtls_ecp_point_init(&P2);
529 mbedtls_ecp_point_init(&R);
530 mbedtls_mpi_init(&u1);
531 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
534 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
535 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
536 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
537 P1_bin->x, P1_bin->len));
538 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
539 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
542 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
543 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
544 &len, actual_result, sizeof(actual_result)));
545 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 ASSERT_COMPARE(expected_result->x, expected_result->len,
548 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200549
550exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_ecp_group_free(&grp);
552 mbedtls_ecp_point_free(&P1);
553 mbedtls_ecp_point_free(&P2);
554 mbedtls_ecp_point_free(&R);
555 mbedtls_mpi_free(&u1);
556 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200557}
558/* END_CASE */
559
Jonas923d5792020-05-13 14:22:45 +0900560/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100561void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100562{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 mbedtls_ecp_group grp;
564 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
567 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
570 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
571 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100572
573 /*
574 * Store correct result before we touch N
575 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 TEST_ASSERT(grp.modp(&N) == 0);
579 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100580
581 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200582 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100583 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
585 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100586
Paul Bakkerbd51b262014-07-10 15:26:12 +0200587exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
589 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100590}
Paul Bakker33b43f12013-08-20 11:48:36 +0200591/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100592
Paul Bakker33b43f12013-08-20 11:48:36 +0200593/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100594void ecp_write_binary(int id, char *x, char *y, char *z, int format,
595 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100596{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_ecp_group grp;
598 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100599 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100600 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
609 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
610 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
613 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 if (ret == 0) {
616 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
617 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100618 }
619
Paul Bakkerbd51b262014-07-10 15:26:12 +0200620exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100622}
Paul Bakker33b43f12013-08-20 11:48:36 +0200623/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100624
Paul Bakker33b43f12013-08-20 11:48:36 +0200625/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100626void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
627 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100628{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 mbedtls_ecp_group grp;
630 mbedtls_ecp_point P;
631 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100632
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
635 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
640 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
641 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 if (ret == 0) {
646 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
647 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
648 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
649 TEST_ASSERT(P.Y.p == NULL);
650 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
651 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
652 } else {
653 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
654 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400657 /* (reading compressed format supported only for
658 * Short Weierstrass curves with prime p where p = 3 mod 4) */
659 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400661 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 mbedtls_mpi_free(&P.Y);
663 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
664 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
665 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400666 }
Janos Follath59b813c2019-02-13 10:44:06 +0000667 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100668 }
669
Paul Bakkerbd51b262014-07-10 15:26:12 +0200670exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
672 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100673}
Paul Bakker33b43f12013-08-20 11:48:36 +0200674/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100675
Paul Bakker33b43f12013-08-20 11:48:36 +0200676/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100677void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
678 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100679{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680 mbedtls_ecp_group grp;
681 mbedtls_ecp_point P;
682 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100683 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100684
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
687 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
692 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
693 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 if (ret == 0) {
698 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
699 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
700 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
701 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100702 }
703
Paul Bakkerbd51b262014-07-10 15:26:12 +0200704exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
706 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100707}
Paul Bakker33b43f12013-08-20 11:48:36 +0200708/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100709
Paul Bakker33b43f12013-08-20 11:48:36 +0200710/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100711void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100712{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 mbedtls_ecp_group grp;
714 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100715 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100716 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100717 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 mbedtls_ecp_group_init(&grp);
720 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
725 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
726 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
727 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
728 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
729 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
730 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
731 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
734 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
735 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
736 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
737 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
738 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
739 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
740 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
743 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
744 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
745 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
746 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
747 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
748 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
751 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
752 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
753 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
754 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
755 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
756 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100757
Paul Bakkerbd51b262014-07-10 15:26:12 +0200758exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 mbedtls_ecp_group_free(&grp);
760 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100761}
Paul Bakker33b43f12013-08-20 11:48:36 +0200762/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100763
Paul Bakker33b43f12013-08-20 11:48:36 +0200764/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100765void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
766 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100767{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100769 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100770 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 TEST_ASSERT(ret == result);
777 if (ret == 0) {
778 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
779 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100780 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100781
Paul Bakkerbd51b262014-07-10 15:26:12 +0200782exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100784}
Paul Bakker33b43f12013-08-20 11:48:36 +0200785/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100786
Paul Bakker33b43f12013-08-20 11:48:36 +0200787/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100789{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100791 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100792 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100793 size_t len;
794 int ret;
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 mbedtls_ecp_group_init(&grp1);
797 mbedtls_ecp_group_init(&grp2);
798 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
803 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
804 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100805
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 if (ret == 0) {
807 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
808 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100809 }
810
Paul Bakkerbd51b262014-07-10 15:26:12 +0200811exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 mbedtls_ecp_group_free(&grp1);
813 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100814}
Paul Bakker33b43f12013-08-20 11:48:36 +0200815/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100816
Valerio Setti46829482023-01-18 13:59:30 +0100817/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100818void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
819 char *P, char *A, char *B,
820 char *G_x, char *G_y, char *N,
821 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100822{
823 mbedtls_ecp_group grp, grp_read, grp_cpy;
824 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100825 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100826 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
827
828 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
829
830 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
831 const unsigned char *vbuf = buf;
832 size_t olen;
833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 mbedtls_ecp_group_init(&grp);
835 mbedtls_ecp_group_init(&grp_read);
836 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 mbedtls_mpi_init(&exp_P);
839 mbedtls_mpi_init(&exp_A);
840 mbedtls_mpi_init(&exp_B);
841 mbedtls_mpi_init(&exp_G_x);
842 mbedtls_mpi_init(&exp_G_y);
843 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100844
845 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
847 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
848 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
849 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
850 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
851 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100852
Werner Lewisc4afef72022-08-25 10:29:19 +0100853 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
855 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
856 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100857 }
858
Werner Lewise54046c2022-08-15 11:43:56 +0100859 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100861
862 // Compare group with expected parameters
863 // A is NULL for SECPxxxR1 curves
864 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
866 if (*A != 0) {
867 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
868 }
869 if (*B != 0) {
870 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
871 }
872 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
873 if (*G_y != 0) {
874 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
875 }
876 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100877
878 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 crv = mbedtls_ecp_curve_info_from_grp_id(id);
880 TEST_EQUAL(crv->grp_id, id);
881 TEST_EQUAL(crv->bit_size, bit_size);
882 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100883
884 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
886 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
887 TEST_EQUAL(crv_tls_id->grp_id, id);
888 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100889
Werner Lewisccae25b2022-09-20 10:00:07 +0100890 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
892 buf, sizeof(buf)),
893 0);
894 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
895 sizeof(ecparameters)),
896 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100897
898 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
900 0);
901 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100902 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
904 0);
905 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100906
907 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
Valerio Setti46829482023-01-18 13:59:30 +0100909#if defined(MBEDTLS_ECDH_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
Valerio Setti46829482023-01-18 13:59:30 +0100911#endif
912#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
914 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Valerio Setti46829482023-01-18 13:59:30 +0100915#endif
Werner Lewise54046c2022-08-15 11:43:56 +0100916
917 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
919 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100920
921 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 for (crv = mbedtls_ecp_curve_list();
923 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
924 crv->grp_id != (unsigned) id;
925 crv++) {
926 ;
927 }
928 TEST_EQUAL(crv->grp_id, id);
929 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100930 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 g_id++) {
932 ;
933 }
934 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100935
936exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
938 mbedtls_ecp_group_free(&grp_read);
939 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
940 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
941 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100942}
943/* END_CASE */
944
Paul Bakker33b43f12013-08-20 11:48:36 +0200945/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100946void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200947{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 mbedtls_ecp_group grp;
949 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 mbedtls_ecp_group_init(&grp);
952 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
955 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200958
Paul Bakkerbd51b262014-07-10 15:26:12 +0200959exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 mbedtls_ecp_group_free(&grp);
961 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200962}
Paul Bakker33b43f12013-08-20 11:48:36 +0200963/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200964
Paul Bakker33b43f12013-08-20 11:48:36 +0200965/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100966void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
967 int id, char *d, char *Qx, char *Qy,
968 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100969{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200971 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 mbedtls_ecp_keypair_init(&pub);
974 mbedtls_ecp_keypair_init(&prv);
975 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 if (id_pub != MBEDTLS_ECP_DP_NONE) {
978 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
979 }
980 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 if (id != MBEDTLS_ECP_DP_NONE) {
983 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
984 }
985 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
986 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
989 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100990
991exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 mbedtls_ecp_keypair_free(&pub);
993 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100994}
995/* END_CASE */
996
997/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100998void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100999{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001000 mbedtls_ecp_group grp;
1001 mbedtls_ecp_point Q;
1002 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001003 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 mbedtls_ecp_group_init(&grp);
1006 mbedtls_ecp_point_init(&Q);
1007 mbedtls_mpi_init(&d);
1008 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1013 &mbedtls_test_rnd_pseudo_rand,
1014 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001015
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1017 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001018
Paul Bakkerbd51b262014-07-10 15:26:12 +02001019exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 mbedtls_ecp_group_free(&grp);
1021 mbedtls_ecp_point_free(&Q);
1022 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001023}
Paul Bakker33b43f12013-08-20 11:48:36 +02001024/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001025
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001026/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001027void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001028{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001030 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 mbedtls_ecp_keypair_init(&key);
1033 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1036 &mbedtls_test_rnd_pseudo_rand,
1037 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1040 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001041
Paul Bakkerbd51b262014-07-10 15:26:12 +02001042exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001044}
1045/* END_CASE */
1046
Janos Follath171a7ef2019-02-15 16:17:45 +00001047/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001048void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001049{
1050 int ret = 0;
1051 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001052 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 mbedtls_ecp_keypair_init(&key);
1055 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1058 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 if (expected == 0) {
1061 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1062 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001063
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001065 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001066
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1068 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 ASSERT_COMPARE(in_key->x, in_key->len,
1071 buf, in_key->len);
1072 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001073 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001074 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1077 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001078
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1080 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001081
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1083 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001084
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 ASSERT_COMPARE(export1, in_key->len,
1086 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001087 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001088 }
1089
1090exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 mbedtls_ecp_keypair_free(&key);
1092 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001093}
1094/* END_CASE */
1095
Gilles Peskine618be2e2021-04-03 21:47:53 +02001096/* BEGIN_CASE depends_on:HAVE_FIX_NEGATIVE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001097void fix_negative(data_t *N_bin, int c, int bits)
Gilles Peskine618be2e2021-04-03 21:47:53 +02001098{
1099 mbedtls_mpi C, M, N;
1100
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 mbedtls_mpi_init(&C);
1102 mbedtls_mpi_init(&M);
1103 mbedtls_mpi_init(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001104
Gilles Peskine392d1012021-04-09 15:46:51 +02001105 /* C = - c * 2^bits (positive since c is negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 TEST_EQUAL(0, mbedtls_mpi_lset(&C, -c));
1107 TEST_EQUAL(0, mbedtls_mpi_shift_l(&C, bits));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001108
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 TEST_EQUAL(0, mbedtls_mpi_read_binary(&N, N_bin->x, N_bin->len));
1110 TEST_EQUAL(0, mbedtls_mpi_grow(&N, C.n));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001111
Gilles Peskine392d1012021-04-09 15:46:51 +02001112 /* M = N - C = - ( C - N ) (expected result of fix_negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 TEST_EQUAL(0, mbedtls_mpi_sub_mpi(&M, &N, &C));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001114
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 mbedtls_ecp_fix_negative(&N, c, bits);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001116
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&N, &M));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001118
1119exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 mbedtls_mpi_free(&C);
1121 mbedtls_mpi_free(&M);
1122 mbedtls_mpi_free(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001123}
1124/* END_CASE */
1125
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001126/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +01001127void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001128{
1129 mbedtls_test_rnd_buf_info rnd_info;
1130 mbedtls_mpi d;
1131 int ret;
1132 uint8_t *actual = NULL;
1133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001135 rnd_info.buf = seed->x;
1136 rnd_info.length = seed->len;
1137 rnd_info.fallback_f_rng = NULL;
1138 rnd_info.fallback_p_rng = NULL;
1139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1143 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001144
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001146 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 TEST_ASSERT(ret != 0);
1148 } else {
1149 TEST_EQUAL(ret, 0);
1150 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1151 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001152 /* Test the exact result. This assumes that the output of the
1153 * RNG is used in a specific way, which is overly constraining.
1154 * The advantage is that it's easier to test the expected properties
1155 * of the generated key:
1156 * - The most significant bit must be at a specific positions
1157 * (can be enforced by checking the bit-length).
1158 * - The least significant bits must have specific values
1159 * (can be enforced by checking these bits).
1160 * - Other bits must be random (by testing with different RNG outputs,
1161 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 ASSERT_COMPARE(expected->x, expected->len,
1163 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001164 }
1165
1166exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 mbedtls_free(actual);
1168 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001169}
1170/* END_CASE */
1171
Werner Lewis3b097392022-08-08 11:53:45 +01001172/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001173void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001174{
1175 mbedtls_ecp_group grp;
1176 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1177
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 mbedtls_ecp_group_init(&grp);
1179 mbedtls_ecp_point_init(&pt);
1180 mbedtls_ecp_point_init(&zero_pt);
1181 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001182
1183 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1185 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1186 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1187 P_bin->x, P_bin->len), 0);
1188 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1189 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001190
1191 // Test initialized point
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1193 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1194 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1195 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1196 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001197
1198 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1200 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1201 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1202 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1203 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001204
1205 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1207 P_bin->x, P_bin->len), 0);
1208 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1209 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1210 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1211 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001212
1213 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1215 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1216 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1217 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1218 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001219
1220 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1222 P_bin->x, P_bin->len), 0);
1223 mbedtls_ecp_point_free(&pt);
1224 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1225 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1226 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1227 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1228 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001229
1230exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 mbedtls_ecp_group_free(&grp);
1232 mbedtls_ecp_point_free(&pt);
1233 mbedtls_ecp_point_free(&zero_pt);
1234 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001235}
1236/* END_CASE */
1237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001239void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001240{
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001242}
Paul Bakker33b43f12013-08-20 11:48:36 +02001243/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001244
1245/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001246void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001247{
1248 mbedtls_ecp_keypair key;
1249 mbedtls_ecp_group export_grp;
1250 mbedtls_mpi export_d;
1251 mbedtls_ecp_point export_Q;
1252
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 mbedtls_ecp_group_init(&export_grp);
1254 mbedtls_ecp_group_init(&key.grp);
1255 mbedtls_mpi_init(&export_d);
1256 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001257
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 mbedtls_ecp_keypair_init(&key);
1259 if (invalid_grp == 0) {
1260 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1261 }
1262 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1263 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001264
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1266 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001267
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 if (expected_ret == 0) {
1269 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1270 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1271 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001272 }
1273
1274exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 mbedtls_ecp_keypair_free(&key);
1276 mbedtls_ecp_group_free(&export_grp);
1277 mbedtls_mpi_free(&export_d);
1278 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001279}
1280/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001281
1282/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001283void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001284{
1285 mbedtls_ecp_group grp;
1286 mbedtls_mpi expected_n;
1287
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 mbedtls_ecp_group_init(&grp);
1289 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001290
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1292 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001293
1294 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1296 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001297
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001299
1300exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 mbedtls_ecp_group_free(&grp);
1302 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001303}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001304/* END_CASE */
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001305
1306/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1307void ecp_mod_p192_raw(char *input_N,
1308 char *input_X,
1309 char *result)
1310{
1311 mbedtls_mpi_uint *X = NULL;
1312 mbedtls_mpi_uint *N = NULL;
1313 mbedtls_mpi_uint *res = NULL;
1314 size_t limbs_X;
1315 size_t limbs_N;
1316 size_t limbs_res;
1317
1318 mbedtls_mpi_mod_modulus m;
1319 mbedtls_mpi_mod_modulus_init(&m);
1320
1321 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1322 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1323 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1324
1325 size_t limbs = limbs_N;
1326 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1327
1328 TEST_EQUAL(limbs_X, 2 * limbs);
1329 TEST_EQUAL(limbs_res, limbs);
1330
1331 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1332 &m, N, limbs,
1333 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1334
Gabor Mezei2038ce92023-01-31 14:33:12 +01001335 TEST_EQUAL(mbedtls_ecp_mod_p192_raw(X, limbs_X), 0);
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01001336 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 192);
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001337 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1338 ASSERT_COMPARE(X, bytes, res, bytes);
1339
1340exit:
1341 mbedtls_free(X);
1342 mbedtls_free(res);
1343
1344 mbedtls_mpi_mod_modulus_free(&m);
1345 mbedtls_free(N);
1346}
1347/* END_CASE */
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001348
1349/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1350void ecp_mod_p521_raw(char *input_N,
1351 char *input_X,
1352 char *result)
1353{
1354 mbedtls_mpi_uint *X = NULL;
1355 mbedtls_mpi_uint *N = NULL;
1356 mbedtls_mpi_uint *res = NULL;
1357 size_t limbs_X;
1358 size_t limbs_N;
1359 size_t limbs_res;
1360
1361 mbedtls_mpi_mod_modulus m;
1362 mbedtls_mpi_mod_modulus_init(&m);
1363
1364 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1365 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1366 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1367
1368 size_t limbs = limbs_N;
1369 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1370
Gabor Mezeicf228702023-02-15 16:52:33 +01001371 TEST_EQUAL(limbs_X, 2 * limbs);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001372 TEST_EQUAL(limbs_res, limbs);
1373
1374 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1375 &m, N, limbs,
1376 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1377
Gabor Mezeib62ad5d2023-02-06 17:13:02 +01001378 TEST_EQUAL(mbedtls_ecp_mod_p521_raw(X, limbs_X), 0);
Gabor Mezei555b1f72023-02-15 17:13:20 +01001379 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 522);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001380 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1381 ASSERT_COMPARE(X, bytes, res, bytes);
1382
1383exit:
1384 mbedtls_free(X);
1385 mbedtls_free(res);
1386
1387 mbedtls_mpi_mod_modulus_free(&m);
1388 mbedtls_free(N);
1389}
1390/* END_CASE */
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00001391
1392/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1393void ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1394{
1395 int ret;
1396 mbedtls_mpi_mod_modulus m;
1397 mbedtls_mpi_mod_modulus_init(&m);
1398 mbedtls_mpi_uint *p = NULL;
1399 size_t p_limbs;
1400 size_t bytes;
1401
1402 TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1403
1404 ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1405 TEST_EQUAL(ret, iret);
1406
1407 if (ret == 0) {
1408
1409 /* Test for limb sizes */
1410 TEST_EQUAL(m.limbs, p_limbs);
1411 bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1412
1413 /* Test for validity of moduli by the presence of Montgomery consts */
1414
1415 TEST_ASSERT(m.rep.mont.mm != 0);
1416 TEST_ASSERT(m.rep.mont.rr != NULL);
1417
1418
1419 /* Compare output byte-by-byte */
1420 ASSERT_COMPARE(p, bytes, m.p, bytes);
1421
1422 /* Test for user free-ing allocated memory */
1423 mbedtls_mpi_mod_modulus_free(&m);
1424 }
1425
1426exit:
1427 mbedtls_mpi_mod_modulus_free(&m);
1428 mbedtls_free(p);
1429}
1430/* END_CASE */