summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2020-12-04 08:55:30 +0000
committertb <>2020-12-04 08:55:30 +0000
commiteba5b622a3ad6c48a28a09d15ca32cdfac91f91b (patch)
treeca443fbe605894704c5097fc9a5a6d9acc5a1b63 /src/lib
parent4dd2176959a6cdcb7f7ea0d8e3883f1ea62b1e55 (diff)
downloadopenbsd-eba5b622a3ad6c48a28a09d15ca32cdfac91f91b.tar.gz
openbsd-eba5b622a3ad6c48a28a09d15ca32cdfac91f91b.tar.bz2
openbsd-eba5b622a3ad6c48a28a09d15ca32cdfac91f91b.zip
Move point-on-curve check to set_affine_coordinates
Bad API design makes it possible to set an EC_KEY public key to a point not on the curve. As a consequence, it was possible to have bogus ECDSA signatures validated. In practice, all software uses either EC_POINT_oct2point*() to unmarshal public keys or issues a call to EC_KEY_check_key() after setting it. This way, a point on curve check is performed and the problem is mitigated. In OpenSSL commit 1e2012b7ff4a5f12273446b281775faa5c8a1858, Emilia Kasper moved the point-on-curve check from EC_POINT_oct2point to EC_POINT_set_affine_coordinates_*, which results in more checking. In addition to this commit, we also check in the currently unused codepath of a user set callback for setting compressed coordinates, just in case this will be used at some point in the future. The documentation of EC_KEY_check_key() is very vague on what it checks and when checks are needed. It could certainly be improved a lot. It's also strange that EC_KEY_set_key() performs no checks, while EC_KEY_set_public_key_affine_coordinates() implicitly calls EC_KEY_check_key(). It's a mess. Issue found and reported by Guido Vranken who also tested an earlier version of this fix. ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ec/ec2_oct.c15
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c18
-rw-r--r--src/lib/libcrypto/ec/ec_oct.c20
-rw-r--r--src/lib/libcrypto/ec/ecp_oct.c15
4 files changed, 50 insertions, 18 deletions
diff --git a/src/lib/libcrypto/ec/ec2_oct.c b/src/lib/libcrypto/ec/ec2_oct.c
index 268eccf471..5f7f7e3c99 100644
--- a/src/lib/libcrypto/ec/ec2_oct.c
+++ b/src/lib/libcrypto/ec/ec2_oct.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec2_oct.c,v 1.11 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ec2_oct.c,v 1.12 2020/12/04 08:55:30 tb Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 * 4 *
@@ -346,6 +346,10 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
346 goto err; 346 goto err;
347 } 347 }
348 if (form == POINT_CONVERSION_COMPRESSED) { 348 if (form == POINT_CONVERSION_COMPRESSED) {
349 /*
350 * EC_POINT_set_compressed_coordinates_GF2m checks that the
351 * point is on the curve as required by X9.62.
352 */
349 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) 353 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx))
350 goto err; 354 goto err;
351 } else { 355 } else {
@@ -363,15 +367,14 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
363 goto err; 367 goto err;
364 } 368 }
365 } 369 }
370 /*
371 * EC_POINT_set_affine_coordinates_GF2m checks that the
372 * point is on the curve as required by X9.62.
373 */
366 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) 374 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
367 goto err; 375 goto err;
368 } 376 }
369 377
370 /* test required by X9.62 */
371 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
372 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
373 goto err;
374 }
375 ret = 1; 378 ret = 1;
376 379
377 err: 380 err:
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index df9061627e..3442c7a324 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_lib.c,v 1.32 2019/09/29 10:09:09 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.33 2020/12/04 08:55:30 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -964,7 +964,13 @@ EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
964 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 964 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
965 return 0; 965 return 0;
966 } 966 }
967 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 967 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
968 return 0;
969 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
970 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
971 return 0;
972 }
973 return 1;
968} 974}
969 975
970#ifndef OPENSSL_NO_EC2M 976#ifndef OPENSSL_NO_EC2M
@@ -980,7 +986,13 @@ EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
980 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 986 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
981 return 0; 987 return 0;
982 } 988 }
983 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 989 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
990 return 0;
991 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
992 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
993 return 0;
994 }
995 return 1;
984} 996}
985#endif 997#endif
986 998
diff --git a/src/lib/libcrypto/ec/ec_oct.c b/src/lib/libcrypto/ec/ec_oct.c
index f44b174fd7..a285c81459 100644
--- a/src/lib/libcrypto/ec/ec_oct.c
+++ b/src/lib/libcrypto/ec/ec_oct.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_oct.c,v 1.5 2017/01/29 17:49:23 beck Exp $ */ 1/* $OpenBSD: ec_oct.c,v 1.6 2020/12/04 08:55:30 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -98,7 +98,14 @@ EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP * group, EC_POINT * point
98 group, point, x, y_bit, ctx); 98 group, point, x, y_bit, ctx);
99#endif 99#endif
100 } 100 }
101 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx); 101 if (!group->meth->point_set_compressed_coordinates(group, point, x,
102 y_bit, ctx))
103 return 0;
104 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
105 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
106 return 0;
107 }
108 return 1;
102} 109}
103 110
104#ifndef OPENSSL_NO_EC2M 111#ifndef OPENSSL_NO_EC2M
@@ -123,7 +130,14 @@ EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP * group, EC_POINT * poin
123 return ec_GF2m_simple_set_compressed_coordinates( 130 return ec_GF2m_simple_set_compressed_coordinates(
124 group, point, x, y_bit, ctx); 131 group, point, x, y_bit, ctx);
125 } 132 }
126 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx); 133 if (!group->meth->point_set_compressed_coordinates(group, point, x,
134 y_bit, ctx))
135 return 0;
136 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
137 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
138 return 0;
139 }
140 return 1;
127} 141}
128#endif 142#endif
129 143
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c
index 90c5ca2e4e..29d9990546 100644
--- a/src/lib/libcrypto/ec/ecp_oct.c
+++ b/src/lib/libcrypto/ec/ecp_oct.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_oct.c,v 1.11 2018/07/15 16:27:39 tb Exp $ */ 1/* $OpenBSD: ecp_oct.c,v 1.12 2020/12/04 08:55:30 tb Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project. 4 * Includes code written by Bodo Moeller for the OpenSSL project.
@@ -362,6 +362,10 @@ ec_GFp_simple_oct2point(const EC_GROUP * group, EC_POINT * point,
362 goto err; 362 goto err;
363 } 363 }
364 if (form == POINT_CONVERSION_COMPRESSED) { 364 if (form == POINT_CONVERSION_COMPRESSED) {
365 /*
366 * EC_POINT_set_compressed_coordinates_GFp checks that the point
367 * is on the curve as required by X9.62.
368 */
365 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) 369 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx))
366 goto err; 370 goto err;
367 } else { 371 } else {
@@ -377,15 +381,14 @@ ec_GFp_simple_oct2point(const EC_GROUP * group, EC_POINT * point,
377 goto err; 381 goto err;
378 } 382 }
379 } 383 }
384 /*
385 * EC_POINT_set_affine_coordinates_GFp checks that the point is
386 * on the curve as required by X9.62.
387 */
380 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) 388 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
381 goto err; 389 goto err;
382 } 390 }
383 391
384 /* test required by X9.62 */
385 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
386 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
387 goto err;
388 }
389 ret = 1; 392 ret = 1;
390 393
391 err: 394 err: