[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Tue Jun 19 10:49:39 UTC 2018


The branch master has been updated
       via  f667820c16a44245a4a898a568936c47a9b0ee6e (commit)
      from  ddb634fe6f9aeea34fe036cf804903b4240d38ac (commit)


- Log -----------------------------------------------------------------
commit f667820c16a44245a4a898a568936c47a9b0ee6e
Author: Sohaib ul Hassan <soh.19.hassan at gmail.com>
Date:   Sat Jun 16 17:07:40 2018 +0300

    Implement coordinate blinding for EC_POINT
    
    This commit implements coordinate blinding, i.e., it randomizes the
    representative of an elliptic curve point in its equivalence class, for
    prime curves implemented through EC_GFp_simple_method,
    EC_GFp_mont_method, and EC_GFp_nist_method.
    
    This commit is derived from the patch
    https://marc.info/?l=openssl-dev&m=131194808413635 by Billy Brumley.
    
    Coordinate blinding is a generally useful side-channel countermeasure
    and is (mostly) free. The function itself takes a few field
    multiplicationss, but is usually only necessary at the beginning of a
    scalar multiplication (as implemented in the patch). When used this way,
    it makes the values that variables take (i.e., field elements in an
    algorithm state) unpredictable.
    
    For instance, this mitigates chosen EC point side-channel attacks for
    settings such as ECDH and EC private key decryption, for the
    aforementioned curves.
    
    For EC_METHODs using different coordinate representations this commit
    does nothing, but the corresponding coordinate blinding function can be
    easily added in the future to extend these changes to such curves.
    
    Co-authored-by: Nicola Tuveri <nic.tuv at gmail.com>
    Co-authored-by: Billy Brumley <bbrumley at gmail.com>
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6501)

-----------------------------------------------------------------------

Summary of changes:
 CHANGES                  |  5 +++++
 crypto/ec/ec2_smpl.c     |  4 +++-
 crypto/ec/ec_err.c       |  2 ++
 crypto/ec/ec_lcl.h       |  5 +++++
 crypto/ec/ec_lib.c       | 18 +++++++++++++++
 crypto/ec/ec_mult.c      | 11 +++++++++
 crypto/ec/ecp_mont.c     |  4 +++-
 crypto/ec/ecp_nist.c     |  4 +++-
 crypto/ec/ecp_nistp224.c |  4 +++-
 crypto/ec/ecp_nistp521.c |  4 +++-
 crypto/ec/ecp_nistz256.c |  3 ++-
 crypto/ec/ecp_smpl.c     | 58 +++++++++++++++++++++++++++++++++++++++++++++++-
 crypto/err/openssl.txt   |  1 +
 include/openssl/ecerr.h  |  1 +
 14 files changed, 117 insertions(+), 7 deletions(-)

diff --git a/CHANGES b/CHANGES
index fe3e13a..a4beda6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,11 @@
  release branch.
 
  Changes between 1.1.0h and 1.1.1 [xx XXX xxxx]
+  *) Add coordinate blinding for EC_POINT and implement projective
+     coordinate blinding for generic prime curves as a countermeasure to
+     chosen point SCA attacks.
+     [Sohaib ul Hassan, Nicola Tuveri, Billy Bob Brumley]
+
   *) Add blinding to an ECDSA signature to protect against side channel attacks
      discovered by Keegan Ryan (NCC Group).
      [Matt Caswell]
diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c
index b79e60b..cef6ba4 100644
--- a/crypto/ec/ec2_smpl.c
+++ b/crypto/ec/ec2_smpl.c
@@ -64,7 +64,9 @@ const EC_METHOD *EC_GF2m_simple_method(void)
         ec_key_simple_generate_public_key,
         0, /* keycopy */
         0, /* keyfinish */
-        ecdh_simple_compute_key
+        ecdh_simple_compute_key,
+        0, /* field_inverse_mod_ord */
+        0  /* blind_coordinates */
     };
 
     return &ret;
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index 6a1be2e..342b84f 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -116,6 +116,8 @@ static const ERR_STRING_DATA EC_str_functs[] = {
      "ec_GFp_nist_field_sqr"},
     {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_GROUP_SET_CURVE, 0),
      "ec_GFp_nist_group_set_curve"},
+    {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0),
+     "ec_GFp_simple_blind_coordinates"},
     {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
      "ec_GFp_simple_group_check_discriminant"},
     {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0),
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index 5e14071..006e3b6 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -176,6 +176,7 @@ struct ec_method_st {
     /* Inverse modulo order */
     int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r, BIGNUM *x,
                                  BN_CTX *ctx);
+    int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
 };
 
 /*
@@ -382,6 +383,8 @@ int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
                             const BIGNUM *b, BN_CTX *);
 int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
                             BN_CTX *);
+int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
+                                   BN_CTX *ctx);
 
 /* method functions in ecp_mont.c */
 int ec_GFp_mont_group_init(EC_GROUP *);
@@ -635,3 +638,5 @@ void X25519_public_from_private(uint8_t out_public_value[32],
 
 int EC_GROUP_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
                             BIGNUM *x, BN_CTX *ctx);
+
+int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 30b11f7..d0393e8 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -1025,3 +1025,21 @@ int EC_GROUP_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
     else
         return 0;
 }
+
+/*-
+ * Coordinate blinding for EC_POINT.
+ *
+ * The underlying EC_METHOD can optionally implement this function:
+ * underlying implementations should return 0 on errors, or 1 on
+ * success.
+ *
+ * This wrapper returns 1 in case the underlying EC_METHOD does not
+ * support coordinate blinding.
+ */
+int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
+{
+    if (group->meth->blind_coordinates == NULL)
+        return 1; /* ignore if not implemented */
+
+    return group->meth->blind_coordinates(group, p, ctx);
+}
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index 05a3aca..b668e87 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -211,6 +211,17 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
         || (bn_wexpand(r->Z, group_top) == NULL))
         goto err;
 
+    /*-
+     * Apply coordinate blinding for EC_POINT.
+     *
+     * The underlying EC_METHOD can optionally implement this function:
+     * ec_point_blind_coordinates() returns 0 in case of errors or 1 on
+     * success or if coordinate blinding is not implemented for this
+     * group.
+     */
+    if (!ec_point_blind_coordinates(group, s, ctx))
+        goto err;
+
     /* top bit is a 1, in a fixed pos */
     if (!EC_POINT_copy(r, s))
         goto err;
diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c
index 1a760d1..27ece3b 100644
--- a/crypto/ec/ecp_mont.c
+++ b/crypto/ec/ecp_mont.c
@@ -61,7 +61,9 @@ const EC_METHOD *EC_GFp_mont_method(void)
         ec_key_simple_generate_public_key,
         0, /* keycopy */
         0, /* keyfinish */
-        ecdh_simple_compute_key
+        ecdh_simple_compute_key,
+        0, /* field_inverse_mod_ord */
+        ec_GFp_simple_blind_coordinates
     };
 
     return &ret;
diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c
index 16c4cce..aaa73d6 100644
--- a/crypto/ec/ecp_nist.c
+++ b/crypto/ec/ecp_nist.c
@@ -63,7 +63,9 @@ const EC_METHOD *EC_GFp_nist_method(void)
         ec_key_simple_generate_public_key,
         0, /* keycopy */
         0, /* keyfinish */
-        ecdh_simple_compute_key
+        ecdh_simple_compute_key,
+        0, /* field_inverse_mod_ord */
+        ec_GFp_simple_blind_coordinates
     };
 
     return &ret;
diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c
index 364b7f2..6e7c687 100644
--- a/crypto/ec/ecp_nistp224.c
+++ b/crypto/ec/ecp_nistp224.c
@@ -290,7 +290,9 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
         ec_key_simple_generate_public_key,
         0, /* keycopy */
         0, /* keyfinish */
-        ecdh_simple_compute_key
+        ecdh_simple_compute_key,
+        0, /* field_inverse_mod_ord */
+        0  /* blind_coordinates */
     };
 
     return &ret;
diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c
index 3f68ae3..43f3e2d 100644
--- a/crypto/ec/ecp_nistp521.c
+++ b/crypto/ec/ecp_nistp521.c
@@ -1658,7 +1658,9 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
         ec_key_simple_generate_public_key,
         0, /* keycopy */
         0, /* keyfinish */
-        ecdh_simple_compute_key
+        ecdh_simple_compute_key,
+        0, /* field_inverse_mod_ord */
+        0  /* blind_coordinates */
     };
 
     return &ret;
diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c
index d3603fb..0292561 100644
--- a/crypto/ec/ecp_nistz256.c
+++ b/crypto/ec/ecp_nistz256.c
@@ -1730,7 +1730,8 @@ const EC_METHOD *EC_GFp_nistz256_method(void)
         0, /* keycopy */
         0, /* keyfinish */
         ecdh_simple_compute_key,
-        ecp_nistz256_inv_mod_ord                    /* can be #define-d NULL */
+        ecp_nistz256_inv_mod_ord,                   /* can be #define-d NULL */
+        0                                           /* blind_coordinates */
     };
 
     return &ret;
diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c
index 35d15a6..e0e4996 100644
--- a/crypto/ec/ecp_smpl.c
+++ b/crypto/ec/ecp_smpl.c
@@ -62,7 +62,9 @@ const EC_METHOD *EC_GFp_simple_method(void)
         ec_key_simple_generate_public_key,
         0, /* keycopy */
         0, /* keyfinish */
-        ecdh_simple_compute_key
+        ecdh_simple_compute_key,
+        0, /* field_inverse_mod_ord */
+        ec_GFp_simple_blind_coordinates
     };
 
     return &ret;
@@ -1363,3 +1365,57 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
 {
     return BN_mod_sqr(r, a, group->field, ctx);
 }
+
+/*-
+ * Apply randomization of EC point projective coordinates:
+ *
+ *   (X, Y ,Z ) = (lambda^2*X, lambda^3*Y, lambda*Z)
+ *   lambda = [1,group->field)
+ *
+ */
+int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
+                                    BN_CTX *ctx)
+{
+    int ret = 0;
+    BIGNUM *lambda = NULL;
+    BIGNUM *temp = NULL;
+
+    BN_CTX_start(ctx);
+    lambda = BN_CTX_get(ctx);
+    temp = BN_CTX_get(ctx);
+    if (temp == NULL) {
+        ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* make sure lambda is not zero */
+    do {
+        if (!BN_priv_rand_range(lambda, group->field)) {
+            ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB);
+            goto err;
+        }
+    } while (BN_is_zero(lambda));
+
+    /* if field_encode defined convert between representations */
+    if (group->meth->field_encode != NULL
+        && !group->meth->field_encode(group, lambda, lambda, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, p->Z, p->Z, lambda, ctx))
+        goto err;
+    if (!group->meth->field_sqr(group, temp, lambda, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, p->X, p->X, temp, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, temp, temp, lambda, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
+        goto err;
+    p->Z_is_one = 0;
+
+    ret = 1;
+
+ err:
+     BN_CTX_end(ctx);
+     return ret;
+}
+
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 23671a0..e0580a8 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -550,6 +550,7 @@ EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES:235:\
 EC_F_EC_GFP_NIST_FIELD_MUL:200:ec_GFp_nist_field_mul
 EC_F_EC_GFP_NIST_FIELD_SQR:201:ec_GFp_nist_field_sqr
 EC_F_EC_GFP_NIST_GROUP_SET_CURVE:202:ec_GFp_nist_group_set_curve
+EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES:287:ec_GFp_simple_blind_coordinates
 EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT:165:\
 	ec_GFp_simple_group_check_discriminant
 EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE:166:ec_GFp_simple_group_set_curve
diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h
index 603efcc..8db7967 100644
--- a/include/openssl/ecerr.h
+++ b/include/openssl/ecerr.h
@@ -87,6 +87,7 @@ int ERR_load_EC_strings(void);
 #  define EC_F_EC_GFP_NIST_FIELD_MUL                       200
 #  define EC_F_EC_GFP_NIST_FIELD_SQR                       201
 #  define EC_F_EC_GFP_NIST_GROUP_SET_CURVE                 202
+#  define EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES             287
 #  define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT      165
 #  define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE               166
 #  define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE                   102


More information about the openssl-commits mailing list