blob: f5cb3df77a2b92ded2127b2ec1abed91aa8201d5 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/ecp.h"
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00003#include "ecp_invasive.h"
Werner Lewise54046c2022-08-15 11:43:56 +01004#include "mbedtls/ecdsa.h"
5#include "mbedtls/ecdh.h"
Paul Bakkerdbd443d2013-08-16 13:38:47 +02006
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01007#include "bignum_core.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +02008#include "ecp_invasive.h"
Gabor Mezeid8f67b92023-02-06 15:49:42 +01009#include "bignum_mod_raw_invasive.h"
Gilles Peskine618be2e2021-04-03 21:47:53 +020010
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020011#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020012
Gilles Peskine449bd832023-01-11 14:50:10 +010013#define ECP_PT_RESET(x) \
14 mbedtls_ecp_point_free(x); \
15 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020016
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010017/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010018inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
19 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010020{
Gilles Peskine449bd832023-01-11 14:50:10 +010021 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010022 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010023 }
24 if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010025 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010026 }
27 if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010028 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010029 }
30 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010031 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010032 }
33 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010034 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010035 }
36 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010037 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 }
39 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010040 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010041 }
42 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010043 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010044 }
45 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010046 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010047 }
48 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010049 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010050 }
51 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010052 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010053 }
54 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010055 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010056 }
57 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010058 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010059 }
60 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010061 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010062 }
63 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010064 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010065 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010066
67 return 0;
68}
69
Paul Bakker33b43f12013-08-20 11:48:36 +020070/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010071
Paul Bakker33b43f12013-08-20 11:48:36 +020072/* BEGIN_DEPENDENCIES
Valerio Setti0c477d32023-04-07 15:54:20 +020073 * depends_on:MBEDTLS_ECP_LIGHT
Paul Bakker33b43f12013-08-20 11:48:36 +020074 * END_DEPENDENCIES
75 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010076
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010077/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010078void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000079{
80 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000081 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000082 int invalid_fmt = 42;
83 size_t olen;
84 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000085
Gilles Peskine449bd832023-01-11 14:50:10 +010086 mbedtls_ecp_group_init(&grp);
87 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020088
Gilles Peskine449bd832023-01-11 14:50:10 +010089 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
90 mbedtls_ecp_point_write_binary(&grp, &P,
91 invalid_fmt,
92 &olen,
93 buf, sizeof(buf)));
94 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
95 mbedtls_ecp_tls_write_point(&grp, &P,
96 invalid_fmt,
97 &olen,
98 buf,
99 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000100
101exit:
102 return;
103}
104/* END_CASE */
105
Paul Bakker33b43f12013-08-20 11:48:36 +0200106/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100107void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100108{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
112 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
113 by_name = mbedtls_ecp_curve_info_from_name(name);
114 TEST_ASSERT(by_id != NULL);
115 TEST_ASSERT(by_tls != NULL);
116 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100117
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 TEST_ASSERT(by_id == by_tls);
119 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 TEST_ASSERT(by_id->bit_size == size);
122 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
123 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100124}
125/* END_CASE */
126
127/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100128void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
129 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100130{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 mbedtls_ecp_group grp;
132 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 mbedtls_ecp_group_init(&grp);
135 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
140 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
141 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100144
Paul Bakkerbd51b262014-07-10 15:26:12 +0200145exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 mbedtls_ecp_group_free(&grp);
147 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100148}
149/* END_CASE */
150
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200151/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100152void ecp_test_vect_restart(int id,
153 char *dA_str, char *xA_str, char *yA_str,
154 char *dB_str, char *xZ_str, char *yZ_str,
155 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100156{
157 /*
158 * Test for early restart. Based on test vectors like ecp_test_vect(),
159 * but for the sake of simplicity only does half of each side. It's
160 * important to test both base point and random point, though, as memory
161 * management is different in each case.
162 *
163 * Don't try using too precise bounds for restarts as the exact number
164 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
165 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
166 * change in the future. A factor 2 is a minimum safety margin.
167 *
168 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100169 * - Random point mult: ~3250M
170 * - Cold base point mult: ~3300M
171 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100172 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100173 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100174 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200175 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100176 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200177 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100178 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
179 int cnt_restarts;
180 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200181 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 mbedtls_ecp_restart_init(&ctx);
184 mbedtls_ecp_group_init(&grp);
185 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
186 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
187 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
188 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
193 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
194 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
197 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
198 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100201
202 /* Base point case */
203 cnt_restarts = 0;
204 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 ECP_PT_RESET(&R);
206 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
207 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
208 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 TEST_ASSERT(ret == 0);
211 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
212 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 TEST_ASSERT(cnt_restarts >= min_restarts);
215 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100216
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100217 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100219 cnt_restarts = 0;
220 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 ECP_PT_RESET(&R);
222 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
223 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
224 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 TEST_ASSERT(ret == 0);
227 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
228 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 TEST_ASSERT(cnt_restarts >= min_restarts);
231 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100232
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200233 /* Do we leak memory when aborting an operation?
234 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 if (min_restarts > 0) {
236 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
237 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
238 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200239 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100240
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100241exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 mbedtls_ecp_restart_free(&ctx);
243 mbedtls_ecp_group_free(&grp);
244 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
245 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
246 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100247}
248/* END_CASE */
249
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100250/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100251void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
252 char *u1_str, char *u2_str,
253 char *xQ_str, char *yQ_str,
254 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200255{
256 /*
257 * Compute R = u1 * G + u2 * Q
258 * (test vectors mostly taken from ECDSA intermediate results)
259 *
260 * See comments at the top of ecp_test_vect_restart()
261 */
262 mbedtls_ecp_restart_ctx ctx;
263 mbedtls_ecp_group grp;
264 mbedtls_ecp_point R, Q;
265 mbedtls_mpi u1, u2, xR, yR;
266 int cnt_restarts;
267 int ret;
268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 mbedtls_ecp_restart_init(&ctx);
270 mbedtls_ecp_group_init(&grp);
271 mbedtls_ecp_point_init(&R);
272 mbedtls_ecp_point_init(&Q);
273 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
274 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200277
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
279 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
280 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
281 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
284 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
285 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200288
289 cnt_restarts = 0;
290 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 ECP_PT_RESET(&R);
292 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
293 &u1, &grp.G, &u2, &Q, &ctx);
294 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 TEST_ASSERT(ret == 0);
297 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
298 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200299
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 TEST_ASSERT(cnt_restarts >= min_restarts);
301 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200302
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200303 /* Do we leak memory when aborting an operation?
304 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 if (min_restarts > 0) {
306 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
307 &u1, &grp.G, &u2, &Q, &ctx);
308 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200309 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200310
311exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 mbedtls_ecp_restart_free(&ctx);
313 mbedtls_ecp_group_free(&grp);
314 mbedtls_ecp_point_free(&R);
315 mbedtls_ecp_point_free(&Q);
316 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
317 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200318}
319/* END_CASE */
320
Valerio Setti0c477d32023-04-07 15:54:20 +0200321/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100322void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
323 char *dB_str, char *xB_str, char *yB_str,
324 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100325{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 mbedtls_ecp_group grp;
327 mbedtls_ecp_point R;
328 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200329 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
332 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
333 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
334 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
341 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
342 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
343 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
344 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
345 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
346 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
347 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
350 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
351 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
352 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
353 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
354 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
355 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
356 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
357 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
358 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
361 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
362 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
363 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
364 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
365 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
366 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
367 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
368 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
369 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100370
Paul Bakkerbd51b262014-07-10 15:26:12 +0200371exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
373 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
374 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 +0100375}
Paul Bakker33b43f12013-08-20 11:48:36 +0200376/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100377
Valerio Setti0c477d32023-04-07 15:54:20 +0200378/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100379void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
380 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100381{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382 mbedtls_ecp_group grp;
383 mbedtls_ecp_point R;
384 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200385 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
388 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
389 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
390 mbedtls_mpi_init(&xS);
391 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
398 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
399 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
400 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
401 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
404 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
405 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
406 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
409 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
410 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
411 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
414 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
415 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
416 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
419 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
420 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
421 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100422
Paul Bakkerbd51b262014-07-10 15:26:12 +0200423exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
425 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
426 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
427 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100428}
429/* END_CASE */
430
Valerio Setti0c477d32023-04-07 15:54:20 +0200431/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100432void ecp_test_mul(int id, data_t *n_hex,
433 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
434 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
435 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100436{
437 mbedtls_ecp_group grp;
438 mbedtls_ecp_point P, nP, R;
439 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200440 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
443 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
444 mbedtls_mpi_init(&n);
445 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
454 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
455 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
456 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
457 == 0);
458 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
459 == 0);
460 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
461 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100462
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
464 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
465 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 if (expected_ret == 0) {
468 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
469 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
470 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100471 }
472
473exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
475 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
476 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100477}
478/* END_CASE */
479
Valerio Setti0c477d32023-04-07 15:54:20 +0200480/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100481void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900482{
483 mbedtls_ecp_group grp;
484 mbedtls_mpi d;
485 mbedtls_ecp_point Q;
486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
488 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
497 &mbedtls_test_rnd_zero_rand, NULL)
498 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900499
500exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
502 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900503}
504/* END_CASE */
505
Valerio Setti0c477d32023-04-07 15:54:20 +0200506/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100507void ecp_muladd(int id,
508 data_t *u1_bin, data_t *P1_bin,
509 data_t *u2_bin, data_t *P2_bin,
510 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200511{
512 /* Compute R = u1 * P1 + u2 * P2 */
513 mbedtls_ecp_group grp;
514 mbedtls_ecp_point P1, P2, R;
515 mbedtls_mpi u1, u2;
516 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
517 size_t len;
518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 mbedtls_ecp_group_init(&grp);
520 mbedtls_ecp_point_init(&P1);
521 mbedtls_ecp_point_init(&P2);
522 mbedtls_ecp_point_init(&R);
523 mbedtls_mpi_init(&u1);
524 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
527 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
528 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
529 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
530 P1_bin->x, P1_bin->len));
531 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
532 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
535 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
536 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
537 &len, actual_result, sizeof(actual_result)));
538 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 ASSERT_COMPARE(expected_result->x, expected_result->len,
541 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200542
543exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 mbedtls_ecp_group_free(&grp);
545 mbedtls_ecp_point_free(&P1);
546 mbedtls_ecp_point_free(&P2);
547 mbedtls_ecp_point_free(&R);
548 mbedtls_mpi_free(&u1);
549 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200550}
551/* END_CASE */
552
Jonas923d5792020-05-13 14:22:45 +0900553/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100554void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100555{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_ecp_group grp;
557 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
560 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
563 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
564 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100565
566 /*
567 * Store correct result before we touch N
568 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 TEST_ASSERT(grp.modp(&N) == 0);
572 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100573
574 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200575 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100576 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
578 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100579
Paul Bakkerbd51b262014-07-10 15:26:12 +0200580exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
582 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100583}
Paul Bakker33b43f12013-08-20 11:48:36 +0200584/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100585
Paul Bakker33b43f12013-08-20 11:48:36 +0200586/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100587void ecp_write_binary(int id, char *x, char *y, char *z, int format,
588 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100589{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_ecp_group grp;
591 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100592 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100593 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100596
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
602 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
603 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
606 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 if (ret == 0) {
609 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
610 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100611 }
612
Paul Bakkerbd51b262014-07-10 15:26:12 +0200613exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100615}
Paul Bakker33b43f12013-08-20 11:48:36 +0200616/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100617
Paul Bakker33b43f12013-08-20 11:48:36 +0200618/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100619void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
620 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100621{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_ecp_group grp;
623 mbedtls_ecp_point P;
624 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100625
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
628 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
633 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
634 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (ret == 0) {
639 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
640 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
641 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
642 TEST_ASSERT(P.Y.p == NULL);
643 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
644 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
645 } else {
646 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
647 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400650 /* (reading compressed format supported only for
651 * Short Weierstrass curves with prime p where p = 3 mod 4) */
652 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400654 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 mbedtls_mpi_free(&P.Y);
656 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
657 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
658 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400659 }
Janos Follath59b813c2019-02-13 10:44:06 +0000660 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100661 }
662
Paul Bakkerbd51b262014-07-10 15:26:12 +0200663exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
665 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100666}
Paul Bakker33b43f12013-08-20 11:48:36 +0200667/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100668
Paul Bakker33b43f12013-08-20 11:48:36 +0200669/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100670void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
671 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100672{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 mbedtls_ecp_group grp;
674 mbedtls_ecp_point P;
675 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100676 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100677
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
680 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
685 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
686 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 if (ret == 0) {
691 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
692 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
693 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
694 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100695 }
696
Paul Bakkerbd51b262014-07-10 15:26:12 +0200697exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
699 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100700}
Paul Bakker33b43f12013-08-20 11:48:36 +0200701/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100702
Paul Bakker33b43f12013-08-20 11:48:36 +0200703/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100704void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100705{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 mbedtls_ecp_group grp;
707 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100708 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100709 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100710 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 mbedtls_ecp_group_init(&grp);
713 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
718 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
719 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
720 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
721 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
722 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
723 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
724 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
727 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
728 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
729 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
730 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
731 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
732 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
733 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
736 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
737 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
738 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
739 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
740 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
741 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
744 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
745 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
746 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
747 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
748 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
749 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100750
Paul Bakkerbd51b262014-07-10 15:26:12 +0200751exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 mbedtls_ecp_group_free(&grp);
753 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100754}
Paul Bakker33b43f12013-08-20 11:48:36 +0200755/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100756
Paul Bakker33b43f12013-08-20 11:48:36 +0200757/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
759 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100760{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100762 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100763 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 TEST_ASSERT(ret == result);
770 if (ret == 0) {
771 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
772 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100773 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100774
Paul Bakkerbd51b262014-07-10 15:26:12 +0200775exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100777}
Paul Bakker33b43f12013-08-20 11:48:36 +0200778/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100779
Paul Bakker33b43f12013-08-20 11:48:36 +0200780/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100781void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100782{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100784 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100785 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100786 size_t len;
787 int ret;
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 mbedtls_ecp_group_init(&grp1);
790 mbedtls_ecp_group_init(&grp2);
791 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
796 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
797 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 if (ret == 0) {
800 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
801 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100802 }
803
Paul Bakkerbd51b262014-07-10 15:26:12 +0200804exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 mbedtls_ecp_group_free(&grp1);
806 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100807}
Paul Bakker33b43f12013-08-20 11:48:36 +0200808/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100809
Valerio Setti46829482023-01-18 13:59:30 +0100810/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100811void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
812 char *P, char *A, char *B,
813 char *G_x, char *G_y, char *N,
814 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100815{
816 mbedtls_ecp_group grp, grp_read, grp_cpy;
817 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100818 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100819 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
820
821 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
822
823 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
824 const unsigned char *vbuf = buf;
825 size_t olen;
826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 mbedtls_ecp_group_init(&grp);
828 mbedtls_ecp_group_init(&grp_read);
829 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 mbedtls_mpi_init(&exp_P);
832 mbedtls_mpi_init(&exp_A);
833 mbedtls_mpi_init(&exp_B);
834 mbedtls_mpi_init(&exp_G_x);
835 mbedtls_mpi_init(&exp_G_y);
836 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100837
838 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
840 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
841 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
842 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
843 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
844 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100845
Werner Lewisc4afef72022-08-25 10:29:19 +0100846 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
848 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
849 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100850 }
851
Werner Lewise54046c2022-08-15 11:43:56 +0100852 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100854
855 // Compare group with expected parameters
856 // A is NULL for SECPxxxR1 curves
857 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
859 if (*A != 0) {
860 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
861 }
862 if (*B != 0) {
863 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
864 }
865 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
866 if (*G_y != 0) {
867 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
868 }
869 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100870
871 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 crv = mbedtls_ecp_curve_info_from_grp_id(id);
873 TEST_EQUAL(crv->grp_id, id);
874 TEST_EQUAL(crv->bit_size, bit_size);
875 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100876
877 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
879 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
880 TEST_EQUAL(crv_tls_id->grp_id, id);
881 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100882
Werner Lewisccae25b2022-09-20 10:00:07 +0100883 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
885 buf, sizeof(buf)),
886 0);
887 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
888 sizeof(ecparameters)),
889 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100890
891 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
893 0);
894 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100895 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
897 0);
898 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100899
900 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
Valerio Setti46829482023-01-18 13:59:30 +0100902#if defined(MBEDTLS_ECDH_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
Valerio Setti46829482023-01-18 13:59:30 +0100904#endif
905#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
907 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Valerio Setti46829482023-01-18 13:59:30 +0100908#endif
Werner Lewise54046c2022-08-15 11:43:56 +0100909
910 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
912 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100913
914 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 for (crv = mbedtls_ecp_curve_list();
916 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
917 crv->grp_id != (unsigned) id;
918 crv++) {
919 ;
920 }
921 TEST_EQUAL(crv->grp_id, id);
922 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100923 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 g_id++) {
925 ;
926 }
927 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100928
929exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
931 mbedtls_ecp_group_free(&grp_read);
932 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
933 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
934 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100935}
936/* END_CASE */
937
Paul Bakker33b43f12013-08-20 11:48:36 +0200938/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100939void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200940{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_ecp_group grp;
942 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 mbedtls_ecp_group_init(&grp);
945 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
948 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200951
Paul Bakkerbd51b262014-07-10 15:26:12 +0200952exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 mbedtls_ecp_group_free(&grp);
954 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200955}
Paul Bakker33b43f12013-08-20 11:48:36 +0200956/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200957
Valerio Setti0c477d32023-04-07 15:54:20 +0200958/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100959void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
960 int id, char *d, char *Qx, char *Qy,
961 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100962{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200964 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 mbedtls_ecp_keypair_init(&pub);
967 mbedtls_ecp_keypair_init(&prv);
968 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 if (id_pub != MBEDTLS_ECP_DP_NONE) {
971 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
972 }
973 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 if (id != MBEDTLS_ECP_DP_NONE) {
976 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
977 }
978 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
979 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
982 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100983
984exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 mbedtls_ecp_keypair_free(&pub);
986 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100987}
988/* END_CASE */
989
Valerio Setti0c477d32023-04-07 15:54:20 +0200990/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100991void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100992{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_ecp_group grp;
994 mbedtls_ecp_point Q;
995 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200996 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100997
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 mbedtls_ecp_group_init(&grp);
999 mbedtls_ecp_point_init(&Q);
1000 mbedtls_mpi_init(&d);
1001 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1006 &mbedtls_test_rnd_pseudo_rand,
1007 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1010 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001011
Paul Bakkerbd51b262014-07-10 15:26:12 +02001012exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 mbedtls_ecp_group_free(&grp);
1014 mbedtls_ecp_point_free(&Q);
1015 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001016}
Paul Bakker33b43f12013-08-20 11:48:36 +02001017/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001018
Valerio Setti0c477d32023-04-07 15:54:20 +02001019/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +01001020void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001021{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001023 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 mbedtls_ecp_keypair_init(&key);
1026 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1029 &mbedtls_test_rnd_pseudo_rand,
1030 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1033 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001034
Paul Bakkerbd51b262014-07-10 15:26:12 +02001035exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001037}
1038/* END_CASE */
1039
Janos Follath171a7ef2019-02-15 16:17:45 +00001040/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001041void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001042{
1043 int ret = 0;
1044 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001045 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 mbedtls_ecp_keypair_init(&key);
1048 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1051 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if (expected == 0) {
1054 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1055 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001058 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1061 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001062
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 ASSERT_COMPARE(in_key->x, in_key->len,
1064 buf, in_key->len);
1065 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001066 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001067 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1070 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001071
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1073 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1076 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001077
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 ASSERT_COMPARE(export1, in_key->len,
1079 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001080 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001081 }
1082
1083exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 mbedtls_ecp_keypair_free(&key);
1085 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001086}
1087/* END_CASE */
1088
Valerio Setti0c477d32023-04-07 15:54:20 +02001089/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBBEDTLS_ECP_C */
Gilles Peskine449bd832023-01-11 14:50:10 +01001090void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001091{
1092 mbedtls_test_rnd_buf_info rnd_info;
1093 mbedtls_mpi d;
1094 int ret;
1095 uint8_t *actual = NULL;
1096
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001098 rnd_info.buf = seed->x;
1099 rnd_info.length = seed->len;
1100 rnd_info.fallback_f_rng = NULL;
1101 rnd_info.fallback_p_rng = NULL;
1102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001104
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1106 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001107
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001109 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 TEST_ASSERT(ret != 0);
1111 } else {
1112 TEST_EQUAL(ret, 0);
1113 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1114 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001115 /* Test the exact result. This assumes that the output of the
1116 * RNG is used in a specific way, which is overly constraining.
1117 * The advantage is that it's easier to test the expected properties
1118 * of the generated key:
1119 * - The most significant bit must be at a specific positions
1120 * (can be enforced by checking the bit-length).
1121 * - The least significant bits must have specific values
1122 * (can be enforced by checking these bits).
1123 * - Other bits must be random (by testing with different RNG outputs,
1124 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 ASSERT_COMPARE(expected->x, expected->len,
1126 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001127 }
1128
1129exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 mbedtls_free(actual);
1131 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001132}
1133/* END_CASE */
1134
Werner Lewis3b097392022-08-08 11:53:45 +01001135/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001136void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001137{
1138 mbedtls_ecp_group grp;
1139 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 mbedtls_ecp_group_init(&grp);
1142 mbedtls_ecp_point_init(&pt);
1143 mbedtls_ecp_point_init(&zero_pt);
1144 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001145
1146 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1148 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1149 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1150 P_bin->x, P_bin->len), 0);
1151 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1152 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001153
1154 // Test initialized point
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1156 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1157 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1158 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1159 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001160
1161 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1163 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1164 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1165 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1166 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001167
1168 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1170 P_bin->x, P_bin->len), 0);
1171 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1172 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1173 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1174 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001175
1176 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1178 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1179 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1180 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1181 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001182
1183 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1185 P_bin->x, P_bin->len), 0);
1186 mbedtls_ecp_point_free(&pt);
1187 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1188 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1189 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1190 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1191 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001192
1193exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001194 mbedtls_ecp_group_free(&grp);
1195 mbedtls_ecp_point_free(&pt);
1196 mbedtls_ecp_point_free(&zero_pt);
1197 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001198}
1199/* END_CASE */
1200
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001201/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001202void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001203{
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001205}
Paul Bakker33b43f12013-08-20 11:48:36 +02001206/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001207
1208/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001209void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001210{
1211 mbedtls_ecp_keypair key;
1212 mbedtls_ecp_group export_grp;
1213 mbedtls_mpi export_d;
1214 mbedtls_ecp_point export_Q;
1215
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 mbedtls_ecp_group_init(&export_grp);
1217 mbedtls_ecp_group_init(&key.grp);
1218 mbedtls_mpi_init(&export_d);
1219 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001220
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 mbedtls_ecp_keypair_init(&key);
1222 if (invalid_grp == 0) {
1223 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1224 }
1225 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1226 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001227
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1229 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 if (expected_ret == 0) {
1232 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1233 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1234 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001235 }
1236
1237exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 mbedtls_ecp_keypair_free(&key);
1239 mbedtls_ecp_group_free(&export_grp);
1240 mbedtls_mpi_free(&export_d);
1241 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001242}
1243/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001244
1245/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001246void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001247{
1248 mbedtls_ecp_group grp;
1249 mbedtls_mpi expected_n;
1250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 mbedtls_ecp_group_init(&grp);
1252 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001253
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1255 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001256
1257 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1259 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001260
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001262
1263exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 mbedtls_ecp_group_free(&grp);
1265 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001266}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001267/* END_CASE */
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001268
Minos Galanakis6d2ee702023-04-12 09:14:29 +01001269/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
Minos Galanakis13586482023-03-21 12:08:37 +00001270void ecp_mod_p_generic_raw(int curve_id,
1271 char *input_N,
1272 char *input_X,
1273 char *result)
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001274{
1275 mbedtls_mpi_uint *X = NULL;
1276 mbedtls_mpi_uint *N = NULL;
1277 mbedtls_mpi_uint *res = NULL;
1278 size_t limbs_X;
1279 size_t limbs_N;
1280 size_t limbs_res;
1281
Minos Galanakis13586482023-03-21 12:08:37 +00001282 size_t bytes;
1283 size_t limbs;
1284 size_t curve_bits;
1285 int (*curve_func)(mbedtls_mpi_uint *X, size_t X_limbs);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001286
1287 mbedtls_mpi_mod_modulus m;
1288 mbedtls_mpi_mod_modulus_init(&m);
1289
1290 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1291 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1292 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
Minos Galanakis13586482023-03-21 12:08:37 +00001293 bytes = limbs_N * sizeof(mbedtls_mpi_uint);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001294
Minos Galanakis13586482023-03-21 12:08:37 +00001295 switch (curve_id) {
1296#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
1297 case MBEDTLS_ECP_DP_SECP192R1:
1298 limbs = 2 * limbs_N;
1299 curve_bits = 192;
1300 curve_func = &mbedtls_ecp_mod_p192_raw;
1301 break;
1302#endif
1303#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
1304 case MBEDTLS_ECP_DP_SECP224R1:
1305 limbs = 448 / biL;
1306 curve_bits = 224;
1307 curve_func = &mbedtls_ecp_mod_p224_raw;
1308 break;
1309#endif
1310#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
1311 case MBEDTLS_ECP_DP_SECP256R1:
1312 limbs = 2 * limbs_N;
1313 curve_bits = 256;
1314 curve_func = &mbedtls_ecp_mod_p256_raw;
1315 break;
1316#endif
1317#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
1318 case MBEDTLS_ECP_DP_SECP384R1:
1319 limbs = 2 * limbs_N;
1320 curve_bits = 384;
1321 curve_func = &mbedtls_ecp_mod_p384_raw;
1322 break;
1323#endif
1324#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
1325 case MBEDTLS_ECP_DP_SECP521R1:
1326 limbs = 2 * limbs_N;
1327 curve_bits = 522;
1328 curve_func = &mbedtls_ecp_mod_p521_raw;
1329 break;
1330#endif
1331 default:
1332 mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__);
1333 goto exit;
1334 }
Gabor Mezeif65a0592023-02-14 18:26:36 +01001335
Minos Galanakis13586482023-03-21 12:08:37 +00001336 TEST_EQUAL(limbs_X, limbs);
1337 TEST_EQUAL(limbs_res, limbs_N);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001338
1339 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
Minos Galanakis13586482023-03-21 12:08:37 +00001340 &m, N, limbs_N,
Minos Galanakis6d2ee702023-04-12 09:14:29 +01001341 MBEDTLS_MPI_MOD_REP_OPT_RED), 0);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001342
Minos Galanakis13586482023-03-21 12:08:37 +00001343 TEST_EQUAL((*curve_func)(X, limbs_X), 0);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001344
Minos Galanakis13586482023-03-21 12:08:37 +00001345 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001346 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1347 ASSERT_COMPARE(X, bytes, res, bytes);
1348
1349exit:
1350 mbedtls_free(X);
1351 mbedtls_free(res);
1352
1353 mbedtls_mpi_mod_modulus_free(&m);
1354 mbedtls_free(N);
1355}
1356/* END_CASE */
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00001357
Gabor Mezeib86ead32023-04-11 15:43:12 +02001358/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP192K1_ENABLED */
1359void ecp_mod_p192k1(char *input_N,
1360 char *input_X,
1361 char *result)
1362{
1363 mbedtls_mpi X;
1364 mbedtls_mpi N;
1365 mbedtls_mpi res;
Gabor Mezeib86ead32023-04-11 15:43:12 +02001366
1367 mbedtls_mpi_init(&X);
1368 mbedtls_mpi_init(&N);
1369 mbedtls_mpi_init(&res);
1370
1371 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
1372 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
1373 TEST_EQUAL(mbedtls_test_read_mpi(&res, result), 0);
1374
Gabor Mezeib70f5f12023-04-13 13:12:00 +02001375 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
1376 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
1377 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
Gabor Mezeib86ead32023-04-11 15:43:12 +02001378
Gabor Mezei00c9c7a2023-04-13 13:13:14 +02001379 size_t limbs = N.n;
Gabor Mezeib86ead32023-04-11 15:43:12 +02001380 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1381
Gabor Mezei00c9c7a2023-04-13 13:13:14 +02001382 TEST_EQUAL(X.n, 2 * limbs);
1383 TEST_EQUAL(res.n, limbs);
Gabor Mezeib86ead32023-04-11 15:43:12 +02001384
1385 TEST_EQUAL(mbedtls_ecp_mod_p192k1(&X), 0);
1386 TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
Gabor Mezei00c9c7a2023-04-13 13:13:14 +02001387 TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 192);
Gabor Mezeib86ead32023-04-11 15:43:12 +02001388 ASSERT_COMPARE(X.p, bytes, res.p, bytes);
1389
1390exit:
1391 mbedtls_mpi_free(&X);
1392 mbedtls_mpi_free(&N);
1393 mbedtls_mpi_free(&res);
1394}
1395/* END_CASE */
1396
Minos Galanakise5dab972023-04-11 16:42:06 +01001397/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP224K1_ENABLED */
1398void ecp_mod_p224k1(char *input_N,
1399 char *input_X,
1400 char *result)
1401{
1402 mbedtls_mpi X;
Minos Galanakis357b9e12023-04-18 11:39:11 +01001403 mbedtls_mpi N;
1404 mbedtls_mpi res;
Minos Galanakise5dab972023-04-11 16:42:06 +01001405
Minos Galanakise5dab972023-04-11 16:42:06 +01001406 mbedtls_mpi_init(&X);
Minos Galanakis357b9e12023-04-18 11:39:11 +01001407 mbedtls_mpi_init(&N);
1408 mbedtls_mpi_init(&res);
Minos Galanakise5dab972023-04-11 16:42:06 +01001409
Minos Galanakis357b9e12023-04-18 11:39:11 +01001410 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
1411 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
1412 TEST_EQUAL(mbedtls_test_read_mpi(&res, result), 0);
Minos Galanakise5dab972023-04-11 16:42:06 +01001413
Minos Galanakis357b9e12023-04-18 11:39:11 +01001414 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
1415 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
1416 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
1417
1418 size_t limbs = N.n;
Minos Galanakise5dab972023-04-11 16:42:06 +01001419 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1420
Minos Galanakise5dab972023-04-11 16:42:06 +01001421 TEST_LE_U(X.n, 448 / biL);
Minos Galanakis357b9e12023-04-18 11:39:11 +01001422 TEST_EQUAL(res.n, limbs);
Minos Galanakise5dab972023-04-11 16:42:06 +01001423
1424 TEST_EQUAL(mbedtls_ecp_mod_p224k1(&X), 0);
Minos Galanakis357b9e12023-04-18 11:39:11 +01001425 TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
Minos Galanakise5dab972023-04-11 16:42:06 +01001426 TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 224);
Minos Galanakis357b9e12023-04-18 11:39:11 +01001427 ASSERT_COMPARE(X.p, bytes, res.p, bytes);
Minos Galanakise5dab972023-04-11 16:42:06 +01001428
1429exit:
1430 mbedtls_mpi_free(&X);
Minos Galanakis357b9e12023-04-18 11:39:11 +01001431 mbedtls_mpi_free(&N);
1432 mbedtls_mpi_free(&res);
Minos Galanakise5dab972023-04-11 16:42:06 +01001433}
1434/* END_CASE */
1435
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001436/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP256K1_ENABLED */
1437void ecp_mod_p256k1(char *input_N,
1438 char *input_X,
1439 char *result)
1440{
1441 mbedtls_mpi X;
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001442 mbedtls_mpi N;
1443 mbedtls_mpi res;
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001444
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001445 mbedtls_mpi_init(&X);
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001446 mbedtls_mpi_init(&N);
1447 mbedtls_mpi_init(&res);
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001448
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001449 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
1450 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
1451 TEST_EQUAL(mbedtls_test_read_mpi(&res, result), 0);
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001452
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001453 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
1454 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
1455 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
1456
1457 size_t limbs = N.n;
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001458 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1459
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001460 TEST_LE_U(X.n, 2 * limbs);
1461 TEST_EQUAL(res.n, limbs);
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001462
Minos Galanakis9c2c81f2023-04-12 11:10:03 +01001463 TEST_EQUAL(mbedtls_ecp_mod_p256k1(&X), 0);
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001464 TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001465 TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 256);
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001466 ASSERT_COMPARE(X.p, bytes, res.p, bytes);
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001467
1468exit:
1469 mbedtls_mpi_free(&X);
Minos Galanakis4dfed0a2023-04-18 11:58:51 +01001470 mbedtls_mpi_free(&N);
1471 mbedtls_mpi_free(&res);
Minos Galanakisd6751dc2023-04-11 17:25:31 +01001472}
1473/* END_CASE */
1474
Paul Elliott16648be2023-04-23 23:19:21 +01001475/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_CURVE448_ENABLED */
1476void ecp_mod_p448(char *input_N,
1477 char *input_X,
1478 char *result)
1479{
1480 mbedtls_mpi X;
1481 mbedtls_mpi N;
1482 mbedtls_mpi res;
1483
1484 mbedtls_mpi_init(&X);
1485 mbedtls_mpi_init(&N);
1486 mbedtls_mpi_init(&res);
1487
1488 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
1489 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
1490 TEST_EQUAL(mbedtls_test_read_mpi(&res, result), 0);
1491
1492 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, X.p, X.n));
1493 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, N.p, N.n));
1494 TEST_ASSERT(mbedtls_mpi_core_uint_le_mpi(0, res.p, res.n));
1495
1496 size_t limbs = N.n;
1497 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1498
1499 TEST_LE_U(X.n, 2 * limbs);
1500 TEST_EQUAL(res.n, limbs);
1501
1502 TEST_EQUAL(mbedtls_ecp_mod_p448(&X), 0);
1503 TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
1504 TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 448);
1505 ASSERT_COMPARE(X.p, bytes, res.p, bytes);
1506
1507exit:
1508 mbedtls_mpi_free(&X);
1509 mbedtls_mpi_free(&N);
1510 mbedtls_mpi_free(&res);
1511}
1512/* END_CASE */
1513
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00001514/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1515void ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1516{
1517 int ret;
1518 mbedtls_mpi_mod_modulus m;
1519 mbedtls_mpi_mod_modulus_init(&m);
1520 mbedtls_mpi_uint *p = NULL;
1521 size_t p_limbs;
1522 size_t bytes;
1523
1524 TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1525
1526 ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1527 TEST_EQUAL(ret, iret);
1528
1529 if (ret == 0) {
1530
1531 /* Test for limb sizes */
1532 TEST_EQUAL(m.limbs, p_limbs);
1533 bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1534
1535 /* Test for validity of moduli by the presence of Montgomery consts */
1536
1537 TEST_ASSERT(m.rep.mont.mm != 0);
1538 TEST_ASSERT(m.rep.mont.rr != NULL);
1539
1540
1541 /* Compare output byte-by-byte */
1542 ASSERT_COMPARE(p, bytes, m.p, bytes);
1543
1544 /* Test for user free-ing allocated memory */
1545 mbedtls_mpi_mod_modulus_free(&m);
1546 }
1547
1548exit:
1549 mbedtls_mpi_mod_modulus_free(&m);
1550 mbedtls_free(p);
1551}
1552/* END_CASE */
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001553
1554/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
Xiaokang Qianc1f5e542023-05-18 02:02:48 +00001555void ecp_mod_mul_inv(char *input_A, int id, int ctype)
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001556{
Xiaokang Qian78b93b12023-05-17 06:41:21 +00001557 size_t limbs;
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001558 mbedtls_mpi_mod_modulus m;
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001559 mbedtls_mpi_mod_residue rA; // For input
1560 mbedtls_mpi_mod_residue rA_inverse; // For inverse input
1561 mbedtls_mpi_mod_residue rX; // For result
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001562 mbedtls_mpi_uint *rX_raw = NULL;
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001563 mbedtls_mpi_uint *A_inverse = NULL;
1564 mbedtls_mpi_uint *A = NULL;
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001565 mbedtls_mpi_uint *bufx = NULL;
Xiaokang Qianc8f677d2023-05-18 03:04:26 +00001566 const mbedtls_mpi_uint one[1] = { 1 };
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001567
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001568 mbedtls_mpi_mod_modulus_init(&m);
1569
Xiaokang Qian78b93b12023-05-17 06:41:21 +00001570 TEST_ASSERT(mbedtls_ecp_modulus_setup(&m, id, ctype) == 0);
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001571
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001572 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs, input_A), 0);
1573 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
Xiaokang Qian8ca64372023-04-26 10:56:22 +00001574
Xiaokang Qian78b93b12023-05-17 06:41:21 +00001575 /* Test for limb sizes */
1576 TEST_EQUAL(m.limbs, limbs);
Xiaokang Qian8ca64372023-04-26 10:56:22 +00001577
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001578 ASSERT_ALLOC(A_inverse, limbs);
1579 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA_inverse, &m, A_inverse, limbs));
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001580
Xiaokang Qian78b93b12023-05-17 06:41:21 +00001581 ASSERT_ALLOC(rX_raw, limbs);
1582 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001583
Xiaokang Qian78b93b12023-05-17 06:41:21 +00001584 /* Get inverse of A mode m, and multiply it with itself,
Xiaokang Qianc8f677d2023-05-18 03:04:26 +00001585 * to see whether the result equal to '1' */
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001586 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&rA_inverse, &rA, &m));
1587 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA_inverse, &m), 0);
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001588
Xiaokang Qian78b93b12023-05-17 06:41:21 +00001589 ASSERT_ALLOC(bufx, limbs);
1590 TEST_EQUAL(mbedtls_mpi_mod_write(&rX, &m, (unsigned char *) bufx,
Xiaokang Qianc8f677d2023-05-18 03:04:26 +00001591 limbs * ciL,
1592 MBEDTLS_MPI_MOD_EXT_REP_LE), 0);
1593
1594 ASSERT_COMPARE(bufx, ciL, one, ciL);
1595 /*Borrow the buffer of A to compare the left lims with 0 */
1596 memset(A, 0, limbs * ciL);
1597 ASSERT_COMPARE(&bufx[1], (limbs - 1) * ciL, A, (limbs - 1) * ciL);
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001598
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001599exit:
1600 mbedtls_mpi_mod_modulus_free(&m);
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001601 mbedtls_mpi_mod_residue_release(&rA);
1602 mbedtls_mpi_mod_residue_release(&rA_inverse);
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001603 mbedtls_mpi_mod_residue_release(&rX);
Xiaokang Qian1ae7ca42023-05-17 09:09:40 +00001604 mbedtls_free(A);
1605 mbedtls_free(A_inverse);
Xiaokang Qian5e25f802023-04-21 09:45:16 +00001606 mbedtls_free(rX_raw);
1607 mbedtls_free(bufx);
1608}
1609/* END_CASE */
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001610
1611/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
Xiaokang Qianc304e532023-05-18 07:46:59 +00001612void ecp_mod_add_sub(char *input_A, char *input_B, int id, int ctype)
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001613{
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001614 size_t p_A_limbs;
1615 size_t p_B_limbs;
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001616 size_t bytes;
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001617 mbedtls_mpi_mod_modulus m;
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001618 mbedtls_mpi_mod_residue rA;
1619 mbedtls_mpi_mod_residue rB;
1620 mbedtls_mpi_mod_residue rS;
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001621 mbedtls_mpi_uint *p_A = NULL;
1622 mbedtls_mpi_uint *p_B = NULL;
1623 mbedtls_mpi_uint *p_S = NULL;
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001624
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001625 mbedtls_mpi_mod_modulus_init(&m);
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001626
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001627 TEST_EQUAL(mbedtls_test_read_mpi_core(&p_A, &p_A_limbs, input_A), 0);
1628 TEST_EQUAL(mbedtls_test_read_mpi_core(&p_B, &p_B_limbs, input_B), 0);
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001629
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001630 TEST_ASSERT(mbedtls_ecp_modulus_setup(&m, id, ctype) == 0);
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001631
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001632 /* Test for limb sizes for two input value and modulus */
1633 TEST_EQUAL(p_A_limbs, p_B_limbs);
1634 TEST_EQUAL(m.limbs, p_A_limbs);
1635 bytes = p_A_limbs * ciL;
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001636
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001637 ASSERT_ALLOC(p_S, p_A_limbs);
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001638
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001639 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rA, &m, p_A, p_A_limbs), 0);
1640 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rB, &m, p_B, p_B_limbs), 0);
1641 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rS, &m, p_S, p_A_limbs), 0);
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001642
Xiaokang Qian10b6daf2023-05-22 02:28:06 +00001643 /* Firstly add A and B to get the sum S, then subtract B,
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001644 * the difference should be equal to A*/
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001645 TEST_EQUAL(0, mbedtls_mpi_mod_add(&rS, &rA, &rB, &m));
1646 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&rS, &rS, &rB, &m));
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001647
Xiaokang Qian6d02c2f2023-05-18 09:35:25 +00001648 /* Compare difference with rA byte-by-byte */
Xiaokang Qian61b0c1c2023-05-17 09:57:57 +00001649 ASSERT_COMPARE(rA.p, bytes, rS.p, bytes);
Xiaokang Qian5fc78462023-04-27 13:16:55 +00001650
1651exit:
1652 mbedtls_mpi_mod_modulus_free(&m);
1653 mbedtls_mpi_mod_residue_release(&rA);
1654 mbedtls_mpi_mod_residue_release(&rB);
1655 mbedtls_mpi_mod_residue_release(&rS);
1656 mbedtls_free(p_A);
1657 mbedtls_free(p_B);
1658 mbedtls_free(p_S);
1659}
1660/* END_CASE */