diff options
Diffstat (limited to 'security/nss/lib/freebl/unix_rand.c')
-rw-r--r-- | security/nss/lib/freebl/unix_rand.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c index 12b08aea3..512964154 100644 --- a/security/nss/lib/freebl/unix_rand.c +++ b/security/nss/lib/freebl/unix_rand.c @@ -43,6 +43,7 @@ #include <assert.h> #include "secrng.h" +size_t RNG_FileUpdate(const char *fileName, size_t limit); /* * When copying data to the buffer we want the least signicant bytes @@ -726,10 +727,10 @@ void RNG_SystemInfoForRNG(void) FILE *fp; char buf[BUFSIZ]; size_t bytes; - extern char **environ; - char **cp; + extern const char * const * const environ; + const char * const *cp; char *randfile; - char *files[] = { + static const char * const files[] = { "/etc/passwd", "/etc/utmp", "/tmp", @@ -788,6 +789,9 @@ for the small amount of entropy it provides. } GiveSystemInfo(); + /* grab some data from system's PRNG before any other files. */ + RNG_FileUpdate("/dev/urandom", 1024); + /* If the user points us to a random file, pass it through the rng */ randfile = getenv("NSRANDFILE"); if ( ( randfile != NULL ) && ( randfile[0] != '\0') ) { @@ -859,26 +863,36 @@ void RNG_SystemInfoForRNG(void) } #endif -void RNG_FileForRNG(char *fileName) +#define TOTAL_FILE_LIMIT 1000000 /* one million */ + +size_t RNG_FileUpdate(const char *fileName, size_t limit) { - struct stat stat_buf; + FILE * file; + size_t bytes; + size_t fileBytes = 0; + struct stat stat_buf; unsigned char buffer[BUFSIZ]; - size_t bytes; - FILE *file; static size_t totalFileBytes = 0; if (stat((char *)fileName, &stat_buf) < 0) - return; + return fileBytes; RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); file = fopen((char *)fileName, "r"); if (file != NULL) { - for (;;) { - bytes = fread(buffer, 1, sizeof(buffer), file); - if (bytes == 0) break; + 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; - if (totalFileBytes > 1024*1024) break; + /* 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); } @@ -888,4 +902,10 @@ void RNG_FileForRNG(char *fileName) */ bytes = RNG_GetNoise(buffer, sizeof(buffer)); RNG_RandomUpdate(buffer, bytes); + return fileBytes; +} + +void RNG_FileForRNG(const char *fileName) +{ + RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); } |