Hi,

  I've been playing around with rngd for a bit, and came up with
the following patch.

- Add -x to allow startup without /dev/hw_random being available
- Add usleep(1500) to main loop so it doesn't grab 100% cpu if
  /dev/hwrandom is lost
- Complain to syslog

  Please comment,

- marcel
--- rng-tools-3/rngd.c-org      2012-01-25 20:56:21.000000000 +0100
+++ rng-tools-3/rngd.c  2012-01-27 10:45:50.000000000 +0100
@@ -77,6 +77,8 @@
 
        { "background", 'b', 0, 0, "Become a daemon (default)" },
 
+       { "soft-fail", 'x', 0, 0, "Soft fail file input (i.e. keep trying if 
open() fails)" },
+
        { "random-device", 'o', "file", 0,
          "Kernel device used for random number output (default: /dev/random)" 
},
 
@@ -104,12 +106,15 @@
        .fill_watermark = 2048,
        .daemon         = 1,
        .enable_tpm     = 1,
+       .soft_fail      = 0,
 };
 struct arguments *arguments = &default_arguments;
 
 static struct rng rng_default = {
        .rng_name       = "/dev/hw_random",
        .rng_fd         = -1,
+       .valid          = 0,
+       .last_invalid   = 0,
        .xread          = xread,
        .fipsctx        = NULL,
        .next           = NULL,
@@ -118,6 +123,8 @@
 static struct rng rng_tpm = {
        .rng_name       = "/dev/tpm0",
        .rng_fd         = -1,
+       .valid          = 0,
+       .last_invalid   = 0,
        .xread          = xread_tpm,
        .fipsctx        = NULL,
        .next           = NULL,
@@ -137,6 +144,9 @@
        case 'r':
                rng_default.rng_name = arg;
                break;
+       case 'x':
+               arguments->soft_fail = 1;
+               break;
        case 't': {
                float f;
                if (sscanf(arg, "%f", &f) == 0)
@@ -210,13 +220,36 @@
 
        for (;;) {
                struct rng *iter;
-               for (iter = rng_list; iter; iter = iter->next)
-               {
-                       retval = iter->xread(buf, sizeof buf, iter);
-                       if (retval == 0)
-                               update_kernel_random(random_step,
-                                                    poll_timeout, buf,
-                                                    iter->fipsctx);
+               int n = 0;
+
+               for (iter = rng_list; iter; iter = iter->next) {
+                       if (iter->valid == -1 && (iter->last_invalid + 10) <= 
time(NULL)) {
+                               iter->valid = 0;
+                               message(LOG_DAEMON|LOG_ERR,
+                                       "Re-enable %s\n", iter->rng_name);
+                       }
+                       if (iter->valid == 0)
+                               n++;
+               }
+               if (n == 0)
+                       usleep(1500);
+               if (n != 0) {
+                       for (iter = rng_list; iter; iter = iter->next) {
+                               if (iter->valid == 0) {
+                                       retval = iter->xread(buf, sizeof buf, 
iter);
+                                       if (retval == 0) {
+                                               
update_kernel_random(random_step,
+                                                       poll_timeout, buf,
+                                                       iter->fipsctx);
+                                       }
+                                       else {
+                                               iter->valid = -1;
+                                               iter->last_invalid = time(NULL);
+                                               message(LOG_DAEMON|LOG_ERR,
+                                                       "Error reading from 
device %s, skipping it for a bit\n", iter->rng_name);
+                                       }
+                               }
+                       }
                }
        }
 }
--- rng-tools-3/rngd.h-org      2012-01-25 20:56:26.000000000 +0100
+++ rng-tools-3/rngd.h  2012-01-27 10:46:01.000000000 +0100
@@ -29,6 +29,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <syslog.h>
+#include <time.h>
 
 #include "fips.h"
 
@@ -42,6 +43,7 @@
 
        int daemon;
        int enable_tpm;
+       int soft_fail;
 };
 extern struct arguments *arguments;
 
@@ -50,6 +52,9 @@
        char *rng_name;
        int rng_fd;
 
+       int valid;
+       time_t last_invalid;
+
        int (*xread) (void *buf, size_t size, struct rng *ent_src);
        fips_ctx_t *fipsctx;
 
--- rng-tools-3/rngd_entsource.c-org    2012-01-26 13:29:21.000000000 +0100
+++ rng-tools-3/rngd_entsource.c        2012-01-27 10:46:28.000000000 +0100
@@ -52,7 +52,11 @@
        size_t off = 0;
        ssize_t r;
 
-       while (size > 0) {
+       if (ent_src->rng_fd == -1) {
+               ent_src->rng_fd = open(ent_src->rng_name, O_RDONLY);
+               }
+
+       while (size > 0 && ent_src->rng_fd != -1) {
                do {
                        r = read(ent_src->rng_fd, buf + off, size);
                } while ((r == -1) && (errno == EINTR));
@@ -64,6 +68,8 @@
 
        if (size) {
                message(LOG_DAEMON|LOG_ERR, "read error\n");
+               close(ent_src->rng_fd);
+               ent_src->rng_fd = -1;
                return -1;
        }
        return 0;
@@ -167,7 +173,7 @@
 int init_entropy_source(struct rng *ent_src)
 {
        ent_src->rng_fd = open(ent_src->rng_name, O_RDONLY);
-       if (ent_src->rng_fd == -1) {
+       if (ent_src->rng_fd == -1 && arguments->soft_fail == 0) {
                return 1;
        }
        src_list_add(ent_src);
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to