static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
-static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
- BIGNUM **rp);
-static int ecdsa_sign_setup_with_digest(EC_KEY *eckey, BN_CTX *ctx_in,
+static int ecdsa_sign_setup_no_digest(EC_KEY *eckey,
+ BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
BIGNUM **kinvp, BIGNUM **rp,
const unsigned char *dgst, int dlen);
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
static ECDSA_METHOD openssl_ecdsa_meth = {
"OpenSSL ECDSA method",
ecdsa_do_sign,
- ecdsa_sign_setup,
+ ecdsa_sign_setup_no_digest,
ecdsa_do_verify,
#if 0
NULL, /* init */
return &openssl_ecdsa_meth;
}
-static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
- BIGNUM **rp) {
- return ecdsa_sign_setup_with_digest(eckey, ctx_in, kinvp, rp, NULL, 0);
+static int ecdsa_sign_setup_no_digest(EC_KEY *eckey,
+ BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) {
+ return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
}
-static int ecdsa_sign_setup_with_digest(EC_KEY *eckey, BN_CTX *ctx_in,
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
BIGNUM **kinvp, BIGNUM **rp,
const unsigned char *dgst, int dlen)
{
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);
{
if (in_kinv == NULL || in_r == NULL)
{
- if (!ecdsa_sign_setup_with_digest(
+ if (!ecdsa_sign_setup(
eckey, ctx, &kinv, &ret->r, dgst, dgst_len))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);