diff --git a/config.h.in b/config.h.in index 387a1cd..5c22894 100644 --- a/config.h.in +++ b/config.h.in @@ -15,6 +15,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H +/* Has /dev/arandom */ +#undef HAVE_DEV_ARANDOM + +/* Has /dev/random */ +#undef HAVE_DEV_RANDOM + +/* Has /dev/urandom */ +#undef HAVE_DEV_URANDOM + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H diff --git a/configure b/configure index ea08168..8311cc7 100755 --- a/configure +++ b/configure @@ -6154,6 +6154,26 @@ done fi +if test -c "/dev/random"; then + +$as_echo "#define HAVE_DEV_RANDOM 1" >>confdefs.h + +fi + +if test -c "/dev/urandom"; then + +$as_echo "#define HAVE_DEV_URANDOM 1" >>confdefs.h + +fi + +if test -c "/dev/arandom"; then + +$as_echo "#define HAVE_DEV_ARANDOM 1" >>confdefs.h + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lc" >&5 $as_echo_n "checking for socket in -lc... " >&6; } if ${ac_cv_lib_c_socket+:} false; then : diff --git a/configure.ac b/configure.ac index 6678a78..b076cc8 100644 --- a/configure.ac +++ b/configure.ac @@ -133,6 +133,23 @@ then AC_CHECK_HEADERS(CommonCrypto/CommonDigest.h) fi +dnl ############################################## +dnl check for various RNG/PRNG devices +dnl ############################################## + +if test -c "/dev/random"; then + AC_DEFINE(HAVE_DEV_RANDOM, [1], [Has /dev/random]) +fi + +if test -c "/dev/urandom"; then + AC_DEFINE(HAVE_DEV_URANDOM, [1], [Has /dev/urandom]) +fi + +if test -c "/dev/arandom"; then + AC_DEFINE(HAVE_DEV_ARANDOM, [1], [Has /dev/arandom]) +fi + + dnl ############################################## dnl Checks for various platform specific libraries dnl ############################################## diff --git a/src/twcrypto/crypto.cpp b/src/twcrypto/crypto.cpp index e673cfc..1eb5953 100644 --- a/src/twcrypto/crypto.cpp +++ b/src/twcrypto/crypto.cpp @@ -39,6 +39,7 @@ #include "core/errorgeneral.h" #include "time.h" #include "core/archive.h" +#include "core/usernotify.h" #include "cryptlib/sha.h" #include "cryptlib/rng.h" @@ -53,6 +54,11 @@ #include "cryptlib/rsa.h" #endif +#include +#include + +#define HAVE_DEVICE_RANDOM (HAVE_DEV_RANDOM || HAVE_DEV_URANDOM || HAVE_DEV_ARANDOM) + const uint32 EL_GAMAL_SIG_PUBLIC_MAGIC_NUM = 0x7ae2c945; const uint32 EL_GAMAL_SIG_PRIVATE_MAGIC_NUM = 0x0d0ffa12; @@ -1235,6 +1241,21 @@ cHashedKey192::~cHashedKey192() RandomizeBytes(mKey, KEYLEN); } + +static bool randomize_by_device(const char* device_name, int8* destbuf, int len) +{ + int dev_random = open("/dev/random", O_RDONLY|O_NONBLOCK); + if (dev_random >= 0) + { + int bytes_read = read(dev_random, destbuf, len); + close(dev_random); + if (bytes_read == len) + return true; + } + + return false; +} + /////////////////////////////////////////////////////////////////////////////// // void RandomizeBytes(byte* destbuf, int len) -- Fill a buffer with random bytes @@ -1242,6 +1263,30 @@ static bool gRandomizeBytesSeeded = false; void RandomizeBytes(int8* destbuf, int len) { +#if HAVE_DEVICE_RANDOM + +#if HAVE_DEV_RANDOM + if (randomize_by_device("/dev/random", destbuf, len)) + return; + + iUserNotify::GetInstance()->Notify( iUserNotify::V_NORMAL, "Could not read from /dev/random, falling back to /dev/urandom"); +#endif + +#if HAVE_DEV_URANDOM + if (randomize_by_device("/dev/urandom", destbuf, len)) + return; +#endif + +#if HAVE_DEV_ARANDOM + if (randomize_by_device("/dev/arandom", destbuf, len)) + return; +#endif + + ThrowAndAssert(eInternal(_T("Failed to read from any RNG devices"))); + +// TODO: OpenSSL or other impls that are better than the default one + +#else if (!gRandomizeBytesSeeded) { // generate a rancom number from processor timing. @@ -1267,5 +1312,6 @@ void RandomizeBytes(int8* destbuf, int len) int i; for (i = 0; i < len; ++i) destbuf[i] = (byte)( (rand() * 256 / RAND_MAX) ^ 0xdc ); // 0xdc came from random.org +#endif }