Remove fips_constseg references.
[openssl.git] / crypto / ec / ec_lib.c
index f7b2025ea6f2a9fd6626b3471559159bb98adc1d..bef2e9572c26f79d93a7cb5339550c7084de9c00 100644 (file)
@@ -70,7 +70,6 @@
 
 #include "ec_lcl.h"
 
-__fips_constseg
 static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
 
 
@@ -101,6 +100,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 +132,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 +158,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 +206,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 +334,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 +348,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)
        {
@@ -945,7 +979,7 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *
 
 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
        {
-       if (group->meth->dbl == 0)
+       if (group->meth->invert == 0)
                {
                ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
                return 0;
@@ -1097,3 +1131,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;
+       }