2 * Adaped from libtomcrypt by Tom St Denis.
4 * by Nathan Wagner, and released into the public domain
10 #define TRY_URANDOM_FIRST 1
13 #define LTC_DEVRANDOM 1
17 /* on *NIX read /dev/random */
18 static unsigned long rng_nix(unsigned char *buf, unsigned long len) {
24 #ifdef TRY_URANDOM_FIRST
25 f = fopen("/dev/urandom", "rb");
28 f = fopen("/dev/random", "rb");
33 /* disable buffering */
34 if (setvbuf(f, NULL, _IONBF, 0) != 0) {
38 x = (unsigned long) fread(buf, 1, (size_t) len, f);
46 /* TODO remove this. It's too slow really (I think) */
47 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
48 #if defined(CLOCKS_PER_SEC) && !defined(WINCE)
52 static unsigned long rng_ansic(unsigned char *buf, unsigned long len) {
54 int l, acc, bits, a, b;
56 if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
66 while (t1 == XCLOCK())
69 while (t1 == XCLOCK())
78 acc = bits = a = b = 0;
84 /* Try the Microsoft CSP */
85 #if defined(WIN32) || defined(WINCE)
87 #define _WIN32_WINNT 0x0400
95 static unsigned long rng_win32(unsigned char *buf, unsigned long len) {
98 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
99 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
100 !CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
101 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
104 if (CryptGenRandom(hProv, len, buf) == TRUE) {
105 CryptReleaseContext(hProv, 0);
108 CryptReleaseContext(hProv, 0);
115 unsigned long pd_uuid_rng_get_bytes(unsigned char *out, unsigned long outlen) {
118 LTC_ARGCHK(out != NULL);
120 #if defined(LTC_DEVRANDOM)
121 x = rng_nix(out, outlen);
127 x = rng_win32(out, outlen);
133 x = rng_ansic(out, outlen);