- (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c]
[openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@, tested tim@
This commit is contained in:
parent
9159310087
commit
720711960b
|
@ -2,6 +2,10 @@
|
|||
- (djm) [openbsd-compat/arc4random.c openbsd-compat/chacha_private.h] Pull
|
||||
in OpenBSD implementation of arc4random, shortly to replace the existing
|
||||
bsd-arc4random.c
|
||||
- (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c]
|
||||
[openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random
|
||||
implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@,
|
||||
tested tim@
|
||||
|
||||
20130922
|
||||
- (dtucker) [platform.c platform.h sshd.c] bz#2156: restore Linux oom_adj
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile.in,v 1.51 2013/05/10 06:28:56 dtucker Exp $
|
||||
# $Id: Makefile.in,v 1.52 2013/10/08 23:44:49 djm Exp $
|
||||
|
||||
sysconfdir=@sysconfdir@
|
||||
piddir=@piddir@
|
||||
|
@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@
|
|||
|
||||
OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o
|
||||
|
||||
COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
|
||||
|
||||
PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */
|
||||
|
||||
/* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -22,16 +24,19 @@
|
|||
* ChaCha based random number generator for OpenBSD.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include "includes.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include "thread_private.h"
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define KEYSTREAM_ONLY
|
||||
#include "chacha_private.h"
|
||||
|
@ -42,6 +47,10 @@
|
|||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
/* OpenSSH isn't multithreaded */
|
||||
#define _ARC4_LOCK()
|
||||
#define _ARC4_UNLOCK()
|
||||
|
||||
#define KEYSZ 32
|
||||
#define IVSZ 8
|
||||
#define BLOCKSZ 64
|
||||
|
@ -67,15 +76,11 @@ _rs_init(u_char *buf, size_t n)
|
|||
static void
|
||||
_rs_stir(void)
|
||||
{
|
||||
int mib[2];
|
||||
size_t len;
|
||||
u_char rnd[KEYSZ + IVSZ];
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_ARND;
|
||||
|
||||
len = sizeof(rnd);
|
||||
sysctl(mib, 2, rnd, &len, NULL, 0);
|
||||
if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
|
||||
fatal("Couldn't obtain random bytes (error %ld)",
|
||||
ERR_get_error());
|
||||
|
||||
if (!rs_initialized) {
|
||||
rs_initialized = 1;
|
||||
|
@ -194,6 +199,11 @@ arc4random(void)
|
|||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are providing arc4random, then we can provide a more efficient
|
||||
* arc4random_buf().
|
||||
*/
|
||||
# ifndef HAVE_ARC4RANDOM_BUF
|
||||
void
|
||||
arc4random_buf(void *buf, size_t n)
|
||||
{
|
||||
|
@ -201,7 +211,29 @@ arc4random_buf(void *buf, size_t n)
|
|||
_rs_random_buf(buf, n);
|
||||
_ARC4_UNLOCK();
|
||||
}
|
||||
# endif /* !HAVE_ARC4RANDOM_BUF */
|
||||
#endif /* !HAVE_ARC4RANDOM */
|
||||
|
||||
/* arc4random_buf() that uses platform arc4random() */
|
||||
#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM)
|
||||
void
|
||||
arc4random_buf(void *_buf, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
u_int32_t r = 0;
|
||||
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 /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM_UNIFORM
|
||||
/*
|
||||
* Calculate a uniformly distributed random number less than upper_bound
|
||||
* avoiding "modulo bias".
|
||||
|
@ -237,6 +269,7 @@ arc4random_uniform(u_int32_t upper_bound)
|
|||
|
||||
return r % upper_bound;
|
||||
}
|
||||
#endif /* !HAVE_ARC4RANDOM_UNIFORM */
|
||||
|
||||
#if 0
|
||||
/*-------- Test code for i386 --------*/
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999,2000,2004 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* Size of key to use */
|
||||
#define SEED_SIZE 20
|
||||
|
||||
/* Number of bytes to reseed after */
|
||||
#define REKEY_BYTES (1 << 24)
|
||||
|
||||
static int rc4_ready = 0;
|
||||
static RC4_KEY rc4;
|
||||
|
||||
unsigned int
|
||||
arc4random(void)
|
||||
{
|
||||
unsigned int r = 0;
|
||||
static int first_time = 1;
|
||||
|
||||
if (rc4_ready <= 0) {
|
||||
if (first_time)
|
||||
seed_rng();
|
||||
first_time = 0;
|
||||
arc4random_stir();
|
||||
}
|
||||
|
||||
RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r);
|
||||
|
||||
rc4_ready -= sizeof(r);
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
void
|
||||
arc4random_stir(void)
|
||||
{
|
||||
unsigned char rand_buf[SEED_SIZE];
|
||||
int i;
|
||||
|
||||
memset(&rc4, 0, sizeof(rc4));
|
||||
if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0)
|
||||
fatal("Couldn't obtain random bytes (error %ld)",
|
||||
ERR_get_error());
|
||||
RC4_set_key(&rc4, sizeof(rand_buf), rand_buf);
|
||||
|
||||
/*
|
||||
* Discard early keystream, as per recommendations in:
|
||||
* http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
|
||||
*/
|
||||
for(i = 0; i <= 256; i += sizeof(rand_buf))
|
||||
RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf);
|
||||
|
||||
memset(rand_buf, 0, sizeof(rand_buf));
|
||||
|
||||
rc4_ready = REKEY_BYTES;
|
||||
}
|
||||
#endif /* !HAVE_ARC4RANDOM */
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM_BUF
|
||||
void
|
||||
arc4random_buf(void *_buf, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
u_int32_t r = 0;
|
||||
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 HAVE_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 */
|
Loading…
Reference in New Issue