.gear/rng-tools.default | 17 ++++++ .gear/rng-tools.init | 107 +++++++++++++++++++++++++++++++++++ .gear/rng-tools.service | 8 +++ .gear/rng-tools.spec | 147 ++++++++++++++++++++++++++++++++++++++++++++++++ .gear/rules | 7 +++ .gear/tags/list | 1 + configure.ac | 7 +++ rngd.c | 2 +- rngd_jitter.c | 84 +++++++++++++++++++-------- tests/rngtestjitter.sh | 18 +++--- 10 files changed, 367 insertions(+), 31 deletions(-) diff --git a/.gear/rng-tools.default b/.gear/rng-tools.default new file mode 100644 index 0000000..b7ae677 --- /dev/null +++ b/.gear/rng-tools.default @@ -0,0 +1,17 @@ +# Configuration for the rng-tools initscript +# $Id: rng-tools.default,v 1.1.2.1.2.2 2005/05/11 09:44:51 hmh Exp $ + +# This is a POSIX shell fragment + +# Set to the input source for random data, leave undefined +# for the initscript to attempt auto-detection +#HRNGDEVICE=/dev/hwrng + +# Set to the input source for pseudo random data if hardware is absent +#HRNGDEVICE=/dev/urandom + +# Additional options to send to rngd. See the rngd(8) manpage for +# more information. Do not specify -r/--rng-device here, use +# HRNGDEVICE for that instead. +#RNGDOPTIONS="--trng=intelfwh" +#RNGDOPTIONS="--trng=via" diff --git a/.gear/rng-tools.init b/.gear/rng-tools.init new file mode 100644 index 0000000..80a8c1f --- /dev/null +++ b/.gear/rng-tools.init @@ -0,0 +1,107 @@ +#!/bin/sh +# +# rng-tools initscript for the rng-tools package +# Copr. 2003 by Henrique de Moraes Holschuh +# Copr. 2002 by Viral Shah +# +# $Id: rng-tools.init,v 1.6.2.5.2.4 2005/05/11 09:29:26 hmh Exp $ +# +# chkconfig: 2345 34 66 +# description: Hardware RNG entropy gatherer daemon + +### BEGIN INIT INFO +# Provides: rngd +# Required-Start: $network +# Required-Stop: $network +# Default-Start: +# Default-Stop: +# Short-Description: Start rngd at boot time +# Description: Hardware RNG entropy gatherer daemon +### END INIT INFO + +WITHOUT_RC_COMPAT=1 + +# Source function library. +. /etc/init.d/functions + +HRNGDEVICE=/dev/hwrng +RNGDOPTIONS= +DESC="Hardware RNG entropy gatherer daemon" + +SourceIfNotEmpty /etc/sysconfig/rngd + +DAEMON=/usr/sbin/rngd +NAME=rngd +PIDFILE=/var/run/rngd.pid +LOCKFILE=/var/lock/subsys/rngd + +DEVICELIST="hwrng hw_random hwrandom intel_rng i810_rng" + +[ -f ${DAEMON} ] || exit 0 + +finddevice () { + [ -c "$HRNGDEVICE" ] && return 0 + for i in $DEVICELIST ; do + if [ -c "/dev/$i" ] ; then + HRNGDEVICE="/dev/$i" + return 0 + fi + if [ -c "/dev/misc/$i" ] ; then + HRNGDEVICE="/dev/misc/$i" + return 0 + fi + done + + echo "(Hardware RNG device inode not found)" + echo "$0: Cannot find a hardware RNG device to use." >&2 + exit 1 +} + +start() +{ + finddevice + start_daemon --pidfile "$PIDFILE" --make-pidfile --lockfile "$LOCKFILE" --name "$NAME" -- rngd -f -r "$HRNGDEVICE" "$RNGDOPTIONS" + RETVAL=$? +} + +stop() +{ + stop_daemon --pidfile "$PIDFILE" --lockfile "$LOCKFILE" --name "$NAME" -- rngd + RETVAL=$? +} + +restart() +{ + stop + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|reload) + restart + ;; + condstop) + if [ -e "$LOCKFILE" ]; then + stop + fi + ;; + condrestart) + if [ -e "$LOCKFILE" ]; then + restart + fi + ;; + status) + status --pidfile "$PIDFILE" --expect-user root rngd + ;; + *) + echo "Usage: ${0##*/} {start|stop|reload|restart|condstop|condrestart|status}" + RETVAL=1 +esac + +exit $RETVAL diff --git a/.gear/rng-tools.service b/.gear/rng-tools.service new file mode 100644 index 0000000..0479343 --- /dev/null +++ b/.gear/rng-tools.service @@ -0,0 +1,8 @@ +[Unit] +Description=Hardware RNG Entropy Gatherer Daemon + +[Service] +ExecStart=/usr/sbin/rngd -f + +[Install] +WantedBy=multi-user.target diff --git a/.gear/rng-tools.spec b/.gear/rng-tools.spec new file mode 100644 index 0000000..c83694e --- /dev/null +++ b/.gear/rng-tools.spec @@ -0,0 +1,147 @@ +%define _unpackaged_files_terminate_build 1 +%def_with check + +Name: rng-tools +Version: 6.14 +Release: alt1.git82f665c4 + +Summary: Random number generator related utilities +License: GPLv2+ +Group: System/Kernel and hardware + +URL: https://github.com/nhorman/rng-tools +#Git: https://github.com/nhorman/rng-tools.git +Source0: %name-%version.tar +Source1: %name.init +Source2: %name.default +Source3: %name.service + +Patch0: %name-%version.patch + +# Automatically added by buildreq on Wed Apr 03 2019 +# optimized out: glibc-kernheaders-generic glibc-kernheaders-x86 gnu-config +# libsasl2-3 libssl-devel perl pkg-config python-base sh4 +BuildRequires: libcurl-devel +BuildRequires: libxml2-devel +BuildRequires: libp11-devel +BuildRequires: jitterentropy-devel +BuildRequires: libjansson-devel +BuildRequires: rtl-sdr-devel +%if_with check +BuildRequires: /proc +%endif + +Obsoletes: kernel-utils + +%description +Hardware random number generation tool. +It monitors a set of entropy sources, and supplies entropy from them +to the system kernel's /dev/random machinery. + +%prep +%setup +%patch0 -p1 + +%build +./autogen.sh +%configure +%make_build + +%install +%makeinstall_std +mkdir -p %buildroot{%_initdir,%_sysconfdir/sysconfig,%_unitdir} +install -m755 %SOURCE1 %buildroot%_initdir/rngd +install -m644 %SOURCE2 %buildroot%_sysconfdir/sysconfig/rngd +install -m644 %SOURCE3 %buildroot%_unitdir/rngd.service + +%check +make check + +%post +%post_service rngd + +%preun +%preun_service rngd + +%files +%config(noreplace) %_sysconfdir/sysconfig/rngd +%_initdir/rngd +%_unitdir/rngd.service +%_bindir/rngtest +%_bindir/randstat +%_sbindir/rngd +%_man1dir/rngtest.1* +%_man8dir/rngd.8* + +%changelog +* Mon Sep 20 2021 Nikolai Kostrigin 6.14-alt1.git82f665c4 +- Version 6.14 plus latest upstream fixes + + pack new randstat utility +- spec: add /proc to BR: due to test scripts requirement + + add check handle + +* Fri Jun 18 2021 Nikolai Kostrigin 6.13-alt1 +- Version 6.13 + +* Thu Mar 11 2021 Nikolai Kostrigin 6.12-alt1 +- Version 6.12 +- remove BR: libsysfs-devel (according to upstream code changes) + +* Fri Jan 08 2021 Nikolai Kostrigin 6.11-alt1 +- Version 6.11 + +* Mon Jun 01 2020 Nikolai Kostrigin 6.10-alt1 +- Version 6.10 +- add new BR: libjansson-devel, rtl-sdr-devel (add rtlsdr radio entropy source) +- remove BR: libgcrypt (all entropy sources now use openssl instead of gcrypt) + +* Tue Dec 17 2019 Nikolai Kostrigin 6.9-alt1 +- Version 6.9 +- remove obsolete patches + +* Tue May 28 2019 Nikolai Kostrigin 6.7-alt3 +- add upstream patch skipping periodical urandom test failures + +* Thu Apr 04 2019 Nikolai Kostrigin 6.7-alt2 +- add libgcrypt-devel to BR +- switch auto tests on + +* Wed Apr 03 2019 Nikolai Kostrigin 6.7-alt1 +- Version 6.7 +- rearrange package git repo + +* Sat Sep 01 2018 Sergey Y. Afonin 5-alt1 +- Version 5 +- added LSB init header to init script +- added example with /dev/urandom to /etc/sysconfig/rngd +- do not pack deprecated modutils.d/rng-tools + +* Mon Apr 15 2013 Dmitry V. Levin (QA) 3-alt1.qa1 +- NMU: rebuilt for debuginfo. + +* Mon Oct 25 2010 Victor Forsiuk 3-alt1 +- Version 3. + +* Thu Feb 02 2006 LAKostis 2.0-alt2 +- add some improvements from debian package (init.d script, defaults). + +* Thu Feb 02 2006 LAKostis 2.0-alt1 +- rebuild for ALTLinux. + +* Fri Dec 16 2005 Jesse Keating +- rebuilt for new gcj + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Wed Apr 13 2005 Florian La Roche +- remove empty scripts + +* Tue Mar 1 2005 Dave Jones +- Rebuild for gcc4 + +* Wed Feb 9 2005 Dave Jones +- Use $RPM_OPT_FLAGS + +* Sat Dec 18 2004 Dave Jones +- Initial packaging, based upon kernel-utils. diff --git a/.gear/rules b/.gear/rules new file mode 100644 index 0000000..7b0f34d --- /dev/null +++ b/.gear/rules @@ -0,0 +1,7 @@ +spec: .gear/rng-tools.spec +copy: .gear/*.default +copy: .gear/*.init +copy: .gear/*.service +copy?: .gear/*.patch +tar: v@version@:. +diff: v@version@:. . name=@name@-@version@.patch diff --git a/.gear/tags/list b/.gear/tags/list new file mode 100644 index 0000000..318b99f --- /dev/null +++ b/.gear/tags/list @@ -0,0 +1 @@ +c16176d3800b91f4d016b66733b384493b06f294 v6.14 diff --git a/configure.ac b/configure.ac index 9df633d..d0c2179 100644 --- a/configure.ac +++ b/configure.ac @@ -25,6 +25,7 @@ AC_CANONICAL_TARGET dnl required for broken AX_PTHREAD AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_HEADERS([rng-tools-config.h]) AC_CONFIG_MACRO_DIRS([m4]) +AC_USE_SYSTEM_EXTENSIONS dnl Parse options @@ -100,6 +101,12 @@ AS_IF( ], [AC_MSG_NOTICE([Disabling JITTER entropy source])] ) +AC_CHECK_DECL(pthread_attr_setaffinity_np, + [AC_DEFINE([HAVE_PTHREAD_ATTR_SETAFFINITY], 1,[Set ATTR_SETAFFINITY])], + [ AC_CHECK_DECL(pthread_setaffinity_np, + [AC_DEFINE([HAVE_PTHREAD_SETAFFINITY],1, [Set PTHREAD_SETAFFINITY])], [ AC_MSG_ERROR([Neither pthread_setaffinity_np nor pthread_attr_setaffinity_np found])],[[#include ]]) + ], [[#include ]]) + AS_IF( [ test "x$with_nistbeacon" != "xno"], [ diff --git a/rngd.c b/rngd.c index a358fc7..a4eaff8 100644 --- a/rngd.c +++ b/rngd.c @@ -924,7 +924,7 @@ int main(int argc, char **argv) if (!ent_sources) { message(LOG_DAEMON|LOG_ERR, - "can't open any entropy source"); + "Can't open any entropy source\n"); message(LOG_DAEMON|LOG_ERR, "Maybe RNG device modules are not loaded\n"); return 1; diff --git a/rngd_jitter.c b/rngd_jitter.c index ea29436..f74e7cd 100644 --- a/rngd_jitter.c +++ b/rngd_jitter.c @@ -46,7 +46,7 @@ static int rngd_notime_start(void *ctx, { struct jent_notime_ctx *thread_ctx = (struct jent_notime_ctx *)ctx; int ret; - int i; + long i; cpu_set_t *cpus; size_t cpusize; @@ -60,19 +60,32 @@ static int rngd_notime_start(void *ctx, /* * the soft timer function should affine to all cpus */ - i = sysconf(_SC_NPROCESSORS_CONF); + i = sysconf(_SC_NPROCESSORS_ONLN); cpus = CPU_ALLOC(i); cpusize = CPU_ALLOC_SIZE(i); CPU_ZERO_S(cpusize, cpus); - for(i=i-1;i>=0;i--) { - CPU_SET(i,cpus); + for(i=i-1; i>=0; i--) { + CPU_SET(i, cpus); } - pthread_attr_setaffinity_np(&thread_ctx->notime_pthread_attr, cpusize, cpus); + /* + * Note that only one of: + * HAVE_PTHREAD_ATTR_SETAFFINITY + * and + * HAVE_PTHREAD_SETAFFINITY + * Will ever be set, as per the configure.ac logic + */ +#ifdef HAVE_PTHREAD_ATTR_SETAFFINITY + pthread_attr_setaffinity_np(&thread_ctx->notime_pthread_attr, cpusize, cpus); +#endif ret = -pthread_create(&thread_ctx->notime_thread_id, &thread_ctx->notime_pthread_attr, start_routine, arg); +#ifdef HAVE_PTHREAD_SETAFFINITY + pthread_setaffinity_np(&thread_ctx->notime_thread_id, cpusize, cpus); +#endif + CPU_FREE(cpus); return ret; } @@ -85,9 +98,20 @@ static void rngd_notime_stop(void *ctx) pthread_attr_destroy(&thread_ctx->notime_pthread_attr); } - static int rngd_notime_init(void **ctx) { + long ncpu = sysconf(_SC_NPROCESSORS_ONLN); + + if (ncpu == -1) + return -errno; + + if (ncpu == 0) + return -EFAULT; + + // Don't allow for software thread if there is only a single cpu + if (ncpu < 2) + return -EOPNOTSUPP; + using_soft_timer = true; return jent_notime_init(ctx); } @@ -105,8 +129,9 @@ static struct jent_notime_thread rngd_notime_thread_builtin = { #define RDRAND_ROUNDS 512 /* 512:1 data reduction */ static int num_threads = 0; + struct thread_data { - struct rng *ent_src; + struct rng *ent_src; int core_id; int pipe_fd; struct rand_data *ec; @@ -118,7 +143,7 @@ struct thread_data { /* done states -1 : init, 0 : ready, 1 : complete */ int done; struct timespec slptm; - sigjmp_buf jmpbuf; + sigjmp_buf jmpbuf; }; @@ -192,8 +217,8 @@ static inline double elapsed_time(struct timespec *start, struct timespec *end) if (start->tv_nsec >= end->tv_nsec) delta = (delta * 1.0e9) + (start->tv_nsec - end->tv_nsec); else - delta = ((delta + 1) * 1.0e9) + (end->tv_nsec - start->tv_nsec); - delta = delta / 1.0e9; + delta = ((delta + 1) * 1.0e9) + (end->tv_nsec - start->tv_nsec); + delta = delta / 1.0e9; return delta; } @@ -202,7 +227,6 @@ static inline void update_sleep_time(struct thread_data *me, struct timespec *start, struct timespec *end) { - /* * if slpmode is anything other than -1 * it will be a positive integer representing @@ -233,6 +257,7 @@ void jitter_thread_exit_signal(int signum) static void *thread_entropy_task(void *data) { + sigset_t blockset; cpu_set_t cpuset; ssize_t ret; @@ -242,9 +267,15 @@ static void *thread_entropy_task(void *data) int written; /* STARTUP */ + sigemptyset(&blockset); + sigaddset(&blockset, SIGINT); + sigaddset(&blockset, SIGTERM); + sigaddset(&blockset, SIGALRM); + pthread_sigmask(SIG_BLOCK, &blockset, NULL); + /* * Set our timeout value - * -1 means adaptive, i.e. sleep for the last + * -1 means adaptive, i.e. sleep for the last * recorded execution time of a jitter read * otherwise sleep for slpmode seconds */ @@ -265,7 +296,7 @@ static void *thread_entropy_task(void *data) } /* - * A signal will call siglongjmp and return us here when we exit + * A signal will call siglongjmp and return us here when we exit */ if (sigsetjmp(me->jmpbuf, 1)) goto out_interrupt; @@ -321,7 +352,9 @@ int validate_jitter_options(struct rng *ent_src) int refill = ent_src->rng_options[JITTER_OPT_REFILL].int_val; int delay = ent_src->rng_options[JITTER_OPT_RETRY_DELAY].int_val; int rcount = ent_src->rng_options[JITTER_OPT_RETRY_COUNT].int_val; +#ifndef HAVE_JITTER_NOTIME int soft_timer = ent_src->rng_options[JITTER_OPT_FORCE_INT_TIMER].int_val; +#endif /* Need at least one thread to do this work */ if (!threads) { @@ -354,7 +387,6 @@ int validate_jitter_options(struct rng *ent_src) return 0; } - /* * Init JITTER */ @@ -362,7 +394,7 @@ int init_jitter_entropy_source(struct rng *ent_src) { cpu_set_t *cpus; size_t cpusize; - int i; + long i; int size; int flags; int entflags = 0; @@ -386,7 +418,7 @@ int init_jitter_entropy_source(struct rng *ent_src) #endif ret = jent_entropy_init(); - if(ret) { + if (ret) { message_entsrc(ent_src,LOG_DAEMON|LOG_WARNING, "JITTER rng fails with code %d\n", ret); return 1; } @@ -401,13 +433,13 @@ int init_jitter_entropy_source(struct rng *ent_src) * 2 threads for two or more cpus * 4 threads for four or more cpus */ - i = sysconf(_SC_NPROCESSORS_CONF); + i = sysconf(_SC_NPROCESSORS_ONLN); cpus = CPU_ALLOC(i); cpusize = CPU_ALLOC_SIZE(i); CPU_ZERO_S(cpusize, cpus); if (sched_getaffinity(0, cpusize, cpus) < 0) { message_entsrc(ent_src,LOG_DAEMON|LOG_DEBUG, "Can not determine affinity of process, defaulting to 1 thread\n"); - CPU_SET(0,cpus); + CPU_SET(0, cpus); } num_threads = CPU_COUNT_S(cpusize, cpus); @@ -447,6 +479,14 @@ int init_jitter_entropy_source(struct rng *ent_src) core_id++; tdata[i].buf_sz = ent_src->rng_options[JITTER_OPT_BUF_SZ].int_val; tdata[i].ec = jent_entropy_collector_alloc(1, entflags); + if (tdata[i].ec == NULL) { + message_entsrc(ent_src,LOG_DAEMON|LOG_WARNING, "Unable to start thread for jitter, likely due to lack of cpu count\n"); + close(pipefds[0]); + close(pipefds[1]); + free(tdata); + free(threads); + return 1; + } tdata[i].slpmode = ent_src->rng_options[JITTER_OPT_RETRY_DELAY].int_val; pthread_create(&threads[i], NULL, thread_entropy_task, &tdata[i]); pthread_mutex_lock(&tdata[i].statemtx); @@ -454,9 +494,9 @@ int init_jitter_entropy_source(struct rng *ent_src) pthread_cond_wait(&tdata[i].statecond, &tdata[i].statemtx); if (tdata[i].done == 1) /* we failed during startup */ - message_entsrc(ent_src, LOG_DAEMON|LOG_DEBUG, "CPU thread %d failed\n", i); + message_entsrc(ent_src, LOG_DAEMON|LOG_DEBUG, "CPU thread %ld failed\n", i); else - message_entsrc(ent_src,LOG_DAEMON|LOG_DEBUG, "CPU Thread %d is ready\n", i); + message_entsrc(ent_src,LOG_DAEMON|LOG_DEBUG, "CPU Thread %ld is ready\n", i); pthread_mutex_unlock(&tdata[i].statemtx); if (using_soft_timer == true) { num_threads = 1; @@ -516,10 +556,10 @@ void close_jitter_entropy_source(struct rng *ent_src) /* And wait for completion of each thread */ for (i=0; i < num_threads; i++) { - /* Signal the threads to exit */ - pthread_kill(threads[i], SIGUSR1); /* and wait for them to shutdown */ pthread_mutex_lock(&tdata[i].statemtx); + pthread_kill(threads[i], SIGUSR1); + /* Signal the threads to exit */ if (!tdata[i].done) { message_entsrc(ent_src,LOG_DAEMON|LOG_DEBUG, "Checking on done for thread %d\n", i); pthread_cond_wait(&tdata[i].statecond, &tdata[i].statemtx); diff --git a/tests/rngtestjitter.sh b/tests/rngtestjitter.sh index b6ebb6f..6abfec4 100755 --- a/tests/rngtestjitter.sh +++ b/tests/rngtestjitter.sh @@ -1,11 +1,13 @@ #!/bin/sh -# Test that we catch a repeating zero failure in rngtest -./rngd -f -o /dev/stdout -x hwrng -x rdrand -x tpm -O jitter:use_aes:1 | ../rngtest -c 100 --pipe > /dev/null -if [ $? -eq 0 ] -then - exit 1 -fi - -exit 0 +kill_rngd() { + sleep 15 + echo "killing" + killall -9 rngd +} + +kill_rngd & + +../rngd -f -o /dev/stdout -x hwrng -x rdrand -x tpm -O jitter:use_aes:1 | ../rngtest -c 100 --pipe > /dev/null +