Forbid setting EC public key to point at infinity The point at infinity is not a valid EC public key. We already refuse to parse it. This CL makes it forbidden to set an EC public key to a manually-constructed point at infinity. This change will allow callers to assume that ECDH is infallible given a valid peer public key. Update-Note: EC_KEY_set_public_key will now return an error if configuring the point at infinity as a public key. This does not impact parsing, which already rejected such a point, and the resulting key would have failed all operations already. Change-Id: I202307a510543f4305b1cb46094d2c83174047af Fixed: 438493754 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81267 Commit-Queue: Lily Chen <chlily@google.com> Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/ec/ec_key.cc.inc b/crypto/fipsmodule/ec/ec_key.cc.inc index d471e84..754998a 100644 --- a/crypto/fipsmodule/ec/ec_key.cc.inc +++ b/crypto/fipsmodule/ec/ec_key.cc.inc
@@ -213,6 +213,11 @@ return 0; } + if (pub_key != NULL && EC_POINT_is_at_infinity(pub_key->group, pub_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + if (pub_key != NULL && EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) { OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); return 0;
diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index 4be8d5b..2f269fa 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc
@@ -453,6 +453,17 @@ EXPECT_FALSE(EC_KEY_get0_public_key(key.get())); } +TEST(ECTest, PointAtInfinity) { + bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + ASSERT_TRUE(key); + + bssl::UniquePtr<EC_POINT> inf(EC_POINT_new(key->group)); + ASSERT_TRUE(inf); + ASSERT_TRUE(EC_POINT_set_to_infinity(key->group, inf.get())); + // Configuring a public key with the point at infinity is invalid. + EXPECT_FALSE(EC_KEY_set_public_key(key.get(), inf.get())); +} + TEST(ECTest, GroupMismatch) { bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_secp384r1)); ASSERT_TRUE(key);
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 1133a37..47d5063 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h
@@ -87,7 +87,7 @@ // EC_KEY_set_public_key sets the public key of |key| to |pub|, by copying it. // It returns one on success and zero otherwise. |key| must already have had a // group configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|), and -// |pub| must also belong to that group. +// |pub| must also belong to that group, and must not be the point at infinity. OPENSSL_EXPORT int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); #define EC_PKEY_NO_PARAMETERS 0x001