aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/ec/ec_lib.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_lib.c
parentf45846f50036343778d7575578e7115e92a3fce1 (diff)
downloadopenssl-01ad66f85d22fd001582b5f2e6e18db8b820c550.tar.gz
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_lib.c')
-rw-r--r--crypto/ec/ec_lib.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 6a2d1b5800..457cd3593c 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -919,11 +919,38 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx)
{
- if (group->meth->mul == 0)
+ int ret = 0;
+ size_t i = 0;
+ BN_CTX *new_ctx = NULL;
+
+ if ((scalar == NULL) && (num == 0)) {
+ return EC_POINT_set_to_infinity(group, r);
+ }
+
+ if (!ec_point_is_compat(r, group)) {
+ ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ for (i = 0; i < num; i++) {
+ if (!ec_point_is_compat(points[i], group)) {
+ ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ }
+
+ if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) {
+ ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (group->meth->mul != NULL)
+ ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+ else
/* use default */
- return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
- return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+ BN_CTX_free(new_ctx);
+ return ret;
}
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,