1 /* $NetBSD: rand-timer.c,v 1.1.1.1 2011/04/13 18:14:50 elric Exp $ */
4 * Copyright (c) 1995, 1996, 1997, 1999, 2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 #include <krb5/roken.h>
46 #ifndef WIN32 /* don't bother with this on windows */
48 static volatile int counter
;
49 static volatile unsigned char *gdata
; /* Global data */
50 static volatile int igdata
; /* Index into global data */
58 gdata
[igdata
++] ^= counter
& 0xff;
60 #ifndef HAVE_SIGACTION
61 signal(SIGALRM
, sigALRM
); /* Reinstall SysV signal handler */
66 #ifndef HAVE_SETITIMER
68 pacemaker(struct timeval
*tv
)
76 select(1, &fds
, NULL
, NULL
, tv
);
83 /* XXX ugly hack, should perhaps use function from roken */
85 (*fake_signal(int sig
, RETSIGTYPE (*f
)(int)))(int)
87 struct sigaction sa
, osa
;
90 sigemptyset(&sa
.sa_mask
);
91 sigaction(sig
, &sa
, &osa
);
92 return osa
.sa_handler
;
94 #define signal(S, F) fake_signal((S), (F))
104 timer_seed(const void *indata
, int size
)
109 timer_bytes(unsigned char *outdata
, int size
)
114 struct itimerval tv
, otv
;
115 RETSIGTYPE (*osa
)(int);
117 #ifndef HAVE_SETITIMER
118 RETSIGTYPE (*ochld
)(int);
126 osa
= signal(SIGALRM
, sigALRM
);
129 tv
.it_value
.tv_sec
= 0;
130 tv
.it_value
.tv_usec
= 10 * 1000; /* 10 ms */
131 tv
.it_interval
= tv
.it_value
;
132 #ifdef HAVE_SETITIMER
133 setitimer(ITIMER_REAL
, &tv
, &otv
);
135 ochld
= signal(SIGCHLD
, SIG_IGN
);
138 signal(SIGCHLD
, ochld
!= SIG_ERR
? ochld
: SIG_DFL
);
139 des_not_rand_data(data
, size
);
143 pacemaker(&tv
.it_interval
);
146 for(i
= 0; i
< 4; i
++) {
147 for (igdata
= 0; igdata
< size
;) /* igdata++ in sigALRM */
149 for (j
= 0; j
< size
; j
++) /* Only use 2 bits each lap */
150 gdata
[j
] = (gdata
[j
]>>2) | (gdata
[j
]<<6);
152 #ifdef HAVE_SETITIMER
153 setitimer(ITIMER_REAL
, &otv
, 0);
156 while(waitpid(pid
, NULL
, 0) != pid
);
157 signal(SIGCHLD
, ochld
!= SIG_ERR
? ochld
: SIG_DFL
);
159 signal(SIGALRM
, osa
!= SIG_ERR
? osa
: SIG_DFL
);
171 timer_add(const void *indata
, int size
, double entropi
)
176 timer_pseudorand(unsigned char *outdata
, int size
)
178 return timer_bytes(outdata
, size
);
191 const RAND_METHOD hc_rand_timer_method
= {
201 RAND_timer_method(void)
203 return &hc_rand_timer_method
;