nostril

A C cli tool for creating nostr events
git clone git://jb55.com/nostril
Log | Files | Refs | Submodules | README | LICENSE

random.h (2987B)


      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     for (i = 0; i < size; i++) {
     69         fprintf(stderr, "%02x", data[i]);
     70     }
     71     fprintf(stderr, "\n");
     72 }