static void test_BCryptGenRandom(void) { NTSTATUS ret; UCHAR buffer[256]; ret = BCryptGenRandom(NULL, NULL, 0, 0); ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret); ret = BCryptGenRandom(NULL, buffer, 0, 0); ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret); ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), 0); ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret); ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); ret = BCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret); /* Zero sized buffer should work too */ ret = BCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */ memset(buffer, 0, 16); ret = BCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n"); }
int xpfurandom_get_random_data(void** data, uint32_t size, void* win_alg_handle, xpfurandom_settings* s){ NTSTATUS st; st = BCryptGenRandom(win_alg_handle, *data, size, 0); switch (st){ case STATUS_SUCCESS:break; case STATUS_INVALID_HANDLE: { fprintf(stderr, "XPFUrandom: BCryptGenRandom failed: invalid algorithm handle(STATUS_INVALID_HANDLE)\n"); return FAIL; }break; case STATUS_INVALID_PARAMETER: { fprintf(stderr, "XPFUrandom: BCryptGenRandom failed: invalid parameter(STATUS_INVALID_PARAMETER)\n"); return FAIL; }break; } if (s->file_out) { st = fwrite(*data, 1, size, s->file_out); if (st != size) { fprintf(stderr, "XPFUrandom: fwrite failed\n"); return FAIL; } st = fflush(s->file_out); if (st) { fprintf(stderr, "XPFUrandom: fflush failed: %s\n",strerror(errno)); return FAIL; } } return OK; }
int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE]) { char input[RANDBYTES]; int workf; char *aux; #ifdef WIN32 BCryptGenRandom(NULL, input, RANDBYTES, BCRYPT_USE_SYSTEM_PREFERRED_RNG); #else int fd; fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return 1; if (try_read(fd, input, RANDBYTES) != 0) { if (try_close(fd) != 0) return 4; return 2; } if (try_close(fd) != 0) return 3; #endif /* Generate salt. */ workf = (factor < 4 || factor > 31)?12:factor; aux = crypt_gensalt_rn("$2a$", workf, input, RANDBYTES, salt, BCRYPT_HASHSIZE); return (aux == NULL)?5:0; }
void NonblockingRng::GenerateBlock(byte *output, size_t size) { #ifdef CRYPTOPP_WIN32_AVAILABLE // Acquiring a provider is expensive. Do it once and retain the reference. static const MicrosoftCryptoProvider &hProvider = Singleton<MicrosoftCryptoProvider>().Ref(); # if defined(USE_MS_CRYPTOAPI) if (!CryptGenRandom(hProvider.GetProviderHandle(), (DWORD)size, output)) throw OS_RNG_Err("CryptGenRandom"); # elif defined(USE_MS_CNGAPI) NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, (ULONG)size, 0); if (!(BCRYPT_SUCCESS(ret))) { // Hack... OS_RNG_Err calls GetLastError() SetLastError(NtStatusToErrorCode(ret)); throw OS_RNG_Err("BCryptGenRandom"); } # endif #else while (size) { ssize_t len = read(m_fd, output, size); if (len < 0) { // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) if (errno != EINTR && errno != EAGAIN) throw OS_RNG_Err("read /dev/urandom"); continue; } output += len; size -= len; } #endif // CRYPTOPP_WIN32_AVAILABLE }
int _libssh2_wincng_random(void *buf, int len) { int ret; ret = BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, len, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
//***_cpri__GenerateRandom() // Generate a 'randomSize' number or random bytes. UINT16 _cpri__GenerateRandom( INT32 randomSize, BYTE *buffer ) { // // We don't do negative sizes or ones that are too large if (randomSize < 0 || randomSize > UINT16_MAX) return 0; return (BCryptGenRandom(g_hRngAlg, buffer, randomSize, 0) == ERROR_SUCCESS) ? (UINT16)randomSize : 0; }
int main(int argc, char* argv[]) { int data_amount = 0; int data_read = 0; if (argv[1] == NULL) { puts("No argument detected, exiting. Run with -h argument for help."); return -1; } if (strcmp("-h", argv[1]) == 0) { puts("Valid arguments:\n-h: Prints this\nX: Number of output bytes desired, 0<=X<2147483647"); return 0; } else { data_amount = strtol(argv[1], NULL, 10); if (data_amount == 0) { puts("Invalid argument, reading default amount of data (1KB)"); data_amount = 1024; } } PUCHAR data = calloc(data_amount+1,1); if (data == NULL) { puts("Allocation failed, exiting."); return 1; } while (data_read < data_amount) { NTSTATUS status = BCryptGenRandom(NULL, data+data_read, data_amount-data_read, 0x00000003); // argument 1 : algorithm to use, iff NULL AND (arg4 & 0x2) uses system-preferred CSPRNG (not supported on Vista) // arg 2 : pointer to data storage // arg 3 : number of bytes of data to be read // arg 4 : flags; 0x2 see above, 0x1 uses entropy in arg3 as extra(ignored on Win8+), // else uses just a random number for entropy switch (status) { case STATUS_SUCCESS: //just continue, all good break; case STATUS_INVALID_HANDLE: puts("RNG algorithm handle invalid, exiting."); return 2; break; case STATUS_INVALID_PARAMETER: puts("Most likely invalid flags, exiting"); return 2; } data_read = strlen(data); } //while-loop is necessary, test runs sometimes came up with less data than desired puts(data); // demonstrates functionality return 0; }
int RAND_poll(void) { MEMORYSTATUS mst; # ifndef RAND_WINDOWS_USE_BCRYPT HCRYPTPROV hProvider; # endif DWORD w; BYTE buf[64]; # ifdef RAND_WINDOWS_USE_BCRYPT if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) { RAND_add(buf, sizeof(buf), sizeof(buf)); } # else /* poll the CryptoAPI PRNG */ /* The CryptoAPI returns sizeof(buf) bytes of randomness */ if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) { RAND_add(buf, sizeof(buf), sizeof(buf)); } CryptReleaseContext(hProvider, 0); } /* poll the Pentium PRG with CryptoAPI */ if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) { RAND_add(buf, sizeof(buf), sizeof(buf)); } CryptReleaseContext(hProvider, 0); } # endif /* timer data */ readtimer(); /* memory usage statistics */ GlobalMemoryStatus(&mst); RAND_add(&mst, sizeof(mst), 1); /* process ID */ w = GetCurrentProcessId(); RAND_add(&w, sizeof(w), 1); return (1); }
static void read_entropy(uint8_t *entropy, size_t size) { NTSTATUS nts = 0; BCRYPT_ALG_HANDLE hAlgorithm = 0; nts = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(nts)) { nts = BCryptGenRandom(hAlgorithm, (PUCHAR)entropy, (ULONG)size, 0); (void)BCryptCloseAlgorithmProvider(hAlgorithm, 0); } if (!BCRYPT_SUCCESS(nts)) { perror("ptls_minicrypto_random_bytes: could not open BCrypt RNG Algorithm"); abort(); } }
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) { ((void)data); *olen = 0; /* * size_t may be 64 bits, but ULONG is always 32. * If len is larger than the maximum for ULONG, just fail. * It's unlikely anything ever will want to ask for this much randomness. */ if (len > 0xFFFFFFFFULL) { return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); } if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, (ULONG) len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); } *olen = len; return (0); }
int _mongoc_rand_bytes (uint8_t *buf, int num) { static BCRYPT_ALG_HANDLE algorithm = 0; NTSTATUS status = 0; if (!algorithm) { status = BCryptOpenAlgorithmProvider ( &algorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %d", status); return 0; } } status = BCryptGenRandom (algorithm, buf, num, 0); if (NT_SUCCESS (status)) { return 1; } MONGOC_ERROR ("BCryptGenRandom(): %d", status); return 0; }
/** Generate 128 bits of random noise for seeding RNGs. Attempts to * use various OS-specific sources of random bits, with a fallback * based on time and pid. */ void generate_seed(uint64_t seeds[]) { bool seed_generated = false; static int stream_count = 0; int len = sizeof(uint64_t) * 2; #ifdef HAVE_GETENTROPY /* On OpenBSD and up to date Linux, use getentropy() to avoid the open/read/close sequence with /dev/urandom */ if (!seed_generated && getentropy(seeds, len) == 0) { fprintf(stderr, "Seeded RNG with getentropy()\n"); seed_generated = true; } #endif #ifdef HAVE_ARC4RANDOM_BUF /* Most (all?) of the BSDs have this seeder. Use it for the reasons above. Also available on Linux with libbsd, but we don't check for that. */ if (!seed_generated) { arc4random_buf(seeds, len); fprintf(stderr, "Seeded RNG with arc4random\n"); seed_generated = true; } #endif #ifdef WIN32 if (!seed_generated) { /* Use the Win32 bcrypto RNG interface */ if (BCryptGenRandom(NULL, (PUCHAR) seeds, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) { fprintf(stderr, "Seeding RNG with BCryptGenRandom()\n"); seed_generated = true; } } #endif #ifdef HAVE_DEV_URANDOM if (!seed_generated) { /* Seed from /dev/urandom if available */ int fd; fd = open("/dev/urandom", O_RDONLY); if (fd >= 0) { int r = read(fd, (void *) seeds, len); close(fd); if (r != len) { fprintf(stderr, "Couldn't read from /dev/urandom! Resorting to normal " "seeding method.\n"); } else { fprintf(stderr, "Seeding RNG with /dev/urandom\n"); seed_generated = true; } } else { fprintf(stderr, "Couldn't open /dev/urandom to seed random number " "generator. Resorting to normal seeding method.\n"); } } #endif if (!seed_generated) { /* Default seeder. Pick a seed that's slightly random */ #ifdef WIN32 seeds[0] = (uint64_t) time(NULL); seeds[1] = (uint64_t) GetCurrentProcessId() + stream_count; #else seeds[0] = (uint64_t) time(NULL); seeds[1] = (uint64_t) getpid() + stream_count; #endif stream_count += 1; } }