From a85dbe65fafbcc7e272231317b9ffd7cb5e97a82 Mon Sep 17 00:00:00 2001 From: sniperbeamer Date: Wed, 12 Mar 2008 18:55:57 +0000 Subject: [PATCH] Improved seeding of the random number generator Fixed AppDir on Windows git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@183 b624d157-de02-0410-bad0-e51aec6abb33 --- changelog | 1 + src/crypto/yarrow.cpp | 16 ++++++---- src/crypto/yarrow.h | 2 ++ src/keepassx.h | 1 - src/lib/random.cpp | 70 ++++++++++++++++++++++++++++++++----------- src/lib/random.h | 38 ++++++++++++++++++++++- src/main_win32.cpp | 13 +++++++- 7 files changed, 115 insertions(+), 26 deletions(-) diff --git a/changelog b/changelog index 5b469f2..5cce96c 100644 --- a/changelog +++ b/changelog @@ -11,6 +11,7 @@ - fixed crash when re-arranging groups (Bug #1754998) - fixed size problems of some dialogs - files are not longer truncated when saving fails (Bug #1648616) +- improved seeding of the random number generator --------------- 0.3.0a diff --git a/src/crypto/yarrow.cpp b/src/crypto/yarrow.cpp index 3397435..b368601 100644 --- a/src/crypto/yarrow.cpp +++ b/src/crypto/yarrow.cpp @@ -26,6 +26,7 @@ #include #include "yarrow.h" +#include "random.h" #ifndef YARROW_DEBUG #define YARROW_DEBUG 0 @@ -399,12 +400,15 @@ struct yarrow_source StrongSrc[2]; void initYarrow(){ yarrow256_init(&WeakCtx,2,WeakSrc); yarrow256_init(&StrongCtx,2,StrongSrc); - quint8 buffer[100]; - getRandomBytes(buffer,100); - yarrow256_update(&WeakCtx,0,800,100,buffer); - getRandomBytes(buffer,100); - yarrow256_update(&WeakCtx,1,800,100,buffer); - Q_ASSERT(yarrow256_is_seeded(&WeakCtx)); + new RandomSource(); +} + +void yarrowUpdateWeak(unsigned source, unsigned entropy, unsigned length, const quint8 *data){ + yarrow256_update(&WeakCtx,source,entropy,length,data); +} + +void yarrowUpdateStrong(unsigned source, unsigned entropy, unsigned length, const quint8 *data){ + yarrow256_update(&StrongCtx,source,entropy,length,data); } void randomize(void* buffer, unsigned int length){ diff --git a/src/crypto/yarrow.h b/src/crypto/yarrow.h index 99a4c87..eb0f52d 100644 --- a/src/crypto/yarrow.h +++ b/src/crypto/yarrow.h @@ -182,6 +182,8 @@ do { \ (src) += (blocksize)) ) void initYarrow(); +void yarrowUpdateWeak(unsigned source, unsigned entropy, unsigned length, const quint8 *data); +void yarrowUpdateStrong(unsigned source, unsigned entropy, unsigned length, const quint8 *data); void randomize(void* buffer, unsigned int length); void reseedStrongPool(quint8* buffer1,int l1,quint8* buffer2,int l2); diff --git a/src/keepassx.h b/src/keepassx.h index 0326f9c..65d26fe 100644 --- a/src/keepassx.h +++ b/src/keepassx.h @@ -84,7 +84,6 @@ #include "crypto/yarrow.h" #include "lib/bookmarks.h" #include "lib/FileDialogs.h" -#include "lib/random.h" #include "lib/SecString.h" #include "lib/tools.h" #include "lib/UrlLabel.h" diff --git a/src/lib/random.cpp b/src/lib/random.cpp index 6e08103..29d1ae6 100644 --- a/src/lib/random.cpp +++ b/src/lib/random.cpp @@ -17,27 +17,49 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include -#include + #include "random.h" #if defined(Q_WS_WIN) - #include -#include #include + #include #endif -using namespace std; +RandomSource::RandomSource(){ + quint8 buffer[100]; + for (int i=0; i<2; i++){ + getRandomWeak(buffer,100); + yarrowUpdateWeak(i,100*8,100,buffer); + } + +#ifdef HAS_DEV_RANDOM + if (QFile::exists("/dev/random")){ + DevRandom* devRandom = new DevRandom(this); + connect(devRandom, SIGNAL(randomAvailable(int,QByteArray,int)), SLOT(seedStrong(int,QByteArray,int))); + connect(devRandom, SIGNAL(finished()), SLOT(deleteLater())); + devRandom->start(); + } + else{ + deleteLater(); + } +#else + deleteLater(); +#endif +} -void getRandomBytes(void* buffer,int NumBlocks){ -#if defined(Q_WS_WIN) +void RandomSource::getRandomWeak(quint8* buffer, int length){ +#if defined(HAS_DEV_RANDOM) + QFile dev_urandom("/dev/urandom"); + if (dev_urandom.open(QIODevice::ReadOnly|QIODevice::Unbuffered) && dev_urandom.read((char*)buffer,length)==length) + return; +#elif defined(Q_WS_WIN) // RtlGenRandom if (QSysInfo::WindowsVersion>=QSysInfo::WV_XP){ bool success=false; HMODULE hLib=LoadLibraryA("ADVAPI32.DLL"); if (hLib) { BOOLEAN (APIENTRY *pfn)(void*, ULONG) = (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036"); - if (pfn && pfn(buffer,NumBlocks)) { + if (pfn && pfn(buffer,length)) { success=true; } FreeLibrary(hLib); @@ -45,18 +67,32 @@ void getRandomBytes(void* buffer,int NumBlocks){ if (success) return; } -#else - FILE* dev_random = fopen("/dev/random","r"); - if (dev_random){ - size_t bytesRead = fread(buffer,1,NumBlocks,dev_random); - fclose(dev_random); - if (bytesRead==NumBlocks) - return; - } #endif srand(time(NULL)); - for(int i=0;i + +#if defined(Q_WS_X11) || defined(Q_WS_MAC) +#define HAS_DEV_RANDOM +#include +#endif + +class RandomSource : public QObject { + Q_OBJECT + + public: + RandomSource(); + + private: + static void getRandomWeak(quint8* buffer, int length); + +#ifdef HAS_DEV_RANDOM + private slots: + void seedStrong(int source, QByteArray buffer, int length); +#endif +}; + +#ifdef HAS_DEV_RANDOM +class DevRandom : public QThread { + Q_OBJECT + + public: + DevRandom(QObject* parent = 0); + void run(); + + signals: + void randomAvailable(int source, QByteArray buffer, int length); + + private: + static bool getRandomStrong(quint8* buffer, int length); +}; +#endif #endif diff --git a/src/main_win32.cpp b/src/main_win32.cpp index 8f00ba6..9944d86 100644 --- a/src/main_win32.cpp +++ b/src/main_win32.cpp @@ -23,7 +23,18 @@ #include "main.h" void initAppPaths(int argc,char** argv){ - AppDir = QApplication::applicationDirPath(); + QFileInfo filePath; + QT_WA({ + wchar_t module_name[256]; + GetModuleFileNameW(0, module_name, sizeof(module_name) / sizeof(wchar_t)); + filePath = QString::fromUtf16((ushort *)module_name); + }, { + char module_name[256]; + GetModuleFileNameA(0, module_name, sizeof(module_name)); + filePath = QString::fromLocal8Bit(module_name); + }); + AppDir = filePath.filePath(); + AppDir.truncate(AppDir.lastIndexOf("/")); HomeDir = QString::fromLocal8Bit(qgetenv("APPDATA").constData()); if(!HomeDir.isEmpty() && QFile::exists(HomeDir))