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
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel