LCOV - code coverage report
Current view: top level - ec - ecp_mont.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 70 106 66.0 %
Date: 2014-08-02 Functions: 10 11 90.9 %
Branches: 28 60 46.7 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/ec/ecp_mont.c */
       2                 :            : /*
       3                 :            :  * Originally written by Bodo Moeller for the OpenSSL project.
       4                 :            :  */
       5                 :            : /* ====================================================================
       6                 :            :  * Copyright (c) 1998-2001 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                 :            :  * Portions of this software developed by SUN MICROSYSTEMS, INC.,
      61                 :            :  * and contributed to the OpenSSL project.
      62                 :            :  */
      63                 :            : 
      64                 :            : #define OPENSSL_FIPSAPI
      65                 :            : 
      66                 :            : #include <openssl/err.h>
      67                 :            : 
      68                 :            : #include "ec_lcl.h"
      69                 :            : 
      70                 :            : 
      71                 :        134 : const EC_METHOD *EC_GFp_mont_method(void)
      72                 :            :         {
      73                 :            :         static const EC_METHOD ret = {
      74                 :            :                 EC_FLAGS_DEFAULT_OCT,
      75                 :            :                 NID_X9_62_prime_field,
      76                 :            :                 ec_GFp_mont_group_init,
      77                 :            :                 ec_GFp_mont_group_finish,
      78                 :            :                 ec_GFp_mont_group_clear_finish,
      79                 :            :                 ec_GFp_mont_group_copy,
      80                 :            :                 ec_GFp_mont_group_set_curve,
      81                 :            :                 ec_GFp_simple_group_get_curve,
      82                 :            :                 ec_GFp_simple_group_get_degree,
      83                 :            :                 ec_GFp_simple_group_check_discriminant,
      84                 :            :                 ec_GFp_simple_point_init,
      85                 :            :                 ec_GFp_simple_point_finish,
      86                 :            :                 ec_GFp_simple_point_clear_finish,
      87                 :            :                 ec_GFp_simple_point_copy,
      88                 :            :                 ec_GFp_simple_point_set_to_infinity,
      89                 :            :                 ec_GFp_simple_set_Jprojective_coordinates_GFp,
      90                 :            :                 ec_GFp_simple_get_Jprojective_coordinates_GFp,
      91                 :            :                 ec_GFp_simple_point_set_affine_coordinates,
      92                 :            :                 ec_GFp_simple_point_get_affine_coordinates,
      93                 :            :                 0,0,0,
      94                 :            :                 ec_GFp_simple_add,
      95                 :            :                 ec_GFp_simple_dbl,
      96                 :            :                 ec_GFp_simple_invert,
      97                 :            :                 ec_GFp_simple_is_at_infinity,
      98                 :            :                 ec_GFp_simple_is_on_curve,
      99                 :            :                 ec_GFp_simple_cmp,
     100                 :            :                 ec_GFp_simple_make_affine,
     101                 :            :                 ec_GFp_simple_points_make_affine,
     102                 :            :                 0 /* mul */,
     103                 :            :                 0 /* precompute_mult */,
     104                 :            :                 0 /* have_precompute_mult */,   
     105                 :            :                 ec_GFp_mont_field_mul,
     106                 :            :                 ec_GFp_mont_field_sqr,
     107                 :            :                 0 /* field_div */,
     108                 :            :                 ec_GFp_mont_field_encode,
     109                 :            :                 ec_GFp_mont_field_decode,
     110                 :            :                 ec_GFp_mont_field_set_to_one };
     111                 :            : 
     112                 :        134 :         return &ret;
     113                 :            :         }
     114                 :            : 
     115                 :            : 
     116                 :        223 : int ec_GFp_mont_group_init(EC_GROUP *group)
     117                 :            :         {
     118                 :            :         int ok;
     119                 :            : 
     120                 :        223 :         ok = ec_GFp_simple_group_init(group);
     121                 :        223 :         group->field_data1 = NULL;
     122                 :        223 :         group->field_data2 = NULL;
     123                 :        223 :         return ok;
     124                 :            :         }
     125                 :            : 
     126                 :            : 
     127                 :        223 : void ec_GFp_mont_group_finish(EC_GROUP *group)
     128                 :            :         {
     129         [ +  - ]:        223 :         if (group->field_data1 != NULL)
     130                 :            :                 {
     131                 :        223 :                 BN_MONT_CTX_free(group->field_data1);
     132                 :        223 :                 group->field_data1 = NULL;
     133                 :            :                 }
     134         [ +  - ]:        223 :         if (group->field_data2 != NULL)
     135                 :            :                 {
     136                 :        223 :                 BN_free(group->field_data2);
     137                 :        223 :                 group->field_data2 = NULL;
     138                 :            :                 }
     139                 :        223 :         ec_GFp_simple_group_finish(group);
     140                 :        223 :         }
     141                 :            : 
     142                 :            : 
     143                 :          0 : void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
     144                 :            :         {
     145         [ #  # ]:          0 :         if (group->field_data1 != NULL)
     146                 :            :                 {
     147                 :          0 :                 BN_MONT_CTX_free(group->field_data1);
     148                 :          0 :                 group->field_data1 = NULL;
     149                 :            :                 }
     150         [ #  # ]:          0 :         if (group->field_data2 != NULL)
     151                 :            :                 {
     152                 :          0 :                 BN_clear_free(group->field_data2);
     153                 :          0 :                 group->field_data2 = NULL;
     154                 :            :                 }
     155                 :          0 :         ec_GFp_simple_group_clear_finish(group);
     156                 :          0 :         }
     157                 :            : 
     158                 :            : 
     159                 :         89 : int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
     160                 :            :         {
     161         [ -  + ]:         89 :         if (dest->field_data1 != NULL)
     162                 :            :                 {
     163                 :          0 :                 BN_MONT_CTX_free(dest->field_data1);
     164                 :          0 :                 dest->field_data1 = NULL;
     165                 :            :                 }
     166         [ -  + ]:         89 :         if (dest->field_data2 != NULL)
     167                 :            :                 {
     168                 :          0 :                 BN_clear_free(dest->field_data2);
     169                 :          0 :                 dest->field_data2 = NULL;
     170                 :            :                 }
     171                 :            : 
     172         [ +  - ]:         89 :         if (!ec_GFp_simple_group_copy(dest, src)) return 0;
     173                 :            : 
     174         [ +  - ]:         89 :         if (src->field_data1 != NULL)
     175                 :            :                 {
     176                 :         89 :                 dest->field_data1 = BN_MONT_CTX_new();
     177         [ +  - ]:         89 :                 if (dest->field_data1 == NULL) return 0;
     178         [ +  - ]:         89 :                 if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
     179                 :            :                 }
     180         [ +  - ]:         89 :         if (src->field_data2 != NULL)
     181                 :            :                 {
     182                 :         89 :                 dest->field_data2 = BN_dup(src->field_data2);
     183         [ -  + ]:         89 :                 if (dest->field_data2 == NULL) goto err;
     184                 :            :                 }
     185                 :            : 
     186                 :            :         return 1;
     187                 :            : 
     188                 :            :  err:
     189         [ #  # ]:          0 :         if (dest->field_data1 != NULL)
     190                 :            :                 {
     191                 :          0 :                 BN_MONT_CTX_free(dest->field_data1);
     192                 :          0 :                 dest->field_data1 = NULL;
     193                 :            :                 }
     194                 :            :         return 0;       
     195                 :            :         }
     196                 :            : 
     197                 :            : 
     198                 :        140 : int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
     199                 :            :         {
     200                 :        140 :         BN_CTX *new_ctx = NULL;
     201                 :        140 :         BN_MONT_CTX *mont = NULL;
     202                 :        140 :         BIGNUM *one = NULL;
     203                 :        140 :         int ret = 0;
     204                 :            : 
     205         [ +  + ]:        140 :         if (group->field_data1 != NULL)
     206                 :            :                 {
     207                 :          6 :                 BN_MONT_CTX_free(group->field_data1);
     208                 :          6 :                 group->field_data1 = NULL;
     209                 :            :                 }
     210         [ +  + ]:        140 :         if (group->field_data2 != NULL)
     211                 :            :                 {
     212                 :          6 :                 BN_free(group->field_data2);
     213                 :          6 :                 group->field_data2 = NULL;
     214                 :            :                 }
     215                 :            :         
     216         [ -  + ]:        140 :         if (ctx == NULL)
     217                 :            :                 {
     218                 :          0 :                 ctx = new_ctx = BN_CTX_new();
     219         [ #  # ]:          0 :                 if (ctx == NULL)
     220                 :            :                         return 0;
     221                 :            :                 }
     222                 :            : 
     223                 :        140 :         mont = BN_MONT_CTX_new();
     224         [ +  - ]:        140 :         if (mont == NULL) goto err;
     225         [ -  + ]:        140 :         if (!BN_MONT_CTX_set(mont, p, ctx))
     226                 :            :                 {
     227                 :          0 :                 ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
     228                 :          0 :                 goto err;
     229                 :            :                 }
     230                 :        140 :         one = BN_new();
     231         [ +  - ]:        140 :         if (one == NULL) goto err;
     232         [ +  - ]:        140 :         if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
     233                 :            : 
     234                 :        140 :         group->field_data1 = mont;
     235                 :        140 :         mont = NULL;
     236                 :        140 :         group->field_data2 = one;
     237                 :        140 :         one = NULL;
     238                 :            : 
     239                 :        140 :         ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
     240                 :            : 
     241         [ -  + ]:        140 :         if (!ret)
     242                 :            :                 {
     243                 :          0 :                 BN_MONT_CTX_free(group->field_data1);
     244                 :          0 :                 group->field_data1 = NULL;
     245                 :          0 :                 BN_free(group->field_data2);
     246                 :          0 :                 group->field_data2 = NULL;
     247                 :            :                 }
     248                 :            : 
     249                 :            :  err:
     250         [ -  + ]:        140 :         if (new_ctx != NULL)
     251                 :          0 :                 BN_CTX_free(new_ctx);
     252         [ -  + ]:        140 :         if (mont != NULL)
     253                 :          0 :                 BN_MONT_CTX_free(mont);
     254                 :        140 :         return ret;
     255                 :            :         }
     256                 :            : 
     257                 :            : 
     258                 :     748048 : int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
     259                 :            :         {
     260         [ -  + ]:     748048 :         if (group->field_data1 == NULL)
     261                 :            :                 {
     262                 :          0 :                 ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
     263                 :          0 :                 return 0;
     264                 :            :                 }
     265                 :            : 
     266                 :     748048 :         return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
     267                 :            :         }
     268                 :            : 
     269                 :            : 
     270                 :     632410 : int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
     271                 :            :         {
     272         [ -  + ]:     632410 :         if (group->field_data1 == NULL)
     273                 :            :                 {
     274                 :          0 :                 ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
     275                 :          0 :                 return 0;
     276                 :            :                 }
     277                 :            : 
     278                 :     632410 :         return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
     279                 :            :         }
     280                 :            : 
     281                 :            : 
     282                 :       1472 : int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
     283                 :            :         {
     284         [ -  + ]:       1472 :         if (group->field_data1 == NULL)
     285                 :            :                 {
     286                 :          0 :                 ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
     287                 :          0 :                 return 0;
     288                 :            :                 }
     289                 :            : 
     290                 :       1472 :         return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
     291                 :            :         }
     292                 :            : 
     293                 :            : 
     294                 :        377 : int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
     295                 :            :         {
     296         [ -  + ]:        377 :         if (group->field_data1 == NULL)
     297                 :            :                 {
     298                 :          0 :                 ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
     299                 :          0 :                 return 0;
     300                 :            :                 }
     301                 :            : 
     302                 :        377 :         return BN_from_montgomery(r, a, group->field_data1, ctx);
     303                 :            :         }
     304                 :            : 
     305                 :            : 
     306                 :       4902 : int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
     307                 :            :         {
     308         [ -  + ]:       4902 :         if (group->field_data2 == NULL)
     309                 :            :                 {
     310                 :          0 :                 ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
     311                 :          0 :                 return 0;
     312                 :            :                 }
     313                 :            : 
     314         [ +  - ]:       4902 :         if (!BN_copy(r, group->field_data2)) return 0;
     315                 :       4902 :         return 1;
     316                 :            :         }

Generated by: LCOV version 1.9