summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2025-01-05 16:07:08 +0000
committertb <>2025-01-05 16:07:08 +0000
commit2193869c42abbda84814f22a4ab38d0067921360 (patch)
tree01052cd554006bd8d0b366164df08e22b7dd6d57
parentdb85eb543d9f117c58266ef87044672cadbaa8be (diff)
downloadopenbsd-2193869c42abbda84814f22a4ab38d0067921360.tar.gz
openbsd-2193869c42abbda84814f22a4ab38d0067921360.tar.bz2
openbsd-2193869c42abbda84814f22a4ab38d0067921360.zip
Move BIGNUMs in EC_GROUP and EC_POINT to the heap
The only way to get an EC_GROUP or an EC_POINT is by calling the relevant _new() function and to get rid of it, something must call _free(). Thus we can establish the invariant that every group has Weierstrass coefficients p, a, b as well as order and cofactor hanging off it. Similarly, Every point has allocated BIGNUMs for its Jacobian projective coordinates. Unfortunately, a group has the generator as an optional component in addition to seed and montgomery context/one (where optionality makes more sense). This is a mostly mechanical diff and only drops a few silly comments and a couple of unnecessary NULL checks since in our part of the wrold the word invariant has a meaning. This should also appease Coverity who likes to throw fits at calling BN_free() for BIGNUM on the stack (yes, this is actually a thing). ok jsing
-rw-r--r--src/lib/libcrypto/ec/ec_convert.c12
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c97
-rw-r--r--src/lib/libcrypto/ec/ec_local.h23
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c4
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c266
5 files changed, 208 insertions, 194 deletions
diff --git a/src/lib/libcrypto/ec/ec_convert.c b/src/lib/libcrypto/ec/ec_convert.c
index b48fc85315..a18bc49132 100644
--- a/src/lib/libcrypto/ec/ec_convert.c
+++ b/src/lib/libcrypto/ec/ec_convert.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_convert.c,v 1.13 2024/12/16 06:11:26 tb Exp $ */ 1/* $OpenBSD: ec_convert.c,v 1.14 2025/01/05 16:07:08 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -157,11 +157,11 @@ ec_encoded_length(const EC_GROUP *group, uint8_t form, size_t *out_len)
157 *out_len = 1; 157 *out_len = 1;
158 return 1; 158 return 1;
159 case EC_POINT_COMPRESSED: 159 case EC_POINT_COMPRESSED:
160 *out_len = 1 + BN_num_bytes(&group->p); 160 *out_len = 1 + BN_num_bytes(group->p);
161 return 1; 161 return 1;
162 case EC_POINT_UNCOMPRESSED: 162 case EC_POINT_UNCOMPRESSED:
163 case EC_POINT_HYBRID: 163 case EC_POINT_HYBRID:
164 *out_len = 1 + 2 * BN_num_bytes(&group->p); 164 *out_len = 1 + 2 * BN_num_bytes(group->p);
165 return 1; 165 return 1;
166 default: 166 default:
167 return 0; 167 return 0;
@@ -172,14 +172,14 @@ static int
172ec_field_element_is_valid(const EC_GROUP *group, const BIGNUM *bn) 172ec_field_element_is_valid(const EC_GROUP *group, const BIGNUM *bn)
173{ 173{
174 /* Ensure bn is in the range [0, p). */ 174 /* Ensure bn is in the range [0, p). */
175 return !BN_is_negative(bn) && BN_cmp(&group->p, bn) > 0; 175 return !BN_is_negative(bn) && BN_cmp(group->p, bn) > 0;
176} 176}
177 177
178static int 178static int
179ec_add_field_element_cbb(CBB *cbb, const EC_GROUP *group, const BIGNUM *bn) 179ec_add_field_element_cbb(CBB *cbb, const EC_GROUP *group, const BIGNUM *bn)
180{ 180{
181 uint8_t *buf = NULL; 181 uint8_t *buf = NULL;
182 int buf_len = BN_num_bytes(&group->p); 182 int buf_len = BN_num_bytes(group->p);
183 183
184 if (!ec_field_element_is_valid(group, bn)) { 184 if (!ec_field_element_is_valid(group, bn)) {
185 ECerror(EC_R_BIGNUM_OUT_OF_RANGE); 185 ECerror(EC_R_BIGNUM_OUT_OF_RANGE);
@@ -202,7 +202,7 @@ ec_get_field_element_cbs(CBS *cbs, const EC_GROUP *group, BIGNUM *bn)
202{ 202{
203 CBS field_element; 203 CBS field_element;
204 204
205 if (!CBS_get_bytes(cbs, &field_element, BN_num_bytes(&group->p))) { 205 if (!CBS_get_bytes(cbs, &field_element, BN_num_bytes(group->p))) {
206 ECerror(EC_R_INVALID_ENCODING); 206 ECerror(EC_R_INVALID_ENCODING);
207 return 0; 207 return 0;
208 } 208 }
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 89d26e1177..d961ad0ee4 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_lib.c,v 1.93 2025/01/01 10:01:31 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.94 2025/01/05 16:07:08 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -94,6 +94,23 @@ EC_GROUP_new(const EC_METHOD *meth)
94 group->asn1_flag = OPENSSL_EC_NAMED_CURVE; 94 group->asn1_flag = OPENSSL_EC_NAMED_CURVE;
95 group->asn1_form = POINT_CONVERSION_UNCOMPRESSED; 95 group->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
96 96
97 if ((group->p = BN_new()) == NULL)
98 goto err;
99 if ((group->a = BN_new()) == NULL)
100 goto err;
101 if ((group->b = BN_new()) == NULL)
102 goto err;
103
104 if ((group->order = BN_new()) == NULL)
105 goto err;
106 if ((group->cofactor = BN_new()) == NULL)
107 goto err;
108
109 /*
110 * generator and seed are optional. mont_ctx, mont_one are only for
111 * curves using EC_GFp_mont_method()
112 */
113
97 return group; 114 return group;
98 115
99 err: 116 err:
@@ -109,16 +126,16 @@ EC_GROUP_free(EC_GROUP *group)
109 if (group == NULL) 126 if (group == NULL)
110 return; 127 return;
111 128
112 BN_free(&group->p); 129 BN_free(group->p);
113 BN_free(&group->a); 130 BN_free(group->a);
114 BN_free(&group->b); 131 BN_free(group->b);
115 132
116 BN_MONT_CTX_free(group->mont_ctx); 133 BN_MONT_CTX_free(group->mont_ctx);
117 BN_free(group->mont_one); 134 BN_free(group->mont_one);
118 135
119 EC_POINT_free(group->generator); 136 EC_POINT_free(group->generator);
120 BN_free(&group->order); 137 BN_free(group->order);
121 BN_free(&group->cofactor); 138 BN_free(group->cofactor);
122 139
123 freezero(group->seed, group->seed_len); 140 freezero(group->seed, group->seed_len);
124 freezero(group, sizeof *group); 141 freezero(group, sizeof *group);
@@ -152,14 +169,14 @@ EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
152 EC_POINT_free(dest->generator); 169 EC_POINT_free(dest->generator);
153 dest->generator = NULL; 170 dest->generator = NULL;
154 if (src->generator != NULL) { 171 if (src->generator != NULL) {
155 if (!EC_GROUP_set_generator(dest, src->generator, &src->order, 172 if (!EC_GROUP_set_generator(dest, src->generator, src->order,
156 &src->cofactor)) 173 src->cofactor))
157 return 0; 174 return 0;
158 } else { 175 } else {
159 /* XXX - should do the sanity checks as in set_generator() */ 176 /* XXX - should do the sanity checks as in set_generator() */
160 if (!bn_copy(&dest->order, &src->order)) 177 if (!bn_copy(dest->order, src->order))
161 return 0; 178 return 0;
162 if (!bn_copy(&dest->cofactor, &src->cofactor)) 179 if (!bn_copy(dest->cofactor, src->cofactor))
163 return 0; 180 return 0;
164 } 181 }
165 182
@@ -241,7 +258,7 @@ ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
241 BIGNUM *cofactor; 258 BIGNUM *cofactor;
242 int ret = 0; 259 int ret = 0;
243 260
244 BN_zero(&group->cofactor); 261 BN_zero(group->cofactor);
245 262
246 if ((ctx = BN_CTX_new()) == NULL) 263 if ((ctx = BN_CTX_new()) == NULL)
247 goto err; 264 goto err;
@@ -269,7 +286,7 @@ ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
269 * If the cofactor is too large, we cannot guess it and default to zero. 286 * If the cofactor is too large, we cannot guess it and default to zero.
270 * The RHS of below is a strict overestimate of log(4 * sqrt(p)). 287 * The RHS of below is a strict overestimate of log(4 * sqrt(p)).
271 */ 288 */
272 if (BN_num_bits(&group->order) <= (BN_num_bits(&group->p) + 1) / 2 + 3) 289 if (BN_num_bits(group->order) <= (BN_num_bits(group->p) + 1) / 2 + 3)
273 goto done; 290 goto done;
274 291
275 /* 292 /*
@@ -278,26 +295,26 @@ ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
278 */ 295 */
279 296
280 /* h = n/2 */ 297 /* h = n/2 */
281 if (!BN_rshift1(cofactor, &group->order)) 298 if (!BN_rshift1(cofactor, group->order))
282 goto err; 299 goto err;
283 /* h = 1 + n/2 */ 300 /* h = 1 + n/2 */
284 if (!BN_add_word(cofactor, 1)) 301 if (!BN_add_word(cofactor, 1))
285 goto err; 302 goto err;
286 /* h = p + 1 + n/2 */ 303 /* h = p + 1 + n/2 */
287 if (!BN_add(cofactor, cofactor, &group->p)) 304 if (!BN_add(cofactor, cofactor, group->p))
288 goto err; 305 goto err;
289 /* h = (p + 1 + n/2) / n */ 306 /* h = (p + 1 + n/2) / n */
290 if (!BN_div_ct(cofactor, NULL, cofactor, &group->order, ctx)) 307 if (!BN_div_ct(cofactor, NULL, cofactor, group->order, ctx))
291 goto err; 308 goto err;
292 309
293 done: 310 done:
294 /* Use Hasse's theorem to bound the cofactor. */ 311 /* Use Hasse's theorem to bound the cofactor. */
295 if (BN_num_bits(cofactor) > BN_num_bits(&group->p) + 1) { 312 if (BN_num_bits(cofactor) > BN_num_bits(group->p) + 1) {
296 ECerror(EC_R_INVALID_GROUP_ORDER); 313 ECerror(EC_R_INVALID_GROUP_ORDER);
297 goto err; 314 goto err;
298 } 315 }
299 316
300 if (!bn_copy(&group->cofactor, cofactor)) 317 if (!bn_copy(group->cofactor, cofactor))
301 goto err; 318 goto err;
302 319
303 ret = 1; 320 ret = 1;
@@ -319,7 +336,7 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
319 } 336 }
320 337
321 /* Require p >= 1. */ 338 /* Require p >= 1. */
322 if (BN_is_zero(&group->p) || BN_is_negative(&group->p)) { 339 if (BN_is_zero(group->p) || BN_is_negative(group->p)) {
323 ECerror(EC_R_INVALID_FIELD); 340 ECerror(EC_R_INVALID_FIELD);
324 return 0; 341 return 0;
325 } 342 }
@@ -329,7 +346,7 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
329 * than the field cardinality due to Hasse's theorem. 346 * than the field cardinality due to Hasse's theorem.
330 */ 347 */
331 if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 || 348 if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 ||
332 BN_num_bits(order) > BN_num_bits(&group->p) + 1) { 349 BN_num_bits(order) > BN_num_bits(group->p) + 1) {
333 ECerror(EC_R_INVALID_GROUP_ORDER); 350 ECerror(EC_R_INVALID_GROUP_ORDER);
334 return 0; 351 return 0;
335 } 352 }
@@ -342,7 +359,7 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
342 if (!EC_POINT_copy(group->generator, generator)) 359 if (!EC_POINT_copy(group->generator, generator))
343 return 0; 360 return 0;
344 361
345 if (!bn_copy(&group->order, order)) 362 if (!bn_copy(group->order, order))
346 return 0; 363 return 0;
347 364
348 if (!ec_set_cofactor(group, cofactor)) 365 if (!ec_set_cofactor(group, cofactor))
@@ -362,7 +379,7 @@ LCRYPTO_ALIAS(EC_GROUP_get0_generator);
362int 379int
363EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) 380EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
364{ 381{
365 if (!bn_copy(order, &group->order)) 382 if (!bn_copy(order, group->order))
366 return 0; 383 return 0;
367 384
368 return !BN_is_zero(order); 385 return !BN_is_zero(order);
@@ -372,7 +389,7 @@ LCRYPTO_ALIAS(EC_GROUP_get_order);
372const BIGNUM * 389const BIGNUM *
373EC_GROUP_get0_order(const EC_GROUP *group) 390EC_GROUP_get0_order(const EC_GROUP *group)
374{ 391{
375 return &group->order; 392 return group->order;
376} 393}
377 394
378int 395int
@@ -385,17 +402,17 @@ LCRYPTO_ALIAS(EC_GROUP_order_bits);
385int 402int
386EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) 403EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
387{ 404{
388 if (!bn_copy(cofactor, &group->cofactor)) 405 if (!bn_copy(cofactor, group->cofactor))
389 return 0; 406 return 0;
390 407
391 return !BN_is_zero(&group->cofactor); 408 return !BN_is_zero(group->cofactor);
392} 409}
393LCRYPTO_ALIAS(EC_GROUP_get_cofactor); 410LCRYPTO_ALIAS(EC_GROUP_get_cofactor);
394 411
395const BIGNUM * 412const BIGNUM *
396EC_GROUP_get0_cofactor(const EC_GROUP *group) 413EC_GROUP_get0_cofactor(const EC_GROUP *group)
397{ 414{
398 return &group->cofactor; 415 return group->cofactor;
399} 416}
400 417
401void 418void
@@ -784,6 +801,13 @@ EC_POINT_new(const EC_GROUP *group)
784 goto err; 801 goto err;
785 } 802 }
786 803
804 if ((point->X = BN_new()) == NULL)
805 goto err;
806 if ((point->Y = BN_new()) == NULL)
807 goto err;
808 if ((point->Z = BN_new()) == NULL)
809 goto err;
810
787 point->meth = group->meth; 811 point->meth = group->meth;
788 812
789 return point; 813 return point;
@@ -801,9 +825,9 @@ EC_POINT_free(EC_POINT *point)
801 if (point == NULL) 825 if (point == NULL)
802 return; 826 return;
803 827
804 BN_free(&point->X); 828 BN_free(point->X);
805 BN_free(&point->Y); 829 BN_free(point->Y);
806 BN_free(&point->Z); 830 BN_free(point->Z);
807 831
808 freezero(point, sizeof *point); 832 freezero(point, sizeof *point);
809} 833}
@@ -826,11 +850,11 @@ EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
826 if (dest == src) 850 if (dest == src)
827 return 1; 851 return 1;
828 852
829 if (!bn_copy(&dest->X, &src->X)) 853 if (!bn_copy(dest->X, src->X))
830 return 0; 854 return 0;
831 if (!bn_copy(&dest->Y, &src->Y)) 855 if (!bn_copy(dest->Y, src->Y))
832 return 0; 856 return 0;
833 if (!bn_copy(&dest->Z, &src->Z)) 857 if (!bn_copy(dest->Z, src->Z))
834 return 0; 858 return 0;
835 dest->Z_is_one = src->Z_is_one; 859 dest->Z_is_one = src->Z_is_one;
836 860
@@ -876,7 +900,7 @@ EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
876 return 0; 900 return 0;
877 } 901 }
878 902
879 BN_zero(&point->Z); 903 BN_zero(point->Z);
880 point->Z_is_one = 0; 904 point->Z_is_one = 0;
881 905
882 return 1; 906 return 1;
@@ -1193,7 +1217,7 @@ EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1193 return 0; 1217 return 0;
1194 } 1218 }
1195 1219
1196 return BN_is_zero(&point->Z); 1220 return BN_is_zero(point->Z);
1197} 1221}
1198LCRYPTO_ALIAS(EC_POINT_is_at_infinity); 1222LCRYPTO_ALIAS(EC_POINT_is_at_infinity);
1199 1223
@@ -1440,10 +1464,5 @@ LCRYPTO_ALIAS(EC_GROUP_have_precompute_mult);
1440int 1464int
1441ec_group_simple_order_bits(const EC_GROUP *group) 1465ec_group_simple_order_bits(const EC_GROUP *group)
1442{ 1466{
1443 /* XXX change group->order to a pointer? */ 1467 return BN_num_bits(group->order);
1444#if 0
1445 if (group->order == NULL)
1446 return 0;
1447#endif
1448 return BN_num_bits(&group->order);
1449} 1468}
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index cc918b38fd..0d734351de 100644
--- a/src/lib/libcrypto/ec/ec_local.h
+++ b/src/lib/libcrypto/ec/ec_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_local.h,v 1.45 2025/01/01 10:01:31 tb Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.46 2025/01/05 16:07:08 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -160,8 +160,8 @@ struct ec_group_st {
160 const EC_METHOD *meth; 160 const EC_METHOD *meth;
161 161
162 EC_POINT *generator; /* Optional */ 162 EC_POINT *generator; /* Optional */
163 BIGNUM order; 163 BIGNUM *order;
164 BIGNUM cofactor; 164 BIGNUM *cofactor;
165 165
166 int nid; /* Optional NID for named curve. */ 166 int nid; /* Optional NID for named curve. */
167 167
@@ -181,9 +181,9 @@ struct ec_group_st {
181 /* 181 /*
182 * Coefficients of the Weierstrass equation y^2 = x^3 + a*x + b (mod p). 182 * Coefficients of the Weierstrass equation y^2 = x^3 + a*x + b (mod p).
183 */ 183 */
184 BIGNUM p; 184 BIGNUM *p;
185 BIGNUM a; 185 BIGNUM *a;
186 BIGNUM b; 186 BIGNUM *b;
187 187
188 /* Enables optimized point arithmetics for special case. */ 188 /* Enables optimized point arithmetics for special case. */
189 int a_is_minus3; 189 int a_is_minus3;
@@ -216,17 +216,12 @@ struct ec_point_st {
216 const EC_METHOD *meth; 216 const EC_METHOD *meth;
217 217
218 /* 218 /*
219 * All members except 'meth' are handled by the method functions,
220 * even if they appear generic.
221 */
222
223 /*
224 * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3) 219 * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3)
225 * if Z != 0 220 * if Z != 0
226 */ 221 */
227 BIGNUM X; 222 BIGNUM *X;
228 BIGNUM Y; 223 BIGNUM *Y;
229 BIGNUM Z; 224 BIGNUM *Z;
230 int Z_is_one; /* enable optimized point arithmetics for special case */ 225 int Z_is_one; /* enable optimized point arithmetics for special case */
231} /* EC_POINT */; 226} /* EC_POINT */;
232 227
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
index 424d1896b2..6d74a7f8a4 100644
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ b/src/lib/libcrypto/ec/ec_pmeth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_pmeth.c,v 1.23 2024/10/19 14:41:03 tb Exp $ */ 1/* $OpenBSD: ec_pmeth.c,v 1.24 2025/01/05 16:07:08 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -323,7 +323,7 @@ pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
323 if (!ec_key->group) 323 if (!ec_key->group)
324 return -2; 324 return -2;
325 /* If cofactor is 1 cofactor mode does nothing */ 325 /* If cofactor is 1 cofactor mode does nothing */
326 if (BN_is_one(&ec_key->group->cofactor)) 326 if (BN_is_one(ec_key->group->cofactor))
327 return 1; 327 return 1;
328 if (!dctx->co_key) { 328 if (!dctx->co_key) {
329 dctx->co_key = EC_KEY_dup(ec_key); 329 dctx->co_key = EC_KEY_dup(ec_key);
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index af19addab4..b2ecc7e17a 100644
--- a/src/lib/libcrypto/ec/ecp_methods.c
+++ b/src/lib/libcrypto/ec/ecp_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_methods.c,v 1.17 2025/01/01 10:01:31 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.18 2025/01/05 16:07:08 tb Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project. 4 * Includes code written by Bodo Moeller for the OpenSSL project.
@@ -87,11 +87,11 @@
87static int 87static int
88ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) 88ec_group_copy(EC_GROUP *dest, const EC_GROUP *src)
89{ 89{
90 if (!bn_copy(&dest->p, &src->p)) 90 if (!bn_copy(dest->p, src->p))
91 return 0; 91 return 0;
92 if (!bn_copy(&dest->a, &src->a)) 92 if (!bn_copy(dest->a, src->a))
93 return 0; 93 return 0;
94 if (!bn_copy(&dest->b, &src->b)) 94 if (!bn_copy(dest->b, src->b))
95 return 0; 95 return 0;
96 96
97 dest->a_is_minus3 = src->a_is_minus3; 97 dest->a_is_minus3 = src->a_is_minus3;
@@ -114,7 +114,7 @@ ec_decode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx
114static int 114static int
115ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx) 115ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx)
116{ 116{
117 if (!BN_nnmod(bn, x, &group->p, ctx)) 117 if (!BN_nnmod(bn, x, group->p, ctx))
118 return 0; 118 return 0;
119 119
120 if (group->meth->field_encode != NULL) 120 if (group->meth->field_encode != NULL)
@@ -127,7 +127,7 @@ static int
127ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one, 127ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one,
128 const BIGNUM *z, BN_CTX *ctx) 128 const BIGNUM *z, BN_CTX *ctx)
129{ 129{
130 if (!BN_nnmod(bn, z, &group->p, ctx)) 130 if (!BN_nnmod(bn, z, group->p, ctx))
131 return 0; 131 return 0;
132 132
133 *is_one = BN_is_one(bn); 133 *is_one = BN_is_one(bn);
@@ -158,18 +158,18 @@ ec_group_set_curve(EC_GROUP *group,
158 if ((a_plus_3 = BN_CTX_get(ctx)) == NULL) 158 if ((a_plus_3 = BN_CTX_get(ctx)) == NULL)
159 goto err; 159 goto err;
160 160
161 if (!bn_copy(&group->p, p)) 161 if (!bn_copy(group->p, p))
162 goto err; 162 goto err;
163 BN_set_negative(&group->p, 0); 163 BN_set_negative(group->p, 0);
164 164
165 if (!ec_encode_scalar(group, &group->a, a, ctx)) 165 if (!ec_encode_scalar(group, group->a, a, ctx))
166 goto err; 166 goto err;
167 if (!ec_encode_scalar(group, &group->b, b, ctx)) 167 if (!ec_encode_scalar(group, group->b, b, ctx))
168 goto err; 168 goto err;
169 169
170 if (!BN_set_word(a_plus_3, 3)) 170 if (!BN_set_word(a_plus_3, 3))
171 goto err; 171 goto err;
172 if (!BN_mod_add(a_plus_3, a_plus_3, a, &group->p, ctx)) 172 if (!BN_mod_add(a_plus_3, a_plus_3, a, group->p, ctx))
173 goto err; 173 goto err;
174 174
175 group->a_is_minus3 = BN_is_zero(a_plus_3); 175 group->a_is_minus3 = BN_is_zero(a_plus_3);
@@ -187,12 +187,12 @@ ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
187 BN_CTX *ctx) 187 BN_CTX *ctx)
188{ 188{
189 if (p != NULL) { 189 if (p != NULL) {
190 if (!bn_copy(p, &group->p)) 190 if (!bn_copy(p, group->p))
191 return 0; 191 return 0;
192 } 192 }
193 if (!ec_decode_scalar(group, a, &group->a, ctx)) 193 if (!ec_decode_scalar(group, a, group->a, ctx))
194 return 0; 194 return 0;
195 if (!ec_decode_scalar(group, b, &group->b, ctx)) 195 if (!ec_decode_scalar(group, b, group->b, ctx))
196 return 0; 196 return 0;
197 197
198 return 1; 198 return 1;
@@ -201,7 +201,7 @@ ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
201static int 201static int
202ec_group_get_degree(const EC_GROUP *group) 202ec_group_get_degree(const EC_GROUP *group)
203{ 203{
204 return BN_num_bits(&group->p); 204 return BN_num_bits(group->p);
205} 205}
206 206
207static int 207static int
@@ -273,15 +273,15 @@ ec_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point,
273 */ 273 */
274 274
275 if (x != NULL) { 275 if (x != NULL) {
276 if (!ec_encode_scalar(group, &point->X, x, ctx)) 276 if (!ec_encode_scalar(group, point->X, x, ctx))
277 goto err; 277 goto err;
278 } 278 }
279 if (y != NULL) { 279 if (y != NULL) {
280 if (!ec_encode_scalar(group, &point->Y, y, ctx)) 280 if (!ec_encode_scalar(group, point->Y, y, ctx))
281 goto err; 281 goto err;
282 } 282 }
283 if (z != NULL) { 283 if (z != NULL) {
284 if (!ec_encode_z_coordinate(group, &point->Z, &point->Z_is_one, 284 if (!ec_encode_z_coordinate(group, point->Z, &point->Z_is_one,
285 z, ctx)) 285 z, ctx))
286 goto err; 286 goto err;
287 } 287 }
@@ -298,11 +298,11 @@ ec_get_Jprojective_coordinates(const EC_GROUP *group, const EC_POINT *point,
298{ 298{
299 int ret = 0; 299 int ret = 0;
300 300
301 if (!ec_decode_scalar(group, x, &point->X, ctx)) 301 if (!ec_decode_scalar(group, x, point->X, ctx))
302 goto err; 302 goto err;
303 if (!ec_decode_scalar(group, y, &point->Y, ctx)) 303 if (!ec_decode_scalar(group, y, point->Y, ctx))
304 goto err; 304 goto err;
305 if (!ec_decode_scalar(group, z, &point->Z, ctx)) 305 if (!ec_decode_scalar(group, z, point->Z, ctx))
306 goto err; 306 goto err;
307 307
308 ret = 1; 308 ret = 1;
@@ -346,18 +346,18 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
346 346
347 /* Convert from projective coordinates (X, Y, Z) into (X/Z^2, Y/Z^3). */ 347 /* Convert from projective coordinates (X, Y, Z) into (X/Z^2, Y/Z^3). */
348 348
349 if (!ec_decode_scalar(group, z, &point->Z, ctx)) 349 if (!ec_decode_scalar(group, z, point->Z, ctx))
350 goto err; 350 goto err;
351 351
352 if (BN_is_one(z)) { 352 if (BN_is_one(z)) {
353 if (!ec_decode_scalar(group, x, &point->X, ctx)) 353 if (!ec_decode_scalar(group, x, point->X, ctx))
354 goto err; 354 goto err;
355 if (!ec_decode_scalar(group, y, &point->Y, ctx)) 355 if (!ec_decode_scalar(group, y, point->Y, ctx))
356 goto err; 356 goto err;
357 goto done; 357 goto done;
358 } 358 }
359 359
360 if (BN_mod_inverse_ct(Z_1, z, &group->p, ctx) == NULL) { 360 if (BN_mod_inverse_ct(Z_1, z, group->p, ctx) == NULL) {
361 ECerror(ERR_R_BN_LIB); 361 ECerror(ERR_R_BN_LIB);
362 goto err; 362 goto err;
363 } 363 }
@@ -366,7 +366,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
366 if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) 366 if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
367 goto err; 367 goto err;
368 } else { 368 } else {
369 if (!BN_mod_sqr(Z_2, Z_1, &group->p, ctx)) 369 if (!BN_mod_sqr(Z_2, Z_1, group->p, ctx))
370 goto err; 370 goto err;
371 } 371 }
372 372
@@ -375,7 +375,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
375 * in the Montgomery case, field_mul will cancel out 375 * in the Montgomery case, field_mul will cancel out
376 * Montgomery factor in X: 376 * Montgomery factor in X:
377 */ 377 */
378 if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) 378 if (!group->meth->field_mul(group, x, point->X, Z_2, ctx))
379 goto err; 379 goto err;
380 } 380 }
381 if (y != NULL) { 381 if (y != NULL) {
@@ -384,7 +384,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
384 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) 384 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
385 goto err; 385 goto err;
386 } else { 386 } else {
387 if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->p, ctx)) 387 if (!BN_mod_mul(Z_3, Z_2, Z_1, group->p, ctx))
388 goto err; 388 goto err;
389 } 389 }
390 390
@@ -392,7 +392,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
392 * in the Montgomery case, field_mul will cancel out 392 * in the Montgomery case, field_mul will cancel out
393 * Montgomery factor in Y: 393 * Montgomery factor in Y:
394 */ 394 */
395 if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) 395 if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx))
396 goto err; 396 goto err;
397 } 397 }
398 398
@@ -409,7 +409,7 @@ static int
409ec_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 409ec_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
410 const BIGNUM *in_x, int y_bit, BN_CTX *ctx) 410 const BIGNUM *in_x, int y_bit, BN_CTX *ctx)
411{ 411{
412 const BIGNUM *p = &group->p, *a = &group->a, *b = &group->b; 412 const BIGNUM *p = group->p, *a = group->a, *b = group->b;
413 BIGNUM *w, *x, *y; 413 BIGNUM *w, *x, *y;
414 int ret = 0; 414 int ret = 0;
415 415
@@ -522,7 +522,7 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
522 522
523 field_mul = group->meth->field_mul; 523 field_mul = group->meth->field_mul;
524 field_sqr = group->meth->field_sqr; 524 field_sqr = group->meth->field_sqr;
525 p = &group->p; 525 p = group->p;
526 526
527 BN_CTX_start(ctx); 527 BN_CTX_start(ctx);
528 528
@@ -549,44 +549,44 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
549 549
550 /* n1, n2 */ 550 /* n1, n2 */
551 if (b->Z_is_one) { 551 if (b->Z_is_one) {
552 if (!bn_copy(n1, &a->X)) 552 if (!bn_copy(n1, a->X))
553 goto end; 553 goto end;
554 if (!bn_copy(n2, &a->Y)) 554 if (!bn_copy(n2, a->Y))
555 goto end; 555 goto end;
556 /* n1 = X_a */ 556 /* n1 = X_a */
557 /* n2 = Y_a */ 557 /* n2 = Y_a */
558 } else { 558 } else {
559 if (!field_sqr(group, n0, &b->Z, ctx)) 559 if (!field_sqr(group, n0, b->Z, ctx))
560 goto end; 560 goto end;
561 if (!field_mul(group, n1, &a->X, n0, ctx)) 561 if (!field_mul(group, n1, a->X, n0, ctx))
562 goto end; 562 goto end;
563 /* n1 = X_a * Z_b^2 */ 563 /* n1 = X_a * Z_b^2 */
564 564
565 if (!field_mul(group, n0, n0, &b->Z, ctx)) 565 if (!field_mul(group, n0, n0, b->Z, ctx))
566 goto end; 566 goto end;
567 if (!field_mul(group, n2, &a->Y, n0, ctx)) 567 if (!field_mul(group, n2, a->Y, n0, ctx))
568 goto end; 568 goto end;
569 /* n2 = Y_a * Z_b^3 */ 569 /* n2 = Y_a * Z_b^3 */
570 } 570 }
571 571
572 /* n3, n4 */ 572 /* n3, n4 */
573 if (a->Z_is_one) { 573 if (a->Z_is_one) {
574 if (!bn_copy(n3, &b->X)) 574 if (!bn_copy(n3, b->X))
575 goto end; 575 goto end;
576 if (!bn_copy(n4, &b->Y)) 576 if (!bn_copy(n4, b->Y))
577 goto end; 577 goto end;
578 /* n3 = X_b */ 578 /* n3 = X_b */
579 /* n4 = Y_b */ 579 /* n4 = Y_b */
580 } else { 580 } else {
581 if (!field_sqr(group, n0, &a->Z, ctx)) 581 if (!field_sqr(group, n0, a->Z, ctx))
582 goto end; 582 goto end;
583 if (!field_mul(group, n3, &b->X, n0, ctx)) 583 if (!field_mul(group, n3, b->X, n0, ctx))
584 goto end; 584 goto end;
585 /* n3 = X_b * Z_a^2 */ 585 /* n3 = X_b * Z_a^2 */
586 586
587 if (!field_mul(group, n0, n0, &a->Z, ctx)) 587 if (!field_mul(group, n0, n0, a->Z, ctx))
588 goto end; 588 goto end;
589 if (!field_mul(group, n4, &b->Y, n0, ctx)) 589 if (!field_mul(group, n4, b->Y, n0, ctx))
590 goto end; 590 goto end;
591 /* n4 = Y_b * Z_a^3 */ 591 /* n4 = Y_b * Z_a^3 */
592 } 592 }
@@ -608,7 +608,7 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
608 goto end; 608 goto end;
609 } else { 609 } else {
610 /* a is the inverse of b */ 610 /* a is the inverse of b */
611 BN_zero(&r->Z); 611 BN_zero(r->Z);
612 r->Z_is_one = 0; 612 r->Z_is_one = 0;
613 ret = 1; 613 ret = 1;
614 goto end; 614 goto end;
@@ -624,20 +624,20 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
624 624
625 /* Z_r */ 625 /* Z_r */
626 if (a->Z_is_one && b->Z_is_one) { 626 if (a->Z_is_one && b->Z_is_one) {
627 if (!bn_copy(&r->Z, n5)) 627 if (!bn_copy(r->Z, n5))
628 goto end; 628 goto end;
629 } else { 629 } else {
630 if (a->Z_is_one) { 630 if (a->Z_is_one) {
631 if (!bn_copy(n0, &b->Z)) 631 if (!bn_copy(n0, b->Z))
632 goto end; 632 goto end;
633 } else if (b->Z_is_one) { 633 } else if (b->Z_is_one) {
634 if (!bn_copy(n0, &a->Z)) 634 if (!bn_copy(n0, a->Z))
635 goto end; 635 goto end;
636 } else { 636 } else {
637 if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) 637 if (!field_mul(group, n0, a->Z, b->Z, ctx))
638 goto end; 638 goto end;
639 } 639 }
640 if (!field_mul(group, &r->Z, n0, n5, ctx)) 640 if (!field_mul(group, r->Z, n0, n5, ctx))
641 goto end; 641 goto end;
642 } 642 }
643 r->Z_is_one = 0; 643 r->Z_is_one = 0;
@@ -650,12 +650,12 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
650 goto end; 650 goto end;
651 if (!field_mul(group, n3, n1, n4, ctx)) 651 if (!field_mul(group, n3, n1, n4, ctx))
652 goto end; 652 goto end;
653 if (!BN_mod_sub_quick(&r->X, n0, n3, p)) 653 if (!BN_mod_sub_quick(r->X, n0, n3, p))
654 goto end; 654 goto end;
655 /* X_r = n6^2 - n5^2 * 'n7' */ 655 /* X_r = n6^2 - n5^2 * 'n7' */
656 656
657 /* 'n9' */ 657 /* 'n9' */
658 if (!BN_mod_lshift1_quick(n0, &r->X, p)) 658 if (!BN_mod_lshift1_quick(n0, r->X, p))
659 goto end; 659 goto end;
660 if (!BN_mod_sub_quick(n0, n3, n0, p)) 660 if (!BN_mod_sub_quick(n0, n3, n0, p))
661 goto end; 661 goto end;
@@ -674,7 +674,7 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
674 if (!BN_add(n0, n0, p)) 674 if (!BN_add(n0, n0, p))
675 goto end; 675 goto end;
676 /* now 0 <= n0 < 2*p, and n0 is even */ 676 /* now 0 <= n0 < 2*p, and n0 is even */
677 if (!BN_rshift1(&r->Y, n0)) 677 if (!BN_rshift1(r->Y, n0))
678 goto end; 678 goto end;
679 /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ 679 /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
680 680
@@ -700,7 +700,7 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
700 700
701 field_mul = group->meth->field_mul; 701 field_mul = group->meth->field_mul;
702 field_sqr = group->meth->field_sqr; 702 field_sqr = group->meth->field_sqr;
703 p = &group->p; 703 p = group->p;
704 704
705 BN_CTX_start(ctx); 705 BN_CTX_start(ctx);
706 706
@@ -721,21 +721,21 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
721 721
722 /* n1 */ 722 /* n1 */
723 if (a->Z_is_one) { 723 if (a->Z_is_one) {
724 if (!field_sqr(group, n0, &a->X, ctx)) 724 if (!field_sqr(group, n0, a->X, ctx))
725 goto err; 725 goto err;
726 if (!BN_mod_lshift1_quick(n1, n0, p)) 726 if (!BN_mod_lshift1_quick(n1, n0, p))
727 goto err; 727 goto err;
728 if (!BN_mod_add_quick(n0, n0, n1, p)) 728 if (!BN_mod_add_quick(n0, n0, n1, p))
729 goto err; 729 goto err;
730 if (!BN_mod_add_quick(n1, n0, &group->a, p)) 730 if (!BN_mod_add_quick(n1, n0, group->a, p))
731 goto err; 731 goto err;
732 /* n1 = 3 * X_a^2 + a_curve */ 732 /* n1 = 3 * X_a^2 + a_curve */
733 } else if (group->a_is_minus3) { 733 } else if (group->a_is_minus3) {
734 if (!field_sqr(group, n1, &a->Z, ctx)) 734 if (!field_sqr(group, n1, a->Z, ctx))
735 goto err; 735 goto err;
736 if (!BN_mod_add_quick(n0, &a->X, n1, p)) 736 if (!BN_mod_add_quick(n0, a->X, n1, p))
737 goto err; 737 goto err;
738 if (!BN_mod_sub_quick(n2, &a->X, n1, p)) 738 if (!BN_mod_sub_quick(n2, a->X, n1, p))
739 goto err; 739 goto err;
740 if (!field_mul(group, n1, n0, n2, ctx)) 740 if (!field_mul(group, n1, n0, n2, ctx))
741 goto err; 741 goto err;
@@ -748,17 +748,17 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
748 * Z_a^4 748 * Z_a^4
749 */ 749 */
750 } else { 750 } else {
751 if (!field_sqr(group, n0, &a->X, ctx)) 751 if (!field_sqr(group, n0, a->X, ctx))
752 goto err; 752 goto err;
753 if (!BN_mod_lshift1_quick(n1, n0, p)) 753 if (!BN_mod_lshift1_quick(n1, n0, p))
754 goto err; 754 goto err;
755 if (!BN_mod_add_quick(n0, n0, n1, p)) 755 if (!BN_mod_add_quick(n0, n0, n1, p))
756 goto err; 756 goto err;
757 if (!field_sqr(group, n1, &a->Z, ctx)) 757 if (!field_sqr(group, n1, a->Z, ctx))
758 goto err; 758 goto err;
759 if (!field_sqr(group, n1, n1, ctx)) 759 if (!field_sqr(group, n1, n1, ctx))
760 goto err; 760 goto err;
761 if (!field_mul(group, n1, n1, &group->a, ctx)) 761 if (!field_mul(group, n1, n1, group->a, ctx))
762 goto err; 762 goto err;
763 if (!BN_mod_add_quick(n1, n1, n0, p)) 763 if (!BN_mod_add_quick(n1, n1, n0, p))
764 goto err; 764 goto err;
@@ -767,21 +767,21 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
767 767
768 /* Z_r */ 768 /* Z_r */
769 if (a->Z_is_one) { 769 if (a->Z_is_one) {
770 if (!bn_copy(n0, &a->Y)) 770 if (!bn_copy(n0, a->Y))
771 goto err; 771 goto err;
772 } else { 772 } else {
773 if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) 773 if (!field_mul(group, n0, a->Y, a->Z, ctx))
774 goto err; 774 goto err;
775 } 775 }
776 if (!BN_mod_lshift1_quick(&r->Z, n0, p)) 776 if (!BN_mod_lshift1_quick(r->Z, n0, p))
777 goto err; 777 goto err;
778 r->Z_is_one = 0; 778 r->Z_is_one = 0;
779 /* Z_r = 2 * Y_a * Z_a */ 779 /* Z_r = 2 * Y_a * Z_a */
780 780
781 /* n2 */ 781 /* n2 */
782 if (!field_sqr(group, n3, &a->Y, ctx)) 782 if (!field_sqr(group, n3, a->Y, ctx))
783 goto err; 783 goto err;
784 if (!field_mul(group, n2, &a->X, n3, ctx)) 784 if (!field_mul(group, n2, a->X, n3, ctx))
785 goto err; 785 goto err;
786 if (!BN_mod_lshift_quick(n2, n2, 2, p)) 786 if (!BN_mod_lshift_quick(n2, n2, 2, p))
787 goto err; 787 goto err;
@@ -790,9 +790,9 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
790 /* X_r */ 790 /* X_r */
791 if (!BN_mod_lshift1_quick(n0, n2, p)) 791 if (!BN_mod_lshift1_quick(n0, n2, p))
792 goto err; 792 goto err;
793 if (!field_sqr(group, &r->X, n1, ctx)) 793 if (!field_sqr(group, r->X, n1, ctx))
794 goto err; 794 goto err;
795 if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) 795 if (!BN_mod_sub_quick(r->X, r->X, n0, p))
796 goto err; 796 goto err;
797 /* X_r = n1^2 - 2 * n2 */ 797 /* X_r = n1^2 - 2 * n2 */
798 798
@@ -804,11 +804,11 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
804 /* n3 = 8 * Y_a^4 */ 804 /* n3 = 8 * Y_a^4 */
805 805
806 /* Y_r */ 806 /* Y_r */
807 if (!BN_mod_sub_quick(n0, n2, &r->X, p)) 807 if (!BN_mod_sub_quick(n0, n2, r->X, p))
808 goto err; 808 goto err;
809 if (!field_mul(group, n0, n1, n0, ctx)) 809 if (!field_mul(group, n0, n1, n0, ctx))
810 goto err; 810 goto err;
811 if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) 811 if (!BN_mod_sub_quick(r->Y, n0, n3, p))
812 goto err; 812 goto err;
813 /* Y_r = n1 * (n2 - X_r) - n3 */ 813 /* Y_r = n1 * (n2 - X_r) - n3 */
814 814
@@ -823,11 +823,11 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
823static int 823static int
824ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 824ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
825{ 825{
826 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) 826 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
827 /* point is its own inverse */ 827 /* point is its own inverse */
828 return 1; 828 return 1;
829 829
830 return BN_usub(&point->Y, &group->p, &point->Y); 830 return BN_usub(point->Y, group->p, point->Y);
831} 831}
832 832
833static int 833static int
@@ -844,7 +844,7 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
844 844
845 field_mul = group->meth->field_mul; 845 field_mul = group->meth->field_mul;
846 field_sqr = group->meth->field_sqr; 846 field_sqr = group->meth->field_sqr;
847 p = &group->p; 847 p = group->p;
848 848
849 BN_CTX_start(ctx); 849 BN_CTX_start(ctx);
850 850
@@ -867,11 +867,11 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
867 */ 867 */
868 868
869 /* rh := X^2 */ 869 /* rh := X^2 */
870 if (!field_sqr(group, rh, &point->X, ctx)) 870 if (!field_sqr(group, rh, point->X, ctx))
871 goto err; 871 goto err;
872 872
873 if (!point->Z_is_one) { 873 if (!point->Z_is_one) {
874 if (!field_sqr(group, tmp, &point->Z, ctx)) 874 if (!field_sqr(group, tmp, point->Z, ctx))
875 goto err; 875 goto err;
876 if (!field_sqr(group, Z4, tmp, ctx)) 876 if (!field_sqr(group, Z4, tmp, ctx))
877 goto err; 877 goto err;
@@ -886,19 +886,19 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
886 goto err; 886 goto err;
887 if (!BN_mod_sub_quick(rh, rh, tmp, p)) 887 if (!BN_mod_sub_quick(rh, rh, tmp, p))
888 goto err; 888 goto err;
889 if (!field_mul(group, rh, rh, &point->X, ctx)) 889 if (!field_mul(group, rh, rh, point->X, ctx))
890 goto err; 890 goto err;
891 } else { 891 } else {
892 if (!field_mul(group, tmp, Z4, &group->a, ctx)) 892 if (!field_mul(group, tmp, Z4, group->a, ctx))
893 goto err; 893 goto err;
894 if (!BN_mod_add_quick(rh, rh, tmp, p)) 894 if (!BN_mod_add_quick(rh, rh, tmp, p))
895 goto err; 895 goto err;
896 if (!field_mul(group, rh, rh, &point->X, ctx)) 896 if (!field_mul(group, rh, rh, point->X, ctx))
897 goto err; 897 goto err;
898 } 898 }
899 899
900 /* rh := rh + b*Z^6 */ 900 /* rh := rh + b*Z^6 */
901 if (!field_mul(group, tmp, &group->b, Z6, ctx)) 901 if (!field_mul(group, tmp, group->b, Z6, ctx))
902 goto err; 902 goto err;
903 if (!BN_mod_add_quick(rh, rh, tmp, p)) 903 if (!BN_mod_add_quick(rh, rh, tmp, p))
904 goto err; 904 goto err;
@@ -906,17 +906,17 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
906 /* point->Z_is_one */ 906 /* point->Z_is_one */
907 907
908 /* rh := (rh + a)*X */ 908 /* rh := (rh + a)*X */
909 if (!BN_mod_add_quick(rh, rh, &group->a, p)) 909 if (!BN_mod_add_quick(rh, rh, group->a, p))
910 goto err; 910 goto err;
911 if (!field_mul(group, rh, rh, &point->X, ctx)) 911 if (!field_mul(group, rh, rh, point->X, ctx))
912 goto err; 912 goto err;
913 /* rh := rh + b */ 913 /* rh := rh + b */
914 if (!BN_mod_add_quick(rh, rh, &group->b, p)) 914 if (!BN_mod_add_quick(rh, rh, group->b, p))
915 goto err; 915 goto err;
916 } 916 }
917 917
918 /* 'lh' := Y^2 */ 918 /* 'lh' := Y^2 */
919 if (!field_sqr(group, tmp, &point->Y, ctx)) 919 if (!field_sqr(group, tmp, point->Y, ctx))
920 goto err; 920 goto err;
921 921
922 ret = (0 == BN_ucmp(tmp, rh)); 922 ret = (0 == BN_ucmp(tmp, rh));
@@ -946,7 +946,7 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
946 return 1; 946 return 1;
947 947
948 if (a->Z_is_one && b->Z_is_one) 948 if (a->Z_is_one && b->Z_is_one)
949 return BN_cmp(&a->X, &b->X) != 0 || BN_cmp(&a->Y, &b->Y) != 0; 949 return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
950 950
951 field_mul = group->meth->field_mul; 951 field_mul = group->meth->field_mul;
952 field_sqr = group->meth->field_sqr; 952 field_sqr = group->meth->field_sqr;
@@ -969,21 +969,21 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
969 */ 969 */
970 970
971 if (!b->Z_is_one) { 971 if (!b->Z_is_one) {
972 if (!field_sqr(group, Zb23, &b->Z, ctx)) 972 if (!field_sqr(group, Zb23, b->Z, ctx))
973 goto end; 973 goto end;
974 if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) 974 if (!field_mul(group, tmp1, a->X, Zb23, ctx))
975 goto end; 975 goto end;
976 tmp1_ = tmp1; 976 tmp1_ = tmp1;
977 } else 977 } else
978 tmp1_ = &a->X; 978 tmp1_ = a->X;
979 if (!a->Z_is_one) { 979 if (!a->Z_is_one) {
980 if (!field_sqr(group, Za23, &a->Z, ctx)) 980 if (!field_sqr(group, Za23, a->Z, ctx))
981 goto end; 981 goto end;
982 if (!field_mul(group, tmp2, &b->X, Za23, ctx)) 982 if (!field_mul(group, tmp2, b->X, Za23, ctx))
983 goto end; 983 goto end;
984 tmp2_ = tmp2; 984 tmp2_ = tmp2;
985 } else 985 } else
986 tmp2_ = &b->X; 986 tmp2_ = b->X;
987 987
988 /* compare X_a*Z_b^2 with X_b*Z_a^2 */ 988 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
989 if (BN_cmp(tmp1_, tmp2_) != 0) { 989 if (BN_cmp(tmp1_, tmp2_) != 0) {
@@ -991,21 +991,21 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
991 goto end; 991 goto end;
992 } 992 }
993 if (!b->Z_is_one) { 993 if (!b->Z_is_one) {
994 if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) 994 if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
995 goto end; 995 goto end;
996 if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) 996 if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
997 goto end; 997 goto end;
998 /* tmp1_ = tmp1 */ 998 /* tmp1_ = tmp1 */
999 } else 999 } else
1000 tmp1_ = &a->Y; 1000 tmp1_ = a->Y;
1001 if (!a->Z_is_one) { 1001 if (!a->Z_is_one) {
1002 if (!field_mul(group, Za23, Za23, &a->Z, ctx)) 1002 if (!field_mul(group, Za23, Za23, a->Z, ctx))
1003 goto end; 1003 goto end;
1004 if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) 1004 if (!field_mul(group, tmp2, b->Y, Za23, ctx))
1005 goto end; 1005 goto end;
1006 /* tmp2_ = tmp2 */ 1006 /* tmp2_ = tmp2 */
1007 } else 1007 } else
1008 tmp2_ = &b->Y; 1008 tmp2_ = b->Y;
1009 1009
1010 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ 1010 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
1011 if (BN_cmp(tmp1_, tmp2_) != 0) { 1011 if (BN_cmp(tmp1_, tmp2_) != 0) {
@@ -1084,8 +1084,8 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1084 * skipping any zero-valued inputs (pretend that they're 1). 1084 * skipping any zero-valued inputs (pretend that they're 1).
1085 */ 1085 */
1086 1086
1087 if (!BN_is_zero(&points[0]->Z)) { 1087 if (!BN_is_zero(points[0]->Z)) {
1088 if (!bn_copy(prod_Z[0], &points[0]->Z)) 1088 if (!bn_copy(prod_Z[0], points[0]->Z))
1089 goto err; 1089 goto err;
1090 } else { 1090 } else {
1091 if (group->meth->field_set_to_one != NULL) { 1091 if (group->meth->field_set_to_one != NULL) {
@@ -1098,9 +1098,9 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1098 } 1098 }
1099 1099
1100 for (i = 1; i < num; i++) { 1100 for (i = 1; i < num; i++) {
1101 if (!BN_is_zero(&points[i]->Z)) { 1101 if (!BN_is_zero(points[i]->Z)) {
1102 if (!group->meth->field_mul(group, prod_Z[i], 1102 if (!group->meth->field_mul(group, prod_Z[i],
1103 prod_Z[i - 1], &points[i]->Z, ctx)) 1103 prod_Z[i - 1], points[i]->Z, ctx))
1104 goto err; 1104 goto err;
1105 } else { 1105 } else {
1106 if (!bn_copy(prod_Z[i], prod_Z[i - 1])) 1106 if (!bn_copy(prod_Z[i], prod_Z[i - 1]))
@@ -1112,7 +1112,7 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1112 * Now use a single explicit inversion to replace every non-zero 1112 * Now use a single explicit inversion to replace every non-zero
1113 * points[i]->Z by its inverse. 1113 * points[i]->Z by its inverse.
1114 */ 1114 */
1115 if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], &group->p, ctx)) { 1115 if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], group->p, ctx)) {
1116 ECerror(ERR_R_BN_LIB); 1116 ECerror(ERR_R_BN_LIB);
1117 goto err; 1117 goto err;
1118 } 1118 }
@@ -1134,23 +1134,23 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1134 * Loop invariant: tmp is the product of the inverses of 1134 * Loop invariant: tmp is the product of the inverses of
1135 * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped). 1135 * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped).
1136 */ 1136 */
1137 if (BN_is_zero(&points[i]->Z)) 1137 if (BN_is_zero(points[i]->Z))
1138 continue; 1138 continue;
1139 1139
1140 /* Set tmp_Z to the inverse of points[i]->Z. */ 1140 /* Set tmp_Z to the inverse of points[i]->Z. */
1141 if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) 1141 if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
1142 goto err; 1142 goto err;
1143 /* Adjust tmp to satisfy loop invariant. */ 1143 /* Adjust tmp to satisfy loop invariant. */
1144 if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) 1144 if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
1145 goto err; 1145 goto err;
1146 /* Replace points[i]->Z by its inverse. */ 1146 /* Replace points[i]->Z by its inverse. */
1147 if (!bn_copy(&points[i]->Z, tmp_Z)) 1147 if (!bn_copy(points[i]->Z, tmp_Z))
1148 goto err; 1148 goto err;
1149 } 1149 }
1150 1150
1151 if (!BN_is_zero(&points[0]->Z)) { 1151 if (!BN_is_zero(points[0]->Z)) {
1152 /* Replace points[0]->Z by its inverse. */ 1152 /* Replace points[0]->Z by its inverse. */
1153 if (!bn_copy(&points[0]->Z, tmp)) 1153 if (!bn_copy(points[0]->Z, tmp))
1154 goto err; 1154 goto err;
1155 } 1155 }
1156 1156
@@ -1158,26 +1158,26 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1158 for (i = 0; i < num; i++) { 1158 for (i = 0; i < num; i++) {
1159 EC_POINT *p = points[i]; 1159 EC_POINT *p = points[i];
1160 1160
1161 if (BN_is_zero(&p->Z)) 1161 if (BN_is_zero(p->Z))
1162 continue; 1162 continue;
1163 1163
1164 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ 1164 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
1165 1165
1166 if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) 1166 if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
1167 goto err; 1167 goto err;
1168 if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) 1168 if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
1169 goto err; 1169 goto err;
1170 1170
1171 if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) 1171 if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
1172 goto err; 1172 goto err;
1173 if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) 1173 if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
1174 goto err; 1174 goto err;
1175 1175
1176 if (group->meth->field_set_to_one != NULL) { 1176 if (group->meth->field_set_to_one != NULL) {
1177 if (!group->meth->field_set_to_one(group, &p->Z, ctx)) 1177 if (!group->meth->field_set_to_one(group, p->Z, ctx))
1178 goto err; 1178 goto err;
1179 } else { 1179 } else {
1180 if (!BN_one(&p->Z)) 1180 if (!BN_one(p->Z))
1181 goto err; 1181 goto err;
1182 } 1182 }
1183 p->Z_is_one = 1; 1183 p->Z_is_one = 1;
@@ -1196,13 +1196,13 @@ static int
1196ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 1196ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
1197 BN_CTX *ctx) 1197 BN_CTX *ctx)
1198{ 1198{
1199 return BN_mod_mul(r, a, b, &group->p, ctx); 1199 return BN_mod_mul(r, a, b, group->p, ctx);
1200} 1200}
1201 1201
1202static int 1202static int
1203ec_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) 1203ec_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1204{ 1204{
1205 return BN_mod_sqr(r, a, &group->p, ctx); 1205 return BN_mod_sqr(r, a, group->p, ctx);
1206} 1206}
1207 1207
1208/* 1208/*
@@ -1226,7 +1226,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
1226 goto err; 1226 goto err;
1227 1227
1228 /* Generate lambda in [1, p). */ 1228 /* Generate lambda in [1, p). */
1229 if (!bn_rand_interval(lambda, 1, &group->p)) 1229 if (!bn_rand_interval(lambda, 1, group->p))
1230 goto err; 1230 goto err;
1231 1231
1232 if (group->meth->field_encode != NULL && 1232 if (group->meth->field_encode != NULL &&
@@ -1234,7 +1234,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
1234 goto err; 1234 goto err;
1235 1235
1236 /* Z = lambda * Z */ 1236 /* Z = lambda * Z */
1237 if (!group->meth->field_mul(group, &p->Z, lambda, &p->Z, ctx)) 1237 if (!group->meth->field_mul(group, p->Z, lambda, p->Z, ctx))
1238 goto err; 1238 goto err;
1239 1239
1240 /* tmp = lambda^2 */ 1240 /* tmp = lambda^2 */
@@ -1242,7 +1242,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
1242 goto err; 1242 goto err;
1243 1243
1244 /* X = lambda^2 * X */ 1244 /* X = lambda^2 * X */
1245 if (!group->meth->field_mul(group, &p->X, tmp, &p->X, ctx)) 1245 if (!group->meth->field_mul(group, p->X, tmp, p->X, ctx))
1246 goto err; 1246 goto err;
1247 1247
1248 /* tmp = lambda^3 */ 1248 /* tmp = lambda^3 */
@@ -1250,7 +1250,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
1250 goto err; 1250 goto err;
1251 1251
1252 /* Y = lambda^3 * Y */ 1252 /* Y = lambda^3 * Y */
1253 if (!group->meth->field_mul(group, &p->Y, tmp, &p->Y, ctx)) 1253 if (!group->meth->field_mul(group, p->Y, tmp, p->Y, ctx))
1254 goto err; 1254 goto err;
1255 1255
1256 /* Disable optimized arithmetics after replacing Z by lambda * Z. */ 1256 /* Disable optimized arithmetics after replacing Z by lambda * Z. */
@@ -1264,15 +1264,15 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
1264} 1264}
1265 1265
1266#define EC_POINT_BN_set_flags(P, flags) do { \ 1266#define EC_POINT_BN_set_flags(P, flags) do { \
1267 BN_set_flags(&(P)->X, (flags)); \ 1267 BN_set_flags((P)->X, (flags)); \
1268 BN_set_flags(&(P)->Y, (flags)); \ 1268 BN_set_flags((P)->Y, (flags)); \
1269 BN_set_flags(&(P)->Z, (flags)); \ 1269 BN_set_flags((P)->Z, (flags)); \
1270} while(0) 1270} while(0)
1271 1271
1272#define EC_POINT_CSWAP(c, a, b, w, t) do { \ 1272#define EC_POINT_CSWAP(c, a, b, w, t) do { \
1273 if (!BN_swap_ct(c, &(a)->X, &(b)->X, w) || \ 1273 if (!BN_swap_ct(c, (a)->X, (b)->X, w) || \
1274 !BN_swap_ct(c, &(a)->Y, &(b)->Y, w) || \ 1274 !BN_swap_ct(c, (a)->Y, (b)->Y, w) || \
1275 !BN_swap_ct(c, &(a)->Z, &(b)->Z, w)) \ 1275 !BN_swap_ct(c, (a)->Z, (b)->Z, w)) \
1276 goto err; \ 1276 goto err; \
1277 t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ 1277 t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
1278 (a)->Z_is_one ^= (t); \ 1278 (a)->Z_is_one ^= (t); \
@@ -1332,7 +1332,7 @@ ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1332 goto err; 1332 goto err;
1333 if ((k = BN_CTX_get(ctx)) == NULL) 1333 if ((k = BN_CTX_get(ctx)) == NULL)
1334 goto err; 1334 goto err;
1335 if (!BN_mul(cardinality, &group->order, &group->cofactor, ctx)) 1335 if (!BN_mul(cardinality, group->order, group->cofactor, ctx))
1336 goto err; 1336 goto err;
1337 1337
1338 /* 1338 /*
@@ -1374,13 +1374,13 @@ ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1374 if (!BN_swap_ct(kbit, k, lambda, group_top + 2)) 1374 if (!BN_swap_ct(kbit, k, lambda, group_top + 2))
1375 goto err; 1375 goto err;
1376 1376
1377 group_top = group->p.top; 1377 group_top = group->p->top;
1378 if (!bn_wexpand(&s->X, group_top) || 1378 if (!bn_wexpand(s->X, group_top) ||
1379 !bn_wexpand(&s->Y, group_top) || 1379 !bn_wexpand(s->Y, group_top) ||
1380 !bn_wexpand(&s->Z, group_top) || 1380 !bn_wexpand(s->Z, group_top) ||
1381 !bn_wexpand(&r->X, group_top) || 1381 !bn_wexpand(r->X, group_top) ||
1382 !bn_wexpand(&r->Y, group_top) || 1382 !bn_wexpand(r->Y, group_top) ||
1383 !bn_wexpand(&r->Z, group_top)) 1383 !bn_wexpand(r->Z, group_top))
1384 goto err; 1384 goto err;
1385 1385
1386 /* 1386 /*