1193645Ssimon/*
2193645Ssimon * Crude test driver for processing the VST and MCT testvector files
3193645Ssimon * generated by the CMVP RNGVS product.
4193645Ssimon *
5193645Ssimon * Note the input files are assumed to have a _very_ specific format
6193645Ssimon * as described in the NIST document "The Random Number Generator
7193645Ssimon * Validation System (RNGVS)", May 25, 2004.
8193645Ssimon *
9193645Ssimon */
10193645Ssimon#include <openssl/opensslconf.h>
11193645Ssimon
12193645Ssimon#ifndef OPENSSL_FIPS
13296465Sdelphij# include <stdio.h>
14193645Ssimon
15193645Ssimonint main(int argc, char **argv)
16193645Ssimon{
17193645Ssimon    printf("No FIPS RNG support\n");
18193645Ssimon    return 0;
19193645Ssimon}
20193645Ssimon#else
21193645Ssimon
22296465Sdelphij# include <openssl/bn.h>
23296465Sdelphij# include <openssl/dsa.h>
24296465Sdelphij# include <openssl/fips.h>
25296465Sdelphij# include <openssl/err.h>
26296465Sdelphij# include <openssl/rand.h>
27296465Sdelphij# include <openssl/fips_rand.h>
28296465Sdelphij# include <openssl/x509v3.h>
29296465Sdelphij# include <string.h>
30296465Sdelphij# include <ctype.h>
31193645Ssimon
32296465Sdelphij# include "fips_utl.h"
33193645Ssimon
34205128Ssimonstatic void vst()
35296465Sdelphij{
36193645Ssimon    unsigned char *key = NULL;
37193645Ssimon    unsigned char *v = NULL;
38193645Ssimon    unsigned char *dt = NULL;
39193645Ssimon    unsigned char ret[16];
40193645Ssimon    char buf[1024];
41193645Ssimon    char lbuf[1024];
42193645Ssimon    char *keyword, *value;
43193645Ssimon    long i, keylen;
44193645Ssimon
45193645Ssimon    keylen = 0;
46193645Ssimon
47296465Sdelphij    while (fgets(buf, sizeof buf, stdin) != NULL) {
48296465Sdelphij        fputs(buf, stdout);
49296465Sdelphij        if (!strncmp(buf, "[AES 128-Key]", 13))
50296465Sdelphij            keylen = 16;
51296465Sdelphij        else if (!strncmp(buf, "[AES 192-Key]", 13))
52296465Sdelphij            keylen = 24;
53296465Sdelphij        else if (!strncmp(buf, "[AES 256-Key]", 13))
54296465Sdelphij            keylen = 32;
55296465Sdelphij        if (!parse_line(&keyword, &value, lbuf, buf))
56296465Sdelphij            continue;
57296465Sdelphij        if (!strcmp(keyword, "Key")) {
58296465Sdelphij            key = hex2bin_m(value, &i);
59296465Sdelphij            if (i != keylen) {
60296465Sdelphij                fprintf(stderr, "Invalid key length, expecting %ld\n",
61296465Sdelphij                        keylen);
62296465Sdelphij                return;
63296465Sdelphij            }
64296465Sdelphij        } else if (!strcmp(keyword, "DT")) {
65296465Sdelphij            dt = hex2bin_m(value, &i);
66296465Sdelphij            if (i != 16) {
67296465Sdelphij                fprintf(stderr, "Invalid DT length\n");
68296465Sdelphij                return;
69296465Sdelphij            }
70296465Sdelphij        } else if (!strcmp(keyword, "V")) {
71296465Sdelphij            v = hex2bin_m(value, &i);
72296465Sdelphij            if (i != 16) {
73296465Sdelphij                fprintf(stderr, "Invalid V length\n");
74296465Sdelphij                return;
75296465Sdelphij            }
76193645Ssimon
77296465Sdelphij            if (!key || !dt) {
78296465Sdelphij                fprintf(stderr, "Missing key or DT\n");
79296465Sdelphij                return;
80296465Sdelphij            }
81193645Ssimon
82296465Sdelphij            FIPS_rand_set_key(key, keylen);
83296465Sdelphij            FIPS_rand_seed(v, 16);
84296465Sdelphij            FIPS_rand_set_dt(dt);
85296465Sdelphij            if (FIPS_rand_bytes(ret, 16) <= 0) {
86296465Sdelphij                fprintf(stderr, "Error getting PRNG value\n");
87296465Sdelphij                return;
88296465Sdelphij            }
89193645Ssimon
90296465Sdelphij            pv("R", ret, 16);
91296465Sdelphij            OPENSSL_free(key);
92296465Sdelphij            key = NULL;
93296465Sdelphij            OPENSSL_free(dt);
94296465Sdelphij            dt = NULL;
95296465Sdelphij            OPENSSL_free(v);
96296465Sdelphij            v = NULL;
97296465Sdelphij        }
98193645Ssimon    }
99296465Sdelphij}
100193645Ssimon
101205128Ssimonstatic void mct()
102296465Sdelphij{
103193645Ssimon    unsigned char *key = NULL;
104193645Ssimon    unsigned char *v = NULL;
105193645Ssimon    unsigned char *dt = NULL;
106193645Ssimon    unsigned char ret[16];
107193645Ssimon    char buf[1024];
108193645Ssimon    char lbuf[1024];
109193645Ssimon    char *keyword, *value;
110193645Ssimon    long i, keylen;
111193645Ssimon    int j;
112193645Ssimon
113193645Ssimon    keylen = 0;
114193645Ssimon
115296465Sdelphij    while (fgets(buf, sizeof buf, stdin) != NULL) {
116296465Sdelphij        fputs(buf, stdout);
117296465Sdelphij        if (!strncmp(buf, "[AES 128-Key]", 13))
118296465Sdelphij            keylen = 16;
119296465Sdelphij        else if (!strncmp(buf, "[AES 192-Key]", 13))
120296465Sdelphij            keylen = 24;
121296465Sdelphij        else if (!strncmp(buf, "[AES 256-Key]", 13))
122296465Sdelphij            keylen = 32;
123296465Sdelphij        if (!parse_line(&keyword, &value, lbuf, buf))
124296465Sdelphij            continue;
125296465Sdelphij        if (!strcmp(keyword, "Key")) {
126296465Sdelphij            key = hex2bin_m(value, &i);
127296465Sdelphij            if (i != keylen) {
128296465Sdelphij                fprintf(stderr, "Invalid key length, expecting %ld\n",
129296465Sdelphij                        keylen);
130296465Sdelphij                return;
131296465Sdelphij            }
132296465Sdelphij        } else if (!strcmp(keyword, "DT")) {
133296465Sdelphij            dt = hex2bin_m(value, &i);
134296465Sdelphij            if (i != 16) {
135296465Sdelphij                fprintf(stderr, "Invalid DT length\n");
136296465Sdelphij                return;
137296465Sdelphij            }
138296465Sdelphij        } else if (!strcmp(keyword, "V")) {
139296465Sdelphij            v = hex2bin_m(value, &i);
140296465Sdelphij            if (i != 16) {
141296465Sdelphij                fprintf(stderr, "Invalid V length\n");
142296465Sdelphij                return;
143296465Sdelphij            }
144193645Ssimon
145296465Sdelphij            if (!key || !dt) {
146296465Sdelphij                fprintf(stderr, "Missing key or DT\n");
147296465Sdelphij                return;
148296465Sdelphij            }
149193645Ssimon
150296465Sdelphij            FIPS_rand_set_key(key, keylen);
151296465Sdelphij            FIPS_rand_seed(v, 16);
152296465Sdelphij            for (i = 0; i < 10000; i++) {
153296465Sdelphij                FIPS_rand_set_dt(dt);
154296465Sdelphij                if (FIPS_rand_bytes(ret, 16) <= 0) {
155296465Sdelphij                    fprintf(stderr, "Error getting PRNG value\n");
156296465Sdelphij                    return;
157296465Sdelphij                }
158296465Sdelphij                /* Increment DT */
159296465Sdelphij                for (j = 15; j >= 0; j--) {
160296465Sdelphij                    dt[j]++;
161296465Sdelphij                    if (dt[j])
162296465Sdelphij                        break;
163296465Sdelphij                }
164296465Sdelphij            }
165193645Ssimon
166296465Sdelphij            pv("R", ret, 16);
167296465Sdelphij            OPENSSL_free(key);
168296465Sdelphij            key = NULL;
169296465Sdelphij            OPENSSL_free(dt);
170296465Sdelphij            dt = NULL;
171296465Sdelphij            OPENSSL_free(v);
172296465Sdelphij            v = NULL;
173296465Sdelphij        }
174193645Ssimon    }
175296465Sdelphij}
176193645Ssimon
177296465Sdelphijint main(int argc, char **argv)
178296465Sdelphij{
179296465Sdelphij    if (argc != 2) {
180296465Sdelphij        fprintf(stderr, "%s [mct|vst]\n", argv[0]);
181296465Sdelphij        exit(1);
182296465Sdelphij    }
183296465Sdelphij    if (!FIPS_mode_set(1)) {
184296465Sdelphij        do_print_errors();
185296465Sdelphij        exit(1);
186296465Sdelphij    }
187193645Ssimon    FIPS_rand_reset();
188296465Sdelphij    if (!FIPS_rand_test_mode()) {
189296465Sdelphij        fprintf(stderr, "Error setting PRNG test mode\n");
190296465Sdelphij        do_print_errors();
191296465Sdelphij        exit(1);
192296465Sdelphij    }
193296465Sdelphij    if (!strcmp(argv[1], "mct"))
194296465Sdelphij        mct();
195296465Sdelphij    else if (!strcmp(argv[1], "vst"))
196296465Sdelphij        vst();
197296465Sdelphij    else {
198296465Sdelphij        fprintf(stderr, "Don't know how to %s.\n", argv[1]);
199296465Sdelphij        exit(1);
200296465Sdelphij    }
201193645Ssimon
202193645Ssimon    return 0;
203296465Sdelphij}
204193645Ssimon#endif
205