LCOV - code coverage report
Current view: top level - rsa - rsa_gen.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 66 76 86.8 %
Date: 2014-08-02 Functions: 2 2 100.0 %
Branches: 50 104 48.1 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/rsa/rsa_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                 :            : 
      60                 :            : /* NB: these functions have been "upgraded", the deprecated versions (which are
      61                 :            :  * compatibility wrappers using these functions) are in rsa_depr.c.
      62                 :            :  * - Geoff
      63                 :            :  */
      64                 :            : 
      65                 :            : #define OPENSSL_FIPSAPI
      66                 :            : 
      67                 :            : #include <stdio.h>
      68                 :            : #include <time.h>
      69                 :            : #include "cryptlib.h"
      70                 :            : #include <openssl/bn.h>
      71                 :            : #include <openssl/rsa.h>
      72                 :            : 
      73                 :            : #ifdef OPENSSL_FIPS
      74                 :            : 
      75                 :            : 
      76                 :            : #include <openssl/fips.h>
      77                 :            : #include <openssl/fips_rand.h>
      78                 :            : #include <openssl/evp.h>
      79                 :            : 
      80                 :            : /* Check PRNG has sufficient security level to handle an RSA operation */
      81                 :            : 
      82                 :            : int fips_check_rsa_prng(RSA *rsa, int bits)
      83                 :            :         {
      84                 :            :         int strength;
      85                 :            :         if (!FIPS_module_mode())
      86                 :            :                 return 1;
      87                 :            : 
      88                 :            :         if (rsa->flags & (RSA_FLAG_NON_FIPS_ALLOW|RSA_FLAG_CHECKED))
      89                 :            :                 return 1;
      90                 :            : 
      91                 :            :         if (bits == 0)
      92                 :            :                 bits = BN_num_bits(rsa->n);
      93                 :            : 
      94                 :            :         /* Should never happen */
      95                 :            :         if (bits < 1024)
      96                 :            :                 {
      97                 :            :                 FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_KEY_TOO_SHORT);
      98                 :            :                 return 0;
      99                 :            :                 }
     100                 :            :         /* From SP800-57 */
     101                 :            :         if (bits < 2048)
     102                 :            :                 strength = 80;
     103                 :            :         else if (bits < 3072)
     104                 :            :                 strength = 112;
     105                 :            :         else if (bits < 7680)
     106                 :            :                 strength = 128;
     107                 :            :         else if (bits < 15360)
     108                 :            :                 strength = 192;
     109                 :            :         else 
     110                 :            :                 strength = 256;
     111                 :            : 
     112                 :            :         if (FIPS_rand_strength() >= strength)
     113                 :            :                 return 1;
     114                 :            : 
     115                 :            :         FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW);
     116                 :            :         return 0;
     117                 :            :         }
     118                 :            :         
     119                 :            : 
     120                 :            : int fips_check_rsa(RSA *rsa)
     121                 :            :         {
     122                 :            :         const unsigned char tbs[] = "RSA Pairwise Check Data";
     123                 :            :         unsigned char *ctbuf = NULL, *ptbuf = NULL;
     124                 :            :         int len, ret = 0;
     125                 :            :         EVP_PKEY pk;
     126                 :            :         pk.type = EVP_PKEY_RSA;
     127                 :            :         pk.pkey.rsa = rsa;
     128                 :            : 
     129                 :            :         /* Perform pairwise consistency signature test */
     130                 :            :         if (!fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
     131                 :            :                         NULL, 0, NULL, RSA_PKCS1_PADDING, NULL)
     132                 :            :                 || !fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
     133                 :            :                         NULL, 0, NULL, RSA_X931_PADDING, NULL)
     134                 :            :                 || !fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
     135                 :            :                         NULL, 0, NULL, RSA_PKCS1_PSS_PADDING, NULL))
     136                 :            :                 goto err;
     137                 :            :         /* Now perform pairwise consistency encrypt/decrypt test */
     138                 :            :         ctbuf = OPENSSL_malloc(RSA_size(rsa));
     139                 :            :         if (!ctbuf)
     140                 :            :                 goto err;
     141                 :            : 
     142                 :            :         len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING);
     143                 :            :         if (len <= 0)
     144                 :            :                 goto err;
     145                 :            :         /* Check ciphertext doesn't match plaintext */
     146                 :            :         if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len))
     147                 :            :                 goto err;
     148                 :            :         ptbuf = OPENSSL_malloc(RSA_size(rsa));
     149                 :            : 
     150                 :            :         if (!ptbuf)
     151                 :            :                 goto err;
     152                 :            :         len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING);
     153                 :            :         if (len != (sizeof(tbs) - 1))
     154                 :            :                 goto err;
     155                 :            :         if (memcmp(ptbuf, tbs, len))
     156                 :            :                 goto err;
     157                 :            : 
     158                 :            :         ret = 1;
     159                 :            : 
     160                 :            :         if (!ptbuf)
     161                 :            :                 goto err;
     162                 :            :         
     163                 :            :         err:
     164                 :            :         if (ret == 0)
     165                 :            :                 {
     166                 :            :                 fips_set_selftest_fail();
     167                 :            :                 FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
     168                 :            :                 }
     169                 :            : 
     170                 :            :         if (ctbuf)
     171                 :            :                 OPENSSL_free(ctbuf);
     172                 :            :         if (ptbuf)
     173                 :            :                 OPENSSL_free(ptbuf);
     174                 :            : 
     175                 :            :         return ret;
     176                 :            :         }
     177                 :            : #endif
     178                 :            : 
     179                 :            : static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
     180                 :            : 
     181                 :            : /* NB: this wrapper would normally be placed in rsa_lib.c and the static
     182                 :            :  * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
     183                 :            :  * that we don't introduce a new linker dependency. Eg. any application that
     184                 :            :  * wasn't previously linking object code related to key-generation won't have to
     185                 :            :  * now just because key-generation is part of RSA_METHOD. */
     186                 :         43 : int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
     187                 :            :         {
     188         [ -  + ]:         43 :         if(rsa->meth->rsa_keygen)
     189                 :          0 :                 return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
     190                 :         43 :         return rsa_builtin_keygen(rsa, bits, e_value, cb);
     191                 :            :         }
     192                 :            : 
     193                 :         43 : static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
     194                 :            :         {
     195                 :         43 :         BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
     196                 :            :         BIGNUM local_r0,local_d,local_p;
     197                 :            :         BIGNUM *pr0,*d,*p;
     198                 :         43 :         int bitsp,bitsq,ok= -1,n=0;
     199                 :         43 :         BN_CTX *ctx=NULL;
     200                 :            : 
     201                 :            : #ifdef OPENSSL_FIPS
     202                 :            :         if(FIPS_selftest_failed())
     203                 :            :             {
     204                 :            :             FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED);
     205                 :            :             return 0;
     206                 :            :             }
     207                 :            : 
     208                 :            :         if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) 
     209                 :            :                 && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
     210                 :            :             {
     211                 :            :             FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT);
     212                 :            :             return 0;
     213                 :            :             }
     214                 :            :         if (!fips_check_rsa_prng(rsa, bits))
     215                 :            :             return 0;
     216                 :            : #endif
     217                 :            : 
     218                 :         43 :         ctx=BN_CTX_new();
     219         [ +  - ]:         43 :         if (ctx == NULL) goto err;
     220                 :         43 :         BN_CTX_start(ctx);
     221                 :         43 :         r0 = BN_CTX_get(ctx);
     222                 :         43 :         r1 = BN_CTX_get(ctx);
     223                 :         43 :         r2 = BN_CTX_get(ctx);
     224                 :         43 :         r3 = BN_CTX_get(ctx);
     225         [ +  - ]:         43 :         if (r3 == NULL) goto err;
     226                 :            : 
     227                 :         43 :         bitsp=(bits+1)/2;
     228                 :         43 :         bitsq=bits-bitsp;
     229                 :            : 
     230                 :            :         /* We need the RSA components non-NULL */
     231 [ +  - ][ +  - ]:         43 :         if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
     232 [ +  - ][ +  - ]:         43 :         if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
     233 [ +  - ][ +  - ]:         43 :         if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
     234 [ +  - ][ +  - ]:         43 :         if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
     235 [ +  - ][ +  - ]:         43 :         if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
     236 [ +  - ][ +  - ]:         43 :         if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
     237 [ +  - ][ +  - ]:         43 :         if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
     238 [ +  - ][ +  - ]:         43 :         if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
     239                 :            : 
     240                 :         43 :         BN_copy(rsa->e, e_value);
     241                 :            : 
     242                 :            :         /* generate p and q */
     243                 :            :         for (;;)
     244                 :            :                 {
     245         [ +  - ]:         43 :                 if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
     246                 :            :                         goto err;
     247         [ +  - ]:         43 :                 if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
     248         [ +  - ]:         43 :                 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
     249 [ +  - ][ +  - ]:         43 :                 if (BN_is_one(r1)) break;
                 [ -  + ]
     250         [ #  # ]:          0 :                 if(!BN_GENCB_call(cb, 2, n++))
     251                 :            :                         goto err;
     252                 :            :                 }
     253         [ +  - ]:         43 :         if(!BN_GENCB_call(cb, 3, 0))
     254                 :            :                 goto err;
     255                 :            :         for (;;)
     256                 :            :                 {
     257                 :            :                 /* When generating ridiculously small keys, we can get stuck
     258                 :            :                  * continually regenerating the same prime values. Check for
     259                 :            :                  * this and bail if it happens 3 times. */
     260                 :         43 :                 unsigned int degenerate = 0;
     261                 :            :                 do
     262                 :            :                         {
     263         [ +  - ]:         43 :                         if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
     264                 :            :                                 goto err;
     265 [ -  + ][ #  # ]:         43 :                         } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
     266         [ -  + ]:         43 :                 if(degenerate == 3)
     267                 :            :                         {
     268                 :          0 :                         ok = 0; /* we set our own err */
     269                 :          0 :                         RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
     270                 :          0 :                         goto err;
     271                 :            :                         }
     272         [ +  - ]:         43 :                 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
     273         [ +  - ]:         43 :                 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
     274 [ +  - ][ +  - ]:         43 :                 if (BN_is_one(r1))
                 [ -  + ]
     275                 :            :                         break;
     276         [ #  # ]:          0 :                 if(!BN_GENCB_call(cb, 2, n++))
     277                 :            :                         goto err;
     278                 :            :                 }
     279         [ +  - ]:         43 :         if(!BN_GENCB_call(cb, 3, 1))
     280                 :            :                 goto err;
     281         [ +  + ]:         43 :         if (BN_cmp(rsa->p,rsa->q) < 0)
     282                 :            :                 {
     283                 :         19 :                 tmp=rsa->p;
     284                 :         19 :                 rsa->p=rsa->q;
     285                 :         19 :                 rsa->q=tmp;
     286                 :            :                 }
     287                 :            : 
     288                 :            :         /* calculate n */
     289         [ +  - ]:         43 :         if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
     290                 :            : 
     291                 :            :         /* calculate d */
     292         [ +  - ]:         43 :         if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;     /* p-1 */
     293         [ +  - ]:         43 :         if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;     /* q-1 */
     294         [ +  - ]:         43 :         if (!BN_mul(r0,r1,r2,ctx)) goto err;    /* (p-1)(q-1) */
     295         [ +  - ]:         43 :         if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
     296                 :            :                 {
     297                 :         43 :                   pr0 = &local_r0;
     298                 :         43 :                   BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
     299                 :            :                 }
     300                 :            :         else
     301                 :            :           pr0 = r0;
     302         [ +  - ]:         43 :         if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;     /* d */
     303                 :            : 
     304                 :            :         /* set up d for correct BN_FLG_CONSTTIME flag */
     305         [ +  - ]:         43 :         if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
     306                 :            :                 {
     307                 :         43 :                 d = &local_d;
     308                 :         43 :                 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
     309                 :            :                 }
     310                 :            :         else
     311                 :          0 :                 d = rsa->d;
     312                 :            : 
     313                 :            :         /* calculate d mod (p-1) */
     314         [ +  - ]:         43 :         if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
     315                 :            : 
     316                 :            :         /* calculate d mod (q-1) */
     317         [ +  - ]:         43 :         if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
     318                 :            : 
     319                 :            :         /* calculate inverse of q mod p */
     320         [ +  - ]:         43 :         if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
     321                 :            :                 {
     322                 :         43 :                 p = &local_p;
     323                 :         43 :                 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
     324                 :            :                 }
     325                 :            :         else
     326                 :          0 :                 p = rsa->p;
     327         [ +  - ]:         43 :         if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
     328                 :            : 
     329                 :            : #ifdef OPENSSL_FIPS
     330                 :            :         if(!fips_check_rsa(rsa))
     331                 :            :             goto err;
     332                 :            : #endif
     333                 :            : 
     334                 :         43 :         ok=1;
     335                 :            : err:
     336         [ -  + ]:         43 :         if (ok == -1)
     337                 :            :                 {
     338                 :          0 :                 RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
     339                 :          0 :                 ok=0;
     340                 :            :                 }
     341         [ +  - ]:         43 :         if (ctx != NULL)
     342                 :            :                 {
     343                 :         43 :                 BN_CTX_end(ctx);
     344                 :         43 :                 BN_CTX_free(ctx);
     345                 :            :                 }
     346                 :            : 
     347                 :         43 :         return ok;
     348                 :            :         }
     349                 :            : 

Generated by: LCOV version 1.9