diff options
-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 | } |