diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/ec/ecp_oct.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c index 133704bd7f..9646e44499 100644 --- a/src/lib/libcrypto/ec/ecp_oct.c +++ b/src/lib/libcrypto/ec/ecp_oct.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ecp_oct.c,v 1.22 2024/10/22 12:09:57 tb Exp $ */ | 1 | /* $OpenBSD: ecp_oct.c,v 1.23 2024/10/22 21:06:16 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. |
| @@ -63,6 +63,7 @@ | |||
| 63 | */ | 63 | */ |
| 64 | 64 | ||
| 65 | #include <stddef.h> | 65 | #include <stddef.h> |
| 66 | #include <stdint.h> | ||
| 66 | 67 | ||
| 67 | #include <openssl/bn.h> | 68 | #include <openssl/bn.h> |
| 68 | #include <openssl/ec.h> | 69 | #include <openssl/ec.h> |
| @@ -182,17 +183,52 @@ ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, | |||
| 182 | return ret; | 183 | return ret; |
| 183 | } | 184 | } |
| 184 | 185 | ||
| 186 | /* | ||
| 187 | * Only the last three bits of the leading octet of a point should be set. | ||
| 188 | * Bits 3 and 2 encode the conversion form for all points except the point | ||
| 189 | * at infinity. In compressed and hybrid form bit 1 indicates if the even | ||
| 190 | * or the odd solution of the quadratic equation for y should be used. | ||
| 191 | * | ||
| 192 | * The public point_conversion_t enum lacks the point at infinity, so we | ||
| 193 | * ignore it except at the API boundary. | ||
| 194 | */ | ||
| 195 | |||
| 196 | #define EC_OCT_YBIT 0x01 | ||
| 197 | |||
| 198 | #define EC_OCT_POINT_AT_INFINITY 0x00 | ||
| 199 | #define EC_OCT_POINT_COMPRESSED 0x02 | ||
| 200 | #define EC_OCT_POINT_UNCOMPRESSED 0x04 | ||
| 201 | #define EC_OCT_POINT_HYBRID 0x06 | ||
| 202 | #define EC_OCT_POINT_CONVERSION_MASK 0x06 | ||
| 203 | |||
| 204 | static int | ||
| 205 | ec_oct_conversion_form_is_valid(uint8_t form) | ||
| 206 | { | ||
| 207 | return (form & EC_OCT_POINT_CONVERSION_MASK) == form; | ||
| 208 | } | ||
| 209 | |||
| 185 | size_t | 210 | size_t |
| 186 | ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, | 211 | ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, |
| 187 | point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx) | 212 | point_conversion_form_t conversion_form, unsigned char *buf, size_t len, |
| 213 | BN_CTX *ctx) | ||
| 188 | { | 214 | { |
| 215 | uint8_t form; | ||
| 189 | BIGNUM *x, *y; | 216 | BIGNUM *x, *y; |
| 190 | size_t field_len, i, skip; | 217 | size_t field_len, i, skip; |
| 191 | size_t ret = 0; | 218 | size_t ret = 0; |
| 192 | 219 | ||
| 193 | if (form != POINT_CONVERSION_COMPRESSED && | 220 | if (conversion_form > UINT8_MAX) { |
| 194 | form != POINT_CONVERSION_UNCOMPRESSED && | 221 | ECerror(EC_R_INVALID_FORM); |
| 195 | form != POINT_CONVERSION_HYBRID) { | 222 | return 0; |
| 223 | } | ||
| 224 | |||
| 225 | form = conversion_form; | ||
| 226 | |||
| 227 | /* | ||
| 228 | * Established behavior is to reject a request for the form 0 for the | ||
| 229 | * point at infinity even if it is valid. | ||
| 230 | */ | ||
| 231 | if (form == 0 || !ec_oct_conversion_form_is_valid(form)) { | ||
| 196 | ECerror(EC_R_INVALID_FORM); | 232 | ECerror(EC_R_INVALID_FORM); |
| 197 | return 0; | 233 | return 0; |
| 198 | } | 234 | } |
