Don't use BN_mod_inverse for inverses mod p in RSA keygen.
Instead, use BN_mod_exp_mont_consttime of p - 2. This removes two more
call sites sensitive to BN_FLG_CONSTTIME. We're down to just that last
BN_mod_inverse modulo φ(n). (Sort of. It's actually not sensitive
because even mod inverses always hit the other codepath. Perhaps we
should just leave it alone.)
Note this comes with a slight behavior change. The BN_MONT_CTXs are
initialized a little earlier. If a caller calls RSA_generate_* and then
reaches into the struct to scrap all the fields on it, they'll get
confused. Before, they had to perform an operation on it to get
confused. This is a completely ridiculous thing to do.
Since we do this a lot, this introduces some convenience functions for
doing the Fermat's Little Theorem mod inverse and fixes a leak in the
DSA code should computing kinv hit a malloc error.
BUG=125
Change-Id: Iafcae2fc6fd379d161f015c90ff7050e2282e905
Reviewed-on: https://boringssl-review.googlesource.com/12925
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/dsa/dsa.c b/crypto/dsa/dsa.c
index 65e4091..15583be 100644
--- a/crypto/dsa/dsa.c
+++ b/crypto/dsa/dsa.c
@@ -72,6 +72,7 @@
#include <openssl/sha.h>
#include <openssl/thread.h>
+#include "../bn/internal.h"
#include "../internal.h"
@@ -814,7 +815,7 @@
int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
BIGNUM **out_r) {
BN_CTX *ctx;
- BIGNUM k, kq, qm2, *kinv = NULL, *r = NULL;
+ BIGNUM k, kq, *kinv = NULL, *r = NULL;
int ret = 0;
if (!dsa->p || !dsa->q || !dsa->g) {
@@ -824,7 +825,6 @@
BN_init(&k);
BN_init(&kq);
- BN_init(&qm2);
ctx = ctx_in;
if (ctx == NULL) {
@@ -886,9 +886,7 @@
* Theorem. */
kinv = BN_new();
if (kinv == NULL ||
- !BN_set_word(&qm2, 2) ||
- !BN_sub(&qm2, dsa->q, &qm2) ||
- !BN_mod_exp_mont(kinv, &k, &qm2, dsa->q, ctx, dsa->method_mont_q)) {
+ !bn_mod_inverse_prime(kinv, &k, dsa->q, ctx, dsa->method_mont_q)) {
goto err;
}
@@ -912,7 +910,7 @@
}
BN_clear_free(&k);
BN_clear_free(&kq);
- BN_free(&qm2);
+ BN_clear_free(kinv);
return ret;
}