LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/ecdsa - ecs_ossl.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 209 0.0 %
Date: 2015-10-10 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* crypto/ecdsa/ecs_ossl.c */
       2             : /*
       3             :  * Written by Nils Larsch for the OpenSSL project
       4             :  */
       5             : /* ====================================================================
       6             :  * Copyright (c) 1998-2004 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             : #include "ecs_locl.h"
      60             : #include <openssl/err.h>
      61             : #include <openssl/obj_mac.h>
      62             : #include <openssl/bn.h>
      63             : 
      64             : static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
      65             :                                 const BIGNUM *, const BIGNUM *,
      66             :                                 EC_KEY *eckey);
      67             : static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
      68             :                             BIGNUM **rp);
      69             : static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
      70             :                            const ECDSA_SIG *sig, EC_KEY *eckey);
      71             : 
      72             : static ECDSA_METHOD openssl_ecdsa_meth = {
      73             :     "OpenSSL ECDSA method",
      74             :     ecdsa_do_sign,
      75             :     ecdsa_sign_setup,
      76             :     ecdsa_do_verify,
      77             : #if 0
      78             :     NULL,                       /* init */
      79             :     NULL,                       /* finish */
      80             : #endif
      81             :     0,                          /* flags */
      82             :     NULL                        /* app_data */
      83             : };
      84             : 
      85           0 : const ECDSA_METHOD *ECDSA_OpenSSL(void)
      86             : {
      87           0 :     return &openssl_ecdsa_meth;
      88             : }
      89             : 
      90           0 : static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
      91             :                             BIGNUM **rp)
      92             : {
      93             :     BN_CTX *ctx = NULL;
      94             :     BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
      95             :     EC_POINT *tmp_point = NULL;
      96             :     const EC_GROUP *group;
      97             :     int ret = 0;
      98             : 
      99           0 :     if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
     100           0 :         ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
     101           0 :         return 0;
     102             :     }
     103             : 
     104           0 :     if (ctx_in == NULL) {
     105           0 :         if ((ctx = BN_CTX_new()) == NULL) {
     106           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
     107           0 :             return 0;
     108             :         }
     109             :     } else
     110             :         ctx = ctx_in;
     111             : 
     112           0 :     k = BN_new();               /* this value is later returned in *kinvp */
     113           0 :     r = BN_new();               /* this value is later returned in *rp */
     114           0 :     order = BN_new();
     115           0 :     X = BN_new();
     116           0 :     if (!k || !r || !order || !X) {
     117           0 :         ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
     118           0 :         goto err;
     119             :     }
     120           0 :     if ((tmp_point = EC_POINT_new(group)) == NULL) {
     121           0 :         ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
     122           0 :         goto err;
     123             :     }
     124           0 :     if (!EC_GROUP_get_order(group, order, ctx)) {
     125           0 :         ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
     126           0 :         goto err;
     127             :     }
     128             : 
     129             :     do {
     130             :         /* get random k */
     131             :         do
     132           0 :             if (!BN_rand_range(k, order)) {
     133           0 :                 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
     134             :                          ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
     135           0 :                 goto err;
     136             :             }
     137           0 :         while (BN_is_zero(k)) ;
     138             : 
     139             :         /*
     140             :          * We do not want timing information to leak the length of k, so we
     141             :          * compute G*k using an equivalent scalar of fixed bit-length.
     142             :          */
     143             : 
     144           0 :         if (!BN_add(k, k, order))
     145             :             goto err;
     146           0 :         if (BN_num_bits(k) <= BN_num_bits(order))
     147           0 :             if (!BN_add(k, k, order))
     148             :                 goto err;
     149             : 
     150             :         /* compute r the x-coordinate of generator * k */
     151           0 :         if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
     152           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
     153           0 :             goto err;
     154             :         }
     155           0 :         if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
     156             :             NID_X9_62_prime_field) {
     157           0 :             if (!EC_POINT_get_affine_coordinates_GFp
     158           0 :                 (group, tmp_point, X, NULL, ctx)) {
     159           0 :                 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
     160           0 :                 goto err;
     161             :             }
     162             :         }
     163             : #ifndef OPENSSL_NO_EC2M
     164             :         else {                  /* NID_X9_62_characteristic_two_field */
     165             : 
     166           0 :             if (!EC_POINT_get_affine_coordinates_GF2m(group,
     167             :                                                       tmp_point, X, NULL,
     168             :                                                       ctx)) {
     169           0 :                 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
     170           0 :                 goto err;
     171             :             }
     172             :         }
     173             : #endif
     174           0 :         if (!BN_nnmod(r, X, order, ctx)) {
     175           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
     176           0 :             goto err;
     177             :         }
     178             :     }
     179           0 :     while (BN_is_zero(r));
     180             : 
     181             :     /* compute the inverse of k */
     182           0 :     if (EC_GROUP_get_mont_data(group) != NULL) {
     183             :         /*
     184             :          * We want inverse in constant time, therefore we utilize the fact
     185             :          * order must be prime and use Fermats Little Theorem instead.
     186             :          */
     187           0 :         if (!BN_set_word(X, 2)) {
     188           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
     189           0 :             goto err;
     190             :         }
     191           0 :         if (!BN_mod_sub(X, order, X, order, ctx)) {
     192           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
     193           0 :             goto err;
     194             :         }
     195           0 :         BN_set_flags(X, BN_FLG_CONSTTIME);
     196           0 :         if (!BN_mod_exp_mont_consttime
     197           0 :             (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
     198           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
     199           0 :             goto err;
     200             :         }
     201             :     } else {
     202           0 :         if (!BN_mod_inverse(k, k, order, ctx)) {
     203           0 :             ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
     204           0 :             goto err;
     205             :         }
     206             :     }
     207             : 
     208             :     /* clear old values if necessary */
     209           0 :     if (*rp != NULL)
     210           0 :         BN_clear_free(*rp);
     211           0 :     if (*kinvp != NULL)
     212           0 :         BN_clear_free(*kinvp);
     213             :     /* save the pre-computed values  */
     214           0 :     *rp = r;
     215           0 :     *kinvp = k;
     216             :     ret = 1;
     217             :  err:
     218           0 :     if (!ret) {
     219           0 :         if (k != NULL)
     220           0 :             BN_clear_free(k);
     221           0 :         if (r != NULL)
     222           0 :             BN_clear_free(r);
     223             :     }
     224           0 :     if (ctx_in == NULL)
     225           0 :         BN_CTX_free(ctx);
     226           0 :     if (order != NULL)
     227           0 :         BN_free(order);
     228           0 :     if (tmp_point != NULL)
     229           0 :         EC_POINT_free(tmp_point);
     230           0 :     if (X)
     231           0 :         BN_clear_free(X);
     232           0 :     return (ret);
     233             : }
     234             : 
     235           0 : static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
     236             :                                 const BIGNUM *in_kinv, const BIGNUM *in_r,
     237             :                                 EC_KEY *eckey)
     238             : {
     239             :     int ok = 0, i;
     240           0 :     BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
     241             :     const BIGNUM *ckinv;
     242             :     BN_CTX *ctx = NULL;
     243             :     const EC_GROUP *group;
     244             :     ECDSA_SIG *ret;
     245             :     ECDSA_DATA *ecdsa;
     246             :     const BIGNUM *priv_key;
     247             : 
     248           0 :     ecdsa = ecdsa_check(eckey);
     249           0 :     group = EC_KEY_get0_group(eckey);
     250           0 :     priv_key = EC_KEY_get0_private_key(eckey);
     251             : 
     252           0 :     if (group == NULL || priv_key == NULL || ecdsa == NULL) {
     253           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
     254           0 :         return NULL;
     255             :     }
     256             : 
     257           0 :     ret = ECDSA_SIG_new();
     258           0 :     if (!ret) {
     259           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
     260           0 :         return NULL;
     261             :     }
     262           0 :     s = ret->s;
     263             : 
     264           0 :     if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
     265           0 :         (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
     266           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
     267           0 :         goto err;
     268             :     }
     269             : 
     270           0 :     if (!EC_GROUP_get_order(group, order, ctx)) {
     271           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
     272           0 :         goto err;
     273             :     }
     274           0 :     i = BN_num_bits(order);
     275             :     /*
     276             :      * Need to truncate digest if it is too long: first truncate whole bytes.
     277             :      */
     278           0 :     if (8 * dgst_len > i)
     279           0 :         dgst_len = (i + 7) / 8;
     280           0 :     if (!BN_bin2bn(dgst, dgst_len, m)) {
     281           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
     282           0 :         goto err;
     283             :     }
     284             :     /* If still too long truncate remaining bits with a shift */
     285           0 :     if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
     286           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
     287           0 :         goto err;
     288             :     }
     289             :     do {
     290           0 :         if (in_kinv == NULL || in_r == NULL) {
     291           0 :             if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) {
     292           0 :                 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB);
     293           0 :                 goto err;
     294             :             }
     295           0 :             ckinv = kinv;
     296             :         } else {
     297             :             ckinv = in_kinv;
     298           0 :             if (BN_copy(ret->r, in_r) == NULL) {
     299           0 :                 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
     300           0 :                 goto err;
     301             :             }
     302             :         }
     303             : 
     304           0 :         if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
     305           0 :             ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
     306           0 :             goto err;
     307             :         }
     308           0 :         if (!BN_mod_add_quick(s, tmp, m, order)) {
     309           0 :             ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
     310           0 :             goto err;
     311             :         }
     312           0 :         if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
     313           0 :             ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
     314           0 :             goto err;
     315             :         }
     316           0 :         if (BN_is_zero(s)) {
     317             :             /*
     318             :              * if kinv and r have been supplied by the caller don't to
     319             :              * generate new kinv and r values
     320             :              */
     321           0 :             if (in_kinv != NULL && in_r != NULL) {
     322           0 :                 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
     323             :                          ECDSA_R_NEED_NEW_SETUP_VALUES);
     324           0 :                 goto err;
     325             :             }
     326             :         } else
     327             :             /* s != 0 => we have a valid signature */
     328             :             break;
     329             :     }
     330             :     while (1);
     331             : 
     332             :     ok = 1;
     333             :  err:
     334           0 :     if (!ok) {
     335           0 :         ECDSA_SIG_free(ret);
     336             :         ret = NULL;
     337             :     }
     338           0 :     if (ctx)
     339           0 :         BN_CTX_free(ctx);
     340           0 :     if (m)
     341           0 :         BN_clear_free(m);
     342           0 :     if (tmp)
     343           0 :         BN_clear_free(tmp);
     344           0 :     if (order)
     345           0 :         BN_free(order);
     346           0 :     if (kinv)
     347           0 :         BN_clear_free(kinv);
     348           0 :     return ret;
     349             : }
     350             : 
     351           0 : static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
     352             :                            const ECDSA_SIG *sig, EC_KEY *eckey)
     353             : {
     354             :     int ret = -1, i;
     355             :     BN_CTX *ctx;
     356             :     BIGNUM *order, *u1, *u2, *m, *X;
     357             :     EC_POINT *point = NULL;
     358             :     const EC_GROUP *group;
     359             :     const EC_POINT *pub_key;
     360             : 
     361             :     /* check input values */
     362           0 :     if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
     363           0 :         (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
     364           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
     365           0 :         return -1;
     366             :     }
     367             : 
     368           0 :     ctx = BN_CTX_new();
     369           0 :     if (!ctx) {
     370           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
     371           0 :         return -1;
     372             :     }
     373           0 :     BN_CTX_start(ctx);
     374           0 :     order = BN_CTX_get(ctx);
     375           0 :     u1 = BN_CTX_get(ctx);
     376           0 :     u2 = BN_CTX_get(ctx);
     377           0 :     m = BN_CTX_get(ctx);
     378           0 :     X = BN_CTX_get(ctx);
     379           0 :     if (!X) {
     380           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     381           0 :         goto err;
     382             :     }
     383             : 
     384           0 :     if (!EC_GROUP_get_order(group, order, ctx)) {
     385           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
     386           0 :         goto err;
     387             :     }
     388             : 
     389           0 :     if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
     390           0 :         BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
     391           0 :         BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
     392           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
     393             :         ret = 0;                /* signature is invalid */
     394           0 :         goto err;
     395             :     }
     396             :     /* calculate tmp1 = inv(S) mod order */
     397           0 :     if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
     398           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     399           0 :         goto err;
     400             :     }
     401             :     /* digest -> m */
     402           0 :     i = BN_num_bits(order);
     403             :     /*
     404             :      * Need to truncate digest if it is too long: first truncate whole bytes.
     405             :      */
     406           0 :     if (8 * dgst_len > i)
     407           0 :         dgst_len = (i + 7) / 8;
     408           0 :     if (!BN_bin2bn(dgst, dgst_len, m)) {
     409           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     410           0 :         goto err;
     411             :     }
     412             :     /* If still too long truncate remaining bits with a shift */
     413           0 :     if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
     414           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     415           0 :         goto err;
     416             :     }
     417             :     /* u1 = m * tmp mod order */
     418           0 :     if (!BN_mod_mul(u1, m, u2, order, ctx)) {
     419           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     420           0 :         goto err;
     421             :     }
     422             :     /* u2 = r * w mod q */
     423           0 :     if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
     424           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     425           0 :         goto err;
     426             :     }
     427             : 
     428           0 :     if ((point = EC_POINT_new(group)) == NULL) {
     429           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
     430           0 :         goto err;
     431             :     }
     432           0 :     if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
     433           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
     434           0 :         goto err;
     435             :     }
     436           0 :     if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
     437             :         NID_X9_62_prime_field) {
     438           0 :         if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
     439           0 :             ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
     440           0 :             goto err;
     441             :         }
     442             :     }
     443             : #ifndef OPENSSL_NO_EC2M
     444             :     else {                      /* NID_X9_62_characteristic_two_field */
     445             : 
     446           0 :         if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) {
     447           0 :             ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
     448           0 :             goto err;
     449             :         }
     450             :     }
     451             : #endif
     452           0 :     if (!BN_nnmod(u1, X, order, ctx)) {
     453           0 :         ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
     454           0 :         goto err;
     455             :     }
     456             :     /*  if the signature is correct u1 is equal to sig->r */
     457           0 :     ret = (BN_ucmp(u1, sig->r) == 0);
     458             :  err:
     459           0 :     BN_CTX_end(ctx);
     460           0 :     BN_CTX_free(ctx);
     461           0 :     if (point)
     462           0 :         EC_POINT_free(point);
     463           0 :     return ret;
     464             : }

Generated by: LCOV version 1.10