summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2025-01-06 10:56:46 +0000
committertb <>2025-01-06 10:56:46 +0000
commit1d5dc8af4f29575850958ce2ca4c6ffcc27dece5 (patch)
tree5250419bf796593e37d9a70cab2f081aaa78174e
parent41644a653441af880b86e412a5c8e52ef0c53151 (diff)
downloadopenbsd-1d5dc8af4f29575850958ce2ca4c6ffcc27dece5.tar.gz
openbsd-1d5dc8af4f29575850958ce2ca4c6ffcc27dece5.tar.bz2
openbsd-1d5dc8af4f29575850958ce2ca4c6ffcc27dece5.zip
Prepare removal accessors for Jprojective coordinates
That the BN-driven EC code uses Jacobian projective coordinates as an optimization is an implementation detail. As such this should never have leaked out of the library as part of the public API. No consumer should ever care and if they do they're doing it wrong. The only port that cares is one of those stupid little perl modules that expose all the things and transform terrible OpenSSL regress tests into similarly horrible Perl. In practice, only affine coordinates matter (perhaps in compressed form). This prunes two more function pointers from EC_GROUP and prepares the removal of the field_set_to_one() method which is now only used in ec_points_make_affine(). ok jsing sthen
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c76
-rw-r--r--src/lib/libcrypto/ec/ec_local.h11
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c79
3 files changed, 16 insertions, 150 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index d961ad0ee4..03c6f3aa90 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.94 2025/01/05 16:07:08 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.95 2025/01/06 10:56:46 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 */
@@ -908,78 +908,11 @@ EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
908LCRYPTO_ALIAS(EC_POINT_set_to_infinity); 908LCRYPTO_ALIAS(EC_POINT_set_to_infinity);
909 909
910int 910int
911EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point,
912 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx_in)
913{
914 BN_CTX *ctx;
915 int ret = 0;
916
917 if ((ctx = ctx_in) == NULL)
918 ctx = BN_CTX_new();
919 if (ctx == NULL)
920 goto err;
921
922 if (group->meth->point_set_Jprojective_coordinates == NULL) {
923 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
924 goto err;
925 }
926 if (group->meth != point->meth) {
927 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
928 goto err;
929 }
930 if (!group->meth->point_set_Jprojective_coordinates(group, point,
931 x, y, z, ctx))
932 goto err;
933
934 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
935 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
936 goto err;
937 }
938
939 ret = 1;
940
941 err:
942 if (ctx != ctx_in)
943 BN_CTX_free(ctx);
944
945 return ret;
946}
947
948int
949EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group,
950 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx_in)
951{
952 BN_CTX *ctx;
953 int ret = 0;
954
955 if ((ctx = ctx_in) == NULL)
956 ctx = BN_CTX_new();
957 if (ctx == NULL)
958 goto err;
959
960 if (group->meth->point_get_Jprojective_coordinates == NULL) {
961 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
962 goto err;
963 }
964 if (group->meth != point->meth) {
965 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
966 goto err;
967 }
968 ret = group->meth->point_get_Jprojective_coordinates(group, point,
969 x, y, z, ctx);
970
971 err:
972 if (ctx != ctx_in)
973 BN_CTX_free(ctx);
974
975 return ret;
976}
977
978int
979EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 911EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
980 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 912 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
981{ 913{
982 return EC_POINT_set_Jprojective_coordinates(group, point, x, y, z, ctx); 914 ECerror(ERR_R_DISABLED);
915 return 0;
983} 916}
984LCRYPTO_ALIAS(EC_POINT_set_Jprojective_coordinates_GFp); 917LCRYPTO_ALIAS(EC_POINT_set_Jprojective_coordinates_GFp);
985 918
@@ -987,7 +920,8 @@ int
987EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, 920EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
988 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 921 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
989{ 922{
990 return EC_POINT_get_Jprojective_coordinates(group, point, x, y, z, ctx); 923 ECerror(ERR_R_DISABLED);
924 return 0;
991} 925}
992LCRYPTO_ALIAS(EC_POINT_get_Jprojective_coordinates_GFp); 926LCRYPTO_ALIAS(EC_POINT_get_Jprojective_coordinates_GFp);
993 927
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index 0d734351de..2bddaddd8a 100644
--- a/src/lib/libcrypto/ec/ec_local.h
+++ b/src/lib/libcrypto/ec/ec_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_local.h,v 1.46 2025/01/05 16:07:08 tb Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.47 2025/01/06 10:56:46 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 */
@@ -99,10 +99,6 @@ struct ec_method_st {
99 int (*group_order_bits)(const EC_GROUP *); 99 int (*group_order_bits)(const EC_GROUP *);
100 int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *); 100 int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
101 101
102 int (*point_set_Jprojective_coordinates)(const EC_GROUP *, EC_POINT *,
103 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
104 int (*point_get_Jprojective_coordinates)(const EC_GROUP *,
105 const EC_POINT *, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
106 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *, 102 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
107 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 103 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
108 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, 104 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
@@ -277,11 +273,6 @@ int ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
277int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, 273int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z,
278 size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md); 274 size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md);
279 275
280int EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *p,
281 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
282int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group,
283 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
284
285int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid); 276int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid);
286int ec_group_get_field_type(const EC_GROUP *group); 277int ec_group_get_field_type(const EC_GROUP *group);
287 278
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index b2ecc7e17a..7bdeb351da 100644
--- a/src/lib/libcrypto/ec/ecp_methods.c
+++ b/src/lib/libcrypto/ec/ecp_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_methods.c,v 1.18 2025/01/05 16:07:08 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.19 2025/01/06 10:56:46 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.
@@ -124,23 +124,6 @@ ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx
124} 124}
125 125
126static int 126static int
127ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one,
128 const BIGNUM *z, BN_CTX *ctx)
129{
130 if (!BN_nnmod(bn, z, group->p, ctx))
131 return 0;
132
133 *is_one = BN_is_one(bn);
134 if (*is_one && group->meth->field_set_to_one != NULL)
135 return group->meth->field_set_to_one(group, bn, ctx);
136
137 if (group->meth->field_encode != NULL)
138 return group->meth->field_encode(group, bn, bn, ctx);
139
140 return 1;
141}
142
143static int
144ec_group_set_curve(EC_GROUP *group, 127ec_group_set_curve(EC_GROUP *group,
145 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 128 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
146{ 129{
@@ -262,48 +245,23 @@ ec_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
262} 245}
263 246
264static int 247static int
265ec_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, 248ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
266 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 249 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
267{ 250{
268 int ret = 0; 251 int ret = 0;
269 252
270 /* 253 if (x == NULL || y == NULL) {
271 * Setting individual coordinates allows the creation of bad points. 254 ECerror(ERR_R_PASSED_NULL_PARAMETER);
272 * EC_POINT_set_Jprojective_coordinates() checks at the API boundary. 255 goto err;
273 */
274
275 if (x != NULL) {
276 if (!ec_encode_scalar(group, point->X, x, ctx))
277 goto err;
278 }
279 if (y != NULL) {
280 if (!ec_encode_scalar(group, point->Y, y, ctx))
281 goto err;
282 }
283 if (z != NULL) {
284 if (!ec_encode_z_coordinate(group, point->Z, &point->Z_is_one,
285 z, ctx))
286 goto err;
287 } 256 }
288 257
289 ret = 1; 258 if (!ec_encode_scalar(group, point->X, x, ctx))
290
291 err:
292 return ret;
293}
294
295static int
296ec_get_Jprojective_coordinates(const EC_GROUP *group, const EC_POINT *point,
297 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
298{
299 int ret = 0;
300
301 if (!ec_decode_scalar(group, x, point->X, ctx))
302 goto err; 259 goto err;
303 if (!ec_decode_scalar(group, y, point->Y, ctx)) 260 if (!ec_encode_scalar(group, point->Y, y, ctx))
304 goto err; 261 goto err;
305 if (!ec_decode_scalar(group, z, point->Z, ctx)) 262 if (!ec_encode_scalar(group, point->Z, BN_value_one(), ctx))
306 goto err; 263 goto err;
264 point->Z_is_one = 1;
307 265
308 ret = 1; 266 ret = 1;
309 267
@@ -312,19 +270,6 @@ ec_get_Jprojective_coordinates(const EC_GROUP *group, const EC_POINT *point,
312} 270}
313 271
314static int 272static int
315ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
316 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
317{
318 if (x == NULL || y == NULL) {
319 /* unlike for projective coordinates, we do not tolerate this */
320 ECerror(ERR_R_PASSED_NULL_PARAMETER);
321 return 0;
322 }
323 return EC_POINT_set_Jprojective_coordinates(group, point, x, y,
324 BN_value_one(), ctx);
325}
326
327static int
328ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 273ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
329 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 274 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
330{ 275{
@@ -1652,8 +1597,6 @@ static const EC_METHOD ec_GFp_simple_method = {
1652 .group_get_degree = ec_group_get_degree, 1597 .group_get_degree = ec_group_get_degree,
1653 .group_order_bits = ec_group_simple_order_bits, 1598 .group_order_bits = ec_group_simple_order_bits,
1654 .group_check_discriminant = ec_group_check_discriminant, 1599 .group_check_discriminant = ec_group_check_discriminant,
1655 .point_set_Jprojective_coordinates = ec_set_Jprojective_coordinates,
1656 .point_get_Jprojective_coordinates = ec_get_Jprojective_coordinates,
1657 .point_set_affine_coordinates = ec_point_set_affine_coordinates, 1600 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1658 .point_get_affine_coordinates = ec_point_get_affine_coordinates, 1601 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1659 .point_set_compressed_coordinates = ec_set_compressed_coordinates, 1602 .point_set_compressed_coordinates = ec_set_compressed_coordinates,
@@ -1687,8 +1630,6 @@ static const EC_METHOD ec_GFp_mont_method = {
1687 .group_get_degree = ec_group_get_degree, 1630 .group_get_degree = ec_group_get_degree,
1688 .group_order_bits = ec_group_simple_order_bits, 1631 .group_order_bits = ec_group_simple_order_bits,
1689 .group_check_discriminant = ec_group_check_discriminant, 1632 .group_check_discriminant = ec_group_check_discriminant,
1690 .point_set_Jprojective_coordinates = ec_set_Jprojective_coordinates,
1691 .point_get_Jprojective_coordinates = ec_get_Jprojective_coordinates,
1692 .point_set_affine_coordinates = ec_point_set_affine_coordinates, 1633 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1693 .point_get_affine_coordinates = ec_point_get_affine_coordinates, 1634 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1694 .point_set_compressed_coordinates = ec_set_compressed_coordinates, 1635 .point_set_compressed_coordinates = ec_set_compressed_coordinates,