- (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
|
- (djm) [openbsd-compat/arc4random.c openbsd-compat/chacha_private.h] Pull
|
||||||
in OpenBSD implementation of arc4random, shortly to replace the existing
|
in OpenBSD implementation of arc4random, shortly to replace the existing
|
||||||
bsd-arc4random.c
|
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
|
20130922
|
||||||
- (dtucker) [platform.c platform.h sshd.c] bz#2156: restore Linux oom_adj
|
- (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@
|
sysconfdir=@sysconfdir@
|
||||||
piddir=@piddir@
|
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
|
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
|
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 $ */
|
/* $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.
|
* ChaCha based random number generator for OpenBSD.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include "includes.h"
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/time.h>
|
#ifndef HAVE_ARC4RANDOM
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include "thread_private.h"
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#define KEYSTREAM_ONLY
|
#define KEYSTREAM_ONLY
|
||||||
#include "chacha_private.h"
|
#include "chacha_private.h"
|
||||||
|
@ -42,6 +47,10 @@
|
||||||
#define inline
|
#define inline
|
||||||
#endif /* !__GNUC__ */
|
#endif /* !__GNUC__ */
|
||||||
|
|
||||||
|
/* OpenSSH isn't multithreaded */
|
||||||
|
#define _ARC4_LOCK()
|
||||||
|
#define _ARC4_UNLOCK()
|
||||||
|
|
||||||
#define KEYSZ 32
|
#define KEYSZ 32
|
||||||
#define IVSZ 8
|
#define IVSZ 8
|
||||||
#define BLOCKSZ 64
|
#define BLOCKSZ 64
|
||||||
|
@ -67,15 +76,11 @@ _rs_init(u_char *buf, size_t n)
|
||||||
static void
|
static void
|
||||||
_rs_stir(void)
|
_rs_stir(void)
|
||||||
{
|
{
|
||||||
int mib[2];
|
|
||||||
size_t len;
|
|
||||||
u_char rnd[KEYSZ + IVSZ];
|
u_char rnd[KEYSZ + IVSZ];
|
||||||
|
|
||||||
mib[0] = CTL_KERN;
|
if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
|
||||||
mib[1] = KERN_ARND;
|
fatal("Couldn't obtain random bytes (error %ld)",
|
||||||
|
ERR_get_error());
|
||||||
len = sizeof(rnd);
|
|
||||||
sysctl(mib, 2, rnd, &len, NULL, 0);
|
|
||||||
|
|
||||||
if (!rs_initialized) {
|
if (!rs_initialized) {
|
||||||
rs_initialized = 1;
|
rs_initialized = 1;
|
||||||
|
@ -194,6 +199,11 @@ arc4random(void)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are providing arc4random, then we can provide a more efficient
|
||||||
|
* arc4random_buf().
|
||||||
|
*/
|
||||||
|
# ifndef HAVE_ARC4RANDOM_BUF
|
||||||
void
|
void
|
||||||
arc4random_buf(void *buf, size_t n)
|
arc4random_buf(void *buf, size_t n)
|
||||||
{
|
{
|
||||||
|
@ -201,7 +211,29 @@ arc4random_buf(void *buf, size_t n)
|
||||||
_rs_random_buf(buf, n);
|
_rs_random_buf(buf, n);
|
||||||
_ARC4_UNLOCK();
|
_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
|
* Calculate a uniformly distributed random number less than upper_bound
|
||||||
* avoiding "modulo bias".
|
* avoiding "modulo bias".
|
||||||
|
@ -237,6 +269,7 @@ arc4random_uniform(u_int32_t upper_bound)
|
||||||
|
|
||||||
return r % upper_bound;
|
return r % upper_bound;
|
||||||
}
|
}
|
||||||
|
#endif /* !HAVE_ARC4RANDOM_UNIFORM */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*-------- Test code for i386 --------*/
|
/*-------- 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