xref: /freebsd-14.2/sys/dev/random/unit_test.c (revision 10cb2424)
1*10cb2424SMark Murray /*-
2*10cb2424SMark Murray  * Copyright (c) 2000-2013 Mark R V Murray
3*10cb2424SMark Murray  * All rights reserved.
4*10cb2424SMark Murray  *
5*10cb2424SMark Murray  * Redistribution and use in source and binary forms, with or without
6*10cb2424SMark Murray  * modification, are permitted provided that the following conditions
7*10cb2424SMark Murray  * are met:
8*10cb2424SMark Murray  * 1. Redistributions of source code must retain the above copyright
9*10cb2424SMark Murray  *    notice, this list of conditions and the following disclaimer
10*10cb2424SMark Murray  *    in this position and unchanged.
11*10cb2424SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
12*10cb2424SMark Murray  *    notice, this list of conditions and the following disclaimer in the
13*10cb2424SMark Murray  *    documentation and/or other materials provided with the distribution.
14*10cb2424SMark Murray  *
15*10cb2424SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16*10cb2424SMark Murray  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*10cb2424SMark Murray  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*10cb2424SMark Murray  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19*10cb2424SMark Murray  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*10cb2424SMark Murray  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*10cb2424SMark Murray  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*10cb2424SMark Murray  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*10cb2424SMark Murray  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*10cb2424SMark Murray  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*10cb2424SMark Murray  *
26*10cb2424SMark Murray  * $FreeBSD$
27*10cb2424SMark Murray  */
28*10cb2424SMark Murray 
29*10cb2424SMark Murray /*
30*10cb2424SMark Murray  Build this by going:
31*10cb2424SMark Murray 
32*10cb2424SMark Murray cc -g -O0 -pthread -DRANDOM_<alg> -DRANDOM_DEBUG -I../.. -lstdthreads -Wall \
33*10cb2424SMark Murray 	unit_test.c \
34*10cb2424SMark Murray 	yarrow.c \
35*10cb2424SMark Murray 	fortuna.c \
36*10cb2424SMark Murray 	hash.c \
37*10cb2424SMark Murray 	../../crypto/rijndael/rijndael-api-fst.c \
38*10cb2424SMark Murray 	../../crypto/rijndael/rijndael-alg-fst.c \
39*10cb2424SMark Murray 	../../crypto/sha2/sha2.c \
40*10cb2424SMark Murray 	-o unit_test
41*10cb2424SMark Murray ./unit_test
42*10cb2424SMark Murray 
43*10cb2424SMark Murray Where <alg> is YARROW or FORTUNA.
44*10cb2424SMark Murray */
45*10cb2424SMark Murray 
46*10cb2424SMark Murray #include <sys/types.h>
47*10cb2424SMark Murray #include <inttypes.h>
48*10cb2424SMark Murray #include <stdio.h>
49*10cb2424SMark Murray #include <stdlib.h>
50*10cb2424SMark Murray #include <threads.h>
51*10cb2424SMark Murray #include <unistd.h>
52*10cb2424SMark Murray 
53*10cb2424SMark Murray #include "unit_test.h"
54*10cb2424SMark Murray 
55*10cb2424SMark Murray #ifdef RANDOM_YARROW
56*10cb2424SMark Murray #include "dev/random/yarrow.h"
57*10cb2424SMark Murray #endif
58*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
59*10cb2424SMark Murray #include "dev/random/fortuna.h"
60*10cb2424SMark Murray #endif
61*10cb2424SMark Murray 
62*10cb2424SMark Murray #define NUM_THREADS	  3
63*10cb2424SMark Murray 
64*10cb2424SMark Murray static volatile int stopseeding = 0;
65*10cb2424SMark Murray 
66*10cb2424SMark Murray void
67*10cb2424SMark Murray random_adaptor_unblock(void)
68*10cb2424SMark Murray {
69*10cb2424SMark Murray 
70*10cb2424SMark Murray #if 0
71*10cb2424SMark Murray 	if (mtx_trylock(&random_reseed_mtx) == thrd_busy)
72*10cb2424SMark Murray 		printf("Mutex held. Good.\n");
73*10cb2424SMark Murray 	else {
74*10cb2424SMark Murray 		printf("Mutex not held. PANIC!!\n");
75*10cb2424SMark Murray 		thrd_exit(0);
76*10cb2424SMark Murray 	}
77*10cb2424SMark Murray #endif
78*10cb2424SMark Murray 	printf("random: unblocking device.\n");
79*10cb2424SMark Murray }
80*10cb2424SMark Murray 
81*10cb2424SMark Murray static int
82*10cb2424SMark Murray RunHarvester(void *arg __unused)
83*10cb2424SMark Murray {
84*10cb2424SMark Murray 	int i, r;
85*10cb2424SMark Murray 	struct harvest_event e;
86*10cb2424SMark Murray 
87*10cb2424SMark Murray 	for (i = 0; ; i++) {
88*10cb2424SMark Murray 		if (stopseeding)
89*10cb2424SMark Murray 			break;
90*10cb2424SMark Murray 		if (i % 1000 == 0)
91*10cb2424SMark Murray 			printf("Harvest: %d\n", i);
92*10cb2424SMark Murray 		r = random()%10;
93*10cb2424SMark Murray 		e.he_somecounter = i;
94*10cb2424SMark Murray 		*((uint64_t *)e.he_entropy) = random();
95*10cb2424SMark Murray 		e.he_size = 8;
96*10cb2424SMark Murray 		e.he_bits = random()%4;
97*10cb2424SMark Murray 		e.he_destination = i;
98*10cb2424SMark Murray 		e.he_source = (i + 3)%7;
99*10cb2424SMark Murray 		e.he_next = NULL;
100*10cb2424SMark Murray #ifdef RANDOM_YARROW
101*10cb2424SMark Murray 		random_yarrow_process_event(&e);
102*10cb2424SMark Murray #endif
103*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
104*10cb2424SMark Murray 		random_fortuna_process_event(&e);
105*10cb2424SMark Murray #endif
106*10cb2424SMark Murray 		usleep(r);
107*10cb2424SMark Murray 	}
108*10cb2424SMark Murray 
109*10cb2424SMark Murray 	printf("Thread #0 ends\n");
110*10cb2424SMark Murray 
111*10cb2424SMark Murray 	thrd_exit(0);
112*10cb2424SMark Murray 
113*10cb2424SMark Murray 	return (0);
114*10cb2424SMark Murray }
115*10cb2424SMark Murray 
116*10cb2424SMark Murray static int
117*10cb2424SMark Murray WriteCSPRNG(void *threadid)
118*10cb2424SMark Murray {
119*10cb2424SMark Murray 	uint8_t *buf;
120*10cb2424SMark Murray 	int i;
121*10cb2424SMark Murray 
122*10cb2424SMark Murray 	printf("Thread #1 starts\n");
123*10cb2424SMark Murray 
124*10cb2424SMark Murray 	for (i = 0; ; i++) {
125*10cb2424SMark Murray 		if (stopseeding)
126*10cb2424SMark Murray 			break;
127*10cb2424SMark Murray 		buf = malloc(4096);
128*10cb2424SMark Murray 		if (i % 1000 == 0)
129*10cb2424SMark Murray 			printf("Thread write 1 - %d\n", i);
130*10cb2424SMark Murray 		if (buf != NULL) {
131*10cb2424SMark Murray #ifdef RANDOM_YARROW
132*10cb2424SMark Murray 			random_yarrow_write(buf, i);
133*10cb2424SMark Murray #endif
134*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
135*10cb2424SMark Murray 			random_fortuna_write(buf, i);
136*10cb2424SMark Murray #endif
137*10cb2424SMark Murray 			free(buf);
138*10cb2424SMark Murray 		}
139*10cb2424SMark Murray 		usleep(1000000);
140*10cb2424SMark Murray 	}
141*10cb2424SMark Murray 
142*10cb2424SMark Murray 	printf("Thread #1 ends\n");
143*10cb2424SMark Murray 
144*10cb2424SMark Murray 	thrd_exit(0);
145*10cb2424SMark Murray 
146*10cb2424SMark Murray 	return (0);
147*10cb2424SMark Murray }
148*10cb2424SMark Murray 
149*10cb2424SMark Murray static int
150*10cb2424SMark Murray ReadCSPRNG(void *threadid)
151*10cb2424SMark Murray {
152*10cb2424SMark Murray 	size_t tid;
153*10cb2424SMark Murray 	uint8_t *buf;
154*10cb2424SMark Murray 	int i;
155*10cb2424SMark Murray 
156*10cb2424SMark Murray 	tid = (size_t)threadid;
157*10cb2424SMark Murray 	printf("Thread #%zd starts\n", tid);
158*10cb2424SMark Murray 
159*10cb2424SMark Murray #ifdef RANDOM_YARROW
160*10cb2424SMark Murray 	while (!random_yarrow_seeded())
161*10cb2424SMark Murray #endif
162*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
163*10cb2424SMark Murray 	while (!random_fortuna_seeded())
164*10cb2424SMark Murray #endif
165*10cb2424SMark Murray 	{
166*10cb2424SMark Murray #ifdef RANDOM_YARROW
167*10cb2424SMark Murray 		random_yarrow_read(NULL, 0);
168*10cb2424SMark Murray 		random_yarrow_read(NULL, 1);
169*10cb2424SMark Murray #endif
170*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
171*10cb2424SMark Murray 		random_fortuna_read(NULL, 0);
172*10cb2424SMark Murray 		random_fortuna_read(NULL, 1);
173*10cb2424SMark Murray #endif
174*10cb2424SMark Murray 		usleep(100);
175*10cb2424SMark Murray 	}
176*10cb2424SMark Murray 
177*10cb2424SMark Murray 	for (i = 0; i < 100000; i++) {
178*10cb2424SMark Murray 		buf = malloc(i);
179*10cb2424SMark Murray 		if (i % 1000 == 0)
180*10cb2424SMark Murray 			printf("Thread read %zd - %d %p\n", tid, i, buf);
181*10cb2424SMark Murray 		if (buf != NULL) {
182*10cb2424SMark Murray #ifdef RANDOM_YARROW
183*10cb2424SMark Murray 			random_yarrow_read(NULL, 0);
184*10cb2424SMark Murray 			random_yarrow_read(buf, i);
185*10cb2424SMark Murray 			random_yarrow_read(NULL, 1);
186*10cb2424SMark Murray #endif
187*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
188*10cb2424SMark Murray 			random_fortuna_read(NULL, 0);
189*10cb2424SMark Murray 			random_fortuna_read(buf, i);
190*10cb2424SMark Murray 			random_fortuna_read(NULL, 1);
191*10cb2424SMark Murray #endif
192*10cb2424SMark Murray #if 0
193*10cb2424SMark Murray 			{
194*10cb2424SMark Murray 			int j;
195*10cb2424SMark Murray 
196*10cb2424SMark Murray 			for (j = 0; j < i; j++) {
197*10cb2424SMark Murray 				printf(" %02X", buf[j]);
198*10cb2424SMark Murray 				if (j % 32 == 31 || j == i - 1)
199*10cb2424SMark Murray 					printf("\n");
200*10cb2424SMark Murray 			}
201*10cb2424SMark Murray 			}
202*10cb2424SMark Murray #endif
203*10cb2424SMark Murray 			free(buf);
204*10cb2424SMark Murray 		}
205*10cb2424SMark Murray 		usleep(100);
206*10cb2424SMark Murray 	}
207*10cb2424SMark Murray 
208*10cb2424SMark Murray 	printf("Thread #%zd ends\n", tid);
209*10cb2424SMark Murray 
210*10cb2424SMark Murray 	thrd_exit(0);
211*10cb2424SMark Murray 
212*10cb2424SMark Murray 	return (0);
213*10cb2424SMark Murray }
214*10cb2424SMark Murray 
215*10cb2424SMark Murray int
216*10cb2424SMark Murray main(int argc, char *argv[])
217*10cb2424SMark Murray {
218*10cb2424SMark Murray 	thrd_t threads[NUM_THREADS];
219*10cb2424SMark Murray 	int rc;
220*10cb2424SMark Murray 	long t;
221*10cb2424SMark Murray 
222*10cb2424SMark Murray #ifdef RANDOM_YARROW
223*10cb2424SMark Murray 	random_yarrow_init_alg();
224*10cb2424SMark Murray #endif
225*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
226*10cb2424SMark Murray 	random_fortuna_init_alg();
227*10cb2424SMark Murray #endif
228*10cb2424SMark Murray 
229*10cb2424SMark Murray 	for (t = 0; t < NUM_THREADS; t++) {
230*10cb2424SMark Murray 		printf("In main: creating thread %ld\n", t);
231*10cb2424SMark Murray 		rc = thrd_create(&threads[t], (t == 0 ? RunHarvester : (t == 1 ? WriteCSPRNG : ReadCSPRNG)), t);
232*10cb2424SMark Murray 		if (rc != thrd_success) {
233*10cb2424SMark Murray 			printf("ERROR; return code from thrd_create() is %d\n", rc);
234*10cb2424SMark Murray 			exit(-1);
235*10cb2424SMark Murray 		}
236*10cb2424SMark Murray 	}
237*10cb2424SMark Murray 
238*10cb2424SMark Murray 	for (t = 2; t < NUM_THREADS; t++)
239*10cb2424SMark Murray 		thrd_join(threads[t], &rc);
240*10cb2424SMark Murray 
241*10cb2424SMark Murray 	stopseeding = 1;
242*10cb2424SMark Murray 
243*10cb2424SMark Murray 	thrd_join(threads[1], &rc);
244*10cb2424SMark Murray 	thrd_join(threads[0], &rc);
245*10cb2424SMark Murray 
246*10cb2424SMark Murray #ifdef RANDOM_YARROW
247*10cb2424SMark Murray 	random_yarrow_deinit_alg();
248*10cb2424SMark Murray #endif
249*10cb2424SMark Murray #ifdef RANDOM_FORTUNA
250*10cb2424SMark Murray 	random_fortuna_deinit_alg();
251*10cb2424SMark Murray #endif
252*10cb2424SMark Murray 
253*10cb2424SMark Murray 	/* Last thing that main() should do */
254*10cb2424SMark Murray 	thrd_exit(0);
255*10cb2424SMark Murray 
256*10cb2424SMark Murray 	return (0);
257*10cb2424SMark Murray }
258