|
Packit |
40b132 |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
40b132 |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
40b132 |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
#define INCL_DOS
|
|
Packit |
40b132 |
#define INCL_DOSERRORS
|
|
Packit |
40b132 |
#include <os2.h>
|
|
Packit |
40b132 |
#include "secrng.h"
|
|
Packit |
40b132 |
#include "prerror.h"
|
|
Packit |
40b132 |
#include <stdlib.h>
|
|
Packit |
40b132 |
#include <time.h>
|
|
Packit |
40b132 |
#include <stdio.h>
|
|
Packit |
40b132 |
#include <sys/stat.h>
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
APIRET rc = NO_ERROR;
|
|
Packit |
40b132 |
QWORD qword = {0,0};
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rc = DosTmrQueryTime(&qword);
|
|
Packit |
40b132 |
if (rc != NO_ERROR)
|
|
Packit |
40b132 |
return FALSE;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*phigh = qword.ulHi;
|
|
Packit |
40b132 |
*plow = qword.ulLo;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return TRUE;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
size_t RNG_GetNoise(void *buf, size_t maxbuf)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
unsigned long high = 0;
|
|
Packit |
40b132 |
unsigned long low = 0;
|
|
Packit |
40b132 |
clock_t val = 0;
|
|
Packit |
40b132 |
int n = 0;
|
|
Packit |
40b132 |
int nBytes = 0;
|
|
Packit |
40b132 |
time_t sTime;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (maxbuf <= 0)
|
|
Packit |
40b132 |
return 0;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
clockTickTime(&high, &low);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* get the maximally changing bits first */
|
|
Packit |
40b132 |
nBytes = sizeof(low) > maxbuf ? maxbuf : sizeof(low);
|
|
Packit |
40b132 |
memcpy(buf, &low, nBytes);
|
|
Packit |
40b132 |
n += nBytes;
|
|
Packit |
40b132 |
maxbuf -= nBytes;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (maxbuf <= 0)
|
|
Packit |
40b132 |
return n;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
nBytes = sizeof(high) > maxbuf ? maxbuf : sizeof(high);
|
|
Packit |
40b132 |
memcpy(((char *)buf) + n, &high, nBytes);
|
|
Packit |
40b132 |
n += nBytes;
|
|
Packit |
40b132 |
maxbuf -= nBytes;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (maxbuf <= 0)
|
|
Packit |
40b132 |
return n;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* get the number of milliseconds that have elapsed since application started */
|
|
Packit |
40b132 |
val = clock();
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
nBytes = sizeof(val) > maxbuf ? maxbuf : sizeof(val);
|
|
Packit |
40b132 |
memcpy(((char *)buf) + n, &val, nBytes);
|
|
Packit |
40b132 |
n += nBytes;
|
|
Packit |
40b132 |
maxbuf -= nBytes;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (maxbuf <= 0)
|
|
Packit |
40b132 |
return n;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* get the time in seconds since midnight Jan 1, 1970 */
|
|
Packit |
40b132 |
time(&sTime);
|
|
Packit |
40b132 |
nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
|
|
Packit |
40b132 |
memcpy(((char *)buf) + n, &sTime, nBytes);
|
|
Packit |
40b132 |
n += nBytes;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return n;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static BOOL
|
|
Packit |
40b132 |
EnumSystemFiles(void (*func)(const char *))
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
APIRET rc;
|
|
Packit |
40b132 |
ULONG sysInfo = 0;
|
|
Packit |
40b132 |
char bootLetter[2];
|
|
Packit |
40b132 |
char sysDir[_MAX_PATH] = "";
|
|
Packit |
40b132 |
char filename[_MAX_PATH];
|
|
Packit |
40b132 |
HDIR hdir = HDIR_CREATE;
|
|
Packit |
40b132 |
ULONG numFiles = 1;
|
|
Packit |
40b132 |
FILEFINDBUF3 fileBuf = {0};
|
|
Packit |
40b132 |
ULONG buflen = sizeof(FILEFINDBUF3);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&sysInfo,
|
|
Packit |
40b132 |
sizeof(ULONG)) == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
bootLetter[0] = sysInfo + 'A' -1;
|
|
Packit |
40b132 |
bootLetter[1] = '\0';
|
|
Packit |
40b132 |
strcpy(sysDir, bootLetter);
|
|
Packit |
40b132 |
strcpy(sysDir+1, ":\\OS2\\");
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
strcpy( filename, sysDir );
|
|
Packit |
40b132 |
strcat( filename, "*.*" );
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rc =DosFindFirst( filename, &hdir, FILE_NORMAL, &fileBuf, buflen,
|
|
Packit |
40b132 |
&numFiles, FIL_STANDARD );
|
|
Packit |
40b132 |
if( rc == NO_ERROR )
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
do {
|
|
Packit |
40b132 |
// pass the full pathname to the callback
|
|
Packit |
40b132 |
sprintf( filename, "%s%s", sysDir, fileBuf.achName );
|
|
Packit |
40b132 |
(*func)(filename);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
numFiles = 1;
|
|
Packit |
40b132 |
rc = DosFindNext( hdir, &fileBuf, buflen, &numFiles );
|
|
Packit |
40b132 |
if( rc != NO_ERROR && rc != ERROR_NO_MORE_FILES )
|
|
Packit |
40b132 |
printf( "DosFindNext errod code = %d\n", rc );
|
|
Packit |
40b132 |
} while ( rc == NO_ERROR );
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rc = DosFindClose(hdir);
|
|
Packit |
40b132 |
if( rc != NO_ERROR )
|
|
Packit |
40b132 |
printf( "DosFindClose error code = %d", rc );
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
else
|
|
Packit |
40b132 |
printf( "DosFindFirst error code = %d", rc );
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return TRUE;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static int dwNumFiles, dwReadEvery, dwFileToRead=0;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static void
|
|
Packit |
40b132 |
CountFiles(const char *file)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
dwNumFiles++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static void
|
|
Packit |
40b132 |
ReadFiles(const char *file)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
if ((dwNumFiles % dwReadEvery) == 0)
|
|
Packit |
40b132 |
RNG_FileForRNG(file);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
dwNumFiles++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static void
|
|
Packit |
40b132 |
ReadSingleFile(const char *filename)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
unsigned char buffer[1024];
|
|
Packit |
40b132 |
FILE *file;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
file = fopen((char *)filename, "rb");
|
|
Packit |
40b132 |
if (file != NULL) {
|
|
Packit |
40b132 |
while (fread(buffer, 1, sizeof(buffer), file) > 0)
|
|
Packit |
40b132 |
;
|
|
Packit |
40b132 |
fclose(file);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static void
|
|
Packit |
40b132 |
ReadOneFile(const char *file)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
if (dwNumFiles == dwFileToRead) {
|
|
Packit |
40b132 |
ReadSingleFile(file);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
dwNumFiles++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static void
|
|
Packit |
40b132 |
ReadSystemFiles(void)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
// first count the number of files
|
|
Packit |
40b132 |
dwNumFiles = 0;
|
|
Packit |
40b132 |
if (!EnumSystemFiles(CountFiles))
|
|
Packit |
40b132 |
return;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
// now read 10 files
|
|
Packit |
40b132 |
if (dwNumFiles == 0)
|
|
Packit |
40b132 |
return;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
dwReadEvery = dwNumFiles / 10;
|
|
Packit |
40b132 |
if (dwReadEvery == 0)
|
|
Packit |
40b132 |
dwReadEvery = 1; // less than 10 files
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
dwNumFiles = 0;
|
|
Packit |
40b132 |
EnumSystemFiles(ReadFiles);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
void RNG_SystemInfoForRNG(void)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
unsigned long *plong = 0;
|
|
Packit |
40b132 |
PTIB ptib;
|
|
Packit |
40b132 |
PPIB ppib;
|
|
Packit |
40b132 |
APIRET rc = NO_ERROR;
|
|
Packit |
40b132 |
DATETIME dt;
|
|
Packit |
40b132 |
COUNTRYCODE cc = {0};
|
|
Packit |
40b132 |
COUNTRYINFO ci = {0};
|
|
Packit |
40b132 |
unsigned long actual = 0;
|
|
Packit |
40b132 |
char path[_MAX_PATH]="";
|
|
Packit |
40b132 |
char fullpath[_MAX_PATH]="";
|
|
Packit |
40b132 |
unsigned long pathlength = sizeof(path);
|
|
Packit |
40b132 |
FSALLOCATE fsallocate;
|
|
Packit |
40b132 |
FILESTATUS3 fstatus;
|
|
Packit |
40b132 |
unsigned long defaultdrive = 0;
|
|
Packit |
40b132 |
unsigned long logicaldrives = 0;
|
|
Packit |
40b132 |
unsigned long sysInfo[QSV_MAX] = {0};
|
|
Packit |
40b132 |
char buffer[20];
|
|
Packit |
40b132 |
int nBytes = 0;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
nBytes = RNG_GetNoise(buffer, sizeof(buffer));
|
|
Packit |
40b132 |
RNG_RandomUpdate(buffer, nBytes);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* allocate memory and use address and memory */
|
|
Packit |
40b132 |
plong = (unsigned long *)malloc(sizeof(*plong));
|
|
Packit |
40b132 |
RNG_RandomUpdate(&plong, sizeof(plong));
|
|
Packit |
40b132 |
RNG_RandomUpdate(plong, sizeof(*plong));
|
|
Packit |
40b132 |
free(plong);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* process info */
|
|
Packit |
40b132 |
rc = DosGetInfoBlocks(&ptib, &ppib);
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(ptib, sizeof(*ptib));
|
|
Packit |
40b132 |
RNG_RandomUpdate(ppib, sizeof(*ppib));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* time */
|
|
Packit |
40b132 |
rc = DosGetDateTime(&dt);
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(&dt, sizeof(dt));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* country */
|
|
Packit |
40b132 |
rc = DosQueryCtryInfo(sizeof(ci), &cc, &ci, &actual);
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(&cc, sizeof(cc));
|
|
Packit |
40b132 |
RNG_RandomUpdate(&ci, sizeof(ci));
|
|
Packit |
40b132 |
RNG_RandomUpdate(&actual, sizeof(actual));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* current directory */
|
|
Packit |
40b132 |
rc = DosQueryCurrentDir(0, path, &pathlength);
|
|
Packit |
40b132 |
strcat(fullpath, "\\");
|
|
Packit |
40b132 |
strcat(fullpath, path);
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(fullpath, strlen(fullpath));
|
|
Packit |
40b132 |
// path info
|
|
Packit |
40b132 |
rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus));
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(&fstatus, sizeof(fstatus));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* file system info */
|
|
Packit |
40b132 |
rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate));
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(&fsallocate, sizeof(fsallocate));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* drive info */
|
|
Packit |
40b132 |
rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives);
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive));
|
|
Packit |
40b132 |
RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* system info */
|
|
Packit |
40b132 |
rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG)*QSV_MAX);
|
|
Packit |
40b132 |
if (rc == NO_ERROR)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
RNG_RandomUpdate(&sysInfo, sizeof(sysInfo));
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
// now let's do some files
|
|
Packit |
40b132 |
ReadSystemFiles();
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* more noise */
|
|
Packit |
40b132 |
nBytes = RNG_GetNoise(buffer, sizeof(buffer));
|
|
Packit |
40b132 |
RNG_RandomUpdate(buffer, nBytes);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
void RNG_FileForRNG(const char *filename)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
struct stat stat_buf;
|
|
Packit |
40b132 |
unsigned char buffer[1024];
|
|
Packit |
40b132 |
FILE *file = 0;
|
|
Packit |
40b132 |
int nBytes = 0;
|
|
Packit |
40b132 |
static int totalFileBytes = 0;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (stat((char *)filename, &stat_buf) < 0)
|
|
Packit |
40b132 |
return;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf));
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
file = fopen((char *)filename, "r");
|
|
Packit |
40b132 |
if (file != NULL)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
for (;;)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
size_t bytes = fread(buffer, 1, sizeof(buffer), file);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (bytes == 0)
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
RNG_RandomUpdate(buffer, bytes);
|
|
Packit |
40b132 |
totalFileBytes += bytes;
|
|
Packit |
40b132 |
if (totalFileBytes > 250000)
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
fclose(file);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
nBytes = RNG_GetNoise(buffer, 20);
|
|
Packit |
40b132 |
RNG_RandomUpdate(buffer, nBytes);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static void rng_systemJitter(void)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
dwNumFiles = 0;
|
|
Packit |
40b132 |
EnumSystemFiles(ReadOneFile);
|
|
Packit |
40b132 |
dwFileToRead++;
|
|
Packit |
40b132 |
if (dwFileToRead >= dwNumFiles) {
|
|
Packit |
40b132 |
dwFileToRead = 0;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
size_t RNG_SystemRNG(void *dest, size_t maxLen)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
return rng_systemFromNoise(dest,maxLen);
|
|
Packit |
40b132 |
}
|