Mercurial > dropbear
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 } |