fips_rngvs.c revision 296465
1/*
2 * Crude test driver for processing the VST and MCT testvector files
3 * generated by the CMVP RNGVS product.
4 *
5 * Note the input files are assumed to have a _very_ specific format
6 * as described in the NIST document "The Random Number Generator
7 * Validation System (RNGVS)", May 25, 2004.
8 *
9 */
10#include <openssl/opensslconf.h>
11
12#ifndef OPENSSL_FIPS
13# include <stdio.h>
14
15int main(int argc, char **argv)
16{
17    printf("No FIPS RNG support\n");
18    return 0;
19}
20#else
21
22# include <openssl/bn.h>
23# include <openssl/dsa.h>
24# include <openssl/fips.h>
25# include <openssl/err.h>
26# include <openssl/rand.h>
27# include <openssl/fips_rand.h>
28# include <openssl/x509v3.h>
29# include <string.h>
30# include <ctype.h>
31
32# include "fips_utl.h"
33
34static void vst()
35{
36    unsigned char *key = NULL;
37    unsigned char *v = NULL;
38    unsigned char *dt = NULL;
39    unsigned char ret[16];
40    char buf[1024];
41    char lbuf[1024];
42    char *keyword, *value;
43    long i, keylen;
44
45    keylen = 0;
46
47    while (fgets(buf, sizeof buf, stdin) != NULL) {
48        fputs(buf, stdout);
49        if (!strncmp(buf, "[AES 128-Key]", 13))
50            keylen = 16;
51        else if (!strncmp(buf, "[AES 192-Key]", 13))
52            keylen = 24;
53        else if (!strncmp(buf, "[AES 256-Key]", 13))
54            keylen = 32;
55        if (!parse_line(&keyword, &value, lbuf, buf))
56            continue;
57        if (!strcmp(keyword, "Key")) {
58            key = hex2bin_m(value, &i);
59            if (i != keylen) {
60                fprintf(stderr, "Invalid key length, expecting %ld\n",
61                        keylen);
62                return;
63            }
64        } else if (!strcmp(keyword, "DT")) {
65            dt = hex2bin_m(value, &i);
66            if (i != 16) {
67                fprintf(stderr, "Invalid DT length\n");
68                return;
69            }
70        } else if (!strcmp(keyword, "V")) {
71            v = hex2bin_m(value, &i);
72            if (i != 16) {
73                fprintf(stderr, "Invalid V length\n");
74                return;
75            }
76
77            if (!key || !dt) {
78                fprintf(stderr, "Missing key or DT\n");
79                return;
80            }
81
82            FIPS_rand_set_key(key, keylen);
83            FIPS_rand_seed(v, 16);
84            FIPS_rand_set_dt(dt);
85            if (FIPS_rand_bytes(ret, 16) <= 0) {
86                fprintf(stderr, "Error getting PRNG value\n");
87                return;
88            }
89
90            pv("R", ret, 16);
91            OPENSSL_free(key);
92            key = NULL;
93            OPENSSL_free(dt);
94            dt = NULL;
95            OPENSSL_free(v);
96            v = NULL;
97        }
98    }
99}
100
101static void mct()
102{
103    unsigned char *key = NULL;
104    unsigned char *v = NULL;
105    unsigned char *dt = NULL;
106    unsigned char ret[16];
107    char buf[1024];
108    char lbuf[1024];
109    char *keyword, *value;
110    long i, keylen;
111    int j;
112
113    keylen = 0;
114
115    while (fgets(buf, sizeof buf, stdin) != NULL) {
116        fputs(buf, stdout);
117        if (!strncmp(buf, "[AES 128-Key]", 13))
118            keylen = 16;
119        else if (!strncmp(buf, "[AES 192-Key]", 13))
120            keylen = 24;
121        else if (!strncmp(buf, "[AES 256-Key]", 13))
122            keylen = 32;
123        if (!parse_line(&keyword, &value, lbuf, buf))
124            continue;
125        if (!strcmp(keyword, "Key")) {
126            key = hex2bin_m(value, &i);
127            if (i != keylen) {
128                fprintf(stderr, "Invalid key length, expecting %ld\n",
129                        keylen);
130                return;
131            }
132        } else if (!strcmp(keyword, "DT")) {
133            dt = hex2bin_m(value, &i);
134            if (i != 16) {
135                fprintf(stderr, "Invalid DT length\n");
136                return;
137            }
138        } else if (!strcmp(keyword, "V")) {
139            v = hex2bin_m(value, &i);
140            if (i != 16) {
141                fprintf(stderr, "Invalid V length\n");
142                return;
143            }
144
145            if (!key || !dt) {
146                fprintf(stderr, "Missing key or DT\n");
147                return;
148            }
149
150            FIPS_rand_set_key(key, keylen);
151            FIPS_rand_seed(v, 16);
152            for (i = 0; i < 10000; i++) {
153                FIPS_rand_set_dt(dt);
154                if (FIPS_rand_bytes(ret, 16) <= 0) {
155                    fprintf(stderr, "Error getting PRNG value\n");
156                    return;
157                }
158                /* Increment DT */
159                for (j = 15; j >= 0; j--) {
160                    dt[j]++;
161                    if (dt[j])
162                        break;
163                }
164            }
165
166            pv("R", ret, 16);
167            OPENSSL_free(key);
168            key = NULL;
169            OPENSSL_free(dt);
170            dt = NULL;
171            OPENSSL_free(v);
172            v = NULL;
173        }
174    }
175}
176
177int main(int argc, char **argv)
178{
179    if (argc != 2) {
180        fprintf(stderr, "%s [mct|vst]\n", argv[0]);
181        exit(1);
182    }
183    if (!FIPS_mode_set(1)) {
184        do_print_errors();
185        exit(1);
186    }
187    FIPS_rand_reset();
188    if (!FIPS_rand_test_mode()) {
189        fprintf(stderr, "Error setting PRNG test mode\n");
190        do_print_errors();
191        exit(1);
192    }
193    if (!strcmp(argv[1], "mct"))
194        mct();
195    else if (!strcmp(argv[1], "vst"))
196        vst();
197    else {
198        fprintf(stderr, "Don't know how to %s.\n", argv[1]);
199        exit(1);
200    }
201
202    return 0;
203}
204#endif
205