Path: blob/master/libs/tomcrypt/src/prngs/rng_get_bytes.c
5971 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910#ifdef LTC_RNG_GET_BYTES11/**12@file rng_get_bytes.c13portable way to get secure random bits to feed a PRNG (Tom St Denis)14*/1516#if defined(LTC_DEVRANDOM) && !defined(_WIN32)17/* on *NIX read /dev/random */18static unsigned long _rng_nix(unsigned char *buf, unsigned long len,19void (*callback)(void))20{21#ifdef LTC_NO_FILE22LTC_UNUSED_PARAM(callback);23LTC_UNUSED_PARAM(buf);24LTC_UNUSED_PARAM(len);25return 0;26#else27FILE *f;28unsigned long x;29LTC_UNUSED_PARAM(callback);30#ifdef LTC_TRY_URANDOM_FIRST31f = fopen("/dev/urandom", "rb");32if (f == NULL)33#endif /* LTC_TRY_URANDOM_FIRST */34f = fopen("/dev/random", "rb");3536if (f == NULL) {37return 0;38}3940/* disable buffering */41if (setvbuf(f, NULL, _IONBF, 0) != 0) {42fclose(f);43return 0;44}4546x = (unsigned long)fread(buf, 1, (size_t)len, f);47fclose(f);48return x;49#endif /* LTC_NO_FILE */50}5152#endif /* LTC_DEVRANDOM */5354#if !defined(_WIN32_WCE)5556#define ANSI_RNG5758static unsigned long _rng_ansic(unsigned char *buf, unsigned long len,59void (*callback)(void))60{61clock_t t1;62int l, acc, bits, a, b;6364l = len;65bits = 8;66acc = a = b = 0;67while (len--) {68if (callback != NULL) callback();69while (bits--) {70do {71t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;72t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;73} while (a == b);74acc = (acc << 1) | a;75}76*buf++ = acc;77acc = 0;78bits = 8;79}80return l;81}8283#endif8485/* Try the Microsoft CSP */86#if defined(_WIN32) || defined(_WIN32_WCE)87#ifndef _WIN32_WINNT88#define _WIN32_WINNT 0x040089#endif90#ifdef _WIN32_WCE91#define UNDER_CE92#define ARM93#endif9495#define WIN32_LEAN_AND_MEAN96#include <windows.h>97#include <ntsecapi.h>9899static unsigned long _rng_win32(unsigned char *buf, unsigned long len,100void (*callback)(void))101{102LTC_UNUSED_PARAM(callback);103RtlGenRandom(buf, len);104return len;105}106107#endif /* WIN32 */108109/**110Read the system RNG111@param out Destination112@param outlen Length desired (octets)113@param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL114@return Number of octets read115*/116unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen,117void (*callback)(void))118{119unsigned long x;120121LTC_ARGCHK(out != NULL);122123#ifdef LTC_PRNG_ENABLE_LTC_RNG124if (ltc_rng) {125x = ltc_rng(out, outlen, callback);126if (x != 0) {127return x;128}129}130#endif131132#if defined(_WIN32) || defined(_WIN32_WCE)133x = _rng_win32(out, outlen, callback); if (x != 0) { return x; }134#elif defined(LTC_DEVRANDOM)135x = _rng_nix(out, outlen, callback); if (x != 0) { return x; }136#endif137#ifdef ANSI_RNG138x = _rng_ansic(out, outlen, callback); if (x != 0) { return x; }139#endif140return 0;141}142#endif /* #ifdef LTC_RNG_GET_BYTES */143144145