MCPcopy Create free account
hub / github.com/ElementsProject/elements / GetOSRand

Function GetOSRand

src/random.cpp:275–345  ·  view source on GitHub ↗

Get 32 bytes of system entropy. */

Source from the content-addressed store, hash-verified

273
274/** Get 32 bytes of system entropy. */
275void GetOSRand(unsigned char *ent32)
276{
277#if defined(WIN32)
278 HCRYPTPROV hProvider;
279 int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
280 if (!ret) {
281 RandFailure();
282 }
283 ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
284 if (!ret) {
285 RandFailure();
286 }
287 CryptReleaseContext(hProvider, 0);
288#elif defined(HAVE_SYS_GETRANDOM)
289 /* Linux. From the getrandom(2) man page:
290 * "If the urandom source has been initialized, reads of up to 256 bytes
291 * will always return as many bytes as requested and will not be
292 * interrupted by signals."
293 */
294 int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
295 if (rv != NUM_OS_RANDOM_BYTES) {
296 if (rv < 0 && errno == ENOSYS) {
297 /* Fallback for kernel <3.17: the return value will be -1 and errno
298 * ENOSYS if the syscall is not available, in that case fall back
299 * to /dev/urandom.
300 */
301 GetDevURandom(ent32);
302 } else {
303 RandFailure();
304 }
305 }
306#elif defined(__OpenBSD__)
307 /* OpenBSD. From the arc4random(3) man page:
308 "Use of these functions is encouraged for almost all random number
309 consumption because the other interfaces are deficient in either
310 quality, portability, standardization, or availability."
311 The function call is always successful.
312 */
313 arc4random_buf(ent32, NUM_OS_RANDOM_BYTES);
314 // Silence a compiler warning about unused function.
315 (void)GetDevURandom;
316#elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
317 /* getentropy() is available on macOS 10.12 and later.
318 */
319 if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
320 RandFailure();
321 }
322 // Silence a compiler warning about unused function.
323 (void)GetDevURandom;
324#elif defined(HAVE_SYSCTL_ARND)
325 /* FreeBSD, NetBSD and similar. It is possible for the call to return less
326 * bytes than requested, so need to read in a loop.
327 */
328 static int name[2] = {CTL_KERN, KERN_ARND};
329 int have = 0;
330 do {
331 size_t len = NUM_OS_RANDOM_BYTES - have;
332 if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) != 0) {

Callers 2

SeedSlowFunction · 0.85
Random_SanityCheckFunction · 0.85

Calls 3

RandFailureFunction · 0.85
GetDevURandomFunction · 0.85
sizeFunction · 0.70

Tested by

no test coverage detected