summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libcrypto/ec
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r--src/lib/libcrypto/ec/ec.h675
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c1065
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c1461
-rw-r--r--src/lib/libcrypto/ec/ec_convert.c575
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c1765
-rw-r--r--src/lib/libcrypto/ec/ec_err.c151
-rw-r--r--src/lib/libcrypto/ec/ec_key.c809
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c1369
-rw-r--r--src/lib/libcrypto/ec/ec_local.h254
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c407
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c545
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c357
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c1327
-rw-r--r--src/lib/libcrypto/ec/ecx_methods.c973
14 files changed, 0 insertions, 11733 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
deleted file mode 100644
index 5438dd8013..0000000000
--- a/src/lib/libcrypto/ec/ec.h
+++ /dev/null
@@ -1,675 +0,0 @@
1/* $OpenBSD: ec.h,v 1.55 2025/03/10 08:38:11 tb Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 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#ifndef HEADER_EC_H
72#define HEADER_EC_H
73
74#include <openssl/opensslconf.h>
75
76#include <openssl/asn1.h>
77#include <openssl/bn.h>
78
79#ifdef __cplusplus
80extern "C" {
81#endif
82
83#ifndef OPENSSL_ECC_MAX_FIELD_BITS
84#define OPENSSL_ECC_MAX_FIELD_BITS 661
85#endif
86
87/* Elliptic point conversion form as per X9.62, page 4 and section 4.4.2. */
88typedef enum {
89 POINT_CONVERSION_COMPRESSED = 2,
90 POINT_CONVERSION_UNCOMPRESSED = 4,
91 POINT_CONVERSION_HYBRID = 6
92} point_conversion_form_t;
93
94typedef struct ec_group_st EC_GROUP;
95typedef struct ec_point_st EC_POINT;
96
97void EC_GROUP_free(EC_GROUP *group);
98void EC_GROUP_clear_free(EC_GROUP *group);
99
100EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
101
102int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
103 const BIGNUM *order, const BIGNUM *cofactor);
104const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
105
106int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
107int EC_GROUP_order_bits(const EC_GROUP *group);
108int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
109
110void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
111int EC_GROUP_get_curve_name(const EC_GROUP *group);
112
113void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
114int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
115
116void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
117 point_conversion_form_t form);
118point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
119
120unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
121size_t EC_GROUP_get_seed_len(const EC_GROUP *);
122size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
123
124int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
125 const BIGNUM *b, BN_CTX *ctx);
126int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
127 BN_CTX *ctx);
128
129int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
130 const BIGNUM *b, BN_CTX *ctx);
131int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
132 BIGNUM *b, BN_CTX *ctx);
133
134int EC_GROUP_get_degree(const EC_GROUP *group);
135
136int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
137int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
138
139/* Compare two EC_GROUPs. Returns 0 if both groups are equal, 1 otherwise. */
140int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
141
142EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
143 const BIGNUM *b, BN_CTX *ctx);
144EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
145
146typedef struct {
147 int nid;
148 const char *comment;
149} EC_builtin_curve;
150
151size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
152
153const char *EC_curve_nid2nist(int nid);
154int EC_curve_nist2nid(const char *name);
155
156EC_POINT *EC_POINT_new(const EC_GROUP *group);
157void EC_POINT_free(EC_POINT *point);
158void EC_POINT_clear_free(EC_POINT *point);
159int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
160EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
161
162int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
163
164int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p,
165 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
166int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p,
167 BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
168int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p,
169 const BIGNUM *x, int y_bit, BN_CTX *ctx);
170
171int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
172 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
173int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
174 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
175int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
176 const BIGNUM *x, int y_bit, BN_CTX *ctx);
177size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
178 point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx);
179int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
180 const unsigned char *buf, size_t len, BN_CTX *ctx);
181
182BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
183 point_conversion_form_t form, BIGNUM *, BN_CTX *);
184EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, EC_POINT *,
185 BN_CTX *);
186char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
187 point_conversion_form_t form, BN_CTX *);
188EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, EC_POINT *,
189 BN_CTX *);
190
191int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
192 const EC_POINT *b, BN_CTX *ctx);
193int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
194 BN_CTX *ctx);
195int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
196int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
197int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
198 BN_CTX *ctx);
199int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
200 BN_CTX *ctx);
201
202int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
203int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
204 const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
205
206int EC_GROUP_get_basis_type(const EC_GROUP *);
207
208#define OPENSSL_EC_EXPLICIT_CURVE 0x000
209#define OPENSSL_EC_NAMED_CURVE 0x001
210
211EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
212int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
213
214#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
215#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
216#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
217 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
218#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
219 (unsigned char *)(x))
220
221#ifndef OPENSSL_NO_BIO
222int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
223#endif
224int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
225
226#define EC_PKEY_NO_PARAMETERS 0x001
227#define EC_PKEY_NO_PUBKEY 0x002
228
229#define EC_FLAG_NON_FIPS_ALLOW 0x1
230#define EC_FLAG_FIPS_CHECKED 0x2
231#define EC_FLAG_COFACTOR_ECDH 0x1000
232
233EC_KEY *EC_KEY_new(void);
234int EC_KEY_get_flags(const EC_KEY *key);
235void EC_KEY_set_flags(EC_KEY *key, int flags);
236void EC_KEY_clear_flags(EC_KEY *key, int flags);
237EC_KEY *EC_KEY_new_by_curve_name(int nid);
238void EC_KEY_free(EC_KEY *key);
239EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
240EC_KEY *EC_KEY_dup(const EC_KEY *src);
241int EC_KEY_up_ref(EC_KEY *key);
242
243const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
244int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
245const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
246int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
247const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
248int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
249
250unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
251void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
252point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
253void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
254
255void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
256int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
257int EC_KEY_generate_key(EC_KEY *key);
258int EC_KEY_check_key(const EC_KEY *key);
259int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
260
261EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
262int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
263EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
264int i2d_ECParameters(EC_KEY *key, unsigned char **out);
265
266EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
267int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out);
268
269#ifndef OPENSSL_NO_BIO
270int ECParameters_print(BIO *bp, const EC_KEY *key);
271int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
272#endif
273int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
274int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
275
276#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \
277 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef)
278int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg);
279void *EC_KEY_get_ex_data(const EC_KEY *key, int idx);
280
281const EC_KEY_METHOD *EC_KEY_OpenSSL(void);
282const EC_KEY_METHOD *EC_KEY_get_default_method(void);
283void EC_KEY_set_default_method(const EC_KEY_METHOD *meth);
284const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key);
285int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth);
286EC_KEY *EC_KEY_new_method(ENGINE *engine);
287
288int ECDH_size(const EC_KEY *ecdh);
289int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
290 EC_KEY *ecdh,
291 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
292
293typedef struct ECDSA_SIG_st ECDSA_SIG;
294
295ECDSA_SIG *ECDSA_SIG_new(void);
296void ECDSA_SIG_free(ECDSA_SIG *sig);
297int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
298ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
299
300const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig);
301const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig);
302void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
303int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
304
305int ECDSA_size(const EC_KEY *eckey);
306
307ECDSA_SIG *ECDSA_do_sign(const unsigned char *digest, int digest_len,
308 EC_KEY *eckey);
309int ECDSA_do_verify(const unsigned char *digest, int digest_len,
310 const ECDSA_SIG *sig, EC_KEY *eckey);
311
312int ECDSA_sign(int type, const unsigned char *digest, int digest_len,
313 unsigned char *signature, unsigned int *signature_len, EC_KEY *eckey);
314int ECDSA_verify(int type, const unsigned char *digest, int digest_len,
315 const unsigned char *signature, int signature_len, EC_KEY *eckey);
316
317EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth);
318void EC_KEY_METHOD_free(EC_KEY_METHOD *meth);
319void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
320 int (*init)(EC_KEY *key),
321 void (*finish)(EC_KEY *key),
322 int (*copy)(EC_KEY *dest, const EC_KEY *src),
323 int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
324 int (*set_private)(EC_KEY *key, const BIGNUM *priv_key),
325 int (*set_public)(EC_KEY *key, const EC_POINT *pub_key));
326void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
327 int (*keygen)(EC_KEY *key));
328void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
329 int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key,
330 const EC_KEY *ecdh));
331void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
332 int (*sign)(int type, const unsigned char *digest, int digest_len,
333 unsigned char *signature, unsigned int *signature_len,
334 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
335 int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp),
336 ECDSA_SIG *(*sign_sig)(const unsigned char *digest, int digest_len,
337 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey));
338void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
339 int (*verify)(int type, const unsigned char *digest, int digest_len,
340 const unsigned char *signature, int signature_len, EC_KEY *eckey),
341 int (*verify_sig)(const unsigned char *digest, int digest_len,
342 const ECDSA_SIG *sig, EC_KEY *eckey));
343void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth,
344 int (**pinit)(EC_KEY *key),
345 void (**pfinish)(EC_KEY *key),
346 int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
347 int (**pset_group)(EC_KEY *key, const EC_GROUP *grp),
348 int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key),
349 int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key));
350void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
351 int (**pkeygen)(EC_KEY *key));
352void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth,
353 int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key,
354 const EC_KEY *ecdh));
355void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth,
356 int (**psign)(int type, const unsigned char *digest, int digest_len,
357 unsigned char *signature, unsigned int *signature_len,
358 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
359 int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp),
360 ECDSA_SIG *(**psign_sig)(const unsigned char *digest, int digest_len,
361 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey));
362void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
363 int (**pverify)(int type, const unsigned char *digest, int digest_len,
364 const unsigned char *signature, int signature_len, EC_KEY *eckey),
365 int (**pverify_sig)(const unsigned char *digest, int digest_len,
366 const ECDSA_SIG *sig, EC_KEY *eckey));
367
368EC_KEY *ECParameters_dup(EC_KEY *key);
369
370#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
371 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
372 EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
373 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
374
375#define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
376 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
377 EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
378 EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL)
379
380#define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \
381 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
382 EVP_PKEY_OP_DERIVE, \
383 EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL)
384
385#define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \
386 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
387 EVP_PKEY_OP_DERIVE, \
388 EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL)
389
390#define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \
391 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
392 EVP_PKEY_OP_DERIVE, \
393 EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL)
394
395#define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \
396 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
397 EVP_PKEY_OP_DERIVE, \
398 EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL)
399
400#define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \
401 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
402 EVP_PKEY_OP_DERIVE, \
403 EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md))
404
405#define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \
406 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
407 EVP_PKEY_OP_DERIVE, \
408 EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd))
409
410#define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \
411 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
412 EVP_PKEY_OP_DERIVE, \
413 EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL)
414
415#define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \
416 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
417 EVP_PKEY_OP_DERIVE, \
418 EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \
419 (void *)(plen))
420
421#define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \
422 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
423 EVP_PKEY_OP_DERIVE, \
424 EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p))
425
426#define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \
427 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
428 EVP_PKEY_OP_DERIVE, \
429 EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p))
430
431/* SM2 will skip the operation check so no need to pass operation here */
432#define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \
433 EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
434 EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id))
435
436#define EVP_PKEY_CTX_get1_id(ctx, id) \
437 EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
438 EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id))
439
440#define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \
441 EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
442 EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len))
443
444#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
445#define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2)
446#define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3)
447#define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4)
448#define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5)
449#define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6)
450#define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7)
451#define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8)
452#define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9)
453#define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10)
454#define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11)
455#define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12)
456#define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13)
457
458/* KDF types */
459#define EVP_PKEY_ECDH_KDF_NONE 1
460#define EVP_PKEY_ECDH_KDF_X9_63 2
461
462void ERR_load_EC_strings(void);
463
464/* Error codes for the EC functions. */
465
466/* Function codes. */
467#define EC_F_BN_TO_FELEM 224
468#define EC_F_COMPUTE_WNAF 143
469#define EC_F_D2I_ECPARAMETERS 144
470#define EC_F_D2I_ECPKPARAMETERS 145
471#define EC_F_D2I_ECPRIVATEKEY 146
472#define EC_F_DO_EC_KEY_PRINT 221
473#define EC_F_ECKEY_PARAM2TYPE 223
474#define EC_F_ECKEY_PARAM_DECODE 212
475#define EC_F_ECKEY_PRIV_DECODE 213
476#define EC_F_ECKEY_PRIV_ENCODE 214
477#define EC_F_ECKEY_PUB_DECODE 215
478#define EC_F_ECKEY_PUB_ENCODE 216
479#define EC_F_ECKEY_TYPE2PARAM 220
480#define EC_F_ECPARAMETERS_PRINT 147
481#define EC_F_ECPARAMETERS_PRINT_FP 148
482#define EC_F_ECPKPARAMETERS_PRINT 149
483#define EC_F_ECPKPARAMETERS_PRINT_FP 150
484#define EC_F_ECP_NIST_MOD_192 203
485#define EC_F_ECP_NIST_MOD_224 204
486#define EC_F_ECP_NIST_MOD_256 205
487#define EC_F_ECP_NIST_MOD_521 206
488#define EC_F_ECP_NISTZ256_GET_AFFINE 240
489#define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243
490#define EC_F_ECP_NISTZ256_POINTS_MUL 241
491#define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244
492#define EC_F_ECP_NISTZ256_SET_WORDS 245
493#define EC_F_ECP_NISTZ256_WINDOWED_MUL 242
494#define EC_F_EC_ASN1_GROUP2CURVE 153
495#define EC_F_EC_ASN1_GROUP2FIELDID 154
496#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
497#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
498#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
499#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
500#define EC_F_EC_EX_DATA_SET_DATA 211
501#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
502#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
503#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
504#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
505#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
506#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
507#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
508#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
509#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
510#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
511#define EC_F_EC_GFP_MONT_FIELD_MUL 131
512#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209
513#define EC_F_EC_GFP_MONT_FIELD_SQR 132
514#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
515#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
516#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225
517#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228
518#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
519#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230
520#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231
521#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
522#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233
523#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234
524#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
525#define EC_F_EC_GFP_NIST_FIELD_MUL 200
526#define EC_F_EC_GFP_NIST_FIELD_SQR 201
527#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
528#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
529#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
530#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
531#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
532#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
533#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
534#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
535#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
536#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
537#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
538#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
539#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
540#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
541#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
542#define EC_F_EC_GROUP_CHECK 170
543#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
544#define EC_F_EC_GROUP_COPY 106
545#define EC_F_EC_GROUP_GET0_GENERATOR 139
546#define EC_F_EC_GROUP_GET_COFACTOR 140
547#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
548#define EC_F_EC_GROUP_GET_CURVE_GFP 130
549#define EC_F_EC_GROUP_GET_DEGREE 173
550#define EC_F_EC_GROUP_GET_ORDER 141
551#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
552#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
553#define EC_F_EC_GROUP_NEW 108
554#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174
555#define EC_F_EC_GROUP_NEW_FROM_DATA 175
556#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
557#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
558#define EC_F_EC_GROUP_SET_CURVE_GFP 109
559#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
560#define EC_F_EC_GROUP_SET_GENERATOR 111
561#define EC_F_EC_KEY_CHECK_KEY 177
562#define EC_F_EC_KEY_COPY 178
563#define EC_F_EC_KEY_GENERATE_KEY 179
564#define EC_F_EC_KEY_NEW 182
565#define EC_F_EC_KEY_PRINT 180
566#define EC_F_EC_KEY_PRINT_FP 181
567#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229
568#define EC_F_EC_POINTS_MAKE_AFFINE 136
569#define EC_F_EC_POINT_ADD 112
570#define EC_F_EC_POINT_CMP 113
571#define EC_F_EC_POINT_COPY 114
572#define EC_F_EC_POINT_DBL 115
573#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
574#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
575#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
576#define EC_F_EC_POINT_INVERT 210
577#define EC_F_EC_POINT_IS_AT_INFINITY 118
578#define EC_F_EC_POINT_IS_ON_CURVE 119
579#define EC_F_EC_POINT_MAKE_AFFINE 120
580#define EC_F_EC_POINT_MUL 184
581#define EC_F_EC_POINT_NEW 121
582#define EC_F_EC_POINT_OCT2POINT 122
583#define EC_F_EC_POINT_POINT2OCT 123
584#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
585#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
586#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
587#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
588#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
589#define EC_F_EC_POINT_SET_TO_INFINITY 127
590#define EC_F_EC_PRE_COMP_DUP 207
591#define EC_F_EC_PRE_COMP_NEW 196
592#define EC_F_EC_WNAF_MUL 187
593#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
594#define EC_F_I2D_ECPARAMETERS 190
595#define EC_F_I2D_ECPKPARAMETERS 191
596#define EC_F_I2D_ECPRIVATEKEY 192
597#define EC_F_I2O_ECPUBLICKEY 151
598#define EC_F_NISTP224_PRE_COMP_NEW 227
599#define EC_F_NISTP256_PRE_COMP_NEW 236
600#define EC_F_NISTP521_PRE_COMP_NEW 237
601#define EC_F_O2I_ECPUBLICKEY 152
602#define EC_F_OLD_EC_PRIV_DECODE 222
603#define EC_F_PKEY_EC_CTRL 197
604#define EC_F_PKEY_EC_CTRL_STR 198
605#define EC_F_PKEY_EC_DERIVE 217
606#define EC_F_PKEY_EC_KEYGEN 199
607#define EC_F_PKEY_EC_PARAMGEN 219
608#define EC_F_PKEY_EC_SIGN 218
609
610/* Reason codes. */
611#define EC_R_ASN1_ERROR 115
612#define EC_R_ASN1_UNKNOWN_FIELD 116
613#define EC_R_BAD_SIGNATURE 166
614#define EC_R_BIGNUM_OUT_OF_RANGE 144
615#define EC_R_BUFFER_TOO_SMALL 100
616#define EC_R_COORDINATES_OUT_OF_RANGE 146
617#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
618#define EC_R_DECODE_ERROR 142
619#define EC_R_DISCRIMINANT_IS_ZERO 118
620#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
621#define EC_R_FIELD_TOO_LARGE 143
622#define EC_R_GF2M_NOT_SUPPORTED 147
623#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
624#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
625#define EC_R_INCOMPATIBLE_OBJECTS 101
626#define EC_R_INVALID_ARGUMENT 112
627#define EC_R_INVALID_COMPRESSED_POINT 110
628#define EC_R_INVALID_COMPRESSION_BIT 109
629#define EC_R_INVALID_CURVE 141
630#define EC_R_INVALID_DIGEST 151
631#define EC_R_INVALID_DIGEST_TYPE 138
632#define EC_R_INVALID_ENCODING 102
633#define EC_R_INVALID_FIELD 103
634#define EC_R_INVALID_FORM 104
635#define EC_R_INVALID_GROUP_ORDER 122
636#define EC_R_INVALID_KEY 165
637#define EC_R_INVALID_OUTPUT_LENGTH 171
638#define EC_R_INVALID_PEER_KEY 152
639#define EC_R_INVALID_PENTANOMIAL_BASIS 132
640#define EC_R_INVALID_PRIVATE_KEY 123
641#define EC_R_INVALID_TRINOMIAL_BASIS 137
642#define EC_R_KDF_FAILED 167
643#define EC_R_KDF_PARAMETER_ERROR 148
644#define EC_R_KEY_TRUNCATION 168
645#define EC_R_KEYS_NOT_SET 140
646#define EC_R_MISSING_PARAMETERS 124
647#define EC_R_MISSING_PRIVATE_KEY 125
648#define EC_R_NEED_NEW_SETUP_VALUES 170
649#define EC_R_NOT_A_NIST_PRIME 135
650#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
651#define EC_R_NOT_IMPLEMENTED 126
652#define EC_R_NOT_INITIALIZED 111
653#define EC_R_NO_FIELD_MOD 133
654#define EC_R_NO_PARAMETERS_SET 139
655#define EC_R_PASSED_NULL_PARAMETER 134
656#define EC_R_PEER_KEY_ERROR 149
657#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
658#define EC_R_POINT_AT_INFINITY 106
659#define EC_R_POINT_ARITHMETIC_FAILURE 169
660#define EC_R_POINT_IS_NOT_ON_CURVE 107
661#define EC_R_SHARED_INFO_ERROR 150
662#define EC_R_SLOT_FULL 108
663#define EC_R_UNDEFINED_GENERATOR 113
664#define EC_R_UNDEFINED_ORDER 128
665#define EC_R_UNKNOWN_COFACTOR 164
666#define EC_R_UNKNOWN_GROUP 129
667#define EC_R_UNKNOWN_ORDER 114
668#define EC_R_UNSUPPORTED_FIELD 131
669#define EC_R_WRONG_CURVE_PARAMETERS 145
670#define EC_R_WRONG_ORDER 130
671
672#ifdef __cplusplus
673}
674#endif
675#endif
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
deleted file mode 100644
index 903b18a8db..0000000000
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ /dev/null
@@ -1,1065 +0,0 @@
1/* $OpenBSD: ec_ameth.c,v 1.73 2024/11/25 06:51:39 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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 * licensing@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#include <stddef.h>
60#include <stdlib.h>
61
62#include <openssl/opensslconf.h>
63
64#include <openssl/asn1.h>
65#include <openssl/bio.h>
66#include <openssl/bn.h>
67#include <openssl/cms.h>
68#include <openssl/ec.h>
69#include <openssl/err.h>
70#include <openssl/evp.h>
71#include <openssl/pkcs7.h>
72#include <openssl/objects.h>
73#include <openssl/x509.h>
74
75#include "asn1_local.h"
76#include "bn_local.h"
77#include "evp_local.h"
78#include "x509_local.h"
79
80#ifndef OPENSSL_NO_CMS
81static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
82static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
83#endif
84
85static void
86eckey_param_free(int ptype, void *pval)
87{
88 if (pval == NULL)
89 return;
90 if (ptype == V_ASN1_OBJECT)
91 ASN1_OBJECT_free(pval); /* XXX - really necessary? */
92 else
93 ASN1_STRING_free(pval);
94}
95
96static int
97eckey_get_curve_name(const EC_KEY *eckey, int *nid)
98{
99 const EC_GROUP *group;
100
101 *nid = NID_undef;
102
103 if ((group = EC_KEY_get0_group(eckey)) == NULL) {
104 ECerror(EC_R_MISSING_PARAMETERS);
105 return 0;
106 }
107 if ((EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) != 0)
108 *nid = EC_GROUP_get_curve_name(group);
109
110 return 1;
111}
112
113static int
114eckey_to_explicit_params(EC_KEY *eckey, void **out_val)
115{
116 ASN1_STRING *astr = NULL;
117 unsigned char *params = NULL;
118 int params_len = 0;
119 int ret = 0;
120
121 *out_val = NULL;
122
123 if ((params_len = i2d_ECParameters(eckey, &params)) <= 0) {
124 ECerror(ERR_R_EC_LIB);
125 params_len = 0;
126 goto err;
127 }
128
129 if ((astr = ASN1_STRING_new()) == NULL)
130 goto err;
131 ASN1_STRING_set0(astr, params, params_len);
132 params = NULL;
133 params_len = 0;
134
135 *out_val = astr;
136 astr = NULL;
137
138 ret = 1;
139
140 err:
141 freezero(params, params_len);
142 ASN1_STRING_free(astr);
143
144 return ret;
145}
146
147static int
148eckey_from_explicit_params(const ASN1_STRING *astr, EC_KEY **out_eckey)
149{
150 const unsigned char *params = astr->data;
151 int params_len = astr->length;
152
153 EC_KEY_free(*out_eckey);
154 if ((*out_eckey = d2i_ECParameters(NULL, &params, params_len)) == NULL) {
155 ECerror(EC_R_DECODE_ERROR);
156 return 0;
157 }
158
159 return 1;
160}
161
162static int
163eckey_to_object(const EC_KEY *eckey, void **out_val)
164{
165 int nid = NID_undef;
166
167 *out_val = NULL;
168
169 if (!eckey_get_curve_name(eckey, &nid))
170 return 0;
171 if ((*out_val = OBJ_nid2obj(nid)) == NULL)
172 return 0;
173
174 return 1;
175}
176
177static int
178eckey_from_object(const ASN1_OBJECT *aobj, EC_KEY **out_eckey)
179{
180 int nid;
181
182 EC_KEY_free(*out_eckey);
183 *out_eckey = NULL;
184
185 if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
186 return 0;
187 if ((*out_eckey = EC_KEY_new_by_curve_name(nid)) == NULL)
188 return 0;
189
190 return 1;
191}
192
193static int
194eckey_to_params(EC_KEY *eckey, int *out_type, void **out_val)
195{
196 int nid;
197
198 *out_type = NID_undef;
199 *out_val = NULL;
200
201 if (!eckey_get_curve_name(eckey, &nid))
202 return 0;
203
204 if (nid == NID_undef) {
205 *out_type = V_ASN1_SEQUENCE;
206 return eckey_to_explicit_params(eckey, out_val);
207 } else {
208 *out_type = V_ASN1_OBJECT;
209 return eckey_to_object(eckey, out_val);
210 }
211}
212
213static int
214eckey_from_params(int ptype, const void *pval, EC_KEY **out_eckey)
215{
216 EC_KEY_free(*out_eckey);
217 *out_eckey = NULL;
218
219 if (ptype == V_ASN1_SEQUENCE)
220 return eckey_from_explicit_params(pval, out_eckey);
221 if (ptype == V_ASN1_OBJECT)
222 return eckey_from_object(pval, out_eckey);
223
224 ECerror(EC_R_DECODE_ERROR);
225 return 0;
226}
227
228static int
229eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
230{
231 EC_KEY *eckey = pkey->pkey.ec;
232 int ptype = V_ASN1_UNDEF;
233 void *pval = NULL;
234 ASN1_OBJECT *aobj;
235 unsigned char *key = NULL;
236 int key_len = 0;
237 int ret = 0;
238
239 if (!eckey_to_params(eckey, &ptype, &pval)) {
240 ECerror(ERR_R_EC_LIB);
241 goto err;
242 }
243 if ((key_len = i2o_ECPublicKey(eckey, &key)) <= 0) {
244 key_len = 0;
245 goto err;
246 }
247 if ((aobj = OBJ_nid2obj(EVP_PKEY_EC)) == NULL)
248 goto err;
249 if (!X509_PUBKEY_set0_param(pk, aobj, ptype, pval, key, key_len))
250 goto err;
251 pval = NULL;
252 key = NULL;
253 key_len = 0;
254
255 ret = 1;
256
257 err:
258 eckey_param_free(ptype, pval);
259 freezero(key, key_len);
260
261 return ret;
262}
263
264static int
265eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
266{
267 const unsigned char *p = NULL;
268 const void *pval;
269 int ptype, pklen;
270 EC_KEY *eckey = NULL;
271 X509_ALGOR *palg;
272 int ret = 0;
273
274 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
275 goto err;
276
277 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
278 if (!eckey_from_params(ptype, pval, &eckey))
279 goto err;
280
281 if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
282 ECerror(EC_R_DECODE_ERROR);
283 goto err;
284 }
285 if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
286 goto err;
287 eckey = NULL;
288
289 ret = 1;
290
291 err:
292 EC_KEY_free(eckey);
293
294 return ret;
295}
296
297static int
298eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
299{
300 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
301 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec);
302 const EC_POINT *pb = EC_KEY_get0_public_key(b->pkey.ec);
303 int r;
304
305 r = EC_POINT_cmp(group, pa, pb, NULL);
306 if (r == 0)
307 return 1;
308 if (r == 1)
309 return 0;
310 return -2;
311}
312
313int
314eckey_compute_pubkey(EC_KEY *eckey)
315{
316 const BIGNUM *priv_key;
317 const EC_GROUP *group;
318 EC_POINT *pub_key = NULL;
319 int ret = 0;
320
321 if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL)
322 goto err;
323 if ((group = EC_KEY_get0_group(eckey)) == NULL)
324 goto err;
325 if ((pub_key = EC_POINT_new(group)) == NULL)
326 goto err;
327 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
328 goto err;
329 if (!EC_KEY_set_public_key(eckey, pub_key))
330 goto err;
331
332 ret = 1;
333
334 err:
335 EC_POINT_free(pub_key);
336
337 return ret;
338}
339
340static int
341eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
342{
343 const unsigned char *priv = NULL;
344 int priv_len;
345 const void *pval;
346 int ptype;
347 EC_KEY *eckey = NULL;
348 const X509_ALGOR *palg;
349 int ret = 0;
350
351 if (!PKCS8_pkey_get0(NULL, &priv, &priv_len, &palg, p8))
352 goto err;
353
354 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
355 if (!eckey_from_params(ptype, pval, &eckey))
356 goto err;
357
358 /* Decode private key into eckey. */
359 if (d2i_ECPrivateKey(&eckey, &priv, priv_len) == NULL) {
360 ECerror(EC_R_DECODE_ERROR);
361 goto err;
362 }
363 /* If public key was missing from SEC1 key, compute it. */
364 if (EC_KEY_get0_public_key(eckey) == NULL) {
365 if (!eckey_compute_pubkey(eckey))
366 goto err;
367 }
368
369 if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
370 goto err;
371 eckey = NULL;
372
373 ret = 1;
374
375 err:
376 EC_KEY_free(eckey);
377
378 return ret;
379}
380
381static int
382eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
383{
384 EC_KEY *eckey = pkey->pkey.ec;
385 void *pval = NULL;
386 int ptype = V_ASN1_UNDEF;
387 ASN1_OBJECT *aobj;
388 unsigned char *key = NULL;
389 int key_len = 0;
390 unsigned int flags;
391 int ret = 0;
392
393 flags = EC_KEY_get_enc_flags(eckey);
394
395 if (!eckey_to_params(eckey, &ptype, &pval)) {
396 ECerror(EC_R_DECODE_ERROR);
397 goto err;
398 }
399
400 /* PKCS#11 12.11: don't include parameters in the SEC1 private key. */
401 EC_KEY_set_enc_flags(eckey, flags | EC_PKEY_NO_PARAMETERS);
402
403 if ((key_len = i2d_ECPrivateKey(eckey, &key)) <= 0) {
404 ECerror(ERR_R_EC_LIB);
405 key_len = 0;
406 goto err;
407 }
408 if ((aobj = OBJ_nid2obj(NID_X9_62_id_ecPublicKey)) == NULL)
409 goto err;
410 if (!PKCS8_pkey_set0(p8, aobj, 0, ptype, pval, key, key_len))
411 goto err;
412 pval = NULL;
413 key = NULL;
414 key_len = 0;
415
416 ret = 1;
417
418 err:
419 eckey_param_free(ptype, pval);
420 freezero(key, key_len);
421
422 EC_KEY_set_enc_flags(eckey, flags);
423
424 return ret;
425}
426
427static int
428ec_size(const EVP_PKEY *pkey)
429{
430 return ECDSA_size(pkey->pkey.ec);
431}
432
433static int
434ec_bits(const EVP_PKEY *pkey)
435{
436 const EC_GROUP *group;
437
438 if ((group = EC_KEY_get0_group(pkey->pkey.ec)) == NULL)
439 return 0;
440
441 return EC_GROUP_order_bits(group);
442}
443
444static int
445ec_security_bits(const EVP_PKEY *pkey)
446{
447 int ecbits = ec_bits(pkey);
448
449 if (ecbits >= 512)
450 return 256;
451 if (ecbits >= 384)
452 return 192;
453 if (ecbits >= 256)
454 return 128;
455 if (ecbits >= 224)
456 return 112;
457 if (ecbits >= 160)
458 return 80;
459
460 return ecbits / 2;
461}
462
463static int
464ec_missing_parameters(const EVP_PKEY *pkey)
465{
466 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
467 return 1;
468 return 0;
469}
470
471static int
472ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
473{
474 return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
475}
476
477static int
478ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
479{
480 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec);
481 const EC_GROUP *group_b = EC_KEY_get0_group(b->pkey.ec);
482
483 if (EC_GROUP_cmp(group_a, group_b, NULL))
484 return 0;
485 else
486 return 1;
487}
488
489static void
490ec_free(EVP_PKEY *pkey)
491{
492 EC_KEY_free(pkey->pkey.ec);
493}
494
495static int
496do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
497{
498 const char *ecstr;
499 int ret = 0, reason = ERR_R_BIO_LIB;
500 BIGNUM *pub_key = NULL;
501 BN_CTX *ctx = NULL;
502 const EC_GROUP *group;
503 const EC_POINT *public_key;
504 const BIGNUM *priv_key;
505
506 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
507 reason = ERR_R_PASSED_NULL_PARAMETER;
508 goto err;
509 }
510 ctx = BN_CTX_new();
511 if (ctx == NULL) {
512 reason = ERR_R_MALLOC_FAILURE;
513 goto err;
514 }
515 if (ktype > 0) {
516 public_key = EC_KEY_get0_public_key(x);
517 if (public_key != NULL) {
518 if ((pub_key = EC_POINT_point2bn(group, public_key,
519 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
520 reason = ERR_R_EC_LIB;
521 goto err;
522 }
523 }
524 }
525 if (ktype == 2) {
526 priv_key = EC_KEY_get0_private_key(x);
527 } else
528 priv_key = NULL;
529
530 if (ktype == 2)
531 ecstr = "Private-Key";
532 else if (ktype == 1)
533 ecstr = "Public-Key";
534 else
535 ecstr = "ECDSA-Parameters";
536
537 if (!BIO_indent(bp, off, 128))
538 goto err;
539 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
540 EC_GROUP_order_bits(group)) <= 0)
541 goto err;
542
543 if (!bn_printf(bp, priv_key, off, "priv:"))
544 goto err;
545 if (!bn_printf(bp, pub_key, off, "pub: "))
546 goto err;
547 if (!ECPKParameters_print(bp, group, off))
548 goto err;
549
550 ret = 1;
551
552 err:
553 if (!ret)
554 ECerror(reason);
555 BN_free(pub_key);
556 BN_CTX_free(ctx);
557
558 return (ret);
559}
560
561static int
562eckey_param_decode(EVP_PKEY *pkey, const unsigned char **param, int param_len)
563{
564 EC_KEY *eckey;
565 int ret = 0;
566
567 if ((eckey = d2i_ECParameters(NULL, param, param_len)) == NULL)
568 goto err;
569 if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
570 goto err;
571 eckey = NULL;
572
573 ret = 1;
574
575 err:
576 EC_KEY_free(eckey);
577
578 return ret;
579}
580
581static int
582eckey_param_encode(const EVP_PKEY *pkey, unsigned char **param)
583{
584 return i2d_ECParameters(pkey->pkey.ec, param);
585}
586
587static int
588eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
589{
590 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
591}
592
593static int
594eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
595{
596 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
597}
598
599
600static int
601eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
602{
603 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
604}
605
606static int
607old_ec_priv_decode(EVP_PKEY *pkey, const unsigned char **priv, int priv_len)
608{
609 EC_KEY *eckey;
610 int ret = 0;
611
612 if ((eckey = d2i_ECPrivateKey(NULL, priv, priv_len)) == NULL)
613 goto err;
614 if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
615 goto err;
616 eckey = NULL;
617
618 ret = 1;
619
620 err:
621 EC_KEY_free(eckey);
622
623 return ret;
624}
625
626static int
627old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **priv)
628{
629 return i2d_ECPrivateKey(pkey->pkey.ec, priv);
630}
631
632static int
633ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
634{
635 switch (op) {
636 case ASN1_PKEY_CTRL_PKCS7_SIGN:
637 if (arg1 == 0) {
638 int snid, hnid;
639 X509_ALGOR *alg1, *alg2;
640 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
641 if (alg1 == NULL || alg1->algorithm == NULL)
642 return -1;
643 hnid = OBJ_obj2nid(alg1->algorithm);
644 if (hnid == NID_undef)
645 return -1;
646 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
647 return -1;
648 if (!X509_ALGOR_set0_by_nid(alg2, snid, V_ASN1_UNDEF,
649 NULL))
650 return -1;
651 }
652 return 1;
653
654#ifndef OPENSSL_NO_CMS
655 case ASN1_PKEY_CTRL_CMS_SIGN:
656 if (arg1 == 0) {
657 X509_ALGOR *alg1, *alg2;
658 int snid, hnid;
659
660 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
661 if (alg1 == NULL || alg1->algorithm == NULL)
662 return -1;
663 hnid = OBJ_obj2nid(alg1->algorithm);
664 if (hnid == NID_undef)
665 return -1;
666 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
667 return -1;
668 if (!X509_ALGOR_set0_by_nid(alg2, snid, V_ASN1_UNDEF,
669 NULL))
670 return -1;
671 }
672 return 1;
673
674 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
675 if (arg1 == 0)
676 return ecdh_cms_encrypt(arg2);
677 else if (arg1 == 1)
678 return ecdh_cms_decrypt(arg2);
679 return -2;
680
681 case ASN1_PKEY_CTRL_CMS_RI_TYPE:
682 *(int *)arg2 = CMS_RECIPINFO_AGREE;
683 return 1;
684#endif
685
686 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
687 *(int *) arg2 = NID_sha1;
688 return 2;
689
690 default:
691 return -2;
692
693 }
694
695}
696
697#ifndef OPENSSL_NO_CMS
698
699static int
700ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg,
701 ASN1_BIT_STRING *pubkey)
702{
703 const ASN1_OBJECT *aoid;
704 int atype;
705 const void *aval;
706 int rv = 0;
707 EVP_PKEY *pkpeer = NULL;
708 EC_KEY *ecpeer = NULL;
709 const unsigned char *p;
710 int plen;
711
712 X509_ALGOR_get0(&aoid, &atype, &aval, alg);
713 if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
714 goto err;
715
716 /* If absent parameters get group from main key */
717 if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
718 const EC_GROUP *grp;
719 EVP_PKEY *pk;
720
721 pk = EVP_PKEY_CTX_get0_pkey(pctx);
722 if (!pk)
723 goto err;
724 grp = EC_KEY_get0_group(pk->pkey.ec);
725 ecpeer = EC_KEY_new();
726 if (ecpeer == NULL)
727 goto err;
728 if (!EC_KEY_set_group(ecpeer, grp))
729 goto err;
730 } else {
731 if (!eckey_from_params(atype, aval, &ecpeer))
732 goto err;
733 }
734
735 /* We have parameters now set public key */
736 plen = ASN1_STRING_length(pubkey);
737 p = ASN1_STRING_get0_data(pubkey);
738 if (!p || !plen)
739 goto err;
740 if (!o2i_ECPublicKey(&ecpeer, &p, plen))
741 goto err;
742 pkpeer = EVP_PKEY_new();
743 if (pkpeer == NULL)
744 goto err;
745 EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
746 if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
747 rv = 1;
748 err:
749 EC_KEY_free(ecpeer);
750 EVP_PKEY_free(pkpeer);
751 return rv;
752}
753
754/* Set KDF parameters based on KDF NID */
755static int
756ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
757{
758 int kdf_nid, kdfmd_nid, cofactor;
759 const EVP_MD *kdf_md;
760
761 if (eckdf_nid == NID_undef)
762 return 0;
763
764 /* Lookup KDF type, cofactor mode and digest */
765 if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
766 return 0;
767
768 if (kdf_nid == NID_dh_std_kdf)
769 cofactor = 0;
770 else if (kdf_nid == NID_dh_cofactor_kdf)
771 cofactor = 1;
772 else
773 return 0;
774
775 if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
776 return 0;
777
778 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
779 return 0;
780
781 kdf_md = EVP_get_digestbynid(kdfmd_nid);
782 if (!kdf_md)
783 return 0;
784
785 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
786 return 0;
787
788 return 1;
789}
790
791static int
792ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
793{
794 X509_ALGOR *alg, *kekalg = NULL;
795 const ASN1_OBJECT *obj;
796 int nid;
797 const void *parameter;
798 int parameter_type;
799 ASN1_OCTET_STRING *ukm;
800 const unsigned char *p;
801 unsigned char *der = NULL;
802 int plen, keylen;
803 const EVP_CIPHER *kekcipher;
804 EVP_CIPHER_CTX *kekctx;
805 int ret = 0;
806
807 if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
808 goto err;
809
810 X509_ALGOR_get0(&obj, &parameter_type, &parameter, alg);
811
812 if ((nid = OBJ_obj2nid(obj)) == NID_undef)
813 goto err;
814 if (!ecdh_cms_set_kdf_param(pctx, nid)) {
815 ECerror(EC_R_KDF_PARAMETER_ERROR);
816 goto err;
817 }
818
819 if (parameter_type != V_ASN1_SEQUENCE)
820 goto err;
821 if ((p = ASN1_STRING_get0_data(parameter)) == NULL)
822 goto err;
823 plen = ASN1_STRING_length(parameter);
824 if ((kekalg = d2i_X509_ALGOR(NULL, &p, plen)) == NULL)
825 goto err;
826
827 /*
828 * XXX - the reaching into kekalg below is ugly, but unfortunately the
829 * now internal legacy EVP_CIPHER_asn1_to_param() API doesn't interact
830 * nicely with the X509_ALGOR API.
831 */
832
833 if ((kekctx = CMS_RecipientInfo_kari_get0_ctx(ri)) == NULL)
834 goto err;
835 if ((kekcipher = EVP_get_cipherbyobj(kekalg->algorithm)) == NULL)
836 goto err;
837 if (EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
838 goto err;
839 if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
840 goto err;
841 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
842 goto err;
843
844 keylen = EVP_CIPHER_CTX_key_length(kekctx);
845 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
846 goto err;
847
848 if ((plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen)) <= 0)
849 goto err;
850
851 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
852 goto err;
853 der = NULL;
854
855 ret = 1;
856
857 err:
858 X509_ALGOR_free(kekalg);
859 free(der);
860
861 return ret;
862}
863
864static int
865ecdh_cms_decrypt(CMS_RecipientInfo *ri)
866{
867 EVP_PKEY_CTX *pctx;
868
869 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
870 if (!pctx)
871 return 0;
872
873 /* See if we need to set peer key */
874 if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
875 X509_ALGOR *alg;
876 ASN1_BIT_STRING *pubkey;
877
878 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
879 NULL, NULL, NULL))
880 return 0;
881 if (!alg || !pubkey)
882 return 0;
883 if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
884 ECerror(EC_R_PEER_KEY_ERROR);
885 return 0;
886 }
887 }
888
889 /* Set ECDH derivation parameters and initialise unwrap context */
890 if (!ecdh_cms_set_shared_info(pctx, ri)) {
891 ECerror(EC_R_SHARED_INFO_ERROR);
892 return 0;
893 }
894
895 return 1;
896}
897
898static int
899ecdh_cms_encrypt(CMS_RecipientInfo *ri)
900{
901 EVP_PKEY_CTX *pctx;
902 EVP_CIPHER_CTX *ctx;
903 int keylen;
904 X509_ALGOR *talg, *wrap_alg = NULL;
905 const ASN1_OBJECT *aoid;
906 ASN1_BIT_STRING *pubkey;
907 ASN1_STRING *wrap_str = NULL;
908 ASN1_OCTET_STRING *ukm;
909 unsigned char *penc = NULL;
910 int penclen;
911 int ecdh_nid, kdf_nid, wrap_nid;
912 const EVP_MD *kdf_md;
913 int ret = 0;
914
915 if ((pctx = CMS_RecipientInfo_get0_pkey_ctx(ri)) == NULL)
916 goto err;
917 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
918 NULL, NULL, NULL))
919 goto err;
920
921 X509_ALGOR_get0(&aoid, NULL, NULL, talg);
922 if (aoid == OBJ_nid2obj(NID_undef)) {
923 EVP_PKEY *pkey;
924
925 if ((pkey = EVP_PKEY_CTX_get0_pkey(pctx)) == NULL)
926 goto err;
927
928 penc = NULL;
929 if ((penclen = i2o_ECPublicKey(pkey->pkey.ec, &penc)) <= 0)
930 goto err;
931
932 ASN1_STRING_set0(pubkey, penc, penclen);
933 penc = NULL;
934
935 if (!asn1_abs_set_unused_bits(pubkey, 0))
936 goto err;
937
938 if (!X509_ALGOR_set0_by_nid(talg, NID_X9_62_id_ecPublicKey,
939 V_ASN1_UNDEF, NULL))
940 goto err;
941 }
942
943 if (EVP_PKEY_CTX_get_ecdh_kdf_type(pctx) != EVP_PKEY_ECDH_KDF_NONE)
944 goto err;
945 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
946 goto err;
947
948 if ((ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx)) < 0)
949 goto err;
950 if (ecdh_nid == 0)
951 ecdh_nid = NID_dh_std_kdf;
952 else if (ecdh_nid == 1)
953 ecdh_nid = NID_dh_cofactor_kdf;
954
955 if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
956 goto err;
957 if (kdf_md == NULL) {
958 /* Fixme later for better MD */
959 kdf_md = EVP_sha1();
960 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
961 goto err;
962 }
963
964 if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
965 goto err;
966
967 /* Lookup NID for KDF+cofactor+digest */
968 if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
969 goto err;
970
971 /* Get wrap NID */
972 ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
973 wrap_nid = EVP_CIPHER_CTX_type(ctx);
974 keylen = EVP_CIPHER_CTX_key_length(ctx);
975
976 /*
977 * Package wrap algorithm in an AlgorithmIdentifier.
978 *
979 * Incompatibility of X509_ALGOR_set0() with EVP_CIPHER_param_to_asn1()
980 * makes this really gross. See the XXX in ecdh_cms_set_shared_info().
981 */
982
983 if ((wrap_alg = X509_ALGOR_new()) == NULL)
984 goto err;
985 if ((wrap_alg->algorithm = OBJ_nid2obj(wrap_nid)) == NULL)
986 goto err;
987 if ((wrap_alg->parameter = ASN1_TYPE_new()) == NULL)
988 goto err;
989 if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
990 goto err;
991 if (ASN1_TYPE_get(wrap_alg->parameter) == V_ASN1_UNDEF) {
992 ASN1_TYPE_free(wrap_alg->parameter);
993 wrap_alg->parameter = NULL;
994 }
995
996 if ((penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen)) <= 0)
997 goto err;
998
999 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
1000 goto err;
1001 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
1002 goto err;
1003 penc = NULL;
1004
1005 /*
1006 * Wrap encoded wrap AlgorithmIdentifier into parameter of another
1007 * AlgorithmIdentifier.
1008 */
1009
1010 if ((penclen = i2d_X509_ALGOR(wrap_alg, &penc)) <= 0)
1011 goto err;
1012
1013 if ((wrap_str = ASN1_STRING_new()) == NULL)
1014 goto err;
1015 ASN1_STRING_set0(wrap_str, penc, penclen);
1016 penc = NULL;
1017
1018 if (!X509_ALGOR_set0_by_nid(talg, kdf_nid, V_ASN1_SEQUENCE, wrap_str))
1019 goto err;
1020 wrap_str = NULL;
1021
1022 ret = 1;
1023
1024 err:
1025 free(penc);
1026 ASN1_STRING_free(wrap_str);
1027 X509_ALGOR_free(wrap_alg);
1028
1029 return ret;
1030}
1031
1032#endif
1033
1034const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
1035 .base_method = &eckey_asn1_meth,
1036 .pkey_id = EVP_PKEY_EC,
1037
1038 .pem_str = "EC",
1039 .info = "OpenSSL EC algorithm",
1040
1041 .pub_decode = eckey_pub_decode,
1042 .pub_encode = eckey_pub_encode,
1043 .pub_cmp = eckey_pub_cmp,
1044 .pub_print = eckey_pub_print,
1045
1046 .priv_decode = eckey_priv_decode,
1047 .priv_encode = eckey_priv_encode,
1048 .priv_print = eckey_priv_print,
1049
1050 .pkey_size = ec_size,
1051 .pkey_bits = ec_bits,
1052 .pkey_security_bits = ec_security_bits,
1053
1054 .param_decode = eckey_param_decode,
1055 .param_encode = eckey_param_encode,
1056 .param_missing = ec_missing_parameters,
1057 .param_copy = ec_copy_parameters,
1058 .param_cmp = ec_cmp_parameters,
1059 .param_print = eckey_param_print,
1060
1061 .pkey_free = ec_free,
1062 .pkey_ctrl = ec_pkey_ctrl,
1063 .old_priv_decode = old_ec_priv_decode,
1064 .old_priv_encode = old_ec_priv_encode,
1065};
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
deleted file mode 100644
index ef318f8d43..0000000000
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ /dev/null
@@ -1,1461 +0,0 @@
1/* $OpenBSD: ec_asn1.c,v 1.111 2025/03/13 10:31:12 tb Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2003 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 * licensing@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#include <limits.h>
60#include <stddef.h>
61#include <stdlib.h>
62#include <string.h>
63
64#include <openssl/opensslconf.h>
65
66#include <openssl/asn1.h>
67#include <openssl/bn.h>
68#include <openssl/ec.h>
69#include <openssl/err.h>
70#include <openssl/asn1t.h>
71#include <openssl/objects.h>
72
73#include "asn1_local.h"
74#include "ec_local.h"
75
76int
77EC_GROUP_get_basis_type(const EC_GROUP *group)
78{
79 return 0;
80}
81LCRYPTO_ALIAS(EC_GROUP_get_basis_type);
82
83typedef struct x9_62_pentanomial_st {
84 long k1;
85 long k2;
86 long k3;
87} X9_62_PENTANOMIAL;
88
89typedef struct x9_62_characteristic_two_st {
90 long m;
91 ASN1_OBJECT *type;
92 union {
93 char *ptr;
94 /* NID_X9_62_onBasis */
95 ASN1_NULL *onBasis;
96 /* NID_X9_62_tpBasis */
97 ASN1_INTEGER *tpBasis;
98 /* NID_X9_62_ppBasis */
99 X9_62_PENTANOMIAL *ppBasis;
100 /* anything else */
101 ASN1_TYPE *other;
102 } p;
103} X9_62_CHARACTERISTIC_TWO;
104
105typedef struct x9_62_fieldid_st {
106 ASN1_OBJECT *fieldType;
107 union {
108 char *ptr;
109 /* NID_X9_62_prime_field */
110 ASN1_INTEGER *prime;
111 /* NID_X9_62_characteristic_two_field */
112 X9_62_CHARACTERISTIC_TWO *char_two;
113 /* anything else */
114 ASN1_TYPE *other;
115 } p;
116} X9_62_FIELDID;
117
118typedef struct x9_62_curve_st {
119 ASN1_OCTET_STRING *a;
120 ASN1_OCTET_STRING *b;
121 ASN1_BIT_STRING *seed;
122} X9_62_CURVE;
123
124typedef struct ec_parameters_st {
125 long version;
126 X9_62_FIELDID *fieldID;
127 X9_62_CURVE *curve;
128 ASN1_OCTET_STRING *base;
129 ASN1_INTEGER *order;
130 ASN1_INTEGER *cofactor;
131} ECPARAMETERS;
132
133#define ECPK_PARAM_NAMED_CURVE 0
134#define ECPK_PARAM_EXPLICIT 1
135#define ECPK_PARAM_IMPLICITLY_CA 2
136
137typedef struct ecpk_parameters_st {
138 int type;
139 union {
140 ASN1_OBJECT *named_curve;
141 ECPARAMETERS *parameters;
142 ASN1_NULL *implicitlyCA;
143 } value;
144} ECPKPARAMETERS;
145
146typedef struct ec_privatekey_st {
147 long version;
148 ASN1_OCTET_STRING *privateKey;
149 ECPKPARAMETERS *parameters;
150 ASN1_BIT_STRING *publicKey;
151} EC_PRIVATEKEY;
152
153static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = {
154 {
155 .flags = 0,
156 .tag = 0,
157 .offset = offsetof(X9_62_PENTANOMIAL, k1),
158 .field_name = "k1",
159 .item = &LONG_it,
160 },
161 {
162 .flags = 0,
163 .tag = 0,
164 .offset = offsetof(X9_62_PENTANOMIAL, k2),
165 .field_name = "k2",
166 .item = &LONG_it,
167 },
168 {
169 .flags = 0,
170 .tag = 0,
171 .offset = offsetof(X9_62_PENTANOMIAL, k3),
172 .field_name = "k3",
173 .item = &LONG_it,
174 },
175};
176
177static const ASN1_ITEM X9_62_PENTANOMIAL_it = {
178 .itype = ASN1_ITYPE_SEQUENCE,
179 .utype = V_ASN1_SEQUENCE,
180 .templates = X9_62_PENTANOMIAL_seq_tt,
181 .tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
182 .funcs = NULL,
183 .size = sizeof(X9_62_PENTANOMIAL),
184 .sname = "X9_62_PENTANOMIAL",
185};
186
187static const ASN1_TEMPLATE char_two_def_tt = {
188 .flags = 0,
189 .tag = 0,
190 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other),
191 .field_name = "p.other",
192 .item = &ASN1_ANY_it,
193};
194
195static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = {
196 {
197 .value = NID_X9_62_onBasis,
198 .tt = {
199 .flags = 0,
200 .tag = 0,
201 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis),
202 .field_name = "p.onBasis",
203 .item = &ASN1_NULL_it,
204 },
205 },
206 {
207 .value = NID_X9_62_tpBasis,
208 .tt = {
209 .flags = 0,
210 .tag = 0,
211 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis),
212 .field_name = "p.tpBasis",
213 .item = &ASN1_INTEGER_it,
214 },
215 },
216 {
217 .value = NID_X9_62_ppBasis,
218 .tt = {
219 .flags = 0,
220 .tag = 0,
221 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis),
222 .field_name = "p.ppBasis",
223 .item = &X9_62_PENTANOMIAL_it,
224 },
225
226 },
227};
228
229static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = {
230 .flags = 0,
231 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
232 .tbl = X9_62_CHARACTERISTIC_TWO_adbtbl,
233 .tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE),
234 .default_tt = &char_two_def_tt,
235 .null_tt = NULL,
236};
237
238static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = {
239 {
240 .flags = 0,
241 .tag = 0,
242 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, m),
243 .field_name = "m",
244 .item = &LONG_it,
245 },
246 {
247 .flags = 0,
248 .tag = 0,
249 .offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
250 .field_name = "type",
251 .item = &ASN1_OBJECT_it,
252 },
253 {
254 .flags = ASN1_TFLG_ADB_OID,
255 .tag = -1,
256 .offset = 0,
257 .field_name = "X9_62_CHARACTERISTIC_TWO",
258 .item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb,
259 },
260};
261
262static const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = {
263 .itype = ASN1_ITYPE_SEQUENCE,
264 .utype = V_ASN1_SEQUENCE,
265 .templates = X9_62_CHARACTERISTIC_TWO_seq_tt,
266 .tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE),
267 .funcs = NULL,
268 .size = sizeof(X9_62_CHARACTERISTIC_TWO),
269 .sname = "X9_62_CHARACTERISTIC_TWO",
270};
271
272static const ASN1_TEMPLATE fieldID_def_tt = {
273 .flags = 0,
274 .tag = 0,
275 .offset = offsetof(X9_62_FIELDID, p.other),
276 .field_name = "p.other",
277 .item = &ASN1_ANY_it,
278};
279
280static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = {
281 {
282 .value = NID_X9_62_prime_field,
283 .tt = {
284 .flags = 0,
285 .tag = 0,
286 .offset = offsetof(X9_62_FIELDID, p.prime),
287 .field_name = "p.prime",
288 .item = &ASN1_INTEGER_it,
289 },
290 },
291 {
292 .value = NID_X9_62_characteristic_two_field,
293 .tt = {
294 .flags = 0,
295 .tag = 0,
296 .offset = offsetof(X9_62_FIELDID, p.char_two),
297 .field_name = "p.char_two",
298 .item = &X9_62_CHARACTERISTIC_TWO_it,
299 },
300 },
301};
302
303static const ASN1_ADB X9_62_FIELDID_adb = {
304 .flags = 0,
305 .offset = offsetof(X9_62_FIELDID, fieldType),
306 .tbl = X9_62_FIELDID_adbtbl,
307 .tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE),
308 .default_tt = &fieldID_def_tt,
309 .null_tt = NULL,
310};
311
312static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = {
313 {
314 .flags = 0,
315 .tag = 0,
316 .offset = offsetof(X9_62_FIELDID, fieldType),
317 .field_name = "fieldType",
318 .item = &ASN1_OBJECT_it,
319 },
320 {
321 .flags = ASN1_TFLG_ADB_OID,
322 .tag = -1,
323 .offset = 0,
324 .field_name = "X9_62_FIELDID",
325 .item = (const ASN1_ITEM *)&X9_62_FIELDID_adb,
326 },
327};
328
329static const ASN1_ITEM X9_62_FIELDID_it = {
330 .itype = ASN1_ITYPE_SEQUENCE,
331 .utype = V_ASN1_SEQUENCE,
332 .templates = X9_62_FIELDID_seq_tt,
333 .tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE),
334 .funcs = NULL,
335 .size = sizeof(X9_62_FIELDID),
336 .sname = "X9_62_FIELDID",
337};
338
339static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = {
340 {
341 .flags = 0,
342 .tag = 0,
343 .offset = offsetof(X9_62_CURVE, a),
344 .field_name = "a",
345 .item = &ASN1_OCTET_STRING_it,
346 },
347 {
348 .flags = 0,
349 .tag = 0,
350 .offset = offsetof(X9_62_CURVE, b),
351 .field_name = "b",
352 .item = &ASN1_OCTET_STRING_it,
353 },
354 {
355 .flags = ASN1_TFLG_OPTIONAL,
356 .tag = 0,
357 .offset = offsetof(X9_62_CURVE, seed),
358 .field_name = "seed",
359 .item = &ASN1_BIT_STRING_it,
360 },
361};
362
363static const ASN1_ITEM X9_62_CURVE_it = {
364 .itype = ASN1_ITYPE_SEQUENCE,
365 .utype = V_ASN1_SEQUENCE,
366 .templates = X9_62_CURVE_seq_tt,
367 .tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE),
368 .funcs = NULL,
369 .size = sizeof(X9_62_CURVE),
370 .sname = "X9_62_CURVE",
371};
372
373static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = {
374 {
375 .flags = 0,
376 .tag = 0,
377 .offset = offsetof(ECPARAMETERS, version),
378 .field_name = "version",
379 .item = &LONG_it,
380 },
381 {
382 .flags = 0,
383 .tag = 0,
384 .offset = offsetof(ECPARAMETERS, fieldID),
385 .field_name = "fieldID",
386 .item = &X9_62_FIELDID_it,
387 },
388 {
389 .flags = 0,
390 .tag = 0,
391 .offset = offsetof(ECPARAMETERS, curve),
392 .field_name = "curve",
393 .item = &X9_62_CURVE_it,
394 },
395 {
396 .flags = 0,
397 .tag = 0,
398 .offset = offsetof(ECPARAMETERS, base),
399 .field_name = "base",
400 .item = &ASN1_OCTET_STRING_it,
401 },
402 {
403 .flags = 0,
404 .tag = 0,
405 .offset = offsetof(ECPARAMETERS, order),
406 .field_name = "order",
407 .item = &ASN1_INTEGER_it,
408 },
409 {
410 .flags = ASN1_TFLG_OPTIONAL,
411 .tag = 0,
412 .offset = offsetof(ECPARAMETERS, cofactor),
413 .field_name = "cofactor",
414 .item = &ASN1_INTEGER_it,
415 },
416};
417
418static const ASN1_ITEM ECPARAMETERS_it = {
419 .itype = ASN1_ITYPE_SEQUENCE,
420 .utype = V_ASN1_SEQUENCE,
421 .templates = ECPARAMETERS_seq_tt,
422 .tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE),
423 .funcs = NULL,
424 .size = sizeof(ECPARAMETERS),
425 .sname = "ECPARAMETERS",
426};
427
428static ECPARAMETERS *
429ECPARAMETERS_new(void)
430{
431 return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
432}
433
434static void
435ECPARAMETERS_free(ECPARAMETERS *a)
436{
437 ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
438}
439
440static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = {
441 {
442 .flags = 0,
443 .tag = 0,
444 .offset = offsetof(ECPKPARAMETERS, value.named_curve),
445 .field_name = "value.named_curve",
446 .item = &ASN1_OBJECT_it,
447 },
448 {
449 .flags = 0,
450 .tag = 0,
451 .offset = offsetof(ECPKPARAMETERS, value.parameters),
452 .field_name = "value.parameters",
453 .item = &ECPARAMETERS_it,
454 },
455 {
456 .flags = 0,
457 .tag = 0,
458 .offset = offsetof(ECPKPARAMETERS, value.implicitlyCA),
459 .field_name = "value.implicitlyCA",
460 .item = &ASN1_NULL_it,
461 },
462};
463
464static const ASN1_ITEM ECPKPARAMETERS_it = {
465 .itype = ASN1_ITYPE_CHOICE,
466 .utype = offsetof(ECPKPARAMETERS, type),
467 .templates = ECPKPARAMETERS_ch_tt,
468 .tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE),
469 .funcs = NULL,
470 .size = sizeof(ECPKPARAMETERS),
471 .sname = "ECPKPARAMETERS",
472};
473
474static ECPKPARAMETERS *
475d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len)
476{
477 return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
478 &ECPKPARAMETERS_it);
479}
480
481static int
482i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
483{
484 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
485}
486
487static ECPKPARAMETERS *
488ECPKPARAMETERS_new(void)
489{
490 return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
491}
492
493static void
494ECPKPARAMETERS_free(ECPKPARAMETERS *a)
495{
496 ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
497}
498
499static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = {
500 {
501 .flags = 0,
502 .tag = 0,
503 .offset = offsetof(EC_PRIVATEKEY, version),
504 .field_name = "version",
505 .item = &LONG_it,
506 },
507 {
508 .flags = 0,
509 .tag = 0,
510 .offset = offsetof(EC_PRIVATEKEY, privateKey),
511 .field_name = "privateKey",
512 .item = &ASN1_OCTET_STRING_it,
513 },
514 {
515 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
516 .tag = 0,
517 .offset = offsetof(EC_PRIVATEKEY, parameters),
518 .field_name = "parameters",
519 .item = &ECPKPARAMETERS_it,
520 },
521 {
522 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
523 .tag = 1,
524 .offset = offsetof(EC_PRIVATEKEY, publicKey),
525 .field_name = "publicKey",
526 .item = &ASN1_BIT_STRING_it,
527 },
528};
529
530static const ASN1_ITEM EC_PRIVATEKEY_it = {
531 .itype = ASN1_ITYPE_SEQUENCE,
532 .utype = V_ASN1_SEQUENCE,
533 .templates = EC_PRIVATEKEY_seq_tt,
534 .tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
535 .funcs = NULL,
536 .size = sizeof(EC_PRIVATEKEY),
537 .sname = "EC_PRIVATEKEY",
538};
539
540static EC_PRIVATEKEY *
541d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len)
542{
543 return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
544 &EC_PRIVATEKEY_it);
545}
546
547static int
548i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
549{
550 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
551}
552
553static EC_PRIVATEKEY *
554EC_PRIVATEKEY_new(void)
555{
556 return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
557}
558
559static void
560EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
561{
562 ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
563}
564
565static int
566ec_point_from_asn1_string(const EC_GROUP *group, const ASN1_STRING *astr,
567 EC_POINT **out_point, uint8_t *out_form)
568{
569 return ec_point_from_octets(group, astr->data, astr->length,
570 out_point, out_form, NULL);
571}
572
573static int
574ec_point_from_asn1_bit_string(const EC_GROUP *group, const ASN1_BIT_STRING *abs,
575 EC_POINT **out_point, uint8_t *out_form)
576{
577 /*
578 * Per SEC 1, C.3, the bit string representing the public key comes from
579 * an octet string, therefore the unused bits octet must be 0x00.
580 * XXX - move this check to a helper in a_bitstr.c?
581 */
582 if ((abs->flags & ASN1_STRING_FLAG_BITS_LEFT) != 0 &&
583 (abs->flags & 0x07) != 0)
584 return 0;
585
586 return ec_point_from_asn1_string(group, abs, out_point, out_form);
587}
588
589static int
590ec_point_from_asn1_octet_string(const EC_GROUP *group, const ASN1_OCTET_STRING *aos,
591 EC_POINT **out_point, uint8_t *out_form)
592{
593 return ec_point_from_asn1_string(group, aos, out_point, out_form);
594}
595
596static int
597ec_point_to_asn1_string_type(const EC_GROUP *group, const EC_POINT *point,
598 int form, int type, ASN1_STRING **out_astr)
599{
600 ASN1_STRING *astr = NULL;
601 unsigned char *buf = NULL;
602 size_t len = 0;
603 int ret = 0;
604
605 if (*out_astr != NULL && ASN1_STRING_type(*out_astr) != type)
606 goto err;
607
608 if (!ec_point_to_octets(group, point, form, &buf, &len, NULL))
609 goto err;
610
611 if ((astr = *out_astr) == NULL)
612 astr = ASN1_STRING_type_new(type);
613 if (astr == NULL)
614 goto err;
615
616 ASN1_STRING_set0(astr, buf, len);
617 buf = NULL;
618 len = 0;
619
620 *out_astr = astr;
621 astr = NULL;
622
623 ret = 1;
624
625 err:
626 ASN1_STRING_free(astr);
627 freezero(buf, len);
628
629 return ret;
630}
631
632static int
633ec_point_to_asn1_bit_string(const EC_GROUP *group, const EC_POINT *point,
634 int form, ASN1_BIT_STRING **out_abs)
635{
636 if (!ec_point_to_asn1_string_type(group, point, form,
637 V_ASN1_BIT_STRING, out_abs))
638 return 0;
639
640 return asn1_abs_set_unused_bits(*out_abs, 0);
641}
642
643static int
644ec_point_to_asn1_octet_string(const EC_GROUP *group, const EC_POINT *point,
645 int form, ASN1_OCTET_STRING **out_aos)
646{
647 return ec_point_to_asn1_string_type(group, point, form,
648 V_ASN1_OCTET_STRING, out_aos);
649}
650
651static int
652ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
653{
654 int ret = 0;
655
656 if (group == NULL || field == NULL)
657 goto err;
658
659 if ((field->fieldType = OBJ_nid2obj(NID_X9_62_prime_field)) == NULL) {
660 ECerror(ERR_R_OBJ_LIB);
661 goto err;
662 }
663 if ((field->p.prime = BN_to_ASN1_INTEGER(group->p, NULL)) == NULL) {
664 ECerror(ERR_R_ASN1_LIB);
665 goto err;
666 }
667
668 ret = 1;
669
670 err:
671 return ret;
672}
673
674static int
675ec_asn1_encode_bn(const EC_GROUP *group, const BIGNUM *bn, int len,
676 ASN1_OCTET_STRING *os)
677{
678 unsigned char *buf;
679 int ret = 0;
680
681 /* One extra byte for historic NUL termination of ASN1_STRINGs. */
682 if ((buf = calloc(1, len + 1)) == NULL)
683 goto err;
684
685 if (BN_bn2binpad(bn, buf, len) != len)
686 goto err;
687
688 ASN1_STRING_set0(os, buf, len);
689 buf = NULL;
690 len = 0;
691
692 ret = 1;
693
694 err:
695 freezero(buf, len);
696
697 return ret;
698}
699
700static int
701ec_asn1_encode_field_element(const EC_GROUP *group, const BIGNUM *bn,
702 ASN1_OCTET_STRING *os)
703{
704 /* Zero-pad field element to byte length of p per SEC 1, 2.3.5. */
705 return ec_asn1_encode_bn(group, bn, BN_num_bytes(group->p), os);
706}
707
708static int
709ec_asn1_encode_private_key(const EC_GROUP *group, const BIGNUM *bn,
710 ASN1_OCTET_STRING *os)
711{
712 /* Zero-pad private key to byte length of order per SEC 1, C.4. */
713 return ec_asn1_encode_bn(group, bn, BN_num_bytes(group->order), os);
714}
715
716static int
717ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
718{
719 BIGNUM *a = NULL, *b = NULL;
720 int ret = 0;
721
722 if (group == NULL)
723 goto err;
724 if (curve == NULL || curve->a == NULL || curve->b == NULL)
725 goto err;
726
727 if ((a = BN_new()) == NULL || (b = BN_new()) == NULL) {
728 ECerror(ERR_R_MALLOC_FAILURE);
729 goto err;
730 }
731
732 if (!EC_GROUP_get_curve(group, NULL, a, b, NULL)) {
733 ECerror(ERR_R_EC_LIB);
734 goto err;
735 }
736
737 if (!ec_asn1_encode_field_element(group, a, curve->a)) {
738 ECerror(ERR_R_EC_LIB);
739 goto err;
740 }
741 if (!ec_asn1_encode_field_element(group, b, curve->b)) {
742 ECerror(ERR_R_EC_LIB);
743 goto err;
744 }
745
746 ASN1_BIT_STRING_free(curve->seed);
747 curve->seed = NULL;
748
749 if (group->seed != NULL) {
750 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
751 ECerror(ERR_R_MALLOC_FAILURE);
752 goto err;
753 }
754 if (!ASN1_BIT_STRING_set(curve->seed,
755 group->seed, group->seed_len)) {
756 ECerror(ERR_R_ASN1_LIB);
757 goto err;
758 }
759 if (!asn1_abs_set_unused_bits(curve->seed, 0)) {
760 ECerror(ERR_R_ASN1_LIB);
761 goto err;
762 }
763 }
764
765 ret = 1;
766
767 err:
768 BN_free(a);
769 BN_free(b);
770
771 return ret;
772}
773
774static ECPARAMETERS *
775ec_asn1_group2parameters(const EC_GROUP *group)
776{
777 ECPARAMETERS *parameters = NULL;
778 const EC_POINT *generator = NULL;
779 const BIGNUM *order, *cofactor;
780 uint8_t form;
781
782 if ((parameters = ECPARAMETERS_new()) == NULL) {
783 ECerror(ERR_R_MALLOC_FAILURE);
784 goto err;
785 }
786
787 parameters->version = 0x1;
788
789 if (!ec_asn1_group2fieldid(group, parameters->fieldID)) {
790 ECerror(ERR_R_EC_LIB);
791 goto err;
792 }
793
794 if (!ec_asn1_group2curve(group, parameters->curve)) {
795 ECerror(ERR_R_EC_LIB);
796 goto err;
797 }
798
799 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
800 ECerror(EC_R_UNDEFINED_GENERATOR);
801 goto err;
802 }
803
804 form = EC_GROUP_get_point_conversion_form(group);
805 if (!ec_point_to_asn1_octet_string(group, generator, form, &parameters->base))
806 goto err;
807
808 if ((order = EC_GROUP_get0_order(group)) == NULL) {
809 ECerror(ERR_R_EC_LIB);
810 goto err;
811 }
812 if (BN_is_zero(order)) {
813 ECerror(ERR_R_EC_LIB);
814 goto err;
815 }
816 ASN1_INTEGER_free(parameters->order);
817 if ((parameters->order = BN_to_ASN1_INTEGER(order, NULL)) == NULL) {
818 ECerror(ERR_R_ASN1_LIB);
819 goto err;
820 }
821
822 ASN1_INTEGER_free(parameters->cofactor);
823 parameters->cofactor = NULL;
824 if ((cofactor = EC_GROUP_get0_cofactor(group)) == NULL) {
825 ECerror(ERR_R_EC_LIB);
826 goto err;
827 }
828 if (!BN_is_zero(cofactor)) {
829 if ((parameters->cofactor = BN_to_ASN1_INTEGER(cofactor,
830 NULL)) == NULL) {
831 ECerror(ERR_R_ASN1_LIB);
832 goto err;
833 }
834 }
835
836 return parameters;
837
838 err:
839 ECPARAMETERS_free(parameters);
840
841 return NULL;
842}
843
844static ECPKPARAMETERS *
845ec_asn1_group2pkparameters(const EC_GROUP *group)
846{
847 ECPKPARAMETERS *pkparameters;
848 ECPARAMETERS *parameters;
849 ASN1_OBJECT *aobj;
850 int nid;
851
852 if ((pkparameters = ECPKPARAMETERS_new()) == NULL) {
853 ECerror(ERR_R_MALLOC_FAILURE);
854 goto err;
855 }
856
857 if ((EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) != 0) {
858 if ((nid = EC_GROUP_get_curve_name(group)) == NID_undef)
859 goto err;
860 if ((aobj = OBJ_nid2obj(nid)) == NULL)
861 goto err;
862 pkparameters->type = ECPK_PARAM_NAMED_CURVE;
863 pkparameters->value.named_curve = aobj;
864 } else {
865 if ((parameters = ec_asn1_group2parameters(group)) == NULL)
866 goto err;
867 pkparameters->type = ECPK_PARAM_EXPLICIT;
868 pkparameters->value.parameters = parameters;
869 parameters = NULL;
870 }
871
872 return pkparameters;
873
874 err:
875 ECPKPARAMETERS_free(pkparameters);
876
877 return NULL;
878}
879
880static int
881ec_asn1_is_prime_field(const X9_62_FIELDID *fieldid)
882{
883 int nid;
884
885 if (fieldid == NULL) {
886 ECerror(EC_R_ASN1_ERROR);
887 return 0;
888 }
889 if ((nid = OBJ_obj2nid(fieldid->fieldType)) == NID_undef) {
890 ECerror(EC_R_INVALID_FIELD);
891 return 0;
892 }
893 if (nid == NID_X9_62_characteristic_two_field) {
894 ECerror(EC_R_GF2M_NOT_SUPPORTED);
895 return 0;
896 }
897 if (nid != NID_X9_62_prime_field) {
898 ECerror(EC_R_UNSUPPORTED_FIELD);
899 return 0;
900 }
901
902 /* We can't check that this is actually a prime due to DoS risk. */
903 if (fieldid->p.prime == NULL) {
904 ECerror(EC_R_INVALID_FIELD);
905 return 0;
906 }
907
908 return 1;
909}
910
911static int
912ec_asn1_parameters_curve2group(const X9_62_CURVE *curve,
913 const ASN1_INTEGER *prime, EC_GROUP **out_group)
914{
915 EC_GROUP *group = NULL;
916 BIGNUM *p = NULL, *a = NULL, *b = NULL;
917 int ret = 0;
918
919 if (*out_group != NULL)
920 goto err;
921
922 if ((p = ASN1_INTEGER_to_BN(prime, NULL)) == NULL)
923 goto err;
924 if ((a = BN_bin2bn(curve->a->data, curve->a->length, NULL)) == NULL)
925 goto err;
926 if ((b = BN_bin2bn(curve->b->data, curve->b->length, NULL)) == NULL)
927 goto err;
928
929 /*
930 * XXX - move these checks to ec_GFp_simple_group_set_curve()?
931 * What about checking 0 <= a, b < p?
932 */
933 if (BN_is_zero(p) || BN_is_negative(p)) {
934 ECerror(EC_R_INVALID_FIELD);
935 goto err;
936 }
937 if (BN_num_bits(p) > OPENSSL_ECC_MAX_FIELD_BITS) {
938 ECerror(EC_R_FIELD_TOO_LARGE);
939 goto err;
940 }
941
942 if ((group = EC_GROUP_new_curve_GFp(p, a, b, NULL)) == NULL)
943 goto err;
944
945 *out_group = group;
946 group = NULL;
947
948 ret = 1;
949
950 err:
951 BN_free(p);
952 BN_free(a);
953 BN_free(b);
954 EC_GROUP_free(group);
955
956 return ret;
957}
958
959static int
960ec_asn1_set_group_parameters(const ECPARAMETERS *params, EC_GROUP *group)
961{
962 EC_POINT *generator = NULL;
963 BIGNUM *order = NULL, *cofactor = NULL;
964 const ASN1_BIT_STRING *seed;
965 uint8_t form;
966 int ret = 0;
967
968 if (!ec_point_from_asn1_octet_string(group, params->base, &generator, &form))
969 goto err;
970 EC_GROUP_set_point_conversion_form(group, form);
971
972 if ((order = ASN1_INTEGER_to_BN(params->order, NULL)) == NULL) {
973 ECerror(ERR_R_ASN1_LIB);
974 goto err;
975 }
976 if (params->cofactor != NULL) {
977 if ((cofactor = ASN1_INTEGER_to_BN(params->cofactor,
978 NULL)) == NULL) {
979 ECerror(ERR_R_ASN1_LIB);
980 goto err;
981 }
982 }
983
984 /* Checks the Hasse bound and sets the cofactor if possible or fails. */
985 if (!EC_GROUP_set_generator(group, generator, order, cofactor)) {
986 ECerror(ERR_R_EC_LIB);
987 goto err;
988 }
989
990 if ((seed = params->curve->seed) != NULL) {
991 if (EC_GROUP_set_seed(group, seed->data, seed->length) == 0) {
992 ECerror(ERR_R_MALLOC_FAILURE);
993 goto err;
994 }
995 }
996
997 ret = 1;
998
999 err:
1000 EC_POINT_free(generator);
1001 BN_free(order);
1002 BN_free(cofactor);
1003
1004 return ret;
1005}
1006
1007static int
1008ec_asn1_parameters_extract_prime_group(const ECPARAMETERS *params,
1009 EC_GROUP **out_group)
1010{
1011 EC_GROUP *group = NULL;
1012 int ret = 0;
1013
1014 if (*out_group != NULL)
1015 goto err;
1016
1017 if (!ec_asn1_is_prime_field(params->fieldID))
1018 goto err;
1019 if (!ec_asn1_parameters_curve2group(params->curve,
1020 params->fieldID->p.prime, &group))
1021 goto err;
1022 if (!ec_asn1_set_group_parameters(params, group))
1023 goto err;
1024
1025 *out_group = group;
1026 group = NULL;
1027
1028 ret = 1;
1029
1030 err:
1031 EC_GROUP_free(group);
1032
1033 return ret;
1034}
1035
1036static EC_GROUP *
1037ec_asn1_parameters2group(const ECPARAMETERS *params)
1038{
1039 EC_GROUP *group = NULL;
1040 int nid = NID_undef;
1041
1042 if (params == NULL) {
1043 ECerror(EC_R_ASN1_ERROR);
1044 goto err;
1045 }
1046
1047 if (!ec_asn1_parameters_extract_prime_group(params, &group))
1048 goto err;
1049 if (!ec_group_is_builtin_curve(group, &nid))
1050 goto err;
1051 EC_GROUP_set_curve_name(group, nid);
1052
1053 return group;
1054
1055 err:
1056 EC_GROUP_free(group);
1057
1058 return NULL;
1059}
1060
1061static EC_GROUP *
1062ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1063{
1064 EC_GROUP *group;
1065 int nid;
1066
1067 if (params->type == ECPK_PARAM_NAMED_CURVE) {
1068 if ((nid = OBJ_obj2nid(params->value.named_curve)) == NID_undef) {
1069 ECerror(EC_R_UNKNOWN_GROUP);
1070 return NULL;
1071 }
1072 if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
1073 ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1074 return NULL;
1075 }
1076 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
1077 } else if (params->type == ECPK_PARAM_EXPLICIT) {
1078 group = ec_asn1_parameters2group(params->value.parameters);
1079 if (group == NULL) {
1080 ECerror(ERR_R_EC_LIB);
1081 return NULL;
1082 }
1083 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1084 } else if (params->type == ECPK_PARAM_IMPLICITLY_CA) {
1085 return NULL;
1086 } else {
1087 ECerror(EC_R_ASN1_ERROR);
1088 return NULL;
1089 }
1090
1091 return group;
1092}
1093
1094EC_GROUP *
1095d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1096{
1097 EC_GROUP *group = NULL;
1098 ECPKPARAMETERS *params;
1099
1100 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
1101 ECerror(EC_R_D2I_ECPKPARAMETERS_FAILURE);
1102 goto err;
1103 }
1104 if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1105 ECerror(EC_R_PKPARAMETERS2GROUP_FAILURE);
1106 goto err;
1107 }
1108
1109 if (a != NULL) {
1110 EC_GROUP_free(*a);
1111 *a = group;
1112 }
1113
1114 err:
1115 ECPKPARAMETERS_free(params);
1116
1117 return group;
1118}
1119LCRYPTO_ALIAS(d2i_ECPKParameters);
1120
1121int
1122i2d_ECPKParameters(const EC_GROUP *group, unsigned char **out_der)
1123{
1124 ECPKPARAMETERS *parameters;
1125 int ret = 0;
1126
1127 if ((parameters = ec_asn1_group2pkparameters(group)) == NULL) {
1128 ECerror(EC_R_GROUP2PKPARAMETERS_FAILURE);
1129 goto err;
1130 }
1131 if ((ret = i2d_ECPKPARAMETERS(parameters, out_der)) <= 0) {
1132 ECerror(EC_R_I2D_ECPKPARAMETERS_FAILURE);
1133 goto err;
1134 }
1135
1136 err:
1137 ECPKPARAMETERS_free(parameters);
1138
1139 return ret;
1140}
1141LCRYPTO_ALIAS(i2d_ECPKParameters);
1142
1143static int
1144ec_key_set_group_from_parameters(EC_KEY *ec_key, const ECPKPARAMETERS *params)
1145{
1146 EC_GROUP *group = NULL;
1147 int ret = 0;
1148
1149 /* Use group in parameters, if any. Fall back to existing group. */
1150 if (params != NULL) {
1151 if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1152 goto err;
1153 if (!EC_KEY_set_group(ec_key, group))
1154 goto err;
1155 }
1156 if (ec_key->group == NULL)
1157 goto err;
1158
1159 ret = 1;
1160
1161 err:
1162 EC_GROUP_free(group);
1163
1164 return ret;
1165}
1166
1167static int
1168ec_key_set_private_key(EC_KEY *ec_key, const ASN1_OCTET_STRING *aos)
1169{
1170 BIGNUM *priv_key = NULL;
1171 int ret = 0;
1172
1173 if (aos == NULL) {
1174 ECerror(EC_R_MISSING_PRIVATE_KEY);
1175 goto err;
1176 }
1177
1178 /*
1179 * XXX - Sec 1, C.4 requires that this octet string be padded to the
1180 * byte length of the group's order. This can't be enforced because
1181 * i2d_ECPrivateKey() used to produce a semi-compatible ad hoc format.
1182 */
1183 if ((priv_key = BN_bin2bn(aos->data, aos->length, NULL)) == NULL)
1184 goto err;
1185 if (!EC_KEY_set_private_key(ec_key, priv_key))
1186 goto err;
1187
1188 ret = 1;
1189
1190 err:
1191 BN_free(priv_key);
1192
1193 return ret;
1194}
1195
1196static int
1197ec_key_set_public_key(EC_KEY *ec_key, const ASN1_BIT_STRING *abs)
1198{
1199 EC_POINT *pub_key = NULL;
1200 uint8_t form;
1201 int ret = 0;
1202
1203 if (abs == NULL) {
1204 ec_key->enc_flag |= EC_PKEY_NO_PUBKEY;
1205 return eckey_compute_pubkey(ec_key);
1206 }
1207
1208 /* XXX - SEC 1, 2.3.4 does not allow hybrid encoding. */
1209 if (!ec_point_from_asn1_bit_string(ec_key->group, abs, &pub_key, &form))
1210 goto err;
1211 if (!EC_KEY_set_public_key(ec_key, pub_key))
1212 goto err;
1213 EC_KEY_set_conv_form(ec_key, form);
1214
1215 ret = 1;
1216
1217 err:
1218 EC_POINT_free(pub_key);
1219
1220 return ret;
1221}
1222
1223EC_KEY *
1224d2i_ECPrivateKey(EC_KEY **out_ec_key, const unsigned char **in, long len)
1225{
1226 EC_KEY *ec_key = NULL;
1227 EC_PRIVATEKEY *ec_privatekey = NULL;
1228
1229 if (out_ec_key == NULL || (ec_key = *out_ec_key) == NULL)
1230 ec_key = EC_KEY_new();
1231 if (ec_key == NULL)
1232 goto err;
1233
1234 if ((ec_privatekey = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) {
1235 ECerror(ERR_R_EC_LIB);
1236 goto err;
1237 }
1238
1239 ec_key->version = ec_privatekey->version;
1240 if (!ec_key_set_group_from_parameters(ec_key, ec_privatekey->parameters))
1241 goto err;
1242 if (!ec_key_set_private_key(ec_key, ec_privatekey->privateKey))
1243 goto err;
1244 if (!ec_key_set_public_key(ec_key, ec_privatekey->publicKey))
1245 goto err;
1246
1247 EC_PRIVATEKEY_free(ec_privatekey);
1248 ec_privatekey = NULL;
1249
1250 if (out_ec_key != NULL)
1251 *out_ec_key = ec_key;
1252
1253 return ec_key;
1254
1255 err:
1256 if (out_ec_key == NULL || *out_ec_key != ec_key)
1257 EC_KEY_free(ec_key);
1258 EC_PRIVATEKEY_free(ec_privatekey);
1259
1260 return NULL;
1261}
1262LCRYPTO_ALIAS(d2i_ECPrivateKey);
1263
1264int
1265i2d_ECPrivateKey(EC_KEY *ec_key, unsigned char **out)
1266{
1267 EC_PRIVATEKEY *ec_privatekey = NULL;
1268 const EC_GROUP *group;
1269 const BIGNUM *private_key;
1270 const EC_POINT *public_key = NULL;
1271 int ret = 0;
1272
1273 if (ec_key == NULL) {
1274 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1275 goto err;
1276 }
1277 if ((group = EC_KEY_get0_group(ec_key)) == NULL) {
1278 ECerror(EC_R_MISSING_PARAMETERS);
1279 goto err;
1280 }
1281 if ((private_key = EC_KEY_get0_private_key(ec_key)) == NULL) {
1282 ECerror(EC_R_KEYS_NOT_SET);
1283 goto err;
1284 }
1285 if ((ec_key->enc_flag & EC_PKEY_NO_PUBKEY) == 0) {
1286 if ((public_key = EC_KEY_get0_public_key(ec_key)) == NULL) {
1287 ECerror(EC_R_KEYS_NOT_SET);
1288 goto err;
1289 }
1290 }
1291
1292 if ((ec_privatekey = EC_PRIVATEKEY_new()) == NULL) {
1293 ECerror(ERR_R_MALLOC_FAILURE);
1294 goto err;
1295 }
1296 ec_privatekey->version = ec_key->version;
1297
1298 if (!ec_asn1_encode_private_key(group, private_key, ec_privatekey->privateKey))
1299 goto err;
1300 if ((ec_key->enc_flag & EC_PKEY_NO_PARAMETERS) == 0) {
1301 ECPKPARAMETERS *parameters;
1302
1303 if ((parameters = ec_asn1_group2pkparameters(group)) == NULL) {
1304 ECerror(ERR_R_EC_LIB);
1305 goto err;
1306 }
1307 ec_privatekey->parameters = parameters;
1308 }
1309 if (public_key != NULL) {
1310 uint8_t form;
1311
1312 form = EC_KEY_get_conv_form(ec_key);
1313 if (!ec_point_to_asn1_bit_string(group, public_key, form,
1314 &ec_privatekey->publicKey))
1315 goto err;
1316 }
1317
1318 if ((ret = i2d_EC_PRIVATEKEY(ec_privatekey, out)) <= 0) {
1319 ECerror(ERR_R_EC_LIB);
1320 goto err;
1321 }
1322
1323 err:
1324 EC_PRIVATEKEY_free(ec_privatekey);
1325
1326 return ret;
1327}
1328LCRYPTO_ALIAS(i2d_ECPrivateKey);
1329
1330int
1331i2d_ECParameters(EC_KEY *ec_key, unsigned char **out)
1332{
1333 if (ec_key == NULL) {
1334 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1335 return 0;
1336 }
1337 return i2d_ECPKParameters(ec_key->group, out);
1338}
1339LCRYPTO_ALIAS(i2d_ECParameters);
1340
1341EC_KEY *
1342d2i_ECParameters(EC_KEY **out_ec_key, const unsigned char **in, long len)
1343{
1344 EC_KEY *ec_key = NULL;
1345
1346 if (in == NULL || *in == NULL) {
1347 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1348 goto err;
1349 }
1350 if (out_ec_key == NULL || (ec_key = *out_ec_key) == NULL)
1351 ec_key = EC_KEY_new();
1352 if (ec_key == NULL) {
1353 ECerror(ERR_R_MALLOC_FAILURE);
1354 goto err;
1355 }
1356
1357 if (!d2i_ECPKParameters(&ec_key->group, in, len)) {
1358 ECerror(ERR_R_EC_LIB);
1359 goto err;
1360 }
1361
1362 if (out_ec_key != NULL)
1363 *out_ec_key = ec_key;
1364
1365 return ec_key;
1366
1367 err:
1368 if (out_ec_key == NULL || *out_ec_key != ec_key)
1369 EC_KEY_free(ec_key);
1370
1371 return NULL;
1372}
1373LCRYPTO_ALIAS(d2i_ECParameters);
1374
1375EC_KEY *
1376ECParameters_dup(EC_KEY *key)
1377{
1378 const unsigned char *p;
1379 unsigned char *der = NULL;
1380 EC_KEY *dup = NULL;
1381 int len;
1382
1383 if (key == NULL)
1384 return NULL;
1385
1386 if ((len = i2d_ECParameters(key, &der)) <= 0)
1387 return NULL;
1388
1389 p = der;
1390 dup = d2i_ECParameters(NULL, &p, len);
1391 freezero(der, len);
1392
1393 return dup;
1394}
1395LCRYPTO_ALIAS(ECParameters_dup);
1396
1397EC_KEY *
1398o2i_ECPublicKey(EC_KEY **in_ec_key, const unsigned char **in, long len)
1399{
1400 EC_KEY *ec_key = NULL;
1401 const EC_GROUP *group;
1402 uint8_t form;
1403
1404 if (in_ec_key == NULL || (ec_key = *in_ec_key) == NULL) {
1405 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1406 return NULL;
1407 }
1408 if ((group = ec_key->group) == NULL) {
1409 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1410 return NULL;
1411 }
1412 if (len < 0) {
1413 ECerror(EC_R_INVALID_ARGUMENT);
1414 return NULL;
1415 }
1416
1417 if (!ec_point_from_octets(group, *in, len, &ec_key->pub_key, &form, NULL))
1418 return NULL;
1419 EC_KEY_set_conv_form(ec_key, form);
1420
1421 *in += len;
1422
1423 return ec_key;
1424}
1425LCRYPTO_ALIAS(o2i_ECPublicKey);
1426
1427int
1428i2o_ECPublicKey(const EC_KEY *ec_key, unsigned char **out)
1429{
1430 unsigned char *buf = NULL;
1431 size_t buf_len = 0;
1432 int ret = 0;
1433
1434 if (ec_key == NULL) {
1435 ECerror(ERR_R_PASSED_NULL_PARAMETER);
1436 goto err;
1437 }
1438
1439 if (!ec_point_to_octets(ec_key->group, ec_key->pub_key,
1440 ec_key->conv_form, &buf, &buf_len, NULL))
1441 goto err;
1442 if (buf_len > INT_MAX)
1443 goto err;
1444
1445 if (out != NULL && *out != NULL) {
1446 /* Muppet's answer to the Jackass show. */
1447 memcpy(*out, buf, buf_len);
1448 *out += buf_len;
1449 } else if (out != NULL) {
1450 *out = buf;
1451 buf = NULL;
1452 }
1453
1454 ret = buf_len;
1455
1456 err:
1457 freezero(buf, buf_len);
1458
1459 return ret;
1460}
1461LCRYPTO_ALIAS(i2o_ECPublicKey);
diff --git a/src/lib/libcrypto/ec/ec_convert.c b/src/lib/libcrypto/ec/ec_convert.c
deleted file mode 100644
index a18bc49132..0000000000
--- a/src/lib/libcrypto/ec/ec_convert.c
+++ /dev/null
@@ -1,575 +0,0 @@
1/* $OpenBSD: ec_convert.c,v 1.14 2025/01/05 16:07:08 tb Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2003 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 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/asn1.h>
67#include <openssl/err.h>
68
69#include "asn1_local.h"
70#include "ec_local.h"
71
72/*
73 * Internal handling of the point conversion octet
74 * (see X9.62, section 4.4.2, SEC 1 section 2.3.3)
75 *
76 * Only the last three bits of the leading octet of a point should be set.
77 * Bits 3 and 2 encode the conversion form for all points except the point
78 * at infinity. In compressed and hybrid form bit 1 indicates if the even
79 * or the odd solution of the quadratic equation for y should be used.
80 *
81 * The public point_conversion_t enum lacks the point at infinity, so we
82 * ignore it except at the API boundary.
83 */
84
85#define EC_POINT_YBIT 0x01
86
87#define EC_POINT_AT_INFINITY 0x00
88#define EC_POINT_COMPRESSED 0x02
89#define EC_POINT_UNCOMPRESSED 0x04
90#define EC_POINT_HYBRID 0x06
91#define EC_POINT_CONVERSION_MASK 0x06
92
93static int
94ec_conversion_form_is_valid(uint8_t form)
95{
96 return (form & EC_POINT_CONVERSION_MASK) == form;
97}
98
99static int
100ec_check_hybrid_ybit_is_consistent(uint8_t form, int ybit, const BIGNUM *y)
101{
102 if (form == EC_POINT_HYBRID && ybit != BN_is_odd(y)) {
103 ECerror(EC_R_INVALID_ENCODING);
104 return 0;
105 }
106
107 return 1;
108}
109
110/* Nonzero y-bit only makes sense with compressed or hybrid encoding. */
111static int
112ec_nonzero_ybit_allowed(uint8_t form)
113{
114 return form == EC_POINT_COMPRESSED || form == EC_POINT_HYBRID;
115}
116
117static int
118ec_add_leading_octet_cbb(CBB *cbb, uint8_t form, int ybit)
119{
120 if (ec_nonzero_ybit_allowed(form) && ybit != 0)
121 form |= EC_POINT_YBIT;
122
123 return CBB_add_u8(cbb, form);
124}
125
126static int
127ec_get_leading_octet_cbs(CBS *cbs, uint8_t *out_form, int *out_ybit)
128{
129 uint8_t octet;
130
131 if (!CBS_get_u8(cbs, &octet)) {
132 ECerror(EC_R_BUFFER_TOO_SMALL);
133 return 0;
134 }
135
136 *out_ybit = octet & EC_POINT_YBIT;
137 *out_form = octet & ~EC_POINT_YBIT;
138
139 if (!ec_conversion_form_is_valid(*out_form)) {
140 ECerror(EC_R_INVALID_ENCODING);
141 return 0;
142 }
143
144 if (*out_ybit != 0 && !ec_nonzero_ybit_allowed(*out_form)) {
145 ECerror(EC_R_INVALID_ENCODING);
146 return 0;
147 }
148
149 return 1;
150}
151
152static int
153ec_encoded_length(const EC_GROUP *group, uint8_t form, size_t *out_len)
154{
155 switch (form) {
156 case EC_POINT_AT_INFINITY:
157 *out_len = 1;
158 return 1;
159 case EC_POINT_COMPRESSED:
160 *out_len = 1 + BN_num_bytes(group->p);
161 return 1;
162 case EC_POINT_UNCOMPRESSED:
163 case EC_POINT_HYBRID:
164 *out_len = 1 + 2 * BN_num_bytes(group->p);
165 return 1;
166 default:
167 return 0;
168 }
169}
170
171static int
172ec_field_element_is_valid(const EC_GROUP *group, const BIGNUM *bn)
173{
174 /* Ensure bn is in the range [0, p). */
175 return !BN_is_negative(bn) && BN_cmp(group->p, bn) > 0;
176}
177
178static int
179ec_add_field_element_cbb(CBB *cbb, const EC_GROUP *group, const BIGNUM *bn)
180{
181 uint8_t *buf = NULL;
182 int buf_len = BN_num_bytes(group->p);
183
184 if (!ec_field_element_is_valid(group, bn)) {
185 ECerror(EC_R_BIGNUM_OUT_OF_RANGE);
186 return 0;
187 }
188 if (!CBB_add_space(cbb, &buf, buf_len)) {
189 ECerror(ERR_R_MALLOC_FAILURE);
190 return 0;
191 }
192 if (BN_bn2binpad(bn, buf, buf_len) != buf_len) {
193 ECerror(ERR_R_MALLOC_FAILURE);
194 return 0;
195 }
196
197 return 1;
198}
199
200static int
201ec_get_field_element_cbs(CBS *cbs, const EC_GROUP *group, BIGNUM *bn)
202{
203 CBS field_element;
204
205 if (!CBS_get_bytes(cbs, &field_element, BN_num_bytes(group->p))) {
206 ECerror(EC_R_INVALID_ENCODING);
207 return 0;
208 }
209 if (!BN_bin2bn(CBS_data(&field_element), CBS_len(&field_element), bn)) {
210 ECerror(ERR_R_MALLOC_FAILURE);
211 return 0;
212 }
213 if (!ec_field_element_is_valid(group, bn)) {
214 ECerror(EC_R_BIGNUM_OUT_OF_RANGE);
215 return 0;
216 }
217
218 return 1;
219}
220
221static size_t
222ec_point2oct(const EC_GROUP *group, const EC_POINT *point, uint8_t form,
223 unsigned char *buf, size_t len, BN_CTX *ctx)
224{
225 CBB cbb;
226 BIGNUM *x, *y;
227 size_t encoded_length;
228 size_t ret = 0;
229
230 if (EC_POINT_is_at_infinity(group, point))
231 form = EC_POINT_AT_INFINITY;
232
233 if (!ec_encoded_length(group, form, &encoded_length)) {
234 ECerror(EC_R_INVALID_FORM);
235 return 0;
236 }
237
238 if (buf == NULL)
239 return encoded_length;
240
241 if (len < encoded_length) {
242 ECerror(EC_R_BUFFER_TOO_SMALL);
243 return 0;
244 }
245
246 BN_CTX_start(ctx);
247 if (!CBB_init_fixed(&cbb, buf, len))
248 goto err;
249
250 if (form == EC_POINT_AT_INFINITY) {
251 if (!EC_POINT_is_at_infinity(group, point))
252 goto err;
253 if (!ec_add_leading_octet_cbb(&cbb, form, 0))
254 goto err;
255
256 goto done;
257 }
258
259 if ((x = BN_CTX_get(ctx)) == NULL)
260 goto err;
261 if ((y = BN_CTX_get(ctx)) == NULL)
262 goto err;
263 if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
264 goto err;
265
266 if (!ec_add_leading_octet_cbb(&cbb, form, BN_is_odd(y)))
267 goto err;
268
269 if (form == EC_POINT_COMPRESSED) {
270 if (!ec_add_field_element_cbb(&cbb, group, x))
271 goto err;
272 } else {
273 if (!ec_add_field_element_cbb(&cbb, group, x))
274 goto err;
275 if (!ec_add_field_element_cbb(&cbb, group, y))
276 goto err;
277 }
278
279 done:
280 if (!CBB_finish(&cbb, NULL, &ret))
281 goto err;
282
283 if (ret != encoded_length) {
284 ret = 0;
285 goto err;
286 }
287
288 err:
289 CBB_cleanup(&cbb);
290 BN_CTX_end(ctx);
291
292 return ret;
293}
294
295static int
296ec_oct2point(const EC_GROUP *group, EC_POINT *point,
297 const unsigned char *buf, size_t len, BN_CTX *ctx)
298{
299 CBS cbs;
300 uint8_t form;
301 int ybit;
302 BIGNUM *x, *y;
303 int ret = 0;
304
305 BN_CTX_start(ctx);
306 CBS_init(&cbs, buf, len);
307
308 if (!ec_get_leading_octet_cbs(&cbs, &form, &ybit))
309 goto err;
310
311 if (form == EC_POINT_AT_INFINITY) {
312 if (!EC_POINT_set_to_infinity(group, point))
313 goto err;
314
315 goto done;
316 }
317
318 if ((x = BN_CTX_get(ctx)) == NULL)
319 goto err;
320 if ((y = BN_CTX_get(ctx)) == NULL)
321 goto err;
322
323 if (form == EC_POINT_COMPRESSED) {
324 if (!ec_get_field_element_cbs(&cbs, group, x))
325 goto err;
326 if (!EC_POINT_set_compressed_coordinates(group, point, x, ybit, ctx))
327 goto err;
328 } else {
329 if (!ec_get_field_element_cbs(&cbs, group, x))
330 goto err;
331 if (!ec_get_field_element_cbs(&cbs, group, y))
332 goto err;
333 if (!ec_check_hybrid_ybit_is_consistent(form, ybit, y))
334 goto err;
335 if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
336 goto err;
337 }
338
339 done:
340 if (CBS_len(&cbs) > 0) {
341 ECerror(EC_R_INVALID_ENCODING);
342 goto err;
343 }
344
345 ret = 1;
346
347 err:
348 BN_CTX_end(ctx);
349
350 return ret;
351}
352
353int
354ec_point_to_octets(const EC_GROUP *group, const EC_POINT *point, int form,
355 unsigned char **out_buf, size_t *out_len, BN_CTX *ctx)
356{
357 unsigned char *buf = NULL;
358 size_t len = 0;
359 int ret = 0;
360
361 *out_len = 0;
362
363 if (out_buf == NULL || *out_buf != NULL)
364 goto err;
365
366 if ((len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx)) == 0)
367 goto err;
368 if ((buf = calloc(1, len)) == NULL)
369 goto err;
370 if (EC_POINT_point2oct(group, point, form, buf, len, ctx) != len)
371 goto err;
372
373 *out_buf = buf;
374 buf = NULL;
375 *out_len = len;
376 len = 0;
377
378 ret = 1;
379
380 err:
381 freezero(buf, len);
382
383 return ret;
384}
385
386int
387ec_point_from_octets(const EC_GROUP *group, const unsigned char *buf, size_t buf_len,
388 EC_POINT **out_point, uint8_t *out_form, BN_CTX *ctx)
389{
390 EC_POINT *point;
391 int ret = 0;
392
393 if ((point = *out_point) == NULL)
394 point = EC_POINT_new(group);
395 if (point == NULL)
396 goto err;
397
398 if (!EC_POINT_oct2point(group, point, buf, buf_len, ctx))
399 goto err;
400
401 if (out_form != NULL)
402 *out_form = buf[0] & ~EC_POINT_YBIT;
403
404 *out_point = point;
405 point = NULL;
406
407 ret = 1;
408
409 err:
410 if (*out_point != point)
411 EC_POINT_free(point);
412
413 return ret;
414}
415
416static int
417ec_normalize_form(const EC_GROUP *group, const EC_POINT *point, int form,
418 uint8_t *out_form)
419{
420 /*
421 * Established behavior is to reject a request for the form 0 for the
422 * point at infinity even if it is valid.
423 */
424 if (form <= 0 || form > UINT8_MAX)
425 return 0;
426 if (!ec_conversion_form_is_valid(form))
427 return 0;
428
429 *out_form = form;
430 if (EC_POINT_is_at_infinity(group, point))
431 *out_form = EC_POINT_AT_INFINITY;
432
433 return 1;
434}
435
436size_t
437EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
438 point_conversion_form_t conv_form, unsigned char *buf, size_t len,
439 BN_CTX *ctx_in)
440{
441 BN_CTX *ctx = NULL;
442 uint8_t form;
443 size_t ret = 0;
444
445 if (!ec_normalize_form(group, point, conv_form, &form)) {
446 ECerror(EC_R_INVALID_FORM);
447 goto err;
448 }
449
450 if ((ctx = ctx_in) == NULL)
451 ctx = BN_CTX_new();
452 if (ctx == NULL)
453 goto err;
454
455 if (group->meth != point->meth) {
456 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
457 goto err;
458 }
459 ret = ec_point2oct(group, point, form, buf, len, ctx);
460
461 err:
462 if (ctx != ctx_in)
463 BN_CTX_free(ctx);
464
465 return ret;
466}
467LCRYPTO_ALIAS(EC_POINT_point2oct);
468
469int
470EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
471 const unsigned char *buf, size_t len, BN_CTX *ctx_in)
472{
473 BN_CTX *ctx;
474 int ret = 0;
475
476 if ((ctx = ctx_in) == NULL)
477 ctx = BN_CTX_new();
478 if (ctx == NULL)
479 goto err;
480
481 if (group->meth != point->meth) {
482 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
483 goto err;
484 }
485 ret = ec_oct2point(group, point, buf, len, ctx);
486
487 err:
488 if (ctx != ctx_in)
489 BN_CTX_free(ctx);
490
491 return ret;
492}
493LCRYPTO_ALIAS(EC_POINT_oct2point);
494
495BIGNUM *
496EC_POINT_point2bn(const EC_GROUP *group, const EC_POINT *point,
497 point_conversion_form_t form, BIGNUM *in_bn, BN_CTX *ctx)
498{
499 BIGNUM *bn = NULL;
500 unsigned char *buf = NULL;
501 size_t buf_len = 0;
502
503 if (!ec_point_to_octets(group, point, form, &buf, &buf_len, ctx))
504 goto err;
505 if ((bn = BN_bin2bn(buf, buf_len, in_bn)) == NULL)
506 goto err;
507
508 err:
509 freezero(buf, buf_len);
510
511 return bn;
512}
513LCRYPTO_ALIAS(EC_POINT_point2bn);
514
515EC_POINT *
516EC_POINT_bn2point(const EC_GROUP *group,
517 const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
518{
519 unsigned char *buf = NULL;
520 size_t buf_len = 0;
521
522 /* Of course BN_bn2bin() is in no way symmetric to BN_bin2bn()... */
523 if ((buf_len = BN_num_bytes(bn)) == 0)
524 goto err;
525 if ((buf = calloc(1, buf_len)) == NULL)
526 goto err;
527 if (!BN_bn2bin(bn, buf))
528 goto err;
529 if (!ec_point_from_octets(group, buf, buf_len, &point, NULL, ctx))
530 goto err;
531
532 err:
533 freezero(buf, buf_len);
534
535 return point;
536}
537LCRYPTO_ALIAS(EC_POINT_bn2point);
538
539char *
540EC_POINT_point2hex(const EC_GROUP *group, const EC_POINT *point,
541 point_conversion_form_t form, BN_CTX *ctx)
542{
543 BIGNUM *bn;
544 char *hex = NULL;
545
546 if ((bn = EC_POINT_point2bn(group, point, form, NULL, ctx)) == NULL)
547 goto err;
548 if ((hex = BN_bn2hex(bn)) == NULL)
549 goto err;
550
551 err:
552 BN_free(bn);
553
554 return hex;
555}
556LCRYPTO_ALIAS(EC_POINT_point2hex);
557
558EC_POINT *
559EC_POINT_hex2point(const EC_GROUP *group, const char *hex,
560 EC_POINT *in_point, BN_CTX *ctx)
561{
562 EC_POINT *point = NULL;
563 BIGNUM *bn = NULL;
564
565 if (BN_hex2bn(&bn, hex) == 0)
566 goto err;
567 if ((point = EC_POINT_bn2point(group, bn, in_point, ctx)) == NULL)
568 goto err;
569
570 err:
571 BN_free(bn);
572
573 return point;
574}
575LCRYPTO_ALIAS(EC_POINT_hex2point);
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c
deleted file mode 100644
index a3ec2de7fb..0000000000
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ /dev/null
@@ -1,1765 +0,0 @@
1/* $OpenBSD: ec_curve.c,v 1.54 2025/03/09 17:53:11 tb Exp $ */
2/*
3 * Written by Nils Larsch 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 <limits.h>
73#include <stdint.h>
74#include <stdlib.h>
75#include <string.h>
76
77#include <openssl/opensslconf.h>
78
79#include <openssl/bn.h>
80#include <openssl/ec.h>
81#include <openssl/err.h>
82#include <openssl/objects.h>
83
84#include "ec_local.h"
85
86static const struct {
87 uint8_t seed[20];
88 uint8_t p[28];
89 uint8_t a[28];
90 uint8_t b[28];
91 uint8_t x[28];
92 uint8_t y[28];
93 uint8_t order[28];
94} _EC_NIST_PRIME_224 = {
95 .seed = {
96 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7, 0xfc, 0xdc, 0x45,
97 0xb5, 0x9f, 0xa3, 0xb9, 0xab, 0x8f, 0x6a, 0x94, 0x8b, 0xc5,
98 },
99 .p = {
100 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
103 },
104 .a = {
105 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
106 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
107 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
108 },
109 .b = {
110 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41,
111 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba,
112 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4,
113 },
114 .x = {
115 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13,
116 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22,
117 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21,
118 },
119 .y = {
120 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22,
121 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
122 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
123 },
124 .order = {
125 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
126 0xff, 0xff, 0xff, 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e,
127 0x13, 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d,
128 },
129};
130
131static const struct {
132 uint8_t seed[20];
133 uint8_t p[48];
134 uint8_t a[48];
135 uint8_t b[48];
136 uint8_t x[48];
137 uint8_t y[48];
138 uint8_t order[48];
139} _EC_NIST_PRIME_384 = {
140 .seed = {
141 0xa3, 0x35, 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00,
142 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd, 0xac, 0x73,
143 },
144 .p = {
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
147 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
148 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
150 },
151 .a = {
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc,
157 },
158 .b = {
159 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e,
160 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e,
161 0xfe, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13,
162 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d,
163 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef,
164 },
165 .x = {
166 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1,
167 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 0x62,
168 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54,
169 0x2a, 0x38, 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c,
170 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7,
171 },
172 .y = {
173 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e,
174 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd,
175 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0,
176 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
177 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
178 },
179 .order = {
180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
181 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
182 0xff, 0xff, 0xff, 0xff, 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37,
183 0x2d, 0xdf, 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
184 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73,
185 },
186};
187
188static const struct {
189 uint8_t seed[20];
190 uint8_t p[66];
191 uint8_t a[66];
192 uint8_t b[66];
193 uint8_t x[66];
194 uint8_t y[66];
195 uint8_t order[66];
196} _EC_NIST_PRIME_521 = {
197 .seed = {
198 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc,
199 0x67, 0x17, 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba,
200 },
201 .p = {
202 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
203 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
204 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
205 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
207 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
208 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
209 },
210 .a = {
211 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
212 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
213 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
214 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
215 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
216 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
217 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
218 },
219 .b = {
220 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 0x1f,
221 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda,
222 0x72, 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91,
223 0x8e, 0xf1, 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
224 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf, 0x07,
225 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 0xf1, 0xef, 0x45,
226 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00,
227 },
228 .x = {
229 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd,
230 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64,
231 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60,
232 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
233 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde,
234 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
235 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66,
236 },
237 .y = {
238 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
239 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5,
240 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
241 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
242 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
243 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
244 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
245 },
246 .order = {
247 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
248 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
250 0xff, 0xff, 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f,
251 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0,
252 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f,
253 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09,
254 },
255};
256
257static const struct {
258 uint8_t seed[20];
259 uint8_t p[30];
260 uint8_t a[30];
261 uint8_t b[30];
262 uint8_t x[30];
263 uint8_t y[30];
264 uint8_t order[30];
265} _EC_X9_62_PRIME_239V1 = {
266 .seed = {
267 0xe4, 0x3b, 0xb4, 0x60, 0xf0, 0xb8, 0x0c, 0xc0, 0xc0, 0xb0,
268 0x75, 0x79, 0x8e, 0x94, 0x80, 0x60, 0xf8, 0x32, 0x1b, 0x7d,
269 },
270 .p = {
271 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
272 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
274 },
275 .a = {
276 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
277 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc,
279 },
280 .b = {
281 0x6b, 0x01, 0x6c, 0x3b, 0xdc, 0xf1, 0x89, 0x41, 0xd0, 0xd6,
282 0x54, 0x92, 0x14, 0x75, 0xca, 0x71, 0xa9, 0xdb, 0x2f, 0xb2,
283 0x7d, 0x1d, 0x37, 0x79, 0x61, 0x85, 0xc2, 0x94, 0x2c, 0x0a,
284 },
285 .x = {
286 0x0f, 0xfa, 0x96, 0x3c, 0xdc, 0xa8, 0x81, 0x6c, 0xcc, 0x33,
287 0xb8, 0x64, 0x2b, 0xed, 0xf9, 0x05, 0xc3, 0xd3, 0x58, 0x57,
288 0x3d, 0x3f, 0x27, 0xfb, 0xbd, 0x3b, 0x3c, 0xb9, 0xaa, 0xaf,
289 },
290 .y = {
291 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40,
292 0x54, 0xca, 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18,
293 0xce, 0x22, 0x6b, 0x39, 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae,
294 },
295 .order = {
296 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
297 0xff, 0xff, 0x7f, 0xff, 0xff, 0x9e, 0x5e, 0x9a, 0x9f, 0x5d,
298 0x90, 0x71, 0xfb, 0xd1, 0x52, 0x26, 0x88, 0x90, 0x9d, 0x0b,
299 },
300};
301
302static const struct {
303 uint8_t seed[20];
304 uint8_t p[30];
305 uint8_t a[30];
306 uint8_t b[30];
307 uint8_t x[30];
308 uint8_t y[30];
309 uint8_t order[30];
310} _EC_X9_62_PRIME_239V2 = {
311 .seed = {
312 0xe8, 0xb4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xca, 0x3b,
313 0x80, 0x99, 0x98, 0x2b, 0xe0, 0x9f, 0xcb, 0x9a, 0xe6, 0x16,
314 },
315 .p = {
316 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
317 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
319 },
320 .a = {
321 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
322 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc,
324 },
325 .b = {
326 0x61, 0x7f, 0xab, 0x68, 0x32, 0x57, 0x6c, 0xbb, 0xfe, 0xd5,
327 0x0d, 0x99, 0xf0, 0x24, 0x9c, 0x3f, 0xee, 0x58, 0xb9, 0x4b,
328 0xa0, 0x03, 0x8c, 0x7a, 0xe8, 0x4c, 0x8c, 0x83, 0x2f, 0x2c,
329 },
330 .x = {
331 0x38, 0xaf, 0x09, 0xd9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xc9,
332 0x21, 0xbb, 0x5e, 0x9e, 0x26, 0x29, 0x6a, 0x3c, 0xdc, 0xf2,
333 0xf3, 0x57, 0x57, 0xa0, 0xea, 0xfd, 0x87, 0xb8, 0x30, 0xe7,
334 },
335 .y = {
336 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d,
337 0xa0, 0xfc, 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55,
338 0xde, 0x6e, 0xf4, 0x60, 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba,
339 },
340 .order = {
341 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
342 0xff, 0xff, 0x80, 0x00, 0x00, 0xcf, 0xa7, 0xe8, 0x59, 0x43,
343 0x77, 0xd4, 0x14, 0xc0, 0x38, 0x21, 0xbc, 0x58, 0x20, 0x63,
344 },
345};
346
347static const struct {
348 uint8_t seed[20];
349 uint8_t p[30];
350 uint8_t a[30];
351 uint8_t b[30];
352 uint8_t x[30];
353 uint8_t y[30];
354 uint8_t order[30];
355} _EC_X9_62_PRIME_239V3 = {
356 .seed = {
357 0x7d, 0x73, 0x74, 0x16, 0x8f, 0xfe, 0x34, 0x71, 0xb6, 0x0a,
358 0x85, 0x76, 0x86, 0xa1, 0x94, 0x75, 0xd3, 0xbf, 0xa2, 0xff,
359 },
360 .p = {
361 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
362 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
364 },
365 .a = {
366 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
367 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc,
369 },
370 .b = {
371 0x25, 0x57, 0x05, 0xfa, 0x2a, 0x30, 0x66, 0x54, 0xb1, 0xf4,
372 0xcb, 0x03, 0xd6, 0xa7, 0x50, 0xa3, 0x0c, 0x25, 0x01, 0x02,
373 0xd4, 0x98, 0x87, 0x17, 0xd9, 0xba, 0x15, 0xab, 0x6d, 0x3e,
374 },
375 .x = {
376 0x67, 0x68, 0xae, 0x8e, 0x18, 0xbb, 0x92, 0xcf, 0xcf, 0x00,
377 0x5c, 0x94, 0x9a, 0xa2, 0xc6, 0xd9, 0x48, 0x53, 0xd0, 0xe6,
378 0x60, 0xbb, 0xf8, 0x54, 0xb1, 0xc9, 0x50, 0x5f, 0xe9, 0x5a,
379 },
380 .y = {
381 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d,
382 0x55, 0x2b, 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b,
383 0x6e, 0x81, 0x84, 0x99, 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3,
384 },
385 .order = {
386 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
387 0xff, 0xff, 0x7f, 0xff, 0xff, 0x97, 0x5d, 0xeb, 0x41, 0xb3,
388 0xa6, 0x05, 0x7c, 0x3c, 0x43, 0x21, 0x46, 0x52, 0x65, 0x51,
389 },
390};
391
392static const struct {
393 uint8_t seed[20];
394 uint8_t p[32];
395 uint8_t a[32];
396 uint8_t b[32];
397 uint8_t x[32];
398 uint8_t y[32];
399 uint8_t order[32];
400} _EC_X9_62_PRIME_256V1 = {
401 .seed = {
402 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66,
403 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90,
404 },
405 .p = {
406 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
409 0xff, 0xff,
410 },
411 .a = {
412 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
415 0xff, 0xfc,
416 },
417 .b = {
418 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
419 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0,
420 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
421 0x60, 0x4b,
422 },
423 .x = {
424 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
425 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
426 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98,
427 0xc2, 0x96,
428 },
429 .y = {
430 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7,
431 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
432 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf,
433 0x51, 0xf5,
434 },
435 .order = {
436 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
437 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad,
438 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63,
439 0x25, 0x51,
440 },
441};
442
443static const struct {
444 uint8_t p[29];
445 uint8_t a[29];
446 uint8_t b[29];
447 uint8_t x[29];
448 uint8_t y[29];
449 uint8_t order[29];
450} _EC_SECG_PRIME_224K1 = {
451 .p = {
452 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
453 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
454 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xe5, 0x6d,
455 },
456 .a = {
457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 },
461 .b = {
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
465 },
466 .x = {
467 0x00, 0xa1, 0x45, 0x5b, 0x33, 0x4d, 0xf0, 0x99, 0xdf, 0x30,
468 0xfc, 0x28, 0xa1, 0x69, 0xa4, 0x67, 0xe9, 0xe4, 0x70, 0x75,
469 0xa9, 0x0f, 0x7e, 0x65, 0x0e, 0xb6, 0xb7, 0xa4, 0x5c,
470 },
471 .y = {
472 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82,
473 0xca, 0xfb, 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd,
474 0x59, 0xe2, 0xca, 0x4b, 0xdb, 0x55, 0x6d, 0x61, 0xa5,
475 },
476 .order = {
477 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x01, 0xdc, 0xe8, 0xd2, 0xec, 0x61,
479 0x84, 0xca, 0xf0, 0xa9, 0x71, 0x76, 0x9f, 0xb1, 0xf7,
480 },
481};
482
483static const struct {
484 uint8_t p[32];
485 uint8_t a[32];
486 uint8_t b[32];
487 uint8_t x[32];
488 uint8_t y[32];
489 uint8_t order[32];
490} _EC_SECG_PRIME_256K1 = {
491 .p = {
492 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
493 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
494 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
495 0xfc, 0x2f,
496 },
497 .a = {
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00,
502 },
503 .b = {
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x07,
508 },
509 .x = {
510 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0,
511 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb,
512 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8,
513 0x17, 0x98,
514 },
515 .y = {
516 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4,
517 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48,
518 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10,
519 0xd4, 0xb8,
520 },
521 .order = {
522 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
523 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6,
524 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36,
525 0x41, 0x41,
526 },
527};
528
529static const struct {
530 uint8_t p[28];
531 uint8_t a[28];
532 uint8_t b[28];
533 uint8_t x[28];
534 uint8_t y[28];
535 uint8_t order[28];
536} _EC_brainpoolP224r1 = {
537 .p = {
538 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18,
539 0x30, 0x25, 0x75, 0xd1, 0xd7, 0x87, 0xb0, 0x9f, 0x07, 0x57,
540 0x97, 0xda, 0x89, 0xf5, 0x7e, 0xc8, 0xc0, 0xff,
541 },
542 .a = {
543 0x68, 0xa5, 0xe6, 0x2c, 0xa9, 0xce, 0x6c, 0x1c, 0x29, 0x98,
544 0x03, 0xa6, 0xc1, 0x53, 0x0b, 0x51, 0x4e, 0x18, 0x2a, 0xd8,
545 0xb0, 0x04, 0x2a, 0x59, 0xca, 0xd2, 0x9f, 0x43,
546 },
547 .b = {
548 0x25, 0x80, 0xf6, 0x3c, 0xcf, 0xe4, 0x41, 0x38, 0x87, 0x07,
549 0x13, 0xb1, 0xa9, 0x23, 0x69, 0xe3, 0x3e, 0x21, 0x35, 0xd2,
550 0x66, 0xdb, 0xb3, 0x72, 0x38, 0x6c, 0x40, 0x0b,
551 },
552 .x = {
553 0x0d, 0x90, 0x29, 0xad, 0x2c, 0x7e, 0x5c, 0xf4, 0x34, 0x08,
554 0x23, 0xb2, 0xa8, 0x7d, 0xc6, 0x8c, 0x9e, 0x4c, 0xe3, 0x17,
555 0x4c, 0x1e, 0x6e, 0xfd, 0xee, 0x12, 0xc0, 0x7d,
556 },
557 .y = {
558 0x58, 0xaa, 0x56, 0xf7, 0x72, 0xc0, 0x72, 0x6f, 0x24, 0xc6,
559 0xb8, 0x9e, 0x4e, 0xcd, 0xac, 0x24, 0x35, 0x4b, 0x9e, 0x99,
560 0xca, 0xa3, 0xf6, 0xd3, 0x76, 0x14, 0x02, 0xcd,
561 },
562 .order = {
563 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18,
564 0x30, 0x25, 0x75, 0xd0, 0xfb, 0x98, 0xd1, 0x16, 0xbc, 0x4b,
565 0x6d, 0xde, 0xbc, 0xa3, 0xa5, 0xa7, 0x93, 0x9f,
566 },
567};
568
569static const struct {
570 uint8_t p[28];
571 uint8_t a[28];
572 uint8_t b[28];
573 uint8_t x[28];
574 uint8_t y[28];
575 uint8_t order[28];
576} _EC_brainpoolP224t1 = {
577 .p = {
578 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18,
579 0x30, 0x25, 0x75, 0xd1, 0xd7, 0x87, 0xb0, 0x9f, 0x07, 0x57,
580 0x97, 0xda, 0x89, 0xf5, 0x7e, 0xc8, 0xc0, 0xff,
581 },
582 .a = {
583 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18,
584 0x30, 0x25, 0x75, 0xd1, 0xd7, 0x87, 0xb0, 0x9f, 0x07, 0x57,
585 0x97, 0xda, 0x89, 0xf5, 0x7e, 0xc8, 0xc0, 0xfc,
586 },
587 .b = {
588 0x4b, 0x33, 0x7d, 0x93, 0x41, 0x04, 0xcd, 0x7b, 0xef, 0x27,
589 0x1b, 0xf6, 0x0c, 0xed, 0x1e, 0xd2, 0x0d, 0xa1, 0x4c, 0x08,
590 0xb3, 0xbb, 0x64, 0xf1, 0x8a, 0x60, 0x88, 0x8d,
591 },
592 .x = {
593 0x6a, 0xb1, 0xe3, 0x44, 0xce, 0x25, 0xff, 0x38, 0x96, 0x42,
594 0x4e, 0x7f, 0xfe, 0x14, 0x76, 0x2e, 0xcb, 0x49, 0xf8, 0x92,
595 0x8a, 0xc0, 0xc7, 0x60, 0x29, 0xb4, 0xd5, 0x80,
596 },
597 .y = {
598 0x03, 0x74, 0xe9, 0xf5, 0x14, 0x3e, 0x56, 0x8c, 0xd2, 0x3f,
599 0x3f, 0x4d, 0x7c, 0x0d, 0x4b, 0x1e, 0x41, 0xc8, 0xcc, 0x0d,
600 0x1c, 0x6a, 0xbd, 0x5f, 0x1a, 0x46, 0xdb, 0x4c,
601 },
602 .order = {
603 0xd7, 0xc1, 0x34, 0xaa, 0x26, 0x43, 0x66, 0x86, 0x2a, 0x18,
604 0x30, 0x25, 0x75, 0xd0, 0xfb, 0x98, 0xd1, 0x16, 0xbc, 0x4b,
605 0x6d, 0xde, 0xbc, 0xa3, 0xa5, 0xa7, 0x93, 0x9f,
606 },
607};
608
609static const struct {
610 uint8_t p[32];
611 uint8_t a[32];
612 uint8_t b[32];
613 uint8_t x[32];
614 uint8_t y[32];
615 uint8_t order[32];
616} _EC_brainpoolP256r1 = {
617 .p = {
618 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66,
619 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, 0x6e, 0x3b, 0xf6, 0x23,
620 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e,
621 0x53, 0x77,
622 },
623 .a = {
624 0x7d, 0x5a, 0x09, 0x75, 0xfc, 0x2c, 0x30, 0x57, 0xee, 0xf6,
625 0x75, 0x30, 0x41, 0x7a, 0xff, 0xe7, 0xfb, 0x80, 0x55, 0xc1,
626 0x26, 0xdc, 0x5c, 0x6c, 0xe9, 0x4a, 0x4b, 0x44, 0xf3, 0x30,
627 0xb5, 0xd9,
628 },
629 .b = {
630 0x26, 0xdc, 0x5c, 0x6c, 0xe9, 0x4a, 0x4b, 0x44, 0xf3, 0x30,
631 0xb5, 0xd9, 0xbb, 0xd7, 0x7c, 0xbf, 0x95, 0x84, 0x16, 0x29,
632 0x5c, 0xf7, 0xe1, 0xce, 0x6b, 0xcc, 0xdc, 0x18, 0xff, 0x8c,
633 0x07, 0xb6,
634 },
635 .x = {
636 0x8b, 0xd2, 0xae, 0xb9, 0xcb, 0x7e, 0x57, 0xcb, 0x2c, 0x4b,
637 0x48, 0x2f, 0xfc, 0x81, 0xb7, 0xaf, 0xb9, 0xde, 0x27, 0xe1,
638 0xe3, 0xbd, 0x23, 0xc2, 0x3a, 0x44, 0x53, 0xbd, 0x9a, 0xce,
639 0x32, 0x62,
640 },
641 .y = {
642 0x54, 0x7e, 0xf8, 0x35, 0xc3, 0xda, 0xc4, 0xfd, 0x97, 0xf8,
643 0x46, 0x1a, 0x14, 0x61, 0x1d, 0xc9, 0xc2, 0x77, 0x45, 0x13,
644 0x2d, 0xed, 0x8e, 0x54, 0x5c, 0x1d, 0x54, 0xc7, 0x2f, 0x04,
645 0x69, 0x97,
646 },
647 .order = {
648 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66,
649 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x71, 0x8c, 0x39, 0x7a, 0xa3,
650 0xb5, 0x61, 0xa6, 0xf7, 0x90, 0x1e, 0x0e, 0x82, 0x97, 0x48,
651 0x56, 0xa7,
652 },
653};
654
655static const struct {
656 uint8_t p[32];
657 uint8_t a[32];
658 uint8_t b[32];
659 uint8_t x[32];
660 uint8_t y[32];
661 uint8_t order[32];
662} _EC_brainpoolP256t1 = {
663 .p = {
664 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66,
665 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, 0x6e, 0x3b, 0xf6, 0x23,
666 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e,
667 0x53, 0x77,
668 },
669 .a = {
670 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66,
671 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x72, 0x6e, 0x3b, 0xf6, 0x23,
672 0xd5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1d, 0x1f, 0x6e,
673 0x53, 0x74,
674 },
675 .b = {
676 0x66, 0x2c, 0x61, 0xc4, 0x30, 0xd8, 0x4e, 0xa4, 0xfe, 0x66,
677 0xa7, 0x73, 0x3d, 0x0b, 0x76, 0xb7, 0xbf, 0x93, 0xeb, 0xc4,
678 0xaf, 0x2f, 0x49, 0x25, 0x6a, 0xe5, 0x81, 0x01, 0xfe, 0xe9,
679 0x2b, 0x04,
680 },
681 .x = {
682 0xa3, 0xe8, 0xeb, 0x3c, 0xc1, 0xcf, 0xe7, 0xb7, 0x73, 0x22,
683 0x13, 0xb2, 0x3a, 0x65, 0x61, 0x49, 0xaf, 0xa1, 0x42, 0xc4,
684 0x7a, 0xaf, 0xbc, 0x2b, 0x79, 0xa1, 0x91, 0x56, 0x2e, 0x13,
685 0x05, 0xf4,
686 },
687 .y = {
688 0x2d, 0x99, 0x6c, 0x82, 0x34, 0x39, 0xc5, 0x6d, 0x7f, 0x7b,
689 0x22, 0xe1, 0x46, 0x44, 0x41, 0x7e, 0x69, 0xbc, 0xb6, 0xde,
690 0x39, 0xd0, 0x27, 0x00, 0x1d, 0xab, 0xe8, 0xf3, 0x5b, 0x25,
691 0xc9, 0xbe,
692 },
693 .order = {
694 0xa9, 0xfb, 0x57, 0xdb, 0xa1, 0xee, 0xa9, 0xbc, 0x3e, 0x66,
695 0x0a, 0x90, 0x9d, 0x83, 0x8d, 0x71, 0x8c, 0x39, 0x7a, 0xa3,
696 0xb5, 0x61, 0xa6, 0xf7, 0x90, 0x1e, 0x0e, 0x82, 0x97, 0x48,
697 0x56, 0xa7,
698 },
699};
700
701static const struct {
702 uint8_t p[40];
703 uint8_t a[40];
704 uint8_t b[40];
705 uint8_t x[40];
706 uint8_t y[40];
707 uint8_t order[40];
708} _EC_brainpoolP320r1 = {
709 .p = {
710 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c,
711 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa6,
712 0xf6, 0xf4, 0x0d, 0xef, 0x4f, 0x92, 0xb9, 0xec, 0x78, 0x93,
713 0xec, 0x28, 0xfc, 0xd4, 0x12, 0xb1, 0xf1, 0xb3, 0x2e, 0x27,
714 },
715 .a = {
716 0x3e, 0xe3, 0x0b, 0x56, 0x8f, 0xba, 0xb0, 0xf8, 0x83, 0xcc,
717 0xeb, 0xd4, 0x6d, 0x3f, 0x3b, 0xb8, 0xa2, 0xa7, 0x35, 0x13,
718 0xf5, 0xeb, 0x79, 0xda, 0x66, 0x19, 0x0e, 0xb0, 0x85, 0xff,
719 0xa9, 0xf4, 0x92, 0xf3, 0x75, 0xa9, 0x7d, 0x86, 0x0e, 0xb4,
720 },
721 .b = {
722 0x52, 0x08, 0x83, 0x94, 0x9d, 0xfd, 0xbc, 0x42, 0xd3, 0xad,
723 0x19, 0x86, 0x40, 0x68, 0x8a, 0x6f, 0xe1, 0x3f, 0x41, 0x34,
724 0x95, 0x54, 0xb4, 0x9a, 0xcc, 0x31, 0xdc, 0xcd, 0x88, 0x45,
725 0x39, 0x81, 0x6f, 0x5e, 0xb4, 0xac, 0x8f, 0xb1, 0xf1, 0xa6,
726 },
727 .x = {
728 0x43, 0xbd, 0x7e, 0x9a, 0xfb, 0x53, 0xd8, 0xb8, 0x52, 0x89,
729 0xbc, 0xc4, 0x8e, 0xe5, 0xbf, 0xe6, 0xf2, 0x01, 0x37, 0xd1,
730 0x0a, 0x08, 0x7e, 0xb6, 0xe7, 0x87, 0x1e, 0x2a, 0x10, 0xa5,
731 0x99, 0xc7, 0x10, 0xaf, 0x8d, 0x0d, 0x39, 0xe2, 0x06, 0x11,
732 },
733 .y = {
734 0x14, 0xfd, 0xd0, 0x55, 0x45, 0xec, 0x1c, 0xc8, 0xab, 0x40,
735 0x93, 0x24, 0x7f, 0x77, 0x27, 0x5e, 0x07, 0x43, 0xff, 0xed,
736 0x11, 0x71, 0x82, 0xea, 0xa9, 0xc7, 0x78, 0x77, 0xaa, 0xac,
737 0x6a, 0xc7, 0xd3, 0x52, 0x45, 0xd1, 0x69, 0x2e, 0x8e, 0xe1,
738 },
739 .order = {
740 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c,
741 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa5,
742 0xb6, 0x8f, 0x12, 0xa3, 0x2d, 0x48, 0x2e, 0xc7, 0xee, 0x86,
743 0x58, 0xe9, 0x86, 0x91, 0x55, 0x5b, 0x44, 0xc5, 0x93, 0x11,
744 },
745};
746
747static const struct {
748 uint8_t p[40];
749 uint8_t a[40];
750 uint8_t b[40];
751 uint8_t x[40];
752 uint8_t y[40];
753 uint8_t order[40];
754} _EC_brainpoolP320t1 = {
755 .p = {
756 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c,
757 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa6,
758 0xf6, 0xf4, 0x0d, 0xef, 0x4f, 0x92, 0xb9, 0xec, 0x78, 0x93,
759 0xec, 0x28, 0xfc, 0xd4, 0x12, 0xb1, 0xf1, 0xb3, 0x2e, 0x27,
760 },
761 .a = {
762 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c,
763 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa6,
764 0xf6, 0xf4, 0x0d, 0xef, 0x4f, 0x92, 0xb9, 0xec, 0x78, 0x93,
765 0xec, 0x28, 0xfc, 0xd4, 0x12, 0xb1, 0xf1, 0xb3, 0x2e, 0x24,
766 },
767 .b = {
768 0xa7, 0xf5, 0x61, 0xe0, 0x38, 0xeb, 0x1e, 0xd5, 0x60, 0xb3,
769 0xd1, 0x47, 0xdb, 0x78, 0x20, 0x13, 0x06, 0x4c, 0x19, 0xf2,
770 0x7e, 0xd2, 0x7c, 0x67, 0x80, 0xaa, 0xf7, 0x7f, 0xb8, 0xa5,
771 0x47, 0xce, 0xb5, 0xb4, 0xfe, 0xf4, 0x22, 0x34, 0x03, 0x53,
772 },
773 .x = {
774 0x92, 0x5b, 0xe9, 0xfb, 0x01, 0xaf, 0xc6, 0xfb, 0x4d, 0x3e,
775 0x7d, 0x49, 0x90, 0x01, 0x0f, 0x81, 0x34, 0x08, 0xab, 0x10,
776 0x6c, 0x4f, 0x09, 0xcb, 0x7e, 0xe0, 0x78, 0x68, 0xcc, 0x13,
777 0x6f, 0xff, 0x33, 0x57, 0xf6, 0x24, 0xa2, 0x1b, 0xed, 0x52,
778 },
779 .y = {
780 0x63, 0xba, 0x3a, 0x7a, 0x27, 0x48, 0x3e, 0xbf, 0x66, 0x71,
781 0xdb, 0xef, 0x7a, 0xbb, 0x30, 0xeb, 0xee, 0x08, 0x4e, 0x58,
782 0xa0, 0xb0, 0x77, 0xad, 0x42, 0xa5, 0xa0, 0x98, 0x9d, 0x1e,
783 0xe7, 0x1b, 0x1b, 0x9b, 0xc0, 0x45, 0x5f, 0xb0, 0xd2, 0xc3,
784 },
785 .order = {
786 0xd3, 0x5e, 0x47, 0x20, 0x36, 0xbc, 0x4f, 0xb7, 0xe1, 0x3c,
787 0x78, 0x5e, 0xd2, 0x01, 0xe0, 0x65, 0xf9, 0x8f, 0xcf, 0xa5,
788 0xb6, 0x8f, 0x12, 0xa3, 0x2d, 0x48, 0x2e, 0xc7, 0xee, 0x86,
789 0x58, 0xe9, 0x86, 0x91, 0x55, 0x5b, 0x44, 0xc5, 0x93, 0x11,
790 },
791};
792
793static const struct {
794 uint8_t p[48];
795 uint8_t a[48];
796 uint8_t b[48];
797 uint8_t x[48];
798 uint8_t y[48];
799 uint8_t order[48];
800} _EC_brainpoolP384r1 = {
801 .p = {
802 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d,
803 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09,
804 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7,
805 0x11, 0x23, 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71,
806 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x53,
807 },
808 .a = {
809 0x7b, 0xc3, 0x82, 0xc6, 0x3d, 0x8c, 0x15, 0x0c, 0x3c, 0x72,
810 0x08, 0x0a, 0xce, 0x05, 0xaf, 0xa0, 0xc2, 0xbe, 0xa2, 0x8e,
811 0x4f, 0xb2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xef, 0xba, 0x91,
812 0xf9, 0x0f, 0x8a, 0xa5, 0x81, 0x4a, 0x50, 0x3a, 0xd4, 0xeb,
813 0x04, 0xa8, 0xc7, 0xdd, 0x22, 0xce, 0x28, 0x26,
814 },
815 .b = {
816 0x04, 0xa8, 0xc7, 0xdd, 0x22, 0xce, 0x28, 0x26, 0x8b, 0x39,
817 0xb5, 0x54, 0x16, 0xf0, 0x44, 0x7c, 0x2f, 0xb7, 0x7d, 0xe1,
818 0x07, 0xdc, 0xd2, 0xa6, 0x2e, 0x88, 0x0e, 0xa5, 0x3e, 0xeb,
819 0x62, 0xd5, 0x7c, 0xb4, 0x39, 0x02, 0x95, 0xdb, 0xc9, 0x94,
820 0x3a, 0xb7, 0x86, 0x96, 0xfa, 0x50, 0x4c, 0x11,
821 },
822 .x = {
823 0x1d, 0x1c, 0x64, 0xf0, 0x68, 0xcf, 0x45, 0xff, 0xa2, 0xa6,
824 0x3a, 0x81, 0xb7, 0xc1, 0x3f, 0x6b, 0x88, 0x47, 0xa3, 0xe7,
825 0x7e, 0xf1, 0x4f, 0xe3, 0xdb, 0x7f, 0xca, 0xfe, 0x0c, 0xbd,
826 0x10, 0xe8, 0xe8, 0x26, 0xe0, 0x34, 0x36, 0xd6, 0x46, 0xaa,
827 0xef, 0x87, 0xb2, 0xe2, 0x47, 0xd4, 0xaf, 0x1e,
828 },
829 .y = {
830 0x8a, 0xbe, 0x1d, 0x75, 0x20, 0xf9, 0xc2, 0xa4, 0x5c, 0xb1,
831 0xeb, 0x8e, 0x95, 0xcf, 0xd5, 0x52, 0x62, 0xb7, 0x0b, 0x29,
832 0xfe, 0xec, 0x58, 0x64, 0xe1, 0x9c, 0x05, 0x4f, 0xf9, 0x91,
833 0x29, 0x28, 0x0e, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11,
834 0x42, 0x82, 0x03, 0x41, 0x26, 0x3c, 0x53, 0x15,
835 },
836 .order = {
837 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d,
838 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09,
839 0xed, 0x54, 0x56, 0xb3, 0x1f, 0x16, 0x6e, 0x6c, 0xac, 0x04,
840 0x25, 0xa7, 0xcf, 0x3a, 0xb6, 0xaf, 0x6b, 0x7f, 0xc3, 0x10,
841 0x3b, 0x88, 0x32, 0x02, 0xe9, 0x04, 0x65, 0x65,
842 },
843};
844
845static const struct {
846 uint8_t p[48];
847 uint8_t a[48];
848 uint8_t b[48];
849 uint8_t x[48];
850 uint8_t y[48];
851 uint8_t order[48];
852} _EC_brainpoolP384t1 = {
853 .p = {
854 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d,
855 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09,
856 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7,
857 0x11, 0x23, 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71,
858 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x53,
859 },
860 .a = {
861 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d,
862 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09,
863 0xed, 0x54, 0x56, 0xb4, 0x12, 0xb1, 0xda, 0x19, 0x7f, 0xb7,
864 0x11, 0x23, 0xac, 0xd3, 0xa7, 0x29, 0x90, 0x1d, 0x1a, 0x71,
865 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xec, 0x50,
866 },
867 .b = {
868 0x7f, 0x51, 0x9e, 0xad, 0xa7, 0xbd, 0xa8, 0x1b, 0xd8, 0x26,
869 0xdb, 0xa6, 0x47, 0x91, 0x0f, 0x8c, 0x4b, 0x93, 0x46, 0xed,
870 0x8c, 0xcd, 0xc6, 0x4e, 0x4b, 0x1a, 0xbd, 0x11, 0x75, 0x6d,
871 0xce, 0x1d, 0x20, 0x74, 0xaa, 0x26, 0x3b, 0x88, 0x80, 0x5c,
872 0xed, 0x70, 0x35, 0x5a, 0x33, 0xb4, 0x71, 0xee,
873 },
874 .x = {
875 0x18, 0xde, 0x98, 0xb0, 0x2d, 0xb9, 0xa3, 0x06, 0xf2, 0xaf,
876 0xcd, 0x72, 0x35, 0xf7, 0x2a, 0x81, 0x9b, 0x80, 0xab, 0x12,
877 0xeb, 0xd6, 0x53, 0x17, 0x24, 0x76, 0xfe, 0xcd, 0x46, 0x2a,
878 0xab, 0xff, 0xc4, 0xff, 0x19, 0x1b, 0x94, 0x6a, 0x5f, 0x54,
879 0xd8, 0xd0, 0xaa, 0x2f, 0x41, 0x88, 0x08, 0xcc,
880 },
881 .y = {
882 0x25, 0xab, 0x05, 0x69, 0x62, 0xd3, 0x06, 0x51, 0xa1, 0x14,
883 0xaf, 0xd2, 0x75, 0x5a, 0xd3, 0x36, 0x74, 0x7f, 0x93, 0x47,
884 0x5b, 0x7a, 0x1f, 0xca, 0x3b, 0x88, 0xf2, 0xb6, 0xa2, 0x08,
885 0xcc, 0xfe, 0x46, 0x94, 0x08, 0x58, 0x4d, 0xc2, 0xb2, 0x91,
886 0x26, 0x75, 0xbf, 0x5b, 0x9e, 0x58, 0x29, 0x28,
887 },
888 .order = {
889 0x8c, 0xb9, 0x1e, 0x82, 0xa3, 0x38, 0x6d, 0x28, 0x0f, 0x5d,
890 0x6f, 0x7e, 0x50, 0xe6, 0x41, 0xdf, 0x15, 0x2f, 0x71, 0x09,
891 0xed, 0x54, 0x56, 0xb3, 0x1f, 0x16, 0x6e, 0x6c, 0xac, 0x04,
892 0x25, 0xa7, 0xcf, 0x3a, 0xb6, 0xaf, 0x6b, 0x7f, 0xc3, 0x10,
893 0x3b, 0x88, 0x32, 0x02, 0xe9, 0x04, 0x65, 0x65,
894 },
895};
896
897static const struct {
898 uint8_t p[64];
899 uint8_t a[64];
900 uint8_t b[64];
901 uint8_t x[64];
902 uint8_t y[64];
903 uint8_t order[64];
904} _EC_brainpoolP512r1 = {
905 .p = {
906 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4,
907 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3,
908 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33,
909 0x08, 0x71, 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42,
910 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, 0x28, 0x81,
911 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56,
912 0x58, 0x3a, 0x48, 0xf3,
913 },
914 .a = {
915 0x78, 0x30, 0xa3, 0x31, 0x8b, 0x60, 0x3b, 0x89, 0xe2, 0x32,
916 0x71, 0x45, 0xac, 0x23, 0x4c, 0xc5, 0x94, 0xcb, 0xdd, 0x8d,
917 0x3d, 0xf9, 0x16, 0x10, 0xa8, 0x34, 0x41, 0xca, 0xea, 0x98,
918 0x63, 0xbc, 0x2d, 0xed, 0x5d, 0x5a, 0xa8, 0x25, 0x3a, 0xa1,
919 0x0a, 0x2e, 0xf1, 0xc9, 0x8b, 0x9a, 0xc8, 0xb5, 0x7f, 0x11,
920 0x17, 0xa7, 0x2b, 0xf2, 0xc7, 0xb9, 0xe7, 0xc1, 0xac, 0x4d,
921 0x77, 0xfc, 0x94, 0xca,
922 },
923 .b = {
924 0x3d, 0xf9, 0x16, 0x10, 0xa8, 0x34, 0x41, 0xca, 0xea, 0x98,
925 0x63, 0xbc, 0x2d, 0xed, 0x5d, 0x5a, 0xa8, 0x25, 0x3a, 0xa1,
926 0x0a, 0x2e, 0xf1, 0xc9, 0x8b, 0x9a, 0xc8, 0xb5, 0x7f, 0x11,
927 0x17, 0xa7, 0x2b, 0xf2, 0xc7, 0xb9, 0xe7, 0xc1, 0xac, 0x4d,
928 0x77, 0xfc, 0x94, 0xca, 0xdc, 0x08, 0x3e, 0x67, 0x98, 0x40,
929 0x50, 0xb7, 0x5e, 0xba, 0xe5, 0xdd, 0x28, 0x09, 0xbd, 0x63,
930 0x80, 0x16, 0xf7, 0x23,
931 },
932 .x = {
933 0x81, 0xae, 0xe4, 0xbd, 0xd8, 0x2e, 0xd9, 0x64, 0x5a, 0x21,
934 0x32, 0x2e, 0x9c, 0x4c, 0x6a, 0x93, 0x85, 0xed, 0x9f, 0x70,
935 0xb5, 0xd9, 0x16, 0xc1, 0xb4, 0x3b, 0x62, 0xee, 0xf4, 0xd0,
936 0x09, 0x8e, 0xff, 0x3b, 0x1f, 0x78, 0xe2, 0xd0, 0xd4, 0x8d,
937 0x50, 0xd1, 0x68, 0x7b, 0x93, 0xb9, 0x7d, 0x5f, 0x7c, 0x6d,
938 0x50, 0x47, 0x40, 0x6a, 0x5e, 0x68, 0x8b, 0x35, 0x22, 0x09,
939 0xbc, 0xb9, 0xf8, 0x22,
940 },
941 .y = {
942 0x7d, 0xde, 0x38, 0x5d, 0x56, 0x63, 0x32, 0xec, 0xc0, 0xea,
943 0xbf, 0xa9, 0xcf, 0x78, 0x22, 0xfd, 0xf2, 0x09, 0xf7, 0x00,
944 0x24, 0xa5, 0x7b, 0x1a, 0xa0, 0x00, 0xc5, 0x5b, 0x88, 0x1f,
945 0x81, 0x11, 0xb2, 0xdc, 0xde, 0x49, 0x4a, 0x5f, 0x48, 0x5e,
946 0x5b, 0xca, 0x4b, 0xd8, 0x8a, 0x27, 0x63, 0xae, 0xd1, 0xca,
947 0x2b, 0x2f, 0xa8, 0xf0, 0x54, 0x06, 0x78, 0xcd, 0x1e, 0x0f,
948 0x3a, 0xd8, 0x08, 0x92,
949 },
950 .order = {
951 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4,
952 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3,
953 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33,
954 0x08, 0x70, 0x55, 0x3e, 0x5c, 0x41, 0x4c, 0xa9, 0x26, 0x19,
955 0x41, 0x86, 0x61, 0x19, 0x7f, 0xac, 0x10, 0x47, 0x1d, 0xb1,
956 0xd3, 0x81, 0x08, 0x5d, 0xda, 0xdd, 0xb5, 0x87, 0x96, 0x82,
957 0x9c, 0xa9, 0x00, 0x69,
958 },
959};
960
961static const struct {
962 uint8_t p[64];
963 uint8_t a[64];
964 uint8_t b[64];
965 uint8_t x[64];
966 uint8_t y[64];
967 uint8_t order[64];
968} _EC_brainpoolP512t1 = {
969 .p = {
970 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4,
971 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3,
972 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33,
973 0x08, 0x71, 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42,
974 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, 0x28, 0x81,
975 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56,
976 0x58, 0x3a, 0x48, 0xf3,
977 },
978 .a = {
979 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4,
980 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3,
981 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33,
982 0x08, 0x71, 0x7d, 0x4d, 0x9b, 0x00, 0x9b, 0xc6, 0x68, 0x42,
983 0xae, 0xcd, 0xa1, 0x2a, 0xe6, 0xa3, 0x80, 0xe6, 0x28, 0x81,
984 0xff, 0x2f, 0x2d, 0x82, 0xc6, 0x85, 0x28, 0xaa, 0x60, 0x56,
985 0x58, 0x3a, 0x48, 0xf0,
986 },
987 .b = {
988 0x7c, 0xbb, 0xbc, 0xf9, 0x44, 0x1c, 0xfa, 0xb7, 0x6e, 0x18,
989 0x90, 0xe4, 0x68, 0x84, 0xea, 0xe3, 0x21, 0xf7, 0x0c, 0x0b,
990 0xcb, 0x49, 0x81, 0x52, 0x78, 0x97, 0x50, 0x4b, 0xec, 0x3e,
991 0x36, 0xa6, 0x2b, 0xcd, 0xfa, 0x23, 0x04, 0x97, 0x65, 0x40,
992 0xf6, 0x45, 0x00, 0x85, 0xf2, 0xda, 0xe1, 0x45, 0xc2, 0x25,
993 0x53, 0xb4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0e, 0xa2, 0x57,
994 0x18, 0x67, 0x42, 0x3e,
995 },
996 .x = {
997 0x64, 0x0e, 0xce, 0x5c, 0x12, 0x78, 0x87, 0x17, 0xb9, 0xc1,
998 0xba, 0x06, 0xcb, 0xc2, 0xa6, 0xfe, 0xba, 0x85, 0x84, 0x24,
999 0x58, 0xc5, 0x6d, 0xde, 0x9d, 0xb1, 0x75, 0x8d, 0x39, 0xc0,
1000 0x31, 0x3d, 0x82, 0xba, 0x51, 0x73, 0x5c, 0xdb, 0x3e, 0xa4,
1001 0x99, 0xaa, 0x77, 0xa7, 0xd6, 0x94, 0x3a, 0x64, 0xf7, 0xa3,
1002 0xf2, 0x5f, 0xe2, 0x6f, 0x06, 0xb5, 0x1b, 0xaa, 0x26, 0x96,
1003 0xfa, 0x90, 0x35, 0xda,
1004 },
1005 .y = {
1006 0x5b, 0x53, 0x4b, 0xd5, 0x95, 0xf5, 0xaf, 0x0f, 0xa2, 0xc8,
1007 0x92, 0x37, 0x6c, 0x84, 0xac, 0xe1, 0xbb, 0x4e, 0x30, 0x19,
1008 0xb7, 0x16, 0x34, 0xc0, 0x11, 0x31, 0x15, 0x9c, 0xae, 0x03,
1009 0xce, 0xe9, 0xd9, 0x93, 0x21, 0x84, 0xbe, 0xef, 0x21, 0x6b,
1010 0xd7, 0x1d, 0xf2, 0xda, 0xdf, 0x86, 0xa6, 0x27, 0x30, 0x6e,
1011 0xcf, 0xf9, 0x6d, 0xbb, 0x8b, 0xac, 0xe1, 0x98, 0xb6, 0x1e,
1012 0x00, 0xf8, 0xb3, 0x32,
1013 },
1014 .order = {
1015 0xaa, 0xdd, 0x9d, 0xb8, 0xdb, 0xe9, 0xc4, 0x8b, 0x3f, 0xd4,
1016 0xe6, 0xae, 0x33, 0xc9, 0xfc, 0x07, 0xcb, 0x30, 0x8d, 0xb3,
1017 0xb3, 0xc9, 0xd2, 0x0e, 0xd6, 0x63, 0x9c, 0xca, 0x70, 0x33,
1018 0x08, 0x70, 0x55, 0x3e, 0x5c, 0x41, 0x4c, 0xa9, 0x26, 0x19,
1019 0x41, 0x86, 0x61, 0x19, 0x7f, 0xac, 0x10, 0x47, 0x1d, 0xb1,
1020 0xd3, 0x81, 0x08, 0x5d, 0xda, 0xdd, 0xb5, 0x87, 0x96, 0x82,
1021 0x9c, 0xa9, 0x00, 0x69,
1022 },
1023};
1024
1025static const struct {
1026 uint8_t p[32];
1027 uint8_t a[32];
1028 uint8_t b[32];
1029 uint8_t x[32];
1030 uint8_t y[32];
1031 uint8_t order[32];
1032} _EC_FRP256v1 = {
1033 .p = {
1034 0xf1, 0xfd, 0x17, 0x8c, 0x0b, 0x3a, 0xd5, 0x8f, 0x10, 0x12,
1035 0x6d, 0xe8, 0xce, 0x42, 0x43, 0x5b, 0x39, 0x61, 0xad, 0xbc,
1036 0xab, 0xc8, 0xca, 0x6d, 0xe8, 0xfc, 0xf3, 0x53, 0xd8, 0x6e,
1037 0x9c, 0x03,
1038 },
1039 .a = {
1040 0xf1, 0xfd, 0x17, 0x8c, 0x0b, 0x3a, 0xd5, 0x8f, 0x10, 0x12,
1041 0x6d, 0xe8, 0xce, 0x42, 0x43, 0x5b, 0x39, 0x61, 0xad, 0xbc,
1042 0xab, 0xc8, 0xca, 0x6d, 0xe8, 0xfc, 0xf3, 0x53, 0xd8, 0x6e,
1043 0x9c, 0x00,
1044 },
1045 .b = {
1046 0xee, 0x35, 0x3f, 0xca, 0x54, 0x28, 0xa9, 0x30, 0x0d, 0x4a,
1047 0xba, 0x75, 0x4a, 0x44, 0xc0, 0x0f, 0xdf, 0xec, 0x0c, 0x9a,
1048 0xe4, 0xb1, 0xa1, 0x80, 0x30, 0x75, 0xed, 0x96, 0x7b, 0x7b,
1049 0xb7, 0x3f,
1050 },
1051 .x = {
1052 0xb6, 0xb3, 0xd4, 0xc3, 0x56, 0xc1, 0x39, 0xeb, 0x31, 0x18,
1053 0x3d, 0x47, 0x49, 0xd4, 0x23, 0x95, 0x8c, 0x27, 0xd2, 0xdc,
1054 0xaf, 0x98, 0xb7, 0x01, 0x64, 0xc9, 0x7a, 0x2d, 0xd9, 0x8f,
1055 0x5c, 0xff,
1056 },
1057 .y = {
1058 0x61, 0x42, 0xe0, 0xf7, 0xc8, 0xb2, 0x04, 0x91, 0x1f, 0x92,
1059 0x71, 0xf0, 0xf3, 0xec, 0xef, 0x8c, 0x27, 0x01, 0xc3, 0x07,
1060 0xe8, 0xe4, 0xc9, 0xe1, 0x83, 0x11, 0x5a, 0x15, 0x54, 0x06,
1061 0x2c, 0xfb,
1062 },
1063 .order = {
1064 0xf1, 0xfd, 0x17, 0x8c, 0x0b, 0x3a, 0xd5, 0x8f, 0x10, 0x12,
1065 0x6d, 0xe8, 0xce, 0x42, 0x43, 0x5b, 0x53, 0xdc, 0x67, 0xe1,
1066 0x40, 0xd2, 0xbf, 0x94, 0x1f, 0xfd, 0xd4, 0x59, 0xc6, 0xd6,
1067 0x55, 0xe1,
1068 },
1069};
1070
1071static const struct ec_curve {
1072 const char *comment;
1073 int nid;
1074 int seed_len;
1075 int param_len;
1076 unsigned int cofactor;
1077 const uint8_t *seed;
1078 const uint8_t *p;
1079 const uint8_t *a;
1080 const uint8_t *b;
1081 const uint8_t *x;
1082 const uint8_t *y;
1083 const uint8_t *order;
1084} ec_curve_list[] = {
1085 /* secg curves */
1086 {
1087 .comment = "SECG curve secp224k1",
1088 .nid = NID_secp224k1,
1089 .param_len = sizeof(_EC_SECG_PRIME_224K1.p),
1090 .p = _EC_SECG_PRIME_224K1.p,
1091 .a = _EC_SECG_PRIME_224K1.a,
1092 .b = _EC_SECG_PRIME_224K1.b,
1093 .x = _EC_SECG_PRIME_224K1.x,
1094 .y = _EC_SECG_PRIME_224K1.y,
1095 .order = _EC_SECG_PRIME_224K1.order,
1096 .cofactor = 1,
1097 },
1098 {
1099 .comment = "NIST/SECG curve secp224r1",
1100 .nid = NID_secp224r1,
1101 .seed_len = sizeof(_EC_NIST_PRIME_224.seed),
1102 .param_len = sizeof(_EC_NIST_PRIME_224.p),
1103 .seed = _EC_NIST_PRIME_224.seed,
1104 .p = _EC_NIST_PRIME_224.p,
1105 .a = _EC_NIST_PRIME_224.a,
1106 .b = _EC_NIST_PRIME_224.b,
1107 .x = _EC_NIST_PRIME_224.x,
1108 .y = _EC_NIST_PRIME_224.y,
1109 .order = _EC_NIST_PRIME_224.order,
1110 .cofactor = 1,
1111 },
1112 {
1113 .comment = "SECG curve secp256k1",
1114 .nid = NID_secp256k1,
1115 .param_len = sizeof(_EC_SECG_PRIME_256K1.p),
1116 .p = _EC_SECG_PRIME_256K1.p,
1117 .a = _EC_SECG_PRIME_256K1.a,
1118 .b = _EC_SECG_PRIME_256K1.b,
1119 .x = _EC_SECG_PRIME_256K1.x,
1120 .y = _EC_SECG_PRIME_256K1.y,
1121 .order = _EC_SECG_PRIME_256K1.order,
1122 .cofactor = 1,
1123 },
1124 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
1125 {
1126 .comment = "NIST/SECG curve secp384r1",
1127 .nid = NID_secp384r1,
1128 .seed_len = sizeof(_EC_NIST_PRIME_384.seed),
1129 .param_len = sizeof(_EC_NIST_PRIME_384.p),
1130 .seed = _EC_NIST_PRIME_384.seed,
1131 .p = _EC_NIST_PRIME_384.p,
1132 .a = _EC_NIST_PRIME_384.a,
1133 .b = _EC_NIST_PRIME_384.b,
1134 .x = _EC_NIST_PRIME_384.x,
1135 .y = _EC_NIST_PRIME_384.y,
1136 .order = _EC_NIST_PRIME_384.order,
1137 .cofactor = 1,
1138 },
1139 {
1140 .comment = "NIST/SECG curve secp521r1",
1141 .nid = NID_secp521r1,
1142 .seed_len = sizeof(_EC_NIST_PRIME_521.seed),
1143 .param_len = sizeof(_EC_NIST_PRIME_521.p),
1144 .seed = _EC_NIST_PRIME_521.seed,
1145 .p = _EC_NIST_PRIME_521.p,
1146 .a = _EC_NIST_PRIME_521.a,
1147 .b = _EC_NIST_PRIME_521.b,
1148 .x = _EC_NIST_PRIME_521.x,
1149 .y = _EC_NIST_PRIME_521.y,
1150 .order = _EC_NIST_PRIME_521.order,
1151 .cofactor = 1,
1152 },
1153 /* X9.62 curves */
1154 {
1155 .comment = "X9.62 curve prime239v1",
1156 .nid = NID_X9_62_prime239v1,
1157 .seed_len = sizeof(_EC_X9_62_PRIME_239V1.seed),
1158 .param_len = sizeof(_EC_X9_62_PRIME_239V1.p),
1159 .seed = _EC_X9_62_PRIME_239V1.seed,
1160 .p = _EC_X9_62_PRIME_239V1.p,
1161 .a = _EC_X9_62_PRIME_239V1.a,
1162 .b = _EC_X9_62_PRIME_239V1.b,
1163 .x = _EC_X9_62_PRIME_239V1.x,
1164 .y = _EC_X9_62_PRIME_239V1.y,
1165 .order = _EC_X9_62_PRIME_239V1.order,
1166 .cofactor = 1,
1167 },
1168 {
1169 .comment = "X9.62 curve prime239v2",
1170 .nid = NID_X9_62_prime239v2,
1171 .seed_len = sizeof(_EC_X9_62_PRIME_239V2.seed),
1172 .param_len = sizeof(_EC_X9_62_PRIME_239V2.p),
1173 .seed = _EC_X9_62_PRIME_239V2.seed,
1174 .p = _EC_X9_62_PRIME_239V2.p,
1175 .a = _EC_X9_62_PRIME_239V2.a,
1176 .b = _EC_X9_62_PRIME_239V2.b,
1177 .x = _EC_X9_62_PRIME_239V2.x,
1178 .y = _EC_X9_62_PRIME_239V2.y,
1179 .order = _EC_X9_62_PRIME_239V2.order,
1180 .cofactor = 1,
1181 },
1182 {
1183 .comment = "X9.62 curve prime239v3",
1184 .nid = NID_X9_62_prime239v3,
1185 .seed_len = sizeof(_EC_X9_62_PRIME_239V3.seed),
1186 .param_len = sizeof(_EC_X9_62_PRIME_239V3.p),
1187 .seed = _EC_X9_62_PRIME_239V3.seed,
1188 .p = _EC_X9_62_PRIME_239V3.p,
1189 .a = _EC_X9_62_PRIME_239V3.a,
1190 .b = _EC_X9_62_PRIME_239V3.b,
1191 .x = _EC_X9_62_PRIME_239V3.x,
1192 .y = _EC_X9_62_PRIME_239V3.y,
1193 .order = _EC_X9_62_PRIME_239V3.order,
1194 .cofactor = 1,
1195 },
1196 {
1197 .comment = "X9.62/SECG curve prime256v1",
1198 .nid = NID_X9_62_prime256v1,
1199 .seed_len = sizeof(_EC_X9_62_PRIME_256V1.seed),
1200 .param_len = sizeof(_EC_X9_62_PRIME_256V1.p),
1201 .seed = _EC_X9_62_PRIME_256V1.seed,
1202 .p = _EC_X9_62_PRIME_256V1.p,
1203 .a = _EC_X9_62_PRIME_256V1.a,
1204 .b = _EC_X9_62_PRIME_256V1.b,
1205 .x = _EC_X9_62_PRIME_256V1.x,
1206 .y = _EC_X9_62_PRIME_256V1.y,
1207 .order = _EC_X9_62_PRIME_256V1.order,
1208 .cofactor = 1,
1209 },
1210 /* RFC 5639 curves */
1211 {
1212 .comment = "RFC 5639 curve brainpoolP224r1",
1213 .nid = NID_brainpoolP224r1,
1214 .param_len = sizeof(_EC_brainpoolP224r1.p),
1215 .p = _EC_brainpoolP224r1.p,
1216 .a = _EC_brainpoolP224r1.a,
1217 .b = _EC_brainpoolP224r1.b,
1218 .x = _EC_brainpoolP224r1.x,
1219 .y = _EC_brainpoolP224r1.y,
1220 .order = _EC_brainpoolP224r1.order,
1221 .cofactor = 1,
1222 },
1223 {
1224 .comment = "RFC 5639 curve brainpoolP224r2",
1225 .nid = NID_brainpoolP224t1,
1226 .param_len = sizeof(_EC_brainpoolP224t1.p),
1227 .p = _EC_brainpoolP224t1.p,
1228 .a = _EC_brainpoolP224t1.a,
1229 .b = _EC_brainpoolP224t1.b,
1230 .x = _EC_brainpoolP224t1.x,
1231 .y = _EC_brainpoolP224t1.y,
1232 .order = _EC_brainpoolP224t1.order,
1233 .cofactor = 1,
1234 },
1235 {
1236 .comment = "RFC 5639 curve brainpoolP256r1",
1237 .nid = NID_brainpoolP256r1,
1238 .param_len = sizeof(_EC_brainpoolP256r1.p),
1239 .p = _EC_brainpoolP256r1.p,
1240 .a = _EC_brainpoolP256r1.a,
1241 .b = _EC_brainpoolP256r1.b,
1242 .x = _EC_brainpoolP256r1.x,
1243 .y = _EC_brainpoolP256r1.y,
1244 .order = _EC_brainpoolP256r1.order,
1245 .cofactor = 1,
1246 },
1247 {
1248 .comment = "RFC 5639 curve brainpoolP256t1",
1249 .nid = NID_brainpoolP256t1,
1250 .param_len = sizeof(_EC_brainpoolP256t1.p),
1251 .p = _EC_brainpoolP256t1.p,
1252 .a = _EC_brainpoolP256t1.a,
1253 .b = _EC_brainpoolP256t1.b,
1254 .x = _EC_brainpoolP256t1.x,
1255 .y = _EC_brainpoolP256t1.y,
1256 .order = _EC_brainpoolP256t1.order,
1257 .cofactor = 1,
1258 },
1259 {
1260 .comment = "RFC 5639 curve brainpoolP320r1",
1261 .nid = NID_brainpoolP320r1,
1262 .param_len = sizeof(_EC_brainpoolP320r1.p),
1263 .p = _EC_brainpoolP320r1.p,
1264 .a = _EC_brainpoolP320r1.a,
1265 .b = _EC_brainpoolP320r1.b,
1266 .x = _EC_brainpoolP320r1.x,
1267 .y = _EC_brainpoolP320r1.y,
1268 .order = _EC_brainpoolP320r1.order,
1269 .cofactor = 1,
1270 },
1271 {
1272 .comment = "RFC 5639 curve brainpoolP320t1",
1273 .nid = NID_brainpoolP320t1,
1274 .param_len = sizeof(_EC_brainpoolP320t1.p),
1275 .p = _EC_brainpoolP320t1.p,
1276 .a = _EC_brainpoolP320t1.a,
1277 .b = _EC_brainpoolP320t1.b,
1278 .x = _EC_brainpoolP320t1.x,
1279 .y = _EC_brainpoolP320t1.y,
1280 .order = _EC_brainpoolP320t1.order,
1281 .cofactor = 1,
1282 },
1283 {
1284 .comment = "RFC 5639 curve brainpoolP384r1",
1285 .nid = NID_brainpoolP384r1,
1286 .param_len = sizeof(_EC_brainpoolP384r1.p),
1287 .p = _EC_brainpoolP384r1.p,
1288 .a = _EC_brainpoolP384r1.a,
1289 .b = _EC_brainpoolP384r1.b,
1290 .x = _EC_brainpoolP384r1.x,
1291 .y = _EC_brainpoolP384r1.y,
1292 .order = _EC_brainpoolP384r1.order,
1293 .cofactor = 1,
1294 },
1295 {
1296 .comment = "RFC 5639 curve brainpoolP384t1",
1297 .nid = NID_brainpoolP384t1,
1298 .param_len = sizeof(_EC_brainpoolP384t1.p),
1299 .p = _EC_brainpoolP384t1.p,
1300 .a = _EC_brainpoolP384t1.a,
1301 .b = _EC_brainpoolP384t1.b,
1302 .x = _EC_brainpoolP384t1.x,
1303 .y = _EC_brainpoolP384t1.y,
1304 .order = _EC_brainpoolP384t1.order,
1305 .cofactor = 1,
1306 },
1307 {
1308 .comment = "RFC 5639 curve brainpoolP512r1",
1309 .nid = NID_brainpoolP512r1,
1310 .param_len = sizeof(_EC_brainpoolP512r1.p),
1311 .p = _EC_brainpoolP512r1.p,
1312 .a = _EC_brainpoolP512r1.a,
1313 .b = _EC_brainpoolP512r1.b,
1314 .x = _EC_brainpoolP512r1.x,
1315 .y = _EC_brainpoolP512r1.y,
1316 .order = _EC_brainpoolP512r1.order,
1317 .cofactor = 1,
1318 },
1319 {
1320 .comment = "RFC 5639 curve brainpoolP512t1",
1321 .nid = NID_brainpoolP512t1,
1322 .param_len = sizeof(_EC_brainpoolP512t1.p),
1323 .p = _EC_brainpoolP512t1.p,
1324 .a = _EC_brainpoolP512t1.a,
1325 .b = _EC_brainpoolP512t1.b,
1326 .x = _EC_brainpoolP512t1.x,
1327 .y = _EC_brainpoolP512t1.y,
1328 .order = _EC_brainpoolP512t1.order,
1329 .cofactor = 1,
1330 },
1331 /* ANSSI */
1332 {
1333 .comment = "ANSSI curve FRP256v1",
1334 .nid = NID_FRP256v1,
1335 .param_len = sizeof(_EC_FRP256v1.p),
1336 .p = _EC_FRP256v1.p,
1337 .a = _EC_FRP256v1.a,
1338 .b = _EC_FRP256v1.b,
1339 .x = _EC_FRP256v1.x,
1340 .y = _EC_FRP256v1.y,
1341 .order = _EC_FRP256v1.order,
1342 .cofactor = 1,
1343 },
1344};
1345
1346#define EC_CURVE_LIST_LENGTH (sizeof(ec_curve_list) / sizeof(ec_curve_list[0]))
1347
1348static EC_GROUP *
1349ec_group_new_from_data(const struct ec_curve *curve)
1350{
1351 EC_GROUP *group = NULL, *ret = NULL;
1352 EC_POINT *generator = NULL;
1353 BN_CTX *ctx = NULL;
1354 BIGNUM *p, *a, *b, *x, *y, *order, *cofactor;
1355
1356 if ((ctx = BN_CTX_new()) == NULL) {
1357 ECerror(ERR_R_MALLOC_FAILURE);
1358 goto err;
1359 }
1360 BN_CTX_start(ctx);
1361
1362 if ((p = BN_CTX_get(ctx)) == NULL) {
1363 ECerror(ERR_R_BN_LIB);
1364 goto err;
1365 }
1366 if ((a = BN_CTX_get(ctx)) == NULL) {
1367 ECerror(ERR_R_BN_LIB);
1368 goto err;
1369 }
1370 if ((b = BN_CTX_get(ctx)) == NULL) {
1371 ECerror(ERR_R_BN_LIB);
1372 goto err;
1373 }
1374 if ((x = BN_CTX_get(ctx)) == NULL) {
1375 ECerror(ERR_R_BN_LIB);
1376 goto err;
1377 }
1378 if ((y = BN_CTX_get(ctx)) == NULL) {
1379 ECerror(ERR_R_BN_LIB);
1380 goto err;
1381 }
1382 if ((order = BN_CTX_get(ctx)) == NULL) {
1383 ECerror(ERR_R_BN_LIB);
1384 goto err;
1385 }
1386 if ((cofactor = BN_CTX_get(ctx)) == NULL) {
1387 ECerror(ERR_R_BN_LIB);
1388 goto err;
1389 }
1390
1391 if (BN_bin2bn(curve->p, curve->param_len, p) == NULL) {
1392 ECerror(ERR_R_BN_LIB);
1393 goto err;
1394 }
1395 if (BN_bin2bn(curve->a, curve->param_len, a) == NULL) {
1396 ECerror(ERR_R_BN_LIB);
1397 goto err;
1398 }
1399 if (BN_bin2bn(curve->b, curve->param_len, b) == NULL) {
1400 ECerror(ERR_R_BN_LIB);
1401 goto err;
1402 }
1403 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
1404 ECerror(ERR_R_EC_LIB);
1405 goto err;
1406 }
1407 EC_GROUP_set_curve_name(group, curve->nid);
1408
1409 if ((generator = EC_POINT_new(group)) == NULL) {
1410 ECerror(ERR_R_EC_LIB);
1411 goto err;
1412 }
1413 if (BN_bin2bn(curve->x, curve->param_len, x) == NULL) {
1414 ECerror(ERR_R_BN_LIB);
1415 goto err;
1416 }
1417 if (BN_bin2bn(curve->y, curve->param_len, y) == NULL) {
1418 ECerror(ERR_R_BN_LIB);
1419 goto err;
1420 }
1421 if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx)) {
1422 ECerror(ERR_R_EC_LIB);
1423 goto err;
1424 }
1425 if (BN_bin2bn(curve->order, curve->param_len, order) == NULL) {
1426 ECerror(ERR_R_EC_LIB);
1427 goto err;
1428 }
1429 if (!BN_set_word(cofactor, curve->cofactor)) {
1430 ECerror(ERR_R_BN_LIB);
1431 goto err;
1432 }
1433 if (!EC_GROUP_set_generator(group, generator, order, cofactor)) {
1434 ECerror(ERR_R_EC_LIB);
1435 goto err;
1436 }
1437
1438 if (curve->seed != NULL) {
1439 if (!EC_GROUP_set_seed(group, curve->seed, curve->seed_len)) {
1440 ECerror(ERR_R_EC_LIB);
1441 goto err;
1442 }
1443 }
1444
1445 ret = group;
1446 group = NULL;
1447
1448 err:
1449 EC_GROUP_free(group);
1450 EC_POINT_free(generator);
1451 BN_CTX_end(ctx);
1452 BN_CTX_free(ctx);
1453
1454 return ret;
1455}
1456
1457EC_GROUP *
1458EC_GROUP_new_by_curve_name(int nid)
1459{
1460 size_t i;
1461
1462 if (nid <= 0)
1463 return NULL;
1464
1465 for (i = 0; i < EC_CURVE_LIST_LENGTH; i++) {
1466 if (ec_curve_list[i].nid == nid)
1467 return ec_group_new_from_data(&ec_curve_list[i]);
1468 }
1469
1470 ECerror(EC_R_UNKNOWN_GROUP);
1471 return NULL;
1472}
1473LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name);
1474
1475static void
1476ec_curve_free(struct ec_curve *curve)
1477{
1478 if (curve == NULL)
1479 return;
1480
1481 /* PERM UGLY CASTS */
1482 free((uint8_t *)curve->seed);
1483 free((uint8_t *)curve->p);
1484 free((uint8_t *)curve->a);
1485 free((uint8_t *)curve->b);
1486 free((uint8_t *)curve->x);
1487 free((uint8_t *)curve->y);
1488 free((uint8_t *)curve->order);
1489
1490 free(curve);
1491}
1492
1493static int
1494ec_curve_encode_parameter(const BIGNUM *bn, int param_len,
1495 const uint8_t **out_param)
1496{
1497 uint8_t *buf = NULL;
1498 int ret = 0;
1499
1500 if (out_param == NULL || *out_param != NULL)
1501 goto err;
1502
1503 if ((buf = calloc(1, param_len)) == NULL)
1504 goto err;
1505 if (BN_bn2binpad(bn, buf, param_len) != param_len)
1506 goto err;
1507
1508 *out_param = buf;
1509 buf = NULL;
1510
1511 ret = 1;
1512
1513 err:
1514 free(buf);
1515
1516 return ret;
1517}
1518
1519static struct ec_curve *
1520ec_curve_from_group(const EC_GROUP *group)
1521{
1522 struct ec_curve *curve = NULL;
1523 BN_CTX *ctx;
1524 BIGNUM *p, *a, *b, *x, *y;
1525 const EC_POINT *generator = NULL;
1526 const BIGNUM *order, *cofactor;
1527 size_t seed_len;
1528
1529 if ((ctx = BN_CTX_new()) == NULL)
1530 goto err;
1531 BN_CTX_start(ctx);
1532
1533 if ((p = BN_CTX_get(ctx)) == NULL)
1534 goto err;
1535 if ((a = BN_CTX_get(ctx)) == NULL)
1536 goto err;
1537 if ((b = BN_CTX_get(ctx)) == NULL)
1538 goto err;
1539 if ((x = BN_CTX_get(ctx)) == NULL)
1540 goto err;
1541 if ((y = BN_CTX_get(ctx)) == NULL)
1542 goto err;
1543
1544 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
1545 goto err;
1546 if ((generator = EC_GROUP_get0_generator(group)) == NULL)
1547 goto err;
1548 if (!EC_POINT_get_affine_coordinates(group, generator, x, y, ctx))
1549 goto err;
1550 if ((order = EC_GROUP_get0_order(group)) == NULL)
1551 goto err;
1552
1553 if ((curve = calloc(1, sizeof(*curve))) == NULL)
1554 goto err;
1555
1556 curve->param_len = BN_num_bytes(p);
1557 if (BN_num_bytes(order) > curve->param_len)
1558 curve->param_len = BN_num_bytes(order);
1559
1560 if (!ec_curve_encode_parameter(p, curve->param_len, &curve->p))
1561 goto err;
1562 if (!ec_curve_encode_parameter(a, curve->param_len, &curve->a))
1563 goto err;
1564 if (!ec_curve_encode_parameter(b, curve->param_len, &curve->b))
1565 goto err;
1566 if (!ec_curve_encode_parameter(x, curve->param_len, &curve->x))
1567 goto err;
1568 if (!ec_curve_encode_parameter(y, curve->param_len, &curve->y))
1569 goto err;
1570 if (!ec_curve_encode_parameter(order, curve->param_len, &curve->order))
1571 goto err;
1572
1573 if ((cofactor = EC_GROUP_get0_cofactor(group)) != NULL) {
1574 BN_ULONG cofactor_word;
1575
1576 if ((cofactor_word = BN_get_word(cofactor)) == BN_MASK2)
1577 goto err;
1578 if (cofactor_word > INT_MAX)
1579 goto err;
1580
1581 curve->cofactor = cofactor_word;
1582 }
1583
1584 if ((seed_len = EC_GROUP_get_seed_len(group)) > 0) {
1585 uint8_t *seed;
1586
1587 if (seed_len > INT_MAX)
1588 goto err;
1589 if ((seed = calloc(1, seed_len)) == NULL)
1590 goto err;
1591 memcpy(seed, EC_GROUP_get0_seed(group), seed_len);
1592
1593 curve->seed = seed;
1594 curve->seed_len = seed_len;
1595 }
1596
1597 BN_CTX_end(ctx);
1598 BN_CTX_free(ctx);
1599
1600 return curve;
1601
1602 err:
1603 BN_CTX_end(ctx);
1604 BN_CTX_free(ctx);
1605
1606 ec_curve_free(curve);
1607
1608 return NULL;
1609}
1610
1611static int
1612ec_curve_cmp(const struct ec_curve *a, const struct ec_curve *b)
1613{
1614 int cmp;
1615
1616 /* Treat nid as optional. The OID isn't part of EC parameters. */
1617 if (a->nid != NID_undef && b->nid != NID_undef) {
1618 if (a->nid < b->nid)
1619 return -1;
1620 if (a->nid > b->nid)
1621 return 1;
1622 }
1623
1624 if (a->cofactor < b->cofactor)
1625 return -1;
1626 if (a->cofactor > b->cofactor)
1627 return 1;
1628 if (a->param_len < b->param_len)
1629 return -1;
1630 if (a->param_len > b->param_len)
1631 return 1;
1632
1633 if ((cmp = memcmp(a->p, b->p, a->param_len)) != 0)
1634 return cmp;
1635 if ((cmp = memcmp(a->a, b->a, a->param_len)) != 0)
1636 return cmp;
1637 if ((cmp = memcmp(a->b, b->b, a->param_len)) != 0)
1638 return cmp;
1639 if ((cmp = memcmp(a->x, b->x, a->param_len)) != 0)
1640 return cmp;
1641 if ((cmp = memcmp(a->y, b->y, a->param_len)) != 0)
1642 return cmp;
1643 if ((cmp = memcmp(a->order, b->order, a->param_len)) != 0)
1644 return cmp;
1645
1646 /* Seed is optional, not used for computation. Must match if present. */
1647 if (a->seed_len != 0 && b->seed_len != 0) {
1648 if (a->seed_len < b->seed_len)
1649 return -1;
1650 if (a->seed_len > b->seed_len)
1651 return 1;
1652 if (a->seed != NULL && b->seed != NULL) {
1653 if ((cmp = memcmp(a->seed, b->seed, a->seed_len)) != 0)
1654 return cmp;
1655 }
1656 }
1657
1658 return 0;
1659}
1660
1661static int
1662ec_group_nid_from_curve(const struct ec_curve *curve)
1663{
1664 size_t i;
1665
1666 for (i = 0; i < EC_CURVE_LIST_LENGTH; i++) {
1667 if (ec_curve_cmp(curve, &ec_curve_list[i]) == 0)
1668 return ec_curve_list[i].nid;
1669 }
1670
1671 return NID_undef;
1672}
1673
1674int
1675ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid)
1676{
1677 struct ec_curve *curve;
1678 int ret = 0;
1679 int nid;
1680
1681 *out_nid = NID_undef;
1682
1683 if ((curve = ec_curve_from_group(group)) == NULL)
1684 goto err;
1685 if ((nid = ec_group_nid_from_curve(curve)) == NID_undef)
1686 goto err;
1687
1688 *out_nid = nid;
1689
1690 ret = 1;
1691
1692 err:
1693 ec_curve_free(curve);
1694
1695 return ret;
1696}
1697
1698size_t
1699EC_get_builtin_curves(EC_builtin_curve *curves, size_t nitems)
1700{
1701 size_t i;
1702
1703 if (curves == NULL || nitems == 0)
1704 return EC_CURVE_LIST_LENGTH;
1705
1706 if (nitems > EC_CURVE_LIST_LENGTH)
1707 nitems = EC_CURVE_LIST_LENGTH;
1708
1709 for (i = 0; i < nitems; i++) {
1710 curves[i].nid = ec_curve_list[i].nid;
1711 curves[i].comment = ec_curve_list[i].comment;
1712 }
1713
1714 return EC_CURVE_LIST_LENGTH;
1715}
1716LCRYPTO_ALIAS(EC_get_builtin_curves);
1717
1718static const struct {
1719 const char *name;
1720 int nid;
1721} nist_curves[] = {
1722 { "B-163", NID_sect163r2 },
1723 { "B-233", NID_sect233r1 },
1724 { "B-283", NID_sect283r1 },
1725 { "B-409", NID_sect409r1 },
1726 { "B-571", NID_sect571r1 },
1727 { "K-163", NID_sect163k1 },
1728 { "K-233", NID_sect233k1 },
1729 { "K-283", NID_sect283k1 },
1730 { "K-409", NID_sect409k1 },
1731 { "K-571", NID_sect571k1 },
1732 { "P-192", NID_X9_62_prime192v1 },
1733 { "P-224", NID_secp224r1 },
1734 { "P-256", NID_X9_62_prime256v1 },
1735 { "P-384", NID_secp384r1 },
1736 { "P-521", NID_secp521r1 }
1737};
1738
1739const char *
1740EC_curve_nid2nist(int nid)
1741{
1742 size_t i;
1743
1744 for (i = 0; i < sizeof(nist_curves) / sizeof(nist_curves[0]); i++) {
1745 if (nist_curves[i].nid == nid)
1746 return nist_curves[i].name;
1747 }
1748
1749 return NULL;
1750}
1751LCRYPTO_ALIAS(EC_curve_nid2nist);
1752
1753int
1754EC_curve_nist2nid(const char *name)
1755{
1756 size_t i;
1757
1758 for (i = 0; i < sizeof(nist_curves) / sizeof(nist_curves[0]); i++) {
1759 if (strcmp(nist_curves[i].name, name) == 0)
1760 return nist_curves[i].nid;
1761 }
1762
1763 return NID_undef;
1764}
1765LCRYPTO_ALIAS(EC_curve_nist2nid);
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
deleted file mode 100644
index 2a6c419b57..0000000000
--- a/src/lib/libcrypto/ec/ec_err.c
+++ /dev/null
@@ -1,151 +0,0 @@
1/* $OpenBSD: ec_err.c,v 1.20 2024/06/24 06:43:22 tb Exp $ */
2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <stdio.h>
57
58#include <openssl/opensslconf.h>
59
60#include <openssl/err.h>
61#include <openssl/ec.h>
62
63#include "err_local.h"
64
65#ifndef OPENSSL_NO_ERR
66
67#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
68#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
69
70static const ERR_STRING_DATA EC_str_functs[] = {
71 {ERR_FUNC(0xfff), "CRYPTO_internal"},
72 {0, NULL}
73};
74
75static const ERR_STRING_DATA EC_str_reasons[] = {
76 {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
77 {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"},
78 {ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"},
79 {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
80 {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
81 {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
82 {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), "d2i ecpkparameters failure"},
83 {ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
84 {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
85 {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"},
86 {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
87 {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
88 {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), "group2pkparameters failure"},
89 {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), "i2d ecpkparameters failure"},
90 {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
91 {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
92 {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
93 {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
94 {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
95 {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"},
96 {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
97 {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
98 {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
99 {ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
100 {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
101 {ERR_REASON(EC_R_INVALID_KEY), "invalid key"},
102 {ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"},
103 {ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"},
104 {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
105 {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
106 {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
107 {ERR_REASON(EC_R_KDF_FAILED), "kdf failed"},
108 {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
109 {ERR_REASON(EC_R_KEY_TRUNCATION), "key would be truncated"},
110 {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
111 {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
112 {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
113 {ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
114 {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
115 {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), "not a supported NIST prime"},
116 {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
117 {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
118 {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"},
119 {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
120 {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
121 {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
122 {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"},
123 {ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
124 {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
125 {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
126 {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
127 {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
128 {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
129 {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
130 {ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"},
131 {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
132 {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
133 {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
134 {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
135 {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
136 {0, NULL}
137};
138
139#endif
140
141void
142ERR_load_EC_strings(void)
143{
144#ifndef OPENSSL_NO_ERR
145 if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
146 ERR_load_const_strings(EC_str_functs);
147 ERR_load_const_strings(EC_str_reasons);
148 }
149#endif
150}
151LCRYPTO_ALIAS(ERR_load_EC_strings);
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
deleted file mode 100644
index 6257d67cd1..0000000000
--- a/src/lib/libcrypto/ec/ec_key.c
+++ /dev/null
@@ -1,809 +0,0 @@
1/* $OpenBSD: ec_key.c,v 1.51 2025/01/25 10:34:36 tb Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 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 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61 * contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65
66#include <openssl/opensslconf.h>
67
68#include <openssl/ec.h>
69#include <openssl/err.h>
70
71#include "bn_local.h"
72#include "ec_local.h"
73#include "ecdsa_local.h"
74
75EC_KEY *
76EC_KEY_new(void)
77{
78 return EC_KEY_new_method(NULL);
79}
80LCRYPTO_ALIAS(EC_KEY_new);
81
82EC_KEY *
83EC_KEY_new_by_curve_name(int nid)
84{
85 EC_KEY *ec_key;
86
87 if ((ec_key = EC_KEY_new()) == NULL)
88 goto err;
89
90 if ((ec_key->group = EC_GROUP_new_by_curve_name(nid)) == NULL)
91 goto err;
92
93 /* XXX - do we want an ec_key_set0_group()? */
94 if (ec_key->meth->set_group != NULL) {
95 if (!ec_key->meth->set_group(ec_key, ec_key->group))
96 goto err;
97 }
98
99 return ec_key;
100
101 err:
102 EC_KEY_free(ec_key);
103
104 return NULL;
105}
106LCRYPTO_ALIAS(EC_KEY_new_by_curve_name);
107
108void
109EC_KEY_free(EC_KEY *ec_key)
110{
111 if (ec_key == NULL)
112 return;
113
114 if (CRYPTO_add(&ec_key->references, -1, CRYPTO_LOCK_EC) > 0)
115 return;
116
117 if (ec_key->meth != NULL && ec_key->meth->finish != NULL)
118 ec_key->meth->finish(ec_key);
119
120 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, ec_key, &ec_key->ex_data);
121
122 EC_GROUP_free(ec_key->group);
123 EC_POINT_free(ec_key->pub_key);
124 BN_free(ec_key->priv_key);
125
126 freezero(ec_key, sizeof(*ec_key));
127}
128LCRYPTO_ALIAS(EC_KEY_free);
129
130EC_KEY *
131EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
132{
133 if (dest == NULL || src == NULL) {
134 ECerror(ERR_R_PASSED_NULL_PARAMETER);
135 return NULL;
136 }
137
138 if (src->meth != dest->meth) {
139 if (dest->meth != NULL && dest->meth->finish != NULL)
140 dest->meth->finish(dest);
141 }
142
143 if (src->group != NULL) {
144 EC_GROUP_free(dest->group);
145 if ((dest->group = EC_GROUP_dup(src->group)) == NULL)
146 return NULL;
147 if (src->pub_key != NULL) {
148 EC_POINT_free(dest->pub_key);
149 if ((dest->pub_key = EC_POINT_dup(src->pub_key,
150 src->group)) == NULL)
151 return NULL;
152 }
153 }
154
155 BN_free(dest->priv_key);
156 dest->priv_key = NULL;
157 if (src->priv_key != NULL) {
158 if ((dest->priv_key = BN_dup(src->priv_key)) == NULL)
159 return NULL;
160 }
161
162 dest->enc_flag = src->enc_flag;
163 dest->conv_form = src->conv_form;
164 dest->version = src->version;
165 dest->flags = src->flags;
166
167 /*
168 * The fun part about being a toolkit implementer is that the rest of
169 * the world gets to live with your terrible API design choices for
170 * eternity. (To be fair: the signature was changed in OpenSSL 3).
171 */
172 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data,
173 &((EC_KEY *)src)->ex_data)) /* XXX const */
174 return NULL;
175
176 dest->meth = src->meth;
177
178 if (src->meth != NULL && src->meth->copy != NULL) {
179 if (!src->meth->copy(dest, src))
180 return NULL;
181 }
182
183 return dest;
184}
185LCRYPTO_ALIAS(EC_KEY_copy);
186
187EC_KEY *
188EC_KEY_dup(const EC_KEY *in_ec_key)
189{
190 EC_KEY *ec_key;
191
192 /* XXX - Pass NULL - so we're perhaps not running the right init()? */
193 if ((ec_key = EC_KEY_new_method(NULL)) == NULL)
194 goto err;
195 if (EC_KEY_copy(ec_key, in_ec_key) == NULL)
196 goto err;
197
198 return ec_key;
199
200 err:
201 EC_KEY_free(ec_key);
202
203 return NULL;
204}
205LCRYPTO_ALIAS(EC_KEY_dup);
206
207int
208EC_KEY_up_ref(EC_KEY *r)
209{
210 return CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC) > 1;
211}
212LCRYPTO_ALIAS(EC_KEY_up_ref);
213
214int
215EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg)
216{
217 return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
218}
219LCRYPTO_ALIAS(EC_KEY_set_ex_data);
220
221void *
222EC_KEY_get_ex_data(const EC_KEY *r, int idx)
223{
224 return CRYPTO_get_ex_data(&r->ex_data, idx);
225}
226LCRYPTO_ALIAS(EC_KEY_get_ex_data);
227
228int
229EC_KEY_generate_key(EC_KEY *eckey)
230{
231 if (eckey->meth->keygen != NULL)
232 return eckey->meth->keygen(eckey);
233 ECerror(EC_R_NOT_IMPLEMENTED);
234 return 0;
235}
236LCRYPTO_ALIAS(EC_KEY_generate_key);
237
238static int
239ec_key_gen(EC_KEY *eckey)
240{
241 BIGNUM *priv_key = NULL;
242 EC_POINT *pub_key = NULL;
243 const BIGNUM *order;
244 int ret = 0;
245
246 if (eckey == NULL || eckey->group == NULL) {
247 ECerror(ERR_R_PASSED_NULL_PARAMETER);
248 goto err;
249 }
250
251 if ((priv_key = BN_new()) == NULL)
252 goto err;
253 if ((pub_key = EC_POINT_new(eckey->group)) == NULL)
254 goto err;
255
256 if ((order = EC_GROUP_get0_order(eckey->group)) == NULL)
257 goto err;
258 if (!bn_rand_interval(priv_key, 1, order))
259 goto err;
260 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL))
261 goto err;
262
263 BN_free(eckey->priv_key);
264 eckey->priv_key = priv_key;
265 priv_key = NULL;
266
267 EC_POINT_free(eckey->pub_key);
268 eckey->pub_key = pub_key;
269 pub_key = NULL;
270
271 ret = 1;
272
273 err:
274 EC_POINT_free(pub_key);
275 BN_free(priv_key);
276
277 return ret;
278}
279
280int
281EC_KEY_check_key(const EC_KEY *eckey)
282{
283 BN_CTX *ctx = NULL;
284 EC_POINT *point = NULL;
285 const BIGNUM *order;
286 int ret = 0;
287
288 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
289 ECerror(ERR_R_PASSED_NULL_PARAMETER);
290 goto err;
291 }
292
293 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
294 ECerror(EC_R_POINT_AT_INFINITY);
295 goto err;
296 }
297
298 if ((ctx = BN_CTX_new()) == NULL)
299 goto err;
300
301 if ((point = EC_POINT_new(eckey->group)) == NULL)
302 goto err;
303
304 /* Ensure public key is on the elliptic curve. */
305 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
306 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
307 goto err;
308 }
309
310 /* Ensure public key multiplied by the order is the point at infinity. */
311 if ((order = EC_GROUP_get0_order(eckey->group)) == NULL) {
312 ECerror(EC_R_INVALID_GROUP_ORDER);
313 goto err;
314 }
315 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
316 ECerror(ERR_R_EC_LIB);
317 goto err;
318 }
319 if (!EC_POINT_is_at_infinity(eckey->group, point)) {
320 ECerror(EC_R_WRONG_ORDER);
321 goto err;
322 }
323
324 /*
325 * If the private key is present, ensure that the private key multiplied
326 * by the generator matches the public key.
327 */
328 if (eckey->priv_key != NULL) {
329 if (BN_cmp(eckey->priv_key, order) >= 0) {
330 ECerror(EC_R_WRONG_ORDER);
331 goto err;
332 }
333 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL,
334 NULL, ctx)) {
335 ECerror(ERR_R_EC_LIB);
336 goto err;
337 }
338 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
339 ctx) != 0) {
340 ECerror(EC_R_INVALID_PRIVATE_KEY);
341 goto err;
342 }
343 }
344
345 ret = 1;
346
347 err:
348 BN_CTX_free(ctx);
349 EC_POINT_free(point);
350
351 return ret;
352}
353LCRYPTO_ALIAS(EC_KEY_check_key);
354
355int
356EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y)
357{
358 BN_CTX *ctx = NULL;
359 EC_POINT *point = NULL;
360 BIGNUM *tx, *ty;
361 int ret = 0;
362
363 if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
364 ECerror(ERR_R_PASSED_NULL_PARAMETER);
365 goto err;
366 }
367
368 if ((ctx = BN_CTX_new()) == NULL)
369 goto err;
370
371 BN_CTX_start(ctx);
372
373 if ((tx = BN_CTX_get(ctx)) == NULL)
374 goto err;
375 if ((ty = BN_CTX_get(ctx)) == NULL)
376 goto err;
377
378 if ((point = EC_POINT_new(key->group)) == NULL)
379 goto err;
380
381 if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
382 goto err;
383 if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
384 goto err;
385
386 /*
387 * Check if retrieved coordinates match originals: if not values are
388 * out of range.
389 */
390 if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) {
391 ECerror(EC_R_COORDINATES_OUT_OF_RANGE);
392 goto err;
393 }
394 if (!EC_KEY_set_public_key(key, point))
395 goto err;
396 if (EC_KEY_check_key(key) == 0)
397 goto err;
398
399 ret = 1;
400
401 err:
402 BN_CTX_end(ctx);
403 BN_CTX_free(ctx);
404 EC_POINT_free(point);
405
406 return ret;
407}
408LCRYPTO_ALIAS(EC_KEY_set_public_key_affine_coordinates);
409
410const EC_GROUP *
411EC_KEY_get0_group(const EC_KEY *key)
412{
413 return key->group;
414}
415LCRYPTO_ALIAS(EC_KEY_get0_group);
416
417int
418EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
419{
420 if (key->meth->set_group != NULL &&
421 key->meth->set_group(key, group) == 0)
422 return 0;
423 EC_GROUP_free(key->group);
424 key->group = EC_GROUP_dup(group);
425 return (key->group == NULL) ? 0 : 1;
426}
427LCRYPTO_ALIAS(EC_KEY_set_group);
428
429const BIGNUM *
430EC_KEY_get0_private_key(const EC_KEY *key)
431{
432 return key->priv_key;
433}
434LCRYPTO_ALIAS(EC_KEY_get0_private_key);
435
436int
437EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
438{
439 if (key->meth->set_private != NULL &&
440 key->meth->set_private(key, priv_key) == 0)
441 return 0;
442
443 BN_free(key->priv_key);
444 if ((key->priv_key = BN_dup(priv_key)) == NULL)
445 return 0;
446
447 return 1;
448}
449LCRYPTO_ALIAS(EC_KEY_set_private_key);
450
451const EC_POINT *
452EC_KEY_get0_public_key(const EC_KEY *key)
453{
454 return key->pub_key;
455}
456LCRYPTO_ALIAS(EC_KEY_get0_public_key);
457
458int
459EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
460{
461 if (key->meth->set_public != NULL &&
462 key->meth->set_public(key, pub_key) == 0)
463 return 0;
464
465 EC_POINT_free(key->pub_key);
466 if ((key->pub_key = EC_POINT_dup(pub_key, key->group)) == NULL)
467 return 0;
468
469 return 1;
470}
471LCRYPTO_ALIAS(EC_KEY_set_public_key);
472
473unsigned int
474EC_KEY_get_enc_flags(const EC_KEY *key)
475{
476 return key->enc_flag;
477}
478LCRYPTO_ALIAS(EC_KEY_get_enc_flags);
479
480void
481EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
482{
483 key->enc_flag = flags;
484}
485LCRYPTO_ALIAS(EC_KEY_set_enc_flags);
486
487point_conversion_form_t
488EC_KEY_get_conv_form(const EC_KEY *key)
489{
490 return key->conv_form;
491}
492LCRYPTO_ALIAS(EC_KEY_get_conv_form);
493
494void
495EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
496{
497 key->conv_form = cform;
498 if (key->group != NULL)
499 EC_GROUP_set_point_conversion_form(key->group, cform);
500}
501LCRYPTO_ALIAS(EC_KEY_set_conv_form);
502
503void
504EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
505{
506 if (key->group != NULL)
507 EC_GROUP_set_asn1_flag(key->group, flag);
508}
509LCRYPTO_ALIAS(EC_KEY_set_asn1_flag);
510
511int
512EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
513{
514 if (key->group == NULL)
515 return 0;
516 return 1;
517}
518LCRYPTO_ALIAS(EC_KEY_precompute_mult);
519
520int
521EC_KEY_get_flags(const EC_KEY *key)
522{
523 return key->flags;
524}
525LCRYPTO_ALIAS(EC_KEY_get_flags);
526
527void
528EC_KEY_set_flags(EC_KEY *key, int flags)
529{
530 key->flags |= flags;
531}
532LCRYPTO_ALIAS(EC_KEY_set_flags);
533
534void
535EC_KEY_clear_flags(EC_KEY *key, int flags)
536{
537 key->flags &= ~flags;
538}
539LCRYPTO_ALIAS(EC_KEY_clear_flags);
540
541const EC_KEY_METHOD *
542EC_KEY_get_method(const EC_KEY *key)
543{
544 return key->meth;
545}
546LCRYPTO_ALIAS(EC_KEY_get_method);
547
548int
549EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
550{
551 void (*finish)(EC_KEY *key) = key->meth->finish;
552
553 if (finish != NULL)
554 finish(key);
555
556 key->meth = meth;
557 if (meth->init != NULL)
558 return meth->init(key);
559 return 1;
560}
561LCRYPTO_ALIAS(EC_KEY_set_method);
562
563EC_KEY *
564EC_KEY_new_method(ENGINE *engine)
565{
566 EC_KEY *ret;
567
568 if ((ret = calloc(1, sizeof(EC_KEY))) == NULL) {
569 ECerror(ERR_R_MALLOC_FAILURE);
570 return NULL;
571 }
572 ret->meth = EC_KEY_get_default_method();
573 ret->version = 1;
574 ret->flags = 0;
575 ret->group = NULL;
576 ret->pub_key = NULL;
577 ret->priv_key = NULL;
578 ret->enc_flag = 0;
579 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
580 ret->references = 1;
581
582 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data))
583 goto err;
584 if (ret->meth->init != NULL && ret->meth->init(ret) == 0)
585 goto err;
586
587 return ret;
588
589 err:
590 EC_KEY_free(ret);
591 return NULL;
592}
593LCRYPTO_ALIAS(EC_KEY_new_method);
594
595#define EC_KEY_METHOD_DYNAMIC 1
596
597EC_KEY_METHOD *
598EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
599{
600 EC_KEY_METHOD *ret;
601
602 if ((ret = calloc(1, sizeof(*meth))) == NULL)
603 return NULL;
604 if (meth != NULL)
605 *ret = *meth;
606 ret->flags |= EC_KEY_METHOD_DYNAMIC;
607 return ret;
608}
609LCRYPTO_ALIAS(EC_KEY_METHOD_new);
610
611void
612EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
613{
614 if (meth == NULL)
615 return;
616 if (meth->flags & EC_KEY_METHOD_DYNAMIC)
617 free(meth);
618}
619LCRYPTO_ALIAS(EC_KEY_METHOD_free);
620
621void
622EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
623 int (*init)(EC_KEY *key),
624 void (*finish)(EC_KEY *key),
625 int (*copy)(EC_KEY *dest, const EC_KEY *src),
626 int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
627 int (*set_private)(EC_KEY *key, const BIGNUM *priv_key),
628 int (*set_public)(EC_KEY *key, const EC_POINT *pub_key))
629{
630 meth->init = init;
631 meth->finish = finish;
632 meth->copy = copy;
633 meth->set_group = set_group;
634 meth->set_private = set_private;
635 meth->set_public = set_public;
636}
637LCRYPTO_ALIAS(EC_KEY_METHOD_set_init);
638
639void
640EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, int (*keygen)(EC_KEY *key))
641{
642 meth->keygen = keygen;
643}
644LCRYPTO_ALIAS(EC_KEY_METHOD_set_keygen);
645
646void
647EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
648 int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key,
649 const EC_KEY *ecdh))
650{
651 meth->compute_key = ckey;
652}
653LCRYPTO_ALIAS(EC_KEY_METHOD_set_compute_key);
654
655void
656EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
657 int (*sign)(int type, const unsigned char *dgst,
658 int dlen, unsigned char *sig, unsigned int *siglen,
659 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
660 int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
661 BIGNUM **kinvp, BIGNUM **rp),
662 ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
663 int dgst_len, const BIGNUM *in_kinv,
664 const BIGNUM *in_r, EC_KEY *eckey))
665{
666 meth->sign = sign;
667 meth->sign_setup = sign_setup;
668 meth->sign_sig = sign_sig;
669}
670LCRYPTO_ALIAS(EC_KEY_METHOD_set_sign);
671
672void
673EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
674 int (*verify)(int type, const unsigned char *dgst, int dgst_len,
675 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey),
676 int (*verify_sig)(const unsigned char *dgst, int dgst_len,
677 const ECDSA_SIG *sig, EC_KEY *eckey))
678{
679 meth->verify = verify;
680 meth->verify_sig = verify_sig;
681}
682LCRYPTO_ALIAS(EC_KEY_METHOD_set_verify);
683
684
685void
686EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth,
687 int (**pinit)(EC_KEY *key),
688 void (**pfinish)(EC_KEY *key),
689 int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
690 int (**pset_group)(EC_KEY *key, const EC_GROUP *grp),
691 int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key),
692 int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key))
693{
694 if (pinit != NULL)
695 *pinit = meth->init;
696 if (pfinish != NULL)
697 *pfinish = meth->finish;
698 if (pcopy != NULL)
699 *pcopy = meth->copy;
700 if (pset_group != NULL)
701 *pset_group = meth->set_group;
702 if (pset_private != NULL)
703 *pset_private = meth->set_private;
704 if (pset_public != NULL)
705 *pset_public = meth->set_public;
706}
707LCRYPTO_ALIAS(EC_KEY_METHOD_get_init);
708
709void
710EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
711 int (**pkeygen)(EC_KEY *key))
712{
713 if (pkeygen != NULL)
714 *pkeygen = meth->keygen;
715}
716LCRYPTO_ALIAS(EC_KEY_METHOD_get_keygen);
717
718void
719EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth,
720 int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key,
721 const EC_KEY *ecdh))
722{
723 if (pck != NULL)
724 *pck = meth->compute_key;
725}
726LCRYPTO_ALIAS(EC_KEY_METHOD_get_compute_key);
727
728void
729EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth,
730 int (**psign)(int type, const unsigned char *dgst,
731 int dlen, unsigned char *sig, unsigned int *siglen,
732 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
733 int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
734 BIGNUM **kinvp, BIGNUM **rp),
735 ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
736 int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r,
737 EC_KEY *eckey))
738{
739 if (psign != NULL)
740 *psign = meth->sign;
741 if (psign_setup != NULL)
742 *psign_setup = meth->sign_setup;
743 if (psign_sig != NULL)
744 *psign_sig = meth->sign_sig;
745}
746LCRYPTO_ALIAS(EC_KEY_METHOD_get_sign);
747
748void
749EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
750 int (**pverify)(int type, const unsigned char *dgst, int dgst_len,
751 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey),
752 int (**pverify_sig)(const unsigned char *dgst, int dgst_len,
753 const ECDSA_SIG *sig, EC_KEY *eckey))
754{
755 if (pverify != NULL)
756 *pverify = meth->verify;
757 if (pverify_sig != NULL)
758 *pverify_sig = meth->verify_sig;
759}
760LCRYPTO_ALIAS(EC_KEY_METHOD_get_verify);
761
762static const EC_KEY_METHOD openssl_ec_key_method = {
763 .name = "OpenSSL EC_KEY method",
764 .flags = 0,
765
766 .init = NULL,
767 .finish = NULL,
768 .copy = NULL,
769
770 .set_group = NULL,
771 .set_private = NULL,
772 .set_public = NULL,
773
774 .keygen = ec_key_gen,
775 .compute_key = ecdh_compute_key,
776
777 .sign = ecdsa_sign,
778 .sign_setup = ecdsa_sign_setup,
779 .sign_sig = ecdsa_sign_sig,
780
781 .verify = ecdsa_verify,
782 .verify_sig = ecdsa_verify_sig,
783};
784
785const EC_KEY_METHOD *
786EC_KEY_OpenSSL(void)
787{
788 return &openssl_ec_key_method;
789}
790LCRYPTO_ALIAS(EC_KEY_OpenSSL);
791
792const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
793
794const EC_KEY_METHOD *
795EC_KEY_get_default_method(void)
796{
797 return default_ec_key_meth;
798}
799LCRYPTO_ALIAS(EC_KEY_get_default_method);
800
801void
802EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
803{
804 if (meth == NULL)
805 default_ec_key_meth = &openssl_ec_key_method;
806 else
807 default_ec_key_meth = meth;
808}
809LCRYPTO_ALIAS(EC_KEY_set_default_method);
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
deleted file mode 100644
index 7982d23f06..0000000000
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ /dev/null
@@ -1,1369 +0,0 @@
1/* $OpenBSD: ec_lib.c,v 1.123 2025/03/24 13:07:04 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2003 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 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include <stdlib.h>
65#include <string.h>
66
67#include <openssl/opensslconf.h>
68
69#include <openssl/bn.h>
70#include <openssl/ec.h>
71#include <openssl/err.h>
72#include <openssl/objects.h>
73#include <openssl/opensslv.h>
74
75#include "bn_local.h"
76#include "ec_local.h"
77
78EC_GROUP *
79EC_GROUP_new(const EC_METHOD *meth)
80{
81 EC_GROUP *group = NULL;
82
83 if (meth == NULL) {
84 ECerror(EC_R_SLOT_FULL);
85 goto err;
86 }
87 if ((group = calloc(1, sizeof(*group))) == NULL) {
88 ECerror(ERR_R_MALLOC_FAILURE);
89 goto err;
90 }
91
92 group->meth = meth;
93
94 group->asn1_flag = OPENSSL_EC_NAMED_CURVE;
95 group->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
96
97 if ((group->p = BN_new()) == NULL)
98 goto err;
99 if ((group->a = BN_new()) == NULL)
100 goto err;
101 if ((group->b = BN_new()) == NULL)
102 goto err;
103
104 if ((group->order = BN_new()) == NULL)
105 goto err;
106 if ((group->cofactor = BN_new()) == NULL)
107 goto err;
108
109 /*
110 * generator, seed and mont_ctx are optional.
111 */
112
113 return group;
114
115 err:
116 EC_GROUP_free(group);
117
118 return NULL;
119}
120
121void
122EC_GROUP_free(EC_GROUP *group)
123{
124 if (group == NULL)
125 return;
126
127 BN_free(group->p);
128 BN_free(group->a);
129 BN_free(group->b);
130
131 BN_MONT_CTX_free(group->mont_ctx);
132
133 EC_POINT_free(group->generator);
134 BN_free(group->order);
135 BN_free(group->cofactor);
136
137 freezero(group->seed, group->seed_len);
138 freezero(group, sizeof *group);
139}
140LCRYPTO_ALIAS(EC_GROUP_free);
141
142void
143EC_GROUP_clear_free(EC_GROUP *group)
144{
145 EC_GROUP_free(group);
146}
147LCRYPTO_ALIAS(EC_GROUP_clear_free);
148
149static int
150EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src)
151{
152 if (dst->meth != src->meth) {
153 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
154 return 0;
155 }
156 if (dst == src)
157 return 1;
158
159 if (!bn_copy(dst->p, src->p))
160 return 0;
161 if (!bn_copy(dst->a, src->a))
162 return 0;
163 if (!bn_copy(dst->b, src->b))
164 return 0;
165
166 dst->a_is_minus3 = src->a_is_minus3;
167
168 BN_MONT_CTX_free(dst->mont_ctx);
169 dst->mont_ctx = NULL;
170 if (src->mont_ctx != NULL) {
171 if ((dst->mont_ctx = BN_MONT_CTX_new()) == NULL)
172 return 0;
173 if (!BN_MONT_CTX_copy(dst->mont_ctx, src->mont_ctx))
174 return 0;
175 }
176
177 EC_POINT_free(dst->generator);
178 dst->generator = NULL;
179 if (src->generator != NULL) {
180 if (!EC_GROUP_set_generator(dst, src->generator, src->order,
181 src->cofactor))
182 return 0;
183 } else {
184 /* XXX - should do the sanity checks as in set_generator() */
185 if (!bn_copy(dst->order, src->order))
186 return 0;
187 if (!bn_copy(dst->cofactor, src->cofactor))
188 return 0;
189 }
190
191 dst->nid = src->nid;
192 dst->asn1_flag = src->asn1_flag;
193 dst->asn1_form = src->asn1_form;
194
195 if (!EC_GROUP_set_seed(dst, src->seed, src->seed_len))
196 return 0;
197
198 return 1;
199}
200
201EC_GROUP *
202EC_GROUP_dup(const EC_GROUP *in_group)
203{
204 EC_GROUP *group = NULL;
205
206 if (in_group == NULL)
207 goto err;
208
209 if ((group = EC_GROUP_new(in_group->meth)) == NULL)
210 goto err;
211 if (!EC_GROUP_copy(group, in_group))
212 goto err;
213
214 return group;
215
216 err:
217 EC_GROUP_free(group);
218
219 return NULL;
220}
221LCRYPTO_ALIAS(EC_GROUP_dup);
222
223/*
224 * If there is a user-provided cofactor, sanity check and use it. Otherwise
225 * try computing the cofactor from generator order n and field cardinality p.
226 * This works for all curves of cryptographic interest.
227 *
228 * Hasse's theorem: | h * n - (p + 1) | <= 2 * sqrt(p)
229 *
230 * So: h_min = (p + 1 - 2*sqrt(p)) / n and h_max = (p + 1 + 2*sqrt(p)) / n and
231 * therefore h_max - h_min = 4*sqrt(p) / n. So if n > 4*sqrt(p) holds, there is
232 * only one possible value for h:
233 *
234 * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (p + 1)/n \rceil
235 *
236 * Otherwise, zero cofactor and return success.
237 */
238static int
239ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
240{
241 BN_CTX *ctx = NULL;
242 BIGNUM *cofactor;
243 int ret = 0;
244
245 BN_zero(group->cofactor);
246
247 if ((ctx = BN_CTX_new()) == NULL)
248 goto err;
249
250 BN_CTX_start(ctx);
251 if ((cofactor = BN_CTX_get(ctx)) == NULL)
252 goto err;
253
254 /*
255 * Unfortunately, the cofactor is an optional field in many standards.
256 * Internally, the library uses a 0 cofactor as a marker for "unknown
257 * cofactor". So accept in_cofactor == NULL or in_cofactor >= 0.
258 */
259 if (in_cofactor != NULL && !BN_is_zero(in_cofactor)) {
260 if (BN_is_negative(in_cofactor)) {
261 ECerror(EC_R_UNKNOWN_COFACTOR);
262 goto err;
263 }
264 if (!bn_copy(cofactor, in_cofactor))
265 goto err;
266 goto done;
267 }
268
269 /*
270 * If the cofactor is too large, we cannot guess it and default to zero.
271 * The RHS of below is a strict overestimate of log(4 * sqrt(p)).
272 */
273 if (BN_num_bits(group->order) <= (BN_num_bits(group->p) + 1) / 2 + 3)
274 goto done;
275
276 /*
277 * Compute
278 * h = \lfloor (p + 1)/n \rceil = \lfloor (p + 1 + n/2) / n \rfloor.
279 */
280
281 /* h = n/2 */
282 if (!BN_rshift1(cofactor, group->order))
283 goto err;
284 /* h = 1 + n/2 */
285 if (!BN_add_word(cofactor, 1))
286 goto err;
287 /* h = p + 1 + n/2 */
288 if (!BN_add(cofactor, cofactor, group->p))
289 goto err;
290 /* h = (p + 1 + n/2) / n */
291 if (!BN_div_ct(cofactor, NULL, cofactor, group->order, ctx))
292 goto err;
293
294 done:
295 /* Use Hasse's theorem to bound the cofactor. */
296 if (BN_num_bits(cofactor) > BN_num_bits(group->p) + 1) {
297 ECerror(EC_R_INVALID_GROUP_ORDER);
298 goto err;
299 }
300
301 if (!bn_copy(group->cofactor, cofactor))
302 goto err;
303
304 ret = 1;
305
306 err:
307 BN_CTX_end(ctx);
308 BN_CTX_free(ctx);
309
310 return ret;
311}
312
313int
314EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
315 const BIGNUM *order, const BIGNUM *cofactor)
316{
317 if (generator == NULL) {
318 ECerror(ERR_R_PASSED_NULL_PARAMETER);
319 return 0;
320 }
321
322 /* Require p >= 1. */
323 if (BN_is_zero(group->p) || BN_is_negative(group->p)) {
324 ECerror(EC_R_INVALID_FIELD);
325 return 0;
326 }
327
328 /*
329 * Require order > 1 and enforce an upper bound of at most one bit more
330 * than the field cardinality due to Hasse's theorem.
331 */
332 if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 ||
333 BN_num_bits(order) > BN_num_bits(group->p) + 1) {
334 ECerror(EC_R_INVALID_GROUP_ORDER);
335 return 0;
336 }
337
338 if (group->generator == NULL)
339 group->generator = EC_POINT_new(group);
340 if (group->generator == NULL)
341 return 0;
342
343 if (!EC_POINT_copy(group->generator, generator))
344 return 0;
345
346 if (!bn_copy(group->order, order))
347 return 0;
348
349 if (!ec_set_cofactor(group, cofactor))
350 return 0;
351
352 return 1;
353}
354LCRYPTO_ALIAS(EC_GROUP_set_generator);
355
356const EC_POINT *
357EC_GROUP_get0_generator(const EC_GROUP *group)
358{
359 return group->generator;
360}
361LCRYPTO_ALIAS(EC_GROUP_get0_generator);
362
363int
364EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
365{
366 if (!bn_copy(order, group->order))
367 return 0;
368
369 return !BN_is_zero(order);
370}
371LCRYPTO_ALIAS(EC_GROUP_get_order);
372
373const BIGNUM *
374EC_GROUP_get0_order(const EC_GROUP *group)
375{
376 return group->order;
377}
378
379int
380EC_GROUP_order_bits(const EC_GROUP *group)
381{
382 return BN_num_bits(group->order);
383}
384LCRYPTO_ALIAS(EC_GROUP_order_bits);
385
386int
387EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
388{
389 if (!bn_copy(cofactor, group->cofactor))
390 return 0;
391
392 return !BN_is_zero(group->cofactor);
393}
394LCRYPTO_ALIAS(EC_GROUP_get_cofactor);
395
396const BIGNUM *
397EC_GROUP_get0_cofactor(const EC_GROUP *group)
398{
399 return group->cofactor;
400}
401
402void
403EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
404{
405 group->nid = nid;
406}
407LCRYPTO_ALIAS(EC_GROUP_set_curve_name);
408
409int
410EC_GROUP_get_curve_name(const EC_GROUP *group)
411{
412 return group->nid;
413}
414LCRYPTO_ALIAS(EC_GROUP_get_curve_name);
415
416void
417EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
418{
419 group->asn1_flag = flag;
420}
421LCRYPTO_ALIAS(EC_GROUP_set_asn1_flag);
422
423int
424EC_GROUP_get_asn1_flag(const EC_GROUP *group)
425{
426 return group->asn1_flag;
427}
428LCRYPTO_ALIAS(EC_GROUP_get_asn1_flag);
429
430void
431EC_GROUP_set_point_conversion_form(EC_GROUP *group,
432 point_conversion_form_t form)
433{
434 group->asn1_form = form;
435}
436LCRYPTO_ALIAS(EC_GROUP_set_point_conversion_form);
437
438point_conversion_form_t
439EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
440{
441 return group->asn1_form;
442}
443LCRYPTO_ALIAS(EC_GROUP_get_point_conversion_form);
444
445size_t
446EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *seed, size_t len)
447{
448 free(group->seed);
449 group->seed = NULL;
450 group->seed_len = 0;
451
452 if (seed == NULL || len == 0)
453 return 1;
454
455 if ((group->seed = malloc(len)) == NULL)
456 return 0;
457 memcpy(group->seed, seed, len);
458 group->seed_len = len;
459
460 return len;
461}
462LCRYPTO_ALIAS(EC_GROUP_set_seed);
463
464unsigned char *
465EC_GROUP_get0_seed(const EC_GROUP *group)
466{
467 return group->seed;
468}
469LCRYPTO_ALIAS(EC_GROUP_get0_seed);
470
471size_t
472EC_GROUP_get_seed_len(const EC_GROUP *group)
473{
474 return group->seed_len;
475}
476LCRYPTO_ALIAS(EC_GROUP_get_seed_len);
477
478int
479EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
480 const BIGNUM *b, BN_CTX *ctx_in)
481{
482 BN_CTX *ctx;
483 int ret = 0;
484
485 if ((ctx = ctx_in) == NULL)
486 ctx = BN_CTX_new();
487 if (ctx == NULL)
488 goto err;
489
490 if (group->meth->group_set_curve == NULL) {
491 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
492 goto err;
493 }
494 ret = group->meth->group_set_curve(group, p, a, b, ctx);
495
496 err:
497 if (ctx != ctx_in)
498 BN_CTX_free(ctx);
499
500 return ret;
501}
502LCRYPTO_ALIAS(EC_GROUP_set_curve);
503
504int
505EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
506 BN_CTX *ctx_in)
507{
508 BN_CTX *ctx;
509 int ret = 0;
510
511 if ((ctx = ctx_in) == NULL)
512 ctx = BN_CTX_new();
513 if (ctx == NULL)
514 goto err;
515
516 if (group->meth->group_get_curve == NULL) {
517 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
518 goto err;
519 }
520 ret = group->meth->group_get_curve(group, p, a, b, ctx);
521
522 err:
523 if (ctx != ctx_in)
524 BN_CTX_free(ctx);
525
526 return ret;
527}
528LCRYPTO_ALIAS(EC_GROUP_get_curve);
529
530int
531EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
532 const BIGNUM *b, BN_CTX *ctx)
533{
534 return EC_GROUP_set_curve(group, p, a, b, ctx);
535}
536LCRYPTO_ALIAS(EC_GROUP_set_curve_GFp);
537
538int
539EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
540 BN_CTX *ctx)
541{
542 return EC_GROUP_get_curve(group, p, a, b, ctx);
543}
544LCRYPTO_ALIAS(EC_GROUP_get_curve_GFp);
545
546EC_GROUP *
547EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b,
548 BN_CTX *ctx)
549{
550 EC_GROUP *group;
551
552 if ((group = EC_GROUP_new(EC_GFp_mont_method())) == NULL)
553 goto err;
554
555 if (!EC_GROUP_set_curve(group, p, a, b, ctx))
556 goto err;
557
558 return group;
559
560 err:
561 EC_GROUP_free(group);
562
563 return NULL;
564}
565LCRYPTO_ALIAS(EC_GROUP_new_curve_GFp);
566
567int
568EC_GROUP_get_degree(const EC_GROUP *group)
569{
570 return BN_num_bits(group->p);
571}
572LCRYPTO_ALIAS(EC_GROUP_get_degree);
573
574int
575EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in)
576{
577 BN_CTX *ctx;
578 BIGNUM *p, *a, *b, *discriminant;
579 int ret = 0;
580
581 if ((ctx = ctx_in) == NULL)
582 ctx = BN_CTX_new();
583 if (ctx == NULL)
584 goto err;
585
586 BN_CTX_start(ctx);
587
588 if ((p = BN_CTX_get(ctx)) == NULL)
589 goto err;
590 if ((a = BN_CTX_get(ctx)) == NULL)
591 goto err;
592 if ((b = BN_CTX_get(ctx)) == NULL)
593 goto err;
594 if ((discriminant = BN_CTX_get(ctx)) == NULL)
595 goto err;
596
597 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
598 goto err;
599
600 /*
601 * Check that the discriminant 4a^3 + 27b^2 is non-zero modulo p
602 * assuming that p > 3 is prime and that a and b are in [0, p).
603 */
604
605 if (BN_is_zero(a) && BN_is_zero(b))
606 goto err;
607 if (BN_is_zero(a) || BN_is_zero(b))
608 goto done;
609
610 /* Compute the discriminant: first 4a^3, then 27b^2, then their sum. */
611 if (!BN_mod_sqr(discriminant, a, p, ctx))
612 goto err;
613 if (!BN_mod_mul(discriminant, discriminant, a, p, ctx))
614 goto err;
615 if (!BN_lshift(discriminant, discriminant, 2))
616 goto err;
617
618 if (!BN_mod_sqr(b, b, p, ctx))
619 goto err;
620 if (!BN_mul_word(b, 27))
621 goto err;
622
623 if (!BN_mod_add(discriminant, discriminant, b, p, ctx))
624 goto err;
625
626 if (BN_is_zero(discriminant))
627 goto err;
628
629 done:
630 ret = 1;
631
632 err:
633 if (ctx != ctx_in)
634 BN_CTX_free(ctx);
635
636 return ret;
637}
638LCRYPTO_ALIAS(EC_GROUP_check_discriminant);
639
640int
641EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
642{
643 BN_CTX *ctx;
644 EC_POINT *point = NULL;
645 const EC_POINT *generator;
646 const BIGNUM *order;
647 int ret = 0;
648
649 if ((ctx = ctx_in) == NULL)
650 ctx = BN_CTX_new();
651 if (ctx == NULL)
652 goto err;
653
654 if (!EC_GROUP_check_discriminant(group, ctx)) {
655 ECerror(EC_R_DISCRIMINANT_IS_ZERO);
656 goto err;
657 }
658
659 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
660 ECerror(EC_R_UNDEFINED_GENERATOR);
661 goto err;
662 }
663 if (EC_POINT_is_on_curve(group, generator, ctx) <= 0) {
664 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
665 goto err;
666 }
667
668 if ((point = EC_POINT_new(group)) == NULL)
669 goto err;
670 if ((order = EC_GROUP_get0_order(group)) == NULL)
671 goto err;
672 if (BN_is_zero(order)) {
673 ECerror(EC_R_UNDEFINED_ORDER);
674 goto err;
675 }
676 if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
677 goto err;
678 if (!EC_POINT_is_at_infinity(group, point)) {
679 ECerror(EC_R_INVALID_GROUP_ORDER);
680 goto err;
681 }
682
683 ret = 1;
684
685 err:
686 if (ctx != ctx_in)
687 BN_CTX_free(ctx);
688
689 EC_POINT_free(point);
690
691 return ret;
692}
693LCRYPTO_ALIAS(EC_GROUP_check);
694
695/*
696 * Returns -1 on error, 0 if the groups are equal, 1 if they are distinct.
697 */
698int
699EC_GROUP_cmp(const EC_GROUP *group1, const EC_GROUP *group2, BN_CTX *ctx_in)
700{
701 BN_CTX *ctx = NULL;
702 BIGNUM *p1, *a1, *b1, *p2, *a2, *b2;
703 const EC_POINT *generator1, *generator2;
704 const BIGNUM *order1, *order2, *cofactor1, *cofactor2;
705 int nid1, nid2;
706 int cmp = 1;
707 int ret = -1;
708
709 if ((ctx = ctx_in) == NULL)
710 ctx = BN_CTX_new();
711 if (ctx == NULL)
712 goto err;
713
714 BN_CTX_start(ctx);
715
716 if ((nid1 = EC_GROUP_get_curve_name(group1)) != NID_undef &&
717 (nid2 = EC_GROUP_get_curve_name(group2)) != NID_undef) {
718 if (nid1 != nid2)
719 goto distinct;
720 }
721
722 if ((p1 = BN_CTX_get(ctx)) == NULL)
723 goto err;
724 if ((a1 = BN_CTX_get(ctx)) == NULL)
725 goto err;
726 if ((b1 = BN_CTX_get(ctx)) == NULL)
727 goto err;
728 if ((p2 = BN_CTX_get(ctx)) == NULL)
729 goto err;
730 if ((a2 = BN_CTX_get(ctx)) == NULL)
731 goto err;
732 if ((b2 = BN_CTX_get(ctx)) == NULL)
733 goto err;
734
735 /*
736 * If we ever support curves in non-Weierstrass form, this check needs
737 * to be adjusted. The comparison of the generators will fail anyway.
738 */
739 if (!EC_GROUP_get_curve(group1, p1, a1, b1, ctx))
740 goto err;
741 if (!EC_GROUP_get_curve(group2, p2, a2, b2, ctx))
742 goto err;
743
744 if (BN_cmp(p1, p2) != 0 || BN_cmp(a1, a2) != 0 || BN_cmp(b1, b2) != 0)
745 goto distinct;
746
747 if ((generator1 = EC_GROUP_get0_generator(group1)) == NULL)
748 goto err;
749 if ((generator2 = EC_GROUP_get0_generator(group2)) == NULL)
750 goto err;
751
752 /*
753 * It does not matter whether group1 or group2 is used: both points must
754 * have a matching method for this to succeed.
755 */
756 if ((cmp = EC_POINT_cmp(group1, generator1, generator2, ctx)) < 0)
757 goto err;
758 if (cmp == 1)
759 goto distinct;
760 cmp = 1;
761
762 if ((order1 = EC_GROUP_get0_order(group1)) == NULL)
763 goto err;
764 if ((order2 = EC_GROUP_get0_order(group2)) == NULL)
765 goto err;
766
767 if ((cofactor1 = EC_GROUP_get0_cofactor(group1)) == NULL)
768 goto err;
769 if ((cofactor2 = EC_GROUP_get0_cofactor(group2)) == NULL)
770 goto err;
771
772 if (BN_cmp(order1, order2) != 0 || BN_cmp(cofactor1, cofactor2) != 0)
773 goto distinct;
774
775 /* All parameters match: the groups are equal. */
776 cmp = 0;
777
778 distinct:
779 ret = cmp;
780
781 err:
782 BN_CTX_end(ctx);
783
784 if (ctx != ctx_in)
785 BN_CTX_free(ctx);
786
787 return ret;
788}
789LCRYPTO_ALIAS(EC_GROUP_cmp);
790
791EC_POINT *
792EC_POINT_new(const EC_GROUP *group)
793{
794 EC_POINT *point = NULL;
795
796 if (group == NULL) {
797 ECerror(ERR_R_PASSED_NULL_PARAMETER);
798 goto err;
799 }
800
801 if ((point = calloc(1, sizeof(*point))) == NULL) {
802 ECerror(ERR_R_MALLOC_FAILURE);
803 goto err;
804 }
805
806 if ((point->X = BN_new()) == NULL)
807 goto err;
808 if ((point->Y = BN_new()) == NULL)
809 goto err;
810 if ((point->Z = BN_new()) == NULL)
811 goto err;
812
813 point->meth = group->meth;
814
815 return point;
816
817 err:
818 EC_POINT_free(point);
819
820 return NULL;
821}
822LCRYPTO_ALIAS(EC_POINT_new);
823
824void
825EC_POINT_free(EC_POINT *point)
826{
827 if (point == NULL)
828 return;
829
830 BN_free(point->X);
831 BN_free(point->Y);
832 BN_free(point->Z);
833
834 freezero(point, sizeof *point);
835}
836LCRYPTO_ALIAS(EC_POINT_free);
837
838void
839EC_POINT_clear_free(EC_POINT *point)
840{
841 EC_POINT_free(point);
842}
843LCRYPTO_ALIAS(EC_POINT_clear_free);
844
845int
846EC_POINT_copy(EC_POINT *dst, const EC_POINT *src)
847{
848 if (dst->meth != src->meth) {
849 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
850 return 0;
851 }
852 if (dst == src)
853 return 1;
854
855 if (!bn_copy(dst->X, src->X))
856 return 0;
857 if (!bn_copy(dst->Y, src->Y))
858 return 0;
859 if (!bn_copy(dst->Z, src->Z))
860 return 0;
861 dst->Z_is_one = src->Z_is_one;
862
863 return 1;
864}
865LCRYPTO_ALIAS(EC_POINT_copy);
866
867EC_POINT *
868EC_POINT_dup(const EC_POINT *in_point, const EC_GROUP *group)
869{
870 EC_POINT *point = NULL;
871
872 if (in_point == NULL)
873 goto err;
874
875 if ((point = EC_POINT_new(group)) == NULL)
876 goto err;
877
878 if (!EC_POINT_copy(point, in_point))
879 goto err;
880
881 return point;
882
883 err:
884 EC_POINT_free(point);
885
886 return NULL;
887}
888LCRYPTO_ALIAS(EC_POINT_dup);
889
890int
891EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
892{
893 if (group->meth != point->meth) {
894 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
895 return 0;
896 }
897
898 BN_zero(point->Z);
899 point->Z_is_one = 0;
900
901 return 1;
902}
903LCRYPTO_ALIAS(EC_POINT_set_to_infinity);
904
905int
906EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
907 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in)
908{
909 BN_CTX *ctx;
910 int ret = 0;
911
912 if ((ctx = ctx_in) == NULL)
913 ctx = BN_CTX_new();
914 if (ctx == NULL)
915 goto err;
916
917 if (group->meth->point_set_affine_coordinates == NULL) {
918 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
919 goto err;
920 }
921 if (group->meth != point->meth) {
922 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
923 goto err;
924 }
925 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
926 goto err;
927
928 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
929 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
930 goto err;
931 }
932
933 ret = 1;
934
935 err:
936 if (ctx != ctx_in)
937 BN_CTX_free(ctx);
938
939 return ret;
940}
941LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates);
942
943int
944EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
945 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
946{
947 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx);
948}
949LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates_GFp);
950
951int
952EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
953 BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in)
954{
955 BN_CTX *ctx = NULL;
956 int ret = 0;
957
958 if (EC_POINT_is_at_infinity(group, point) > 0) {
959 ECerror(EC_R_POINT_AT_INFINITY);
960 goto err;
961 }
962
963 if ((ctx = ctx_in) == NULL)
964 ctx = BN_CTX_new();
965 if (ctx == NULL)
966 goto err;
967
968 if (group->meth->point_get_affine_coordinates == NULL) {
969 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
970 goto err;
971 }
972 if (group->meth != point->meth) {
973 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
974 goto err;
975 }
976 ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
977
978 err:
979 if (ctx != ctx_in)
980 BN_CTX_free(ctx);
981
982 return ret;
983}
984LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates);
985
986int
987EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
988 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
989{
990 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx);
991}
992LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates_GFp);
993
994int
995EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
996 const BIGNUM *in_x, int y_bit, BN_CTX *ctx_in)
997{
998 BIGNUM *p, *a, *b, *w, *x, *y;
999 BN_CTX *ctx;
1000 int ret = 0;
1001
1002 if ((ctx = ctx_in) == NULL)
1003 ctx = BN_CTX_new();
1004 if (ctx == NULL)
1005 goto err;
1006
1007 y_bit = (y_bit != 0);
1008
1009 BN_CTX_start(ctx);
1010
1011 if ((p = BN_CTX_get(ctx)) == NULL)
1012 goto err;
1013 if ((a = BN_CTX_get(ctx)) == NULL)
1014 goto err;
1015 if ((b = BN_CTX_get(ctx)) == NULL)
1016 goto err;
1017 if ((w = BN_CTX_get(ctx)) == NULL)
1018 goto err;
1019 if ((x = BN_CTX_get(ctx)) == NULL)
1020 goto err;
1021 if ((y = BN_CTX_get(ctx)) == NULL)
1022 goto err;
1023
1024 /*
1025 * Weierstrass equation: y^2 = x^3 + ax + b, so y is one of the
1026 * square roots of x^3 + ax + b. The y-bit indicates which one.
1027 */
1028
1029 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
1030 goto err;
1031
1032 /* XXX - should we not insist on 0 <= x < p instead? */
1033 if (!BN_nnmod(x, in_x, p, ctx))
1034 goto err;
1035
1036 /* y = x^3 */
1037 if (!BN_mod_sqr(y, x, p, ctx))
1038 goto err;
1039 if (!BN_mod_mul(y, y, x, p, ctx))
1040 goto err;
1041
1042 /* y += ax */
1043 if (group->a_is_minus3) {
1044 if (!BN_mod_lshift1_quick(w, x, p))
1045 goto err;
1046 if (!BN_mod_add_quick(w, w, x, p))
1047 goto err;
1048 if (!BN_mod_sub_quick(y, y, w, p))
1049 goto err;
1050 } else {
1051 if (!BN_mod_mul(w, a, x, p, ctx))
1052 goto err;
1053 if (!BN_mod_add_quick(y, y, w, p))
1054 goto err;
1055 }
1056
1057 /* y += b */
1058 if (!BN_mod_add_quick(y, y, b, p))
1059 goto err;
1060
1061 if (!BN_mod_sqrt(y, y, p, ctx)) {
1062 ECerror(EC_R_INVALID_COMPRESSED_POINT);
1063 goto err;
1064 }
1065
1066 if (y_bit == BN_is_odd(y))
1067 goto done;
1068
1069 if (BN_is_zero(y)) {
1070 ECerror(EC_R_INVALID_COMPRESSION_BIT);
1071 goto err;
1072 }
1073 if (!BN_usub(y, p, y))
1074 goto err;
1075
1076 if (y_bit != BN_is_odd(y)) {
1077 /* Can only happen if p is even and should not be reachable. */
1078 ECerror(ERR_R_INTERNAL_ERROR);
1079 goto err;
1080 }
1081
1082 done:
1083 if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1084 goto err;
1085
1086 ret = 1;
1087
1088 err:
1089 BN_CTX_end(ctx);
1090
1091 if (ctx != ctx_in)
1092 BN_CTX_free(ctx);
1093
1094 return ret;
1095}
1096LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates);
1097
1098int
1099EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
1100 const BIGNUM *x, int y_bit, BN_CTX *ctx)
1101{
1102 return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx);
1103}
1104LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates_GFp);
1105
1106int
1107EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1108 const EC_POINT *b, BN_CTX *ctx_in)
1109{
1110 BN_CTX *ctx;
1111 int ret = 0;
1112
1113 if ((ctx = ctx_in) == NULL)
1114 ctx = BN_CTX_new();
1115 if (ctx == NULL)
1116 goto err;
1117
1118 if (group->meth->add == NULL) {
1119 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1120 goto err;
1121 }
1122 if (group->meth != r->meth || group->meth != a->meth ||
1123 group->meth != b->meth) {
1124 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1125 goto err;
1126 }
1127 ret = group->meth->add(group, r, a, b, ctx);
1128
1129 err:
1130 if (ctx != ctx_in)
1131 BN_CTX_free(ctx);
1132
1133 return ret;
1134}
1135LCRYPTO_ALIAS(EC_POINT_add);
1136
1137int
1138EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1139 BN_CTX *ctx_in)
1140{
1141 BN_CTX *ctx;
1142 int ret = 0;
1143
1144 if ((ctx = ctx_in) == NULL)
1145 ctx = BN_CTX_new();
1146 if (ctx == NULL)
1147 goto err;
1148
1149 if (group->meth->dbl == NULL) {
1150 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1151 goto err;
1152 }
1153 if (group->meth != r->meth || r->meth != a->meth) {
1154 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1155 goto err;
1156 }
1157 ret = group->meth->dbl(group, r, a, ctx);
1158
1159 err:
1160 if (ctx != ctx_in)
1161 BN_CTX_free(ctx);
1162
1163 return ret;
1164}
1165LCRYPTO_ALIAS(EC_POINT_dbl);
1166
1167int
1168EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in)
1169{
1170 BN_CTX *ctx;
1171 int ret = 0;
1172
1173 if ((ctx = ctx_in) == NULL)
1174 ctx = BN_CTX_new();
1175 if (ctx == NULL)
1176 goto err;
1177
1178 if (group->meth->invert == NULL) {
1179 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1180 goto err;
1181 }
1182 if (group->meth != a->meth) {
1183 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1184 goto err;
1185 }
1186 ret = group->meth->invert(group, a, ctx);
1187
1188 err:
1189 if (ctx != ctx_in)
1190 BN_CTX_free(ctx);
1191
1192 return ret;
1193}
1194LCRYPTO_ALIAS(EC_POINT_invert);
1195
1196int
1197EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1198{
1199 if (group->meth != point->meth) {
1200 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1201 return 0;
1202 }
1203
1204 return BN_is_zero(point->Z);
1205}
1206LCRYPTO_ALIAS(EC_POINT_is_at_infinity);
1207
1208int
1209EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
1210 BN_CTX *ctx_in)
1211{
1212 BN_CTX *ctx;
1213 int ret = -1;
1214
1215 if ((ctx = ctx_in) == NULL)
1216 ctx = BN_CTX_new();
1217 if (ctx == NULL)
1218 goto err;
1219
1220 if (group->meth->point_is_on_curve == NULL) {
1221 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1222 goto err;
1223 }
1224 if (group->meth != point->meth) {
1225 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1226 goto err;
1227 }
1228 ret = group->meth->point_is_on_curve(group, point, ctx);
1229
1230 err:
1231 if (ctx != ctx_in)
1232 BN_CTX_free(ctx);
1233
1234 return ret;
1235}
1236LCRYPTO_ALIAS(EC_POINT_is_on_curve);
1237
1238int
1239EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1240 BN_CTX *ctx_in)
1241{
1242 BN_CTX *ctx;
1243 int ret = -1;
1244
1245 if ((ctx = ctx_in) == NULL)
1246 ctx = BN_CTX_new();
1247 if (ctx == NULL)
1248 goto err;
1249
1250 if (group->meth->point_cmp == NULL) {
1251 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1252 goto err;
1253 }
1254 if (group->meth != a->meth || a->meth != b->meth) {
1255 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1256 goto err;
1257 }
1258 ret = group->meth->point_cmp(group, a, b, ctx);
1259
1260 err:
1261 if (ctx != ctx_in)
1262 BN_CTX_free(ctx);
1263
1264 return ret;
1265}
1266LCRYPTO_ALIAS(EC_POINT_cmp);
1267
1268int
1269EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in)
1270{
1271 BN_CTX *ctx;
1272 BIGNUM *x, *y;
1273 int ret = 0;
1274
1275 if ((ctx = ctx_in) == NULL)
1276 ctx = BN_CTX_new();
1277 if (ctx == NULL)
1278 goto err;
1279
1280 BN_CTX_start(ctx);
1281
1282 if ((x = BN_CTX_get(ctx)) == NULL)
1283 goto err;
1284 if ((y = BN_CTX_get(ctx)) == NULL)
1285 goto err;
1286
1287 if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
1288 goto err;
1289 if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1290 goto err;
1291
1292 ret = 1;
1293
1294 err:
1295 BN_CTX_end(ctx);
1296
1297 if (ctx != ctx_in)
1298 BN_CTX_free(ctx);
1299
1300 return ret;
1301}
1302LCRYPTO_ALIAS(EC_POINT_make_affine);
1303
1304int
1305EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1306 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in)
1307{
1308 BN_CTX *ctx;
1309 int ret = 0;
1310
1311 if ((ctx = ctx_in) == NULL)
1312 ctx = BN_CTX_new();
1313 if (ctx == NULL)
1314 goto err;
1315
1316 if (group->meth->mul_single_ct == NULL ||
1317 group->meth->mul_double_nonct == NULL) {
1318 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1319 goto err;
1320 }
1321
1322 if (g_scalar != NULL && group->generator == NULL) {
1323 ECerror(EC_R_UNDEFINED_GENERATOR);
1324 goto err;
1325 }
1326
1327 if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1328 /*
1329 * In this case we want to compute g_scalar * GeneratorPoint:
1330 * this codepath is reached most prominently by (ephemeral) key
1331 * generation of EC cryptosystems (i.e. ECDSA keygen and sign
1332 * setup, ECDH keygen/first half), where the scalar is always
1333 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1334 * set and we always call the constant time version.
1335 */
1336 ret = group->meth->mul_single_ct(group, r,
1337 g_scalar, group->generator, ctx);
1338 } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1339 /*
1340 * In this case we want to compute p_scalar * GenericPoint:
1341 * this codepath is reached most prominently by the second half
1342 * of ECDH, where the secret scalar is multiplied by the peer's
1343 * public point. To protect the secret scalar, we ignore if
1344 * BN_FLG_CONSTTIME is actually set and we always call the
1345 * constant time version.
1346 */
1347 ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx);
1348 } else if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1349 /*
1350 * In this case we want to compute
1351 * g_scalar * GeneratorPoint + p_scalar * GenericPoint:
1352 * this codepath is reached most prominently by ECDSA signature
1353 * verification. So we call the non-ct version.
1354 */
1355 ret = group->meth->mul_double_nonct(group, r,
1356 g_scalar, group->generator, p_scalar, point, ctx);
1357 } else {
1358 /* Anything else is an error. */
1359 ECerror(ERR_R_EC_LIB);
1360 goto err;
1361 }
1362
1363 err:
1364 if (ctx != ctx_in)
1365 BN_CTX_free(ctx);
1366
1367 return ret;
1368}
1369LCRYPTO_ALIAS(EC_POINT_mul);
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
deleted file mode 100644
index c7a54d3a2b..0000000000
--- a/src/lib/libcrypto/ec/ec_local.h
+++ /dev/null
@@ -1,254 +0,0 @@
1/* $OpenBSD: ec_local.h,v 1.67 2025/03/24 13:07:04 jsing 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
82typedef struct ec_method_st {
83 int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
84 const BIGNUM *b, BN_CTX *);
85 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
86 BIGNUM *b, BN_CTX *);
87
88 int (*point_is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
89 int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
90 BN_CTX *);
91
92 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
93 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
94 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
95 BIGNUM *x, BIGNUM *y, BN_CTX *);
96
97 /* Only used by the wNAF code. */
98 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT **,
99 BN_CTX *);
100
101 int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
102 const EC_POINT *b, BN_CTX *);
103 int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
104 int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
105
106 int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r,
107 const BIGNUM *scalar, const EC_POINT *point, BN_CTX *);
108 int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r,
109 const BIGNUM *scalar1, const EC_POINT *point1,
110 const BIGNUM *scalar2, const EC_POINT *point2, BN_CTX *);
111
112 /*
113 * These can be used by 'add' and 'dbl' so that the same implementations
114 * of point operations can be used with different optimized versions of
115 * expensive field operations.
116 */
117 int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
118 const BIGNUM *b, BN_CTX *);
119 int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
120 BN_CTX *);
121
122 /* Encode to and decode from other forms (e.g. Montgomery). */
123 int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
124 BN_CTX *);
125 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
126 BN_CTX *);
127} EC_METHOD;
128
129struct ec_group_st {
130 const EC_METHOD *meth;
131
132 EC_POINT *generator; /* Optional */
133 BIGNUM *order;
134 BIGNUM *cofactor;
135
136 int nid; /* Optional NID for named curve. */
137
138 /* ASN.1 encoding controls. */
139 int asn1_flag;
140 point_conversion_form_t asn1_form;
141
142 /* Optional seed for parameters (appears in ASN.1). */
143 unsigned char *seed;
144 size_t seed_len;
145
146 /*
147 * Coefficients of the Weierstrass equation y^2 = x^3 + a*x + b (mod p).
148 */
149 BIGNUM *p;
150 BIGNUM *a;
151 BIGNUM *b;
152
153 /* Enables optimized point arithmetics for special case. */
154 int a_is_minus3;
155
156 /* Montgomery context used by EC_GFp_mont_method. */
157 BN_MONT_CTX *mont_ctx;
158} /* EC_GROUP */;
159
160struct ec_point_st {
161 const EC_METHOD *meth;
162
163 /*
164 * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3)
165 * if Z != 0
166 */
167 BIGNUM *X;
168 BIGNUM *Y;
169 BIGNUM *Z;
170 int Z_is_one; /* enable optimized point arithmetics for special case */
171} /* EC_POINT */;
172
173const EC_METHOD *EC_GFp_simple_method(void);
174const EC_METHOD *EC_GFp_mont_method(void);
175
176/* Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time. */
177int ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
178 const EC_POINT *point1, const BIGNUM *scalar2, const EC_POINT *point2,
179 BN_CTX *ctx);
180
181int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid);
182
183/*
184 * Wrappers around the unergonomic EC_POINT_{oct2point,point2oct}().
185 */
186int ec_point_from_octets(const EC_GROUP *group, const unsigned char *buf,
187 size_t buf_len, EC_POINT **out_point, uint8_t *out_form, BN_CTX *ctx_in);
188int ec_point_to_octets(const EC_GROUP *group, const EC_POINT *point, int form,
189 unsigned char **out_buf, size_t *len, BN_CTX *ctx_in);
190
191/* Public API in OpenSSL */
192const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group);
193const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);
194
195struct ec_key_method_st {
196 const char *name;
197 int32_t flags;
198 int (*init)(EC_KEY *key);
199 void (*finish)(EC_KEY *key);
200 int (*copy)(EC_KEY *dest, const EC_KEY *src);
201 int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
202 int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
203 int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
204 int (*keygen)(EC_KEY *key);
205 int (*compute_key)(unsigned char **out, size_t *out_len,
206 const EC_POINT *pub_key, const EC_KEY *ecdh);
207 int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
208 *sig, unsigned int *siglen, const BIGNUM *kinv,
209 const BIGNUM *r, EC_KEY *eckey);
210 int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
211 BIGNUM **rp);
212 ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
213 const BIGNUM *in_kinv, const BIGNUM *in_r,
214 EC_KEY *eckey);
215 int (*verify)(int type, const unsigned char *dgst, int dgst_len,
216 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
217 int (*verify_sig)(const unsigned char *dgst, int dgst_len,
218 const ECDSA_SIG *sig, EC_KEY *eckey);
219} /* EC_KEY_METHOD */;
220
221struct ec_key_st {
222 const EC_KEY_METHOD *meth;
223
224 int version;
225
226 EC_GROUP *group;
227
228 EC_POINT *pub_key;
229 BIGNUM *priv_key;
230
231 unsigned int enc_flag;
232 point_conversion_form_t conv_form;
233
234 int references;
235 int flags;
236
237 CRYPTO_EX_DATA ex_data;
238} /* EC_KEY */;
239
240int eckey_compute_pubkey(EC_KEY *eckey);
241int ecdh_compute_key(unsigned char **out, size_t *out_len,
242 const EC_POINT *pub_key, const EC_KEY *ecdh);
243int ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
244 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
245int ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
246 const ECDSA_SIG *sig, EC_KEY *eckey);
247
248/*
249 * ECDH Key Derivation Function as defined in ANSI X9.63.
250 */
251int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z,
252 size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md);
253
254__END_HIDDEN_DECLS
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
deleted file mode 100644
index 673696a9fd..0000000000
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ /dev/null
@@ -1,407 +0,0 @@
1/* $OpenBSD: ec_mult.c,v 1.58 2025/03/24 13:07:04 jsing Exp $ */
2/*
3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2007 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 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <stdint.h>
65#include <stdlib.h>
66#include <string.h>
67
68#include <openssl/bn.h>
69#include <openssl/ec.h>
70#include <openssl/err.h>
71
72#include "ec_local.h"
73
74/* Holds the wNAF digits of bn and the corresponding odd multiples of point. */
75struct ec_wnaf {
76 signed char *digits;
77 size_t num_digits;
78 EC_POINT **multiples;
79 size_t num_multiples;
80};
81
82static int
83ec_window_bits(const BIGNUM *bn)
84{
85 int bits = BN_num_bits(bn);
86
87 if (bits >= 2000)
88 return 6;
89 if (bits >= 800)
90 return 5;
91 if (bits >= 300)
92 return 4;
93 if (bits >= 70)
94 return 3;
95 if (bits >= 20)
96 return 2;
97
98 return 1;
99}
100
101/*
102 * Width-(w+1) non-adjacent form of bn = \sum_j n_j 2^j, with odd n_j,
103 * where at most one of any (w+1) consecutive digits is non-zero.
104 */
105
106static int
107ec_compute_wnaf(const BIGNUM *bn, signed char *digits, size_t num_digits)
108{
109 int digit, bit, next, sign, wbits, window;
110 size_t i;
111 int ret = 0;
112
113 if (num_digits != BN_num_bits(bn) + 1) {
114 ECerror(ERR_R_INTERNAL_ERROR);
115 goto err;
116 }
117
118 sign = BN_is_negative(bn) ? -1 : 1;
119
120 wbits = ec_window_bits(bn);
121
122 bit = 1 << wbits;
123 next = bit << 1;
124
125 /* Extract the wbits + 1 lowest bits from bn into window. */
126 window = 0;
127 for (i = 0; i < wbits + 1; i++) {
128 if (BN_is_bit_set(bn, i))
129 window |= (1 << i);
130 }
131
132 /* Instead of bn >>= 1 in each iteration, slide window to the left. */
133 for (i = 0; i < num_digits; i++) {
134 digit = 0;
135
136 /*
137 * If window is odd, the i-th wNAF digit is window (mods 2^w),
138 * where mods is the signed modulo in (-2^w-1, 2^w-1]. Subtract
139 * the digit from window, so window is 0 or next, and add the
140 * digit to the wNAF digits.
141 */
142 if ((window & 1) != 0) {
143 digit = window;
144 if ((window & bit) != 0)
145 digit = window - next;
146 window -= digit;
147 }
148
149 digits[i] = sign * digit;
150
151 /* Slide the window to the left. */
152 window >>= 1;
153 window += bit * BN_is_bit_set(bn, i + wbits + 1);
154 }
155
156 ret = 1;
157
158 err:
159 return ret;
160}
161
162static int
163ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point,
164 EC_POINT **multiples, size_t num_multiples, BN_CTX *ctx)
165{
166 EC_POINT *doubled = NULL;
167 size_t i;
168 int ret = 0;
169
170 if (num_multiples < 1)
171 goto err;
172
173 if ((multiples[0] = EC_POINT_dup(point, group)) == NULL)
174 goto err;
175
176 if ((doubled = EC_POINT_new(group)) == NULL)
177 goto err;
178 if (!EC_POINT_dbl(group, doubled, point, ctx))
179 goto err;
180 for (i = 1; i < num_multiples; i++) {
181 if ((multiples[i] = EC_POINT_new(group)) == NULL)
182 goto err;
183 if (!EC_POINT_add(group, multiples[i], multiples[i - 1], doubled,
184 ctx))
185 goto err;
186 }
187
188 ret = 1;
189
190 err:
191 EC_POINT_free(doubled);
192
193 return ret;
194}
195
196/*
197 * Bring multiples held in wnaf0 and wnaf1 simultaneously into affine form
198 * so that the operations in the loop in ec_wnaf_mul() can take fast paths.
199 */
200
201static int
202ec_normalize_points(const EC_GROUP *group, struct ec_wnaf *wnaf0,
203 struct ec_wnaf *wnaf1, BN_CTX *ctx)
204{
205 EC_POINT **points0 = wnaf0->multiples, **points1 = wnaf1->multiples;
206 size_t len0 = wnaf0->num_multiples, len1 = wnaf1->num_multiples;
207 EC_POINT **val = NULL;
208 size_t len = 0;
209 int ret = 0;
210
211 if (len1 > SIZE_MAX - len0)
212 goto err;
213 len = len0 + len1;
214
215 if ((val = calloc(len, sizeof(*val))) == NULL) {
216 ECerror(ERR_R_MALLOC_FAILURE);
217 goto err;
218 }
219 memcpy(&val[0], points0, sizeof(*val) * len0);
220 memcpy(&val[len0], points1, sizeof(*val) * len1);
221
222 if (!group->meth->points_make_affine(group, len, val, ctx))
223 goto err;
224
225 ret = 1;
226
227 err:
228 free(val);
229
230 return ret;
231}
232
233static void
234ec_points_free(EC_POINT **points, size_t num_points)
235{
236 size_t i;
237
238 if (points == NULL)
239 return;
240
241 for (i = 0; i < num_points; i++)
242 EC_POINT_free(points[i]);
243 free(points);
244}
245
246static void
247ec_wnaf_free(struct ec_wnaf *wnaf)
248{
249 if (wnaf == NULL)
250 return;
251
252 free(wnaf->digits);
253 ec_points_free(wnaf->multiples, wnaf->num_multiples);
254 free(wnaf);
255}
256
257/*
258 * Calculate wNAF splitting of bn and the corresponding odd multiples of point.
259 */
260
261static struct ec_wnaf *
262ec_wnaf_new(const EC_GROUP *group, const BIGNUM *scalar, const EC_POINT *point,
263 BN_CTX *ctx)
264{
265 struct ec_wnaf *wnaf;
266
267 if ((wnaf = calloc(1, sizeof(*wnaf))) == NULL)
268 goto err;
269
270 wnaf->num_digits = BN_num_bits(scalar) + 1;
271 if ((wnaf->digits = calloc(wnaf->num_digits,
272 sizeof(*wnaf->digits))) == NULL)
273 goto err;
274
275 if (!ec_compute_wnaf(scalar, wnaf->digits, wnaf->num_digits))
276 goto err;
277
278 wnaf->num_multiples = 1ULL << (ec_window_bits(scalar) - 1);
279 if ((wnaf->multiples = calloc(wnaf->num_multiples,
280 sizeof(*wnaf->multiples))) == NULL)
281 goto err;
282
283 if (!ec_compute_odd_multiples(group, point, wnaf->multiples,
284 wnaf->num_multiples, ctx))
285 goto err;
286
287 return wnaf;
288
289 err:
290 ec_wnaf_free(wnaf);
291
292 return NULL;
293}
294
295static signed char
296ec_wnaf_digit(struct ec_wnaf *wnaf, size_t idx)
297{
298 if (idx >= wnaf->num_digits)
299 return 0;
300
301 return wnaf->digits[idx];
302}
303
304static const EC_POINT *
305ec_wnaf_multiple(struct ec_wnaf *wnaf, signed char digit)
306{
307 if (digit < 0)
308 return NULL;
309 if (digit >= 2 * wnaf->num_multiples)
310 return NULL;
311
312 return wnaf->multiples[digit >> 1];
313}
314
315/*
316 * Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time.
317 */
318
319int
320ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
321 const EC_POINT *point1, const BIGNUM *scalar2, const EC_POINT *point2,
322 BN_CTX *ctx)
323{
324 struct ec_wnaf *wnaf[2] = { NULL, NULL };
325 size_t i;
326 int k;
327 int r_is_inverted = 0;
328 size_t num_digits;
329 int ret = 0;
330
331 if (scalar1 == NULL || scalar2 == NULL) {
332 ECerror(ERR_R_PASSED_NULL_PARAMETER);
333 goto err;
334 }
335 if (group->meth != r->meth || group->meth != point1->meth ||
336 group->meth != point2->meth) {
337 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
338 goto err;
339 }
340
341 if ((wnaf[0] = ec_wnaf_new(group, scalar1, point1, ctx)) == NULL)
342 goto err;
343 if ((wnaf[1] = ec_wnaf_new(group, scalar2, point2, ctx)) == NULL)
344 goto err;
345
346 if (!ec_normalize_points(group, wnaf[0], wnaf[1], ctx))
347 goto err;
348
349 num_digits = wnaf[0]->num_digits;
350 if (wnaf[1]->num_digits > num_digits)
351 num_digits = wnaf[1]->num_digits;
352
353 /*
354 * Set r to the neutral element. Scan through the wNAF representations
355 * of m and n, starting at the most significant digit. Double r and for
356 * each wNAF digit of scalar1 add the digit times point1, and for each
357 * wNAF digit of scalar2 add the digit times point2, adjusting the signs
358 * as appropriate.
359 */
360
361 if (!EC_POINT_set_to_infinity(group, r))
362 goto err;
363
364 for (k = num_digits - 1; k >= 0; k--) {
365 if (!EC_POINT_dbl(group, r, r, ctx))
366 goto err;
367
368 for (i = 0; i < 2; i++) {
369 const EC_POINT *multiple;
370 signed char digit;
371 int is_neg = 0;
372
373 if ((digit = ec_wnaf_digit(wnaf[i], k)) == 0)
374 continue;
375
376 if (digit < 0) {
377 is_neg = 1;
378 digit = -digit;
379 }
380
381 if (is_neg != r_is_inverted) {
382 if (!EC_POINT_invert(group, r, ctx))
383 goto err;
384 r_is_inverted = !r_is_inverted;
385 }
386
387 if ((multiple = ec_wnaf_multiple(wnaf[i], digit)) == NULL)
388 goto err;
389
390 if (!EC_POINT_add(group, r, r, multiple, ctx))
391 goto err;
392 }
393 }
394
395 if (r_is_inverted) {
396 if (!EC_POINT_invert(group, r, ctx))
397 goto err;
398 }
399
400 ret = 1;
401
402 err:
403 ec_wnaf_free(wnaf[0]);
404 ec_wnaf_free(wnaf[1]);
405
406 return ret;
407}
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
deleted file mode 100644
index 85ac4822d1..0000000000
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ /dev/null
@@ -1,545 +0,0 @@
1/* $OpenBSD: ec_pmeth.c,v 1.26 2025/03/13 10:39:51 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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 * licensing@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#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include <openssl/asn1t.h>
64#include <openssl/ec.h>
65#include <openssl/err.h>
66#include <openssl/evp.h>
67#include <openssl/x509.h>
68
69#include "bn_local.h"
70#include "ec_local.h"
71#include "evp_local.h"
72
73/* EC pkey context structure */
74
75typedef struct {
76 /* Key and paramgen group */
77 EC_GROUP *gen_group;
78 /* message digest */
79 const EVP_MD *md;
80 /* Duplicate key if custom cofactor needed */
81 EC_KEY *co_key;
82 /* Cofactor mode */
83 signed char cofactor_mode;
84 /* KDF (if any) to use for ECDH */
85 char kdf_type;
86 /* Message digest to use for key derivation */
87 const EVP_MD *kdf_md;
88 /* User key material */
89 unsigned char *kdf_ukm;
90 size_t kdf_ukmlen;
91 /* KDF output length */
92 size_t kdf_outlen;
93} EC_PKEY_CTX;
94
95static int
96pkey_ec_init(EVP_PKEY_CTX *ctx)
97{
98 EC_PKEY_CTX *dctx;
99
100 if ((dctx = calloc(1, sizeof(EC_PKEY_CTX))) == NULL) {
101 ECerror(ERR_R_MALLOC_FAILURE);
102 return 0;
103 }
104
105 dctx->cofactor_mode = -1;
106 dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
107
108 ctx->data = dctx;
109
110 return 1;
111}
112
113static int
114pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
115{
116 EC_PKEY_CTX *dctx, *sctx;
117 if (!pkey_ec_init(dst))
118 return 0;
119 sctx = src->data;
120 dctx = dst->data;
121 if (sctx->gen_group) {
122 dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
123 if (!dctx->gen_group)
124 return 0;
125 }
126 dctx->md = sctx->md;
127
128 if (sctx->co_key) {
129 dctx->co_key = EC_KEY_dup(sctx->co_key);
130 if (!dctx->co_key)
131 return 0;
132 }
133 dctx->kdf_type = sctx->kdf_type;
134 dctx->kdf_md = sctx->kdf_md;
135 dctx->kdf_outlen = sctx->kdf_outlen;
136 if (sctx->kdf_ukm) {
137 if ((dctx->kdf_ukm = calloc(1, sctx->kdf_ukmlen)) == NULL)
138 return 0;
139 memcpy(dctx->kdf_ukm, sctx->kdf_ukm, sctx->kdf_ukmlen);
140 } else
141 dctx->kdf_ukm = NULL;
142
143 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
144
145 return 1;
146}
147
148static void
149pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
150{
151 EC_PKEY_CTX *dctx = ctx->data;
152
153 if (dctx != NULL) {
154 EC_GROUP_free(dctx->gen_group);
155 EC_KEY_free(dctx->co_key);
156 free(dctx->kdf_ukm);
157 free(dctx);
158 ctx->data = NULL;
159 }
160}
161
162static int
163pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
164 const unsigned char *tbs, size_t tbslen)
165{
166 int ret, type;
167 unsigned int sltmp;
168 EC_PKEY_CTX *dctx = ctx->data;
169 EC_KEY *ec = ctx->pkey->pkey.ec;
170
171 if (!sig) {
172 *siglen = ECDSA_size(ec);
173 return 1;
174 } else if (*siglen < (size_t) ECDSA_size(ec)) {
175 ECerror(EC_R_BUFFER_TOO_SMALL);
176 return 0;
177 }
178 if (dctx->md)
179 type = EVP_MD_type(dctx->md);
180 else
181 type = NID_sha1;
182
183 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
184 if (ret <= 0)
185 return ret;
186 *siglen = (size_t) sltmp;
187 return 1;
188}
189
190static int
191pkey_ec_verify(EVP_PKEY_CTX *ctx,
192 const unsigned char *sig, size_t siglen,
193 const unsigned char *tbs, size_t tbslen)
194{
195 int ret, type;
196 EC_PKEY_CTX *dctx = ctx->data;
197 EC_KEY *ec = ctx->pkey->pkey.ec;
198
199 if (dctx->md)
200 type = EVP_MD_type(dctx->md);
201 else
202 type = NID_sha1;
203
204 ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
205
206 return ret;
207}
208
209static int
210pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
211{
212 int ret;
213 size_t outlen;
214 const EC_POINT *pubkey = NULL;
215 EC_KEY *eckey;
216 EC_PKEY_CTX *dctx = ctx->data;
217
218 if (!ctx->pkey || !ctx->peerkey) {
219 ECerror(EC_R_KEYS_NOT_SET);
220 return 0;
221 }
222
223 eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
224 if (key == NULL) {
225 *keylen = BN_num_bytes(eckey->group->p);
226 return 1;
227 }
228 pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
229
230 /*
231 * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
232 * not an error, the result is truncated.
233 */
234
235 outlen = *keylen;
236
237 ret = ECDH_compute_key(key, outlen, pubkey, eckey, NULL);
238 if (ret <= 0)
239 return 0;
240
241 *keylen = ret;
242
243 return 1;
244}
245
246static int
247pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
248{
249 EC_PKEY_CTX *dctx = ctx->data;
250 unsigned char *ktmp = NULL;
251 size_t ktmplen;
252 int rv = 0;
253
254 if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
255 return pkey_ec_derive(ctx, key, keylen);
256
257 if (!key) {
258 *keylen = dctx->kdf_outlen;
259 return 1;
260 }
261 if (*keylen != dctx->kdf_outlen)
262 return 0;
263 if (!pkey_ec_derive(ctx, NULL, &ktmplen))
264 return 0;
265 if ((ktmp = calloc(1, ktmplen)) == NULL) {
266 ECerror(ERR_R_MALLOC_FAILURE);
267 return 0;
268 }
269 if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
270 goto err;
271 /* Do KDF stuff */
272 if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, dctx->kdf_ukm,
273 dctx->kdf_ukmlen, dctx->kdf_md))
274 goto err;
275 rv = 1;
276
277 err:
278 freezero(ktmp, ktmplen);
279
280 return rv;
281}
282
283static int
284pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
285{
286 EC_PKEY_CTX *dctx = ctx->data;
287 EC_GROUP *group;
288
289 switch (type) {
290 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
291 group = EC_GROUP_new_by_curve_name(p1);
292 if (group == NULL) {
293 ECerror(EC_R_INVALID_CURVE);
294 return 0;
295 }
296 EC_GROUP_free(dctx->gen_group);
297 dctx->gen_group = group;
298 return 1;
299
300 case EVP_PKEY_CTRL_EC_PARAM_ENC:
301 if (!dctx->gen_group) {
302 ECerror(EC_R_NO_PARAMETERS_SET);
303 return 0;
304 }
305 EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
306 return 1;
307
308 case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
309 if (p1 == -2) {
310 if (dctx->cofactor_mode != -1)
311 return dctx->cofactor_mode;
312 else {
313 EC_KEY *ec_key = ctx->pkey->pkey.ec;
314 return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
315 }
316 } else if (p1 < -1 || p1 > 1)
317 return -2;
318 dctx->cofactor_mode = p1;
319 if (p1 != -1) {
320 EC_KEY *ec_key = ctx->pkey->pkey.ec;
321 if (!ec_key->group)
322 return -2;
323 /* If cofactor is 1 cofactor mode does nothing */
324 if (BN_is_one(ec_key->group->cofactor))
325 return 1;
326 if (!dctx->co_key) {
327 dctx->co_key = EC_KEY_dup(ec_key);
328 if (!dctx->co_key)
329 return 0;
330 }
331 if (p1)
332 EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
333 else
334 EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
335 } else {
336 EC_KEY_free(dctx->co_key);
337 dctx->co_key = NULL;
338 }
339 return 1;
340
341 case EVP_PKEY_CTRL_EC_KDF_TYPE:
342 if (p1 == -2)
343 return dctx->kdf_type;
344 if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63)
345 return -2;
346 dctx->kdf_type = p1;
347 return 1;
348
349 case EVP_PKEY_CTRL_EC_KDF_MD:
350 dctx->kdf_md = p2;
351 return 1;
352
353 case EVP_PKEY_CTRL_GET_EC_KDF_MD:
354 *(const EVP_MD **)p2 = dctx->kdf_md;
355 return 1;
356
357 case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
358 if (p1 <= 0)
359 return -2;
360 dctx->kdf_outlen = (size_t)p1;
361 return 1;
362
363 case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
364 *(int *)p2 = dctx->kdf_outlen;
365 return 1;
366
367 case EVP_PKEY_CTRL_EC_KDF_UKM:
368 free(dctx->kdf_ukm);
369 dctx->kdf_ukm = p2;
370 if (p2)
371 dctx->kdf_ukmlen = p1;
372 else
373 dctx->kdf_ukmlen = 0;
374 return 1;
375
376 case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
377 *(unsigned char **)p2 = dctx->kdf_ukm;
378 return dctx->kdf_ukmlen;
379
380 case EVP_PKEY_CTRL_MD:
381 /* RFC 3279, RFC 5758 and NIST CSOR. */
382 switch (EVP_MD_type(p2)) {
383 case NID_sha1:
384 case NID_ecdsa_with_SHA1:
385 case NID_sha224:
386 case NID_sha256:
387 case NID_sha384:
388 case NID_sha512:
389 case NID_sha3_224:
390 case NID_sha3_256:
391 case NID_sha3_384:
392 case NID_sha3_512:
393 break;
394 default:
395 ECerror(EC_R_INVALID_DIGEST_TYPE);
396 return 0;
397 }
398 dctx->md = p2;
399 return 1;
400
401 case EVP_PKEY_CTRL_GET_MD:
402 *(const EVP_MD **)p2 = dctx->md;
403 return 1;
404
405 case EVP_PKEY_CTRL_PEER_KEY:
406 /* Default behaviour is OK */
407 case EVP_PKEY_CTRL_DIGESTINIT:
408 case EVP_PKEY_CTRL_PKCS7_SIGN:
409 case EVP_PKEY_CTRL_CMS_SIGN:
410 return 1;
411
412 default:
413 return -2;
414
415 }
416}
417
418static int
419pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
420{
421 if (!strcmp(type, "ec_paramgen_curve")) {
422 int nid;
423 nid = EC_curve_nist2nid(value);
424 if (nid == NID_undef)
425 nid = OBJ_sn2nid(value);
426 if (nid == NID_undef)
427 nid = OBJ_ln2nid(value);
428 if (nid == NID_undef) {
429 ECerror(EC_R_INVALID_CURVE);
430 return 0;
431 }
432 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
433 } else if (strcmp(type, "ec_param_enc") == 0) {
434 int param_enc;
435 if (strcmp(value, "explicit") == 0)
436 param_enc = 0;
437 else if (strcmp(value, "named_curve") == 0)
438 param_enc = OPENSSL_EC_NAMED_CURVE;
439 else
440 return -2;
441 return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
442 } else if (strcmp(type, "ecdh_kdf_md") == 0) {
443 const EVP_MD *md;
444 if ((md = EVP_get_digestbyname(value)) == NULL) {
445 ECerror(EC_R_INVALID_DIGEST);
446 return 0;
447 }
448 return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
449 } else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
450 int cofactor_mode;
451 const char *errstr;
452
453 cofactor_mode = strtonum(value, -1, 1, &errstr);
454 if (errstr != NULL)
455 return -2;
456 return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, cofactor_mode);
457 }
458
459 return -2;
460}
461
462static int
463pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
464{
465 EC_KEY *ec = NULL;
466 EC_PKEY_CTX *dctx = ctx->data;
467 int ret = 0;
468
469 if (dctx->gen_group == NULL) {
470 ECerror(EC_R_NO_PARAMETERS_SET);
471 goto err;
472 }
473
474 if ((ec = EC_KEY_new()) == NULL)
475 goto err;
476 if (!EC_KEY_set_group(ec, dctx->gen_group))
477 goto err;
478 if (!EVP_PKEY_assign_EC_KEY(pkey, ec))
479 goto err;
480 ec = NULL;
481
482 ret = 1;
483
484 err:
485 EC_KEY_free(ec);
486
487 return ret;
488}
489
490static int
491pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
492{
493 EC_KEY *ec = NULL;
494 EC_PKEY_CTX *dctx = ctx->data;
495 int ret = 0;
496
497 if (ctx->pkey == NULL && dctx->gen_group == NULL) {
498 ECerror(EC_R_NO_PARAMETERS_SET);
499 goto err;
500 }
501
502 if ((ec = EC_KEY_new()) == NULL)
503 goto err;
504 if (!EVP_PKEY_set1_EC_KEY(pkey, ec))
505 goto err;
506
507 if (ctx->pkey != NULL) {
508 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
509 goto err;
510 } else {
511 if (!EC_KEY_set_group(ec, dctx->gen_group))
512 goto err;
513 }
514
515 if (!EC_KEY_generate_key(ec))
516 goto err;
517
518 ret = 1;
519
520 err:
521 EC_KEY_free(ec);
522
523 return ret;
524}
525
526const EVP_PKEY_METHOD ec_pkey_meth = {
527 .pkey_id = EVP_PKEY_EC,
528
529 .init = pkey_ec_init,
530 .copy = pkey_ec_copy,
531 .cleanup = pkey_ec_cleanup,
532
533 .paramgen = pkey_ec_paramgen,
534
535 .keygen = pkey_ec_keygen,
536
537 .sign = pkey_ec_sign,
538
539 .verify = pkey_ec_verify,
540
541 .derive = pkey_ec_kdf_derive,
542
543 .ctrl = pkey_ec_ctrl,
544 .ctrl_str = pkey_ec_ctrl_str
545};
diff --git a/src/lib/libcrypto/ec/eck_prn.c b/src/lib/libcrypto/ec/eck_prn.c
deleted file mode 100644
index c40a64966a..0000000000
--- a/src/lib/libcrypto/ec/eck_prn.c
+++ /dev/null
@@ -1,357 +0,0 @@
1/* $OpenBSD: eck_prn.c,v 1.41 2025/01/25 10:30:17 tb Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 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 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61 * contributed to the OpenSSL project.
62 */
63
64#include <stdio.h>
65
66#include <openssl/bio.h>
67#include <openssl/bn.h>
68#include <openssl/ec.h>
69#include <openssl/err.h>
70#include <openssl/evp.h>
71#include <openssl/objects.h>
72
73#include "bn_local.h"
74#include "ec_local.h"
75
76int
77EC_KEY_print(BIO *bio, const EC_KEY *ec_key, int off)
78{
79 EVP_PKEY *pkey;
80 int ret = 0;
81
82 if ((pkey = EVP_PKEY_new()) == NULL)
83 goto err;
84
85 if (!EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY *)ec_key))
86 goto err;
87
88 ret = EVP_PKEY_print_private(bio, pkey, off, NULL);
89
90 err:
91 EVP_PKEY_free(pkey);
92
93 return ret;
94}
95LCRYPTO_ALIAS(EC_KEY_print);
96
97int
98EC_KEY_print_fp(FILE *fp, const EC_KEY *ec_key, int off)
99{
100 BIO *bio;
101 int ret;
102
103 if ((bio = BIO_new(BIO_s_file())) == NULL) {
104 ECerror(ERR_R_BIO_LIB);
105 return 0;
106 }
107
108 BIO_set_fp(bio, fp, BIO_NOCLOSE);
109
110 ret = EC_KEY_print(bio, ec_key, off);
111
112 BIO_free(bio);
113
114 return ret;
115}
116LCRYPTO_ALIAS(EC_KEY_print_fp);
117
118int
119ECParameters_print(BIO *bio, const EC_KEY *ec_key)
120{
121 EVP_PKEY *pkey;
122 int ret = 0;
123
124 if ((pkey = EVP_PKEY_new()) == NULL)
125 goto err;
126
127 if (!EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY *)ec_key))
128 goto err;
129
130 ret = EVP_PKEY_print_params(bio, pkey, 4, NULL);
131
132 err:
133 EVP_PKEY_free(pkey);
134
135 return ret;
136}
137LCRYPTO_ALIAS(ECParameters_print);
138
139int
140ECParameters_print_fp(FILE *fp, const EC_KEY *ec_key)
141{
142 BIO *bio;
143 int ret;
144
145 if ((bio = BIO_new(BIO_s_file())) == NULL) {
146 ECerror(ERR_R_BIO_LIB);
147 return 0;
148 }
149
150 BIO_set_fp(bio, fp, BIO_NOCLOSE);
151
152 ret = ECParameters_print(bio, ec_key);
153
154 BIO_free(bio);
155
156 return ret;
157}
158LCRYPTO_ALIAS(ECParameters_print_fp);
159
160static int
161ecpk_print_asn1_parameters(BIO *bio, const EC_GROUP *group, int off)
162{
163 const char *nist_name;
164 int nid;
165 int ret = 0;
166
167 if (!BIO_indent(bio, off, 128)) {
168 ECerror(ERR_R_BIO_LIB);
169 goto err;
170 }
171
172 if ((nid = EC_GROUP_get_curve_name(group)) == NID_undef) {
173 ECerror(ERR_R_INTERNAL_ERROR);
174 goto err;
175 }
176
177 if (BIO_printf(bio, "ASN1 OID: %s\n", OBJ_nid2sn(nid)) <= 0) {
178 ECerror(ERR_R_BIO_LIB);
179 goto err;
180 }
181
182 if ((nist_name = EC_curve_nid2nist(nid)) != NULL) {
183 if (!BIO_indent(bio, off, 128)) {
184 ECerror(ERR_R_BIO_LIB);
185 goto err;
186 }
187 if (BIO_printf(bio, "NIST CURVE: %s\n", nist_name) <= 0) {
188 ECerror(ERR_R_BIO_LIB);
189 goto err;
190 }
191 }
192
193 ret = 1;
194 err:
195
196 return ret;
197}
198
199static int
200ecpk_print_explicit_parameters(BIO *bio, const EC_GROUP *group, int off)
201{
202 BN_CTX *ctx = NULL;
203 const BIGNUM *order;
204 BIGNUM *p, *a, *b, *cofactor;
205 BIGNUM *gen = NULL;
206 const EC_POINT *generator;
207 const char *conversion_form;
208 const unsigned char *seed;
209 size_t seed_len;
210 point_conversion_form_t form;
211 int ret = 0;
212
213 if ((ctx = BN_CTX_new()) == NULL) {
214 ECerror(ERR_R_MALLOC_FAILURE);
215 goto err;
216 }
217
218 BN_CTX_start(ctx);
219
220 if ((p = BN_CTX_get(ctx)) == NULL)
221 goto err;
222 if ((a = BN_CTX_get(ctx)) == NULL)
223 goto err;
224 if ((b = BN_CTX_get(ctx)) == NULL)
225 goto err;
226 if ((cofactor = BN_CTX_get(ctx)) == NULL)
227 goto err;
228 if ((gen = BN_CTX_get(ctx)) == NULL)
229 goto err;
230
231 if (!EC_GROUP_get_curve(group, p, a, b, ctx)) {
232 ECerror(ERR_R_EC_LIB);
233 goto err;
234 }
235 if ((order = EC_GROUP_get0_order(group)) == NULL) {
236 ECerror(ERR_R_EC_LIB);
237 goto err;
238 }
239 if (!EC_GROUP_get_cofactor(group, cofactor, NULL)) {
240 ECerror(ERR_R_EC_LIB);
241 goto err;
242 }
243
244 if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
245 ECerror(ERR_R_EC_LIB);
246 goto err;
247 }
248
249 form = EC_GROUP_get_point_conversion_form(group);
250 if (EC_POINT_point2bn(group, generator, form, gen, ctx) == NULL) {
251 ECerror(ERR_R_EC_LIB);
252 goto err;
253 }
254
255 if (!BIO_indent(bio, off, 128))
256 goto err;
257
258 if (BIO_printf(bio, "Field Type: %s\n", SN_X9_62_prime_field) <= 0)
259 goto err;
260
261 if (!bn_printf(bio, p, off, "Prime:"))
262 goto err;
263 if (!bn_printf(bio, a, off, "A: "))
264 goto err;
265 if (!bn_printf(bio, b, off, "B: "))
266 goto err;
267
268 if (form == POINT_CONVERSION_COMPRESSED)
269 conversion_form = "compressed";
270 else if (form == POINT_CONVERSION_UNCOMPRESSED)
271 conversion_form = "uncompressed";
272 else if (form == POINT_CONVERSION_HYBRID)
273 conversion_form = "hybrid";
274 else
275 conversion_form = "unknown";
276 if (!bn_printf(bio, gen, off, "Generator (%s):", conversion_form))
277 goto err;
278
279 if (!bn_printf(bio, order, off, "Order: "))
280 goto err;
281 if (!bn_printf(bio, cofactor, off, "Cofactor: "))
282 goto err;
283
284 if ((seed = EC_GROUP_get0_seed(group)) != NULL) {
285 size_t i;
286
287 seed_len = EC_GROUP_get_seed_len(group);
288
289 /* XXX - ecx_buf_print() has a CBS version of this - dedup. */
290 if (!BIO_indent(bio, off, 128))
291 goto err;
292 if (BIO_printf(bio, "Seed:") <= 0)
293 goto err;
294
295 for (i = 0; i < seed_len; i++) {
296 const char *sep = ":";
297
298 if (i % 15 == 0) {
299 if (BIO_printf(bio, "\n") <= 0)
300 goto err;
301 if (!BIO_indent(bio, off + 4, 128))
302 goto err;
303 }
304
305 if (i + 1 == seed_len)
306 sep = "";
307 if (BIO_printf(bio, "%02x%s", seed[i], sep) <= 0)
308 goto err;
309 }
310
311 if (BIO_printf(bio, "\n") <= 0)
312 goto err;
313 }
314
315 ret = 1;
316 err:
317 BN_CTX_end(ctx);
318 BN_CTX_free(ctx);
319
320 return ret;
321}
322
323int
324ECPKParameters_print(BIO *bio, const EC_GROUP *group, int off)
325{
326 if (group == NULL) {
327 ECerror(ERR_R_PASSED_NULL_PARAMETER);
328 return 0;
329 }
330
331 if ((EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) != 0)
332 return ecpk_print_asn1_parameters(bio, group, off);
333
334 return ecpk_print_explicit_parameters(bio, group, off);
335}
336LCRYPTO_ALIAS(ECPKParameters_print);
337
338int
339ECPKParameters_print_fp(FILE *fp, const EC_GROUP *group, int off)
340{
341 BIO *bio;
342 int ret;
343
344 if ((bio = BIO_new(BIO_s_file())) == NULL) {
345 ECerror(ERR_R_BUF_LIB);
346 return 0;
347 }
348
349 BIO_set_fp(bio, fp, BIO_NOCLOSE);
350
351 ret = ECPKParameters_print(bio, group, off);
352
353 BIO_free(bio);
354
355 return ret;
356}
357LCRYPTO_ALIAS(ECPKParameters_print_fp);
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
deleted file mode 100644
index ced85ceb1e..0000000000
--- a/src/lib/libcrypto/ec/ecp_methods.c
+++ /dev/null
@@ -1,1327 +0,0 @@
1/* $OpenBSD: ecp_methods.c,v 1.45 2025/03/24 13:07:04 jsing Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project.
5 */
6/* ====================================================================
7 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* ====================================================================
60 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
61 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
62 * and contributed to the OpenSSL project.
63 */
64
65#include <stdlib.h>
66
67#include <openssl/bn.h>
68#include <openssl/ec.h>
69#include <openssl/err.h>
70#include <openssl/objects.h>
71
72#include "bn_local.h"
73#include "ec_local.h"
74
75/*
76 * Most method functions in this file are designed to work with non-trivial
77 * representations of field elements if necessary: while standard modular
78 * addition and subtraction are used, the field_mul and field_sqr methods will
79 * be used for multiplication, and field_encode and field_decode (if defined)
80 * will be used for converting between representations.
81 *
82 * The functions ec_points_make_affine() and ec_point_get_affine_coordinates()
83 * assume that if a non-trivial representation is used, it is a Montgomery
84 * representation (i.e. 'encoding' means multiplying by some factor R).
85 */
86
87static inline int
88ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
89 BN_CTX *ctx)
90{
91 return group->meth->field_mul(group, r, a, b, ctx);
92}
93
94static inline int
95ec_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
96{
97 return group->meth->field_sqr(group, r, a, ctx);
98}
99
100static int
101ec_decode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx)
102{
103 if (bn == NULL)
104 return 1;
105
106 if (group->meth->field_decode != NULL)
107 return group->meth->field_decode(group, bn, x, ctx);
108
109 return bn_copy(bn, x);
110}
111
112static int
113ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx)
114{
115 if (!BN_nnmod(bn, x, group->p, ctx))
116 return 0;
117
118 if (group->meth->field_encode != NULL)
119 return group->meth->field_encode(group, bn, bn, ctx);
120
121 return 1;
122}
123
124static int
125ec_group_set_curve(EC_GROUP *group,
126 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
127{
128 BIGNUM *a_plus_3;
129 int ret = 0;
130
131 /* p must be a prime > 3 */
132 if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
133 ECerror(EC_R_INVALID_FIELD);
134 return 0;
135 }
136
137 BN_CTX_start(ctx);
138
139 if ((a_plus_3 = BN_CTX_get(ctx)) == NULL)
140 goto err;
141
142 if (!bn_copy(group->p, p))
143 goto err;
144 BN_set_negative(group->p, 0);
145
146 if (!ec_encode_scalar(group, group->a, a, ctx))
147 goto err;
148 if (!ec_encode_scalar(group, group->b, b, ctx))
149 goto err;
150
151 if (!BN_set_word(a_plus_3, 3))
152 goto err;
153 if (!BN_mod_add(a_plus_3, a_plus_3, a, group->p, ctx))
154 goto err;
155
156 group->a_is_minus3 = BN_is_zero(a_plus_3);
157
158 ret = 1;
159
160 err:
161 BN_CTX_end(ctx);
162
163 return ret;
164}
165
166static int
167ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
168 BN_CTX *ctx)
169{
170 if (p != NULL) {
171 if (!bn_copy(p, group->p))
172 return 0;
173 }
174 if (!ec_decode_scalar(group, a, group->a, ctx))
175 return 0;
176 if (!ec_decode_scalar(group, b, group->b, ctx))
177 return 0;
178
179 return 1;
180}
181
182static int
183ec_point_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
184{
185 BIGNUM *rh, *tmp, *Z4, *Z6;
186 int ret = -1;
187
188 if (EC_POINT_is_at_infinity(group, point))
189 return 1;
190
191 BN_CTX_start(ctx);
192
193 if ((rh = BN_CTX_get(ctx)) == NULL)
194 goto err;
195 if ((tmp = BN_CTX_get(ctx)) == NULL)
196 goto err;
197 if ((Z4 = BN_CTX_get(ctx)) == NULL)
198 goto err;
199 if ((Z6 = BN_CTX_get(ctx)) == NULL)
200 goto err;
201
202 /*
203 * The curve is defined by a Weierstrass equation y^2 = x^3 + a*x + b.
204 * The point is given in Jacobian projective coordinates where (X, Y, Z)
205 * represents (x, y) = (X/Z^2, Y/Z^3). Substituting this and multiplying
206 * by Z^6 transforms the above into Y^2 = X^3 + a*X*Z^4 + b*Z^6.
207 */
208
209 /* rh := X^2 */
210 if (!ec_field_sqr(group, rh, point->X, ctx))
211 goto err;
212
213 if (!point->Z_is_one) {
214 if (!ec_field_sqr(group, tmp, point->Z, ctx))
215 goto err;
216 if (!ec_field_sqr(group, Z4, tmp, ctx))
217 goto err;
218 if (!ec_field_mul(group, Z6, Z4, tmp, ctx))
219 goto err;
220
221 /* rh := (rh + a*Z^4)*X */
222 if (group->a_is_minus3) {
223 if (!BN_mod_lshift1_quick(tmp, Z4, group->p))
224 goto err;
225 if (!BN_mod_add_quick(tmp, tmp, Z4, group->p))
226 goto err;
227 if (!BN_mod_sub_quick(rh, rh, tmp, group->p))
228 goto err;
229 if (!ec_field_mul(group, rh, rh, point->X, ctx))
230 goto err;
231 } else {
232 if (!ec_field_mul(group, tmp, Z4, group->a, ctx))
233 goto err;
234 if (!BN_mod_add_quick(rh, rh, tmp, group->p))
235 goto err;
236 if (!ec_field_mul(group, rh, rh, point->X, ctx))
237 goto err;
238 }
239
240 /* rh := rh + b*Z^6 */
241 if (!ec_field_mul(group, tmp, group->b, Z6, ctx))
242 goto err;
243 if (!BN_mod_add_quick(rh, rh, tmp, group->p))
244 goto err;
245 } else {
246 /* point->Z_is_one */
247
248 /* rh := (rh + a)*X */
249 if (!BN_mod_add_quick(rh, rh, group->a, group->p))
250 goto err;
251 if (!ec_field_mul(group, rh, rh, point->X, ctx))
252 goto err;
253 /* rh := rh + b */
254 if (!BN_mod_add_quick(rh, rh, group->b, group->p))
255 goto err;
256 }
257
258 /* 'lh' := Y^2 */
259 if (!ec_field_sqr(group, tmp, point->Y, ctx))
260 goto err;
261
262 ret = (0 == BN_ucmp(tmp, rh));
263
264 err:
265 BN_CTX_end(ctx);
266
267 return ret;
268}
269
270/*
271 * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct.
272 */
273
274static int
275ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
276 BN_CTX *ctx)
277{
278 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
279 const BIGNUM *tmp1_, *tmp2_;
280 int ret = -1;
281
282 if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b))
283 return 0;
284 if (EC_POINT_is_at_infinity(group, a) || EC_POINT_is_at_infinity(group, b))
285 return 1;
286
287 if (a->Z_is_one && b->Z_is_one)
288 return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
289
290 BN_CTX_start(ctx);
291
292 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
293 goto end;
294 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
295 goto end;
296 if ((Za23 = BN_CTX_get(ctx)) == NULL)
297 goto end;
298 if ((Zb23 = BN_CTX_get(ctx)) == NULL)
299 goto end;
300
301 /*
302 * Decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), or
303 * equivalently, (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
304 */
305
306 if (!b->Z_is_one) {
307 if (!ec_field_sqr(group, Zb23, b->Z, ctx))
308 goto end;
309 if (!ec_field_mul(group, tmp1, a->X, Zb23, ctx))
310 goto end;
311 tmp1_ = tmp1;
312 } else
313 tmp1_ = a->X;
314 if (!a->Z_is_one) {
315 if (!ec_field_sqr(group, Za23, a->Z, ctx))
316 goto end;
317 if (!ec_field_mul(group, tmp2, b->X, Za23, ctx))
318 goto end;
319 tmp2_ = tmp2;
320 } else
321 tmp2_ = b->X;
322
323 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
324 if (BN_cmp(tmp1_, tmp2_) != 0) {
325 ret = 1; /* points differ */
326 goto end;
327 }
328 if (!b->Z_is_one) {
329 if (!ec_field_mul(group, Zb23, Zb23, b->Z, ctx))
330 goto end;
331 if (!ec_field_mul(group, tmp1, a->Y, Zb23, ctx))
332 goto end;
333 /* tmp1_ = tmp1 */
334 } else
335 tmp1_ = a->Y;
336 if (!a->Z_is_one) {
337 if (!ec_field_mul(group, Za23, Za23, a->Z, ctx))
338 goto end;
339 if (!ec_field_mul(group, tmp2, b->Y, Za23, ctx))
340 goto end;
341 /* tmp2_ = tmp2 */
342 } else
343 tmp2_ = b->Y;
344
345 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
346 if (BN_cmp(tmp1_, tmp2_) != 0) {
347 ret = 1; /* points differ */
348 goto end;
349 }
350 /* points are equal */
351 ret = 0;
352
353 end:
354 BN_CTX_end(ctx);
355
356 return ret;
357}
358
359static int
360ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
361 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
362{
363 int ret = 0;
364
365 if (x == NULL || y == NULL) {
366 ECerror(ERR_R_PASSED_NULL_PARAMETER);
367 goto err;
368 }
369
370 if (!ec_encode_scalar(group, point->X, x, ctx))
371 goto err;
372 if (!ec_encode_scalar(group, point->Y, y, ctx))
373 goto err;
374 if (!ec_encode_scalar(group, point->Z, BN_value_one(), ctx))
375 goto err;
376 point->Z_is_one = 1;
377
378 ret = 1;
379
380 err:
381 return ret;
382}
383
384static int
385ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
386 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
387{
388 BIGNUM *z, *Z, *Z_1, *Z_2, *Z_3;
389 int ret = 0;
390
391 BN_CTX_start(ctx);
392
393 if ((z = BN_CTX_get(ctx)) == NULL)
394 goto err;
395 if ((Z = BN_CTX_get(ctx)) == NULL)
396 goto err;
397 if ((Z_1 = BN_CTX_get(ctx)) == NULL)
398 goto err;
399 if ((Z_2 = BN_CTX_get(ctx)) == NULL)
400 goto err;
401 if ((Z_3 = BN_CTX_get(ctx)) == NULL)
402 goto err;
403
404 /*
405 * Convert from Jacobian projective coordinates (X, Y, Z) into
406 * (X/Z^2, Y/Z^3).
407 */
408
409 if (!ec_decode_scalar(group, z, point->Z, ctx))
410 goto err;
411
412 if (BN_is_one(z)) {
413 if (!ec_decode_scalar(group, x, point->X, ctx))
414 goto err;
415 if (!ec_decode_scalar(group, y, point->Y, ctx))
416 goto err;
417 goto done;
418 }
419
420 if (BN_mod_inverse_ct(Z_1, z, group->p, ctx) == NULL) {
421 ECerror(ERR_R_BN_LIB);
422 goto err;
423 }
424 if (group->meth->field_encode == NULL) {
425 /* field_sqr works on standard representation */
426 if (!ec_field_sqr(group, Z_2, Z_1, ctx))
427 goto err;
428 } else {
429 if (!BN_mod_sqr(Z_2, Z_1, group->p, ctx))
430 goto err;
431 }
432
433 if (x != NULL) {
434 /*
435 * in the Montgomery case, field_mul will cancel out
436 * Montgomery factor in X:
437 */
438 if (!ec_field_mul(group, x, point->X, Z_2, ctx))
439 goto err;
440 }
441 if (y != NULL) {
442 if (group->meth->field_encode == NULL) {
443 /* field_mul works on standard representation */
444 if (!ec_field_mul(group, Z_3, Z_2, Z_1, ctx))
445 goto err;
446 } else {
447 if (!BN_mod_mul(Z_3, Z_2, Z_1, group->p, ctx))
448 goto err;
449 }
450
451 /*
452 * in the Montgomery case, field_mul will cancel out
453 * Montgomery factor in Y:
454 */
455 if (!ec_field_mul(group, y, point->Y, Z_3, ctx))
456 goto err;
457 }
458
459 done:
460 ret = 1;
461
462 err:
463 BN_CTX_end(ctx);
464
465 return ret;
466}
467
468static int
469ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points,
470 BN_CTX *ctx)
471{
472 BIGNUM **prod_Z = NULL;
473 BIGNUM *one, *tmp, *tmp_Z;
474 size_t i;
475 int ret = 0;
476
477 if (num == 0)
478 return 1;
479
480 BN_CTX_start(ctx);
481
482 if ((one = BN_CTX_get(ctx)) == NULL)
483 goto err;
484 if ((tmp = BN_CTX_get(ctx)) == NULL)
485 goto err;
486 if ((tmp_Z = BN_CTX_get(ctx)) == NULL)
487 goto err;
488
489 if (!ec_encode_scalar(group, one, BN_value_one(), ctx))
490 goto err;
491
492 if ((prod_Z = calloc(num, sizeof *prod_Z)) == NULL)
493 goto err;
494 for (i = 0; i < num; i++) {
495 if ((prod_Z[i] = BN_CTX_get(ctx)) == NULL)
496 goto err;
497 }
498
499 /*
500 * Set prod_Z[i] to the product of points[0]->Z, ..., points[i]->Z,
501 * skipping any zero-valued inputs (pretend that they're 1).
502 */
503
504 if (!BN_is_zero(points[0]->Z)) {
505 if (!bn_copy(prod_Z[0], points[0]->Z))
506 goto err;
507 } else {
508 if (!bn_copy(prod_Z[0], one))
509 goto err;
510 }
511
512 for (i = 1; i < num; i++) {
513 if (!BN_is_zero(points[i]->Z)) {
514 if (!ec_field_mul(group, prod_Z[i],
515 prod_Z[i - 1], points[i]->Z, ctx))
516 goto err;
517 } else {
518 if (!bn_copy(prod_Z[i], prod_Z[i - 1]))
519 goto err;
520 }
521 }
522
523 /*
524 * Now use a single explicit inversion to replace every non-zero
525 * points[i]->Z by its inverse.
526 */
527 if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], group->p, ctx)) {
528 ECerror(ERR_R_BN_LIB);
529 goto err;
530 }
531
532 if (group->meth->field_encode != NULL) {
533 /*
534 * In the Montgomery case we just turned R*H (representing H)
535 * into 1/(R*H), but we need R*(1/H) (representing 1/H); i.e.,
536 * we need to multiply by the Montgomery factor twice.
537 */
538 if (!group->meth->field_encode(group, tmp, tmp, ctx))
539 goto err;
540 if (!group->meth->field_encode(group, tmp, tmp, ctx))
541 goto err;
542 }
543
544 for (i = num - 1; i > 0; i--) {
545 /*
546 * Loop invariant: tmp is the product of the inverses of
547 * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped).
548 */
549 if (BN_is_zero(points[i]->Z))
550 continue;
551
552 /* Set tmp_Z to the inverse of points[i]->Z. */
553 if (!ec_field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
554 goto err;
555 /* Adjust tmp to satisfy loop invariant. */
556 if (!ec_field_mul(group, tmp, tmp, points[i]->Z, ctx))
557 goto err;
558 /* Replace points[i]->Z by its inverse. */
559 if (!bn_copy(points[i]->Z, tmp_Z))
560 goto err;
561 }
562
563 if (!BN_is_zero(points[0]->Z)) {
564 /* Replace points[0]->Z by its inverse. */
565 if (!bn_copy(points[0]->Z, tmp))
566 goto err;
567 }
568
569 /* Finally, fix up the X and Y coordinates for all points. */
570 for (i = 0; i < num; i++) {
571 EC_POINT *p = points[i];
572
573 if (BN_is_zero(p->Z))
574 continue;
575
576 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
577
578 if (!ec_field_sqr(group, tmp, p->Z, ctx))
579 goto err;
580 if (!ec_field_mul(group, p->X, p->X, tmp, ctx))
581 goto err;
582
583 if (!ec_field_mul(group, tmp, tmp, p->Z, ctx))
584 goto err;
585 if (!ec_field_mul(group, p->Y, p->Y, tmp, ctx))
586 goto err;
587
588 if (!bn_copy(p->Z, one))
589 goto err;
590 p->Z_is_one = 1;
591 }
592
593 ret = 1;
594
595 err:
596 BN_CTX_end(ctx);
597 free(prod_Z);
598
599 return ret;
600}
601
602static int
603ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
604 BN_CTX *ctx)
605{
606 BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
607 int ret = 0;
608
609 if (a == b)
610 return EC_POINT_dbl(group, r, a, ctx);
611 if (EC_POINT_is_at_infinity(group, a))
612 return EC_POINT_copy(r, b);
613 if (EC_POINT_is_at_infinity(group, b))
614 return EC_POINT_copy(r, a);
615
616 BN_CTX_start(ctx);
617
618 if ((n0 = BN_CTX_get(ctx)) == NULL)
619 goto end;
620 if ((n1 = BN_CTX_get(ctx)) == NULL)
621 goto end;
622 if ((n2 = BN_CTX_get(ctx)) == NULL)
623 goto end;
624 if ((n3 = BN_CTX_get(ctx)) == NULL)
625 goto end;
626 if ((n4 = BN_CTX_get(ctx)) == NULL)
627 goto end;
628 if ((n5 = BN_CTX_get(ctx)) == NULL)
629 goto end;
630 if ((n6 = BN_CTX_get(ctx)) == NULL)
631 goto end;
632
633 /*
634 * Note that in this function we must not read components of 'a' or
635 * 'b' once we have written the corresponding components of 'r'. ('r'
636 * might be one of 'a' or 'b'.)
637 */
638
639 /* n1, n2 */
640 if (b->Z_is_one) {
641 if (!bn_copy(n1, a->X))
642 goto end;
643 if (!bn_copy(n2, a->Y))
644 goto end;
645 /* n1 = X_a */
646 /* n2 = Y_a */
647 } else {
648 if (!ec_field_sqr(group, n0, b->Z, ctx))
649 goto end;
650 if (!ec_field_mul(group, n1, a->X, n0, ctx))
651 goto end;
652 /* n1 = X_a * Z_b^2 */
653
654 if (!ec_field_mul(group, n0, n0, b->Z, ctx))
655 goto end;
656 if (!ec_field_mul(group, n2, a->Y, n0, ctx))
657 goto end;
658 /* n2 = Y_a * Z_b^3 */
659 }
660
661 /* n3, n4 */
662 if (a->Z_is_one) {
663 if (!bn_copy(n3, b->X))
664 goto end;
665 if (!bn_copy(n4, b->Y))
666 goto end;
667 /* n3 = X_b */
668 /* n4 = Y_b */
669 } else {
670 if (!ec_field_sqr(group, n0, a->Z, ctx))
671 goto end;
672 if (!ec_field_mul(group, n3, b->X, n0, ctx))
673 goto end;
674 /* n3 = X_b * Z_a^2 */
675
676 if (!ec_field_mul(group, n0, n0, a->Z, ctx))
677 goto end;
678 if (!ec_field_mul(group, n4, b->Y, n0, ctx))
679 goto end;
680 /* n4 = Y_b * Z_a^3 */
681 }
682
683 /* n5, n6 */
684 if (!BN_mod_sub_quick(n5, n1, n3, group->p))
685 goto end;
686 if (!BN_mod_sub_quick(n6, n2, n4, group->p))
687 goto end;
688 /* n5 = n1 - n3 */
689 /* n6 = n2 - n4 */
690
691 if (BN_is_zero(n5)) {
692 if (BN_is_zero(n6)) {
693 /* a is the same point as b */
694 BN_CTX_end(ctx);
695 ret = EC_POINT_dbl(group, r, a, ctx);
696 ctx = NULL;
697 goto end;
698 } else {
699 /* a is the inverse of b */
700 BN_zero(r->Z);
701 r->Z_is_one = 0;
702 ret = 1;
703 goto end;
704 }
705 }
706 /* 'n7', 'n8' */
707 if (!BN_mod_add_quick(n1, n1, n3, group->p))
708 goto end;
709 if (!BN_mod_add_quick(n2, n2, n4, group->p))
710 goto end;
711 /* 'n7' = n1 + n3 */
712 /* 'n8' = n2 + n4 */
713
714 /* Z_r */
715 if (a->Z_is_one && b->Z_is_one) {
716 if (!bn_copy(r->Z, n5))
717 goto end;
718 } else {
719 if (a->Z_is_one) {
720 if (!bn_copy(n0, b->Z))
721 goto end;
722 } else if (b->Z_is_one) {
723 if (!bn_copy(n0, a->Z))
724 goto end;
725 } else {
726 if (!ec_field_mul(group, n0, a->Z, b->Z, ctx))
727 goto end;
728 }
729 if (!ec_field_mul(group, r->Z, n0, n5, ctx))
730 goto end;
731 }
732 r->Z_is_one = 0;
733 /* Z_r = Z_a * Z_b * n5 */
734
735 /* X_r */
736 if (!ec_field_sqr(group, n0, n6, ctx))
737 goto end;
738 if (!ec_field_sqr(group, n4, n5, ctx))
739 goto end;
740 if (!ec_field_mul(group, n3, n1, n4, ctx))
741 goto end;
742 if (!BN_mod_sub_quick(r->X, n0, n3, group->p))
743 goto end;
744 /* X_r = n6^2 - n5^2 * 'n7' */
745
746 /* 'n9' */
747 if (!BN_mod_lshift1_quick(n0, r->X, group->p))
748 goto end;
749 if (!BN_mod_sub_quick(n0, n3, n0, group->p))
750 goto end;
751 /* n9 = n5^2 * 'n7' - 2 * X_r */
752
753 /* Y_r */
754 if (!ec_field_mul(group, n0, n0, n6, ctx))
755 goto end;
756 if (!ec_field_mul(group, n5, n4, n5, ctx))
757 goto end; /* now n5 is n5^3 */
758 if (!ec_field_mul(group, n1, n2, n5, ctx))
759 goto end;
760 if (!BN_mod_sub_quick(n0, n0, n1, group->p))
761 goto end;
762 if (BN_is_odd(n0))
763 if (!BN_add(n0, n0, group->p))
764 goto end;
765 /* now 0 <= n0 < 2*p, and n0 is even */
766 if (!BN_rshift1(r->Y, n0))
767 goto end;
768 /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
769
770 ret = 1;
771
772 end:
773 BN_CTX_end(ctx);
774
775 return ret;
776}
777
778static int
779ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
780{
781 BIGNUM *n0, *n1, *n2, *n3;
782 int ret = 0;
783
784 if (EC_POINT_is_at_infinity(group, a))
785 return EC_POINT_set_to_infinity(group, r);
786
787 BN_CTX_start(ctx);
788
789 if ((n0 = BN_CTX_get(ctx)) == NULL)
790 goto err;
791 if ((n1 = BN_CTX_get(ctx)) == NULL)
792 goto err;
793 if ((n2 = BN_CTX_get(ctx)) == NULL)
794 goto err;
795 if ((n3 = BN_CTX_get(ctx)) == NULL)
796 goto err;
797
798 /*
799 * Note that in this function we must not read components of 'a' once
800 * we have written the corresponding components of 'r'. ('r' might
801 * the same as 'a'.)
802 */
803
804 /* n1 */
805 if (a->Z_is_one) {
806 if (!ec_field_sqr(group, n0, a->X, ctx))
807 goto err;
808 if (!BN_mod_lshift1_quick(n1, n0, group->p))
809 goto err;
810 if (!BN_mod_add_quick(n0, n0, n1, group->p))
811 goto err;
812 if (!BN_mod_add_quick(n1, n0, group->a, group->p))
813 goto err;
814 /* n1 = 3 * X_a^2 + a_curve */
815 } else if (group->a_is_minus3) {
816 if (!ec_field_sqr(group, n1, a->Z, ctx))
817 goto err;
818 if (!BN_mod_add_quick(n0, a->X, n1, group->p))
819 goto err;
820 if (!BN_mod_sub_quick(n2, a->X, n1, group->p))
821 goto err;
822 if (!ec_field_mul(group, n1, n0, n2, ctx))
823 goto err;
824 if (!BN_mod_lshift1_quick(n0, n1, group->p))
825 goto err;
826 if (!BN_mod_add_quick(n1, n0, n1, group->p))
827 goto err;
828 /*
829 * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) = 3 * X_a^2 - 3 *
830 * Z_a^4
831 */
832 } else {
833 if (!ec_field_sqr(group, n0, a->X, ctx))
834 goto err;
835 if (!BN_mod_lshift1_quick(n1, n0, group->p))
836 goto err;
837 if (!BN_mod_add_quick(n0, n0, n1, group->p))
838 goto err;
839 if (!ec_field_sqr(group, n1, a->Z, ctx))
840 goto err;
841 if (!ec_field_sqr(group, n1, n1, ctx))
842 goto err;
843 if (!ec_field_mul(group, n1, n1, group->a, ctx))
844 goto err;
845 if (!BN_mod_add_quick(n1, n1, n0, group->p))
846 goto err;
847 /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
848 }
849
850 /* Z_r */
851 if (a->Z_is_one) {
852 if (!bn_copy(n0, a->Y))
853 goto err;
854 } else {
855 if (!ec_field_mul(group, n0, a->Y, a->Z, ctx))
856 goto err;
857 }
858 if (!BN_mod_lshift1_quick(r->Z, n0, group->p))
859 goto err;
860 r->Z_is_one = 0;
861 /* Z_r = 2 * Y_a * Z_a */
862
863 /* n2 */
864 if (!ec_field_sqr(group, n3, a->Y, ctx))
865 goto err;
866 if (!ec_field_mul(group, n2, a->X, n3, ctx))
867 goto err;
868 if (!BN_mod_lshift_quick(n2, n2, 2, group->p))
869 goto err;
870 /* n2 = 4 * X_a * Y_a^2 */
871
872 /* X_r */
873 if (!BN_mod_lshift1_quick(n0, n2, group->p))
874 goto err;
875 if (!ec_field_sqr(group, r->X, n1, ctx))
876 goto err;
877 if (!BN_mod_sub_quick(r->X, r->X, n0, group->p))
878 goto err;
879 /* X_r = n1^2 - 2 * n2 */
880
881 /* n3 */
882 if (!ec_field_sqr(group, n0, n3, ctx))
883 goto err;
884 if (!BN_mod_lshift_quick(n3, n0, 3, group->p))
885 goto err;
886 /* n3 = 8 * Y_a^4 */
887
888 /* Y_r */
889 if (!BN_mod_sub_quick(n0, n2, r->X, group->p))
890 goto err;
891 if (!ec_field_mul(group, n0, n1, n0, ctx))
892 goto err;
893 if (!BN_mod_sub_quick(r->Y, n0, n3, group->p))
894 goto err;
895 /* Y_r = n1 * (n2 - X_r) - n3 */
896
897 ret = 1;
898
899 err:
900 BN_CTX_end(ctx);
901
902 return ret;
903}
904
905static int
906ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
907{
908 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
909 /* point is its own inverse */
910 return 1;
911
912 return BN_usub(point->Y, group->p, point->Y);
913}
914
915/*
916 * Apply randomization of EC point Jacobian projective coordinates:
917 *
918 * (X, Y, Z) = (lambda^2 * X, lambda^3 * Y, lambda * Z)
919 *
920 * where lambda is in the interval [1, p).
921 */
922static int
923ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
924{
925 BIGNUM *lambda = NULL;
926 BIGNUM *tmp = NULL;
927 int ret = 0;
928
929 BN_CTX_start(ctx);
930 if ((lambda = BN_CTX_get(ctx)) == NULL)
931 goto err;
932 if ((tmp = BN_CTX_get(ctx)) == NULL)
933 goto err;
934
935 /* Generate lambda in [1, p). */
936 if (!bn_rand_interval(lambda, 1, group->p))
937 goto err;
938
939 if (group->meth->field_encode != NULL &&
940 !group->meth->field_encode(group, lambda, lambda, ctx))
941 goto err;
942
943 /* Z = lambda * Z */
944 if (!ec_field_mul(group, p->Z, lambda, p->Z, ctx))
945 goto err;
946
947 /* tmp = lambda^2 */
948 if (!ec_field_sqr(group, tmp, lambda, ctx))
949 goto err;
950
951 /* X = lambda^2 * X */
952 if (!ec_field_mul(group, p->X, tmp, p->X, ctx))
953 goto err;
954
955 /* tmp = lambda^3 */
956 if (!ec_field_mul(group, tmp, tmp, lambda, ctx))
957 goto err;
958
959 /* Y = lambda^3 * Y */
960 if (!ec_field_mul(group, p->Y, tmp, p->Y, ctx))
961 goto err;
962
963 /* Disable optimized arithmetics after replacing Z by lambda * Z. */
964 p->Z_is_one = 0;
965
966 ret = 1;
967
968 err:
969 BN_CTX_end(ctx);
970 return ret;
971}
972
973#define EC_POINT_BN_set_flags(P, flags) do { \
974 BN_set_flags((P)->X, (flags)); \
975 BN_set_flags((P)->Y, (flags)); \
976 BN_set_flags((P)->Z, (flags)); \
977} while(0)
978
979#define EC_POINT_CSWAP(c, a, b, w, t) do { \
980 if (!BN_swap_ct(c, (a)->X, (b)->X, w) || \
981 !BN_swap_ct(c, (a)->Y, (b)->Y, w) || \
982 !BN_swap_ct(c, (a)->Z, (b)->Z, w)) \
983 goto err; \
984 t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
985 (a)->Z_is_one ^= (t); \
986 (b)->Z_is_one ^= (t); \
987} while(0)
988
989/*
990 * This function computes (in constant time) a point multiplication over the
991 * EC group.
992 *
993 * At a high level, it is Montgomery ladder with conditional swaps.
994 *
995 * It performs either a fixed point multiplication
996 * (scalar * generator)
997 * when point is NULL, or a variable point multiplication
998 * (scalar * point)
999 * when point is not NULL.
1000 *
1001 * scalar should be in the range [0,n) otherwise all constant time bets are off.
1002 *
1003 * NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
1004 * which of course are not constant time themselves.
1005 *
1006 * The product is stored in r.
1007 *
1008 * Returns 1 on success, 0 otherwise.
1009 */
1010static int
1011ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1012 const EC_POINT *point, BN_CTX *ctx)
1013{
1014 int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
1015 EC_POINT *s = NULL;
1016 BIGNUM *k = NULL;
1017 BIGNUM *lambda = NULL;
1018 BIGNUM *cardinality = NULL;
1019 int ret = 0;
1020
1021 BN_CTX_start(ctx);
1022
1023 if ((s = EC_POINT_dup(point, group)) == NULL)
1024 goto err;
1025
1026 EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
1027
1028 if ((cardinality = BN_CTX_get(ctx)) == NULL)
1029 goto err;
1030 if ((lambda = BN_CTX_get(ctx)) == NULL)
1031 goto err;
1032 if ((k = BN_CTX_get(ctx)) == NULL)
1033 goto err;
1034 if (!BN_mul(cardinality, group->order, group->cofactor, ctx))
1035 goto err;
1036
1037 /*
1038 * Group cardinalities are often on a word boundary.
1039 * So when we pad the scalar, some timing diff might
1040 * pop if it needs to be expanded due to carries.
1041 * So expand ahead of time.
1042 */
1043 cardinality_bits = BN_num_bits(cardinality);
1044 group_top = cardinality->top;
1045 if (!bn_wexpand(k, group_top + 2) ||
1046 !bn_wexpand(lambda, group_top + 2))
1047 goto err;
1048
1049 if (!bn_copy(k, scalar))
1050 goto err;
1051
1052 BN_set_flags(k, BN_FLG_CONSTTIME);
1053
1054 if (BN_num_bits(k) > cardinality_bits || BN_is_negative(k)) {
1055 /*
1056 * This is an unusual input, and we don't guarantee
1057 * constant-timeness
1058 */
1059 if (!BN_nnmod(k, k, cardinality, ctx))
1060 goto err;
1061 }
1062
1063 if (!BN_add(lambda, k, cardinality))
1064 goto err;
1065 BN_set_flags(lambda, BN_FLG_CONSTTIME);
1066 if (!BN_add(k, lambda, cardinality))
1067 goto err;
1068 /*
1069 * lambda := scalar + cardinality
1070 * k := scalar + 2*cardinality
1071 */
1072 kbit = BN_is_bit_set(lambda, cardinality_bits);
1073 if (!BN_swap_ct(kbit, k, lambda, group_top + 2))
1074 goto err;
1075
1076 group_top = group->p->top;
1077 if (!bn_wexpand(s->X, group_top) ||
1078 !bn_wexpand(s->Y, group_top) ||
1079 !bn_wexpand(s->Z, group_top) ||
1080 !bn_wexpand(r->X, group_top) ||
1081 !bn_wexpand(r->Y, group_top) ||
1082 !bn_wexpand(r->Z, group_top))
1083 goto err;
1084
1085 /*
1086 * Apply coordinate blinding for EC_POINT if the underlying EC_METHOD
1087 * implements it.
1088 */
1089 if (!ec_blind_coordinates(group, s, ctx))
1090 goto err;
1091
1092 /* top bit is a 1, in a fixed pos */
1093 if (!EC_POINT_copy(r, s))
1094 goto err;
1095
1096 EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
1097
1098 if (!EC_POINT_dbl(group, s, s, ctx))
1099 goto err;
1100
1101 pbit = 0;
1102
1103 /*
1104 * The ladder step, with branches, is
1105 *
1106 * k[i] == 0: S = add(R, S), R = dbl(R)
1107 * k[i] == 1: R = add(S, R), S = dbl(S)
1108 *
1109 * Swapping R, S conditionally on k[i] leaves you with state
1110 *
1111 * k[i] == 0: T, U = R, S
1112 * k[i] == 1: T, U = S, R
1113 *
1114 * Then perform the ECC ops.
1115 *
1116 * U = add(T, U)
1117 * T = dbl(T)
1118 *
1119 * Which leaves you with state
1120 *
1121 * k[i] == 0: U = add(R, S), T = dbl(R)
1122 * k[i] == 1: U = add(S, R), T = dbl(S)
1123 *
1124 * Swapping T, U conditionally on k[i] leaves you with state
1125 *
1126 * k[i] == 0: R, S = T, U
1127 * k[i] == 1: R, S = U, T
1128 *
1129 * Which leaves you with state
1130 *
1131 * k[i] == 0: S = add(R, S), R = dbl(R)
1132 * k[i] == 1: R = add(S, R), S = dbl(S)
1133 *
1134 * So we get the same logic, but instead of a branch it's a
1135 * conditional swap, followed by ECC ops, then another conditional swap.
1136 *
1137 * Optimization: The end of iteration i and start of i-1 looks like
1138 *
1139 * ...
1140 * CSWAP(k[i], R, S)
1141 * ECC
1142 * CSWAP(k[i], R, S)
1143 * (next iteration)
1144 * CSWAP(k[i-1], R, S)
1145 * ECC
1146 * CSWAP(k[i-1], R, S)
1147 * ...
1148 *
1149 * So instead of two contiguous swaps, you can merge the condition
1150 * bits and do a single swap.
1151 *
1152 * k[i] k[i-1] Outcome
1153 * 0 0 No Swap
1154 * 0 1 Swap
1155 * 1 0 Swap
1156 * 1 1 No Swap
1157 *
1158 * This is XOR. pbit tracks the previous bit of k.
1159 */
1160
1161 for (i = cardinality_bits - 1; i >= 0; i--) {
1162 kbit = BN_is_bit_set(k, i) ^ pbit;
1163 EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
1164 if (!EC_POINT_add(group, s, r, s, ctx))
1165 goto err;
1166 if (!EC_POINT_dbl(group, r, r, ctx))
1167 goto err;
1168 /*
1169 * pbit logic merges this cswap with that of the
1170 * next iteration
1171 */
1172 pbit ^= kbit;
1173 }
1174 /* one final cswap to move the right value into r */
1175 EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
1176
1177 ret = 1;
1178
1179 err:
1180 EC_POINT_free(s);
1181 BN_CTX_end(ctx);
1182
1183 return ret;
1184}
1185
1186#undef EC_POINT_BN_set_flags
1187#undef EC_POINT_CSWAP
1188
1189static int
1190ec_mul_single_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1191 const EC_POINT *point, BN_CTX *ctx)
1192{
1193 return ec_mul_ct(group, r, scalar, point, ctx);
1194}
1195
1196static int
1197ec_mul_double_nonct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
1198 const EC_POINT *point1, const BIGNUM *scalar2, const EC_POINT *point2,
1199 BN_CTX *ctx)
1200{
1201 return ec_wnaf_mul(group, r, scalar1, point1, scalar2, point2, ctx);
1202}
1203
1204static int
1205ec_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1206 const BIGNUM *b, BN_CTX *ctx)
1207{
1208 return BN_mod_mul(r, a, b, group->p, ctx);
1209}
1210
1211static int
1212ec_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
1213{
1214 return BN_mod_sqr(r, a, group->p, ctx);
1215}
1216
1217static int
1218ec_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
1219 const BIGNUM *b, BN_CTX *ctx)
1220{
1221 BN_MONT_CTX_free(group->mont_ctx);
1222 if ((group->mont_ctx = BN_MONT_CTX_create(p, ctx)) == NULL)
1223 goto err;
1224
1225 if (!ec_group_set_curve(group, p, a, b, ctx))
1226 goto err;
1227
1228 return 1;
1229
1230 err:
1231 BN_MONT_CTX_free(group->mont_ctx);
1232 group->mont_ctx = NULL;
1233
1234 return 0;
1235}
1236
1237static int
1238ec_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1239 const BIGNUM *b, BN_CTX *ctx)
1240{
1241 if (group->mont_ctx == NULL) {
1242 ECerror(EC_R_NOT_INITIALIZED);
1243 return 0;
1244 }
1245 return BN_mod_mul_montgomery(r, a, b, group->mont_ctx, ctx);
1246}
1247
1248static int
1249ec_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1250 BN_CTX *ctx)
1251{
1252 if (group->mont_ctx == NULL) {
1253 ECerror(EC_R_NOT_INITIALIZED);
1254 return 0;
1255 }
1256 return BN_mod_mul_montgomery(r, a, a, group->mont_ctx, ctx);
1257}
1258
1259static int
1260ec_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1261 BN_CTX *ctx)
1262{
1263 if (group->mont_ctx == NULL) {
1264 ECerror(EC_R_NOT_INITIALIZED);
1265 return 0;
1266 }
1267 return BN_to_montgomery(r, a, group->mont_ctx, ctx);
1268}
1269
1270static int
1271ec_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1272 BN_CTX *ctx)
1273{
1274 if (group->mont_ctx == NULL) {
1275 ECerror(EC_R_NOT_INITIALIZED);
1276 return 0;
1277 }
1278 return BN_from_montgomery(r, a, group->mont_ctx, ctx);
1279}
1280
1281static const EC_METHOD ec_GFp_simple_method = {
1282 .group_set_curve = ec_group_set_curve,
1283 .group_get_curve = ec_group_get_curve,
1284 .point_is_on_curve = ec_point_is_on_curve,
1285 .point_cmp = ec_point_cmp,
1286 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1287 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1288 .points_make_affine = ec_points_make_affine,
1289 .add = ec_add,
1290 .dbl = ec_dbl,
1291 .invert = ec_invert,
1292 .mul_single_ct = ec_mul_single_ct,
1293 .mul_double_nonct = ec_mul_double_nonct,
1294 .field_mul = ec_simple_field_mul,
1295 .field_sqr = ec_simple_field_sqr,
1296};
1297
1298const EC_METHOD *
1299EC_GFp_simple_method(void)
1300{
1301 return &ec_GFp_simple_method;
1302}
1303
1304static const EC_METHOD ec_GFp_mont_method = {
1305 .group_set_curve = ec_mont_group_set_curve,
1306 .group_get_curve = ec_group_get_curve,
1307 .point_is_on_curve = ec_point_is_on_curve,
1308 .point_cmp = ec_point_cmp,
1309 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1310 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1311 .points_make_affine = ec_points_make_affine,
1312 .add = ec_add,
1313 .dbl = ec_dbl,
1314 .invert = ec_invert,
1315 .mul_single_ct = ec_mul_single_ct,
1316 .mul_double_nonct = ec_mul_double_nonct,
1317 .field_mul = ec_mont_field_mul,
1318 .field_sqr = ec_mont_field_sqr,
1319 .field_encode = ec_mont_field_encode,
1320 .field_decode = ec_mont_field_decode,
1321};
1322
1323const EC_METHOD *
1324EC_GFp_mont_method(void)
1325{
1326 return &ec_GFp_mont_method;
1327}
diff --git a/src/lib/libcrypto/ec/ecx_methods.c b/src/lib/libcrypto/ec/ecx_methods.c
deleted file mode 100644
index 6b5759d4fa..0000000000
--- a/src/lib/libcrypto/ec/ecx_methods.c
+++ /dev/null
@@ -1,973 +0,0 @@
1/* $OpenBSD: ecx_methods.c,v 1.14 2024/08/28 07:15:04 tb Exp $ */
2/*
3 * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <string.h>
19
20#include <openssl/cms.h>
21#include <openssl/curve25519.h>
22#include <openssl/ec.h>
23#include <openssl/err.h>
24#include <openssl/evp.h>
25#include <openssl/x509.h>
26
27#include "asn1_local.h"
28#include "bytestring.h"
29#include "curve25519_internal.h"
30#include "evp_local.h"
31#include "x509_local.h"
32
33/*
34 * EVP PKEY and PKEY ASN.1 methods Ed25519 and X25519.
35 *
36 * RFC 7748 - Elliptic Curves for Security.
37 * RFC 8032 - Edwards-Curve Digital Signature Algorithm (EdDSA).
38 */
39
40#define ED25519_BITS 253
41#define ED25519_SECURITY_BITS 128
42#define ED25519_SIG_SIZE 64
43
44#define X25519_BITS 253
45#define X25519_SECURITY_BITS 128
46
47static int
48ecx_key_len(int nid)
49{
50 switch (nid) {
51 case NID_ED25519:
52 return ED25519_KEYLEN;
53 case NID_X25519:
54 return X25519_KEYLEN;
55 }
56
57 return 0;
58}
59
60static struct ecx_key_st *
61ecx_key_new(int nid)
62{
63 struct ecx_key_st *ecx_key;
64 int key_len;
65
66 if ((key_len = ecx_key_len(nid)) == 0)
67 return NULL;
68
69 if ((ecx_key = calloc(1, sizeof(*ecx_key))) == NULL)
70 return NULL;
71
72 ecx_key->nid = nid;
73 ecx_key->key_len = key_len;
74
75 return ecx_key;
76}
77
78static void
79ecx_key_clear(struct ecx_key_st *ecx_key)
80{
81 freezero(ecx_key->priv_key, ecx_key->priv_key_len);
82 ecx_key->priv_key = NULL;
83 ecx_key->priv_key_len = 0;
84
85 freezero(ecx_key->pub_key, ecx_key->pub_key_len);
86 ecx_key->pub_key = NULL;
87 ecx_key->pub_key_len = 0;
88}
89
90static void
91ecx_key_free(struct ecx_key_st *ecx_key)
92{
93 if (ecx_key == NULL)
94 return;
95
96 ecx_key_clear(ecx_key);
97
98 freezero(ecx_key, sizeof(*ecx_key));
99}
100
101static int
102ecx_key_generate(struct ecx_key_st *ecx_key)
103{
104 uint8_t *pub_key = NULL, *priv_key = NULL;
105 int ret = 0;
106
107 ecx_key_clear(ecx_key);
108
109 if ((pub_key = calloc(1, ecx_key->key_len)) == NULL)
110 goto err;
111 if ((priv_key = calloc(1, ecx_key->key_len)) == NULL)
112 goto err;
113
114 switch (ecx_key->nid) {
115 case NID_ED25519:
116 ED25519_keypair(pub_key, priv_key);
117 break;
118 case NID_X25519:
119 X25519_keypair(pub_key, priv_key);
120 break;
121 default:
122 goto err;
123 }
124
125 ecx_key->priv_key = priv_key;
126 ecx_key->priv_key_len = ecx_key->key_len;
127 priv_key = NULL;
128
129 ecx_key->pub_key = pub_key;
130 ecx_key->pub_key_len = ecx_key->key_len;
131 pub_key = NULL;
132
133 ret = 1;
134
135 err:
136 freezero(pub_key, ecx_key->key_len);
137 freezero(priv_key, ecx_key->key_len);
138
139 return ret;
140}
141
142static int
143ecx_key_set_priv(struct ecx_key_st *ecx_key, const uint8_t *priv_key,
144 size_t priv_key_len)
145{
146 uint8_t *pub_key = NULL;
147 CBS cbs;
148
149 ecx_key_clear(ecx_key);
150
151 if (priv_key_len != ecx_key->key_len)
152 goto err;
153
154 if ((pub_key = calloc(1, ecx_key->key_len)) == NULL)
155 goto err;
156
157 switch (ecx_key->nid) {
158 case NID_ED25519:
159 ED25519_public_from_private(pub_key, priv_key);
160 break;
161 case NID_X25519:
162 X25519_public_from_private(pub_key, priv_key);
163 break;
164 default:
165 goto err;
166 }
167
168 CBS_init(&cbs, priv_key, priv_key_len);
169 if (!CBS_stow(&cbs, &ecx_key->priv_key, &ecx_key->priv_key_len))
170 goto err;
171
172 ecx_key->pub_key = pub_key;
173 ecx_key->pub_key_len = ecx_key->key_len;
174 pub_key = NULL;
175
176 err:
177 freezero(pub_key, ecx_key->key_len);
178
179 return 1;
180}
181
182static int
183ecx_key_set_pub(struct ecx_key_st *ecx_key, const uint8_t *pub_key,
184 size_t pub_key_len)
185{
186 CBS cbs;
187
188 ecx_key_clear(ecx_key);
189
190 if (pub_key_len != ecx_key->key_len)
191 return 0;
192
193 CBS_init(&cbs, pub_key, pub_key_len);
194 if (!CBS_stow(&cbs, &ecx_key->pub_key, &ecx_key->pub_key_len))
195 return 0;
196
197 return 1;
198}
199
200static int
201ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *xpubkey)
202{
203 struct ecx_key_st *ecx_key = NULL;
204 X509_ALGOR *algor;
205 int algor_type;
206 const uint8_t *param;
207 int param_len;
208 int ret = 0;
209
210 if (!X509_PUBKEY_get0_param(NULL, &param, &param_len, &algor, xpubkey))
211 goto err;
212
213 /* Ensure that parameters have not been specified in the encoding. */
214 if (algor != NULL) {
215 X509_ALGOR_get0(NULL, &algor_type, NULL, algor);
216 if (algor_type != V_ASN1_UNDEF) {
217 ECerror(EC_R_INVALID_ENCODING);
218 goto err;
219 }
220 }
221
222 if (param == NULL || param_len != ecx_key_len(pkey->ameth->pkey_id)) {
223 ECerror(EC_R_INVALID_ENCODING);
224 goto err;
225 }
226
227 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL)
228 goto err;
229 if (!ecx_key_set_pub(ecx_key, param, param_len))
230 goto err;
231 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key))
232 goto err;
233 ecx_key = NULL;
234
235 ret = 1;
236
237 err:
238 ecx_key_free(ecx_key);
239
240 return ret;
241}
242
243static int
244ecx_pub_encode(X509_PUBKEY *xpubkey, const EVP_PKEY *pkey)
245{
246 const struct ecx_key_st *ecx_key = pkey->pkey.ecx;
247 uint8_t *pub_key = NULL;
248 size_t pub_key_len = 0;
249 ASN1_OBJECT *aobj;
250 CBS cbs;
251 int ret = 0;
252
253 if (ecx_key == NULL) {
254 ECerror(EC_R_INVALID_KEY);
255 goto err;
256 }
257
258 if (ecx_key->pub_key_len != ecx_key->key_len)
259 goto err;
260
261 if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL)
262 goto err;
263
264 CBS_init(&cbs, ecx_key->pub_key, ecx_key->pub_key_len);
265 if (!CBS_stow(&cbs, &pub_key, &pub_key_len))
266 goto err;
267
268 if (!X509_PUBKEY_set0_param(xpubkey, aobj, V_ASN1_UNDEF, NULL,
269 pub_key, pub_key_len))
270 goto err;
271
272 pub_key = NULL;
273 pub_key_len = 0;
274
275 ret = 1;
276
277 err:
278 free(pub_key);
279
280 return ret;
281}
282
283static int
284ecx_pub_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2)
285{
286 if (pkey1->pkey.ecx == NULL || pkey1->pkey.ecx->pub_key == NULL)
287 return -2;
288 if (pkey2->pkey.ecx == NULL || pkey2->pkey.ecx->pub_key == NULL)
289 return -2;
290 if (pkey1->pkey.ecx->pub_key_len != pkey2->pkey.ecx->pub_key_len)
291 return -2;
292
293 return timingsafe_memcmp(pkey1->pkey.ecx->pub_key, pkey2->pkey.ecx->pub_key,
294 pkey1->pkey.ecx->pub_key_len) == 0;
295}
296
297/* Reimplementation of ASN1_buf_print() that adds a secondary indent of 4. */
298static int
299ecx_buf_print(BIO *bio, const uint8_t *buf, size_t buf_len, int indent)
300{
301 uint8_t u8;
302 size_t octets = 0;
303 const char *sep = ":", *nl = "";
304 CBS cbs;
305
306 if (indent > 60)
307 indent = 60;
308 indent += 4;
309 if (indent < 0)
310 indent = 0;
311
312 CBS_init(&cbs, buf, buf_len);
313 while (CBS_len(&cbs) > 0) {
314 if (!CBS_get_u8(&cbs, &u8))
315 return 0;
316 if (octets++ % 15 == 0) {
317 if (BIO_printf(bio, "%s%*s", nl, indent, "") < 0)
318 return 0;
319 nl = "\n";
320 }
321 if (CBS_len(&cbs) == 0)
322 sep = "";
323 if (BIO_printf(bio, "%02x%s", u8, sep) <= 0)
324 return 0;
325 }
326
327 if (BIO_printf(bio, "\n") <= 0)
328 return 0;
329
330 return 1;
331}
332
333static int
334ecx_pub_print(BIO *bio, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
335{
336 struct ecx_key_st *ecx_key = pkey->pkey.ecx;
337 const char *name;
338
339 if ((name = OBJ_nid2ln(pkey->ameth->pkey_id)) == NULL)
340 return 0;
341
342 if (ecx_key == NULL || ecx_key->pub_key == NULL)
343 return BIO_printf(bio, "%*s<INVALID PUBLIC KEY>\n",
344 indent, "") > 0;
345
346 if (BIO_printf(bio, "%*s%s Public-Key:\n", indent, "", name) <= 0)
347 return 0;
348 if (BIO_printf(bio, "%*spub:\n", indent, "") <= 0)
349 return 0;
350 if (!ecx_buf_print(bio, ecx_key->pub_key, ecx_key->pub_key_len, indent))
351 return 0;
352
353 return 1;
354}
355
356static int
357ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8pki)
358{
359 struct ecx_key_st *ecx_key = NULL;
360 ASN1_OCTET_STRING *aos = NULL;
361 const X509_ALGOR *algor;
362 int algor_type;
363 const uint8_t *param;
364 int param_len;
365 int ret = 0;
366
367 if (!PKCS8_pkey_get0(NULL, &param, &param_len, &algor, p8pki))
368 goto err;
369 if ((aos = d2i_ASN1_OCTET_STRING(NULL, &param, param_len)) == NULL)
370 goto err;
371
372 /* Ensure that parameters have not been specified in the encoding. */
373 if (algor != NULL) {
374 X509_ALGOR_get0(NULL, &algor_type, NULL, algor);
375 if (algor_type != V_ASN1_UNDEF) {
376 ECerror(EC_R_INVALID_ENCODING);
377 goto err;
378 }
379 }
380
381 if (ASN1_STRING_get0_data(aos) == NULL ||
382 ASN1_STRING_length(aos) != ecx_key_len(pkey->ameth->pkey_id)) {
383 ECerror(EC_R_INVALID_ENCODING);
384 goto err;
385 }
386
387 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL)
388 goto err;
389 if (!ecx_key_set_priv(ecx_key, ASN1_STRING_get0_data(aos),
390 ASN1_STRING_length(aos)))
391 goto err;
392 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key))
393 goto err;
394 ecx_key = NULL;
395
396 ret = 1;
397
398 err:
399 ASN1_OCTET_STRING_free(aos);
400 ecx_key_free(ecx_key);
401
402 return ret;
403}
404
405static int
406ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8pki, const EVP_PKEY *pkey)
407{
408 struct ecx_key_st *ecx_key = pkey->pkey.ecx;
409 ASN1_OCTET_STRING *aos = NULL;
410 ASN1_OBJECT *aobj;
411 uint8_t *der = NULL;
412 int der_len = 0;
413 int ret = 0;
414
415 if (ecx_key == NULL || ecx_key->priv_key == NULL) {
416 ECerror(EC_R_INVALID_PRIVATE_KEY);
417 goto err;
418 }
419
420 if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL)
421 goto err;
422
423 if ((aos = ASN1_OCTET_STRING_new()) == NULL)
424 goto err;
425 if (!ASN1_OCTET_STRING_set(aos, ecx_key->priv_key,
426 ecx_key->priv_key_len))
427 goto err;
428 if ((der_len = i2d_ASN1_OCTET_STRING(aos, &der)) < 0)
429 goto err;
430 if (!PKCS8_pkey_set0(p8pki, aobj, 0, V_ASN1_UNDEF, NULL, der, der_len))
431 goto err;
432
433 der = NULL;
434 der_len = 0;
435
436 ret = 1;
437
438 err:
439 freezero(der, der_len);
440 ASN1_OCTET_STRING_free(aos);
441
442 return ret;
443}
444
445static int
446ecx_priv_print(BIO *bio, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
447{
448 struct ecx_key_st *ecx_key = pkey->pkey.ecx;
449 const char *name;
450
451 if ((name = OBJ_nid2ln(pkey->ameth->pkey_id)) == NULL)
452 return 0;
453
454 if (ecx_key == NULL || ecx_key->priv_key == NULL)
455 return BIO_printf(bio, "%*s<INVALID PRIVATE KEY>\n",
456 indent, "") > 0;
457
458 if (BIO_printf(bio, "%*s%s Private-Key:\n", indent, "", name) <= 0)
459 return 0;
460 if (BIO_printf(bio, "%*spriv:\n", indent, "") <= 0)
461 return 0;
462 if (!ecx_buf_print(bio, ecx_key->priv_key, ecx_key->priv_key_len, indent))
463 return 0;
464 if (BIO_printf(bio, "%*spub:\n", indent, "") <= 0)
465 return 0;
466 if (!ecx_buf_print(bio, ecx_key->pub_key, ecx_key->pub_key_len, indent))
467 return 0;
468
469 return 1;
470}
471
472static int
473ecx_size(const EVP_PKEY *pkey)
474{
475 return ecx_key_len(pkey->ameth->pkey_id);
476}
477
478static int
479ecx_sig_size(const EVP_PKEY *pkey)
480{
481 switch (pkey->ameth->pkey_id) {
482 case EVP_PKEY_ED25519:
483 return ED25519_SIG_SIZE;
484 }
485 return 0;
486}
487
488static int
489ecx_bits(const EVP_PKEY *pkey)
490{
491 switch (pkey->ameth->pkey_id) {
492 case EVP_PKEY_ED25519:
493 return ED25519_BITS;
494 case EVP_PKEY_X25519:
495 return X25519_BITS;
496 }
497 return 0;
498}
499
500static int
501ecx_security_bits(const EVP_PKEY *pkey)
502{
503 switch (pkey->ameth->pkey_id) {
504 case EVP_PKEY_ED25519:
505 return ED25519_SECURITY_BITS;
506 case EVP_PKEY_X25519:
507 return X25519_SECURITY_BITS;
508 }
509 return 0;
510}
511
512static int
513ecx_signature_info(const X509_ALGOR *algor, int *md_nid, int *pkey_nid,
514 int *security_bits, uint32_t *flags)
515{
516 const ASN1_OBJECT *aobj;
517
518 X509_ALGOR_get0(&aobj, NULL, NULL, algor);
519 if (OBJ_obj2nid(aobj) != EVP_PKEY_ED25519)
520 return 0;
521
522 *md_nid = NID_undef;
523 *pkey_nid = NID_ED25519;
524 *security_bits = ED25519_SECURITY_BITS;
525 *flags = X509_SIG_INFO_TLS | X509_SIG_INFO_VALID;
526
527 return 1;
528}
529
530static int
531ecx_param_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2)
532{
533 /* No parameters, so always equivalent. */
534 return 1;
535}
536
537static void
538ecx_free(EVP_PKEY *pkey)
539{
540 struct ecx_key_st *ecx_key = pkey->pkey.ecx;
541
542 ecx_key_free(ecx_key);
543}
544
545static int
546ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
547{
548 /* Not supported. */
549 return -2;
550}
551
552#ifndef OPENSSL_NO_CMS
553static int
554ecx_cms_sign_or_verify(EVP_PKEY *pkey, long verify, CMS_SignerInfo *si)
555{
556 X509_ALGOR *digestAlgorithm, *signatureAlgorithm;
557
558 if (verify != 0 && verify != 1)
559 return -1;
560
561 /* Check that we have an Ed25519 public key. */
562 if (EVP_PKEY_id(pkey) != NID_ED25519)
563 return -1;
564
565 CMS_SignerInfo_get0_algs(si, NULL, NULL, &digestAlgorithm,
566 &signatureAlgorithm);
567
568 /* RFC 8419, section 2.3: digestAlgorithm MUST be SHA-512. */
569 if (digestAlgorithm == NULL)
570 return -1;
571 if (OBJ_obj2nid(digestAlgorithm->algorithm) != NID_sha512)
572 return -1;
573
574 /*
575 * RFC 8419, section 2.4: signatureAlgorithm MUST be Ed25519, and the
576 * parameters MUST be absent. For verification check that this is the
577 * case, for signing set the signatureAlgorithm accordingly.
578 */
579 if (verify) {
580 const ASN1_OBJECT *obj;
581 int param_type;
582
583 if (signatureAlgorithm == NULL)
584 return -1;
585
586 X509_ALGOR_get0(&obj, &param_type, NULL, signatureAlgorithm);
587 if (OBJ_obj2nid(obj) != NID_ED25519)
588 return -1;
589 if (param_type != V_ASN1_UNDEF)
590 return -1;
591
592 return 1;
593 }
594
595 if (!X509_ALGOR_set0_by_nid(signatureAlgorithm, NID_ED25519,
596 V_ASN1_UNDEF, NULL))
597 return -1;
598
599 return 1;
600}
601#endif
602
603static int
604ecx_sign_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
605{
606 switch (op) {
607#ifndef OPENSSL_NO_CMS
608 case ASN1_PKEY_CTRL_CMS_SIGN:
609 return ecx_cms_sign_or_verify(pkey, arg1, arg2);
610#endif
611 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
612 /* PureEdDSA does its own hashing. */
613 *(int *)arg2 = NID_undef;
614 return 2;
615 }
616 return -2;
617}
618
619static int
620ecx_set_priv_key(EVP_PKEY *pkey, const uint8_t *priv, size_t len)
621{
622 struct ecx_key_st *ecx_key = NULL;
623 int ret = 0;
624
625 if (priv == NULL || len != ecx_key_len(pkey->ameth->pkey_id)) {
626 ECerror(EC_R_INVALID_ENCODING);
627 goto err;
628 }
629
630 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL)
631 goto err;
632 if (!ecx_key_set_priv(ecx_key, priv, len))
633 goto err;
634 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key))
635 goto err;
636 ecx_key = NULL;
637
638 ret = 1;
639
640 err:
641 ecx_key_free(ecx_key);
642
643 return ret;
644}
645
646static int
647ecx_set_pub_key(EVP_PKEY *pkey, const uint8_t *pub, size_t len)
648{
649 struct ecx_key_st *ecx_key = NULL;
650 int ret = 0;
651
652 if (pub == NULL || len != ecx_key_len(pkey->ameth->pkey_id)) {
653 ECerror(EC_R_INVALID_ENCODING);
654 goto err;
655 }
656
657 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL)
658 goto err;
659 if (!ecx_key_set_pub(ecx_key, pub, len))
660 goto err;
661 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key))
662 goto err;
663 ecx_key = NULL;
664
665 ret = 1;
666
667 err:
668 ecx_key_free(ecx_key);
669
670 return ret;
671}
672
673static int
674ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *out_priv, size_t *out_len)
675{
676 struct ecx_key_st *ecx_key = pkey->pkey.ecx;
677 CBS cbs;
678
679 if (out_priv == NULL) {
680 *out_len = ecx_key_len(pkey->ameth->pkey_id);
681 return 1;
682 }
683
684 if (ecx_key == NULL || ecx_key->priv_key == NULL)
685 return 0;
686
687 CBS_init(&cbs, ecx_key->priv_key, ecx_key->priv_key_len);
688 if (!CBS_write_bytes(&cbs, out_priv, *out_len, out_len))
689 return 0;
690
691 return 1;
692}
693
694static int
695ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *out_pub, size_t *out_len)
696{
697 struct ecx_key_st *ecx_key = pkey->pkey.ecx;
698 CBS cbs;
699
700 if (out_pub == NULL) {
701 *out_len = ecx_key_len(pkey->ameth->pkey_id);
702 return 1;
703 }
704
705 if (ecx_key == NULL || ecx_key->pub_key == NULL)
706 return 0;
707
708 CBS_init(&cbs, ecx_key->pub_key, ecx_key->pub_key_len);
709 if (!CBS_write_bytes(&cbs, out_pub, *out_len, out_len))
710 return 0;
711
712 return 1;
713}
714
715static int
716pkey_ecx_keygen(EVP_PKEY_CTX *pkey_ctx, EVP_PKEY *pkey)
717{
718 struct ecx_key_st *ecx_key = NULL;
719 int ret = 0;
720
721 if ((ecx_key = ecx_key_new(pkey_ctx->pmeth->pkey_id)) == NULL)
722 goto err;
723 if (!ecx_key_generate(ecx_key))
724 goto err;
725 if (!EVP_PKEY_assign(pkey, pkey_ctx->pmeth->pkey_id, ecx_key))
726 goto err;
727 ecx_key = NULL;
728
729 ret = 1;
730
731 err:
732 ecx_key_free(ecx_key);
733
734 return ret;
735}
736
737static int
738pkey_ecx_derive(EVP_PKEY_CTX *pkey_ctx, unsigned char *out_key,
739 size_t *out_key_len)
740{
741 struct ecx_key_st *ecx_key, *ecx_peer_key;
742
743 if (pkey_ctx->pkey == NULL || pkey_ctx->peerkey == NULL) {
744 ECerror(EC_R_KEYS_NOT_SET);
745 return 0;
746 }
747
748 if ((ecx_key = pkey_ctx->pkey->pkey.ecx) == NULL) {
749 ECerror(EC_R_INVALID_PRIVATE_KEY);
750 return 0;
751 }
752 if (ecx_key->priv_key == NULL) {
753 ECerror(EC_R_INVALID_PRIVATE_KEY);
754 return 0;
755 }
756
757 if ((ecx_peer_key = pkey_ctx->peerkey->pkey.ecx) == NULL) {
758 ECerror(EC_R_INVALID_PEER_KEY);
759 return 0;
760 }
761
762 if (out_key != NULL) {
763 if (!X25519(out_key, ecx_key->priv_key, ecx_peer_key->pub_key))
764 return 0;
765 }
766
767 *out_key_len = X25519_KEYLEN;
768
769 return 1;
770}
771
772static int
773pkey_ecx_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2)
774{
775 if (op == EVP_PKEY_CTRL_PEER_KEY)
776 return 1;
777
778 return -2;
779}
780
781static int
782ecx_item_verify(EVP_MD_CTX *md_ctx, const ASN1_ITEM *it, void *asn,
783 X509_ALGOR *algor, ASN1_BIT_STRING *abs, EVP_PKEY *pkey)
784{
785 const ASN1_OBJECT *aobj;
786 int nid, param_type;
787
788 X509_ALGOR_get0(&aobj, &param_type, NULL, algor);
789
790 nid = OBJ_obj2nid(aobj);
791
792 if (nid != NID_ED25519 || param_type != V_ASN1_UNDEF) {
793 ECerror(EC_R_INVALID_ENCODING);
794 return -1;
795 }
796
797 if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
798 return -1;
799
800 return 2;
801}
802
803static int
804ecx_item_sign(EVP_MD_CTX *md_ctx, const ASN1_ITEM *it, void *asn,
805 X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *abs)
806{
807 if (!X509_ALGOR_set0_by_nid(algor1, NID_ED25519, V_ASN1_UNDEF, NULL))
808 return 0;
809
810 if (algor2 != NULL) {
811 if (!X509_ALGOR_set0_by_nid(algor2, NID_ED25519, V_ASN1_UNDEF,
812 NULL))
813 return 0;
814 }
815
816 /* Tell ASN1_item_sign_ctx() that identifiers are set and it needs to sign. */
817 return 3;
818}
819
820static int
821pkey_ecx_digestsign(EVP_MD_CTX *md_ctx, unsigned char *out_sig,
822 size_t *out_sig_len, const unsigned char *message, size_t message_len)
823{
824 struct ecx_key_st *ecx_key;
825 EVP_PKEY_CTX *pkey_ctx;
826
827 pkey_ctx = EVP_MD_CTX_pkey_ctx(md_ctx);
828 ecx_key = pkey_ctx->pkey->pkey.ecx;
829
830 if (out_sig == NULL) {
831 *out_sig_len = ecx_sig_size(pkey_ctx->pkey);
832 return 1;
833 }
834 if (*out_sig_len < ecx_sig_size(pkey_ctx->pkey)) {
835 ECerror(EC_R_BUFFER_TOO_SMALL);
836 return 0;
837 }
838
839 if (ecx_key == NULL)
840 return 0;
841 if (ecx_key->priv_key == NULL || ecx_key->pub_key == NULL)
842 return 0;
843
844 if (!ED25519_sign(out_sig, message, message_len, ecx_key->pub_key,
845 ecx_key->priv_key))
846 return 0;
847
848 *out_sig_len = ecx_sig_size(pkey_ctx->pkey);
849
850 return 1;
851}
852
853static int
854pkey_ecx_digestverify(EVP_MD_CTX *md_ctx, const unsigned char *sig,
855 size_t sig_len, const unsigned char *message, size_t message_len)
856{
857 struct ecx_key_st *ecx_key;
858 EVP_PKEY_CTX *pkey_ctx;
859
860 pkey_ctx = EVP_MD_CTX_pkey_ctx(md_ctx);
861 ecx_key = pkey_ctx->pkey->pkey.ecx;
862
863 if (ecx_key == NULL || ecx_key->pub_key == NULL)
864 return -1;
865 if (sig_len != ecx_sig_size(pkey_ctx->pkey))
866 return -1;
867
868 return ED25519_verify(message, message_len, sig, ecx_key->pub_key);
869}
870
871static int
872pkey_ecx_ed_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2)
873{
874 switch (op) {
875 case EVP_PKEY_CTRL_MD:
876 /* PureEdDSA does its own hashing. */
877 if (arg2 != NULL && (const EVP_MD *)arg2 != EVP_md_null()) {
878 ECerror(EC_R_INVALID_DIGEST_TYPE);
879 return 0;
880 }
881 return 1;
882
883#ifndef OPENSSL_NO_CMS
884 case EVP_PKEY_CTRL_CMS_SIGN:
885#endif
886 case EVP_PKEY_CTRL_DIGESTINIT:
887 return 1;
888 }
889 return -2;
890}
891
892const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = {
893 .base_method = &x25519_asn1_meth,
894 .pkey_id = EVP_PKEY_X25519,
895 .pkey_flags = 0,
896 .pem_str = "X25519",
897 .info = "OpenSSL X25519 algorithm",
898
899 .pub_decode = ecx_pub_decode,
900 .pub_encode = ecx_pub_encode,
901 .pub_cmp = ecx_pub_cmp,
902 .pub_print = ecx_pub_print,
903
904 .priv_decode = ecx_priv_decode,
905 .priv_encode = ecx_priv_encode,
906 .priv_print = ecx_priv_print,
907
908 .pkey_size = ecx_size,
909 .pkey_bits = ecx_bits,
910 .pkey_security_bits = ecx_security_bits,
911
912 .param_cmp = ecx_param_cmp,
913
914 .pkey_free = ecx_free,
915 .pkey_ctrl = ecx_ctrl,
916
917 .set_priv_key = ecx_set_priv_key,
918 .set_pub_key = ecx_set_pub_key,
919 .get_priv_key = ecx_get_priv_key,
920 .get_pub_key = ecx_get_pub_key,
921};
922
923const EVP_PKEY_METHOD x25519_pkey_meth = {
924 .pkey_id = EVP_PKEY_X25519,
925 .keygen = pkey_ecx_keygen,
926 .derive = pkey_ecx_derive,
927 .ctrl = pkey_ecx_ctrl,
928};
929
930const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
931 .base_method = &ed25519_asn1_meth,
932 .pkey_id = EVP_PKEY_ED25519,
933 .pkey_flags = 0,
934 .pem_str = "ED25519",
935 .info = "OpenSSL ED25519 algorithm",
936
937 .pub_decode = ecx_pub_decode,
938 .pub_encode = ecx_pub_encode,
939 .pub_cmp = ecx_pub_cmp,
940 .pub_print = ecx_pub_print,
941
942 .priv_decode = ecx_priv_decode,
943 .priv_encode = ecx_priv_encode,
944 .priv_print = ecx_priv_print,
945
946 .pkey_size = ecx_sig_size,
947 .pkey_bits = ecx_bits,
948 .pkey_security_bits = ecx_security_bits,
949
950 .signature_info = ecx_signature_info,
951
952 .param_cmp = ecx_param_cmp,
953
954 .pkey_free = ecx_free,
955 .pkey_ctrl = ecx_sign_ctrl,
956
957 .item_verify = ecx_item_verify,
958 .item_sign = ecx_item_sign,
959
960 .set_priv_key = ecx_set_priv_key,
961 .set_pub_key = ecx_set_pub_key,
962 .get_priv_key = ecx_get_priv_key,
963 .get_pub_key = ecx_get_pub_key,
964};
965
966const EVP_PKEY_METHOD ed25519_pkey_meth = {
967 .pkey_id = EVP_PKEY_ED25519,
968 .flags = EVP_PKEY_FLAG_SIGCTX_CUSTOM,
969 .keygen = pkey_ecx_keygen,
970 .ctrl = pkey_ecx_ed_ctrl,
971 .digestsign = pkey_ecx_digestsign,
972 .digestverify = pkey_ecx_digestverify,
973};