/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <openssl/crypto.h>
#include <openssl/rand.h>
+#include <openssl/rand_drbg.h>
#include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS
# define S_ISREG(m) ((m) & S_IFREG)
# endif
-#define RAND_FILE_SIZE 1024
+#define RAND_BUF_SIZE 1024
#define RFILE ".rnd"
#ifdef OPENSSL_SYS_VMS
*/
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
struct stat sb;
#endif
if (fstat(fileno(in), &sb) < 0) {
RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_INTERNAL_ERROR);
ERR_add_error_data(2, "Filename=", file);
+ fclose(in);
return -1;
}
- if (!S_ISREG(sb.st_mode) && bytes < 0)
- bytes = 256;
+ if (bytes < 0) {
+ if (S_ISREG(sb.st_mode))
+ bytes = sb.st_size;
+ else
+ bytes = RAND_DRBG_STRENGTH;
+ }
#endif
/*
* On VMS, setbuf() will only take 32-bit pointers, and a compilation
for ( ; ; ) {
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
- n = RAND_FILE_SIZE;
+ n = RAND_LOAD_BUF_SIZE;
i = fread(buf, 1, n, in);
#ifdef EINTR
if (ferror(in) && errno == EINTR){
OPENSSL_cleanse(buf, sizeof(buf));
fclose(in);
+ if (!RAND_status()) {
+ RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_RESEED_ERROR);
+ ERR_add_error_data(2, "Filename=", file);
+ return -1;
+ }
+
return ret;
}
int RAND_write_file(const char *file)
{
- unsigned char buf[RAND_FILE_SIZE];
+ unsigned char buf[RAND_BUF_SIZE];
int ret = -1;
FILE *out = NULL;
#ifndef OPENSSL_NO_POSIX_IO
#endif
/* Collect enough random data. */
- if (RAND_bytes(buf, (int)sizeof(buf)) != 1)
+ if (RAND_priv_bytes(buf, (int)sizeof(buf)) != 1)
return -1;
#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && \
chmod(file, 0600);
#endif
- ret = fwrite(buf, 1, RAND_FILE_SIZE, out);
+ ret = fwrite(buf, 1, RAND_BUF_SIZE, out);
fclose(out);
- OPENSSL_cleanse(buf, RAND_FILE_SIZE);
+ OPENSSL_cleanse(buf, RAND_BUF_SIZE);
return ret;
}
size_t len;
int use_randfile = 1;
-#if defined(_WIN32) && defined(CP_UTF8)
+#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE)
DWORD envlen;
WCHAR *var;
}
}
#else
- if (OPENSSL_issetugid() != 0) {
- use_randfile = 0;
- } else if ((s = getenv("RANDFILE")) == NULL || *s == '\0') {
+ if ((s = ossl_safe_getenv("RANDFILE")) == NULL || *s == '\0') {
use_randfile = 0;
- s = getenv("HOME");
+ s = ossl_safe_getenv("HOME");
}
#endif