]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/rand/rand_lib.c
Make clear error message if opt_<number> fails
[thirdparty/openssl.git] / crypto / rand / rand_lib.c
CommitLineData
b1322259
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
dfeab068 3 *
b1322259
RS
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
dfeab068
RE
8 */
9
10#include <stdio.h>
dfeab068 11#include <time.h>
b39fc560 12#include "internal/cryptlib.h"
98186eb4 13#include <openssl/opensslconf.h>
f3cd81d6 14#include "internal/rand.h"
3c27208f 15#include <openssl/engine.h>
87975cfa 16#include "internal/thread_once.h"
dfeab068 17
0b13e9f0 18#ifndef OPENSSL_NO_ENGINE
cb78486d 19/* non-NULL if default_RAND_meth is ENGINE-provided */
0f113f3e 20static ENGINE *funct_ref = NULL;
87975cfa 21static CRYPTO_RWLOCK *rand_engine_lock = NULL;
0b13e9f0 22#endif
cb78486d 23static const RAND_METHOD *default_RAND_meth = NULL;
87975cfa
RL
24static CRYPTO_RWLOCK *rand_meth_lock = NULL;
25static CRYPTO_ONCE rand_lock_init = CRYPTO_ONCE_STATIC_INIT;
26
27DEFINE_RUN_ONCE_STATIC(do_rand_lock_init)
28{
2f881d2d 29 int ret = 1;
87975cfa
RL
30#ifndef OPENSSL_NO_ENGINE
31 rand_engine_lock = CRYPTO_THREAD_lock_new();
2f881d2d 32 ret &= rand_engine_lock != NULL;
87975cfa
RL
33#endif
34 rand_meth_lock = CRYPTO_THREAD_lock_new();
2f881d2d
RL
35 ret &= rand_meth_lock != NULL;
36 return ret;
87975cfa 37}
dfeab068 38
cb78486d 39int RAND_set_rand_method(const RAND_METHOD *meth)
0f113f3e 40{
87975cfa
RL
41 if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
42 return 0;
43
44 CRYPTO_THREAD_write_lock(rand_meth_lock);
0b13e9f0 45#ifndef OPENSSL_NO_ENGINE
7c96dbcd
RS
46 ENGINE_finish(funct_ref);
47 funct_ref = NULL;
0b13e9f0 48#endif
0f113f3e 49 default_RAND_meth = meth;
87975cfa 50 CRYPTO_THREAD_unlock(rand_meth_lock);
0f113f3e
MC
51 return 1;
52}
dfeab068 53
a4a9d97a 54const RAND_METHOD *RAND_get_rand_method(void)
0f113f3e 55{
87975cfa
RL
56 const RAND_METHOD *tmp_meth = NULL;
57
58 if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
59 return NULL;
60
61 CRYPTO_THREAD_write_lock(rand_meth_lock);
0f113f3e 62 if (!default_RAND_meth) {
0b13e9f0 63#ifndef OPENSSL_NO_ENGINE
0f113f3e
MC
64 ENGINE *e = ENGINE_get_default_RAND();
65 if (e) {
66 default_RAND_meth = ENGINE_get_RAND(e);
7c96dbcd 67 if (default_RAND_meth == NULL) {
0f113f3e
MC
68 ENGINE_finish(e);
69 e = NULL;
70 }
71 }
72 if (e)
73 funct_ref = e;
74 else
0b13e9f0 75#endif
b0700d2c 76 default_RAND_meth = RAND_OpenSSL();
0f113f3e 77 }
87975cfa
RL
78 tmp_meth = default_RAND_meth;
79 CRYPTO_THREAD_unlock(rand_meth_lock);
80 return tmp_meth;
0f113f3e 81}
cb78486d 82
0b13e9f0 83#ifndef OPENSSL_NO_ENGINE
cb78486d 84int RAND_set_rand_engine(ENGINE *engine)
0f113f3e
MC
85{
86 const RAND_METHOD *tmp_meth = NULL;
87975cfa
RL
87
88 if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
89 return 0;
90
0f113f3e
MC
91 if (engine) {
92 if (!ENGINE_init(engine))
93 return 0;
94 tmp_meth = ENGINE_get_RAND(engine);
7c96dbcd 95 if (tmp_meth == NULL) {
0f113f3e
MC
96 ENGINE_finish(engine);
97 return 0;
98 }
99 }
87975cfa 100 CRYPTO_THREAD_write_lock(rand_engine_lock);
0f113f3e
MC
101 /* This function releases any prior ENGINE so call it first */
102 RAND_set_rand_method(tmp_meth);
103 funct_ref = engine;
87975cfa 104 CRYPTO_THREAD_unlock(rand_engine_lock);
0f113f3e
MC
105 return 1;
106}
0b13e9f0 107#endif
dfeab068 108
b3599dbb 109void rand_cleanup_int(void)
0f113f3e 110{
5006b37b 111 const RAND_METHOD *meth = default_RAND_meth;
0f113f3e
MC
112 if (meth && meth->cleanup)
113 meth->cleanup();
114 RAND_set_rand_method(NULL);
87975cfa 115 CRYPTO_THREAD_lock_free(rand_meth_lock);
ce57ac43 116#ifndef OPENSSL_NO_ENGINE
87975cfa 117 CRYPTO_THREAD_lock_free(rand_engine_lock);
ce57ac43 118#endif
0f113f3e 119}
dfeab068 120
6343829a 121void RAND_seed(const void *buf, int num)
0f113f3e
MC
122{
123 const RAND_METHOD *meth = RAND_get_rand_method();
124 if (meth && meth->seed)
125 meth->seed(buf, num);
126}
dfeab068 127
6343829a 128void RAND_add(const void *buf, int num, double entropy)
0f113f3e
MC
129{
130 const RAND_METHOD *meth = RAND_get_rand_method();
131 if (meth && meth->add)
132 meth->add(buf, num, entropy);
133}
eb952088 134
6343829a 135int RAND_bytes(unsigned char *buf, int num)
0f113f3e
MC
136{
137 const RAND_METHOD *meth = RAND_get_rand_method();
138 if (meth && meth->bytes)
139 return meth->bytes(buf, num);
140 return (-1);
141}
dfeab068 142
98186eb4 143#if OPENSSL_API_COMPAT < 0x10100000L
6343829a 144int RAND_pseudo_bytes(unsigned char *buf, int num)
0f113f3e
MC
145{
146 const RAND_METHOD *meth = RAND_get_rand_method();
147 if (meth && meth->pseudorand)
148 return meth->pseudorand(buf, num);
149 return (-1);
150}
302d38e3 151#endif
5eb8ca4d
BM
152
153int RAND_status(void)
0f113f3e
MC
154{
155 const RAND_METHOD *meth = RAND_get_rand_method();
156 if (meth && meth->status)
157 return meth->status();
158 return 0;
159}