summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm <djm>2008-05-19 04:47:37 +0000
committerdjm <djm>2008-05-19 04:47:37 +0000
commitf690d624665500312faee3becf0de7f302d77d2d (patch)
treefbe5af4c810b0d5fdffa1e039832f3574cd2c8d1
parent28e753b1704ae55fe420e9c69436881d48f5cab3 (diff)
downloadopenssh-f690d624665500312faee3becf0de7f302d77d2d.tar.gz
- (djm) [openbsd-compat/bsd-arc4random.c openbsd-compat/openbsd-compat.c]
[configure.ac] Implement arc4random_buf(), import implementation of arc4random_uniform() from OpenBSD
-rw-r--r--ChangeLog5
-rw-r--r--configure.ac6
-rw-r--r--openbsd-compat/bsd-arc4random.c65
-rw-r--r--openbsd-compat/openbsd-compat.h10
4 files changed, 82 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index f466f481..66145e52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,9 @@
- djm@cvs.openbsd.org 2008/04/05 02:46:02
[sshd_config.5]
HostbasedAuthentication is supported under Match too
+ - (djm) [openbsd-compat/bsd-arc4random.c openbsd-compat/openbsd-compat.c]
+ [configure.ac] Implement arc4random_buf(), import implementation of
+ arc4random_uniform() from OpenBSD
20080403
- (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile-
@@ -3871,4 +3874,4 @@
OpenServer 6 and add osr5bigcrypt support so when someone migrates
passwords between UnixWare and OpenServer they will still work. OK dtucker@
-$Id: ChangeLog,v 1.4908 2008/05/19 04:29:08 djm Exp $
+$Id: ChangeLog,v 1.4909 2008/05/19 04:47:37 djm Exp $
diff --git a/configure.ac b/configure.ac
index 7b92bad1..e6e916e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.397 2008/03/27 01:33:07 djm Exp $
+# $Id: configure.ac,v 1.398 2008/05/19 04:47:37 djm Exp $
#
# Copyright (c) 1999-2004 Damien Miller
#
@@ -15,7 +15,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
-AC_REVISION($Revision: 1.397 $)
+AC_REVISION($Revision: 1.398 $)
AC_CONFIG_SRCDIR([ssh.c])
AC_CONFIG_HEADER(config.h)
@@ -1288,6 +1288,8 @@ AC_ARG_WITH(audit,
dnl Checks for library functions. Please keep in alphabetical order
AC_CHECK_FUNCS( \
arc4random \
+ arc4random_buf \
+ arc4random_uniform \
asprintf \
b64_ntop \
__b64_ntop \
diff --git a/openbsd-compat/bsd-arc4random.c b/openbsd-compat/bsd-arc4random.c
index d45fb182..8bf31e5d 100644
--- a/openbsd-compat/bsd-arc4random.c
+++ b/openbsd-compat/bsd-arc4random.c
@@ -82,3 +82,68 @@ arc4random_stir(void)
rc4_ready = REKEY_BYTES;
}
#endif /* !HAVE_ARC4RANDOM */
+
+#ifndef ARC4RANDOM_BUF
+void
+arc4random_buf(void *_buf, size_t n)
+{
+ size_t i;
+ u_int32_t r;
+ char *buf = (char *)_buf;
+
+ for (i = 0; i < n; i++) {
+ if (i % 4 == 0)
+ r = arc4random();
+ buf[i] = r & 0xff;
+ r >>= 8;
+ }
+ i = r = 0;
+}
+#endif /* !HAVE_ARC4RANDOM_BUF */
+
+#ifndef ARC4RANDOM_UNIFORM
+/*
+ * 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.
+ */
+u_int32_t
+arc4random_uniform(u_int32_t upper_bound)
+{
+ u_int32_t r, min;
+
+ if (upper_bound < 2)
+ return 0;
+
+#if (ULONG_MAX > 0xffffffffUL)
+ min = 0x100000000UL % upper_bound;
+#else
+ /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
+ if (upper_bound > 0x80000000)
+ min = 1 + ~upper_bound; /* 2**32 - upper_bound */
+ else {
+ /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
+ min = ((0xffffffff - (upper_bound << 2)) + 1) % upper_bound;
+ }
+#endif
+
+ /*
+ * 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.
+ */
+ for (;;) {
+ r = arc4random();
+ if (r >= min)
+ break;
+ }
+
+ return r % upper_bound;
+}
+#endif /* !HAVE_ARC4RANDOM_UNIFORM */
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 6406af19..eb48b362 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
-/* $Id: openbsd-compat.h,v 1.43 2007/06/25 12:15:13 dtucker Exp $ */
+/* $Id: openbsd-compat.h,v 1.44 2008/05/19 04:47:37 djm Exp $ */
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@@ -151,6 +151,14 @@ unsigned int arc4random(void);
void arc4random_stir(void);
#endif /* !HAVE_ARC4RANDOM */
+#ifndef HAVE_ARC4RANDOM_BUF
+void arc4random_buf(void *, size_t);
+#endif
+
+#ifndef HAVE_ARC4RANDOM_UNIFORM
+u_int32_t arc4random_uniform(u_int32_t);
+#endif
+
#ifndef HAVE_ASPRINTF
int asprintf(char **, const char *, ...);
#endif