diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.in | 16 | ||||
-rw-r--r-- | src/havege.c | 36 | ||||
-rw-r--r-- | src/havege.h | 11 | ||||
-rw-r--r-- | src/havegecmd.c | 22 | ||||
-rw-r--r-- | src/havegecmd.h | 6 | ||||
-rw-r--r-- | src/havegecollect.c | 2 | ||||
-rw-r--r-- | src/havegecollect.h | 2 | ||||
-rw-r--r-- | src/haveged.c | 150 | ||||
-rw-r--r-- | src/haveged.h | 10 | ||||
-rw-r--r-- | src/havegetest.c | 2 | ||||
-rw-r--r-- | src/havegetest.h | 2 | ||||
-rw-r--r-- | src/havegetune.c | 2 | ||||
-rw-r--r-- | src/havegetune.h | 2 | ||||
-rw-r--r-- | src/oneiteration.h | 2 |
14 files changed, 199 insertions, 66 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 559af60..cb0a506 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -207,8 +207,6 @@ am__define_uniq_tagged_files = \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ @@ -223,6 +221,8 @@ CC = @CC@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DLLTOOL = @DLLTOOL@ @@ -232,13 +232,13 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVEGE_LT_VERSION = @HAVEGE_LT_VERSION@ -HA_DISTRO = @HA_DISTRO@ HA_LDFLAGS = @HA_LDFLAGS@ -HA_UNITD = @HA_UNITD@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -318,6 +318,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -620,7 +621,6 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am @@ -659,6 +659,8 @@ check: check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES +install-sbinPROGRAMS: install-libLTLIBRARIES + installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ diff --git a/src/havege.c b/src/havege.c index b0070d1..c897113 100644 --- a/src/havege.c +++ b/src/havege.c @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** Copyright 2011-2012 BenEleventh Consulting manolson@beneleventh.com ** @@ -114,7 +114,7 @@ H_PTR havege_create( /* RETURN: app state */ n = 1; if (0 == sz) sz = DEFAULT_BUFSZ; - anchor = (H_SETUP *)calloc(sizeof(H_SETUP),1); + anchor = (H_SETUP *)calloc(1, sizeof(H_SETUP)); if (NULL==anchor) return h; h = &anchor->info; @@ -317,7 +317,7 @@ int havege_status_dump( /* RETURN: output length */ { struct h_status status; int n = 0; - + if (buf != 0) { *buf = 0; len -= 1; @@ -346,7 +346,7 @@ int havege_status_dump( /* RETURN: output length */ case H_SD_TOPIC_TEST: { H_UINT m; - + if (strlen(status.tot_tests)>0) { n += snprintf(buf+n, len-n, "tot tests(%s): ", status.tot_tests); if ((m = status.n_tests[ H_OLT_TOT_A_P] + status.n_tests[ H_OLT_TOT_A_F])>0) @@ -368,19 +368,29 @@ int havege_status_dump( /* RETURN: output length */ case H_SD_TOPIC_SUM: { char units[] = {'T', 'G', 'M', 'K', 0}; - double factor = 1024.0 * 1024.0 * 1024.0 * 1024.0; + double factor[2]; + factor[0] = 1024.0 * 1024.0 * 1024.0 * 1024.0; + factor[1] = factor[0]; double sz = ((double)hptr->n_fills * hptr->i_collectSz) * sizeof(H_UINT); - int i; - - for (i=0;0 != units[i];i++) { - if (sz >= factor) + double ent = ((double) hptr->n_entropy_bytes); + int i[2]; + + for (i[0]=0;0 != units[i[0]];i[0]++) { + if (sz >= factor[0]) + break; + factor[0] /= 1024.0; + } + for (i[1]=0;0 != units[i[1]];i[1]++) { + if (ent >= factor[1]) break; - factor /= 1024.0; + factor[1] /= 1024.0; } - n = snprintf(buf, len, "fills: %u, generated: %.4g %c bytes", + n = snprintf(buf, len, "fills: %u, generated: %.4g %c bytes, RNDADDENTROPY: %.4g %c bytes", hptr->n_fills, - sz / factor, - units[i] + sz / factor[0], + units[i[0]], + ent / factor[1], + units[i[1]] ); } break; diff --git a/src/havege.h b/src/havege.h index 1483c69..e12ec64 100644 --- a/src/havege.h +++ b/src/havege.h @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** Copyright 2011-2012 BenEleventh Consulting manolson@beneleventh.com ** @@ -31,7 +31,7 @@ extern "C" { * header/package version as a numeric major, minor, patch triple. See havege_version() * below for usage. */ -#define HAVEGE_PREP_VERSION "1.9.14" +#define HAVEGE_PREP_VERSION "1.9.19" /** * Basic types */ @@ -56,7 +56,7 @@ typedef void (*pMsg)(const char *format, ...); typedef int (*pRawIn)(volatile H_UINT *pData, H_UINT szData); /** * options for H_PARAMS below. Lower byte transferred from verbose settings - * upper byte set by diagnositic run options + * upper byte set by diagnositic run options */ #define H_VERBOSE 0x001 /* deprecated from ver 1.7 */ #define H_DEBUG_INFO 0x001 /* Show config info, retries */ @@ -65,14 +65,16 @@ typedef int (*pRawIn)(volatile H_UINT *pData, H_UINT szData); #define H_DEBUG_LOOP 0x008 /* Show loop parameters */ #define H_DEBUG_COMPILE 0x010 /* Show assembly info */ #define H_DEBUG_OLT 0x020 /* Show all test info */ +#define H_RNDADDENTROPY_INFO 0x040 /* RNDADDENTROPY info */ #define H_DEBUG_RAW_OUT 0x100 /* diagnostic output */ #define H_DEBUG_RAW_IN 0x200 /* diagnostic input */ #define H_DEBUG_TEST_IN 0x400 /* input test data */ + /** * Initialization parameters. Use non-zero values to override default values. * Notes: - * + * * 1) Correspondence between provided value and value of H_PTR members are: * ioSz <==> i_readSz, collectSize <==> i_collectSz, nCores <==> n_cores, * options <==> havege_opts @@ -159,6 +161,7 @@ typedef struct h_anchor { H_UINT m_sz; /* size of thread ipc area (bytes) */ H_UINT n_cores; /* number of cores */ H_UINT n_fills; /* number of buffer fills */ + size_t n_entropy_bytes; /* total amount of entropy (byte) */ } *H_PTR; /** * Fail/Success counters for tot and production tests. diff --git a/src/havegecmd.c b/src/havegecmd.c index 9ced105..e87767e 100644 --- a/src/havegecmd.c +++ b/src/havegecmd.c @@ -1,7 +1,7 @@ /** ** Provide HAVEGE socket communication API ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2018 Werner Fink <werner@suse.de> ** ** This program is free software: you can redistribute it and/or modify @@ -39,6 +39,7 @@ #include <sys/stat.h> #include <sys/un.h> #include <unistd.h> +#include <semaphore.h> #ifndef HAVE_STRUCT_UCRED struct ucred @@ -54,6 +55,7 @@ struct ucred int first_byte; int socket_fd; static char errmsg[1024]; +extern sem_t *sem; static int new_root( /* RETURN: status */ const char *root, /* IN: path of the new root file system */ @@ -95,6 +97,7 @@ static int new_root( /* RETURN: status */ strerror(errno)); goto err; } + sem_close(sem); ret = execv((const char *)path, argv); if (ret < 0) { snprintf(&errmsg[0], sizeof(errmsg)-1, @@ -265,8 +268,14 @@ int socket_handler( /* RETURN: closed file descriptor */ } if (magic[1] == '\002') { /* ASCII start of text: read argument provided */ - uint32_t alen; - + uint32_t alen = 0; + + /* + * wait for the haveged -c instance to finish writting + * before continuing to read from the socket + */ + sem_wait(sem); + sem_post(sem); ret = receive_uinteger(fd, &alen); if (ret < 0) { print_msg("%s: can not read from UNIX socket\n", params->daemon); @@ -285,6 +294,11 @@ int socket_handler( /* RETURN: closed file descriptor */ print_msg("%s: can not read from UNIX socket\n", params->daemon); goto out; } + /* + * We no more need the semaphore unlink it + * Not sure if it is the best place to unlink here + */ + sem_unlink(SEM_NAME); } clen = sizeof(struct ucred); @@ -444,7 +458,7 @@ int receive_uinteger( /* RETURN: status */ int fd, /* IN: file descriptor */ uint32_t *value) /* OUT: 32 bit unsigned integer */ { - uint8_t buffer[4]; + uint8_t buffer[4] = {0}; if (safein(fd, buffer, 4 * sizeof(uint8_t)) < 0) return -1; diff --git a/src/havegecmd.h b/src/havegecmd.h index 19a1823..5394147 100644 --- a/src/havegecmd.h +++ b/src/havegecmd.h @@ -1,7 +1,7 @@ /** ** Provide HAVEGE socket communication API ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2018 Werner Fink <werner@suse.de> ** ** This program is free software: you can redistribute it and/or modify @@ -40,7 +40,7 @@ extern "C" { #define ASCII_ACK "\x6" /* ASCII acknowledge */ #define ASCII_NAK "\x15" /* ASCII negative acknowledge */ #define ASCII_STX "\x2" /* ASCII start of text */ - + #ifndef SOCK_CLOEXEC #define SOCK_CLOEXEC 0 #endif @@ -49,6 +49,8 @@ extern "C" { #define SOCK_NONBLOCK 0 #endif +#define SEM_NAME "haveged_sem" + /** * Open and listen on a UNIX socket to get command from there */ diff --git a/src/havegecollect.c b/src/havegecollect.c index 1c82e51..71f353a 100644 --- a/src/havegecollect.c +++ b/src/havegecollect.c @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** Copyright 2011-2012 BenEleventh Consulting manolson@beneleventh.com ** diff --git a/src/havegecollect.h b/src/havegecollect.h index 55ffbfb..933297f 100644 --- a/src/havegecollect.h +++ b/src/havegecollect.h @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** Copyright 2011-2012 BenEleventh Consulting manolson@beneleventh.com ** diff --git a/src/haveged.c b/src/haveged.c index b9cb77b..b69ffda 100644 --- a/src/haveged.c +++ b/src/haveged.c @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2024 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** Copyright 2011-2012 BenEleventh Consulting manolson@beneleventh.com ** @@ -19,7 +19,9 @@ ** along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "config.h" +#if defined(HAVE_SYS_AUXV_H) #include <sys/auxv.h> +#endif #include <stdlib.h> #include <stdio.h> #include <getopt.h> @@ -31,6 +33,8 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <time.h> +#include <semaphore.h> #ifndef NO_DAEMON #include <syslog.h> @@ -57,7 +61,7 @@ // {{{ VERSION_TEXT static const char* VERSION_TEXT = "haveged %s\n\n" - "Copyright (C) 2018-2021 Jirka Hladky <hladky.jiri@gmail.com>\n" + "Copyright (C) 2018-2024 Jirka Hladky <hladky.jiri@gmail.com>\n" "Copyright (C) 2009-2014 Gary Wuertz <gary@issiweb.com>\n" "Copyright (C) 2011-2012 BenEleventh Consulting <manolson@beneleventh.com>\n\n" "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n" @@ -76,6 +80,7 @@ static struct pparams defaults = { .buffersz = 0, .detached = 0, .foreground = 0, + .once = 0, .d_cache = 0, .i_cache = 0, .run_level = 0, @@ -89,7 +94,8 @@ static struct pparams defaults = { .sample_out = OUTPUT_DEFAULT, .verbose = 0, .watermark = "/proc/sys/kernel/random/write_wakeup_threshold", - .command = 0 + .command = 0, + .time_interval = TIME_INTERVAL }; struct pparams *params = &defaults; @@ -108,7 +114,7 @@ static H_PTR handle = NULL; * Local prototypes */ #ifndef NO_DAEMON -static H_UINT poolSize = 0; +static int poolSize = 0; static void daemonize(void); static int get_poolsize(void); @@ -127,6 +133,8 @@ static void usage(int db, int nopts, struct option *long_options, const char **c static sigset_t mask, omask; +sem_t *sem = NULL; + #define ATOU(a) (unsigned int)atoi(a) /** * Entry point @@ -135,8 +143,10 @@ int main(int argc, char **argv) { volatile char *path = strdup(argv[0]); volatile char *arg0 = argv[0]; +#if defined(HAVE_SYS_AUXV_H) if (path[0] != '/') path = (char*)getauxval(AT_EXECFN); +#endif static const char* cmds[] = { "b", "buffer", "1", SETTINGR("Buffer size [KW], default: ",COLLECT_BUFSIZE), "d", "data", "1", SETTINGR("Data cache size [KB], with fallback to: ", GENERIC_DCACHE ), @@ -146,6 +156,7 @@ int main(int argc, char **argv) "i", "inst", "1", SETTINGR("Instruction cache size [KB], with fallback to: ", GENERIC_ICACHE), "f", "file", "1", "Sample output file, default: '" OUTPUT_DEFAULT "', '-' for stdout", "F", "Foreground", "0", "Run daemon in foreground", + "e", "once", "0", "Provide entropy to the kernel once and quit immediatelly", "r", "run", "1", "0=daemon, 1=config info, >1=<r>KB sample", "n", "number", "1", "Output size in [k|m|g|t] bytes, 0 = unlimited to stdout", "o", "onlinetest", "1", "[t<x>][c<x>] x=[a[n][w]][b[w]] 't'ot, 'c'ontinuous, default: ta8b", @@ -154,7 +165,8 @@ int main(int argc, char **argv) #if NUMBER_CORES>1 "t", "threads", "1", "Number of threads", #endif - "v", "verbose", "1", "Verbose mask 0=none,1=summary,2=retries,4=timing,8=loop,16=code,32=test", + "T", "time_interval", "1", "Time interval in seconds to add entropy unconditionally. Max rate/timestep is " TOSTRING(PSELECT_TIMEOUT) " seconds. Default: " TOSTRING(TIME_INTERVAL) " seconds.", + "v", "verbose", "1", "Verbose mask 0=none,1=summary,2=retries,4=timing,8=loop,16=code,32=test,64=RNDADDENTROPY", "w", "write", "1", "Set write_wakeup_threshold [bits]", "V", "version", "0", "Print version information and exit", "h", "help", "0", "This help" @@ -190,7 +202,9 @@ int main(int argc, char **argv) params->setup |= MULTI_CORE; #endif - first_byte = arg0[0]; +#ifndef NO_COMMAND_MODE + first_byte = arg0[0]; +#endif if (access("/etc/initrd-release", F_OK) >= 0) { arg0[0] = '@'; path[0] = '/'; @@ -251,7 +265,7 @@ int main(int argc, char **argv) if (0 == (params->setup & MULTI_CORE)) continue; break; - case 'p': case 'w': case 'F': + case 'p': case 'w': case 'F': case 'T': if (0 !=(params->setup & RUN_AS_APP)) continue; break; @@ -262,17 +276,27 @@ int main(int argc, char **argv) long_options[i].val = cmds[j][0]; strcat(short_options,cmds[j]); if (long_options[i].has_arg!=0) strcat(short_options,":"); + // printf("Long option number %u\n", i); + // printf("name\t%s\n", long_options[i].name); + // printf("has_arg\t%d\n", long_options[i].has_arg); + i += 1; } memset(&long_options[i], 0, sizeof(struct option)); + // printf("Short %s\n", short_options); do { c = getopt_long (argc, argv, short_options, long_options, NULL); + // printf("Char %c\n", c); switch(c) { case 'F': params->setup |= RUN_IN_FG; params->foreground = 1; break; + case 'e': + params->setup |= RUN_ONCE; + params->once = 1; + break; case 'b': params->buffersz = ATOU(optarg) * 1024; if (params->buffersz<4) @@ -321,6 +345,9 @@ int main(int argc, char **argv) if (params->ncores > NUMBER_CORES) error_exit("invalid thread count: %s", optarg); break; + case 'T': + params->time_interval = ATOU(optarg); + break; case 'v': params->verbose = ATOU(optarg); break; @@ -347,6 +374,15 @@ int main(int argc, char **argv) fd_set read_fd; sigset_t block; + /* init semaphore */ + sem = sem_open(SEM_NAME, 0); + if (sem == NULL) { + print_msg("sem_open() failed \n"); + print_msg("Error : %s \n", strerror(errno)); + ret = -1; + goto err; + } + socket_fd = cmd_connect(params); if (socket_fd < 0) { ret = -1; @@ -364,9 +400,19 @@ int main(int argc, char **argv) root = optarg; size = (uint32_t)strlen(root)+1; cmd[1] = '\002'; + /* + * Synchronise haveged -c instance and daemon instance + * prevent daemon instance from readin messages + * from the socket until the -c instance finish writting + */ + sem_wait(sem); safeout(socket_fd, &cmd[0], 2); send_uinteger(socket_fd, size); safeout(socket_fd, root, size); + /* + * unblock the daemon instance as we finished writting + */ + sem_post(sem); break; case MAGIC_CLOSE: ptr = &cmd[0]; @@ -388,8 +434,8 @@ int main(int argc, char **argv) FD_SET(socket_fd, &read_fd); do { - struct timeval two = {6, 0}; - ret = select(socket_fd+1, &read_fd, NULL, NULL, &two); + struct timeval timeout = {6, 0}; + ret = select(socket_fd+1, &read_fd, NULL, NULL, &timeout); if (ret >= 0) break; if (errno != EINTR) error_exit("Select error: %s", strerror(errno)); @@ -404,7 +450,7 @@ int main(int argc, char **argv) char *msg; ret = receive_uinteger(socket_fd, &size); if (ret < 0) - goto err; + goto err; msg = calloc(size, sizeof(char)); if (!msg) error_exit("can not allocate memory for message from UNIX socket: %s", @@ -427,9 +473,10 @@ int main(int argc, char **argv) } err: close(socket_fd); + sem_close(sem); return ret; } - else { + else if (!(params->setup & RUN_AS_APP)){ socket_fd = cmd_listen(params); if (socket_fd >= 0) fprintf(stderr, "%s: command socket is listening at fd %d\n", params->daemon, socket_fd); @@ -442,6 +489,11 @@ int main(int argc, char **argv) fprintf(stderr, "%s: disabling command mode for this instance\n", params->daemon); } } + /* Initilize named semaphore to synchronize command isntances */ + sem = sem_open(SEM_NAME, O_CREAT, 0644, 1); + if (sem == NULL) { + error_exit("Couldn't create nammed semaphore " SEM_NAME" error: %s", strerror(errno)); + } } #endif if (params->tests_config == 0) @@ -586,6 +638,7 @@ static void run_daemon( /* RETURN: nothing */ #endif struct rand_pool_info *output; struct stat stat_buf; + time_t t[2]; if (0 != params->run_level) { anchor_info(h); @@ -617,8 +670,13 @@ static void run_daemon( /* RETURN: nothing */ #else sigprocmask(SIG_BLOCK, &mask, &omask); #endif + + + t[0] = 0; for(;;) { int current,nbytes,r,max=0; + H_UINT fills; + char buf[120]; fd_set write_fd; #ifndef NO_COMMAND_MODE fd_set read_fd; @@ -627,6 +685,32 @@ static void run_daemon( /* RETURN: nothing */ if (params->exit_code > 128) error_exit("Stopping due to signal %d\n", params->exit_code - 128); + t[1] = time(NULL); + if (t[1] - t[0] > params->time_interval) { + /* add entropy on daemon start and then every TIME_INTERVAL seconds unconditionally */ + nbytes = poolSize; + r = (nbytes+sizeof(H_UINT)-1)/sizeof(H_UINT); + fills = h->n_fills; + if (havege_rng(h, (H_UINT *)output->buf, r)<1) + error_exit("RNG failed! %d", h->error); + output->buf_size = nbytes; + /* entropy is 8 bits per byte */ + output->entropy_count = nbytes * 8; + if (ioctl(random_fd, RNDADDENTROPY, output) == -1) + error_exit("RNDADDENTROPY failed!"); + h->n_entropy_bytes += nbytes; + if (params->once == 1) { + params->exit_code = 0; + error_exit("Entropy refilled once (%d bytes), exiting.", nbytes); + } + if (0 != (params->verbose & H_RNDADDENTROPY_INFO) && h->n_fills > fills) { + if (havege_status_dump(h, H_SD_TOPIC_SUM, buf, sizeof(buf))>0) + print_msg("%s\n", buf); + } + t[0] = t[1]; + continue; + } + FD_ZERO(&write_fd); #ifndef NO_COMMAND_MODE if (socket_fd >= 0) { @@ -646,20 +730,23 @@ static void run_daemon( /* RETURN: nothing */ if (conn_fd > max) max = conn_fd; } - } + } #endif for(;;) { - struct timespec two = {2, 0}; + struct timespec timeout = {PSELECT_TIMEOUT, 0}; int rc; #ifndef NO_COMMAND_MODE if (socket_fd >= 0) { - rc = pselect(max+1, &read_fd, &write_fd, NULL, &two, &omask); + rc = pselect(max+1, &read_fd, &write_fd, NULL, &timeout, &omask); } else { - rc = pselect(max+1, NULL, &write_fd, NULL, &two, &omask); + rc = pselect(max+1, NULL, &write_fd, NULL, &timeout, &omask); } #else - rc = pselect(max+1, NULL, &write_fd, NULL, &two, &omask); + rc = pselect(max+1, NULL, &write_fd, NULL, &timeout, &omask); #endif + t[1] = time(NULL); + if (t[1] - t[0] > params->time_interval) break; + if (rc >= 0) break; if (params->exit_code > 128) break; @@ -686,7 +773,7 @@ static void run_daemon( /* RETURN: nothing */ if (conn_fd >= 0) continue; } - + if (conn_fd >= 0 && FD_ISSET(conn_fd, &read_fd)) conn_fd = socket_handler(conn_fd, path, argv, params); #endif @@ -696,17 +783,24 @@ static void run_daemon( /* RETURN: nothing */ if (ioctl(random_fd, RNDGETENTCNT, ¤t) == -1) error_exit("Couldn't query entropy-level from kernel"); /* get number of bytes needed to fill pool */ - nbytes = (poolSize - current)/8; + nbytes = (poolSize - current + 7)/8; if(nbytes<1) continue; /* get that many random bytes */ r = (nbytes+sizeof(H_UINT)-1)/sizeof(H_UINT); + fills = h->n_fills; if (havege_rng(h, (H_UINT *)output->buf, r)<1) error_exit("RNG failed! %d", h->error); output->buf_size = nbytes; /* entropy is 8 bits per byte */ output->entropy_count = nbytes * 8; + t[0] = t[1]; if (ioctl(random_fd, RNDADDENTROPY, output) == -1) error_exit("RNDADDENTROPY failed!"); + h->n_entropy_bytes += nbytes; + if (0 != (params->verbose & H_RNDADDENTROPY_INFO) && h->n_fills > fills) { + if (havege_status_dump(h, H_SD_TOPIC_SUM, buf, sizeof(buf))>0) + print_msg("%s\n", buf); + } } } /** @@ -717,7 +811,7 @@ static void set_watermark( /* RETURN: nothing */ { FILE *wm_fh; - if ( (H_UINT) level > (poolSize - 32)) + if ( level > (poolSize - 32)) level = poolSize - 32; wm_fh = fopen(params->watermark, "w"); if (wm_fh) { @@ -738,7 +832,7 @@ static void anchor_info(H_PTR h) char buf[120]; H_SD_TOPIC topics[4] = {H_SD_TOPIC_BUILD, H_SD_TOPIC_TUNE, H_SD_TOPIC_TEST, H_SD_TOPIC_SUM}; int i; - + for(i=0;i<4;i++) if (havege_status_dump(h, topics[i], buf, sizeof(buf))>0) print_msg("%s\n", buf); @@ -765,7 +859,7 @@ void error_exit( /* RETURN: nothing */ #endif { fprintf(stderr, "%s: %s\n", params->daemon, buffer); - if (0 !=(params->setup & RUN_AS_APP) && 0 != handle) { + if (0 !=(params->setup & (RUN_AS_APP | RUN_IN_FG) ) && 0 != handle) { if (havege_status_dump(handle, H_SD_TOPIC_TEST, buffer, sizeof(buffer))>0) fprintf(stderr, "%s\n", buffer); if (havege_status_dump(handle, H_SD_TOPIC_SUM, buffer, sizeof(buffer))>0) @@ -788,7 +882,7 @@ static int get_runsize( /* RETURN: the size */ int p2 = 0; int p10 = APP_BUFF_SIZE * sizeof(H_UINT); long long ct; - + f = strtod(bp, &suffix); if (f < 0 || strlen(suffix)>1) @@ -852,7 +946,7 @@ static char *ppSize( /* RETURN: the formatted size */ char units[] = {'T', 'G', 'M', 'K', 0}; double factor = 1024.0 * 1024.0 * 1024.0 * 1024.0; int i; - + for (i=0;0 != units[i];i++) { if (sz >= factor) break; @@ -869,7 +963,7 @@ void print_msg( /* RETURN: nothing */ ...) /* IN: args */ { char buffer[128]; - + va_list ap; va_start(ap, format); snprintf(buffer, sizeof(buffer), "%s: %s", params->daemon, format); @@ -907,7 +1001,7 @@ static void run_app( /* RETURN: nothing */ #ifdef RAW_IN_ENABLE { char *format, *in="",*out,*sz,*src=""; - + if (params->run_level==DIAG_RUN_INJECT) in = "tics"; else if (params->run_level==DIAG_RUN_TEST) @@ -922,7 +1016,7 @@ static void run_app( /* RETURN: nothing */ else sz = "unlimited"; out = (fout==stdout)? "stdout" : params->sample_out; fprintf(stderr, format, in, src, sz, out); - } + } #else if (limits) fprintf(stderr, "Writing %s output to %s\n", @@ -987,7 +1081,7 @@ static void usage( /* OUT: nothing */ const char **cmds) /* IN: associated text */ { int i, j; - + (void)loc; fprintf(stderr, "\nUsage: %s [options]\n\n", params->daemon); #ifndef NO_DAEMON @@ -999,7 +1093,7 @@ static void usage( /* OUT: nothing */ for(i=j=0;long_options[i].val != 0;i++,j+=4) { while(cmds[j][0] != long_options[i].val && (j+4) < (nopts * 4)) j += 4; - fprintf(stderr," --%-10s, -%c %s %s\n", + fprintf(stderr," --%-13s, -%c %s %s\n", long_options[i].name, long_options[i].val, long_options[i].has_arg? "[]":" ",cmds[j+3]); } diff --git a/src/haveged.h b/src/haveged.h index 6f38c17..397ca43 100644 --- a/src/haveged.h +++ b/src/haveged.h @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2024 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** ** This program is free software: you can redistribute it and/or modify @@ -32,6 +32,7 @@ struct pparams { H_UINT buffersz; /* size of collection buffer (kb) */ H_UINT detached; /* non-zero if daemonized */ H_UINT foreground; /* non-zero if running in foreground */ + H_UINT once; /* 1: refill entropy once and quit immediatelly */ H_UINT run_level; /* type of run 0=daemon,1=setup,2=pip,sample kb */ H_UINT d_cache; /* size of data cache (kb) */ H_UINT i_cache; /* size of instruction cache (kb) */ @@ -47,14 +48,20 @@ struct pparams { char *version; /* Our version */ char *watermark; /* path to write_wakeup_threshold */ char *command; /* command which will be send/received */ + H_UINT time_interval; /* Time interval in seconds to add entropy unconditionally */ }; /** * Buffer size used when not running as daemon */ +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + #define APP_BUFF_SIZE 1024 #define INPUT_DEFAULT "data" #define OUTPUT_DEFAULT "sample" #define PID_DEFAULT "/var/run/haveged.pid" +#define TIME_INTERVAL 60 +#define PSELECT_TIMEOUT 2 /** * Setup options (for app) */ @@ -67,6 +74,7 @@ struct pparams { #define SET_LWM 0x040 #define MULTI_CORE 0x080 #define CMD_MODE 0x100 +#define RUN_ONCE 0x200 /** * Default tests settings */ diff --git a/src/havegetest.c b/src/havegetest.c index 74c72b0..cee5535 100644 --- a/src/havegetest.c +++ b/src/havegetest.c @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2012-2014 Gary Wuertz gary@issiweb.com ** Copyright 2012 BenEleventh Consulting manolson@beneleventh.com ** diff --git a/src/havegetest.h b/src/havegetest.h index 8e9ac28..22b5142 100644 --- a/src/havegetest.h +++ b/src/havegetest.h @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2012-2014 Gary Wuertz gary@issiweb.com ** Copyright 2012 BenEleventh Consulting manolson@beneleventh.com ** diff --git a/src/havegetune.c b/src/havegetune.c index f558e0d..59e00c5 100644 --- a/src/havegetune.c +++ b/src/havegetune.c @@ -1,7 +1,7 @@ /** ** Determine HAVEGE environment ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** Copyright 2011-2012 BenEleventh Consulting manolson@beneleventh.com ** diff --git a/src/havegetune.h b/src/havegetune.h index 5283a0b..7db8f30 100644 --- a/src/havegetune.h +++ b/src/havegetune.h @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2014 Gary Wuertz gary@issiweb.com ** ** This program is free software: you can redistribute it and/or modify diff --git a/src/oneiteration.h b/src/oneiteration.h index e6b16d8..37a39e8 100644 --- a/src/oneiteration.h +++ b/src/oneiteration.h @@ -1,7 +1,7 @@ /** ** Simple entropy harvester based upon the havege RNG ** - ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com + ** Copyright 2018-2022 Jirka Hladky hladky DOT jiri AT gmail DOT com ** Copyright 2009-2013 Gary Wuertz gary@issiweb.com ** ** This program is free software: you can redistribute it and/or modify |