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) |
