[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freewrt-commits
Subject:    [FreeWRT-commits] r3894 - branches/freewrt_1_0/package/rdate
From:       tg () freewrt ! org
Date:       2009-10-19 9:53:20
Message-ID: 20091019095320.882B11C007 () frozenfish ! freewrt ! org
[Download RAW message or body]

Author: tg
Date: 2009-10-19 11:53:19 +0200 (Mon, 19 Oct 2009)
New Revision: 3894

Added:
   branches/freewrt_1_0/package/rdate/arc4random.c
Modified:
   branches/freewrt_1_0/package/rdate/Makefile
   trunk/freewrt/package/rdate/Makefile
   trunk/freewrt/toolchain/uClibc/files/arc4random.c
   trunk/freewrt/toolchain/uClibc/patches/patch-libc_stdlib_Makefile
Log:
update arc4random.c and rdate (and add arc4random.c to 1.0, since it
is no longer contained within the rdate distfile)

thanks XTaran (abe@) for noticing!


Modified: branches/freewrt_1_0/package/rdate/Makefile
===================================================================
--- branches/freewrt_1_0/package/rdate/Makefile	2009-10-18 20:25:22 UTC (rev 3893)
+++ branches/freewrt_1_0/package/rdate/Makefile	2009-10-19 09:53:19 UTC (rev 3894)
@@ -7,17 +7,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME=		rdate
-PKG_VERSION=		20090114
+PKG_VERSION=		20090802
 PKG_RELEASE=		1
-PKG_MD5SUM=		97a47512f67a926205bc553675a6f1b2
+PKG_MD5SUM=		a8fa4550b5a77cff6db1ed0a9d8aa357
 PKG_SOURCE_URL=		http://www.mirbsd.org/MirOS/dist/mir/rdate/
-PKG_SOURCE:=		${PKG_NAME}_${PKG_VERSION}.orig.tar.gz
 
 include $(TOPDIR)/mk/package.mk
 
 $(eval $(call PKG_template,RDATE,rdate,$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
 
 $(WRKBUILD)/.configured:
+	cp -f arc4random.c ${WRKBUILD}/
 	touch $@
 
 $(WRKBUILD)/.built:

Added: branches/freewrt_1_0/package/rdate/arc4random.c
===================================================================
--- branches/freewrt_1_0/package/rdate/arc4random.c	                        (rev 0)
+++ branches/freewrt_1_0/package/rdate/arc4random.c	2009-10-19 09:53:19 UTC (rev \
3894) @@ -0,0 +1,507 @@
+static const char __vcsid[] = "@(#) MirOS contributed arc4random.c (old)"
+    "\n	@(#)rcsid_master: $MirOS: contrib/code/Snippets/arc4random.c,v 1.19 \
2009/09/27 10:45:56 tg Exp $" +    ;
+
+/*-
+ * Arc4 random number generator for OpenBSD.
+ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
+ *
+ * Modification and redistribution in source and binary forms is
+ * permitted provided that due credit is given to the author and the
+ * OpenBSD project by leaving this copyright notice intact.
+ */
+
+/*-
+ * 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.
+ *
+ * Here the stream cipher has been modified always to include the time
+ * when initializing the state.  That makes it impossible to
+ * regenerate the same random sequence twice, so this can't be used
+ * for encryption, but will generate good random numbers.
+ *
+ * RC4 is a registered trademark of RSA Laboratories.
+ */
+
+/*-
+ * Modified by Robert Connolly from OpenBSD lib/libc/crypt/arc4random.c v1.11.
+ * This is arc4random(3) using urandom.
+ */
+
+/*-
+ * Copyright (c) 2008, 2009
+ *	Thorsten Glaser <tg@mirbsd.org>
+ * This is arc4random(3) made more portable,
+ * as well as arc4random_pushb(3) for Cygwin.
+ *
+ * Provided that these terms and disclaimer and all copyright notices
+ * are retained or reproduced in an accompanying document, permission
+ * is granted to deal in this work without restriction, including un-
+ * limited rights to use, publicly perform, distribute, sell, modify,
+ * merge, give away, or sublicence.
+ *
+ * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+ * the utmost extent permitted by applicable law, neither express nor
+ * implied; without malicious intent or gross negligence. In no event
+ * may a licensor, author or contributor be held liable for indirect,
+ * direct, other damage, loss, or other issues arising in any way out
+ * of dealing in the work, even if advised of the possibility of such
+ * damage or existence of a defect, except proven that it results out
+ * of said person's immediate fault when using the work as intended.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#if defined(HAVE_SYS_SYSCTL_H) && HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#include <fcntl.h>
+#if defined(HAVE_STDINT_H) && HAVE_STDINT_H
+#include <stdint.h>
+#elif defined(USE_INTTYPES)
+#include <inttypes.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(__CYGWIN__) || defined(WIN32)
+#define USE_MS_CRYPTOAPI
+#define REDEF_USCORETYPES
+#endif
+
+#ifdef USE_MS_CRYPTOAPI
+#define WIN32_WINNT 0x400
+#define _WIN32_WINNT 0x400
+#include <windows.h>
+#include <wincrypt.h>
+
+static uint8_t w32_buf[16*16384];	/* force reseed */
+static uint8_t w32_hklm[80];		/* registry key (MS, Admin) */
+static uint8_t w32_hkcu[256];		/* registry key (per user) */
+static struct timeval w32_last;		/* last time CGR was used */
+
+static char w32_subkey[] = "SOFTWARE\\Microsoft\\Cryptography\\RNG";
+#endif
+
+#ifndef MIN
+#define	MIN(a,b)	(((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+#define	MAX(a,b)	(((a)>(b))?(a):(b))
+#endif
+
+#ifdef REDEF_USCORETYPES
+#define u_int32_t	uint32_t
+#endif
+
+#ifndef _PATH_URANDOM
+#define _PATH_URANDOM	"/dev/urandom"
+#endif
+
+static struct arc4_stream {
+	uint8_t i;
+	uint8_t j;
+	uint8_t s[256];
+} arc4_ctx;
+
+static int rs_initialized;
+static pid_t arc4_stir_pid;
+static int arc4_count;
+static const char __randomdev[] = _PATH_URANDOM;
+
+static uint8_t arc4_getbyte(void);
+static void stir_finish(int);
+static void arc4_atexit(void);
+static char arc4_writeback(uint8_t *, size_t, char);
+
+#ifndef arc4random_pushk
+u_int32_t arc4random(void);
+void arc4random_addrandom(u_char *, int);
+void arc4random_stir(void);
+#ifdef USE_MS_CRYPTOAPI
+uint32_t arc4random_pushb(const void *, size_t);
+#endif
+#endif
+
+static void
+arc4_init(void)
+{
+	int n;
+
+	for (n = 0; n < 256; n++)
+		arc4_ctx.s[n] = (uint8_t)n;
+	arc4_ctx.i = 0;
+	arc4_ctx.j = 0;
+}
+
+static void
+arc4_addrandom(u_char *dat, int datlen)
+{
+	int n;
+	uint8_t si;
+
+	arc4_ctx.i--;
+	for (n = 0; n < 256; n++) {
+		arc4_ctx.i++;
+		si = arc4_ctx.s[arc4_ctx.i];
+		arc4_ctx.j = (uint8_t)(arc4_ctx.j + si + dat[n % datlen]);
+		arc4_ctx.s[arc4_ctx.i] = arc4_ctx.s[arc4_ctx.j];
+		arc4_ctx.s[arc4_ctx.j] = si;
+	}
+	arc4_ctx.j = arc4_ctx.i;
+}
+
+static void
+arc4_stir(void)
+{
+	int fd;
+	struct {
+		struct timeval tv;
+		pid_t pid;
+		u_int rnd[(128 - (sizeof(struct timeval) + sizeof(pid_t))) / sizeof(u_int)];
+	} rdat;
+	size_t sz = 0;
+
+	gettimeofday(&rdat.tv, NULL);
+	rdat.pid = getpid();
+	memcpy(rdat.rnd, __vcsid, MIN(sizeof(__vcsid), sizeof(rdat.rnd)));
+
+#ifdef USE_MS_CRYPTOAPI
+	if (arc4_writeback((char *)rdat.rnd, sizeof(rdat.rnd), 1))
+		goto stir_okay;
+#endif
+
+	/* /dev/urandom is a multithread interface, sysctl is not. */
+	/* Try to use /dev/urandom before sysctl. */
+	fd = open(__randomdev, O_RDONLY);
+	if (fd != -1) {
+		sz = (size_t)read(fd, rdat.rnd, sizeof(rdat.rnd));
+		close(fd);
+	}
+	if (sz > sizeof(rdat.rnd))
+		sz = 0;
+	if (fd == -1 || sz != sizeof(rdat.rnd)) {
+		/* /dev/urandom failed? Maybe we're in a chroot. */
+#if /* Linux */ defined(_LINUX_SYSCTL_H) || \
+    /* OpenBSD */ (defined(CTL_KERN) && defined(KERN_ARND))
+		int mib[3], nmib = 3;
+		size_t i = sz / sizeof(u_int), len;
+
+#ifdef _LINUX_SYSCTL_H
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_RANDOM;
+		mib[2] = RANDOM_UUID;
+#else
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_ARND;
+		nmib = 2;
+#endif
+
+		while (i < sizeof(rdat.rnd) / sizeof(u_int)) {
+			len = sizeof(u_int);
+			if (sysctl(mib, nmib, &rdat.rnd[i++], &len,
+			    NULL, 0) == -1) {
+				fputs("warning: no entropy source\n", stderr);
+				break;
+			}
+		}
+#else
+		/* XXX kFreeBSD doesn't seem to have KERN_ARND or so */
+		;
+#endif
+	}
+
+#ifdef USE_MS_CRYPTOAPI
+ stir_okay:
+#endif
+	fd = arc4_getbyte();
+
+	/*
+	 * Time to give up. If no entropy could be found then we will just
+	 * use gettimeofday and getpid.
+	 */
+	arc4_addrandom((u_char *)&rdat, sizeof(rdat));
+
+	stir_finish(fd);
+}
+
+static void
+stir_finish(int av)
+{
+	size_t n;
+	uint8_t tb[16];
+
+	arc4_stir_pid = getpid();
+
+	/*
+	 * Discard early keystream, as per recommendations in:
+	 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
+	 * We discard 256 words. A long word is 4 bytes.
+	 * We also discard a randomly fuzzed amount.
+	 */
+	n = 256 * 4 + (arc4_getbyte() & 0x0FU);
+	while (av) {
+		n += (av & 0x0F);
+		av >>= 4;
+	}
+	while (n--)
+		arc4_getbyte();
+	while (n < sizeof(tb))
+		tb[n++] = arc4_getbyte();
+	if (arc4_writeback(tb, sizeof(tb), 0))
+		arc4_getbyte();
+	arc4_count = 400000;
+}
+
+static uint8_t
+arc4_getbyte(void)
+{
+	uint8_t si, sj;
+
+	arc4_ctx.i++;
+	si = arc4_ctx.s[arc4_ctx.i];
+	arc4_ctx.j = (uint8_t)(arc4_ctx.j + si);
+	sj = arc4_ctx.s[arc4_ctx.j];
+	arc4_ctx.s[arc4_ctx.i] = sj;
+	arc4_ctx.s[arc4_ctx.j] = si;
+	return (arc4_ctx.s[(si + sj) & 0xff]);
+}
+
+static uint32_t
+arc4_getword(void)
+{
+	uint32_t val;
+	val = (uint32_t)arc4_getbyte() << 24;
+	val |= (uint32_t)arc4_getbyte() << 16;
+	val |= (uint32_t)arc4_getbyte() << 8;
+	val |= (uint32_t)arc4_getbyte();
+	return (val);
+}
+
+void
+arc4random_stir(void)
+{
+	if (!rs_initialized) {
+		arc4_init();
+		rs_initialized = 1;
+		atexit(arc4_atexit);
+	}
+	arc4_stir();
+}
+
+void
+arc4random_addrandom(u_char *dat, int datlen)
+{
+	if (!rs_initialized)
+		arc4random_stir();
+	arc4_addrandom(dat, datlen);
+}
+
+u_int32_t
+arc4random(void)
+{
+	if (--arc4_count == 0 || !rs_initialized || arc4_stir_pid != getpid())
+		arc4random_stir();
+	return arc4_getword();
+}
+
+/*
+ * Returns 0 if write error; 0 if do_rd and read error;
+ * 1 if !do_rd and read error but not write error;
+ * 1 if no error occured.
+ */
+static char
+arc4_writeback(uint8_t *buf, size_t len, char do_rd)
+{
+#ifdef USE_MS_CRYPTOAPI
+	static char has_provider = 0;
+	static HCRYPTPROV p;
+	HKEY hKeyLM, hKeyCU;
+	DWORD ksz;
+	char rc = 6, has_rkey = 0, w32_a4b[16];
+	size_t i, j, xlen;
+	struct timeval tv;
+
+	for (i = 0; i < sizeof(w32_a4b); ++i)
+		w32_a4b[i] = arc4_getbyte();
+	for (i = arc4_getbyte() & 15; i; --i)
+		arc4_getbyte();
+
+	ksz = sizeof(w32_buf);
+	if ((/* read-write */ RegOpenKeyEx(HKEY_LOCAL_MACHINE, w32_subkey,
+	    0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hKeyLM) == ERROR_SUCCESS ||
+	    /* try read-only */ RegOpenKeyEx(HKEY_LOCAL_MACHINE, w32_subkey,
+	    0, KEY_QUERY_VALUE, &hKeyLM) == ERROR_SUCCESS) && /* get value */
+	    (RegQueryValueEx(hKeyLM, "Seed", NULL, NULL, w32_buf, &ksz) ==
+	    ERROR_SUCCESS) && /* got any content? */ ksz) {
+		/* we got HKLM key, read-write or read-only */
+		has_rkey |= 1;
+		/* move content to destination */
+		memset(w32_hklm, '\0', sizeof(w32_hklm));
+		for (i = 0; i < MAX(ksz, sizeof(w32_hklm)); ++i)
+			w32_hklm[i % sizeof(w32_hklm)] ^= w32_buf[i % ksz];
+	}
+	ksz = sizeof(w32_buf);
+	if ((/* read-write */ RegCreateKeyEx(HKEY_CURRENT_USER, w32_subkey,
+	    0, NULL, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKeyCU,
+	    NULL) == ERROR_SUCCESS || /* R/O */ RegOpenKeyEx(HKEY_CURRENT_USER,
+	    w32_subkey, 0, KEY_QUERY_VALUE, &hKeyLM) == ERROR_SUCCESS) &&
+	    /* get value */ (RegQueryValueEx(hKeyLM, "Seed", NULL, NULL,
+	    w32_buf, &ksz) == ERROR_SUCCESS) && /* got any content? */ ksz) {
+		/* we got HKCU key, created, read-write or read-only */
+		has_rkey |= 2;
+		/* move content to destination */
+		memset(w32_hkcu, '\0', sizeof(w32_hkcu));
+		for (i = 0; i < MAX(ksz, sizeof(w32_hkcu)); ++i)
+			w32_hkcu[i % sizeof(w32_hkcu)] ^= w32_buf[i % ksz];
+	}
+
+	if (!do_rd)
+		goto nogen_out;
+
+	if (has_rkey && gettimeofday(&tv, NULL) == 0) {
+		/* we have registry key; rate-limit CryptGenRandom */
+		if (tv.tv_sec - w32_last.tv_sec < 128 + (arc4_getbyte() & 127))
+			goto nogen_out;
+		/* nope, more than 2-4 minutes, call it */
+		w32_last.tv_sec = tv.tv_sec;
+	}
+
+	if (!has_provider) {
+		if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL, 0)) {
+			if ((HRESULT)GetLastError() != NTE_BAD_KEYSET)
+				goto nogen_out;
+			if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL,
+			    CRYPT_NEWKEYSET))
+				goto nogen_out;
+		}
+		has_provider = 1;
+	}
+	i = 0;
+	while (i < 256)
+		w32_buf[i++] = arc4_getbyte();
+	if (!CryptGenRandom(p, sizeof(w32_buf), w32_buf)) {
+		w32_last.tv_sec = 0;
+ nogen_out:
+		rc |= 1;
+		memset(w32_buf, '\0', 256);
+	}
+	xlen = MIN(sizeof(w32_buf) - sizeof(w32_hklm) - sizeof(w32_hkcu) -
+	    sizeof(w32_a4b), len);
+	j = xlen + sizeof(w32_hklm) + sizeof(w32_hkcu) + sizeof(w32_a4b);
+	for (i = 0; i < MAX(j, len); ++i)
+		w32_buf[i % j] ^= w32_hklm[i % sizeof(w32_hklm)] ^
+		    w32_hkcu[i % sizeof(w32_hkcu)] ^ buf[i % len] ^
+		    arc4_getbyte();
+	if (has_rkey & 1) {
+		if (RegSetValueEx(hKeyLM, "Seed", 0, REG_BINARY,
+		    w32_buf, sizeof(w32_hklm)) == ERROR_SUCCESS)
+			rc &= ~2;
+		RegCloseKey(hKeyLM);
+	}
+	if (has_rkey & 2) {
+		if (RegSetValueEx(hKeyCU, "Seed", 0, REG_BINARY,
+		    w32_buf + sizeof(w32_hklm), sizeof(w32_hkcu)) ==
+		    ERROR_SUCCESS)
+			rc &= ~4;
+		RegCloseKey(hKeyCU);
+	}
+	for (i = 0; i < sizeof(w32_a4b); ++i)
+		w32_a4b[i] ^= w32_buf[sizeof(w32_hklm) + sizeof(w32_hkcu) + i];
+	arc4_addrandom(w32_a4b, sizeof(w32_a4b));
+
+	i = sizeof(w32_hklm) + sizeof(w32_hkcu) + sizeof(w32_a4b);
+	while (len) {
+		j = MIN(len, xlen);
+		memcpy(buf, w32_buf + i, j);
+		buf += j;
+		len -= j;
+	}
+
+	memset(w32_buf, '\0', sizeof(w32_buf));
+
+	return (
+	    /* read error occured */
+	    (!has_rkey && (rc & 1)) ? 0 :
+	    /* don't care about write errors */
+	    !do_rd ? 1 :
+	    /* couldn't write */
+	    (rc & 6) == 6 ? 0 :
+	    /* at least one RegSetValueEx succeeded */
+	    1);
+#elif defined(arc4random_pushk)
+	uint32_t num;
+
+	num = arc4random_pushk(buf, len);
+	memcpy(buf, &num, sizeof(num));
+	return (do_rd ? 0 : 1);
+#else
+	int fd;
+
+	if ((fd = open(__randomdev, O_WRONLY)) != -1) {
+		if (write(fd, buf, len) < 4)
+			do_rd = 1;
+		close(fd);
+	}
+	return (do_rd || fd == -1 ? 0 : 1);
+#endif
+}
+
+#if defined(USE_MS_CRYPTOAPI) || defined(arc4random_pushk)
+uint32_t
+arc4random_pushb(const void *src, size_t len)
+{
+	size_t rlen;
+	union {
+		uint8_t buf[256];
+		struct timeval tv;
+		uint32_t xbuf;
+	} idat;
+	const uint8_t *cbuf = (const uint8_t *)src;
+	uint32_t res = 1;
+
+	if (!rs_initialized) {
+		arc4_init();
+		rs_initialized = 1;
+	}
+
+	gettimeofday(&idat.tv, NULL);
+	for (rlen = 0; rlen < len; ++rlen)
+		idat.buf[rlen % sizeof(idat)] ^= cbuf[rlen];
+	rlen = MIN(sizeof(idat), MAX(sizeof(struct timeval), len));
+
+	if (arc4_writeback(&idat.buf[0], rlen, 1))
+		res = 0;
+	arc4_addrandom(&idat.buf[0], rlen);
+	if (res)
+		res = idat.xbuf;
+	else
+		/* we got entropy from the kernel, so consider us stirred */
+		stir_finish(idat.buf[5]);
+	return (res ^ arc4_getword());
+}
+#endif
+
+static void
+arc4_atexit(void)
+{
+	struct {
+		pid_t spid;
+		int cnt;
+		uint8_t carr[240];
+	} buf;
+	int i = 0;
+
+	while (i < 240)
+		buf.carr[i++] = arc4_getbyte();
+	buf.spid = arc4_stir_pid;
+	buf.cnt = arc4_count;
+
+	arc4_writeback((uint8_t *)&buf, sizeof(buf), 0);
+}

Modified: trunk/freewrt/package/rdate/Makefile
===================================================================
--- trunk/freewrt/package/rdate/Makefile	2009-10-18 20:25:22 UTC (rev 3893)
+++ trunk/freewrt/package/rdate/Makefile	2009-10-19 09:53:19 UTC (rev 3894)
@@ -7,11 +7,10 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME=		rdate
-PKG_VERSION=		20070817
-PKG_RELEASE=		2
-PKG_MD5SUM=		9a6489d7de4311678a3fab001bb503df
+PKG_VERSION=		20090802
+PKG_RELEASE=		1
+PKG_MD5SUM=		a8fa4550b5a77cff6db1ed0a9d8aa357
 MASTER_SITES=		${MASTER_SITE_MIRBSD:distfiles/=dist/mir/rdate/}
-WRKDIST=		${WRKDIR}/${PKG_NAME}
 
 include ${TOPDIR}/mk/package.mk
 

Modified: trunk/freewrt/toolchain/uClibc/files/arc4random.c
===================================================================
--- trunk/freewrt/toolchain/uClibc/files/arc4random.c	2009-10-18 20:25:22 UTC (rev \
                3893)
+++ trunk/freewrt/toolchain/uClibc/files/arc4random.c	2009-10-19 09:53:19 UTC (rev \
3894) @@ -1,4 +1,8 @@
-/*
+static const char __vcsid[] = "@(#) MirOS contributed arc4random.c (old)"
+    "\n	@(#)rcsid_master: $MirOS: contrib/code/Snippets/arc4random.c,v 1.19 \
2009/09/27 10:45:56 tg Exp $" +    ;
+
+/*-
  * Arc4 random number generator for OpenBSD.
  * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
  *
@@ -7,7 +11,7 @@
  * OpenBSD project by leaving this copyright notice intact.
  */
 
-/*
+/*-
  * 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
@@ -22,100 +26,188 @@
  * RC4 is a registered trademark of RSA Laboratories.
  */
 
-/*
+/*-
  * Modified by Robert Connolly from OpenBSD lib/libc/crypt/arc4random.c v1.11.
  * This is arc4random(3) using urandom.
  */
 
+/*-
+ * Copyright (c) 2008, 2009
+ *	Thorsten Glaser <tg@mirbsd.org>
+ * This is arc4random(3) made more portable,
+ * as well as arc4random_pushb(3) for Cygwin.
+ *
+ * Provided that these terms and disclaimer and all copyright notices
+ * are retained or reproduced in an accompanying document, permission
+ * is granted to deal in this work without restriction, including un-
+ * limited rights to use, publicly perform, distribute, sell, modify,
+ * merge, give away, or sublicence.
+ *
+ * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+ * the utmost extent permitted by applicable law, neither express nor
+ * implied; without malicious intent or gross negligence. In no event
+ * may a licensor, author or contributor be held liable for indirect,
+ * direct, other damage, loss, or other issues arising in any way out
+ * of dealing in the work, even if advised of the possibility of such
+ * damage or existence of a defect, except proven that it results out
+ * of said person's immediate fault when using the work as intended.
+ */
+
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/time.h>
-//#if HAVE_SYS_SYSCTL_H
+#if defined(HAVE_SYS_SYSCTL_H) && HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
-//#endif
+#endif
 #include <fcntl.h>
+#if defined(HAVE_STDINT_H) && HAVE_STDINT_H
+#include <stdint.h>
+#elif defined(USE_INTTYPES)
+#include <inttypes.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
-struct arc4_stream {
-	u_int8_t i;
-	u_int8_t j;
-	u_int8_t s[256];
-};
+#if defined(__CYGWIN__) || defined(WIN32)
+#define USE_MS_CRYPTOAPI
+#define REDEF_USCORETYPES
+#endif
 
+#ifdef USE_MS_CRYPTOAPI
+#define WIN32_WINNT 0x400
+#define _WIN32_WINNT 0x400
+#include <windows.h>
+#include <wincrypt.h>
+
+static uint8_t w32_buf[16*16384];	/* force reseed */
+static uint8_t w32_hklm[80];		/* registry key (MS, Admin) */
+static uint8_t w32_hkcu[256];		/* registry key (per user) */
+static struct timeval w32_last;		/* last time CGR was used */
+
+static char w32_subkey[] = "SOFTWARE\\Microsoft\\Cryptography\\RNG";
+#endif
+
+#ifndef MIN
+#define	MIN(a,b)	(((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+#define	MAX(a,b)	(((a)>(b))?(a):(b))
+#endif
+
+#ifdef REDEF_USCORETYPES
+#define u_int32_t	uint32_t
+#endif
+
+#ifndef _PATH_URANDOM
+#define _PATH_URANDOM	"/dev/urandom"
+#endif
+
+static struct arc4_stream {
+	uint8_t i;
+	uint8_t j;
+	uint8_t s[256];
+} arc4_ctx;
+
 static int rs_initialized;
-static struct arc4_stream rs;
 static pid_t arc4_stir_pid;
+static int arc4_count;
+static const char __randomdev[] = _PATH_URANDOM;
 
-static u_int8_t arc4_getbyte(struct arc4_stream *);
+static uint8_t arc4_getbyte(void);
+static void stir_finish(int);
+static void arc4_atexit(void);
+static char arc4_writeback(uint8_t *, size_t, char);
 
+#ifndef arc4random_pushk
 u_int32_t arc4random(void);
 void arc4random_addrandom(u_char *, int);
 void arc4random_stir(void);
+#ifdef USE_MS_CRYPTOAPI
+uint32_t arc4random_pushb(const void *, size_t);
+#endif
+#endif
 
 static void
-arc4_init(struct arc4_stream *as)
+arc4_init(void)
 {
-	int     n;
+	int n;
 
 	for (n = 0; n < 256; n++)
-		as->s[n] = n;
-	as->i = 0;
-	as->j = 0;
+		arc4_ctx.s[n] = (uint8_t)n;
+	arc4_ctx.i = 0;
+	arc4_ctx.j = 0;
 }
 
 static void
-arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
+arc4_addrandom(u_char *dat, int datlen)
 {
-	int     n;
-	u_int8_t si;
+	int n;
+	uint8_t si;
 
-	as->i--;
+	arc4_ctx.i--;
 	for (n = 0; n < 256; n++) {
-		as->i = (as->i + 1);
-		si = as->s[as->i];
-		as->j = (as->j + si + dat[n % datlen]);
-		as->s[as->i] = as->s[as->j];
-		as->s[as->j] = si;
+		arc4_ctx.i++;
+		si = arc4_ctx.s[arc4_ctx.i];
+		arc4_ctx.j = (uint8_t)(arc4_ctx.j + si + dat[n % datlen]);
+		arc4_ctx.s[arc4_ctx.i] = arc4_ctx.s[arc4_ctx.j];
+		arc4_ctx.s[arc4_ctx.j] = si;
 	}
-	as->j = as->i;
+	arc4_ctx.j = arc4_ctx.i;
 }
 
 static void
-arc4_stir(struct arc4_stream *as)
+arc4_stir(void)
 {
-	int     n, fd;
+	int fd;
 	struct {
 		struct timeval tv;
-		u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)];
-	}       rdat;
+		pid_t pid;
+		u_int rnd[(128 - (sizeof(struct timeval) + sizeof(pid_t))) / sizeof(u_int)];
+	} rdat;
+	size_t sz = 0;
 
 	gettimeofday(&rdat.tv, NULL);
+	rdat.pid = getpid();
+	memcpy(rdat.rnd, __vcsid, MIN(sizeof(__vcsid), sizeof(rdat.rnd)));
 
+#ifdef USE_MS_CRYPTOAPI
+	if (arc4_writeback((char *)rdat.rnd, sizeof(rdat.rnd), 1))
+		goto stir_okay;
+#endif
+
 	/* /dev/urandom is a multithread interface, sysctl is not. */
 	/* Try to use /dev/urandom before sysctl. */
-	fd = open("/dev/urandom", O_RDONLY);
+	fd = open(__randomdev, O_RDONLY);
 	if (fd != -1) {
-		read(fd, rdat.rnd, sizeof(rdat.rnd));
+		sz = (size_t)read(fd, rdat.rnd, sizeof(rdat.rnd));
 		close(fd);
-	} else {
+	}
+	if (sz > sizeof(rdat.rnd))
+		sz = 0;
+	if (fd == -1 || sz != sizeof(rdat.rnd)) {
 		/* /dev/urandom failed? Maybe we're in a chroot. */
-//#if defined(CTL_KERN) && defined(KERN_RANDOM) && defined(RANDOM_UUID)
+#if /* Linux */ defined(_LINUX_SYSCTL_H) || \
+    /* OpenBSD */ (defined(CTL_KERN) && defined(KERN_ARND))
+		int mib[3], nmib = 3;
+		size_t i = sz / sizeof(u_int), len;
+
 #ifdef _LINUX_SYSCTL_H
-		/* XXX this is for Linux, which uses enums */
-
-		int mib[3];
-		size_t i, len;
-
 		mib[0] = CTL_KERN;
 		mib[1] = KERN_RANDOM;
 		mib[2] = RANDOM_UUID;
+#else
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_ARND;
+		nmib = 2;
+#endif
 
-		for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) {
+		while (i < sizeof(rdat.rnd) / sizeof(u_int)) {
 			len = sizeof(u_int);
-			if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) {
-				fprintf(stderr, "warning: no entropy source\n");
+			if (sysctl(mib, nmib, &rdat.rnd[i++], &len,
+			    NULL, 0) == -1) {
+				fputs("warning: no entropy source\n", stderr);
 				break;
 			}
 		}
@@ -125,55 +217,82 @@
 #endif
 	}
 
-	arc4_stir_pid = getpid();
+#ifdef USE_MS_CRYPTOAPI
+ stir_okay:
+#endif
+	fd = arc4_getbyte();
+
 	/*
 	 * Time to give up. If no entropy could be found then we will just
-	 * use gettimeofday.
+	 * use gettimeofday and getpid.
 	 */
-	arc4_addrandom(as, (void *)&rdat, sizeof(rdat));
+	arc4_addrandom((u_char *)&rdat, sizeof(rdat));
 
+	stir_finish(fd);
+}
+
+static void
+stir_finish(int av)
+{
+	size_t n;
+	uint8_t tb[16];
+
+	arc4_stir_pid = getpid();
+
 	/*
 	 * Discard early keystream, as per recommendations in:
 	 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
 	 * We discard 256 words. A long word is 4 bytes.
+	 * We also discard a randomly fuzzed amount.
 	 */
-	for (n = 0; n < 256 * 4; n ++)
-		arc4_getbyte(as);
+	n = 256 * 4 + (arc4_getbyte() & 0x0FU);
+	while (av) {
+		n += (av & 0x0F);
+		av >>= 4;
+	}
+	while (n--)
+		arc4_getbyte();
+	while (n < sizeof(tb))
+		tb[n++] = arc4_getbyte();
+	if (arc4_writeback(tb, sizeof(tb), 0))
+		arc4_getbyte();
+	arc4_count = 400000;
 }
 
-static u_int8_t
-arc4_getbyte(struct arc4_stream *as)
+static uint8_t
+arc4_getbyte(void)
 {
-	u_int8_t si, sj;
+	uint8_t si, sj;
 
-	as->i = (as->i + 1);
-	si = as->s[as->i];
-	as->j = (as->j + si);
-	sj = as->s[as->j];
-	as->s[as->i] = sj;
-	as->s[as->j] = si;
-	return (as->s[(si + sj) & 0xff]);
+	arc4_ctx.i++;
+	si = arc4_ctx.s[arc4_ctx.i];
+	arc4_ctx.j = (uint8_t)(arc4_ctx.j + si);
+	sj = arc4_ctx.s[arc4_ctx.j];
+	arc4_ctx.s[arc4_ctx.i] = sj;
+	arc4_ctx.s[arc4_ctx.j] = si;
+	return (arc4_ctx.s[(si + sj) & 0xff]);
 }
 
-static u_int32_t
-arc4_getword(struct arc4_stream *as)
+static uint32_t
+arc4_getword(void)
 {
-	u_int32_t val;
-	val = arc4_getbyte(as) << 24;
-	val |= arc4_getbyte(as) << 16;
-	val |= arc4_getbyte(as) << 8;
-	val |= arc4_getbyte(as);
-	return val;
+	uint32_t val;
+	val = (uint32_t)arc4_getbyte() << 24;
+	val |= (uint32_t)arc4_getbyte() << 16;
+	val |= (uint32_t)arc4_getbyte() << 8;
+	val |= (uint32_t)arc4_getbyte();
+	return (val);
 }
 
 void
 arc4random_stir(void)
 {
 	if (!rs_initialized) {
-		arc4_init(&rs);
+		arc4_init();
 		rs_initialized = 1;
+		atexit(arc4_atexit);
 	}
-	arc4_stir(&rs);
+	arc4_stir();
 }
 
 void
@@ -181,13 +300,208 @@
 {
 	if (!rs_initialized)
 		arc4random_stir();
-	arc4_addrandom(&rs, dat, datlen);
+	arc4_addrandom(dat, datlen);
 }
 
 u_int32_t
 arc4random(void)
 {
-	if (!rs_initialized || arc4_stir_pid != getpid())
+	if (--arc4_count == 0 || !rs_initialized || arc4_stir_pid != getpid())
 		arc4random_stir();
-	return arc4_getword(&rs);
+	return arc4_getword();
 }
+
+/*
+ * Returns 0 if write error; 0 if do_rd and read error;
+ * 1 if !do_rd and read error but not write error;
+ * 1 if no error occured.
+ */
+static char
+arc4_writeback(uint8_t *buf, size_t len, char do_rd)
+{
+#ifdef USE_MS_CRYPTOAPI
+	static char has_provider = 0;
+	static HCRYPTPROV p;
+	HKEY hKeyLM, hKeyCU;
+	DWORD ksz;
+	char rc = 6, has_rkey = 0, w32_a4b[16];
+	size_t i, j, xlen;
+	struct timeval tv;
+
+	for (i = 0; i < sizeof(w32_a4b); ++i)
+		w32_a4b[i] = arc4_getbyte();
+	for (i = arc4_getbyte() & 15; i; --i)
+		arc4_getbyte();
+
+	ksz = sizeof(w32_buf);
+	if ((/* read-write */ RegOpenKeyEx(HKEY_LOCAL_MACHINE, w32_subkey,
+	    0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hKeyLM) == ERROR_SUCCESS ||
+	    /* try read-only */ RegOpenKeyEx(HKEY_LOCAL_MACHINE, w32_subkey,
+	    0, KEY_QUERY_VALUE, &hKeyLM) == ERROR_SUCCESS) && /* get value */
+	    (RegQueryValueEx(hKeyLM, "Seed", NULL, NULL, w32_buf, &ksz) ==
+	    ERROR_SUCCESS) && /* got any content? */ ksz) {
+		/* we got HKLM key, read-write or read-only */
+		has_rkey |= 1;
+		/* move content to destination */
+		memset(w32_hklm, '\0', sizeof(w32_hklm));
+		for (i = 0; i < MAX(ksz, sizeof(w32_hklm)); ++i)
+			w32_hklm[i % sizeof(w32_hklm)] ^= w32_buf[i % ksz];
+	}
+	ksz = sizeof(w32_buf);
+	if ((/* read-write */ RegCreateKeyEx(HKEY_CURRENT_USER, w32_subkey,
+	    0, NULL, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKeyCU,
+	    NULL) == ERROR_SUCCESS || /* R/O */ RegOpenKeyEx(HKEY_CURRENT_USER,
+	    w32_subkey, 0, KEY_QUERY_VALUE, &hKeyLM) == ERROR_SUCCESS) &&
+	    /* get value */ (RegQueryValueEx(hKeyLM, "Seed", NULL, NULL,
+	    w32_buf, &ksz) == ERROR_SUCCESS) && /* got any content? */ ksz) {
+		/* we got HKCU key, created, read-write or read-only */
+		has_rkey |= 2;
+		/* move content to destination */
+		memset(w32_hkcu, '\0', sizeof(w32_hkcu));
+		for (i = 0; i < MAX(ksz, sizeof(w32_hkcu)); ++i)
+			w32_hkcu[i % sizeof(w32_hkcu)] ^= w32_buf[i % ksz];
+	}
+
+	if (!do_rd)
+		goto nogen_out;
+
+	if (has_rkey && gettimeofday(&tv, NULL) == 0) {
+		/* we have registry key; rate-limit CryptGenRandom */
+		if (tv.tv_sec - w32_last.tv_sec < 128 + (arc4_getbyte() & 127))
+			goto nogen_out;
+		/* nope, more than 2-4 minutes, call it */
+		w32_last.tv_sec = tv.tv_sec;
+	}
+
+	if (!has_provider) {
+		if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL, 0)) {
+			if ((HRESULT)GetLastError() != NTE_BAD_KEYSET)
+				goto nogen_out;
+			if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL,
+			    CRYPT_NEWKEYSET))
+				goto nogen_out;
+		}
+		has_provider = 1;
+	}
+	i = 0;
+	while (i < 256)
+		w32_buf[i++] = arc4_getbyte();
+	if (!CryptGenRandom(p, sizeof(w32_buf), w32_buf)) {
+		w32_last.tv_sec = 0;
+ nogen_out:
+		rc |= 1;
+		memset(w32_buf, '\0', 256);
+	}
+	xlen = MIN(sizeof(w32_buf) - sizeof(w32_hklm) - sizeof(w32_hkcu) -
+	    sizeof(w32_a4b), len);
+	j = xlen + sizeof(w32_hklm) + sizeof(w32_hkcu) + sizeof(w32_a4b);
+	for (i = 0; i < MAX(j, len); ++i)
+		w32_buf[i % j] ^= w32_hklm[i % sizeof(w32_hklm)] ^
+		    w32_hkcu[i % sizeof(w32_hkcu)] ^ buf[i % len] ^
+		    arc4_getbyte();
+	if (has_rkey & 1) {
+		if (RegSetValueEx(hKeyLM, "Seed", 0, REG_BINARY,
+		    w32_buf, sizeof(w32_hklm)) == ERROR_SUCCESS)
+			rc &= ~2;
+		RegCloseKey(hKeyLM);
+	}
+	if (has_rkey & 2) {
+		if (RegSetValueEx(hKeyCU, "Seed", 0, REG_BINARY,
+		    w32_buf + sizeof(w32_hklm), sizeof(w32_hkcu)) ==
+		    ERROR_SUCCESS)
+			rc &= ~4;
+		RegCloseKey(hKeyCU);
+	}
+	for (i = 0; i < sizeof(w32_a4b); ++i)
+		w32_a4b[i] ^= w32_buf[sizeof(w32_hklm) + sizeof(w32_hkcu) + i];
+	arc4_addrandom(w32_a4b, sizeof(w32_a4b));
+
+	i = sizeof(w32_hklm) + sizeof(w32_hkcu) + sizeof(w32_a4b);
+	while (len) {
+		j = MIN(len, xlen);
+		memcpy(buf, w32_buf + i, j);
+		buf += j;
+		len -= j;
+	}
+
+	memset(w32_buf, '\0', sizeof(w32_buf));
+
+	return (
+	    /* read error occured */
+	    (!has_rkey && (rc & 1)) ? 0 :
+	    /* don't care about write errors */
+	    !do_rd ? 1 :
+	    /* couldn't write */
+	    (rc & 6) == 6 ? 0 :
+	    /* at least one RegSetValueEx succeeded */
+	    1);
+#elif defined(arc4random_pushk)
+	uint32_t num;
+
+	num = arc4random_pushk(buf, len);
+	memcpy(buf, &num, sizeof(num));
+	return (do_rd ? 0 : 1);
+#else
+	int fd;
+
+	if ((fd = open(__randomdev, O_WRONLY)) != -1) {
+		if (write(fd, buf, len) < 4)
+			do_rd = 1;
+		close(fd);
+	}
+	return (do_rd || fd == -1 ? 0 : 1);
+#endif
+}
+
+#if defined(USE_MS_CRYPTOAPI) || defined(arc4random_pushk)
+uint32_t
+arc4random_pushb(const void *src, size_t len)
+{
+	size_t rlen;
+	union {
+		uint8_t buf[256];
+		struct timeval tv;
+		uint32_t xbuf;
+	} idat;
+	const uint8_t *cbuf = (const uint8_t *)src;
+	uint32_t res = 1;
+
+	if (!rs_initialized) {
+		arc4_init();
+		rs_initialized = 1;
+	}
+
+	gettimeofday(&idat.tv, NULL);
+	for (rlen = 0; rlen < len; ++rlen)
+		idat.buf[rlen % sizeof(idat)] ^= cbuf[rlen];
+	rlen = MIN(sizeof(idat), MAX(sizeof(struct timeval), len));
+
+	if (arc4_writeback(&idat.buf[0], rlen, 1))
+		res = 0;
+	arc4_addrandom(&idat.buf[0], rlen);
+	if (res)
+		res = idat.xbuf;
+	else
+		/* we got entropy from the kernel, so consider us stirred */
+		stir_finish(idat.buf[5]);
+	return (res ^ arc4_getword());
+}
+#endif
+
+static void
+arc4_atexit(void)
+{
+	struct {
+		pid_t spid;
+		int cnt;
+		uint8_t carr[240];
+	} buf;
+	int i = 0;
+
+	while (i < 240)
+		buf.carr[i++] = arc4_getbyte();
+	buf.spid = arc4_stir_pid;
+	buf.cnt = arc4_count;
+
+	arc4_writeback((uint8_t *)&buf, sizeof(buf), 0);
+}

Modified: trunk/freewrt/toolchain/uClibc/patches/patch-libc_stdlib_Makefile
===================================================================
--- trunk/freewrt/toolchain/uClibc/patches/patch-libc_stdlib_Makefile	2009-10-18 \
                20:25:22 UTC (rev 3893)
+++ trunk/freewrt/toolchain/uClibc/patches/patch-libc_stdlib_Makefile	2009-10-19 \
09:53:19 UTC (rev 3894) @@ -1,6 +1,6 @@
 $FreeWRT$
---- uClibc-0.9.28.orig/libc/stdlib/Makefile	2005-08-17 22:49:41.000000000 +0000
-+++ uClibc-0.9.28/libc/stdlib/Makefile	2007-06-15 17:09:35.000000000 +0000
+--- uClibc-0.9.28.orig/libc/stdlib/Makefile	2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28/libc/stdlib/Makefile	2009-10-19 11:48:46.000000000 +0200
 @@ -86,7 +86,7 @@ CSRC =	abort.c getenv.c mkdtemp.c mktemp
  	getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c drand48-iter.c jrand48.c \
  	jrand48_r.c lrand48.c lrand48_r.c mrand48.c mrand48_r.c nrand48.c \
@@ -10,3 +10,14 @@
  ifeq ($(UCLIBC_HAS_FLOATS),y)
  	CSRC += drand48.c drand48_r.c erand48.c erand48_r.c
  endif
+@@ -125,6 +125,10 @@ $(COBJS): %.o : %.c
+ 	$(CC) $(CFLAGS) -c $< -o $@
+ 	$(STRIPTOOL) -x -R .note -R .comment $*.o
+ 
++arc4random.o: arc4random.c
++	$(CC) $(CFLAGS) -DHAVE_STDINT_H -c $< -o $@
++	$(STRIPTOOL) -x -R .note -R .comment $*.o
++
+ $(OBJ): Makefile
+ 
+ subdirs: $(patsubst %, _dir_%, $(DIRS))


Property changes on: \
trunk/freewrt/toolchain/uClibc/patches/patch-libc_stdlib_Makefile \
                ___________________________________________________________________
Name: svn:keywords
   + FreeWRT=Id

_______________________________________________
freewrt-commits mailing list
freewrt-commits@freewrt.org
https://www.freewrt.org/lists/listinfo/freewrt-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic