comparison rng_get_bytes.c @ 0:d7da3b1e1540 libtomcrypt

put back the 0.95 makefile which was inadvertently merged over
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:21:40 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d7da3b1e1540
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11 /* portable way to get secure random bits to feed a PRNG */
12 #include "mycrypt.h"
13
14 #ifdef DEVRANDOM
15 /* on *NIX read /dev/random */
16 static unsigned long rng_nix(unsigned char *buf, unsigned long len,
17 void (*callback)(void))
18 {
19 #ifdef NO_FILE
20 return 0;
21 #else
22 FILE *f;
23 unsigned long x;
24 #ifdef TRY_URANDOM_FIRST
25 f = fopen("/dev/urandom", "rb");
26 if (f == NULL)
27 #endif /* TRY_URANDOM_FIRST */
28 f = fopen("/dev/random", "rb");
29
30 if (f == NULL) {
31 return 0;
32 }
33
34 /* disable buffering */
35 if (setvbuf(f, NULL, _IONBF, 0) != 0) {
36 fclose(f);
37 return 0;
38 }
39
40 x = (unsigned long)fread(buf, 1, (size_t)len, f);
41 fclose(f);
42 return x;
43 #endif /* NO_FILE */
44 }
45
46 #endif /* DEVRANDOM */
47
48 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
49 #if defined(CLOCKS_PER_SEC)
50
51 #define ANSI_RNG
52
53 static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
54 void (*callback)(void))
55 {
56 clock_t t1;
57 int l, acc, bits, a, b;
58
59 if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
60 return 0;
61 }
62
63 l = len;
64 bits = 8;
65 acc = a = b = 0;
66 while (len--) {
67 if (callback != NULL) callback();
68 while (bits--) {
69 do {
70 t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
71 t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
72 } while (a == b);
73 acc = (acc << 1) | a;
74 }
75 *buf++ = acc;
76 acc = 0;
77 bits = 8;
78 }
79 acc = bits = a = b = 0;
80 return l;
81 }
82
83 #endif
84
85 /* Try the Microsoft CSP */
86 #ifdef WIN32
87 #define _WIN32_WINNT 0x0400
88 #include <windows.h>
89 #include <wincrypt.h>
90
91 static unsigned long rng_win32(unsigned char *buf, unsigned long len,
92 void (*callback)(void))
93 {
94 HCRYPTPROV hProv = 0;
95 if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
96 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
97 !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
98 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
99 return 0;
100
101 if (CryptGenRandom(hProv, len, buf) == TRUE) {
102 CryptReleaseContext(hProv, 0);
103 return len;
104 } else {
105 CryptReleaseContext(hProv, 0);
106 return 0;
107 }
108 }
109
110 #endif /* WIN32 */
111
112 unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
113 void (*callback)(void))
114 {
115 unsigned long x;
116
117 _ARGCHK(buf != NULL);
118
119 #if defined(DEVRANDOM)
120 x = rng_nix(buf, len, callback); if (x != 0) { return x; }
121 #endif
122 #ifdef WIN32
123 x = rng_win32(buf, len, callback); if (x != 0) { return x; }
124 #endif
125 #ifdef ANSI_RNG
126 x = rng_ansic(buf, len, callback); if (x != 0) { return x; }
127 #endif
128 return 0;
129 }