summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2025-01-11 15:02:42 +0000
committertb <>2025-01-11 15:02:42 +0000
commit8bbda20016e5c5fe4b795ed53292cc98a0c9232f (patch)
tree292a6d20431880d1a728f0dc021debd5765db59f
parent793c33000da18d1042676e579534a57987870576 (diff)
downloadopenbsd-8bbda20016e5c5fe4b795ed53292cc98a0c9232f.tar.gz
openbsd-8bbda20016e5c5fe4b795ed53292cc98a0c9232f.tar.bz2
openbsd-8bbda20016e5c5fe4b795ed53292cc98a0c9232f.zip
Move compressed coordinate setting into public API
Now that it is method-agnostic, we can remove the method and move the implementation to the body of the public API function. And another method goes away. We're soon down to the ones we really need. discussed with jsing
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c89
-rw-r--r--src/lib/libcrypto/ec/ec_local.h4
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c98
3 files changed, 83 insertions, 108 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index ed51582146..a8b74ce89d 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.109 2025/01/11 14:38:57 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.110 2025/01/11 15:02:42 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 */
@@ -1026,8 +1026,9 @@ LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates_GFp);
1026 1026
1027int 1027int
1028EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 1028EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
1029 const BIGNUM *x, int y_bit, BN_CTX *ctx_in) 1029 const BIGNUM *in_x, int y_bit, BN_CTX *ctx_in)
1030{ 1030{
1031 BIGNUM *p, *a, *b, *w, *x, *y;
1031 BN_CTX *ctx; 1032 BN_CTX *ctx;
1032 int ret = 0; 1033 int ret = 0;
1033 1034
@@ -1036,18 +1037,90 @@ EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
1036 if (ctx == NULL) 1037 if (ctx == NULL)
1037 goto err; 1038 goto err;
1038 1039
1039 if (group->meth->point_set_compressed_coordinates == NULL) { 1040 y_bit = (y_bit != 0);
1040 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1041
1042 BN_CTX_start(ctx);
1043
1044 if ((p = BN_CTX_get(ctx)) == NULL)
1045 goto err;
1046 if ((a = BN_CTX_get(ctx)) == NULL)
1047 goto err;
1048 if ((b = BN_CTX_get(ctx)) == NULL)
1049 goto err;
1050 if ((w = BN_CTX_get(ctx)) == NULL)
1051 goto err;
1052 if ((x = BN_CTX_get(ctx)) == NULL)
1053 goto err;
1054 if ((y = BN_CTX_get(ctx)) == NULL)
1055 goto err;
1056
1057 /*
1058 * Weierstrass equation: y^2 = x^3 + ax + b, so y is one of the
1059 * square roots of x^3 + ax + b. The y-bit indicates which one.
1060 */
1061
1062 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
1063 goto err;
1064
1065 /* XXX - should we not insist on 0 <= x < p instead? */
1066 if (!BN_nnmod(x, in_x, p, ctx))
1067 goto err;
1068
1069 /* y = x^3 */
1070 if (!BN_mod_sqr(y, x, p, ctx))
1071 goto err;
1072 if (!BN_mod_mul(y, y, x, p, ctx))
1073 goto err;
1074
1075 /* y += ax */
1076 if (group->a_is_minus3) {
1077 if (!BN_mod_lshift1_quick(w, x, p))
1078 goto err;
1079 if (!BN_mod_add_quick(w, w, x, p))
1080 goto err;
1081 if (!BN_mod_sub_quick(y, y, w, p))
1082 goto err;
1083 } else {
1084 if (!BN_mod_mul(w, a, x, p, ctx))
1085 goto err;
1086 if (!BN_mod_add_quick(y, y, w, p))
1087 goto err;
1088 }
1089
1090 /* y += b */
1091 if (!BN_mod_add_quick(y, y, b, p))
1092 goto err;
1093
1094 if (!BN_mod_sqrt(y, y, p, ctx)) {
1095 ECerror(EC_R_INVALID_COMPRESSED_POINT);
1041 goto err; 1096 goto err;
1042 } 1097 }
1043 if (group->meth != point->meth) { 1098
1044 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1099 if (y_bit == BN_is_odd(y))
1100 goto done;
1101
1102 if (BN_is_zero(y)) {
1103 ECerror(EC_R_INVALID_COMPRESSION_BIT);
1045 goto err; 1104 goto err;
1046 } 1105 }
1047 ret = group->meth->point_set_compressed_coordinates(group, point, 1106 if (!BN_usub(y, p, y))
1048 x, y_bit, ctx); 1107 goto err;
1108
1109 if (y_bit != BN_is_odd(y)) {
1110 /* Can only happen if p is even and should not be reachable. */
1111 ECerror(ERR_R_INTERNAL_ERROR);
1112 goto err;
1113 }
1114
1115 done:
1116 if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1117 goto err;
1118
1119 ret = 1;
1049 1120
1050 err: 1121 err:
1122 BN_CTX_end(ctx);
1123
1051 if (ctx != ctx_in) 1124 if (ctx != ctx_in)
1052 BN_CTX_free(ctx); 1125 BN_CTX_free(ctx);
1053 1126
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index 0e81ab2b12..674023050c 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.56 2025/01/11 13:58:31 tb Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.57 2025/01/11 15:02:42 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 */
@@ -91,8 +91,6 @@ struct ec_method_st {
91 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 91 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
92 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, 92 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
93 BIGNUM *x, BIGNUM *y, BN_CTX *); 93 BIGNUM *x, BIGNUM *y, BN_CTX *);
94 int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
95 const BIGNUM *x, int y_bit, BN_CTX *);
96 94
97 /* Only used by the wNAF code. */ 95 /* Only used by the wNAF code. */
98 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT **, 96 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT **,
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index 57efce0366..66bde292a8 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.30 2025/01/11 14:53:46 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.31 2025/01/11 15:02:42 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.
@@ -276,100 +276,6 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
276} 276}
277 277
278static int 278static int
279ec_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
280 const BIGNUM *in_x, int y_bit, BN_CTX *ctx)
281{
282 BIGNUM *p, *a, *b, *w, *x, *y;
283 int ret = 0;
284
285 y_bit = (y_bit != 0);
286
287 BN_CTX_start(ctx);
288
289 if ((p = BN_CTX_get(ctx)) == NULL)
290 goto err;
291 if ((a = BN_CTX_get(ctx)) == NULL)
292 goto err;
293 if ((b = BN_CTX_get(ctx)) == NULL)
294 goto err;
295 if ((w = BN_CTX_get(ctx)) == NULL)
296 goto err;
297 if ((x = BN_CTX_get(ctx)) == NULL)
298 goto err;
299 if ((y = BN_CTX_get(ctx)) == NULL)
300 goto err;
301
302 /*
303 * Weierstrass equation: y^2 = x^3 + ax + b, so y is one of the
304 * square roots of x^3 + ax + b. The y-bit indicates which one.
305 */
306
307 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
308 goto err;
309
310 /* XXX - should we not insist on 0 <= x < p instead? */
311 if (!BN_nnmod(x, in_x, p, ctx))
312 goto err;
313
314 /* y = x^3 */
315 if (!BN_mod_sqr(y, x, p, ctx))
316 goto err;
317 if (!BN_mod_mul(y, y, x, p, ctx))
318 goto err;
319
320 /* y += ax */
321 if (group->a_is_minus3) {
322 if (!BN_mod_lshift1_quick(w, x, p))
323 goto err;
324 if (!BN_mod_add_quick(w, w, x, p))
325 goto err;
326 if (!BN_mod_sub_quick(y, y, w, p))
327 goto err;
328 } else {
329 if (!BN_mod_mul(w, a, x, p, ctx))
330 goto err;
331 if (!BN_mod_add_quick(y, y, w, p))
332 goto err;
333 }
334
335 /* y += b */
336 if (!BN_mod_add_quick(y, y, b, p))
337 goto err;
338
339 if (!BN_mod_sqrt(y, y, p, ctx)) {
340 ECerror(EC_R_INVALID_COMPRESSED_POINT);
341 goto err;
342 }
343
344 if (y_bit == BN_is_odd(y))
345 goto done;
346
347 if (BN_is_zero(y)) {
348 ECerror(EC_R_INVALID_COMPRESSION_BIT);
349 goto err;
350 }
351 if (!BN_usub(y, p, y))
352 goto err;
353
354 if (y_bit != BN_is_odd(y)) {
355 /* Can only happen if p is even and should not be reachable. */
356 ECerror(ERR_R_INTERNAL_ERROR);
357 goto err;
358 }
359
360 done:
361 if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
362 goto err;
363
364 ret = 1;
365
366 err:
367 BN_CTX_end(ctx);
368
369 return ret;
370}
371
372static int
373ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points, 279ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points,
374 BN_CTX *ctx) 280 BN_CTX *ctx)
375{ 281{
@@ -1420,7 +1326,6 @@ static const EC_METHOD ec_GFp_simple_method = {
1420 .group_get_curve = ec_group_get_curve, 1326 .group_get_curve = ec_group_get_curve,
1421 .point_set_affine_coordinates = ec_point_set_affine_coordinates, 1327 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1422 .point_get_affine_coordinates = ec_point_get_affine_coordinates, 1328 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1423 .point_set_compressed_coordinates = ec_set_compressed_coordinates,
1424 .points_make_affine = ec_points_make_affine, 1329 .points_make_affine = ec_points_make_affine,
1425 .add = ec_add, 1330 .add = ec_add,
1426 .dbl = ec_dbl, 1331 .dbl = ec_dbl,
@@ -1447,7 +1352,6 @@ static const EC_METHOD ec_GFp_mont_method = {
1447 .group_get_curve = ec_group_get_curve, 1352 .group_get_curve = ec_group_get_curve,
1448 .point_set_affine_coordinates = ec_point_set_affine_coordinates, 1353 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1449 .point_get_affine_coordinates = ec_point_get_affine_coordinates, 1354 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1450 .point_set_compressed_coordinates = ec_set_compressed_coordinates,
1451 .points_make_affine = ec_points_make_affine, 1355 .points_make_affine = ec_points_make_affine,
1452 .add = ec_add, 1356 .add = ec_add,
1453 .dbl = ec_dbl, 1357 .dbl = ec_dbl,