Home | History | Annotate | Line # | Download | only in ec
      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 {
     42     return &openssl_ec_key_method;
     43 }
     44 
     45 const EC_KEY_METHOD *EC_KEY_get_default_method(void)
     46 {
     47     return default_ec_key_meth;
     48 }
     49 
     50 void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
     51 {
     52     if (meth == NULL)
     53         default_ec_key_meth = &openssl_ec_key_method;
     54     else
     55         default_ec_key_meth = meth;
     56 }
     57 
     58 const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
     59 {
     60     return key->meth;
     61 }
     62 
     63 int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
     64 {
     65     void (*finish)(EC_KEY *key) = key->meth->finish;
     66 
     67     if (finish != NULL)
     68         finish(key);
     69 
     70 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
     71     ENGINE_finish(key->engine);
     72     key->engine = NULL;
     73 #endif
     74 
     75     key->meth = meth;
     76     if (meth->init != NULL)
     77         return meth->init(key);
     78     return 1;
     79 }
     80 
     81 EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq,
     82                                    ENGINE *engine)
     83 {
     84     EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
     85 
     86     if (ret == NULL) {
     87         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
     88         return NULL;
     89     }
     90 
     91     ret->libctx = libctx;
     92     if (propq != NULL) {
     93         ret->propq = OPENSSL_strdup(propq);
     94         if (ret->propq == NULL) {
     95             ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
     96             goto err;
     97         }
     98     }
     99 
    100     ret->references = 1;
    101     ret->lock = CRYPTO_THREAD_lock_new();
    102     if (ret->lock == NULL) {
    103         ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
    104         goto err;
    105     }
    106 
    107     ret->meth = EC_KEY_get_default_method();
    108 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
    109     if (engine != NULL) {
    110         if (!ENGINE_init(engine)) {
    111             ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB);
    112             goto err;
    113         }
    114         ret->engine = engine;
    115     } else
    116         ret->engine = ENGINE_get_default_EC();
    117     if (ret->engine != NULL) {
    118         ret->meth = ENGINE_get_EC(ret->engine);
    119         if (ret->meth == NULL) {
    120             ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB);
    121             goto err;
    122         }
    123     }
    124 #endif
    125 
    126     ret->version = 1;
    127     ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
    128 
    129 /* No ex_data inside the FIPS provider */
    130 #ifndef FIPS_MODULE
    131     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
    132         goto err;
    133     }
    134 #endif
    135 
    136     if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
    137         ERR_raise(ERR_LIB_EC, ERR_R_INIT_FAIL);
    138         goto err;
    139     }
    140     return ret;
    141 
    142  err:
    143     EC_KEY_free(ret);
    144     return NULL;
    145 }
    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 {
    159     unsigned char *sec = NULL;
    160     size_t seclen;
    161     if (eckey->meth->compute_key == NULL) {
    162         ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
    163         return 0;
    164     }
    165     if (outlen > INT_MAX) {
    166         ERR_raise(ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH);
    167         return 0;
    168     }
    169     if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
    170         return 0;
    171     if (KDF != NULL) {
    172         KDF(sec, seclen, out, &outlen);
    173     } else {
    174         if (outlen > seclen)
    175             outlen = seclen;
    176         memcpy(out, sec, outlen);
    177     }
    178     OPENSSL_clear_free(sec, seclen);
    179     return outlen;
    180 }
    181 
    182 EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
    183 {
    184     EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
    185 
    186     if (ret == NULL)
    187         return NULL;
    188     if (meth != NULL)
    189         *ret = *meth;
    190     ret->flags |= EC_KEY_METHOD_DYNAMIC;
    191     return ret;
    192 }
    193 
    194 void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
    195 {
    196     if (meth->flags & EC_KEY_METHOD_DYNAMIC)
    197         OPENSSL_free(meth);
    198 }
    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 {
    210     meth->init = init;
    211     meth->finish = finish;
    212     meth->copy = copy;
    213     meth->set_group = set_group;
    214     meth->set_private = set_private;
    215     meth->set_public = set_public;
    216 }
    217 
    218 void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
    219                               int (*keygen)(EC_KEY *key))
    220 {
    221     meth->keygen = keygen;
    222 }
    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 {
    230     meth->compute_key = ckey;
    231 }
    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 {
    247     meth->sign = sign;
    248     meth->sign_setup = sign_setup;
    249     meth->sign_sig = sign_sig;
    250 }
    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 {
    262     meth->verify = verify;
    263     meth->verify_sig = verify_sig;
    264 }
    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 {
    277     if (pinit != NULL)
    278         *pinit = meth->init;
    279     if (pfinish != NULL)
    280         *pfinish = meth->finish;
    281     if (pcopy != NULL)
    282         *pcopy = meth->copy;
    283     if (pset_group != NULL)
    284         *pset_group = meth->set_group;
    285     if (pset_private != NULL)
    286         *pset_private = meth->set_private;
    287     if (pset_public != NULL)
    288         *pset_public = meth->set_public;
    289 }
    290 
    291 void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
    292                               int (**pkeygen)(EC_KEY *key))
    293 {
    294     if (pkeygen != NULL)
    295         *pkeygen = meth->keygen;
    296 }
    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 {
    304     if (pck != NULL)
    305         *pck = meth->compute_key;
    306 }
    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 {
    322     if (psign != NULL)
    323         *psign = meth->sign;
    324     if (psign_setup != NULL)
    325         *psign_setup = meth->sign_setup;
    326     if (psign_sig != NULL)
    327         *psign_sig = meth->sign_sig;
    328 }
    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 {
    340     if (pverify != NULL)
    341         *pverify = meth->verify;
    342     if (pverify_sig != NULL)
    343         *pverify_sig = meth->verify_sig;
    344 }
    345