mirror of
https://github.com/tribes2/engine.git
synced 2026-01-20 03:34:48 +00:00
103 lines
2.4 KiB
C++
103 lines
2.4 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "crypt/cryptRandPool.h"
|
|
#include "Core/bitStream.h"
|
|
#include "crypt/cryptSHA1.h"
|
|
|
|
namespace {
|
|
|
|
CryptRandomPool* sgRandPool = NULL;
|
|
|
|
} // namespace {}
|
|
|
|
|
|
void CryptRandomPool::init()
|
|
{
|
|
AssertFatal(sgRandPool == NULL, "RandPool already initialized");
|
|
|
|
sgRandPool = new CryptRandomPool;
|
|
}
|
|
|
|
void CryptRandomPool::destroy()
|
|
{
|
|
AssertFatal(sgRandPool != NULL, "RandPool not initialized");
|
|
delete sgRandPool;
|
|
sgRandPool = NULL;
|
|
}
|
|
|
|
|
|
CryptRandomPool::CryptRandomPool()
|
|
{
|
|
mPoolPos = 0;
|
|
mAvailableBytes = 0;
|
|
}
|
|
|
|
CryptRandomPool::~CryptRandomPool()
|
|
{
|
|
|
|
}
|
|
|
|
void CryptRandomPool::submitEntropy(U32 value, U32 entropicBits)
|
|
{
|
|
AssertFatal(sgRandPool != NULL, "No Random pool!");
|
|
|
|
for (U32 i = 0; i < entropicBits; i++) {
|
|
U8 bit = value & 0x1;
|
|
value >>= 1;
|
|
|
|
// Write this bit to the current pool pos
|
|
U32 byte = sgRandPool->mPoolPos / 8;
|
|
U32 mask = sgRandPool->mPoolPos % 8;
|
|
sgRandPool->mPool[byte] ^= bit << mask;
|
|
sgRandPool->mPoolPos = (sgRandPool->mPoolPos + 1) % (55 * 8);
|
|
}
|
|
}
|
|
|
|
void CryptRandomPool::extractRandomBytes(U8* pOutput, U32 bytesNeeded)
|
|
{
|
|
AssertFatal(sgRandPool != NULL, "No Random pool!");
|
|
|
|
U32 currOutput = 0;
|
|
|
|
while (sgRandPool->mAvailableBytes != 0 && bytesNeeded != 0) {
|
|
sgRandPool->mAvailableBytes--;
|
|
bytesNeeded--;
|
|
pOutput[currOutput++] = sgRandPool->mRandomBytes[sgRandPool->mAvailableBytes];
|
|
}
|
|
|
|
while (bytesNeeded != 0) {
|
|
sgRandPool->churnPool();
|
|
|
|
while (sgRandPool->mAvailableBytes != 0 && bytesNeeded != 0) {
|
|
sgRandPool->mAvailableBytes--;
|
|
bytesNeeded--;
|
|
pOutput[currOutput++] = sgRandPool->mRandomBytes[sgRandPool->mAvailableBytes];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CryptRandomPool::churnPool()
|
|
{
|
|
SHA1Context hashCTX;
|
|
hashCTX.init();
|
|
hashCTX.hashBytes(mPool, 55);
|
|
hashCTX.finalize();
|
|
|
|
hashCTX.getHash(mRandomBytes);
|
|
mAvailableBytes = 20;
|
|
|
|
const U32* pChurn = (const U32*)mRandomBytes;
|
|
submitEntropy(pChurn[0], 32);
|
|
submitEntropy(pChurn[1], 32);
|
|
submitEntropy(pChurn[2], 32);
|
|
submitEntropy(pChurn[3], 32);
|
|
submitEntropy(pChurn[4], 32);
|
|
|
|
}
|