Skip to content

Commit 114ab64

Browse files
committed
deps: float ebf65dbe from openssl (DSA vulnerability)
Low severity timing vulnerability in the DSA signature algorithm Publicly disclosed but unreleased, pending OpenSSL 1.0.2q, not deemed severe enough to be assigned a CVE #. Ref: openssl/openssl#7487 Ref: openssl/openssl#7512 Ref: nodejs#23965 Upstream: openssl/openssl@415c3356 Upstream: openssl/openssl@ebf65dbe Original commit message: DSA mod inverse fix There is a side channel attack against the division used to calculate one of the modulo inverses in the DSA algorithm. This change takes advantage of the primality of the modulo and Fermat's little theorem to calculate the inverse without leaking information. Thanks to Samuel Weiser for finding and reporting this. Reviewed-by: Matthias St. Pierre <[email protected]> Reviewed-by: Bernd Edlinger <[email protected]> (Merged from openssl/openssl#7487) Original backport commit message: Reviewed-by: Richard Levitte <[email protected]> (Merged from openssl/openssl#7512)
1 parent 56af407 commit 114ab64

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

deps/openssl/openssl/crypto/dsa/dsa_ossl.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
7373
DSA_SIG *sig, DSA *dsa);
7474
static int dsa_init(DSA *dsa);
7575
static int dsa_finish(DSA *dsa);
76+
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
77+
BN_CTX *ctx);
7678

7779
static DSA_METHOD openssl_dsa_meth = {
7880
"OpenSSL DSA method",
@@ -333,8 +335,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
333335
if (!BN_mod(r, r, dsa->q, ctx))
334336
goto err;
335337

336-
/* Compute part of 's = inv(k) (m + xr) mod q' */
337-
if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL)
338+
/* Compute part of 's = inv(k) (m + xr) mod q' */
339+
if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL)
338340
goto err;
339341

340342
if (*kinvp != NULL)
@@ -468,3 +470,31 @@ static int dsa_finish(DSA *dsa)
468470
BN_MONT_CTX_free(dsa->method_mont_p);
469471
return (1);
470472
}
473+
474+
/*
475+
* Compute the inverse of k modulo q.
476+
* Since q is prime, Fermat's Little Theorem applies, which reduces this to
477+
* mod-exp operation. Both the exponent and modulus are public information
478+
* so a mod-exp that doesn't leak the base is sufficient. A newly allocated
479+
* BIGNUM is returned which the caller must free.
480+
*/
481+
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
482+
BN_CTX *ctx)
483+
{
484+
BIGNUM *res = NULL;
485+
BIGNUM *r, e;
486+
487+
if ((r = BN_new()) == NULL)
488+
return NULL;
489+
490+
BN_init(&e);
491+
492+
if (BN_set_word(r, 2)
493+
&& BN_sub(&e, q, r)
494+
&& BN_mod_exp_mont(r, k, &e, q, ctx, NULL))
495+
res = r;
496+
else
497+
BN_free(r);
498+
BN_free(&e);
499+
return res;
500+
}

0 commit comments

Comments
 (0)