Reserve option to use BN_mod_exp_mont_consttime in ECDSA.
[openssl.git] / crypto / ecdsa / ecs_ossl.c
index c4c3e891bd68e9670a141e5e60a05816f7c46644..c23343b64d885c3e9a7e4852c6ce21574737f9c0 100644 (file)
@@ -144,7 +144,6 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
                        }
                while (BN_is_zero(k));
 
-#ifdef ECDSA_POINT_MUL_NO_CONSTTIME
                /* We do not want timing information to leak the length of k,
                 * so we compute G*k using an equivalent scalar of fixed
                 * bit-length. */
@@ -152,7 +151,6 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
                if (!BN_add(k, k, order)) goto err;
                if (BN_num_bits(k) <= BN_num_bits(order))
                        if (!BN_add(k, k, order)) goto err;
-#endif /* def(ECDSA_POINT_MUL_NO_CONSTTIME) */
 
                /* compute r the x-coordinate of generator * k */
                if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
@@ -189,11 +187,37 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
        while (BN_is_zero(r));
 
        /* compute the inverse of k */
-       if (!BN_mod_inverse(k, k, order, ctx))
-       {
-               ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
-               goto err;       
-       }
+       if (EC_GROUP_get_mont_data(group) != NULL)
+               {
+               /* We want inverse in constant time, therefore we utilize the
+                * fact order must be prime and use Fermats Little Theorem
+                * instead. */
+               if (!BN_set_word(X, 2) )
+                       {
+                       ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+                       goto err;
+                       }
+               if (!BN_mod_sub(X, order, X, order, ctx))
+                       {
+                       ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+                       goto err;
+                       }
+               BN_set_flags(X, BN_FLG_CONSTTIME);
+               if (!BN_mod_exp_mont_consttime(k, k, X, order, ctx, EC_GROUP_get_mont_data(group)))
+                       {
+                       ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+                       goto err;
+                       }
+               }
+       else
+               {
+               if (!BN_mod_inverse(k, k, order, ctx))
+                       {
+                       ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+                       goto err;       
+                       }
+               }
+
        /* clear old values if necessary */
        if (*rp != NULL)
                BN_clear_free(*rp);