提交 1d0671b8 编写于 作者: D Dr. Matthias St. Pierre

RAND_load_file(): avoid adding small chunks to RAND_add()

Increase the load buffer size such that it exceeds the chunk
size by a comfortable amount. This is done to avoid calling
RAND_add() with a small final chunk. Instead, such a small
final chunk will be added together with the previous chunk
(unless it's the only one).

Related-to: #7449
Reviewed-by: NPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7456)
上级 13ce8625
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/buffer.h> #include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS #ifdef OPENSSL_SYS_VMS
...@@ -48,7 +49,7 @@ ...@@ -48,7 +49,7 @@
# define S_ISREG(m) ((m) & S_IFREG) # define S_ISREG(m) ((m) & S_IFREG)
# endif # endif
#define RAND_FILE_SIZE 1024 #define RAND_BUF_SIZE 1024
#define RFILE ".rnd" #define RFILE ".rnd"
#ifdef OPENSSL_SYS_VMS #ifdef OPENSSL_SYS_VMS
...@@ -74,7 +75,16 @@ static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) = ...@@ -74,7 +75,16 @@ static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) =
*/ */
int RAND_load_file(const char *file, long bytes) int RAND_load_file(const char *file, long bytes)
{ {
unsigned char buf[RAND_FILE_SIZE]; /*
* The load buffer size exceeds the chunk size by the comfortable amount
* of 'RAND_DRBG_STRENGTH' bytes (not bits!). This is done on purpose
* to avoid calling RAND_add() with a small final chunk. Instead, such
* a small final chunk will be added together with the previous chunk
* (unless it's the only one).
*/
#define RAND_LOAD_BUF_SIZE (RAND_BUF_SIZE + RAND_DRBG_STRENGTH)
unsigned char buf[RAND_LOAD_BUF_SIZE];
#ifndef OPENSSL_NO_POSIX_IO #ifndef OPENSSL_NO_POSIX_IO
struct stat sb; struct stat sb;
#endif #endif
...@@ -98,8 +108,12 @@ int RAND_load_file(const char *file, long bytes) ...@@ -98,8 +108,12 @@ int RAND_load_file(const char *file, long bytes)
return -1; return -1;
} }
if (!S_ISREG(sb.st_mode) && bytes < 0) if (bytes < 0) {
bytes = 256; if (S_ISREG(sb.st_mode))
bytes = (sb.st_size <= LONG_MAX) ? sb.st_size : LONG_MAX;
else
bytes = RAND_DRBG_STRENGTH;
}
#endif #endif
/* /*
* On VMS, setbuf() will only take 32-bit pointers, and a compilation * On VMS, setbuf() will only take 32-bit pointers, and a compilation
...@@ -124,9 +138,9 @@ int RAND_load_file(const char *file, long bytes) ...@@ -124,9 +138,9 @@ int RAND_load_file(const char *file, long bytes)
for ( ; ; ) { for ( ; ; ) {
if (bytes > 0) if (bytes > 0)
n = (bytes < RAND_FILE_SIZE) ? (int)bytes : RAND_FILE_SIZE; n = (bytes <= RAND_LOAD_BUF_SIZE) ? (int)bytes : RAND_BUF_SIZE;
else else
n = RAND_FILE_SIZE; n = RAND_LOAD_BUF_SIZE;
i = fread(buf, 1, n, in); i = fread(buf, 1, n, in);
#ifdef EINTR #ifdef EINTR
if (ferror(in) && errno == EINTR){ if (ferror(in) && errno == EINTR){
...@@ -159,7 +173,7 @@ int RAND_load_file(const char *file, long bytes) ...@@ -159,7 +173,7 @@ int RAND_load_file(const char *file, long bytes)
int RAND_write_file(const char *file) int RAND_write_file(const char *file)
{ {
unsigned char buf[RAND_FILE_SIZE]; unsigned char buf[RAND_BUF_SIZE];
int ret = -1; int ret = -1;
FILE *out = NULL; FILE *out = NULL;
#ifndef OPENSSL_NO_POSIX_IO #ifndef OPENSSL_NO_POSIX_IO
...@@ -228,9 +242,9 @@ int RAND_write_file(const char *file) ...@@ -228,9 +242,9 @@ int RAND_write_file(const char *file)
chmod(file, 0600); chmod(file, 0600);
#endif #endif
ret = fwrite(buf, 1, RAND_FILE_SIZE, out); ret = fwrite(buf, 1, RAND_BUF_SIZE, out);
fclose(out); fclose(out);
OPENSSL_cleanse(buf, RAND_FILE_SIZE); OPENSSL_cleanse(buf, RAND_BUF_SIZE);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册