1 #ifdef _WIN32 2 #include <Wincrypt.h> 3 #else 4 #include <fcntl.h> 5 #include <unistd.h> 6 /* for defined(BSD) */ 7 #include <sys/param.h> 8 9 #ifdef BSD 10 /* for SYS_getentropy */ 11 #include <sys/syscall.h> 12 #endif 13 14 #ifdef __APPLE__ 15 #include <sys/random.h> 16 /* To support weak linking we need to declare this as a weak import even if 17 * it's not present in sys/random (e.g. macOS < 10.12). */ 18 extern int getentropy(void *buffer, size_t size) __attribute((weak_import)); 19 #endif 20 21 #ifdef __linux__ 22 /* for SYS_getrandom */ 23 #include <sys/syscall.h> 24 #ifndef GRND_NONBLOCK 25 #define GRND_NONBLOCK 0x0001 26 #endif /* GRND_NONBLOCK */ 27 #endif /* __linux__ */ 28 #endif /* _WIN32 */ 29 30 #define CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM 1 31 #define CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY 2 32 #define CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM 3 33 #define CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM 4 34 35 #ifndef CRYPTOGRAPHY_OSRANDOM_ENGINE 36 #if defined(_WIN32) 37 /* Windows */ 38 #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM 39 #elif defined(BSD) && defined(SYS_getentropy) 40 /* OpenBSD 5.6+ & macOS with SYS_getentropy defined, although < 10.12 will fallback 41 * to urandom */ 42 #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY 43 #elif defined(__linux__) && defined(SYS_getrandom) 44 /* Linux 3.17+ */ 45 #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM 46 #else 47 /* Keep this as last entry, fall back to /dev/urandom */ 48 #define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM 49 #endif 50 #endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE */ 51 52 /* Fallbacks need /dev/urandom helper functions. */ 53 #if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM || \ 54 CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM || \ 55 (CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY && \ 56 defined(__APPLE__)) 57 #define CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM 1 58 #endif 59 60 enum { 61 CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED = -2, 62 CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT, 63 CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK, 64 CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS 65 }; 66 67 enum { 68 CRYPTOGRAPHY_OSRANDOM_GETENTROPY_NOT_INIT, 69 CRYPTOGRAPHY_OSRANDOM_GETENTROPY_FALLBACK, 70 CRYPTOGRAPHY_OSRANDOM_GETENTROPY_WORKS 71 }; 72 73 /* engine ctrl */ 74 #define CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION ENGINE_CMD_BASE 75 76 /* error reporting */ 77 static void ERR_load_Cryptography_OSRandom_strings(void); 78 static void ERR_Cryptography_OSRandom_error(int function, int reason, 79 char *file, int line); 80 81 #define CRYPTOGRAPHY_OSRANDOM_F_INIT 100 82 #define CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES 101 83 #define CRYPTOGRAPHY_OSRANDOM_F_FINISH 102 84 #define CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD 300 85 #define CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ 301 86 87 #define CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT 100 88 #define CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM 101 89 #define CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT 102 90 91 #define CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED 200 92 93 #define CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED 300 94 #define CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED 301 95 96 #define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED 400 97 #define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED 402 98 #define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED 403 99 #define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT 404 100