diff options
author | jsing <> | 2025-03-24 13:07:04 +0000 |
---|---|---|
committer | jsing <> | 2025-03-24 13:07:04 +0000 |
commit | 70275e713454e731b5cbf6545eff93592d1d9872 (patch) | |
tree | 6397da5be4e5b65da2b65dd38a2c3f1202843573 | |
parent | e8c19f02f4b0497ce5d3eca5d72b3cdaeaff9f09 (diff) | |
download | openbsd-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.c | 10 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 13 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_mult.c | 36 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ecp_methods.c | 9 |
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 { | |||
173 | const EC_METHOD *EC_GFp_simple_method(void); | 173 | const EC_METHOD *EC_GFp_simple_method(void); |
174 | const EC_METHOD *EC_GFp_mont_method(void); | 174 | const 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. */ |
177 | int ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, | 177 | int 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 | ||
180 | int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid); | 181 | int 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 | ||
261 | static struct ec_wnaf * | 261 | static struct ec_wnaf * |
262 | ec_wnaf_new(const EC_GROUP *group, const EC_POINT *point, const BIGNUM *bn, | 262 | ec_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 | ||
319 | int | 319 | int |
320 | ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, | 320 | ec_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 | ||
1196 | static int | 1196 | static int |
1197 | ec_mul_double_nonct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, | 1197 | ec_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 | ||
1203 | static int | 1204 | static int |