00001
00002
00003
00004
00012 #include "stdafx.h"
00013 #include "Pool.h"
00014 #include "Fortuna.h"
00015 #include "FortunaUtils.h"
00016 #include "Sha2.h"
00017 #include "Timer.h"
00018
00019 namespace CitadelSoftwareInc {
00020
00021 Pool::Pool(Fortuna* pFortuna, PoolMgr* pOwner, int iPoolNum)
00022 :
00023 m_pFortuna(pFortuna),
00024 m_pOwner(pOwner),
00025 m_pThread(NULL),
00026 m_PoolMutex(),
00027 m_CompactPoolDataSize(1024),
00028 m_hPoolMutex(0),
00029 m_CompactPoolEvent(TRUE),
00030 m_hCompactPoolEvent(0),
00031 m_TotalBytes(0),
00032 m_hShutdownEvent(0),
00033 m_iPoolNum(iPoolNum),
00034 m_CompactPoolCount(0)
00035 {
00036 for (int i=0; i<32; ++i)
00037 m_redherring[i] = 0xcd;
00038 }
00039
00040 Pool::~Pool()
00041 {
00042 if (m_pThread)
00043 {
00044 delete m_pThread;
00045 m_pThread = NULL;
00046 }
00047
00048 }
00049
00050
00051 bool Pool::StartThread()
00052 {
00053 m_hCompactPoolEvent = m_CompactPoolEvent.GetHandle();
00054 m_hPoolMutex = m_PoolMutex.GetHandle();
00055
00056 m_pThread = new CMclThread(this);
00057
00058 return true;
00059 }
00060
00061
00062 unsigned Pool::ThreadHandlerProc(void)
00063 {
00064
00065 unsigned int seed = GetCurrentThreadId();
00066 seed += (unsigned int)this;
00067 seed += (unsigned int)time(NULL);
00068 {
00069 Timer hptimer;
00070 hptimer.Curr();
00071 seed += hptimer.m_currTime.LowPart;
00072 }
00073
00074 srand(seed);
00075
00076 m_hShutdownEvent = m_pFortuna->GetShutdownEventHandle();
00077
00078 HANDLE harray[2] = {m_hShutdownEvent, m_hCompactPoolEvent};
00079
00080 while(1)
00081 {
00082 DWORD dwResult = WaitForMultipleObjects(2, harray, FALSE, INFINITE);
00083 if (dwResult == WAIT_OBJECT_0)
00084 {
00085
00086
00087 break;
00088 }
00089 else if (dwResult == WAIT_OBJECT_0 + 1)
00090 {
00091 CompactPool();
00092 }
00093 }
00094
00095 return 0;
00096 }
00097
00098 bool Pool::CompactPool()
00099 {
00100
00101
00102 vecuc poolData;
00103 DWORD dwResult = WaitForSingleObject(m_hPoolMutex, INFINITE);
00104
00105 const unsigned int modnum = 255;
00106 m_pool.ExtractAndErase(poolData, modnum);
00107
00108
00109 sha256_ctx ctx[1];
00110 sha256_begin(ctx);
00111
00112 vecuc hashData;
00113 m_hashPool.ExtractAndErase(hashData, modnum);
00114
00115
00116 if (!hashData.empty())
00117 {
00118 unsigned long size = (unsigned long)hashData.size();
00119 sha256_hash(&hashData[0], size, ctx);
00120 }
00121
00122
00123 if (!poolData.empty())
00124 {
00125 unsigned long size = (unsigned long)poolData.size();
00126 sha256_hash(&poolData[0], size, ctx);
00127 }
00128
00129 unsigned char hval[32];
00130 sha256_end(hval, ctx);
00131
00132 int i=0;
00133 for (i=0; i<32; ++i)
00134 {
00135 m_hashPool.Add(hval[i]);
00136 hval[i] = rand() % 256;
00137 }
00138
00139 EraseHash(ctx);
00140
00141
00142 for (i=0; i<32; ++i)
00143 m_redherring[i] = rand() % 256;
00144
00145 ++m_CompactPoolCount;
00146
00147
00148
00149
00150 m_PoolMutex.Release();
00151
00152 m_CompactPoolEvent.Reset();
00153
00154 return true;
00155 }
00156
00157
00158 bool Pool::AddByte(const unsigned char byte)
00159 {
00160 DWORD dwResult = WaitForSingleObject(m_hPoolMutex, INFINITE);
00161
00162 unsigned int size = m_pool.Add(byte);
00163 ++m_TotalBytes;
00164
00165 m_PoolMutex.Release();
00166
00167
00168
00169 if (size > m_CompactPoolDataSize)
00170 {
00171 m_CompactPoolEvent.Set();
00172 }
00173
00174 return true;
00175 }
00176
00177
00178 bool Pool::AddBytes(const unsigned char* pData, unsigned int size)
00179 {
00180 DWORD dwResult = WaitForSingleObject(m_hPoolMutex, INFINITE);
00181
00182 for (unsigned int i=0; i<size; ++i)
00183 {
00184 m_pool.Add(pData[i]);
00185 }
00186
00187 unsigned int poolSize = m_pool.Size();
00188
00189 m_TotalBytes += size;
00190
00191 m_PoolMutex.Release();
00192
00193
00194
00195 if (poolSize > m_CompactPoolDataSize)
00196 {
00197 m_CompactPoolEvent.Set();
00198 }
00199
00200 return true;
00201 }
00202
00203
00204
00205
00206 bool Pool::ExtractAndErase(std::vector<unsigned char>& vBytes, bool& bShuttingDown)
00207 {
00208 HANDLE hVec[2] = {m_hShutdownEvent, m_hPoolMutex };
00209
00210 DWORD dwResult = WaitForMultipleObjects(2, hVec, FALSE, INFINITE);
00211
00212 if (dwResult == WAIT_OBJECT_0)
00213 {
00214 bShuttingDown = true;
00215 return false;
00216 }
00217 else if(dwResult == WAIT_OBJECT_0 + 1)
00218 {
00219 bShuttingDown = false;
00220 }
00221
00222
00223 vBytes.resize(m_pool.Size() + m_hashPool.Size());
00224
00225 std::vector<unsigned char> bytes;
00226 m_pool.ExtractAndErase(bytes, (unsigned int)256);
00227
00228 std::copy(bytes.begin(), bytes.end(), vBytes.begin());
00229
00230 size_t i=0;
00231 size_t size = bytes.size();
00232 for (i=0; i<size; ++i)
00233 bytes[i] = (unsigned char)(rand() % 256);
00234
00235 m_hashPool.ExtractAndErase(bytes, (unsigned int)256);
00236
00237 std::copy(bytes.begin(), bytes.end(), vBytes.begin() + size);
00238
00239 size = bytes.size();
00240 for (i=0; i<size; ++i)
00241 bytes[i] = (unsigned char)(rand() % 256);
00242
00243 m_TotalBytes = 0;
00244 m_CompactPoolCount = 0;
00245
00246 m_PoolMutex.Release();
00247
00248 return true;
00249 }
00250
00251
00252
00253 bool Pool::GetHashedPoolData(std::vector<unsigned char>& vData)
00254 {
00255 HANDLE hVec[2] = {m_hShutdownEvent, m_hPoolMutex };
00256
00257 DWORD dwResult = WaitForMultipleObjects(2, hVec, FALSE, INFINITE);
00258
00259 if (dwResult == WAIT_OBJECT_0)
00260 {
00261 return false;
00262 }
00263 else if(dwResult == WAIT_OBJECT_0 + 1)
00264 {
00265 ;
00266 }
00267 else
00268 {
00269 assert(0);
00270 }
00271
00272 vData.clear();
00273 m_hashPool.Extract(vData);
00274
00275 m_PoolMutex.Release();
00276
00277 return true;
00278 }
00279
00280 bool Pool::SetHashPoolState(vecuc& vState)
00281 {
00282 size_t size = vState.size();
00283 if (size != 32)
00284 {
00285 assert(0);
00286 return false;
00287 }
00288
00289 m_hashPool.Reset();
00290 for (size_t i=0; i<size; ++i)
00291 m_hashPool.Add(vState[i]);
00292
00293 return true;
00294 }
00295
00296
00297
00298
00299
00300
00301 void Pool::AddMachineSignatureToPool(vecuc& vMachineSig)
00302 {
00303 vecuc vPool;
00304 unsigned int iThis = (unsigned int)this;
00305 const unsigned char* pData = (unsigned char*)&iThis;
00306 AddBinaryData(vPool, pData, sizeof(unsigned int));
00307
00308
00309 m_hashPool.AddRandomData(vPool);
00310
00311 vecuc vHashPool;
00312 vHashPool.reserve(1024);
00313 m_hashPool.ExtractAndErase(vHashPool);
00314 m_hashPool.Reset();
00315
00316 AddToVector(vHashPool, vPool);
00317 EraseVector(vPool);
00318
00319 AddToVector(vHashPool, vMachineSig);
00320 EraseVector(vMachineSig);
00321
00322 vecuc vHash;
00323 HashVector(vHashPool, vHash);
00324 EraseVector(vHashPool);
00325
00326 size_t size = vHash.size();
00327 assert( size == 32);
00328
00329 for (size_t i=0; i<size; ++i)
00330 m_hashPool.Add(vHash[i]);
00331
00332 EraseVector(vHash);
00333 }
00334
00335 #ifdef FORTUNAMONITOR
00336 std::string Pool::GetName() const
00337 {
00338 char buffer[64] = {'\0'};
00339 sprintf(buffer,"Pool %d", m_iPoolNum);
00340
00341 return std::string(buffer);
00342 }
00343 #endif
00344
00345 #ifdef FORTUNAMONITOR
00346 std::string Pool::GetRawPool()
00347 {
00348 std::string str;
00349
00350 HANDLE hVec[2] = {m_hShutdownEvent, m_hPoolMutex };
00351 DWORD dwResult = WaitForMultipleObjects(2, hVec, FALSE, INFINITE);
00352
00353 if (dwResult == WAIT_OBJECT_0)
00354 return str;
00355 else if(dwResult == WAIT_OBJECT_0 + 1)
00356 {
00357 ;
00358 }
00359
00360 vecuc vData;
00361 m_pool.Extract(vData);
00362
00363 str = BinaryToString(&vData[0], (int)vData.size());
00364
00365 m_PoolMutex.Release();
00366
00367 return str;
00368 }
00369 #endif
00370
00371 #ifdef FORTUNAMONITOR
00372 std::string Pool::GetHashedPool()
00373 {
00374 std::string str;
00375
00376 HANDLE hVec[2] = {m_hShutdownEvent, m_hPoolMutex };
00377 DWORD dwResult = WaitForMultipleObjects(2, hVec, FALSE, INFINITE);
00378
00379 if (dwResult == WAIT_OBJECT_0)
00380 return str;
00381 else if(dwResult == WAIT_OBJECT_0 + 1)
00382 {
00383 ;
00384 }
00385
00386 vecuc vData;
00387 m_hashPool.Extract(vData);
00388
00389 str = BinaryToString(&vData[0], (int)vData.size());
00390
00391 m_PoolMutex.Release();
00392
00393 return str;
00394 }
00395 #endif
00396
00397 }