• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RandGen.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../Windows/Synchronization.h"
6 
7 #include "RandGen.h"
8 
9 #ifndef _WIN32
10 #include <unistd.h>
11 #define USE_POSIX_TIME
12 #define USE_POSIX_TIME2
13 #endif
14 
15 #ifdef USE_POSIX_TIME
16 #include <time.h>
17 #ifdef USE_POSIX_TIME2
18 #include <sys/time.h>
19 #endif
20 #endif
21 
22 // This is not very good random number generator.
23 // Please use it only for salt.
24 // First generated data block depends from timer and processID.
25 // Other generated data blocks depend from previous state
26 // Maybe it's possible to restore original timer value from generated value.
27 
28 #define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x));
29 
Init()30 void CRandomGenerator::Init()
31 {
32   CSha256 hash;
33   Sha256_Init(&hash);
34 
35   #ifdef _WIN32
36   DWORD w = ::GetCurrentProcessId();
37   HASH_UPD(w);
38   w = ::GetCurrentThreadId();
39   HASH_UPD(w);
40   #else
41   pid_t pid = getpid();
42   HASH_UPD(pid);
43   pid = getppid();
44   HASH_UPD(pid);
45   #endif
46 
47   for (unsigned i = 0; i <
48     #ifdef _DEBUG
49     2;
50     #else
51     1000;
52     #endif
53     i++)
54   {
55     #ifdef _WIN32
56     LARGE_INTEGER v;
57     if (::QueryPerformanceCounter(&v))
58       HASH_UPD(v.QuadPart);
59     #endif
60 
61     #ifdef USE_POSIX_TIME
62     #ifdef USE_POSIX_TIME2
63     timeval v;
64     if (gettimeofday(&v, 0) == 0)
65     {
66       HASH_UPD(v.tv_sec);
67       HASH_UPD(v.tv_usec);
68     }
69     #endif
70     time_t v2 = time(NULL);
71     HASH_UPD(v2);
72     #endif
73 
74     DWORD tickCount = ::GetTickCount();
75     HASH_UPD(tickCount);
76 
77     for (unsigned j = 0; j < 100; j++)
78     {
79       Sha256_Final(&hash, _buff);
80       Sha256_Init(&hash);
81       Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
82     }
83   }
84   Sha256_Final(&hash, _buff);
85   _needInit = false;
86 }
87 
88 static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
89 
Generate(Byte * data,unsigned size)90 void CRandomGenerator::Generate(Byte *data, unsigned size)
91 {
92   g_CriticalSection.Enter();
93   if (_needInit)
94     Init();
95   while (size > 0)
96   {
97     CSha256 hash;
98 
99     Sha256_Init(&hash);
100     Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
101     Sha256_Final(&hash, _buff);
102 
103     Sha256_Init(&hash);
104     UInt32 salt = 0xF672ABD1;
105     HASH_UPD(salt);
106     Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
107     Byte buff[SHA256_DIGEST_SIZE];
108     Sha256_Final(&hash, buff);
109     for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size > 0; i++, size--)
110       *data++ = buff[i];
111   }
112   g_CriticalSection.Leave();
113 }
114 
115 CRandomGenerator g_RandomGenerator;
116