diff options
author | tb <> | 2025-01-11 15:02:42 +0000 |
---|---|---|
committer | tb <> | 2025-01-11 15:02:42 +0000 |
commit | 8bbda20016e5c5fe4b795ed53292cc98a0c9232f (patch) | |
tree | 292a6d20431880d1a728f0dc021debd5765db59f | |
parent | 793c33000da18d1042676e579534a57987870576 (diff) | |
download | openbsd-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.c | 89 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 4 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ecp_methods.c | 98 |
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 | ||
1027 | int | 1027 | int |
1028 | EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, | 1028 | EC_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 | ||
278 | static int | 278 | static int |
279 | ec_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 | |||
372 | static int | ||
373 | ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points, | 279 | ec_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, |