Bitcoin Core  0.20.99
P2P Digital Currency
randomenv.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
8 #endif
9 
10 #include <randomenv.h>
11 
12 #include <clientversion.h>
13 #include <compat/cpuid.h>
14 #include <crypto/sha512.h>
15 #include <support/cleanse.h>
16 #include <util/time.h> // for GetTime()
17 #ifdef WIN32
18 #include <compat.h> // for Windows API
19 #endif
20 
21 #include <algorithm>
22 #include <atomic>
23 #include <chrono>
24 #include <climits>
25 #include <thread>
26 #include <vector>
27 
28 #include <stdint.h>
29 #include <string.h>
30 #ifndef WIN32
31 #include <sys/types.h> // must go before a number of other headers
32 #include <fcntl.h>
33 #include <netinet/in.h>
34 #include <sys/resource.h>
35 #include <sys/socket.h>
36 #include <sys/stat.h>
37 #include <sys/time.h>
38 #include <sys/utsname.h>
39 #include <unistd.h>
40 #endif
41 #if HAVE_DECL_GETIFADDRS
42 #include <ifaddrs.h>
43 #endif
44 #if HAVE_SYSCTL
45 #include <sys/sysctl.h>
46 #if HAVE_VM_VM_PARAM_H
47 #include <vm/vm_param.h>
48 #endif
49 #if HAVE_SYS_RESOURCES_H
50 #include <sys/resources.h>
51 #endif
52 #if HAVE_SYS_VMMETER_H
53 #include <sys/vmmeter.h>
54 #endif
55 #endif
56 #ifdef __linux__
57 #include <sys/auxv.h>
58 #endif
59 
61 extern char** environ;
62 
63 namespace {
64 
65 void RandAddSeedPerfmon(CSHA512& hasher)
66 {
67 #ifdef WIN32
68  // Seed with the entire set of perfmon data
69 
70  // This can take up to 2 seconds, so only do it every 10 minutes
71  static std::atomic<std::chrono::seconds> last_perfmon{std::chrono::seconds{0}};
72  auto last_time = last_perfmon.load();
73  auto current_time = GetTime<std::chrono::seconds>();
74  if (current_time < last_time + std::chrono::minutes{10}) return;
75  last_perfmon = current_time;
76 
77  std::vector<unsigned char> vData(250000, 0);
78  long ret = 0;
79  unsigned long nSize = 0;
80  const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
81  while (true) {
82  nSize = vData.size();
83  ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize);
84  if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
85  break;
86  vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
87  }
88  RegCloseKey(HKEY_PERFORMANCE_DATA);
89  if (ret == ERROR_SUCCESS) {
90  hasher.Write(vData.data(), nSize);
91  memory_cleanse(vData.data(), nSize);
92  } else {
93  // Performance data is only a best-effort attempt at improving the
94  // situation when the OS randomness (and other sources) aren't
95  // adequate. As a result, failure to read it is isn't considered critical,
96  // so we don't call RandFailure().
97  // TODO: Add logging when the logger is made functional before global
98  // constructors have been invoked.
99  }
100 #endif
101 }
102 
108 template<typename T>
109 CSHA512& operator<<(CSHA512& hasher, const T& data) {
110  static_assert(!std::is_same<typename std::decay<T>::type, char*>::value, "Calling operator<<(CSHA512, char*) is probably not what you want");
111  static_assert(!std::is_same<typename std::decay<T>::type, unsigned char*>::value, "Calling operator<<(CSHA512, unsigned char*) is probably not what you want");
112  static_assert(!std::is_same<typename std::decay<T>::type, const char*>::value, "Calling operator<<(CSHA512, const char*) is probably not what you want");
113  static_assert(!std::is_same<typename std::decay<T>::type, const unsigned char*>::value, "Calling operator<<(CSHA512, const unsigned char*) is probably not what you want");
114  hasher.Write((const unsigned char*)&data, sizeof(data));
115  return hasher;
116 }
117 
118 #ifndef WIN32
119 void AddSockaddr(CSHA512& hasher, const struct sockaddr *addr)
120 {
121  if (addr == nullptr) return;
122  switch (addr->sa_family) {
123  case AF_INET:
124  hasher.Write((const unsigned char*)addr, sizeof(sockaddr_in));
125  break;
126  case AF_INET6:
127  hasher.Write((const unsigned char*)addr, sizeof(sockaddr_in6));
128  break;
129  default:
130  hasher.Write((const unsigned char*)&addr->sa_family, sizeof(addr->sa_family));
131  }
132 }
133 
134 void AddFile(CSHA512& hasher, const char *path)
135 {
136  struct stat sb = {};
137  int f = open(path, O_RDONLY);
138  size_t total = 0;
139  if (f != -1) {
140  unsigned char fbuf[4096];
141  int n;
142  hasher.Write((const unsigned char*)&f, sizeof(f));
143  if (fstat(f, &sb) == 0) hasher << sb;
144  do {
145  n = read(f, fbuf, sizeof(fbuf));
146  if (n > 0) hasher.Write(fbuf, n);
147  total += n;
148  /* not bothering with EINTR handling. */
149  } while (n == sizeof(fbuf) && total < 1048576); // Read only the first 1 Mbyte
150  close(f);
151  }
152 }
153 
154 void AddPath(CSHA512& hasher, const char *path)
155 {
156  struct stat sb = {};
157  if (stat(path, &sb) == 0) {
158  hasher.Write((const unsigned char*)path, strlen(path) + 1);
159  hasher << sb;
160  }
161 }
162 #endif
163 
164 #if HAVE_SYSCTL
165 template<int... S>
166 void AddSysctl(CSHA512& hasher)
167 {
168  int CTL[sizeof...(S)] = {S...};
169  unsigned char buffer[65536];
170  size_t siz = 65536;
171  int ret = sysctl(CTL, sizeof...(S), buffer, &siz, nullptr, 0);
172  if (ret == 0 || (ret == -1 && errno == ENOMEM)) {
173  hasher << sizeof(CTL);
174  hasher.Write((const unsigned char*)CTL, sizeof(CTL));
175  if (siz > sizeof(buffer)) siz = sizeof(buffer);
176  hasher << siz;
177  hasher.Write(buffer, siz);
178  }
179 }
180 #endif
181 
182 #ifdef HAVE_GETCPUID
183 void inline AddCPUID(CSHA512& hasher, uint32_t leaf, uint32_t subleaf, uint32_t& ax, uint32_t& bx, uint32_t& cx, uint32_t& dx)
184 {
185  GetCPUID(leaf, subleaf, ax, bx, cx, dx);
186  hasher << leaf << subleaf << ax << bx << cx << dx;
187 }
188 
189 void AddAllCPUID(CSHA512& hasher)
190 {
191  uint32_t ax, bx, cx, dx;
192  // Iterate over all standard leaves
193  AddCPUID(hasher, 0, 0, ax, bx, cx, dx); // Returns max leaf in ax
194  uint32_t max = ax;
195  for (uint32_t leaf = 1; leaf <= max && leaf <= 0xFF; ++leaf) {
196  uint32_t maxsub = 0;
197  for (uint32_t subleaf = 0; subleaf <= 0xFF; ++subleaf) {
198  AddCPUID(hasher, leaf, subleaf, ax, bx, cx, dx);
199  // Iterate subleafs for leaf values 4, 7, 11, 13
200  if (leaf == 4) {
201  if ((ax & 0x1f) == 0) break;
202  } else if (leaf == 7) {
203  if (subleaf == 0) maxsub = ax;
204  if (subleaf == maxsub) break;
205  } else if (leaf == 11) {
206  if ((cx & 0xff00) == 0) break;
207  } else if (leaf == 13) {
208  if (ax == 0 && bx == 0 && cx == 0 && dx == 0) break;
209  } else {
210  // For any other leaf, stop after subleaf 0.
211  break;
212  }
213  }
214  }
215  // Iterate over all extended leaves
216  AddCPUID(hasher, 0x80000000, 0, ax, bx, cx, dx); // Returns max extended leaf in ax
217  uint32_t ext_max = ax;
218  for (uint32_t leaf = 0x80000001; leaf <= ext_max && leaf <= 0x800000FF; ++leaf) {
219  AddCPUID(hasher, leaf, 0, ax, bx, cx, dx);
220  }
221 }
222 #endif
223 } // namespace
224 
226 {
227  RandAddSeedPerfmon(hasher);
228 
229  // Various clocks
230 #ifdef WIN32
231  FILETIME ftime;
232  GetSystemTimeAsFileTime(&ftime);
233  hasher << ftime;
234 #else
235  struct timespec ts = {};
236 # ifdef CLOCK_MONOTONIC
237  clock_gettime(CLOCK_MONOTONIC, &ts);
238  hasher << ts;
239 # endif
240 # ifdef CLOCK_REALTIME
241  clock_gettime(CLOCK_REALTIME, &ts);
242  hasher << ts;
243 # endif
244 # ifdef CLOCK_BOOTTIME
245  clock_gettime(CLOCK_BOOTTIME, &ts);
246  hasher << ts;
247 # endif
248  // gettimeofday is available on all UNIX systems, but only has microsecond precision.
249  struct timeval tv = {};
250  gettimeofday(&tv, nullptr);
251  hasher << tv;
252 #endif
253  // Probably redundant, but also use all the clocks C++11 provides:
254  hasher << std::chrono::system_clock::now().time_since_epoch().count();
255  hasher << std::chrono::steady_clock::now().time_since_epoch().count();
256  hasher << std::chrono::high_resolution_clock::now().time_since_epoch().count();
257 
258 #ifndef WIN32
259  // Current resource usage.
260  struct rusage usage = {};
261  if (getrusage(RUSAGE_SELF, &usage) == 0) hasher << usage;
262 #endif
263 
264 #ifdef __linux__
265  AddFile(hasher, "/proc/diskstats");
266  AddFile(hasher, "/proc/vmstat");
267  AddFile(hasher, "/proc/schedstat");
268  AddFile(hasher, "/proc/zoneinfo");
269  AddFile(hasher, "/proc/meminfo");
270  AddFile(hasher, "/proc/softirqs");
271  AddFile(hasher, "/proc/stat");
272  AddFile(hasher, "/proc/self/schedstat");
273  AddFile(hasher, "/proc/self/status");
274 #endif
275 
276 #if HAVE_SYSCTL
277 # ifdef CTL_KERN
278 # if defined(KERN_PROC) && defined(KERN_PROC_ALL)
279  AddSysctl<CTL_KERN, KERN_PROC, KERN_PROC_ALL>(hasher);
280 # endif
281 # endif
282 # ifdef CTL_HW
283 # ifdef HW_DISKSTATS
284  AddSysctl<CTL_HW, HW_DISKSTATS>(hasher);
285 # endif
286 # endif
287 # ifdef CTL_VM
288 # ifdef VM_LOADAVG
289  AddSysctl<CTL_VM, VM_LOADAVG>(hasher);
290 # endif
291 # ifdef VM_TOTAL
292  AddSysctl<CTL_VM, VM_TOTAL>(hasher);
293 # endif
294 # ifdef VM_METER
295  AddSysctl<CTL_VM, VM_METER>(hasher);
296 # endif
297 # endif
298 #endif
299 
300  // Stack and heap location
301  void* addr = malloc(4097);
302  hasher << &addr << addr;
303  free(addr);
304 }
305 
307 {
308  // Some compile-time static properties
309  hasher << (CHAR_MIN < 0) << sizeof(void*) << sizeof(long) << sizeof(int);
310 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
311  hasher << __GNUC__ << __GNUC_MINOR__ << __GNUC_PATCHLEVEL__;
312 #endif
313 #ifdef _MSC_VER
314  hasher << _MSC_VER;
315 #endif
316  hasher << __cplusplus;
317 #ifdef _XOPEN_VERSION
318  hasher << _XOPEN_VERSION;
319 #endif
320 #ifdef __VERSION__
321  const char* COMPILER_VERSION = __VERSION__;
322  hasher.Write((const unsigned char*)COMPILER_VERSION, strlen(COMPILER_VERSION) + 1);
323 #endif
324 
325  // Bitcoin client version
326  hasher << CLIENT_VERSION;
327 
328 #ifdef __linux__
329  // Information available through getauxval()
330 # ifdef AT_HWCAP
331  hasher << getauxval(AT_HWCAP);
332 # endif
333 # ifdef AT_HWCAP2
334  hasher << getauxval(AT_HWCAP2);
335 # endif
336 # ifdef AT_RANDOM
337  const unsigned char* random_aux = (const unsigned char*)getauxval(AT_RANDOM);
338  if (random_aux) hasher.Write(random_aux, 16);
339 # endif
340 # ifdef AT_PLATFORM
341  const char* platform_str = (const char*)getauxval(AT_PLATFORM);
342  if (platform_str) hasher.Write((const unsigned char*)platform_str, strlen(platform_str) + 1);
343 # endif
344 # ifdef AT_EXECFN
345  const char* exec_str = (const char*)getauxval(AT_EXECFN);
346  if (exec_str) hasher.Write((const unsigned char*)exec_str, strlen(exec_str) + 1);
347 # endif
348 #endif // __linux__
349 
350 #ifdef HAVE_GETCPUID
351  AddAllCPUID(hasher);
352 #endif
353 
354  // Memory locations
355  hasher << &hasher << &RandAddStaticEnv << &malloc << &errno << &environ;
356 
357  // Hostname
358  char hname[256];
359  if (gethostname(hname, 256) == 0) {
360  hasher.Write((const unsigned char*)hname, strnlen(hname, 256));
361  }
362 
363 #if HAVE_DECL_GETIFADDRS
364  // Network interfaces
365  struct ifaddrs *ifad = NULL;
366  getifaddrs(&ifad);
367  struct ifaddrs *ifit = ifad;
368  while (ifit != NULL) {
369  hasher.Write((const unsigned char*)&ifit, sizeof(ifit));
370  hasher.Write((const unsigned char*)ifit->ifa_name, strlen(ifit->ifa_name) + 1);
371  hasher.Write((const unsigned char*)&ifit->ifa_flags, sizeof(ifit->ifa_flags));
372  AddSockaddr(hasher, ifit->ifa_addr);
373  AddSockaddr(hasher, ifit->ifa_netmask);
374  AddSockaddr(hasher, ifit->ifa_dstaddr);
375  ifit = ifit->ifa_next;
376  }
377  freeifaddrs(ifad);
378 #endif
379 
380 #ifndef WIN32
381  // UNIX kernel information
382  struct utsname name;
383  if (uname(&name) != -1) {
384  hasher.Write((const unsigned char*)&name.sysname, strlen(name.sysname) + 1);
385  hasher.Write((const unsigned char*)&name.nodename, strlen(name.nodename) + 1);
386  hasher.Write((const unsigned char*)&name.release, strlen(name.release) + 1);
387  hasher.Write((const unsigned char*)&name.version, strlen(name.version) + 1);
388  hasher.Write((const unsigned char*)&name.machine, strlen(name.machine) + 1);
389  }
390 
391  /* Path and filesystem provided data */
392  AddPath(hasher, "/");
393  AddPath(hasher, ".");
394  AddPath(hasher, "/tmp");
395  AddPath(hasher, "/home");
396  AddPath(hasher, "/proc");
397 #ifdef __linux__
398  AddFile(hasher, "/proc/cmdline");
399  AddFile(hasher, "/proc/cpuinfo");
400  AddFile(hasher, "/proc/version");
401 #endif
402  AddFile(hasher, "/etc/passwd");
403  AddFile(hasher, "/etc/group");
404  AddFile(hasher, "/etc/hosts");
405  AddFile(hasher, "/etc/resolv.conf");
406  AddFile(hasher, "/etc/timezone");
407  AddFile(hasher, "/etc/localtime");
408 #endif
409 
410  // For MacOS/BSDs, gather data through sysctl instead of /proc. Not all of these
411  // will exist on every system.
412 #if HAVE_SYSCTL
413 # ifdef CTL_HW
414 # ifdef HW_MACHINE
415  AddSysctl<CTL_HW, HW_MACHINE>(hasher);
416 # endif
417 # ifdef HW_MODEL
418  AddSysctl<CTL_HW, HW_MODEL>(hasher);
419 # endif
420 # ifdef HW_NCPU
421  AddSysctl<CTL_HW, HW_NCPU>(hasher);
422 # endif
423 # ifdef HW_PHYSMEM
424  AddSysctl<CTL_HW, HW_PHYSMEM>(hasher);
425 # endif
426 # ifdef HW_USERMEM
427  AddSysctl<CTL_HW, HW_USERMEM>(hasher);
428 # endif
429 # ifdef HW_MACHINE_ARCH
430  AddSysctl<CTL_HW, HW_MACHINE_ARCH>(hasher);
431 # endif
432 # ifdef HW_REALMEM
433  AddSysctl<CTL_HW, HW_REALMEM>(hasher);
434 # endif
435 # ifdef HW_CPU_FREQ
436  AddSysctl<CTL_HW, HW_CPU_FREQ>(hasher);
437 # endif
438 # ifdef HW_BUS_FREQ
439  AddSysctl<CTL_HW, HW_BUS_FREQ>(hasher);
440 # endif
441 # ifdef HW_CACHELINE
442  AddSysctl<CTL_HW, HW_CACHELINE>(hasher);
443 # endif
444 # endif
445 # ifdef CTL_KERN
446 # ifdef KERN_BOOTFILE
447  AddSysctl<CTL_KERN, KERN_BOOTFILE>(hasher);
448 # endif
449 # ifdef KERN_BOOTTIME
450  AddSysctl<CTL_KERN, KERN_BOOTTIME>(hasher);
451 # endif
452 # ifdef KERN_CLOCKRATE
453  AddSysctl<CTL_KERN, KERN_CLOCKRATE>(hasher);
454 # endif
455 # ifdef KERN_HOSTID
456  AddSysctl<CTL_KERN, KERN_HOSTID>(hasher);
457 # endif
458 # ifdef KERN_HOSTUUID
459  AddSysctl<CTL_KERN, KERN_HOSTUUID>(hasher);
460 # endif
461 # ifdef KERN_HOSTNAME
462  AddSysctl<CTL_KERN, KERN_HOSTNAME>(hasher);
463 # endif
464 # ifdef KERN_OSRELDATE
465  AddSysctl<CTL_KERN, KERN_OSRELDATE>(hasher);
466 # endif
467 # ifdef KERN_OSRELEASE
468  AddSysctl<CTL_KERN, KERN_OSRELEASE>(hasher);
469 # endif
470 # ifdef KERN_OSREV
471  AddSysctl<CTL_KERN, KERN_OSREV>(hasher);
472 # endif
473 # ifdef KERN_OSTYPE
474  AddSysctl<CTL_KERN, KERN_OSTYPE>(hasher);
475 # endif
476 # ifdef KERN_POSIX1
477  AddSysctl<CTL_KERN, KERN_OSREV>(hasher);
478 # endif
479 # ifdef KERN_VERSION
480  AddSysctl<CTL_KERN, KERN_VERSION>(hasher);
481 # endif
482 # endif
483 #endif
484 
485  // Env variables
486  if (environ) {
487  for (size_t i = 0; environ[i]; ++i) {
488  hasher.Write((const unsigned char*)environ[i], strlen(environ[i]));
489  }
490  }
491 
492  // Process, thread, user, session, group, ... ids.
493 #ifdef WIN32
494  hasher << GetCurrentProcessId() << GetCurrentThreadId();
495 #else
496  hasher << getpid() << getppid() << getsid(0) << getpgid(0) << getuid() << geteuid() << getgid() << getegid();
497 #endif
498  hasher << std::this_thread::get_id();
499 }
char ** environ
Necessary on some platforms.
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
size_t strnlen(const char *start, size_t max_len)
Definition: strnlen.cpp:12
CSHA512 & Write(const unsigned char *data, size_t len)
Definition: sha512.cpp:159
A hasher class for SHA-512.
Definition: sha512.h:12
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:306
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:225