summaryrefslogtreecommitdiff
path: root/security/nss/lib/freebl/unix_rand.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/freebl/unix_rand.c')
-rw-r--r--security/nss/lib/freebl/unix_rand.c44
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);
}