summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/ec/ecp_oct.c46
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
204static int
205ec_oct_conversion_form_is_valid(uint8_t form)
206{
207 return (form & EC_OCT_POINT_CONVERSION_MASK) == form;
208}
209
185size_t 210size_t
186ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, 211ec_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 }