[openssl-commits] [openssl] master update

Rich Salz rsalz at openssl.org
Sun Jul 16 23:39:53 UTC 2017


The branch master has been updated
       via  3ee1eac27a2e3120fbdc60e12db091c082b8de21 (commit)
      from  e90fc053c33a2241004451cfdeecfbf3cbdeb728 (commit)


- Log -----------------------------------------------------------------
commit 3ee1eac27a2e3120fbdc60e12db091c082b8de21
Author: Rich Salz <rsalz at openssl.org>
Date:   Wed Jul 5 10:58:48 2017 -0400

    Standardize apps use of -rand, etc.
    
    Standardized the -rand flag and added a new one:
        -rand file...
                Always reads the specified files
        -writerand file
                Always writes to the file on exit
    
    For apps that use a config file, the RANDFILE config parameter reads
    the file at startup (to seed the RNG) and write to it on exit if
    the -writerand flag isn't used.
    
    Ensured that every app that took -rand also took -writerand, and
    made sure all of that agreed with all the documentation.
    
    Fix error reporting in write_file and -rand
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/3862)

-----------------------------------------------------------------------

Summary of changes:
 apps/app_rand.c        | 130 ++++++++++++++++++++-----------------------------
 apps/apps.h            |  29 ++++++-----
 apps/ca.c              |  14 +++---
 apps/cms.c             |  36 +++++---------
 apps/dgst.c            |  18 +++----
 apps/dhparam.c         |  21 +++-----
 apps/dsaparam.c        |  28 +++--------
 apps/ecparam.c         |  29 ++++-------
 apps/enc.c             |   8 ++-
 apps/gendsa.c          |  23 +++------
 apps/genrsa.c          |  24 +++------
 apps/openssl.c         |   1 +
 apps/passwd.c          |   8 ++-
 apps/pkcs12.c          |  24 +++------
 apps/pkcs8.c           |  10 ++--
 apps/pkeyutl.c         |  11 +++--
 apps/rand.c            |  20 +++-----
 apps/req.c             |  29 ++++-------
 apps/rsautl.c          |  11 +++--
 apps/s_client.c        |  25 +++-------
 apps/s_server.c        |  22 +++------
 apps/smime.c           |  34 ++++---------
 apps/speed.c           |   7 ++-
 apps/srp.c             |  19 +++-----
 apps/ts.c              |  25 +++-------
 apps/x509.c            |  21 ++++----
 crypto/rand/randfile.c |   5 +-
 doc/man1/ca.pod        |  19 +++++++-
 doc/man1/cms.pod       |  12 +++--
 doc/man1/dgst.pod      |  10 +++-
 doc/man1/dhparam.pod   |  12 +++--
 doc/man1/dsaparam.pod  |  12 +++--
 doc/man1/ecparam.pod   |  12 +++--
 doc/man1/enc.pod       |  15 ++++++
 doc/man1/gendsa.pod    |  12 +++--
 doc/man1/genrsa.pod    |  12 +++--
 doc/man1/passwd.pod    |  15 ++++++
 doc/man1/pkcs12.pod    |  12 +++--
 doc/man1/pkcs8.pod     |  15 ++++++
 doc/man1/pkeyutl.pod   |  15 ++++++
 doc/man1/rand.pod      |  16 ++++--
 doc/man1/req.pod       |  16 ++++--
 doc/man1/rsautl.pod    |  15 ++++++
 doc/man1/s_client.pod  |  12 +++--
 doc/man1/s_server.pod  |  12 +++--
 doc/man1/smime.pod     |  12 +++--
 doc/man1/speed.pod     |  15 ++++++
 doc/man1/ts.pod        |  18 +++++--
 doc/man1/x509.pod      |  15 ++++++
 49 files changed, 510 insertions(+), 426 deletions(-)

diff --git a/apps/app_rand.c b/apps/app_rand.c
index 21445ac..960d2fe 100644
--- a/apps/app_rand.c
+++ b/apps/app_rand.c
@@ -10,108 +10,82 @@
 #include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/rand.h>
+#include <openssl/conf.h>
 
-static int seeded = 0;
-static int egdsocket = 0;
+static const char *save_rand_file;
 
-int app_RAND_load_file(const char *file, int dont_warn)
+void app_RAND_load_conf(CONF *c, const char *section)
 {
-    int consider_randfile = (file == NULL);
-    char buffer[200];
+    const char *randfile = NCONF_get_string(c, section, "RANDFILE");
 
-    if (file == NULL) {
-        file = RAND_file_name(buffer, sizeof buffer);
-#ifndef OPENSSL_NO_EGD
-    } else if (RAND_egd(file) > 0) {
-        /*
-         * we try if the given filename is an EGD socket. if it is, we don't
-         * write anything back to the file.
-         */
-        egdsocket = 1;
-        return 1;
-#endif
+    if (randfile == NULL) {
+        ERR_clear_error();
+        return;
     }
-
-    if (file == NULL || !RAND_load_file(file, -1)) {
-        if (RAND_status() == 0) {
-            if (!dont_warn) {
-                BIO_printf(bio_err, "unable to load 'random state'\n");
-                BIO_printf(bio_err,
-                           "This means that the random number generator has not been seeded\n");
-                BIO_printf(bio_err, "with much random data.\n");
-                if (consider_randfile) { /* explanation does not apply when a
-                                          * file is explicitly named */
-                    BIO_printf(bio_err,
-                               "Consider setting the RANDFILE environment variable to point at a file that\n");
-                    BIO_printf(bio_err,
-                               "'random' data can be kept in (the file will be overwritten).\n");
-                }
-            }
-            return 0;
-        }
+    if (RAND_load_file(randfile, -1) < 0) {
+        BIO_printf(bio_err, "Can't load %s into RNG\n", randfile);
+        ERR_print_errors(bio_err);
+        return;
     }
-    seeded = 1;
-    return 1;
+    if (save_rand_file == NULL)
+        save_rand_file = randfile;
 }
 
-long app_RAND_load_files(char *name)
+static int loadfiles(char *name)
 {
     char *p, *n;
-    int last;
-    long tot = 0;
-#ifndef OPENSSL_NO_EGD
-    int egd;
-#endif
+    int last, ret = 1;
 
-    for (;;) {
+    for ( ; ; ) {
         last = 0;
-        for (p = name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++) ;
+        for (p = name; *p != '\0' && *p != LIST_SEPARATOR_CHAR; p++)
+            continue;
         if (*p == '\0')
             last = 1;
         *p = '\0';
+        if (RAND_load_file(name, -1) < 0) {
+            BIO_printf(bio_err, "Can't load %s into RNG\n", name);
+            ERR_print_errors(bio_err);
+            ret = 0;
+        }
         n = name;
-        name = p + 1;
-        if (*n == '\0')
-            break;
-
-#ifndef OPENSSL_NO_EGD
-        egd = RAND_egd(n);
-        if (egd > 0)
-            tot += egd;
-        else
-#endif
-            tot += RAND_load_file(n, -1);
         if (last)
             break;
+        name = p + 1;
+        if (*name == '\0')
+            break;
     }
-    if (tot > 512)
-        app_RAND_allow_write_file();
-    return (tot);
+    return ret;
 }
 
-int app_RAND_write_file(const char *file)
+void app_RAND_write(void)
 {
-    char buffer[200];
-
-    if (egdsocket || !seeded) {
-        /*
-         * If we didn't manage to read the seed file, don't write a
-         * file out -- it would suppress a crucial warning the next
-         * time we want to use it.
-         */
-        return 0;
+    if (save_rand_file == NULL)
+        return;
+    if (RAND_write_file(save_rand_file) == -1) {
+        BIO_printf(bio_err, "Cannot write random bytes:\n");
+        ERR_print_errors(bio_err);
     }
-
-    if (file == NULL)
-        file = RAND_file_name(buffer, sizeof buffer);
-    if (file == NULL || !RAND_write_file(file)) {
-        BIO_printf(bio_err, "unable to write 'random state'\n");
-        return 0;
-    }
-    return 1;
 }
 
-void app_RAND_allow_write_file(void)
+
+/*
+ * See comments in opt_verify for explanation of this.
+ */
+enum r_range { OPT_R_ENUM };
+
+int opt_rand(int opt)
 {
-    seeded = 1;
+    switch ((enum r_range)opt) {
+    case OPT_R__FIRST:
+    case OPT_R__LAST:
+        break;
+    case OPT_R_RAND:
+        return loadfiles(opt_arg());
+        break;
+    case OPT_R_WRITERAND:
+        save_rand_file = opt_arg();
+        break;
+    }
+    return 1;
 }
diff --git a/apps/apps.h b/apps/apps.h
index 09c601b..aa3cd3f 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -40,16 +40,8 @@
  */
 #define _UC(c) ((unsigned char)(c))
 
-int app_RAND_load_file(const char *file, int dont_warn);
-int app_RAND_write_file(const char *file);
-/*
- * When `file' is NULL, use defaults. `bio_e' is for error messages.
- */
-void app_RAND_allow_write_file(void);
-long app_RAND_load_files(char *file); /* `file' is a list of files to read,
-                                       * separated by LIST_SEPARATOR_CHAR
-                                       * (see e_os.h).  The string is
-                                       * destroyed! */
+void app_RAND_load_conf(CONF *c, const char *section);
+void app_RAND_write(void);
 
 extern char *default_config_file;
 extern BIO *bio_in;
@@ -177,7 +169,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
         case OPT_V_ALLOW_PROXY_CERTS
 
 /*
- * Common "extended"? options.
+ * Common "extended validation" options.
  */
 # define OPT_X_ENUM \
         OPT_X__FIRST=1000, \
@@ -300,6 +292,20 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
   || o == OPT_S_NOTLS1_2 || o == OPT_S_NOTLS1_3)
 
 /*
+ * Random state options.
+ */
+# define OPT_R_ENUM \
+        OPT_R__FIRST=1500, OPT_R_RAND, OPT_R_WRITERAND, OPT_R__LAST
+
+# define OPT_R_OPTIONS \
+    {"rand", OPT_R_RAND, 's', "Load the file(s) into the random number generator"}, \
+    {"writerand", OPT_R_WRITERAND, '>', "Write random data to the specified file"}
+
+# define OPT_R_CASES \
+        OPT_R__FIRST: case OPT_R__LAST: break; \
+        case OPT_R_RAND: case OPT_R_WRITERAND
+
+/*
  * Option parsing.
  */
 extern const char OPT_HELP_STR[];
@@ -373,6 +379,7 @@ char *opt_reset(void);
 char **opt_rest(void);
 int opt_num_rest(void);
 int opt_verify(int i, X509_VERIFY_PARAM *vpm);
+int opt_rand(int i);
 void opt_help(const OPTIONS * list);
 int opt_format_error(const char *s, unsigned long flags);
 
diff --git a/apps/ca.c b/apps/ca.c
index 91d962f..c1c2c49 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -153,6 +153,7 @@ typedef enum OPTION_choice {
     OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
     OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
     OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
+    OPT_R_ENUM,
     /* Do not change the order here; see related case statements below */
     OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
 } OPTION_CHOICE;
@@ -217,6 +218,7 @@ const OPTIONS ca_options[] = {
      "sets compromise time to val and the revocation reason to keyCompromise"},
     {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
      "sets compromise time to val and the revocation reason to CACompromise"},
+    OPT_R_OPTIONS,
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 #endif
@@ -247,7 +249,7 @@ int ca_main(int argc, char **argv)
     char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
     const char *serialfile = NULL, *subj = NULL;
     char *prog, *startdate = NULL, *enddate = NULL;
-    char *dbfile = NULL, *f, *randfile = NULL;
+    char *dbfile = NULL, *f;
     char new_cert[CERT_MAX + 1];
     char tmp[10 + 1] = "\0";
     char *const *pp;
@@ -332,6 +334,10 @@ opthelp:
         case OPT_PASSIN:
             passinarg = opt_arg();
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         case OPT_KEY:
             key = opt_arg();
             break;
@@ -465,10 +471,7 @@ end_of_options:
         }
     }
 
-    randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
-    if (randfile == NULL)
-        ERR_clear_error();
-    app_RAND_load_file(randfile, 0);
+    app_RAND_load_conf(conf, BASE_SECTION);
 
     f = NCONF_get_string(conf, section, STRING_MASK);
     if (f == NULL)
@@ -1220,7 +1223,6 @@ end_of_options:
 
     if (ret)
         ERR_print_errors(bio_err);
-    app_RAND_write_file(randfile);
     if (free_key)
         OPENSSL_free(key);
     BN_free(serial);
diff --git a/apps/cms.c b/apps/cms.c
index 25ee7e8..543d013 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -76,10 +76,11 @@ typedef enum OPTION_choice {
     OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE,
     OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT,
     OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE,
-    OPT_RAND, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
+    OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
     OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM,
     OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP,
     OPT_3DES_WRAP, OPT_ENGINE,
+    OPT_R_ENUM,
     OPT_V_ENUM,
     OPT_CIPHER
 } OPTION_CHOICE;
@@ -152,8 +153,6 @@ const OPTIONS cms_options[] = {
     {"secretkeyid", OPT_SECRETKEYID, 's'},
     {"pwri_password", OPT_PWRI_PASSWORD, 's'},
     {"econtent_type", OPT_ECONTENT_TYPE, 's'},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
     {"to", OPT_TO, 's', "To address"},
     {"from", OPT_FROM, 's', "From address"},
@@ -169,6 +168,7 @@ const OPTIONS cms_options[] = {
     {"receipt_request_from", OPT_RR_FROM, 's'},
     {"receipt_request_to", OPT_RR_TO, 's'},
     {"", OPT_CIPHER, '-', "Any supported cipher"},
+    OPT_R_OPTIONS,
     OPT_V_OPTIONS,
     {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"},
     {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"},
@@ -202,16 +202,13 @@ int cms_main(int argc, char **argv)
     const char *CAfile = NULL, *CApath = NULL;
     char *certsoutfile = NULL;
     int noCAfile = 0, noCApath = 0;
-    char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL;
-    char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile =
-        NULL;
+    char *infile = NULL, *outfile = NULL, *rctfile = NULL;
+    char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL;
     char *to = NULL, *from = NULL, *subject = NULL, *prog;
     cms_key_param *key_first = NULL, *key_param = NULL;
-    int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched =
-        0;
+    int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0;
     int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
-    int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst =
-        -1;
+    int operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1;
     int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
     size_t secret_keylen = 0, secret_keyidlen = 0;
     unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
@@ -449,10 +446,6 @@ int cms_main(int argc, char **argv)
                 goto opthelp;
             }
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
-            need_rand = 1;
-            break;
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
             break;
@@ -568,6 +561,10 @@ int cms_main(int argc, char **argv)
                 goto end;
             vpmtouched++;
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         case OPT_3DES_WRAP:
 # ifndef OPENSSL_NO_DES
             wrap_cipher = EVP_des_ede3_wrap();
@@ -624,7 +621,6 @@ int cms_main(int argc, char **argv)
         }
         signerfile = NULL;
         keyfile = NULL;
-        need_rand = 1;
     } else if (operation == SMIME_DECRYPT) {
         if (recipfile == NULL && keyfile == NULL
             && secret_key == NULL && pwri_pass == NULL) {
@@ -638,7 +634,6 @@ int cms_main(int argc, char **argv)
             BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
             goto opthelp;
         }
-        need_rand = 1;
     } else if (!operation) {
         goto opthelp;
     }
@@ -648,13 +643,6 @@ int cms_main(int argc, char **argv)
         goto end;
     }
 
-    if (need_rand) {
-        app_RAND_load_file(NULL, (inrand != NULL));
-        if (inrand != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(inrand));
-    }
-
     ret = 2;
 
     if (!(operation & SMIME_SIGNERS))
@@ -1083,8 +1071,6 @@ int cms_main(int argc, char **argv)
  end:
     if (ret)
         ERR_print_errors(bio_err);
-    if (need_rand)
-        app_RAND_write_file(NULL);
     sk_X509_pop_free(encerts, X509_free);
     sk_X509_pop_free(other, X509_free);
     X509_VERIFY_PARAM_free(vpm);
diff --git a/apps/dgst.c b/apps/dgst.c
index 545c032..df50947 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -29,11 +29,12 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
 
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-    OPT_C, OPT_R, OPT_RAND, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
+    OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
     OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL,
     OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT,
     OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT,
-    OPT_DIGEST
+    OPT_DIGEST,
+    OPT_R_ENUM,
 } OPTION_CHOICE;
 
 const OPTIONS dgst_options[] = {
@@ -43,8 +44,6 @@ const OPTIONS dgst_options[] = {
     {"help", OPT_HELP, '-', "Display this summary"},
     {"c", OPT_C, '-', "Print the digest with separating colons"},
     {"r", OPT_R, '-', "Print the digest in coreutils format"},
-    {"rand", OPT_RAND, 's',
-     "Use file(s) containing random data to seed RNG or an EGD sock"},
     {"out", OPT_OUT, '>', "Output to filename rather than stdout"},
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
     {"sign", OPT_SIGN, 's', "Sign digest using private key"},
@@ -65,6 +64,7 @@ const OPTIONS dgst_options[] = {
     {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
     {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"},
     {"", OPT_DIGEST, '-', "Any supported digest"},
+    OPT_R_OPTIONS,
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
     {"engine_impl", OPT_ENGINE_IMPL, '-',
@@ -84,7 +84,7 @@ int dgst_main(int argc, char **argv)
     char *passinarg = NULL, *passin = NULL;
     const EVP_MD *md = NULL, *m;
     const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
-    const char *sigfile = NULL, *randfile = NULL;
+    const char *sigfile = NULL;
     OPTION_CHOICE o;
     int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
     int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
@@ -113,8 +113,9 @@ int dgst_main(int argc, char **argv)
         case OPT_R:
             separator = 2;
             break;
-        case OPT_RAND:
-            randfile = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_OUT:
             outfile = opt_arg();
@@ -223,9 +224,6 @@ int dgst_main(int argc, char **argv)
             out_bin = 0;
     }
 
-    if (randfile != NULL)
-        app_RAND_load_file(randfile, 0);
-
     out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
     if (out == NULL)
         goto end;
diff --git a/apps/dhparam.c b/apps/dhparam.c
index fc3a51e..28ae6c3 100644
--- a/apps/dhparam.c
+++ b/apps/dhparam.c
@@ -36,7 +36,8 @@ typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
     OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
-    OPT_RAND, OPT_DSAPARAM, OPT_C, OPT_2, OPT_5
+    OPT_DSAPARAM, OPT_C, OPT_2, OPT_5,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS dhparam_options[] = {
@@ -50,8 +51,7 @@ const OPTIONS dhparam_options[] = {
     {"check", OPT_CHECK, '-', "Check the DH parameters"},
     {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"},
     {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"C", OPT_C, '-', "Print C code"},
     {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
     {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},
@@ -69,7 +69,7 @@ int dhparam_main(int argc, char **argv)
 {
     BIO *in = NULL, *out = NULL;
     DH *dh = NULL;
-    char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
+    char *infile = NULL, *outfile = NULL, *prog;
     ENGINE *e = NULL;
 #ifndef OPENSSL_NO_DSA
     int dsaparam = 0;
@@ -130,8 +130,9 @@ int dhparam_main(int argc, char **argv)
         case OPT_NOOUT:
             noout = 1;
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         }
     }
@@ -165,13 +166,6 @@ int dhparam_main(int argc, char **argv)
         }
 
         BN_GENCB_set(cb, dh_cb, bio_err);
-        if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
-            BIO_printf(bio_err,
-                       "warning, not much extra random data, consider using the -rand option\n");
-        }
-        if (inrand != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(inrand));
 
 # ifndef OPENSSL_NO_DSA
         if (dsaparam) {
@@ -211,7 +205,6 @@ int dhparam_main(int argc, char **argv)
         }
 
         BN_GENCB_free(cb);
-        app_RAND_write_file(NULL);
     } else {
 
         in = bio_open_default(infile, 'r', informat);
diff --git a/apps/dsaparam.c b/apps/dsaparam.c
index cf0a10b..39185e3 100644
--- a/apps/dsaparam.c
+++ b/apps/dsaparam.c
@@ -29,7 +29,7 @@ static int dsa_cb(int p, int n, BN_GENCB *cb);
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
-    OPT_NOOUT, OPT_GENKEY, OPT_RAND, OPT_ENGINE
+    OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS dsaparam_options[] = {
@@ -42,7 +42,7 @@ const OPTIONS dsaparam_options[] = {
     {"C", OPT_C, '-', "Output C code"},
     {"noout", OPT_NOOUT, '-', "No output"},
     {"genkey", OPT_GENKEY, '-', "Generate a DSA key"},
-    {"rand", OPT_RAND, 's', "Files to use for random number input"},
+    OPT_R_OPTIONS,
 # ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
 # endif
@@ -55,10 +55,10 @@ int dsaparam_main(int argc, char **argv)
     DSA *dsa = NULL;
     BIO *in = NULL, *out = NULL;
     BN_GENCB *cb = NULL;
-    int numbits = -1, num = 0, genkey = 0, need_rand = 0;
+    int numbits = -1, num = 0, genkey = 0;
     int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
     int ret = 1, i, text = 0, private = 0;
-    char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
+    char *infile = NULL, *outfile = NULL, *prog;
     OPTION_CHOICE o;
 
     prog = opt_init(argc, argv, dsaparam_options);
@@ -97,11 +97,11 @@ int dsaparam_main(int argc, char **argv)
             C = 1;
             break;
         case OPT_GENKEY:
-            genkey = need_rand = 1;
+            genkey = 1;
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
-            need_rand = 1;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_NOOUT:
             noout = 1;
@@ -116,7 +116,6 @@ int dsaparam_main(int argc, char **argv)
             goto end;
         /* generate a key */
         numbits = num;
-        need_rand = 1;
     }
     private = genkey ? 1 : 0;
 
@@ -127,13 +126,6 @@ int dsaparam_main(int argc, char **argv)
     if (out == NULL)
         goto end;
 
-    if (need_rand) {
-        app_RAND_load_file(NULL, (inrand != NULL));
-        if (inrand != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(inrand));
-    }
-
     if (numbits > 0) {
         cb = BN_GENCB_new();
         if (cb == NULL) {
@@ -141,7 +133,6 @@ int dsaparam_main(int argc, char **argv)
             goto end;
         }
         BN_GENCB_set(cb, dsa_cb, bio_err);
-        assert(need_rand);
         dsa = DSA_new();
         if (dsa == NULL) {
             BIO_printf(bio_err, "Error allocating DSA object\n");
@@ -217,7 +208,6 @@ int dsaparam_main(int argc, char **argv)
     if (genkey) {
         DSA *dsakey;
 
-        assert(need_rand);
         if ((dsakey = DSAparams_dup(dsa)) == NULL)
             goto end;
         if (!DSA_generate_key(dsakey)) {
@@ -233,8 +223,6 @@ int dsaparam_main(int argc, char **argv)
                                             NULL);
         DSA_free(dsakey);
     }
-    if (need_rand)
-        app_RAND_write_file(NULL);
     ret = 0;
  end:
     BN_GENCB_free(cb);
diff --git a/apps/ecparam.c b/apps/ecparam.c
index 3661a88..6521ccb 100644
--- a/apps/ecparam.c
+++ b/apps/ecparam.c
@@ -29,7 +29,8 @@ typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
     OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME,
-    OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_RAND, OPT_ENGINE
+    OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_ENGINE,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS ecparam_options[] = {
@@ -52,7 +53,7 @@ const OPTIONS ecparam_options[] = {
     {"param_enc", OPT_PARAM_ENC, 's',
      "Specifies the way the ec parameters are encoded"},
     {"genkey", OPT_GENKEY, '-', "Generate ec key"},
-    {"rand", OPT_RAND, 's', "Files to use for random number input"},
+    OPT_R_OPTIONS,
 # ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 # endif
@@ -80,7 +81,7 @@ int ecparam_main(int argc, char **argv)
     BIO *in = NULL, *out = NULL;
     EC_GROUP *group = NULL;
     point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
-    char *curve_name = NULL, *inrand = NULL;
+    char *curve_name = NULL;
     char *infile = NULL, *outfile = NULL, *prog;
     unsigned char *buffer = NULL;
     OPTION_CHOICE o;
@@ -88,7 +89,7 @@ int ecparam_main(int argc, char **argv)
     int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
     int ret = 1, private = 0;
     int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
-    int text = 0, i, need_rand = 0, genkey = 0;
+    int text = 0, i, genkey = 0;
 
     prog = opt_init(argc, argv, ecparam_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -149,11 +150,11 @@ int ecparam_main(int argc, char **argv)
             new_asn1_flag = 1;
             break;
         case OPT_GENKEY:
-            genkey = need_rand = 1;
+            genkey = 1;
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
-            need_rand = 1;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
@@ -395,21 +396,12 @@ int ecparam_main(int argc, char **argv)
         }
     }
 
-    if (need_rand) {
-        app_RAND_load_file(NULL, (inrand != NULL));
-        if (inrand != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(inrand));
-    }
-
     if (genkey) {
         EC_KEY *eckey = EC_KEY_new();
 
         if (eckey == NULL)
             goto end;
 
-        assert(need_rand);
-
         if (EC_KEY_set_group(eckey, group) == 0) {
             BIO_printf(bio_err, "unable to set group when generating key\n");
             EC_KEY_free(eckey);
@@ -432,9 +424,6 @@ int ecparam_main(int argc, char **argv)
         EC_KEY_free(eckey);
     }
 
-    if (need_rand)
-        app_RAND_write_file(NULL);
-
     ret = 0;
  end:
     BN_free(ec_p);
diff --git a/apps/enc.c b/apps/enc.c
index cc6fa0a..db5d3a2 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -43,7 +43,8 @@ typedef enum OPTION_choice {
     OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V,
     OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
     OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
-    OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER
+    OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS enc_options[] = {
@@ -74,6 +75,7 @@ const OPTIONS enc_options[] = {
     {"md", OPT_MD, 's', "Use specified digest to create a key from the passphrase"},
     {"none", OPT_NONE, '-', "Don't encrypt"},
     {"", OPT_CIPHER, '-', "Any supported cipher"},
+    OPT_R_OPTIONS,
 #ifdef ZLIB
     {"z", OPT_Z, '-', "Use zlib as the 'encryption'"},
 #endif
@@ -255,6 +257,10 @@ int enc_main(int argc, char **argv)
         case OPT_NONE:
             cipher = NULL;
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         }
     }
 
diff --git a/apps/gendsa.c b/apps/gendsa.c
index c9563a7..fa68323 100644
--- a/apps/gendsa.c
+++ b/apps/gendsa.c
@@ -26,7 +26,8 @@ NON_EMPTY_TRANSLATION_UNIT
 
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-    OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_RAND, OPT_CIPHER
+    OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS gendsa_options[] = {
@@ -35,8 +36,7 @@ const OPTIONS gendsa_options[] = {
     {"help", OPT_HELP, '-', "Display this summary"},
     {"out", OPT_OUT, '>', "Output the key to the specified file"},
     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
 # ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
@@ -50,7 +50,7 @@ int gendsa_main(int argc, char **argv)
     BIO *out = NULL, *in = NULL;
     DSA *dsa = NULL;
     const EVP_CIPHER *enc = NULL;
-    char *inrand = NULL, *dsaparams = NULL;
+    char *dsaparams = NULL;
     char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog;
     OPTION_CHOICE o;
     int ret = 1, private = 0;
@@ -77,8 +77,9 @@ int gendsa_main(int argc, char **argv)
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_CIPHER:
             if (!opt_cipher(opt_unknown(), &enc))
@@ -114,21 +115,11 @@ int gendsa_main(int argc, char **argv)
     if (out == NULL)
         goto end2;
 
-    if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
-        BIO_printf(bio_err,
-                   "warning, not much extra random data, consider using the -rand option\n");
-    }
-    if (inrand != NULL)
-        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                   app_RAND_load_files(inrand));
-
     DSA_get0_pqg(dsa, &p, NULL, NULL);
     BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p));
     if (!DSA_generate_key(dsa))
         goto end;
 
-    app_RAND_write_file(NULL);
-
     assert(private);
     if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout))
         goto end;
diff --git a/apps/genrsa.c b/apps/genrsa.c
index 033e692..2bc70a9 100644
--- a/apps/genrsa.c
+++ b/apps/genrsa.c
@@ -33,7 +33,8 @@ static int genrsa_cb(int p, int n, BN_GENCB *cb);
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_3, OPT_F4, OPT_ENGINE,
-    OPT_OUT, OPT_RAND, OPT_PASSOUT, OPT_CIPHER
+    OPT_OUT, OPT_PASSOUT, OPT_CIPHER,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS genrsa_options[] = {
@@ -42,8 +43,7 @@ const OPTIONS genrsa_options[] = {
     {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
     {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
     {"out", OPT_OUT, 's', "Output the key to specified file"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
     {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
 # ifndef OPENSSL_NO_ENGINE
@@ -65,7 +65,7 @@ int genrsa_main(int argc, char **argv)
     int ret = 1, num = DEFBITS, private = 0;
     unsigned long f4 = RSA_F4;
     char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
-    char *inrand = NULL, *prog, *hexe, *dece;
+    char *prog, *hexe, *dece;
     OPTION_CHOICE o;
 
     if (bn == NULL || cb == NULL)
@@ -96,8 +96,9 @@ int genrsa_main(int argc, char **argv)
         case OPT_ENGINE:
             eng = setup_engine(opt_arg(), 0);
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_PASSOUT:
             passoutarg = opt_arg();
@@ -124,15 +125,6 @@ int genrsa_main(int argc, char **argv)
     if (out == NULL)
         goto end;
 
-    if (!app_RAND_load_file(NULL, 1) && inrand == NULL
-        && !RAND_status()) {
-        BIO_printf(bio_err,
-                   "warning, not much extra random data, consider using the -rand option\n");
-    }
-    if (inrand != NULL)
-        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                   app_RAND_load_files(inrand));
-
     BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
                num);
     rsa = eng ? RSA_new_method(eng) : RSA_new();
@@ -142,8 +134,6 @@ int genrsa_main(int argc, char **argv)
     if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, cb))
         goto end;
 
-    app_RAND_write_file(NULL);
-
     RSA_get0_key(rsa, NULL, &e, NULL);
     hexe = BN_bn2hex(e);
     dece = BN_bn2dec(e);
diff --git a/apps/openssl.c b/apps/openssl.c
index e23c390..866c00e 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -240,6 +240,7 @@ int main(int argc, char *argv[])
     OPENSSL_free(default_config_file);
     lh_FUNCTION_free(prog);
     OPENSSL_free(arg.argv);
+    app_RAND_write();
 
     BIO_free(bio_in);
     BIO_free_all(bio_out);
diff --git a/apps/passwd.c b/apps/passwd.c
index 7ce40e0..eb5a622 100644
--- a/apps/passwd.c
+++ b/apps/passwd.c
@@ -65,7 +65,8 @@ typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_IN,
     OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
-    OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN
+    OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN,
+    OPT_R_ENUM,
 } OPTION_CHOICE;
 
 const OPTIONS passwd_options[] = {
@@ -90,6 +91,7 @@ const OPTIONS passwd_options[] = {
 # ifndef OPENSSL_NO_DES
     {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
 # endif
+    OPT_R_OPTIONS,
     {NULL}
 };
 
@@ -182,6 +184,10 @@ int passwd_main(int argc, char **argv)
             in_stdin = 1;
             pw_source_defined = 1;
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         }
     }
     argc = opt_num_rest();
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 2ec8fdc..28ae2d5 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -53,9 +53,10 @@ typedef enum OPTION_choice {
     OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER,
     OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
     OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
-    OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
+    OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
     OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
-    OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE
+    OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS pkcs12_options[] = {
@@ -91,8 +92,7 @@ const OPTIONS pkcs12_options[] = {
     {"macalg", OPT_MACALG, 's',
      "Digest algorithm used in MAC (default SHA1)"},
     {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"inkey", OPT_INKEY, 's', "Private key if not infile"},
     {"certfile", OPT_CERTFILE, '<', "Load certs from file"},
     {"name", OPT_NAME, 's', "Use name as friendly name"},
@@ -133,7 +133,7 @@ int pkcs12_main(int argc, char **argv)
     int ret = 1, macver = 1, add_lmk = 0, private = 0;
     int noprompt = 0;
     char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
-    char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
+    char *passin = NULL, *passout = NULL, *macalg = NULL;
     char *cpass = NULL, *mpass = NULL, *badpass = NULL;
     const char *CApath = NULL, *CAfile = NULL, *prog;
     int noCApath = 0, noCAfile = 0;
@@ -225,8 +225,9 @@ int pkcs12_main(int argc, char **argv)
             if (!set_pbe(&key_pbe, opt_arg()))
                 goto opthelp;
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_INKEY:
             keyname = opt_arg();
@@ -314,13 +315,6 @@ int pkcs12_main(int argc, char **argv)
         mpass = macpass;
     }
 
-    if (export_cert || inrand != NULL) {
-        app_RAND_load_file(NULL, (inrand != NULL));
-        if (inrand != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(inrand));
-    }
-
     if (twopass) {
         /* To avoid bit rot */
         if (1) {
@@ -576,8 +570,6 @@ int pkcs12_main(int argc, char **argv)
     ret = 0;
  end:
     PKCS12_free(p12);
-    if (export_cert || inrand)
-        app_RAND_write_file(NULL);
     release_engine(e);
     BIO_free(in);
     BIO_free_all(out);
diff --git a/apps/pkcs8.c b/apps/pkcs8.c
index ad41f7b..ea0e856 100644
--- a/apps/pkcs8.c
+++ b/apps/pkcs8.c
@@ -24,7 +24,8 @@ typedef enum OPTION_choice {
     OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P,
 #endif
     OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT,
-    OPT_TRADITIONAL
+    OPT_TRADITIONAL,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS pkcs8_options[] = {
@@ -36,6 +37,7 @@ const OPTIONS pkcs8_options[] = {
     {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"},
     {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"},
     {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"},
+    OPT_R_OPTIONS,
     {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"},
     {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"},
     {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
@@ -112,6 +114,10 @@ int pkcs8_main(int argc, char **argv)
         case OPT_NOCRYPT:
             nocrypt = 1;
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         case OPT_TRADITIONAL:
             traditional = 1;
             break;
@@ -248,7 +254,6 @@ int pkcs8_main(int argc, char **argv)
                 BIO_printf(bio_err, "Password required\n");
                 goto end;
             }
-            app_RAND_load_file(NULL, 0);
             p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
             if (p8 == NULL) {
                 X509_ALGOR_free(pbe);
@@ -256,7 +261,6 @@ int pkcs8_main(int argc, char **argv)
                 ERR_print_errors(bio_err);
                 goto end;
             }
-            app_RAND_write_file(NULL);
             assert(private);
             if (outformat == FORMAT_PEM)
                 PEM_write_bio_PKCS8(out, p8);
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index 90e9ae3..990375b 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -36,7 +36,8 @@ typedef enum OPTION_choice {
     OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN,
     OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
     OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN,
-    OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN
+    OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS pkeyutl_options[] = {
@@ -64,6 +65,7 @@ const OPTIONS pkeyutl_options[] = {
     {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"},
     {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
     {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
+    OPT_R_OPTIONS,
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
     {"engine_impl", OPT_ENGINE_IMPL, '-',
@@ -134,6 +136,10 @@ int pkeyutl_main(int argc, char **argv)
             if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
                 goto opthelp;
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
             break;
@@ -238,9 +244,6 @@ int pkeyutl_main(int argc, char **argv)
         goto end;
     }
 
-/* FIXME: seed PRNG only if needed */
-    app_RAND_load_file(NULL, 0);
-
     if (pkey_op != EVP_PKEY_OP_DERIVE) {
         in = bio_open_default(infile, 'r', FORMAT_BINARY);
         if (in == NULL)
diff --git a/apps/rand.c b/apps/rand.c
index 33dbf57..3455006 100644
--- a/apps/rand.c
+++ b/apps/rand.c
@@ -19,7 +19,8 @@
 
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-    OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX
+    OPT_OUT, OPT_ENGINE, OPT_BASE64, OPT_HEX,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS rand_options[] = {
@@ -27,8 +28,7 @@ const OPTIONS rand_options[] = {
     {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
     {"help", OPT_HELP, '-', "Display this summary"},
     {"out", OPT_OUT, '>', "Output file"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"base64", OPT_BASE64, '-', "Base64 encode output"},
     {"hex", OPT_HEX, '-', "Hex encode output"},
 #ifndef OPENSSL_NO_ENGINE
@@ -41,7 +41,7 @@ int rand_main(int argc, char **argv)
 {
     ENGINE *e = NULL;
     BIO *out = NULL;
-    char *inrand = NULL, *outfile = NULL, *prog;
+    char *outfile = NULL, *prog;
     OPTION_CHOICE o;
     int format = FORMAT_BINARY, i, num = -1, r, ret = 1;
 
@@ -63,8 +63,9 @@ int rand_main(int argc, char **argv)
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_BASE64:
             format = FORMAT_BASE64;
@@ -80,11 +81,6 @@ int rand_main(int argc, char **argv)
     if (argc != 1 || !opt_int(argv[0], &num) || num < 0)
         goto opthelp;
 
-    app_RAND_load_file(NULL, (inrand != NULL));
-    if (inrand != NULL)
-        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                   app_RAND_load_files(inrand));
-
     out = bio_open_default(outfile, 'w', format);
     if (out == NULL)
         goto end;
@@ -118,7 +114,7 @@ int rand_main(int argc, char **argv)
     }
     if (format == FORMAT_TEXT)
         BIO_puts(out, "\n");
-    if (BIO_flush(out) <= 0 || !app_RAND_write_file(NULL))
+    if (BIO_flush(out) <= 0)
         goto end;
 
     ret = 0;
diff --git a/apps/req.c b/apps/req.c
index d72a172..f43dae5 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -76,12 +76,13 @@ typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY,
     OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT,
-    OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_RAND, OPT_NEWKEY,
+    OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY,
     OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
     OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
     OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
     OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS,
-    OPT_REQEXTS, OPT_PRECERT, OPT_MD
+    OPT_REQEXTS, OPT_PRECERT, OPT_MD,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS req_options[] = {
@@ -98,8 +99,7 @@ const OPTIONS req_options[] = {
     {"keyout", OPT_KEYOUT, '>', "File to send the key to"},
     {"passin", OPT_PASSIN, 's', "Private key password source"},
     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"},
     {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
     {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
@@ -151,7 +151,7 @@ int req_main(int argc, char **argv)
     const EVP_CIPHER *cipher = NULL;
     const EVP_MD *md_alg = NULL, *digest = NULL;
     char *extensions = NULL, *infile = NULL;
-    char *outfile = NULL, *keyfile = NULL, *inrand = NULL;
+    char *outfile = NULL, *keyfile = NULL;
     char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL;
     char *passin = NULL, *passout = NULL;
     char *nofree_passin = NULL, *nofree_passout = NULL;
@@ -234,8 +234,9 @@ int req_main(int argc, char **argv)
         case OPT_PASSOUT:
             passargout = opt_arg();
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_NEWKEY:
             keyalg = opt_arg();
@@ -454,20 +455,12 @@ int req_main(int argc, char **argv)
             /* load_key() has already printed an appropriate message */
             goto end;
         } else {
-            char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
-            if (randfile == NULL)
-                ERR_clear_error();
-            app_RAND_load_file(randfile, 0);
+            app_RAND_load_conf(req_conf, SECTION);
         }
     }
 
     if (newreq && (pkey == NULL)) {
-        char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
-        if (randfile == NULL)
-            ERR_clear_error();
-        app_RAND_load_file(randfile, 0);
-        if (inrand != NULL)
-            app_RAND_load_files(inrand);
+        app_RAND_load_conf(req_conf, SECTION);
 
         if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
             newkey = DEFAULT_KEY_LENGTH;
@@ -525,8 +518,6 @@ int req_main(int argc, char **argv)
         EVP_PKEY_CTX_free(genctx);
         genctx = NULL;
 
-        app_RAND_write_file(randfile);
-
         if (keyout == NULL) {
             keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
             if (keyout == NULL)
diff --git a/apps/rsautl.c b/apps/rsautl.c
index c8a2650..ca9cb79 100644
--- a/apps/rsautl.c
+++ b/apps/rsautl.c
@@ -32,7 +32,8 @@ typedef enum OPTION_choice {
     OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP,
     OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931,
     OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
-    OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM
+    OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS rsautl_options[] = {
@@ -57,6 +58,7 @@ const OPTIONS rsautl_options[] = {
     {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"},
     {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"},
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    OPT_R_OPTIONS,
 # ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 # endif
@@ -153,6 +155,10 @@ int rsautl_main(int argc, char **argv)
         case OPT_PASSIN:
             passinarg = opt_arg();
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         }
     }
     argc = opt_num_rest();
@@ -169,9 +175,6 @@ int rsautl_main(int argc, char **argv)
         goto end;
     }
 
-/* FIXME: seed PRNG only if needed */
-    app_RAND_load_file(NULL, 0);
-
     switch (key_type) {
     case KEY_PRIVKEY:
         pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key");
diff --git a/apps/s_client.c b/apps/s_client.c
index 114071c..45464a4 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -572,7 +572,7 @@ typedef enum OPTION_choice {
     OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN,
     OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
     OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO,
-    OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF,
+    OPT_SSL_CLIENT_ENGINE, OPT_IGN_EOF, OPT_NO_IGN_EOF,
     OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG,
     OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG,
     OPT_SECURITY_DEBUG_VERBOSE, OPT_SHOWCERTS, OPT_NBIO_TEST, OPT_STATE,
@@ -598,7 +598,8 @@ typedef enum OPTION_choice {
 #ifndef OPENSSL_NO_CT
     OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
 #endif
-    OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME
+    OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS s_client_options[] = {
@@ -654,8 +655,7 @@ const OPTIONS s_client_options[] = {
      "Use the appropriate STARTTLS command before starting TLS"},
     {"xmpphost", OPT_XMPPHOST, 's',
      "Host to use with \"-starttls xmpp[-server]\""},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"},
     {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"},
     {"use_srtp", OPT_USE_SRTP, 's',
@@ -881,7 +881,6 @@ int s_client_main(int argc, char **argv)
     char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
     char *chCApath = NULL, *chCAfile = NULL, *host = NULL;
     char *port = OPENSSL_strdup(PORT);
-    char *inrand = NULL;
     char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
     char *ReqCAfile = NULL;
     char *sess_in = NULL, *crl_file = NULL, *p;
@@ -905,7 +904,6 @@ int s_client_main(int argc, char **argv)
 #endif
     int read_buf_len = 0;
     int fallback_scsv = 0;
-    long randamt = 0;
     OPTION_CHOICE o;
 #ifndef OPENSSL_NO_DTLS
     int enable_timeouts = 0;
@@ -1152,8 +1150,9 @@ int s_client_main(int argc, char **argv)
             }
 #endif
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_IGN_EOF:
             c_ign_eof = 1;
@@ -1604,16 +1603,6 @@ int s_client_main(int argc, char **argv)
     if (!load_excert(&exc))
         goto end;
 
-    if (!app_RAND_load_file(NULL, 1) && inrand == NULL
-        && !RAND_status()) {
-        BIO_printf(bio_err,
-                   "warning, not much extra random data, consider using the -rand option\n");
-    }
-    if (inrand != NULL) {
-        randamt = app_RAND_load_files(inrand);
-        BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt);
-    }
-
     if (bio_c_out == NULL) {
         if (c_quiet && !c_debug) {
             bio_c_out = BIO_new(BIO_s_null());
diff --git a/apps/s_server.c b/apps/s_server.c
index 8df767c..961c738 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -745,10 +745,11 @@ typedef enum OPTION_choice {
     OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
     OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
     OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
-    OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
+    OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
     OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
     OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
     OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA,
+    OPT_R_ENUM,
     OPT_S_ENUM,
     OPT_V_ENUM,
     OPT_X_ENUM
@@ -825,8 +826,7 @@ const OPTIONS s_server_options[] = {
     {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"},
     {"id_prefix", OPT_ID_PREFIX, 's',
      "Generate SSL/TLS session IDs prefixed by arg"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"keymatexport", OPT_KEYMATEXPORT, 's',
      "Export keying material using label"},
     {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
@@ -974,7 +974,7 @@ int s_server_main(int argc, char *argv[])
     X509 *s_cert = NULL, *s_dcert = NULL;
     X509_VERIFY_PARAM *vpm = NULL;
     const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL;
-    char *dpassarg = NULL, *dpass = NULL, *inrand = NULL;
+    char *dpassarg = NULL, *dpass = NULL;
     char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
     char *crl_file = NULL, *prog;
 #ifdef AF_UNIX
@@ -1494,8 +1494,9 @@ int s_server_main(int argc, char *argv[])
         case OPT_ENGINE:
             engine = setup_engine(opt_arg(), 1);
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_SERVERNAME:
             tlsextcbp.servername = opt_arg();
@@ -1708,15 +1709,6 @@ int s_server_main(int argc, char *argv[])
 
     }
 
-    if (!app_RAND_load_file(NULL, 1) && inrand == NULL
-        && !RAND_status()) {
-        BIO_printf(bio_err,
-                   "warning, not much extra random data, consider using the -rand option\n");
-    }
-    if (inrand != NULL)
-        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                   app_RAND_load_files(inrand));
-
     if (bio_s_out == NULL) {
         if (s_quiet && !s_debug) {
             bio_s_out = BIO_new(BIO_s_null());
diff --git a/apps/smime.c b/apps/smime.c
index babe4ef..8617ba4 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -37,9 +37,10 @@ typedef enum OPTION_choice {
     OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN,
     OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP,
     OPT_BINARY, OPT_NOSIGS, OPT_STREAM, OPT_INDEF, OPT_NOINDEF,
-    OPT_CRLFEOL, OPT_RAND, OPT_ENGINE, OPT_PASSIN,
+    OPT_CRLFEOL, OPT_ENGINE, OPT_PASSIN,
     OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD,
     OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE,
+    OPT_R_ENUM,
     OPT_V_ENUM,
     OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT,
     OPT_OUTFORM, OPT_CONTENT
@@ -96,8 +97,7 @@ const OPTIONS smime_options[] = {
     {"indef", OPT_INDEF, '-', "Same as -stream" },
     {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"},
     {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
     {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"},
     {"", OPT_CIPHER, '-', "Any supported cipher"},
@@ -121,15 +121,12 @@ int smime_main(int argc, char **argv)
     const EVP_CIPHER *cipher = NULL;
     const EVP_MD *sign_md = NULL;
     const char *CAfile = NULL, *CApath = NULL, *prog = NULL;
-    char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *inrand = NULL;
-    char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile =
-        NULL;
-    char *passinarg = NULL, *passin = NULL, *to = NULL, *from =
-        NULL, *subject = NULL;
+    char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
+    char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL;
+    char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL;
     OPTION_CHOICE o;
     int noCApath = 0, noCAfile = 0;
-    int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef =
-        0;
+    int flags = PKCS7_DETACHED, operation = 0, ret = 0, indef = 0;
     int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform =
         FORMAT_PEM;
     int vpmtouched = 0, rv = 0;
@@ -224,9 +221,9 @@ int smime_main(int argc, char **argv)
             flags |= PKCS7_CRLFEOL;
             mime_eol = "\r\n";
             break;
-        case OPT_RAND:
-            inrand = opt_arg();
-            need_rand = 1;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
@@ -351,7 +348,6 @@ int smime_main(int argc, char **argv)
         }
         signerfile = NULL;
         keyfile = NULL;
-        need_rand = 1;
     } else if (operation == SMIME_DECRYPT) {
         if (recipfile == NULL && keyfile == NULL) {
             BIO_printf(bio_err,
@@ -363,7 +359,6 @@ int smime_main(int argc, char **argv)
             BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
             goto opthelp;
         }
-        need_rand = 1;
     } else if (!operation) {
         goto opthelp;
     }
@@ -373,13 +368,6 @@ int smime_main(int argc, char **argv)
         goto end;
     }
 
-    if (need_rand) {
-        app_RAND_load_file(NULL, (inrand != NULL));
-        if (inrand != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(inrand));
-    }
-
     ret = 2;
 
     if (!(operation & SMIME_SIGNERS))
@@ -603,8 +591,6 @@ int smime_main(int argc, char **argv)
     }
     ret = 0;
  end:
-    if (need_rand)
-        app_RAND_write_file(NULL);
     if (ret)
         ERR_print_errors(bio_err);
     sk_X509_pop_free(encerts, X509_free);
diff --git a/apps/speed.c b/apps/speed.c
index bd32786..a086060 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -342,7 +342,7 @@ static int found(const char *name, const OPT_PAIR *pairs, int *result)
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
-    OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS
+    OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM,
 } OPTION_CHOICE;
 
 const OPTIONS speed_options[] = {
@@ -365,6 +365,7 @@ const OPTIONS speed_options[] = {
     {"async_jobs", OPT_ASYNCJOBS, 'p',
      "Enable async mode and start pnum jobs"},
 #endif
+    OPT_R_OPTIONS,
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 #endif
@@ -1410,6 +1411,10 @@ int speed_main(int argc, char **argv)
             goto end;
 #endif
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         }
     }
     argc = opt_num_rest();
diff --git a/apps/srp.c b/apps/srp.c
index c31830e..f67c7ff 100644
--- a/apps/srp.c
+++ b/apps/srp.c
@@ -26,7 +26,6 @@ NON_EMPTY_TRANSLATION_UNIT
 # define BASE_SECTION    "srp"
 # define CONFIG_FILE "openssl.cnf"
 
-# define ENV_RANDFILE            "RANDFILE"
 
 # define ENV_DATABASE            "srpvfile"
 # define ENV_DEFAULT_SRP         "default_srp"
@@ -189,7 +188,7 @@ typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SRPVFILE, OPT_ADD,
     OPT_DELETE, OPT_MODIFY, OPT_LIST, OPT_GN, OPT_USERINFO,
-    OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE
+    OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, OPT_R_ENUM,
 } OPTION_CHOICE;
 
 const OPTIONS srp_options[] = {
@@ -207,6 +206,7 @@ const OPTIONS srp_options[] = {
     {"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"},
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    OPT_R_OPTIONS,
 # ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 # endif
@@ -222,7 +222,7 @@ int srp_main(int argc, char **argv)
     int doupdatedb = 0, mode = OPT_ERR;
     char *user = NULL, *passinarg = NULL, *passoutarg = NULL;
     char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL;
-    char *randfile = NULL, *section = NULL;
+    char *section = NULL;
     char **gNrow = NULL, *configfile = NULL;
     char *srpvfile = NULL, **pp, *prog;
     OPTION_CHOICE o;
@@ -278,6 +278,10 @@ int srp_main(int argc, char **argv)
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 0);
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         }
     }
     argc = opt_num_rest();
@@ -335,8 +339,7 @@ int srp_main(int argc, char **argv)
                 goto end;
         }
 
-        if (randfile == NULL)
-            randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+        app_RAND_load_conf(conf, BASE_SECTION);
 
         if (verbose)
             BIO_printf(bio_err,
@@ -347,10 +350,6 @@ int srp_main(int argc, char **argv)
         if (srpvfile == NULL)
             goto end;
     }
-    if (randfile == NULL)
-        ERR_clear_error();
-    else
-        app_RAND_load_file(randfile, 0);
 
     if (verbose)
         BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n",
@@ -604,8 +603,6 @@ int srp_main(int argc, char **argv)
     OPENSSL_free(passout);
     if (ret)
         ERR_print_errors(bio_err);
-    if (randfile != NULL)
-        app_RAND_write_file(randfile);
     NCONF_free(conf);
     free_index(db);
     release_engine(e);
diff --git a/apps/ts.c b/apps/ts.c
index 636c777..5e7729e 100644
--- a/apps/ts.c
+++ b/apps/ts.c
@@ -79,11 +79,11 @@ static int verify_cb(int ok, X509_STORE_CTX *ctx);
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA,
-    OPT_DIGEST, OPT_RAND, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
+    OPT_DIGEST, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
     OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT,
     OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER,
     OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED,
-    OPT_MD, OPT_V_ENUM
+    OPT_MD, OPT_V_ENUM, OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS ts_options[] = {
@@ -93,8 +93,7 @@ const OPTIONS ts_options[] = {
     {"query", OPT_QUERY, '-', "Generate a TS query"},
     {"data", OPT_DATA, '<', "File to hash"},
     {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"},
-    {"rand", OPT_RAND, 's',
-     "Load the file(s) into the random number generator"},
+    OPT_R_OPTIONS,
     {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"},
     {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"},
     {"cert", OPT_CERT, '-', "Put cert request into query"},
@@ -158,7 +157,7 @@ int ts_main(int argc, char **argv)
     const char *section = NULL;
     char **helpp;
     char *password = NULL;
-    char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL;
+    char *data = NULL, *digest = NULL, *policy = NULL;
     char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
     char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
     const EVP_MD *md = NULL;
@@ -207,8 +206,9 @@ int ts_main(int argc, char **argv)
         case OPT_DIGEST:
             digest = opt_arg();
             break;
-        case OPT_RAND:
-            rnd = opt_arg();
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
             break;
         case OPT_TSPOLICY:
             policy = opt_arg();
@@ -275,16 +275,6 @@ int ts_main(int argc, char **argv)
     if (mode == OPT_ERR || opt_num_rest() != 0)
         goto opthelp;
 
-    /* Seed the random number generator if it is going to be used. */
-    if (mode == OPT_QUERY && !no_nonce) {
-        if (!app_RAND_load_file(NULL, 1) && rnd == NULL)
-            BIO_printf(bio_err, "warning, not much extra random "
-                       "data, consider using the -rand option\n");
-        if (rnd != NULL)
-            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-                       app_RAND_load_files(rnd));
-    }
-
     if (mode == OPT_REPLY && passin &&
         !app_passwd(passin, NULL, &password, NULL)) {
         BIO_printf(bio_err, "Error getting password.\n");
@@ -328,7 +318,6 @@ int ts_main(int argc, char **argv)
 
  end:
     X509_VERIFY_PARAM_free(vpm);
-    app_RAND_write_file(NULL);
     NCONF_free(conf);
     OPENSSL_free(password);
     return (ret);
diff --git a/apps/x509.c b/apps/x509.c
index 6a24da2..7928ccb 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -58,7 +58,8 @@ typedef enum OPTION_choice {
     OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID,
     OPT_SUBJECT_HASH_OLD,
     OPT_ISSUER_HASH_OLD,
-    OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT, OPT_PRESERVE_DATES
+    OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT, OPT_PRESERVE_DATES,
+    OPT_R_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS x509_options[] = {
@@ -118,6 +119,7 @@ const OPTIONS x509_options[] = {
     {"text", OPT_TEXT, '-', "Print the certificate in text form"},
     {"C", OPT_C, '-', "Print out C code forms"},
     {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"},
+    OPT_R_OPTIONS,
     {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"},
     {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
     {"certopt", OPT_CERTOPT, 's', "Various certificate text options"},
@@ -166,7 +168,7 @@ int x509_main(int argc, char **argv)
     char *prog;
     int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
     int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
-    int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
+    int fingerprint = 0, reqfile = 0, checkend = 0;
     int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
     int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
     int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
@@ -227,7 +229,7 @@ int x509_main(int argc, char **argv)
             outfile = opt_arg();
             break;
         case OPT_REQ:
-            reqfile = need_rand = 1;
+            reqfile = 1;
             break;
 
         case OPT_SIGOPT:
@@ -247,18 +249,20 @@ int x509_main(int argc, char **argv)
         case OPT_EXTFILE:
             extfile = opt_arg();
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         case OPT_EXTENSIONS:
             extsect = opt_arg();
             break;
         case OPT_SIGNKEY:
             keyfile = opt_arg();
             sign_flag = ++num;
-            need_rand = 1;
             break;
         case OPT_CA:
             CAfile = opt_arg();
             CA_flag = ++num;
-            need_rand = 1;
             break;
         case OPT_CAKEY:
             CAkeyfile = opt_arg();
@@ -460,9 +464,6 @@ int x509_main(int argc, char **argv)
     if (out == NULL)
         goto end;
 
-    if (need_rand)
-        app_RAND_load_file(NULL, 0);
-
     if (!app_passwd(passinarg, NULL, &passin, NULL)) {
         BIO_printf(bio_err, "Error getting password\n");
         goto end;
@@ -793,7 +794,6 @@ int x509_main(int argc, char **argv)
                         goto end;
                 }
 
-                assert(need_rand);
                 if (!sign(x, Upkey, days, clrext, digest, extconf, extsect, preserve_dates))
                     goto end;
             } else if (CA_flag == i) {
@@ -805,7 +805,6 @@ int x509_main(int argc, char **argv)
                         goto end;
                 }
 
-                assert(need_rand);
                 if (!x509_certify(ctx, CAfile, digest, x, xca,
                                   CApkey, sigopts,
                                   CAserial, CA_createserial, days, clrext,
@@ -882,8 +881,6 @@ int x509_main(int argc, char **argv)
     }
     ret = 0;
  end:
-    if (need_rand)
-        app_RAND_write_file(NULL);
     NCONF_free(extconf);
     BIO_free_all(out);
     X509_STORE_free(ctx);
diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c
index 4005f78..904653f 100644
--- a/crypto/rand/randfile.c
+++ b/crypto/rand/randfile.c
@@ -175,8 +175,11 @@ int RAND_write_file(const char *file)
 
     if (out == NULL)
         out = openssl_fopen(file, "wb");
-    if (out == NULL)
+    if (out == NULL) {
+        RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_CANNOT_OPEN_FILE);
+        ERR_add_error_data(2, "Filename=", file);
         return -1;
+    }
 
 #if !defined(NO_CHMOD) && !defined(OPENSSL_NO_POSIX_IO)
     /*
diff --git a/doc/man1/ca.pod b/doc/man1/ca.pod
index 26d648e..4a59708 100644
--- a/doc/man1/ca.pod
+++ b/doc/man1/ca.pod
@@ -52,6 +52,8 @@ B<openssl> B<ca>
 [B<-utf8>]
 [B<-create_serial>]
 [B<-multivalue-rdn>]
+[B<-rand file...>]
+[B<-writerand file>]
 
 =head1 DESCRIPTION
 
@@ -266,6 +268,19 @@ I</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe>
 
 If -multi-rdn is not used then the UID value is I<123456+CN=John Doe>.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =back
 
 =head1 CRL OPTIONS
@@ -397,8 +412,8 @@ CA private key. Mandatory.
 
 =item B<RANDFILE>
 
-A file used to read and write random number seed information, or
-an EGD socket (see L<RAND_egd(3)>).
+At startup the specified file is loaded into the random number generator,
+and at exit 256 bytes will be written to it.
 
 =item B<default_days>
 
diff --git a/doc/man1/cms.pod b/doc/man1/cms.pod
index c63ac45..33549d4 100644
--- a/doc/man1/cms.pod
+++ b/doc/man1/cms.pod
@@ -92,7 +92,8 @@ B<openssl> B<cms>
 [B<-inkey file>]
 [B<-keyopt name:parameter>]
 [B<-passin arg>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<cert.pem...>]
 [B<-to addr>]
 [B<-from addr>]
@@ -461,14 +462,19 @@ or to modify default parameters for ECDH.
 The private key password source. For more information about the format of B<arg>
 see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)>.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<cert.pem...>
 
 One or more certificates of message recipients: used when encrypting
diff --git a/doc/man1/dgst.pod b/doc/man1/dgst.pod
index 677f2b2..0cbcf85 100644
--- a/doc/man1/dgst.pod
+++ b/doc/man1/dgst.pod
@@ -23,6 +23,7 @@ B<openssl> B<dgst>
 [B<-signature filename>]
 [B<-hmac key>]
 [B<-fips-fingerprint>]
+[B<-rand file...>]
 [B<-engine id>]
 [B<-engine_impl>]
 [B<file...>]
@@ -149,14 +150,19 @@ for example exactly 32 chars for gost-mac.
 
 =back
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-fips-fingerprint>
 
 Compute HMAC using a specific key for certain OpenSSL-FIPS operations.
diff --git a/doc/man1/dhparam.pod b/doc/man1/dhparam.pod
index a6317a9..852469d 100644
--- a/doc/man1/dhparam.pod
+++ b/doc/man1/dhparam.pod
@@ -19,7 +19,8 @@ B<openssl dhparam>
 [B<-C>]
 [B<-2>]
 [B<-5>]
-[B<-rand> I<file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-engine id>]
 [I<numbits>]
 
@@ -82,14 +83,19 @@ input file is ignored and parameters are generated instead. If not
 present but B<numbits> is present, parameters are generated with the
 default generator 2.
 
-=item B<-rand> I<file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item I<numbits>
 
 This option specifies that a parameter set should be generated of size
diff --git a/doc/man1/dsaparam.pod b/doc/man1/dsaparam.pod
index 0a34c29..4c07463 100644
--- a/doc/man1/dsaparam.pod
+++ b/doc/man1/dsaparam.pod
@@ -15,7 +15,8 @@ B<openssl dsaparam>
 [B<-noout>]
 [B<-text>]
 [B<-C>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-genkey>]
 [B<-engine id>]
 [B<numbits>]
@@ -74,14 +75,19 @@ be loaded by calling the get_dsaXXX() function.
 This option will generate a DSA either using the specified or generated
 parameters.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<numbits>
 
 This option specifies that a parameter set should be generated of size
diff --git a/doc/man1/ecparam.pod b/doc/man1/ecparam.pod
index 7e0d074..3f76dc0 100644
--- a/doc/man1/ecparam.pod
+++ b/doc/man1/ecparam.pod
@@ -21,7 +21,8 @@ B<openssl ecparam>
 [B<-conv_form arg>]
 [B<-param_enc arg>]
 [B<-no_seed>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-genkey>]
 [B<-engine id>]
 
@@ -116,14 +117,19 @@ is included in the ECParameters structure (see RFC 3279).
 
 This option will generate an EC private key using the specified parameters.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-engine id>
 
 Specifying an engine (by its unique B<id> string) will cause B<ecparam>
diff --git a/doc/man1/enc.pod b/doc/man1/enc.pod
index 13f1272..ad76be0 100644
--- a/doc/man1/enc.pod
+++ b/doc/man1/enc.pod
@@ -31,6 +31,8 @@ B<openssl enc -ciphername>
 [B<-nopad>]
 [B<-debug>]
 [B<-none>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-engine id>]
 
 =head1 DESCRIPTION
@@ -165,6 +167,19 @@ or zlib-dynamic option.
 
 Use NULL cipher (no encryption or decryption of input).
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =back
 
 =head1 NOTES
diff --git a/doc/man1/gendsa.pod b/doc/man1/gendsa.pod
index 1068ffd..9cb84df 100644
--- a/doc/man1/gendsa.pod
+++ b/doc/man1/gendsa.pod
@@ -21,7 +21,8 @@ B<openssl> B<gendsa>
 [B<-des>]
 [B<-des3>]
 [B<-idea>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-engine id>]
 [B<paramfile>]
 
@@ -49,14 +50,19 @@ These options encrypt the private key with specified
 cipher before outputting it. A pass phrase is prompted for.
 If none of these options is specified no encryption is used.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-engine id>
 
 Specifying an engine (by its unique B<id> string) will cause B<gendsa>
diff --git a/doc/man1/genrsa.pod b/doc/man1/genrsa.pod
index 4e44fe5..57b4cf8 100644
--- a/doc/man1/genrsa.pod
+++ b/doc/man1/genrsa.pod
@@ -24,7 +24,8 @@ B<openssl> B<genrsa>
 [B<-idea>]
 [B<-f4>]
 [B<-3>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-engine id>]
 [B<numbits>]
 
@@ -61,14 +62,19 @@ for if it is not supplied via the B<-passout> argument.
 
 The public exponent to use, either 65537 or 3. The default is 65537.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-engine id>
 
 Specifying an engine (by its unique B<id> string) will cause B<genrsa>
diff --git a/doc/man1/passwd.pod b/doc/man1/passwd.pod
index 02f6339..3c16946 100644
--- a/doc/man1/passwd.pod
+++ b/doc/man1/passwd.pod
@@ -20,6 +20,8 @@ B<openssl passwd>
 [B<-noverify>]
 [B<-quiet>]
 [B<-table>]
+[B<-rand file...>]
+[B<-writerand file>]
 {I<password>}
 
 =head1 DESCRIPTION
@@ -88,6 +90,19 @@ Don't output warnings when passwords given at the command line are truncated.
 In the output list, prepend the cleartext password and a TAB character
 to each password hash.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =back
 
 =head1 EXAMPLES
diff --git a/doc/man1/pkcs12.pod b/doc/man1/pkcs12.pod
index a40ae7f..2eb6b07 100644
--- a/doc/man1/pkcs12.pod
+++ b/doc/man1/pkcs12.pod
@@ -36,7 +36,8 @@ B<openssl> B<pkcs12>
 [B<-password arg>]
 [B<-passin arg>]
 [B<-passout arg>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-CAfile file>]
 [B<-CApath dir>]
 [B<-no-CAfile>]
@@ -275,14 +276,19 @@ to be needed to use MAC iterations counts but they are now used by default.
 
 Don't attempt to provide the MAC integrity.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-CAfile file>
 
 CA storage as a file.
diff --git a/doc/man1/pkcs8.pod b/doc/man1/pkcs8.pod
index ebdcea9..42e2468 100644
--- a/doc/man1/pkcs8.pod
+++ b/doc/man1/pkcs8.pod
@@ -17,6 +17,8 @@ B<openssl> B<pkcs8>
 [B<-passout arg>]
 [B<-iter count>]
 [B<-noiter>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-nocrypt>]
 [B<-traditional>]
 [B<-v2 alg>]
@@ -99,6 +101,19 @@ This option does not encrypt private keys at all and should only be used
 when absolutely necessary. Certain software such as some versions of Java
 code signing software used unencrypted private keys.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-v2 alg>
 
 This option sets the PKCS#5 v2.0 algorithm.
diff --git a/doc/man1/pkeyutl.pod b/doc/man1/pkeyutl.pod
index ee8a588..5e16bc6 100644
--- a/doc/man1/pkeyutl.pod
+++ b/doc/man1/pkeyutl.pod
@@ -30,6 +30,8 @@ B<openssl> B<pkeyutl>
 [B<-pkeyopt opt:value>]
 [B<-hexdump>]
 [B<-asn1parse>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-engine id>]
 [B<-engine_impl>]
 
@@ -146,6 +148,19 @@ hex dump the output data.
 Parse the ASN.1 output data, this is useful when combined with the
 B<-verifyrecover> option when an ASN1 structure is signed.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-engine id>
 
 Specifying an engine (by its unique B<id> string) will cause B<pkeyutl>
diff --git a/doc/man1/rand.pod b/doc/man1/rand.pod
index 0faf687..2248203 100644
--- a/doc/man1/rand.pod
+++ b/doc/man1/rand.pod
@@ -9,7 +9,8 @@ rand - generate pseudo-random bytes
 B<openssl rand>
 [B<-help>]
 [B<-out> I<file>]
-[B<-rand> I<file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-base64>]
 [B<-hex>]
 I<num>
@@ -31,18 +32,23 @@ seeding was obtained from these sources.
 
 Print out a usage message.
 
-=item B<-out> I<file>
+=item B<-out file>
 
 Write to I<file> instead of standard output.
 
-=item B<-rand> I<file(s)>
+=item B<-rand file...>
 
-Use specified file or files or EGD socket (see L<RAND_egd(3)>)
-for seeding the random number generator.
+A file or files containing random data used to seed the random number
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-base64>
 
 Perform base64 encoding on the output.
diff --git a/doc/man1/req.pod b/doc/man1/req.pod
index 4dbd489..e15434a 100644
--- a/doc/man1/req.pod
+++ b/doc/man1/req.pod
@@ -20,7 +20,8 @@ B<openssl> B<req>
 [B<-verify>]
 [B<-modulus>]
 [B<-new>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-newkey rsa:bits>]
 [B<-newkey alg:file>]
 [B<-nodes>]
@@ -130,14 +131,19 @@ in the configuration file and any requested extensions.
 If the B<-key> option is not used it will generate a new RSA private
 key using information specified in the configuration file.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-newkey arg>
 
 This option creates a new certificate request and a new private
@@ -365,8 +371,8 @@ and long names are the same when this option is used.
 
 =item B<RANDFILE>
 
-This specifies a filename in which random number seed information is
-placed and read from, or an EGD socket (see L<RAND_egd(3)>).
+At startup the specified file is loaded into the random number generator,
+and at exit 256 bytes will be written to it.
 It is used for private key generation.
 
 =item B<encrypt_key>
diff --git a/doc/man1/rsautl.pod b/doc/man1/rsautl.pod
index 8883c7b..f80bf42 100644
--- a/doc/man1/rsautl.pod
+++ b/doc/man1/rsautl.pod
@@ -18,6 +18,8 @@ B<openssl> B<rsautl>
 [B<-verify>]
 [B<-encrypt>]
 [B<-decrypt>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-pkcs>]
 [B<-ssl>]
 [B<-raw>]
@@ -80,6 +82,19 @@ Encrypt the input data using an RSA public key.
 
 Decrypt the input data using an RSA private key.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-pkcs, -oaep, -ssl, -raw>
 
 The padding to use: PKCS#1 v1.5 (the default), PKCS#1 OAEP,
diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod
index c262d4a..7f2fd7b 100644
--- a/doc/man1/s_client.pod
+++ b/doc/man1/s_client.pod
@@ -105,7 +105,8 @@ B<openssl> B<s_client>
 [B<-no_ticket>]
 [B<-sess_out filename>]
 [B<-sess_in filename>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-serverinfo types>]
 [B<-status>]
 [B<-alpn protocols>]
@@ -536,14 +537,19 @@ to attempt to obtain a functional reference to the specified engine,
 thus initialising it if needed. The engine will then be set as the default
 for all available algorithms.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-serverinfo types>
 
 A list of comma-separated TLS Extension Types (numbers between 0 and
diff --git a/doc/man1/s_server.pod b/doc/man1/s_server.pod
index b1195fd..9865789 100644
--- a/doc/man1/s_server.pod
+++ b/doc/man1/s_server.pod
@@ -52,7 +52,8 @@ B<openssl> B<s_server>
 [B<-tlsextdebug>]
 [B<-HTTP>]
 [B<-id_prefix val>]
-[B<-rand val>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-keymatexport val>]
 [B<-keymatexportlen +int>]
 [B<-CRL infile>]
@@ -381,14 +382,19 @@ for testing any SSL/TLS code (eg. proxies) that wish to deal with multiple
 servers, when each of which might be generating a unique range of session
 IDs (eg. with a certain prefix).
 
-=item B<-rand val>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-verify_return_error>
 
 Verification errors normally just print a message but allow the
diff --git a/doc/man1/smime.pod b/doc/man1/smime.pod
index 7df780f..5b13fda 100644
--- a/doc/man1/smime.pod
+++ b/doc/man1/smime.pod
@@ -65,7 +65,8 @@ B<openssl> B<smime>
 [B<-indef>]
 [B<-noindef>]
 [B<-stream>]
-[B<-rand file(s)>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-md digest>]
 [cert.pem]...
 
@@ -295,14 +296,19 @@ specified, the argument is given to the engine as a key identifier.
 The private key password source. For more information about the format of B<arg>
 see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)>.
 
-=item B<-rand file(s)>
+=item B<-rand file...>
 
 A file or files containing random data used to seed the random number
-generator, or an EGD socket (see L<RAND_egd(3)>).
+generator.
 Multiple files can be specified separated by an OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<cert.pem...>
 
 One or more certificates of message recipients: used when encrypting
diff --git a/doc/man1/speed.pod b/doc/man1/speed.pod
index b0d4daa..0e5bb57 100644
--- a/doc/man1/speed.pod
+++ b/doc/man1/speed.pod
@@ -12,6 +12,8 @@ B<openssl speed>
 [B<-elapsed>]
 [B<-evp algo>]
 [B<-decrypt>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<algorithm...>]
 
 =head1 DESCRIPTION
@@ -48,6 +50,19 @@ Use the specified cipher or message digest algorithm via the EVP interface.
 
 Time the decryption instead of encryption. Affects only the EVP testing.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<[zero or more test algorithms]>
 
 If any options are given, B<speed> tests those algorithms, otherwise all of
diff --git a/doc/man1/ts.pod b/doc/man1/ts.pod
index c04a623..56ace24 100644
--- a/doc/man1/ts.pod
+++ b/doc/man1/ts.pod
@@ -8,7 +8,8 @@ ts - Time Stamping Authority tool (client/server)
 
 B<openssl> B<ts>
 B<-query>
-[B<-rand> file:file...]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-config> configfile]
 [B<-data> file_to_hash]
 [B<-digest> digest_bytes]
@@ -131,11 +132,18 @@ request with the following options:
 
 =over 4
 
-=item B<-rand> file:file...
+=item B<-rand file...>
 
-The files containing random data for seeding the random number
-generator. Multiple files can be specified, the separator is B<;> for
-MS-Windows, B<,> for VMS and B<:> for all other platforms. (Optional)
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
 
 =item B<-config> configfile
 
diff --git a/doc/man1/x509.pod b/doc/man1/x509.pod
index 587c630..68fbf81 100644
--- a/doc/man1/x509.pod
+++ b/doc/man1/x509.pod
@@ -59,6 +59,8 @@ B<openssl> B<x509>
 [B<-clrext>]
 [B<-extfile filename>]
 [B<-extensions section>]
+[B<-rand file...>]
+[B<-writerand file>]
 [B<-engine id>]
 [B<-preserve_dates>]
 
@@ -115,6 +117,19 @@ Any digest supported by the OpenSSL B<dgst> command can be used.
 If not specified then SHA1 is used with B<-fingerprint> or
 the default digest for the signing algorithm is used, typically SHA256.
 
+=item B<-rand file...>
+
+A file or files containing random data used to seed the random number
+generator.
+Multiple files can be specified separated by an OS-dependent character.
+The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
+all others.
+
+=item [B<-writerand file>]
+
+Writes random data to the specified I<file> upon exit.
+This can be used with a subsequent B<-rand> flag.
+
 =item B<-engine id>
 
 Specifying an engine (by its unique B<id> string) will cause B<x509>


More information about the openssl-commits mailing list