Commit a35f607c authored by Rich Salz's avatar Rich Salz
Browse files

Make RAND_DRBG fork-safe



Use atfork to count child forks, and reseed DRBG when the counts don't
match.

Reviewed-by: default avatarPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/4101)
parent 99801878
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -9,6 +9,11 @@
 Changes between 1.1.0f and 1.1.1 [xx XXX xxxx]
 Changes between 1.1.0f and 1.1.1 [xx XXX xxxx]
  *) Add "atfork" functions.  If building on a system that without
     pthreads, see doc/man3/OPENSSL_fork_prepare.pod for application
     requirements.  The RAND facility now uses/requires this.
     [Rich Salz]
  *) Add SHA3.
  *) Add SHA3.
     [Andy Polyakov]
     [Andy Polyakov]
+1 −0
Original line number Original line Diff line number Diff line
@@ -18,3 +18,4 @@
#include <openssl/rand.h>
#include <openssl/rand.h>


void rand_cleanup_int(void);
void rand_cleanup_int(void);
void rand_fork(void);
+1 −0
Original line number Original line Diff line number Diff line
@@ -704,5 +704,6 @@ void OPENSSL_fork_parent(void)


void OPENSSL_fork_child(void)
void OPENSSL_fork_child(void)
{
{
    rand_fork();
}
}
#endif
#endif
+6 −1
Original line number Original line Diff line number Diff line
@@ -72,7 +72,7 @@ RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
    }
    }
    drbg->size = RANDOMNESS_NEEDED;
    drbg->size = RANDOMNESS_NEEDED;
    drbg->randomness = ucp;
    drbg->randomness = ucp;

    drbg->fork_count = rand_fork_count;
    drbg->parent = parent;
    drbg->parent = parent;
    if (RAND_DRBG_set(drbg, type, flags) < 0)
    if (RAND_DRBG_set(drbg, type, flags) < 0)
        goto err;
        goto err;
@@ -266,6 +266,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
        return 0;
        return 0;
    }
    }


    if (drbg->fork_count != rand_fork_count) {
        drbg->fork_count = rand_fork_count;
        drbg->state = DRBG_RESEED;
    }

    if (drbg->reseed_counter >= drbg->reseed_interval)
    if (drbg->reseed_counter >= drbg->reseed_interval)
        drbg->state = DRBG_RESEED;
        drbg->state = DRBG_RESEED;


+4 −0
Original line number Original line Diff line number Diff line
@@ -88,6 +88,7 @@ struct rand_drbg_st {
    CRYPTO_RWLOCK *lock;
    CRYPTO_RWLOCK *lock;
    RAND_DRBG *parent;
    RAND_DRBG *parent;
    int nid; /* the underlying algorithm */
    int nid; /* the underlying algorithm */
    int fork_count;
    unsigned short flags; /* various external flags */
    unsigned short flags; /* various external flags */
    unsigned short filled;
    unsigned short filled;
    /*
    /*
@@ -127,6 +128,9 @@ extern RAND_BYTES_BUFFER rand_bytes;
extern RAND_DRBG rand_drbg;
extern RAND_DRBG rand_drbg;
extern RAND_DRBG priv_drbg;
extern RAND_DRBG priv_drbg;


/* How often we've forked (only incremented in child). */
extern int rand_fork_count;

/* Hardware-based seeding functions. */
/* Hardware-based seeding functions. */
void rand_read_tsc(RAND_poll_fn cb, void *arg);
void rand_read_tsc(RAND_poll_fn cb, void *arg);
int rand_read_cpu(RAND_poll_fn cb, void *arg);
int rand_read_cpu(RAND_poll_fn cb, void *arg);
Loading