diff options
author | tb <> | 2024-11-01 05:20:58 +0000 |
---|---|---|
committer | tb <> | 2024-11-01 05:20:58 +0000 |
commit | 61bfefaa1ab36049ad0ee2736841ce07e2859de0 (patch) | |
tree | 4b39e7d5d135d31e112ccfe8357eef5accb5457b /src | |
parent | 4094cfb081d56f52cfc4c476889db294fab4e641 (diff) | |
download | openbsd-61bfefaa1ab36049ad0ee2736841ce07e2859de0.tar.gz openbsd-61bfefaa1ab36049ad0ee2736841ce07e2859de0.tar.bz2 openbsd-61bfefaa1ab36049ad0ee2736841ce07e2859de0.zip |
Move point_conversion_t conversion to API boundary
EC_POINT_oct2point() is the only API that needs detailed knowledge about
this incomplete enum. [Arguably, the setters for the EC_KEY and EC_GROUP
member of that type would also need to be able to validate what's being
set, but they can't since they can't fail.] Anyway. Add a helper that lets
EC_POINT_oct2point() translate that enum to its internal representation
at the API boundary and add a check that ensures that we only encode the
point at infinity as the point at infinity.
ok jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/ec/ec_convert.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/src/lib/libcrypto/ec/ec_convert.c b/src/lib/libcrypto/ec/ec_convert.c index 65636f27fa..f3eb6d5791 100644 --- a/src/lib/libcrypto/ec/ec_convert.c +++ b/src/lib/libcrypto/ec/ec_convert.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_convert.c,v 1.8 2024/10/31 15:42:47 tb Exp $ */ | 1 | /* $OpenBSD: ec_convert.c,v 1.9 2024/11/01 05:20:58 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 | */ |
@@ -219,32 +219,14 @@ ec_get_field_element_cbs(CBS *cbs, const EC_GROUP *group, BIGNUM *bn) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | static size_t | 221 | static size_t |
222 | ec_point2oct(const EC_GROUP *group, const EC_POINT *point, | 222 | ec_point2oct(const EC_GROUP *group, const EC_POINT *point, uint8_t form, |
223 | point_conversion_form_t conversion_form, unsigned char *buf, size_t len, | 223 | unsigned char *buf, size_t len, BN_CTX *ctx) |
224 | BN_CTX *ctx) | ||
225 | { | 224 | { |
226 | CBB cbb; | 225 | CBB cbb; |
227 | uint8_t form; | ||
228 | BIGNUM *x, *y; | 226 | BIGNUM *x, *y; |
229 | size_t encoded_length; | 227 | size_t encoded_length; |
230 | size_t ret = 0; | 228 | size_t ret = 0; |
231 | 229 | ||
232 | if (conversion_form > UINT8_MAX) { | ||
233 | ECerror(EC_R_INVALID_FORM); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | form = conversion_form; | ||
238 | |||
239 | /* | ||
240 | * Established behavior is to reject a request for the form 0 for the | ||
241 | * point at infinity even if it is valid. | ||
242 | */ | ||
243 | if (form == 0 || !ec_conversion_form_is_valid(form)) { | ||
244 | ECerror(EC_R_INVALID_FORM); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | if (EC_POINT_is_at_infinity(group, point)) | 230 | if (EC_POINT_is_at_infinity(group, point)) |
249 | form = EC_OCT_POINT_AT_INFINITY; | 231 | form = EC_OCT_POINT_AT_INFINITY; |
250 | 232 | ||
@@ -266,6 +248,8 @@ ec_point2oct(const EC_GROUP *group, const EC_POINT *point, | |||
266 | goto err; | 248 | goto err; |
267 | 249 | ||
268 | if (form == EC_OCT_POINT_AT_INFINITY) { | 250 | if (form == EC_OCT_POINT_AT_INFINITY) { |
251 | if (!EC_POINT_is_at_infinity(group, point)) | ||
252 | goto err; | ||
269 | if (!ec_add_leading_octet_cbb(&cbb, form, 0)) | 253 | if (!ec_add_leading_octet_cbb(&cbb, form, 0)) |
270 | goto err; | 254 | goto err; |
271 | 255 | ||
@@ -434,14 +418,40 @@ ec_point_from_octets(const EC_GROUP *group, const unsigned char *buf, size_t buf | |||
434 | return ret; | 418 | return ret; |
435 | } | 419 | } |
436 | 420 | ||
421 | static int | ||
422 | ec_normalize_form(const EC_GROUP *group, const EC_POINT *point, int form, | ||
423 | uint8_t *out_form) | ||
424 | { | ||
425 | /* | ||
426 | * Established behavior is to reject a request for the form 0 for the | ||
427 | * point at infinity even if it is valid. | ||
428 | */ | ||
429 | if (form <= 0 || form > UINT8_MAX) | ||
430 | return 0; | ||
431 | if (!ec_conversion_form_is_valid(form)) | ||
432 | return 0; | ||
433 | |||
434 | *out_form = form; | ||
435 | if (EC_POINT_is_at_infinity(group, point)) | ||
436 | *out_form = EC_OCT_POINT_AT_INFINITY; | ||
437 | |||
438 | return 1; | ||
439 | } | ||
440 | |||
437 | size_t | 441 | size_t |
438 | EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, | 442 | EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, |
439 | point_conversion_form_t form, unsigned char *buf, size_t len, | 443 | point_conversion_form_t conv_form, unsigned char *buf, size_t len, |
440 | BN_CTX *ctx_in) | 444 | BN_CTX *ctx_in) |
441 | { | 445 | { |
442 | BN_CTX *ctx; | 446 | BN_CTX *ctx = NULL; |
447 | uint8_t form; | ||
443 | size_t ret = 0; | 448 | size_t ret = 0; |
444 | 449 | ||
450 | if (!ec_normalize_form(group, point, conv_form, &form)) { | ||
451 | ECerror(EC_R_INVALID_FORM); | ||
452 | goto err; | ||
453 | } | ||
454 | |||
445 | if ((ctx = ctx_in) == NULL) | 455 | if ((ctx = ctx_in) == NULL) |
446 | ctx = BN_CTX_new(); | 456 | ctx = BN_CTX_new(); |
447 | if (ctx == NULL) | 457 | if (ctx == NULL) |