File: rndseed.c

package info (click to toggle)
mixmaster 3.0b2-4
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 1,356 kB
  • ctags: 1,173
  • sloc: ansic: 18,314; sh: 1,285; yacc: 698; perl: 314; makefile: 161
file content (157 lines) | stat: -rw-r--r-- 3,482 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* Mixmaster version 3.0  --  (C) 1999 - 2004 Anonymizer Inc. and others.

   Mixmaster may be redistributed and modified under certain conditions.
   This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
   ANY KIND, either express or implied. See the file COPYRIGHT for
   details.

   Get randomness from device or user
   $Id: rndseed.c 785 2004-05-01 00:30:40Z weasel $ */


#include "mix3.h"
#include <assert.h>
#include <time.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#ifdef POSIX
#include <unistd.h>
#include <termios.h>
#else /* end of POSIX */
#include <io.h>
#include <process.h>
#endif /* else if not POSIX */
#if defined(WIN32) || defined(MSDOS)
#include <conio.h>
#endif /* defined(WIN32) || defined(MSDOS) */
#ifdef WIN32
#include <windows.h>
#endif /* WIN32 */

#define NEEDED 128

#ifndef O_NDELAY
#define O_NDELAY 0
#endif /* not O_NDELAY */

int kbd_noecho(void)
{
#ifdef HAVE_TERMIOS
  int fd;
  struct termios attr;

  setbuf(stdin, NULL);
  fd = fileno(stdin);
  if (tcgetattr(fd, &attr) != 0)
    return (-1);
  attr.c_lflag &= ~(ECHO | ICANON);
  if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
    return (-1);
#endif /* HAVE_TERMIOS */
  return (0);
}

int kbd_echo(void)
{
#ifdef HAVE_TERMIOS
  int fd;
  struct termios attr;

  setvbuf(stdin, NULL, _IOLBF, BUFSIZ);
  fd = fileno(stdin);
  if (tcgetattr(fd, &attr) != 0)
    return (-1);
  attr.c_lflag |= ECHO | ICANON;
  if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
    return (-1);
#endif /* HAVE_TERMIOS */
  return (0);
}

void rnd_error(void)
{
  errlog(ERRORMSG,
	 "Random number generator not initialized. Aborting.\n\
Run the program interactively to seed the generator.\n");
  exit(3);
}

/* get randomness from system or user. If the application has promised that
   it will seed the RNG later, we do not ask for user input */

int rnd_seed(void)
{
  int fd = -1;
  byte b[512], c = 0;
  int bytes = 0;

#ifdef DEV_RANDOM
  fd = open(DEV_RANDOM, O_RDONLY | O_NDELAY);
#endif /* DEV_RANDOM */
  if (fd == -1) {
#if 1
    if (rnd_state == RND_WILLSEED)
      return(-1);
    if (!isatty(fileno(stdin)))
      rnd_error();
#else /* end of 1 */
#error "should initialize the prng from system ressources"
#endif /* else if not 1 */
    fprintf(stderr, "Please enter some random characters.\n");
    kbd_noecho();
    while (bytes < NEEDED) {
      fprintf(stderr, "  %d     \r", NEEDED - bytes);
#ifdef HAVE_GETKEY
      if (kbhit(), *b = getkey())
#else /* end of HAVE_GETKEY */
      if (read(fileno(stdin), b, 1) > 0)
#endif /* else if not HAVE_GETKEY */
	{
	  rnd_add(b, 1);
	  rnd_time();
	  if (*b != c)
	    bytes++;
	  c = *b;
	}
    }
    fprintf(stderr, "Thanks.\n");
    sleep(1);
    kbd_echo();
  }
#ifdef DEV_RANDOM
  else {
    bytes = read(fd, b, sizeof(b));
    if (bytes > 0) {
      rnd_add(b, bytes);
    } else {
      bytes = 0;
    }
    close(fd);
    if (bytes < NEEDED) {
      fd = open(DEV_RANDOM, O_RDONLY);	/* re-open in blocking mode */
      if (isatty(fileno(stdin))) {
	fprintf(stderr,
		"Please move the mouse, enter random characters, etc.\n");
	kbd_noecho();
      }
      while (bytes < NEEDED) {
	if (isatty(fileno(stdin)))
	  fprintf(stderr, "  %d     \r", NEEDED - bytes);
	if (read(fd, b, 1) > 0) {
	  rnd_add(b, 1);
	  bytes++;
	}
      }
      if (isatty(fileno(stdin))) {
	fprintf(stderr, "Thanks.\n");
	sleep(1);
	kbd_echo();
      }
      close(fd);
    }
  }
#endif /* DEV_RANDOM */
  rnd_state = RND_SEEDED;
  return (0);
}