On Sun, Aug 17, 2008 at 09:07:32PM +0000, Malek wrote:
> Tito a écrit :
>> On Sunday 17 August 2008 16:55:16 Malek wrote:
>>> This new applet adds the rngd daemon to Busybox like rng-tools
>>>
>>> Thanks
>>>
>>> Malek
>>>
>>
>> Hi,
>> please fix ioctl_or_perror_and_die as strerror(errno) and \n are not needed.
>>
>> -       ioctl_or_perror_and_die(random_fd, RNDADDENTROPY, entropy, 
>> "RNDADDENTROPY failed: %s\n",
>> -                       strerror(errno));
>> +       ioctl_or_perror_and_die(random_fd, RNDADDENTROPY, entropy, 
>> "RNDADDENTROPY failed: %s");
>>
>> -       ioctl_or_perror_and_die(random_fd, RNDGETENTCNT, &ent_count, 
>> "RNDGETENTCNT failed: %s\n",
>> -                       strerror(errno));
>> +       ioctl_or_perror_and_die(random_fd, RNDGETENTCNT, &ent_count, 
>> "RNDGETENTCNT failed: %s");
>>
>>
>> Ciao,
>> Tito
>>
> Ok, done
>
> Denys Vlasenko a écrit :
> > On Sunday 17 August 2008 16:55, Malek wrote:
> >> This new applet adds the rngd daemon to Busybox like rng-tools
> >
> > Can you get rid of rng_fips.h and move its contents into rngd.c?
>
> done
>
> > Otherwise, it looks ok.
> >
> > Did you create this patch because you needed it for some project?
>
> not specially
>
> >
> > Which version of rngd it is based on?
>
> It based on rng-tools 2
>
> > How much of "standard" functionality it implements?
>
> It implements all functionalities of the original rngd
>
> > Can you write a comment describing this?
> > --
> > vda
>  done in Config.in
>
> Thanks
>
> Malek

>diff -U 3 -H -d -p -r -N -- busybox.orig/include/applets.h 
>busybox/include/applets.h
>--- busybox.orig/include/applets.h     2008-08-17 07:20:15.000000000 +0000
>+++ busybox/include/applets.h  2008-08-17 12:13:47.000000000 +0000
>@@ -298,6 +298,7 @@ USE_RESTORECON(APPLET_ODDNAME(restorecon
> USE_RM(APPLET_NOFORK(rm, rm, _BB_DIR_BIN, _BB_SUID_NEVER, rm))
> USE_RMDIR(APPLET_NOFORK(rmdir, rmdir, _BB_DIR_BIN, _BB_SUID_NEVER, rmdir))
> USE_RMMOD(APPLET(rmmod, _BB_DIR_SBIN, _BB_SUID_NEVER))
>+USE_RNGD(APPLET(rngd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
> USE_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, _BB_DIR_SBIN, 
> _BB_SUID_NEVER, modprobe))
> USE_ROUTE(APPLET(route, _BB_DIR_SBIN, _BB_SUID_NEVER))
> USE_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER))
>diff -U 3 -H -d -p -r -N -- busybox.orig/include/usage.h 
>busybox/include/usage.h
>--- busybox.orig/include/usage.h       2008-08-17 07:20:15.000000000 +0000
>+++ busybox/include/usage.h    2008-08-17 12:14:54.000000000 +0000
>@@ -3277,6 +3277,42 @@
> #define rmmod_example_usage \
>        "$ rmmod tulip\n"
> 
>+#define rngd_trivial_usage \
>+       "[-bf] [-o random file] [-r rng file] [-s step] [-t nnn] [-W n]"
>+#define rngd_full_usage "\n\n" \
>+       "Check and feed random data from hardware device to kernel entropy 
>pool.\n" \
>+      "\nOptions:" \
>+      USE_FEATURE_RNGD_LONG_OPTIONS( \
>+     "\n      -b,--background         Become a daemon (default)" \
>+     "\n      -f,--foreground         Do not fork and become a daemon" \
>+     "\n      -o,--rng-device=file    Kernel device used for random number 
>output" \
>+     "\n                              (default: /dev/random)" \
>+     "\n      -r,--random-step=nnn    Kernel device used for random number 
>input" \
>+     "\n                              (default: /dev/hw_random)" \
>+     "\n      -s,--random-step=nnn    Number of bytes written to 
>random-device at a time" \
>+     "\n                              (default: 64)" \
>+     "\n      -t,--timeout=nnn        Interval written to random-device when 
>the entropy" \
>+     "\n                              pool is full, in seconds (default: 60)" 
>\
>+     "\n      -W,--fill-watermark=n   Do not stop feeding entropy to 
>random-device until" \
>+     "\n                              at least n bits of entropy are 
>available in the" \
>+     "\n                              pool (default: 2048), 0 <= n <= 4096" \
>+      ) \
>+      SKIP_FEATURE_RNGD_LONG_OPTIONS( \
>+     "\n      -b      Become a daemon (default)" \
>+     "\n      -f      Do not fork and become a daemon" \
>+     "\n      -o      Kernel device used for random number output" \
>+     "\n              (default: /dev/random)" \
>+     "\n      -r      Kernel device used for random number input" \
>+     "\n              (default: /dev/hw_random)" \
>+     "\n      -s      Number of bytes written to random-device at a time" \
>+     "\n              (default: 64)" \
>+     "\n      -t      Interval written to random-device when the entropy" \
>+     "\n              pool is full, in seconds (default: 60)" \
>+     "\n      -W      Do not stop feeding entropy to random-device until" \
>+     "\n              at least n bits of entropy are available in the" \
>+     "\n              pool (default: 2048), 0 <= n <= 4096" \
>+      )
>+
> #define route_trivial_usage \
>        "[{add|del|delete}]"
> #define route_full_usage "\n\n" \
>diff -U 3 -H -d -p -r -N -- busybox.orig/miscutils/Config.in 
>busybox/miscutils/Config.in
>--- busybox.orig/miscutils/Config.in   2008-08-17 07:20:15.000000000 +0000
>+++ busybox/miscutils/Config.in        2008-08-17 20:50:42.000000000 +0000
>@@ -448,6 +448,23 @@ config READAHEAD
>         As readahead(2) blocks until each file has been read, it is best to
>         run this applet as a background job.
> 
>+config RNGD
>+      bool "rngd"
>+      default n
>+      help
>+        Hardware random number generation daemon.
>+
>+        rngd is a daemon that feeds data from a hardware random number
>+        generator to the kernel's random number entropy pool. it improves
>+        the functioning of sshd/dropbear, stunnel...
>+
>+config FEATURE_RNGD_LONG_OPTIONS
>+      bool "Enable long options"
>+      default n
>+      depends on RNGD && GETOPT_LONG
>+      help
>+        Support long options for the rngd applet.
>+
> config RUNLEVEL
>       bool "runlevel"
>       default n
>diff -U 3 -H -d -p -r -N -- busybox.orig/miscutils/Kbuild 
>busybox/miscutils/Kbuild
>--- busybox.orig/miscutils/Kbuild      2008-08-17 07:20:15.000000000 +0000
>+++ busybox/miscutils/Kbuild   2008-08-17 12:12:24.000000000 +0000
>@@ -27,6 +27,7 @@ lib-$(CONFIG_MOUNTPOINT)  += mountpoint.
> lib-$(CONFIG_MT)          += mt.o
> lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o
> lib-$(CONFIG_READAHEAD)   += readahead.o
>+lib-$(CONFIG_RNGD)        += rngd.o
> lib-$(CONFIG_RUNLEVEL)    += runlevel.o
> lib-$(CONFIG_RX)          += rx.o
> lib-$(CONFIG_SETSID)      += setsid.o
>diff -U 3 -H -d -p -r -N -- busybox.orig/miscutils/rngd.c 
>busybox/miscutils/rngd.c
>--- busybox.orig/miscutils/rngd.c      1970-01-01 00:00:00.000000000 +0000
>+++ busybox/miscutils/rngd.c   2008-08-17 20:17:00.000000000 +0000
>@@ -0,0 +1,297 @@
>+/* vi: set sw=4 ts=4: */
>+/*
>+ * rngd implementation for busybox
>+ *
>+ * The original version was writen by Philipp Rumpf

s/writen/written/g

>+ *
>+ * Ported to busybox by Malek Degachi
>+ *
>+ * Licensed under GPLv2 or later, see file License in this tarball for 
>details.
>+ *
>+ */
>+
>+#include "libbb.h"
>+#include <syslog.h>
>+
>+#ifndef __u32
>+typedef unsigned int __u32;
>+#endif

__u32 comes from include/platform.h or from the compiler and as such
must not be defined here. Please remove it.

>+#include <linux/random.h>     /* struct rand_pool_info, RNDADDENTROPY and 
>RNDGETENTCNT */
>+
>+/**********************************************
>+ * FIPS part
>+ *********************************************/
>+
>+/*  Size of a FIPS test buffer, do not change this */
>+#define FIPS_RNG_BUFFER_SIZE 2500
>+
>+/* Context for running FIPS tests */
>+typedef struct {
>+      int poker[16];
>+      int runs[12];
>+      int ones;
>+      int rlength;
>+      int current_bit;
>+      int last_bit;
>+      int longrun;
>+      unsigned int last32;
>+} fips_ctx_t;
>+
>+/*
>+ * Return values for fips_run_rng_test. These values are OR'ed together
>+ * for all tests that failed.
>+ */
>+#define FIPS_RNG_MONOBIT              0x0001 /* FIPS 140-2 2001-10-10 monobit 
>*/
>+#define FIPS_RNG_POKER                        0x0002 /* FIPS 140-2 2001-10-10 
>poker */
>+#define FIPS_RNG_RUNS                 0x0004 /* FIPS 140-2 2001-10-10 runs */
>+#define FIPS_RNG_LONGRUN              0x0008 /* FIPS 140-2 2001-10-10 long 
>run */
>+#define FIPS_RNG_CONTINUOUS_RUN       0x0010 /* FIPS 140-2 continuous run */
>+
>+/*
>+ * fips_test_store - store 8 bits of entropy in FIPS
>+ * internal test data pool
>+ */
>+static void fips_test_store(fips_ctx_t *ctx, unsigned int rng_data)
>+{
>+      int j;
>+
>+      ctx->poker[rng_data >> 4]++;
>+      ctx->poker[rng_data & 15]++;
>+
>+      /* Note in the loop below rlength is always one less than the actual
>+         run length. This makes things easier. */
>+      for (j = 7; j >= 0; j--) {
>+              ctx->ones += ctx->current_bit = ((rng_data >> j) & 1);
>+              if (ctx->current_bit != ctx->last_bit) {
>+                      /* If runlength is 1-6 count it in correct bucket. 0's 
>go in
>+                         runs[0-5] 1's go in runs[6-11] hence the 
>6*current_bit below */
>+                      if (ctx->rlength < 5) {
>+                              ctx->runs[ctx->rlength +
>+                                   (6 * ctx->current_bit)]++;
>+                      } else {
>+                              ctx->runs[5 + (6 * ctx->current_bit)]++;
>+                      }
>+
>+                      /* Check if we just failed longrun test */
>+                      if (ctx->rlength >= 25)
>+                              ctx->longrun = 1;
>+                      ctx->rlength = 0;
>+                      /* flip the current run type */
>+                      ctx->last_bit = ctx->current_bit;
>+              } else {
>+                      ctx->rlength++;
>+              }
>+      }
>+}
>+
>+static int fips_run_rng_test(fips_ctx_t *ctx, const void *buf)
>+{
>+      int i, j;
>+      int rng_test = 0;
>+      unsigned char *rngdatabuf;
>+
>+      if (!ctx) return -1;
>+      if (!buf) return -1;
>+      rngdatabuf = (unsigned char *)buf;
>+
>+      for (i=0; i<FIPS_RNG_BUFFER_SIZE; i += 4) {
>+              int new32 = rngdatabuf[i] | 
>+                          ( rngdatabuf[i+1] << 8 ) | 
>+                          ( rngdatabuf[i+2] << 16 ) | 

above 3 lines contain whitespace damage.

>+                          ( rngdatabuf[i+3] << 24 );
>+              if (new32 == ctx->last32) rng_test |= FIPS_RNG_CONTINUOUS_RUN;
>+              ctx->last32 = new32;
>+              fips_test_store(ctx, rngdatabuf[i]);
>+              fips_test_store(ctx, rngdatabuf[i+1]);
>+              fips_test_store(ctx, rngdatabuf[i+2]);
>+              fips_test_store(ctx, rngdatabuf[i+3]);
>+      }
>+
>+      /* add in the last (possibly incomplete) run */
>+      if (ctx->rlength < 5)
>+              ctx->runs[ctx->rlength + (6 * ctx->current_bit)]++;
>+      else {
>+              ctx->runs[5 + (6 * ctx->current_bit)]++;
>+              if (ctx->rlength >= 25)
>+                      rng_test |= FIPS_RNG_LONGRUN;
>+      }
>+      

whitespace damage in the above line.

>+      if (ctx->longrun) {
>+              rng_test |= FIPS_RNG_LONGRUN;
>+              ctx->longrun = 0;
>+      }
>+
>+      /* Ones test */
>+      if ((ctx->ones >= 10275) || (ctx->ones <= 9725))
>+              rng_test |= FIPS_RNG_MONOBIT;
>+      /* Poker calcs */
>+      for (i = 0, j = 0; i < 16; i++)
>+              j += ctx->poker[i] * ctx->poker[i];
>+      /* 16/5000*1563176-5000 = 2.1632  */
>+      /* 16/5000*1576928-5000 = 46.1696 */
>+      if ((j > 1576928) || (j < 1563176))
>+              rng_test |= FIPS_RNG_POKER;
>+
>+      if ((ctx->runs[0] < 2315) || (ctx->runs[0] > 2685) ||
>+          (ctx->runs[1] < 1114) || (ctx->runs[1] > 1386) ||
>+          (ctx->runs[2] < 527) || (ctx->runs[2] > 723) ||
>+          (ctx->runs[3] < 240) || (ctx->runs[3] > 384) ||
>+          (ctx->runs[4] < 103) || (ctx->runs[4] > 209) ||
>+          (ctx->runs[5] < 103) || (ctx->runs[5] > 209) ||
>+          (ctx->runs[6] < 2315) || (ctx->runs[6] > 2685) ||
>+          (ctx->runs[7] < 1114) || (ctx->runs[7] > 1386) ||
>+          (ctx->runs[8] < 527) || (ctx->runs[8] > 723) ||
>+          (ctx->runs[9] < 240) || (ctx->runs[9] > 384) ||
>+          (ctx->runs[10] < 103) || (ctx->runs[10] > 209) ||
>+          (ctx->runs[11] < 103) || (ctx->runs[11] > 209)) {
>+              rng_test |= FIPS_RNG_RUNS;
>+      }
>+      

whitespace damage in the above line.

>+      /* finally, clear out FIPS variables for start of next run */
>+      memset(ctx->poker, 0, sizeof (ctx->poker));
>+      memset(ctx->runs, 0, sizeof (ctx->runs));
>+      ctx->ones = 0;
>+      ctx->rlength = -1;
>+      ctx->current_bit = 0;
>+
>+      return rng_test;
>+}
>+/**********************************************
>+ * End of FIPS part
>+ *********************************************/
>+
>+enum {
>+      RNG_b   = (1 << 0),
>+      RNG_f   = (1 << 1),
>+      RNG_o   = (1 << 2),
>+      RNG_r   = (1 << 3),
>+      RNG_s   = (1 << 4),
>+      RNG_t   = (1 << 5),
>+      RNG_W   = (1 << 6),

No need for that ',' in the line above.

>+};
>+
>+static void random_add_entropy(int random_fd, void *buf, size_t size)
>+{
>+      struct rand_pool_info *entropy;
>+
>+      entropy = xmalloc(sizeof(struct rand_pool_info) + size);
>+
>+      entropy->entropy_count = size * 8;
>+      entropy->buf_size = size;
>+      memcpy(entropy->buf, buf, size);
>+
>+      ioctl_or_perror_and_die(random_fd, RNDADDENTROPY, entropy, 
>"RNDADDENTROPY failed");

This ignores our setting that controls whether or not to print IOCTL
names. Please fix.

>+}
>+
>+static void random_sleep(int random_fd, double timeout, unsigned 
>fill_watermark)
>+{
>+      int ent_count;
>+      struct pollfd pfd[1];
>+
>+      pfd[0].fd = random_fd;
>+      pfd[0].events = POLLOUT;
>+
>+      ioctl_or_perror_and_die(random_fd, RNDGETENTCNT, &ent_count, 
>"RNDGETENTCNT failed");

ditto

>+      if (ent_count < fill_watermark) return;
>+      

whitespace damage in the above line.

>+      safe_poll(pfd, 1, 1000.0 * timeout);
>+}

Is it smaller to fold both random_add_entropy() and random_sleep() into
their only user?

>+
>+/* Initialize entropy source */
>+static int discard_initial_data(int rng_fd)
>+{
>+      /* Trash 32 bits of what is probably stale (non-random)
>+       * initial state from the RNG.  For Intel's, 8 bits would
>+       * be enough, but since AMD's generates 32 bits at a time...
>+       *
>+       * The kernel drivers should be doing this at device powerup,
>+       * but at least up to 2.4.24, it doesn't. */
>+      unsigned char tempbuf[4];
>+
>+      xread(rng_fd, tempbuf, sizeof tempbuf);
>+
>+      /* Return 32 bits of bootstrap data */
>+      xread(rng_fd, tempbuf, sizeof tempbuf);
>+
>+      return tempbuf[0] | (tempbuf[1] << 8) | 

whitespace damage in the above line.

>+              (tempbuf[2] << 16) | (tempbuf[3] << 24);
>+}
>+
>+
>+#if ENABLE_FEATURE_RNGD_LONG_OPTIONS
>+static const char rngd_longopts[] ALIGN1 =
>+      "background\0"          No_argument             "b"
>+      "foreground\0"          No_argument             "f"
>+      "random-device\0"       Required_argument       "o"
>+      "rng-device\0"          Required_argument       "r"
>+      "random-step\0"         Required_argument       "s"
>+      "timeout\0"             Required_argument       "t"
>+      "fill-watermark\0"      Required_argument       "W"
>+      ;
>+#endif
>+
>+int rngd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
>+int rngd_main(int argc UNUSED_PARAM, char **argv)
>+{
>+      const char *random_name = "/dev/random";
>+      const char *rng_name = "/dev/hw_random";

I think we have something like device_open() which prepends "/dev/" for
you.

>+      int random_step = 64;
>+      unsigned fill_watermark;
>+      double poll_timeout = 60;

Eh, a double is a bit heavy, can we get away with unsigned long ?

>+
>+      const char *watermark = "2048";
>+      static int rng_fd;
>+      static int random_fd;
>+
>+      unsigned char buf[FIPS_RNG_BUFFER_SIZE];
>+      unsigned char *p;
>+      int fips;

unneeded variable "fips". Please remove it.

>+      fips_ctx_t *fipsctx;
>+
>+#if ENABLE_FEATURE_RNGD_LONG_OPTIONS
>+      applet_long_options = rngd_longopts;
>+#endif
>+
>+      opt_complementary = "s+:t+";
>+      getopt32(argv, "bfo:r:s:t:W:", &random_name, &rng_name, &random_step, 
>&poll_timeout, &watermark);
>+      argv += optind;
>+
>+      fill_watermark = xatou_range(watermark, 0, 4096);
>+
>+      /* Init entropy source, and open hardware RNG device */
>+      rng_fd = xopen(rng_name, O_RDONLY);
>+
>+      /* Bootstrap FIPS tests */
>+      fipsctx = (fips_ctx_t *) xzalloc(sizeof(fips_ctx_t));
>+      fipsctx->rlength = -1;
>+      fipsctx->last32 = discard_initial_data(rng_fd);
>+
>+      /* Init entropy sink and open random device */
>+      random_fd = xopen(random_name, O_RDWR);
>+
>+      if (!(option_mask32 & RNG_f)) { /* no -f */
>+              bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
>+              openlog(applet_name, LOG_PID, LOG_DAEMON);
>+              logmode = LOGMODE_SYSLOG;
>+      }
>+
>+      write_pidfile("/var/run/rngd.pid");
>+      for (;;) {
>+              xread(rng_fd, buf, sizeof buf);
>+
>+              fips = fips_run_rng_test(fipsctx, buf);
>+
>+              if (fips) {
>+                      bb_info_msg("failed fips test");
>+                      sleep(1);
>+                      continue;
>+              }
>+
>+              for (p = buf; p + random_step <= &buf[sizeof buf]; p += 
>random_step) {
>+                      random_add_entropy(random_fd, p, random_step);
>+                      random_sleep(random_fd, poll_timeout ? : -1.0, 
>fill_watermark);
>+              }
>+      }
>+
>+      return EXIT_SUCCESS;
>+}

Please provide size(1) output for this applet.
TIA,
Bernhard
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to