diff options
author | djm <> | 2012-01-05 23:01:39 +0000 |
---|---|---|
committer | djm <> | 2012-01-05 23:01:39 +0000 |
commit | f48d9d4a955d7e4c1c692099ab67e1dbfeb51137 (patch) | |
tree | 866512933d8f0c1ea5465d0169915b36c1ca3cae /src/lib/libcrypto/rand/rand_unix.c | |
parent | 35dadfe897866818c3fd0350efefc5caae349fb6 (diff) | |
download | openbsd-f48d9d4a955d7e4c1c692099ab67e1dbfeb51137.tar.gz openbsd-f48d9d4a955d7e4c1c692099ab67e1dbfeb51137.tar.bz2 openbsd-f48d9d4a955d7e4c1c692099ab67e1dbfeb51137.zip |
OpenSSL 1.0.0f: merge
Diffstat (limited to 'src/lib/libcrypto/rand/rand_unix.c')
-rw-r--r-- | src/lib/libcrypto/rand/rand_unix.c | 108 |
1 files changed, 74 insertions, 34 deletions
diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c index 4bb9666e49..3316388443 100644 --- a/src/lib/libcrypto/rand/rand_unix.c +++ b/src/lib/libcrypto/rand/rand_unix.c | |||
@@ -133,47 +133,87 @@ | |||
133 | # define FD_SETSIZE (8*sizeof(fd_set)) | 133 | # define FD_SETSIZE (8*sizeof(fd_set)) |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | #ifdef __VOS__ | 136 | #if defined(OPENSSL_SYS_VOS) |
137 | |||
138 | /* The following algorithm repeatedly samples the real-time clock | ||
139 | (RTC) to generate a sequence of unpredictable data. The algorithm | ||
140 | relies upon the uneven execution speed of the code (due to factors | ||
141 | such as cache misses, interrupts, bus activity, and scheduling) and | ||
142 | upon the rather large relative difference between the speed of the | ||
143 | clock and the rate at which it can be read. | ||
144 | |||
145 | If this code is ported to an environment where execution speed is | ||
146 | more constant or where the RTC ticks at a much slower rate, or the | ||
147 | clock can be read with fewer instructions, it is likely that the | ||
148 | results would be far more predictable. | ||
149 | |||
150 | As a precaution, we generate 4 times the minimum required amount of | ||
151 | seed data. */ | ||
152 | |||
137 | int RAND_poll(void) | 153 | int RAND_poll(void) |
138 | { | 154 | { |
139 | unsigned char buf[ENTROPY_NEEDED]; | 155 | short int code; |
156 | gid_t curr_gid; | ||
140 | pid_t curr_pid; | 157 | pid_t curr_pid; |
141 | uid_t curr_uid; | 158 | uid_t curr_uid; |
142 | static int first=1; | 159 | int i, k; |
143 | int i; | ||
144 | long rnd = 0; | ||
145 | struct timespec ts; | 160 | struct timespec ts; |
146 | unsigned seed; | 161 | unsigned char v; |
147 | |||
148 | /* The VOS random() function starts from a static seed so its | ||
149 | initial value is predictable. If random() returns the | ||
150 | initial value, reseed it with dynamic data. The VOS | ||
151 | real-time clock has a granularity of 1 nsec so it should be | ||
152 | reasonably difficult to predict its exact value. Do not | ||
153 | gratuitously reseed the PRNG because other code in this | ||
154 | process or thread may be using it. */ | ||
155 | |||
156 | if (first) { | ||
157 | first = 0; | ||
158 | rnd = random (); | ||
159 | if (rnd == 1804289383) { | ||
160 | clock_gettime (CLOCK_REALTIME, &ts); | ||
161 | curr_pid = getpid(); | ||
162 | curr_uid = getuid(); | ||
163 | seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid; | ||
164 | srandom (seed); | ||
165 | } | ||
166 | } | ||
167 | 162 | ||
168 | for (i = 0; i < sizeof(buf); i++) { | 163 | #ifdef OPENSSL_SYS_VOS_HPPA |
169 | if (i % 4 == 0) | 164 | long duration; |
170 | rnd = random(); | 165 | extern void s$sleep (long *_duration, short int *_code); |
171 | buf[i] = rnd; | 166 | #else |
172 | rnd >>= 8; | 167 | #ifdef OPENSSL_SYS_VOS_IA32 |
173 | } | 168 | long long duration; |
174 | RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); | 169 | extern void s$sleep2 (long long *_duration, short int *_code); |
175 | memset(buf, 0, sizeof(buf)); | 170 | #else |
171 | #error "Unsupported Platform." | ||
172 | #endif /* OPENSSL_SYS_VOS_IA32 */ | ||
173 | #endif /* OPENSSL_SYS_VOS_HPPA */ | ||
176 | 174 | ||
175 | /* Seed with the gid, pid, and uid, to ensure *some* | ||
176 | variation between different processes. */ | ||
177 | |||
178 | curr_gid = getgid(); | ||
179 | RAND_add (&curr_gid, sizeof curr_gid, 1); | ||
180 | curr_gid = 0; | ||
181 | |||
182 | curr_pid = getpid(); | ||
183 | RAND_add (&curr_pid, sizeof curr_pid, 1); | ||
184 | curr_pid = 0; | ||
185 | |||
186 | curr_uid = getuid(); | ||
187 | RAND_add (&curr_uid, sizeof curr_uid, 1); | ||
188 | curr_uid = 0; | ||
189 | |||
190 | for (i=0; i<(ENTROPY_NEEDED*4); i++) | ||
191 | { | ||
192 | /* burn some cpu; hope for interrupts, cache | ||
193 | collisions, bus interference, etc. */ | ||
194 | for (k=0; k<99; k++) | ||
195 | ts.tv_nsec = random (); | ||
196 | |||
197 | #ifdef OPENSSL_SYS_VOS_HPPA | ||
198 | /* sleep for 1/1024 of a second (976 us). */ | ||
199 | duration = 1; | ||
200 | s$sleep (&duration, &code); | ||
201 | #else | ||
202 | #ifdef OPENSSL_SYS_VOS_IA32 | ||
203 | /* sleep for 1/65536 of a second (15 us). */ | ||
204 | duration = 1; | ||
205 | s$sleep2 (&duration, &code); | ||
206 | #endif /* OPENSSL_SYS_VOS_IA32 */ | ||
207 | #endif /* OPENSSL_SYS_VOS_HPPA */ | ||
208 | |||
209 | /* get wall clock time. */ | ||
210 | clock_gettime (CLOCK_REALTIME, &ts); | ||
211 | |||
212 | /* take 8 bits */ | ||
213 | v = (unsigned char) (ts.tv_nsec % 256); | ||
214 | RAND_add (&v, sizeof v, 1); | ||
215 | v = 0; | ||
216 | } | ||
177 | return 1; | 217 | return 1; |
178 | } | 218 | } |
179 | #elif defined __OpenBSD__ | 219 | #elif defined __OpenBSD__ |