Patch to enable multiple possible sources of entropy
mouring at etoh.eviladmin.org
mouring at etoh.eviladmin.org
Mon Jun 11 03:49:18 EST 2001
Hmm.. my only complaints about the patch is that seed_rng and init_rng are
pretty unreadable due to #ifdef/#end, and that I don't know if I like the
idea of ssh/sshd stepping down in entropy quality on a whim. Which is
what this patch would do if for some odd reason prngd is offline at
startup of sshd/ssh.
- Ben
On Thu, 7 Jun 2001, Dave Dykstra wrote:
> I have a need to have the same OpenSSH binaries run on multiple machines
> which are administered by different people. That means on Solaris, for
> example, there will be some with /dev/random, some on which I can run prngd
> because they'll be installing my binaries as root, and some which will have
> neither because they will be only installed as non-root. Below is a patch
> to enable choosing all 3 possible sources at compile time, with the
> available source selected at run time. If no configure parameters are
> given, it will still determine the entropy source at compile time and only
> the code for the one type, exactly as it does today. The patch adds a
> configure option called --with-builtin-entropy.
>
> I have tested this in all possible combinations of entropy sources, and on
> 6 different flavors of Unix (linux, solaris, sunos4, hpux, irix, and
> unixware1). The patch is against 2.9p1 but applies cleanly to the current
> CVS. Please accept this patch into the openssh code base. Don't forget to
> run autoheader and autoconf.
>
> - Dave Dykstra
>
> *** entropy.c.O Fri Jun 1 15:52:20 2001
> --- entropy.c Tue Jun 5 17:41:47 2001
> ***************
> *** 80,91 ****
> # define USE_PRNGD
> #endif
>
> - #if defined(USE_PRNGD) || defined(RANDOM_POOL)
> -
> #ifdef USE_PRNGD
> /* Collect entropy from PRNGD/EGD */
> int
> ! get_random_bytes(unsigned char *buf, int len)
> {
> int fd;
> char msg[2];
> --- 80,89 ----
> # define USE_PRNGD
> #endif
>
> #ifdef USE_PRNGD
> /* Collect entropy from PRNGD/EGD */
> int
> ! prngd_get_random_bytes(unsigned char *buf, int len)
> {
> int fd;
> char msg[2];
> ***************
> *** 100,110 ****
> --- 98,110 ----
> memset(&addr, '\0', sizeof(addr));
>
> #ifdef PRNGD_PORT
> + debug2("Opening entropy socket on localhost port %d", PRNGD_PORT);
> addr.sin_family = AF_INET;
> addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
> addr.sin_port = htons(PRNGD_PORT);
> addr_len = sizeof(struct sockaddr_in);
> #else /* use IP socket PRNGD_SOCKET instead */
> + debug2("Opening entropy socket at %s", PRNGD_SOCKET);
> /* Sanity checks */
> if (sizeof(PRNGD_SOCKET) > sizeof(addr.sun_path))
> fatal("Random pool path is too long");
> ***************
> *** 179,192 ****
> close(fd);
> return(rval);
> }
> ! #else /* !USE_PRNGD */
> #ifdef RANDOM_POOL
> /* Collect entropy from /dev/urandom or pipe */
> int
> ! get_random_bytes(unsigned char *buf, int len)
> {
> int random_pool;
>
> random_pool = open(RANDOM_POOL, O_RDONLY);
> if (random_pool == -1) {
> error("Couldn't open random pool \"%s\": %s",
> --- 179,194 ----
> close(fd);
> return(rval);
> }
> ! #endif /* !USE_PRNGD */
> !
> #ifdef RANDOM_POOL
> /* Collect entropy from /dev/urandom or pipe */
> int
> ! pool_get_random_bytes(unsigned char *buf, int len)
> {
> int random_pool;
>
> + debug2("Opening random pool at %s", RANDOM_POOL);
> random_pool = open(RANDOM_POOL, O_RDONLY);
> if (random_pool == -1) {
> error("Couldn't open random pool \"%s\": %s",
> ***************
> *** 206,242 ****
> return(1);
> }
> #endif /* RANDOM_POOL */
> - #endif /* USE_PRNGD */
> -
> - /*
> - * Seed OpenSSL's random number pool from Kernel random number generator
> - * or PRNGD/EGD
> - */
> - void
> - seed_rng(void)
> - {
> - unsigned char buf[32];
> -
> - debug("Seeding random number generator");
> -
> - if (!get_random_bytes(buf, sizeof(buf))) {
> - if (!RAND_status())
> - fatal("Entropy collection failed and entropy exhausted");
> - } else {
> - RAND_add(buf, sizeof(buf), sizeof(buf));
> - }
> -
> - memset(buf, '\0', sizeof(buf));
> - }
> -
> - void
> - init_rng(void)
> - {
> - check_openssl_version();
> - }
> -
> - #else /* defined(USE_PRNGD) || defined(RANDOM_POOL) */
>
> /*
> * FIXME: proper entropy estimations. All current values are guesses
> * FIXME: (ATL) do estimates at compile time?
> --- 208,215 ----
> return(1);
> }
> #endif /* RANDOM_POOL */
>
> + #ifdef USE_BUILTIN_ENTROPY
> /*
> * FIXME: proper entropy estimations. All current values are guesses
> * FIXME: (ATL) do estimates at compile time?
> ***************
> *** 834,840 ****
> * syscalls and program output
> */
> void
> ! seed_rng(void)
> {
> mysig_t old_sigchld_handler;
>
> --- 807,813 ----
> * syscalls and program output
> */
> void
> ! prng_seed_rng(void)
> {
> mysig_t old_sigchld_handler;
>
> ***************
> *** 860,871 ****
> }
>
> void
> ! init_rng(void)
> {
> int original_euid;
>
> - check_openssl_version();
> -
> original_uid = getuid();
> original_euid = geteuid();
>
> --- 833,842 ----
> }
>
> void
> ! prng_init_rng(void)
> {
> int original_euid;
>
> original_uid = getuid();
> original_euid = geteuid();
>
> ***************
> *** 912,915 ****
> prng_initialised = 1;
> }
>
> ! #endif /* defined(USE_PRNGD) || defined(RANDOM_POOL) */
> --- 883,979 ----
> prng_initialised = 1;
> }
>
> ! #endif /* USE_BUILTIN_ENTROPY */
> !
> ! #define BUILTIN_SOURCE 1
> ! #define PRNGD_SOURCE 2
> ! #define POOL_SOURCE 3
> !
> ! static int seed_source = 0;
> !
> ! void
> ! init_rng(void)
> ! {
> ! check_openssl_version();
> !
> ! #ifdef RANDOM_POOL
> ! #if !defined(USE_PRNGD) && !defined(USE_BUILTIN_ENTROPY)
> ! seed_source = POOL_SOURCE;
> ! #else
> ! if (access(RANDOM_POOL, R_OK) == 0) {
> ! seed_source = POOL_SOURCE;
> ! return;
> ! }
> ! #endif
> ! #endif /* RANDOM_POOL */
> !
> ! /* it's not trivial to probe for an open port so just make it
> ! * take priority over the other sources if it is defined
> ! */
> ! #ifdef PRNGD_PORT
> ! seed_source = PRNGD_SOURCE;
> ! #else
> !
> ! #ifdef PRNGD_SOCKET
> ! #ifndef USE_BUILTIN_ENTROPY
> ! seed_source = PRNGD_SOURCE;
> ! #else
> ! if (access(PRNGD_SOCKET, R_OK) == 0) {
> ! seed_source = PRNGD_SOURCE;
> ! return;
> ! }
> ! #endif /* USE_BUILTIN_ENTROPY */
> ! #endif /* PRNGD_SOCKET */
> !
> ! #ifdef USE_BUILTIN_ENTROPY
> ! seed_source = BUILTIN_SOURCE;
> ! prng_init_rng();
> ! #endif
> !
> ! #endif /* PRNGD_PORT */
> !
> ! if (seed_source == 0)
> ! fatal("Couldn't find source for random number generator seed");
> ! }
> !
> ! /*
> ! * Seed OpenSSL's random number pool
> ! */
> ! void
> ! seed_rng(void)
> ! {
> ! unsigned char buf[32];
> ! int ret;
> !
> ! debug("Seeding random number generator");
> !
> ! switch (seed_source) {
> ! #ifdef USE_BUILTIN_ENTROPY
> ! case BUILTIN_SOURCE:
> ! prng_seed_rng();
> ! return;
> ! #endif
> ! #ifdef USE_PRNGD
> ! case PRNGD_SOURCE:
> ! ret = prngd_get_random_bytes(buf, sizeof(buf));
> ! break;
> ! #endif
> ! #ifdef RANDOM_POOL
> ! case POOL_SOURCE:
> ! ret = pool_get_random_bytes(buf, sizeof(buf));
> ! break;
> ! #endif
> ! }
> !
> ! #if defined(USE_PRNGD) || defined(RANDOM_POOL)
> ! if (!ret) {
> ! if (!RAND_status())
> ! fatal("Entropy collection failed and entropy exhausted");
> ! } else {
> ! RAND_add(buf, sizeof(buf), sizeof(buf));
> ! }
> !
> ! memset(buf, '\0', sizeof(buf));
> ! #endif
> ! }
> !
> *** configure.in.O Mon Jun 4 12:25:12 2001
> --- configure.in Thu Jun 7 13:37:09 2001
> ***************
> *** 1334,1340 ****
> ]
> )
>
> ! # Check for PRNGD/EGD pool file
> AC_ARG_WITH(prngd-port,
> [ --with-prngd-port=PORT read entropy from PRNGD/EGD localhost:PORT],
> [
> --- 1334,1340 ----
> ]
> )
>
> ! # Check for PRNGD/EGD pool port request
> AC_ARG_WITH(prngd-port,
> [ --with-prngd-port=PORT read entropy from PRNGD/EGD localhost:PORT],
> [
> ***************
> *** 1349,1354 ****
> --- 1349,1357 ----
> AC_ARG_WITH(prngd-socket,
> [ --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)],
> [
> + if test ! -z "$PRNGD_PORT" ; then
> + AC_MSG_ERROR([*** cannot use both --with-prngd-port and --with-prngd-socket])
> + fi
> if test "x$withval" != "xno" ; then
> PRNGD_SOCKET="$withval"
> AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET")
> ***************
> *** 1375,1385 ****
> ]
> )
>
>
> # detect pathnames for entropy gathering commands, if we need them
> INSTALL_SSH_PRNG_CMDS=""
> rm -f prng_commands
> ! if (test -z "$RANDOM_POOL" && test -z "$PRNGD") ; then
> # Use these commands to collect entropy
> OSSH_PATH_ENTROPY_PROG(PROG_LS, ls)
> OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat)
> --- 1378,1406 ----
> ]
> )
>
> + # Check for use of builtin entropy collector
> + AC_ARG_WITH(builtin-entropy,
> + [ --with-builtin-entropy use builtin entropy collector if nothing else available],
> + [
> + if test ! -z "$PRNGD_PORT" ; then
> + AC_MSG_ERROR([*** cannot use both --with-prngd-port and --with-builtin-entropy])
> + fi
> + BUILTIN_RNG=1
> + ],
> + [
> + # Only select by default if don't have another method
> + if test -z "$RANDOM_POOL" && test -z "$PRNGD" ; then
> + BUILTIN_RNG=1
> + fi
> + ]
> + )
>
> # detect pathnames for entropy gathering commands, if we need them
> INSTALL_SSH_PRNG_CMDS=""
> rm -f prng_commands
> ! if test ! -z "$BUILTIN_RNG" ; then
> ! AC_DEFINE(USE_BUILTIN_ENTROPY)
> !
> # Use these commands to collect entropy
> OSSH_PATH_ENTROPY_PROG(PROG_LS, ls)
> OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat)
> ***************
> *** 1885,1901 ****
>
> # Print summary of options
>
> ! if test ! -z "$RANDOM_POOL" ; then
> ! RAND_MSG="Device ($RANDOM_POOL)"
> ! else
> ! if test ! -z "$PRNGD_PORT" ; then
> ! RAND_MSG="PRNGD/EGD (port localhost:$PRNGD_PORT)"
> ! elif test ! -z "$PRNGD_SOCKET" ; then
> ! RAND_MSG="PRNGD/EGD (socket $PRNGD_SOCKET)"
> else
> ! RAND_MSG="Builtin (timeout $entropy_timeout)"
> ! BUILTIN_RNG=1
> fi
> fi
>
> # Someone please show me a better way :)
> --- 1906,1930 ----
>
> # Print summary of options
>
> ! RAND_MSG=""
> ! randmsg()
> ! {
> ! if test -z "$RAND_MSG" ; then
> ! RAND_MSG="$1"
> else
> ! RAND_MSG="$RAND_MSG or $1"
> fi
> + }
> + if test ! -z "$RANDOM_POOL" ; then
> + randmsg "Device ($RANDOM_POOL)"
> + fi
> + if test ! -z "$PRNGD_PORT" ; then
> + randmsg "PRNGD/EGD (port localhost:$PRNGD_PORT)"
> + elif test ! -z "$PRNGD_SOCKET" ; then
> + randmsg "PRNGD/EGD (socket $PRNGD_SOCKET)"
> + fi
> + if test ! -z "$BUILTIN_RNG" ; then
> + randmsg "Builtin (timeout $entropy_timeout)"
> fi
>
> # Someone please show me a better way :)
> *** acconfig.h.O Mon Jun 4 12:42:09 2001
> --- acconfig.h Mon Jun 4 13:53:36 2001
> ***************
> *** 95,100 ****
> --- 95,103 ----
> /* Port number of PRNGD/EGD random number socket */
> #undef PRNGD_PORT
>
> + /* Use builtin entropy collector if nothing else available */
> + #undef USE_BUILTIN_ENTROPY
> +
> /* Builtin PRNG command timeout */
> #undef ENTROPY_TIMEOUT_MSEC
>
>
More information about the openssh-unix-dev
mailing list