void RNG_FileForRNG(const char *filename) { struct stat stat_buf; unsigned char buffer[1024]; FILE *file = 0; int nBytes = 0; static int totalFileBytes = 0; if (stat((char *)filename, &stat_buf) < 0) return; RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf)); file = fopen((char *)filename, "r"); if (file != NULL) { for (;;) { size_t bytes = fread(buffer, 1, sizeof(buffer), file); if (bytes == 0) break; RNG_RandomUpdate(buffer, bytes); totalFileBytes += bytes; if (totalFileBytes > 250000) break; } fclose(file); } nBytes = RNG_GetNoise(buffer, 20); RNG_RandomUpdate(buffer, nBytes); }
void RNG_FileForRNG(const char *filename) { PRFileDesc * file; int nBytes; PRFileInfo infoBuf; unsigned char buffer[1024]; if (PR_GetFileInfo(filename, &infoBuf) != PR_SUCCESS) return; RNG_RandomUpdate((unsigned char*)&infoBuf, sizeof(infoBuf)); file = PR_Open(filename, PR_RDONLY, 0); if (file != NULL) { for (;;) { PRInt32 bytes = PR_Read(file, buffer, sizeof buffer); if (bytes <= 0) break; RNG_RandomUpdate(buffer, bytes); totalFileBytes += bytes; if (totalFileBytes > maxFileBytes) break; } PR_Close(file); } nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes RNG_RandomUpdate(buffer, nBytes); }
void RNG_SystemInfoForRNG(void) { FILE *fp; char buf[BUFSIZ]; size_t bytes; int extra; char **cp; extern char **environ; char *randfile; GiveSystemInfo(); bytes = RNG_GetNoise(buf, sizeof(buf)); RNG_RandomUpdate(buf, bytes); /* * Pass the C environment and the addresses of the pointers to the * hash function. This makes the random number function depend on the * execution environment of the user and on the platform the program * is running on. */ cp = environ; while (*cp) { RNG_RandomUpdate(*cp, strlen(*cp)); cp++; } RNG_RandomUpdate(environ, (char*)cp - (char*)environ); /* Give in system information */ if (gethostname(buf, sizeof(buf)) > 0) { RNG_RandomUpdate(buf, strlen(buf)); } GiveSystemInfo(); /* If the user points us to a random file, pass it through the rng */ randfile = getenv("NSRANDFILE"); if ( ( randfile != NULL ) && ( randfile[0] != '\0') ) { RNG_FileForRNG(randfile); } /* ** We need to generate at least 1024 bytes of seed data. Since we don't ** do the file stuff for VMS, and because the environ list is so short ** on VMS, we need to make sure we generate enough. So do another 1000 ** bytes to be sure. */ extra = 1000; while (extra > 0) { cp = environ; while (*cp) { int n = strlen(*cp); RNG_RandomUpdate(*cp, n); extra -= n; cp++; } } }
static void GiveSystemInfo(void) { long si; /* This is not very good */ si = sysconf(_AES_OS_VERSION); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_CPU_VERSION); RNG_RandomUpdate(&si, sizeof(si)); }
size_t RNG_FileUpdate(const char *fileName, size_t limit) { FILE * file; int fd; int bytes; size_t fileBytes = 0; struct stat stat_buf; unsigned char buffer[BUFSIZ]; static size_t totalFileBytes = 0; /* suppress valgrind warnings due to holes in struct stat */ memset(&stat_buf, 0, sizeof(stat_buf)); if (stat((char *)fileName, &stat_buf) < 0) return fileBytes; RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); file = fopen(fileName, "r"); if (file != NULL) { /* Read from the underlying file descriptor directly to bypass stdio * buffering and avoid reading more bytes than we need from * /dev/urandom. NOTE: we can't use fread with unbuffered I/O because * fread may return EOF in unbuffered I/O mode on Android. * * Moreover, we read into a buffer of size BUFSIZ, so buffered I/O * has no performance advantage. */ fd = fileno(file); /* 'file' was just opened, so this should not fail. */ PORT_Assert(fd != -1); while (limit > fileBytes && fd != -1) { bytes = PR_MIN(sizeof buffer, limit - fileBytes); bytes = read(fd, buffer, bytes); if (bytes <= 0) break; RNG_RandomUpdate(buffer, bytes); fileBytes += bytes; totalFileBytes += bytes; /* after TOTAL_FILE_LIMIT has been reached, only read in first ** buffer of data from each subsequent file. */ if (totalFileBytes > TOTAL_FILE_LIMIT) break; } fclose(file); } /* * Pass yet another snapshot of our highest resolution clock into * the hash function. */ bytes = RNG_GetNoise(buffer, sizeof(buffer)); RNG_RandomUpdate(buffer, bytes); return fileBytes; }
/* Buffer entropy data, and feed it to the RNG, entropy_buf_len bytes at a time. * Returns error if RNG_RandomUpdate fails. Also increments *total_fed * by the number of bytes successfully buffered. */ static SECStatus BufferEntropy(char* inbuf, PRUint32 inlen, char* entropy_buf, PRUint32* entropy_buffered, PRUint32* total_fed) { PRUint32 tocopy = 0; PRUint32 avail = 0; SECStatus rv = SECSuccess; while (inlen) { avail = entropy_buf_len - *entropy_buffered; if (!avail) { /* Buffer is full, time to feed it to the RNG. */ rv = RNG_RandomUpdate(entropy_buf, entropy_buf_len); if (SECSuccess != rv) { break; } *entropy_buffered = 0; avail = entropy_buf_len; } tocopy = PR_MIN(avail, inlen); memcpy(entropy_buf + *entropy_buffered, inbuf, tocopy); *entropy_buffered += tocopy; inlen -= tocopy; inbuf += tocopy; *total_fed += tocopy; } return rv; }
static void GiveSystemInfo(void) { struct sysinfo si; if (sysinfo(&si) == 0) { RNG_RandomUpdate(&si, sizeof(si)); } }
static void GiveSystemInfo(void) { long si; /* * Is this really necessary? Why not use rand48 or something? */ si = sysconf(_SC_CHILD_MAX); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_STREAM_MAX); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_OPEN_MAX); RNG_RandomUpdate(&si, sizeof(si)); }
size_t RNG_FileUpdate(const char *fileName, size_t limit) { FILE * file; size_t bytes; size_t fileBytes = 0; struct stat stat_buf; unsigned char buffer[BUFSIZ]; static size_t totalFileBytes = 0; /* suppress valgrind warnings due to holes in struct stat */ memset(&stat_buf, 0, sizeof(stat_buf)); if (stat((char *)fileName, &stat_buf) < 0) return fileBytes; RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); file = fopen(fileName, "r"); if (file != NULL) { /* Set buffering mode to unbuffered I/O to avoid reading more bytes * than we need from /dev/urandom. Moreover, we read into a buffer * of size BUFSIZ, so buffered I/O has no performance advantage. */ setvbuf(file, NULL, _IONBF, 0); while (limit > fileBytes) { bytes = PR_MIN(sizeof buffer, limit - fileBytes); bytes = fread(buffer, 1, bytes, file); if (bytes == 0) break; RNG_RandomUpdate(buffer, bytes); fileBytes += bytes; totalFileBytes += bytes; /* after TOTAL_FILE_LIMIT has been reached, only read in first ** buffer of data from each subsequent file. */ if (totalFileBytes > TOTAL_FILE_LIMIT) break; } fclose(file); } /* * Pass yet another snapshot of our highest resolution clock into * the hash function. */ bytes = RNG_GetNoise(buffer, sizeof(buffer)); RNG_RandomUpdate(buffer, bytes); return fileBytes; }
/* Feed kernel statistics structures and ks_data field to the RNG. * Returns status as well as the number of bytes successfully fed to the RNG. */ static SECStatus RNG_kstat(PRUint32* fed) { kstat_ctl_t* kc = NULL; kstat_t* ksp = NULL; PRUint32 entropy_buffered = 0; char* entropy_buf = NULL; SECStatus rv = SECSuccess; PORT_Assert(fed); if (!fed) { return SECFailure; } *fed = 0; kc = kstat_open(); PORT_Assert(kc); if (!kc) { return SECFailure; } entropy_buf = (char*) PORT_Alloc(entropy_buf_len); PORT_Assert(entropy_buf); if (entropy_buf) { for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { if (-1 == kstat_read(kc, ksp, NULL)) { /* missing data from a single kstat shouldn't be fatal */ continue; } rv = BufferEntropy((char*)ksp, sizeof(kstat_t), entropy_buf, &entropy_buffered, fed); if (SECSuccess != rv) { break; } if (ksp->ks_data && ksp->ks_data_size>0 && ksp->ks_ndata>0) { rv = BufferEntropy((char*)ksp->ks_data, ksp->ks_data_size, entropy_buf, &entropy_buffered, fed); if (SECSuccess != rv) { break; } } } if (SECSuccess == rv && entropy_buffered) { /* Buffer is not empty, time to feed it to the RNG */ rv = RNG_RandomUpdate(entropy_buf, entropy_buffered); } PORT_Free(entropy_buf); } else { rv = SECFailure; } if (kstat_close(kc)) { PORT_Assert(0); rv = SECFailure; } return rv; }
static void GiveSystemInfo(void) { long si; /* This is not very good */ si = sysconf(_SC_CHILD_MAX); RNG_RandomUpdate(&si, sizeof(si)); }
static void GiveSystemInfo(void) { long si; /* * This is copied from the SCO/UNIXWARE etc section. And like the comment * there says, what's the point? This isn't random, it generates the same * stuff every time its run! */ si = sysconf(_SC_CHILD_MAX); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_STREAM_MAX); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_OPEN_MAX); RNG_RandomUpdate(&si, sizeof(si)); }
static void GiveSystemInfo(void) { int rv; char buf[2000]; rv = sysinfo(SI_MACHINE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } }
static void GiveSystemInfo(void) { system_info *info = NULL; PRInt32 val; get_system_info(info); if (info) { val = info->boot_time; RNG_RandomUpdate(&val, sizeof(val)); val = info->used_pages; RNG_RandomUpdate(&val, sizeof(val)); val = info->used_ports; RNG_RandomUpdate(&val, sizeof(val)); val = info->used_threads; RNG_RandomUpdate(&val, sizeof(val)); val = info->used_teams; RNG_RandomUpdate(&val, sizeof(val)); } }
static void GiveSystemInfo(void) { #ifndef NO_SYSINFO struct sysinfo si; if (sysinfo(&si) == 0) { RNG_RandomUpdate(&si, sizeof(si)); } #endif }
size_t RNG_FileUpdate(const char *fileName, size_t limit) { FILE * file; size_t bytes; size_t fileBytes = 0; struct stat stat_buf; unsigned char buffer[BUFSIZ]; static size_t totalFileBytes = 0; /* suppress valgrind warnings due to holes in struct stat */ memset(&stat_buf, 0, sizeof(stat_buf)); if (stat((char *)fileName, &stat_buf) < 0) return fileBytes; RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); file = fopen((char *)fileName, "r"); if (file != NULL) { while (limit > fileBytes) { bytes = PR_MIN(sizeof buffer, limit - fileBytes); bytes = fread(buffer, 1, bytes, file); if (bytes == 0) break; RNG_RandomUpdate(buffer, bytes); fileBytes += bytes; totalFileBytes += bytes; /* after TOTAL_FILE_LIMIT has been reached, only read in first ** buffer of data from each subsequent file. */ if (totalFileBytes > TOTAL_FILE_LIMIT) break; } fclose(file); } /* * Pass yet another snapshot of our highest resolution clock into * the hash function. */ bytes = RNG_GetNoise(buffer, sizeof(buffer)); RNG_RandomUpdate(buffer, bytes); return fileBytes; }
static void GiveSystemInfo(void) { int rv; char buf[4096]; rv = syssgi(SGI_SYSID, &buf[0]); if (rv > 0) { RNG_RandomUpdate(buf, MAXSYSIDSIZE); } #ifdef SGI_RDUBLK rv = syssgi(SGI_RDUBLK, getpid(), &buf[0], sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, sizeof(buf)); } #endif /* SGI_RDUBLK */ rv = syssgi(SGI_INVENT, SGI_INV_READ, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, sizeof(buf)); } rv = sysinfo(SI_MACHINE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } }
void RNG_FileForRNG(const char *filename) { FILE* file; int nBytes; struct stat stat_buf; unsigned char buffer[1024]; /* windows doesn't initialize all the bytes in the stat buf, * so initialize them all here to avoid UMRs. */ memset(&stat_buf, 0, sizeof stat_buf); if (stat((char *)filename, &stat_buf) < 0) return; RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf)); file = fopen((char *)filename, "r"); if (file != NULL) { for (;;) { size_t bytes = fread(buffer, 1, sizeof(buffer), file); if (bytes == 0) break; RNG_RandomUpdate(buffer, bytes); totalFileBytes += bytes; if (totalFileBytes > maxFileBytes) break; } fclose(file); } nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes RNG_RandomUpdate(buffer, nBytes); }
static void ReadSystemFiles(void) { // first count the number of files dwNumFiles = 0; if (!EnumSystemFiles(CountFiles)) return; RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles)); // now read 10 files if (dwNumFiles == 0) return; dwReadEvery = dwNumFiles / 10; if (dwReadEvery == 0) dwReadEvery = 1; // less than 10 files dwNumFiles = 0; EnumSystemFiles(ReadFiles); }
static void ReadSystemFiles(void) { // first count the number of files dwNumFiles = 0; if (!EnumSystemFiles(CountFiles)) return; RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles)); // now read the first 10 readable files, then 10 or 11 files // spread throughout the system directory filesToRead = 10; if (dwNumFiles == 0) return; dwReadEvery = dwNumFiles / 10; if (dwReadEvery == 0) dwReadEvery = 1; // less than 10 files dwNumFiles = 0; totalFileBytes = 0; EnumSystemFiles(ReadFiles); }
void RNG_SystemInfoForRNG(void) { FILE *fp; char buf[BUFSIZ]; size_t bytes; const char * const *cp; char *randfile; #ifdef DARWIN #if TARGET_OS_IPHONE /* iOS does not expose a way to access environ. */ char **environ = NULL; #else char **environ = *_NSGetEnviron(); #endif #else extern char **environ; #endif #ifdef BEOS static const char * const files[] = { "/boot/var/swap", "/boot/var/log/syslog", "/boot/var/tmp", "/boot/home/config/settings", "/boot/home", 0 }; #else static const char * const files[] = { "/etc/passwd", "/etc/utmp", "/tmp", "/var/tmp", "/usr/tmp", 0 }; #endif #if defined(BSDI) static char netstat_ni_cmd[] = "netstat -nis"; #else static char netstat_ni_cmd[] = "netstat -ni"; #endif GiveSystemInfo(); bytes = RNG_GetNoise(buf, sizeof(buf)); RNG_RandomUpdate(buf, bytes); /* * Pass the C environment and the addresses of the pointers to the * hash function. This makes the random number function depend on the * execution environment of the user and on the platform the program * is running on. */ if (environ != NULL) { cp = (const char * const *) environ; while (*cp) { RNG_RandomUpdate(*cp, strlen(*cp)); cp++; } RNG_RandomUpdate(environ, (char*)cp - (char*)environ); } /* Give in system information */ if (gethostname(buf, sizeof(buf)) == 0) { RNG_RandomUpdate(buf, strlen(buf)); } GiveSystemInfo(); /* grab some data from system's PRNG before any other files. */ bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT); /* If the user points us to a random file, pass it through the rng */ randfile = getenv("NSRANDFILE"); if ( ( randfile != NULL ) && ( randfile[0] != '\0') ) { char *randCountString = getenv("NSRANDCOUNT"); int randCount = randCountString ? atoi(randCountString) : 0; if (randCount != 0) { RNG_FileUpdate(randfile, randCount); } else { RNG_FileForRNG(randfile); } } /* pass other files through */ for (cp = files; *cp; cp++) RNG_FileForRNG(*cp); /* * Bug 100447: On BSD/OS 4.2 and 4.3, we have problem calling safe_popen * in a pthreads environment. Therefore, we call safe_popen last and on * BSD/OS we do not call safe_popen when we succeeded in getting data * from /dev/urandom. * * Bug 174993: On platforms providing /dev/urandom, don't fork netstat * either, if data has been gathered successfully. */ #if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \ || defined(OPENBSD) || defined(DARWIN) || defined(LINUX) \ || defined(HPUX) if (bytes) return; #endif #ifdef SOLARIS /* * On Solaris, NSS may be initialized automatically from libldap in * applications that are unaware of the use of NSS. safe_popen forks, and * sometimes creates issues with some applications' pthread_atfork handlers. * We always have /dev/urandom on Solaris 9 and above as an entropy source, * and for Solaris 8 we have the libkstat interface, so we don't need to * fork netstat. */ #undef DO_NETSTAT if (!bytes) { /* On Solaris 8, /dev/urandom isn't available, so we use libkstat. */ PRUint32 kstat_bytes = 0; if (SECSuccess != RNG_kstat(&kstat_bytes)) { PORT_Assert(0); } bytes += kstat_bytes; PORT_Assert(bytes); } #endif #ifdef DO_NETSTAT fp = safe_popen(netstat_ni_cmd); if (fp != NULL) { while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0) RNG_RandomUpdate(buf, bytes); safe_pclose(fp); } #endif }
void RNG_SystemInfoForRNG(void) { DWORD dwVal; char buffer[256]; int nBytes; MEMORYSTATUS sMem; HANDLE hVal; DWORD dwSerialNum; DWORD dwComponentLen; DWORD dwSysFlags; char volName[128]; DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters; nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes RNG_RandomUpdate(buffer, nBytes); sMem.dwLength = sizeof(sMem); GlobalMemoryStatus(&sMem); // assorted memory stats RNG_RandomUpdate(&sMem, sizeof(sMem)); dwVal = GetLogicalDrives(); RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25 dwVal = sizeof(buffer); if (GetComputerName(buffer, &dwVal)) RNG_RandomUpdate(buffer, dwVal); hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a // constant!) of current process RNG_RandomUpdate(&hVal, sizeof(hVal)); dwVal = GetCurrentProcessId(); // process ID (4 bytes) RNG_RandomUpdate(&dwVal, sizeof(dwVal)); dwVal = GetCurrentThreadId(); // thread ID (4 bytes) RNG_RandomUpdate(&dwVal, sizeof(dwVal)); volName[0] = '\0'; buffer[0] = '\0'; GetVolumeInformation(NULL, volName, sizeof(volName), &dwSerialNum, &dwComponentLen, &dwSysFlags, buffer, sizeof(buffer)); RNG_RandomUpdate(volName, strlen(volName)); RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum)); RNG_RandomUpdate(&dwComponentLen, sizeof(dwComponentLen)); RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags)); RNG_RandomUpdate(buffer, strlen(buffer)); if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters, &dwNumClusters)) { RNG_RandomUpdate(&dwSectors, sizeof(dwSectors)); RNG_RandomUpdate(&dwBytes, sizeof(dwBytes)); RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters)); RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters)); } // Skip the potentially slow file scanning if the OS's PRNG worked. if (!usedWindowsPRNG) ReadSystemFiles(); nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes RNG_RandomUpdate(buffer, nBytes); }
void RNG_SystemInfoForRNG(void) { unsigned long *plong = 0; PTIB ptib; PPIB ppib; APIRET rc = NO_ERROR; DATETIME dt; COUNTRYCODE cc = {0}; COUNTRYINFO ci = {0}; unsigned long actual = 0; char path[_MAX_PATH]=""; char fullpath[_MAX_PATH]=""; unsigned long pathlength = sizeof(path); FSALLOCATE fsallocate; FILESTATUS3 fstatus; unsigned long defaultdrive = 0; unsigned long logicaldrives = 0; unsigned long sysInfo[QSV_MAX] = {0}; char buffer[20]; int nBytes = 0; nBytes = RNG_GetNoise(buffer, sizeof(buffer)); RNG_RandomUpdate(buffer, nBytes); /* allocate memory and use address and memory */ plong = (unsigned long *)malloc(sizeof(*plong)); RNG_RandomUpdate(&plong, sizeof(plong)); RNG_RandomUpdate(plong, sizeof(*plong)); free(plong); /* process info */ rc = DosGetInfoBlocks(&ptib, &ppib); if (rc == NO_ERROR) { RNG_RandomUpdate(ptib, sizeof(*ptib)); RNG_RandomUpdate(ppib, sizeof(*ppib)); } /* time */ rc = DosGetDateTime(&dt); if (rc == NO_ERROR) { RNG_RandomUpdate(&dt, sizeof(dt)); } /* country */ rc = DosQueryCtryInfo(sizeof(ci), &cc, &ci, &actual); if (rc == NO_ERROR) { RNG_RandomUpdate(&cc, sizeof(cc)); RNG_RandomUpdate(&ci, sizeof(ci)); RNG_RandomUpdate(&actual, sizeof(actual)); } /* current directory */ rc = DosQueryCurrentDir(0, path, &pathlength); strcat(fullpath, "\\"); strcat(fullpath, path); if (rc == NO_ERROR) { RNG_RandomUpdate(fullpath, strlen(fullpath)); // path info rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus)); if (rc == NO_ERROR) { RNG_RandomUpdate(&fstatus, sizeof(fstatus)); } } /* file system info */ rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate)); if (rc == NO_ERROR) { RNG_RandomUpdate(&fsallocate, sizeof(fsallocate)); } /* drive info */ rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives); if (rc == NO_ERROR) { RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive)); RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives)); } /* system info */ rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG)*QSV_MAX); if (rc == NO_ERROR) { RNG_RandomUpdate(&sysInfo, sizeof(sysInfo)); } // now let's do some files ReadSystemFiles(); /* more noise */ nBytes = RNG_GetNoise(buffer, sizeof(buffer)); RNG_RandomUpdate(buffer, nBytes); }