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