diff options
Diffstat (limited to '')
| -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 e9ead3a529..e3a65571c8 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 */ | ||
| 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; | ||
| 176 | 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__ |
