Blame SOURCES/openssl-1.1.1-cve-2019-1547.patch

b63792
From 30c22fa8b1d840036b8e203585738df62a03cec8 Mon Sep 17 00:00:00 2001
b63792
From: Billy Brumley <bbrumley@gmail.com>
b63792
Date: Thu, 5 Sep 2019 21:25:37 +0300
b63792
Subject: [PATCH] [crypto/ec] for ECC parameters with NULL or zero cofactor,
b63792
 compute it
b63792
b63792
The cofactor argument to EC_GROUP_set_generator is optional, and SCA
b63792
mitigations for ECC currently use it. So the library currently falls
b63792
back to very old SCA-vulnerable code if the cofactor is not present.
b63792
b63792
This PR allows EC_GROUP_set_generator to compute the cofactor for all
b63792
curves of cryptographic interest. Steering scalar multiplication to more
b63792
SCA-robust code.
b63792
b63792
This issue affects persisted private keys in explicit parameter form,
b63792
where the (optional) cofactor field is zero or absent.
b63792
b63792
It also affects curves not built-in to the library, but constructed
b63792
programatically with explicit parameters, then calling
b63792
EC_GROUP_set_generator with a nonsensical value (NULL, zero).
b63792
b63792
The very old scalar multiplication code is known to be vulnerable to
b63792
local uarch attacks, outside of the OpenSSL threat model. New results
b63792
suggest the code path is also vulnerable to traditional wall clock
b63792
timing attacks.
b63792
b63792
CVE-2019-1547
b63792
b63792
Reviewed-by: Matt Caswell <matt@openssl.org>
b63792
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
b63792
Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
b63792
(Merged from https://github.com/openssl/openssl/pull/9781)
b63792
---
b63792
 crypto/ec/ec_lib.c | 103 ++++++++++++++++++++++++++++++++++++++++++---
b63792
 1 file changed, 96 insertions(+), 7 deletions(-)
b63792
b63792
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
b63792
index 8cab5a5061..1289c8608e 100644
b63792
--- a/crypto/ec/ec_lib.c
b63792
+++ b/crypto/ec/ec_lib.c
b63792
@@ -265,6 +265,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
b63792
 
b63792
 static int ec_precompute_mont_data(EC_GROUP *);
b63792
 
b63792
+/*-
b63792
+ * Try computing cofactor from the generator order (n) and field cardinality (q).
b63792
+ * This works for all curves of cryptographic interest.
b63792
+ *
b63792
+ * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
b63792
+ * h_min = (q + 1 - 2*sqrt(q))/n
b63792
+ * h_max = (q + 1 + 2*sqrt(q))/n
b63792
+ * h_max - h_min = 4*sqrt(q)/n
b63792
+ * So if n > 4*sqrt(q) holds, there is only one possible value for h:
b63792
+ * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
b63792
+ *
b63792
+ * Otherwise, zero cofactor and return success.
b63792
+ */
b63792
+static int ec_guess_cofactor(EC_GROUP *group) {
b63792
+    int ret = 0;
b63792
+    BN_CTX *ctx = NULL;
b63792
+    BIGNUM *q = NULL;
b63792
+
b63792
+    /*-
b63792
+     * If the cofactor is too large, we cannot guess it.
b63792
+     * The RHS of below is a strict overestimate of lg(4 * sqrt(q))
b63792
+     */
b63792
+    if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) {
b63792
+        /* default to 0 */
b63792
+        BN_zero(group->cofactor);
b63792
+        /* return success */
b63792
+        return 1;
b63792
+    }
b63792
+
b63792
+    if ((ctx = BN_CTX_new()) == NULL)
b63792
+        return 0;
b63792
+
b63792
+    BN_CTX_start(ctx);
b63792
+    if ((q = BN_CTX_get(ctx)) == NULL)
b63792
+        goto err;
b63792
+
b63792
+    /* set q = 2**m for binary fields; q = p otherwise */
b63792
+    if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
b63792
+        BN_zero(q);
b63792
+        if (!BN_set_bit(q, BN_num_bits(group->field) - 1))
b63792
+            goto err;
b63792
+    } else {
b63792
+        if (!BN_copy(q, group->field))
b63792
+            goto err;
b63792
+    }
b63792
+
b63792
+    /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
b63792
+    if (!BN_rshift1(group->cofactor, group->order) /* n/2 */
b63792
+        || !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */
b63792
+        /* q + 1 + n/2 */
b63792
+        || !BN_add(group->cofactor, group->cofactor, BN_value_one())
b63792
+        /* (q + 1 + n/2)/n */
b63792
+        || !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx))
b63792
+        goto err;
b63792
+    ret = 1;
b63792
+ err:
b63792
+    BN_CTX_end(ctx);
b63792
+    BN_CTX_free(ctx);
b63792
+    return ret;
b63792
+}
b63792
+
b63792
 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
b63792
                            const BIGNUM *order, const BIGNUM *cofactor)
b63792
 {
b63792
@@ -273,6 +334,34 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
b63792
         return 0;
b63792
     }
b63792
 
b63792
+    /* require group->field >= 1 */
b63792
+    if (group->field == NULL || BN_is_zero(group->field)
b63792
+        || BN_is_negative(group->field)) {
b63792
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
b63792
+        return 0;
b63792
+    }
b63792
+
b63792
+    /*-
b63792
+     * - require order >= 1
b63792
+     * - enforce upper bound due to Hasse thm: order can be no more than one bit
b63792
+     *   longer than field cardinality
b63792
+     */
b63792
+    if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
b63792
+        || BN_num_bits(order) > BN_num_bits(group->field) + 1) {
b63792
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
b63792
+        return 0;
b63792
+    }
b63792
+
b63792
+    /*-
b63792
+     * Unfortunately the cofactor is an optional field in many standards.
b63792
+     * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
b63792
+     * So accept cofactor == NULL or cofactor >= 0.
b63792
+     */
b63792
+    if (cofactor != NULL && BN_is_negative(cofactor)) {
b63792
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
b63792
+        return 0;
b63792
+    }
b63792
+
b63792
     if (group->generator == NULL) {
b63792
         group->generator = EC_POINT_new(group);
b63792
         if (group->generator == NULL)
b63792
@@ -281,17 +370,17 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
b63792
     if (!EC_POINT_copy(group->generator, generator))
b63792
         return 0;
b63792
 
b63792
-    if (order != NULL) {
b63792
-        if (!BN_copy(group->order, order))
b63792
-            return 0;
b63792
-    } else
b63792
-        BN_zero(group->order);
b63792
+    if (!BN_copy(group->order, order))
b63792
+        return 0;
b63792
 
b63792
-    if (cofactor != NULL) {
b63792
+    /* Either take the provided positive cofactor, or try to compute it */
b63792
+    if (cofactor != NULL && !BN_is_zero(cofactor)) {
b63792
         if (!BN_copy(group->cofactor, cofactor))
b63792
             return 0;
b63792
-    } else
b63792
+    } else if (!ec_guess_cofactor(group)) {
b63792
         BN_zero(group->cofactor);
b63792
+        return 0;
b63792
+    }
b63792
 
b63792
     /*
b63792
      * Some groups have an order with
b63792
-- 
b63792
2.20.1
b63792