summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c14
-rw-r--r--src/lib/libcrypto/ec/ec2_oct.c59
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c78
-rw-r--r--src/lib/libcrypto/ec/ec_check.c31
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c452
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c22
-rw-r--r--src/lib/libcrypto/ec/ec_oct.c70
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c12
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c58
-rw-r--r--src/lib/libcrypto/ec/ecp_oct.c62
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c186
11 files changed, 553 insertions, 491 deletions
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
index d32b7442c4..d7cbd933f2 100644
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ b/src/lib/libcrypto/ec/ec2_mult.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec2_mult.c,v 1.16 2023/03/27 10:25:02 tb Exp $ */ 1/* $OpenBSD: ec2_mult.c,v 1.17 2023/04/11 18:58:20 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 * 4 *
@@ -375,17 +375,11 @@ int
375ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 375ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
376 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 376 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
377{ 377{
378 BN_CTX *new_ctx = NULL;
379 int ret = 0;
380 size_t i;
381 EC_POINT *p = NULL; 378 EC_POINT *p = NULL;
382 EC_POINT *acc = NULL; 379 EC_POINT *acc = NULL;
380 size_t i;
381 int ret = 0;
383 382
384 if (ctx == NULL) {
385 ctx = new_ctx = BN_CTX_new();
386 if (ctx == NULL)
387 return 0;
388 }
389 /* 383 /*
390 * This implementation is more efficient than the wNAF implementation 384 * This implementation is more efficient than the wNAF implementation
391 * for 2 or fewer points. Use the ec_wNAF_mul implementation for 3 385 * for 2 or fewer points. Use the ec_wNAF_mul implementation for 3
@@ -432,7 +426,7 @@ ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
432 err: 426 err:
433 EC_POINT_free(p); 427 EC_POINT_free(p);
434 EC_POINT_free(acc); 428 EC_POINT_free(acc);
435 BN_CTX_free(new_ctx); 429
436 return ret; 430 return ret;
437} 431}
438 432
diff --git a/src/lib/libcrypto/ec/ec2_oct.c b/src/lib/libcrypto/ec/ec2_oct.c
index d3fbc12749..6cb7259824 100644
--- a/src/lib/libcrypto/ec/ec2_oct.c
+++ b/src/lib/libcrypto/ec/ec2_oct.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec2_oct.c,v 1.19 2022/11/26 16:08:52 tb Exp $ */ 1/* $OpenBSD: ec2_oct.c,v 1.20 2023/04/11 18:58:20 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 * 4 *
@@ -94,21 +94,17 @@ int
94ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 94ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
95 const BIGNUM *x_, int y_bit, BN_CTX *ctx) 95 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
96{ 96{
97 BN_CTX *new_ctx = NULL;
98 BIGNUM *tmp, *x, *y, *z; 97 BIGNUM *tmp, *x, *y, *z;
99 int ret = 0, z0; 98 int z0;
99 int ret = 0;
100 100
101 /* clear error queue */ 101 /* clear error queue */
102 ERR_clear_error(); 102 ERR_clear_error();
103 103
104 if (ctx == NULL) {
105 ctx = new_ctx = BN_CTX_new();
106 if (ctx == NULL)
107 return 0;
108 }
109 y_bit = (y_bit != 0) ? 1 : 0; 104 y_bit = (y_bit != 0) ? 1 : 0;
110 105
111 BN_CTX_start(ctx); 106 BN_CTX_start(ctx);
107
112 if ((tmp = BN_CTX_get(ctx)) == NULL) 108 if ((tmp = BN_CTX_get(ctx)) == NULL)
113 goto err; 109 goto err;
114 if ((x = BN_CTX_get(ctx)) == NULL) 110 if ((x = BN_CTX_get(ctx)) == NULL)
@@ -163,7 +159,7 @@ ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point
163 159
164 err: 160 err:
165 BN_CTX_end(ctx); 161 BN_CTX_end(ctx);
166 BN_CTX_free(new_ctx); 162
167 return ret; 163 return ret;
168} 164}
169 165
@@ -177,18 +173,17 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
177 point_conversion_form_t form, 173 point_conversion_form_t form,
178 unsigned char *buf, size_t len, BN_CTX *ctx) 174 unsigned char *buf, size_t len, BN_CTX *ctx)
179{ 175{
180 size_t ret;
181 BN_CTX *new_ctx = NULL;
182 int used_ctx = 0;
183 BIGNUM *x, *y, *yxi; 176 BIGNUM *x, *y, *yxi;
184 size_t field_len, i, skip; 177 size_t field_len, i, skip;
178 size_t ret;
185 179
186 if ((form != POINT_CONVERSION_COMPRESSED) 180 if (form != POINT_CONVERSION_COMPRESSED &&
187 && (form != POINT_CONVERSION_UNCOMPRESSED) 181 form != POINT_CONVERSION_UNCOMPRESSED &&
188 && (form != POINT_CONVERSION_HYBRID)) { 182 form != POINT_CONVERSION_HYBRID) {
189 ECerror(EC_R_INVALID_FORM); 183 ECerror(EC_R_INVALID_FORM);
190 goto err; 184 return 0;
191 } 185 }
186
192 if (EC_POINT_is_at_infinity(group, point) > 0) { 187 if (EC_POINT_is_at_infinity(group, point) > 0) {
193 /* encodes to a single 0 octet */ 188 /* encodes to a single 0 octet */
194 if (buf != NULL) { 189 if (buf != NULL) {
@@ -200,6 +195,9 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
200 } 195 }
201 return 1; 196 return 1;
202 } 197 }
198
199 BN_CTX_start(ctx);
200
203 /* ret := required output buffer length */ 201 /* ret := required output buffer length */
204 field_len = (EC_GROUP_get_degree(group) + 7) / 8; 202 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
205 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 203 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
@@ -211,13 +209,7 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
211 ECerror(EC_R_BUFFER_TOO_SMALL); 209 ECerror(EC_R_BUFFER_TOO_SMALL);
212 goto err; 210 goto err;
213 } 211 }
214 if (ctx == NULL) { 212
215 ctx = new_ctx = BN_CTX_new();
216 if (ctx == NULL)
217 return 0;
218 }
219 BN_CTX_start(ctx);
220 used_ctx = 1;
221 if ((x = BN_CTX_get(ctx)) == NULL) 213 if ((x = BN_CTX_get(ctx)) == NULL)
222 goto err; 214 goto err;
223 if ((y = BN_CTX_get(ctx)) == NULL) 215 if ((y = BN_CTX_get(ctx)) == NULL)
@@ -271,18 +263,12 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
271 goto err; 263 goto err;
272 } 264 }
273 } 265 }
274 if (used_ctx)
275 BN_CTX_end(ctx);
276 BN_CTX_free(new_ctx);
277 return ret;
278 266
279 err: 267 err:
280 if (used_ctx) 268 BN_CTX_end(ctx);
281 BN_CTX_end(ctx);
282 BN_CTX_free(new_ctx);
283 return 0;
284}
285 269
270 return ret;
271}
286 272
287/* 273/*
288 * Converts an octet string representation to an EC_POINT. 274 * Converts an octet string representation to an EC_POINT.
@@ -294,7 +280,6 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
294{ 280{
295 point_conversion_form_t form; 281 point_conversion_form_t form;
296 int y_bit; 282 int y_bit;
297 BN_CTX *new_ctx = NULL;
298 BIGNUM *x, *y, *yxi; 283 BIGNUM *x, *y, *yxi;
299 size_t field_len, enc_len; 284 size_t field_len, enc_len;
300 int ret = 0; 285 int ret = 0;
@@ -349,12 +334,8 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
349 return 0; 334 return 0;
350 } 335 }
351 336
352 if (ctx == NULL) {
353 ctx = new_ctx = BN_CTX_new();
354 if (ctx == NULL)
355 return 0;
356 }
357 BN_CTX_start(ctx); 337 BN_CTX_start(ctx);
338
358 if ((x = BN_CTX_get(ctx)) == NULL) 339 if ((x = BN_CTX_get(ctx)) == NULL)
359 goto err; 340 goto err;
360 if ((y = BN_CTX_get(ctx)) == NULL) 341 if ((y = BN_CTX_get(ctx)) == NULL)
@@ -415,7 +396,7 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
415 396
416 err: 397 err:
417 BN_CTX_end(ctx); 398 BN_CTX_end(ctx);
418 BN_CTX_free(new_ctx); 399
419 return ret; 400 return ret;
420} 401}
421#endif 402#endif
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
index 1ad339cbd7..850159cb25 100644
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ b/src/lib/libcrypto/ec/ec2_smpl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec2_smpl.c,v 1.34 2023/03/27 10:25:02 tb Exp $ */ 1/* $OpenBSD: ec2_smpl.c,v 1.35 2023/04/11 18:58:20 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 * 4 *
@@ -216,18 +216,11 @@ ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
216static int 216static int
217ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 217ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
218{ 218{
219 int ret = 0;
220 BIGNUM *b; 219 BIGNUM *b;
221 BN_CTX *new_ctx = NULL; 220 int ret = 0;
222 221
223 if (ctx == NULL) {
224 ctx = new_ctx = BN_CTX_new();
225 if (ctx == NULL) {
226 ECerror(ERR_R_MALLOC_FAILURE);
227 goto err;
228 }
229 }
230 BN_CTX_start(ctx); 222 BN_CTX_start(ctx);
223
231 if ((b = BN_CTX_get(ctx)) == NULL) 224 if ((b = BN_CTX_get(ctx)) == NULL)
232 goto err; 225 goto err;
233 226
@@ -244,9 +237,8 @@ ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
244 ret = 1; 237 ret = 1;
245 238
246 err: 239 err:
247 if (ctx != NULL) 240 BN_CTX_end(ctx);
248 BN_CTX_end(ctx); 241
249 BN_CTX_free(new_ctx);
250 return ret; 242 return ret;
251} 243}
252 244
@@ -368,7 +360,6 @@ static int
368ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 360ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
369 const EC_POINT *b, BN_CTX *ctx) 361 const EC_POINT *b, BN_CTX *ctx)
370{ 362{
371 BN_CTX *new_ctx = NULL;
372 BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; 363 BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
373 int ret = 0; 364 int ret = 0;
374 365
@@ -382,12 +373,9 @@ ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
382 return 0; 373 return 0;
383 return 1; 374 return 1;
384 } 375 }
385 if (ctx == NULL) { 376
386 ctx = new_ctx = BN_CTX_new();
387 if (ctx == NULL)
388 return 0;
389 }
390 BN_CTX_start(ctx); 377 BN_CTX_start(ctx);
378
391 if ((x0 = BN_CTX_get(ctx)) == NULL) 379 if ((x0 = BN_CTX_get(ctx)) == NULL)
392 goto err; 380 goto err;
393 if ((y0 = BN_CTX_get(ctx)) == NULL) 381 if ((y0 = BN_CTX_get(ctx)) == NULL)
@@ -475,7 +463,7 @@ ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
475 463
476 err: 464 err:
477 BN_CTX_end(ctx); 465 BN_CTX_end(ctx);
478 BN_CTX_free(new_ctx); 466
479 return ret; 467 return ret;
480} 468}
481 469
@@ -517,11 +505,10 @@ ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
517static int 505static int
518ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) 506ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
519{ 507{
520 int ret = -1;
521 BN_CTX *new_ctx = NULL;
522 BIGNUM *lh, *y2;
523 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 508 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
524 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 509 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
510 BIGNUM *lh, *y2;
511 int ret = -1;
525 512
526 if (EC_POINT_is_at_infinity(group, point) > 0) 513 if (EC_POINT_is_at_infinity(group, point) > 0)
527 return 1; 514 return 1;
@@ -533,12 +520,8 @@ ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX
533 if (!point->Z_is_one) 520 if (!point->Z_is_one)
534 return -1; 521 return -1;
535 522
536 if (ctx == NULL) {
537 ctx = new_ctx = BN_CTX_new();
538 if (ctx == NULL)
539 return -1;
540 }
541 BN_CTX_start(ctx); 523 BN_CTX_start(ctx);
524
542 if ((y2 = BN_CTX_get(ctx)) == NULL) 525 if ((y2 = BN_CTX_get(ctx)) == NULL)
543 goto err; 526 goto err;
544 if ((lh = BN_CTX_get(ctx)) == NULL) 527 if ((lh = BN_CTX_get(ctx)) == NULL)
@@ -563,11 +546,12 @@ ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX
563 goto err; 546 goto err;
564 if (!BN_GF2m_add(lh, lh, y2)) 547 if (!BN_GF2m_add(lh, lh, y2))
565 goto err; 548 goto err;
549
566 ret = BN_is_zero(lh); 550 ret = BN_is_zero(lh);
551
567 err: 552 err:
568 if (ctx) 553 BN_CTX_end(ctx);
569 BN_CTX_end(ctx); 554
570 BN_CTX_free(new_ctx);
571 return ret; 555 return ret;
572} 556}
573 557
@@ -583,24 +567,19 @@ ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
583 const EC_POINT *b, BN_CTX *ctx) 567 const EC_POINT *b, BN_CTX *ctx)
584{ 568{
585 BIGNUM *aX, *aY, *bX, *bY; 569 BIGNUM *aX, *aY, *bX, *bY;
586 BN_CTX *new_ctx = NULL;
587 int ret = -1; 570 int ret = -1;
588 571
589 if (EC_POINT_is_at_infinity(group, a) > 0) { 572 if (EC_POINT_is_at_infinity(group, a) > 0)
590 return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1; 573 return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
591 } 574
592 if (EC_POINT_is_at_infinity(group, b) > 0) 575 if (EC_POINT_is_at_infinity(group, b) > 0)
593 return 1; 576 return 1;
594 577
595 if (a->Z_is_one && b->Z_is_one) { 578 if (a->Z_is_one && b->Z_is_one)
596 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; 579 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
597 } 580
598 if (ctx == NULL) {
599 ctx = new_ctx = BN_CTX_new();
600 if (ctx == NULL)
601 return -1;
602 }
603 BN_CTX_start(ctx); 581 BN_CTX_start(ctx);
582
604 if ((aX = BN_CTX_get(ctx)) == NULL) 583 if ((aX = BN_CTX_get(ctx)) == NULL)
605 goto err; 584 goto err;
606 if ((aY = BN_CTX_get(ctx)) == NULL) 585 if ((aY = BN_CTX_get(ctx)) == NULL)
@@ -617,9 +596,8 @@ ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
617 ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; 596 ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
618 597
619 err: 598 err:
620 if (ctx) 599 BN_CTX_end(ctx);
621 BN_CTX_end(ctx); 600
622 BN_CTX_free(new_ctx);
623 return ret; 601 return ret;
624} 602}
625 603
@@ -627,19 +605,14 @@ ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
627static int 605static int
628ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 606ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
629{ 607{
630 BN_CTX *new_ctx = NULL;
631 BIGNUM *x, *y; 608 BIGNUM *x, *y;
632 int ret = 0; 609 int ret = 0;
633 610
634 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0) 611 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
635 return 1; 612 return 1;
636 613
637 if (ctx == NULL) {
638 ctx = new_ctx = BN_CTX_new();
639 if (ctx == NULL)
640 return 0;
641 }
642 BN_CTX_start(ctx); 614 BN_CTX_start(ctx);
615
643 if ((x = BN_CTX_get(ctx)) == NULL) 616 if ((x = BN_CTX_get(ctx)) == NULL)
644 goto err; 617 goto err;
645 if ((y = BN_CTX_get(ctx)) == NULL) 618 if ((y = BN_CTX_get(ctx)) == NULL)
@@ -657,9 +630,8 @@ ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
657 ret = 1; 630 ret = 1;
658 631
659 err: 632 err:
660 if (ctx) 633 BN_CTX_end(ctx);
661 BN_CTX_end(ctx); 634
662 BN_CTX_free(new_ctx);
663 return ret; 635 return ret;
664} 636}
665 637
diff --git a/src/lib/libcrypto/ec/ec_check.c b/src/lib/libcrypto/ec/ec_check.c
index 5c6165e129..4e065c739a 100644
--- a/src/lib/libcrypto/ec/ec_check.c
+++ b/src/lib/libcrypto/ec/ec_check.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_check.c,v 1.12 2022/11/26 16:08:52 tb Exp $ */ 1/* $OpenBSD: ec_check.c,v 1.13 2023/04/11 18:58:20 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -57,21 +57,20 @@
57#include <openssl/err.h> 57#include <openssl/err.h>
58 58
59int 59int
60EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) 60EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
61{ 61{
62 int ret = 0; 62 BN_CTX *ctx;
63 BIGNUM *order; 63 BIGNUM *order;
64 BN_CTX *new_ctx = NULL;
65 EC_POINT *point = NULL; 64 EC_POINT *point = NULL;
65 int ret = 0;
66
67 if ((ctx = ctx_in) == NULL)
68 ctx = BN_CTX_new();
69 if (ctx == NULL)
70 goto err;
66 71
67 if (ctx == NULL) {
68 ctx = new_ctx = BN_CTX_new();
69 if (ctx == NULL) {
70 ECerror(ERR_R_MALLOC_FAILURE);
71 goto err;
72 }
73 }
74 BN_CTX_start(ctx); 72 BN_CTX_start(ctx);
73
75 if ((order = BN_CTX_get(ctx)) == NULL) 74 if ((order = BN_CTX_get(ctx)) == NULL)
76 goto err; 75 goto err;
77 76
@@ -104,12 +103,16 @@ EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
104 ECerror(EC_R_INVALID_GROUP_ORDER); 103 ECerror(EC_R_INVALID_GROUP_ORDER);
105 goto err; 104 goto err;
106 } 105 }
106
107 ret = 1; 107 ret = 1;
108 108
109 err: 109 err:
110 if (ctx != NULL) 110 BN_CTX_end(ctx);
111 BN_CTX_end(ctx); 111
112 BN_CTX_free(new_ctx); 112 if (ctx != ctx_in)
113 BN_CTX_free(ctx);
114
113 EC_POINT_free(point); 115 EC_POINT_free(point);
116
114 return ret; 117 return ret;
115} 118}
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 38ddd7af9f..bc472b73b7 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.52 2023/03/27 10:25:02 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.53 2023/04/11 18:58:20 jsing 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 */
@@ -487,24 +487,52 @@ EC_GROUP_get_seed_len(const EC_GROUP *group)
487 487
488int 488int
489EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 489EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
490 const BIGNUM *b, BN_CTX *ctx) 490 const BIGNUM *b, BN_CTX *ctx_in)
491{ 491{
492 BN_CTX *ctx;
493 int ret = 0;
494
495 if ((ctx = ctx_in) == NULL)
496 ctx = BN_CTX_new();
497 if (ctx == NULL)
498 goto err;
499
492 if (group->meth->group_set_curve == NULL) { 500 if (group->meth->group_set_curve == NULL) {
493 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 501 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
494 return 0; 502 goto err;
495 } 503 }
496 return group->meth->group_set_curve(group, p, a, b, ctx); 504 ret = group->meth->group_set_curve(group, p, a, b, ctx);
505
506 err:
507 if (ctx != ctx_in)
508 BN_CTX_free(ctx);
509
510 return ret;
497} 511}
498 512
499int 513int
500EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, 514EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
501 BN_CTX *ctx) 515 BN_CTX *ctx_in)
502{ 516{
517 BN_CTX *ctx;
518 int ret = 0;
519
520 if ((ctx = ctx_in) == NULL)
521 ctx = BN_CTX_new();
522 if (ctx == NULL)
523 goto err;
524
503 if (group->meth->group_get_curve == NULL) { 525 if (group->meth->group_get_curve == NULL) {
504 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 526 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
505 return 0; 527 return 0;
506 } 528 }
507 return group->meth->group_get_curve(group, p, a, b, ctx); 529 ret = group->meth->group_get_curve(group, p, a, b, ctx);
530
531 err:
532 if (ctx != ctx_in)
533 BN_CTX_free(ctx);
534
535 return ret;
508} 536}
509 537
510int 538int
@@ -549,13 +577,27 @@ EC_GROUP_get_degree(const EC_GROUP *group)
549 577
550 578
551int 579int
552EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 580EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in)
553{ 581{
582 BN_CTX *ctx;
583 int ret = 0;
584
585 if ((ctx = ctx_in) == NULL)
586 ctx = BN_CTX_new();
587 if (ctx == NULL)
588 goto err;
589
554 if (group->meth->group_check_discriminant == 0) { 590 if (group->meth->group_check_discriminant == 0) {
555 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 591 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
556 return 0; 592 return 0;
557 } 593 }
558 return group->meth->group_check_discriminant(group, ctx); 594 return group->meth->group_check_discriminant(group, ctx);
595
596 err:
597 if (ctx != ctx_in)
598 BN_CTX_free(ctx);
599
600 return ret;
559} 601}
560 602
561 603
@@ -803,9 +845,6 @@ EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
803 *ex_data = NULL; 845 *ex_data = NULL;
804} 846}
805 847
806
807/* functions for EC_POINT objects */
808
809EC_POINT * 848EC_POINT *
810EC_POINT_new(const EC_GROUP *group) 849EC_POINT_new(const EC_GROUP *group)
811{ 850{
@@ -867,7 +906,6 @@ EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
867 return dest->meth->point_copy(dest, src); 906 return dest->meth->point_copy(dest, src);
868} 907}
869 908
870
871EC_POINT * 909EC_POINT *
872EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) 910EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
873{ 911{
@@ -888,18 +926,16 @@ EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
888 return t; 926 return t;
889} 927}
890 928
891
892const EC_METHOD * 929const EC_METHOD *
893EC_POINT_method_of(const EC_POINT *point) 930EC_POINT_method_of(const EC_POINT *point)
894{ 931{
895 return point->meth; 932 return point->meth;
896} 933}
897 934
898
899int 935int
900EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 936EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
901{ 937{
902 if (group->meth->point_set_to_infinity == 0) { 938 if (group->meth->point_set_to_infinity == NULL) {
903 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 939 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
904 return 0; 940 return 0;
905 } 941 }
@@ -912,40 +948,70 @@ EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
912 948
913int 949int
914EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, 950EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point,
915 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 951 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx_in)
916{ 952{
953 BN_CTX *ctx;
954 int ret = 0;
955
956 if ((ctx = ctx_in) == NULL)
957 ctx = BN_CTX_new();
958 if (ctx == NULL)
959 goto err;
960
917 if (group->meth->point_set_Jprojective_coordinates == NULL) { 961 if (group->meth->point_set_Jprojective_coordinates == NULL) {
918 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 962 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
919 return 0; 963 goto err;
920 } 964 }
921 if (group->meth != point->meth) { 965 if (group->meth != point->meth) {
922 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 966 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
923 return 0; 967 goto err;
924 } 968 }
925 if (!group->meth->point_set_Jprojective_coordinates(group, point, 969 if (!group->meth->point_set_Jprojective_coordinates(group, point,
926 x, y, z, ctx)) 970 x, y, z, ctx))
927 return 0; 971 goto err;
972
928 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 973 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
929 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 974 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
930 return 0; 975 goto err;
931 } 976 }
932 return 1; 977
978 ret = 1;
979
980 err:
981 if (ctx != ctx_in)
982 BN_CTX_free(ctx);
983
984 return ret;
933} 985}
934 986
935int 987int
936EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, 988EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group,
937 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 989 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx_in)
938{ 990{
991 BN_CTX *ctx;
992 int ret = 0;
993
994 if ((ctx = ctx_in) == NULL)
995 ctx = BN_CTX_new();
996 if (ctx == NULL)
997 goto err;
998
939 if (group->meth->point_get_Jprojective_coordinates == NULL) { 999 if (group->meth->point_get_Jprojective_coordinates == NULL) {
940 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1000 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
941 return 0; 1001 goto err;
942 } 1002 }
943 if (group->meth != point->meth) { 1003 if (group->meth != point->meth) {
944 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1004 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
945 return 0; 1005 goto err;
946 } 1006 }
947 return group->meth->point_get_Jprojective_coordinates(group, point, 1007 ret = group->meth->point_get_Jprojective_coordinates(group, point,
948 x, y, z, ctx); 1008 x, y, z, ctx);
1009
1010 err:
1011 if (ctx != ctx_in)
1012 BN_CTX_free(ctx);
1013
1014 return ret;
949} 1015}
950 1016
951int 1017int
@@ -964,23 +1030,39 @@ EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
964 1030
965int 1031int
966EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 1032EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
967 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 1033 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in)
968{ 1034{
1035 BN_CTX *ctx;
1036 int ret = 0;
1037
1038 if ((ctx = ctx_in) == NULL)
1039 ctx = BN_CTX_new();
1040 if (ctx == NULL)
1041 goto err;
1042
969 if (group->meth->point_set_affine_coordinates == NULL) { 1043 if (group->meth->point_set_affine_coordinates == NULL) {
970 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1044 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
971 return 0; 1045 goto err;
972 } 1046 }
973 if (group->meth != point->meth) { 1047 if (group->meth != point->meth) {
974 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1048 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
975 return 0; 1049 goto err;
976 } 1050 }
977 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) 1051 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
978 return 0; 1052 goto err;
1053
979 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 1054 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
980 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 1055 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
981 return 0; 1056 goto err;
982 } 1057 }
983 return 1; 1058
1059 ret = 1;
1060
1061 err:
1062 if (ctx != ctx_in)
1063 BN_CTX_free(ctx);
1064
1065 return ret;
984} 1066}
985 1067
986int 1068int
@@ -1001,8 +1083,16 @@ EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
1001 1083
1002int 1084int
1003EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 1085EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
1004 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 1086 BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in)
1005{ 1087{
1088 BN_CTX *ctx;
1089 int ret = 0;
1090
1091 if ((ctx = ctx_in) == NULL)
1092 ctx = BN_CTX_new();
1093 if (ctx == NULL)
1094 goto err;
1095
1006 if (group->meth->point_get_affine_coordinates == NULL) { 1096 if (group->meth->point_get_affine_coordinates == NULL) {
1007 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1097 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1008 return 0; 1098 return 0;
@@ -1011,7 +1101,13 @@ EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
1011 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1101 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1012 return 0; 1102 return 0;
1013 } 1103 }
1014 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 1104 ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
1105
1106 err:
1107 if (ctx != ctx_in)
1108 BN_CTX_free(ctx);
1109
1110 return ret;
1015} 1111}
1016 1112
1017int 1113int
@@ -1032,38 +1128,74 @@ EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *poin
1032 1128
1033int 1129int
1034EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 1130EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1035 const EC_POINT *b, BN_CTX *ctx) 1131 const EC_POINT *b, BN_CTX *ctx_in)
1036{ 1132{
1037 if (group->meth->add == 0) { 1133 BN_CTX *ctx;
1134 int ret = 0;
1135
1136 if ((ctx = ctx_in) == NULL)
1137 ctx = BN_CTX_new();
1138 if (ctx == NULL)
1139 goto err;
1140
1141 if (group->meth->add == NULL) {
1038 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1142 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1039 return 0; 1143 goto err;
1040 } 1144 }
1041 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) { 1145 if (group->meth != r->meth || group->meth != a->meth ||
1146 group->meth != b->meth) {
1042 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1147 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1043 return 0; 1148 goto err;
1044 } 1149 }
1045 return group->meth->add(group, r, a, b, ctx); 1150 ret = group->meth->add(group, r, a, b, ctx);
1046}
1047 1151
1152 err:
1153 if (ctx != ctx_in)
1154 BN_CTX_free(ctx);
1155
1156 return ret;
1157}
1048 1158
1049int 1159int
1050EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) 1160EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1161 BN_CTX *ctx_in)
1051{ 1162{
1052 if (group->meth->dbl == 0) { 1163 BN_CTX *ctx;
1164 int ret = 0;
1165
1166 if ((ctx = ctx_in) == NULL)
1167 ctx = BN_CTX_new();
1168 if (ctx == NULL)
1169 goto err;
1170
1171 if (group->meth->dbl == NULL) {
1053 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1172 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1054 return 0; 1173 return 0;
1055 } 1174 }
1056 if ((group->meth != r->meth) || (r->meth != a->meth)) { 1175 if (group->meth != r->meth || r->meth != a->meth) {
1057 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1176 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1058 return 0; 1177 return 0;
1059 } 1178 }
1060 return group->meth->dbl(group, r, a, ctx); 1179 ret = group->meth->dbl(group, r, a, ctx);
1061}
1062 1180
1181 err:
1182 if (ctx != ctx_in)
1183 BN_CTX_free(ctx);
1184
1185 return ret;
1186}
1063 1187
1064int 1188int
1065EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 1189EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in)
1066{ 1190{
1191 BN_CTX *ctx;
1192 int ret = 0;
1193
1194 if ((ctx = ctx_in) == NULL)
1195 ctx = BN_CTX_new();
1196 if (ctx == NULL)
1197 goto err;
1198
1067 if (group->meth->invert == 0) { 1199 if (group->meth->invert == 0) {
1068 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1200 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1069 return 0; 1201 return 0;
@@ -1073,13 +1205,18 @@ EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
1073 return 0; 1205 return 0;
1074 } 1206 }
1075 return group->meth->invert(group, a, ctx); 1207 return group->meth->invert(group, a, ctx);
1076}
1077 1208
1209 err:
1210 if (ctx != ctx_in)
1211 BN_CTX_free(ctx);
1212
1213 return ret;
1214}
1078 1215
1079int 1216int
1080EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 1217EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1081{ 1218{
1082 if (group->meth->is_at_infinity == 0) { 1219 if (group->meth->is_at_infinity == NULL) {
1083 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1220 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1084 return 0; 1221 return 0;
1085 } 1222 }
@@ -1090,114 +1227,184 @@ EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1090 return group->meth->is_at_infinity(group, point); 1227 return group->meth->is_at_infinity(group, point);
1091} 1228}
1092 1229
1093
1094int 1230int
1095EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) 1231EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
1232 BN_CTX *ctx_in)
1096{ 1233{
1097 if (group->meth->is_on_curve == 0) { 1234 BN_CTX *ctx;
1235 int ret = 0;
1236
1237 if ((ctx = ctx_in) == NULL)
1238 ctx = BN_CTX_new();
1239 if (ctx == NULL)
1240 goto err;
1241
1242 if (group->meth->is_on_curve == NULL) {
1098 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1243 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1099 return 0; 1244 goto err;
1100 } 1245 }
1101 if (group->meth != point->meth) { 1246 if (group->meth != point->meth) {
1102 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1247 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1103 return 0; 1248 goto err;
1104 } 1249 }
1105 return group->meth->is_on_curve(group, point, ctx); 1250 ret = group->meth->is_on_curve(group, point, ctx);
1106} 1251
1252 err:
1253 if (ctx != ctx_in)
1254 BN_CTX_free(ctx);
1107 1255
1256 return ret;
1257}
1108 1258
1109int 1259int
1110EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 1260EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1111 BN_CTX *ctx) 1261 BN_CTX *ctx_in)
1112{ 1262{
1113 if (group->meth->point_cmp == 0) { 1263 BN_CTX *ctx;
1264 int ret = -1;
1265
1266 if ((ctx = ctx_in) == NULL)
1267 ctx = BN_CTX_new();
1268 if (ctx == NULL)
1269 goto err;
1270
1271 if (group->meth->point_cmp == NULL) {
1114 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1272 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1115 return -1; 1273 goto err;
1116 } 1274 }
1117 if ((group->meth != a->meth) || (a->meth != b->meth)) { 1275 if (group->meth != a->meth || a->meth != b->meth) {
1118 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1276 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1119 return -1; 1277 goto err;
1120 } 1278 }
1121 return group->meth->point_cmp(group, a, b, ctx); 1279 ret = group->meth->point_cmp(group, a, b, ctx);
1122} 1280
1281 err:
1282 if (ctx != ctx_in)
1283 BN_CTX_free(ctx);
1123 1284
1285 return ret;
1286}
1124 1287
1125int 1288int
1126EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 1289EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in)
1127{ 1290{
1128 if (group->meth->make_affine == 0) { 1291 BN_CTX *ctx;
1292 int ret = 0;
1293
1294 if ((ctx = ctx_in) == NULL)
1295 ctx = BN_CTX_new();
1296 if (ctx == NULL)
1297 goto err;
1298
1299 if (group->meth->make_affine == NULL) {
1129 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1300 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1130 return 0; 1301 goto err;
1131 } 1302 }
1132 if (group->meth != point->meth) { 1303 if (group->meth != point->meth) {
1133 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1304 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1134 return 0; 1305 goto err;
1135 } 1306 }
1136 return group->meth->make_affine(group, point, ctx); 1307 ret = group->meth->make_affine(group, point, ctx);
1137}
1138 1308
1309 err:
1310 if (ctx != ctx_in)
1311 BN_CTX_free(ctx);
1312
1313 return ret;
1314}
1139 1315
1140int 1316int
1141EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 1317EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1142 BN_CTX *ctx) 1318 BN_CTX *ctx_in)
1143{ 1319{
1320 BN_CTX *ctx;
1144 size_t i; 1321 size_t i;
1322 int ret = 0;
1145 1323
1146 if (group->meth->points_make_affine == 0) { 1324 if ((ctx = ctx_in) == NULL)
1325 ctx = BN_CTX_new();
1326 if (ctx == NULL)
1327 goto err;
1328
1329 if (group->meth->points_make_affine == NULL) {
1147 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1330 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1148 return 0; 1331 goto err;
1149 } 1332 }
1150 for (i = 0; i < num; i++) { 1333 for (i = 0; i < num; i++) {
1151 if (group->meth != points[i]->meth) { 1334 if (group->meth != points[i]->meth) {
1152 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1335 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1153 return 0; 1336 goto err;
1154 } 1337 }
1155 } 1338 }
1156 return group->meth->points_make_affine(group, num, points, ctx); 1339 ret = group->meth->points_make_affine(group, num, points, ctx);
1157}
1158 1340
1341 err:
1342 if (ctx != ctx_in)
1343 BN_CTX_free(ctx);
1344
1345 return ret;
1346}
1159 1347
1160/* Functions for point multiplication */
1161int 1348int
1162EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 1349EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1163 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 1350 size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
1351 BN_CTX *ctx_in)
1164{ 1352{
1165 /* 1353 BN_CTX *ctx;
1166 * The function pointers must be set, and only support num == 0 and 1354 int ret = 0;
1167 * num == 1. 1355
1168 */ 1356 if ((ctx = ctx_in) == NULL)
1357 ctx = BN_CTX_new();
1358 if (ctx == NULL)
1359 goto err;
1360
1361 /* Only num == 0 and num == 1 is supported. */
1169 if (group->meth->mul_generator_ct == NULL || 1362 if (group->meth->mul_generator_ct == NULL ||
1170 group->meth->mul_single_ct == NULL || 1363 group->meth->mul_single_ct == NULL ||
1171 group->meth->mul_double_nonct == NULL || 1364 group->meth->mul_double_nonct == NULL ||
1172 num > 1) { 1365 num > 1) {
1173 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1366 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1174 return 0; 1367 goto err;
1175 } 1368 }
1176 1369
1177 /* Either bP or aG + bP, this is sane. */ 1370 if (num == 1 && points != NULL && scalars != NULL) {
1178 if (num == 1 && points != NULL && scalars != NULL) 1371 /* Either bP or aG + bP, this is sane. */
1179 return EC_POINT_mul(group, r, scalar, points[0], scalars[0], 1372 ret = EC_POINT_mul(group, r, scalar, points[0], scalars[0], ctx);
1180 ctx); 1373 } else if (scalar != NULL && points == NULL && scalars == NULL) {
1374 /* aG, this is sane */
1375 ret = EC_POINT_mul(group, r, scalar, NULL, NULL, ctx);
1376 } else {
1377 /* anything else is an error */
1378 ECerror(ERR_R_EC_LIB);
1379 goto err;
1380 }
1181 1381
1182 /* aG, this is sane */ 1382 err:
1183 if (scalar != NULL && points == NULL && scalars == NULL) 1383 if (ctx != ctx_in)
1184 return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); 1384 BN_CTX_free(ctx);
1185 1385
1186 /* anything else is an error */ 1386 return ret;
1187 ECerror(ERR_R_EC_LIB);
1188 return 0;
1189} 1387}
1190 1388
1191int 1389int
1192EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1390EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1193 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 1391 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in)
1194{ 1392{
1393 BN_CTX *ctx;
1394 int ret = 0;
1395
1396 if ((ctx = ctx_in) == NULL)
1397 ctx = BN_CTX_new();
1398 if (ctx == NULL)
1399 goto err;
1400
1195 if (group->meth->mul_generator_ct == NULL || 1401 if (group->meth->mul_generator_ct == NULL ||
1196 group->meth->mul_single_ct == NULL || 1402 group->meth->mul_single_ct == NULL ||
1197 group->meth->mul_double_nonct == NULL) { 1403 group->meth->mul_double_nonct == NULL) {
1198 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1404 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1199 return 0; 1405 goto err;
1200 } 1406 }
1407
1201 if (g_scalar != NULL && point == NULL && p_scalar == NULL) { 1408 if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1202 /* 1409 /*
1203 * In this case we want to compute g_scalar * GeneratorPoint: 1410 * In this case we want to compute g_scalar * GeneratorPoint:
@@ -1207,52 +1414,69 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1207 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually 1414 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1208 * set and we always call the constant time version. 1415 * set and we always call the constant time version.
1209 */ 1416 */
1210 return group->meth->mul_generator_ct(group, r, g_scalar, ctx); 1417 ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx);
1211 } 1418 } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1212 if (g_scalar == NULL && point != NULL && p_scalar != NULL) { 1419 /*
1213 /* In this case we want to compute p_scalar * GenericPoint: 1420 * In this case we want to compute p_scalar * GenericPoint:
1214 * this codepath is reached most prominently by the second half 1421 * this codepath is reached most prominently by the second half
1215 * of ECDH, where the secret scalar is multiplied by the peer's 1422 * of ECDH, where the secret scalar is multiplied by the peer's
1216 * public point. To protect the secret scalar, we ignore if 1423 * public point. To protect the secret scalar, we ignore if
1217 * BN_FLG_CONSTTIME is actually set and we always call the 1424 * BN_FLG_CONSTTIME is actually set and we always call the
1218 * constant time version. 1425 * constant time version.
1219 */ 1426 */
1220 return group->meth->mul_single_ct(group, r, p_scalar, point, 1427 ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx);
1221 ctx); 1428 } else if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1222 }
1223 if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1224 /* 1429 /*
1225 * In this case we want to compute 1430 * In this case we want to compute
1226 * g_scalar * GeneratorPoint + p_scalar * GenericPoint: 1431 * g_scalar * GeneratorPoint + p_scalar * GenericPoint:
1227 * this codepath is reached most prominently by ECDSA signature 1432 * this codepath is reached most prominently by ECDSA signature
1228 * verification. So we call the non-ct version. 1433 * verification. So we call the non-ct version.
1229 */ 1434 */
1230 return group->meth->mul_double_nonct(group, r, g_scalar, 1435 ret = group->meth->mul_double_nonct(group, r, g_scalar,
1231 p_scalar, point, ctx); 1436 p_scalar, point, ctx);
1437 } else {
1438 /* Anything else is an error. */
1439 ECerror(ERR_R_EC_LIB);
1440 goto err;
1232 } 1441 }
1233 1442
1234 /* Anything else is an error. */ 1443 err:
1235 ECerror(ERR_R_EC_LIB); 1444 if (ctx != ctx_in)
1236 return 0; 1445 BN_CTX_free(ctx);
1446
1447 return ret;
1237} 1448}
1238 1449
1239int 1450int
1240EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 1451EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in)
1241{ 1452{
1242 if (group->meth->precompute_mult != 0) 1453 BN_CTX *ctx;
1243 return group->meth->precompute_mult(group, ctx); 1454 int ret = 0;
1244 else 1455
1245 return 1; /* nothing to do, so report success */ 1456 if (group->meth->precompute_mult == NULL)
1457 return 1;
1458
1459 if ((ctx = ctx_in) == NULL)
1460 ctx = BN_CTX_new();
1461 if (ctx == NULL)
1462 goto err;
1463
1464 ret = group->meth->precompute_mult(group, ctx);
1465
1466 err:
1467 if (ctx != ctx_in)
1468 BN_CTX_free(ctx);
1469
1470 return ret;
1246} 1471}
1247 1472
1248int 1473int
1249EC_GROUP_have_precompute_mult(const EC_GROUP *group) 1474EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1250{ 1475{
1251 if (group->meth->have_precompute_mult != 0) 1476 if (group->meth->have_precompute_mult == NULL)
1252 return group->meth->have_precompute_mult(group); 1477 return 0;
1253 else 1478
1254 return 0; /* cannot tell whether precomputation has 1479 return group->meth->have_precompute_mult(group);
1255 * been performed */
1256} 1480}
1257 1481
1258int 1482int
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
index c792725661..b70e60a1b4 100644
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ b/src/lib/libcrypto/ec/ec_mult.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_mult.c,v 1.28 2023/03/08 05:45:31 jsing Exp $ */ 1/* $OpenBSD: ec_mult.c,v 1.29 2023/04/11 18:58:20 jsing Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. 3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -335,7 +335,6 @@ int
335ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 335ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
336 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 336 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
337{ 337{
338 BN_CTX *new_ctx = NULL;
339 const EC_POINT *generator = NULL; 338 const EC_POINT *generator = NULL;
340 EC_POINT *tmp = NULL; 339 EC_POINT *tmp = NULL;
341 size_t totalnum; 340 size_t totalnum;
@@ -375,11 +374,6 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
375 } 374 }
376 } 375 }
377 376
378 if (ctx == NULL) {
379 ctx = new_ctx = BN_CTX_new();
380 if (ctx == NULL)
381 goto err;
382 }
383 if (scalar != NULL) { 377 if (scalar != NULL) {
384 generator = EC_GROUP_get0_generator(group); 378 generator = EC_GROUP_get0_generator(group);
385 if (generator == NULL) { 379 if (generator == NULL) {
@@ -679,7 +673,6 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
679 ret = 1; 673 ret = 1;
680 674
681 err: 675 err:
682 BN_CTX_free(new_ctx);
683 EC_POINT_free(tmp); 676 EC_POINT_free(tmp);
684 free(wsize); 677 free(wsize);
685 free(wNAF_len); 678 free(wNAF_len);
@@ -726,7 +719,6 @@ ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
726{ 719{
727 const EC_POINT *generator; 720 const EC_POINT *generator;
728 EC_POINT *tmp_point = NULL, *base = NULL, **var; 721 EC_POINT *tmp_point = NULL, *base = NULL, **var;
729 BN_CTX *new_ctx = NULL;
730 BIGNUM *order; 722 BIGNUM *order;
731 size_t i, bits, w, pre_points_per_block, blocksize, numblocks, 723 size_t i, bits, w, pre_points_per_block, blocksize, numblocks,
732 num; 724 num;
@@ -745,12 +737,9 @@ ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
745 ECerror(EC_R_UNDEFINED_GENERATOR); 737 ECerror(EC_R_UNDEFINED_GENERATOR);
746 goto err; 738 goto err;
747 } 739 }
748 if (ctx == NULL) { 740
749 ctx = new_ctx = BN_CTX_new();
750 if (ctx == NULL)
751 goto err;
752 }
753 BN_CTX_start(ctx); 741 BN_CTX_start(ctx);
742
754 if ((order = BN_CTX_get(ctx)) == NULL) 743 if ((order = BN_CTX_get(ctx)) == NULL)
755 goto err; 744 goto err;
756 745
@@ -857,10 +846,9 @@ ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
857 pre_comp = NULL; 846 pre_comp = NULL;
858 847
859 ret = 1; 848 ret = 1;
849
860 err: 850 err:
861 if (ctx != NULL) 851 BN_CTX_end(ctx);
862 BN_CTX_end(ctx);
863 BN_CTX_free(new_ctx);
864 ec_pre_comp_free(pre_comp); 852 ec_pre_comp_free(pre_comp);
865 if (points) { 853 if (points) {
866 EC_POINT **p; 854 EC_POINT **p;
diff --git a/src/lib/libcrypto/ec/ec_oct.c b/src/lib/libcrypto/ec/ec_oct.c
index ef17ec59a5..b1c9e6a634 100644
--- a/src/lib/libcrypto/ec/ec_oct.c
+++ b/src/lib/libcrypto/ec/ec_oct.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_oct.c,v 1.10 2023/03/08 04:50:27 jsing Exp $ */ 1/* $OpenBSD: ec_oct.c,v 1.11 2023/04/11 18:58:20 jsing 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 */
@@ -72,18 +72,32 @@
72 72
73int 73int
74EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 74EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
75 const BIGNUM *x, int y_bit, BN_CTX *ctx) 75 const BIGNUM *x, int y_bit, BN_CTX *ctx_in)
76{ 76{
77 BN_CTX *ctx;
78 int ret = 0;
79
80 if ((ctx = ctx_in) == NULL)
81 ctx = BN_CTX_new();
82 if (ctx == NULL)
83 goto err;
84
77 if (group->meth->point_set_compressed_coordinates == NULL) { 85 if (group->meth->point_set_compressed_coordinates == NULL) {
78 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 86 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
79 return 0; 87 goto err;
80 } 88 }
81 if (group->meth != point->meth) { 89 if (group->meth != point->meth) {
82 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 90 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
83 return 0; 91 goto err;
84 } 92 }
85 return group->meth->point_set_compressed_coordinates(group, point, 93 ret = group->meth->point_set_compressed_coordinates(group, point,
86 x, y_bit, ctx); 94 x, y_bit, ctx);
95
96 err:
97 if (ctx != ctx_in)
98 BN_CTX_free(ctx);
99
100 return ret;
87} 101}
88 102
89int 103int
@@ -104,31 +118,59 @@ EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
104 118
105size_t 119size_t
106EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, 120EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
107 point_conversion_form_t form, 121 point_conversion_form_t form, unsigned char *buf, size_t len,
108 unsigned char *buf, size_t len, BN_CTX *ctx) 122 BN_CTX *ctx_in)
109{ 123{
124 BN_CTX *ctx;
125 int ret = 0;
126
127 if ((ctx = ctx_in) == NULL)
128 ctx = BN_CTX_new();
129 if (ctx == NULL)
130 goto err;
131
110 if (group->meth->point2oct == NULL) { 132 if (group->meth->point2oct == NULL) {
111 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 133 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
112 return 0; 134 goto err;
113 } 135 }
114 if (group->meth != point->meth) { 136 if (group->meth != point->meth) {
115 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 137 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
116 return 0; 138 goto err;
117 } 139 }
118 return group->meth->point2oct(group, point, form, buf, len, ctx); 140 ret = group->meth->point2oct(group, point, form, buf, len, ctx);
141
142 err:
143 if (ctx != ctx_in)
144 BN_CTX_free(ctx);
145
146 return ret;
119} 147}
120 148
121int 149int
122EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, 150EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
123 const unsigned char *buf, size_t len, BN_CTX *ctx) 151 const unsigned char *buf, size_t len, BN_CTX *ctx_in)
124{ 152{
153 BN_CTX *ctx;
154 int ret = 0;
155
156 if ((ctx = ctx_in) == NULL)
157 ctx = BN_CTX_new();
158 if (ctx == NULL)
159 goto err;
160
125 if (group->meth->oct2point == NULL) { 161 if (group->meth->oct2point == NULL) {
126 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 162 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
127 return 0; 163 goto err;
128 } 164 }
129 if (group->meth != point->meth) { 165 if (group->meth != point->meth) {
130 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 166 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
131 return 0; 167 goto err;
132 } 168 }
133 return group->meth->oct2point(group, point, buf, len, ctx); 169 ret = group->meth->oct2point(group, point, buf, len, ctx);
170
171 err:
172 if (ctx != ctx_in)
173 BN_CTX_free(ctx);
174
175 return ret;
134} 176}
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
index 915cf15f72..b113855603 100644
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ b/src/lib/libcrypto/ec/ecp_mont.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_mont.c,v 1.28 2023/03/27 10:25:02 tb Exp $ */ 1/* $OpenBSD: ecp_mont.c,v 1.29 2023/04/11 18:58:20 jsing 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 */
@@ -127,18 +127,12 @@ static int
127ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 127ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
128 const BIGNUM *b, BN_CTX *ctx) 128 const BIGNUM *b, BN_CTX *ctx)
129{ 129{
130 BN_CTX *new_ctx = NULL;
131 BN_MONT_CTX *mont = NULL; 130 BN_MONT_CTX *mont = NULL;
132 BIGNUM *one = NULL; 131 BIGNUM *one = NULL;
133 int ret = 0; 132 int ret = 0;
134 133
135 ec_GFp_mont_group_clear(group); 134 ec_GFp_mont_group_clear(group);
136 135
137 if (ctx == NULL) {
138 ctx = new_ctx = BN_CTX_new();
139 if (ctx == NULL)
140 return 0;
141 }
142 mont = BN_MONT_CTX_new(); 136 mont = BN_MONT_CTX_new();
143 if (mont == NULL) 137 if (mont == NULL)
144 goto err; 138 goto err;
@@ -158,14 +152,13 @@ ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
158 one = NULL; 152 one = NULL;
159 153
160 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); 154 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
161
162 if (!ret) 155 if (!ret)
163 ec_GFp_mont_group_clear(group); 156 ec_GFp_mont_group_clear(group);
164 157
165 err: 158 err:
166 BN_CTX_free(new_ctx);
167 BN_MONT_CTX_free(mont); 159 BN_MONT_CTX_free(mont);
168 BN_free(one); 160 BN_free(one);
161
169 return ret; 162 return ret;
170} 163}
171 164
@@ -222,6 +215,7 @@ ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
222 } 215 }
223 if (!bn_copy(r, group->mont_one)) 216 if (!bn_copy(r, group->mont_one))
224 return 0; 217 return 0;
218
225 return 1; 219 return 1;
226} 220}
227 221
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
index c736526a66..9478b4dc6e 100644
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ b/src/lib/libcrypto/ec/ecp_nist.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_nist.c,v 1.25 2023/04/11 18:53:20 jsing Exp $ */ 1/* $OpenBSD: ecp_nist.c,v 1.26 2023/04/11 18:58:20 jsing Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -80,15 +80,6 @@ static int
80ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, 80ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
81 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 81 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
82{ 82{
83 int ret = 0;
84 BN_CTX *new_ctx = NULL;
85
86 if (ctx == NULL)
87 if ((ctx = new_ctx = BN_CTX_new()) == NULL)
88 return 0;
89
90 BN_CTX_start(ctx);
91
92 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) 83 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
93 group->field_mod_func = BN_nist_mod_192; 84 group->field_mod_func = BN_nist_mod_192;
94 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) 85 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
@@ -101,67 +92,40 @@ ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
101 group->field_mod_func = BN_nist_mod_521; 92 group->field_mod_func = BN_nist_mod_521;
102 else { 93 else {
103 ECerror(EC_R_NOT_A_NIST_PRIME); 94 ECerror(EC_R_NOT_A_NIST_PRIME);
104 goto err; 95 return 0;
105 } 96 }
106 97
107 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); 98 return ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
108
109 err:
110 BN_CTX_end(ctx);
111 BN_CTX_free(new_ctx);
112 return ret;
113} 99}
114 100
115static int 101static int
116ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, 102ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
117 const BIGNUM *b, BN_CTX *ctx) 103 const BIGNUM *b, BN_CTX *ctx)
118{ 104{
119 int ret = 0; 105 if (group == NULL || r == NULL || a == NULL || b == NULL) {
120 BN_CTX *ctx_new = NULL;
121
122 if (!group || !r || !a || !b) {
123 ECerror(ERR_R_PASSED_NULL_PARAMETER); 106 ECerror(ERR_R_PASSED_NULL_PARAMETER);
124 goto err; 107 return 0;
125 } 108 }
126 if (!ctx)
127 if ((ctx_new = ctx = BN_CTX_new()) == NULL)
128 goto err;
129 109
130 if (!BN_mul(r, a, b, ctx)) 110 if (!BN_mul(r, a, b, ctx))
131 goto err; 111 return 0;
132 if (!group->field_mod_func(r, r, &group->field, ctx))
133 goto err;
134 112
135 ret = 1; 113 return group->field_mod_func(r, r, &group->field, ctx);
136 err:
137 BN_CTX_free(ctx_new);
138 return ret;
139} 114}
140 115
141static int 116static int
142ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, 117ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
143 BN_CTX *ctx) 118 BN_CTX *ctx)
144{ 119{
145 int ret = 0; 120 if (group == NULL || r == NULL || a == NULL) {
146 BN_CTX *ctx_new = NULL;
147
148 if (!group || !r || !a) {
149 ECerror(EC_R_PASSED_NULL_PARAMETER); 121 ECerror(EC_R_PASSED_NULL_PARAMETER);
150 goto err; 122 return 0;
151 } 123 }
152 if (!ctx)
153 if ((ctx_new = ctx = BN_CTX_new()) == NULL)
154 goto err;
155 124
156 if (!BN_sqr(r, a, ctx)) 125 if (!BN_sqr(r, a, ctx))
157 goto err; 126 return 0;
158 if (!group->field_mod_func(r, r, &group->field, ctx))
159 goto err;
160 127
161 ret = 1; 128 return group->field_mod_func(r, r, &group->field, ctx);
162 err:
163 BN_CTX_free(ctx_new);
164 return ret;
165} 129}
166 130
167static const EC_METHOD ec_GFp_nist_method = { 131static const EC_METHOD ec_GFp_nist_method = {
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c
index f2f1929e84..8cdf544bf1 100644
--- a/src/lib/libcrypto/ec/ecp_oct.c
+++ b/src/lib/libcrypto/ec/ecp_oct.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_oct.c,v 1.19 2022/11/26 16:08:52 tb Exp $ */ 1/* $OpenBSD: ecp_oct.c,v 1.20 2023/04/11 18:58:20 jsing 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.
@@ -70,21 +70,16 @@ int
70ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, 70ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
71 EC_POINT *point, const BIGNUM *x_, int y_bit, BN_CTX *ctx) 71 EC_POINT *point, const BIGNUM *x_, int y_bit, BN_CTX *ctx)
72{ 72{
73 BN_CTX *new_ctx = NULL;
74 BIGNUM *tmp1, *tmp2, *x, *y; 73 BIGNUM *tmp1, *tmp2, *x, *y;
75 int ret = 0; 74 int ret = 0;
76 75
77 /* clear error queue */ 76 /* clear error queue */
78 ERR_clear_error(); 77 ERR_clear_error();
79 78
80 if (ctx == NULL) {
81 ctx = new_ctx = BN_CTX_new();
82 if (ctx == NULL)
83 return 0;
84 }
85 y_bit = (y_bit != 0); 79 y_bit = (y_bit != 0);
86 80
87 BN_CTX_start(ctx); 81 BN_CTX_start(ctx);
82
88 if ((tmp1 = BN_CTX_get(ctx)) == NULL) 83 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
89 goto err; 84 goto err;
90 if ((tmp2 = BN_CTX_get(ctx)) == NULL) 85 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
@@ -179,27 +174,25 @@ ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
179 174
180 err: 175 err:
181 BN_CTX_end(ctx); 176 BN_CTX_end(ctx);
182 BN_CTX_free(new_ctx); 177
183 return ret; 178 return ret;
184} 179}
185 180
186
187size_t 181size_t
188ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, 182ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
189 unsigned char *buf, size_t len, BN_CTX *ctx) 183 point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx)
190{ 184{
191 size_t ret;
192 BN_CTX *new_ctx = NULL;
193 int used_ctx = 0;
194 BIGNUM *x, *y; 185 BIGNUM *x, *y;
195 size_t field_len, i, skip; 186 size_t field_len, i, skip;
187 size_t ret = 0;
196 188
197 if ((form != POINT_CONVERSION_COMPRESSED) 189 if (form != POINT_CONVERSION_COMPRESSED &&
198 && (form != POINT_CONVERSION_UNCOMPRESSED) 190 form != POINT_CONVERSION_UNCOMPRESSED &&
199 && (form != POINT_CONVERSION_HYBRID)) { 191 form != POINT_CONVERSION_HYBRID) {
200 ECerror(EC_R_INVALID_FORM); 192 ECerror(EC_R_INVALID_FORM);
201 goto err; 193 return 0;
202 } 194 }
195
203 if (EC_POINT_is_at_infinity(group, point) > 0) { 196 if (EC_POINT_is_at_infinity(group, point) > 0) {
204 /* encodes to a single 0 octet */ 197 /* encodes to a single 0 octet */
205 if (buf != NULL) { 198 if (buf != NULL) {
@@ -211,23 +204,20 @@ ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conv
211 } 204 }
212 return 1; 205 return 1;
213 } 206 }
207
214 /* ret := required output buffer length */ 208 /* ret := required output buffer length */
215 field_len = BN_num_bytes(&group->field); 209 field_len = BN_num_bytes(&group->field);
216 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; 210 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
217 211
212 BN_CTX_start(ctx);
213
218 /* if 'buf' is NULL, just return required length */ 214 /* if 'buf' is NULL, just return required length */
219 if (buf != NULL) { 215 if (buf != NULL) {
220 if (len < ret) { 216 if (len < ret) {
221 ECerror(EC_R_BUFFER_TOO_SMALL); 217 ECerror(EC_R_BUFFER_TOO_SMALL);
222 goto err; 218 goto err;
223 } 219 }
224 if (ctx == NULL) { 220
225 ctx = new_ctx = BN_CTX_new();
226 if (ctx == NULL)
227 return 0;
228 }
229 BN_CTX_start(ctx);
230 used_ctx = 1;
231 if ((x = BN_CTX_get(ctx)) == NULL) 221 if ((x = BN_CTX_get(ctx)) == NULL)
232 goto err; 222 goto err;
233 if ((y = BN_CTX_get(ctx)) == NULL) 223 if ((y = BN_CTX_get(ctx)) == NULL)
@@ -276,18 +266,12 @@ ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conv
276 goto err; 266 goto err;
277 } 267 }
278 } 268 }
279 if (used_ctx)
280 BN_CTX_end(ctx);
281 BN_CTX_free(new_ctx);
282 return ret;
283 269
284 err: 270 err:
285 if (used_ctx) 271 BN_CTX_end(ctx);
286 BN_CTX_end(ctx);
287 BN_CTX_free(new_ctx);
288 return 0;
289}
290 272
273 return ret;
274}
291 275
292int 276int
293ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, 277ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
@@ -295,7 +279,6 @@ ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
295{ 279{
296 point_conversion_form_t form; 280 point_conversion_form_t form;
297 int y_bit; 281 int y_bit;
298 BN_CTX *new_ctx = NULL;
299 BIGNUM *x, *y; 282 BIGNUM *x, *y;
300 size_t field_len, enc_len; 283 size_t field_len, enc_len;
301 int ret = 0; 284 int ret = 0;
@@ -331,12 +314,9 @@ ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
331 ECerror(EC_R_INVALID_ENCODING); 314 ECerror(EC_R_INVALID_ENCODING);
332 return 0; 315 return 0;
333 } 316 }
334 if (ctx == NULL) { 317
335 ctx = new_ctx = BN_CTX_new();
336 if (ctx == NULL)
337 return 0;
338 }
339 BN_CTX_start(ctx); 318 BN_CTX_start(ctx);
319
340 if ((x = BN_CTX_get(ctx)) == NULL) 320 if ((x = BN_CTX_get(ctx)) == NULL)
341 goto err; 321 goto err;
342 if ((y = BN_CTX_get(ctx)) == NULL) 322 if ((y = BN_CTX_get(ctx)) == NULL)
@@ -380,6 +360,6 @@ ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
380 360
381 err: 361 err:
382 BN_CTX_end(ctx); 362 BN_CTX_end(ctx);
383 BN_CTX_free(new_ctx); 363
384 return ret; 364 return ret;
385} 365}
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
index 90330652e4..1162d89ca5 100644
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ b/src/lib/libcrypto/ec/ecp_smpl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_smpl.c,v 1.43 2023/03/27 10:25:02 tb Exp $ */ 1/* $OpenBSD: ecp_smpl.c,v 1.44 2023/04/11 18:58:20 jsing 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.
@@ -118,21 +118,17 @@ int
118ec_GFp_simple_group_set_curve(EC_GROUP *group, 118ec_GFp_simple_group_set_curve(EC_GROUP *group,
119 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 119 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
120{ 120{
121 int ret = 0;
122 BN_CTX *new_ctx = NULL;
123 BIGNUM *tmp_a; 121 BIGNUM *tmp_a;
122 int ret = 0;
124 123
125 /* p must be a prime > 3 */ 124 /* p must be a prime > 3 */
126 if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { 125 if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
127 ECerror(EC_R_INVALID_FIELD); 126 ECerror(EC_R_INVALID_FIELD);
128 return 0; 127 return 0;
129 } 128 }
130 if (ctx == NULL) { 129
131 ctx = new_ctx = BN_CTX_new();
132 if (ctx == NULL)
133 return 0;
134 }
135 BN_CTX_start(ctx); 130 BN_CTX_start(ctx);
131
136 if ((tmp_a = BN_CTX_get(ctx)) == NULL) 132 if ((tmp_a = BN_CTX_get(ctx)) == NULL)
137 goto err; 133 goto err;
138 134
@@ -166,51 +162,38 @@ ec_GFp_simple_group_set_curve(EC_GROUP *group,
166 162
167 err: 163 err:
168 BN_CTX_end(ctx); 164 BN_CTX_end(ctx);
169 BN_CTX_free(new_ctx); 165
170 return ret; 166 return ret;
171} 167}
172 168
173int 169int
174ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 170ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
175{ 171{
176 int ret = 0;
177 BN_CTX *new_ctx = NULL;
178
179 if (p != NULL) { 172 if (p != NULL) {
180 if (!bn_copy(p, &group->field)) 173 if (!bn_copy(p, &group->field))
181 return 0; 174 return 0;
182 } 175 }
183 if (a != NULL || b != NULL) { 176 if (group->meth->field_decode != NULL) {
184 if (group->meth->field_decode) { 177 if (a != NULL) {
185 if (ctx == NULL) { 178 if (!group->meth->field_decode(group, a, &group->a, ctx))
186 ctx = new_ctx = BN_CTX_new(); 179 return 0;
187 if (ctx == NULL) 180 }
188 return 0; 181 if (b != NULL) {
189 } 182 if (!group->meth->field_decode(group, b, &group->b, ctx))
190 if (a != NULL) { 183 return 0;
191 if (!group->meth->field_decode(group, a, &group->a, ctx)) 184 }
192 goto err; 185 } else {
193 } 186 if (a != NULL) {
194 if (b != NULL) { 187 if (!bn_copy(a, &group->a))
195 if (!group->meth->field_decode(group, b, &group->b, ctx)) 188 return 0;
196 goto err; 189 }
197 } 190 if (b != NULL) {
198 } else { 191 if (!bn_copy(b, &group->b))
199 if (a != NULL) { 192 return 0;
200 if (!bn_copy(a, &group->a))
201 goto err;
202 }
203 if (b != NULL) {
204 if (!bn_copy(b, &group->b))
205 goto err;
206 }
207 } 193 }
208 } 194 }
209 ret = 1;
210 195
211 err: 196 return 1;
212 BN_CTX_free(new_ctx);
213 return ret;
214} 197}
215 198
216int 199int
@@ -222,19 +205,12 @@ ec_GFp_simple_group_get_degree(const EC_GROUP *group)
222int 205int
223ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 206ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
224{ 207{
225 int ret = 0;
226 BIGNUM *a, *b, *order, *tmp_1, *tmp_2; 208 BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
227 const BIGNUM *p = &group->field; 209 const BIGNUM *p = &group->field;
228 BN_CTX *new_ctx = NULL; 210 int ret = 0;
229 211
230 if (ctx == NULL) {
231 ctx = new_ctx = BN_CTX_new();
232 if (ctx == NULL) {
233 ECerror(ERR_R_MALLOC_FAILURE);
234 goto err;
235 }
236 }
237 BN_CTX_start(ctx); 212 BN_CTX_start(ctx);
213
238 if ((a = BN_CTX_get(ctx)) == NULL) 214 if ((a = BN_CTX_get(ctx)) == NULL)
239 goto err; 215 goto err;
240 if ((b = BN_CTX_get(ctx)) == NULL) 216 if ((b = BN_CTX_get(ctx)) == NULL)
@@ -288,9 +264,8 @@ ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
288 ret = 1; 264 ret = 1;
289 265
290 err: 266 err:
291 if (ctx != NULL) 267 BN_CTX_end(ctx);
292 BN_CTX_end(ctx); 268
293 BN_CTX_free(new_ctx);
294 return ret; 269 return ret;
295} 270}
296 271
@@ -341,18 +316,12 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group,
341 EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, 316 EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z,
342 BN_CTX *ctx) 317 BN_CTX *ctx)
343{ 318{
344 BN_CTX *new_ctx = NULL;
345 int ret = 0; 319 int ret = 0;
346 320
347 if (ctx == NULL) {
348 ctx = new_ctx = BN_CTX_new();
349 if (ctx == NULL)
350 return 0;
351 }
352 if (x != NULL) { 321 if (x != NULL) {
353 if (!BN_nnmod(&point->X, x, &group->field, ctx)) 322 if (!BN_nnmod(&point->X, x, &group->field, ctx))
354 goto err; 323 goto err;
355 if (group->meth->field_encode) { 324 if (group->meth->field_encode != NULL) {
356 if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) 325 if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
357 goto err; 326 goto err;
358 } 327 }
@@ -360,7 +329,7 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group,
360 if (y != NULL) { 329 if (y != NULL) {
361 if (!BN_nnmod(&point->Y, y, &group->field, ctx)) 330 if (!BN_nnmod(&point->Y, y, &group->field, ctx))
362 goto err; 331 goto err;
363 if (group->meth->field_encode) { 332 if (group->meth->field_encode != NULL) {
364 if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) 333 if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
365 goto err; 334 goto err;
366 } 335 }
@@ -371,7 +340,7 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group,
371 if (!BN_nnmod(&point->Z, z, &group->field, ctx)) 340 if (!BN_nnmod(&point->Z, z, &group->field, ctx))
372 goto err; 341 goto err;
373 Z_is_one = BN_is_one(&point->Z); 342 Z_is_one = BN_is_one(&point->Z);
374 if (group->meth->field_encode) { 343 if (group->meth->field_encode != NULL) {
375 if (Z_is_one && (group->meth->field_set_to_one != 0)) { 344 if (Z_is_one && (group->meth->field_set_to_one != 0)) {
376 if (!group->meth->field_set_to_one(group, &point->Z, ctx)) 345 if (!group->meth->field_set_to_one(group, &point->Z, ctx))
377 goto err; 346 goto err;
@@ -385,7 +354,6 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group,
385 ret = 1; 354 ret = 1;
386 355
387 err: 356 err:
388 BN_CTX_free(new_ctx);
389 return ret; 357 return ret;
390} 358}
391 359
@@ -393,15 +361,9 @@ int
393ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group, 361ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group,
394 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 362 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
395{ 363{
396 BN_CTX *new_ctx = NULL;
397 int ret = 0; 364 int ret = 0;
398 365
399 if (group->meth->field_decode != 0) { 366 if (group->meth->field_decode != NULL) {
400 if (ctx == NULL) {
401 ctx = new_ctx = BN_CTX_new();
402 if (ctx == NULL)
403 return 0;
404 }
405 if (x != NULL) { 367 if (x != NULL) {
406 if (!group->meth->field_decode(group, x, &point->X, ctx)) 368 if (!group->meth->field_decode(group, x, &point->X, ctx))
407 goto err; 369 goto err;
@@ -432,7 +394,6 @@ ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group,
432 ret = 1; 394 ret = 1;
433 395
434 err: 396 err:
435 BN_CTX_free(new_ctx);
436 return ret; 397 return ret;
437} 398}
438 399
@@ -453,7 +414,6 @@ int
453ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 414ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
454 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 415 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
455{ 416{
456 BN_CTX *new_ctx = NULL;
457 BIGNUM *Z, *Z_1, *Z_2, *Z_3; 417 BIGNUM *Z, *Z_1, *Z_2, *Z_3;
458 const BIGNUM *Z_; 418 const BIGNUM *Z_;
459 int ret = 0; 419 int ret = 0;
@@ -462,12 +422,9 @@ ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT
462 ECerror(EC_R_POINT_AT_INFINITY); 422 ECerror(EC_R_POINT_AT_INFINITY);
463 return 0; 423 return 0;
464 } 424 }
465 if (ctx == NULL) { 425
466 ctx = new_ctx = BN_CTX_new();
467 if (ctx == NULL)
468 return 0;
469 }
470 BN_CTX_start(ctx); 426 BN_CTX_start(ctx);
427
471 if ((Z = BN_CTX_get(ctx)) == NULL) 428 if ((Z = BN_CTX_get(ctx)) == NULL)
472 goto err; 429 goto err;
473 if ((Z_1 = BN_CTX_get(ctx)) == NULL) 430 if ((Z_1 = BN_CTX_get(ctx)) == NULL)
@@ -552,7 +509,7 @@ ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT
552 509
553 err: 510 err:
554 BN_CTX_end(ctx); 511 BN_CTX_end(ctx);
555 BN_CTX_free(new_ctx); 512
556 return ret; 513 return ret;
557} 514}
558 515
@@ -561,9 +518,8 @@ ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const E
561{ 518{
562 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 519 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
563 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 520 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
564 const BIGNUM *p;
565 BN_CTX *new_ctx = NULL;
566 BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; 521 BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
522 const BIGNUM *p;
567 int ret = 0; 523 int ret = 0;
568 524
569 if (a == b) 525 if (a == b)
@@ -577,12 +533,8 @@ ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const E
577 field_sqr = group->meth->field_sqr; 533 field_sqr = group->meth->field_sqr;
578 p = &group->field; 534 p = &group->field;
579 535
580 if (ctx == NULL) {
581 ctx = new_ctx = BN_CTX_new();
582 if (ctx == NULL)
583 return 0;
584 }
585 BN_CTX_start(ctx); 536 BN_CTX_start(ctx);
537
586 if ((n0 = BN_CTX_get(ctx)) == NULL) 538 if ((n0 = BN_CTX_get(ctx)) == NULL)
587 goto end; 539 goto end;
588 if ((n1 = BN_CTX_get(ctx)) == NULL) 540 if ((n1 = BN_CTX_get(ctx)) == NULL)
@@ -738,9 +690,8 @@ ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const E
738 ret = 1; 690 ret = 1;
739 691
740 end: 692 end:
741 if (ctx) /* otherwise we already called BN_CTX_end */ 693 BN_CTX_end(ctx);
742 BN_CTX_end(ctx); 694
743 BN_CTX_free(new_ctx);
744 return ret; 695 return ret;
745} 696}
746 697
@@ -750,7 +701,6 @@ ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX
750 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 701 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
751 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 702 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
752 const BIGNUM *p; 703 const BIGNUM *p;
753 BN_CTX *new_ctx = NULL;
754 BIGNUM *n0, *n1, *n2, *n3; 704 BIGNUM *n0, *n1, *n2, *n3;
755 int ret = 0; 705 int ret = 0;
756 706
@@ -763,12 +713,8 @@ ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX
763 field_sqr = group->meth->field_sqr; 713 field_sqr = group->meth->field_sqr;
764 p = &group->field; 714 p = &group->field;
765 715
766 if (ctx == NULL) {
767 ctx = new_ctx = BN_CTX_new();
768 if (ctx == NULL)
769 return 0;
770 }
771 BN_CTX_start(ctx); 716 BN_CTX_start(ctx);
717
772 if ((n0 = BN_CTX_get(ctx)) == NULL) 718 if ((n0 = BN_CTX_get(ctx)) == NULL)
773 goto err; 719 goto err;
774 if ((n1 = BN_CTX_get(ctx)) == NULL) 720 if ((n1 = BN_CTX_get(ctx)) == NULL)
@@ -881,7 +827,7 @@ ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX
881 827
882 err: 828 err:
883 BN_CTX_end(ctx); 829 BN_CTX_end(ctx);
884 BN_CTX_free(new_ctx); 830
885 return ret; 831 return ret;
886} 832}
887 833
@@ -907,7 +853,6 @@ ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *
907 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 853 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
908 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 854 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
909 const BIGNUM *p; 855 const BIGNUM *p;
910 BN_CTX *new_ctx = NULL;
911 BIGNUM *rh, *tmp, *Z4, *Z6; 856 BIGNUM *rh, *tmp, *Z4, *Z6;
912 int ret = -1; 857 int ret = -1;
913 858
@@ -918,12 +863,8 @@ ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *
918 field_sqr = group->meth->field_sqr; 863 field_sqr = group->meth->field_sqr;
919 p = &group->field; 864 p = &group->field;
920 865
921 if (ctx == NULL) {
922 ctx = new_ctx = BN_CTX_new();
923 if (ctx == NULL)
924 return -1;
925 }
926 BN_CTX_start(ctx); 866 BN_CTX_start(ctx);
867
927 if ((rh = BN_CTX_get(ctx)) == NULL) 868 if ((rh = BN_CTX_get(ctx)) == NULL)
928 goto err; 869 goto err;
929 if ((tmp = BN_CTX_get(ctx)) == NULL) 870 if ((tmp = BN_CTX_get(ctx)) == NULL)
@@ -999,7 +940,7 @@ ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *
999 940
1000 err: 941 err:
1001 BN_CTX_end(ctx); 942 BN_CTX_end(ctx);
1002 BN_CTX_free(new_ctx); 943
1003 return ret; 944 return ret;
1004} 945}
1005 946
@@ -1013,29 +954,24 @@ ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, B
1013 954
1014 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 955 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
1015 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 956 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1016 BN_CTX *new_ctx = NULL;
1017 BIGNUM *tmp1, *tmp2, *Za23, *Zb23; 957 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
1018 const BIGNUM *tmp1_, *tmp2_; 958 const BIGNUM *tmp1_, *tmp2_;
1019 int ret = -1; 959 int ret = -1;
1020 960
1021 if (EC_POINT_is_at_infinity(group, a) > 0) { 961 if (EC_POINT_is_at_infinity(group, a) > 0)
1022 return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1; 962 return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
1023 } 963
1024 if (EC_POINT_is_at_infinity(group, b) > 0) 964 if (EC_POINT_is_at_infinity(group, b) > 0)
1025 return 1; 965 return 1;
1026 966
1027 if (a->Z_is_one && b->Z_is_one) { 967 if (a->Z_is_one && b->Z_is_one)
1028 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; 968 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
1029 } 969
1030 field_mul = group->meth->field_mul; 970 field_mul = group->meth->field_mul;
1031 field_sqr = group->meth->field_sqr; 971 field_sqr = group->meth->field_sqr;
1032 972
1033 if (ctx == NULL) {
1034 ctx = new_ctx = BN_CTX_new();
1035 if (ctx == NULL)
1036 return -1;
1037 }
1038 BN_CTX_start(ctx); 973 BN_CTX_start(ctx);
974
1039 if ((tmp1 = BN_CTX_get(ctx)) == NULL) 975 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
1040 goto end; 976 goto end;
1041 if ((tmp2 = BN_CTX_get(ctx)) == NULL) 977 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
@@ -1100,26 +1036,21 @@ ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, B
1100 1036
1101 end: 1037 end:
1102 BN_CTX_end(ctx); 1038 BN_CTX_end(ctx);
1103 BN_CTX_free(new_ctx); 1039
1104 return ret; 1040 return ret;
1105} 1041}
1106 1042
1107int 1043int
1108ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 1044ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1109{ 1045{
1110 BN_CTX *new_ctx = NULL;
1111 BIGNUM *x, *y; 1046 BIGNUM *x, *y;
1112 int ret = 0; 1047 int ret = 0;
1113 1048
1114 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0) 1049 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
1115 return 1; 1050 return 1;
1116 1051
1117 if (ctx == NULL) {
1118 ctx = new_ctx = BN_CTX_new();
1119 if (ctx == NULL)
1120 return 0;
1121 }
1122 BN_CTX_start(ctx); 1052 BN_CTX_start(ctx);
1053
1123 if ((x = BN_CTX_get(ctx)) == NULL) 1054 if ((x = BN_CTX_get(ctx)) == NULL)
1124 goto err; 1055 goto err;
1125 if ((y = BN_CTX_get(ctx)) == NULL) 1056 if ((y = BN_CTX_get(ctx)) == NULL)
@@ -1137,14 +1068,13 @@ ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
1137 1068
1138 err: 1069 err:
1139 BN_CTX_end(ctx); 1070 BN_CTX_end(ctx);
1140 BN_CTX_free(new_ctx); 1071
1141 return ret; 1072 return ret;
1142} 1073}
1143 1074
1144int 1075int
1145ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) 1076ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
1146{ 1077{
1147 BN_CTX *new_ctx = NULL;
1148 BIGNUM *tmp0, *tmp1; 1078 BIGNUM *tmp0, *tmp1;
1149 size_t pow2 = 0; 1079 size_t pow2 = 0;
1150 BIGNUM **heap = NULL; 1080 BIGNUM **heap = NULL;
@@ -1154,12 +1084,8 @@ ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *po
1154 if (num == 0) 1084 if (num == 0)
1155 return 1; 1085 return 1;
1156 1086
1157 if (ctx == NULL) {
1158 ctx = new_ctx = BN_CTX_new();
1159 if (ctx == NULL)
1160 return 0;
1161 }
1162 BN_CTX_start(ctx); 1087 BN_CTX_start(ctx);
1088
1163 if ((tmp0 = BN_CTX_get(ctx)) == NULL) 1089 if ((tmp0 = BN_CTX_get(ctx)) == NULL)
1164 goto err; 1090 goto err;
1165 if ((tmp1 = BN_CTX_get(ctx)) == NULL) 1091 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
@@ -1301,7 +1227,7 @@ ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *po
1301 1227
1302 err: 1228 err:
1303 BN_CTX_end(ctx); 1229 BN_CTX_end(ctx);
1304 BN_CTX_free(new_ctx); 1230
1305 if (heap != NULL) { 1231 if (heap != NULL) {
1306 /* 1232 /*
1307 * heap[pow2/2] .. heap[pow2-1] have not been allocated 1233 * heap[pow2/2] .. heap[pow2-1] have not been allocated
@@ -1431,12 +1357,8 @@ ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1431 BIGNUM *k = NULL; 1357 BIGNUM *k = NULL;
1432 BIGNUM *lambda = NULL; 1358 BIGNUM *lambda = NULL;
1433 BIGNUM *cardinality = NULL; 1359 BIGNUM *cardinality = NULL;
1434 BN_CTX *new_ctx = NULL;
1435 int ret = 0; 1360 int ret = 0;
1436 1361
1437 if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL)
1438 return 0;
1439
1440 BN_CTX_start(ctx); 1362 BN_CTX_start(ctx);
1441 1363
1442 if ((s = EC_POINT_new(group)) == NULL) 1364 if ((s = EC_POINT_new(group)) == NULL)
@@ -1605,9 +1527,7 @@ ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1605 1527
1606 err: 1528 err:
1607 EC_POINT_free(s); 1529 EC_POINT_free(s);
1608 if (ctx != NULL) 1530 BN_CTX_end(ctx);
1609 BN_CTX_end(ctx);
1610 BN_CTX_free(new_ctx);
1611 1531
1612 return ret; 1532 return ret;
1613} 1533}