diff options
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r-- | src/lib/libcrypto/ec/ec.h | 675 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_ameth.c | 1065 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 1461 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_convert.c | 575 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_curve.c | 1765 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_err.c | 151 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_key.c | 809 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_lib.c | 1369 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 254 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_mult.c | 407 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_pmeth.c | 545 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/eck_prn.c | 357 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ecp_methods.c | 1327 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ecx_methods.c | 973 |
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 | ||
80 | extern "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. */ | ||
88 | typedef enum { | ||
89 | POINT_CONVERSION_COMPRESSED = 2, | ||
90 | POINT_CONVERSION_UNCOMPRESSED = 4, | ||
91 | POINT_CONVERSION_HYBRID = 6 | ||
92 | } point_conversion_form_t; | ||
93 | |||
94 | typedef struct ec_group_st EC_GROUP; | ||
95 | typedef struct ec_point_st EC_POINT; | ||
96 | |||
97 | void EC_GROUP_free(EC_GROUP *group); | ||
98 | void EC_GROUP_clear_free(EC_GROUP *group); | ||
99 | |||
100 | EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); | ||
101 | |||
102 | int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | ||
103 | const BIGNUM *order, const BIGNUM *cofactor); | ||
104 | const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); | ||
105 | |||
106 | int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); | ||
107 | int EC_GROUP_order_bits(const EC_GROUP *group); | ||
108 | int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); | ||
109 | |||
110 | void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); | ||
111 | int EC_GROUP_get_curve_name(const EC_GROUP *group); | ||
112 | |||
113 | void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); | ||
114 | int EC_GROUP_get_asn1_flag(const EC_GROUP *group); | ||
115 | |||
116 | void EC_GROUP_set_point_conversion_form(EC_GROUP *group, | ||
117 | point_conversion_form_t form); | ||
118 | point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); | ||
119 | |||
120 | unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); | ||
121 | size_t EC_GROUP_get_seed_len(const EC_GROUP *); | ||
122 | size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); | ||
123 | |||
124 | int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, | ||
125 | const BIGNUM *b, BN_CTX *ctx); | ||
126 | int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, | ||
127 | BN_CTX *ctx); | ||
128 | |||
129 | int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, | ||
130 | const BIGNUM *b, BN_CTX *ctx); | ||
131 | int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, | ||
132 | BIGNUM *b, BN_CTX *ctx); | ||
133 | |||
134 | int EC_GROUP_get_degree(const EC_GROUP *group); | ||
135 | |||
136 | int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); | ||
137 | int 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. */ | ||
140 | int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); | ||
141 | |||
142 | EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, | ||
143 | const BIGNUM *b, BN_CTX *ctx); | ||
144 | EC_GROUP *EC_GROUP_new_by_curve_name(int nid); | ||
145 | |||
146 | typedef struct { | ||
147 | int nid; | ||
148 | const char *comment; | ||
149 | } EC_builtin_curve; | ||
150 | |||
151 | size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); | ||
152 | |||
153 | const char *EC_curve_nid2nist(int nid); | ||
154 | int EC_curve_nist2nid(const char *name); | ||
155 | |||
156 | EC_POINT *EC_POINT_new(const EC_GROUP *group); | ||
157 | void EC_POINT_free(EC_POINT *point); | ||
158 | void EC_POINT_clear_free(EC_POINT *point); | ||
159 | int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); | ||
160 | EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); | ||
161 | |||
162 | int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); | ||
163 | |||
164 | int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, | ||
165 | const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); | ||
166 | int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, | ||
167 | BIGNUM *x, BIGNUM *y, BN_CTX *ctx); | ||
168 | int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p, | ||
169 | const BIGNUM *x, int y_bit, BN_CTX *ctx); | ||
170 | |||
171 | int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, | ||
172 | const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); | ||
173 | int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, | ||
174 | const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); | ||
175 | int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, | ||
176 | const BIGNUM *x, int y_bit, BN_CTX *ctx); | ||
177 | size_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); | ||
179 | int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, | ||
180 | const unsigned char *buf, size_t len, BN_CTX *ctx); | ||
181 | |||
182 | BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, | ||
183 | point_conversion_form_t form, BIGNUM *, BN_CTX *); | ||
184 | EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, EC_POINT *, | ||
185 | BN_CTX *); | ||
186 | char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, | ||
187 | point_conversion_form_t form, BN_CTX *); | ||
188 | EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, EC_POINT *, | ||
189 | BN_CTX *); | ||
190 | |||
191 | int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, | ||
192 | const EC_POINT *b, BN_CTX *ctx); | ||
193 | int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, | ||
194 | BN_CTX *ctx); | ||
195 | int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); | ||
196 | int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); | ||
197 | int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, | ||
198 | BN_CTX *ctx); | ||
199 | int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, | ||
200 | BN_CTX *ctx); | ||
201 | |||
202 | int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); | ||
203 | int 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 | |||
206 | int EC_GROUP_get_basis_type(const EC_GROUP *); | ||
207 | |||
208 | #define OPENSSL_EC_EXPLICIT_CURVE 0x000 | ||
209 | #define OPENSSL_EC_NAMED_CURVE 0x001 | ||
210 | |||
211 | EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); | ||
212 | int 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 | ||
222 | int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); | ||
223 | #endif | ||
224 | int 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 | |||
233 | EC_KEY *EC_KEY_new(void); | ||
234 | int EC_KEY_get_flags(const EC_KEY *key); | ||
235 | void EC_KEY_set_flags(EC_KEY *key, int flags); | ||
236 | void EC_KEY_clear_flags(EC_KEY *key, int flags); | ||
237 | EC_KEY *EC_KEY_new_by_curve_name(int nid); | ||
238 | void EC_KEY_free(EC_KEY *key); | ||
239 | EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); | ||
240 | EC_KEY *EC_KEY_dup(const EC_KEY *src); | ||
241 | int EC_KEY_up_ref(EC_KEY *key); | ||
242 | |||
243 | const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); | ||
244 | int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); | ||
245 | const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); | ||
246 | int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); | ||
247 | const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); | ||
248 | int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); | ||
249 | |||
250 | unsigned EC_KEY_get_enc_flags(const EC_KEY *key); | ||
251 | void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); | ||
252 | point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); | ||
253 | void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); | ||
254 | |||
255 | void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); | ||
256 | int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); | ||
257 | int EC_KEY_generate_key(EC_KEY *key); | ||
258 | int EC_KEY_check_key(const EC_KEY *key); | ||
259 | int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y); | ||
260 | |||
261 | EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); | ||
262 | int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); | ||
263 | EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); | ||
264 | int i2d_ECParameters(EC_KEY *key, unsigned char **out); | ||
265 | |||
266 | EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); | ||
267 | int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out); | ||
268 | |||
269 | #ifndef OPENSSL_NO_BIO | ||
270 | int ECParameters_print(BIO *bp, const EC_KEY *key); | ||
271 | int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); | ||
272 | #endif | ||
273 | int ECParameters_print_fp(FILE *fp, const EC_KEY *key); | ||
274 | int 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) | ||
278 | int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg); | ||
279 | void *EC_KEY_get_ex_data(const EC_KEY *key, int idx); | ||
280 | |||
281 | const EC_KEY_METHOD *EC_KEY_OpenSSL(void); | ||
282 | const EC_KEY_METHOD *EC_KEY_get_default_method(void); | ||
283 | void EC_KEY_set_default_method(const EC_KEY_METHOD *meth); | ||
284 | const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key); | ||
285 | int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth); | ||
286 | EC_KEY *EC_KEY_new_method(ENGINE *engine); | ||
287 | |||
288 | int ECDH_size(const EC_KEY *ecdh); | ||
289 | int 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 | |||
293 | typedef struct ECDSA_SIG_st ECDSA_SIG; | ||
294 | |||
295 | ECDSA_SIG *ECDSA_SIG_new(void); | ||
296 | void ECDSA_SIG_free(ECDSA_SIG *sig); | ||
297 | int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); | ||
298 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); | ||
299 | |||
300 | const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); | ||
301 | const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); | ||
302 | void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); | ||
303 | int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); | ||
304 | |||
305 | int ECDSA_size(const EC_KEY *eckey); | ||
306 | |||
307 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *digest, int digest_len, | ||
308 | EC_KEY *eckey); | ||
309 | int ECDSA_do_verify(const unsigned char *digest, int digest_len, | ||
310 | const ECDSA_SIG *sig, EC_KEY *eckey); | ||
311 | |||
312 | int ECDSA_sign(int type, const unsigned char *digest, int digest_len, | ||
313 | unsigned char *signature, unsigned int *signature_len, EC_KEY *eckey); | ||
314 | int ECDSA_verify(int type, const unsigned char *digest, int digest_len, | ||
315 | const unsigned char *signature, int signature_len, EC_KEY *eckey); | ||
316 | |||
317 | EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth); | ||
318 | void EC_KEY_METHOD_free(EC_KEY_METHOD *meth); | ||
319 | void 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)); | ||
326 | void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, | ||
327 | int (*keygen)(EC_KEY *key)); | ||
328 | void 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)); | ||
331 | void 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)); | ||
338 | void 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)); | ||
343 | void 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)); | ||
350 | void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, | ||
351 | int (**pkeygen)(EC_KEY *key)); | ||
352 | void 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)); | ||
355 | void 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)); | ||
362 | void 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 | |||
368 | EC_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 | |||
462 | void 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 | ||
81 | static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); | ||
82 | static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); | ||
83 | #endif | ||
84 | |||
85 | static void | ||
86 | eckey_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 | |||
96 | static int | ||
97 | eckey_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 | |||
113 | static int | ||
114 | eckey_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, ¶ms)) <= 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 | |||
147 | static int | ||
148 | eckey_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, ¶ms, params_len)) == NULL) { | ||
155 | ECerror(EC_R_DECODE_ERROR); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | static int | ||
163 | eckey_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 | |||
177 | static int | ||
178 | eckey_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 | |||
193 | static int | ||
194 | eckey_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 | |||
213 | static int | ||
214 | eckey_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 | |||
228 | static int | ||
229 | eckey_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 | |||
264 | static int | ||
265 | eckey_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 | |||
297 | static int | ||
298 | eckey_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 | |||
313 | int | ||
314 | eckey_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 | |||
340 | static int | ||
341 | eckey_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 | |||
381 | static int | ||
382 | eckey_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 | |||
427 | static int | ||
428 | ec_size(const EVP_PKEY *pkey) | ||
429 | { | ||
430 | return ECDSA_size(pkey->pkey.ec); | ||
431 | } | ||
432 | |||
433 | static int | ||
434 | ec_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 | |||
444 | static int | ||
445 | ec_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 | |||
463 | static int | ||
464 | ec_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 | |||
471 | static int | ||
472 | ec_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 | |||
477 | static int | ||
478 | ec_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 | |||
489 | static void | ||
490 | ec_free(EVP_PKEY *pkey) | ||
491 | { | ||
492 | EC_KEY_free(pkey->pkey.ec); | ||
493 | } | ||
494 | |||
495 | static int | ||
496 | do_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 | |||
561 | static int | ||
562 | eckey_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 | |||
581 | static int | ||
582 | eckey_param_encode(const EVP_PKEY *pkey, unsigned char **param) | ||
583 | { | ||
584 | return i2d_ECParameters(pkey->pkey.ec, param); | ||
585 | } | ||
586 | |||
587 | static int | ||
588 | eckey_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 | |||
593 | static int | ||
594 | eckey_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 | |||
600 | static int | ||
601 | eckey_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 | |||
606 | static int | ||
607 | old_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 | |||
626 | static int | ||
627 | old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **priv) | ||
628 | { | ||
629 | return i2d_ECPrivateKey(pkey->pkey.ec, priv); | ||
630 | } | ||
631 | |||
632 | static int | ||
633 | ec_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 | |||
699 | static int | ||
700 | ecdh_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 */ | ||
755 | static int | ||
756 | ecdh_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 | |||
791 | static int | ||
792 | ecdh_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, ¶meter_type, ¶meter, 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 | |||
864 | static int | ||
865 | ecdh_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 | |||
898 | static int | ||
899 | ecdh_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 | |||
1034 | const 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 | |||
76 | int | ||
77 | EC_GROUP_get_basis_type(const EC_GROUP *group) | ||
78 | { | ||
79 | return 0; | ||
80 | } | ||
81 | LCRYPTO_ALIAS(EC_GROUP_get_basis_type); | ||
82 | |||
83 | typedef struct x9_62_pentanomial_st { | ||
84 | long k1; | ||
85 | long k2; | ||
86 | long k3; | ||
87 | } X9_62_PENTANOMIAL; | ||
88 | |||
89 | typedef 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 | |||
105 | typedef 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 | |||
118 | typedef 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 | |||
124 | typedef 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 | |||
137 | typedef 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 | |||
146 | typedef struct ec_privatekey_st { | ||
147 | long version; | ||
148 | ASN1_OCTET_STRING *privateKey; | ||
149 | ECPKPARAMETERS *parameters; | ||
150 | ASN1_BIT_STRING *publicKey; | ||
151 | } EC_PRIVATEKEY; | ||
152 | |||
153 | static 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 | |||
177 | static 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 | |||
187 | static 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 | |||
195 | static 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 | |||
229 | static 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 | |||
238 | static 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 | |||
262 | static 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 | |||
272 | static 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 | |||
280 | static 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 | |||
303 | static 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 | |||
312 | static 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 | |||
329 | static 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 | |||
339 | static 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 | |||
363 | static 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 | |||
373 | static 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 | |||
418 | static 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 | |||
428 | static ECPARAMETERS * | ||
429 | ECPARAMETERS_new(void) | ||
430 | { | ||
431 | return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it); | ||
432 | } | ||
433 | |||
434 | static void | ||
435 | ECPARAMETERS_free(ECPARAMETERS *a) | ||
436 | { | ||
437 | ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it); | ||
438 | } | ||
439 | |||
440 | static 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 | |||
464 | static 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 | |||
474 | static ECPKPARAMETERS * | ||
475 | d2i_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 | |||
481 | static int | ||
482 | i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out) | ||
483 | { | ||
484 | return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it); | ||
485 | } | ||
486 | |||
487 | static ECPKPARAMETERS * | ||
488 | ECPKPARAMETERS_new(void) | ||
489 | { | ||
490 | return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it); | ||
491 | } | ||
492 | |||
493 | static void | ||
494 | ECPKPARAMETERS_free(ECPKPARAMETERS *a) | ||
495 | { | ||
496 | ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it); | ||
497 | } | ||
498 | |||
499 | static 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 | |||
530 | static 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 | |||
540 | static EC_PRIVATEKEY * | ||
541 | d2i_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 | |||
547 | static int | ||
548 | i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out) | ||
549 | { | ||
550 | return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it); | ||
551 | } | ||
552 | |||
553 | static EC_PRIVATEKEY * | ||
554 | EC_PRIVATEKEY_new(void) | ||
555 | { | ||
556 | return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it); | ||
557 | } | ||
558 | |||
559 | static void | ||
560 | EC_PRIVATEKEY_free(EC_PRIVATEKEY *a) | ||
561 | { | ||
562 | ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it); | ||
563 | } | ||
564 | |||
565 | static int | ||
566 | ec_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 | |||
573 | static int | ||
574 | ec_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 | |||
589 | static int | ||
590 | ec_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 | |||
596 | static int | ||
597 | ec_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 | |||
632 | static int | ||
633 | ec_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 | |||
643 | static int | ||
644 | ec_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 | |||
651 | static int | ||
652 | ec_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 | |||
674 | static int | ||
675 | ec_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 | |||
700 | static int | ||
701 | ec_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 | |||
708 | static int | ||
709 | ec_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 | |||
716 | static int | ||
717 | ec_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 | |||
774 | static ECPARAMETERS * | ||
775 | ec_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, ¶meters->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 | |||
844 | static ECPKPARAMETERS * | ||
845 | ec_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 | |||
880 | static int | ||
881 | ec_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 | |||
911 | static int | ||
912 | ec_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 | |||
959 | static int | ||
960 | ec_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 | |||
1007 | static int | ||
1008 | ec_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 | |||
1036 | static EC_GROUP * | ||
1037 | ec_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 | |||
1061 | static EC_GROUP * | ||
1062 | ec_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 | |||
1094 | EC_GROUP * | ||
1095 | d2i_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 | } | ||
1119 | LCRYPTO_ALIAS(d2i_ECPKParameters); | ||
1120 | |||
1121 | int | ||
1122 | i2d_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 | } | ||
1141 | LCRYPTO_ALIAS(i2d_ECPKParameters); | ||
1142 | |||
1143 | static int | ||
1144 | ec_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 | |||
1167 | static int | ||
1168 | ec_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 | |||
1196 | static int | ||
1197 | ec_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 | |||
1223 | EC_KEY * | ||
1224 | d2i_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 | } | ||
1262 | LCRYPTO_ALIAS(d2i_ECPrivateKey); | ||
1263 | |||
1264 | int | ||
1265 | i2d_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 | } | ||
1328 | LCRYPTO_ALIAS(i2d_ECPrivateKey); | ||
1329 | |||
1330 | int | ||
1331 | i2d_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 | } | ||
1339 | LCRYPTO_ALIAS(i2d_ECParameters); | ||
1340 | |||
1341 | EC_KEY * | ||
1342 | d2i_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 | } | ||
1373 | LCRYPTO_ALIAS(d2i_ECParameters); | ||
1374 | |||
1375 | EC_KEY * | ||
1376 | ECParameters_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 | } | ||
1395 | LCRYPTO_ALIAS(ECParameters_dup); | ||
1396 | |||
1397 | EC_KEY * | ||
1398 | o2i_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 | } | ||
1425 | LCRYPTO_ALIAS(o2i_ECPublicKey); | ||
1426 | |||
1427 | int | ||
1428 | i2o_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 | } | ||
1461 | LCRYPTO_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 | |||
93 | static int | ||
94 | ec_conversion_form_is_valid(uint8_t form) | ||
95 | { | ||
96 | return (form & EC_POINT_CONVERSION_MASK) == form; | ||
97 | } | ||
98 | |||
99 | static int | ||
100 | ec_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. */ | ||
111 | static int | ||
112 | ec_nonzero_ybit_allowed(uint8_t form) | ||
113 | { | ||
114 | return form == EC_POINT_COMPRESSED || form == EC_POINT_HYBRID; | ||
115 | } | ||
116 | |||
117 | static int | ||
118 | ec_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 | |||
126 | static int | ||
127 | ec_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 | |||
152 | static int | ||
153 | ec_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 | |||
171 | static int | ||
172 | ec_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 | |||
178 | static int | ||
179 | ec_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 | |||
200 | static int | ||
201 | ec_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 | |||
221 | static size_t | ||
222 | ec_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 | |||
295 | static int | ||
296 | ec_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 | |||
353 | int | ||
354 | ec_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 | |||
386 | int | ||
387 | ec_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 | |||
416 | static int | ||
417 | ec_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 | |||
436 | size_t | ||
437 | EC_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 | } | ||
467 | LCRYPTO_ALIAS(EC_POINT_point2oct); | ||
468 | |||
469 | int | ||
470 | EC_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 | } | ||
493 | LCRYPTO_ALIAS(EC_POINT_oct2point); | ||
494 | |||
495 | BIGNUM * | ||
496 | EC_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 | } | ||
513 | LCRYPTO_ALIAS(EC_POINT_point2bn); | ||
514 | |||
515 | EC_POINT * | ||
516 | EC_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 | } | ||
537 | LCRYPTO_ALIAS(EC_POINT_bn2point); | ||
538 | |||
539 | char * | ||
540 | EC_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 | } | ||
556 | LCRYPTO_ALIAS(EC_POINT_point2hex); | ||
557 | |||
558 | EC_POINT * | ||
559 | EC_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 | } | ||
575 | LCRYPTO_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 | |||
86 | static 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 | |||
131 | static 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 | |||
188 | static 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 | |||
257 | static 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 | |||
302 | static 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 | |||
347 | static 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 | |||
392 | static 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 | |||
443 | static 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 | |||
483 | static 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 | |||
529 | static 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 | |||
569 | static 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 | |||
609 | static 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 | |||
655 | static 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 | |||
701 | static 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 | |||
747 | static 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 | |||
793 | static 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 | |||
845 | static 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 | |||
897 | static 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 | |||
961 | static 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 | |||
1025 | static 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 | |||
1071 | static 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 | |||
1348 | static EC_GROUP * | ||
1349 | ec_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 | |||
1457 | EC_GROUP * | ||
1458 | EC_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 | } | ||
1473 | LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name); | ||
1474 | |||
1475 | static void | ||
1476 | ec_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 | |||
1493 | static int | ||
1494 | ec_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 | |||
1519 | static struct ec_curve * | ||
1520 | ec_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 | |||
1611 | static int | ||
1612 | ec_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 | |||
1661 | static int | ||
1662 | ec_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 | |||
1674 | int | ||
1675 | ec_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 | |||
1698 | size_t | ||
1699 | EC_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 | } | ||
1716 | LCRYPTO_ALIAS(EC_get_builtin_curves); | ||
1717 | |||
1718 | static 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 | |||
1739 | const char * | ||
1740 | EC_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 | } | ||
1751 | LCRYPTO_ALIAS(EC_curve_nid2nist); | ||
1752 | |||
1753 | int | ||
1754 | EC_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 | } | ||
1765 | LCRYPTO_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 | |||
70 | static const ERR_STRING_DATA EC_str_functs[] = { | ||
71 | {ERR_FUNC(0xfff), "CRYPTO_internal"}, | ||
72 | {0, NULL} | ||
73 | }; | ||
74 | |||
75 | static 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 | |||
141 | void | ||
142 | ERR_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 | } | ||
151 | LCRYPTO_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 | |||
75 | EC_KEY * | ||
76 | EC_KEY_new(void) | ||
77 | { | ||
78 | return EC_KEY_new_method(NULL); | ||
79 | } | ||
80 | LCRYPTO_ALIAS(EC_KEY_new); | ||
81 | |||
82 | EC_KEY * | ||
83 | EC_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 | } | ||
106 | LCRYPTO_ALIAS(EC_KEY_new_by_curve_name); | ||
107 | |||
108 | void | ||
109 | EC_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 | } | ||
128 | LCRYPTO_ALIAS(EC_KEY_free); | ||
129 | |||
130 | EC_KEY * | ||
131 | EC_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 | } | ||
185 | LCRYPTO_ALIAS(EC_KEY_copy); | ||
186 | |||
187 | EC_KEY * | ||
188 | EC_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 | } | ||
205 | LCRYPTO_ALIAS(EC_KEY_dup); | ||
206 | |||
207 | int | ||
208 | EC_KEY_up_ref(EC_KEY *r) | ||
209 | { | ||
210 | return CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC) > 1; | ||
211 | } | ||
212 | LCRYPTO_ALIAS(EC_KEY_up_ref); | ||
213 | |||
214 | int | ||
215 | EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg) | ||
216 | { | ||
217 | return CRYPTO_set_ex_data(&r->ex_data, idx, arg); | ||
218 | } | ||
219 | LCRYPTO_ALIAS(EC_KEY_set_ex_data); | ||
220 | |||
221 | void * | ||
222 | EC_KEY_get_ex_data(const EC_KEY *r, int idx) | ||
223 | { | ||
224 | return CRYPTO_get_ex_data(&r->ex_data, idx); | ||
225 | } | ||
226 | LCRYPTO_ALIAS(EC_KEY_get_ex_data); | ||
227 | |||
228 | int | ||
229 | EC_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 | } | ||
236 | LCRYPTO_ALIAS(EC_KEY_generate_key); | ||
237 | |||
238 | static int | ||
239 | ec_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 | |||
280 | int | ||
281 | EC_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 | } | ||
353 | LCRYPTO_ALIAS(EC_KEY_check_key); | ||
354 | |||
355 | int | ||
356 | EC_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 | } | ||
408 | LCRYPTO_ALIAS(EC_KEY_set_public_key_affine_coordinates); | ||
409 | |||
410 | const EC_GROUP * | ||
411 | EC_KEY_get0_group(const EC_KEY *key) | ||
412 | { | ||
413 | return key->group; | ||
414 | } | ||
415 | LCRYPTO_ALIAS(EC_KEY_get0_group); | ||
416 | |||
417 | int | ||
418 | EC_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 | } | ||
427 | LCRYPTO_ALIAS(EC_KEY_set_group); | ||
428 | |||
429 | const BIGNUM * | ||
430 | EC_KEY_get0_private_key(const EC_KEY *key) | ||
431 | { | ||
432 | return key->priv_key; | ||
433 | } | ||
434 | LCRYPTO_ALIAS(EC_KEY_get0_private_key); | ||
435 | |||
436 | int | ||
437 | EC_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 | } | ||
449 | LCRYPTO_ALIAS(EC_KEY_set_private_key); | ||
450 | |||
451 | const EC_POINT * | ||
452 | EC_KEY_get0_public_key(const EC_KEY *key) | ||
453 | { | ||
454 | return key->pub_key; | ||
455 | } | ||
456 | LCRYPTO_ALIAS(EC_KEY_get0_public_key); | ||
457 | |||
458 | int | ||
459 | EC_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 | } | ||
471 | LCRYPTO_ALIAS(EC_KEY_set_public_key); | ||
472 | |||
473 | unsigned int | ||
474 | EC_KEY_get_enc_flags(const EC_KEY *key) | ||
475 | { | ||
476 | return key->enc_flag; | ||
477 | } | ||
478 | LCRYPTO_ALIAS(EC_KEY_get_enc_flags); | ||
479 | |||
480 | void | ||
481 | EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) | ||
482 | { | ||
483 | key->enc_flag = flags; | ||
484 | } | ||
485 | LCRYPTO_ALIAS(EC_KEY_set_enc_flags); | ||
486 | |||
487 | point_conversion_form_t | ||
488 | EC_KEY_get_conv_form(const EC_KEY *key) | ||
489 | { | ||
490 | return key->conv_form; | ||
491 | } | ||
492 | LCRYPTO_ALIAS(EC_KEY_get_conv_form); | ||
493 | |||
494 | void | ||
495 | EC_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 | } | ||
501 | LCRYPTO_ALIAS(EC_KEY_set_conv_form); | ||
502 | |||
503 | void | ||
504 | EC_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 | } | ||
509 | LCRYPTO_ALIAS(EC_KEY_set_asn1_flag); | ||
510 | |||
511 | int | ||
512 | EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) | ||
513 | { | ||
514 | if (key->group == NULL) | ||
515 | return 0; | ||
516 | return 1; | ||
517 | } | ||
518 | LCRYPTO_ALIAS(EC_KEY_precompute_mult); | ||
519 | |||
520 | int | ||
521 | EC_KEY_get_flags(const EC_KEY *key) | ||
522 | { | ||
523 | return key->flags; | ||
524 | } | ||
525 | LCRYPTO_ALIAS(EC_KEY_get_flags); | ||
526 | |||
527 | void | ||
528 | EC_KEY_set_flags(EC_KEY *key, int flags) | ||
529 | { | ||
530 | key->flags |= flags; | ||
531 | } | ||
532 | LCRYPTO_ALIAS(EC_KEY_set_flags); | ||
533 | |||
534 | void | ||
535 | EC_KEY_clear_flags(EC_KEY *key, int flags) | ||
536 | { | ||
537 | key->flags &= ~flags; | ||
538 | } | ||
539 | LCRYPTO_ALIAS(EC_KEY_clear_flags); | ||
540 | |||
541 | const EC_KEY_METHOD * | ||
542 | EC_KEY_get_method(const EC_KEY *key) | ||
543 | { | ||
544 | return key->meth; | ||
545 | } | ||
546 | LCRYPTO_ALIAS(EC_KEY_get_method); | ||
547 | |||
548 | int | ||
549 | EC_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 | } | ||
561 | LCRYPTO_ALIAS(EC_KEY_set_method); | ||
562 | |||
563 | EC_KEY * | ||
564 | EC_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 | } | ||
593 | LCRYPTO_ALIAS(EC_KEY_new_method); | ||
594 | |||
595 | #define EC_KEY_METHOD_DYNAMIC 1 | ||
596 | |||
597 | EC_KEY_METHOD * | ||
598 | EC_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 | } | ||
609 | LCRYPTO_ALIAS(EC_KEY_METHOD_new); | ||
610 | |||
611 | void | ||
612 | EC_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 | } | ||
619 | LCRYPTO_ALIAS(EC_KEY_METHOD_free); | ||
620 | |||
621 | void | ||
622 | EC_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 | } | ||
637 | LCRYPTO_ALIAS(EC_KEY_METHOD_set_init); | ||
638 | |||
639 | void | ||
640 | EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, int (*keygen)(EC_KEY *key)) | ||
641 | { | ||
642 | meth->keygen = keygen; | ||
643 | } | ||
644 | LCRYPTO_ALIAS(EC_KEY_METHOD_set_keygen); | ||
645 | |||
646 | void | ||
647 | EC_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 | } | ||
653 | LCRYPTO_ALIAS(EC_KEY_METHOD_set_compute_key); | ||
654 | |||
655 | void | ||
656 | EC_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 | } | ||
670 | LCRYPTO_ALIAS(EC_KEY_METHOD_set_sign); | ||
671 | |||
672 | void | ||
673 | EC_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 | } | ||
682 | LCRYPTO_ALIAS(EC_KEY_METHOD_set_verify); | ||
683 | |||
684 | |||
685 | void | ||
686 | EC_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 | } | ||
707 | LCRYPTO_ALIAS(EC_KEY_METHOD_get_init); | ||
708 | |||
709 | void | ||
710 | EC_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 | } | ||
716 | LCRYPTO_ALIAS(EC_KEY_METHOD_get_keygen); | ||
717 | |||
718 | void | ||
719 | EC_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 | } | ||
726 | LCRYPTO_ALIAS(EC_KEY_METHOD_get_compute_key); | ||
727 | |||
728 | void | ||
729 | EC_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 | } | ||
746 | LCRYPTO_ALIAS(EC_KEY_METHOD_get_sign); | ||
747 | |||
748 | void | ||
749 | EC_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 | } | ||
760 | LCRYPTO_ALIAS(EC_KEY_METHOD_get_verify); | ||
761 | |||
762 | static 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 | |||
785 | const EC_KEY_METHOD * | ||
786 | EC_KEY_OpenSSL(void) | ||
787 | { | ||
788 | return &openssl_ec_key_method; | ||
789 | } | ||
790 | LCRYPTO_ALIAS(EC_KEY_OpenSSL); | ||
791 | |||
792 | const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; | ||
793 | |||
794 | const EC_KEY_METHOD * | ||
795 | EC_KEY_get_default_method(void) | ||
796 | { | ||
797 | return default_ec_key_meth; | ||
798 | } | ||
799 | LCRYPTO_ALIAS(EC_KEY_get_default_method); | ||
800 | |||
801 | void | ||
802 | EC_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 | } | ||
809 | LCRYPTO_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 | |||
78 | EC_GROUP * | ||
79 | EC_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 | |||
121 | void | ||
122 | EC_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 | } | ||
140 | LCRYPTO_ALIAS(EC_GROUP_free); | ||
141 | |||
142 | void | ||
143 | EC_GROUP_clear_free(EC_GROUP *group) | ||
144 | { | ||
145 | EC_GROUP_free(group); | ||
146 | } | ||
147 | LCRYPTO_ALIAS(EC_GROUP_clear_free); | ||
148 | |||
149 | static int | ||
150 | EC_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 | |||
201 | EC_GROUP * | ||
202 | EC_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 | } | ||
221 | LCRYPTO_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 | */ | ||
238 | static int | ||
239 | ec_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 | |||
313 | int | ||
314 | EC_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 | } | ||
354 | LCRYPTO_ALIAS(EC_GROUP_set_generator); | ||
355 | |||
356 | const EC_POINT * | ||
357 | EC_GROUP_get0_generator(const EC_GROUP *group) | ||
358 | { | ||
359 | return group->generator; | ||
360 | } | ||
361 | LCRYPTO_ALIAS(EC_GROUP_get0_generator); | ||
362 | |||
363 | int | ||
364 | EC_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 | } | ||
371 | LCRYPTO_ALIAS(EC_GROUP_get_order); | ||
372 | |||
373 | const BIGNUM * | ||
374 | EC_GROUP_get0_order(const EC_GROUP *group) | ||
375 | { | ||
376 | return group->order; | ||
377 | } | ||
378 | |||
379 | int | ||
380 | EC_GROUP_order_bits(const EC_GROUP *group) | ||
381 | { | ||
382 | return BN_num_bits(group->order); | ||
383 | } | ||
384 | LCRYPTO_ALIAS(EC_GROUP_order_bits); | ||
385 | |||
386 | int | ||
387 | EC_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 | } | ||
394 | LCRYPTO_ALIAS(EC_GROUP_get_cofactor); | ||
395 | |||
396 | const BIGNUM * | ||
397 | EC_GROUP_get0_cofactor(const EC_GROUP *group) | ||
398 | { | ||
399 | return group->cofactor; | ||
400 | } | ||
401 | |||
402 | void | ||
403 | EC_GROUP_set_curve_name(EC_GROUP *group, int nid) | ||
404 | { | ||
405 | group->nid = nid; | ||
406 | } | ||
407 | LCRYPTO_ALIAS(EC_GROUP_set_curve_name); | ||
408 | |||
409 | int | ||
410 | EC_GROUP_get_curve_name(const EC_GROUP *group) | ||
411 | { | ||
412 | return group->nid; | ||
413 | } | ||
414 | LCRYPTO_ALIAS(EC_GROUP_get_curve_name); | ||
415 | |||
416 | void | ||
417 | EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) | ||
418 | { | ||
419 | group->asn1_flag = flag; | ||
420 | } | ||
421 | LCRYPTO_ALIAS(EC_GROUP_set_asn1_flag); | ||
422 | |||
423 | int | ||
424 | EC_GROUP_get_asn1_flag(const EC_GROUP *group) | ||
425 | { | ||
426 | return group->asn1_flag; | ||
427 | } | ||
428 | LCRYPTO_ALIAS(EC_GROUP_get_asn1_flag); | ||
429 | |||
430 | void | ||
431 | EC_GROUP_set_point_conversion_form(EC_GROUP *group, | ||
432 | point_conversion_form_t form) | ||
433 | { | ||
434 | group->asn1_form = form; | ||
435 | } | ||
436 | LCRYPTO_ALIAS(EC_GROUP_set_point_conversion_form); | ||
437 | |||
438 | point_conversion_form_t | ||
439 | EC_GROUP_get_point_conversion_form(const EC_GROUP *group) | ||
440 | { | ||
441 | return group->asn1_form; | ||
442 | } | ||
443 | LCRYPTO_ALIAS(EC_GROUP_get_point_conversion_form); | ||
444 | |||
445 | size_t | ||
446 | EC_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 | } | ||
462 | LCRYPTO_ALIAS(EC_GROUP_set_seed); | ||
463 | |||
464 | unsigned char * | ||
465 | EC_GROUP_get0_seed(const EC_GROUP *group) | ||
466 | { | ||
467 | return group->seed; | ||
468 | } | ||
469 | LCRYPTO_ALIAS(EC_GROUP_get0_seed); | ||
470 | |||
471 | size_t | ||
472 | EC_GROUP_get_seed_len(const EC_GROUP *group) | ||
473 | { | ||
474 | return group->seed_len; | ||
475 | } | ||
476 | LCRYPTO_ALIAS(EC_GROUP_get_seed_len); | ||
477 | |||
478 | int | ||
479 | EC_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 | } | ||
502 | LCRYPTO_ALIAS(EC_GROUP_set_curve); | ||
503 | |||
504 | int | ||
505 | EC_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 | } | ||
528 | LCRYPTO_ALIAS(EC_GROUP_get_curve); | ||
529 | |||
530 | int | ||
531 | EC_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 | } | ||
536 | LCRYPTO_ALIAS(EC_GROUP_set_curve_GFp); | ||
537 | |||
538 | int | ||
539 | EC_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 | } | ||
544 | LCRYPTO_ALIAS(EC_GROUP_get_curve_GFp); | ||
545 | |||
546 | EC_GROUP * | ||
547 | EC_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 | } | ||
565 | LCRYPTO_ALIAS(EC_GROUP_new_curve_GFp); | ||
566 | |||
567 | int | ||
568 | EC_GROUP_get_degree(const EC_GROUP *group) | ||
569 | { | ||
570 | return BN_num_bits(group->p); | ||
571 | } | ||
572 | LCRYPTO_ALIAS(EC_GROUP_get_degree); | ||
573 | |||
574 | int | ||
575 | EC_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 | } | ||
638 | LCRYPTO_ALIAS(EC_GROUP_check_discriminant); | ||
639 | |||
640 | int | ||
641 | EC_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 | } | ||
693 | LCRYPTO_ALIAS(EC_GROUP_check); | ||
694 | |||
695 | /* | ||
696 | * Returns -1 on error, 0 if the groups are equal, 1 if they are distinct. | ||
697 | */ | ||
698 | int | ||
699 | EC_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 | } | ||
789 | LCRYPTO_ALIAS(EC_GROUP_cmp); | ||
790 | |||
791 | EC_POINT * | ||
792 | EC_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 | } | ||
822 | LCRYPTO_ALIAS(EC_POINT_new); | ||
823 | |||
824 | void | ||
825 | EC_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 | } | ||
836 | LCRYPTO_ALIAS(EC_POINT_free); | ||
837 | |||
838 | void | ||
839 | EC_POINT_clear_free(EC_POINT *point) | ||
840 | { | ||
841 | EC_POINT_free(point); | ||
842 | } | ||
843 | LCRYPTO_ALIAS(EC_POINT_clear_free); | ||
844 | |||
845 | int | ||
846 | EC_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 | } | ||
865 | LCRYPTO_ALIAS(EC_POINT_copy); | ||
866 | |||
867 | EC_POINT * | ||
868 | EC_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 | } | ||
888 | LCRYPTO_ALIAS(EC_POINT_dup); | ||
889 | |||
890 | int | ||
891 | EC_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 | } | ||
903 | LCRYPTO_ALIAS(EC_POINT_set_to_infinity); | ||
904 | |||
905 | int | ||
906 | EC_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 | } | ||
941 | LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates); | ||
942 | |||
943 | int | ||
944 | EC_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 | } | ||
949 | LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates_GFp); | ||
950 | |||
951 | int | ||
952 | EC_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 | } | ||
984 | LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates); | ||
985 | |||
986 | int | ||
987 | EC_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 | } | ||
992 | LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates_GFp); | ||
993 | |||
994 | int | ||
995 | EC_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 | } | ||
1096 | LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates); | ||
1097 | |||
1098 | int | ||
1099 | EC_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 | } | ||
1104 | LCRYPTO_ALIAS(EC_POINT_set_compressed_coordinates_GFp); | ||
1105 | |||
1106 | int | ||
1107 | EC_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 | } | ||
1135 | LCRYPTO_ALIAS(EC_POINT_add); | ||
1136 | |||
1137 | int | ||
1138 | EC_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 | } | ||
1165 | LCRYPTO_ALIAS(EC_POINT_dbl); | ||
1166 | |||
1167 | int | ||
1168 | EC_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 | } | ||
1194 | LCRYPTO_ALIAS(EC_POINT_invert); | ||
1195 | |||
1196 | int | ||
1197 | EC_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 | } | ||
1206 | LCRYPTO_ALIAS(EC_POINT_is_at_infinity); | ||
1207 | |||
1208 | int | ||
1209 | EC_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 | } | ||
1236 | LCRYPTO_ALIAS(EC_POINT_is_on_curve); | ||
1237 | |||
1238 | int | ||
1239 | EC_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 | } | ||
1266 | LCRYPTO_ALIAS(EC_POINT_cmp); | ||
1267 | |||
1268 | int | ||
1269 | EC_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 | } | ||
1302 | LCRYPTO_ALIAS(EC_POINT_make_affine); | ||
1303 | |||
1304 | int | ||
1305 | EC_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 | } | ||
1369 | LCRYPTO_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 | |||
82 | typedef 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 | |||
129 | struct 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 | |||
160 | struct 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 | |||
173 | const EC_METHOD *EC_GFp_simple_method(void); | ||
174 | const EC_METHOD *EC_GFp_mont_method(void); | ||
175 | |||
176 | /* Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time. */ | ||
177 | int 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 | |||
181 | int ec_group_is_builtin_curve(const EC_GROUP *group, int *out_nid); | ||
182 | |||
183 | /* | ||
184 | * Wrappers around the unergonomic EC_POINT_{oct2point,point2oct}(). | ||
185 | */ | ||
186 | int 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); | ||
188 | int 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 */ | ||
192 | const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); | ||
193 | const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); | ||
194 | |||
195 | struct 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 | |||
221 | struct 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 | |||
240 | int eckey_compute_pubkey(EC_KEY *eckey); | ||
241 | int ecdh_compute_key(unsigned char **out, size_t *out_len, | ||
242 | const EC_POINT *pub_key, const EC_KEY *ecdh); | ||
243 | int ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, | ||
244 | const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); | ||
245 | int 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 | */ | ||
251 | int 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. */ | ||
75 | struct ec_wnaf { | ||
76 | signed char *digits; | ||
77 | size_t num_digits; | ||
78 | EC_POINT **multiples; | ||
79 | size_t num_multiples; | ||
80 | }; | ||
81 | |||
82 | static int | ||
83 | ec_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 | |||
106 | static int | ||
107 | ec_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 | |||
162 | static int | ||
163 | ec_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 | |||
201 | static int | ||
202 | ec_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 | |||
233 | static void | ||
234 | ec_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 | |||
246 | static void | ||
247 | ec_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 | |||
261 | static struct ec_wnaf * | ||
262 | ec_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 | |||
295 | static signed char | ||
296 | ec_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 | |||
304 | static const EC_POINT * | ||
305 | ec_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 | |||
319 | int | ||
320 | ec_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 | |||
75 | typedef 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 | |||
95 | static int | ||
96 | pkey_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 | |||
113 | static int | ||
114 | pkey_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 | |||
148 | static void | ||
149 | pkey_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 | |||
162 | static int | ||
163 | pkey_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 | |||
190 | static int | ||
191 | pkey_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 | |||
209 | static int | ||
210 | pkey_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 | |||
246 | static int | ||
247 | pkey_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 | |||
283 | static int | ||
284 | pkey_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 | |||
418 | static int | ||
419 | pkey_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 | |||
462 | static int | ||
463 | pkey_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 | |||
490 | static int | ||
491 | pkey_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 | |||
526 | const 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 | |||
76 | int | ||
77 | EC_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 | } | ||
95 | LCRYPTO_ALIAS(EC_KEY_print); | ||
96 | |||
97 | int | ||
98 | EC_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 | } | ||
116 | LCRYPTO_ALIAS(EC_KEY_print_fp); | ||
117 | |||
118 | int | ||
119 | ECParameters_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 | } | ||
137 | LCRYPTO_ALIAS(ECParameters_print); | ||
138 | |||
139 | int | ||
140 | ECParameters_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 | } | ||
158 | LCRYPTO_ALIAS(ECParameters_print_fp); | ||
159 | |||
160 | static int | ||
161 | ecpk_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 | |||
199 | static int | ||
200 | ecpk_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 | |||
323 | int | ||
324 | ECPKParameters_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 | } | ||
336 | LCRYPTO_ALIAS(ECPKParameters_print); | ||
337 | |||
338 | int | ||
339 | ECPKParameters_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 | } | ||
357 | LCRYPTO_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 | |||
87 | static inline int | ||
88 | ec_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 | |||
94 | static inline int | ||
95 | ec_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 | |||
100 | static int | ||
101 | ec_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 | |||
112 | static int | ||
113 | ec_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 | |||
124 | static int | ||
125 | ec_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 | |||
166 | static int | ||
167 | ec_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 | |||
182 | static int | ||
183 | ec_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 | |||
274 | static int | ||
275 | ec_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 | |||
359 | static int | ||
360 | ec_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 | |||
384 | static int | ||
385 | ec_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 | |||
468 | static int | ||
469 | ec_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 | |||
602 | static int | ||
603 | ec_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 | |||
778 | static int | ||
779 | ec_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 | |||
905 | static int | ||
906 | ec_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 | */ | ||
922 | static int | ||
923 | ec_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 | */ | ||
1010 | static int | ||
1011 | ec_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 | |||
1189 | static int | ||
1190 | ec_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 | |||
1196 | static int | ||
1197 | ec_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 | |||
1204 | static int | ||
1205 | ec_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 | |||
1211 | static int | ||
1212 | ec_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 | |||
1217 | static int | ||
1218 | ec_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 | |||
1237 | static int | ||
1238 | ec_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 | |||
1248 | static int | ||
1249 | ec_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 | |||
1259 | static int | ||
1260 | ec_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 | |||
1270 | static int | ||
1271 | ec_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 | |||
1281 | static 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 | |||
1298 | const EC_METHOD * | ||
1299 | EC_GFp_simple_method(void) | ||
1300 | { | ||
1301 | return &ec_GFp_simple_method; | ||
1302 | } | ||
1303 | |||
1304 | static 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 | |||
1323 | const EC_METHOD * | ||
1324 | EC_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 | |||
47 | static int | ||
48 | ecx_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 | |||
60 | static struct ecx_key_st * | ||
61 | ecx_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 | |||
78 | static void | ||
79 | ecx_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 | |||
90 | static void | ||
91 | ecx_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 | |||
101 | static int | ||
102 | ecx_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 | |||
142 | static int | ||
143 | ecx_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 | |||
182 | static int | ||
183 | ecx_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 | |||
200 | static int | ||
201 | ecx_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, ¶m, ¶m_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 | |||
243 | static int | ||
244 | ecx_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 | |||
283 | static int | ||
284 | ecx_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. */ | ||
298 | static int | ||
299 | ecx_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 | |||
333 | static int | ||
334 | ecx_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 | |||
356 | static int | ||
357 | ecx_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, ¶m, ¶m_len, &algor, p8pki)) | ||
368 | goto err; | ||
369 | if ((aos = d2i_ASN1_OCTET_STRING(NULL, ¶m, 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 | |||
405 | static int | ||
406 | ecx_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 | |||
445 | static int | ||
446 | ecx_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 | |||
472 | static int | ||
473 | ecx_size(const EVP_PKEY *pkey) | ||
474 | { | ||
475 | return ecx_key_len(pkey->ameth->pkey_id); | ||
476 | } | ||
477 | |||
478 | static int | ||
479 | ecx_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 | |||
488 | static int | ||
489 | ecx_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 | |||
500 | static int | ||
501 | ecx_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 | |||
512 | static int | ||
513 | ecx_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 | |||
530 | static int | ||
531 | ecx_param_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2) | ||
532 | { | ||
533 | /* No parameters, so always equivalent. */ | ||
534 | return 1; | ||
535 | } | ||
536 | |||
537 | static void | ||
538 | ecx_free(EVP_PKEY *pkey) | ||
539 | { | ||
540 | struct ecx_key_st *ecx_key = pkey->pkey.ecx; | ||
541 | |||
542 | ecx_key_free(ecx_key); | ||
543 | } | ||
544 | |||
545 | static int | ||
546 | ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
547 | { | ||
548 | /* Not supported. */ | ||
549 | return -2; | ||
550 | } | ||
551 | |||
552 | #ifndef OPENSSL_NO_CMS | ||
553 | static int | ||
554 | ecx_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, ¶m_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 | |||
603 | static int | ||
604 | ecx_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 | |||
619 | static int | ||
620 | ecx_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 | |||
646 | static int | ||
647 | ecx_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 | |||
673 | static int | ||
674 | ecx_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 | |||
694 | static int | ||
695 | ecx_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 | |||
715 | static int | ||
716 | pkey_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 | |||
737 | static int | ||
738 | pkey_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 | |||
772 | static int | ||
773 | pkey_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 | |||
781 | static int | ||
782 | ecx_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, ¶m_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 | |||
803 | static int | ||
804 | ecx_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 | |||
820 | static int | ||
821 | pkey_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 | |||
853 | static int | ||
854 | pkey_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 | |||
871 | static int | ||
872 | pkey_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 | |||
892 | const 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 | |||
923 | const 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 | |||
930 | const 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 | |||
966 | const 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 | }; | ||