LCOV - code coverage report
Current view: top level - dh - dh_key.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 83 94 88.3 %
Date: 2014-08-02 Functions: 9 9 100.0 %
Branches: 45 76 59.2 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/dh/dh_key.c */
       2                 :            : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3                 :            :  * All rights reserved.
       4                 :            :  *
       5                 :            :  * This package is an SSL implementation written
       6                 :            :  * by Eric Young (eay@cryptsoft.com).
       7                 :            :  * The implementation was written so as to conform with Netscapes SSL.
       8                 :            :  * 
       9                 :            :  * This library is free for commercial and non-commercial use as long as
      10                 :            :  * the following conditions are aheared to.  The following conditions
      11                 :            :  * apply to all code found in this distribution, be it the RC4, RSA,
      12                 :            :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13                 :            :  * included with this distribution is covered by the same copyright terms
      14                 :            :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15                 :            :  * 
      16                 :            :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17                 :            :  * the code are not to be removed.
      18                 :            :  * If this package is used in a product, Eric Young should be given attribution
      19                 :            :  * as the author of the parts of the library used.
      20                 :            :  * This can be in the form of a textual message at program startup or
      21                 :            :  * in documentation (online or textual) provided with the package.
      22                 :            :  * 
      23                 :            :  * Redistribution and use in source and binary forms, with or without
      24                 :            :  * modification, are permitted provided that the following conditions
      25                 :            :  * are met:
      26                 :            :  * 1. Redistributions of source code must retain the copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer.
      28                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      29                 :            :  *    notice, this list of conditions and the following disclaimer in the
      30                 :            :  *    documentation and/or other materials provided with the distribution.
      31                 :            :  * 3. All advertising materials mentioning features or use of this software
      32                 :            :  *    must display the following acknowledgement:
      33                 :            :  *    "This product includes cryptographic software written by
      34                 :            :  *     Eric Young (eay@cryptsoft.com)"
      35                 :            :  *    The word 'cryptographic' can be left out if the rouines from the library
      36                 :            :  *    being used are not cryptographic related :-).
      37                 :            :  * 4. If you include any Windows specific code (or a derivative thereof) from 
      38                 :            :  *    the apps directory (application code) you must include an acknowledgement:
      39                 :            :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40                 :            :  * 
      41                 :            :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51                 :            :  * SUCH DAMAGE.
      52                 :            :  * 
      53                 :            :  * The licence and distribution terms for any publically available version or
      54                 :            :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55                 :            :  * copied and put under another distribution licence
      56                 :            :  * [including the GNU Public Licence.]
      57                 :            :  */
      58                 :            : 
      59                 :            : #define OPENSSL_FIPSAPI
      60                 :            : 
      61                 :            : #include <stdio.h>
      62                 :            : #include "cryptlib.h"
      63                 :            : #include <openssl/bn.h>
      64                 :            : #include <openssl/rand.h>
      65                 :            : #include <openssl/dh.h>
      66                 :            : #ifdef OPENSSL_FIPS
      67                 :            : #include <openssl/fips.h>
      68                 :            : #endif
      69                 :            : 
      70                 :            : static int generate_key(DH *dh);
      71                 :            : static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
      72                 :            : static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
      73                 :            :                         const BIGNUM *a, const BIGNUM *p,
      74                 :            :                         const BIGNUM *m, BN_CTX *ctx,
      75                 :            :                         BN_MONT_CTX *m_ctx);
      76                 :            : static int dh_init(DH *dh);
      77                 :            : static int dh_finish(DH *dh);
      78                 :            : 
      79                 :       1018 : int DH_generate_key(DH *dh)
      80                 :            :         {
      81                 :       1018 :         return dh->meth->generate_key(dh);
      82                 :            :         }
      83                 :            : 
      84                 :        404 : int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
      85                 :            :         {
      86                 :        404 :         return dh->meth->compute_key(key, pub_key, dh);
      87                 :            :         }
      88                 :            : 
      89                 :          2 : int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
      90                 :            :         {
      91                 :            :         int rv, pad;
      92                 :          2 :         rv = dh->meth->compute_key(key, pub_key, dh);
      93         [ +  - ]:          2 :         if (rv <= 0)
      94                 :            :                 return rv;
      95                 :          2 :         pad = BN_num_bytes(dh->p) - rv;
      96         [ -  + ]:          2 :         if (pad > 0)
      97                 :            :                 {
      98                 :          0 :                 memmove(key + pad, key, rv);
      99                 :          0 :                 memset(key, 0, pad);
     100                 :            :                 }
     101                 :          2 :         return rv + pad;
     102                 :            :         }
     103                 :            : 
     104                 :            : static DH_METHOD dh_ossl = {
     105                 :            : "OpenSSL DH Method",
     106                 :            : generate_key,
     107                 :            : compute_key,
     108                 :            : dh_bn_mod_exp,
     109                 :            : dh_init,
     110                 :            : dh_finish,
     111                 :            : DH_FLAG_FIPS_METHOD,
     112                 :            : NULL,
     113                 :            : NULL
     114                 :            : };
     115                 :            : 
     116                 :       5970 : const DH_METHOD *DH_OpenSSL(void)
     117                 :            : {
     118                 :       5970 :         return &dh_ossl;
     119                 :            : }
     120                 :            : 
     121                 :       1018 : static int generate_key(DH *dh)
     122                 :            :         {
     123                 :       1018 :         int ok=0;
     124                 :       1018 :         int generate_new_key=0;
     125                 :            :         unsigned l;
     126                 :            :         BN_CTX *ctx;
     127                 :       1018 :         BN_MONT_CTX *mont=NULL;
     128                 :       1018 :         BIGNUM *pub_key=NULL,*priv_key=NULL;
     129                 :            : 
     130                 :            : #ifdef OPENSSL_FIPS
     131                 :            :         if (FIPS_module_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
     132                 :            :                 {
     133                 :            :                 DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
     134                 :            :                 return 0;
     135                 :            :                 }
     136                 :            : #endif
     137                 :            : 
     138                 :       1018 :         ctx = BN_CTX_new();
     139         [ +  - ]:       1018 :         if (ctx == NULL) goto err;
     140                 :            : 
     141         [ +  + ]:       1018 :         if (dh->priv_key == NULL)
     142                 :            :                 {
     143                 :       1017 :                 priv_key=BN_new();
     144         [ +  - ]:       1017 :                 if (priv_key == NULL) goto err;
     145                 :            :                 generate_new_key=1;
     146                 :            :                 }
     147                 :            :         else
     148                 :            :                 priv_key=dh->priv_key;
     149                 :            : 
     150         [ +  - ]:       1018 :         if (dh->pub_key == NULL)
     151                 :            :                 {
     152                 :       1018 :                 pub_key=BN_new();
     153         [ +  - ]:       1018 :                 if (pub_key == NULL) goto err;
     154                 :            :                 }
     155                 :            :         else
     156                 :            :                 pub_key=dh->pub_key;
     157                 :            : 
     158                 :            : 
     159         [ +  - ]:       1018 :         if (dh->flags & DH_FLAG_CACHE_MONT_P)
     160                 :            :                 {
     161                 :       1018 :                 mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
     162                 :       1018 :                                 CRYPTO_LOCK_DH, dh->p, ctx);
     163         [ +  - ]:       1018 :                 if (!mont)
     164                 :            :                         goto err;
     165                 :            :                 }
     166                 :            : 
     167         [ +  + ]:       1018 :         if (generate_new_key)
     168                 :            :                 {
     169         [ +  + ]:       1017 :                 if (dh->q)
     170                 :            :                         {
     171                 :            :                         do
     172                 :            :                                 {
     173         [ +  - ]:          1 :                                 if (!BN_rand_range(priv_key, dh->q))
     174                 :            :                                         goto err;
     175                 :            :                                 }
     176 [ -  + ][ -  + ]:          1 :                         while (BN_is_zero(priv_key) || BN_is_one(priv_key));
         [ #  # ][ #  # ]
     177                 :            :                         }
     178                 :            :                 else
     179                 :            :                         {
     180                 :            :                         /* secret exponent length */
     181         [ +  + ]:       1016 :                         l = dh->length ? dh->length : BN_num_bits(dh->p)-1;
     182         [ +  - ]:       1016 :                         if (!BN_rand(priv_key, l, 0, 0)) goto err;
     183                 :            :                         }
     184                 :            :                 }
     185                 :            : 
     186                 :            :         {
     187                 :            :                 BIGNUM local_prk;
     188                 :            :                 BIGNUM *prk;
     189                 :            : 
     190         [ +  + ]:       1018 :                 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
     191                 :            :                         {
     192                 :       1017 :                         BN_init(&local_prk);
     193                 :       1017 :                         prk = &local_prk;
     194                 :       1017 :                         BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
     195                 :            :                         }
     196                 :            :                 else
     197                 :            :                         prk = priv_key;
     198                 :            : 
     199         [ +  - ]:       1018 :                 if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err;
     200                 :            :         }
     201                 :            :                 
     202                 :       1018 :         dh->pub_key=pub_key;
     203                 :       1018 :         dh->priv_key=priv_key;
     204                 :       1018 :         ok=1;
     205                 :            : err:
     206         [ -  + ]:       1018 :         if (ok != 1)
     207                 :          0 :                 DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);
     208                 :            : 
     209 [ +  - ][ -  + ]:       1018 :         if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
     210 [ +  - ][ -  + ]:       1018 :         if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
     211                 :       1018 :         BN_CTX_free(ctx);
     212                 :       1018 :         return(ok);
     213                 :            :         }
     214                 :            : 
     215                 :        406 : static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
     216                 :            :         {
     217                 :        406 :         BN_CTX *ctx=NULL;
     218                 :        406 :         BN_MONT_CTX *mont=NULL;
     219                 :            :         BIGNUM *tmp;
     220                 :        406 :         int ret= -1;
     221                 :            :         int check_result;
     222                 :            : 
     223         [ -  + ]:        406 :         if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
     224                 :            :                 {
     225                 :          0 :                 DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
     226                 :          0 :                 goto err;
     227                 :            :                 }
     228                 :            : 
     229                 :            : #ifdef OPENSSL_FIPS
     230                 :            :         if (FIPS_module_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
     231                 :            :                 {
     232                 :            :                 DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
     233                 :            :                 goto err;
     234                 :            :                 }
     235                 :            : #endif
     236                 :            : 
     237                 :        406 :         ctx = BN_CTX_new();
     238         [ +  - ]:        406 :         if (ctx == NULL) goto err;
     239                 :        406 :         BN_CTX_start(ctx);
     240                 :        406 :         tmp = BN_CTX_get(ctx);
     241                 :            :         
     242         [ -  + ]:        406 :         if (dh->priv_key == NULL)
     243                 :            :                 {
     244                 :          0 :                 DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
     245                 :          0 :                 goto err;
     246                 :            :                 }
     247                 :            : 
     248         [ +  - ]:        406 :         if (dh->flags & DH_FLAG_CACHE_MONT_P)
     249                 :            :                 {
     250                 :        406 :                 mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
     251                 :        406 :                                 CRYPTO_LOCK_DH, dh->p, ctx);
     252         [ +  + ]:        406 :                 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
     253                 :            :                         {
     254                 :            :                         /* XXX */
     255                 :        405 :                         BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
     256                 :            :                         }
     257         [ +  - ]:        406 :                 if (!mont)
     258                 :            :                         goto err;
     259                 :            :                 }
     260                 :            : 
     261 [ +  - ][ -  + ]:        406 :         if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result)
     262                 :            :                 {
     263                 :          0 :                 DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY);
     264                 :          0 :                 goto err;
     265                 :            :                 }
     266                 :            : 
     267         [ -  + ]:        406 :         if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
     268                 :            :                 {
     269                 :          0 :                 DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);
     270                 :          0 :                 goto err;
     271                 :            :                 }
     272                 :            : 
     273                 :        406 :         ret=BN_bn2bin(tmp,key);
     274                 :            : err:
     275         [ +  - ]:        406 :         if (ctx != NULL)
     276                 :            :                 {
     277                 :        406 :                 BN_CTX_end(ctx);
     278                 :        406 :                 BN_CTX_free(ctx);
     279                 :            :                 }
     280                 :        406 :         return(ret);
     281                 :            :         }
     282                 :            : 
     283                 :       1424 : static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
     284                 :            :                         const BIGNUM *a, const BIGNUM *p,
     285                 :            :                         const BIGNUM *m, BN_CTX *ctx,
     286                 :            :                         BN_MONT_CTX *m_ctx)
     287                 :            :         {
     288                 :            :         /* If a is only one word long and constant time is false, use the faster
     289                 :            :          * exponenentiation function.
     290                 :            :          */
     291 [ +  + ][ +  + ]:       1424 :         if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0))
     292                 :            :                 {
     293                 :          2 :                 BN_ULONG A = a->d[0];
     294                 :          2 :                 return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
     295                 :            :                 }
     296                 :            :         else
     297                 :       1422 :                 return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
     298                 :            :         }
     299                 :            : 
     300                 :            : 
     301                 :       2955 : static int dh_init(DH *dh)
     302                 :            :         {
     303                 :            : #ifdef OPENSSL_FIPS
     304                 :            :         if(FIPS_selftest_failed())
     305                 :            :                 {
     306                 :            :                 FIPSerr(FIPS_F_DH_INIT,FIPS_R_FIPS_SELFTEST_FAILED);
     307                 :            :                 return 0;
     308                 :            :                 }
     309                 :            : #endif
     310                 :       2955 :         dh->flags |= DH_FLAG_CACHE_MONT_P;
     311                 :       2955 :         return(1);
     312                 :            :         }
     313                 :            : 
     314                 :       2955 : static int dh_finish(DH *dh)
     315                 :            :         {
     316         [ +  + ]:       2955 :         if(dh->method_mont_p)
     317                 :       1112 :                 BN_MONT_CTX_free(dh->method_mont_p);
     318                 :       2955 :         return(1);
     319                 :            :         }

Generated by: LCOV version 1.9