From: Roy Marples Date: Sun, 7 Sep 2014 17:24:07 +0000 (+0000) Subject: Split arc4random_uniform into it's own compat function and add X-Git-Tag: v6.4.4~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=01890c79df552fe5ed717fb97d9dd5bfb622980d;p=thirdparty%2Fdhcpcd.git Split arc4random_uniform into it's own compat function and add it's proper copyright. Add a new test for it to configure so that we can use the uclibc arc4random function and our compat arc4random_uniform function. --- diff --git a/compat/arc4random.c b/compat/arc4random.c index 058c55ae..70a459a3 100644 --- a/compat/arc4random.c +++ b/compat/arc4random.c @@ -149,38 +149,3 @@ arc4random() arc4_stir_if_needed(&rs); return arc4_getword(&rs); } - -/* - * Calculate a uniformly distributed random number less than upper_bound - * avoiding "modulo bias". - * - * Uniformity is achieved by generating new random numbers until the one - * returned is outside the range [0, 2**32 % upper_bound). This - * guarantees the selected random number will be inside - * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) - * after reduction modulo upper_bound. - */ -uint32_t -arc4random_uniform(uint32_t upper_bound) -{ - uint32_t r, min; - - if (upper_bound < 2) - return 0; - - /* 2**32 % x == (2**32 - x) % x */ - min = -upper_bound % upper_bound; - - /* - * This could theoretically loop forever but each retry has - * p > 0.5 (worst case, usually far better) of selecting a - * number inside the range we need, so it should rarely need - * to re-roll. - */ - do - r = arc4random(); - while (r < min); - - return r % upper_bound; -} - diff --git a/compat/arc4random.h b/compat/arc4random.h index b851d540..d8ae3c78 100644 --- a/compat/arc4random.h +++ b/compat/arc4random.h @@ -31,5 +31,4 @@ #include uint32_t arc4random(void); -uint32_t arc4random_uniform(uint32_t); #endif diff --git a/compat/arc4random_uniform.c b/compat/arc4random_uniform.c new file mode 100644 index 00000000..96c1c1bc --- /dev/null +++ b/compat/arc4random_uniform.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008, Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* We need to include config.h so we pickup either the system arc4random + * or our compat one. */ +#include "../config.h" + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + do + r = arc4random(); + while (r < min); + + return r % upper_bound; +} diff --git a/compat/arc4random_uniform.h b/compat/arc4random_uniform.h new file mode 100644 index 00000000..e6a9b744 --- /dev/null +++ b/compat/arc4random_uniform.h @@ -0,0 +1,34 @@ +/* + * dhcpcd - DHCP client daemon + * Copyright (c) 2006-2014 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ARC4RANDOM_UNIFORM_H +#define ARC4RANDOM_UNIFORM_H + +#include + +uint32_t arc4random_uniform(uint32_t); +#endif diff --git a/configure b/configure index 9c322223..fccfb470 100755 --- a/configure +++ b/configure @@ -509,6 +509,28 @@ if [ "$ARC4RANDOM" = no ]; then echo "#include \"compat/arc4random.h\"" >>$CONFIG_H fi +if [ -z "$ARC4RANDOM_UNIFORM" ]; then + printf "Testing for arc4random_uniform ... " + cat <_arc4random_uniform.c +#include +int main(void) { + arc4random_uniform(100); + return 0; +} +EOF + if $XCC _arc4random_uniform.c -o _arc4random_uniform 2>/dev/null; then + ARC4RANDOM_UNIFORM=yes + else + ARC4RANDOM_UNIFORM=no + fi + echo "$ARC4RANDOM" + rm -f _arc4random.c _arc4random +fi +if [ "$ARC4RANDOM_UNIFORM" = no ]; then + echo "COMPAT_SRCS+= compat/arc4random_uniform.c" >>$CONFIG_MK + echo "#include \"compat/arc4random_uniform.h\"" >>$CONFIG_H +fi + if [ -z "$CLOSEFROM" ]; then printf "Testing for closefrom ... " cat <_closefrom.c