Fortuna PRNG C++ Source Code

Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

CitadelSoftwareInc::PoolMgr Class Reference

Creates, Deletes and gives access to the Pools. More...

#include <PoolMgr.h>

List of all members.

Public Member Functions

 PoolMgr (Fortuna *pOwner)
 ~PoolMgr ()
virtual unsigned ThreadHandlerProc (void)
bool StartThread ()
HANDLE GetThreadHandle () const
PoolGetPool (const int num)
bool Reseed (std::vector< unsigned char > &seed, bool &bShuttingDown)

Private Types

enum  { eNumberOfPools = 32 }

Private Member Functions

bool GetPools (std::vector< Pool * > &Pools)
 PoolMgr ()
 PoolMgr (const PoolMgr &x)
PoolMgroperator= (const PoolMgr &x)

Private Attributes

Fortunam_pOwner
CMclThread * m_pThread
std::string m_sStatus
DWORD m_dwLastReseedTime
unsigned int m_reseedcount
std::vector< Pool * > m_Pools

Friends

class SourceMgr
class Generator
class Fortuna

Detailed Description

Creates, Deletes and gives access to the Pools.

Definition at line 23 of file PoolMgr.h.

Member Enumeration Documentation

anonymous enum [private]
 

Enumeration values:
eNumberOfPools 

Definition at line 56 of file PoolMgr.h.

00056 {eNumberOfPools=32};

Constructor & Destructor Documentation

CitadelSoftwareInc::PoolMgr::PoolMgr Fortuna pOwner  ) 
 

Definition at line 20 of file PoolMgr.cpp.

References eNumberOfPools, m_Pools, and m_pOwner.

00021         :
00022         m_pOwner(pOwner),
00023         m_pThread(NULL),
00024         m_dwLastReseedTime(0),
00025         m_reseedcount(0)
00026 {
00027         m_Pools.resize(eNumberOfPools);
00028         for (int i=0; i<eNumberOfPools; ++i)
00029         {
00030                 Pool *p = new Pool(m_pOwner, this, i);
00031                 m_Pools[i] = p;
00032         }
00033 }

CitadelSoftwareInc::PoolMgr::~PoolMgr  ) 
 

Definition at line 35 of file PoolMgr.cpp.

References eNumberOfPools, m_Pools, and m_pThread.

00036 {
00037         for (int i=0; i<eNumberOfPools; ++i)
00038         {
00039                 Pool *p = m_Pools[i];
00040                 delete p;
00041                 m_Pools[i] = NULL;
00042         }
00043 
00044         if (m_pThread)
00045         {
00046                 delete m_pThread;
00047                 m_pThread = NULL;
00048         }
00049 }

CitadelSoftwareInc::PoolMgr::PoolMgr  )  [private]
 

CitadelSoftwareInc::PoolMgr::PoolMgr const PoolMgr x  )  [private]
 

Member Function Documentation

Pool * CitadelSoftwareInc::PoolMgr::GetPool const int  num  ) 
 

Definition at line 118 of file PoolMgr.cpp.

References m_Pools.

Referenced by CitadelSoftwareInc::Fortuna::GetPool().

00119 {
00120         Pool *pPool = NULL;
00121 
00122         if (num < 0)
00123                 return pPool;
00124 
00125         if (num >= (int)m_Pools.size())
00126                 return pPool;
00127 
00128         pPool = m_Pools[num];
00129 
00130         return pPool;
00131 }

bool CitadelSoftwareInc::PoolMgr::GetPools std::vector< Pool * > &  Pools  )  [private]
 

Definition at line 108 of file PoolMgr.cpp.

References eNumberOfPools, and m_Pools.

Referenced by CitadelSoftwareInc::Fortuna::Fortuna(), CitadelSoftwareInc::Generator::SetPoolMgr(), and CitadelSoftwareInc::SourceMgr::SourceMgr().

00109 {
00110         Pools.resize(eNumberOfPools);
00111         std::copy(m_Pools.begin(), m_Pools.end(), Pools.begin());
00112 
00113         return true;
00114 }

HANDLE CitadelSoftwareInc::PoolMgr::GetThreadHandle  )  const [inline]
 

Definition at line 35 of file PoolMgr.h.

References m_pThread.

Referenced by CitadelSoftwareInc::Fortuna::Stop().

00035 { return m_pThread->GetHandle(); }

PoolMgr& CitadelSoftwareInc::PoolMgr::operator= const PoolMgr x  )  [private]
 

bool CitadelSoftwareInc::PoolMgr::Reseed std::vector< unsigned char > &  seed,
bool &  bShuttingDown
 

Returns true if the reseed was performed Reseeds are only performed when there is enough entropy available in Pool p0 and the last reseed was over 100 ms ago

Definition at line 137 of file PoolMgr.cpp.

References eNumberOfPools, CitadelSoftwareInc::Pool::ExtractAndErase(), CitadelSoftwareInc::Pool::GetTotalBytes(), m_dwLastReseedTime, m_Pools, and m_reseedcount.

Referenced by CitadelSoftwareInc::Generator::GetRandomBytes().

00138 {
00139         int i=0; 
00140         DWORD dwTime = GetTickCount();
00141 
00142         if (dwTime - m_dwLastReseedTime < 100)          // don't allow a reseed within 100ms of the previous reseed
00143                 return false;
00144 
00145         Pool* pool = m_Pools[0];
00146         unsigned int totalBytes = pool->GetTotalBytes();
00147 
00148         if (totalBytes < 128)
00149                 return false;
00150 
00151         m_dwLastReseedTime = dwTime;
00152 
00153         int seedSizeAlloc = 1024;
00154         int seedSize      = 0;
00155         unsigned char *pSeeds = new unsigned char[seedSizeAlloc];
00156         for (i=0; i<seedSizeAlloc; ++i)
00157                 pSeeds[i] = (unsigned char)(rand() % 256);              // fill in with random looking data
00158 
00159         bool bStatus = false;
00160         bShuttingDown=false;
00161 
00162         ++m_reseedcount;
00163 
00164         unsigned int two_i = 1;         // 2^i
00165         std::vector<unsigned char> poolState;           // includes the pool hash and the current pool state
00166         for (i=0; i<eNumberOfPools; ++i)
00167         {
00168                 if (i == 0 || m_reseedcount % two_i == 0)
00169                 {
00170                         std::vector<unsigned char> tempState;
00171                         pool = m_Pools[i];
00172                         bStatus = pool->ExtractAndErase(tempState, bShuttingDown);              // extract both the hash and the current pool state
00173                         if (!bStatus || bShuttingDown)
00174                         {
00175                                 delete [] pSeeds;
00176                                 return false;
00177                         }
00178 
00179                         int tempSize = (int)tempState.size();
00180                         if (seedSize + tempSize < seedSizeAlloc)
00181                         {
00182                                 std::copy(tempState.begin(), tempState.end(), pSeeds+seedSize);
00183                                 seedSize += tempSize;
00184                         }
00185                         else
00186                         {
00187                                 int seedSizeAllocNew = seedSizeAlloc + tempSize + 64*1024;
00188                                 unsigned char *pSeedsNew = new unsigned char[seedSizeAllocNew];
00189                                 std::copy(pSeeds, pSeeds+seedSize, pSeedsNew);
00190                                 std::copy(tempState.begin(), tempState.end(), pSeedsNew+seedSize);
00191 
00192                                 // put random data in the end of the new vector (past the existing data)
00193                                 for (int i=seedSize + tempSize; i<seedSizeAllocNew; ++i)
00194                                         pSeedsNew[i] = (unsigned char)(rand() % 256);
00195 
00196                                 // overwrite the previous seed with random looking data
00197                                 for (int i=0; i<seedSize; ++i)
00198                                         pSeeds[i] = (unsigned char)(rand() % 256);
00199 
00200                                 seedSizeAlloc = seedSizeAllocNew;
00201                                 seedSize      += tempSize;
00202                                 delete [] pSeeds;
00203                                 pSeeds = pSeedsNew;
00204                         }
00205                 }
00206                 else
00207                         break;                          // astute readers will note...
00208 
00209                 two_i *= 2;                             // next value of 2^i
00210         }
00211 
00212         // all of the pool state has been accumulated into pSeeds and is of data size seedSize and allocated seedSizeAlloc
00213 
00214         // now hash the seeds
00215         sha256_ctx ctx[1];
00216     sha256_begin(ctx);
00217 
00218         sha256_hash(pSeeds, seedSize, ctx);
00219 
00220         for (i=0; i<seedSize; ++i)
00221                 pSeeds[i] = (unsigned char)(rand() % 256);
00222 
00223         delete [] pSeeds;
00224 
00225         unsigned char hval[32];
00226         sha256_end(hval, ctx);
00227 
00228         seed.resize(32);
00229         std::copy(&hval[0], &hval[0]+32, seed.begin());
00230 
00231         for (i=0; i<32; ++i)
00232                 hval[i] = (unsigned char)(rand() % 256);
00233 
00234         return true;
00235 }

bool CitadelSoftwareInc::PoolMgr::StartThread  ) 
 

Definition at line 53 of file PoolMgr.cpp.

References m_pThread.

Referenced by CitadelSoftwareInc::Fortuna::StartThreads().

00054 {
00055         m_pThread = new CMclThread(this);
00056 
00057         return true;
00058 }

unsigned CitadelSoftwareInc::PoolMgr::ThreadHandlerProc void   )  [virtual]
 

Definition at line 62 of file PoolMgr.cpp.

References eNumberOfPools, CitadelSoftwareInc::Fortuna::GetShutdownEventHandle(), m_Pools, m_pOwner, m_sStatus, and CitadelSoftwareInc::Pool::StartThread().

00063 {
00064         // give each thread a different seed for rand()
00065         unsigned int seed = GetCurrentThreadId();
00066         seed += (unsigned int)this;
00067         seed += (unsigned int)time(NULL);
00068         srand(seed);
00069 
00070         for (int i=0; i<eNumberOfPools; ++i)
00071         {
00072                 Pool *p = m_Pools[i];
00073                 p->StartThread();
00074         }
00075 
00076         HANDLE hShutdownEvent = m_pOwner->GetShutdownEventHandle();
00077         DWORD dwResult = WaitForSingleObject(hShutdownEvent, INFINITE);
00078 
00079         if (dwResult == WAIT_FAILED)
00080         {
00081                 m_sStatus += "Wait for ShutdownEventHandle Failed";
00082         }
00083 
00084         std::vector<HANDLE> vPoolHandles(eNumberOfPools);
00085         for (i=0; i<eNumberOfPools; ++i)
00086         {
00087                 vPoolHandles[i] = m_Pools[i]->GetThreadHandle();
00088         }
00089 
00090         DWORD nCount = eNumberOfPools;
00091         dwResult = WaitForMultipleObjects(nCount, &vPoolHandles[0], TRUE, INFINITE);
00092 
00093         if (dwResult == WAIT_OBJECT_0)
00094         {
00095                 ;       // do nothing
00096         }
00097         else if (dwResult == WAIT_FAILED)
00098         {
00099                 m_sStatus += "WaitForMultipleObjects on all pool threads failed";
00100                 assert(0);
00101         }
00102 
00103 
00104         return 0;
00105 }

Friends And Related Function Documentation

friend class Fortuna [friend]
 

Definition at line 75 of file PoolMgr.h.

friend class Generator [friend]
 

Definition at line 74 of file PoolMgr.h.

friend class SourceMgr [friend]
 

Definition at line 73 of file PoolMgr.h.

Member Data Documentation

DWORD CitadelSoftwareInc::PoolMgr::m_dwLastReseedTime [private]
 

Definition at line 61 of file PoolMgr.h.

Referenced by Reseed().

std::vector<Pool*> CitadelSoftwareInc::PoolMgr::m_Pools [private]
 

Definition at line 71 of file PoolMgr.h.

Referenced by GetPool(), GetPools(), PoolMgr(), Reseed(), ThreadHandlerProc(), and ~PoolMgr().

Fortuna* CitadelSoftwareInc::PoolMgr::m_pOwner [private]
 

Definition at line 53 of file PoolMgr.h.

Referenced by PoolMgr(), and ThreadHandlerProc().

CMclThread* CitadelSoftwareInc::PoolMgr::m_pThread [private]
 

Definition at line 54 of file PoolMgr.h.

Referenced by GetThreadHandle(), StartThread(), and ~PoolMgr().

unsigned int CitadelSoftwareInc::PoolMgr::m_reseedcount [private]
 

Definition at line 63 of file PoolMgr.h.

Referenced by Reseed().

std::string CitadelSoftwareInc::PoolMgr::m_sStatus [private]
 

Definition at line 58 of file PoolMgr.h.

Referenced by ThreadHandlerProc().

The documentation for this class was generated from the following files:
bulletPoolMgr.h
bulletPoolMgr.cpp

Generated on Sat Feb 28 17:24:43 2004 for Fortuna by doxygen 1.3.5