summaryrefslogtreecommitdiffstats
path: root/crypto/ec/ec_lib.c
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2014-09-12 00:13:20 +0200
committerAndy Polyakov <appro@openssl.org>2014-09-12 00:13:20 +0200
commitf54be179aa4cbbd944728771d7d59ed588158a12 (patch)
tree0dc5e2fa108f0db85230a0ce2d040eb7597642b4 /crypto/ec/ec_lib.c
parent902b30df193afc3417a96ba72a81ed390bd50de3 (diff)
Reserve option to use BN_mod_exp_mont_consttime in ECDSA.
Submitted by Shay Gueron, Intel Corp. RT: 3149 Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/ec/ec_lib.c')
-rw-r--r--crypto/ec/ec_lib.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index a295a84f2b..0a182d4229 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -101,6 +101,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
ret->meth = meth;
ret->extra_data = NULL;
+ ret->mont_data = NULL;
ret->generator = NULL;
BN_init(&ret->order);
@@ -132,6 +133,9 @@ void EC_GROUP_free(EC_GROUP *group)
EC_EX_DATA_free_all_data(&group->extra_data);
+ if (group->mont_data)
+ BN_MONT_CTX_free(group->mont_data);
+
if (group->generator != NULL)
EC_POINT_free(group->generator);
BN_free(&group->order);
@@ -155,6 +159,9 @@ void EC_GROUP_clear_free(EC_GROUP *group)
EC_EX_DATA_clear_free_all_data(&group->extra_data);
+ if (group->mont_data)
+ BN_MONT_CTX_free(group->mont_data);
+
if (group->generator != NULL)
EC_POINT_clear_free(group->generator);
BN_clear_free(&group->order);
@@ -200,6 +207,25 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
return 0;
}
+ if (src->mont_data != NULL)
+ {
+ if (dest->mont_data == NULL)
+ {
+ dest->mont_data = BN_MONT_CTX_new();
+ if (dest->mont_data == NULL) return 0;
+ }
+ if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) return 0;
+ }
+ else
+ {
+ /* src->generator == NULL */
+ if (dest->mont_data != NULL)
+ {
+ BN_MONT_CTX_free(dest->mont_data);
+ dest->mont_data = NULL;
+ }
+ }
+
if (src->generator != NULL)
{
if (dest->generator == NULL)
@@ -309,6 +335,11 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG
else
BN_zero(&group->cofactor);
+ /* We ignore the return value because some groups have an order with
+ * factors of two, which makes the Montgomery setup fail.
+ * |group->mont_data| will be NULL in this case. */
+ ec_precompute_mont_data(group);
+
return 1;
}
@@ -318,6 +349,10 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
return group->generator;
}
+BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
+ {
+ return group->mont_data;
+ }
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
{
@@ -1097,3 +1132,39 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
else
return 0; /* cannot tell whether precomputation has been performed */
}
+
+/* ec_precompute_mont_data sets |group->mont_data| from |group->order| and
+ * returns one on success. On error it returns zero. */
+int ec_precompute_mont_data(EC_GROUP *group)
+ {
+ BN_CTX *ctx = BN_CTX_new();
+ int ret = 0;
+
+ if (group->mont_data)
+ {
+ BN_MONT_CTX_free(group->mont_data);
+ group->mont_data = NULL;
+ }
+
+ if (ctx == NULL)
+ goto err;
+
+ group->mont_data = BN_MONT_CTX_new();
+ if (!group->mont_data)
+ goto err;
+
+ if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx))
+ {
+ BN_MONT_CTX_free(group->mont_data);
+ group->mont_data = NULL;
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+
+ if (ctx)
+ BN_CTX_free(ctx);
+ return ret;
+ }