1 /* $NetBSD: arc4random.c,v 1.21 2013/10/17 23:56:17 christos Exp $ */
2 /* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */
5 * Arc4 random number generator for OpenBSD.
6 * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
8 * Modification and redistribution in source and binary forms is
9 * permitted provided that due credit is given to the author and the
10 * OpenBSD project by leaving this copyright notice intact.
14 * This code is derived from section 17.1 of Applied Cryptography,
15 * second edition, which describes a stream cipher allegedly
16 * compatible with RSA Labs "RC4" cipher (the actual description of
17 * which is a trade secret). The same algorithm is used as a stream
18 * cipher called "arcfour" in Tatu Ylonen's ssh package.
20 * Here the stream cipher has been modified always to include the time
21 * when initializing the state. That makes it impossible to
22 * regenerate the same random sequence twice, so this can't be used
23 * for encryption, but will generate good random numbers.
25 * RC4 is a registered trademark of RSA Laboratories.
28 #include <sys/cdefs.h>
29 #if defined(LIBC_SCCS) && !defined(lint)
30 __RCSID("$NetBSD: arc4random.c,v 1.21 2013/10/17 23:56:17 christos Exp $");
31 #endif /* LIBC_SCCS and not lint */
33 #include "namespace.h"
34 #include "reentrant.h"
38 #include <sys/types.h>
39 #include <sys/param.h>
41 #include <sys/sysctl.h>
44 __weak_alias(arc4random
,_arc4random
)
45 __weak_alias(arc4random_addrandom
,_arc4random_addrandom
)
46 __weak_alias(arc4random_buf
,_arc4random_buf
)
47 __weak_alias(arc4random_stir
,_arc4random_stir
)
48 __weak_alias(arc4random_uniform
,_arc4random_uniform
)
56 uint8_t s
[(uint8_t)~0u + 1u]; /* 256 to you and me */
64 int isthreaded = __isthreaded; \
66 mutex_lock(&(rs)->mtx);
69 mutex_unlock(&(rs)->mtx); \
77 #define S4(n) S(n), S(n + 1), S(n + 2), S(n + 3)
78 #define S16(n) S4(n), S4(n + 4), S4(n + 8), S4(n + 12)
79 #define S64(n) S16(n), S16(n + 16), S16(n + 32), S16(n + 48)
80 #define S256 S64(0), S64(64), S64(128), S64(192)
82 static struct arc4_stream rs
= { .i
= 0xff, .j
= 0, .s
= { S256
},
84 .stirred
= 0, .mtx
= MUTEX_INITIALIZER
};
95 static inline void arc4_addrandom(struct arc4_stream
*, u_char
*, int);
96 static __noinline
void arc4_stir(struct arc4_stream
*);
97 static inline uint8_t arc4_getbyte(struct arc4_stream
*);
98 static inline uint32_t arc4_getword(struct arc4_stream
*);
101 arc4_check_init(struct arc4_stream
*as
)
103 if (__predict_true(rs
.stirred
))
111 arc4_addrandom(struct arc4_stream
*as
, u_char
*dat
, int datlen
)
116 for (n
= 0; n
< __arraycount(as
->s
); n
++) {
119 as
->j
= (as
->j
+ si
+ dat
[n
% datlen
]);
120 as
->s
[as
->i
] = as
->s
[as
->j
];
125 static __noinline
void
126 arc4_stir(struct arc4_stream
*as
)
129 /* LSC: We do not have a compatibility layer for the
130 * KERN_URND call, so use the old way... */
135 u_int rnd
[(128 - sizeof(struct timeval
)) / sizeof(u_int
)];
138 gettimeofday(&rdat
.tv
, NULL
);
139 fd
= open("/dev/urandom", O_RDONLY
);
141 read(fd
, rdat
.rnd
, sizeof(rdat
.rnd
));
145 /* fd < 0 or failed sysctl ? Ah, what the heck. We'll just take
146 * whatever was on the stack... */
149 int mib
[] = { CTL_KERN
, KERN_URND
};
154 * This code once opened and read /dev/urandom on each
155 * call. That causes repeated rekeying of the kernel stream
156 * generator, which is very wasteful. Because of application
157 * behavior, caching the fd doesn't really help. So we just
158 * fill up the tank from sysctl, which is a tiny bit slower
159 * for us but much friendlier to other entropy consumers.
162 for (i
= 0; i
< __arraycount(rdat
); i
++) {
163 len
= sizeof(rdat
[i
]);
164 if (sysctl(mib
, 2, &rdat
[i
], &len
, NULL
, 0) == -1)
167 #endif /* !defined(__minix) */
169 arc4_addrandom(as
, (void *) &rdat
, (int)sizeof(rdat
));
172 * Throw away the first N words of output, as suggested in the
173 * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
174 * by Fluher, Mantin, and Shamir. (N = 256 in our case.)
176 for (j
= 0; j
< __arraycount(as
->s
) * 4; j
++)
182 static __inline
uint8_t
183 arc4_getbyte_ij(struct arc4_stream
*as
, uint8_t *i
, uint8_t *j
)
193 return (as
->s
[(si
+ sj
) & 0xff]);
196 static inline uint8_t
197 arc4_getbyte(struct arc4_stream
*as
)
199 return arc4_getbyte_ij(as
, &as
->i
, &as
->j
);
202 static inline uint32_t
203 arc4_getword(struct arc4_stream
*as
)
206 val
= arc4_getbyte(as
) << 24;
207 val
|= arc4_getbyte(as
) << 16;
208 val
|= arc4_getbyte(as
) << 8;
209 val
|= arc4_getbyte(as
);
214 arc4random_stir(void)
222 arc4random_addrandom(u_char
*dat
, int datlen
)
225 arc4_check_init(&rs
);
226 arc4_addrandom(&rs
, dat
, datlen
);
236 arc4_check_init(&rs
);
237 v
= arc4_getword(&rs
);
243 arc4random_buf(void *buf
, size_t len
)
246 uint8_t *ep
= bp
+ len
;
250 arc4_check_init(&rs
);
252 /* cache i and j - compiler can't know 'buf' doesn't alias them */
257 *bp
++ = arc4_getbyte_ij(&rs
, &i
, &j
);
265 * Written by Damien Miller.
266 * With simplifications by Jinmei Tatuya.
270 * Calculate a uniformly distributed random number less than
271 * upper_bound avoiding "modulo bias".
273 * Uniformity is achieved by generating new random numbers
274 * until the one returned is outside the range
275 * [0, 2^32 % upper_bound[. This guarantees the selected
276 * random number will be inside the range
277 * [2^32 % upper_bound, 2^32[ which maps back to
278 * [0, upper_bound[ after reduction modulo upper_bound.
281 arc4random_uniform(uint32_t upper_bound
)
288 /* calculate (2^32 % upper_bound) avoiding 64-bit math */
289 /* ((2^32 - x) % x) == (2^32 % x) when x <= 2^31 */
290 min
= (0xFFFFFFFFU
- upper_bound
+ 1) % upper_bound
;
293 arc4_check_init(&rs
);
296 * This could theoretically loop forever but each retry has
297 * p > 0.5 (worst case, usually far better) of selecting a
298 * number inside the range we need, so it should rarely need
299 * to re-roll (at all).
302 r
= arc4_getword(&rs
);
306 return r
% upper_bound
;