2 * Adaped from libtomcrypt by Tom St Denis.
4 * by Nathan Wagner, and released into the public domain
10 #define USE_DEVRANDOM 1
15 /* on *NIX read /dev/random */
16 static unsigned long rng_nix(unsigned char *buf, unsigned long len) {
20 f = fopen("/dev/urandom", "rb");
22 f = fopen("/dev/random", "rb");
29 /* disable buffering */
30 if (setvbuf(f, NULL, _IONBF, 0) != 0) {
35 x = fread(buf, 1, (size_t) len, f);
42 /* TODO remove this. It's too slow really (I think) */
43 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
44 #if defined(CLOCKS_PER_SEC) && !defined(WINCE)
48 static unsigned long rng_ansic(unsigned char *buf, unsigned long len) {
50 int l, acc, bits, a, b;
52 if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
62 while (t1 == XCLOCK())
65 while (t1 == XCLOCK())
74 acc = bits = a = b = 0;
80 /* Try the Microsoft CSP */
81 #if defined(WIN32) || defined(WINCE)
83 #define _WIN32_WINNT 0x0400
91 static unsigned long rng_win32(unsigned char *buf, unsigned long len) {
94 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
95 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
96 !CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
97 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
100 if (CryptGenRandom(hProv, len, buf) == TRUE) {
101 CryptReleaseContext(hProv, 0);
104 CryptReleaseContext(hProv, 0);
111 unsigned long pd_uuid_rng_get_bytes(unsigned char *out, unsigned long outlen) {
116 #if defined(USE_DEVRANDOM)
117 x = rng_nix(out, outlen);
122 x = rng_win32(out, outlen);
126 #elif defined(ANSI_RNG)
127 x = rng_ansic(out, outlen);