blob: 9faeef5eacf6cc7b60b2dff86aaa8f4fddaa73c2 [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) && \
Gabor Mezeiab6ac912023-03-01 16:01:52 +010012 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Gilles Peskine618be2e2021-04-03 21:47:53 +020013#define HAVE_FIX_NEGATIVE
14#endif
15
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +020016#define ECP_PF_UNKNOWN -1
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +020017
Gilles Peskine449bd832023-01-11 14:50:10 +010018#define ECP_PT_RESET(x) \
19 mbedtls_ecp_point_free(x); \
20 mbedtls_ecp_point_init(x);
Gilles Peskine78880732021-03-29 21:32:16 +020021
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010022/* Auxiliary function to compare two mbedtls_ecp_group objects. */
Gilles Peskine449bd832023-01-11 14:50:10 +010023inline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
24 mbedtls_ecp_group *grp2)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010025{
Gilles Peskine449bd832023-01-11 14:50:10 +010026 if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010027 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010028 }
29 if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010030 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010031 }
32 if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010033 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010034 }
35 if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010036 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010037 }
38 if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010039 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010040 }
41 if (grp1->id != grp2->id) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010042 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010043 }
44 if (grp1->pbits != grp2->pbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010045 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010046 }
47 if (grp1->nbits != grp2->nbits) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010048 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010049 }
50 if (grp1->h != grp2->h) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010051 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010052 }
53 if (grp1->modp != grp2->modp) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010054 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010055 }
56 if (grp1->t_pre != grp2->t_pre) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010057 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010058 }
59 if (grp1->t_post != grp2->t_post) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010060 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010061 }
62 if (grp1->t_data != grp2->t_data) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010063 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010064 }
65 if (grp1->T_size != grp2->T_size) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010066 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010067 }
68 if (grp1->T != grp2->T) {
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010069 return 1;
Gilles Peskine449bd832023-01-11 14:50:10 +010070 }
Przemek Stekiel4b30feb2022-03-18 13:58:26 +010071
72 return 0;
73}
74
Paul Bakker33b43f12013-08-20 11:48:36 +020075/* END_HEADER */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010076
Paul Bakker33b43f12013-08-20 11:48:36 +020077/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078 * depends_on:MBEDTLS_ECP_C
Paul Bakker33b43f12013-08-20 11:48:36 +020079 * END_DEPENDENCIES
80 */
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +010081
Tuvshinzaya Erdenekhuufb389dd2022-07-27 15:23:02 +010082/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010083void ecp_invalid_param()
Hanno Becker12dff032018-12-14 15:08:13 +000084{
85 mbedtls_ecp_group grp;
Hanno Becker12dff032018-12-14 15:08:13 +000086 mbedtls_ecp_point P;
Hanno Becker12dff032018-12-14 15:08:13 +000087 int invalid_fmt = 42;
88 size_t olen;
89 unsigned char buf[42] = { 0 };
Hanno Becker12dff032018-12-14 15:08:13 +000090
Gilles Peskine449bd832023-01-11 14:50:10 +010091 mbedtls_ecp_group_init(&grp);
92 mbedtls_ecp_point_init(&P);
Gabor Mezeif29c2a52022-09-23 15:25:27 +020093
Gilles Peskine449bd832023-01-11 14:50:10 +010094 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
95 mbedtls_ecp_point_write_binary(&grp, &P,
96 invalid_fmt,
97 &olen,
98 buf, sizeof(buf)));
99 TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
100 mbedtls_ecp_tls_write_point(&grp, &P,
101 invalid_fmt,
102 &olen,
103 buf,
104 sizeof(buf)));
Hanno Becker12dff032018-12-14 15:08:13 +0000105
106exit:
107 return;
108}
109/* END_CASE */
110
Paul Bakker33b43f12013-08-20 11:48:36 +0200111/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100112void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100113{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100115
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 by_id = mbedtls_ecp_curve_info_from_grp_id(id);
117 by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id);
118 by_name = mbedtls_ecp_curve_info_from_name(name);
119 TEST_ASSERT(by_id != NULL);
120 TEST_ASSERT(by_tls != NULL);
121 TEST_ASSERT(by_name != NULL);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 TEST_ASSERT(by_id == by_tls);
124 TEST_ASSERT(by_id == by_name);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 TEST_ASSERT(by_id->bit_size == size);
127 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
128 TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
Manuel Pégourié-Gonnard0267e3d2013-11-30 15:10:14 +0100129}
130/* END_CASE */
131
132/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100133void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
134 int ret)
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100135{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136 mbedtls_ecp_group grp;
137 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 mbedtls_ecp_group_init(&grp);
140 mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100141
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100143
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
145 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
146 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100149
Paul Bakkerbd51b262014-07-10 15:26:12 +0200150exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 mbedtls_ecp_group_free(&grp);
152 mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100153}
154/* END_CASE */
155
Manuel Pégourié-Gonnard4b9c51e2017-04-20 15:50:26 +0200156/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100157void ecp_test_vect_restart(int id,
158 char *dA_str, char *xA_str, char *yA_str,
159 char *dB_str, char *xZ_str, char *yZ_str,
160 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100161{
162 /*
163 * Test for early restart. Based on test vectors like ecp_test_vect(),
164 * but for the sake of simplicity only does half of each side. It's
165 * important to test both base point and random point, though, as memory
166 * management is different in each case.
167 *
168 * Don't try using too precise bounds for restarts as the exact number
169 * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
170 * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
171 * change in the future. A factor 2 is a minimum safety margin.
172 *
173 * For reference, with mbed TLS 2.4 and default settings, for P-256:
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100174 * - Random point mult: ~3250M
175 * - Cold base point mult: ~3300M
176 * - Hot base point mult: ~1100M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100177 * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
Manuel Pégourié-Gonnard9c5c78f2017-03-20 14:13:07 +0100178 * - Random point mult: ~3850M
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100179 */
Manuel Pégourié-Gonnardb739a712017-04-19 10:11:56 +0200180 mbedtls_ecp_restart_ctx ctx;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100181 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard7a28e992018-10-16 11:22:45 +0200182 mbedtls_ecp_point R, P;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100183 mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
184 int cnt_restarts;
185 int ret;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200186 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 mbedtls_ecp_restart_init(&ctx);
189 mbedtls_ecp_group_init(&grp);
190 mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
191 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
192 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
193 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
198 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
199 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
202 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
203 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100206
207 /* Base point case */
208 cnt_restarts = 0;
209 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 ECP_PT_RESET(&R);
211 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
212 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
213 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100214
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 TEST_ASSERT(ret == 0);
216 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
217 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 TEST_ASSERT(cnt_restarts >= min_restarts);
220 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100221
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100222 /* Non-base point case */
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 mbedtls_ecp_copy(&P, &R);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100224 cnt_restarts = 0;
225 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 ECP_PT_RESET(&R);
227 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
228 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
229 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 TEST_ASSERT(ret == 0);
232 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
233 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 TEST_ASSERT(cnt_restarts >= min_restarts);
236 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100237
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200238 /* Do we leak memory when aborting an operation?
239 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (min_restarts > 0) {
241 ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
242 &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
243 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200244 }
Manuel Pégourié-Gonnard77af79a2017-03-14 10:58:00 +0100245
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100246exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 mbedtls_ecp_restart_free(&ctx);
248 mbedtls_ecp_group_free(&grp);
249 mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
250 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
251 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
Manuel Pégourié-Gonnard510d5ca2017-03-08 11:41:47 +0100252}
253/* END_CASE */
254
Manuel Pégourié-Gonnard57866462022-12-06 12:14:49 +0100255/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100256void ecp_muladd_restart(int id, char *xR_str, char *yR_str,
257 char *u1_str, char *u2_str,
258 char *xQ_str, char *yQ_str,
259 int max_ops, int min_restarts, int max_restarts)
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200260{
261 /*
262 * Compute R = u1 * G + u2 * Q
263 * (test vectors mostly taken from ECDSA intermediate results)
264 *
265 * See comments at the top of ecp_test_vect_restart()
266 */
267 mbedtls_ecp_restart_ctx ctx;
268 mbedtls_ecp_group grp;
269 mbedtls_ecp_point R, Q;
270 mbedtls_mpi u1, u2, xR, yR;
271 int cnt_restarts;
272 int ret;
273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 mbedtls_ecp_restart_init(&ctx);
275 mbedtls_ecp_group_init(&grp);
276 mbedtls_ecp_point_init(&R);
277 mbedtls_ecp_point_init(&Q);
278 mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
279 mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 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(&u1, u1_str) == 0);
284 TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
285 TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
286 TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
289 TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
290 TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 mbedtls_ecp_set_max_ops((unsigned) max_ops);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200293
294 cnt_restarts = 0;
295 do {
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 ECP_PT_RESET(&R);
297 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
298 &u1, &grp.G, &u2, &Q, &ctx);
299 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 TEST_ASSERT(ret == 0);
302 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
303 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 TEST_ASSERT(cnt_restarts >= min_restarts);
306 TEST_ASSERT(cnt_restarts <= max_restarts);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200307
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200308 /* Do we leak memory when aborting an operation?
309 * This test only makes sense when we actually restart */
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 if (min_restarts > 0) {
311 ret = mbedtls_ecp_muladd_restartable(&grp, &R,
312 &u1, &grp.G, &u2, &Q, &ctx);
313 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200314 }
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200315
316exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_ecp_restart_free(&ctx);
318 mbedtls_ecp_group_free(&grp);
319 mbedtls_ecp_point_free(&R);
320 mbedtls_ecp_point_free(&Q);
321 mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
322 mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
Manuel Pégourié-Gonnard54dd6522017-04-20 13:36:18 +0200323}
324/* END_CASE */
325
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100326/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100327void ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
328 char *dB_str, char *xB_str, char *yB_str,
329 char *xZ_str, char *yZ_str)
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100330{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331 mbedtls_ecp_group grp;
332 mbedtls_ecp_point R;
333 mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200334 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
337 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
338 mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
339 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard4b8c3f22012-11-07 21:39:45 +0100342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnard1c330572012-11-24 12:05:44 +0100344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
346 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
347 TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
348 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
349 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
350 TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
351 TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
352 TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
355 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
356 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
357 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
358 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
359 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
360 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
361 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
362 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
363 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
366 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
367 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
368 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
369 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
370 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
371 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
372 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
373 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
374 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
Manuel Pégourié-Gonnarde739f012012-11-07 12:24:22 +0100375
Paul Bakkerbd51b262014-07-10 15:26:12 +0200376exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
378 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
379 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 +0100380}
Paul Bakker33b43f12013-08-20 11:48:36 +0200381/* END_CASE */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100382
Paul Bakker33b43f12013-08-20 11:48:36 +0200383/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384void ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
385 char *xB_hex, char *xS_hex)
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100386{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 mbedtls_ecp_group grp;
388 mbedtls_ecp_point R;
389 mbedtls_mpi dA, xA, dB, xB, xS;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200390 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
393 mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
394 mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
395 mbedtls_mpi_init(&xS);
396 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
403 TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
404 TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
405 TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
406 TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 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, &dA, &grp.G,
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, &xA) == 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, &R,
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, &xS) == 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, &dB, &grp.G,
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, &xB) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
424 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
425 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
426 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100427
Paul Bakkerbd51b262014-07-10 15:26:12 +0200428exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
430 mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
431 mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
432 mbedtls_mpi_free(&xS);
Manuel Pégourié-Gonnarda0179b82013-12-04 11:49:20 +0100433}
434/* END_CASE */
435
436/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437void ecp_test_mul(int id, data_t *n_hex,
438 data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
439 data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
440 int expected_ret)
Janos Follath182b0b92019-04-26 14:28:19 +0100441{
442 mbedtls_ecp_group grp;
443 mbedtls_ecp_point P, nP, R;
444 mbedtls_mpi n;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200445 mbedtls_test_rnd_pseudo_info rnd_info;
Janos Follath182b0b92019-04-26 14:28:19 +0100446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
448 mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
449 mbedtls_mpi_init(&n);
450 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Janos Follath182b0b92019-04-26 14:28:19 +0100451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
459 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
460 TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
461 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
462 == 0);
463 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
464 == 0);
465 TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
466 == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
469 &mbedtls_test_rnd_pseudo_rand, &rnd_info)
470 == expected_ret);
Janos Follath182b0b92019-04-26 14:28:19 +0100471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 if (expected_ret == 0) {
473 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
474 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
475 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
Janos Follath182b0b92019-04-26 14:28:19 +0100476 }
477
478exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
480 mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
481 mbedtls_mpi_free(&n);
Janos Follath182b0b92019-04-26 14:28:19 +0100482}
483/* END_CASE */
484
485/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486void ecp_test_mul_rng(int id, data_t *d_hex)
Jonas923d5792020-05-13 14:22:45 +0900487{
488 mbedtls_ecp_group grp;
489 mbedtls_mpi d;
490 mbedtls_ecp_point Q;
491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
493 mbedtls_ecp_point_init(&Q);
Jonas923d5792020-05-13 14:22:45 +0900494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Jonas923d5792020-05-13 14:22:45 +0900496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
Jonas923d5792020-05-13 14:22:45 +0900498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
Jonas923d5792020-05-13 14:22:45 +0900500
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
502 &mbedtls_test_rnd_zero_rand, NULL)
503 == MBEDTLS_ERR_ECP_RANDOM_FAILED);
Jonas923d5792020-05-13 14:22:45 +0900504
505exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
507 mbedtls_ecp_point_free(&Q);
Jonas923d5792020-05-13 14:22:45 +0900508}
509/* END_CASE */
510
Gilles Peskineca91ee42021-04-03 18:31:01 +0200511/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +0100512void ecp_muladd(int id,
513 data_t *u1_bin, data_t *P1_bin,
514 data_t *u2_bin, data_t *P2_bin,
515 data_t *expected_result)
Gilles Peskineca91ee42021-04-03 18:31:01 +0200516{
517 /* Compute R = u1 * P1 + u2 * P2 */
518 mbedtls_ecp_group grp;
519 mbedtls_ecp_point P1, P2, R;
520 mbedtls_mpi u1, u2;
521 uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
522 size_t len;
523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 mbedtls_ecp_group_init(&grp);
525 mbedtls_ecp_point_init(&P1);
526 mbedtls_ecp_point_init(&P2);
527 mbedtls_ecp_point_init(&R);
528 mbedtls_mpi_init(&u1);
529 mbedtls_mpi_init(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
532 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
533 TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
534 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
535 P1_bin->x, P1_bin->len));
536 TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
537 P2_bin->x, P2_bin->len));
Gilles Peskineca91ee42021-04-03 18:31:01 +0200538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
540 TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
541 &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
542 &len, actual_result, sizeof(actual_result)));
543 TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 ASSERT_COMPARE(expected_result->x, expected_result->len,
546 actual_result, len);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200547
548exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 mbedtls_ecp_group_free(&grp);
550 mbedtls_ecp_point_free(&P1);
551 mbedtls_ecp_point_free(&P2);
552 mbedtls_ecp_point_free(&R);
553 mbedtls_mpi_free(&u1);
554 mbedtls_mpi_free(&u2);
Gilles Peskineca91ee42021-04-03 18:31:01 +0200555}
556/* END_CASE */
557
Jonas923d5792020-05-13 14:22:45 +0900558/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100559void ecp_fast_mod(int id, char *N_str)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100560{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 mbedtls_ecp_group grp;
562 mbedtls_mpi N, R;
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
565 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
568 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
569 TEST_ASSERT(grp.modp != NULL);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100570
571 /*
572 * Store correct result before we touch N
573 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 TEST_ASSERT(grp.modp(&N) == 0);
577 TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100578
579 /*
Paul Bakkerd8b0c5e2014-04-11 15:31:33 +0200580 * Use mod rather than addition/subtraction in case previous test fails
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100581 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
583 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100584
Paul Bakkerbd51b262014-07-10 15:26:12 +0200585exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
587 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100588}
Paul Bakker33b43f12013-08-20 11:48:36 +0200589/* END_CASE */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100590
Paul Bakker33b43f12013-08-20 11:48:36 +0200591/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592void ecp_write_binary(int id, char *x, char *y, char *z, int format,
593 data_t *out, int blen, int ret)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100594{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_ecp_group grp;
596 mbedtls_ecp_point P;
Azim Khanf1aaec92017-05-30 14:23:15 +0100597 unsigned char buf[256];
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100598 size_t olen;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
607 TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
608 TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
611 &olen, buf, blen) == ret);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 if (ret == 0) {
614 TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
615 TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100616 }
617
Paul Bakkerbd51b262014-07-10 15:26:12 +0200618exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100620}
Paul Bakker33b43f12013-08-20 11:48:36 +0200621/* END_CASE */
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100622
Paul Bakker33b43f12013-08-20 11:48:36 +0200623/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100624void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
625 int ret)
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100626{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_ecp_group grp;
628 mbedtls_ecp_point P;
629 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100630
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
633 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
638 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
639 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (ret == 0) {
644 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
645 if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
646 TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
647 TEST_ASSERT(P.Y.p == NULL);
648 TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
649 TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
650 } else {
651 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
652 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 if (buf->x[0] == 0x04 &&
Glenn Strauss2ff77112022-09-14 23:27:50 -0400655 /* (reading compressed format supported only for
656 * Short Weierstrass curves with prime p where p = 3 mod 4) */
657 id != MBEDTLS_ECP_DP_SECP224R1 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 id != MBEDTLS_ECP_DP_SECP224K1) {
Glenn Strauss2ff77112022-09-14 23:27:50 -0400659 /* re-encode in compressed format and test read again */
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 mbedtls_mpi_free(&P.Y);
661 buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
662 TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
663 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
Glenn Strauss2ff77112022-09-14 23:27:50 -0400664 }
Janos Follath59b813c2019-02-13 10:44:06 +0000665 }
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100666 }
667
Paul Bakkerbd51b262014-07-10 15:26:12 +0200668exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
670 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100671}
Paul Bakker33b43f12013-08-20 11:48:36 +0200672/* END_CASE */
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100673
Paul Bakker33b43f12013-08-20 11:48:36 +0200674/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100675void mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
676 char *z, int ret)
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100677{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678 mbedtls_ecp_group grp;
679 mbedtls_ecp_point P;
680 mbedtls_mpi X, Y, Z;
Azim Khand30ca132017-06-09 04:32:58 +0100681 const unsigned char *vbuf = buf->x;
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100682
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
685 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
690 TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
691 TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 if (ret == 0) {
696 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
697 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
698 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
699 TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100700 }
701
Paul Bakkerbd51b262014-07-10 15:26:12 +0200702exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
704 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100705}
Paul Bakker33b43f12013-08-20 11:48:36 +0200706/* END_CASE */
Manuel Pégourié-Gonnard8c16f962013-02-10 13:00:20 +0100707
Paul Bakker33b43f12013-08-20 11:48:36 +0200708/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709void ecp_tls_write_read_point(int id)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100710{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711 mbedtls_ecp_group grp;
712 mbedtls_ecp_point pt;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100713 unsigned char buf[256];
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100714 const unsigned char *vbuf;
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100715 size_t olen;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 mbedtls_ecp_group_init(&grp);
718 mbedtls_ecp_point_init(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
723 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
724 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
725 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
726 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
727 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
728 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
729 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
732 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
733 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
734 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
735 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
736 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
737 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
738 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
741 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
742 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
743 MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
744 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
745 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
746 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 memset(buf, 0x00, sizeof(buf)); vbuf = buf;
749 TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
750 TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
751 MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
752 TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
753 TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
754 TEST_ASSERT(vbuf == buf + olen);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100755
Paul Bakkerbd51b262014-07-10 15:26:12 +0200756exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 mbedtls_ecp_group_free(&grp);
758 mbedtls_ecp_point_free(&pt);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100759}
Paul Bakker33b43f12013-08-20 11:48:36 +0200760/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100761
Paul Bakker33b43f12013-08-20 11:48:36 +0200762/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100763void mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
764 int record_len)
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100765{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766 mbedtls_ecp_group grp;
Azim Khand30ca132017-06-09 04:32:58 +0100767 const unsigned char *vbuf = buf->x;
Azim Khanf1aaec92017-05-30 14:23:15 +0100768 int ret;
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100769
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 mbedtls_ecp_group_init(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 TEST_ASSERT(ret == result);
775 if (ret == 0) {
776 TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
777 TEST_ASSERT(vbuf - buf->x == record_len);
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100778 }
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100779
Paul Bakkerbd51b262014-07-10 15:26:12 +0200780exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 mbedtls_ecp_group_free(&grp);
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100782}
Paul Bakker33b43f12013-08-20 11:48:36 +0200783/* END_CASE */
Manuel Pégourié-Gonnard6282aca2013-02-10 11:15:11 +0100784
Paul Bakker33b43f12013-08-20 11:48:36 +0200785/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100786void ecp_tls_write_read_group(int id)
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100787{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_ecp_group grp1, grp2;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100789 unsigned char buf[10];
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100790 const unsigned char *vbuf = buf;
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100791 size_t len;
792 int ret;
793
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 mbedtls_ecp_group_init(&grp1);
795 mbedtls_ecp_group_init(&grp2);
796 memset(buf, 0x00, sizeof(buf));
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
801 ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
802 TEST_ASSERT(ret == 0);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 if (ret == 0) {
805 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
806 TEST_ASSERT(grp1.id == grp2.id);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100807 }
808
Paul Bakkerbd51b262014-07-10 15:26:12 +0200809exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_ecp_group_free(&grp1);
811 mbedtls_ecp_group_free(&grp2);
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100812}
Paul Bakker33b43f12013-08-20 11:48:36 +0200813/* END_CASE */
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100814
Valerio Setti46829482023-01-18 13:59:30 +0100815/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100816void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
817 char *P, char *A, char *B,
818 char *G_x, char *G_y, char *N,
819 int tls_id)
Werner Lewise54046c2022-08-15 11:43:56 +0100820{
821 mbedtls_ecp_group grp, grp_read, grp_cpy;
822 const mbedtls_ecp_group_id *g_id;
Werner Lewisccae25b2022-09-20 10:00:07 +0100823 mbedtls_ecp_group_id read_g_id;
Werner Lewise54046c2022-08-15 11:43:56 +0100824 const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
825
826 mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
827
828 unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
829 const unsigned char *vbuf = buf;
830 size_t olen;
831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 mbedtls_ecp_group_init(&grp);
833 mbedtls_ecp_group_init(&grp_read);
834 mbedtls_ecp_group_init(&grp_cpy);
Werner Lewise54046c2022-08-15 11:43:56 +0100835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 mbedtls_mpi_init(&exp_P);
837 mbedtls_mpi_init(&exp_A);
838 mbedtls_mpi_init(&exp_B);
839 mbedtls_mpi_init(&exp_G_x);
840 mbedtls_mpi_init(&exp_G_y);
841 mbedtls_mpi_init(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100842
843 // Read expected parameters
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
845 TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
846 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
847 TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
848 TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
849 TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100850
Werner Lewisc4afef72022-08-25 10:29:19 +0100851 // Convert exp_A to internal representation (A+2)/4
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
853 TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
854 TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
Werner Lewisc4afef72022-08-25 10:29:19 +0100855 }
856
Werner Lewise54046c2022-08-15 11:43:56 +0100857 // Load group
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100859
860 // Compare group with expected parameters
861 // A is NULL for SECPxxxR1 curves
862 // B and G_y are NULL for curve25519 and curve448
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
864 if (*A != 0) {
865 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
866 }
867 if (*B != 0) {
868 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
869 }
870 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
871 if (*G_y != 0) {
872 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
873 }
874 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100875
876 // Load curve info and compare with known values
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 crv = mbedtls_ecp_curve_info_from_grp_id(id);
878 TEST_EQUAL(crv->grp_id, id);
879 TEST_EQUAL(crv->bit_size, bit_size);
880 TEST_EQUAL(crv->tls_id, tls_id);
Werner Lewise54046c2022-08-15 11:43:56 +0100881
882 // Load curve from TLS ID and name, and compare IDs
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
884 crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
885 TEST_EQUAL(crv_tls_id->grp_id, id);
886 TEST_EQUAL(crv_name->grp_id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100887
Werner Lewisccae25b2022-09-20 10:00:07 +0100888 // Validate write_group against test data
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
890 buf, sizeof(buf)),
891 0);
892 TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
893 sizeof(ecparameters)),
894 0);
Werner Lewisccae25b2022-09-20 10:00:07 +0100895
896 // Read group from buffer and compare with expected ID
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
898 0);
899 TEST_EQUAL(read_g_id, id);
Werner Lewis05feee12022-09-20 12:05:00 +0100900 vbuf = buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
902 0);
903 TEST_EQUAL(grp_read.id, id);
Werner Lewise54046c2022-08-15 11:43:56 +0100904
905 // Check curve type, and if it can be used for ECDH/ECDSA
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
Valerio Setti46829482023-01-18 13:59:30 +0100907#if defined(MBEDTLS_ECDH_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
Valerio Setti46829482023-01-18 13:59:30 +0100909#endif
910#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 TEST_EQUAL(mbedtls_ecdsa_can_do(id),
912 crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
Valerio Setti46829482023-01-18 13:59:30 +0100913#endif
Werner Lewise54046c2022-08-15 11:43:56 +0100914
915 // Copy group and compare with original
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
917 TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
Werner Lewise54046c2022-08-15 11:43:56 +0100918
919 // Check curve is in curve list and group ID list
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 for (crv = mbedtls_ecp_curve_list();
921 crv->grp_id != MBEDTLS_ECP_DP_NONE &&
922 crv->grp_id != (unsigned) id;
923 crv++) {
924 ;
925 }
926 TEST_EQUAL(crv->grp_id, id);
927 for (g_id = mbedtls_ecp_grp_id_list();
Werner Lewise54046c2022-08-15 11:43:56 +0100928 *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 g_id++) {
930 ;
931 }
932 TEST_EQUAL(*g_id, (unsigned) id);
Werner Lewise54046c2022-08-15 11:43:56 +0100933
934exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
936 mbedtls_ecp_group_free(&grp_read);
937 mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
938 mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
939 mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
Werner Lewise54046c2022-08-15 11:43:56 +0100940}
941/* END_CASE */
942
Paul Bakker33b43f12013-08-20 11:48:36 +0200943/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100944void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200945{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_ecp_group grp;
947 mbedtls_mpi d;
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 mbedtls_ecp_group_init(&grp);
950 mbedtls_mpi_init(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
953 TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200956
Paul Bakkerbd51b262014-07-10 15:26:12 +0200957exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 mbedtls_ecp_group_free(&grp);
959 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200960}
Paul Bakker33b43f12013-08-20 11:48:36 +0200961/* END_CASE */
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +0200962
Paul Bakker33b43f12013-08-20 11:48:36 +0200963/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100964void mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
965 int id, char *d, char *Qx, char *Qy,
966 int ret)
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100967{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 mbedtls_ecp_keypair pub, prv;
Manuel Pégourié-Gonnardf8c24bf2021-06-15 11:29:26 +0200969 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 mbedtls_ecp_keypair_init(&pub);
972 mbedtls_ecp_keypair_init(&prv);
973 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 if (id_pub != MBEDTLS_ECP_DP_NONE) {
976 TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
977 }
978 TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 if (id != MBEDTLS_ECP_DP_NONE) {
981 TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
982 }
983 TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
984 TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
987 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100988
989exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 mbedtls_ecp_keypair_free(&pub);
991 mbedtls_ecp_keypair_free(&prv);
Manuel Pégourié-Gonnard30668d62014-11-06 15:25:32 +0100992}
993/* END_CASE */
994
995/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100996void mbedtls_ecp_gen_keypair(int id)
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +0100997{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 mbedtls_ecp_group grp;
999 mbedtls_ecp_point Q;
1000 mbedtls_mpi d;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001001 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 mbedtls_ecp_group_init(&grp);
1004 mbedtls_ecp_point_init(&Q);
1005 mbedtls_mpi_init(&d);
1006 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1011 &mbedtls_test_rnd_pseudo_rand,
1012 &rnd_info) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1015 TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001016
Paul Bakkerbd51b262014-07-10 15:26:12 +02001017exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 mbedtls_ecp_group_free(&grp);
1019 mbedtls_ecp_point_free(&Q);
1020 mbedtls_mpi_free(&d);
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001021}
Paul Bakker33b43f12013-08-20 11:48:36 +02001022/* END_CASE */
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001023
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001024/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001025void mbedtls_ecp_gen_key(int id)
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001026{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 mbedtls_ecp_keypair key;
Ronald Cron351f0ee2020-06-10 12:12:18 +02001028 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 mbedtls_ecp_keypair_init(&key);
1031 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1034 &mbedtls_test_rnd_pseudo_rand,
1035 &rnd_info) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1038 TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001039
Paul Bakkerbd51b262014-07-10 15:26:12 +02001040exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 mbedtls_ecp_keypair_free(&key);
Manuel Pégourié-Gonnard104ee1d2013-11-30 14:13:16 +01001042}
1043/* END_CASE */
1044
Janos Follath171a7ef2019-02-15 16:17:45 +00001045/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001046void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
Janos Follath171a7ef2019-02-15 16:17:45 +00001047{
1048 int ret = 0;
1049 mbedtls_ecp_keypair key;
Steven Cooremande8593f2020-06-09 19:55:26 +02001050 mbedtls_ecp_keypair key2;
Janos Follath171a7ef2019-02-15 16:17:45 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 mbedtls_ecp_keypair_init(&key);
1053 mbedtls_ecp_keypair_init(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1056 TEST_ASSERT(ret == expected);
Janos Follath171a7ef2019-02-15 16:17:45 +00001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (expected == 0) {
1059 ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1060 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 if (canonical) {
Steven Cooremande8593f2020-06-09 19:55:26 +02001063 unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001064
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1066 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 ASSERT_COMPARE(in_key->x, in_key->len,
1069 buf, in_key->len);
1070 } else {
Steven Cooremande8593f2020-06-09 19:55:26 +02001071 unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001072 unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
Steven Cooremande8593f2020-06-09 19:55:26 +02001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1075 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001076
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1078 TEST_ASSERT(ret == expected);
Steven Cooremande8593f2020-06-09 19:55:26 +02001079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1081 TEST_ASSERT(ret == 0);
Steven Cooremande8593f2020-06-09 19:55:26 +02001082
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 ASSERT_COMPARE(export1, in_key->len,
1084 export2, in_key->len);
Steven Cooremande8593f2020-06-09 19:55:26 +02001085 }
Janos Follath171a7ef2019-02-15 16:17:45 +00001086 }
1087
1088exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 mbedtls_ecp_keypair_free(&key);
1090 mbedtls_ecp_keypair_free(&key2);
Janos Follath171a7ef2019-02-15 16:17:45 +00001091}
1092/* END_CASE */
1093
Gilles Peskine618be2e2021-04-03 21:47:53 +02001094/* BEGIN_CASE depends_on:HAVE_FIX_NEGATIVE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001095void fix_negative(data_t *N_bin, int c, int bits)
Gilles Peskine618be2e2021-04-03 21:47:53 +02001096{
1097 mbedtls_mpi C, M, N;
1098
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 mbedtls_mpi_init(&C);
1100 mbedtls_mpi_init(&M);
1101 mbedtls_mpi_init(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001102
Gilles Peskine392d1012021-04-09 15:46:51 +02001103 /* C = - c * 2^bits (positive since c is negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001104 TEST_EQUAL(0, mbedtls_mpi_lset(&C, -c));
1105 TEST_EQUAL(0, mbedtls_mpi_shift_l(&C, bits));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 TEST_EQUAL(0, mbedtls_mpi_read_binary(&N, N_bin->x, N_bin->len));
1108 TEST_EQUAL(0, mbedtls_mpi_grow(&N, C.n));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001109
Gilles Peskine392d1012021-04-09 15:46:51 +02001110 /* M = N - C = - ( C - N ) (expected result of fix_negative) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 TEST_EQUAL(0, mbedtls_mpi_sub_mpi(&M, &N, &C));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001112
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 mbedtls_ecp_fix_negative(&N, c, bits);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001114
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&N, &M));
Gilles Peskine618be2e2021-04-03 21:47:53 +02001116
1117exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 mbedtls_mpi_free(&C);
1119 mbedtls_mpi_free(&M);
1120 mbedtls_mpi_free(&N);
Gilles Peskine618be2e2021-04-03 21:47:53 +02001121}
1122/* END_CASE */
1123
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001124/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */
Gilles Peskine449bd832023-01-11 14:50:10 +01001125void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001126{
1127 mbedtls_test_rnd_buf_info rnd_info;
1128 mbedtls_mpi d;
1129 int ret;
1130 uint8_t *actual = NULL;
1131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 mbedtls_mpi_init(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001133 rnd_info.buf = seed->x;
1134 rnd_info.length = seed->len;
1135 rnd_info.fallback_f_rng = NULL;
1136 rnd_info.fallback_p_rng = NULL;
1137
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 ASSERT_ALLOC(actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1141 mbedtls_test_rnd_buffer_rand, &rnd_info);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001142
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 if (expected->len == 0) {
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001144 /* Expecting an error (happens if there isn't enough randomness) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 TEST_ASSERT(ret != 0);
1146 } else {
1147 TEST_EQUAL(ret, 0);
1148 TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1149 TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001150 /* Test the exact result. This assumes that the output of the
1151 * RNG is used in a specific way, which is overly constraining.
1152 * The advantage is that it's easier to test the expected properties
1153 * of the generated key:
1154 * - The most significant bit must be at a specific positions
1155 * (can be enforced by checking the bit-length).
1156 * - The least significant bits must have specific values
1157 * (can be enforced by checking these bits).
1158 * - Other bits must be random (by testing with different RNG outputs,
1159 * we validate that those bits are indeed influenced by the RNG). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 ASSERT_COMPARE(expected->x, expected->len,
1161 actual, expected->len);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001162 }
1163
1164exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 mbedtls_free(actual);
1166 mbedtls_mpi_free(&d);
Gilles Peskine6ff8a012021-03-24 12:01:02 +01001167}
1168/* END_CASE */
1169
Werner Lewis3b097392022-08-08 11:53:45 +01001170/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001171void ecp_set_zero(int id, data_t *P_bin)
Werner Lewis3b097392022-08-08 11:53:45 +01001172{
1173 mbedtls_ecp_group grp;
1174 mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 mbedtls_ecp_group_init(&grp);
1177 mbedtls_ecp_point_init(&pt);
1178 mbedtls_ecp_point_init(&zero_pt);
1179 mbedtls_ecp_point_init(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001180
1181 // Set zero and non-zero points for comparison
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1183 TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1184 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1185 P_bin->x, P_bin->len), 0);
1186 TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1187 TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001188
1189 // Test initialized point
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1191 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1192 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1193 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1194 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001195
1196 // Test zeroed point
Gilles Peskine449bd832023-01-11 14:50:10 +01001197 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1198 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1199 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1200 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1201 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001202
1203 // Set point to non-zero value
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1205 P_bin->x, P_bin->len), 0);
1206 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1207 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1208 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1209 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
Werner Lewis3b097392022-08-08 11:53:45 +01001210
1211 // Test non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1213 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1214 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1215 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1216 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001217
1218 // Test freed non-zero point
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1220 P_bin->x, P_bin->len), 0);
1221 mbedtls_ecp_point_free(&pt);
1222 TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1223 TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1224 TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1225 TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1226 MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
Werner Lewis3b097392022-08-08 11:53:45 +01001227
1228exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 mbedtls_ecp_group_free(&grp);
1230 mbedtls_ecp_point_free(&pt);
1231 mbedtls_ecp_point_free(&zero_pt);
1232 mbedtls_ecp_point_free(&nonzero_pt);
Werner Lewis3b097392022-08-08 11:53:45 +01001233}
1234/* END_CASE */
1235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001237void ecp_selftest()
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001238{
Gilles Peskine449bd832023-01-11 14:50:10 +01001239 TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001240}
Paul Bakker33b43f12013-08-20 11:48:36 +02001241/* END_CASE */
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001242
1243/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001244void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001245{
1246 mbedtls_ecp_keypair key;
1247 mbedtls_ecp_group export_grp;
1248 mbedtls_mpi export_d;
1249 mbedtls_ecp_point export_Q;
1250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 mbedtls_ecp_group_init(&export_grp);
1252 mbedtls_ecp_group_init(&key.grp);
1253 mbedtls_mpi_init(&export_d);
1254 mbedtls_ecp_point_init(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001255
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 mbedtls_ecp_keypair_init(&key);
1257 if (invalid_grp == 0) {
1258 TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1259 }
1260 TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1261 TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1264 &export_d, &export_Q), expected_ret);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001265
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 if (expected_ret == 0) {
1267 TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1268 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1269 TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001270 }
1271
1272exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 mbedtls_ecp_keypair_free(&key);
1274 mbedtls_ecp_group_free(&export_grp);
1275 mbedtls_mpi_free(&export_d);
1276 mbedtls_ecp_point_free(&export_Q);
Przemek Stekiel4b30feb2022-03-18 13:58:26 +01001277}
1278/* END_CASE */
Dave Rodgman57080462022-06-17 13:41:18 +01001279
1280/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001281void ecp_check_order(int id, char *expected_order_hex)
Dave Rodgman57080462022-06-17 13:41:18 +01001282{
1283 mbedtls_ecp_group grp;
1284 mbedtls_mpi expected_n;
1285
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 mbedtls_ecp_group_init(&grp);
1287 mbedtls_mpi_init(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001288
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1290 TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001291
1292 // check sign bits are well-formed (i.e. 1 or -1) - see #5810
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1294 TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
Dave Rodgman5cab9da2022-06-17 13:48:29 +01001295
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
Dave Rodgman57080462022-06-17 13:41:18 +01001297
1298exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 mbedtls_ecp_group_free(&grp);
1300 mbedtls_mpi_free(&expected_n);
Dave Rodgman57080462022-06-17 13:41:18 +01001301}
Dave Rodgmaneb8570f2022-06-17 14:59:36 +01001302/* END_CASE */
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001303
Valerio Settie4758aa2023-03-24 16:51:17 +01001304/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001305void ecp_mod_p192_raw(char *input_N,
1306 char *input_X,
1307 char *result)
1308{
1309 mbedtls_mpi_uint *X = NULL;
1310 mbedtls_mpi_uint *N = NULL;
1311 mbedtls_mpi_uint *res = NULL;
1312 size_t limbs_X;
1313 size_t limbs_N;
1314 size_t limbs_res;
1315
1316 mbedtls_mpi_mod_modulus m;
1317 mbedtls_mpi_mod_modulus_init(&m);
1318
1319 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1320 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1321 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1322
1323 size_t limbs = limbs_N;
1324 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1325
1326 TEST_EQUAL(limbs_X, 2 * limbs);
1327 TEST_EQUAL(limbs_res, limbs);
1328
1329 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1330 &m, N, limbs,
1331 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1332
Gabor Mezei2038ce92023-01-31 14:33:12 +01001333 TEST_EQUAL(mbedtls_ecp_mod_p192_raw(X, limbs_X), 0);
Gabor Mezei23d4b8b2023-02-13 14:13:33 +01001334 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 192);
Gabor Mezei51ec06a2023-01-25 18:05:44 +01001335 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1336 ASSERT_COMPARE(X, bytes, res, bytes);
1337
1338exit:
1339 mbedtls_free(X);
1340 mbedtls_free(res);
1341
1342 mbedtls_mpi_mod_modulus_free(&m);
1343 mbedtls_free(N);
1344}
1345/* END_CASE */
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001346
Valerio Setti1a6d96f2023-03-24 14:10:24 +01001347/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Gabor Mezeif65a0592023-02-14 18:26:36 +01001348void ecp_mod_p224_raw(char *input_N,
1349 char *input_X,
1350 char *result)
1351{
1352 mbedtls_mpi_uint *X = NULL;
1353 mbedtls_mpi_uint *N = NULL;
1354 mbedtls_mpi_uint *res = NULL;
1355 size_t limbs_X;
1356 size_t limbs_N;
1357 size_t limbs_res;
1358
1359 mbedtls_mpi_mod_modulus m;
1360 mbedtls_mpi_mod_modulus_init(&m);
1361
1362 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1363 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1364 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1365
1366 size_t limbs = limbs_N;
1367 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1368
1369 TEST_EQUAL(limbs_X, 448 / biL);
1370 TEST_EQUAL(limbs_res, limbs);
1371
1372 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1373 &m, N, limbs,
1374 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1375
Gabor Mezei804cfd32023-02-27 16:50:09 +01001376 TEST_EQUAL(mbedtls_ecp_mod_p224_raw(X, limbs_X), 0);
Gabor Mezeif65a0592023-02-14 18:26:36 +01001377 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 224);
1378 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1379 ASSERT_COMPARE(X, bytes, res, bytes);
1380
1381exit:
1382 mbedtls_free(X);
1383 mbedtls_free(res);
1384
1385 mbedtls_mpi_mod_modulus_free(&m);
1386 mbedtls_free(N);
1387}
1388/* END_CASE */
1389
Valerio Setti1a6d96f2023-03-24 14:10:24 +01001390/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Gabor Mezeieb591ff2023-03-08 14:06:04 +01001391void ecp_mod_p256_raw(char *input_N,
1392 char *input_X,
1393 char *result)
1394{
1395 mbedtls_mpi_uint *X = NULL;
1396 mbedtls_mpi_uint *N = NULL;
1397 mbedtls_mpi_uint *res = NULL;
1398 size_t limbs_X;
1399 size_t limbs_N;
1400 size_t limbs_res;
1401
1402 mbedtls_mpi_mod_modulus m;
1403 mbedtls_mpi_mod_modulus_init(&m);
1404
1405 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1406 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1407 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1408
1409 size_t limbs = limbs_N;
1410 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1411
1412 TEST_EQUAL(limbs_X, 2 * limbs);
1413 TEST_EQUAL(limbs_res, limbs);
1414
1415 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1416 &m, N, limbs,
1417 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1418
1419 TEST_EQUAL(mbedtls_ecp_mod_p256_raw(X, limbs_X), 0);
1420 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 256);
1421 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1422 ASSERT_COMPARE(X, bytes, res, bytes);
1423
1424exit:
1425 mbedtls_free(X);
1426 mbedtls_free(res);
1427
1428 mbedtls_mpi_mod_modulus_free(&m);
1429 mbedtls_free(N);
1430}
1431/* END_CASE */
1432
Minos Galanakis37bdd932023-03-27 18:19:22 +01001433/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Minos Galanakis619385d2023-03-06 10:00:46 +00001434void ecp_mod_p384_raw(char *input_N,
1435 char *input_X,
1436 char *result)
1437{
1438 mbedtls_mpi_uint *X = NULL;
1439 mbedtls_mpi_uint *N = NULL;
1440 mbedtls_mpi_uint *res = NULL;
1441 size_t limbs_X;
1442 size_t limbs_N;
1443 size_t limbs_res;
1444
1445 mbedtls_mpi_mod_modulus m;
1446 mbedtls_mpi_mod_modulus_init(&m);
1447
1448 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1449 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1450 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1451
1452 size_t limbs = limbs_N;
1453 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1454
Minos Galanakis37f4cb62023-03-09 11:15:15 +00001455 TEST_EQUAL(limbs_X, 2 * limbs);
Minos Galanakis619385d2023-03-06 10:00:46 +00001456 TEST_EQUAL(limbs_res, limbs);
1457
1458 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1459 &m, N, limbs,
1460 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1461
1462 TEST_EQUAL(mbedtls_ecp_mod_p384_raw(X, limbs_X), 0);
1463 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 384);
1464 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1465 ASSERT_COMPARE(X, bytes, res, bytes);
1466
1467exit:
1468 mbedtls_free(X);
1469 mbedtls_free(res);
1470
1471 mbedtls_mpi_mod_modulus_free(&m);
1472 mbedtls_free(N);
1473}
1474/* END_CASE */
1475
Valerio Setti1a6d96f2023-03-24 14:10:24 +01001476/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001477void ecp_mod_p521_raw(char *input_N,
1478 char *input_X,
1479 char *result)
1480{
1481 mbedtls_mpi_uint *X = NULL;
1482 mbedtls_mpi_uint *N = NULL;
1483 mbedtls_mpi_uint *res = NULL;
1484 size_t limbs_X;
1485 size_t limbs_N;
1486 size_t limbs_res;
1487
1488 mbedtls_mpi_mod_modulus m;
1489 mbedtls_mpi_mod_modulus_init(&m);
1490
1491 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
1492 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
1493 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
1494
1495 size_t limbs = limbs_N;
1496 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
1497
Gabor Mezeicf228702023-02-15 16:52:33 +01001498 TEST_EQUAL(limbs_X, 2 * limbs);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001499 TEST_EQUAL(limbs_res, limbs);
1500
1501 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1502 &m, N, limbs,
1503 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
1504
Gabor Mezeib62ad5d2023-02-06 17:13:02 +01001505 TEST_EQUAL(mbedtls_ecp_mod_p521_raw(X, limbs_X), 0);
Gabor Mezei555b1f72023-02-15 17:13:20 +01001506 TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 522);
Gabor Mezeid8f67b92023-02-06 15:49:42 +01001507 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1508 ASSERT_COMPARE(X, bytes, res, bytes);
1509
1510exit:
1511 mbedtls_free(X);
1512 mbedtls_free(res);
1513
1514 mbedtls_mpi_mod_modulus_free(&m);
1515 mbedtls_free(N);
1516}
1517/* END_CASE */
Minos Galanakis9a1d02d2023-02-03 19:14:56 +00001518
1519/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
1520void ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1521{
1522 int ret;
1523 mbedtls_mpi_mod_modulus m;
1524 mbedtls_mpi_mod_modulus_init(&m);
1525 mbedtls_mpi_uint *p = NULL;
1526 size_t p_limbs;
1527 size_t bytes;
1528
1529 TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1530
1531 ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1532 TEST_EQUAL(ret, iret);
1533
1534 if (ret == 0) {
1535
1536 /* Test for limb sizes */
1537 TEST_EQUAL(m.limbs, p_limbs);
1538 bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1539
1540 /* Test for validity of moduli by the presence of Montgomery consts */
1541
1542 TEST_ASSERT(m.rep.mont.mm != 0);
1543 TEST_ASSERT(m.rep.mont.rr != NULL);
1544
1545
1546 /* Compare output byte-by-byte */
1547 ASSERT_COMPARE(p, bytes, m.p, bytes);
1548
1549 /* Test for user free-ing allocated memory */
1550 mbedtls_mpi_mod_modulus_free(&m);
1551 }
1552
1553exit:
1554 mbedtls_mpi_mod_modulus_free(&m);
1555 mbedtls_free(p);
1556}
1557/* END_CASE */