| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
- /* portable way to get secure random bits to feed a PRNG */
- #include "mycrypt.h"
- #ifdef DEVRANDOM
- /* on *NIX read /dev/random */
- static unsigned long rng_nix(unsigned char *buf, unsigned long len,
- void (*callback)(void))
- {
- #ifdef NO_FILE
- return 0;
- #else
- FILE *f;
- unsigned long x;
- #ifdef TRY_URANDOM_FIRST
- f = fopen("/dev/urandom", "rb");
- if (f == NULL)
- #endif /* TRY_URANDOM_FIRST */
- f = fopen("/dev/random", "rb");
- if (f == NULL) {
- return 0;
- }
-
- /* disable buffering */
- if (setvbuf(f, NULL, _IONBF, 0) != 0) {
- fclose(f);
- return 0;
- }
-
- x = (unsigned long)fread(buf, 1, (size_t)len, f);
- fclose(f);
- return x;
- #endif /* NO_FILE */
- }
- #endif /* DEVRANDOM */
- /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
- #if defined(CLOCKS_PER_SEC)
- #define ANSI_RNG
- static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
- void (*callback)(void))
- {
- clock_t t1;
- int l, acc, bits, a, b;
- if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
- return 0;
- }
- l = len;
- bits = 8;
- acc = a = b = 0;
- while (len--) {
- if (callback != NULL) callback();
- while (bits--) {
- do {
- t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
- t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
- } while (a == b);
- acc = (acc << 1) | a;
- }
- *buf++ = acc;
- acc = 0;
- bits = 8;
- }
- acc = bits = a = b = 0;
- return l;
- }
- #endif
- /* Try the Microsoft CSP */
- #ifdef WIN32
- #define _WIN32_WINNT 0x0400
- #include <windows.h>
- #include <wincrypt.h>
- static unsigned long rng_win32(unsigned char *buf, unsigned long len,
- void (*callback)(void))
- {
- HCRYPTPROV hProv = 0;
- if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
- (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
- !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
- return 0;
- if (CryptGenRandom(hProv, len, buf) == TRUE) {
- CryptReleaseContext(hProv, 0);
- return len;
- } else {
- CryptReleaseContext(hProv, 0);
- return 0;
- }
- }
- #endif /* WIN32 */
- unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
- void (*callback)(void))
- {
- unsigned long x;
- _ARGCHK(buf != NULL);
- #if defined(DEVRANDOM)
- x = rng_nix(buf, len, callback); if (x != 0) { return x; }
- #endif
- #ifdef WIN32
- x = rng_win32(buf, len, callback); if (x != 0) { return x; }
- #endif
- #ifdef ANSI_RNG
- x = rng_ansic(buf, len, callback); if (x != 0) { return x; }
- #endif
- return 0;
- }
|