Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
random.h
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2020-2021 Elichai Turkel *
3 * Distributed under the CC0 software license, see the accompanying file *
4 * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
5 *************************************************************************/
6
7/*
8 * This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems.
9 * It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below.
10 *
11 * Platform randomness sources:
12 * Linux -> `getrandom(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. http://man7.org/linux/man-pages/man2/getrandom.2.html, https://linux.die.net/man/4/urandom
13 * macOS -> `getentropy(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. https://www.unix.com/man-page/mojave/2/getentropy, https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man4/random.4.auto.html
14 * FreeBSD -> `getrandom(2)`(`sys/random.h`), if not available `kern.arandom` should be used. https://www.freebsd.org/cgi/man.cgi?query=getrandom, https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
15 * OpenBSD -> `getentropy(2)`(`unistd.h`), if not available `/dev/urandom` should be used. https://man.openbsd.org/getentropy, https://man.openbsd.org/urandom
16 * Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
17 */
18
19#if defined(_WIN32)
20#include <windows.h>
21#include <ntstatus.h>
22#include <bcrypt.h>
23#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
24#include <sys/random.h>
25#elif defined(__OpenBSD__)
26#include <unistd.h>
27#else
28#error "Couldn't identify the OS"
29#endif
30
31#include <stddef.h>
32#include <limits.h>
33#include <stdio.h>
34
35
36/* Returns 1 on success, and 0 on failure. */
37static int fill_random(unsigned char* data, size_t size) {
38#if defined(_WIN32)
39 NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
40 if (res != STATUS_SUCCESS || size > ULONG_MAX) {
41 return 0;
42 } else {
43 return 1;
44 }
45#elif defined(__linux__) || defined(__FreeBSD__)
46 /* If `getrandom(2)` is not available you should fallback to /dev/urandom */
47 ssize_t res = getrandom(data, size, 0);
48 if (res < 0 || (size_t)res != size ) {
49 return 0;
50 } else {
51 return 1;
52 }
53#elif defined(__APPLE__) || defined(__OpenBSD__)
54 /* If `getentropy(2)` is not available you should fallback to either
55 * `SecRandomCopyBytes` or /dev/urandom */
56 int res = getentropy(data, size);
57 if (res == 0) {
58 return 1;
59 } else {
60 return 0;
61 }
62#endif
63 return 0;
64}
65
66static void print_hex(unsigned char* data, size_t size) {
67 size_t i;
68 printf("0x");
69 for (i = 0; i < size; i++) {
70 printf("%02x", data[i]);
71 }
72 printf("\n");
73}
LOGGING_API void printf(Category category, const char *format,...)
Definition Logging.cpp:30