Blame SOURCES/openssl-1.0.2k-cve-2018-0734.patch

3eeb22
diff -up openssl-1.0.2k/crypto/dsa/dsa_ossl.c.dsa-signing openssl-1.0.2k/crypto/dsa/dsa_ossl.c
3eeb22
--- openssl-1.0.2k/crypto/dsa/dsa_ossl.c.dsa-signing	2019-02-08 10:53:17.825805336 +0100
3eeb22
+++ openssl-1.0.2k/crypto/dsa/dsa_ossl.c	2019-04-04 16:05:53.155386419 +0200
3eeb22
@@ -76,6 +76,8 @@ static int dsa_do_verify(const unsigned
3eeb22
                          DSA_SIG *sig, DSA *dsa);
3eeb22
 static int dsa_init(DSA *dsa);
3eeb22
 static int dsa_finish(DSA *dsa);
3eeb22
+static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
3eeb22
+                                      BN_CTX *ctx);
3eeb22
 
3eeb22
 static DSA_METHOD openssl_dsa_meth = {
3eeb22
     "OpenSSL DSA method",
3eeb22
@@ -275,7 +277,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
 {
3eeb22
     BN_CTX *ctx;
3eeb22
     BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
3eeb22
+    BIGNUM l, m;
3eeb22
     int ret = 0;
3eeb22
+    int q_bits;
3eeb22
 
3eeb22
     if (!dsa->p || !dsa->q || !dsa->g) {
3eeb22
         DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
3eeb22
@@ -284,6 +288,8 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
 
3eeb22
     BN_init(&k);
3eeb22
     BN_init(&kq;;
3eeb22
+    BN_init(&l);
3eeb22
+    BN_init(&m);
3eeb22
 
3eeb22
     if (ctx_in == NULL) {
3eeb22
         if ((ctx = BN_CTX_new()) == NULL)
3eeb22
@@ -294,6 +300,13 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
     if ((r = BN_new()) == NULL)
3eeb22
         goto err;
3eeb22
 
3eeb22
+    /* Preallocate space */
3eeb22
+    q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16;
3eeb22
+    if (!BN_set_bit(&k, q_bits)
3eeb22
+        || !BN_set_bit(&l, q_bits)
3eeb22
+        || !BN_set_bit(&m, q_bits))
3eeb22
+        goto err;
3eeb22
+
3eeb22
     /* Get random k */
3eeb22
     do
3eeb22
         if (!BN_rand_range(&k, dsa->q))
3eeb22
@@ -302,9 +315,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
 
3eeb22
     if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
3eeb22
         BN_set_flags(&k, BN_FLG_CONSTTIME);
3eeb22
+        BN_set_flags(&l, BN_FLG_CONSTTIME);
3eeb22
     }
3eeb22
 
3eeb22
-
3eeb22
     if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
3eeb22
         if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
3eeb22
                                     CRYPTO_LOCK_DSA, dsa->p, ctx))
3eeb22
@@ -314,24 +327,23 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
     /* Compute r = (g^k mod p) mod q */
3eeb22
 
3eeb22
     if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
3eeb22
-        if (!BN_copy(&kq, &k))
3eeb22
-            goto err;
3eeb22
-
3eeb22
-        BN_set_flags(&kq, BN_FLG_CONSTTIME);
3eeb22
-
3eeb22
         /*
3eeb22
          * We do not want timing information to leak the length of k, so we
3eeb22
-         * compute g^k using an equivalent exponent of fixed length. (This
3eeb22
-         * is a kludge that we need because the BN_mod_exp_mont() does not
3eeb22
-         * let us specify the desired timing behaviour.)
3eeb22
+         * compute G^k using an equivalent scalar of fixed bit-length.
3eeb22
+         *
3eeb22
+         * We unconditionally perform both of these additions to prevent a
3eeb22
+         * small timing information leakage.  We then choose the sum that is
3eeb22
+         * one bit longer than the modulus.
3eeb22
+         *
3eeb22
+         * TODO: revisit the BN_copy aiming for a memory access agnostic
3eeb22
+         * conditional copy.
3eeb22
          */
3eeb22
-
3eeb22
-        if (!BN_add(&kq, &kq, dsa->q))
3eeb22
+        if (!BN_add(&l, &k, dsa->q)
3eeb22
+            || !BN_add(&m, &l, dsa->q)
3eeb22
+            || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m))
3eeb22
             goto err;
3eeb22
-        if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) {
3eeb22
-            if (!BN_add(&kq, &kq, dsa->q))
3eeb22
-                goto err;
3eeb22
-        }
3eeb22
+
3eeb22
+        BN_set_flags(&kq, BN_FLG_CONSTTIME);
3eeb22
 
3eeb22
         K = &kq;
3eeb22
     } else {
3eeb22
@@ -343,8 +355,8 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
     if (!BN_mod(r, r, dsa->q, ctx))
3eeb22
         goto err;
3eeb22
 
3eeb22
-    /* Compute  part of 's = inv(k) (m + xr) mod q' */
3eeb22
-    if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL)
3eeb22
+    /* Compute part of 's = inv(k) (m + xr) mod q' */
3eeb22
+    if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL)
3eeb22
         goto err;
3eeb22
 
3eeb22
     if (*kinvp != NULL)
3eeb22
@@ -365,7 +377,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C
3eeb22
         BN_CTX_free(ctx);
3eeb22
     BN_clear_free(&k);
3eeb22
     BN_clear_free(&kq;;
3eeb22
-    return (ret);
3eeb22
+    BN_clear_free(&l);
3eeb22
+    BN_clear_free(&m);
3eeb22
+    return ret;
3eeb22
 }
3eeb22
 
3eeb22
 static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
3eeb22
@@ -491,3 +505,31 @@ static int dsa_finish(DSA *dsa)
3eeb22
         BN_MONT_CTX_free(dsa->method_mont_p);
3eeb22
     return (1);
3eeb22
 }
3eeb22
+
3eeb22
+/*
3eeb22
+ * Compute the inverse of k modulo q.
3eeb22
+ * Since q is prime, Fermat's Little Theorem applies, which reduces this to
3eeb22
+ * mod-exp operation.  Both the exponent and modulus are public information
3eeb22
+ * so a mod-exp that doesn't leak the base is sufficient.  A newly allocated
3eeb22
+ * BIGNUM is returned which the caller must free.
3eeb22
+ */
3eeb22
+static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
3eeb22
+                                      BN_CTX *ctx)
3eeb22
+{
3eeb22
+    BIGNUM *res = NULL;
3eeb22
+    BIGNUM *r, e;
3eeb22
+
3eeb22
+    if ((r = BN_new()) == NULL)
3eeb22
+        return NULL;
3eeb22
+
3eeb22
+    BN_init(&e);
3eeb22
+
3eeb22
+    if (BN_set_word(r, 2)
3eeb22
+            && BN_sub(&e, q, r)
3eeb22
+            && BN_mod_exp_mont(r, k, &e, q, ctx, NULL))
3eeb22
+        res = r;
3eeb22
+    else
3eeb22
+        BN_free(r);
3eeb22
+    BN_free(&e);
3eeb22
+    return res;
3eeb22
+}