From: Jeff Garzik Date: Sun, 4 Jul 2010 02:43:21 +0000 (-0400) Subject: Add TPM RNG support. X-Git-Tag: v3~2 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Frng-tools.git;a=commitdiff_plain;h=d1b4c50492be7346f9b4eea44a3e18b15cbca0c5 Add TPM RNG support. also, trim trailing whitespace. Contributed by Dell, with bug fixes by David Howells @ Red Hat. Signed-off-by: Jeff Garzik --- diff --git a/exits.h b/exits.h index e1432fc..a739581 100644 --- a/exits.h +++ b/exits.h @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the diff --git a/fips.c b/fips.c index 04d2b97..a0c04e2 100644 --- a/fips.c +++ b/fips.c @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -49,18 +49,18 @@ const unsigned int fips_test_mask[N_FIPS_TESTS] = { /* These are the startup tests suggested by the FIPS 140-1 spec section * 4.11.1 (http://csrc.nist.gov/fips/fips1401.htm), and updated by FIPS -* 140-2 4.9, errata of 2001-10-10. FIPS 140-2, errata of 2002-12-03 +* 140-2 4.9, errata of 2001-10-10. FIPS 140-2, errata of 2002-12-03 * removed all requirements for non-deterministic RNGs, and thus most of * the tests we need are not mentioned in FIPS 140-2 anymore. We also * implement FIPS 140-1 4.11.2/FIPS 140-2 4.9 Continuous Run test. -* +* * The Monobit, Poker, Runs, and Long Runs tests are implemented below. -* This test must be run at periodic intervals to verify data is -* sufficiently random. If the tests are failed the RNG module shall -* no longer submit data to the entropy pool, but the tests shall +* This test must be run at periodic intervals to verify data is +* sufficiently random. If the tests are failed the RNG module shall +* no longer submit data to the entropy pool, but the tests shall * continue to run at the given interval. If at a later time the RNG * passes all tests it shall be re-enabled for the next period. -* +* * The reason for this is that it is not unlikely that at some time * during normal operation one of the tests will fail. This does not * necessarily mean the RNG is not operating properly, it is just a @@ -69,7 +69,7 @@ const unsigned int fips_test_mask[N_FIPS_TESTS] = { * time until the tests are rerun and passed. * * For the continuous run test, we need to check all bits of data, so -* "periodic" above shall be read as "for every back-to-back block of +* "periodic" above shall be read as "for every back-to-back block of * 20000 bits". We verify 32 bits to accomodate the AMD TRNG, and * to reduce false positives with other TRNGs. */ @@ -123,9 +123,9 @@ int fips_run_rng_test (fips_ctx_t *ctx, const void *buf) rngdatabuf = (unsigned char *)buf; for (i=0; ilast32) rng_test |= FIPS_RNG_CONTINUOUS_RUN; ctx->last32 = new32; @@ -143,7 +143,7 @@ int fips_run_rng_test (fips_ctx_t *ctx, const void *buf) if (ctx->rlength >= 25) rng_test |= FIPS_RNG_LONGRUN; } - + if (ctx->longrun) { rng_test |= FIPS_RNG_LONGRUN; ctx->longrun = 0; @@ -174,7 +174,7 @@ int fips_run_rng_test (fips_ctx_t *ctx, const void *buf) (ctx->runs[11] < 103) || (ctx->runs[11] > 209)) { rng_test |= FIPS_RNG_RUNS; } - + /* finally, clear out FIPS variables for start of next run */ memset (ctx->poker, 0, sizeof (ctx->poker)); memset (ctx->runs, 0, sizeof (ctx->runs)); diff --git a/fips.h b/fips.h index 679776e..a736277 100644 --- a/fips.h +++ b/fips.h @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -56,12 +56,12 @@ extern const unsigned int fips_test_mask[N_FIPS_TESTS]; /* * Runs the FIPS 140-1 4.11.1 and 4.11.2 tests, as updated by * FIPS 140-2 4.9, errata from 2001-10-10 (which set more strict - * intervals for the tests to pass), on a buffer of size + * intervals for the tests to pass), on a buffer of size * FIPS_RNG_BUFFER_SIZE, using the given context. * - * FIPS 140-2, errata of 2002-12-03 removed tests for non-deterministic + * FIPS 140-2, errata of 2002-12-03 removed tests for non-deterministic * RNGs, other than Continuous Run test. - * + * * This funtion returns 0 if all tests passed, or a bitmask * with bits set for every test that failed. * diff --git a/rngd.c b/rngd.c index 5c32ed6..6ebef64 100644 --- a/rngd.c +++ b/rngd.c @@ -3,7 +3,7 @@ * * rngd reads data from a hardware random number generator, verifies it * looks like random data, and adds it to /dev/random's entropy store. - * + * * In theory, this should allow you to read very quickly from * /dev/random; rngd also adds bytes to the entropy store periodically * when it's full, which makes predicting the entropy store's contents @@ -15,7 +15,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -60,7 +60,7 @@ int am_daemon; /* Nonzero if we went daemon */ /* Command line arguments and processing */ -const char *argp_program_version = +const char *argp_program_version = "rngd " VERSION "\n" "Copyright 2001-2004 Jeff Garzik\n" "Copyright (c) 2001 by Philipp Rumpf\n" @@ -91,20 +91,39 @@ static struct argp_option options[] = { { "timeout", 't', "nnn", 0, "Interval written to random-device when the entropy pool is full, in seconds (default: 60)" }, + { "no-tpm", 'n', "1|0", 0, + "do not use tpm as a source of random number input (default: 0)" }, { 0 }, }; static struct arguments default_arguments = { - .rng_name = "/dev/hw_random", .random_name = "/dev/random", .poll_timeout = 60, .random_step = 64, - .fill_watermark = 2048, + .fill_watermark = 2048, .daemon = 1, + .enable_tpm = 1, }; struct arguments *arguments = &default_arguments; +static struct rng rng_default = { + .rng_name = "/dev/hw_random", + .rng_fd = -1, + .xread = xread, + .fipsctx = NULL, + .next = NULL, +}; + +static struct rng rng_tpm = { + .rng_name = "/dev/tpm0", + .rng_fd = -1, + .xread = xread_tpm, + .fipsctx = NULL, + .next = NULL, +}; + +struct rng *rng_list; /* * command line processing @@ -116,7 +135,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) arguments->random_name = arg; break; case 'r': - arguments->rng_name = arg; + rng_default.rng_name = arg; break; case 't': { float f; @@ -145,6 +164,14 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) arguments->fill_watermark = n; break; } + case 'n': { + int n; + if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1)) + argp_usage(state); + else + arguments->enable_tpm = 0; + break; + } default: return ARGP_ERR_UNKNOWN; @@ -156,39 +183,64 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) static struct argp argp = { options, parse_opt, NULL, doc }; -static void do_loop(int random_step, - double poll_timeout) +static int update_kernel_random(int random_step, double poll_timeout, + unsigned char *buf, fips_ctx_t *fipsctx) { - unsigned char buf[FIPS_RNG_BUFFER_SIZE]; unsigned char *p; int fips; - for (;;) { - xread(buf, sizeof buf); + fips = fips_run_rng_test(fipsctx, buf); + if (fips) { + message(LOG_DAEMON|LOG_ERR, "failed fips test\n"); + return 1; + } - fips = fips_run_rng_test(&fipsctx, buf); + for (p = buf; p + random_step <= &buf[FIPS_RNG_BUFFER_SIZE]; + p += random_step) { + random_add_entropy(p, random_step); + random_sleep(poll_timeout); + } + return 0; +} - if (fips) { - message(LOG_DAEMON|LOG_ERR, "failed fips test\n"); - sleep(1); - continue; - } +static void do_loop(int random_step, double poll_timeout) +{ + unsigned char buf[FIPS_RNG_BUFFER_SIZE]; + int retval; - for (p = buf; p + random_step <= &buf[sizeof buf]; - p += random_step) { - random_add_entropy(p, random_step); - random_sleep(poll_timeout); + 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 main(int argc, char **argv) { + int rc_rng = 1; + int rc_tpm = 1; + + /* Parsing of commandline parameters */ argp_parse(&argp, argc, argv, 0, 0, arguments); - /* Init entropy source, and open TRNG device */ - init_entropy_source(arguments->rng_name); + /* Init entropy sources, and open TRNG device */ + rc_rng = init_entropy_source(&rng_default); + if (arguments->enable_tpm) + rc_tpm = init_tpm_entropy_source(&rng_tpm); + + if (rc_rng && rc_tpm) { + message(LOG_DAEMON|LOG_ERR, + "can't open entropy source(tpm or intel/amd rng)"); + message(LOG_DAEMON|LOG_ERR, + "Maybe RNG device modules are not loaded\n"); + return 1; + } /* Init entropy sink and open random device */ init_kernel_rng(arguments->random_name); diff --git a/rngd.h b/rngd.h index dbc4419..e2e3a62 100644 --- a/rngd.h +++ b/rngd.h @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -35,16 +35,27 @@ /* Command line arguments and processing */ struct arguments { char *random_name; - char *rng_name; - + int random_step; int fill_watermark; double poll_timeout; int daemon; + int enable_tpm; }; extern struct arguments *arguments; +/* structures to store rng information */ +struct rng { + char *rng_name; + int rng_fd; + + int (*xread) (void *buf, size_t size, struct rng *ent_src); + fips_ctx_t *fipsctx; + + struct rng *next; +}; + /* Background/daemon mode */ extern int am_daemon; /* Nonzero if we went daemon */ @@ -61,5 +72,6 @@ extern int am_daemon; /* Nonzero if we went daemon */ } \ } while (0) +extern void list_add(struct rng *ent_src); #endif /* RNGD__H */ diff --git a/rngd_entsource.c b/rngd_entsource.c index 86d6646..102178b 100644 --- a/rngd_entsource.c +++ b/rngd_entsource.c @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -42,20 +42,19 @@ #include "rngd_entsource.h" -/* Logic and contexts */ -static int rng_fd; /* rng data source */ -fips_ctx_t fipsctx; /* Context for the FIPS tests */ - +/* The overhead incured when tpm returns the random nos as per TCG spec + * it is 14 bytes.*/ +#define TPM_GET_RNG_OVERHEAD 14 /* Read data from the entropy source */ -void xread(void *buf, size_t size) +int xread(void *buf, size_t size, struct rng *ent_src) { size_t off = 0; ssize_t r; while (size > 0) { do { - r = read(rng_fd, buf + off, size); + r = read(ent_src->rng_fd, buf + off, size); } while ((r == -1) && (errno == EINTR)); if (r <= 0) break; @@ -65,42 +64,132 @@ void xread(void *buf, size_t size) if (size) { message(LOG_DAEMON|LOG_ERR, "read error\n"); - exit(1); + return -1; + } + return 0; +} + +/* tpm rng read call to kernel has 13 bytes of overhead + * the logic to process this involves reading to a temporary_buf + * and copying the no generated to buf */ +int xread_tpm(void *buf, size_t size, struct rng *ent_src) +{ + size_t bytes_read = 0; + ssize_t r; + int retval; + unsigned char *temp_buf = NULL; + unsigned char rng_cmd[] = { + 0, 193, /* TPM_TAG_RQU_COMMAND */ + 0, 0, 0, 14, /* length */ + 0, 0, 0, 70, /* TPM_ORD_GetRandom */ + 0, 0, 0, 0, /* number of bytes to return */ + }; + char *offset; + + ent_src->rng_fd = open(ent_src->rng_name, O_RDWR); + if (ent_src->rng_fd == -1) { + return -1; + } + + temp_buf = (unsigned char *) malloc(size + TPM_GET_RNG_OVERHEAD); + memset(temp_buf, 0, (size+TPM_GET_RNG_OVERHEAD)); + if (temp_buf == NULL) { + message(LOG_ERR|LOG_INFO,"No memory"); + return -1; } + /* 32 bits has been reserved for random byte size */ + rng_cmd[13] = (unsigned char)(size & 0xFF); + rng_cmd[12] = (unsigned char)((size >> 8) & 0xFF); + rng_cmd[11] = (unsigned char)((size >> 16) & 0xFF); + rng_cmd[10] = (unsigned char)((size >> 24) & 0xFF); + offset = buf; + while (bytes_read < size) { + r=0; + while (r < sizeof(rng_cmd)) { + retval = write(ent_src->rng_fd, + rng_cmd + r, + sizeof(rng_cmd) - r); + if (retval < 0) { + message(LOG_ERR|LOG_INFO, + "Error writing %s\n", + ent_src->rng_name); + retval = -1; + goto error_out; + } + r += retval; + } + if (r < sizeof(rng_cmd)) { + message(LOG_ERR|LOG_INFO, + "Error writing %s\n", ent_src->rng_name); + retval = -1; + goto error_out; + } + r = read(ent_src->rng_fd, temp_buf,size); + r = (r - TPM_GET_RNG_OVERHEAD); + bytes_read = bytes_read + r; + if (bytes_read > size) { + memcpy(offset,temp_buf + TPM_GET_RNG_OVERHEAD, + r - (bytes_read - size)); + break; + } + memcpy(offset, temp_buf + TPM_GET_RNG_OVERHEAD, r); + offset = offset + r; + } + retval = 0; +error_out: + close(ent_src->rng_fd); + free(temp_buf); + return retval; } /* Initialize entropy source */ -static int discard_initial_data(void) +static int discard_initial_data(struct rng *ent_src) { /* Trash 32 bits of what is probably stale (non-random) * initial state from the RNG. For Intel's, 8 bits would * be enough, but since AMD's generates 32 bits at a time... - * + * * The kernel drivers should be doing this at device powerup, * but at least up to 2.4.24, it doesn't. */ unsigned char tempbuf[4]; - xread(tempbuf, sizeof tempbuf); + xread(tempbuf, sizeof tempbuf, ent_src); /* Return 32 bits of bootstrap data */ - xread(tempbuf, sizeof tempbuf); + xread(tempbuf, sizeof tempbuf, ent_src); - return tempbuf[0] | (tempbuf[1] << 8) | + return tempbuf[0] | (tempbuf[1] << 8) | (tempbuf[2] << 16) | (tempbuf[3] << 24); } /* * Open entropy source, and initialize it */ -void init_entropy_source(const char* sourcedev) +int init_entropy_source(struct rng *ent_src) { - rng_fd = open(sourcedev, O_RDONLY); - if (rng_fd == -1) { - message(LOG_DAEMON|LOG_ERR, "can't open %s: %s", - sourcedev, strerror(errno)); - exit(EXIT_FAIL); + ent_src->rng_fd = open(ent_src->rng_name, O_RDONLY); + if (ent_src->rng_fd == -1) { + return 1; } - + list_add(ent_src); /* Bootstrap FIPS tests */ - fips_init(&fipsctx, discard_initial_data()); + ent_src->fipsctx = malloc(sizeof(fips_ctx_t)); + fips_init(ent_src->fipsctx, discard_initial_data(ent_src)); + return 0; } +/* + * Open tpm entropy source, and initialize it + */ +int init_tpm_entropy_source(struct rng *ent_src) +{ + ent_src->rng_fd = open(ent_src->rng_name, O_RDWR); + if (ent_src->rng_fd == -1) { + return 1; + } + list_add(ent_src); + /* Bootstrap FIPS tests */ + ent_src->fipsctx = malloc(sizeof(fips_ctx_t)); + fips_init(ent_src->fipsctx, 0); + close(ent_src->rng_fd); + return 0; +} diff --git a/rngd_entsource.h b/rngd_entsource.h index 5c9b350..dd1d116 100644 --- a/rngd_entsource.h +++ b/rngd_entsource.h @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -28,15 +28,18 @@ /* Logic and contexts */ extern fips_ctx_t fipsctx; /* Context for the FIPS tests */ +extern fips_ctx_t tpm_fipsctx; /* Context for the tpm FIPS tests */ /* * Initialize entropy source and entropy conditioning * * sourcedev is the path to the entropy source */ -extern void init_entropy_source(const char* sourcedev); +extern int init_entropy_source(struct rng *); +extern int init_tpm_entropy_source(struct rng *); /* Read data from the entropy source */ -void xread(void *buf, size_t size); +extern int xread(void *buf, size_t size, struct rng *ent_src); +extern int xread_tpm(void *buf, size_t size, struct rng *ent_src); #endif /* RNGD_ENTSOURCE__H */ diff --git a/rngd_linux.c b/rngd_linux.c index 13ea618..031a22b 100644 --- a/rngd_linux.c +++ b/rngd_linux.c @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -48,6 +48,7 @@ #include "exits.h" #include "rngd_linux.h" +extern struct rng *rng_list; /* Kernel output device */ static int random_fd; @@ -80,7 +81,7 @@ void random_add_entropy(void *buf, size_t size) entropy.ent_count = size * 8; entropy.size = size; memcpy(entropy.data, buf, size); - + if (ioctl(random_fd, RNDADDENTROPY, &entropy) != 0) { message(LOG_DAEMON|LOG_ERR, "RNDADDENTROPY failed: %s\n", strerror(errno)); @@ -99,7 +100,21 @@ void random_sleep(double poll_timeout) if (ioctl(random_fd, RNDGETENTCNT, &ent_count) == 0 && ent_count < arguments->fill_watermark) return; - + poll(&pfd, 1, 1000.0 * poll_timeout); } +void list_add(struct rng *ent_src) +{ + if (rng_list) { + struct rng *iter; + + iter = rng_list; + while (iter->next) { + iter = iter->next; + } + iter->next = ent_src; + } else { + rng_list = ent_src; + } +} diff --git a/rngd_linux.h b/rngd_linux.h index 5c65dd5..d16644b 100644 --- a/rngd_linux.h +++ b/rngd_linux.h @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the diff --git a/rngtest.c b/rngtest.c index 762415c..6b4a029 100644 --- a/rngtest.c +++ b/rngtest.c @@ -3,14 +3,14 @@ * * This program tests the input stream in stdin for randomness, * using the tests defined by FIPS 140-1/140-2 2001-10-10. - * + * * Copyright (C) 2004 Henrique de Moraes Holschuh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -100,7 +100,7 @@ static struct arguments default_arguments = { static error_t parse_opt (int key, char *arg, struct argp_state *state) { struct arguments *arguments = state->input; - + switch(key) { case 'c': { int n; @@ -152,7 +152,7 @@ struct { uint64_t good_fips_blocks; /* Blocks approved by FIPS 140-2 */ uint64_t fips_failures[N_FIPS_TESTS]; /* Breakdown of block failures per FIPS test */ - + uint64_t bytes_received; /* Bytes read from input */ uint64_t bytes_sent; /* Bytes sent to output */ @@ -194,7 +194,7 @@ static void init_sighandlers(void) /* Handle SIGTERM and SIGINT the same way */ if (sigaction(SIGTERM, &action, NULL) < 0) { - fprintf(stderr, + fprintf(stderr, "unable to install signal handler for SIGTERM: %s", strerror(errno)); exit(EXIT_OSERR); @@ -221,8 +221,8 @@ static int xread(void *buf, size_t size) break; } else if (!r) { if (!arguments->pipemode) - fprintf(stderr, - "%sentropy source drained\n", + fprintf(stderr, + "%sentropy source drained\n", logprefix); return -1; } @@ -253,7 +253,7 @@ static int xwrite(void *buf, size_t size) if ((errno == EAGAIN) || (errno == EINTR)) continue; break; } else if (!r) { - fprintf(stderr, + fprintf(stderr, "%swrite channel stuck\n", logprefix); exitstatus = EXIT_IOERR; return -1; @@ -333,7 +333,7 @@ static int discard_initial_data(void) /* Bootstrap data for FIPS tests */ if (xread(tempbuf, sizeof tempbuf)) exit(EXIT_FAIL); - return tempbuf[0] | (tempbuf[1] << 8) | + return tempbuf[0] | (tempbuf[1] << 8) | (tempbuf[2] << 16) | (tempbuf[3] << 24); } @@ -350,7 +350,7 @@ static void do_rng_fips_test_loop( void ) gettimeofday(&start, 0); if (xread(rng_buffer, sizeof(rng_buffer))) return; gettimeofday(&stop, 0); - update_usectimer_stat(&rng_stats.source_blockfill, + update_usectimer_stat(&rng_stats.source_blockfill, &start, &stop); gettimeofday(&start, 0); @@ -381,7 +381,7 @@ static void do_rng_fips_test_loop( void ) (++runs >= arguments->blockcount)) break; gettimeofday(&now, 0); - if ((arguments->blockstats && + if ((arguments->blockstats && (++statruns >= arguments->blockstats)) || (arguments->timedstats && (elapsed_time(&statdump, &now) > arguments->timedstats))) { @@ -413,10 +413,10 @@ int main(int argc, char **argv) fips_init(&fipsctx, discard_initial_data()); do_rng_fips_test_loop(); - + dump_rng_stats(); - if ((exitstatus == EXIT_SUCCESS) && + if ((exitstatus == EXIT_SUCCESS) && (rng_stats.bad_fips_blocks || !rng_stats.good_fips_blocks)) { exitstatus = EXIT_FAIL; } diff --git a/stats.c b/stats.c index 86c908d..eede033 100644 --- a/stats.c +++ b/stats.c @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -45,8 +45,8 @@ void set_stat_prefix(const char* prefix) strncpy(stat_prefix, prefix, sizeof(stat_prefix)-1); } -static void scale_mult_unit(char *unit, int unitsize, - const char *baseunit, +static void scale_mult_unit(char *unit, int unitsize, + const char *baseunit, double *value_min, double *value_avg, double *value_max) @@ -54,7 +54,7 @@ static void scale_mult_unit(char *unit, int unitsize, int mult = 0; char multchar[] = "KMGTPE"; - while ((*value_min >= 1024.0) && (*value_avg >= 1024.0) && + while ((*value_min >= 1024.0) && (*value_avg >= 1024.0) && (*value_max >= 1024.0) && (mult < sizeof(multchar))) { mult++; *value_min = *value_min / 1024.0; @@ -128,8 +128,8 @@ char *dump_stat_stat(char *buf, int size, } char *dump_stat_bw(char *buf, int size, - const char *msg, const char *unit, - struct rng_stat *stat, + const char *msg, const char *unit, + struct rng_stat *stat, uint64_t blocksize) { char unitscaled[20]; diff --git a/stats.h b/stats.h index 9807192..74df71a 100644 --- a/stats.h +++ b/stats.h @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -50,9 +50,9 @@ extern void update_stat(struct rng_stat *stat, uint64_t value); * The following functions format a stat dump on buf, and * return a pointer to the start of buf */ - + /* Dump simple counter */ -extern char *dump_stat_counter(char *buf, int size, +extern char *dump_stat_counter(char *buf, int size, const char *msg, uint64_t value); /* Dump min-max time stat */