diff options
| author | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
|---|---|---|
| committer | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
| commit | b1ddde874c215cc8891531ed92876f091b7eb83e (patch) | |
| tree | edb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libcrypto/ec | |
| parent | f0a36529837a161734c802ae4c42e84e42347be2 (diff) | |
| download | openbsd-tb_20250414.tar.gz openbsd-tb_20250414.tar.bz2 openbsd-tb_20250414.zip | |
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libcrypto/ec')
| -rw-r--r-- | src/lib/libcrypto/ec/ec.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 | }; | ||
