The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / openssl / openssl / crypto / rand / rand_lib.c @ aa3b4b4d

History | View | Annotate | Download (8.47 KB)

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
int RAND_set_rand_method(const RAND_METHOD *meth)
81
        {
82
#ifndef OPENSSL_NO_ENGINE
83
        if(funct_ref)
84
                {
85
                ENGINE_finish(funct_ref);
86
                funct_ref = NULL;
87
                }
88
#endif
89
        default_RAND_meth = meth;
90
        return 1;
91
        }
92

    
93
const RAND_METHOD *RAND_get_rand_method(void)
94
        {
95
        if (!default_RAND_meth)
96
                {
97
#ifndef OPENSSL_NO_ENGINE
98
                ENGINE *e = ENGINE_get_default_RAND();
99
                if(e)
100
                        {
101
                        default_RAND_meth = ENGINE_get_RAND(e);
102
                        if(!default_RAND_meth)
103
                                {
104
                                ENGINE_finish(e);
105
                                e = NULL;
106
                                }
107
                        }
108
                if(e)
109
                        funct_ref = e;
110
                else
111
#endif
112
                        default_RAND_meth = RAND_SSLeay();
113
                }
114
        return default_RAND_meth;
115
        }
116

    
117
#ifndef OPENSSL_NO_ENGINE
118
int RAND_set_rand_engine(ENGINE *engine)
119
        {
120
        const RAND_METHOD *tmp_meth = NULL;
121
        if(engine)
122
                {
123
                if(!ENGINE_init(engine))
124
                        return 0;
125
                tmp_meth = ENGINE_get_RAND(engine);
126
                if(!tmp_meth)
127
                        {
128
                        ENGINE_finish(engine);
129
                        return 0;
130
                        }
131
                }
132
        /* This function releases any prior ENGINE so call it first */
133
        RAND_set_rand_method(tmp_meth);
134
        funct_ref = engine;
135
        return 1;
136
        }
137
#endif
138

    
139
void RAND_cleanup(void)
140
        {
141
        const RAND_METHOD *meth = RAND_get_rand_method();
142
        if (meth && meth->cleanup)
143
                meth->cleanup();
144
        RAND_set_rand_method(NULL);
145
        }
146

    
147
void RAND_seed(const void *buf, int num)
148
        {
149
        const RAND_METHOD *meth = RAND_get_rand_method();
150
        if (meth && meth->seed)
151
                meth->seed(buf,num);
152
        }
153

    
154
void RAND_add(const void *buf, int num, double entropy)
155
        {
156
        const RAND_METHOD *meth = RAND_get_rand_method();
157
        if (meth && meth->add)
158
                meth->add(buf,num,entropy);
159
        }
160

    
161
int RAND_bytes(unsigned char *buf, int num)
162
        {
163
        const RAND_METHOD *meth = RAND_get_rand_method();
164
        if (meth && meth->bytes)
165
                return meth->bytes(buf,num);
166
        return(-1);
167
        }
168

    
169
int RAND_pseudo_bytes(unsigned char *buf, int num)
170
        {
171
        const RAND_METHOD *meth = RAND_get_rand_method();
172
        if (meth && meth->pseudorand)
173
                return meth->pseudorand(buf,num);
174
        return(-1);
175
        }
176

    
177
int RAND_status(void)
178
        {
179
        const RAND_METHOD *meth = RAND_get_rand_method();
180
        if (meth && meth->status)
181
                return meth->status();
182
        return 0;
183
        }
184

    
185
#ifdef OPENSSL_FIPS
186

    
187
/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
188
 * rest of OpenSSL. 
189
 */
190

    
191
/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
192
 * entropy internally through RAND_poll().
193
 */
194

    
195
static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
196
                                int entropy, size_t min_len, size_t max_len)
197
        {
198
        /* Round up request to multiple of block size */
199
        min_len = ((min_len + 19) / 20) * 20;
200
        *pout = OPENSSL_malloc(min_len);
201
        if (!*pout)
202
                return 0;
203
        if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0)
204
                {
205
                OPENSSL_free(*pout);
206
                *pout = NULL;
207
                return 0;
208
                }
209
        return min_len;
210
        }
211

    
212
static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
213
        {
214
        if (out)
215
                {
216
                OPENSSL_cleanse(out, olen);
217
                OPENSSL_free(out);
218
                }
219
        }
220

    
221
/* Set "additional input" when generating random data. This uses the
222
 * current PID, a time value and a counter.
223
 */
224

    
225
static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
226
            {
227
        /* Use of static variables is OK as this happens under a lock */
228
        static unsigned char buf[16];
229
        static unsigned long counter;
230
        FIPS_get_timevec(buf, &counter);
231
        *pout = buf;
232
        return sizeof(buf);
233
        }
234

    
235
/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is 
236
 * correctly seeded by RAND_poll().
237
 */
238

    
239
static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
240
                                double entropy)
241
        {
242
        RAND_SSLeay()->add(in, inlen, entropy);
243
        return 1;
244
        }
245

    
246
static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
247
        {
248
        RAND_SSLeay()->seed(in, inlen);
249
        return 1;
250
        }
251

    
252
#ifndef OPENSSL_DRBG_DEFAULT_TYPE
253
#define OPENSSL_DRBG_DEFAULT_TYPE        NID_aes_256_ctr
254
#endif
255
#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
256
#define OPENSSL_DRBG_DEFAULT_FLAGS        DRBG_FLAG_CTR_USE_DF
257
#endif 
258

    
259
static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
260
static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
261

    
262
void RAND_set_fips_drbg_type(int type, int flags)
263
        {
264
        fips_drbg_type = type;
265
        fips_drbg_flags = flags;
266
        }
267

    
268
int RAND_init_fips(void)
269
        {
270
        DRBG_CTX *dctx;
271
        size_t plen;
272
        unsigned char pers[32], *p;
273
#ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
274
        if (fips_drbg_type >> 16)
275
                {
276
                RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
277
                return 0;
278
                }
279
#endif
280
                
281
        dctx = FIPS_get_default_drbg();
282
        if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
283
                {
284
                RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
285
                return 0;
286
                }
287
                
288
        FIPS_drbg_set_callbacks(dctx,
289
                                drbg_get_entropy, drbg_free_entropy, 20,
290
                                drbg_get_entropy, drbg_free_entropy);
291
        FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
292
                                        drbg_rand_seed, drbg_rand_add);
293
        /* Personalisation string: a string followed by date time vector */
294
        strcpy((char *)pers, "OpenSSL DRBG2.0");
295
        plen = drbg_get_adin(dctx, &p);
296
        memcpy(pers + 16, p, plen);
297

    
298
        if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
299
                {
300
                RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
301
                return 0;
302
                }
303
        FIPS_rand_set_method(FIPS_drbg_method());
304
        return 1;
305
        }
306

    
307
#endif