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	{
49	fputs(buf,stdout);
50	if(!strncmp(buf,"[AES 128-Key]", 13))
51		keylen = 16;
52	else if(!strncmp(buf,"[AES 192-Key]", 13))
53		keylen = 24;
54	else if(!strncmp(buf,"[AES 256-Key]", 13))
55		keylen = 32;
56	if (!parse_line(&keyword, &value, lbuf, buf))
57		continue;
58	if(!strcmp(keyword,"Key"))
59	    {
60	    key=hex2bin_m(value,&i);
61	    if (i != keylen)
62		{
63		fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
64		return;
65		}
66	    }
67	else if(!strcmp(keyword,"DT"))
68	    {
69	    dt=hex2bin_m(value,&i);
70	    if (i != 16)
71		{
72		fprintf(stderr, "Invalid DT length\n");
73		return;
74		}
75	    }
76	else if(!strcmp(keyword,"V"))
77	    {
78	    v=hex2bin_m(value,&i);
79	    if (i != 16)
80		{
81		fprintf(stderr, "Invalid V length\n");
82		return;
83		}
84
85	    if (!key || !dt)
86		{
87		fprintf(stderr, "Missing key or DT\n");
88		return;
89		}
90
91	    FIPS_rand_set_key(key, keylen);
92	    FIPS_rand_seed(v,16);
93	    FIPS_rand_set_dt(dt);
94	    if (FIPS_rand_bytes(ret,16) <= 0)
95		{
96		fprintf(stderr, "Error getting PRNG value\n");
97	        return;
98	        }
99
100	    pv("R",ret,16);
101	    OPENSSL_free(key);
102	    key = NULL;
103	    OPENSSL_free(dt);
104	    dt = NULL;
105	    OPENSSL_free(v);
106	    v = NULL;
107	    }
108	}
109    }
110
111static void mct()
112    {
113    unsigned char *key = NULL;
114    unsigned char *v = NULL;
115    unsigned char *dt = NULL;
116    unsigned char ret[16];
117    char buf[1024];
118    char lbuf[1024];
119    char *keyword, *value;
120    long i, keylen;
121    int j;
122
123    keylen = 0;
124
125    while(fgets(buf,sizeof buf,stdin) != NULL)
126	{
127	fputs(buf,stdout);
128	if(!strncmp(buf,"[AES 128-Key]", 13))
129		keylen = 16;
130	else if(!strncmp(buf,"[AES 192-Key]", 13))
131		keylen = 24;
132	else if(!strncmp(buf,"[AES 256-Key]", 13))
133		keylen = 32;
134	if (!parse_line(&keyword, &value, lbuf, buf))
135		continue;
136	if(!strcmp(keyword,"Key"))
137	    {
138	    key=hex2bin_m(value,&i);
139	    if (i != keylen)
140		{
141		fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
142		return;
143		}
144	    }
145	else if(!strcmp(keyword,"DT"))
146	    {
147	    dt=hex2bin_m(value,&i);
148	    if (i != 16)
149		{
150		fprintf(stderr, "Invalid DT length\n");
151		return;
152		}
153	    }
154	else if(!strcmp(keyword,"V"))
155	    {
156	    v=hex2bin_m(value,&i);
157	    if (i != 16)
158		{
159		fprintf(stderr, "Invalid V length\n");
160		return;
161		}
162
163	    if (!key || !dt)
164		{
165		fprintf(stderr, "Missing key or DT\n");
166		return;
167		}
168
169	    FIPS_rand_set_key(key, keylen);
170	    FIPS_rand_seed(v,16);
171	    for (i = 0; i < 10000; i++)
172		{
173		    FIPS_rand_set_dt(dt);
174		    if (FIPS_rand_bytes(ret,16) <= 0)
175			{
176			fprintf(stderr, "Error getting PRNG value\n");
177		        return;
178		        }
179		    /* Increment DT */
180		    for (j = 15; j >= 0; j--)
181			{
182			dt[j]++;
183			if (dt[j])
184				break;
185			}
186		}
187
188	    pv("R",ret,16);
189	    OPENSSL_free(key);
190	    key = NULL;
191	    OPENSSL_free(dt);
192	    dt = NULL;
193	    OPENSSL_free(v);
194	    v = NULL;
195	    }
196	}
197    }
198
199int main(int argc,char **argv)
200    {
201    if(argc != 2)
202	{
203	fprintf(stderr,"%s [mct|vst]\n",argv[0]);
204	exit(1);
205	}
206    if(!FIPS_mode_set(1))
207	{
208	do_print_errors();
209	exit(1);
210	}
211    FIPS_rand_reset();
212    if (!FIPS_rand_test_mode())
213	{
214	fprintf(stderr, "Error setting PRNG test mode\n");
215	do_print_errors();
216	exit(1);
217	}
218    if(!strcmp(argv[1],"mct"))
219	mct();
220    else if(!strcmp(argv[1],"vst"))
221	vst();
222    else
223	{
224	fprintf(stderr,"Don't know how to %s.\n",argv[1]);
225	exit(1);
226	}
227
228    return 0;
229    }
230#endif
231