Bitcoin Core  25.99.0
P2P Digital Currency
examples_util.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. */
37 static 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 
66 static 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 }
74 
75 #if defined(_MSC_VER)
76 // For SecureZeroMemory
77 #include <Windows.h>
78 #endif
79 /* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
80 static SECP256K1_INLINE void secure_erase(void *ptr, size_t len) {
81 #if defined(_MSC_VER)
82  /* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
83  SecureZeroMemory(ptr, len);
84 #elif defined(__GNUC__)
85  /* We use a memory barrier that scares the compiler away from optimizing out the memset.
86  *
87  * Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
88  * in BoringSSL (ISC License):
89  * As best as we can tell, this is sufficient to break any optimisations that
90  * might try to eliminate "superfluous" memsets.
91  * This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is
92  * pretty efficient, because the compiler can still implement the memset() efficently,
93  * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
94  * Yang et al. (USENIX Security 2017) for more background.
95  */
96  memset(ptr, 0, len);
97  __asm__ __volatile__("" : : "r"(ptr) : "memory");
98 #else
99  void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
100  volatile_memset(ptr, 0, len);
101 #endif
102 }
static int fill_random(unsigned char *data, size_t size)
Definition: examples_util.h:37
static void print_hex(unsigned char *data, size_t size)
Definition: examples_util.h:66
static SECP256K1_INLINE void secure_erase(void *ptr, size_t len)
Definition: examples_util.h:80
void printf(const char *fmt, const Args &... args)
Format list of arguments to std::cout, according to the given format string.
Definition: tinyformat.h:1077
#define SECP256K1_INLINE
Definition: secp256k1.h:131