1/*-------------------------------------------------------------------------
4 * generate a cryptographically secure random number
6 * Our definition of "strong" is that it's suitable for generating random
7 * salts and query cancellation keys, during authentication.
9 * Note: this code is run quite early in postmaster and backend startup;
10 * therefore, even when built for backend, it cannot rely on backend
11 * infrastructure such as elog() or palloc().
13 * Copyright (c) 1996-2025, PostgreSQL Global Development Group
16 * src/port/pg_strong_random.c
18 *-------------------------------------------------------------------------
28 * pg_strong_random & pg_strong_random_init
30 * Generate requested number of random bytes. The returned bytes are
31 * cryptographically secure, suitable for use e.g. in authentication.
33 * Before pg_strong_random is called in any process, the generator must first
34 * be initialized by calling pg_strong_random_init(). Initialization is a no-
35 * op for all supported randomness sources, it is kept to maintain backwards
36 * compatibility with extensions.
38 * We rely on system facilities for actually generating the numbers.
39 * We support a number of sources:
41 * 1. OpenSSL's RAND_bytes()
42 * 2. Windows' CryptGenRandom() function
45 * Returns true on success, and false if none of the sources
46 * were available. NB: It is important to check the return value!
47 * Proceeding with key generation when no random data was available
48 * would lead to predictable keys and security issues.
55#include <openssl/rand.h>
60 /* No initialization needed */
69 * Check that OpenSSL's CSPRNG has been sufficiently seeded, and if not
70 * add more seed data using RAND_poll(). With some older versions of
71 * OpenSSL, it may be necessary to call RAND_poll() a number of times. If
72 * RAND_poll() fails to generate seed data within the given amount of
73 * retries, subsequent RAND_bytes() calls will fail, but we allow that to
74 * happen to let pg_strong_random() callers handle that with appropriate
77#define NUM_RAND_POLL_RETRIES 8
79 for (
i = 0;
i < NUM_RAND_POLL_RETRIES;
i++)
81 if (RAND_status() == 1)
83 /* The CSPRNG is sufficiently seeded */
90 if (RAND_bytes(
buf,
len) == 1)
99 * Cache a global crypto provider that only gets freed when the process
100 * exits, in case we need random numbers more than once.
102static HCRYPTPROV hProvider = 0;
107 /* No initialization needed on WIN32 */
115 if (!CryptAcquireContext(&hProvider,
119 CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
122 * On failure, set back to 0 in case the value was for some reason
128 /* Re-check in case we just retrieved the provider */
131 if (CryptGenRandom(hProvider,
len,
buf))
137#else /* not USE_OPENSSL or WIN32 */
140 * Without OpenSSL or Win32 support, just read /dev/urandom ourselves.
146 /* No initialization needed */
156 f = open(
"/dev/urandom", O_RDONLY, 0);
166 continue;
/* interrupted by signal, just retry */
bool pg_strong_random(void *buf, size_t len)
void pg_strong_random_init(void)