t2 engine svn checkout

This commit is contained in:
loop 2024-01-07 04:36:33 +00:00
commit ff569bd2ae
988 changed files with 394180 additions and 0 deletions

44
crypt/cryptMGF.cc Normal file
View file

@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#include "crypt/cryptMGF.h"
#include "crypt/cryptSHA1.h"
bool MGF1(const U8* seed, const U32 seedLen,
U8* mask, const U32 maskLen)
{
AssertFatal(seed != NULL, "Error, no seed!");
AssertFatal(mask != NULL && maskLen != 0, "No mask pointer or maskLen == 0");
U32 upper = (maskLen + SHA1Context::csmHashLenBytes - 1) / SHA1Context::csmHashLenBytes;
U8* maskBuffer = new U8[upper * SHA1Context::csmHashLenBytes];
U8* catBuffer = new U8[seedLen + 4];
dMemcpy(catBuffer, seed, seedLen);
SHA1Context hashContext;
for (U32 i = 0; i < upper; i++) {
catBuffer[seedLen + 0] = (i >> 24) & 0xFF;
catBuffer[seedLen + 1] = (i >> 16) & 0xFF;
catBuffer[seedLen + 2] = (i >> 8) & 0xFF;
catBuffer[seedLen + 3] = (i >> 0) & 0xFF;
hashContext.init();
hashContext.hashBytes(catBuffer, seedLen + 4);
hashContext.finalize();
hashContext.getHash(maskBuffer + (SHA1Context::csmHashLenBytes * i));
}
dMemcpy(mask, maskBuffer, maskLen);
delete [] catBuffer;
delete [] maskBuffer;
return true;
}

18
crypt/cryptMGF.h Normal file
View file

@ -0,0 +1,18 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _CRYPTMGF_H_
#define _CRYPTMGF_H_
#ifndef _PLATFORM_H_
#include "Platform/platform.h"
#endif
bool MGF1(const U8* seed, const U32 seedLen,
U8* mask, const U32 maskLen);
#endif // _H_CRYPTMGF_

102
crypt/cryptRandPool.cc Normal file
View file

@ -0,0 +1,102 @@
//-----------------------------------------------------------------------------
// 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);
}

39
crypt/cryptRandPool.h Normal file
View file

@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _CRYPTRANDPOOL_H_
#define _CRYPTRANDPOOL_H_
#ifndef _PLATFORM_H_
#include "Platform/platform.h"
#endif
class BitStream;
class CryptRandomPool
{
U8 mPool[55];
U32 mPoolPos;
U8 mRandomBytes[20];
U32 mAvailableBytes;
void churnPool();
CryptRandomPool();
~CryptRandomPool();
public:
static void init();
static void destroy();
static void submitEntropy(U32 value, U32 entropicBits);
static void extractRandomBytes(U8* pOutput,
U32 bytesNeeded);
};
#endif // _H_CRYPTRANDPOOL_

229
crypt/cryptSHA1.cc Normal file
View file

@ -0,0 +1,229 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#include "crypt/cryptSHA1.h"
namespace {
inline U32 rollLeft(U32 val, U32 rol)
{
return (val << rol) | (val >> (32 - rol));
}
} // namespace {}
//--------------------------------------------------------------------------
//-------------------------------------- SHA1Context
//
const U32 SHA1Context::csmHashInitialValues[5] = { 0x67452301,
0xEFCDAB89,
0x98BADCFE,
0x10325476,
0xC3D2E1F0 };
const U32 SHA1Context::csmRoundConstants[4] = { 0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6 };
const U32 SHA1Context::csmHashLenBits = 160;
const U32 SHA1Context::csmHashLenBytes = 20;
SHA1Context::SHA1Context()
{
U32 mBytesWritten = 0;
bool mInitialized = false;
bool mHashValid = false;
U32 mBufferLen = 0;
}
SHA1Context::~SHA1Context()
{
U32 mBytesWritten = 0;
bool mInitialized = false;
bool mHashValid = false;
U32 mBufferLen = 0;
}
void SHA1Context::init()
{
for (U32 i = 0; i < 5; i++)
mHashVals[i] = csmHashInitialValues[i];
mBufferLen = 0;
mBytesWritten = 0;
mInitialized = true;
mHashValid = false;
}
void SHA1Context::hashBytes(const void* input, const U32 inputLen)
{
AssertFatal(input != NULL, "Error, invalid input pointer");
AssertFatal(mInitialized == true, "Error, SHA1Context not initialized. Must init() before writing bytes");
AssertFatal(mHashValid == false, "Error, SHA1Context already finalized. Must reinit() before writing more bytes");
if (inputLen == 0)
return;
const U8* pByteInput = reinterpret_cast<const U8*>(input);
U32 currInputPos = 0;
if (mBufferLen != 0) {
// Copy out enough bytes to finish off the buffer, if enough exist
while (mBufferLen < 64 && currInputPos < inputLen) {
mBuffer[mBufferLen++] = pByteInput[currInputPos++];
mBytesWritten++;
}
if (mBufferLen == 64) {
hashBlock(mBuffer);
mBufferLen = 0;
}
}
AssertFatal(mBufferLen == 0 || currInputPos == inputLen, "Hm, something goofed");
if (currInputPos < inputLen) {
// More bytes to hash...
U32 bytesLeft = inputLen - currInputPos;
while (bytesLeft >= 64) {
hashBlock(&pByteInput[currInputPos]);
currInputPos += 64;
bytesLeft -= 64;
mBytesWritten += 64;
}
if (bytesLeft != 0) {
dMemcpy(mBuffer, &pByteInput[currInputPos], bytesLeft);
mBytesWritten += bytesLeft;
mBufferLen = bytesLeft;
}
}
}
void SHA1Context::finalize()
{
// We assume that bytes written is less than 256 megs. Seems safe for now.
AssertFatal(mInitialized == true, "Error, hash context not initialized.");
AssertFatal(mBytesWritten < (1 << 27), "Error, too many bytes written to SHAContext");
AssertFatal(mBufferLen < 64, "Error, unflushed buffer, or invalid bufferlen");
if (mBufferLen < (64 - 8 - 1)) {
// We have enough room in this buffer for the padding structure...
//
mBuffer[mBufferLen++] = 0x80;
for (U32 i = mBufferLen; i < (64 - 8); i++)
mBuffer[mBufferLen++] = 0x0;
} else {
// We have to create a new block to finalize this one...
mBuffer[mBufferLen++] = 0x80;
for (U32 i = mBufferLen; i < 64; i++)
mBuffer[i] = 0x00;
hashBlock(mBuffer);
mBufferLen = 0;
for (U32 i = 0; i < (64 - 8); i++)
mBuffer[mBufferLen++] = 0x00;
}
AssertFatal(mBufferLen == (64 - 8), "Error in one of the above loops");
U32* pLenVals = reinterpret_cast<U32*>(&mBuffer[(64 - 8)]);
pLenVals[0] = 0;
pLenVals[1] = convertHostToBEndian(mBytesWritten * 8);
hashBlock(mBuffer);
mBufferLen = 0;
mHashValid = true;
mBytesWritten = 0;
}
bool SHA1Context::getHash(U8* pHash)
{
if (mHashValid == true) {
U32* pWordHash = reinterpret_cast<U32*>(pHash);
pWordHash[0] = convertHostToBEndian(mHashVals[0]);
pWordHash[1] = convertHostToBEndian(mHashVals[1]);
pWordHash[2] = convertHostToBEndian(mHashVals[2]);
pWordHash[3] = convertHostToBEndian(mHashVals[3]);
pWordHash[4] = convertHostToBEndian(mHashVals[4]);
return true;
}
return false;
}
//--------------------------------------------------------------------------
//-------------------------------------- Note that this isn't the most optimal
// implementation, but it's easy, and since
// we're not overly concerned with speed
// (right now), we're fine
//
inline U32 SHA1Context::sha1Nonlinear(U32 x, U32 y, U32 z, U32 t)
{
AssertFatal(t < 80, "Error, invalid round");
if (t <= 19) {
return ((x & y) | ((~x) & z)) + csmRoundConstants[0];
} else if (t <= 39) {
return (x ^ y ^ z) + csmRoundConstants[1];
} else if (t <= 59) {
return ((x & y) | (x & z) | (y & z)) + csmRoundConstants[2];
} else {
return (x ^ y ^ z) + csmRoundConstants[3];
}
}
void SHA1Context::hashBlock(const void* pInput)
{
const U32* pWordInput = reinterpret_cast<const U32*>(pInput);
// First expand the message to 80 words
//
U32 expandedBlock[80];
for (U32 i = 0; i < 16; i++)
expandedBlock[i] = convertBEndianToHost(pWordInput[i]);
for (U32 i = 16; i < 80; i++)
expandedBlock[i] = rollLeft(expandedBlock[i - 3] ^ expandedBlock[i - 8] ^
expandedBlock[i - 14] ^ expandedBlock[i - 16], 1);
register U32 a = mHashVals[0];
register U32 b = mHashVals[1];
register U32 c = mHashVals[2];
register U32 d = mHashVals[3];
register U32 e = mHashVals[4];
U32 tmp;
for (U32 i = 0; i < 80; i++) {
// In this implementation, the round constants are in the nonlinear function
//
tmp = rollLeft(a, 5) +
sha1Nonlinear(b, c, d, i) +
e +
expandedBlock[i];
e = d;
d = c;
c = rollLeft(b, 30);
b = a;
a = tmp;
}
mHashVals[0] += a;
mHashVals[1] += b;
mHashVals[2] += c;
mHashVals[3] += d;
mHashVals[4] += e;
}

47
crypt/cryptSHA1.h Normal file
View file

@ -0,0 +1,47 @@
//-----------------------------------------------------------------------------
// V12 Engine
//
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------
#ifndef _CRYPTSHA1_H_
#define _CRYPTSHA1_H_
#ifndef _PLATFORM_H_
#include "Platform/platform.h"
#endif
class SHA1Context
{
static const U32 csmHashInitialValues[5];
static const U32 csmRoundConstants[4];
U32 mHashVals[5];
U32 mBytesWritten;
bool mInitialized;
bool mHashValid;
U8 mBuffer[64];
U32 mBufferLen;
private:
void hashBlock(const void*);
U32 sha1Nonlinear(U32, U32, U32, U32);
public:
SHA1Context();
~SHA1Context();
static const U32 csmHashLenBits;
static const U32 csmHashLenBytes;
void init();
void hashBytes(const void* input, const U32 inputLen);
void finalize();
bool getHash(U8* pHash);
};
#endif // _H_CRYPTSHA1_