xref: /openbsd/lib/libcrypto/ec/ec_local.h (revision 5cae5e37)
1 /* $OpenBSD: ec_local.h,v 1.36 2024/11/01 05:10:40 tb Exp $ */
2 /*
3  * Originally written by Bodo Moeller for the OpenSSL project.
4  */
5 /* ====================================================================
6  * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    openssl-core@openssl.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 /* ====================================================================
59  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60  *
61  * Portions of the attached software ("Contribution") are developed by
62  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63  *
64  * The Contribution is licensed pursuant to the OpenSSL open source
65  * license provided above.
66  *
67  * The elliptic curve binary polynomial software is originally written by
68  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69  *
70  */
71 
72 #include <stdlib.h>
73 
74 #include <openssl/bn.h>
75 #include <openssl/ec.h>
76 #include <openssl/objects.h>
77 
78 #include "bn_local.h"
79 
80 __BEGIN_HIDDEN_DECLS
81 
82 #if defined(__SUNPRO_C)
83 # if __SUNPRO_C >= 0x520
84 # pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
85 # endif
86 #endif
87 
88 struct ec_method_st {
89 	int field_type;
90 
91 	int (*group_init)(EC_GROUP *);
92 	void (*group_finish)(EC_GROUP *);
93 	int (*group_copy)(EC_GROUP *, const EC_GROUP *);
94 
95 	int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
96 	    const BIGNUM *b, BN_CTX *);
97 	int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
98 	    BIGNUM *b, BN_CTX *);
99 
100 	int (*group_get_degree)(const EC_GROUP *);
101 	int (*group_order_bits)(const EC_GROUP *);
102 	int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
103 
104 	int (*point_init)(EC_POINT *);
105 	void (*point_finish)(EC_POINT *);
106 	int (*point_copy)(EC_POINT *, const EC_POINT *);
107 
108 	int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
109 	int (*point_set_Jprojective_coordinates)(const EC_GROUP *, EC_POINT *,
110 	    const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
111 	int (*point_get_Jprojective_coordinates)(const EC_GROUP *,
112 	    const EC_POINT *, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
113 	int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
114 	    const BIGNUM *x, const BIGNUM *y, BN_CTX *);
115 	int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
116 	    BIGNUM *x, BIGNUM *y, BN_CTX *);
117 	int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
118 	    const BIGNUM *x, int y_bit, BN_CTX *);
119 
120 	int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
121 	    const EC_POINT *b, BN_CTX *);
122 	int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
123 	int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
124 
125 	int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
126 	int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
127 	int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
128 	    BN_CTX *);
129 
130 	int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
131 	int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[],
132 	    BN_CTX *);
133 
134 	int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r,
135 	    const BIGNUM *scalar, BN_CTX *);
136 	int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r,
137 	    const BIGNUM *scalar, const EC_POINT *point, BN_CTX *);
138 	int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r,
139 	    const BIGNUM *g_scalar, const BIGNUM *p_scalar,
140 	    const EC_POINT *point, BN_CTX *);
141 
142 	/*
143 	 * Internal methods.
144 	 */
145 
146 	/*
147 	 * These can be used by 'add' and 'dbl' so that the same implementations
148 	 * of point operations can be used with different optimized versions of
149 	 * expensive field operations.
150 	 */
151 	int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
152 	    const BIGNUM *b, BN_CTX *);
153 	int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
154 	    BN_CTX *);
155 
156 	/* Encode to and decode from other forms (e.g. Montgomery). */
157 	int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
158 	    BN_CTX *);
159 	int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
160 	    BN_CTX *);
161 
162 	int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
163 	int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p,
164 	    BN_CTX *ctx);
165 } /* EC_METHOD */;
166 
167 struct ec_group_st {
168 	/*
169 	 * Methods and members exposed via the public API.
170 	 */
171 
172 	const EC_METHOD *meth;
173 
174 	EC_POINT *generator;	/* Optional */
175 	BIGNUM order;
176 	BIGNUM cofactor;
177 
178 	int curve_name;		/* Optional NID for named curve. */
179 
180 	/* ASN.1 encoding controls. */
181 	int asn1_flag;
182 	point_conversion_form_t asn1_form;
183 
184 	/* Optional seed for parameters (appears in ASN.1). */
185 	unsigned char *seed;
186 	size_t seed_len;
187 
188 	/*
189 	 * Internal methods and members. Handled by the method functions, even
190 	 * if they appear to be generic.
191 	 */
192 
193 	/*
194 	 * Field specification. For GF(p) this is the modulus; for GF(2^m),
195 	 * this is the irreducible polynomial defining the field.
196 	 */
197 	BIGNUM field;
198 
199 	/*
200 	 * Curve coefficients. In characteristic > 3, the curve is defined by a
201 	 * Weierstrass equation of the form y^2 = x^3 + a*x + b.
202 	 */
203 	BIGNUM a, b;
204 
205 	/* Enables optimized point arithmetics for special case. */
206 	int a_is_minus3;
207 
208 	/* Montgomery context and values used by EC_GFp_mont_method. */
209 	BN_MONT_CTX *mont_ctx;
210 	BIGNUM *mont_one;
211 } /* EC_GROUP */;
212 
213 struct ec_key_st {
214 	const EC_KEY_METHOD *meth;
215 
216 	int version;
217 
218 	EC_GROUP *group;
219 
220 	EC_POINT *pub_key;
221 	BIGNUM	 *priv_key;
222 
223 	unsigned int enc_flag;
224 	point_conversion_form_t conv_form;
225 
226 	int	references;
227 	int	flags;
228 
229 	CRYPTO_EX_DATA ex_data;
230 } /* EC_KEY */;
231 
232 struct ec_point_st {
233 	const EC_METHOD *meth;
234 
235 	/*
236 	 * All members except 'meth' are handled by the method functions,
237 	 * even if they appear generic.
238 	 */
239 
240 	/*
241 	 * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3)
242 	 * if Z != 0
243 	 */
244 	BIGNUM X;
245 	BIGNUM Y;
246 	BIGNUM Z;
247 	int Z_is_one; /* enable optimized point arithmetics for special case */
248 } /* EC_POINT */;
249 
250 /* method functions in ec_mult.c
251  * (ec_lib.c uses these as defaults if group->method->mul is 0) */
252 int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
253 	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
254 
255 /* method functions in ecp_smpl.c */
256 int ec_GFp_simple_group_init(EC_GROUP *);
257 void ec_GFp_simple_group_finish(EC_GROUP *);
258 int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
259 int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
260 int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
261 int ec_GFp_simple_group_get_degree(const EC_GROUP *);
262 int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
263 int ec_GFp_simple_point_init(EC_POINT *);
264 void ec_GFp_simple_point_finish(EC_POINT *);
265 int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
266 int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
267 int ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *, EC_POINT *,
268     const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
269 int ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *,
270     const EC_POINT *, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
271 int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
272 	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
273 int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
274 	BIGNUM *x, BIGNUM *y, BN_CTX *);
275 int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
276 	const BIGNUM *x, int y_bit, BN_CTX *);
277 int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
278 int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
279 int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
280 int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
281 int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
282 int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
283 int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
284 int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
285 int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
286 int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
287 int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
288 int ec_GFp_simple_mul_generator_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar, BN_CTX *);
289 int ec_GFp_simple_mul_single_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *scalar,
290 	const EC_POINT *point, BN_CTX *);
291 int ec_GFp_simple_mul_double_nonct(const EC_GROUP *, EC_POINT *r, const BIGNUM *g_scalar,
292 	const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *);
293 
294 int ec_group_simple_order_bits(const EC_GROUP *group);
295 int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
296 
297 /* EC_METHOD definitions */
298 
299 struct ec_key_method_st {
300 	const char *name;
301 	int32_t flags;
302 	int (*init)(EC_KEY *key);
303 	void (*finish)(EC_KEY *key);
304 	int (*copy)(EC_KEY *dest, const EC_KEY *src);
305 	int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
306 	int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
307 	int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
308 	int (*keygen)(EC_KEY *key);
309 	int (*compute_key)(unsigned char **out, size_t *out_len,
310 	    const EC_POINT *pub_key, const EC_KEY *ecdh);
311 	int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
312 	    *sig, unsigned int *siglen, const BIGNUM *kinv,
313 	    const BIGNUM *r, EC_KEY *eckey);
314 	int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
315 	    BIGNUM **rp);
316 	ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
317 	    const BIGNUM *in_kinv, const BIGNUM *in_r,
318 	    EC_KEY *eckey);
319 	int (*verify)(int type, const unsigned char *dgst, int dgst_len,
320 	    const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
321 	int (*verify_sig)(const unsigned char *dgst, int dgst_len,
322 	    const ECDSA_SIG *sig, EC_KEY *eckey);
323 } /* EC_KEY_METHOD */;
324 
325 #define EC_KEY_METHOD_DYNAMIC   1
326 
327 int eckey_compute_pubkey(EC_KEY *eckey);
328 int ec_key_gen(EC_KEY *eckey);
329 int ecdh_compute_key(unsigned char **out, size_t *out_len,
330     const EC_POINT *pub_key, const EC_KEY *ecdh);
331 int ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
332     const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
333 int ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
334     const ECDSA_SIG *sig, EC_KEY *eckey);
335 
336 /*
337  * ECDH Key Derivation Function as defined in ANSI X9.63.
338  */
339 int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z,
340     size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md);
341 
342 int EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *p,
343     const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
344 int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group,
345     const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
346 
347 int ec_group_is_builtin_curve(const EC_GROUP *group);
348 int ec_group_get_field_type(const EC_GROUP *group);
349 
350 /*
351  * Wrappers around the unergonomic EC_POINT_{oct2point,point2oct}().
352  */
353 int ec_point_from_octets(const EC_GROUP *group, const unsigned char *buf,
354     size_t buf_len, EC_POINT **out_point, uint8_t *out_form, BN_CTX *ctx_in);
355 int ec_point_to_octets(const EC_GROUP *group, const EC_POINT *point, int form,
356     unsigned char **out_buf, size_t *len, BN_CTX *ctx_in);
357 
358 /* Public API in OpenSSL */
359 const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group);
360 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);
361 
362 __END_HIDDEN_DECLS
363