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 BootStrapXLOG(), build_client_first_message(), build_server_first_message(), CheckMD5Auth(), drandom(), gen_random_uuid(), init_sess_key(), 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.
112  */
113 #define NUM_RAND_POLL_RETRIES 8
114 
115  for (i = 0; i < NUM_RAND_POLL_RETRIES; i++)
116  {
117  if (RAND_status() == 1)
118  {
119  /* The CSPRNG is sufficiently seeded */
120  break;
121  }
122 
123  if (RAND_poll() == 0)
124  {
125  /*
126  * RAND_poll() failed to generate any seed data, which means that
127  * RAND_bytes() will probably fail. For now, just fall through
128  * and let that happen. XXX: maybe we could seed it some other
129  * way.
130  */
131  break;
132  }
133  }
134 
135  if (RAND_bytes(buf, len) == 1)
136  return true;
137  return false;
138 
139  /*
140  * Windows has CryptoAPI for strong cryptographic numbers.
141  */
142 #elif defined(USE_WIN32_RANDOM)
143  if (hProvider == 0)
144  {
145  if (!CryptAcquireContext(&hProvider,
146  NULL,
147  MS_DEF_PROV,
148  PROV_RSA_FULL,
149  CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
150  {
151  /*
152  * On failure, set back to 0 in case the value was for some reason
153  * modified.
154  */
155  hProvider = 0;
156  }
157  }
158  /* Re-check in case we just retrieved the provider */
159  if (hProvider != 0)
160  {
161  if (CryptGenRandom(hProvider, len, buf))
162  return true;
163  }
164  return false;
165 
166  /*
167  * Read /dev/urandom ourselves.
168  */
169 #elif defined(USE_DEV_URANDOM)
170  if (random_from_file("/dev/urandom", buf, len))
171  return true;
172  return false;
173 
174 #else
175  /* The autoconf script should not have allowed this */
176 #error no source of random numbers configured
177 #endif
178 }
static char * buf
Definition: pg_test_fsync.c:67
int i