summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2025-03-24 13:07:04 +0000
committerjsing <>2025-03-24 13:07:04 +0000
commit70275e713454e731b5cbf6545eff93592d1d9872 (patch)
tree6397da5be4e5b65da2b65dd38a2c3f1202843573
parente8c19f02f4b0497ce5d3eca5d72b3cdaeaff9f09 (diff)
downloadopenbsd-70275e713454e731b5cbf6545eff93592d1d9872.tar.gz
openbsd-70275e713454e731b5cbf6545eff93592d1d9872.tar.bz2
openbsd-70275e713454e731b5cbf6545eff93592d1d9872.zip
Explicitly pass group generator to mul_double_nonct() from EC_POINT_mul().
EC_POINT_mul() has a complex multi-use interface - there are effectively three different ways it will behave, depending on which arguments are NULL. In the case where we compute g_scalar * generator + p_scalar * point, the mul_double_nonct() function pointer is called, however only g_scalar, p_scalar and point are passed - it is expected that the lower level implementation (in this case ec_wnaf_mul()) will use the generator from the group. Change mul_double_nonct(), ec_mul_double_nonct() and ec_wnaf_mul() so that they take scalar1, point1, scalar2 and point2. This removes all knowledge of g_scalar and the generator from the multiplication code, keeping it limited to EC_POINT_mul(). While here also consistently pass scalar then point, rather than a mix of scalar/point and point/scalar. ok tb@
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c10
-rw-r--r--src/lib/libcrypto/ec/ec_local.h13
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c36
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c9
4 files changed, 33 insertions, 35 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 598038de1d..7982d23f06 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.122 2025/03/24 12:49:13 jsing Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.123 2025/03/24 13:07:04 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 */
@@ -1333,8 +1333,8 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1333 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually 1333 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1334 * set and we always call the constant time version. 1334 * set and we always call the constant time version.
1335 */ 1335 */
1336 ret = group->meth->mul_single_ct(group, r, g_scalar, 1336 ret = group->meth->mul_single_ct(group, r,
1337 group->generator, ctx); 1337 g_scalar, group->generator, ctx);
1338 } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) { 1338 } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1339 /* 1339 /*
1340 * In this case we want to compute p_scalar * GenericPoint: 1340 * In this case we want to compute p_scalar * GenericPoint:
@@ -1352,8 +1352,8 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1352 * this codepath is reached most prominently by ECDSA signature 1352 * this codepath is reached most prominently by ECDSA signature
1353 * verification. So we call the non-ct version. 1353 * verification. So we call the non-ct version.
1354 */ 1354 */
1355 ret = group->meth->mul_double_nonct(group, r, g_scalar, 1355 ret = group->meth->mul_double_nonct(group, r,
1356 p_scalar, point, ctx); 1356 g_scalar, group->generator, p_scalar, point, ctx);
1357 } else { 1357 } else {
1358 /* Anything else is an error. */ 1358 /* Anything else is an error. */
1359 ECerror(ERR_R_EC_LIB); 1359 ECerror(ERR_R_EC_LIB);
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index 9c188c0197..c7a54d3a2b 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.66 2025/03/09 15:33:35 tb Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.67 2025/03/24 13:07:04 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 */
@@ -106,8 +106,8 @@ typedef struct ec_method_st {
106 int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r, 106 int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r,
107 const BIGNUM *scalar, const EC_POINT *point, BN_CTX *); 107 const BIGNUM *scalar, const EC_POINT *point, BN_CTX *);
108 int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r, 108 int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r,
109 const BIGNUM *g_scalar, const BIGNUM *p_scalar, 109 const BIGNUM *scalar1, const EC_POINT *point1,
110 const EC_POINT *point, BN_CTX *); 110 const BIGNUM *scalar2, const EC_POINT *point2, BN_CTX *);
111 111
112 /* 112 /*
113 * These can be used by 'add' and 'dbl' so that the same implementations 113 * These can be used by 'add' and 'dbl' so that the same implementations
@@ -173,9 +173,10 @@ struct ec_point_st {
173const EC_METHOD *EC_GFp_simple_method(void); 173const EC_METHOD *EC_GFp_simple_method(void);
174const EC_METHOD *EC_GFp_mont_method(void); 174const EC_METHOD *EC_GFp_mont_method(void);
175 175
176/* Compute r = generator * m + point * n in non-constant time. */ 176/* Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time. */
177int ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, 177int ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
178 const EC_POINT *point, const BIGNUM *n, BN_CTX *ctx); 178 const EC_POINT *point1, const BIGNUM *scalar2, const EC_POINT *point2,
179 BN_CTX *ctx);
179 180
180int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid); 181int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid);
181 182
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
index 68061ffd67..673696a9fd 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.57 2025/01/11 13:58:31 tb Exp $ */ 1/* $OpenBSD: ec_mult.c,v 1.58 2025/03/24 13:07:04 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 */
@@ -259,7 +259,7 @@ ec_wnaf_free(struct ec_wnaf *wnaf)
259 */ 259 */
260 260
261static struct ec_wnaf * 261static struct ec_wnaf *
262ec_wnaf_new(const EC_GROUP *group, const EC_POINT *point, const BIGNUM *bn, 262ec_wnaf_new(const EC_GROUP *group, const BIGNUM *scalar, const EC_POINT *point,
263 BN_CTX *ctx) 263 BN_CTX *ctx)
264{ 264{
265 struct ec_wnaf *wnaf; 265 struct ec_wnaf *wnaf;
@@ -267,15 +267,15 @@ ec_wnaf_new(const EC_GROUP *group, const EC_POINT *point, const BIGNUM *bn,
267 if ((wnaf = calloc(1, sizeof(*wnaf))) == NULL) 267 if ((wnaf = calloc(1, sizeof(*wnaf))) == NULL)
268 goto err; 268 goto err;
269 269
270 wnaf->num_digits = BN_num_bits(bn) + 1; 270 wnaf->num_digits = BN_num_bits(scalar) + 1;
271 if ((wnaf->digits = calloc(wnaf->num_digits, 271 if ((wnaf->digits = calloc(wnaf->num_digits,
272 sizeof(*wnaf->digits))) == NULL) 272 sizeof(*wnaf->digits))) == NULL)
273 goto err; 273 goto err;
274 274
275 if (!ec_compute_wnaf(bn, wnaf->digits, wnaf->num_digits)) 275 if (!ec_compute_wnaf(scalar, wnaf->digits, wnaf->num_digits))
276 goto err; 276 goto err;
277 277
278 wnaf->num_multiples = 1ULL << (ec_window_bits(bn) - 1); 278 wnaf->num_multiples = 1ULL << (ec_window_bits(scalar) - 1);
279 if ((wnaf->multiples = calloc(wnaf->num_multiples, 279 if ((wnaf->multiples = calloc(wnaf->num_multiples,
280 sizeof(*wnaf->multiples))) == NULL) 280 sizeof(*wnaf->multiples))) == NULL)
281 goto err; 281 goto err;
@@ -313,38 +313,34 @@ ec_wnaf_multiple(struct ec_wnaf *wnaf, signed char digit)
313} 313}
314 314
315/* 315/*
316 * Compute r = generator * m + point * n in non-constant time. 316 * Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time.
317 */ 317 */
318 318
319int 319int
320ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, 320ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
321 const EC_POINT *point, const BIGNUM *n, BN_CTX *ctx) 321 const EC_POINT *point1, const BIGNUM *scalar2, const EC_POINT *point2,
322 BN_CTX *ctx)
322{ 323{
323 struct ec_wnaf *wnaf[2] = { NULL, NULL }; 324 struct ec_wnaf *wnaf[2] = { NULL, NULL };
324 const EC_POINT *generator;
325 size_t i; 325 size_t i;
326 int k; 326 int k;
327 int r_is_inverted = 0; 327 int r_is_inverted = 0;
328 size_t num_digits; 328 size_t num_digits;
329 int ret = 0; 329 int ret = 0;
330 330
331 if (m == NULL || n == NULL) { 331 if (scalar1 == NULL || scalar2 == NULL) {
332 ECerror(ERR_R_PASSED_NULL_PARAMETER); 332 ECerror(ERR_R_PASSED_NULL_PARAMETER);
333 goto err; 333 goto err;
334 } 334 }
335 if (group->meth != r->meth || group->meth != point->meth) { 335 if (group->meth != r->meth || group->meth != point1->meth ||
336 group->meth != point2->meth) {
336 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 337 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
337 goto err; 338 goto err;
338 } 339 }
339 340
340 if ((generator = EC_GROUP_get0_generator(group)) == NULL) { 341 if ((wnaf[0] = ec_wnaf_new(group, scalar1, point1, ctx)) == NULL)
341 ECerror(EC_R_UNDEFINED_GENERATOR);
342 goto err;
343 }
344
345 if ((wnaf[0] = ec_wnaf_new(group, generator, m, ctx)) == NULL)
346 goto err; 342 goto err;
347 if ((wnaf[1] = ec_wnaf_new(group, point, n, ctx)) == NULL) 343 if ((wnaf[1] = ec_wnaf_new(group, scalar2, point2, ctx)) == NULL)
348 goto err; 344 goto err;
349 345
350 if (!ec_normalize_points(group, wnaf[0], wnaf[1], ctx)) 346 if (!ec_normalize_points(group, wnaf[0], wnaf[1], ctx))
@@ -357,8 +353,8 @@ ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m,
357 /* 353 /*
358 * Set r to the neutral element. Scan through the wNAF representations 354 * Set r to the neutral element. Scan through the wNAF representations
359 * of m and n, starting at the most significant digit. Double r and for 355 * of m and n, starting at the most significant digit. Double r and for
360 * each wNAF digit of m add the digit times the generator, and for each 356 * each wNAF digit of scalar1 add the digit times point1, and for each
361 * wNAF digit of n add the digit times the point, adjusting the signs 357 * wNAF digit of scalar2 add the digit times point2, adjusting the signs
362 * as appropriate. 358 * as appropriate.
363 */ 359 */
364 360
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index 544c2be4d4..ced85ceb1e 100644
--- a/src/lib/libcrypto/ec/ecp_methods.c
+++ b/src/lib/libcrypto/ec/ecp_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_methods.c,v 1.44 2025/03/09 15:33:35 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.45 2025/03/24 13:07:04 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.
@@ -1194,10 +1194,11 @@ ec_mul_single_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1194} 1194}
1195 1195
1196static int 1196static int
1197ec_mul_double_nonct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1197ec_mul_double_nonct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
1198 const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *ctx) 1198 const EC_POINT *point1, const BIGNUM *scalar2, const EC_POINT *point2,
1199 BN_CTX *ctx)
1199{ 1200{
1200 return ec_wnaf_mul(group, r, g_scalar, point, p_scalar, ctx); 1201 return ec_wnaf_mul(group, r, scalar1, point1, scalar2, point2, ctx);
1201} 1202}
1202 1203
1203static int 1204static int