PostgreSQL Source Code  git master
pg_strong_random.c File Reference
#include "c.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
Include dependency graph for pg_strong_random.c:

Go to the source code of this file.

Functions

bool pg_strong_random (void *buf, size_t len)
 

Function Documentation

◆ pg_strong_random()

bool pg_strong_random ( void *  buf,
size_t  len 
)

Definition at line 100 of file pg_strong_random.c.

References i.

Referenced by build_client_first_message(), build_server_first_message(), CheckMD5Auth(), drandom(), gen_random_uuid(), init_sess_key(), InitControlFile(), InitProcessGlobals(), mp_px_rand(), pad_eme_pkcs1_v15(), PerformRadiusTransaction(), pg_be_scram_build_secret(), pg_fe_scram_build_secret(), pg_random_bytes(), pgp_s2k_fill(), px_gen_salt(), RandomCancelKey(), set_random_seed(), and write_prefix().

101 {
102  /*
103  * When built with OpenSSL, use OpenSSL's RAND_bytes function.
104  */
105 #if defined(USE_OPENSSL_RANDOM)
106  int i;
107 
108  /*
109  * Check that OpenSSL's CSPRNG has been sufficiently seeded, and if not
110  * add more seed data using RAND_poll(). With some older versions of
111  * OpenSSL, it may be necessary to call RAND_poll() a number of times. If
112  * RAND_poll() fails to generate seed data within the given amount of
113  * retries, subsequent RAND_bytes() calls will fail, but we allow that to
114  * happen to let pg_strong_random() callers handle that with appropriate
115  * error handling.
116  */
117 #define NUM_RAND_POLL_RETRIES 8
118 
119  for (i = 0; i < NUM_RAND_POLL_RETRIES; i++)
120  {
121  if (RAND_status() == 1)
122  {
123  /* The CSPRNG is sufficiently seeded */
124  break;
125  }
126 
127  RAND_poll();
128  }
129 
130  if (RAND_bytes(buf, len) == 1)
131  return true;
132  return false;
133 
134  /*
135  * Windows has CryptoAPI for strong cryptographic numbers.
136  */
137 #elif defined(USE_WIN32_RANDOM)
138  if (hProvider == 0)
139  {
140  if (!CryptAcquireContext(&hProvider,
141  NULL,
142  MS_DEF_PROV,
143  PROV_RSA_FULL,
144  CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
145  {
146  /*
147  * On failure, set back to 0 in case the value was for some reason
148  * modified.
149  */
150  hProvider = 0;
151  }
152  }
153  /* Re-check in case we just retrieved the provider */
154  if (hProvider != 0)
155  {
156  if (CryptGenRandom(hProvider, len, buf))
157  return true;
158  }
159  return false;
160 
161  /*
162  * Read /dev/urandom ourselves.
163  */
164 #elif defined(USE_DEV_URANDOM)
165  if (random_from_file("/dev/urandom", buf, len))
166  return true;
167  return false;
168 
169 #else
170  /* The autoconf script should not have allowed this */
171 #error no source of random numbers configured
172 #endif
173 }
static char * buf
Definition: pg_test_fsync.c:67
int i