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