ec_lib.c revision 296465
11541Srgrimes/* crypto/ec/ec_lib.c */ 21541Srgrimes/* 31541Srgrimes * Originally written by Bodo Moeller for the OpenSSL project. 41541Srgrimes */ 51541Srgrimes/* ==================================================================== 61541Srgrimes * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 71541Srgrimes * 81541Srgrimes * Redistribution and use in source and binary forms, with or without 91541Srgrimes * modification, are permitted provided that the following conditions 101541Srgrimes * are met: 111541Srgrimes * 121541Srgrimes * 1. Redistributions of source code must retain the above copyright 131541Srgrimes * notice, this list of conditions and the following disclaimer. 141541Srgrimes * 151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161541Srgrimes * notice, this list of conditions and the following disclaimer in 171541Srgrimes * the documentation and/or other materials provided with the 181541Srgrimes * distribution. 191541Srgrimes * 201541Srgrimes * 3. All advertising materials mentioning features or use of this 211541Srgrimes * software must display the following acknowledgment: 221541Srgrimes * "This product includes software developed by the OpenSSL Project 231541Srgrimes * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 241541Srgrimes * 251541Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 261541Srgrimes * endorse or promote products derived from this software without 271541Srgrimes * prior written permission. For written permission, please contact 281541Srgrimes * openssl-core@openssl.org. 291541Srgrimes * 301541Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 311541Srgrimes * nor may "OpenSSL" appear in their names without prior written 321541Srgrimes * permission of the OpenSSL Project. 331541Srgrimes * 341541Srgrimes * 6. Redistributions of any form whatsoever must retain the following 351541Srgrimes * acknowledgment: 3622521Sdyson * "This product includes software developed by the OpenSSL Project 3732011Sbde * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 381541Srgrimes * 391541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4022521Sdyson * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 411541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 429336Sdfr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 431541Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 441541Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 451541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 461541Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 471541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 489336Sdfr * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 499336Sdfr * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 501541Srgrimes * OF THE POSSIBILITY OF SUCH DAMAGE. 511541Srgrimes * ==================================================================== 521541Srgrimes * 531541Srgrimes * This product includes cryptographic software written by Eric Young 541541Srgrimes * (eay@cryptsoft.com). This product includes software written by Tim 551541Srgrimes * Hudson (tjh@cryptsoft.com). 561541Srgrimes * 579336Sdfr */ 581960Sdg/* ==================================================================== 591541Srgrimes * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 601541Srgrimes * Binary polynomial ECC support in OpenSSL originally developed by 6112662Sdg * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 6232011Sbde */ 631541Srgrimes 6429363Speter#include <string.h> 651541Srgrimes 661541Srgrimes#include <openssl/err.h> 671541Srgrimes#include <openssl/opensslv.h> 689336Sdfr 691541Srgrimes#include "ec_lcl.h" 701541Srgrimes 711541Srgrimesstatic const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; 721541Srgrimes 731541Srgrimes/* functions for EC_GROUP objects */ 741541Srgrimes 751541SrgrimesEC_GROUP *EC_GROUP_new(const EC_METHOD *meth) 769336Sdfr{ 779336Sdfr EC_GROUP *ret; 789336Sdfr 799336Sdfr if (meth == NULL) { 801541Srgrimes ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER); 811541Srgrimes return NULL; 821541Srgrimes } 831541Srgrimes if (meth->group_init == 0) { 841541Srgrimes ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 859336Sdfr return NULL; 869336Sdfr } 879336Sdfr 889336Sdfr ret = OPENSSL_malloc(sizeof *ret); 899336Sdfr if (ret == NULL) { 909336Sdfr ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); 919336Sdfr return NULL; 929336Sdfr } 9311921Sphk 9411921Sphk ret->meth = meth; 9511921Sphk 9611921Sphk ret->extra_data = NULL; 9711921Sphk 9811921Sphk ret->generator = NULL; 9929363Speter BN_init(&ret->order); 10011921Sphk BN_init(&ret->cofactor); 10111921Sphk 10230118Sphk ret->curve_name = 0; 10311921Sphk ret->asn1_flag = 0; 10411921Sphk ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; 10511921Sphk 10611921Sphk ret->seed = NULL; 10711921Sphk ret->seed_len = 0; 10811921Sphk 10911921Sphk if (!meth->group_init(ret)) { 11011921Sphk OPENSSL_free(ret); 11111921Sphk return NULL; 11211921Sphk } 11311921Sphk 11411921Sphk return ret; 11511921Sphk} 11611921Sphk 11711921Sphkvoid EC_GROUP_free(EC_GROUP *group) 11811921Sphk{ 11911921Sphk if (!group) 12011921Sphk return; 12111921Sphk 12211921Sphk if (group->meth->group_finish != 0) 12311921Sphk group->meth->group_finish(group); 12411921Sphk 12511921Sphk EC_EX_DATA_free_all_data(&group->extra_data); 12611921Sphk 12711921Sphk if (group->generator != NULL) 12811921Sphk EC_POINT_free(group->generator); 1299336Sdfr BN_free(&group->order); 1301541Srgrimes BN_free(&group->cofactor); 1311541Srgrimes 13212158Sbde if (group->seed) 13311921Sphk OPENSSL_free(group->seed); 13430743Sphk 13530431Sphk OPENSSL_free(group); 13630431Sphk} 13730431Sphk 13830431Sphkvoid EC_GROUP_clear_free(EC_GROUP *group) 13930431Sphk{ 14030431Sphk if (!group) 14130431Sphk return; 14230431Sphk 14330431Sphk if (group->meth->group_clear_finish != 0) 14430434Sphk group->meth->group_clear_finish(group); 14530434Sphk else if (group->meth->group_finish != 0) 14630743Sphk group->meth->group_finish(group); 14730431Sphk 14830474Sphk EC_EX_DATA_clear_free_all_data(&group->extra_data); 14930431Sphk 15030431Sphk if (group->generator != NULL) 15130431Sphk EC_POINT_clear_free(group->generator); 15230431Sphk BN_clear_free(&group->order); 15330431Sphk BN_clear_free(&group->cofactor); 15430431Sphk 15530431Sphk if (group->seed) { 15630431Sphk OPENSSL_cleanse(group->seed, group->seed_len); 15730431Sphk OPENSSL_free(group->seed); 15830434Sphk } 15930431Sphk 16030431Sphk OPENSSL_cleanse(group, sizeof *group); 16130431Sphk OPENSSL_free(group); 16230431Sphk} 16330431Sphk 16430434Sphkint EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) 16530431Sphk{ 16630431Sphk EC_EXTRA_DATA *d; 16712158Sbde 1681541Srgrimes if (dest->meth->group_copy == 0) { 16911921Sphk ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1701541Srgrimes return 0; 1712946Swollman } 1721541Srgrimes if (dest->meth != src->meth) { 1731541Srgrimes ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); 1741541Srgrimes return 0; 1751541Srgrimes } 17612158Sbde if (dest == src) 17730496Sphk return 1; 17830439Sphk 17930431Sphk EC_EX_DATA_free_all_data(&dest->extra_data); 18030431Sphk 18130431Sphk for (d = src->extra_data; d != NULL; d = d->next) { 18230431Sphk void *t = d->dup_func(d->data); 18330434Sphk 18430474Sphk if (t == NULL) 18530431Sphk return 0; 18630431Sphk if (!EC_EX_DATA_set_data 18730431Sphk (&dest->extra_data, t, d->dup_func, d->free_func, 18830431Sphk d->clear_free_func)) 18930431Sphk return 0; 19012158Sbde } 1911541Srgrimes 19211921Sphk if (src->generator != NULL) { 19330496Sphk if (dest->generator == NULL) { 1942946Swollman dest->generator = EC_POINT_new(dest); 1951541Srgrimes if (dest->generator == NULL) 19612158Sbde return 0; 19730496Sphk } 19830439Sphk if (!EC_POINT_copy(dest->generator, src->generator)) 19930431Sphk return 0; 20030431Sphk } else { 20130431Sphk /* src->generator == NULL */ 20230431Sphk if (dest->generator != NULL) { 20330434Sphk EC_POINT_clear_free(dest->generator); 20430474Sphk dest->generator = NULL; 20530431Sphk } 20630431Sphk } 20730431Sphk 20830431Sphk if (!BN_copy(&dest->order, &src->order)) 20930431Sphk return 0; 21012158Sbde if (!BN_copy(&dest->cofactor, &src->cofactor)) 2111541Srgrimes return 0; 21211921Sphk 21330496Sphk dest->curve_name = src->curve_name; 2142946Swollman dest->asn1_flag = src->asn1_flag; 2151541Srgrimes dest->asn1_form = src->asn1_form; 21612457Sbde 21712457Sbde if (src->seed) { 21812457Sbde if (dest->seed) 21912457Sbde OPENSSL_free(dest->seed); 22012457Sbde dest->seed = OPENSSL_malloc(src->seed_len); 22112457Sbde if (dest->seed == NULL) 22212457Sbde return 0; 22312457Sbde if (!memcpy(dest->seed, src->seed, src->seed_len)) 22412457Sbde return 0; 22512457Sbde dest->seed_len = src->seed_len; 22612457Sbde } else { 22712457Sbde if (dest->seed) 22812457Sbde OPENSSL_free(dest->seed); 22912457Sbde dest->seed = NULL; 2301541Srgrimes dest->seed_len = 0; 2311541Srgrimes } 2321541Srgrimes 2331541Srgrimes return dest->meth->group_copy(dest, src); 2349336Sdfr} 2359336Sdfr 2369336SdfrEC_GROUP *EC_GROUP_dup(const EC_GROUP *a) 2371541Srgrimes{ 23819449Sdfr EC_GROUP *t = NULL; 2391541Srgrimes int ok = 0; 2401541Srgrimes 2411541Srgrimes if (a == NULL) 2421541Srgrimes return NULL; 2431541Srgrimes 2449336Sdfr if ((t = EC_GROUP_new(a->meth)) == NULL) 2459336Sdfr return (NULL); 2469336Sdfr if (!EC_GROUP_copy(t, a)) 2471541Srgrimes goto err; 24811921Sphk 2491541Srgrimes ok = 1; 2501541Srgrimes 2511541Srgrimes err: 2521541Srgrimes if (!ok) { 2531541Srgrimes if (t) 2541541Srgrimes EC_GROUP_free(t); 2551541Srgrimes return NULL; 2561541Srgrimes } else 2571541Srgrimes return t; 2581541Srgrimes} 2591541Srgrimes 2609336Sdfrconst EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) 2619336Sdfr{ 2629336Sdfr return group->meth; 2631541Srgrimes} 2649336Sdfr 2659336Sdfrint EC_METHOD_get_field_type(const EC_METHOD *meth) 2661541Srgrimes{ 2671541Srgrimes return meth->field_type; 26811644Sdg} 26911644Sdg 27011644Sdgint EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 27111644Sdg const BIGNUM *order, const BIGNUM *cofactor) 27211644Sdg{ 27311644Sdg if (generator == NULL) { 27411644Sdg ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); 27511644Sdg return 0; 27611644Sdg } 27711644Sdg 27811644Sdg if (group->generator == NULL) { 2799336Sdfr group->generator = EC_POINT_new(group); 2801541Srgrimes if (group->generator == NULL) 2811541Srgrimes return 0; 2821541Srgrimes } 2831541Srgrimes if (!EC_POINT_copy(group->generator, generator)) 2841541Srgrimes return 0; 2851541Srgrimes 2869336Sdfr if (order != NULL) { 2879336Sdfr if (!BN_copy(&group->order, order)) 2889336Sdfr return 0; 2899336Sdfr } else 2909336Sdfr BN_zero(&group->order); 2911541Srgrimes 2929336Sdfr if (cofactor != NULL) { 2931541Srgrimes if (!BN_copy(&group->cofactor, cofactor)) 2949336Sdfr return 0; 2959336Sdfr } else 2969336Sdfr BN_zero(&group->cofactor); 2979336Sdfr 2989336Sdfr return 1; 2999336Sdfr} 3009336Sdfr 3019336Sdfrconst EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) 3029336Sdfr{ 3039336Sdfr return group->generator; 3049336Sdfr} 3059336Sdfr 3069336Sdfrint EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) 3079336Sdfr{ 3089336Sdfr if (!BN_copy(order, &group->order)) 3099336Sdfr return 0; 3109336Sdfr 3119336Sdfr return !BN_is_zero(order); 3129336Sdfr} 3139336Sdfr 3149336Sdfrint EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 3159336Sdfr BN_CTX *ctx) 3169336Sdfr{ 3179336Sdfr if (!BN_copy(cofactor, &group->cofactor)) 3189336Sdfr return 0; 3199336Sdfr 3209336Sdfr return !BN_is_zero(&group->cofactor); 3211541Srgrimes} 3221541Srgrimes 32325611Sdfrvoid EC_GROUP_set_curve_name(EC_GROUP *group, int nid) 32425611Sdfr{ 32525611Sdfr group->curve_name = nid; 32625611Sdfr} 32725611Sdfr 32825611Sdfrint EC_GROUP_get_curve_name(const EC_GROUP *group) 32925611Sdfr{ 33025611Sdfr return group->curve_name; 33125611Sdfr} 33225611Sdfr 33325611Sdfrvoid EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) 33425611Sdfr{ 33525611Sdfr group->asn1_flag = flag; 33625611Sdfr} 33725611Sdfr 33825611Sdfrint EC_GROUP_get_asn1_flag(const EC_GROUP *group) 33925611Sdfr{ 34025611Sdfr return group->asn1_flag; 34125611Sdfr} 34225611Sdfr 34325611Sdfrvoid EC_GROUP_set_point_conversion_form(EC_GROUP *group, 34425611Sdfr point_conversion_form_t form) 34525611Sdfr{ 34625611Sdfr group->asn1_form = form; 34725611Sdfr} 34825611Sdfr 34925611Sdfrpoint_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP 35025611Sdfr *group) 35125611Sdfr{ 35225611Sdfr return group->asn1_form; 35331017Sphk} 35431017Sphk 35531017Sphksize_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) 35625611Sdfr{ 35725611Sdfr if (group->seed) { 35831017Sphk OPENSSL_free(group->seed); 35925611Sdfr group->seed = NULL; 36025611Sdfr group->seed_len = 0; 36125611Sdfr } 36225611Sdfr 36325611Sdfr if (!len || !p) 36425611Sdfr return 1; 36525611Sdfr 3661541Srgrimes if ((group->seed = OPENSSL_malloc(len)) == NULL) 3671541Srgrimes return 0; 3681541Srgrimes memcpy(group->seed, p, len); 3691541Srgrimes group->seed_len = len; 3701541Srgrimes 3711541Srgrimes return len; 3721541Srgrimes} 3731541Srgrimes 3741541Srgrimesunsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) 3751541Srgrimes{ 37611921Sphk return group->seed; 3771541Srgrimes} 3781541Srgrimes 3791541Srgrimessize_t EC_GROUP_get_seed_len(const EC_GROUP *group) 3801541Srgrimes{ 3811541Srgrimes return group->seed_len; 3821541Srgrimes} 3831541Srgrimes 3841541Srgrimesint EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 3851541Srgrimes const BIGNUM *b, BN_CTX *ctx) 3861541Srgrimes{ 3871541Srgrimes if (group->meth->group_set_curve == 0) { 3881541Srgrimes ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 3891541Srgrimes return 0; 3901541Srgrimes } 3911541Srgrimes return group->meth->group_set_curve(group, p, a, b, ctx); 3929336Sdfr} 3931541Srgrimes 3949336Sdfrint EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 3952384Sdg BIGNUM *b, BN_CTX *ctx) 3962384Sdg{ 3972384Sdg if (group->meth->group_get_curve == 0) { 3982384Sdg ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 3999336Sdfr return 0; 4001541Srgrimes } 4019336Sdfr return group->meth->group_get_curve(group, p, a, b, ctx); 4029336Sdfr} 4031541Srgrimes 4041541Srgrimesint EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 4051541Srgrimes const BIGNUM *b, BN_CTX *ctx) 4061541Srgrimes{ 4071541Srgrimes if (group->meth->group_set_curve == 0) { 4081541Srgrimes ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, 4091541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 4101541Srgrimes return 0; 41122521Sdyson } 4121541Srgrimes return group->meth->group_set_curve(group, p, a, b, ctx); 4131541Srgrimes} 4141541Srgrimes 4152384Sdgint EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 4161541Srgrimes BIGNUM *b, BN_CTX *ctx) 4171541Srgrimes{ 4181541Srgrimes if (group->meth->group_get_curve == 0) { 4191541Srgrimes ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, 4201541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 4219336Sdfr return 0; 4229336Sdfr } 4233305Sphk return group->meth->group_get_curve(group, p, a, b, ctx); 4243305Sphk} 4251541Srgrimes 42618397Snateint EC_GROUP_get_degree(const EC_GROUP *group) 4271541Srgrimes{ 4283305Sphk if (group->meth->group_get_degree == 0) { 4293305Sphk ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 4301541Srgrimes return 0; 43118397Snate } 4329336Sdfr return group->meth->group_get_degree(group); 4339336Sdfr} 4341541Srgrimes 4351541Srgrimesint EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 4361541Srgrimes{ 43718397Snate if (group->meth->group_check_discriminant == 0) { 4381541Srgrimes ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, 4391541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 4402384Sdg return 0; 4412384Sdg } 4421541Srgrimes return group->meth->group_check_discriminant(group, ctx); 4431541Srgrimes} 4441541Srgrimes 4451541Srgrimesint EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) 4461541Srgrimes{ 4471541Srgrimes int r = 0; 4489336Sdfr BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; 4499336Sdfr BN_CTX *ctx_new = NULL; 4509336Sdfr 4519336Sdfr /* compare the field types */ 4529336Sdfr if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != 4539336Sdfr EC_METHOD_get_field_type(EC_GROUP_method_of(b))) 4549336Sdfr return 1; 4559336Sdfr /* compare the curve name (if present in both) */ 4569336Sdfr if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && 4579336Sdfr EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) 4589336Sdfr return 1; 4599336Sdfr 4609336Sdfr if (!ctx) 4619336Sdfr ctx_new = ctx = BN_CTX_new(); 4629336Sdfr if (!ctx) 4639336Sdfr return -1; 4649336Sdfr 4659336Sdfr BN_CTX_start(ctx); 4669336Sdfr a1 = BN_CTX_get(ctx); 4679336Sdfr a2 = BN_CTX_get(ctx); 4689336Sdfr a3 = BN_CTX_get(ctx); 4699336Sdfr b1 = BN_CTX_get(ctx); 4709336Sdfr b2 = BN_CTX_get(ctx); 4719336Sdfr b3 = BN_CTX_get(ctx); 4729336Sdfr if (!b3) { 4739336Sdfr BN_CTX_end(ctx); 4749336Sdfr if (ctx_new) 4751541Srgrimes BN_CTX_free(ctx); 4761541Srgrimes return -1; 47711921Sphk } 4781541Srgrimes 4791541Srgrimes /* 4801541Srgrimes * XXX This approach assumes that the external representation of curves 4811541Srgrimes * over the same field type is the same. 4821541Srgrimes */ 4831541Srgrimes if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || 4841541Srgrimes !b->meth->group_get_curve(b, b1, b2, b3, ctx)) 4851541Srgrimes r = 1; 4861541Srgrimes 4871541Srgrimes if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) 4881541Srgrimes r = 1; 4891541Srgrimes 4901541Srgrimes /* XXX EC_POINT_cmp() assumes that the methods are equal */ 4911541Srgrimes if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), 4921541Srgrimes EC_GROUP_get0_generator(b), ctx)) 4931541Srgrimes r = 1; 4949522Sdfr 4959336Sdfr if (!r) { 4969522Sdfr /* compare the order and cofactor */ 4979522Sdfr if (!EC_GROUP_get_order(a, a1, ctx) || 4989336Sdfr !EC_GROUP_get_order(b, b1, ctx) || 4991541Srgrimes !EC_GROUP_get_cofactor(a, a2, ctx) || 5001541Srgrimes !EC_GROUP_get_cofactor(b, b2, ctx)) { 5011541Srgrimes BN_CTX_end(ctx); 5021541Srgrimes if (ctx_new) 5031541Srgrimes BN_CTX_free(ctx); 5041541Srgrimes return -1; 5051541Srgrimes } 5061541Srgrimes if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) 5071541Srgrimes r = 1; 5081541Srgrimes } 5091541Srgrimes 5101541Srgrimes BN_CTX_end(ctx); 5111541Srgrimes if (ctx_new) 51211921Sphk BN_CTX_free(ctx); 5131541Srgrimes 5141541Srgrimes return r; 5151541Srgrimes} 5161541Srgrimes 5171541Srgrimes/* this has 'package' visibility */ 5181541Srgrimesint EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data, 5191541Srgrimes void *(*dup_func) (void *), 5201541Srgrimes void (*free_func) (void *), 5211541Srgrimes void (*clear_free_func) (void *)) 5221541Srgrimes{ 5231541Srgrimes EC_EXTRA_DATA *d; 5249336Sdfr 5259336Sdfr if (ex_data == NULL) 5261541Srgrimes return 0; 5271541Srgrimes 5281541Srgrimes for (d = *ex_data; d != NULL; d = d->next) { 5299336Sdfr if (d->dup_func == dup_func && d->free_func == free_func 53022521Sdyson && d->clear_free_func == clear_free_func) { 5311541Srgrimes ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); 5321541Srgrimes return 0; 5331541Srgrimes } 5341541Srgrimes } 5351541Srgrimes 5361541Srgrimes if (data == NULL) 5371541Srgrimes /* no explicit entry needed */ 5381541Srgrimes return 1; 5391541Srgrimes 5401541Srgrimes d = OPENSSL_malloc(sizeof *d); 5411541Srgrimes if (d == NULL) 5429336Sdfr return 0; 5439336Sdfr 5441541Srgrimes d->data = data; 5459336Sdfr d->dup_func = dup_func; 5469336Sdfr d->free_func = free_func; 5471541Srgrimes d->clear_free_func = clear_free_func; 5481541Srgrimes 5491541Srgrimes d->next = *ex_data; 5501541Srgrimes *ex_data = d; 5511541Srgrimes 5521541Srgrimes return 1; 5531541Srgrimes} 55411921Sphk 5551541Srgrimes/* this has 'package' visibility */ 5561541Srgrimesvoid *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data, 5571541Srgrimes void *(*dup_func) (void *), 5581541Srgrimes void (*free_func) (void *), 5591541Srgrimes void (*clear_free_func) (void *)) 5601541Srgrimes{ 5611541Srgrimes const EC_EXTRA_DATA *d; 5621541Srgrimes 5631541Srgrimes for (d = ex_data; d != NULL; d = d->next) { 5641541Srgrimes if (d->dup_func == dup_func && d->free_func == free_func 5651541Srgrimes && d->clear_free_func == clear_free_func) 5661541Srgrimes return d->data; 5679336Sdfr } 5689336Sdfr 5691541Srgrimes return NULL; 5709336Sdfr} 5719336Sdfr 5729336Sdfr/* this has 'package' visibility */ 57311644Sdgvoid EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data, 57411644Sdg void *(*dup_func) (void *), 57511644Sdg void (*free_func) (void *), 57622521Sdyson void (*clear_free_func) (void *)) 57718397Snate{ 57818397Snate EC_EXTRA_DATA **p; 57911644Sdg 58011644Sdg if (ex_data == NULL) 5813664Sphk return; 5829336Sdfr 5839336Sdfr for (p = ex_data; *p != NULL; p = &((*p)->next)) { 5849336Sdfr if ((*p)->dup_func == dup_func && (*p)->free_func == free_func 5859336Sdfr && (*p)->clear_free_func == clear_free_func) { 5869336Sdfr EC_EXTRA_DATA *next = (*p)->next; 58722521Sdyson 58822521Sdyson (*p)->free_func((*p)->data); 58918397Snate OPENSSL_free(*p); 59018397Snate 5913664Sphk *p = next; 5929336Sdfr return; 5939336Sdfr } 5943664Sphk } 5959336Sdfr} 5969336Sdfr 5979336Sdfr/* this has 'package' visibility */ 59811644Sdgvoid EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data, 59911644Sdg void *(*dup_func) (void *), 60011644Sdg void (*free_func) (void *), 60111644Sdg void (*clear_free_func) (void *)) 60211644Sdg{ 60311644Sdg EC_EXTRA_DATA **p; 60422521Sdyson 60522521Sdyson if (ex_data == NULL) 6069336Sdfr return; 6079336Sdfr 60822521Sdyson for (p = ex_data; *p != NULL; p = &((*p)->next)) { 6099336Sdfr if ((*p)->dup_func == dup_func && (*p)->free_func == free_func 6109336Sdfr && (*p)->clear_free_func == clear_free_func) { 61122521Sdyson EC_EXTRA_DATA *next = (*p)->next; 6129336Sdfr 61322521Sdyson (*p)->clear_free_func((*p)->data); 6149336Sdfr OPENSSL_free(*p); 6159336Sdfr 6169336Sdfr *p = next; 6179336Sdfr return; 61818397Snate } 61922521Sdyson } 6209336Sdfr} 6219336Sdfr 6229336Sdfr/* this has 'package' visibility */ 6239336Sdfrvoid EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data) 6249336Sdfr{ 6259681Sdfr EC_EXTRA_DATA *d; 6269681Sdfr 6279336Sdfr if (ex_data == NULL) 6289336Sdfr return; 6299336Sdfr 6309336Sdfr d = *ex_data; 6319336Sdfr while (d) { 6329336Sdfr EC_EXTRA_DATA *next = d->next; 6339336Sdfr 6349336Sdfr d->free_func(d->data); 63511921Sphk OPENSSL_free(d); 6369336Sdfr 6379336Sdfr d = next; 6389336Sdfr } 6399336Sdfr *ex_data = NULL; 6409336Sdfr} 6419336Sdfr 6429336Sdfr/* this has 'package' visibility */ 6439336Sdfrvoid EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data) 6449336Sdfr{ 6459336Sdfr EC_EXTRA_DATA *d; 6469336Sdfr 6479336Sdfr if (ex_data == NULL) 6489336Sdfr return; 6499336Sdfr 6509336Sdfr d = *ex_data; 6519336Sdfr while (d) { 6529336Sdfr EC_EXTRA_DATA *next = d->next; 6539336Sdfr 6549336Sdfr d->clear_free_func(d->data); 6559336Sdfr OPENSSL_free(d); 6569336Sdfr 6579336Sdfr d = next; 6589336Sdfr } 6599336Sdfr *ex_data = NULL; 6609336Sdfr} 6619336Sdfr 6629336Sdfr/* functions for EC_POINT objects */ 6639336Sdfr 6649336SdfrEC_POINT *EC_POINT_new(const EC_GROUP *group) 6659336Sdfr{ 6669336Sdfr EC_POINT *ret; 6679336Sdfr 6689336Sdfr if (group == NULL) { 6699336Sdfr ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); 6709336Sdfr return NULL; 6719336Sdfr } 6729336Sdfr if (group->meth->point_init == 0) { 6739336Sdfr ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 6749336Sdfr return NULL; 6759336Sdfr } 6769336Sdfr 6779336Sdfr ret = OPENSSL_malloc(sizeof *ret); 6789336Sdfr if (ret == NULL) { 6799336Sdfr ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); 6809336Sdfr return NULL; 6819336Sdfr } 6829336Sdfr 6839336Sdfr ret->meth = group->meth; 6849336Sdfr 6859336Sdfr if (!ret->meth->point_init(ret)) { 6869336Sdfr OPENSSL_free(ret); 68718397Snate return NULL; 68818397Snate } 6899336Sdfr 6909336Sdfr return ret; 6919336Sdfr} 6929336Sdfr 6939336Sdfrvoid EC_POINT_free(EC_POINT *point) 6949336Sdfr{ 6951541Srgrimes if (!point) 6969336Sdfr return; 6979336Sdfr 6989336Sdfr if (point->meth->point_finish != 0) 6993664Sphk point->meth->point_finish(point); 70018397Snate OPENSSL_free(point); 70118397Snate} 7029336Sdfr 7039336Sdfrvoid EC_POINT_clear_free(EC_POINT *point) 70417186Sdfr{ 7059336Sdfr if (!point) 7069336Sdfr return; 7079336Sdfr 7089336Sdfr if (point->meth->point_clear_finish != 0) 7099336Sdfr point->meth->point_clear_finish(point); 7109336Sdfr else if (point->meth != NULL && point->meth->point_finish != 0) 7119336Sdfr point->meth->point_finish(point); 7129336Sdfr OPENSSL_cleanse(point, sizeof *point); 7139336Sdfr OPENSSL_free(point); 7149336Sdfr} 7151541Srgrimes 7169336Sdfrint EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) 7179336Sdfr{ 7189336Sdfr if (dest->meth->point_copy == 0) { 7199336Sdfr ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 7209336Sdfr return 0; 7219336Sdfr } 7229336Sdfr if (dest->meth != src->meth) { 7239336Sdfr ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); 7249336Sdfr return 0; 7259336Sdfr } 7269336Sdfr if (dest == src) 7279336Sdfr return 1; 7289336Sdfr return dest->meth->point_copy(dest, src); 7299336Sdfr} 7309336Sdfr 7319336SdfrEC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) 7321541Srgrimes{ 7339336Sdfr EC_POINT *t; 7349336Sdfr int r; 7359336Sdfr 7369336Sdfr if (a == NULL) 7379336Sdfr return NULL; 7381541Srgrimes 7391541Srgrimes t = EC_POINT_new(group); 7401541Srgrimes if (t == NULL) 7411541Srgrimes return (NULL); 7421541Srgrimes r = EC_POINT_copy(t, a); 7431541Srgrimes if (!r) { 74430118Sphk EC_POINT_free(t); 74530118Sphk return NULL; 7461541Srgrimes } else 74711921Sphk return t; 7481541Srgrimes} 74930118Sphk 7501541Srgrimesconst EC_METHOD *EC_POINT_method_of(const EC_POINT *point) 7511541Srgrimes{ 7521541Srgrimes return point->meth; 7531541Srgrimes} 7541541Srgrimes 7551541Srgrimesint EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 7561541Srgrimes{ 7571541Srgrimes if (group->meth->point_set_to_infinity == 0) { 7581541Srgrimes ECerr(EC_F_EC_POINT_SET_TO_INFINITY, 7591541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 7609336Sdfr return 0; 7611541Srgrimes } 7621541Srgrimes if (group->meth != point->meth) { 7631541Srgrimes ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); 7641541Srgrimes return 0; 7651541Srgrimes } 7661541Srgrimes return group->meth->point_set_to_infinity(group, point); 7671541Srgrimes} 7689336Sdfr 7691541Srgrimesint EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, 7709336Sdfr EC_POINT *point, const BIGNUM *x, 7719336Sdfr const BIGNUM *y, const BIGNUM *z, 77222521Sdyson BN_CTX *ctx) 7731541Srgrimes{ 77430118Sphk if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { 77530118Sphk ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 77630118Sphk ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 7779336Sdfr return 0; 77830118Sphk } 77930118Sphk if (group->meth != point->meth) { 7801541Srgrimes ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 7811541Srgrimes EC_R_INCOMPATIBLE_OBJECTS); 7821541Srgrimes return 0; 7831541Srgrimes } 78430118Sphk return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, 78530118Sphk y, z, ctx); 78630118Sphk} 78730118Sphk 78830118Sphkint EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, 78930118Sphk const EC_POINT *point, BIGNUM *x, 79030118Sphk BIGNUM *y, BIGNUM *z, 79130118Sphk BN_CTX *ctx) 79230118Sphk{ 79330118Sphk if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { 79430118Sphk ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 79530118Sphk ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 79630118Sphk return 0; 79730118Sphk } 79830118Sphk if (group->meth != point->meth) { 79930118Sphk ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 80030118Sphk EC_R_INCOMPATIBLE_OBJECTS); 80130118Sphk return 0; 80230118Sphk } 80330118Sphk return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, 80430118Sphk y, z, ctx); 80530118Sphk} 80630118Sphk 80730118Sphkint EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, 80830118Sphk EC_POINT *point, const BIGNUM *x, 80930118Sphk const BIGNUM *y, BN_CTX *ctx) 81030118Sphk{ 81130118Sphk if (group->meth->point_set_affine_coordinates == 0) { 81230118Sphk ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 81330118Sphk ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 81430118Sphk return 0; 81530118Sphk } 81630118Sphk if (group->meth != point->meth) { 81730118Sphk ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 81830118Sphk EC_R_INCOMPATIBLE_OBJECTS); 81930118Sphk return 0; 82030118Sphk } 82130118Sphk return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 82230118Sphk} 82330118Sphk 82430118Sphkint EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, 82530118Sphk EC_POINT *point, const BIGNUM *x, 82630118Sphk const BIGNUM *y, BN_CTX *ctx) 82730118Sphk{ 82830118Sphk if (group->meth->point_set_affine_coordinates == 0) { 82930118Sphk ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 83030118Sphk ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 83130118Sphk return 0; 83230118Sphk } 8331541Srgrimes if (group->meth != point->meth) { 8349336Sdfr ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 8351541Srgrimes EC_R_INCOMPATIBLE_OBJECTS); 8361541Srgrimes return 0; 8371541Srgrimes } 8389336Sdfr return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 8399336Sdfr} 8409336Sdfr 8411541Srgrimesint EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 8421541Srgrimes const EC_POINT *point, BIGNUM *x, 8431541Srgrimes BIGNUM *y, BN_CTX *ctx) 8449336Sdfr{ 8459336Sdfr if (group->meth->point_get_affine_coordinates == 0) { 8469336Sdfr ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 8471541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 8489336Sdfr return 0; 8491541Srgrimes } 8501541Srgrimes if (group->meth != point->meth) { 8511541Srgrimes ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 8521541Srgrimes EC_R_INCOMPATIBLE_OBJECTS); 8531541Srgrimes return 0; 8549336Sdfr } 8551541Srgrimes return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 8561541Srgrimes} 8571541Srgrimes 8589336Sdfrint EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, 8591541Srgrimes const EC_POINT *point, BIGNUM *x, 8601541Srgrimes BIGNUM *y, BN_CTX *ctx) 8611541Srgrimes{ 8621541Srgrimes if (group->meth->point_get_affine_coordinates == 0) { 8639336Sdfr ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 8649336Sdfr ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 8659336Sdfr return 0; 8669336Sdfr } 8679336Sdfr if (group->meth != point->meth) { 8681541Srgrimes ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 8691541Srgrimes EC_R_INCOMPATIBLE_OBJECTS); 8701541Srgrimes return 0; 8719336Sdfr } 87222521Sdyson return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 8731541Srgrimes} 8741541Srgrimes 8751541Srgrimesint EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, 8769336Sdfr EC_POINT *point, const BIGNUM *x, 87722521Sdyson int y_bit, BN_CTX *ctx) 8789336Sdfr{ 8799336Sdfr if (group->meth->point_set_compressed_coordinates == 0) { 88022521Sdyson ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 8819336Sdfr ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 8829336Sdfr return 0; 8839336Sdfr } 8849336Sdfr if (group->meth != point->meth) { 88522521Sdyson ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 8869336Sdfr EC_R_INCOMPATIBLE_OBJECTS); 8879336Sdfr return 0; 8889336Sdfr } 8899336Sdfr return group->meth->point_set_compressed_coordinates(group, point, x, 8901541Srgrimes y_bit, ctx); 8911541Srgrimes} 8921541Srgrimes 8939336Sdfrint EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, 8941541Srgrimes EC_POINT *point, const BIGNUM *x, 8951541Srgrimes int y_bit, BN_CTX *ctx) 8961541Srgrimes{ 8979336Sdfr if (group->meth->point_set_compressed_coordinates == 0) { 89822521Sdyson ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 8991541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9001541Srgrimes return 0; 9019336Sdfr } 9029336Sdfr if (group->meth != point->meth) { 9039336Sdfr ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 9049336Sdfr EC_R_INCOMPATIBLE_OBJECTS); 9059336Sdfr return 0; 9061541Srgrimes } 9071541Srgrimes return group->meth->point_set_compressed_coordinates(group, point, x, 9081541Srgrimes y_bit, ctx); 9091541Srgrimes} 91018397Snate 9119336Sdfrsize_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, 9121541Srgrimes point_conversion_form_t form, unsigned char *buf, 9139336Sdfr size_t len, BN_CTX *ctx) 9149336Sdfr{ 9159336Sdfr if (group->meth->point2oct == 0) { 91626928Sdfr ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9179336Sdfr return 0; 91826928Sdfr } 91926928Sdfr if (group->meth != point->meth) { 9209336Sdfr ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); 9219336Sdfr return 0; 9229336Sdfr } 92322521Sdyson return group->meth->point2oct(group, point, form, buf, len, ctx); 92411644Sdg} 92511644Sdg 92611644Sdgint EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, 92711644Sdg const unsigned char *buf, size_t len, BN_CTX *ctx) 9289336Sdfr{ 9299336Sdfr if (group->meth->oct2point == 0) { 9309336Sdfr ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9319336Sdfr return 0; 9329336Sdfr } 9331541Srgrimes if (group->meth != point->meth) { 9341541Srgrimes ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); 9351541Srgrimes return 0; 9361541Srgrimes } 9371541Srgrimes return group->meth->oct2point(group, point, buf, len, ctx); 9381541Srgrimes} 93911921Sphk 9401541Srgrimesint EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 9411541Srgrimes const EC_POINT *b, BN_CTX *ctx) 9421541Srgrimes{ 9431541Srgrimes if (group->meth->add == 0) { 9441541Srgrimes ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9451541Srgrimes return 0; 9461541Srgrimes } 9471541Srgrimes if ((group->meth != r->meth) || (r->meth != a->meth) 9481541Srgrimes || (a->meth != b->meth)) { 9491541Srgrimes ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); 9501541Srgrimes return 0; 9511541Srgrimes } 95225930Sdfr return group->meth->add(group, r, a, b, ctx); 9531541Srgrimes} 9541541Srgrimes 9551541Srgrimesint EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 9561541Srgrimes BN_CTX *ctx) 9571541Srgrimes{ 95811921Sphk if (group->meth->dbl == 0) { 9591541Srgrimes ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9601541Srgrimes return 0; 9611541Srgrimes } 9621541Srgrimes if ((group->meth != r->meth) || (r->meth != a->meth)) { 9631541Srgrimes ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); 9641541Srgrimes return 0; 9651541Srgrimes } 9661541Srgrimes return group->meth->dbl(group, r, a, ctx); 9671541Srgrimes} 9681541Srgrimes 9691541Srgrimesint EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 97025930Sdfr{ 9711541Srgrimes if (group->meth->invert == 0) { 9721541Srgrimes ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9731541Srgrimes return 0; 9741541Srgrimes } 9751541Srgrimes if (group->meth != a->meth) { 9761541Srgrimes ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); 9771541Srgrimes return 0; 9781541Srgrimes } 9791541Srgrimes return group->meth->invert(group, a, ctx); 9801541Srgrimes} 9811541Srgrimes 9821541Srgrimesint EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 9831541Srgrimes{ 9841541Srgrimes if (group->meth->is_at_infinity == 0) { 9859336Sdfr ECerr(EC_F_EC_POINT_IS_AT_INFINITY, 9861541Srgrimes ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 9879336Sdfr return 0; 9881541Srgrimes } 9899336Sdfr if (group->meth != point->meth) { 9901541Srgrimes ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); 9911541Srgrimes return 0; 9929336Sdfr } 9939336Sdfr return group->meth->is_at_infinity(group, point); 9941541Srgrimes} 9959336Sdfr 9969336Sdfr/* 9979336Sdfr * Check whether an EC_POINT is on the curve or not. Note that the return 9989336Sdfr * value for this function should NOT be treated as a boolean. Return values: 9999336Sdfr * 1: The point is on the curve 10009336Sdfr * 0: The point is not on the curve 10011541Srgrimes * -1: An error occurred 10021541Srgrimes */ 10031541Srgrimesint EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 10041541Srgrimes BN_CTX *ctx) 10051541Srgrimes{ 10061541Srgrimes if (group->meth->is_on_curve == 0) { 10071541Srgrimes ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 10081541Srgrimes return 0; 10091541Srgrimes } 10101541Srgrimes if (group->meth != point->meth) { 10111541Srgrimes ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); 10121541Srgrimes return 0; 10131541Srgrimes } 10141541Srgrimes return group->meth->is_on_curve(group, point, ctx); 10151541Srgrimes} 10161541Srgrimes 10179336Sdfrint EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 10181541Srgrimes BN_CTX *ctx) 10191541Srgrimes{ 10201541Srgrimes if (group->meth->point_cmp == 0) { 10219336Sdfr ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 10229336Sdfr return -1; 10231541Srgrimes } 10249336Sdfr if ((group->meth != a->meth) || (a->meth != b->meth)) { 10259336Sdfr ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); 10269336Sdfr return -1; 10271541Srgrimes } 10281541Srgrimes return group->meth->point_cmp(group, a, b, ctx); 10299336Sdfr} 10301541Srgrimes 10311541Srgrimesint EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 10321541Srgrimes{ 10331541Srgrimes if (group->meth->make_affine == 0) { 10349336Sdfr ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 10359336Sdfr return 0; 10369336Sdfr } 10379336Sdfr if (group->meth != point->meth) { 10381541Srgrimes ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); 10391541Srgrimes return 0; 10401541Srgrimes } 10411541Srgrimes return group->meth->make_affine(group, point, ctx); 10421541Srgrimes} 10431541Srgrimes 10441541Srgrimesint EC_POINTs_make_affine(const EC_GROUP *group, size_t num, 10451541Srgrimes EC_POINT *points[], BN_CTX *ctx) 10469336Sdfr{ 10479336Sdfr size_t i; 10489336Sdfr 10499336Sdfr if (group->meth->points_make_affine == 0) { 10509336Sdfr ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 10519336Sdfr return 0; 10529336Sdfr } 10539336Sdfr for (i = 0; i < num; i++) { 10549336Sdfr if (group->meth != points[i]->meth) { 10559336Sdfr ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); 10561541Srgrimes return 0; 10571541Srgrimes } 10581541Srgrimes } 10599336Sdfr return group->meth->points_make_affine(group, num, points, ctx); 10609336Sdfr} 10619336Sdfr 10629336Sdfr/* 10639336Sdfr * Functions for point multiplication. If group->meth->mul is 0, we use the 10641541Srgrimes * wNAF-based implementations in ec_mult.c; otherwise we dispatch through 10651541Srgrimes * methods. 10661541Srgrimes */ 10671541Srgrimes 10681541Srgrimesint EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 10691541Srgrimes size_t num, const EC_POINT *points[], 10701541Srgrimes const BIGNUM *scalars[], BN_CTX *ctx) 10711541Srgrimes{ 10721541Srgrimes if (group->meth->mul == 0) 10731541Srgrimes /* use default */ 10749336Sdfr return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 10751541Srgrimes 10769336Sdfr return group->meth->mul(group, r, scalar, num, points, scalars, ctx); 10771541Srgrimes} 10789336Sdfr 10791541Srgrimesint EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 10801541Srgrimes const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 10811541Srgrimes{ 10829336Sdfr /* just a convenient interface to EC_POINTs_mul() */ 10831541Srgrimes 10841541Srgrimes const EC_POINT *points[1]; 10859336Sdfr const BIGNUM *scalars[1]; 10869336Sdfr 10879336Sdfr points[0] = point; 10881541Srgrimes scalars[0] = p_scalar; 10899336Sdfr 10909336Sdfr return EC_POINTs_mul(group, r, g_scalar, 10919336Sdfr (point != NULL 10929336Sdfr && p_scalar != NULL), points, scalars, ctx); 10939336Sdfr} 10941541Srgrimes 10959336Sdfrint EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 10961541Srgrimes{ 10971541Srgrimes if (group->meth->mul == 0) 10981541Srgrimes /* use default */ 10991541Srgrimes return ec_wNAF_precompute_mult(group, ctx); 11001541Srgrimes 11019336Sdfr if (group->meth->precompute_mult != 0) 11029336Sdfr return group->meth->precompute_mult(group, ctx); 11039336Sdfr else 11049336Sdfr return 1; /* nothing to do, so report success */ 11051541Srgrimes} 11061541Srgrimes 11079336Sdfrint EC_GROUP_have_precompute_mult(const EC_GROUP *group) 11089336Sdfr{ 11091541Srgrimes if (group->meth->mul == 0) 11109336Sdfr /* use default */ 11111541Srgrimes return ec_wNAF_have_precompute_mult(group); 11121541Srgrimes 11131541Srgrimes if (group->meth->have_precompute_mult != 0) 11141541Srgrimes return group->meth->have_precompute_mult(group); 11151541Srgrimes else 11161541Srgrimes return 0; /* cannot tell whether precomputation has 11179336Sdfr * been performed */ 11189336Sdfr} 11199336Sdfr