diff options
Diffstat (limited to 'CPP/7zip/Crypto/RandGen.cpp')
-rw-r--r-- | CPP/7zip/Crypto/RandGen.cpp | 135 |
1 files changed, 122 insertions, 13 deletions
diff --git a/CPP/7zip/Crypto/RandGen.cpp b/CPP/7zip/Crypto/RandGen.cpp index 408f73f1..f98878f5 100644 --- a/CPP/7zip/Crypto/RandGen.cpp +++ b/CPP/7zip/Crypto/RandGen.cpp @@ -2,14 +2,44 @@ #include "StdAfx.h" +#include "RandGen.h" + +#ifndef USE_STATIC_SYSTEM_RAND + #ifndef _7ZIP_ST #include "../../Windows/Synchronization.h" #endif -#include "RandGen.h" -#ifndef _WIN32 +#ifdef _WIN32 + +#ifdef _WIN64 +#define USE_STATIC_RtlGenRandom +#endif + +#ifdef USE_STATIC_RtlGenRandom + +#include <ntsecapi.h> + +EXTERN_C_BEGIN +#ifndef RtlGenRandom + #define RtlGenRandom SystemFunction036 + BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +#endif +EXTERN_C_END + +#else +EXTERN_C_BEGIN +typedef BOOLEAN (WINAPI * Func_RtlGenRandom)(PVOID RandomBuffer, ULONG RandomBufferLength); +EXTERN_C_END +#endif + + +#else #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #define USE_POSIX_TIME #define USE_POSIX_TIME2 #endif @@ -21,11 +51,9 @@ #endif #endif -// This is not very good random number generator. -// Please use it only for salt. -// First generated data block depends from timer and processID. +// The seed and first generated data block depend from processID, +// theadID, timer and system random generator, if available. // Other generated data blocks depend from previous state -// Maybe it's possible to restore original timer value from generated value. #define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x)); @@ -34,25 +62,102 @@ void CRandomGenerator::Init() CSha256 hash; Sha256_Init(&hash); + unsigned numIterations = 1000; + + { + #ifndef UNDER_CE + const unsigned kNumIterations_Small = 100; + const unsigned kBufSize = 32; + Byte buf[kBufSize]; + #endif + #ifdef _WIN32 + DWORD w = ::GetCurrentProcessId(); HASH_UPD(w); w = ::GetCurrentThreadId(); HASH_UPD(w); + + #ifdef UNDER_CE + /* + if (CeGenRandom(kBufSize, buf)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + */ + #elif defined(USE_STATIC_RtlGenRandom) + if (RtlGenRandom(buf, kBufSize)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } #else + { + HMODULE hModule = ::LoadLibrary(TEXT("Advapi32.dll")); + if (hModule) + { + // SystemFunction036() is real name of RtlGenRandom() function + Func_RtlGenRandom my_RtlGenRandom = (Func_RtlGenRandom)GetProcAddress(hModule, "SystemFunction036"); + if (my_RtlGenRandom) + { + if (my_RtlGenRandom(buf, kBufSize)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + } + ::FreeLibrary(hModule); + } + } + #endif + + #else + pid_t pid = getpid(); HASH_UPD(pid); pid = getppid(); HASH_UPD(pid); + + { + int f = open("/dev/urandom", O_RDONLY); + unsigned numBytes = kBufSize; + if (f >= 0) + { + do + { + int n = read(f, buf, numBytes); + if (n <= 0) + break; + Sha256_Update(&hash, buf, n); + numBytes -= n; + } + while (numBytes); + close(f); + if (numBytes == 0) + numIterations = kNumIterations_Small; + } + } + /* + { + int n = getrandom(buf, kBufSize, 0); + if (n > 0) + { + Sha256_Update(&hash, buf, n); + if (n == kBufSize) + numIterations = kNumIterations_Small; + } + } + */ + + #endif + } + + #ifdef _DEBUG + numIterations = 2; #endif - for (unsigned i = 0; i < - #ifdef _DEBUG - 2; - #else - 1000; - #endif - i++) + do { #ifdef _WIN32 LARGE_INTEGER v; @@ -85,6 +190,8 @@ void CRandomGenerator::Init() Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); } } + while (--numIterations); + Sha256_Final(&hash, _buff); _needInit = false; } @@ -122,3 +229,5 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) } CRandomGenerator g_RandomGenerator; + +#endif |