LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/ec - ec_lib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 216 502 43.0 %
Date: 2015-10-10 Functions: 34 60 56.7 %

          Line data    Source code
       1             : /* crypto/ec/ec_lib.c */
       2             : /*
       3             :  * Originally written by Bodo Moeller for the OpenSSL project.
       4             :  */
       5             : /* ====================================================================
       6             :  * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  *
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  *
      15             :  * 2. Redistributions in binary form must reproduce the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer in
      17             :  *    the documentation and/or other materials provided with the
      18             :  *    distribution.
      19             :  *
      20             :  * 3. All advertising materials mentioning features or use of this
      21             :  *    software must display the following acknowledgment:
      22             :  *    "This product includes software developed by the OpenSSL Project
      23             :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      24             :  *
      25             :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      26             :  *    endorse or promote products derived from this software without
      27             :  *    prior written permission. For written permission, please contact
      28             :  *    openssl-core@openssl.org.
      29             :  *
      30             :  * 5. Products derived from this software may not be called "OpenSSL"
      31             :  *    nor may "OpenSSL" appear in their names without prior written
      32             :  *    permission of the OpenSSL Project.
      33             :  *
      34             :  * 6. Redistributions of any form whatsoever must retain the following
      35             :  *    acknowledgment:
      36             :  *    "This product includes software developed by the OpenSSL Project
      37             :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      38             :  *
      39             :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      40             :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      41             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      42             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      43             :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      44             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      45             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      46             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      47             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      48             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      49             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      50             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      51             :  * ====================================================================
      52             :  *
      53             :  * This product includes cryptographic software written by Eric Young
      54             :  * (eay@cryptsoft.com).  This product includes software written by Tim
      55             :  * Hudson (tjh@cryptsoft.com).
      56             :  *
      57             :  */
      58             : /* ====================================================================
      59             :  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
      60             :  * Binary polynomial ECC support in OpenSSL originally developed by
      61             :  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
      62             :  */
      63             : 
      64             : #include <string.h>
      65             : 
      66             : #include <openssl/err.h>
      67             : #include <openssl/opensslv.h>
      68             : 
      69             : #include "ec_lcl.h"
      70             : 
      71             : const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
      72             : 
      73             : /* functions for EC_GROUP objects */
      74             : 
      75        4344 : EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
      76             : {
      77             :     EC_GROUP *ret;
      78             : 
      79        4344 :     if (meth == NULL) {
      80           0 :         ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
      81           0 :         return NULL;
      82             :     }
      83        4344 :     if (meth->group_init == 0) {
      84           0 :         ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
      85           0 :         return NULL;
      86             :     }
      87             : 
      88        4344 :     ret = OPENSSL_malloc(sizeof *ret);
      89        4344 :     if (ret == NULL) {
      90           0 :         ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
      91           0 :         return NULL;
      92             :     }
      93             : 
      94        4344 :     ret->meth = meth;
      95             : 
      96        4344 :     ret->extra_data = NULL;
      97        4344 :     ret->mont_data = NULL;
      98             : 
      99        4344 :     ret->generator = NULL;
     100        4344 :     BN_init(&ret->order);
     101        4344 :     BN_init(&ret->cofactor);
     102             : 
     103        4344 :     ret->curve_name = 0;
     104        4344 :     ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK;
     105        4344 :     ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
     106             : 
     107        4344 :     ret->seed = NULL;
     108        4344 :     ret->seed_len = 0;
     109             : 
     110        4344 :     if (!meth->group_init(ret)) {
     111           0 :         OPENSSL_free(ret);
     112           0 :         return NULL;
     113             :     }
     114             : 
     115             :     return ret;
     116             : }
     117             : 
     118        4344 : void EC_GROUP_free(EC_GROUP *group)
     119             : {
     120        4344 :     if (!group)
     121        4344 :         return;
     122             : 
     123        4344 :     if (group->meth->group_finish != 0)
     124        4344 :         group->meth->group_finish(group);
     125             : 
     126        4344 :     EC_EX_DATA_free_all_data(&group->extra_data);
     127             : 
     128        4344 :     if (EC_GROUP_VERSION(group) && group->mont_data)
     129        4344 :         BN_MONT_CTX_free(group->mont_data);
     130             : 
     131        4344 :     if (group->generator != NULL)
     132        4344 :         EC_POINT_free(group->generator);
     133        4344 :     BN_free(&group->order);
     134        4344 :     BN_free(&group->cofactor);
     135             : 
     136        4344 :     if (group->seed)
     137        4344 :         OPENSSL_free(group->seed);
     138             : 
     139        4344 :     OPENSSL_free(group);
     140             : }
     141             : 
     142           0 : void EC_GROUP_clear_free(EC_GROUP *group)
     143             : {
     144           0 :     if (!group)
     145           0 :         return;
     146             : 
     147           0 :     if (group->meth->group_clear_finish != 0)
     148           0 :         group->meth->group_clear_finish(group);
     149           0 :     else if (group->meth->group_finish != 0)
     150           0 :         group->meth->group_finish(group);
     151             : 
     152           0 :     EC_EX_DATA_clear_free_all_data(&group->extra_data);
     153             : 
     154           0 :     if (EC_GROUP_VERSION(group) && group->mont_data)
     155           0 :         BN_MONT_CTX_free(group->mont_data);
     156             : 
     157           0 :     if (group->generator != NULL)
     158           0 :         EC_POINT_clear_free(group->generator);
     159           0 :     BN_clear_free(&group->order);
     160           0 :     BN_clear_free(&group->cofactor);
     161             : 
     162           0 :     if (group->seed) {
     163           0 :         OPENSSL_cleanse(group->seed, group->seed_len);
     164           0 :         OPENSSL_free(group->seed);
     165             :     }
     166             : 
     167           0 :     OPENSSL_cleanse(group, sizeof *group);
     168           0 :     OPENSSL_free(group);
     169             : }
     170             : 
     171        3102 : int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
     172             : {
     173             :     EC_EXTRA_DATA *d;
     174             : 
     175        3102 :     if (dest->meth->group_copy == 0) {
     176           0 :         ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     177           0 :         return 0;
     178             :     }
     179        3102 :     if (dest->meth != src->meth) {
     180           0 :         ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
     181           0 :         return 0;
     182             :     }
     183        3102 :     if (dest == src)
     184             :         return 1;
     185             : 
     186        3102 :     EC_EX_DATA_free_all_data(&dest->extra_data);
     187             : 
     188        3102 :     for (d = src->extra_data; d != NULL; d = d->next) {
     189           0 :         void *t = d->dup_func(d->data);
     190             : 
     191           0 :         if (t == NULL)
     192             :             return 0;
     193           0 :         if (!EC_EX_DATA_set_data
     194           0 :             (&dest->extra_data, t, d->dup_func, d->free_func,
     195             :              d->clear_free_func))
     196             :             return 0;
     197             :     }
     198             : 
     199        3102 :     if (EC_GROUP_VERSION(src) && src->mont_data != NULL) {
     200        3102 :         if (dest->mont_data == NULL) {
     201        3102 :             dest->mont_data = BN_MONT_CTX_new();
     202        3102 :             if (dest->mont_data == NULL)
     203             :                 return 0;
     204             :         }
     205        3102 :         if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
     206             :             return 0;
     207             :     } else {
     208             :         /* src->generator == NULL */
     209           0 :         if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) {
     210           0 :             BN_MONT_CTX_free(dest->mont_data);
     211           0 :             dest->mont_data = NULL;
     212             :         }
     213             :     }
     214             : 
     215        3102 :     if (src->generator != NULL) {
     216        3102 :         if (dest->generator == NULL) {
     217        3102 :             dest->generator = EC_POINT_new(dest);
     218        3102 :             if (dest->generator == NULL)
     219             :                 return 0;
     220             :         }
     221        3102 :         if (!EC_POINT_copy(dest->generator, src->generator))
     222             :             return 0;
     223             :     } else {
     224             :         /* src->generator == NULL */
     225           0 :         if (dest->generator != NULL) {
     226           0 :             EC_POINT_clear_free(dest->generator);
     227           0 :             dest->generator = NULL;
     228             :         }
     229             :     }
     230             : 
     231        3102 :     if (!BN_copy(&dest->order, &src->order))
     232             :         return 0;
     233        3102 :     if (!BN_copy(&dest->cofactor, &src->cofactor))
     234             :         return 0;
     235             : 
     236        3102 :     dest->curve_name = src->curve_name;
     237        3102 :     dest->asn1_flag = src->asn1_flag;
     238        3102 :     dest->asn1_form = src->asn1_form;
     239             : 
     240        3102 :     if (src->seed) {
     241        3102 :         if (dest->seed)
     242           0 :             OPENSSL_free(dest->seed);
     243        3102 :         dest->seed = OPENSSL_malloc(src->seed_len);
     244        3102 :         if (dest->seed == NULL)
     245             :             return 0;
     246        6204 :         if (!memcpy(dest->seed, src->seed, src->seed_len))
     247             :             return 0;
     248        3102 :         dest->seed_len = src->seed_len;
     249             :     } else {
     250           0 :         if (dest->seed)
     251           0 :             OPENSSL_free(dest->seed);
     252           0 :         dest->seed = NULL;
     253           0 :         dest->seed_len = 0;
     254             :     }
     255             : 
     256        3102 :     return dest->meth->group_copy(dest, src);
     257             : }
     258             : 
     259        1107 : EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
     260             : {
     261             :     EC_GROUP *t = NULL;
     262             :     int ok = 0;
     263             : 
     264        1107 :     if (a == NULL)
     265             :         return NULL;
     266             : 
     267        1107 :     if ((t = EC_GROUP_new(a->meth)) == NULL)
     268             :         return (NULL);
     269        1107 :     if (!EC_GROUP_copy(t, a))
     270             :         goto err;
     271             : 
     272             :     ok = 1;
     273             : 
     274             :  err:
     275        1107 :     if (!ok) {
     276           0 :         if (t)
     277           0 :             EC_GROUP_free(t);
     278             :         return NULL;
     279             :     } else
     280             :         return t;
     281             : }
     282             : 
     283        3105 : const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
     284             : {
     285        3105 :     return group->meth;
     286             : }
     287             : 
     288        1110 : int EC_METHOD_get_field_type(const EC_METHOD *meth)
     289             : {
     290        1110 :     return meth->field_type;
     291             : }
     292             : 
     293        1242 : int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
     294             :                            const BIGNUM *order, const BIGNUM *cofactor)
     295             : {
     296        1242 :     if (generator == NULL) {
     297           0 :         ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
     298           0 :         return 0;
     299             :     }
     300             : 
     301        1242 :     if (group->generator == NULL) {
     302        1242 :         group->generator = EC_POINT_new(group);
     303        1242 :         if (group->generator == NULL)
     304             :             return 0;
     305             :     }
     306        1242 :     if (!EC_POINT_copy(group->generator, generator))
     307             :         return 0;
     308             : 
     309        1242 :     if (order != NULL) {
     310        1242 :         if (!BN_copy(&group->order, order))
     311             :             return 0;
     312             :     } else
     313           0 :         BN_zero(&group->order);
     314             : 
     315        1242 :     if (cofactor != NULL) {
     316        1242 :         if (!BN_copy(&group->cofactor, cofactor))
     317             :             return 0;
     318             :     } else
     319           0 :         BN_zero(&group->cofactor);
     320             : 
     321             :     /*
     322             :      * We ignore the return value because some groups have an order with
     323             :      * factors of two, which makes the Montgomery setup fail.
     324             :      * |group->mont_data| will be NULL in this case.
     325             :      */
     326        1242 :     ec_precompute_mont_data(group);
     327             : 
     328        1242 :     return 1;
     329             : }
     330             : 
     331        1615 : const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
     332             : {
     333        1615 :     return group->generator;
     334             : }
     335             : 
     336           0 : BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
     337             : {
     338           0 :     return EC_GROUP_VERSION(group) ? group->mont_data : NULL;
     339             : }
     340             : 
     341        1615 : int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
     342             : {
     343        1615 :     if (!BN_copy(order, &group->order))
     344             :         return 0;
     345             : 
     346        1615 :     return !BN_is_zero(order);
     347             : }
     348             : 
     349           0 : int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
     350             :                           BN_CTX *ctx)
     351             : {
     352           0 :     if (!BN_copy(cofactor, &group->cofactor))
     353             :         return 0;
     354             : 
     355           0 :     return !BN_is_zero(&group->cofactor);
     356             : }
     357             : 
     358        1242 : void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
     359             : {
     360        1242 :     group->curve_name = nid;
     361        1242 : }
     362             : 
     363         746 : int EC_GROUP_get_curve_name(const EC_GROUP *group)
     364             : {
     365         746 :     return group->curve_name;
     366             : }
     367             : 
     368           0 : void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
     369             : {
     370           0 :     group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK;
     371           0 :     group->asn1_flag |= flag & EC_GROUP_ASN1_FLAG_MASK;
     372           0 : }
     373             : 
     374           0 : int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
     375             : {
     376           0 :     return group->asn1_flag & EC_GROUP_ASN1_FLAG_MASK;
     377             : }
     378             : 
     379           0 : void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
     380             :                                         point_conversion_form_t form)
     381             : {
     382           0 :     group->asn1_form = form;
     383           0 : }
     384             : 
     385           0 : point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
     386             :                                                            *group)
     387             : {
     388           0 :     return group->asn1_form;
     389             : }
     390             : 
     391        1242 : size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
     392             : {
     393        1242 :     if (group->seed) {
     394           0 :         OPENSSL_free(group->seed);
     395           0 :         group->seed = NULL;
     396           0 :         group->seed_len = 0;
     397             :     }
     398             : 
     399        1242 :     if (!len || !p)
     400             :         return 1;
     401             : 
     402        1242 :     if ((group->seed = OPENSSL_malloc(len)) == NULL)
     403             :         return 0;
     404             :     memcpy(group->seed, p, len);
     405        1242 :     group->seed_len = len;
     406             : 
     407        1242 :     return len;
     408             : }
     409             : 
     410           0 : unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
     411             : {
     412           0 :     return group->seed;
     413             : }
     414             : 
     415           0 : size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
     416             : {
     417           0 :     return group->seed_len;
     418             : }
     419             : 
     420        1242 : int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
     421             :                            const BIGNUM *b, BN_CTX *ctx)
     422             : {
     423        1242 :     if (group->meth->group_set_curve == 0) {
     424           0 :         ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     425           0 :         return 0;
     426             :     }
     427        1242 :     return group->meth->group_set_curve(group, p, a, b, ctx);
     428             : }
     429             : 
     430           0 : int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
     431             :                            BIGNUM *b, BN_CTX *ctx)
     432             : {
     433           0 :     if (group->meth->group_get_curve == 0) {
     434           0 :         ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     435           0 :         return 0;
     436             :     }
     437           0 :     return group->meth->group_get_curve(group, p, a, b, ctx);
     438             : }
     439             : 
     440             : #ifndef OPENSSL_NO_EC2M
     441           0 : int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
     442             :                             const BIGNUM *b, BN_CTX *ctx)
     443             : {
     444           0 :     if (group->meth->group_set_curve == 0) {
     445           0 :         ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
     446             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     447           0 :         return 0;
     448             :     }
     449           0 :     return group->meth->group_set_curve(group, p, a, b, ctx);
     450             : }
     451             : 
     452           0 : int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
     453             :                             BIGNUM *b, BN_CTX *ctx)
     454             : {
     455           0 :     if (group->meth->group_get_curve == 0) {
     456           0 :         ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
     457             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     458           0 :         return 0;
     459             :     }
     460           0 :     return group->meth->group_get_curve(group, p, a, b, ctx);
     461             : }
     462             : #endif
     463             : 
     464        1474 : int EC_GROUP_get_degree(const EC_GROUP *group)
     465             : {
     466        1474 :     if (group->meth->group_get_degree == 0) {
     467           0 :         ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     468           0 :         return 0;
     469             :     }
     470        1474 :     return group->meth->group_get_degree(group);
     471             : }
     472             : 
     473           0 : int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
     474             : {
     475           0 :     if (group->meth->group_check_discriminant == 0) {
     476           0 :         ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
     477             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     478           0 :         return 0;
     479             :     }
     480           0 :     return group->meth->group_check_discriminant(group, ctx);
     481             : }
     482             : 
     483           0 : int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
     484             : {
     485             :     int r = 0;
     486             :     BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
     487             :     BN_CTX *ctx_new = NULL;
     488             : 
     489             :     /* compare the field types */
     490           0 :     if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
     491             :         EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
     492             :         return 1;
     493             :     /* compare the curve name (if present in both) */
     494           0 :     if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
     495             :         EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
     496             :         return 1;
     497             : 
     498           0 :     if (!ctx)
     499           0 :         ctx_new = ctx = BN_CTX_new();
     500           0 :     if (!ctx)
     501             :         return -1;
     502             : 
     503           0 :     BN_CTX_start(ctx);
     504           0 :     a1 = BN_CTX_get(ctx);
     505           0 :     a2 = BN_CTX_get(ctx);
     506           0 :     a3 = BN_CTX_get(ctx);
     507           0 :     b1 = BN_CTX_get(ctx);
     508           0 :     b2 = BN_CTX_get(ctx);
     509           0 :     b3 = BN_CTX_get(ctx);
     510           0 :     if (!b3) {
     511           0 :         BN_CTX_end(ctx);
     512           0 :         if (ctx_new)
     513           0 :             BN_CTX_free(ctx);
     514             :         return -1;
     515             :     }
     516             : 
     517             :     /*
     518             :      * XXX This approach assumes that the external representation of curves
     519             :      * over the same field type is the same.
     520             :      */
     521           0 :     if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
     522           0 :         !b->meth->group_get_curve(b, b1, b2, b3, ctx))
     523             :         r = 1;
     524             : 
     525           0 :     if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
     526             :         r = 1;
     527             : 
     528             :     /* XXX EC_POINT_cmp() assumes that the methods are equal */
     529           0 :     if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
     530             :                           EC_GROUP_get0_generator(b), ctx))
     531             :         r = 1;
     532             : 
     533           0 :     if (!r) {
     534             :         /* compare the order and cofactor */
     535           0 :         if (!EC_GROUP_get_order(a, a1, ctx) ||
     536           0 :             !EC_GROUP_get_order(b, b1, ctx) ||
     537           0 :             !EC_GROUP_get_cofactor(a, a2, ctx) ||
     538             :             !EC_GROUP_get_cofactor(b, b2, ctx)) {
     539           0 :             BN_CTX_end(ctx);
     540           0 :             if (ctx_new)
     541           0 :                 BN_CTX_free(ctx);
     542             :             return -1;
     543             :         }
     544           0 :         if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
     545             :             r = 1;
     546             :     }
     547             : 
     548           0 :     BN_CTX_end(ctx);
     549           0 :     if (ctx_new)
     550           0 :         BN_CTX_free(ctx);
     551             : 
     552           0 :     return r;
     553             : }
     554             : 
     555             : /* this has 'package' visibility */
     556         737 : int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
     557             :                         void *(*dup_func) (void *),
     558             :                         void (*free_func) (void *),
     559             :                         void (*clear_free_func) (void *))
     560             : {
     561             :     EC_EXTRA_DATA *d;
     562             : 
     563         737 :     if (ex_data == NULL)
     564             :         return 0;
     565             : 
     566         737 :     for (d = *ex_data; d != NULL; d = d->next) {
     567           0 :         if (d->dup_func == dup_func && d->free_func == free_func
     568           0 :             && d->clear_free_func == clear_free_func) {
     569           0 :             ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
     570           0 :             return 0;
     571             :         }
     572             :     }
     573             : 
     574         737 :     if (data == NULL)
     575             :         /* no explicit entry needed */
     576             :         return 1;
     577             : 
     578         737 :     d = OPENSSL_malloc(sizeof *d);
     579         737 :     if (d == NULL)
     580             :         return 0;
     581             : 
     582         737 :     d->data = data;
     583         737 :     d->dup_func = dup_func;
     584         737 :     d->free_func = free_func;
     585         737 :     d->clear_free_func = clear_free_func;
     586             : 
     587         737 :     d->next = *ex_data;
     588         737 :     *ex_data = d;
     589             : 
     590         737 :     return 1;
     591             : }
     592             : 
     593             : /* this has 'package' visibility */
     594        3089 : void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
     595             :                           void *(*dup_func) (void *),
     596             :                           void (*free_func) (void *),
     597             :                           void (*clear_free_func) (void *))
     598             : {
     599             :     const EC_EXTRA_DATA *d;
     600             : 
     601        3089 :     for (d = ex_data; d != NULL; d = d->next) {
     602           0 :         if (d->dup_func == dup_func && d->free_func == free_func
     603           0 :             && d->clear_free_func == clear_free_func)
     604           0 :             return d->data;
     605             :     }
     606             : 
     607             :     return NULL;
     608             : }
     609             : 
     610             : /* this has 'package' visibility */
     611           0 : void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
     612             :                           void *(*dup_func) (void *),
     613             :                           void (*free_func) (void *),
     614             :                           void (*clear_free_func) (void *))
     615             : {
     616             :     EC_EXTRA_DATA **p;
     617             : 
     618           0 :     if (ex_data == NULL)
     619             :         return;
     620             : 
     621           0 :     for (p = ex_data; *p != NULL; p = &((*p)->next)) {
     622           0 :         if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
     623           0 :             && (*p)->clear_free_func == clear_free_func) {
     624           0 :             EC_EXTRA_DATA *next = (*p)->next;
     625             : 
     626           0 :             (*p)->free_func((*p)->data);
     627           0 :             OPENSSL_free(*p);
     628             : 
     629           0 :             *p = next;
     630           0 :             return;
     631             :         }
     632             :     }
     633             : }
     634             : 
     635             : /* this has 'package' visibility */
     636           0 : void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
     637             :                                 void *(*dup_func) (void *),
     638             :                                 void (*free_func) (void *),
     639             :                                 void (*clear_free_func) (void *))
     640             : {
     641             :     EC_EXTRA_DATA **p;
     642             : 
     643           0 :     if (ex_data == NULL)
     644             :         return;
     645             : 
     646           0 :     for (p = ex_data; *p != NULL; p = &((*p)->next)) {
     647           0 :         if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
     648           0 :             && (*p)->clear_free_func == clear_free_func) {
     649           0 :             EC_EXTRA_DATA *next = (*p)->next;
     650             : 
     651           0 :             (*p)->clear_free_func((*p)->data);
     652           0 :             OPENSSL_free(*p);
     653             : 
     654           0 :             *p = next;
     655           0 :             return;
     656             :         }
     657             :     }
     658             : }
     659             : 
     660             : /* this has 'package' visibility */
     661       13415 : void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
     662             : {
     663             :     EC_EXTRA_DATA *d;
     664             : 
     665       13415 :     if (ex_data == NULL)
     666       13415 :         return;
     667             : 
     668       13415 :     d = *ex_data;
     669       27567 :     while (d) {
     670         737 :         EC_EXTRA_DATA *next = d->next;
     671             : 
     672         737 :         d->free_func(d->data);
     673         737 :         OPENSSL_free(d);
     674             : 
     675             :         d = next;
     676             :     }
     677       13415 :     *ex_data = NULL;
     678             : }
     679             : 
     680             : /* this has 'package' visibility */
     681           0 : void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
     682             : {
     683             :     EC_EXTRA_DATA *d;
     684             : 
     685           0 :     if (ex_data == NULL)
     686           0 :         return;
     687             : 
     688           0 :     d = *ex_data;
     689           0 :     while (d) {
     690           0 :         EC_EXTRA_DATA *next = d->next;
     691             : 
     692           0 :         d->clear_free_func(d->data);
     693           0 :         OPENSSL_free(d);
     694             : 
     695             :         d = next;
     696             :     }
     697           0 :     *ex_data = NULL;
     698             : }
     699             : 
     700             : /* functions for EC_POINT objects */
     701             : 
     702       21555 : EC_POINT *EC_POINT_new(const EC_GROUP *group)
     703             : {
     704             :     EC_POINT *ret;
     705             : 
     706       21555 :     if (group == NULL) {
     707           0 :         ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
     708           0 :         return NULL;
     709             :     }
     710       21555 :     if (group->meth->point_init == 0) {
     711           0 :         ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     712           0 :         return NULL;
     713             :     }
     714             : 
     715       21555 :     ret = OPENSSL_malloc(sizeof *ret);
     716       21555 :     if (ret == NULL) {
     717           0 :         ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
     718           0 :         return NULL;
     719             :     }
     720             : 
     721       21555 :     ret->meth = group->meth;
     722             : 
     723       21555 :     if (!ret->meth->point_init(ret)) {
     724           0 :         OPENSSL_free(ret);
     725           0 :         return NULL;
     726             :     }
     727             : 
     728             :     return ret;
     729             : }
     730             : 
     731       12147 : void EC_POINT_free(EC_POINT *point)
     732             : {
     733       12147 :     if (!point)
     734       12147 :         return;
     735             : 
     736       12147 :     if (point->meth->point_finish != 0)
     737       12147 :         point->meth->point_finish(point);
     738       12147 :     OPENSSL_free(point);
     739             : }
     740             : 
     741        9408 : void EC_POINT_clear_free(EC_POINT *point)
     742             : {
     743        9408 :     if (!point)
     744        9408 :         return;
     745             : 
     746        9408 :     if (point->meth->point_clear_finish != 0)
     747        9408 :         point->meth->point_clear_finish(point);
     748           0 :     else if (point->meth->point_finish != 0)
     749           0 :         point->meth->point_finish(point);
     750        9408 :     OPENSSL_cleanse(point, sizeof *point);
     751        9408 :     OPENSSL_free(point);
     752             : }
     753             : 
     754       10541 : int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
     755             : {
     756       10541 :     if (dest->meth->point_copy == 0) {
     757           0 :         ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     758           0 :         return 0;
     759             :     }
     760       10541 :     if (dest->meth != src->meth) {
     761           0 :         ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
     762           0 :         return 0;
     763             :     }
     764       10541 :     if (dest == src)
     765             :         return 1;
     766       10541 :     return dest->meth->point_copy(dest, src);
     767             : }
     768             : 
     769         370 : EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
     770             : {
     771             :     EC_POINT *t;
     772             :     int r;
     773             : 
     774         370 :     if (a == NULL)
     775             :         return NULL;
     776             : 
     777         370 :     t = EC_POINT_new(group);
     778         370 :     if (t == NULL)
     779             :         return (NULL);
     780         370 :     r = EC_POINT_copy(t, a);
     781         370 :     if (!r) {
     782           0 :         EC_POINT_free(t);
     783           0 :         return NULL;
     784             :     } else
     785             :         return t;
     786             : }
     787             : 
     788           0 : const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
     789             : {
     790           0 :     return point->meth;
     791             : }
     792             : 
     793           0 : int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
     794             : {
     795           0 :     if (group->meth->point_set_to_infinity == 0) {
     796           0 :         ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
     797             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     798           0 :         return 0;
     799             :     }
     800           0 :     if (group->meth != point->meth) {
     801           0 :         ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
     802           0 :         return 0;
     803             :     }
     804           0 :     return group->meth->point_set_to_infinity(group, point);
     805             : }
     806             : 
     807        1979 : int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
     808             :                                              EC_POINT *point, const BIGNUM *x,
     809             :                                              const BIGNUM *y, const BIGNUM *z,
     810             :                                              BN_CTX *ctx)
     811             : {
     812        1979 :     if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
     813           0 :         ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
     814             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     815           0 :         return 0;
     816             :     }
     817        1979 :     if (group->meth != point->meth) {
     818           0 :         ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
     819             :               EC_R_INCOMPATIBLE_OBJECTS);
     820           0 :         return 0;
     821             :     }
     822        1979 :     return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
     823             :                                                               y, z, ctx);
     824             : }
     825             : 
     826           0 : int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
     827             :                                              const EC_POINT *point, BIGNUM *x,
     828             :                                              BIGNUM *y, BIGNUM *z,
     829             :                                              BN_CTX *ctx)
     830             : {
     831           0 :     if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
     832           0 :         ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
     833             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     834           0 :         return 0;
     835             :     }
     836           0 :     if (group->meth != point->meth) {
     837           0 :         ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
     838             :               EC_R_INCOMPATIBLE_OBJECTS);
     839           0 :         return 0;
     840             :     }
     841           0 :     return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
     842             :                                                               y, z, ctx);
     843             : }
     844             : 
     845        1979 : int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
     846             :                                         EC_POINT *point, const BIGNUM *x,
     847             :                                         const BIGNUM *y, BN_CTX *ctx)
     848             : {
     849        1979 :     if (group->meth->point_set_affine_coordinates == 0) {
     850           0 :         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
     851             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     852           0 :         return 0;
     853             :     }
     854        1979 :     if (group->meth != point->meth) {
     855           0 :         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
     856             :               EC_R_INCOMPATIBLE_OBJECTS);
     857           0 :         return 0;
     858             :     }
     859        1979 :     return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
     860             : }
     861             : 
     862             : #ifndef OPENSSL_NO_EC2M
     863           0 : int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
     864             :                                          EC_POINT *point, const BIGNUM *x,
     865             :                                          const BIGNUM *y, BN_CTX *ctx)
     866             : {
     867           0 :     if (group->meth->point_set_affine_coordinates == 0) {
     868           0 :         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
     869             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     870           0 :         return 0;
     871             :     }
     872           0 :     if (group->meth != point->meth) {
     873           0 :         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
     874             :               EC_R_INCOMPATIBLE_OBJECTS);
     875           0 :         return 0;
     876             :     }
     877           0 :     return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
     878             : }
     879             : #endif
     880             : 
     881        1480 : int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
     882             :                                         const EC_POINT *point, BIGNUM *x,
     883             :                                         BIGNUM *y, BN_CTX *ctx)
     884             : {
     885        1480 :     if (group->meth->point_get_affine_coordinates == 0) {
     886           0 :         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
     887             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     888           0 :         return 0;
     889             :     }
     890        1480 :     if (group->meth != point->meth) {
     891           0 :         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
     892             :               EC_R_INCOMPATIBLE_OBJECTS);
     893           0 :         return 0;
     894             :     }
     895        1480 :     return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
     896             : }
     897             : 
     898             : #ifndef OPENSSL_NO_EC2M
     899           0 : int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
     900             :                                          const EC_POINT *point, BIGNUM *x,
     901             :                                          BIGNUM *y, BN_CTX *ctx)
     902             : {
     903           0 :     if (group->meth->point_get_affine_coordinates == 0) {
     904           0 :         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
     905             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     906           0 :         return 0;
     907             :     }
     908           0 :     if (group->meth != point->meth) {
     909           0 :         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
     910             :               EC_R_INCOMPATIBLE_OBJECTS);
     911           0 :         return 0;
     912             :     }
     913           0 :     return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
     914             : }
     915             : #endif
     916             : 
     917      126147 : int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
     918             :                  const EC_POINT *b, BN_CTX *ctx)
     919             : {
     920      126147 :     if (group->meth->add == 0) {
     921           0 :         ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     922           0 :         return 0;
     923             :     }
     924      126147 :     if ((group->meth != r->meth) || (r->meth != a->meth)
     925      126147 :         || (a->meth != b->meth)) {
     926           0 :         ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
     927           0 :         return 0;
     928             :     }
     929      126147 :     return group->meth->add(group, r, a, b, ctx);
     930             : }
     931             : 
     932      598791 : int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
     933             :                  BN_CTX *ctx)
     934             : {
     935      598791 :     if (group->meth->dbl == 0) {
     936           0 :         ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     937           0 :         return 0;
     938             :     }
     939      598791 :     if ((group->meth != r->meth) || (r->meth != a->meth)) {
     940           0 :         ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
     941           0 :         return 0;
     942             :     }
     943      598791 :     return group->meth->dbl(group, r, a, ctx);
     944             : }
     945             : 
     946       60674 : int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
     947             : {
     948       60674 :     if (group->meth->invert == 0) {
     949           0 :         ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     950           0 :         return 0;
     951             :     }
     952       60674 :     if (group->meth != a->meth) {
     953           0 :         ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
     954           0 :         return 0;
     955             :     }
     956       60674 :     return group->meth->invert(group, a, ctx);
     957             : }
     958             : 
     959      915462 : int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
     960             : {
     961      915462 :     if (group->meth->is_at_infinity == 0) {
     962           0 :         ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
     963             :               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     964           0 :         return 0;
     965             :     }
     966      915462 :     if (group->meth != point->meth) {
     967           0 :         ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
     968           0 :         return 0;
     969             :     }
     970      915462 :     return group->meth->is_at_infinity(group, point);
     971             : }
     972             : 
     973             : /*
     974             :  * Check whether an EC_POINT is on the curve or not. Note that the return
     975             :  * value for this function should NOT be treated as a boolean. Return values:
     976             :  *  1: The point is on the curve
     977             :  *  0: The point is not on the curve
     978             :  * -1: An error occurred
     979             :  */
     980         737 : int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
     981             :                          BN_CTX *ctx)
     982             : {
     983         737 :     if (group->meth->is_on_curve == 0) {
     984           0 :         ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     985           0 :         return 0;
     986             :     }
     987         737 :     if (group->meth != point->meth) {
     988           0 :         ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
     989           0 :         return 0;
     990             :     }
     991         737 :     return group->meth->is_on_curve(group, point, ctx);
     992             : }
     993             : 
     994           0 : int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
     995             :                  BN_CTX *ctx)
     996             : {
     997           0 :     if (group->meth->point_cmp == 0) {
     998           0 :         ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     999           0 :         return -1;
    1000             :     }
    1001           0 :     if ((group->meth != a->meth) || (a->meth != b->meth)) {
    1002           0 :         ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
    1003           0 :         return -1;
    1004             :     }
    1005           0 :     return group->meth->point_cmp(group, a, b, ctx);
    1006             : }
    1007             : 
    1008           0 : int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
    1009             : {
    1010           0 :     if (group->meth->make_affine == 0) {
    1011           0 :         ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    1012           0 :         return 0;
    1013             :     }
    1014           0 :     if (group->meth != point->meth) {
    1015           0 :         ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
    1016           0 :         return 0;
    1017             :     }
    1018           0 :     return group->meth->make_affine(group, point, ctx);
    1019             : }
    1020             : 
    1021        2352 : int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
    1022             :                           EC_POINT *points[], BN_CTX *ctx)
    1023             : {
    1024             :     size_t i;
    1025             : 
    1026        2352 :     if (group->meth->points_make_affine == 0) {
    1027           0 :         ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    1028           0 :         return 0;
    1029             :     }
    1030        9408 :     for (i = 0; i < num; i++) {
    1031        9408 :         if (group->meth != points[i]->meth) {
    1032           0 :             ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
    1033           0 :             return 0;
    1034             :         }
    1035             :     }
    1036        2352 :     return group->meth->points_make_affine(group, num, points, ctx);
    1037             : }
    1038             : 
    1039             : /*
    1040             :  * Functions for point multiplication. If group->meth->mul is 0, we use the
    1041             :  * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
    1042             :  * methods.
    1043             :  */
    1044             : 
    1045        2352 : int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
    1046             :                   size_t num, const EC_POINT *points[],
    1047             :                   const BIGNUM *scalars[], BN_CTX *ctx)
    1048             : {
    1049        2352 :     if (group->meth->mul == 0)
    1050             :         /* use default */
    1051        2352 :         return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
    1052             : 
    1053           0 :     return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
    1054             : }
    1055             : 
    1056        2352 : int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    1057             :                  const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
    1058             : {
    1059             :     /* just a convenient interface to EC_POINTs_mul() */
    1060             : 
    1061             :     const EC_POINT *points[1];
    1062             :     const BIGNUM *scalars[1];
    1063             : 
    1064        2352 :     points[0] = point;
    1065        2352 :     scalars[0] = p_scalar;
    1066             : 
    1067        2352 :     return EC_POINTs_mul(group, r, g_scalar,
    1068        2352 :                          (point != NULL
    1069        2352 :                           && p_scalar != NULL), points, scalars, ctx);
    1070             : }
    1071             : 
    1072           0 : int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
    1073             : {
    1074           0 :     if (group->meth->mul == 0)
    1075             :         /* use default */
    1076           0 :         return ec_wNAF_precompute_mult(group, ctx);
    1077             : 
    1078           0 :     if (group->meth->precompute_mult != 0)
    1079           0 :         return group->meth->precompute_mult(group, ctx);
    1080             :     else
    1081             :         return 1;               /* nothing to do, so report success */
    1082             : }
    1083             : 
    1084           0 : int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
    1085             : {
    1086           0 :     if (group->meth->mul == 0)
    1087             :         /* use default */
    1088           0 :         return ec_wNAF_have_precompute_mult(group);
    1089             : 
    1090           0 :     if (group->meth->have_precompute_mult != 0)
    1091           0 :         return group->meth->have_precompute_mult(group);
    1092             :     else
    1093             :         return 0;               /* cannot tell whether precomputation has
    1094             :                                  * been performed */
    1095             : }
    1096             : 
    1097             : /*
    1098             :  * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
    1099             :  * returns one on success. On error it returns zero.
    1100             :  */
    1101        1242 : int ec_precompute_mont_data(EC_GROUP *group)
    1102             : {
    1103        1242 :     BN_CTX *ctx = BN_CTX_new();
    1104             :     int ret = 0;
    1105             : 
    1106        1242 :     if (!EC_GROUP_VERSION(group))
    1107             :         goto err;
    1108             : 
    1109        1242 :     if (group->mont_data) {
    1110           0 :         BN_MONT_CTX_free(group->mont_data);
    1111           0 :         group->mont_data = NULL;
    1112             :     }
    1113             : 
    1114        1242 :     if (ctx == NULL)
    1115             :         goto err;
    1116             : 
    1117        1242 :     group->mont_data = BN_MONT_CTX_new();
    1118        1242 :     if (!group->mont_data)
    1119             :         goto err;
    1120             : 
    1121        1242 :     if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) {
    1122           0 :         BN_MONT_CTX_free(group->mont_data);
    1123           0 :         group->mont_data = NULL;
    1124           0 :         goto err;
    1125             :     }
    1126             : 
    1127             :     ret = 1;
    1128             : 
    1129             :  err:
    1130             : 
    1131        1242 :     if (ctx)
    1132        1242 :         BN_CTX_free(ctx);
    1133        1242 :     return ret;
    1134             : }

Generated by: LCOV version 1.10