summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2023-06-24 17:49:44 +0000
committerjsing <>2023-06-24 17:49:44 +0000
commit7f15e5a3e5c10e4517df9decdb2e27dcf9550d6c (patch)
tree668a9ce3c8e1082d03e94389c51d3f971147b538 /src
parent929c71e96837b9af0aab24ea7bacc4159d89cc64 (diff)
downloadopenbsd-7f15e5a3e5c10e4517df9decdb2e27dcf9550d6c.tar.gz
openbsd-7f15e5a3e5c10e4517df9decdb2e27dcf9550d6c.tar.bz2
openbsd-7f15e5a3e5c10e4517df9decdb2e27dcf9550d6c.zip
Mop up EC_GROUP precomp machinery.
Since there are now no EC implementations that perform pre-computation at the EC_GROUP level, remove all of the precomp machinery, including the extra_data EC_GROUP member. The ec_wNAF_mul() code is horrific - simply cut out the precomp code, rather than trying to rewrite it (that's a project for another day). ok tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c20
-rw-r--r--src/lib/libcrypto/ec/ec_local.h4
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c238
3 files changed, 10 insertions, 252 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 817b0239be..93a9065129 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.58 2023/06/20 14:37:15 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.59 2023/06/24 17:49:44 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 */
@@ -93,8 +93,6 @@ EC_GROUP_new(const EC_METHOD *meth)
93 } 93 }
94 ret->meth = meth; 94 ret->meth = meth;
95 95
96 ret->extra_data = NULL;
97
98 ret->generator = NULL; 96 ret->generator = NULL;
99 BN_init(&ret->order); 97 BN_init(&ret->order);
100 BN_init(&ret->cofactor); 98 BN_init(&ret->cofactor);
@@ -123,8 +121,6 @@ EC_GROUP_free(EC_GROUP *group)
123 if (group->meth->group_finish != NULL) 121 if (group->meth->group_finish != NULL)
124 group->meth->group_finish(group); 122 group->meth->group_finish(group);
125 123
126 EC_EX_DATA_clear_free_all_data(&group->extra_data);
127
128 EC_POINT_free(group->generator); 124 EC_POINT_free(group->generator);
129 BN_free(&group->order); 125 BN_free(&group->order);
130 BN_free(&group->cofactor); 126 BN_free(&group->cofactor);
@@ -142,8 +138,6 @@ EC_GROUP_clear_free(EC_GROUP *group)
142int 138int
143EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) 139EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
144{ 140{
145 EC_EXTRA_DATA *d;
146
147 if (dest->meth->group_copy == NULL) { 141 if (dest->meth->group_copy == NULL) {
148 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 142 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
149 return 0; 143 return 0;
@@ -155,18 +149,6 @@ EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
155 if (dest == src) 149 if (dest == src)
156 return 1; 150 return 1;
157 151
158 EC_EX_DATA_free_all_data(&dest->extra_data);
159
160 for (d = src->extra_data; d != NULL; d = d->next) {
161 void *t = d->dup_func(d->data);
162
163 if (t == NULL)
164 return 0;
165 if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func,
166 d->free_func, d->clear_free_func))
167 return 0;
168 }
169
170 if (src->generator != NULL) { 152 if (src->generator != NULL) {
171 if (dest->generator == NULL) { 153 if (dest->generator == NULL) {
172 dest->generator = EC_POINT_new(dest); 154 dest->generator = EC_POINT_new(dest);
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index d178665c1f..c0689a3c3e 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.15 2023/06/24 17:18:15 jsing Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.16 2023/06/24 17:49:44 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 */
@@ -209,8 +209,6 @@ struct ec_group_st {
209 * if they appear to be generic. 209 * if they appear to be generic.
210 */ 210 */
211 211
212 EC_EXTRA_DATA *extra_data;
213
214 /* 212 /*
215 * Field specification. For GF(p) this is the modulus; for GF(2^m), 213 * Field specification. For GF(p) this is the modulus; for GF(2^m),
216 * this is the irreducible polynomial defining the field. 214 * this is the irreducible polynomial defining the field.
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
index 61428eb142..a0e97437bb 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.30 2023/06/24 17:18:15 jsing Exp $ */ 1/* $OpenBSD: ec_mult.c,v 1.31 2023/06/24 17:49:44 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 */
@@ -67,7 +67,6 @@
67 67
68#include "ec_local.h" 68#include "ec_local.h"
69 69
70
71/* 70/*
72 * This file implements the wNAF-based interleaving multi-exponentation method 71 * This file implements the wNAF-based interleaving multi-exponentation method
73 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>); 72 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
@@ -75,91 +74,6 @@
75 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>). 74 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
76 */ 75 */
77 76
78
79
80
81/* structure for precomputed multiples of the generator */
82typedef struct ec_pre_comp_st {
83 const EC_GROUP *group; /* parent EC_GROUP object */
84 size_t blocksize; /* block size for wNAF splitting */
85 size_t numblocks; /* max. number of blocks for which we have
86 * precomputation */
87 size_t w; /* window size */
88 EC_POINT **points; /* array with pre-calculated multiples of
89 * generator: 'num' pointers to EC_POINT
90 * objects followed by a NULL */
91 size_t num; /* numblocks * 2^(w-1) */
92 int references;
93} EC_PRE_COMP;
94
95/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
96static void *ec_pre_comp_dup(void *);
97static void ec_pre_comp_free(void *);
98static void ec_pre_comp_clear_free(void *);
99
100static void *
101ec_pre_comp_dup(void *src_)
102{
103 EC_PRE_COMP *src = src_;
104
105 /* no need to actually copy, these objects never change! */
106
107 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
108
109 return src_;
110}
111
112static void
113ec_pre_comp_free(void *pre_)
114{
115 int i;
116 EC_PRE_COMP *pre = pre_;
117
118 if (!pre)
119 return;
120
121 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
122 if (i > 0)
123 return;
124
125 if (pre->points) {
126 EC_POINT **p;
127
128 for (p = pre->points; *p != NULL; p++)
129 EC_POINT_free(*p);
130 free(pre->points);
131 }
132 free(pre);
133}
134
135static void
136ec_pre_comp_clear_free(void *pre_)
137{
138 int i;
139 EC_PRE_COMP *pre = pre_;
140
141 if (!pre)
142 return;
143
144 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
145 if (i > 0)
146 return;
147
148 if (pre->points) {
149 EC_POINT **p;
150
151 for (p = pre->points; *p != NULL; p++) {
152 EC_POINT_free(*p);
153 explicit_bzero(p, sizeof *p);
154 }
155 free(pre->points);
156 }
157 freezero(pre, sizeof *pre);
158}
159
160
161
162
163/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. 77/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
164 * This is an array r[] of values that are either zero or odd with an 78 * This is an array r[] of values that are either zero or odd with an
165 * absolute value less than 2^w satisfying 79 * absolute value less than 2^w satisfying
@@ -315,8 +229,7 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
315 const EC_POINT *generator = NULL; 229 const EC_POINT *generator = NULL;
316 EC_POINT *tmp = NULL; 230 EC_POINT *tmp = NULL;
317 size_t totalnum; 231 size_t totalnum;
318 size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ 232 size_t numblocks = 0; /* for wNAF splitting */
319 size_t pre_points_per_block = 0;
320 size_t i, j; 233 size_t i, j;
321 int k; 234 int k;
322 int r_is_inverted = 0; 235 int r_is_inverted = 0;
@@ -331,7 +244,6 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
331 EC_POINT **v; 244 EC_POINT **v;
332 EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or 245 EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
333 * 'pre_comp->points' */ 246 * 'pre_comp->points' */
334 const EC_PRE_COMP *pre_comp = NULL;
335 int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be 247 int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be
336 * treated like other scalars, i.e. 248 * treated like other scalars, i.e.
337 * precomputation is not available */ 249 * precomputation is not available */
@@ -357,42 +269,10 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
357 ECerror(EC_R_UNDEFINED_GENERATOR); 269 ECerror(EC_R_UNDEFINED_GENERATOR);
358 goto err; 270 goto err;
359 } 271 }
360 /* look if we can use precomputed multiples of generator */
361
362 pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
363
364 if (pre_comp && pre_comp->numblocks &&
365 (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
366 blocksize = pre_comp->blocksize;
367
368 /*
369 * determine maximum number of blocks that wNAF
370 * splitting may yield (NB: maximum wNAF length is
371 * bit length plus one)
372 */
373 numblocks = (BN_num_bits(scalar) / blocksize) + 1;
374 272
375 /* 273 numblocks = 1;
376 * we cannot use more blocks than we have 274 num_scalar = 1; /* treat 'scalar' like 'num'-th
377 * precomputation for 275 * element of 'scalars' */
378 */
379 if (numblocks > pre_comp->numblocks)
380 numblocks = pre_comp->numblocks;
381
382 pre_points_per_block = (size_t) 1 << (pre_comp->w - 1);
383
384 /* check that pre_comp looks sane */
385 if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
386 ECerror(ERR_R_INTERNAL_ERROR);
387 goto err;
388 }
389 } else {
390 /* can't use precomputation */
391 pre_comp = NULL;
392 numblocks = 1;
393 num_scalar = 1; /* treat 'scalar' like 'num'-th
394 * element of 'scalars' */
395 }
396 } 276 }
397 totalnum = num + numblocks; 277 totalnum = num + numblocks;
398 278
@@ -434,111 +314,9 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
434 if (numblocks) { 314 if (numblocks) {
435 /* we go here iff scalar != NULL */ 315 /* we go here iff scalar != NULL */
436 316
437 if (pre_comp == NULL) { 317 if (num_scalar != 1) {
438 if (num_scalar != 1) { 318 ECerror(ERR_R_INTERNAL_ERROR);
439 ECerror(ERR_R_INTERNAL_ERROR); 319 goto err;
440 goto err;
441 }
442 /* we have already generated a wNAF for 'scalar' */
443 } else {
444 size_t tmp_len = 0;
445
446 if (num_scalar != 0) {
447 ECerror(ERR_R_INTERNAL_ERROR);
448 goto err;
449 }
450 /*
451 * use the window size for which we have
452 * precomputation
453 */
454 wsize[num] = pre_comp->w;
455 tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
456 if (tmp_wNAF == NULL)
457 goto err;
458
459 if (tmp_len <= max_len) {
460 /*
461 * One of the other wNAFs is at least as long
462 * as the wNAF belonging to the generator, so
463 * wNAF splitting will not buy us anything.
464 */
465
466 numblocks = 1;
467 totalnum = num + 1; /* don't use wNAF
468 * splitting */
469 wNAF[num] = tmp_wNAF;
470 tmp_wNAF = NULL;
471 wNAF[num + 1] = NULL;
472 wNAF_len[num] = tmp_len;
473 if (tmp_len > max_len)
474 max_len = tmp_len;
475 /*
476 * pre_comp->points starts with the points
477 * that we need here:
478 */
479 val_sub[num] = pre_comp->points;
480 } else {
481 /*
482 * don't include tmp_wNAF directly into wNAF
483 * array - use wNAF splitting and include the
484 * blocks
485 */
486
487 signed char *pp;
488 EC_POINT **tmp_points;
489
490 if (tmp_len < numblocks * blocksize) {
491 /*
492 * possibly we can do with fewer
493 * blocks than estimated
494 */
495 numblocks = (tmp_len + blocksize - 1) / blocksize;
496 if (numblocks > pre_comp->numblocks) {
497 ECerror(ERR_R_INTERNAL_ERROR);
498 goto err;
499 }
500 totalnum = num + numblocks;
501 }
502 /* split wNAF in 'numblocks' parts */
503 pp = tmp_wNAF;
504 tmp_points = pre_comp->points;
505
506 for (i = num; i < totalnum; i++) {
507 if (i < totalnum - 1) {
508 wNAF_len[i] = blocksize;
509 if (tmp_len < blocksize) {
510 ECerror(ERR_R_INTERNAL_ERROR);
511 goto err;
512 }
513 tmp_len -= blocksize;
514 } else
515 /*
516 * last block gets whatever
517 * is left (this could be
518 * more or less than
519 * 'blocksize'!)
520 */
521 wNAF_len[i] = tmp_len;
522
523 wNAF[i + 1] = NULL;
524 wNAF[i] = malloc(wNAF_len[i]);
525 if (wNAF[i] == NULL) {
526 ECerror(ERR_R_MALLOC_FAILURE);
527 goto err;
528 }
529 memcpy(wNAF[i], pp, wNAF_len[i]);
530 if (wNAF_len[i] > max_len)
531 max_len = wNAF_len[i];
532
533 if (*tmp_points == NULL) {
534 ECerror(ERR_R_INTERNAL_ERROR);
535 goto err;
536 }
537 val_sub[i] = tmp_points;
538 tmp_points += pre_points_per_block;
539 pp += blocksize;
540 }
541 }
542 } 320 }
543 } 321 }
544 /* 322 /*