deprecate EC_POINTs_mul function
authorBilly Brumley <bbrumley@gmail.com>
Wed, 13 May 2020 04:33:59 +0000 (07:33 +0300)
committerMatt Caswell <matt@openssl.org>
Sat, 16 May 2020 16:20:37 +0000 (17:20 +0100)
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11807)

CHANGES.md
crypto/ec/ec_lib.c
crypto/err/openssl.txt
doc/man3/EC_POINT_add.pod
include/openssl/ec.h
include/openssl/ecerr.h
test/ectest.c
util/libcrypto.num

index 589cc55..bc4f524 100644 (file)
@@ -23,6 +23,11 @@ OpenSSL 3.0
 
 ### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
 
+ * Deprecated EC_POINTs_mul(). This function is not widely used and applications
+   should instead use the L<EC_POINT_mul(3)> function.
+
+   *Billy Bob Brumley*
+
  * Removed FIPS_mode() and FIPS_mode_set(). These functions are legacy API's
    that are not applicable to the new provider model. Applications should
    instead use EVP_default_properties_is_fips_enabled() and
index 589380d..cdeffb4 100644 (file)
@@ -1041,6 +1041,7 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
  * methods.
  */
 
+#ifndef OPENSSL_NO_DEPRECATED_3_0
 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)
@@ -1086,21 +1087,46 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
 #endif
     return ret;
 }
+#endif
 
 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
                  const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
 {
-    /* just a convenient interface to EC_POINTs_mul() */
+    int ret = 0;
+#ifndef FIPS_MODULE
+    BN_CTX *new_ctx = NULL;
+#endif
 
-    const EC_POINT *points[1];
-    const BIGNUM *scalars[1];
+    if (!ec_point_is_compat(r, group)
+        || (point != NULL && !ec_point_is_compat(point, group))) {
+        ECerr(EC_F_EC_POINT_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
 
-    points[0] = point;
-    scalars[0] = p_scalar;
+    if (g_scalar == NULL && p_scalar == NULL)
+        return EC_POINT_set_to_infinity(group, r);
 
-    return EC_POINTs_mul(group, r, g_scalar,
-                         (point != NULL
-                          && p_scalar != NULL), points, scalars, ctx);
+#ifndef FIPS_MODULE
+    if (ctx == NULL)
+        ctx = new_ctx = BN_CTX_secure_new();
+#endif
+    if (ctx == NULL) {
+        ECerr(EC_F_EC_POINT_MUL, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    if (group->meth->mul != NULL)
+        ret = group->meth->mul(group, r, g_scalar, point != NULL
+                               && p_scalar != NULL, &point, &p_scalar, ctx);
+    else
+        /* use default */
+        ret = ec_wNAF_mul(group, r, g_scalar, point != NULL
+                          && p_scalar != NULL, &point, &p_scalar, ctx);
+
+#ifndef FIPS_MODULE
+    BN_CTX_free(new_ctx);
+#endif
+    return ret;
 }
 
 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
index 7bf0611..9d5e960 100644 (file)
@@ -696,6 +696,7 @@ EC_F_EC_POINT_INVERT:210:EC_POINT_invert
 EC_F_EC_POINT_IS_AT_INFINITY:118:EC_POINT_is_at_infinity
 EC_F_EC_POINT_IS_ON_CURVE:119:EC_POINT_is_on_curve
 EC_F_EC_POINT_MAKE_AFFINE:120:EC_POINT_make_affine
+EC_F_EC_POINT_MUL:309:
 EC_F_EC_POINT_NEW:121:EC_POINT_new
 EC_F_EC_POINT_OCT2POINT:122:EC_POINT_oct2point
 EC_F_EC_POINT_POINT2BUF:281:EC_POINT_point2buf
index 9b71d71..3ac567f 100644 (file)
@@ -18,13 +18,15 @@ EC_POINT_add, EC_POINT_dbl, EC_POINT_invert, EC_POINT_is_at_infinity, EC_POINT_i
  int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
  int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
                            EC_POINT *points[], BN_CTX *ctx);
- int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num,
-                   const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
  int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
                   const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
  int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
  int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
 
+ Deprecated since OpenSSL 3.0:
+
+ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num,
+                   const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
 
 =head1 DESCRIPTION
 
@@ -43,12 +45,14 @@ The functions EC_POINT_make_affine and EC_POINTs_make_affine force the internal
 co-ordinate system. In the case of EC_POINTs_make_affine the value B<num> provides the number of points in the array B<points> to be
 forced.
 
-EC_POINT_mul is a convenient interface to EC_POINTs_mul: it calculates the value generator * B<n> + B<q> * B<m> and stores the result in B<r>.
+EC_POINT_mul calculates the value generator * B<n> + B<q> * B<m> and stores the result in B<r>.
 The value B<n> may be NULL in which case the result is just B<q> * B<m> (variable point multiplication). Alternatively, both B<q> and B<m> may be NULL, and B<n> non-NULL, in which case the result is just generator * B<n> (fixed point multiplication).
 When performing a single fixed or variable point multiplication, the underlying implementation uses a constant time algorithm, when the input scalar (either B<n> or B<m>) is in the range [0, ec_group_order).
 
+Although deprecated in OpenSSL 3.0 and should no longer be used,
 EC_POINTs_mul calculates the value generator * B<n> + B<q[0]> * B<m[0]> + ... + B<q[num-1]> * B<m[num-1]>. As for EC_POINT_mul the value B<n> may be NULL or B<num> may be zero.
 When performing a fixed point multiplication (B<n> is non-NULL and B<num> is 0) or a variable point multiplication (B<n> is NULL and B<num> is 1), the underlying implementation uses a constant time algorithm, when the input scalar (either B<n> or B<m[0]>) is in the range [0, ec_group_order).
+Modern versions should instead use EC_POINT_mul(), combined (if needed) with EC_POINT_add() in such rare circumstances.
 
 The function EC_GROUP_precompute_mult stores multiples of the generator for faster point multiplication, whilst
 EC_GROUP_have_precompute_mult tests whether precomputation has already been done. See L<EC_GROUP_copy(3)> for information
@@ -74,6 +78,10 @@ L<crypto(7)>, L<EC_GROUP_new(3)>, L<EC_GROUP_copy(3)>,
 L<EC_POINT_new(3)>, L<EC_KEY_new(3)>,
 L<EC_GFp_simple_method(3)>, L<d2i_ECPKParameters(3)>
 
+=head1 HISTORY
+
+EC_POINTs_mul() was deprecated in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved.
index 09c3e29..703fc1c 100644 (file)
@@ -775,9 +775,10 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
  *  \param  ctx    BN_CTX object (optional)
  *  \return 1 on success and 0 if an error occurred
  */
-int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
-                  size_t num, const EC_POINT *p[], const BIGNUM *m[],
-                  BN_CTX *ctx);
+DEPRECATEDIN_3_0(int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r,
+                                   const BIGNUM *n, size_t num,
+                                   const EC_POINT *p[], const BIGNUM *m[],
+                                   BN_CTX *ctx))
 
 /** Computes r = generator * n + q * m
  *  \param  group  underlying EC_GROUP object
index cf845fb..49adc7c 100644 (file)
@@ -170,6 +170,7 @@ int ERR_load_EC_strings(void);
 #   define EC_F_EC_POINT_IS_AT_INFINITY                     0
 #   define EC_F_EC_POINT_IS_ON_CURVE                        0
 #   define EC_F_EC_POINT_MAKE_AFFINE                        0
+#   define EC_F_EC_POINT_MUL                                0
 #   define EC_F_EC_POINT_NEW                                0
 #   define EC_F_EC_POINT_OCT2POINT                          0
 #   define EC_F_EC_POINT_POINT2BUF                          0
index 5c31efe..bbcd967 100644 (file)
@@ -8,6 +8,14 @@
  * https://www.openssl.org/source/license.html
  */
 
+/*
+ * We need access to the deprecated EC_POINTs_mul for testing purposes
+ * when the deprecated calls are not hidden
+ */
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+# define OPENSSL_SUPPRESS_DEPRECATED
+#endif
+
 #include <string.h>
 #include "internal/nelem.h"
 #include "testutil.h"
@@ -64,8 +72,10 @@ static int group_order_tests(EC_GROUP *group)
         goto err;
 
     for (i = 1; i <= 2; i++) {
+# ifndef OPENSSL_NO_DEPRECATED_3_0
         const BIGNUM *scalars[6];
         const EC_POINT *points[6];
+# endif
 
         if (!TEST_true(BN_set_word(n1, i))
             /*
@@ -97,11 +107,11 @@ static int group_order_tests(EC_GROUP *group)
             /* Add P to verify the result. */
             || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
             || !TEST_true(EC_POINT_is_at_infinity(group, Q))
-
-            /* Exercise EC_POINTs_mul, including corner cases. */
             || !TEST_false(EC_POINT_is_at_infinity(group, P)))
             goto err;
 
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+        /* Exercise EC_POINTs_mul, including corner cases. */
         scalars[0] = scalars[1] = BN_value_one();
         points[0]  = points[1]  = P;
 
@@ -125,6 +135,7 @@ static int group_order_tests(EC_GROUP *group)
         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
             || !TEST_true(EC_POINT_is_at_infinity(group, P)))
             goto err;
+# endif
     }
 
     r = 1;
@@ -152,8 +163,10 @@ static int prime_field_tests(void)
              *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
     EC_POINT *P = NULL, *Q = NULL, *R = NULL;
     BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
+# ifndef OPENSSL_NO_DEPRECATED_3_0
     const EC_POINT *points[4];
     const BIGNUM *scalars[4];
+# endif
     unsigned char buf[100];
     size_t len, r = 0;
     int k;
@@ -548,6 +561,9 @@ static int prime_field_tests(void)
         || !TEST_true(EC_POINT_is_at_infinity(group, R))    /* R = P + 2Q */
         || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
         goto err;
+
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+    TEST_note("combined multiplication ...");
     points[0] = Q;
     points[1] = Q;
     points[2] = Q;
@@ -558,11 +574,10 @@ static int prime_field_tests(void)
         || !TEST_BN_even(y)
         || !TEST_true(BN_rshift1(y, y)))
         goto err;
+
     scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
     scalars[1] = y;
 
-    TEST_note("combined multiplication ...");
-
     /* z is still the group order */
     if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
         || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
@@ -593,10 +608,8 @@ static int prime_field_tests(void)
     if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
         || !TEST_true(EC_POINT_is_at_infinity(group, P)))
         goto err;
-
+# endif
     TEST_note(" ok\n");
-
-
     r = 1;
 err:
     BN_CTX_free(ctx);
@@ -803,8 +816,10 @@ static int char2_curve_test(int n)
     BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
     EC_GROUP *group = NULL, *variable = NULL;
     EC_POINT *P = NULL, *Q = NULL, *R = NULL;
+# ifndef OPENSSL_NO_DEPRECATED_3_0
     const EC_POINT *points[3];
     const BIGNUM *scalars[3];
+# endif
     struct c2_curve_test *const test = char2_curve_tests + n;
 
     if (!TEST_ptr(ctx = BN_CTX_new())
@@ -888,6 +903,8 @@ static int char2_curve_test(int n)
             || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
             goto err;
 
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+        TEST_note("combined multiplication ...");
         points[0] = Q;
         points[1] = Q;
         points[2] = Q;
@@ -899,8 +916,6 @@ static int char2_curve_test(int n)
         scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
         scalars[1] = y;
 
-        TEST_note("combined multiplication ...");
-
         /* z is still the group order */
         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
             || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
@@ -929,7 +944,8 @@ static int char2_curve_test(int n)
 
         if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
             || !TEST_true(EC_POINT_is_at_infinity(group, P)))
-            goto err;;
+            goto err;
+# endif
     }
 
     r = 1;
index 104e065..ef0b76b 100644 (file)
@@ -144,7 +144,7 @@ IDEA_set_decrypt_key                    146 3_0_0   EXIST::FUNCTION:DEPRECATEDIN_3
 X509_STORE_CTX_set_flags                147    3_0_0   EXIST::FUNCTION:
 BIO_ADDR_rawmake                        148    3_0_0   EXIST::FUNCTION:SOCK
 EVP_PKEY_asn1_set_ctrl                  149    3_0_0   EXIST::FUNCTION:
-EC_POINTs_mul                           150    3_0_0   EXIST::FUNCTION:EC
+EC_POINTs_mul                           150    3_0_0   EXIST::FUNCTION:DEPRECATEDIN_3_0,EC
 ASN1_get_object                         151    3_0_0   EXIST::FUNCTION:
 i2d_IPAddressFamily                     152    3_0_0   EXIST::FUNCTION:RFC3779
 ENGINE_get_ctrl_function                153    3_0_0   EXIST::FUNCTION:ENGINE