Delete Cygwin's arc4random in favor of new Newlib implementation
* Makefile.in (DLL_OFILES): Remove arc4random.o. * libc/arc4random.c: Remove file. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
		| @@ -155,7 +155,6 @@ MT_SAFE_OBJECTS:= | |||||||
| # | # | ||||||
| DLL_OFILES:= \ | DLL_OFILES:= \ | ||||||
| 	advapi32.o \ | 	advapi32.o \ | ||||||
| 	arc4random.o \ |  | ||||||
| 	assert.o \ | 	assert.o \ | ||||||
| 	autoload.o \ | 	autoload.o \ | ||||||
| 	base64.o \ | 	base64.o \ | ||||||
|   | |||||||
| @@ -1,363 +0,0 @@ | |||||||
| /*	$OpenBSD: arc4random.c,v 1.22 2010/12/22 08:23:42 otto Exp $	*/ |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Copyright (c) 1996, David Mazieres <dm@uun.org> |  | ||||||
|  * Copyright (c) 2008, Damien Miller <djm@openbsd.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. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Arc4 random number generator for OpenBSD. |  | ||||||
|  * |  | ||||||
|  * This code is derived from section 17.1 of Applied Cryptography, |  | ||||||
|  * second edition, which describes a stream cipher allegedly |  | ||||||
|  * compatible with RSA Labs "RC4" cipher (the actual description of |  | ||||||
|  * which is a trade secret).  The same algorithm is used as a stream |  | ||||||
|  * cipher called "arcfour" in Tatu Ylonen's ssh package. |  | ||||||
|  * |  | ||||||
|  * RC4 is a registered trademark of RSA Laboratories. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <sys/cdefs.h> |  | ||||||
| __FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.30 2012/11/17 01:49:23 svnexp Exp $"); |  | ||||||
|  |  | ||||||
| #ifdef __CYGWIN__ |  | ||||||
| #include "winsup.h" |  | ||||||
| #include "sync.h" |  | ||||||
| #else |  | ||||||
| #include "namespace.h" |  | ||||||
| #endif |  | ||||||
| #include <fcntl.h> |  | ||||||
| #include <limits.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <unistd.h> |  | ||||||
| #include <sys/types.h> |  | ||||||
| #include <sys/param.h> |  | ||||||
| #ifndef __CYGWIN__ |  | ||||||
| #include <sys/sysctl.h> |  | ||||||
| #endif |  | ||||||
| #include <sys/time.h> |  | ||||||
| #include <pthread.h> |  | ||||||
|  |  | ||||||
| #ifndef __CYGWIN__ |  | ||||||
| #include "libc_private.h" |  | ||||||
| #include "un-namespace.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifdef __CYGWIN__ |  | ||||||
| #define _open open |  | ||||||
| #define _read read |  | ||||||
| #define _close close |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifdef __GNUC__ |  | ||||||
| #define inline __inline |  | ||||||
| #else				/* !__GNUC__ */ |  | ||||||
| #define inline |  | ||||||
| #endif				/* !__GNUC__ */ |  | ||||||
|  |  | ||||||
| struct arc4_stream { |  | ||||||
| 	u_int8_t i; |  | ||||||
| 	u_int8_t j; |  | ||||||
| 	u_int8_t s[256]; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #ifdef __CYGWIN__ |  | ||||||
| static NO_COPY muto arc4random_mtx; |  | ||||||
| #else |  | ||||||
| static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #define	RANDOMDEV	"/dev/random" |  | ||||||
| #define	KEYSIZE		128 |  | ||||||
| #ifdef __CYGWIN__ |  | ||||||
| #define _ARC4_LOCK()						\ |  | ||||||
| 	do {							\ |  | ||||||
| 		if (__isthreaded)				\ |  | ||||||
| 			arc4random_mtx.init ("arc4random_mtx")->acquire (); \ |  | ||||||
| 	} while (0) |  | ||||||
| #define _ARC4_UNLOCK()						\ |  | ||||||
| 	do {							\ |  | ||||||
| 		if (__isthreaded)				\ |  | ||||||
| 			arc4random_mtx.release ();		\ |  | ||||||
| 	} while (0) |  | ||||||
| #else |  | ||||||
| #define	_ARC4_LOCK()						\ |  | ||||||
| 	do {							\ |  | ||||||
| 		if (__isthreaded)				\ |  | ||||||
| 			_pthread_mutex_lock(&arc4random_mtx);	\ |  | ||||||
| 	} while (0) |  | ||||||
|  |  | ||||||
| #define	_ARC4_UNLOCK()						\ |  | ||||||
| 	do {							\ |  | ||||||
| 		if (__isthreaded)				\ |  | ||||||
| 			_pthread_mutex_unlock(&arc4random_mtx);	\ |  | ||||||
| 	} while (0) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| static int rs_initialized; |  | ||||||
| static struct arc4_stream rs; |  | ||||||
| static pid_t arc4_stir_pid; |  | ||||||
| static int arc4_count; |  | ||||||
|  |  | ||||||
| #ifndef __CYGWIN__ |  | ||||||
| extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, |  | ||||||
|     void *newp, size_t newlen); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| static inline u_int8_t arc4_getbyte(void); |  | ||||||
| static void arc4_stir(void); |  | ||||||
|  |  | ||||||
| static inline void |  | ||||||
| arc4_init(void) |  | ||||||
| { |  | ||||||
| 	int     n; |  | ||||||
|  |  | ||||||
| 	for (n = 0; n < 256; n++) |  | ||||||
| 		rs.s[n] = n; |  | ||||||
| 	rs.i = 0; |  | ||||||
| 	rs.j = 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline void |  | ||||||
| arc4_addrandom(u_char *dat, int datlen) |  | ||||||
| { |  | ||||||
| 	int     n; |  | ||||||
| 	u_int8_t si; |  | ||||||
|  |  | ||||||
| 	rs.i--; |  | ||||||
| 	for (n = 0; n < 256; n++) { |  | ||||||
| 		rs.i = (rs.i + 1); |  | ||||||
| 		si = rs.s[rs.i]; |  | ||||||
| 		rs.j = (rs.j + si + dat[n % datlen]); |  | ||||||
| 		rs.s[rs.i] = rs.s[rs.j]; |  | ||||||
| 		rs.s[rs.j] = si; |  | ||||||
| 	} |  | ||||||
| 	rs.j = rs.i; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #ifndef __CYGWIN__ |  | ||||||
| static size_t |  | ||||||
| arc4_sysctl(u_char *buf, size_t size) |  | ||||||
| { |  | ||||||
| 	int mib[2]; |  | ||||||
| 	size_t len, done; |  | ||||||
|  |  | ||||||
| 	mib[0] = CTL_KERN; |  | ||||||
| 	mib[1] = KERN_ARND; |  | ||||||
| 	done = 0; |  | ||||||
|  |  | ||||||
| 	do { |  | ||||||
| 		len = size; |  | ||||||
| 		if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1) |  | ||||||
| 			return (done); |  | ||||||
| 		done += len; |  | ||||||
| 		buf += len; |  | ||||||
| 		size -= len; |  | ||||||
| 	} while (size > 0); |  | ||||||
|  |  | ||||||
| 	return (done); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| static void |  | ||||||
| arc4_stir(void) |  | ||||||
| { |  | ||||||
| 	int done, fd, i; |  | ||||||
| 	struct { |  | ||||||
| 		struct timeval	tv; |  | ||||||
| 		pid_t		pid; |  | ||||||
| 		u_char	 	rnd[KEYSIZE]; |  | ||||||
| 	} rdat; |  | ||||||
|  |  | ||||||
| 	if (!rs_initialized) { |  | ||||||
| 		arc4_init(); |  | ||||||
| 		rs_initialized = 1; |  | ||||||
| 	} |  | ||||||
| 	done = 0; |  | ||||||
| #ifndef __CYGWIN__ |  | ||||||
| 	if (arc4_sysctl((u_char *)&rdat, KEYSIZE) == KEYSIZE) |  | ||||||
| 		done = 1; |  | ||||||
| #endif |  | ||||||
| 	if (!done) { |  | ||||||
| 		fd = _open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0); |  | ||||||
| 		if (fd >= 0) { |  | ||||||
| 			if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) |  | ||||||
| 				done = 1; |  | ||||||
| 			(void)_close(fd); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if (!done) { |  | ||||||
| 		(void)gettimeofday(&rdat.tv, NULL); |  | ||||||
| 		rdat.pid = getpid(); |  | ||||||
| 		/* We'll just take whatever was on the stack too... */ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	arc4_addrandom((u_char *)&rdat, KEYSIZE); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Discard early keystream, as per recommendations in: |  | ||||||
| 	 * "(Not So) Random Shuffles of RC4" by Ilya Mironov. |  | ||||||
| 	 */ |  | ||||||
| 	for (i = 0; i < 1024; i++) |  | ||||||
| 		(void)arc4_getbyte(); |  | ||||||
| 	arc4_count = 1600000; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void |  | ||||||
| arc4_stir_if_needed(void) |  | ||||||
| { |  | ||||||
| 	pid_t pid = getpid(); |  | ||||||
|  |  | ||||||
| 	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) |  | ||||||
| 	{ |  | ||||||
| 		arc4_stir_pid = pid; |  | ||||||
| 		arc4_stir(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline u_int8_t |  | ||||||
| arc4_getbyte(void) |  | ||||||
| { |  | ||||||
| 	u_int8_t si, sj; |  | ||||||
|  |  | ||||||
| 	rs.i = (rs.i + 1); |  | ||||||
| 	si = rs.s[rs.i]; |  | ||||||
| 	rs.j = (rs.j + si); |  | ||||||
| 	sj = rs.s[rs.j]; |  | ||||||
| 	rs.s[rs.i] = sj; |  | ||||||
| 	rs.s[rs.j] = si; |  | ||||||
| 	return (rs.s[(si + sj) & 0xff]); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline u_int32_t |  | ||||||
| arc4_getword(void) |  | ||||||
| { |  | ||||||
| 	u_int32_t val; |  | ||||||
| 	val = arc4_getbyte() << 24; |  | ||||||
| 	val |= arc4_getbyte() << 16; |  | ||||||
| 	val |= arc4_getbyte() << 8; |  | ||||||
| 	val |= arc4_getbyte(); |  | ||||||
| 	return val; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| arc4random_stir(void) |  | ||||||
| { |  | ||||||
| 	_ARC4_LOCK(); |  | ||||||
| 	arc4_stir(); |  | ||||||
| 	_ARC4_UNLOCK(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| arc4random_addrandom(u_char *dat, int datlen) |  | ||||||
| { |  | ||||||
| 	_ARC4_LOCK(); |  | ||||||
| 	if (!rs_initialized) |  | ||||||
| 		arc4_stir(); |  | ||||||
| 	arc4_addrandom(dat, datlen); |  | ||||||
| 	_ARC4_UNLOCK(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| u_int32_t |  | ||||||
| arc4random(void) |  | ||||||
| { |  | ||||||
| 	u_int32_t val; |  | ||||||
| 	_ARC4_LOCK(); |  | ||||||
| 	arc4_count -= 4; |  | ||||||
| 	arc4_stir_if_needed(); |  | ||||||
| 	val = arc4_getword(); |  | ||||||
| 	_ARC4_UNLOCK(); |  | ||||||
| 	return val; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| arc4random_buf(void *_buf, size_t n) |  | ||||||
| { |  | ||||||
| 	u_char *buf = (u_char *)_buf; |  | ||||||
| 	_ARC4_LOCK(); |  | ||||||
| 	arc4_stir_if_needed(); |  | ||||||
| 	while (n--) { |  | ||||||
| 		if (--arc4_count <= 0) |  | ||||||
| 			arc4_stir(); |  | ||||||
| 		buf[n] = arc4_getbyte(); |  | ||||||
| 	} |  | ||||||
| 	_ARC4_UNLOCK(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * 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; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| /*-------- Test code for i386 --------*/ |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <machine/pctr.h> |  | ||||||
| int |  | ||||||
| main(int argc, char **argv) |  | ||||||
| { |  | ||||||
| 	const int iter = 1000000; |  | ||||||
| 	int     i; |  | ||||||
| 	pctrval v; |  | ||||||
|  |  | ||||||
| 	v = rdtsc(); |  | ||||||
| 	for (i = 0; i < iter; i++) |  | ||||||
| 		arc4random(); |  | ||||||
| 	v = rdtsc() - v; |  | ||||||
| 	v /= iter; |  | ||||||
|  |  | ||||||
| 	printf("%qd cycles\n", v); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
		Reference in New Issue
	
	Block a user