summaryrefslogtreecommitdiffstats
path: root/crypto/ec/ec_mult.c
diff options
context:
space:
mode:
authorNicola Tuveri <nic.tuv@gmail.com>2018-07-08 10:39:39 +0300
committerMatt Caswell <matt@openssl.org>2018-07-16 10:17:40 +0100
commit01ad66f85d22fd001582b5f2e6e18db8b820c550 (patch)
treee9fc5b120ead1fc093bcac475ad9f025dff831b2 /crypto/ec/ec_mult.c
parentf45846f50036343778d7575578e7115e92a3fce1 (diff)
EC2M Lopez-Dahab ladder: use it also for ECDSA verify
By default `ec_scalar_mul_ladder` (which uses the Lopez-Dahab ladder implementation) is used only for (k * Generator) or (k * VariablePoint). ECDSA verification uses (a * Generator + b * VariablePoint): this commit forces the use of `ec_scalar_mul_ladder` also for the ECDSA verification path, while using the default wNAF implementation for any other case. With this commit `ec_scalar_mul_ladder` loses the static attribute, and is added to ec_lcl.h so EC_METHODs can directly use it. While working on a new custom EC_POINTs_mul implementation, I realized that many checks (e.g. all the points being compatible with the given EC_GROUP, creating a temporary BN_CTX if `ctx == NULL`, check for the corner case `scalar == NULL && num == 0`) were duplicated again and again in every single implementation (and actually some implementations lacked some of the tests). I thought that it makes way more sense for those checks that are independent from the actual implementation and should always be done, to be moved in the EC_POINTs_mul wrapper: so this commit also includes these changes. Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6690)
Diffstat (limited to 'crypto/ec/ec_mult.c')
-rw-r--r--crypto/ec/ec_mult.c41
1 files changed, 13 insertions, 28 deletions
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index 55cbfa105d..7e1b3650e7 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -121,6 +121,9 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
* `scalar` cannot be NULL and should be in the range [0,n) otherwise all
* constant time bets are off (where n is the cardinality of the EC group).
*
+ * This function expects `group->order` and `group->cardinality` to be well
+ * defined and non-zero: it fails with an error code otherwise.
+ *
* NB: This says nothing about the constant-timeness of the ladder step
* implementation (i.e., the default implementation is based on EC_POINT_add and
* EC_POINT_dbl, which of course are not constant time themselves) or the
@@ -128,9 +131,11 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
*
* The product is stored in `r`.
*
+ * This is an internal function: callers are in charge of ensuring that the
+ * input parameters `group`, `r`, `scalar` and `ctx` are not NULL.
+ *
* Returns 1 on success, 0 otherwise.
*/
-static
int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, const EC_POINT *point,
BN_CTX *ctx)
@@ -141,15 +146,20 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
BIGNUM *k = NULL;
BIGNUM *lambda = NULL;
BIGNUM *cardinality = NULL;
- BN_CTX *new_ctx = NULL;
int ret = 0;
/* early exit if the input point is the point at infinity */
if (point != NULL && EC_POINT_is_at_infinity(group, point))
return EC_POINT_set_to_infinity(group, r);
- if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
+ if (BN_is_zero(group->order)) {
+ ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER);
return 0;
+ }
+ if (BN_is_zero(group->cofactor)) {
+ ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR);
+ return 0;
+ }
BN_CTX_start(ctx);
@@ -370,7 +380,6 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
EC_POINT_free(p);
EC_POINT_free(s);
BN_CTX_end(ctx);
- BN_CTX_free(new_ctx);
return ret;
}
@@ -402,7 +411,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *ctx)
{
- BN_CTX *new_ctx = NULL;
const EC_POINT *generator = NULL;
EC_POINT *tmp = NULL;
size_t totalnum;
@@ -427,15 +435,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* precomputation is not available */
int ret = 0;
- if (!ec_point_is_compat(r, group)) {
- ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
-
- if ((scalar == NULL) && (num == 0)) {
- return EC_POINT_set_to_infinity(group, r);
- }
-
if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) {
/*-
* Handle the common cases where the scalar is secret, enforcing a
@@ -465,19 +464,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
- for (i = 0; i < num; i++) {
- if (!ec_point_is_compat(points[i], group)) {
- ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
- return 0;
- }
- }
-
- if (ctx == NULL) {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- goto err;
- }
-
if (scalar != NULL) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
@@ -784,7 +770,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
ret = 1;
err:
- BN_CTX_free(new_ctx);
EC_POINT_free(tmp);
OPENSSL_free(wsize);
OPENSSL_free(wNAF_len);