xref: /minix3/crypto/external/bsd/heimdal/dist/lib/hcrypto/test_rand.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 /*	$NetBSD: test_rand.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $	*/
2 
3 /*
4  * Copyright (c) 2007 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  *
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * 3. Neither the name of the Institute nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #include <config.h>
39 
40 #include <stdio.h>
41 
42 #include <krb5/roken.h>
43 #include <krb5/getarg.h>
44 
45 #include "rand.h"
46 
47 
48 /*
49  *
50  */
51 
52 static int version_flag;
53 static int help_flag;
54 static int len = 1024 * 1024;
55 static char *rand_method;
56 static char *filename;
57 
58 static struct getargs args[] = {
59     { "length",	0,	arg_integer,	&len,
60       "length", NULL },
61     { "file",	0,	arg_string,	&filename,
62       "file name", NULL },
63     { "method",	0,	arg_string,	&rand_method,
64       "method", NULL },
65     { "version",	0,	arg_flag,	&version_flag,
66       "print version", NULL },
67     { "help",		0,	arg_flag,	&help_flag,
68       NULL, 	NULL }
69 };
70 
71 /*
72  *
73  */
74 
75 /*
76  *
77  */
78 
79 static void
usage(int ret)80 usage (int ret)
81 {
82     arg_printusage (args,
83 		    sizeof(args)/sizeof(args[0]),
84 		    NULL,
85 		    "");
86     exit (ret);
87 }
88 
89 int
main(int argc,char ** argv)90 main(int argc, char **argv)
91 {
92     int idx = 0;
93     char *buffer;
94     char path[MAXPATHLEN];
95 
96     setprogname(argv[0]);
97 
98     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &idx))
99 	usage(1);
100 
101     if (help_flag)
102 	usage(0);
103 
104     if(version_flag){
105 	print_version(NULL);
106 	exit(0);
107     }
108 
109     argc -= idx;
110     argv += idx;
111 
112     if (argc != 0)
113 	usage(1);
114 
115     buffer = emalloc(len);
116 
117     if (rand_method) {
118 	if (0) {
119 	}
120 #ifndef NO_RAND_FORTUNA_METHOD
121 	else if (strcasecmp(rand_method, "fortuna") == 0)
122 	    RAND_set_rand_method(RAND_fortuna_method());
123 #endif
124 #ifndef NO_RAND_UNIX_METHOD
125 	else if (strcasecmp(rand_method, "unix") == 0)
126 	    RAND_set_rand_method(RAND_unix_method());
127 #endif
128 #ifndef NO_RAND_EGD_METHOD
129 	else if (strcasecmp(rand_method, "egd") == 0)
130 	    RAND_set_rand_method(RAND_egd_method());
131 #endif
132 #ifdef WIN32
133 	else if (strcasecmp(rand_method, "w32crypto") == 0)
134 	    RAND_set_rand_method(RAND_w32crypto_method());
135 #endif
136 	else
137 	    errx(1, "unknown method %s", rand_method);
138     }
139 
140     if (RAND_file_name(path, sizeof(path)) == NULL)
141 	errx(1, "RAND_file_name failed");
142 
143     if (RAND_status() != 1)
144 	errx(1, "random not ready yet");
145 
146     if (RAND_bytes(buffer, len) != 1)
147 	errx(1, "RAND_bytes");
148 
149     if (filename)
150 	rk_dumpdata(filename, buffer, len);
151 
152     /* head vs tail */
153     if (len >= 100000) {
154 	int bit, i;
155 	double res;
156 	int bits[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
157 
158 	for (i = 0; i < len; i++) {
159 	    unsigned char c = ((unsigned char *)buffer)[i];
160 	    for (bit = 0; bit < 8 && c; bit++) {
161 		if (c & 1)
162 		    bits[bit]++;
163 		c = c >> 1;
164 	    }
165 	}
166 
167 	for (bit = 0; bit < 8; bit++) {
168 
169 	    res = ((double)abs(len - bits[bit] * 2)) / (double)len;
170 	    if (res > 0.005)
171 		errx(1, "head%d vs tail%d > 0.5%%%% %lf == %d vs %d",
172 		     bit, bit, res, len, bits[bit]);
173 
174 	    printf("head vs tails bit%d: %lf\n", bit, res);
175 	}
176     }
177 
178     free(buffer);
179 
180     /* test write random file */
181     {
182 	static const char *file = "test.file";
183 	if (RAND_write_file(file) != 1)
184 	    errx(1, "RAND_write_file");
185 	if (RAND_load_file(file, 1024) != 1)
186 	    errx(1, "RAND_load_file");
187 	unlink(file);
188     }
189 
190     return 0;
191 }
192