1*f6dc9357SAndroid Build Coastguard Worker // RandGen.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "RandGen.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_STATIC_SYSTEM_RAND
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/Synchronization.h"
11*f6dc9357SAndroid Build Coastguard Worker #endif
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker
14*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
15*f6dc9357SAndroid Build Coastguard Worker
16*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN64
17*f6dc9357SAndroid Build Coastguard Worker #define USE_STATIC_RtlGenRandom
18*f6dc9357SAndroid Build Coastguard Worker #endif
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_STATIC_RtlGenRandom
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker // #include <NTSecAPI.h>
23*f6dc9357SAndroid Build Coastguard Worker
24*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
25*f6dc9357SAndroid Build Coastguard Worker #ifndef RtlGenRandom
26*f6dc9357SAndroid Build Coastguard Worker #define RtlGenRandom SystemFunction036
27*f6dc9357SAndroid Build Coastguard Worker BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
28*f6dc9357SAndroid Build Coastguard Worker #endif
29*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker #else
32*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
33*f6dc9357SAndroid Build Coastguard Worker typedef BOOLEAN (WINAPI * Func_RtlGenRandom)(PVOID RandomBuffer, ULONG RandomBufferLength);
34*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
35*f6dc9357SAndroid Build Coastguard Worker #endif
36*f6dc9357SAndroid Build Coastguard Worker
37*f6dc9357SAndroid Build Coastguard Worker
38*f6dc9357SAndroid Build Coastguard Worker #else
39*f6dc9357SAndroid Build Coastguard Worker #include <unistd.h>
40*f6dc9357SAndroid Build Coastguard Worker #include <sys/types.h>
41*f6dc9357SAndroid Build Coastguard Worker #include <sys/stat.h>
42*f6dc9357SAndroid Build Coastguard Worker #include <fcntl.h>
43*f6dc9357SAndroid Build Coastguard Worker #define USE_POSIX_TIME
44*f6dc9357SAndroid Build Coastguard Worker #define USE_POSIX_TIME2
45*f6dc9357SAndroid Build Coastguard Worker #endif
46*f6dc9357SAndroid Build Coastguard Worker
47*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME
48*f6dc9357SAndroid Build Coastguard Worker #include <time.h>
49*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME2
50*f6dc9357SAndroid Build Coastguard Worker #include <sys/time.h>
51*f6dc9357SAndroid Build Coastguard Worker #endif
52*f6dc9357SAndroid Build Coastguard Worker #endif
53*f6dc9357SAndroid Build Coastguard Worker
54*f6dc9357SAndroid Build Coastguard Worker // The seed and first generated data block depend from processID,
55*f6dc9357SAndroid Build Coastguard Worker // theadID, timer and system random generator, if available.
56*f6dc9357SAndroid Build Coastguard Worker // Other generated data blocks depend from previous state
57*f6dc9357SAndroid Build Coastguard Worker
58*f6dc9357SAndroid Build Coastguard Worker #define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x));
59*f6dc9357SAndroid Build Coastguard Worker
Init()60*f6dc9357SAndroid Build Coastguard Worker void CRandomGenerator::Init()
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN (16)
63*f6dc9357SAndroid Build Coastguard Worker CSha256 hash;
64*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&hash);
65*f6dc9357SAndroid Build Coastguard Worker
66*f6dc9357SAndroid Build Coastguard Worker unsigned numIterations = 1000;
67*f6dc9357SAndroid Build Coastguard Worker
68*f6dc9357SAndroid Build Coastguard Worker {
69*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
70*f6dc9357SAndroid Build Coastguard Worker const unsigned kNumIterations_Small = 100;
71*f6dc9357SAndroid Build Coastguard Worker const unsigned kBufSize = 32;
72*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN (16)
73*f6dc9357SAndroid Build Coastguard Worker Byte buf[kBufSize];
74*f6dc9357SAndroid Build Coastguard Worker #endif
75*f6dc9357SAndroid Build Coastguard Worker
76*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
77*f6dc9357SAndroid Build Coastguard Worker
78*f6dc9357SAndroid Build Coastguard Worker DWORD w = ::GetCurrentProcessId();
79*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(w)
80*f6dc9357SAndroid Build Coastguard Worker w = ::GetCurrentThreadId();
81*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(w)
82*f6dc9357SAndroid Build Coastguard Worker
83*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
84*f6dc9357SAndroid Build Coastguard Worker /*
85*f6dc9357SAndroid Build Coastguard Worker if (CeGenRandom(kBufSize, buf))
86*f6dc9357SAndroid Build Coastguard Worker {
87*f6dc9357SAndroid Build Coastguard Worker numIterations = kNumIterations_Small;
88*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, buf, kBufSize);
89*f6dc9357SAndroid Build Coastguard Worker }
90*f6dc9357SAndroid Build Coastguard Worker */
91*f6dc9357SAndroid Build Coastguard Worker #elif defined(USE_STATIC_RtlGenRandom)
92*f6dc9357SAndroid Build Coastguard Worker if (RtlGenRandom(buf, kBufSize))
93*f6dc9357SAndroid Build Coastguard Worker {
94*f6dc9357SAndroid Build Coastguard Worker numIterations = kNumIterations_Small;
95*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, buf, kBufSize);
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker #else
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll"));
100*f6dc9357SAndroid Build Coastguard Worker if (hModule)
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker // SystemFunction036() is real name of RtlGenRandom() function
103*f6dc9357SAndroid Build Coastguard Worker const
104*f6dc9357SAndroid Build Coastguard Worker Func_RtlGenRandom
105*f6dc9357SAndroid Build Coastguard Worker my_RtlGenRandom = Z7_GET_PROC_ADDRESS(
106*f6dc9357SAndroid Build Coastguard Worker Func_RtlGenRandom, hModule, "SystemFunction036");
107*f6dc9357SAndroid Build Coastguard Worker if (my_RtlGenRandom)
108*f6dc9357SAndroid Build Coastguard Worker {
109*f6dc9357SAndroid Build Coastguard Worker if (my_RtlGenRandom(buf, kBufSize))
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker numIterations = kNumIterations_Small;
112*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, buf, kBufSize);
113*f6dc9357SAndroid Build Coastguard Worker }
114*f6dc9357SAndroid Build Coastguard Worker }
115*f6dc9357SAndroid Build Coastguard Worker ::FreeLibrary(hModule);
116*f6dc9357SAndroid Build Coastguard Worker }
117*f6dc9357SAndroid Build Coastguard Worker }
118*f6dc9357SAndroid Build Coastguard Worker #endif
119*f6dc9357SAndroid Build Coastguard Worker
120*f6dc9357SAndroid Build Coastguard Worker #else
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker pid_t pid = getpid();
123*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(pid)
124*f6dc9357SAndroid Build Coastguard Worker pid = getppid();
125*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(pid)
126*f6dc9357SAndroid Build Coastguard Worker
127*f6dc9357SAndroid Build Coastguard Worker {
128*f6dc9357SAndroid Build Coastguard Worker int f = open("/dev/urandom", O_RDONLY);
129*f6dc9357SAndroid Build Coastguard Worker unsigned numBytes = kBufSize;
130*f6dc9357SAndroid Build Coastguard Worker if (f >= 0)
131*f6dc9357SAndroid Build Coastguard Worker {
132*f6dc9357SAndroid Build Coastguard Worker do
133*f6dc9357SAndroid Build Coastguard Worker {
134*f6dc9357SAndroid Build Coastguard Worker ssize_t n = read(f, buf, numBytes);
135*f6dc9357SAndroid Build Coastguard Worker if (n <= 0)
136*f6dc9357SAndroid Build Coastguard Worker break;
137*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, buf, (size_t)n);
138*f6dc9357SAndroid Build Coastguard Worker numBytes -= (unsigned)n;
139*f6dc9357SAndroid Build Coastguard Worker }
140*f6dc9357SAndroid Build Coastguard Worker while (numBytes);
141*f6dc9357SAndroid Build Coastguard Worker close(f);
142*f6dc9357SAndroid Build Coastguard Worker if (numBytes == 0)
143*f6dc9357SAndroid Build Coastguard Worker numIterations = kNumIterations_Small;
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker }
146*f6dc9357SAndroid Build Coastguard Worker /*
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker int n = getrandom(buf, kBufSize, 0);
149*f6dc9357SAndroid Build Coastguard Worker if (n > 0)
150*f6dc9357SAndroid Build Coastguard Worker {
151*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, buf, n);
152*f6dc9357SAndroid Build Coastguard Worker if (n == kBufSize)
153*f6dc9357SAndroid Build Coastguard Worker numIterations = kNumIterations_Small;
154*f6dc9357SAndroid Build Coastguard Worker }
155*f6dc9357SAndroid Build Coastguard Worker }
156*f6dc9357SAndroid Build Coastguard Worker */
157*f6dc9357SAndroid Build Coastguard Worker
158*f6dc9357SAndroid Build Coastguard Worker #endif
159*f6dc9357SAndroid Build Coastguard Worker }
160*f6dc9357SAndroid Build Coastguard Worker
161*f6dc9357SAndroid Build Coastguard Worker #ifdef _DEBUG
162*f6dc9357SAndroid Build Coastguard Worker numIterations = 2;
163*f6dc9357SAndroid Build Coastguard Worker #endif
164*f6dc9357SAndroid Build Coastguard Worker
165*f6dc9357SAndroid Build Coastguard Worker do
166*f6dc9357SAndroid Build Coastguard Worker {
167*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
168*f6dc9357SAndroid Build Coastguard Worker LARGE_INTEGER v;
169*f6dc9357SAndroid Build Coastguard Worker if (::QueryPerformanceCounter(&v))
170*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(v.QuadPart)
171*f6dc9357SAndroid Build Coastguard Worker #endif
172*f6dc9357SAndroid Build Coastguard Worker
173*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME
174*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_POSIX_TIME2
175*f6dc9357SAndroid Build Coastguard Worker timeval v;
176*f6dc9357SAndroid Build Coastguard Worker if (gettimeofday(&v, NULL) == 0)
177*f6dc9357SAndroid Build Coastguard Worker {
178*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(v.tv_sec)
179*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(v.tv_usec)
180*f6dc9357SAndroid Build Coastguard Worker }
181*f6dc9357SAndroid Build Coastguard Worker #endif
182*f6dc9357SAndroid Build Coastguard Worker const time_t v2 = time(NULL);
183*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(v2)
184*f6dc9357SAndroid Build Coastguard Worker #endif
185*f6dc9357SAndroid Build Coastguard Worker
186*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
187*f6dc9357SAndroid Build Coastguard Worker const DWORD tickCount = ::GetTickCount();
188*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(tickCount)
189*f6dc9357SAndroid Build Coastguard Worker #endif
190*f6dc9357SAndroid Build Coastguard Worker
191*f6dc9357SAndroid Build Coastguard Worker for (unsigned j = 0; j < 100; j++)
192*f6dc9357SAndroid Build Coastguard Worker {
193*f6dc9357SAndroid Build Coastguard Worker Sha256_Final(&hash, _buff);
194*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&hash);
195*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
196*f6dc9357SAndroid Build Coastguard Worker }
197*f6dc9357SAndroid Build Coastguard Worker }
198*f6dc9357SAndroid Build Coastguard Worker while (--numIterations);
199*f6dc9357SAndroid Build Coastguard Worker
200*f6dc9357SAndroid Build Coastguard Worker Sha256_Final(&hash, _buff);
201*f6dc9357SAndroid Build Coastguard Worker _needInit = false;
202*f6dc9357SAndroid Build Coastguard Worker }
203*f6dc9357SAndroid Build Coastguard Worker
204*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
205*f6dc9357SAndroid Build Coastguard Worker static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
206*f6dc9357SAndroid Build Coastguard Worker #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
207*f6dc9357SAndroid Build Coastguard Worker #else
208*f6dc9357SAndroid Build Coastguard Worker #define MT_LOCK
209*f6dc9357SAndroid Build Coastguard Worker #endif
210*f6dc9357SAndroid Build Coastguard Worker
Generate(Byte * data,unsigned size)211*f6dc9357SAndroid Build Coastguard Worker void CRandomGenerator::Generate(Byte *data, unsigned size)
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker MT_LOCK
214*f6dc9357SAndroid Build Coastguard Worker
215*f6dc9357SAndroid Build Coastguard Worker if (_needInit)
216*f6dc9357SAndroid Build Coastguard Worker Init();
217*f6dc9357SAndroid Build Coastguard Worker while (size != 0)
218*f6dc9357SAndroid Build Coastguard Worker {
219*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN (16)
220*f6dc9357SAndroid Build Coastguard Worker CSha256 hash;
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&hash);
223*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
224*f6dc9357SAndroid Build Coastguard Worker Sha256_Final(&hash, _buff);
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker Sha256_Init(&hash);
227*f6dc9357SAndroid Build Coastguard Worker UInt32 salt = 0xF672ABD1;
228*f6dc9357SAndroid Build Coastguard Worker HASH_UPD(salt)
229*f6dc9357SAndroid Build Coastguard Worker Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
230*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN (16)
231*f6dc9357SAndroid Build Coastguard Worker Byte buff[SHA256_DIGEST_SIZE];
232*f6dc9357SAndroid Build Coastguard Worker Sha256_Final(&hash, buff);
233*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--)
234*f6dc9357SAndroid Build Coastguard Worker *data++ = buff[i];
235*f6dc9357SAndroid Build Coastguard Worker }
236*f6dc9357SAndroid Build Coastguard Worker }
237*f6dc9357SAndroid Build Coastguard Worker
238*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN (16)
239*f6dc9357SAndroid Build Coastguard Worker CRandomGenerator g_RandomGenerator;
240*f6dc9357SAndroid Build Coastguard Worker
241*f6dc9357SAndroid Build Coastguard Worker #endif
242