1160814Ssimon/* crypto/ec/ec_key.c */ 2160814Ssimon/* 3160814Ssimon * Written by Nils Larsch for the OpenSSL project. 4160814Ssimon */ 5160814Ssimon/* ==================================================================== 6160814Ssimon * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 7160814Ssimon * 8160814Ssimon * Redistribution and use in source and binary forms, with or without 9160814Ssimon * modification, are permitted provided that the following conditions 10160814Ssimon * are met: 11160814Ssimon * 12160814Ssimon * 1. Redistributions of source code must retain the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer. 14160814Ssimon * 15160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16160814Ssimon * notice, this list of conditions and the following disclaimer in 17160814Ssimon * the documentation and/or other materials provided with the 18160814Ssimon * distribution. 19160814Ssimon * 20160814Ssimon * 3. All advertising materials mentioning features or use of this 21160814Ssimon * software must display the following acknowledgment: 22160814Ssimon * "This product includes software developed by the OpenSSL Project 23160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24160814Ssimon * 25160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26160814Ssimon * endorse or promote products derived from this software without 27160814Ssimon * prior written permission. For written permission, please contact 28160814Ssimon * openssl-core@openssl.org. 29160814Ssimon * 30160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31160814Ssimon * nor may "OpenSSL" appear in their names without prior written 32160814Ssimon * permission of the OpenSSL Project. 33160814Ssimon * 34160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 35160814Ssimon * acknowledgment: 36160814Ssimon * "This product includes software developed by the OpenSSL Project 37160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38160814Ssimon * 39160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51160814Ssimon * ==================================================================== 52160814Ssimon * 53160814Ssimon * This product includes cryptographic software written by Eric Young 54160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 55160814Ssimon * Hudson (tjh@cryptsoft.com). 56160814Ssimon * 57160814Ssimon */ 58160814Ssimon/* ==================================================================== 59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60160814Ssimon * Portions originally developed by SUN MICROSYSTEMS, INC., and 61160814Ssimon * contributed to the OpenSSL project. 62160814Ssimon */ 63160814Ssimon 64160814Ssimon#include <string.h> 65160814Ssimon#include "ec_lcl.h" 66160814Ssimon#include <openssl/err.h> 67238405Sjkim#ifdef OPENSSL_FIPS 68238405Sjkim#include <openssl/fips.h> 69238405Sjkim#endif 70160814Ssimon 71160814SsimonEC_KEY *EC_KEY_new(void) 72160814Ssimon { 73160814Ssimon EC_KEY *ret; 74160814Ssimon 75160814Ssimon ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); 76160814Ssimon if (ret == NULL) 77160814Ssimon { 78160814Ssimon ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); 79160814Ssimon return(NULL); 80160814Ssimon } 81160814Ssimon 82160814Ssimon ret->version = 1; 83238405Sjkim ret->flags = 0; 84160814Ssimon ret->group = NULL; 85160814Ssimon ret->pub_key = NULL; 86160814Ssimon ret->priv_key= NULL; 87160814Ssimon ret->enc_flag= 0; 88160814Ssimon ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 89160814Ssimon ret->references= 1; 90160814Ssimon ret->method_data = NULL; 91160814Ssimon return(ret); 92160814Ssimon } 93160814Ssimon 94160814SsimonEC_KEY *EC_KEY_new_by_curve_name(int nid) 95160814Ssimon { 96160814Ssimon EC_KEY *ret = EC_KEY_new(); 97160814Ssimon if (ret == NULL) 98160814Ssimon return NULL; 99160814Ssimon ret->group = EC_GROUP_new_by_curve_name(nid); 100160814Ssimon if (ret->group == NULL) 101160814Ssimon { 102160814Ssimon EC_KEY_free(ret); 103160814Ssimon return NULL; 104160814Ssimon } 105160814Ssimon return ret; 106160814Ssimon } 107160814Ssimon 108160814Ssimonvoid EC_KEY_free(EC_KEY *r) 109160814Ssimon { 110160814Ssimon int i; 111160814Ssimon 112160814Ssimon if (r == NULL) return; 113160814Ssimon 114160814Ssimon i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC); 115160814Ssimon#ifdef REF_PRINT 116160814Ssimon REF_PRINT("EC_KEY",r); 117160814Ssimon#endif 118160814Ssimon if (i > 0) return; 119160814Ssimon#ifdef REF_CHECK 120160814Ssimon if (i < 0) 121160814Ssimon { 122160814Ssimon fprintf(stderr,"EC_KEY_free, bad reference count\n"); 123160814Ssimon abort(); 124160814Ssimon } 125160814Ssimon#endif 126160814Ssimon 127160814Ssimon if (r->group != NULL) 128160814Ssimon EC_GROUP_free(r->group); 129160814Ssimon if (r->pub_key != NULL) 130160814Ssimon EC_POINT_free(r->pub_key); 131160814Ssimon if (r->priv_key != NULL) 132160814Ssimon BN_clear_free(r->priv_key); 133160814Ssimon 134160814Ssimon EC_EX_DATA_free_all_data(&r->method_data); 135160814Ssimon 136160814Ssimon OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); 137160814Ssimon 138160814Ssimon OPENSSL_free(r); 139160814Ssimon } 140160814Ssimon 141160814SsimonEC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) 142160814Ssimon { 143160814Ssimon EC_EXTRA_DATA *d; 144160814Ssimon 145160814Ssimon if (dest == NULL || src == NULL) 146160814Ssimon { 147160814Ssimon ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); 148160814Ssimon return NULL; 149160814Ssimon } 150160814Ssimon /* copy the parameters */ 151160814Ssimon if (src->group) 152160814Ssimon { 153160814Ssimon const EC_METHOD *meth = EC_GROUP_method_of(src->group); 154160814Ssimon /* clear the old group */ 155160814Ssimon if (dest->group) 156160814Ssimon EC_GROUP_free(dest->group); 157160814Ssimon dest->group = EC_GROUP_new(meth); 158160814Ssimon if (dest->group == NULL) 159160814Ssimon return NULL; 160160814Ssimon if (!EC_GROUP_copy(dest->group, src->group)) 161160814Ssimon return NULL; 162160814Ssimon } 163160814Ssimon /* copy the public key */ 164160814Ssimon if (src->pub_key && src->group) 165160814Ssimon { 166160814Ssimon if (dest->pub_key) 167160814Ssimon EC_POINT_free(dest->pub_key); 168160814Ssimon dest->pub_key = EC_POINT_new(src->group); 169160814Ssimon if (dest->pub_key == NULL) 170160814Ssimon return NULL; 171160814Ssimon if (!EC_POINT_copy(dest->pub_key, src->pub_key)) 172160814Ssimon return NULL; 173160814Ssimon } 174160814Ssimon /* copy the private key */ 175160814Ssimon if (src->priv_key) 176160814Ssimon { 177160814Ssimon if (dest->priv_key == NULL) 178160814Ssimon { 179160814Ssimon dest->priv_key = BN_new(); 180160814Ssimon if (dest->priv_key == NULL) 181160814Ssimon return NULL; 182160814Ssimon } 183160814Ssimon if (!BN_copy(dest->priv_key, src->priv_key)) 184160814Ssimon return NULL; 185160814Ssimon } 186160814Ssimon /* copy method/extra data */ 187160814Ssimon EC_EX_DATA_free_all_data(&dest->method_data); 188160814Ssimon 189160814Ssimon for (d = src->method_data; d != NULL; d = d->next) 190160814Ssimon { 191160814Ssimon void *t = d->dup_func(d->data); 192160814Ssimon 193160814Ssimon if (t == NULL) 194160814Ssimon return 0; 195160814Ssimon if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func)) 196160814Ssimon return 0; 197160814Ssimon } 198160814Ssimon 199160814Ssimon /* copy the rest */ 200160814Ssimon dest->enc_flag = src->enc_flag; 201160814Ssimon dest->conv_form = src->conv_form; 202160814Ssimon dest->version = src->version; 203238405Sjkim dest->flags = src->flags; 204160814Ssimon 205160814Ssimon return dest; 206160814Ssimon } 207160814Ssimon 208160814SsimonEC_KEY *EC_KEY_dup(const EC_KEY *ec_key) 209160814Ssimon { 210160814Ssimon EC_KEY *ret = EC_KEY_new(); 211160814Ssimon if (ret == NULL) 212160814Ssimon return NULL; 213160814Ssimon if (EC_KEY_copy(ret, ec_key) == NULL) 214160814Ssimon { 215160814Ssimon EC_KEY_free(ret); 216160814Ssimon return NULL; 217160814Ssimon } 218160814Ssimon return ret; 219160814Ssimon } 220160814Ssimon 221160814Ssimonint EC_KEY_up_ref(EC_KEY *r) 222160814Ssimon { 223160814Ssimon int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); 224160814Ssimon#ifdef REF_PRINT 225160814Ssimon REF_PRINT("EC_KEY",r); 226160814Ssimon#endif 227160814Ssimon#ifdef REF_CHECK 228160814Ssimon if (i < 2) 229160814Ssimon { 230160814Ssimon fprintf(stderr, "EC_KEY_up, bad reference count\n"); 231160814Ssimon abort(); 232160814Ssimon } 233160814Ssimon#endif 234160814Ssimon return ((i > 1) ? 1 : 0); 235160814Ssimon } 236160814Ssimon 237160814Ssimonint EC_KEY_generate_key(EC_KEY *eckey) 238160814Ssimon { 239160814Ssimon int ok = 0; 240160814Ssimon BN_CTX *ctx = NULL; 241160814Ssimon BIGNUM *priv_key = NULL, *order = NULL; 242160814Ssimon EC_POINT *pub_key = NULL; 243160814Ssimon 244238405Sjkim#ifdef OPENSSL_FIPS 245238405Sjkim if (FIPS_mode()) 246238405Sjkim return FIPS_ec_key_generate_key(eckey); 247238405Sjkim#endif 248238405Sjkim 249160814Ssimon if (!eckey || !eckey->group) 250160814Ssimon { 251160814Ssimon ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); 252160814Ssimon return 0; 253160814Ssimon } 254160814Ssimon 255160814Ssimon if ((order = BN_new()) == NULL) goto err; 256160814Ssimon if ((ctx = BN_CTX_new()) == NULL) goto err; 257160814Ssimon 258160814Ssimon if (eckey->priv_key == NULL) 259160814Ssimon { 260160814Ssimon priv_key = BN_new(); 261160814Ssimon if (priv_key == NULL) 262160814Ssimon goto err; 263160814Ssimon } 264160814Ssimon else 265160814Ssimon priv_key = eckey->priv_key; 266160814Ssimon 267160814Ssimon if (!EC_GROUP_get_order(eckey->group, order, ctx)) 268160814Ssimon goto err; 269160814Ssimon 270160814Ssimon do 271160814Ssimon if (!BN_rand_range(priv_key, order)) 272160814Ssimon goto err; 273160814Ssimon while (BN_is_zero(priv_key)); 274160814Ssimon 275160814Ssimon if (eckey->pub_key == NULL) 276160814Ssimon { 277160814Ssimon pub_key = EC_POINT_new(eckey->group); 278160814Ssimon if (pub_key == NULL) 279160814Ssimon goto err; 280160814Ssimon } 281160814Ssimon else 282160814Ssimon pub_key = eckey->pub_key; 283160814Ssimon 284160814Ssimon if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) 285160814Ssimon goto err; 286160814Ssimon 287160814Ssimon eckey->priv_key = priv_key; 288160814Ssimon eckey->pub_key = pub_key; 289160814Ssimon 290160814Ssimon ok=1; 291160814Ssimon 292160814Ssimonerr: 293160814Ssimon if (order) 294160814Ssimon BN_free(order); 295160814Ssimon if (pub_key != NULL && eckey->pub_key == NULL) 296160814Ssimon EC_POINT_free(pub_key); 297160814Ssimon if (priv_key != NULL && eckey->priv_key == NULL) 298160814Ssimon BN_free(priv_key); 299160814Ssimon if (ctx != NULL) 300160814Ssimon BN_CTX_free(ctx); 301160814Ssimon return(ok); 302160814Ssimon } 303160814Ssimon 304160814Ssimonint EC_KEY_check_key(const EC_KEY *eckey) 305160814Ssimon { 306160814Ssimon int ok = 0; 307160814Ssimon BN_CTX *ctx = NULL; 308194206Ssimon const BIGNUM *order = NULL; 309160814Ssimon EC_POINT *point = NULL; 310160814Ssimon 311160814Ssimon if (!eckey || !eckey->group || !eckey->pub_key) 312160814Ssimon { 313160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); 314160814Ssimon return 0; 315160814Ssimon } 316237657Sjkim 317237657Sjkim if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) 318237657Sjkim { 319237657Sjkim ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); 320237657Sjkim goto err; 321237657Sjkim } 322237657Sjkim 323160814Ssimon if ((ctx = BN_CTX_new()) == NULL) 324160814Ssimon goto err; 325160814Ssimon if ((point = EC_POINT_new(eckey->group)) == NULL) 326160814Ssimon goto err; 327160814Ssimon 328160814Ssimon /* testing whether the pub_key is on the elliptic curve */ 329160814Ssimon if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) 330160814Ssimon { 331160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); 332160814Ssimon goto err; 333160814Ssimon } 334160814Ssimon /* testing whether pub_key * order is the point at infinity */ 335194206Ssimon order = &eckey->group->order; 336194206Ssimon if (BN_is_zero(order)) 337160814Ssimon { 338160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); 339160814Ssimon goto err; 340160814Ssimon } 341194206Ssimon if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) 342160814Ssimon { 343160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); 344160814Ssimon goto err; 345160814Ssimon } 346160814Ssimon if (!EC_POINT_is_at_infinity(eckey->group, point)) 347160814Ssimon { 348160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); 349160814Ssimon goto err; 350160814Ssimon } 351160814Ssimon /* in case the priv_key is present : 352160814Ssimon * check if generator * priv_key == pub_key 353160814Ssimon */ 354160814Ssimon if (eckey->priv_key) 355160814Ssimon { 356160814Ssimon if (BN_cmp(eckey->priv_key, order) >= 0) 357160814Ssimon { 358160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); 359160814Ssimon goto err; 360160814Ssimon } 361160814Ssimon if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, 362160814Ssimon NULL, NULL, ctx)) 363160814Ssimon { 364160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); 365160814Ssimon goto err; 366160814Ssimon } 367160814Ssimon if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 368160814Ssimon ctx) != 0) 369160814Ssimon { 370160814Ssimon ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); 371160814Ssimon goto err; 372160814Ssimon } 373160814Ssimon } 374160814Ssimon ok = 1; 375160814Ssimonerr: 376160814Ssimon if (ctx != NULL) 377160814Ssimon BN_CTX_free(ctx); 378160814Ssimon if (point != NULL) 379160814Ssimon EC_POINT_free(point); 380160814Ssimon return(ok); 381160814Ssimon } 382160814Ssimon 383238405Sjkimint EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) 384238405Sjkim { 385238405Sjkim BN_CTX *ctx = NULL; 386238405Sjkim BIGNUM *tx, *ty; 387238405Sjkim EC_POINT *point = NULL; 388238405Sjkim int ok = 0, tmp_nid, is_char_two = 0; 389238405Sjkim 390238405Sjkim if (!key || !key->group || !x || !y) 391238405Sjkim { 392238405Sjkim ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 393238405Sjkim ERR_R_PASSED_NULL_PARAMETER); 394238405Sjkim return 0; 395238405Sjkim } 396238405Sjkim ctx = BN_CTX_new(); 397238405Sjkim if (!ctx) 398238405Sjkim goto err; 399238405Sjkim 400238405Sjkim point = EC_POINT_new(key->group); 401238405Sjkim 402238405Sjkim if (!point) 403238405Sjkim goto err; 404238405Sjkim 405238405Sjkim tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); 406238405Sjkim 407238405Sjkim if (tmp_nid == NID_X9_62_characteristic_two_field) 408238405Sjkim is_char_two = 1; 409238405Sjkim 410238405Sjkim tx = BN_CTX_get(ctx); 411238405Sjkim ty = BN_CTX_get(ctx); 412238405Sjkim#ifndef OPENSSL_NO_EC2M 413238405Sjkim if (is_char_two) 414238405Sjkim { 415238405Sjkim if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, 416238405Sjkim x, y, ctx)) 417238405Sjkim goto err; 418238405Sjkim if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, 419238405Sjkim tx, ty, ctx)) 420238405Sjkim goto err; 421238405Sjkim } 422238405Sjkim else 423238405Sjkim#endif 424238405Sjkim { 425238405Sjkim if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, 426238405Sjkim x, y, ctx)) 427238405Sjkim goto err; 428238405Sjkim if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, 429238405Sjkim tx, ty, ctx)) 430238405Sjkim goto err; 431238405Sjkim } 432238405Sjkim /* Check if retrieved coordinates match originals: if not values 433238405Sjkim * are out of range. 434238405Sjkim */ 435238405Sjkim if (BN_cmp(x, tx) || BN_cmp(y, ty)) 436238405Sjkim { 437238405Sjkim ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 438238405Sjkim EC_R_COORDINATES_OUT_OF_RANGE); 439238405Sjkim goto err; 440238405Sjkim } 441238405Sjkim 442238405Sjkim if (!EC_KEY_set_public_key(key, point)) 443238405Sjkim goto err; 444238405Sjkim 445238405Sjkim if (EC_KEY_check_key(key) == 0) 446238405Sjkim goto err; 447238405Sjkim 448238405Sjkim ok = 1; 449238405Sjkim 450238405Sjkim err: 451238405Sjkim if (ctx) 452238405Sjkim BN_CTX_free(ctx); 453238405Sjkim if (point) 454238405Sjkim EC_POINT_free(point); 455238405Sjkim return ok; 456238405Sjkim 457238405Sjkim } 458238405Sjkim 459160814Ssimonconst EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) 460160814Ssimon { 461160814Ssimon return key->group; 462160814Ssimon } 463160814Ssimon 464160814Ssimonint EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) 465160814Ssimon { 466160814Ssimon if (key->group != NULL) 467160814Ssimon EC_GROUP_free(key->group); 468160814Ssimon key->group = EC_GROUP_dup(group); 469160814Ssimon return (key->group == NULL) ? 0 : 1; 470160814Ssimon } 471160814Ssimon 472160814Ssimonconst BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) 473160814Ssimon { 474160814Ssimon return key->priv_key; 475160814Ssimon } 476160814Ssimon 477160814Ssimonint EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) 478160814Ssimon { 479160814Ssimon if (key->priv_key) 480160814Ssimon BN_clear_free(key->priv_key); 481160814Ssimon key->priv_key = BN_dup(priv_key); 482160814Ssimon return (key->priv_key == NULL) ? 0 : 1; 483160814Ssimon } 484160814Ssimon 485160814Ssimonconst EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) 486160814Ssimon { 487160814Ssimon return key->pub_key; 488160814Ssimon } 489160814Ssimon 490160814Ssimonint EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) 491160814Ssimon { 492160814Ssimon if (key->pub_key != NULL) 493160814Ssimon EC_POINT_free(key->pub_key); 494160814Ssimon key->pub_key = EC_POINT_dup(pub_key, key->group); 495160814Ssimon return (key->pub_key == NULL) ? 0 : 1; 496160814Ssimon } 497160814Ssimon 498160814Ssimonunsigned int EC_KEY_get_enc_flags(const EC_KEY *key) 499160814Ssimon { 500160814Ssimon return key->enc_flag; 501160814Ssimon } 502160814Ssimon 503160814Ssimonvoid EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) 504160814Ssimon { 505160814Ssimon key->enc_flag = flags; 506160814Ssimon } 507160814Ssimon 508160814Ssimonpoint_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) 509160814Ssimon { 510160814Ssimon return key->conv_form; 511160814Ssimon } 512160814Ssimon 513160814Ssimonvoid EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) 514160814Ssimon { 515160814Ssimon key->conv_form = cform; 516160814Ssimon if (key->group != NULL) 517160814Ssimon EC_GROUP_set_point_conversion_form(key->group, cform); 518160814Ssimon } 519160814Ssimon 520160814Ssimonvoid *EC_KEY_get_key_method_data(EC_KEY *key, 521160814Ssimon void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 522160814Ssimon { 523246772Sjkim void *ret; 524246772Sjkim 525246772Sjkim CRYPTO_r_lock(CRYPTO_LOCK_EC); 526246772Sjkim ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 527246772Sjkim CRYPTO_r_unlock(CRYPTO_LOCK_EC); 528246772Sjkim 529246772Sjkim return ret; 530160814Ssimon } 531160814Ssimon 532246772Sjkimvoid *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, 533160814Ssimon void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 534160814Ssimon { 535160814Ssimon EC_EXTRA_DATA *ex_data; 536246772Sjkim 537160814Ssimon CRYPTO_w_lock(CRYPTO_LOCK_EC); 538160814Ssimon ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 539160814Ssimon if (ex_data == NULL) 540160814Ssimon EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); 541160814Ssimon CRYPTO_w_unlock(CRYPTO_LOCK_EC); 542246772Sjkim 543246772Sjkim return ex_data; 544160814Ssimon } 545160814Ssimon 546160814Ssimonvoid EC_KEY_set_asn1_flag(EC_KEY *key, int flag) 547160814Ssimon { 548160814Ssimon if (key->group != NULL) 549160814Ssimon EC_GROUP_set_asn1_flag(key->group, flag); 550160814Ssimon } 551160814Ssimon 552160814Ssimonint EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) 553160814Ssimon { 554160814Ssimon if (key->group == NULL) 555160814Ssimon return 0; 556160814Ssimon return EC_GROUP_precompute_mult(key->group, ctx); 557160814Ssimon } 558238405Sjkim 559238405Sjkimint EC_KEY_get_flags(const EC_KEY *key) 560238405Sjkim { 561238405Sjkim return key->flags; 562238405Sjkim } 563238405Sjkim 564238405Sjkimvoid EC_KEY_set_flags(EC_KEY *key, int flags) 565238405Sjkim { 566238405Sjkim key->flags |= flags; 567238405Sjkim } 568238405Sjkim 569238405Sjkimvoid EC_KEY_clear_flags(EC_KEY *key, int flags) 570238405Sjkim { 571238405Sjkim key->flags &= ~flags; 572238405Sjkim } 573