| 124 | } |
| 125 | |
| 126 | void crypto_random_bytes(span<char> buffer) |
| 127 | { |
| 128 | #ifdef TORRENT_BUILD_SIMULATOR |
| 129 | // In the simulator we want deterministic random numbers |
| 130 | std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); |
| 131 | #elif TORRENT_USE_CNG |
| 132 | aux::cng_gen_random(buffer); |
| 133 | #elif TORRENT_USE_CRYPTOAPI |
| 134 | // windows |
| 135 | aux::crypt_gen_random(buffer); |
| 136 | #elif defined TORRENT_USE_LIBCRYPTO && !defined TORRENT_USE_WOLFSSL |
| 137 | // wolfSSL uses wc_RNG_GenerateBlock as the internal function for the |
| 138 | // openssl compatibility layer. This function API does not support |
| 139 | // an arbitrary buffer size (openssl does), it is limited by the |
| 140 | // constant RNG_MAX_BLOCK_LEN. |
| 141 | // TODO: improve calling RAND_bytes multiple times, using fallback for now |
| 142 | |
| 143 | // openssl |
| 144 | int r = RAND_bytes(reinterpret_cast<unsigned char*>(buffer.data()) |
| 145 | , int(buffer.size())); |
| 146 | if (r != 1) aux::throw_ex<system_error>(errors::no_entropy); |
| 147 | #elif TORRENT_USE_GETRANDOM |
| 148 | ssize_t const r = ::getrandom(buffer.data(), static_cast<std::size_t>(buffer.size()), 0); |
| 149 | if (r == ssize_t(buffer.size())) return; |
| 150 | if (r == -1 && errno != ENOSYS) aux::throw_ex<system_error>(error_code(errno, generic_category())); |
| 151 | static dev_random dev; |
| 152 | dev.read(buffer); |
| 153 | #elif TORRENT_USE_DEV_RANDOM |
| 154 | static dev_random dev; |
| 155 | dev.read(buffer); |
| 156 | #else |
| 157 | |
| 158 | #if TORRENT_BROKEN_RANDOM_DEVICE |
| 159 | // even pseudo random numbers rely on being able to seed the random |
| 160 | // generator |
| 161 | #error "no entropy source available" |
| 162 | #else |
| 163 | #ifdef TORRENT_I_WANT_INSECURE_RANDOM_NUMBERS |
| 164 | std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); |
| 165 | #else |
| 166 | #error "no secure entropy source available. If you really want insecure random numbers, define TORRENT_I_WANT_INSECURE_RANDOM_NUMBERS" |
| 167 | #endif |
| 168 | #endif |
| 169 | |
| 170 | #endif |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | std::uint32_t random(std::uint32_t const max) |
no test coverage detected