1 /* $OpenBSD: ec_kmeth.c,v 1.4 2019/01/19 01:18:56 tb Exp $ */ 2 /* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6 /* ==================================================================== 7 * Copyright (c) 2015 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 * licensing@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 55 #include <openssl/ec.h> 56 #ifndef OPENSSL_NO_ENGINE 57 #include <openssl/engine.h> 58 #endif 59 #include <openssl/err.h> 60 61 #include "ec_lcl.h" 62 #include "ecs_locl.h" 63 64 static const EC_KEY_METHOD openssl_ec_key_method = { 65 .name = "OpenSSL EC_KEY method", 66 .flags = 0, 67 68 .init = NULL, 69 .finish = NULL, 70 .copy = NULL, 71 72 .set_group = NULL, 73 .set_private = NULL, 74 .set_public = NULL, 75 76 .keygen = ossl_ec_key_gen, 77 .compute_key = ossl_ecdh_compute_key, 78 79 .sign = ossl_ecdsa_sign, 80 .sign_setup = ossl_ecdsa_sign_setup, 81 .sign_sig = ossl_ecdsa_sign_sig, 82 83 .verify = ossl_ecdsa_verify, 84 .verify_sig = ossl_ecdsa_verify_sig, 85 }; 86 87 const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; 88 89 const EC_KEY_METHOD * 90 EC_KEY_OpenSSL(void) 91 { 92 return &openssl_ec_key_method; 93 } 94 95 const EC_KEY_METHOD * 96 EC_KEY_get_default_method(void) 97 { 98 return default_ec_key_meth; 99 } 100 101 void 102 EC_KEY_set_default_method(const EC_KEY_METHOD *meth) 103 { 104 if (meth == NULL) 105 default_ec_key_meth = &openssl_ec_key_method; 106 else 107 default_ec_key_meth = meth; 108 } 109 110 const EC_KEY_METHOD * 111 EC_KEY_get_method(const EC_KEY *key) 112 { 113 return key->meth; 114 } 115 116 int 117 EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) 118 { 119 void (*finish)(EC_KEY *key) = key->meth->finish; 120 121 if (finish != NULL) 122 finish(key); 123 124 #ifndef OPENSSL_NO_ENGINE 125 ENGINE_finish(key->engine); 126 key->engine = NULL; 127 #endif 128 129 key->meth = meth; 130 if (meth->init != NULL) 131 return meth->init(key); 132 return 1; 133 } 134 135 EC_KEY * 136 EC_KEY_new_method(ENGINE *engine) 137 { 138 EC_KEY *ret; 139 140 if ((ret = calloc(1, sizeof(EC_KEY))) == NULL) { 141 ECerror(ERR_R_MALLOC_FAILURE); 142 return NULL; 143 } 144 ret->meth = EC_KEY_get_default_method(); 145 #ifndef OPENSSL_NO_ENGINE 146 if (engine != NULL) { 147 if (!ENGINE_init(engine)) { 148 ECerror(ERR_R_ENGINE_LIB); 149 goto err; 150 } 151 ret->engine = engine; 152 } else 153 ret->engine = ENGINE_get_default_EC(); 154 if (ret->engine) { 155 ret->meth = ENGINE_get_EC(ret->engine); 156 if (ret->meth == NULL) { 157 ECerror(ERR_R_ENGINE_LIB); 158 goto err; 159 } 160 } 161 #endif 162 ret->version = 1; 163 ret->flags = 0; 164 ret->group = NULL; 165 ret->pub_key = NULL; 166 ret->priv_key = NULL; 167 ret->enc_flag = 0; 168 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 169 ret->references = 1; 170 ret->method_data = NULL; 171 172 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) 173 goto err; 174 if (ret->meth->init != NULL && ret->meth->init(ret) == 0) 175 goto err; 176 177 return ret; 178 179 err: 180 EC_KEY_free(ret); 181 return NULL; 182 } 183 184 EC_KEY_METHOD * 185 EC_KEY_METHOD_new(const EC_KEY_METHOD *meth) 186 { 187 EC_KEY_METHOD *ret; 188 189 if ((ret = malloc(sizeof(*meth))) == NULL) 190 return NULL; 191 if (meth != NULL) 192 *ret = *meth; 193 ret->flags |= EC_KEY_METHOD_DYNAMIC; 194 return ret; 195 } 196 197 void 198 EC_KEY_METHOD_free(EC_KEY_METHOD *meth) 199 { 200 if (meth == NULL) 201 return; 202 if (meth->flags & EC_KEY_METHOD_DYNAMIC) 203 free(meth); 204 } 205 206 void 207 EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, 208 int (*init)(EC_KEY *key), 209 void (*finish)(EC_KEY *key), 210 int (*copy)(EC_KEY *dest, const EC_KEY *src), 211 int (*set_group)(EC_KEY *key, const EC_GROUP *grp), 212 int (*set_private)(EC_KEY *key, const BIGNUM *priv_key), 213 int (*set_public)(EC_KEY *key, const EC_POINT *pub_key)) 214 { 215 meth->init = init; 216 meth->finish = finish; 217 meth->copy = copy; 218 meth->set_group = set_group; 219 meth->set_private = set_private; 220 meth->set_public = set_public; 221 } 222 223 void 224 EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, int (*keygen)(EC_KEY *key)) 225 { 226 meth->keygen = keygen; 227 } 228 229 void 230 EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, 231 int (*ckey)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, 232 void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))) 233 { 234 meth->compute_key = ckey; 235 } 236 237 void 238 EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, 239 int (*sign)(int type, const unsigned char *dgst, 240 int dlen, unsigned char *sig, unsigned int *siglen, 241 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), 242 int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, 243 BIGNUM **kinvp, BIGNUM **rp), 244 ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, 245 int dgst_len, const BIGNUM *in_kinv, 246 const BIGNUM *in_r, EC_KEY *eckey)) 247 { 248 meth->sign = sign; 249 meth->sign_setup = sign_setup; 250 meth->sign_sig = sign_sig; 251 } 252 253 void 254 EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, 255 int (*verify)(int type, const unsigned char *dgst, int dgst_len, 256 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), 257 int (*verify_sig)(const unsigned char *dgst, int dgst_len, 258 const ECDSA_SIG *sig, EC_KEY *eckey)) 259 { 260 meth->verify = verify; 261 meth->verify_sig = verify_sig; 262 } 263 264 265 void 266 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, const EC_GROUP *grp), 271 int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key), 272 int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key)) 273 { 274 if (pinit != NULL) 275 *pinit = meth->init; 276 if (pfinish != NULL) 277 *pfinish = meth->finish; 278 if (pcopy != NULL) 279 *pcopy = meth->copy; 280 if (pset_group != NULL) 281 *pset_group = meth->set_group; 282 if (pset_private != NULL) 283 *pset_private = meth->set_private; 284 if (pset_public != NULL) 285 *pset_public = meth->set_public; 286 } 287 288 void 289 EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, 290 int (**pkeygen)(EC_KEY *key)) 291 { 292 if (pkeygen != NULL) 293 *pkeygen = meth->keygen; 294 } 295 296 void 297 EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, 298 int (**pck)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, 299 void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))) 300 { 301 if (pck != NULL) 302 *pck = meth->compute_key; 303 } 304 305 void 306 EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, 307 int (**psign)(int type, const unsigned char *dgst, 308 int dlen, unsigned char *sig, unsigned int *siglen, 309 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), 310 int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, 311 BIGNUM **kinvp, BIGNUM **rp), 312 ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, 313 int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, 314 EC_KEY *eckey)) 315 { 316 if (psign != NULL) 317 *psign = meth->sign; 318 if (psign_setup != NULL) 319 *psign_setup = meth->sign_setup; 320 if (psign_sig != NULL) 321 *psign_sig = meth->sign_sig; 322 } 323 324 void 325 EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, 326 int (**pverify)(int type, const unsigned char *dgst, int dgst_len, 327 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), 328 int (**pverify_sig)(const unsigned char *dgst, int dgst_len, 329 const ECDSA_SIG *sig, EC_KEY *eckey)) 330 { 331 if (pverify != NULL) 332 *pverify = meth->verify; 333 if (pverify_sig != NULL) 334 *pverify_sig = meth->verify_sig; 335 } 336