xref: /aosp_15_r20/external/lzma/CPP/7zip/Crypto/RandGen.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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