#include "entropyFile.h"
#include "debug.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
#define DEFAULT_ENTROPY_FILE_PATH "/var/db/SystemEntropyCache"
static char *entropyFilePath = NULL;
static OSErr errNoToOSErr(int err)
{
switch(err) {
case ENOENT:
return fnfErr;
case EPERM:
return permErr;
default:
return ioErr;
}
}
static char *getEntropyFilePath()
{
if(entropyFilePath) {
return entropyFilePath;
}
else {
return DEFAULT_ENTROPY_FILE_PATH;
}
}
OSErr setEntropyFilePath(
const char *path)
{
unsigned len;
if(entropyFilePath) {
free(entropyFilePath);
entropyFilePath = NULL;
}
if(path == NULL) {
return noErr;
}
len = strlen(path);
if(len > 255) {
return bdNamErr;
}
entropyFilePath = malloc(len + 1);
if(entropyFilePath == NULL) {
return memFullErr;
}
memmove(entropyFilePath, path, len + 1);
return noErr;
}
OSErr writeEntropyFile(
UInt8 *bytes,
UInt32 numBytes)
{
int rtn;
int fd;
OSErr ortn;
fd = open(getEntropyFilePath(), O_RDWR | O_CREAT | O_TRUNC, 0600);
if(fd <= 0) {
rtn = errno;
errorLog1("writeEntropyFile: open returned %d\n", rtn);
return errNoToOSErr(rtn);
}
rtn = lseek(fd, 0, SEEK_SET);
if(rtn < 0) {
rtn = errno;
errorLog1("writeEntropyFile: lseek returned %d\n", rtn);
return errNoToOSErr(rtn);
}
rtn = write(fd, bytes, (size_t)numBytes);
if(rtn != (int)numBytes) {
if(rtn < 0) {
errorLog1("writeEntropyFile: write() returned %d\n", rtn);
ortn = errNoToOSErr(errno);
}
else {
errorLog0("writeEntropyFile(): short write\n");
ortn = ioErr;
}
}
else {
ortn = noErr;
}
close(fd);
return ortn;
}
OSErr readEntropyFile(
UInt8 *bytes,
UInt32 numBytes, UInt32 *actualBytes) {
int rtn;
int fd;
OSErr ortn;
*actualBytes = 0;
fd = open(getEntropyFilePath(), O_RDONLY, 0);
if(fd <= 0) {
rtn = errno;
errorLog1("readEntropyFile: open returned %d\n", rtn);
return errNoToOSErr(rtn);
}
rtn = lseek(fd, 0, SEEK_SET);
if(rtn < 0) {
rtn = errno;
errorLog1("readEntropyFile: lseek returned %d\n", rtn);
return errNoToOSErr(rtn);
}
rtn = read(fd, bytes, (size_t)numBytes);
if(rtn < 0) {
errorLog1("readEntropyFile: read() returned %d\n", rtn);
ortn = errNoToOSErr(errno);
}
else {
*actualBytes = (UInt32)rtn;
ortn = noErr;
}
close(fd);
return ortn;
}