summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,