rngd: Allow up to a 1:1000 false error rate on FIPS tests

The FIPS tests have a measured false positive error rate of
approximately 1:1250.  In order to not permanently disable a
functioning random number source under high traffic, allow
one failure per 1000 successful blocks.

However, never allow more than 25 subsequent failures; this is
handled by not allowing the failures counter to go below zero.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
diff --git a/rngd.c b/rngd.c
index 8ab219c..d7cd1b2 100644
--- a/rngd.c
+++ b/rngd.c
@@ -213,11 +213,8 @@
 	int fips;
 
 	fips = fips_run_rng_test(fipsctx_in, buf);
-	if (fips) {
-		if (!arguments->quiet)
-			message(LOG_DAEMON|LOG_ERR, "failed fips test\n");
+	if (fips)
 		return 1;
-	}
 
 	for (p = buf; p + random_step <= &buf[FIPS_RNG_BUFFER_SIZE];
 		 p += random_step) {
@@ -256,8 +253,15 @@
 
 			rc = update_kernel_random(random_step,
 					     buf, iter->fipsctx);
-			if (rc == 0)
+			if (rc == 0) {
+				iter->success++;
+				if (iter->success >= RNG_OK_CREDIT) {
+					if (iter->failures)
+						iter->failures--;
+					iter->success = 0;
+				}
 				break;	/* succeeded, work done */
+			}
 
 			iter->failures++;
 			if (iter->failures == MAX_RNG_FAILURES) {
diff --git a/rngd.h b/rngd.h
index ca321d6..2dd8481 100644
--- a/rngd.h
+++ b/rngd.h
@@ -35,6 +35,7 @@
 
 enum {
 	MAX_RNG_FAILURES		= 25,
+	RNG_OK_CREDIT			= 1000, /* ~1:1250 false positives */
 };
 
 /* Command line arguments and processing */
@@ -59,6 +60,7 @@
 	int rng_fd;
 	bool disabled;
 	int failures;
+	int success;
 
 	int (*xread) (void *buf, size_t size, struct rng *ent_src);
 	fips_ctx_t *fipsctx;