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