summaryrefslogtreecommitdiff
path: root/openbsd-compat/arc4random.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-09 10:44:47 +1100
committerDamien Miller <djm@mindrot.org>2013-10-09 10:44:47 +1100
commit720711960b130d36dfdd3d50eb25ef482bdd000e (patch)
tree8b633b6901b92ec4ac380f46720011e9bd157b40 /openbsd-compat/arc4random.c
parent9159310087a218e28940a592896808b8eb76a039 (diff)
- (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c]
[openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@, tested tim@
Diffstat (limited to 'openbsd-compat/arc4random.c')
-rw-r--r--openbsd-compat/arc4random.c59
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)
67static void 76static 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
197void 207void
198arc4random_buf(void *buf, size_t n) 208arc4random_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)
219void
220arc4random_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 --------*/