LCOV - code coverage report
Current view: top level - dsa - dsa_gen.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 103 273 37.7 %
Date: 2014-08-02 Functions: 2 4 50.0 %
Branches: 68 328 20.7 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/dsa/dsa_gen.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                 :            : #undef GENUINE_DSA
      60                 :            : 
      61                 :            : #ifdef GENUINE_DSA
      62                 :            : /* Parameter generation follows the original release of FIPS PUB 186,
      63                 :            :  * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
      64                 :            : #define HASH    EVP_sha()
      65                 :            : #else
      66                 :            : /* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
      67                 :            :  * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
      68                 :            :  * FIPS PUB 180-1) */
      69                 :            : #define HASH    EVP_sha1()
      70                 :            : #endif 
      71                 :            : 
      72                 :            : #include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
      73                 :            : 
      74                 :            : #ifndef OPENSSL_NO_SHA
      75                 :            : 
      76                 :            : #define OPENSSL_FIPSAPI
      77                 :            : 
      78                 :            : #include <stdio.h>
      79                 :            : #include "cryptlib.h"
      80                 :            : #include <openssl/evp.h>
      81                 :            : #include <openssl/bn.h>
      82                 :            : #include <openssl/rand.h>
      83                 :            : #include <openssl/sha.h>
      84                 :            : #ifdef OPENSSL_FIPS
      85                 :            : #include <openssl/fips.h>
      86                 :            : #include <openssl/fips_rand.h>
      87                 :            : #endif
      88                 :            : 
      89                 :            : #include "dsa_locl.h"
      90                 :            : 
      91                 :          2 : int DSA_generate_parameters_ex(DSA *ret, int bits,
      92                 :            :                 const unsigned char *seed_in, int seed_len,
      93                 :            :                 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
      94                 :            :         {
      95         [ -  + ]:          2 :         if(ret->meth->dsa_paramgen)
      96                 :          0 :                 return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
      97                 :            :                                 counter_ret, h_ret, cb);
      98                 :            :         else
      99                 :            :                 {
     100                 :            :                 const EVP_MD *evpmd;
     101                 :          2 :                 size_t qbits = bits >= 2048 ? 256 : 160;
     102                 :            : 
     103         [ -  + ]:          2 :                 if (bits >= 2048)
     104                 :            :                         {
     105                 :          0 :                         qbits = 256;
     106                 :          0 :                         evpmd = EVP_sha256();
     107                 :            :                         }
     108                 :            :                 else
     109                 :            :                         {
     110                 :          2 :                         qbits = 160;
     111                 :          2 :                         evpmd = EVP_sha1();
     112                 :            :                         }
     113                 :            : 
     114                 :          2 :                 return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
     115                 :            :                         seed_in, seed_len, NULL, counter_ret, h_ret, cb);
     116                 :            :                 }
     117                 :            :         }
     118                 :            : 
     119                 :          2 : int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
     120                 :            :         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
     121                 :            :         unsigned char *seed_out,
     122                 :            :         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
     123                 :            :         {
     124                 :          2 :         int ok=0;
     125                 :            :         unsigned char seed[SHA256_DIGEST_LENGTH];
     126                 :            :         unsigned char md[SHA256_DIGEST_LENGTH];
     127                 :            :         unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH];
     128                 :            :         BIGNUM *r0,*W,*X,*c,*test;
     129                 :          2 :         BIGNUM *g=NULL,*q=NULL,*p=NULL;
     130                 :          2 :         BN_MONT_CTX *mont=NULL;
     131                 :          2 :         int i, k, n=0, m=0, qsize = qbits >> 3;
     132                 :          2 :         int counter=0;
     133                 :          2 :         int r=0;
     134                 :          2 :         BN_CTX *ctx=NULL;
     135                 :          2 :         unsigned int h=2;
     136                 :            : 
     137                 :            : #ifdef OPENSSL_FIPS
     138                 :            :         if(FIPS_selftest_failed())
     139                 :            :             {
     140                 :            :             FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, FIPS_R_FIPS_SELFTEST_FAILED);
     141                 :            :             goto err;
     142                 :            :             }
     143                 :            : 
     144                 :            :         if (FIPS_module_mode() && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW) 
     145                 :            :                         && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
     146                 :            :                 {
     147                 :            :                 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL);
     148                 :            :                 goto err;
     149                 :            :                 }
     150                 :            : #endif
     151                 :            : 
     152 [ -  + ][ #  # ]:          2 :         if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
     153                 :            :             qsize != SHA256_DIGEST_LENGTH)
     154                 :            :                 /* invalid q size */
     155                 :            :                 return 0;
     156                 :            : 
     157         [ -  + ]:          2 :         if (evpmd == NULL)
     158                 :            :                 /* use SHA1 as default */
     159                 :          0 :                 evpmd = EVP_sha1();
     160                 :            : 
     161         [ -  + ]:          2 :         if (bits < 512)
     162                 :          0 :                 bits = 512;
     163                 :            : 
     164                 :          2 :         bits = (bits+63)/64*64;
     165                 :            : 
     166                 :            :         /* NB: seed_len == 0 is special case: copy generated seed to
     167                 :            :          * seed_in if it is not NULL.
     168                 :            :          */
     169 [ +  - ][ -  + ]:          2 :         if (seed_len && (seed_len < (size_t)qsize))
     170                 :          0 :                 seed_in = NULL;         /* seed buffer too small -- ignore */
     171         [ -  + ]:          2 :         if (seed_len > (size_t)qsize) 
     172                 :          0 :                 seed_len = qsize;       /* App. 2.2 of FIPS PUB 186 allows larger SEED,
     173                 :            :                                          * but our internal buffers are restricted to 160 bits*/
     174         [ +  - ]:          2 :         if (seed_in != NULL)
     175                 :            :                 memcpy(seed, seed_in, seed_len);
     176                 :            : 
     177         [ +  - ]:          2 :         if ((ctx=BN_CTX_new()) == NULL)
     178                 :            :                 goto err;
     179                 :            : 
     180         [ +  - ]:          2 :         if ((mont=BN_MONT_CTX_new()) == NULL)
     181                 :            :                 goto err;
     182                 :            : 
     183                 :          2 :         BN_CTX_start(ctx);
     184                 :          2 :         r0 = BN_CTX_get(ctx);
     185                 :          2 :         g = BN_CTX_get(ctx);
     186                 :          2 :         W = BN_CTX_get(ctx);
     187                 :          2 :         q = BN_CTX_get(ctx);
     188                 :          2 :         X = BN_CTX_get(ctx);
     189                 :          2 :         c = BN_CTX_get(ctx);
     190                 :          2 :         p = BN_CTX_get(ctx);
     191                 :          2 :         test = BN_CTX_get(ctx);
     192                 :            : 
     193         [ +  - ]:          2 :         if (!BN_lshift(test,BN_value_one(),bits-1))
     194                 :            :                 goto err;
     195                 :            : 
     196                 :            :         for (;;)
     197                 :            :                 {
     198                 :            :                 for (;;) /* find q */
     199                 :            :                         {
     200                 :            :                         int seed_is_random;
     201                 :            : 
     202                 :            :                         /* step 1 */
     203         [ +  - ]:          2 :                         if(!BN_GENCB_call(cb, 0, m++))
     204                 :            :                                 goto err;
     205                 :            : 
     206         [ -  + ]:          2 :                         if (!seed_len)
     207                 :            :                                 {
     208         [ #  # ]:          0 :                                 if (RAND_pseudo_bytes(seed, qsize) < 0)
     209                 :            :                                         goto err;
     210                 :            :                                 seed_is_random = 1;
     211                 :            :                                 }
     212                 :            :                         else
     213                 :            :                                 {
     214                 :            :                                 seed_is_random = 0;
     215                 :            :                                 seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
     216                 :            :                                 }
     217                 :          2 :                         memcpy(buf , seed, qsize);
     218                 :          2 :                         memcpy(buf2, seed, qsize);
     219                 :            :                         /* precompute "SEED + 1" for step 7: */
     220         [ +  - ]:          2 :                         for (i = qsize-1; i >= 0; i--)
     221                 :            :                                 {
     222                 :          2 :                                 buf[i]++;
     223         [ -  + ]:          2 :                                 if (buf[i] != 0)
     224                 :            :                                         break;
     225                 :            :                                 }
     226                 :            : 
     227                 :            :                         /* step 2 */
     228         [ +  - ]:          2 :                         if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL))
     229                 :            :                                 goto err;
     230         [ +  - ]:          2 :                         if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL))
     231                 :            :                                 goto err;
     232         [ +  + ]:         42 :                         for (i = 0; i < qsize; i++)
     233                 :         40 :                                 md[i]^=buf2[i];
     234                 :            : 
     235                 :            :                         /* step 3 */
     236                 :          2 :                         md[0] |= 0x80;
     237                 :          2 :                         md[qsize-1] |= 0x01;
     238         [ +  - ]:          2 :                         if (!BN_bin2bn(md, qsize, q))
     239                 :            :                                 goto err;
     240                 :            : 
     241                 :            :                         /* step 4 */
     242                 :          2 :                         r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
     243                 :            :                                         seed_is_random, cb);
     244         [ -  + ]:          2 :                         if (r > 0)
     245                 :            :                                 break;
     246         [ #  # ]:          0 :                         if (r != 0)
     247                 :            :                                 goto err;
     248                 :            : 
     249                 :            :                         /* do a callback call */
     250                 :            :                         /* step 5 */
     251                 :            :                         }
     252                 :            : 
     253         [ +  - ]:          2 :                 if(!BN_GENCB_call(cb, 2, 0)) goto err;
     254         [ +  - ]:          2 :                 if(!BN_GENCB_call(cb, 3, 0)) goto err;
     255                 :            : 
     256                 :            :                 /* step 6 */
     257                 :          2 :                 counter=0;
     258                 :            :                 /* "offset = 2" */
     259                 :            : 
     260                 :          2 :                 n=(bits-1)/160;
     261                 :            : 
     262                 :            :                 for (;;)
     263                 :            :                         {
     264 [ +  + ][ +  - ]:        212 :                         if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
     265                 :            :                                 goto err;
     266                 :            : 
     267                 :            :                         /* step 7 */
     268                 :        212 :                         BN_zero(W);
     269                 :            :                         /* now 'buf' contains "SEED + offset - 1" */
     270         [ +  + ]:       1060 :                         for (k=0; k<=n; k++)
     271                 :            :                                 {
     272                 :            :                                 /* obtain "SEED + offset + k" by incrementing: */
     273         [ +  - ]:        852 :                                 for (i = qsize-1; i >= 0; i--)
     274                 :            :                                         {
     275                 :        852 :                                         buf[i]++;
     276         [ +  + ]:        852 :                                         if (buf[i] != 0)
     277                 :            :                                                 break;
     278                 :            :                                         }
     279                 :            : 
     280         [ +  - ]:        848 :                                 if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
     281                 :            :                                                                         NULL))
     282                 :            :                                         goto err;
     283                 :            : 
     284                 :            :                                 /* step 8 */
     285         [ +  - ]:        848 :                                 if (!BN_bin2bn(md, qsize, r0))
     286                 :            :                                         goto err;
     287         [ +  - ]:        848 :                                 if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err;
     288         [ +  - ]:        848 :                                 if (!BN_add(W,W,r0)) goto err;
     289                 :            :                                 }
     290                 :            : 
     291                 :            :                         /* more of step 8 */
     292         [ +  - ]:        212 :                         if (!BN_mask_bits(W,bits-1)) goto err;
     293         [ +  - ]:        212 :                         if (!BN_copy(X,W)) goto err;
     294         [ +  - ]:        212 :                         if (!BN_add(X,X,test)) goto err;
     295                 :            : 
     296                 :            :                         /* step 9 */
     297         [ +  - ]:        212 :                         if (!BN_lshift1(r0,q)) goto err;
     298         [ +  - ]:        212 :                         if (!BN_mod(c,X,r0,ctx)) goto err;
     299         [ +  - ]:        212 :                         if (!BN_sub(r0,c,BN_value_one())) goto err;
     300         [ +  - ]:        212 :                         if (!BN_sub(p,X,r0)) goto err;
     301                 :            : 
     302                 :            :                         /* step 10 */
     303         [ +  - ]:        212 :                         if (BN_cmp(p,test) >= 0)
     304                 :            :                                 {
     305                 :            :                                 /* step 11 */
     306                 :        212 :                                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
     307                 :            :                                                 ctx, 1, cb);
     308         [ +  + ]:        212 :                                 if (r > 0)
     309                 :            :                                                 goto end; /* found it */
     310         [ +  - ]:        210 :                                 if (r != 0)
     311                 :            :                                         goto err;
     312                 :            :                                 }
     313                 :            : 
     314                 :            :                         /* step 13 */
     315                 :        210 :                         counter++;
     316                 :            :                         /* "offset = offset + n + 1" */
     317                 :            : 
     318                 :            :                         /* step 14 */
     319         [ -  + ]:        210 :                         if (counter >= 4096) break;
     320                 :            :                         }
     321                 :            :                 }
     322                 :            : end:
     323         [ +  - ]:          2 :         if(!BN_GENCB_call(cb, 2, 1))
     324                 :            :                 goto err;
     325                 :            : 
     326                 :            :         /* We now need to generate g */
     327                 :            :         /* Set r0=(p-1)/q */
     328         [ +  - ]:          2 :         if (!BN_sub(test,p,BN_value_one())) goto err;
     329         [ +  - ]:          2 :         if (!BN_div(r0,NULL,test,q,ctx)) goto err;
     330                 :            : 
     331         [ +  - ]:          2 :         if (!BN_set_word(test,h)) goto err;
     332         [ +  - ]:          2 :         if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;
     333                 :            : 
     334                 :            :         for (;;)
     335                 :            :                 {
     336                 :            :                 /* g=test^r0%p */
     337         [ +  - ]:          2 :                 if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
     338 [ -  + ][ #  # ]:          2 :                 if (!BN_is_one(g)) break;
                 [ #  # ]
     339         [ #  # ]:          0 :                 if (!BN_add(test,test,BN_value_one())) goto err;
     340                 :          0 :                 h++;
     341                 :          0 :                 }
     342                 :            : 
     343         [ +  - ]:          2 :         if(!BN_GENCB_call(cb, 3, 1))
     344                 :            :                 goto err;
     345                 :            : 
     346                 :          2 :         ok=1;
     347                 :            : err:
     348         [ +  - ]:          2 :         if (ok)
     349                 :            :                 {
     350         [ -  + ]:          2 :                 if(ret->p) BN_free(ret->p);
     351         [ -  + ]:          2 :                 if(ret->q) BN_free(ret->q);
     352         [ -  + ]:          2 :                 if(ret->g) BN_free(ret->g);
     353                 :          2 :                 ret->p=BN_dup(p);
     354                 :          2 :                 ret->q=BN_dup(q);
     355                 :          2 :                 ret->g=BN_dup(g);
     356 [ -  + ][ -  + ]:          2 :                 if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
                 [ -  + ]
     357                 :            :                         {
     358                 :            :                         ok=0;
     359                 :            :                         goto err;
     360                 :            :                         }
     361         [ +  - ]:          2 :                 if (counter_ret != NULL) *counter_ret=counter;
     362         [ +  - ]:          2 :                 if (h_ret != NULL) *h_ret=h;
     363         [ -  + ]:          2 :                 if (seed_out)
     364                 :          0 :                         memcpy(seed_out, seed, qsize);
     365                 :            :                 }
     366         [ +  - ]:          2 :         if(ctx)
     367                 :            :                 {
     368                 :          2 :                 BN_CTX_end(ctx);
     369                 :          2 :                 BN_CTX_free(ctx);
     370                 :            :                 }
     371         [ +  - ]:          2 :         if (mont != NULL) BN_MONT_CTX_free(mont);
     372                 :          2 :         return ok;
     373                 :            :         }
     374                 :            : 
     375                 :            : #ifdef OPENSSL_FIPS
     376                 :            : 
     377                 :            : /* Security strength of parameter values for (L,N): see FIPS186-3 4.2
     378                 :            :  * and SP800-131A
     379                 :            :  */
     380                 :            : 
     381                 :            : 
     382                 :            : static int fips_ffc_strength(size_t L, size_t N)
     383                 :            :         {
     384                 :            :         if (L >= 15360 && N >= 512)
     385                 :            :                 return 256;
     386                 :            :         if (L >= 7680 && N >= 384)
     387                 :            :                 return 192;
     388                 :            :         if (L >= 3072 && N >= 256)
     389                 :            :                 return 128;
     390                 :            :         if (L >= 2048 && N >= 224)
     391                 :            :                 return 112;
     392                 :            :         if (L >= 1024 && N >= 160)
     393                 :            :                 return  80;
     394                 :            :         return 0;
     395                 :            :         }
     396                 :            : 
     397                 :            : /* Valid DSA2 parameters from FIPS 186-3 */
     398                 :            : 
     399                 :            : static int dsa2_valid_parameters(size_t L, size_t N)
     400                 :            :         {
     401                 :            :         if (L == 1024 && N == 160)
     402                 :            :                 return 80;
     403                 :            :         if (L == 2048 && N == 224)
     404                 :            :                 return 112;
     405                 :            :         if (L == 2048 && N == 256)
     406                 :            :                 return 112;
     407                 :            :         if (L == 3072 && N == 256)
     408                 :            :                 return 128;
     409                 :            :         return 0;
     410                 :            :         }
     411                 :            : 
     412                 :            : int fips_check_dsa_prng(DSA *dsa, size_t L, size_t N)
     413                 :            :         {
     414                 :            :         int strength;
     415                 :            :         if (!FIPS_module_mode())
     416                 :            :                 return 1;
     417                 :            : 
     418                 :            :         if (dsa->flags & (DSA_FLAG_NON_FIPS_ALLOW|DSA_FLAG_FIPS_CHECKED))
     419                 :            :                 return 1;
     420                 :            : 
     421                 :            :         if (!L || !N)
     422                 :            :                 {
     423                 :            :                 L = BN_num_bits(dsa->p);
     424                 :            :                 N = BN_num_bits(dsa->q);
     425                 :            :                 }
     426                 :            :         if (!dsa2_valid_parameters(L, N))
     427                 :            :                 {
     428                 :            :                 FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG, FIPS_R_INVALID_PARAMETERS);
     429                 :            :                 return 0;
     430                 :            :                 }
     431                 :            : 
     432                 :            :         strength = fips_ffc_strength(L, N);
     433                 :            : 
     434                 :            :         if (!strength)
     435                 :            :                 {
     436                 :            :                 FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG,FIPS_R_KEY_TOO_SHORT);
     437                 :            :                 return 0;
     438                 :            :                 }
     439                 :            : 
     440                 :            :         if (FIPS_rand_strength() >= strength)
     441                 :            :                 return 1;
     442                 :            : 
     443                 :            :         FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW);
     444                 :            :         return 0;
     445                 :            : 
     446                 :            :         }
     447                 :            : #endif /* OPENSSL_FIPS */
     448                 :            : 
     449                 :            : /* This is a parameter generation algorithm for the DSA2 algorithm as
     450                 :            :  * described in FIPS 186-3.
     451                 :            :  */
     452                 :            : 
     453                 :          0 : int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
     454                 :            :         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
     455                 :            :         int idx, unsigned char *seed_out,
     456                 :            :         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
     457                 :            :         {
     458                 :          0 :         int ok=-1;
     459                 :          0 :         unsigned char *seed = NULL, *seed_tmp = NULL;
     460                 :            :         unsigned char md[EVP_MAX_MD_SIZE];
     461                 :            :         int mdsize;
     462                 :            :         BIGNUM *r0,*W,*X,*c,*test;
     463                 :          0 :         BIGNUM *g=NULL,*q=NULL,*p=NULL;
     464                 :          0 :         BN_MONT_CTX *mont=NULL;
     465                 :          0 :         int i, k, n=0, m=0, qsize = N >> 3;
     466                 :          0 :         int counter=0;
     467                 :          0 :         int r=0;
     468                 :          0 :         BN_CTX *ctx=NULL;
     469                 :            :         EVP_MD_CTX mctx;
     470                 :          0 :         unsigned int h=2;
     471                 :            : 
     472                 :          0 :         EVP_MD_CTX_init(&mctx);
     473                 :            : 
     474                 :            : #ifdef OPENSSL_FIPS
     475                 :            :         if(FIPS_selftest_failed())
     476                 :            :             {
     477                 :            :             FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN2,
     478                 :            :                     FIPS_R_FIPS_SELFTEST_FAILED);
     479                 :            :             goto err;
     480                 :            :             }
     481                 :            : 
     482                 :            :         if (!fips_check_dsa_prng(ret, L, N))
     483                 :            :                 goto err;
     484                 :            : #endif
     485                 :            : 
     486         [ #  # ]:          0 :         if (evpmd == NULL)
     487                 :            :                 {
     488         [ #  # ]:          0 :                 if (N == 160)
     489                 :          0 :                         evpmd = EVP_sha1();
     490         [ #  # ]:          0 :                 else if (N == 224)
     491                 :          0 :                         evpmd = EVP_sha224();
     492                 :            :                 else
     493                 :          0 :                         evpmd = EVP_sha256();
     494                 :            :                 }
     495                 :            : 
     496                 :          0 :         mdsize = M_EVP_MD_size(evpmd);
     497                 :            :         /* If unverificable g generation only don't need seed */
     498 [ #  # ][ #  # ]:          0 :         if (!ret->p || !ret->q || idx >= 0)
                 [ #  # ]
     499                 :            :                 {
     500         [ #  # ]:          0 :                 if (seed_len == 0)
     501                 :          0 :                         seed_len = mdsize;
     502                 :            : 
     503                 :          0 :                 seed = OPENSSL_malloc(seed_len);
     504                 :            : 
     505         [ #  # ]:          0 :                 if (seed_out)
     506                 :            :                         seed_tmp = seed_out;
     507                 :            :                 else
     508                 :          0 :                         seed_tmp = OPENSSL_malloc(seed_len);
     509                 :            : 
     510         [ #  # ]:          0 :                 if (!seed || !seed_tmp)
     511                 :            :                         goto err;
     512                 :            : 
     513         [ #  # ]:          0 :                 if (seed_in)
     514                 :            :                         memcpy(seed, seed_in, seed_len);
     515                 :            : 
     516                 :            :                 }
     517                 :            : 
     518         [ #  # ]:          0 :         if ((ctx=BN_CTX_new()) == NULL)
     519                 :            :                 goto err;
     520                 :            : 
     521         [ #  # ]:          0 :         if ((mont=BN_MONT_CTX_new()) == NULL)
     522                 :            :                 goto err;
     523                 :            : 
     524                 :          0 :         BN_CTX_start(ctx);
     525                 :          0 :         r0 = BN_CTX_get(ctx);
     526                 :          0 :         g = BN_CTX_get(ctx);
     527                 :          0 :         W = BN_CTX_get(ctx);
     528                 :          0 :         X = BN_CTX_get(ctx);
     529                 :          0 :         c = BN_CTX_get(ctx);
     530                 :          0 :         test = BN_CTX_get(ctx);
     531                 :            : 
     532                 :            :         /* if p, q already supplied generate g only */
     533 [ #  # ][ #  # ]:          0 :         if (ret->p && ret->q)
     534                 :            :                 {
     535                 :          0 :                 p = ret->p;
     536                 :          0 :                 q = ret->q;
     537         [ #  # ]:          0 :                 if (idx >= 0)
     538                 :            :                         memcpy(seed_tmp, seed, seed_len);
     539                 :            :                 goto g_only;
     540                 :            :                 }
     541                 :            :         else
     542                 :            :                 {
     543                 :          0 :                 p = BN_CTX_get(ctx);
     544                 :          0 :                 q = BN_CTX_get(ctx);
     545                 :            :                 }
     546                 :            : 
     547         [ #  # ]:          0 :         if (!BN_lshift(test,BN_value_one(),L-1))
     548                 :            :                 goto err;
     549                 :            :         for (;;)
     550                 :            :                 {
     551                 :            :                 for (;;) /* find q */
     552                 :            :                         {
     553                 :            :                         unsigned char *pmd;
     554                 :            :                         /* step 1 */
     555         [ #  # ]:          0 :                         if(!BN_GENCB_call(cb, 0, m++))
     556                 :            :                                 goto err;
     557                 :            : 
     558         [ #  # ]:          0 :                         if (!seed_in)
     559                 :            :                                 {
     560         [ #  # ]:          0 :                                 if (RAND_pseudo_bytes(seed, seed_len) < 0)
     561                 :            :                                         goto err;
     562                 :            :                                 }
     563                 :            :                         /* step 2 */
     564         [ #  # ]:          0 :                         if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
     565                 :            :                                 goto err;
     566                 :            :                         /* Take least significant bits of md */
     567         [ #  # ]:          0 :                         if (mdsize > qsize)
     568                 :          0 :                                 pmd = md + mdsize - qsize;
     569                 :            :                         else
     570                 :            :                                 pmd = md;
     571                 :            : 
     572         [ #  # ]:          0 :                         if (mdsize < qsize)
     573                 :          0 :                                 memset(md + mdsize, 0, qsize - mdsize);
     574                 :            : 
     575                 :            :                         /* step 3 */
     576                 :          0 :                         pmd[0] |= 0x80;
     577                 :          0 :                         pmd[qsize-1] |= 0x01;
     578         [ #  # ]:          0 :                         if (!BN_bin2bn(pmd, qsize, q))
     579                 :            :                                 goto err;
     580                 :            : 
     581                 :            :                         /* step 4 */
     582                 :          0 :                         r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
     583                 :            :                                         seed_in ? 1 : 0, cb);
     584         [ #  # ]:          0 :                         if (r > 0)
     585                 :            :                                 break;
     586         [ #  # ]:          0 :                         if (r != 0)
     587                 :            :                                 goto err;
     588                 :            :                         /* Provided seed didn't produce a prime: error */
     589         [ #  # ]:          0 :                         if (seed_in)
     590                 :            :                                 {
     591                 :          0 :                                 ok = 0;
     592                 :          0 :                                 DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
     593                 :          0 :                                 goto err;
     594                 :            :                                 }
     595                 :            : 
     596                 :            :                         /* do a callback call */
     597                 :            :                         /* step 5 */
     598                 :            :                         }
     599                 :            :                 /* Copy seed to seed_out before we mess with it */
     600         [ #  # ]:          0 :                 if (seed_out)
     601                 :            :                         memcpy(seed_out, seed, seed_len);
     602                 :            : 
     603         [ #  # ]:          0 :                 if(!BN_GENCB_call(cb, 2, 0)) goto err;
     604         [ #  # ]:          0 :                 if(!BN_GENCB_call(cb, 3, 0)) goto err;
     605                 :            : 
     606                 :            :                 /* step 6 */
     607                 :          0 :                 counter=0;
     608                 :            :                 /* "offset = 1" */
     609                 :            : 
     610                 :          0 :                 n=(L-1)/(mdsize << 3);
     611                 :            : 
     612                 :            :                 for (;;)
     613                 :            :                         {
     614 [ #  # ][ #  # ]:          0 :                         if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
     615                 :            :                                 goto err;
     616                 :            : 
     617                 :            :                         /* step 7 */
     618                 :          0 :                         BN_zero(W);
     619                 :            :                         /* now 'buf' contains "SEED + offset - 1" */
     620         [ #  # ]:          0 :                         for (k=0; k<=n; k++)
     621                 :            :                                 {
     622                 :            :                                 /* obtain "SEED + offset + k" by incrementing: */
     623         [ #  # ]:          0 :                                 for (i = seed_len-1; i >= 0; i--)
     624                 :            :                                         {
     625                 :          0 :                                         seed[i]++;
     626         [ #  # ]:          0 :                                         if (seed[i] != 0)
     627                 :            :                                                 break;
     628                 :            :                                         }
     629                 :            : 
     630         [ #  # ]:          0 :                                 if (!EVP_Digest(seed, seed_len, md ,NULL, evpmd,
     631                 :            :                                                                         NULL))
     632                 :            :                                         goto err;
     633                 :            : 
     634                 :            :                                 /* step 8 */
     635         [ #  # ]:          0 :                                 if (!BN_bin2bn(md, mdsize, r0))
     636                 :            :                                         goto err;
     637         [ #  # ]:          0 :                                 if (!BN_lshift(r0,r0,(mdsize << 3)*k)) goto err;
     638         [ #  # ]:          0 :                                 if (!BN_add(W,W,r0)) goto err;
     639                 :            :                                 }
     640                 :            : 
     641                 :            :                         /* more of step 8 */
     642         [ #  # ]:          0 :                         if (!BN_mask_bits(W,L-1)) goto err;
     643         [ #  # ]:          0 :                         if (!BN_copy(X,W)) goto err;
     644         [ #  # ]:          0 :                         if (!BN_add(X,X,test)) goto err;
     645                 :            : 
     646                 :            :                         /* step 9 */
     647         [ #  # ]:          0 :                         if (!BN_lshift1(r0,q)) goto err;
     648         [ #  # ]:          0 :                         if (!BN_mod(c,X,r0,ctx)) goto err;
     649         [ #  # ]:          0 :                         if (!BN_sub(r0,c,BN_value_one())) goto err;
     650         [ #  # ]:          0 :                         if (!BN_sub(p,X,r0)) goto err;
     651                 :            : 
     652                 :            :                         /* step 10 */
     653         [ #  # ]:          0 :                         if (BN_cmp(p,test) >= 0)
     654                 :            :                                 {
     655                 :            :                                 /* step 11 */
     656                 :          0 :                                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
     657                 :            :                                                 ctx, 1, cb);
     658         [ #  # ]:          0 :                                 if (r > 0)
     659                 :            :                                                 goto end; /* found it */
     660         [ #  # ]:          0 :                                 if (r != 0)
     661                 :            :                                         goto err;
     662                 :            :                                 }
     663                 :            : 
     664                 :            :                         /* step 13 */
     665                 :          0 :                         counter++;
     666                 :            :                         /* "offset = offset + n + 1" */
     667                 :            : 
     668                 :            :                         /* step 14 */
     669         [ #  # ]:          0 :                         if (counter >= (int)(4 * L)) break;
     670                 :            :                         }
     671         [ #  # ]:          0 :                 if (seed_in)
     672                 :            :                         {
     673                 :          0 :                         ok = 0;
     674                 :          0 :                         DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
     675                 :          0 :                         goto err;
     676                 :            :                         }
     677                 :            :                 }
     678                 :            : end:
     679         [ #  # ]:          0 :         if(!BN_GENCB_call(cb, 2, 1))
     680                 :            :                 goto err;
     681                 :            : 
     682                 :            :         g_only:
     683                 :            : 
     684                 :            :         /* We now need to generate g */
     685                 :            :         /* Set r0=(p-1)/q */
     686         [ #  # ]:          0 :         if (!BN_sub(test,p,BN_value_one())) goto err;
     687         [ #  # ]:          0 :         if (!BN_div(r0,NULL,test,q,ctx)) goto err;
     688                 :            : 
     689         [ #  # ]:          0 :         if (idx < 0)
     690                 :            :                 {
     691         [ #  # ]:          0 :                 if (!BN_set_word(test,h))
     692                 :            :                         goto err;
     693                 :            :                 }
     694                 :            :         else
     695                 :            :                 h = 1;
     696         [ #  # ]:          0 :         if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;
     697                 :            : 
     698                 :            :         for (;;)
     699                 :            :                 {
     700                 :            :                 __fips_constseg
     701                 :            :                 static const unsigned char ggen[4] = {0x67,0x67,0x65,0x6e};
     702         [ #  # ]:          0 :                 if (idx >= 0)
     703                 :            :                         {
     704                 :          0 :                         md[0] = idx & 0xff;
     705                 :          0 :                         md[1] = (h >> 8) & 0xff;
     706                 :          0 :                         md[2] = h & 0xff;
     707         [ #  # ]:          0 :                         if (!EVP_DigestInit_ex(&mctx, evpmd, NULL))
     708                 :            :                                 goto err;
     709         [ #  # ]:          0 :                         if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len))
     710                 :            :                                 goto err;
     711         [ #  # ]:          0 :                         if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen)))
     712                 :            :                                 goto err;
     713         [ #  # ]:          0 :                         if (!EVP_DigestUpdate(&mctx, md, 3))
     714                 :            :                                 goto err;
     715         [ #  # ]:          0 :                         if (!EVP_DigestFinal_ex(&mctx, md, NULL))
     716                 :            :                                 goto err;
     717         [ #  # ]:          0 :                         if (!BN_bin2bn(md, mdsize, test))
     718                 :            :                                 goto err;
     719                 :            :                         }
     720                 :            :                 /* g=test^r0%p */
     721         [ #  # ]:          0 :                 if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
     722 [ #  # ][ #  # ]:          0 :                 if (!BN_is_one(g)) break;
                 [ #  # ]
     723 [ #  # ][ #  # ]:          0 :                 if (idx < 0 && !BN_add(test,test,BN_value_one())) goto err;
     724                 :          0 :                 h++;
     725         [ #  # ]:          0 :                 if ( idx >= 0 && h > 0xffff)
     726                 :            :                         goto err;
     727                 :            :                 }
     728                 :            : 
     729         [ #  # ]:          0 :         if(!BN_GENCB_call(cb, 3, 1))
     730                 :            :                 goto err;
     731                 :            : 
     732                 :          0 :         ok=1;
     733                 :            : err:
     734         [ #  # ]:          0 :         if (ok == 1)
     735                 :            :                 {
     736         [ #  # ]:          0 :                 if (p != ret->p)
     737                 :            :                         {
     738         [ #  # ]:          0 :                         if(ret->p) BN_free(ret->p);
     739                 :          0 :                         ret->p=BN_dup(p);
     740                 :            :                         }
     741         [ #  # ]:          0 :                 if (q != ret->q)
     742                 :            :                         {
     743         [ #  # ]:          0 :                         if(ret->q) BN_free(ret->q);
     744                 :          0 :                         ret->q=BN_dup(q);
     745                 :            :                         }
     746         [ #  # ]:          0 :                 if(ret->g) BN_free(ret->g);
     747                 :          0 :                 ret->g=BN_dup(g);
     748 [ #  # ][ #  # ]:          0 :                 if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
                 [ #  # ]
     749                 :            :                         {
     750                 :            :                         ok=-1;
     751                 :            :                         goto err;
     752                 :            :                         }
     753         [ #  # ]:          0 :                 if (counter_ret != NULL) *counter_ret=counter;
     754         [ #  # ]:          0 :                 if (h_ret != NULL) *h_ret=h;
     755                 :            :                 }
     756         [ #  # ]:          0 :         if (seed)
     757                 :          0 :                 OPENSSL_free(seed);
     758         [ #  # ]:          0 :         if (seed_out != seed_tmp)
     759                 :          0 :                 OPENSSL_free(seed_tmp);
     760         [ #  # ]:          0 :         if(ctx)
     761                 :            :                 {
     762                 :          0 :                 BN_CTX_end(ctx);
     763                 :          0 :                 BN_CTX_free(ctx);
     764                 :            :                 }
     765         [ #  # ]:          0 :         if (mont != NULL) BN_MONT_CTX_free(mont);
     766                 :          0 :         EVP_MD_CTX_cleanup(&mctx);
     767                 :          0 :         return ok;
     768                 :            :         }
     769                 :            : 
     770                 :          0 : int dsa_paramgen_check_g(DSA *dsa)
     771                 :            :         {
     772                 :            :         BN_CTX *ctx;
     773                 :            :         BIGNUM *tmp;
     774                 :          0 :         BN_MONT_CTX *mont = NULL;
     775                 :          0 :         int rv = -1;
     776                 :          0 :         ctx = BN_CTX_new();
     777         [ #  # ]:          0 :         if (!ctx)
     778                 :            :                 return -1;
     779                 :          0 :         BN_CTX_start(ctx);
     780         [ #  # ]:          0 :         if (BN_cmp(dsa->g, BN_value_one()) <= 0)
     781                 :            :                 return 0;
     782         [ #  # ]:          0 :         if (BN_cmp(dsa->g, dsa->p) >= 0)
     783                 :            :                 return 0;
     784                 :          0 :         tmp = BN_CTX_get(ctx);
     785         [ #  # ]:          0 :         if (!tmp)
     786                 :            :                 goto err;
     787         [ #  # ]:          0 :         if ((mont=BN_MONT_CTX_new()) == NULL)
     788                 :            :                 goto err;
     789         [ #  # ]:          0 :         if (!BN_MONT_CTX_set(mont,dsa->p,ctx))
     790                 :            :                 goto err;
     791                 :            :         /* Work out g^q mod p */
     792         [ #  # ]:          0 :         if (!BN_mod_exp_mont(tmp,dsa->g,dsa->q, dsa->p, ctx, mont))
     793                 :            :                 goto err;
     794         [ #  # ]:          0 :         if (!BN_cmp(tmp, BN_value_one()))
     795                 :            :                 rv = 1;
     796                 :            :         else
     797                 :          0 :                 rv = 0;
     798                 :            :         err:
     799                 :          0 :         BN_CTX_end(ctx);
     800         [ #  # ]:          0 :         if (mont)
     801                 :          0 :                 BN_MONT_CTX_free(mont);
     802                 :          0 :         BN_CTX_free(ctx);
     803                 :          0 :         return rv;
     804                 :            : 
     805                 :            :         }
     806                 :            : 
     807                 :            : #endif

Generated by: LCOV version 1.9