diff options
Diffstat (limited to 'openbsd-compat/arc4random.c')
-rw-r--r-- | openbsd-compat/arc4random.c | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c index 356e23181..eac073cc0 100644 --- a/openbsd-compat/arc4random.c +++ b/openbsd-compat/arc4random.c | |||
@@ -1,3 +1,5 @@ | |||
1 | /* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */ | ||
2 | |||
1 | /* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */ | 3 | /* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */ |
2 | 4 | ||
3 | /* | 5 | /* |
@@ -22,16 +24,19 @@ | |||
22 | * ChaCha based random number generator for OpenBSD. | 24 | * ChaCha based random number generator for OpenBSD. |
23 | */ | 25 | */ |
24 | 26 | ||
25 | #include <fcntl.h> | 27 | #include "includes.h" |
26 | #include <limits.h> | 28 | |
27 | #include <stdlib.h> | 29 | #include <stdlib.h> |
28 | #include <string.h> | 30 | #include <string.h> |
29 | #include <unistd.h> | 31 | #include <unistd.h> |
30 | #include <sys/types.h> | 32 | #include <sys/types.h> |
31 | #include <sys/param.h> | 33 | |
32 | #include <sys/time.h> | 34 | #ifndef HAVE_ARC4RANDOM |
33 | #include <sys/sysctl.h> | 35 | |
34 | #include "thread_private.h" | 36 | #include <openssl/rand.h> |
37 | #include <openssl/err.h> | ||
38 | |||
39 | #include "log.h" | ||
35 | 40 | ||
36 | #define KEYSTREAM_ONLY | 41 | #define KEYSTREAM_ONLY |
37 | #include "chacha_private.h" | 42 | #include "chacha_private.h" |
@@ -42,6 +47,10 @@ | |||
42 | #define inline | 47 | #define inline |
43 | #endif /* !__GNUC__ */ | 48 | #endif /* !__GNUC__ */ |
44 | 49 | ||
50 | /* OpenSSH isn't multithreaded */ | ||
51 | #define _ARC4_LOCK() | ||
52 | #define _ARC4_UNLOCK() | ||
53 | |||
45 | #define KEYSZ 32 | 54 | #define KEYSZ 32 |
46 | #define IVSZ 8 | 55 | #define IVSZ 8 |
47 | #define BLOCKSZ 64 | 56 | #define BLOCKSZ 64 |
@@ -67,15 +76,11 @@ _rs_init(u_char *buf, size_t n) | |||
67 | static void | 76 | static void |
68 | _rs_stir(void) | 77 | _rs_stir(void) |
69 | { | 78 | { |
70 | int mib[2]; | ||
71 | size_t len; | ||
72 | u_char rnd[KEYSZ + IVSZ]; | 79 | u_char rnd[KEYSZ + IVSZ]; |
73 | 80 | ||
74 | mib[0] = CTL_KERN; | 81 | if (RAND_bytes(rnd, sizeof(rnd)) <= 0) |
75 | mib[1] = KERN_ARND; | 82 | fatal("Couldn't obtain random bytes (error %ld)", |
76 | 83 | ERR_get_error()); | |
77 | len = sizeof(rnd); | ||
78 | sysctl(mib, 2, rnd, &len, NULL, 0); | ||
79 | 84 | ||
80 | if (!rs_initialized) { | 85 | if (!rs_initialized) { |
81 | rs_initialized = 1; | 86 | rs_initialized = 1; |
@@ -194,6 +199,11 @@ arc4random(void) | |||
194 | return val; | 199 | return val; |
195 | } | 200 | } |
196 | 201 | ||
202 | /* | ||
203 | * If we are providing arc4random, then we can provide a more efficient | ||
204 | * arc4random_buf(). | ||
205 | */ | ||
206 | # ifndef HAVE_ARC4RANDOM_BUF | ||
197 | void | 207 | void |
198 | arc4random_buf(void *buf, size_t n) | 208 | arc4random_buf(void *buf, size_t n) |
199 | { | 209 | { |
@@ -201,7 +211,29 @@ arc4random_buf(void *buf, size_t n) | |||
201 | _rs_random_buf(buf, n); | 211 | _rs_random_buf(buf, n); |
202 | _ARC4_UNLOCK(); | 212 | _ARC4_UNLOCK(); |
203 | } | 213 | } |
214 | # endif /* !HAVE_ARC4RANDOM_BUF */ | ||
215 | #endif /* !HAVE_ARC4RANDOM */ | ||
216 | |||
217 | /* arc4random_buf() that uses platform arc4random() */ | ||
218 | #if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) | ||
219 | void | ||
220 | arc4random_buf(void *_buf, size_t n) | ||
221 | { | ||
222 | size_t i; | ||
223 | u_int32_t r = 0; | ||
224 | char *buf = (char *)_buf; | ||
225 | |||
226 | for (i = 0; i < n; i++) { | ||
227 | if (i % 4 == 0) | ||
228 | r = arc4random(); | ||
229 | buf[i] = r & 0xff; | ||
230 | r >>= 8; | ||
231 | } | ||
232 | i = r = 0; | ||
233 | } | ||
234 | #endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */ | ||
204 | 235 | ||
236 | #ifndef HAVE_ARC4RANDOM_UNIFORM | ||
205 | /* | 237 | /* |
206 | * Calculate a uniformly distributed random number less than upper_bound | 238 | * Calculate a uniformly distributed random number less than upper_bound |
207 | * avoiding "modulo bias". | 239 | * avoiding "modulo bias". |
@@ -237,6 +269,7 @@ arc4random_uniform(u_int32_t upper_bound) | |||
237 | 269 | ||
238 | return r % upper_bound; | 270 | return r % upper_bound; |
239 | } | 271 | } |
272 | #endif /* !HAVE_ARC4RANDOM_UNIFORM */ | ||
240 | 273 | ||
241 | #if 0 | 274 | #if 0 |
242 | /*-------- Test code for i386 --------*/ | 275 | /*-------- Test code for i386 --------*/ |