rndseed.c (3481B)
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others. 2 3 Mixmaster may be redistributed and modified under certain conditions. 4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 5 ANY KIND, either express or implied. See the file COPYRIGHT for 6 details. 7 8 Get randomness from device or user 9 $Id: rndseed.c 934 2006-06-24 13:40:39Z rabbi $ */ 10 11 12 #include "mix3.h" 13 #include <assert.h> 14 #include <time.h> 15 #include <fcntl.h> 16 #include <time.h> 17 #include <stdlib.h> 18 #ifdef POSIX 19 #include <unistd.h> 20 #include <termios.h> 21 #else /* end of POSIX */ 22 #include <io.h> 23 #include <process.h> 24 #endif /* else if not POSIX */ 25 #if defined(WIN32) || defined(MSDOS) 26 #include <conio.h> 27 #endif /* defined(WIN32) || defined(MSDOS) */ 28 #ifdef WIN32 29 #include <windows.h> 30 #endif /* WIN32 */ 31 32 #define NEEDED 128 33 34 #ifndef O_NDELAY 35 #define O_NDELAY 0 36 #endif /* not O_NDELAY */ 37 38 int kbd_noecho(void) 39 { 40 #ifdef HAVE_TERMIOS 41 int fd; 42 struct termios attr; 43 44 setbuf(stdin, NULL); 45 fd = fileno(stdin); 46 if (tcgetattr(fd, &attr) != 0) 47 return (-1); 48 attr.c_lflag &= ~(ECHO | ICANON); 49 if (tcsetattr(fd, TCSAFLUSH, &attr) != 0) 50 return (-1); 51 #endif /* HAVE_TERMIOS */ 52 return (0); 53 } 54 55 int kbd_echo(void) 56 { 57 #ifdef HAVE_TERMIOS 58 int fd; 59 struct termios attr; 60 61 setvbuf(stdin, NULL, _IOLBF, BUFSIZ); 62 fd = fileno(stdin); 63 if (tcgetattr(fd, &attr) != 0) 64 return (-1); 65 attr.c_lflag |= ECHO | ICANON; 66 if (tcsetattr(fd, TCSAFLUSH, &attr) != 0) 67 return (-1); 68 #endif /* HAVE_TERMIOS */ 69 return (0); 70 } 71 72 void rnd_error(void) 73 { 74 errlog(ERRORMSG, 75 "Random number generator not initialized. Aborting.\n\ 76 Run the program interactively to seed the generator.\n"); 77 exit(3); 78 } 79 80 /* get randomness from system or user. If the application has promised that 81 it will seed the RNG later, we do not ask for user input */ 82 83 int rnd_seed(void) 84 { 85 int fd = -1; 86 byte b[512], c = 0; 87 int bytes = 0; 88 89 #ifdef DEV_RANDOM 90 fd = open(DEV_RANDOM, O_RDONLY | O_NDELAY); 91 #endif /* DEV_RANDOM */ 92 if (fd == -1) { 93 #if 1 94 if (rnd_state == RND_WILLSEED) 95 return(-1); 96 if (!isatty(fileno(stdin))) 97 rnd_error(); 98 #else /* end of 1 */ 99 #error "should initialize the prng from system ressources" 100 #endif /* else if not 1 */ 101 fprintf(stderr, "Please enter some random characters.\n"); 102 kbd_noecho(); 103 while (bytes < NEEDED) { 104 fprintf(stderr, " %d \r", NEEDED - bytes); 105 #ifdef HAVE_GETKEY 106 if (kbhit(), *b = getkey()) 107 #else /* end of HAVE_GETKEY */ 108 if (read(fileno(stdin), b, 1) > 0) 109 #endif /* else if not HAVE_GETKEY */ 110 { 111 rnd_add(b, 1); 112 rnd_time(); 113 if (*b != c) 114 bytes++; 115 c = *b; 116 } 117 } 118 fprintf(stderr, "Thanks.\n"); 119 sleep(1); 120 kbd_echo(); 121 } 122 #ifdef DEV_RANDOM 123 else { 124 bytes = read(fd, b, sizeof(b)); 125 if (bytes > 0) { 126 rnd_add(b, bytes); 127 } else { 128 bytes = 0; 129 } 130 close(fd); 131 if (bytes < NEEDED) { 132 fd = open(DEV_RANDOM, O_RDONLY); /* re-open in blocking mode */ 133 if (isatty(fileno(stdin))) { 134 fprintf(stderr, 135 "Please move the mouse, enter random characters, etc.\n"); 136 kbd_noecho(); 137 } 138 while (bytes < NEEDED) { 139 if (isatty(fileno(stdin))) 140 fprintf(stderr, " %d \r", NEEDED - bytes); 141 if (read(fd, b, 1) > 0) { 142 rnd_add(b, 1); 143 bytes++; 144 } 145 } 146 if (isatty(fileno(stdin))) { 147 fprintf(stderr, "Thanks.\n"); 148 sleep(1); 149 kbd_echo(); 150 } 151 close(fd); 152 } 153 } 154 #endif /* DEV_RANDOM */ 155 rnd_state = RND_SEEDED; 156 return (0); 157 }