YarrowServer_OS9.c [plain text]
#include <yarrowUtils.h>
#include "YarrowServer_OS9.h"
#include "entropyFile.h"
#include <debug.h>
#include <yarrow.h>
#include <Errors.h>
#include <Timer.h>
#include <LowMem.h>
static PrngRef prng = NULL;
#define ENTROPY_COLLECT_INTERVAL (10 * 60)
#define SYSTEM_ENTROPY_SIZE 20
#define ENTROPY_FILE_SIZE 20
#define RESEED_TICKS 100
#pragma mark -
#pragma mark * * * Private Functions * * *
#ifdef __cplusplus
extern "C" {
#endif
OSErr _init(void *initBlk);
void _fini(void);
int main();
#ifdef __cplusplus
}
#endif
static void
systemEntropy(
UInt8 *buf,
UInt32 bufSize,
UInt32 *numBytes, UInt32 *bitsOfEntropy);
OSErr
_init(void *initBlk)
{
prng_error_status prtn;
UInt8 entropyFileData[ENTROPY_FILE_SIZE];
UInt8 sysEntropyData[SYSTEM_ENTROPY_SIZE];
UInt32 actLen;
OSErr ortn;
UInt32 entropyBits;
prtn = prngInitialize(&prng);
if(prtn) {
errorLog1("_init: prngInitialize returned %s\n", perrorString(prtn));
return perrorToOSErr(prtn);
}
ortn = readEntropyFile(entropyFileData,
ENTROPY_FILE_SIZE,
&actLen);
if((ortn == noErr) && (actLen > 0)) {
prtn = prngInput(prng,
entropyFileData,
actLen,
ENTROPY_FILE_SOURCE,
actLen * 8); if(prtn) {
errorLog1("_init: prngInput returned %s\n",
perrorString(prtn));
return perrorToOSErr(prtn);
}
}
trashMemory(entropyFileData, actLen);
systemEntropy(sysEntropyData,
SYSTEM_ENTROPY_SIZE,
&actLen,
&entropyBits);
if(actLen > 0) {
prtn = prngInput(prng,
entropyFileData,
actLen,
SYSTEM_SOURCE,
entropyBits);
if(prtn) {
errorLog1("_init: prngInput returned %s\n",
perrorString(prtn));
return perrorToOSErr(prtn);
}
}
trashMemory(sysEntropyData, actLen);
prtn = prngForceReseed(prng, RESEED_TICKS);
if(prtn) {
errorLog1("_init: prngForceReseed returned %s\n",
perrorString(prtn));
return perrorToOSErr(prtn);
}
prtn = prngOutput(prng, entropyFileData, ENTROPY_FILE_SIZE);
if(prtn) {
errorLog1("_init: prngOutput returned %s\n",
perrorString(prtn));
return perrorToOSErr(prtn);
}
ortn = writeEntropyFile(entropyFileData, ENTROPY_FILE_SIZE, false);
if(ortn) {
return ortn;
}
return noErr;
}
void
_fini(void)
{
if(prng != NULL) {
prngDestroy(prng);
prng = NULL;
}
}
static void
prngLock()
{
}
static void
prngUnlock()
{
}
static void
systemEntropy(
UInt8 *buf,
UInt32 bufSize,
UInt32 *numBytes, UInt32 *bitsOfEntropy) {
UnsignedWide curTime;
unsigned ticks = 0;
UInt8 pool[6];
UInt8 *pp = pool;
Microseconds(&curTime);
*pp++ = curTime.lo & 0xff;
*pp++ = curTime.lo >> 8;
*pp++ = curTime.lo >> 16;
*pp++ = curTime.lo >> 24;
*pp++ = ticks & 0xff;
*pp = ticks >> 8;
if(bufSize > 6) {
bufSize = 6;
}
BlockMove(pool, buf, bufSize);
*numBytes = bufSize;
*bitsOfEntropy = 3 * 8;
}
static void
entropyCollector()
{
}
#pragma mark -
#pragma mark * * * Public Functions * * *
OSErr yarrowAddEntropy(
UInt8 *bytes,
UInt32 numBytes,
UInt32 bitsOfEntropy)
{
UInt8 sysEntropy[SYSTEM_ENTROPY_SIZE];
UInt32 numSysBytes;
UInt32 numSysEntropyBits;
prng_error_status prtn;
OSErr ortn = noErr;
if(prng == NULL) {
return notOpenErr;
}
prngLock();
prtn = prngInput(prng, bytes, numBytes, CLIENT_SOURCE, bitsOfEntropy);
if(prtn) {
errorLog1("prngInput returned %s\n", perrorString(prtn));
ortn = ioErr;
goto done;
}
systemEntropy(sysEntropy, SYSTEM_ENTROPY_SIZE, &numSysBytes,
&numSysEntropyBits);
prtn = prngInput(prng, sysEntropy, numSysBytes, SYSTEM_SOURCE,
numSysEntropyBits);
if(prtn) {
errorLog1("prngInput returned %s\n", perrorString(prtn));
ortn = ioErr;
goto done;
}
prngAllowReseed(prng, RESEED_TICKS);
done:
prngUnlock();
return ortn;
}
OSErr yarrowGetRandomBytes(
UInt8 *bytes,
UInt32 numBytes)
{
if(prng == NULL) {
return notOpenErr;
}
prngLock();
prngOutput(prng, bytes, numBytes);
prngUnlock();
return noErr;
}