unsigned random_device::operator()() { unsigned r; size_t n = sizeof(r); size_t bytes_written; int error = nacl_secure_random(&r, n, &bytes_written); if (error != 0) __throw_system_error(error, "random_device failed getting bytes"); else if (bytes_written != n) __throw_runtime_error("random_device failed to obtain enough bytes"); return r; }
void GenRandomBytes(void* dest, size_t size) { #ifdef _WIN32 HCRYPTPROV prov; if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) Sys::Error("CryptAcquireContext failed: %s", Win32StrError(GetLastError())); if (!CryptGenRandom(prov, size, (BYTE*)dest)) Sys::Error("CryptGenRandom failed: %s", Win32StrError(GetLastError())); CryptReleaseContext(prov, 0); #elif defined(__native_client__) size_t bytes_written; if (nacl_secure_random(dest, size, &bytes_written) != 0 || bytes_written != size) Sys::Error("nacl_secure_random failed"); #else int fd = open("/dev/urandom", O_RDONLY); if (fd == -1) Sys::Error("Failed to open /dev/urandom: %s", strerror(errno)); if (read(fd, dest, size) != (ssize_t) size) Sys::Error("Failed to read from /dev/urandom: %s", strerror(errno)); close(fd); #endif }