Fix some issues near recent chomp changes.
[openssl.git] / crypto / ec / ec_lib.c
index 890a274b9738141d44dba6e363085ca6373bf284..a34113c95342d367f4729e7d0ab65026262e09d8 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/ec/ec_lib.c */
 /*
  * Originally written by Bodo Moeller for the OpenSSL project.
  */
@@ -109,7 +108,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 +144,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 +163,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);
@@ -328,13 +327,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 +354,43 @@ 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->order)
+        return BN_num_bits(group->order);
+    return 0;
+}
+
 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;
@@ -537,16 +563,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 +599,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;