[openssl] master update

nic.tuv at gmail.com nic.tuv at gmail.com
Sun May 9 12:21:33 UTC 2021


The branch master has been updated
       via  f0f4a46c4f5c82d4d9d0fb8a51d546c3135668a2 (commit)
       via  e70abb8b4cb3b6259812137f72efa100797bca22 (commit)
       via  56f0237938c7e99d04f004886d56cb76514c4d56 (commit)
      from  32b1da718d5d6f35fcef82f3794273807d6202e9 (commit)


- Log -----------------------------------------------------------------
commit f0f4a46c4f5c82d4d9d0fb8a51d546c3135668a2
Author: Nicola Tuveri <nic.tuv at gmail.com>
Date:   Sun May 9 14:57:14 2021 +0300

    FIPS checksums update
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15108)

commit e70abb8b4cb3b6259812137f72efa100797bca22
Author: Theo Buehler <tb at openbsd.org>
Date:   Sat May 1 13:09:10 2021 +0200

    Test oct2point for hybrid point encoding of (0, y)
    
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15108)

commit 56f0237938c7e99d04f004886d56cb76514c4d56
Author: Theo Buehler <tb at openbsd.org>
Date:   Sat May 1 12:25:50 2021 +0200

    Avoid division by zero in hybrid point encoding
    
    In hybrid and compressed point encodings, the form octet contains a bit
    of information allowing to calculate y from x.  For a point on a binary
    curve, this bit is zero if x is zero, otherwise it must match the
    rightmost bit of of the field element y / x.  The existing code only
    considers the second possibility. It could thus incorrecly fail with a
    division by zero error as found by Guido Vranken's cryptofuzz.
    
    This commit adds a few explanatory comments to oct2point. The only
    actual code change is in the last hunk which adds a BN_is_zero(x)
    check to avoid the division by zero.
    
    Fixes #15021
    
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15108)

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

Summary of changes:
 crypto/ec/ec2_oct.c              | 41 +++++++++++++++++++++++++-------
 providers/fips-sources.checksums |  2 +-
 providers/fips.checksum          |  2 +-
 test/ectest.c                    | 50 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/crypto/ec/ec2_oct.c b/crypto/ec/ec2_oct.c
index 9f6e5de6fd..1970efd65c 100644
--- a/crypto/ec/ec2_oct.c
+++ b/crypto/ec/ec2_oct.c
@@ -270,9 +270,21 @@ int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
         ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
         return 0;
     }
-    form = buf[0];
-    y_bit = form & 1;
-    form = form & ~1U;
+
+    /*
+     * The first octet is the point converison octet PC, see X9.62, page 4
+     * and section 4.4.2.  It must be:
+     *     0x00          for the point at infinity
+     *     0x02 or 0x03  for compressed form
+     *     0x04          for uncompressed form
+     *     0x06 or 0x07  for hybrid form.
+     * For compressed or hybrid forms, we store the last bit of buf[0] as
+     * y_bit and clear it from buf[0] so as to obtain a POINT_CONVERSION_*.
+     * We error if buf[0] contains any but the above values.
+     */
+    y_bit = buf[0] & 1;
+    form = buf[0] & ~1U;
+
     if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
         && (form != POINT_CONVERSION_UNCOMPRESSED)
         && (form != POINT_CONVERSION_HYBRID)) {
@@ -284,6 +296,7 @@ int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
         return 0;
     }
 
+    /* The point at infinity is represented by a single zero octet. */
     if (form == 0) {
         if (len != 1) {
             ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
@@ -337,11 +350,23 @@ int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
             goto err;
         }
         if (form == POINT_CONVERSION_HYBRID) {
-            if (!group->meth->field_div(group, yxi, y, x, ctx))
-                goto err;
-            if (y_bit != BN_is_odd(yxi)) {
-                ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
-                goto err;
+            /*
+             * Check that the form in the encoding was set correctly
+             * according to X9.62 4.4.2.a, 4(c), see also first paragraph
+             * of X9.62, 4.4.1.b.
+             */
+            if (BN_is_zero(x)) {
+                if (y_bit != 0) {
+                    ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+                    goto err;
+                }
+            } else {
+                if (!group->meth->field_div(group, yxi, y, x, ctx))
+                    goto err;
+                if (y_bit != BN_is_odd(yxi)) {
+                    ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
+                    goto err;
+                }
             }
         }
 
diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums
index 0ab5e40394..49535d99e5 100644
--- a/providers/fips-sources.checksums
+++ b/providers/fips-sources.checksums
@@ -140,7 +140,7 @@ eaa940893610f5ec1cc04f5b1842bfa0ba65bf048039e6cc2d2b83bbb575bb51  crypto/ec/curv
 a1211ed3991af967c728b9f6d0774b9ea098d43cef0631ff88984a2580d2ac4f  crypto/ec/curve448/eddsa.c
 d4969259e4fa5b71d8abbf5e736e658bd1daad6e46d272a9b88e190e2de96b61  crypto/ec/curve448/f_generic.c
 7aeddfe47959556f50856cb387d74b51d222c65f891acb83742313ddc49c0e93  crypto/ec/curve448/scalar.c
-ed003170c5eaaaa4a33f4ef37b43465f2ba7a5fa5fec2d7d17c1e0897ea818d7  crypto/ec/ec2_oct.c
+04f8d52acc6332bdf879bf1684e8c59d2f4d8ca303d16c74d87aab3dd4a94932  crypto/ec/ec2_oct.c
 7579a156234dfa44e02d08e121f42035229364f9e40f38b11333edbae2282762  crypto/ec/ec2_smpl.c
 69d64accd498583e65df2dc43730eee2922217a7bfefda2cd1a9da176e3d1dcd  crypto/ec/ec_asn1.c
 8cf8af8e9bfc29e0cdc41720ec4a6d6c74eb5c15a9fc8193f8ec8270c0df1d37  crypto/ec/ec_backend.c
diff --git a/providers/fips.checksum b/providers/fips.checksum
index cbb359f123..2f3dff8cfc 100644
--- a/providers/fips.checksum
+++ b/providers/fips.checksum
@@ -1 +1 @@
-db2202782291f6e77fbe9f6271517cb41d7c06790a606a61f69e564f002f76f5  providers/fips-sources.checksums
+5a2795b0bfeec67d234e9cf05bbac1571f205ba2da7e378e81b6e105fec1c85b  providers/fips-sources.checksums
diff --git a/test/ectest.c b/test/ectest.c
index 8b737149d8..f58cd4e4bc 100644
--- a/test/ectest.c
+++ b/test/ectest.c
@@ -1083,6 +1083,55 @@ err:
     BN_free(yplusone);
     return r;
 }
+
+static int hybrid_point_encoding_test(void)
+{
+    BIGNUM *x = NULL, *y = NULL;
+    EC_GROUP *group = NULL;
+    EC_POINT *point = NULL;
+    unsigned char *buf = NULL;
+    size_t len;
+    int r = 0;
+
+    if (!TEST_true(BN_dec2bn(&x, "0"))
+        || !TEST_true(BN_dec2bn(&y, "1"))
+        || !TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_sect571k1))
+        || !TEST_ptr(point = EC_POINT_new(group))
+        || !TEST_true(EC_POINT_set_affine_coordinates(group, point, x, y, NULL))
+        || !TEST_size_t_ne(0, (len = EC_POINT_point2oct(group,
+                                                        point,
+                                                        POINT_CONVERSION_HYBRID,
+                                                        NULL,
+                                                        0,
+                                                        NULL)))
+        || !TEST_ptr(buf = OPENSSL_malloc(len))
+        || !TEST_size_t_eq(len, EC_POINT_point2oct(group,
+                                                   point,
+                                                   POINT_CONVERSION_HYBRID,
+                                                   buf,
+                                                   len,
+                                                   NULL)))
+        goto err;
+
+    r = 1;
+
+    /* buf contains a valid hybrid point, check that we can decode it. */
+    if (!TEST_true(EC_POINT_oct2point(group, point, buf, len, NULL)))
+        r = 0;
+
+    /* Flip the y_bit and verify that the invalid encoding is rejected. */
+    buf[0] ^= 1;
+    if (!TEST_false(EC_POINT_oct2point(group, point, buf, len, NULL)))
+        r = 0;
+
+err:
+    BN_free(x);
+    BN_free(y);
+    EC_GROUP_free(group);
+    EC_POINT_free(point);
+    OPENSSL_free(buf);
+    return r;
+}
 #endif
 
 static int internal_curve_test(int n)
@@ -2929,6 +2978,7 @@ int setup_tests(void)
     ADD_ALL_TESTS(cardinality_test, crv_len);
     ADD_TEST(prime_field_tests);
 #ifndef OPENSSL_NO_EC2M
+    ADD_TEST(hybrid_point_encoding_test);
     ADD_TEST(char2_field_tests);
     ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
 #endif


More information about the openssl-commits mailing list