diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp | 173 |
1 files changed, 145 insertions, 28 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp index 408f73f1686..05a6c06d4c3 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp +++ b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp @@ -2,14 +2,44 @@ #include "StdAfx.h" -#ifndef _7ZIP_ST +#include "RandGen.h" + +#ifndef USE_STATIC_SYSTEM_RAND + +#ifndef Z7_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,61 +51,141 @@ #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)); void CRandomGenerator::Init() { + MY_ALIGN (16) CSha256 hash; Sha256_Init(&hash); + unsigned numIterations = 1000; + + { + #ifndef UNDER_CE + const unsigned kNumIterations_Small = 100; + const unsigned kBufSize = 32; + MY_ALIGN (16) + Byte buf[kBufSize]; + #endif + #ifdef _WIN32 + DWORD w = ::GetCurrentProcessId(); - HASH_UPD(w); + HASH_UPD(w) w = ::GetCurrentThreadId(); - HASH_UPD(w); + 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 + { + const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); + if (hModule) + { + // SystemFunction036() is real name of RtlGenRandom() function + const + Func_RtlGenRandom + my_RtlGenRandom = Z7_GET_PROC_ADDRESS( + Func_RtlGenRandom, 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); + HASH_UPD(pid) pid = getppid(); - HASH_UPD(pid); + HASH_UPD(pid) + + { + int f = open("/dev/urandom", O_RDONLY); + unsigned numBytes = kBufSize; + if (f >= 0) + { + do + { + ssize_t n = read(f, buf, numBytes); + if (n <= 0) + break; + Sha256_Update(&hash, buf, (size_t)n); + numBytes -= (unsigned)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; if (::QueryPerformanceCounter(&v)) - HASH_UPD(v.QuadPart); + HASH_UPD(v.QuadPart) #endif #ifdef USE_POSIX_TIME #ifdef USE_POSIX_TIME2 timeval v; - if (gettimeofday(&v, 0) == 0) + if (gettimeofday(&v, NULL) == 0) { - HASH_UPD(v.tv_sec); - HASH_UPD(v.tv_usec); + HASH_UPD(v.tv_sec) + HASH_UPD(v.tv_usec) } #endif - time_t v2 = time(NULL); - HASH_UPD(v2); + const time_t v2 = time(NULL); + HASH_UPD(v2) #endif #ifdef _WIN32 - DWORD tickCount = ::GetTickCount(); - HASH_UPD(tickCount); + const DWORD tickCount = ::GetTickCount(); + HASH_UPD(tickCount) #endif for (unsigned j = 0; j < 100; j++) @@ -85,11 +195,13 @@ void CRandomGenerator::Init() Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); } } + while (--numIterations); + Sha256_Final(&hash, _buff); _needInit = false; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static NWindows::NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -104,6 +216,7 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) Init(); while (size != 0) { + MY_ALIGN (16) CSha256 hash; Sha256_Init(&hash); @@ -112,8 +225,9 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) Sha256_Init(&hash); UInt32 salt = 0xF672ABD1; - HASH_UPD(salt); + HASH_UPD(salt) Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); + MY_ALIGN (16) Byte buff[SHA256_DIGEST_SIZE]; Sha256_Final(&hash, buff); for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--) @@ -121,4 +235,7 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) } } +MY_ALIGN (16) CRandomGenerator g_RandomGenerator; + +#endif |