]> git.ipfire.org Git - thirdparty/rng-tools.git/blobdiff - rngd.c
rngd: Allow up to a 1:1000 false error rate on FIPS tests
[thirdparty/rng-tools.git] / rngd.c
diff --git a/rngd.c b/rngd.c
index 46ae23a904398e23e23a4d7c72b158713e4e412d..d7cd1b22706c274409b5f40dcde693c598e96ed2 100644 (file)
--- a/rngd.c
+++ b/rngd.c
@@ -84,7 +84,7 @@ static struct argp_option options[] = {
          "Kernel device used for random number output (default: /dev/random)" },
 
        { "rng-device", 'r', "file", 0,
-         "Kernel device used for random number input (default: /dev/hw_random)" },
+         "Kernel device used for random number input (default: /dev/hwrng)" },
 
        { "pid-file", 'p', "file", 0,
          "File used for recording daemon PID, and multiple exclusion (default: /var/run/rngd.pid)" },
@@ -99,8 +99,11 @@ static struct argp_option options[] = {
 
        { "verbose" ,'v', 0, 0, "Report available entropy sources" },
 
+       { "no-drng", 'd', "1|0", 0,
+         "Do not use drng as a source of random number input (default: 0)" },
+       
        { "no-tpm", 'n', "1|0", 0,
-         "do not use tpm as a source of random number input (default: 0)" },
+         "Do not use tpm as a source of random number input (default: 0)" },
 
        { 0 },
 };
@@ -109,8 +112,8 @@ static struct arguments default_arguments = {
        .random_name    = "/dev/random",
        .pid_file       = "/var/run/rngd.pid",
        .random_step    = 64,
-       .fill_watermark = 2048,
        .daemon         = true,
+       .enable_drng    = true,
        .enable_tpm     = true,
        .quiet          = false,
        .verbose        = false,
@@ -118,11 +121,17 @@ static struct arguments default_arguments = {
 struct arguments *arguments = &default_arguments;
 
 static struct rng rng_default = {
-       .rng_name       = "/dev/hw_random",
+       .rng_name       = "/dev/hwrng",
        .rng_fd         = -1,
        .xread          = xread,
 };
 
+static struct rng rng_drng = {
+       .rng_name       = "drng",
+       .rng_fd         = -1,
+       .xread          = xread_drng,
+};
+
 static struct rng rng_tpm = {
        .rng_name       = "/dev/tpm0",
        .rng_fd         = -1,
@@ -170,6 +179,14 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
        case 'v':
                arguments->verbose = true;
                break;
+       case 'd': {
+               int n;
+               if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1))
+                       argp_usage(state);
+               else
+                       arguments->enable_drng = false;
+               break;
+       }
        case 'n': {
                int n;
                if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1))
@@ -196,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) {
@@ -239,8 +253,15 @@ static void do_loop(int random_step)
 
                        rc = update_kernel_random(random_step,
                                             buf, iter->fipsctx);
-                       if (rc == 0)
-                               continue;       /* succeeded, work done */
+                       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) {
@@ -267,24 +288,30 @@ static void term_signal(int signo)
 
 int main(int argc, char **argv)
 {
-       int rc_rng = 0;
-       int rc_tpm = 0;
+       int rc_rng = 1;
+       int rc_drng = 1;
+       int rc_tpm = 1;
        int pid_fd = -1;
 
        openlog("rngd", 0, LOG_DAEMON);
 
+       /* Get the default watermark level for this platform */
+       arguments->fill_watermark = default_watermark();
+
        /* Parsing of commandline parameters */
        argp_parse(&argp, argc, argv, 0, 0, arguments);
 
        /* Init entropy sources, and open TRNG device */
        rc_rng = init_entropy_source(&rng_default);
-       if (arguments->enable_tpm)
+       if (arguments->enable_drng)
+               rc_drng = init_drng_entropy_source(&rng_drng);
+       if (arguments->enable_tpm && rc_rng)
                rc_tpm = init_tpm_entropy_source(&rng_tpm);
 
-       if (rc_rng && rc_tpm) {
+       if (rc_rng && rc_drng && rc_tpm) {
                if (!arguments->quiet) {
                        message(LOG_DAEMON|LOG_ERR,
-                               "can't open entropy source(tpm or intel/amd rng)");
+                               "can't open any entropy source");
                        message(LOG_DAEMON|LOG_ERR,
                                "Maybe RNG device modules are not loaded\n");
                }
@@ -295,11 +322,14 @@ int main(int argc, char **argv)
                printf("Available entropy sources:\n");
                if (!rc_rng)
                        printf("\tIntel/AMD hardware rng\n");
+               if (!rc_drng)
+                       printf("\tDRNG\n");
                if (!rc_tpm)
                        printf("\tTPM\n");
        }
 
        if (rc_rng
+               && (rc_drng || !arguments->enable_drng)
                && (rc_tpm || !arguments->enable_tpm)) {
                if (!arguments->quiet)
                        message(LOG_DAEMON|LOG_ERR,