~ubuntu-branches/ubuntu/vivid/rng-tools/vivid

« back to all changes in this revision

Viewing changes to rngtest.c

  • Committer: Package Import Robot
  • Author(s): Tim Gardner
  • Date: 2013-08-13 13:12:05 UTC
  • mfrom: (1.2.5)
  • Revision ID: package-import@ubuntu.com-20130813131205-rxv50a9sgze6ya6o
Tags: 4-0ubuntu1
Merge from upstream git://git.kernel.org/pub/scm/utils/kernel/rng-tools/rng-tools.git
908d733527a361621da88cdf931a71aa83cba430
-LP: #1084378

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * This program tests the input stream in stdin for randomness,
5
5
 * using the tests defined by FIPS 140-1/140-2 2001-10-10.
6
 
 * 
 
6
 *
7
7
 * Copyright (C) 2004 Henrique de Moraes Holschuh <hmh@debian.org>
8
8
 *
9
9
 * This program is free software; you can redistribute it and/or modify
10
10
 * it under the terms of the GNU General Public License as published by
11
11
 * the Free Software Foundation; either version 2 of the License, or
12
12
 * (at your option) any later version.
13
 
 * 
 
13
 *
14
14
 * This program is distributed in the hope that it will be useful,
15
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
18
 *
19
19
 * You should have received a copy of the GNU General Public License
20
20
 * along with this program; if not, write to the Free Software
21
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335  USA
22
22
 */
23
23
 
24
24
#define _GNU_SOURCE
29
29
 
30
30
#include "rng-tools-config.h"
31
31
 
32
 
/* For printf types macros (PRIu64) */
33
 
#define __STDC_FORMAT_MACROS
34
 
 
35
32
#include <unistd.h>
36
33
#include <stdint.h>
37
 
#include <inttypes.h>
38
34
#include <stdio.h>
39
35
#include <stdlib.h>
40
36
#include <sys/time.h>
46
42
#include "fips.h"
47
43
#include "stats.h"
48
44
#include "exits.h"
49
 
#include "util.h"
50
45
 
51
46
#define PROGNAME "rngtest"
52
47
const char* logprefix = PROGNAME ": ";
89
84
};
90
85
 
91
86
struct arguments {
92
 
        unsigned long int blockstats;
 
87
        int blockstats;
93
88
        uint64_t timedstats;            /* microseconds */
94
89
        int pipemode;
95
 
        unsigned long int blockcount;
 
90
        int blockcount;
96
91
};
97
92
 
98
93
static struct arguments default_arguments = {
105
100
static error_t parse_opt (int key, char *arg, struct argp_state *state)
106
101
{
107
102
        struct arguments *arguments = state->input;
108
 
        
 
103
 
109
104
        switch(key) {
110
105
        case 'c': {
111
 
                long int n;
112
 
                char *p;
113
 
                n = strtol(arg, &p, 10);
114
 
                if ((p == arg) || (*p != 0) || (n < 0))
 
106
                int n;
 
107
                if ((sscanf(arg, "%i", &n) == 0) || (n < 0))
115
108
                        argp_usage(state);
116
109
                else
117
110
                        arguments->blockcount = n;
118
111
                break;
119
112
        }
120
113
        case 'b': {
121
 
                long int n;
122
 
                char *p;
123
 
                n = strtol(arg, &p, 10);
124
 
                if ((p == arg) || (*p != 0) || (n < 0))
 
114
                int n;
 
115
                if ((sscanf(arg, "%i", &n) == 0) || (n < 0))
125
116
                        argp_usage(state);
126
117
                else
127
118
                        arguments->blockstats = n;
128
119
                break;
129
120
        }
130
121
        case 't': {
131
 
                long int n;
132
 
                char *p;
133
 
                n = strtol(arg, &p, 10);
134
 
                if ((p == arg) || (*p != 0) || (n < 0))
 
122
                int n;
 
123
                if ((sscanf(arg, "%i", &n) == 0) || (n < 0))
135
124
                        argp_usage(state);
136
125
                else
137
126
                        arguments->timedstats = 1000000ULL * n;
163
152
        uint64_t good_fips_blocks;      /* Blocks approved by FIPS 140-2 */
164
153
        uint64_t fips_failures[N_FIPS_TESTS];   /* Breakdown of block
165
154
                                           failures per FIPS test */
166
 
        
 
155
 
167
156
        uint64_t bytes_received;        /* Bytes read from input */
168
157
        uint64_t bytes_sent;            /* Bytes sent to output */
169
158
 
205
194
 
206
195
        /* Handle SIGTERM and SIGINT the same way */
207
196
        if (sigaction(SIGTERM, &action, NULL) < 0) {
208
 
                fprintf(stderr, 
 
197
                fprintf(stderr,
209
198
                        "unable to install signal handler for SIGTERM: %s",
210
199
                        strerror(errno));
211
200
                exit(EXIT_OSERR);
225
214
        ssize_t r;
226
215
 
227
216
        while (size) {
228
 
                r = read(0, (unsigned char *)buf + off, size);
 
217
                r = read(0, buf + off, size);
229
218
                if (r < 0) {
230
219
                        if (gotsigterm) return -1;
231
220
                        if ((errno == EAGAIN) || (errno == EINTR)) continue;
232
221
                        break;
233
222
                } else if (!r) {
234
223
                        if (!arguments->pipemode)
235
 
                                fprintf(stderr, 
236
 
                                        "%sentropy source exhausted!\n", 
 
224
                                fprintf(stderr,
 
225
                                        "%sentropy source drained\n",
237
226
                                        logprefix);
238
227
                        return -1;
239
228
                }
258
247
        ssize_t r;
259
248
 
260
249
        while (size) {
261
 
                r = write(1, (unsigned char *)buf + off, size);
 
250
                r = write(1, buf + off, size);
262
251
                if (r < 0) {
263
252
                        if (gotsigterm) return -1;
264
253
                        if ((errno == EAGAIN) || (errno == EINTR)) continue;
265
254
                        break;
266
255
                } else if (!r) {
267
 
                        fprintf(stderr, 
 
256
                        fprintf(stderr,
268
257
                                "%swrite channel stuck\n", logprefix);
269
258
                        exitstatus = EXIT_IOERR;
270
259
                        return -1;
327
316
                        &rng_stats.sink_blockfill, FIPS_RNG_BUFFER_SIZE*8));
328
317
 
329
318
        gettimeofday(&now, 0);
330
 
        fprintf(stderr, "%sProgram run time: %" PRIu64 " microseconds\n",
331
 
                logprefix, elapsed_time(&rng_stats.progstart, &now));
 
319
        fprintf(stderr, "%sProgram run time: %llu microseconds\n",
 
320
                logprefix,
 
321
                (unsigned long long) elapsed_time(&rng_stats.progstart, &now));
332
322
}
333
323
 
334
324
/* Return 32 bits of bootstrap data */
335
 
static unsigned int discard_initial_data(void)
 
325
static int discard_initial_data(void)
336
326
{
337
327
        unsigned char tempbuf[4];
338
328
 
343
333
        /* Bootstrap data for FIPS tests */
344
334
        if (xread(tempbuf, sizeof tempbuf)) exit(EXIT_FAIL);
345
335
 
346
 
        return tempbuf[0] | (tempbuf[1] << 8) | 
 
336
        return tempbuf[0] | (tempbuf[1] << 8) |
347
337
                (tempbuf[2] << 16) | (tempbuf[3] << 24);
348
338
}
349
339
 
352
342
        int j;
353
343
        int fips_result;
354
344
        struct timeval start, stop, statdump, now;
355
 
        unsigned long int statruns, runs;
 
345
        int statruns, runs;
356
346
 
357
347
        runs = statruns = 0;
358
348
        gettimeofday(&statdump, 0);
360
350
                gettimeofday(&start, 0);
361
351
                if (xread(rng_buffer, sizeof(rng_buffer))) return;
362
352
                gettimeofday(&stop, 0);
363
 
                update_usectimer_stat(&rng_stats.source_blockfill, 
 
353
                update_usectimer_stat(&rng_stats.source_blockfill,
364
354
                                &start, &stop);
365
355
 
366
356
                gettimeofday(&start, 0);
391
381
                    (++runs >= arguments->blockcount)) break;
392
382
 
393
383
                gettimeofday(&now, 0);
394
 
                if ((arguments->blockstats && 
 
384
                if ((arguments->blockstats &&
395
385
                     (++statruns >= arguments->blockstats)) ||
396
386
                    (arguments->timedstats &&
397
387
                     (elapsed_time(&statdump, &now) > arguments->timedstats))) {
423
413
        fips_init(&fipsctx, discard_initial_data());
424
414
 
425
415
        do_rng_fips_test_loop();
426
 
        
 
416
 
427
417
        dump_rng_stats();
428
418
 
429
 
        if ((exitstatus == EXIT_SUCCESS) && 
 
419
        if ((exitstatus == EXIT_SUCCESS) &&
430
420
            (rng_stats.bad_fips_blocks || !rng_stats.good_fips_blocks)) {
431
421
                exitstatus = EXIT_FAIL;
432
422
        }