2 * Copyright (c) 1996, David Mazieres <dm@uun.org>
3 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * Arc4 random number generator for OpenBSD.
21 * This code is derived from section 17.1 of Applied Cryptography,
22 * second edition, which describes a stream cipher allegedly
23 * compatible with RSA Labs "RC4" cipher (the actual description of
24 * which is a trade secret). The same algorithm is used as a stream
25 * cipher called "arcfour" in Tatu Ylonen's ssh package.
27 * Here the stream cipher has been modified always to include the time
28 * when initializing the state. That makes it impossible to
29 * regenerate the same random sequence twice, so this can't be used
30 * for encryption, but will generate good random numbers.
32 * RC4 is a registered trademark of RSA Laboratories.
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.25 2008/09/09 09:46:36 ache Exp $");
38 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/random.h>
45 #include <os/assumes.h>
49 #include "libc_private.h"
51 #define CACHE_LENGTH 64
54 #define INITIAL_COUNT 1600000
55 #define MAX_BUF_COUNT 4096
57 static os_unfair_lock arc4_lock
= OS_UNFAIR_LOCK_INIT
;
58 static int arc4_count
;
60 uint64_t arc4random64(void);
62 #define RANDOMDEV "/dev/random"
65 _my_getentropy(uint8_t *buf
, size_t size
){
68 if (getentropy(buf
, size
) == 0) {
72 // The above should never fail, but we'll try /dev/random anyway
73 fd
= open(RANDOMDEV
, O_RDONLY
, 0);
75 #if !defined(VARIANT_STATIC)
76 os_crash("arc4random: unable to open /dev/random");
82 ret
= read(fd
, buf
, size
);
84 #if !defined(VARIANT_STATIC)
85 os_crash("arc4random: unable to read from /dev/random");
89 } else if ((size_t)ret
< size
) {
97 #if defined(__APPLE__) && !defined(VARIANT_STATIC)
98 #include <corecrypto/ccdrbg.h>
99 #include <corecrypto/ccaes.h>
101 static struct ccdrbg_info rng_info
;
102 static struct ccdrbg_nistctr_custom rng_custom
;
103 static struct ccdrbg_state
*rng_state
;
105 static int cache_pos
= CACHE_LENGTH
;
106 static uint32_t rand_buffer
[CACHE_LENGTH
];
111 if (rng_state
!= NULL
) return;
113 uint8_t entropy
[BUFFERSIZE
];
115 rng_custom
.ctr_info
= ccaes_ctr_crypt_mode();
116 rng_custom
.keylen
= 16;
117 rng_custom
.strictFIPS
= 0;
118 rng_custom
.use_df
= 1;
119 ccdrbg_factory_nistctr(&rng_info
, &rng_custom
);
120 rng_state
= malloc(rng_info
.size
);
121 os_assert(rng_state
!= NULL
);
123 _my_getentropy(entropy
, BUFFERSIZE
);
125 ret
= ccdrbg_init(&rng_info
, rng_state
,
126 sizeof(entropy
), entropy
,
130 memset_s(entropy
, sizeof(entropy
), 0, sizeof(entropy
));
132 arc4_count
= INITIAL_COUNT
;
138 uint8_t entropy
[BUFFERSIZE
];
143 _my_getentropy(entropy
, BUFFERSIZE
);
145 ret
= ccdrbg_reseed(&rng_info
, rng_state
,
146 sizeof(entropy
), entropy
,
150 memset_s(entropy
, sizeof(entropy
), 0, sizeof(entropy
));
152 arc4_count
= INITIAL_COUNT
;
156 arc4random_addrandom(__unused u_char
*dat
, __unused
int datlen
)
158 /* NOP - deprecated */
165 os_unfair_lock_lock(&arc4_lock
);
167 if (arc4_count
<= 0) {
170 if (cache_pos
>= CACHE_LENGTH
) {
171 ret
= ccdrbg_generate(&rng_info
, rng_state
, sizeof(rand_buffer
), rand_buffer
, 0, NULL
);
175 uint32_t rand
= rand_buffer
[cache_pos
];
176 // Delete the current random number from buffer
177 memset_s(rand_buffer
+cache_pos
, sizeof(rand_buffer
[cache_pos
]), 0, sizeof(rand_buffer
[cache_pos
]));
180 os_unfair_lock_unlock(&arc4_lock
);
185 arc4random_buf(void *_buf
, size_t buf_size
)
188 os_unfair_lock_lock(&arc4_lock
);
190 while (buf_size
> 0) {
191 if (arc4_count
<= 0 ) {
194 size_t n
= MIN(buf_size
, (size_t)MIN(MAX_BUF_COUNT
, arc4_count
) * sizeof(uint32_t));
195 int ret
= ccdrbg_generate(&rng_info
, rng_state
, n
, buf
, 0, NULL
);
199 arc4_count
-= n
/sizeof(uint32_t);
202 os_unfair_lock_unlock(&arc4_lock
);
203 // Give others a chance to get the lock
204 os_unfair_lock_lock(&arc4_lock
);
207 os_unfair_lock_unlock(&arc4_lock
);
210 __private_extern__
void
211 _arc4_fork_child(void)
213 arc4_lock
= OS_UNFAIR_LOCK_INIT
;
214 cache_pos
= CACHE_LENGTH
;
215 if (rng_state
!= NULL
) {
217 memset_s(rand_buffer
, sizeof(rand_buffer
), 0, sizeof(rand_buffer
));
218 memset_s(rng_state
, rng_info
.size
, 0, rng_info
.size
);
219 free(rng_state
); rng_state
= NULL
;
220 bzero(&rng_info
, sizeof(rng_info
));
221 bzero(&rng_custom
, sizeof(rng_custom
));
225 #else /* __APPLE__ && !VARIANT_STATIC */
235 static struct arc4_stream rs
= {
239 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
240 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
241 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
242 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
243 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
244 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
245 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
246 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
247 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
248 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
249 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
250 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
251 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
252 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
253 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
254 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
257 static int rs_stired
;
259 static inline u_int8_t
arc4_getbyte(void);
260 static void arc4_stir(void);
265 u_int8_t rnd
[KEYSIZE
];
267 static volatile int rs_data_available
= 0;
270 arc4_addrandom(u_char
*dat
, int datlen
)
276 for (n
= 0; n
< 256; n
++) {
279 rs
.j
= (rs
.j
+ si
+ dat
[n
% datlen
]);
280 rs
.s
[rs
.i
] = rs
.s
[rs
.j
];
289 _my_getentropy((uint8_t*)&rdat
, KEYSIZE
);
297 * If we don't have data, we need some now before we can integrate
298 * it into the static buffers
300 if (!rs_data_available
)
304 rs_data_available
= 0;
305 __sync_synchronize();
307 arc4_addrandom((u_char
*)&rdat
, KEYSIZE
);
310 * Throw away the first N bytes of output, as suggested in the
311 * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
312 * by Fluher, Mantin, and Shamir. N=1024 is based on
313 * suggestions in the paper "(Not So) Random Shuffles of RC4"
316 for (n
= 0; n
< 1024; n
++)
317 (void) arc4_getbyte();
318 arc4_count
= 1600000;
322 static inline u_int8_t
334 return (rs
.s
[(si
+ sj
) & 0xff]);
337 static inline u_int32_t
342 val
= arc4_getbyte() << 24;
343 val
|= arc4_getbyte() << 16;
344 val
|= arc4_getbyte() << 8;
345 val
|= arc4_getbyte();
350 /* 7944700: force restir in child */
351 __private_extern__
void
352 _arc4_fork_child(void)
354 arc4_lock
= OS_UNFAIR_LOCK_INIT
;
356 rs_data_available
= 0;
360 arc4_check_stir(void)
362 if (!rs_stired
|| arc4_count
<= 0) {
370 arc4random_addrandom(u_char
*dat
, int datlen
)
372 os_unfair_lock_lock(&arc4_lock
);
374 arc4_addrandom(dat
, datlen
);
375 os_unfair_lock_unlock(&arc4_lock
);
383 os_unfair_lock_lock(&arc4_lock
);
385 int did_stir
= arc4_check_stir();
386 rnd
= arc4_getword();
389 os_unfair_lock_unlock(&arc4_lock
);
392 /* stirring used up our data pool, we need to read in new data outside of the lock */
394 rs_data_available
= 1;
395 __sync_synchronize();
402 arc4random_buf(void *_buf
, size_t n
)
404 u_char
*buf
= (u_char
*)_buf
;
407 os_unfair_lock_lock(&arc4_lock
);
410 if (arc4_check_stir())
414 buf
[n
] = arc4_getbyte();
418 os_unfair_lock_unlock(&arc4_lock
);
421 /* stirring used up our data pool, we need to read in new data outside of the lock */
423 rs_data_available
= 1;
424 __sync_synchronize();
428 #endif /* __APPLE__ */
431 arc4random_stir(void)
433 os_unfair_lock_lock(&arc4_lock
);
435 os_unfair_lock_unlock(&arc4_lock
);
439 * Calculate a uniformly distributed random number less than upper_bound
440 * avoiding "modulo bias".
442 * Uniformity is achieved by trying successive ranges of bits from the random
443 * value, each large enough to hold the desired upper bound, until a range
444 * holding a value less than the bound is found.
447 arc4random_uniform(uint32_t upper_bound
)
452 // find smallest 2**n -1 >= upper_bound
453 int zeros
= __builtin_clz(upper_bound
);
454 int bits
= CHAR_BIT
* sizeof(uint32_t) - zeros
;
455 uint32_t mask
= 0xFFFFFFFFU
>> zeros
;
458 uint32_t value
= arc4random();
460 // If low 2**n-1 bits satisfy the requested condition, return result
461 uint32_t result
= value
& mask
;
462 if (result
< upper_bound
) {
466 // otherwise consume remaining bits of randomness looking for a satisfactory result.
467 int bits_left
= zeros
;
468 while (bits_left
>= bits
) {
470 result
= value
& mask
;
471 if (result
< upper_bound
) {