Replace overrides.
[openssl.git] / crypto / ec / ec_lib.c
index 890a274b9738141d44dba6e363085ca6373bf284..1f487b48a071696812b98e83cf3367a24c5da81a 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/ec/ec_lib.c */
 /*
  * Originally written by Bodo Moeller for the OpenSSL project.
  */
@@ -90,12 +89,14 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
     }
 
     ret->meth = meth;
-    ret->order = BN_new();
-    if (ret->order == NULL)
-        goto err;
-    ret->cofactor = BN_new();
-    if (ret->cofactor == NULL)
-        goto err;
+    if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
+        ret->order = BN_new();
+        if (ret->order == NULL)
+            goto err;
+        ret->cofactor = BN_new();
+        if (ret->cofactor == NULL)
+            goto err;
+    }
     ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
     ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
     if (!meth->group_init(ret))
@@ -109,7 +110,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
     return NULL;
 }
 
-static void ec_group_free_precomp(EC_GROUP *group)
+void EC_pre_comp_free(EC_GROUP *group)
 {
     switch (group->pre_comp_type) {
     default:
@@ -145,7 +146,7 @@ void EC_GROUP_free(EC_GROUP *group)
     if (group->meth->group_finish != 0)
         group->meth->group_finish(group);
 
-    ec_group_free_precomp(group);
+    EC_pre_comp_free(group);
     BN_MONT_CTX_free(group->mont_data);
     EC_POINT_free(group->generator);
     BN_free(group->order);
@@ -164,7 +165,7 @@ void EC_GROUP_clear_free(EC_GROUP *group)
     else if (group->meth->group_finish != 0)
         group->meth->group_finish(group);
 
-    ec_group_free_precomp(group);
+    EC_pre_comp_free(group);
     BN_MONT_CTX_free(group->mont_data);
     EC_POINT_clear_free(group->generator);
     BN_clear_free(group->order);
@@ -241,10 +242,12 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
         dest->generator = NULL;
     }
 
-    if (!BN_copy(dest->order, src->order))
-        return 0;
-    if (!BN_copy(dest->cofactor, src->cofactor))
-        return 0;
+    if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
+        if (!BN_copy(dest->order, src->order))
+            return 0;
+        if (!BN_copy(dest->cofactor, src->cofactor))
+            return 0;
+    }
 
     dest->curve_name = src->curve_name;
     dest->asn1_flag = src->asn1_flag;
@@ -328,13 +331,18 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
     } else
         BN_zero(group->cofactor);
 
     /*
-     * We ignore the return value because some groups have an order with
+     * 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);
+    if (BN_is_odd(group->order)) {
+        return ec_precompute_mont_data(group);
+    }
 
+    BN_MONT_CTX_free(group->mont_data);
+    group->mont_data = NULL;
     return 1;
 }
 
@@ -350,21 +358,45 @@ BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
 
 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
 {
+    if (group->order == NULL)
+        return 0;
     if (!BN_copy(order, group->order))
         return 0;
 
     return !BN_is_zero(order);
 }
 
+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)
+{
+    return group->order;
+}
+
+int EC_GROUP_order_bits(const EC_GROUP *group)
+{
+    if (group->meth->group_order_bits == NULL) {
+        ECerr(EC_F_EC_GROUP_ORDER_BITS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_order_bits(group);
+}
+
 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
                           BN_CTX *ctx)
 {
+
+    if (group->cofactor == NULL)
+        return 0;
     if (!BN_copy(cofactor, group->cofactor))
         return 0;
 
     return !BN_is_zero(group->cofactor);
 }
 
+const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group)
+{
+    return group->cofactor;
+}
+
 void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
 {
     group->curve_name = nid;
@@ -501,6 +533,8 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
     if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
         EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
         return 1;
+    if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
+        return 0;
 
     if (ctx == NULL)
         ctx_new = ctx = BN_CTX_new();
@@ -537,16 +571,18 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
         r = 1;
 
     if (!r) {
+        const BIGNUM *ao, *bo, *ac, *bc;
         /* compare the order and cofactor */
-        if (!EC_GROUP_get_order(a, a1, ctx) ||
-            !EC_GROUP_get_order(b, b1, ctx) ||
-            !EC_GROUP_get_cofactor(a, a2, ctx) ||
-            !EC_GROUP_get_cofactor(b, b2, ctx)) {
+        ao = EC_GROUP_get0_order(a);
+        bo = EC_GROUP_get0_order(b);
+        ac = EC_GROUP_get0_cofactor(a);
+        bc = EC_GROUP_get0_cofactor(b);
+        if (ao == NULL || bo == NULL) {
             BN_CTX_end(ctx);
             BN_CTX_free(ctx_new);
             return -1;
         }
-        if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
+        if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
             r = 1;
     }
 
@@ -571,7 +607,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group)
         return NULL;
     }
 
-    ret = OPENSSL_malloc(sizeof(*ret));
+    ret = OPENSSL_zalloc(sizeof(*ret));
     if (ret == NULL) {
         ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
         return NULL;
@@ -994,3 +1030,10 @@ void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
 {
     return CRYPTO_get_ex_data(&key->ex_data, idx);
 }
+
+int ec_group_simple_order_bits(const EC_GROUP *group)
+{
+    if (group->order == NULL)
+        return 0;
+    return BN_num_bits(group->order);
+}