LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/rand - rand_lib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 24 53 45.3 %
Date: 2015-10-10 Functions: 5 9 55.6 %

          Line data    Source code
       1             : /* crypto/rand/rand_lib.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             : #include <stdio.h>
      60             : #include <time.h>
      61             : #include "cryptlib.h"
      62             : #include <openssl/rand.h>
      63             : 
      64             : #ifndef OPENSSL_NO_ENGINE
      65             : # include <openssl/engine.h>
      66             : #endif
      67             : 
      68             : #ifdef OPENSSL_FIPS
      69             : # include <openssl/fips.h>
      70             : # include <openssl/fips_rand.h>
      71             : # include "rand_lcl.h"
      72             : #endif
      73             : 
      74             : #ifndef OPENSSL_NO_ENGINE
      75             : /* non-NULL if default_RAND_meth is ENGINE-provided */
      76             : static ENGINE *funct_ref = NULL;
      77             : #endif
      78             : static const RAND_METHOD *default_RAND_meth = NULL;
      79             : 
      80           0 : int RAND_set_rand_method(const RAND_METHOD *meth)
      81             : {
      82             : #ifndef OPENSSL_NO_ENGINE
      83           0 :     if (funct_ref) {
      84           0 :         ENGINE_finish(funct_ref);
      85           0 :         funct_ref = NULL;
      86             :     }
      87             : #endif
      88           0 :     default_RAND_meth = meth;
      89           0 :     return 1;
      90             : }
      91             : 
      92       11259 : const RAND_METHOD *RAND_get_rand_method(void)
      93             : {
      94       11259 :     if (!default_RAND_meth) {
      95             : #ifndef OPENSSL_NO_ENGINE
      96         124 :         ENGINE *e = ENGINE_get_default_RAND();
      97         124 :         if (e) {
      98           0 :             default_RAND_meth = ENGINE_get_RAND(e);
      99           0 :             if (!default_RAND_meth) {
     100           0 :                 ENGINE_finish(e);
     101             :                 e = NULL;
     102             :             }
     103             :         }
     104         124 :         if (e)
     105           0 :             funct_ref = e;
     106             :         else
     107             : #endif
     108         124 :             default_RAND_meth = RAND_SSLeay();
     109             :     }
     110       11259 :     return default_RAND_meth;
     111             : }
     112             : 
     113             : #ifndef OPENSSL_NO_ENGINE
     114           0 : int RAND_set_rand_engine(ENGINE *engine)
     115             : {
     116             :     const RAND_METHOD *tmp_meth = NULL;
     117           0 :     if (engine) {
     118           0 :         if (!ENGINE_init(engine))
     119             :             return 0;
     120           0 :         tmp_meth = ENGINE_get_RAND(engine);
     121           0 :         if (!tmp_meth) {
     122           0 :             ENGINE_finish(engine);
     123           0 :             return 0;
     124             :         }
     125             :     }
     126             :     /* This function releases any prior ENGINE so call it first */
     127             :     RAND_set_rand_method(tmp_meth);
     128           0 :     funct_ref = engine;
     129           0 :     return 1;
     130             : }
     131             : #endif
     132             : 
     133           0 : void RAND_cleanup(void)
     134             : {
     135           0 :     const RAND_METHOD *meth = RAND_get_rand_method();
     136           0 :     if (meth && meth->cleanup)
     137           0 :         meth->cleanup();
     138             :     RAND_set_rand_method(NULL);
     139           0 : }
     140             : 
     141           0 : void RAND_seed(const void *buf, int num)
     142             : {
     143           0 :     const RAND_METHOD *meth = RAND_get_rand_method();
     144           0 :     if (meth && meth->seed)
     145           0 :         meth->seed(buf, num);
     146           0 : }
     147             : 
     148        4396 : void RAND_add(const void *buf, int num, double entropy)
     149             : {
     150        4396 :     const RAND_METHOD *meth = RAND_get_rand_method();
     151        4396 :     if (meth && meth->add)
     152        4396 :         meth->add(buf, num, entropy);
     153        4396 : }
     154             : 
     155        4859 : int RAND_bytes(unsigned char *buf, int num)
     156             : {
     157        4859 :     const RAND_METHOD *meth = RAND_get_rand_method();
     158        4859 :     if (meth && meth->bytes)
     159        4859 :         return meth->bytes(buf, num);
     160             :     return (-1);
     161             : }
     162             : 
     163        1659 : int RAND_pseudo_bytes(unsigned char *buf, int num)
     164             : {
     165        1659 :     const RAND_METHOD *meth = RAND_get_rand_method();
     166        1659 :     if (meth && meth->pseudorand)
     167        1659 :         return meth->pseudorand(buf, num);
     168             :     return (-1);
     169             : }
     170             : 
     171         345 : int RAND_status(void)
     172             : {
     173         345 :     const RAND_METHOD *meth = RAND_get_rand_method();
     174         345 :     if (meth && meth->status)
     175         345 :         return meth->status();
     176             :     return 0;
     177             : }
     178             : 
     179             : #ifdef OPENSSL_FIPS
     180             : 
     181             : /*
     182             :  * FIPS DRBG initialisation code. This sets up the DRBG for use by the rest
     183             :  * of OpenSSL.
     184             :  */
     185             : 
     186             : /*
     187             :  * Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
     188             :  * entropy internally through RAND_poll().
     189             :  */
     190             : 
     191             : static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
     192             :                                int entropy, size_t min_len, size_t max_len)
     193             : {
     194             :     /* Round up request to multiple of block size */
     195             :     min_len = ((min_len + 19) / 20) * 20;
     196             :     *pout = OPENSSL_malloc(min_len);
     197             :     if (!*pout)
     198             :         return 0;
     199             :     if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) {
     200             :         OPENSSL_free(*pout);
     201             :         *pout = NULL;
     202             :         return 0;
     203             :     }
     204             :     return min_len;
     205             : }
     206             : 
     207             : static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
     208             : {
     209             :     if (out) {
     210             :         OPENSSL_cleanse(out, olen);
     211             :         OPENSSL_free(out);
     212             :     }
     213             : }
     214             : 
     215             : /*
     216             :  * Set "additional input" when generating random data. This uses the current
     217             :  * PID, a time value and a counter.
     218             :  */
     219             : 
     220             : static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
     221             : {
     222             :     /* Use of static variables is OK as this happens under a lock */
     223             :     static unsigned char buf[16];
     224             :     static unsigned long counter;
     225             :     FIPS_get_timevec(buf, &counter);
     226             :     *pout = buf;
     227             :     return sizeof(buf);
     228             : }
     229             : 
     230             : /*
     231             :  * RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
     232             :  * correctly seeded by RAND_poll().
     233             :  */
     234             : 
     235             : static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
     236             :                          double entropy)
     237             : {
     238             :     RAND_SSLeay()->add(in, inlen, entropy);
     239             :     return 1;
     240             : }
     241             : 
     242             : static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
     243             : {
     244             :     RAND_SSLeay()->seed(in, inlen);
     245             :     return 1;
     246             : }
     247             : 
     248             : # ifndef OPENSSL_DRBG_DEFAULT_TYPE
     249             : #  define OPENSSL_DRBG_DEFAULT_TYPE       NID_aes_256_ctr
     250             : # endif
     251             : # ifndef OPENSSL_DRBG_DEFAULT_FLAGS
     252             : #  define OPENSSL_DRBG_DEFAULT_FLAGS      DRBG_FLAG_CTR_USE_DF
     253             : # endif
     254             : 
     255             : static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
     256             : static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
     257             : 
     258             : void RAND_set_fips_drbg_type(int type, int flags)
     259             : {
     260             :     fips_drbg_type = type;
     261             :     fips_drbg_flags = flags;
     262             : }
     263             : 
     264             : int RAND_init_fips(void)
     265             : {
     266             :     DRBG_CTX *dctx;
     267             :     size_t plen;
     268             :     unsigned char pers[32], *p;
     269             : # ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
     270             :     if (fips_drbg_type >> 16) {
     271             :         RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
     272             :         return 0;
     273             :     }
     274             : # endif
     275             : 
     276             :     dctx = FIPS_get_default_drbg();
     277             :     if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) {
     278             :         RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
     279             :         return 0;
     280             :     }
     281             : 
     282             :     FIPS_drbg_set_callbacks(dctx,
     283             :                             drbg_get_entropy, drbg_free_entropy, 20,
     284             :                             drbg_get_entropy, drbg_free_entropy);
     285             :     FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
     286             :                                  drbg_rand_seed, drbg_rand_add);
     287             :     /* Personalisation string: a string followed by date time vector */
     288             :     strcpy((char *)pers, "OpenSSL DRBG2.0");
     289             :     plen = drbg_get_adin(dctx, &p);
     290             :     memcpy(pers + 16, p, plen);
     291             : 
     292             :     if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) {
     293             :         RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
     294             :         return 0;
     295             :     }
     296             :     FIPS_rand_set_method(FIPS_drbg_method());
     297             :     return 1;
     298             : }
     299             : 
     300             : #endif

Generated by: LCOV version 1.10