aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Crypto/RandGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Crypto/RandGen.cpp')
-rw-r--r--CPP/7zip/Crypto/RandGen.cpp135
1 files changed, 122 insertions, 13 deletions
diff --git a/CPP/7zip/Crypto/RandGen.cpp b/CPP/7zip/Crypto/RandGen.cpp
index 542f39b..791275f 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