mixmaster

mixmaster 3.0 patched for libressl
git clone git://parazyd.org/mixmaster.git
Log | Files | Refs | README

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 }