/src/openssl30/crypto/ec/ec_kmeth.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
| 5 |  |  * this file except in compliance with the License.  You can obtain a copy | 
| 6 |  |  * in the file LICENSE in the source distribution or at | 
| 7 |  |  * https://www.openssl.org/source/license.html | 
| 8 |  |  */ | 
| 9 |  |  | 
| 10 |  | /* | 
| 11 |  |  * ECDH and ECDSA low level APIs are deprecated for public use, but still ok | 
| 12 |  |  * for internal use. | 
| 13 |  |  */ | 
| 14 |  | #include "internal/deprecated.h" | 
| 15 |  |  | 
| 16 |  | #include <string.h> | 
| 17 |  | #include <openssl/ec.h> | 
| 18 |  | #ifndef FIPS_MODULE | 
| 19 |  | # include <openssl/engine.h> | 
| 20 |  | #endif | 
| 21 |  | #include <openssl/err.h> | 
| 22 |  | #include "ec_local.h" | 
| 23 |  |  | 
| 24 |  |  | 
| 25 |  | static const EC_KEY_METHOD openssl_ec_key_method = { | 
| 26 |  |     "OpenSSL EC_KEY method", | 
| 27 |  |     0, | 
| 28 |  |     0,0,0,0,0,0, | 
| 29 |  |     ossl_ec_key_gen, | 
| 30 |  |     ossl_ecdh_compute_key, | 
| 31 |  |     ossl_ecdsa_sign, | 
| 32 |  |     ossl_ecdsa_sign_setup, | 
| 33 |  |     ossl_ecdsa_sign_sig, | 
| 34 |  |     ossl_ecdsa_verify, | 
| 35 |  |     ossl_ecdsa_verify_sig | 
| 36 |  | }; | 
| 37 |  |  | 
| 38 |  | static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; | 
| 39 |  |  | 
| 40 |  | const EC_KEY_METHOD *EC_KEY_OpenSSL(void) | 
| 41 | 119k | { | 
| 42 | 119k |     return &openssl_ec_key_method; | 
| 43 | 119k | } | 
| 44 |  |  | 
| 45 |  | const EC_KEY_METHOD *EC_KEY_get_default_method(void) | 
| 46 | 343k | { | 
| 47 | 343k |     return default_ec_key_meth; | 
| 48 | 343k | } | 
| 49 |  |  | 
| 50 |  | void EC_KEY_set_default_method(const EC_KEY_METHOD *meth) | 
| 51 | 0 | { | 
| 52 | 0 |     if (meth == NULL) | 
| 53 | 0 |         default_ec_key_meth = &openssl_ec_key_method; | 
| 54 | 0 |     else | 
| 55 | 0 |         default_ec_key_meth = meth; | 
| 56 | 0 | } | 
| 57 |  |  | 
| 58 |  | const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key) | 
| 59 | 119k | { | 
| 60 | 119k |     return key->meth; | 
| 61 | 119k | } | 
| 62 |  |  | 
| 63 |  | int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) | 
| 64 | 0 | { | 
| 65 | 0 |     void (*finish)(EC_KEY *key) = key->meth->finish; | 
| 66 |  | 
 | 
| 67 | 0 |     if (finish != NULL) | 
| 68 | 0 |         finish(key); | 
| 69 |  | 
 | 
| 70 | 0 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) | 
| 71 | 0 |     ENGINE_finish(key->engine); | 
| 72 | 0 |     key->engine = NULL; | 
| 73 | 0 | #endif | 
| 74 |  | 
 | 
| 75 | 0 |     key->meth = meth; | 
| 76 | 0 |     if (meth->init != NULL) | 
| 77 | 0 |         return meth->init(key); | 
| 78 | 0 |     return 1; | 
| 79 | 0 | } | 
| 80 |  |  | 
| 81 |  | EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, | 
| 82 |  |                                    ENGINE *engine) | 
| 83 | 117k | { | 
| 84 | 117k |     EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); | 
| 85 |  |  | 
| 86 | 117k |     if (ret == NULL) { | 
| 87 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | 
| 88 | 0 |         return NULL; | 
| 89 | 0 |     } | 
| 90 |  |  | 
| 91 | 117k |     ret->libctx = libctx; | 
| 92 | 117k |     if (propq != NULL) { | 
| 93 | 0 |         ret->propq = OPENSSL_strdup(propq); | 
| 94 | 0 |         if (ret->propq == NULL) { | 
| 95 | 0 |             ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | 
| 96 | 0 |             goto err; | 
| 97 | 0 |         } | 
| 98 | 0 |     } | 
| 99 |  |  | 
| 100 | 117k |     ret->references = 1; | 
| 101 | 117k |     ret->lock = CRYPTO_THREAD_lock_new(); | 
| 102 | 117k |     if (ret->lock == NULL) { | 
| 103 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); | 
| 104 | 0 |         goto err; | 
| 105 | 0 |     } | 
| 106 |  |  | 
| 107 | 117k |     ret->meth = EC_KEY_get_default_method(); | 
| 108 | 117k | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) | 
| 109 | 117k |     if (engine != NULL) { | 
| 110 | 0 |         if (!ENGINE_init(engine)) { | 
| 111 | 0 |             ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB); | 
| 112 | 0 |             goto err; | 
| 113 | 0 |         } | 
| 114 | 0 |         ret->engine = engine; | 
| 115 | 0 |     } else | 
| 116 | 117k |         ret->engine = ENGINE_get_default_EC(); | 
| 117 | 117k |     if (ret->engine != NULL) { | 
| 118 | 0 |         ret->meth = ENGINE_get_EC(ret->engine); | 
| 119 | 0 |         if (ret->meth == NULL) { | 
| 120 | 0 |             ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB); | 
| 121 | 0 |             goto err; | 
| 122 | 0 |         } | 
| 123 | 0 |     } | 
| 124 | 117k | #endif | 
| 125 |  |  | 
| 126 | 117k |     ret->version = 1; | 
| 127 | 117k |     ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; | 
| 128 |  |  | 
| 129 |  | /* No ex_data inside the FIPS provider */ | 
| 130 | 117k | #ifndef FIPS_MODULE | 
| 131 | 117k |     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { | 
| 132 | 0 |         goto err; | 
| 133 | 0 |     } | 
| 134 | 117k | #endif | 
| 135 |  |  | 
| 136 | 117k |     if (ret->meth->init != NULL && ret->meth->init(ret) == 0) { | 
| 137 | 0 |         ERR_raise(ERR_LIB_EC, ERR_R_INIT_FAIL); | 
| 138 | 0 |         goto err; | 
| 139 | 0 |     } | 
| 140 | 117k |     return ret; | 
| 141 |  |  | 
| 142 | 0 |  err: | 
| 143 | 0 |     EC_KEY_free(ret); | 
| 144 | 0 |     return NULL; | 
| 145 | 117k | } | 
| 146 |  |  | 
| 147 |  | #ifndef FIPS_MODULE | 
| 148 |  | EC_KEY *EC_KEY_new_method(ENGINE *engine) | 
| 149 |  | { | 
| 150 |  |     return ossl_ec_key_new_method_int(NULL, NULL, engine); | 
| 151 |  | } | 
| 152 |  | #endif | 
| 153 |  |  | 
| 154 |  | int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, | 
| 155 |  |                      const EC_KEY *eckey, | 
| 156 |  |                      void *(*KDF) (const void *in, size_t inlen, void *out, | 
| 157 |  |                                    size_t *outlen)) | 
| 158 | 1.08k | { | 
| 159 | 1.08k |     unsigned char *sec = NULL; | 
| 160 | 1.08k |     size_t seclen; | 
| 161 | 1.08k |     if (eckey->meth->compute_key == NULL) { | 
| 162 | 0 |         ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); | 
| 163 | 0 |         return 0; | 
| 164 | 0 |     } | 
| 165 | 1.08k |     if (outlen > INT_MAX) { | 
| 166 | 0 |         ERR_raise(ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH); | 
| 167 | 0 |         return 0; | 
| 168 | 0 |     } | 
| 169 | 1.08k |     if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey)) | 
| 170 | 13 |         return 0; | 
| 171 | 1.07k |     if (KDF != NULL) { | 
| 172 | 0 |         KDF(sec, seclen, out, &outlen); | 
| 173 | 1.07k |     } else { | 
| 174 | 1.07k |         if (outlen > seclen) | 
| 175 | 0 |             outlen = seclen; | 
| 176 | 1.07k |         memcpy(out, sec, outlen); | 
| 177 | 1.07k |     } | 
| 178 | 1.07k |     OPENSSL_clear_free(sec, seclen); | 
| 179 | 1.07k |     return outlen; | 
| 180 | 1.08k | } | 
| 181 |  |  | 
| 182 |  | EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth) | 
| 183 | 0 | { | 
| 184 | 0 |     EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth)); | 
| 185 |  | 
 | 
| 186 | 0 |     if (ret == NULL) | 
| 187 | 0 |         return NULL; | 
| 188 | 0 |     if (meth != NULL) | 
| 189 | 0 |         *ret = *meth; | 
| 190 | 0 |     ret->flags |= EC_KEY_METHOD_DYNAMIC; | 
| 191 | 0 |     return ret; | 
| 192 | 0 | } | 
| 193 |  |  | 
| 194 |  | void EC_KEY_METHOD_free(EC_KEY_METHOD *meth) | 
| 195 | 0 | { | 
| 196 | 0 |     if (meth->flags & EC_KEY_METHOD_DYNAMIC) | 
| 197 | 0 |         OPENSSL_free(meth); | 
| 198 | 0 | } | 
| 199 |  |  | 
| 200 |  | void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, | 
| 201 |  |                             int (*init)(EC_KEY *key), | 
| 202 |  |                             void (*finish)(EC_KEY *key), | 
| 203 |  |                             int (*copy)(EC_KEY *dest, const EC_KEY *src), | 
| 204 |  |                             int (*set_group)(EC_KEY *key, const EC_GROUP *grp), | 
| 205 |  |                             int (*set_private)(EC_KEY *key, | 
| 206 |  |                                                const BIGNUM *priv_key), | 
| 207 |  |                             int (*set_public)(EC_KEY *key, | 
| 208 |  |                                               const EC_POINT *pub_key)) | 
| 209 | 0 | { | 
| 210 | 0 |     meth->init = init; | 
| 211 | 0 |     meth->finish = finish; | 
| 212 | 0 |     meth->copy = copy; | 
| 213 | 0 |     meth->set_group = set_group; | 
| 214 | 0 |     meth->set_private = set_private; | 
| 215 | 0 |     meth->set_public = set_public; | 
| 216 | 0 | } | 
| 217 |  |  | 
| 218 |  | void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, | 
| 219 |  |                               int (*keygen)(EC_KEY *key)) | 
| 220 | 0 | { | 
| 221 | 0 |     meth->keygen = keygen; | 
| 222 | 0 | } | 
| 223 |  |  | 
| 224 |  | void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, | 
| 225 |  |                                    int (*ckey)(unsigned char **psec, | 
| 226 |  |                                                size_t *pseclen, | 
| 227 |  |                                                const EC_POINT *pub_key, | 
| 228 |  |                                                const EC_KEY *ecdh)) | 
| 229 | 0 | { | 
| 230 | 0 |     meth->compute_key = ckey; | 
| 231 | 0 | } | 
| 232 |  |  | 
| 233 |  | void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, | 
| 234 |  |                             int (*sign)(int type, const unsigned char *dgst, | 
| 235 |  |                                         int dlen, unsigned char *sig, | 
| 236 |  |                                         unsigned int *siglen, | 
| 237 |  |                                         const BIGNUM *kinv, const BIGNUM *r, | 
| 238 |  |                                         EC_KEY *eckey), | 
| 239 |  |                             int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, | 
| 240 |  |                                               BIGNUM **kinvp, BIGNUM **rp), | 
| 241 |  |                             ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, | 
| 242 |  |                                                    int dgst_len, | 
| 243 |  |                                                    const BIGNUM *in_kinv, | 
| 244 |  |                                                    const BIGNUM *in_r, | 
| 245 |  |                                                    EC_KEY *eckey)) | 
| 246 | 0 | { | 
| 247 | 0 |     meth->sign = sign; | 
| 248 | 0 |     meth->sign_setup = sign_setup; | 
| 249 | 0 |     meth->sign_sig = sign_sig; | 
| 250 | 0 | } | 
| 251 |  |  | 
| 252 |  | void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, | 
| 253 |  |                               int (*verify)(int type, const unsigned | 
| 254 |  |                                             char *dgst, int dgst_len, | 
| 255 |  |                                             const unsigned char *sigbuf, | 
| 256 |  |                                             int sig_len, EC_KEY *eckey), | 
| 257 |  |                               int (*verify_sig)(const unsigned char *dgst, | 
| 258 |  |                                                 int dgst_len, | 
| 259 |  |                                                 const ECDSA_SIG *sig, | 
| 260 |  |                                                 EC_KEY *eckey)) | 
| 261 | 0 | { | 
| 262 | 0 |     meth->verify = verify; | 
| 263 | 0 |     meth->verify_sig = verify_sig; | 
| 264 | 0 | } | 
| 265 |  |  | 
| 266 |  | void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, | 
| 267 |  |                             int (**pinit)(EC_KEY *key), | 
| 268 |  |                             void (**pfinish)(EC_KEY *key), | 
| 269 |  |                             int (**pcopy)(EC_KEY *dest, const EC_KEY *src), | 
| 270 |  |                             int (**pset_group)(EC_KEY *key, | 
| 271 |  |                                                const EC_GROUP *grp), | 
| 272 |  |                             int (**pset_private)(EC_KEY *key, | 
| 273 |  |                                                  const BIGNUM *priv_key), | 
| 274 |  |                             int (**pset_public)(EC_KEY *key, | 
| 275 |  |                                                 const EC_POINT *pub_key)) | 
| 276 | 0 | { | 
| 277 | 0 |     if (pinit != NULL) | 
| 278 | 0 |         *pinit = meth->init; | 
| 279 | 0 |     if (pfinish != NULL) | 
| 280 | 0 |         *pfinish = meth->finish; | 
| 281 | 0 |     if (pcopy != NULL) | 
| 282 | 0 |         *pcopy = meth->copy; | 
| 283 | 0 |     if (pset_group != NULL) | 
| 284 | 0 |         *pset_group = meth->set_group; | 
| 285 | 0 |     if (pset_private != NULL) | 
| 286 | 0 |         *pset_private = meth->set_private; | 
| 287 | 0 |     if (pset_public != NULL) | 
| 288 | 0 |         *pset_public = meth->set_public; | 
| 289 | 0 | } | 
| 290 |  |  | 
| 291 |  | void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, | 
| 292 |  |                               int (**pkeygen)(EC_KEY *key)) | 
| 293 | 0 | { | 
| 294 | 0 |     if (pkeygen != NULL) | 
| 295 | 0 |         *pkeygen = meth->keygen; | 
| 296 | 0 | } | 
| 297 |  |  | 
| 298 |  | void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, | 
| 299 |  |                                    int (**pck)(unsigned char **pout, | 
| 300 |  |                                                size_t *poutlen, | 
| 301 |  |                                                const EC_POINT *pub_key, | 
| 302 |  |                                                const EC_KEY *ecdh)) | 
| 303 | 0 | { | 
| 304 | 0 |     if (pck != NULL) | 
| 305 | 0 |         *pck = meth->compute_key; | 
| 306 | 0 | } | 
| 307 |  |  | 
| 308 |  | void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, | 
| 309 |  |                             int (**psign)(int type, const unsigned char *dgst, | 
| 310 |  |                                           int dlen, unsigned char *sig, | 
| 311 |  |                                           unsigned int *siglen, | 
| 312 |  |                                           const BIGNUM *kinv, const BIGNUM *r, | 
| 313 |  |                                           EC_KEY *eckey), | 
| 314 |  |                             int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, | 
| 315 |  |                                                 BIGNUM **kinvp, BIGNUM **rp), | 
| 316 |  |                             ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, | 
| 317 |  |                                                      int dgst_len, | 
| 318 |  |                                                      const BIGNUM *in_kinv, | 
| 319 |  |                                                      const BIGNUM *in_r, | 
| 320 |  |                                                      EC_KEY *eckey)) | 
| 321 | 0 | { | 
| 322 | 0 |     if (psign != NULL) | 
| 323 | 0 |         *psign = meth->sign; | 
| 324 | 0 |     if (psign_setup != NULL) | 
| 325 | 0 |         *psign_setup = meth->sign_setup; | 
| 326 | 0 |     if (psign_sig != NULL) | 
| 327 | 0 |         *psign_sig = meth->sign_sig; | 
| 328 | 0 | } | 
| 329 |  |  | 
| 330 |  | void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, | 
| 331 |  |                               int (**pverify)(int type, const unsigned | 
| 332 |  |                                               char *dgst, int dgst_len, | 
| 333 |  |                                               const unsigned char *sigbuf, | 
| 334 |  |                                               int sig_len, EC_KEY *eckey), | 
| 335 |  |                               int (**pverify_sig)(const unsigned char *dgst, | 
| 336 |  |                                                   int dgst_len, | 
| 337 |  |                                                   const ECDSA_SIG *sig, | 
| 338 |  |                                                   EC_KEY *eckey)) | 
| 339 | 0 | { | 
| 340 | 0 |     if (pverify != NULL) | 
| 341 | 0 |         *pverify = meth->verify; | 
| 342 | 0 |     if (pverify_sig != NULL) | 
| 343 | 0 |         *pverify_sig = meth->verify_sig; | 
| 344 | 0 | } |