1 /* $NetBSD: random.c,v 1.8 2009/02/16 20:53:54 christos Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
34 __RCSID("$NetBSD: random.c,v 1.8 2009/02/16 20:53:54 christos Exp $");
38 * Functions for stirring in additional noise into the
39 * cryptographically strong PRNG.
40 * the functions are not using "arc4" in any ways, they are placed here
41 * to make porting easy.
44 #include <sys/types.h>
51 #include "pathnames.h"
55 static const char *rndfail
= "random number device is mandatory. see rnd(4).";
58 arc4random_check(void)
62 fd
= open(_PATH_URANDOM
, O_RDONLY
, 0666);
72 arc4random_buf(void *_buf
, size_t n
)
76 char *buf
= (char *)_buf
;
78 for (i
= 0; i
< n
; i
++) {
88 * Calculate a uniformly distributed random number less than upper_bound
89 * avoiding "modulo bias".
91 * Uniformity is achieved by generating new random numbers until the one
92 * returned is outside the range [0, 2**32 % upper_bound). This
93 * guarantees the selected random number will be inside
94 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
95 * after reduction modulo upper_bound.
98 arc4random_uniform(u_int32_t upper_bound
)
105 #if (ULONG_MAX > 0xffffffffUL)
106 min
= 0x100000000UL
% upper_bound
;
108 /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
109 if (upper_bound
> 0x80000000)
110 min
= 1 + ~upper_bound
; /* 2**32 - upper_bound */
112 /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
113 min
= ((0xffffffff - (upper_bound
* 2)) + 1) % upper_bound
;
118 * This could theoretically loop forever but each retry has
119 * p > 0.5 (worst case, usually far better) of selecting a
120 * number inside the range we need, so it should rarely need
129 return r
% upper_bound
;