]> git.ipfire.org Git - thirdparty/rng-tools.git/commitdiff
rngd: Allow up to a 1:1000 false error rate on FIPS tests
authorH. Peter Anvin <hpa@linux.intel.com>
Wed, 1 Aug 2012 21:31:39 +0000 (14:31 -0700)
committerJeff Garzik <jgarzik@redhat.com>
Thu, 2 Aug 2012 04:19:01 +0000 (00:19 -0400)
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>
rngd.c
rngd.h

diff --git a/rngd.c b/rngd.c
index 8ab219c296de4504ed41759f2baf9dbf1bd564dd..d7cd1b22706c274409b5f40dcde693c598e96ed2 100644 (file)
--- a/rngd.c
+++ b/rngd.c
@@ -213,11 +213,8 @@ static int update_kernel_random(int random_step,
        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 @@ static void do_loop(int random_step)
 
                        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 ca321d681c3754ca2d9bc0780fb8d5674a73253b..2dd84813d1ca6d24500ac9c0a79235eb4d712521 100644 (file)
--- 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 @@ struct rng {
        int rng_fd;
        bool disabled;
        int failures;
+       int success;
 
        int (*xread) (void *buf, size_t size, struct rng *ent_src);
        fips_ctx_t *fipsctx;