damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

random.h (2866B)


      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 #include <Security/SecRandom.h>
     26 #elif defined(__OpenBSD__)
     27 #include <unistd.h>
     28 #else
     29 #error "Couldn't identify the OS"
     30 #endif
     31 
     32 #include <stddef.h>
     33 #include <limits.h>
     34 #include <stdio.h>
     35 
     36 
     37 /* Returns 1 on success, and 0 on failure. */
     38 static int fill_random(unsigned char* data, size_t size) {
     39 #if defined(_WIN32)
     40     NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
     41     if (res != STATUS_SUCCESS || size > ULONG_MAX) {
     42         return 0;
     43     } else {
     44         return 1;
     45     }
     46 #elif defined(__linux__) || defined(__FreeBSD__)
     47     /* If `getrandom(2)` is not available you should fallback to /dev/urandom */
     48     ssize_t res = getrandom(data, size, 0);
     49     if (res < 0 || (size_t)res != size ) {
     50         return 0;
     51     } else {
     52         return 1;
     53     }
     54 #elif defined(__APPLE__) || defined(__OpenBSD__)
     55     /* If `getentropy(2)` is not available you should fallback to either
     56      * `SecRandomCopyBytes` or /dev/urandom */
     57     int res = SecRandomCopyBytes(kSecRandomDefault, size, data);
     58     if (res == 0) {
     59         return 1;
     60     } else {
     61         return 0;
     62     }
     63 #endif
     64     return 0;
     65 }
     66