Author: archaic Date: 2005-10-18 17:43:43 -0600 (Tue, 18 Oct 2005) New Revision: 1204
Added: trunk/glibc/glibc-2.3.5-arc4random-2.patch trunk/openssl/openssl-0.9.7h-arc4random-2.patch trunk/uClibc/uClibc-0.9.28-arc4random-2.patch Log: Added updated arc4random patches for uClibc, openssl, and glibc. Added: trunk/glibc/glibc-2.3.5-arc4random-2.patch =================================================================== --- trunk/glibc/glibc-2.3.5-arc4random-2.patch 2005-10-18 18:05:28 UTC (rev 1203) +++ trunk/glibc/glibc-2.3.5-arc4random-2.patch 2005-10-18 23:43:43 UTC (rev 1204) @@ -0,0 +1,557 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2005-10-18 +Initial Package Version: 2.3.5 +Upstream Status: Not submitted +Origin: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/crypt/arc4random.c +Description: This patch adds the arc4random() and arc4randomII() functions +to Glibc, and hooks so mktemp(3) can use arc4randomII(). + +Also see: +http://www.linuxfromscratch.org/hlfs/ +http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt + +diff -Naur glibc-2.3.5.orig/manual/arc4random.3 glibc-2.3.5/manual/arc4random.3 +--- glibc-2.3.5.orig/manual/arc4random.3 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.5/manual/arc4random.3 2005-10-18 23:27:25.000000000 +0000 +@@ -0,0 +1,74 @@ ++.TH ARC4RANDOM 3 "February 11, 2005" ++.SH NAME ++arc4random - arc4 random number generator ++.SH SYNOPSIS ++.nf ++.B #include <stdlib.h> ++.sp ++.I u_int32_t ++.B arc4random(void); ++.sp ++.I u_int32_t ++.B arc4randomII(void); ++.fi ++.SH DESCRIPTION ++The \fBarc4random()\fP function generates a pseudo-random number using the ++ARC4 cipher key stream generator. ARCFOUR uses 8*8 8 bit S-Boxes, and can ++be in about (2**1700) states. ++ ++The \fBarc4random()\fP function is seeded automatically from /dev/urandom, ++or from sysctl \fBurandom\fP if /dev/urandom is not accessible (chroot), or from ++sysctl random.uuid if sysctl \fBurandom\fP is not accessible. \fBgettimeofday(2)\fP ++is always included when initializing the state of \fBarc4random()\fP, this makes ++it impossible to generate the same random sequence twice. \fBarc4random()\fP ++is intended to be safe to use with encryption software to provide entropy. ++ ++The \fBarc4randomII()\fP function is identical to \fBarc4random()\fP except ++that \fBarc4randomII()\fP is seeded automatically from /dev/erandom, and ++sysctl erandom. \fBarc4randomII()\fP is NOT intended for cryptography, but is ++ideal for \fBmktemp(3)\fP, and other functions with a short lifespan. ++\fBarc4randomII()\fP and erandom do not consume any kernel entropy. ++ ++Sysctl urandom, and erandom require a modified kernel. See: ++http://www.linuxfromscratch.org/hlfs/ ++ ++.SH EXAMPLES ++.TP ++Return a random number between 0 and 100. ++.sp ++arc4random() % 100; ++.TP ++Return any random number. ++.sp ++arc4random(); ++.TP ++.nf ++Sample program; this will display a number between 0 and 65536. ++ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("%d\n", random_number); ++ return 0; ++} ++.fi ++.SH "SEE ALSO" ++.BR random (3), ++.BR gettimeofday (2), ++.BR mktemp (3) ++ ++.SH HISTORY ++An algorithm called RC4 was designed by RSA Data Security, Inc. It was ++considered a trade secret, but not trademarked. Because it was a trade ++secret, it obviously could not be patented. A clone of this was posted ++anonymously to USENET and confirmed to be equivalent by several sources ++who had access to the original cipher. Because of the trade secret situation, ++RSA Data Security, Inc. can do nothing about the release of the ++ARC4 algorithm. Since RC4 used to be a trade secret, the cipher is now ++referred to as ARC4 (Another RC4). ++ ++These functions first appeared in OpenBSD 2.1. ++ +diff -Naur glibc-2.3.5.orig/stdlib/Makefile glibc-2.3.5/stdlib/Makefile +--- glibc-2.3.5.orig/stdlib/Makefile 2005-02-16 11:23:58.000000000 +0000 ++++ glibc-2.3.5/stdlib/Makefile 2005-10-18 23:27:25.000000000 +0000 +@@ -27,7 +27,7 @@ + + routines := \ + atof atoi atol atoll \ +- abort \ ++ abort arc4random arc4randomII \ + bsearch qsort msort \ + getenv putenv setenv secure-getenv \ + exit on_exit atexit cxa_atexit cxa_finalize old_atexit \ +diff -Naur glibc-2.3.5.orig/stdlib/arc4random.c glibc-2.3.5/stdlib/arc4random.c +--- glibc-2.3.5.orig/stdlib/arc4random.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.5/stdlib/arc4random.c 2005-10-18 23:27:25.000000000 +0000 +@@ -0,0 +1,205 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres <[EMAIL PROTECTED]>. ++ * ++ * 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. ++ */ ++ ++#include <fcntl.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/time.h> ++#include <sys/sysctl.h> ++ ++#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]; ++}; ++ ++static int rs_initialized; ++static struct arc4_stream rs; ++static pid_t arc4_stir_pid; ++ ++static inline u_int8_t arc4_getbyte(struct arc4_stream *); ++ ++static inline void ++arc4_init(struct arc4_stream *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->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; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stir(struct arc4_stream *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = open("/dev/urandom", O_RDONLY); ++ if (fd != -1) { ++ read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ close(fd); ++ } ++ ++#if defined(SYSCTL_URANDOM) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_URANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ if (i < sizeof(rdat.rnd) / 4) { ++ /* Sysctl urandom failed? Maybe we're running a vanilla kernel. */ ++ mib[2] = RANDOM_UUID; ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++ } ++#endif ++ ++ arc4_stir_pid = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandom(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * 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. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyte(as); ++} ++ ++static inline u_int8_t ++arc4_getbyte(struct arc4_stream *as) ++{ ++ u_int8_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]); ++} ++ ++static inline u_int32_t ++arc4_getword(struct arc4_stream *as) ++{ ++ 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; ++} ++ ++void ++arc4random_stir(void) ++{ ++ if (!rs_initialized) { ++ arc4_init(&rs); ++ rs_initialized = 1; ++ } ++ arc4_stir(&rs); ++} ++ ++void ++arc4random_addrandom(u_char *dat, int datlen) ++{ ++ if (!rs_initialized) ++ arc4random_stir(); ++ arc4_addrandom(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4random(void) ++{ ++ if (!rs_initialized || arc4_stir_pid != getpid()) ++ arc4random_stir(); ++ return arc4_getword(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur glibc-2.3.5.orig/stdlib/arc4randomII.c glibc-2.3.5/stdlib/arc4randomII.c +--- glibc-2.3.5.orig/stdlib/arc4randomII.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.5/stdlib/arc4randomII.c 2005-10-18 23:27:25.000000000 +0000 +@@ -0,0 +1,196 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres <[EMAIL PROTECTED]>. ++ * ++ * 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 arc4randomII(3) using erandom. ++ */ ++ ++#include <fcntl.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/time.h> ++#include <sys/sysctl.h> ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++struct arc4_streamII { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initializedII; ++static struct arc4_streamII rs; ++static pid_t arc4_stir_pidII; ++ ++static inline u_int8_t arc4_getbyteII(struct arc4_streamII *); ++ ++static inline void ++arc4_initII(struct arc4_streamII *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandomII(struct arc4_streamII *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->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; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stirII(struct arc4_streamII *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = open("/dev/erandom", O_RDONLY); ++ if (fd != -1) { ++ read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ close(fd); ++ } ++ ++#if defined(SYSCTL_ERANDOM) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_ERANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++#endif ++ ++ arc4_stir_pidII = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandomII(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * 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. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyteII(as); ++} ++ ++static inline u_int8_t ++arc4_getbyteII(struct arc4_streamII *as) ++{ ++ u_int8_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]); ++} ++ ++static inline u_int32_t ++arc4_getwordII(struct arc4_streamII *as) ++{ ++ u_int32_t val; ++ val = arc4_getbyteII(as) << 24; ++ val |= arc4_getbyteII(as) << 16; ++ val |= arc4_getbyteII(as) << 8; ++ val |= arc4_getbyteII(as); ++ return val; ++} ++ ++void ++arc4random_stirII(void) ++{ ++ if (!rs_initializedII) { ++ arc4_initII(&rs); ++ rs_initializedII = 1; ++ } ++ arc4_stirII(&rs); ++} ++ ++void ++arc4random_addrandomII(u_char *dat, int datlen) ++{ ++ if (!rs_initializedII) ++ arc4random_stirII(); ++ arc4_addrandomII(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4randomII(void) ++{ ++ if (!rs_initializedII || arc4_stir_pidII != getpid()) ++ arc4random_stirII(); ++ return arc4_getwordII(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4randomII() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur glibc-2.3.5.orig/stdlib/stdlib.h glibc-2.3.5/stdlib/stdlib.h +--- glibc-2.3.5.orig/stdlib/stdlib.h 2004-12-01 19:54:34.000000000 +0000 ++++ glibc-2.3.5/stdlib/stdlib.h 2005-10-18 23:28:10.000000000 +0000 +@@ -572,6 +572,15 @@ + extern int lcong48_r (unsigned short int __param[7], + struct drand48_data *__buffer) + __THROW __nonnull ((1, 2)); ++ ++#define LIBC_HAS_ARC4RANDOM ++u_int32_t arc4random(void); ++void arc4random_stir(void); ++void arc4random_addrandom(unsigned char *, int); ++u_int32_t arc4randomII(void); ++void arc4random_stirII(void); ++void arc4random_addrandomII(unsigned char *, int); ++ + # endif /* Use misc. */ + #endif /* Use SVID or X/Open. */ + +diff -Naur glibc-2.3.5.orig/sysdeps/posix/tempname.c glibc-2.3.5/sysdeps/posix/tempname.c +--- glibc-2.3.5.orig/sysdeps/posix/tempname.c 2001-11-27 03:35:06.000000000 +0000 ++++ glibc-2.3.5/sysdeps/posix/tempname.c 2005-10-18 23:27:25.000000000 +0000 +@@ -258,6 +258,10 @@ + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6]; + ++/* Get real random data. */ ++#if defined(HAVE_ARC4RANDOM) ++ random_time_bits = arc4randomII(); ++#else + /* Get some more or less random data. */ + #ifdef RANDOM_BITS + RANDOM_BITS (random_time_bits); +@@ -272,7 +276,12 @@ + random_time_bits = time (NULL); + # endif + #endif ++#endif ++#if defined(HAVE_ARC4RANDOM) ++ value += random_time_bits ^ arc4randomII(); ++#else + value += random_time_bits ^ __getpid (); ++#endif + + for (count = 0; count < attempts; value += 7777, ++count) + { Added: trunk/openssl/openssl-0.9.7h-arc4random-2.patch =================================================================== --- trunk/openssl/openssl-0.9.7h-arc4random-2.patch 2005-10-18 18:05:28 UTC (rev 1203) +++ trunk/openssl/openssl-0.9.7h-arc4random-2.patch 2005-10-18 23:43:43 UTC (rev 1204) @@ -0,0 +1,24 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2005-10-18 +Initial Package Version: 0.9.7h +Upstream Status: Not submitted +Origin: None +Description: This patch enables the arc4random() function in OpenSSL, when +using the Glibc or uClibc arc4random patch. + +Also see: +http://www.linuxfromscratch.org/hlfs/ +http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt + +diff -Naur openssl-0.9.7h.orig/crypto/rand/rand_unix.c openssl-0.9.7h/crypto/rand/rand_unix.c +--- openssl-0.9.7h.orig/crypto/rand/rand_unix.c 2005-01-14 16:19:47.000000000 +0000 ++++ openssl-0.9.7h/crypto/rand/rand_unix.c 2005-10-18 23:20:08.000000000 +0000 +@@ -125,7 +125,7 @@ + #include <unistd.h> + #include <time.h> + +-#ifdef __OpenBSD__ ++#ifdef __OpenBSD__ || defined(LIBC_HAS_ARC4RANDOM) + int RAND_poll(void) + { + u_int32_t rnd = 0, i; Added: trunk/uClibc/uClibc-0.9.28-arc4random-2.patch =================================================================== --- trunk/uClibc/uClibc-0.9.28-arc4random-2.patch 2005-10-18 18:05:28 UTC (rev 1203) +++ trunk/uClibc/uClibc-0.9.28-arc4random-2.patch 2005-10-18 23:43:43 UTC (rev 1204) @@ -0,0 +1,790 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2005-10-18 +Initial Package Version: 0.9.28 +Upstream Status: Submitted, declined +Origin: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/crypt/arc4random.c +Description: This patch adds the arc4random() and arc4randomII() functions +to uClibc, and hooks so mktemp(3) and SSP can use arc4randomII(). + +Also see: +http://www.linuxfromscratch.org/hlfs/ +http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt + +diff -Naur uClibc-0.9.28.orig/extra/Configs/Config.in uClibc-0.9.28/extra/Configs/Config.in +--- uClibc-0.9.28.orig/extra/Configs/Config.in 2005-08-17 22:49:41.000000000 +0000 ++++ uClibc-0.9.28/extra/Configs/Config.in 2005-10-18 23:22:25.000000000 +0000 +@@ -1138,6 +1138,49 @@ + libraries have to be built with -fPIC or -fpic, and all assembler + functions must be written as position independent code (PIC). + ++config UCLIBC_HAS_ARC4RANDOM ++ bool "Add the arc4random() function to the library" ++ depends on UCLIBC_SECURITY ++ default n ++ help ++ Answer Y to add the OpenBSD-like arc4random() function. arc4random() ++ generates a pseudo-random number using the ARC4 key stream cipher. ++ The arc4random() function is seeded automatically from /dev/urandom ++ and can be in about (2**1700) states. gettimeofday(2) is always ++ included when initializing the state, making it impossible to ++ generate the same random sequence twice. arc4randomII() is identical ++ to arc4random() except that erandom is used as the seed source. ++ arc4random() is safe for an entropy source for cryptography, while ++ arc4randomII() is suited for mktemp, and other functions with a short ++ lifespan. This library is very small (approx. 2KB) and very fast. ++ If you answer Y here, mktemp(3), and propolice stack protection, can ++ use arc4randomII() for their entropy source. ++ OpenSSL and OpenNTPD also support this function. ++ Erandom requires a modified kernel. More informataion is on: ++ http://frandom.sourceforge.net/ ++ and ++ http://www.linuxfromscratch.org/hlfs/ ++ Most people will answer N. ++ ++config MKTEMP_USE_ARC4RANDOM ++ bool "Use arc4randomII() in mktemp(3)" ++ depends on UCLIBC_HAS_ARC4RANDOM ++ default n ++ help ++ Answer Y to use arc4randomII() as mktemp's (tempname.c) entropy source. ++ This will save kernel entropy while making tempfiles unpredictable. ++ Most people will answer N. ++ ++config ARC4RANDOM_USE_SYSCTL ++ bool "Make arc4random() use sysctl if /dev is not accessible" ++ depends on UCLIBC_HAS_ARC4RANDOM ++ default n ++ help ++ Answer Y to use sysctl only if /dev/*random fails (chroot). ++ This requires a modified kernel. ++ For more info see: http://www.linuxfromscratch.org/hlfs/ ++ Most people will answer N. ++ + config UCLIBC_HAS_SSP + bool "Support for propolice smashing stack protector" + depends on UCLIBC_SECURITY +@@ -1152,26 +1195,14 @@ + <http://www.research.ibm.com/trl/projects/security/ssp/> + Most people will answer N. + +-config SSP_QUICK_CANARY +- bool "Use simple guard values without accessing /dev/urandom" +- depends on UCLIBC_HAS_SSP +- default n +- help +- Use gettimeofday(2) to define the __guard without accessing +- /dev/urandom. +- WARNING: This makes smashing stack protector vulnerable to timing +- attacks. +- Most people will answer N. +- +-config SSP_USE_ERANDOM +- bool "Use erandom for setting guard value if /dev/urandom fails" +- depends on UCLIBC_HAS_SSP && !SSP_QUICK_CANARY ++config SSP_USE_ARC4RANDOM ++ bool "Make propolice use arc4randomII()" ++ depends on UCLIBC_HAS_ARC4RANDOM + default n + help +- Use /dev/erandom to define the guard if /dev/urandom fails (chroot). +- This requires a modified kernel. +- More information at: +- <http://frandom.sourceforge.net/> ++ Answer Y to use arc4randomII() as propolice's __guard entropy ++ source. This will save kernel entropy while making __guard's value ++ unpredictable. + Most people will answer N. + + choice +diff -Naur uClibc-0.9.28.orig/include/stdlib.h uClibc-0.9.28/include/stdlib.h +--- uClibc-0.9.28.orig/include/stdlib.h 2005-08-17 22:49:41.000000000 +0000 ++++ uClibc-0.9.28/include/stdlib.h 2005-10-18 23:23:04.000000000 +0000 +@@ -449,7 +449,18 @@ + + extern int lcong48_r (unsigned short int __param[7], + struct drand48_data *__buffer) __THROW; +-# endif /* Use misc. */ ++ ++#if defined(__UCLIBC_HAS_ARC4RANDOM__) ++#define LIBC_HAS_ARC4RANDOM ++u_int32_t arc4random(void); ++void arc4random_stir(void); ++void arc4random_addrandom(unsigned char *, int); ++u_int32_t arc4randomII(void); ++void arc4random_stirII(void); ++void arc4random_addrandomII(unsigned char *, int); ++#endif ++ ++# endif /* Use misc. */ + #endif /* Use SVID or X/Open. */ + + #endif /* don't just need malloc and calloc */ +diff -Naur uClibc-0.9.28.orig/libc/misc/internals/tempname.c uClibc-0.9.28/libc/misc/internals/tempname.c +--- uClibc-0.9.28.orig/libc/misc/internals/tempname.c 2005-08-17 22:49:48.000000000 +0000 ++++ uClibc-0.9.28/libc/misc/internals/tempname.c 2005-10-18 23:22:25.000000000 +0000 +@@ -122,6 +122,7 @@ + static const char letters[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + ++#if !defined(__MKTEMP_USE_ARC4RANDOM__) + static unsigned int fillrand(unsigned char *buf, unsigned int len) + { + int fd; +@@ -136,6 +137,7 @@ + } + return result; + } ++#endif + + static void brain_damaged_fillrand(unsigned char *buf, unsigned int len) + { +@@ -193,10 +195,16 @@ + XXXXXX = &tmpl[len - 6]; + + /* Get some random data. */ ++ #if defined(__MKTEMP_USE_ARC4RANDOM__) ++ for (i = 0 ; i < sizeof(randomness) ; i++) { ++ randomness[i] = (arc4randomII() % 62); ++ } ++ #else + if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) { + /* if random device nodes failed us, lets use the braindamaged ver */ + brain_damaged_fillrand(randomness, sizeof(randomness)); + } ++ #endif + for (i = 0 ; i < sizeof(randomness) ; i++) { + k = ((randomness[i]) % 62); + XXXXXX[i] = letters[k]; +diff -Naur uClibc-0.9.28.orig/libc/stdlib/Makefile uClibc-0.9.28/libc/stdlib/Makefile +--- uClibc-0.9.28.orig/libc/stdlib/Makefile 2005-08-17 22:49:41.000000000 +0000 ++++ uClibc-0.9.28/libc/stdlib/Makefile 2005-10-18 23:22:25.000000000 +0000 +@@ -90,6 +90,10 @@ + ifeq ($(UCLIBC_HAS_FLOATS),y) + CSRC += drand48.c drand48_r.c erand48.c erand48_r.c + endif ++ifeq ($(UCLIBC_HAS_ARC4RANDOM),y) ++ CSRC += arc4random.c arc4randomII.c ++endif ++ + COBJS=$(patsubst %.c,%.o, $(CSRC)) + + OBJS=$(MOBJ) $(MOBJx) $(MOBJ1) $(MOBJ1x) $(MOBJ2) $(COBJS) +diff -Naur uClibc-0.9.28.orig/libc/stdlib/arc4random.c uClibc-0.9.28/libc/stdlib/arc4random.c +--- uClibc-0.9.28.orig/libc/stdlib/arc4random.c 1970-01-01 00:00:00.000000000 +0000 ++++ uClibc-0.9.28/libc/stdlib/arc4random.c 2005-10-18 23:22:25.000000000 +0000 +@@ -0,0 +1,217 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres <[EMAIL PROTECTED]>. ++ * ++ * 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. ++ */ ++ ++#include <fcntl.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/time.h> ++#if defined(__ARC4RANDOM_USE_SYSCTL__) ++#include <sys/sysctl.h> ++#endif ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++#ifdef __UCLIBC__ ++extern int __libc_open(__const char *file, int flags, ...); ++extern ssize_t __libc_read(int fd, void *buf, size_t count); ++extern int __libc_close(int fd); ++#else ++# define __libc_open(file, flags) __open(file, flags) ++# define __libc_read(fd, buf, count) __read(fd, buf, count) ++# define __libc_close(fd) __close(fd) ++#endif ++ ++struct arc4_stream { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initialized; ++static struct arc4_stream rs; ++static pid_t arc4_stir_pid; ++ ++static inline u_int8_t arc4_getbyte(struct arc4_stream *); ++ ++static inline void ++arc4_init(struct arc4_stream *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->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; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stir(struct arc4_stream *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = __libc_open("/dev/urandom", O_RDONLY); ++ if (fd != -1) { ++ __libc_read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ __libc_close(fd); ++ } ++ ++#if defined(__ARC4RANDOM_USE_SYSCTL__) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_URANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ if (i < sizeof(rdat.rnd) / 4) { ++ /* Sysctl urandom failed? Maybe we're running a vanilla kernel. */ ++ mib[2] = RANDOM_UUID; ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++ } ++#endif ++ ++ arc4_stir_pid = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandom(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * 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. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyte(as); ++} ++ ++static inline u_int8_t ++arc4_getbyte(struct arc4_stream *as) ++{ ++ u_int8_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]); ++} ++ ++static inline u_int32_t ++arc4_getword(struct arc4_stream *as) ++{ ++ 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; ++} ++ ++void ++arc4random_stir(void) ++{ ++ if (!rs_initialized) { ++ arc4_init(&rs); ++ rs_initialized = 1; ++ } ++ arc4_stir(&rs); ++} ++ ++void ++arc4random_addrandom(u_char *dat, int datlen) ++{ ++ if (!rs_initialized) ++ arc4random_stir(); ++ arc4_addrandom(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4random(void) ++{ ++ if (!rs_initialized || arc4_stir_pid != getpid()) ++ arc4random_stir(); ++ return arc4_getword(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur uClibc-0.9.28.orig/libc/stdlib/arc4randomII.c uClibc-0.9.28/libc/stdlib/arc4randomII.c +--- uClibc-0.9.28.orig/libc/stdlib/arc4randomII.c 1970-01-01 00:00:00.000000000 +0000 ++++ uClibc-0.9.28/libc/stdlib/arc4randomII.c 2005-10-18 23:22:25.000000000 +0000 +@@ -0,0 +1,208 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres <[EMAIL PROTECTED]>. ++ * ++ * 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 arc4randomII(3) using erandom. ++ */ ++ ++#include <fcntl.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/time.h> ++#if defined(__ARC4RANDOM_USE_SYSCTL__) ++#include <sys/sysctl.h> ++#endif ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++#ifdef __UCLIBC__ ++extern int __libc_open(__const char *file, int flags, ...); ++extern ssize_t __libc_read(int fd, void *buf, size_t count); ++extern int __libc_close(int fd); ++#else ++# define __libc_open(file, flags) __open(file, flags) ++# define __libc_read(fd, buf, count) __read(fd, buf, count) ++# define __libc_close(fd) __close(fd) ++#endif ++ ++struct arc4_streamII { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initializedII; ++static struct arc4_streamII rs; ++static pid_t arc4_stir_pidII; ++ ++static inline u_int8_t arc4_getbyteII(struct arc4_streamII *); ++ ++static inline void ++arc4_initII(struct arc4_streamII *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandomII(struct arc4_streamII *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->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; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stirII(struct arc4_streamII *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = __libc_open("/dev/erandom", O_RDONLY); ++ if (fd != -1) { ++ __libc_read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ __libc_close(fd); ++ } ++ ++#if defined(__ARC4RANDOM_USE_SYSCTL__) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_ERANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++#endif ++ ++ arc4_stir_pidII = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandomII(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * 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. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyteII(as); ++} ++ ++static inline u_int8_t ++arc4_getbyteII(struct arc4_streamII *as) ++{ ++ u_int8_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]); ++} ++ ++static inline u_int32_t ++arc4_getwordII(struct arc4_streamII *as) ++{ ++ u_int32_t val; ++ val = arc4_getbyteII(as) << 24; ++ val |= arc4_getbyteII(as) << 16; ++ val |= arc4_getbyteII(as) << 8; ++ val |= arc4_getbyteII(as); ++ return val; ++} ++ ++void ++arc4random_stirII(void) ++{ ++ if (!rs_initializedII) { ++ arc4_initII(&rs); ++ rs_initializedII = 1; ++ } ++ arc4_stirII(&rs); ++} ++ ++void ++arc4random_addrandomII(u_char *dat, int datlen) ++{ ++ if (!rs_initializedII) ++ arc4random_stirII(); ++ arc4_addrandomII(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4randomII(void) ++{ ++ if (!rs_initializedII || arc4_stir_pidII != getpid()) ++ arc4random_stirII(); ++ return arc4_getwordII(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4randomII() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur uClibc-0.9.28.orig/libc/stdlib/man/arc4random.3 uClibc-0.9.28/libc/stdlib/man/arc4random.3 +--- uClibc-0.9.28.orig/libc/stdlib/man/arc4random.3 1970-01-01 00:00:00.000000000 +0000 ++++ uClibc-0.9.28/libc/stdlib/man/arc4random.3 2005-10-18 23:22:25.000000000 +0000 +@@ -0,0 +1,74 @@ ++.TH ARC4RANDOM 3 "February 11, 2005" ++.SH NAME ++arc4random - arc4 random number generator ++.SH SYNOPSIS ++.nf ++.B #include <stdlib.h> ++.sp ++.I u_int32_t ++.B arc4random(void); ++.sp ++.I u_int32_t ++.B arc4randomII(void); ++.fi ++.SH DESCRIPTION ++The \fBarc4random()\fP function generates a pseudo-random number using the ++ARC4 cipher key stream generator. ARCFOUR uses 8*8 8 bit S-Boxes, and can ++be in about (2**1700) states. ++ ++The \fBarc4random()\fP function is seeded automatically from /dev/urandom, ++or from sysctl \fBurandom\fP if /dev/urandom is not accessible (chroot), or from ++sysctl random.uuid if sysctl \fBurandom\fP is not accessible. \fBgettimeofday(2)\fP ++is always included when initializing the state of \fBarc4random()\fP, this makes ++it impossible to generate the same random sequence twice. \fBarc4random()\fP ++is intended to be safe to use with encryption software to provide entropy. ++ ++The \fBarc4randomII()\fP function is identical to \fBarc4random()\fP except ++that \fBarc4randomII()\fP is seeded automatically from /dev/erandom, and ++sysctl erandom. \fBarc4randomII()\fP is NOT intended for cryptography, but is ++ideal for \fBmktemp(3)\fP, and other functions with a short lifespan. ++\fBarc4randomII()\fP and erandom do not consume any kernel entropy. ++ ++Sysctl urandom, and erandom require a modified kernel. See: ++http://www.linuxfromscratch.org/hlfs/ ++ ++.SH EXAMPLES ++.TP ++Return a random number between 0 and 100. ++.sp ++arc4random() % 100; ++.TP ++Return any random number. ++.sp ++arc4random(); ++.TP ++.nf ++Sample program; this will display a number between 0 and 65536. ++ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("%d\n", random_number); ++ return 0; ++} ++.fi ++.SH "SEE ALSO" ++.BR random (3), ++.BR gettimeofday (2), ++.BR mktemp (3) ++ ++.SH HISTORY ++An algorithm called RC4 was designed by RSA Data Security, Inc. It was ++considered a trade secret, but not trademarked. Because it was a trade ++secret, it obviously could not be patented. A clone of this was posted ++anonymously to USENET and confirmed to be equivalent by several sources ++who had access to the original cipher. Because of the trade secret situation, ++RSA Data Security, Inc. can do nothing about the release of the ++ARC4 algorithm. Since RC4 used to be a trade secret, the cipher is now ++referred to as ARC4 (Another RC4). ++ ++These functions first appeared in OpenBSD 2.1. ++ +diff -Naur uClibc-0.9.28.orig/libc/sysdeps/linux/common/ssp.c uClibc-0.9.28/libc/sysdeps/linux/common/ssp.c +--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/ssp.c 2005-08-17 22:49:42.000000000 +0000 ++++ uClibc-0.9.28/libc/sysdeps/linux/common/ssp.c 2005-10-18 23:22:25.000000000 +0000 +@@ -16,16 +16,15 @@ + * + */ + +-#ifdef HAVE_CONFIG_H +-# include <config.h> +-#endif +- + #ifdef __SSP__ + # error ssp.c has to be built w/ -fno-stack-protector + #endif + + #include <stdio.h> + #include <string.h> ++#if defined(__SSP_USE_ARC4RANDOM__) ++#include <stdlib.h> /* For arc4random() */ ++#endif + #include <fcntl.h> + #include <unistd.h> + #include <signal.h> +@@ -33,9 +32,6 @@ + #include <sys/un.h> + #include <sys/syslog.h> + #include <sys/time.h> +-#ifdef __SSP_USE_ERANDOM__ +-# include <sys/sysctl.h> +-#endif + + #ifdef __PROPOLICE_BLOCK_SEGV__ + # define SSP_SIGTYPE SIGSEGV +@@ -65,7 +61,9 @@ + void __guard_setup(void) __attribute__ ((constructor)); + void __guard_setup(void) + { +- size_t size; ++ int i=0; ++ size_t size; ++ struct timeval tv; + + if (__guard != 0UL) + return; +@@ -73,48 +71,26 @@ + /* Start with the "terminator canary". */ + __guard = 0xFF0A0D00UL; + +-#ifndef __SSP_QUICK_CANARY__ +-# ifdef __SSP_USE_ERANDOM__ +- { +- int mib[3]; +- /* Random is another depth in Linux, hence an array of 3. */ +- mib[0] = CTL_KERN; +- mib[1] = KERN_RANDOM; +- mib[2] = RANDOM_ERANDOM; ++ /* Then with the time. */ ++ gettimeofday(&tv, NULL); ++ __guard ^= tv.tv_usec ^ tv.tv_sec; + ++#if defined(__SSP_USE_ARC4RANDOM__) ++ for (i = 0; i < sizeof(__guard) / 4; i ++) { + size = sizeof(unsigned long); +- if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1)) +- if (__guard != 0UL) +- return; ++ if ((__guard = (int)(arc4randomII())) == (-1)) ++ break; + } +-# endif /* ifdef __SSP_USE_ERANDOM__ */ +- /* +- * Attempt to open kernel pseudo random device if one exists before +- * opening urandom to avoid system entropy depletion. +- */ +- { +- int fd; +- +-# ifdef __SSP_USE_ERANDOM__ +- if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1)) +-# endif +- fd = __libc_open("/dev/urandom", O_RDONLY); ++#else ++ int fd=0; ++ if (i < sizeof(__guard) / 4) { ++ fd = __libc_open("/dev/urandom", O_RDONLY); + if (fd != (-1)) { + size = __libc_read(fd, (char *) &__guard, sizeof(__guard)); +- __libc_close(fd); +- if (size == sizeof(__guard)) +- return; +- } +- } +-#endif /* ifndef __SSP_QUICK_CANARY__ */ +- +- /* Everything failed? Or we are using a weakened model of the +- * terminator canary */ +- { +- struct timeval tv; +- gettimeofday(&tv, NULL); +- __guard ^= tv.tv_usec ^ tv.tv_sec; +- } ++ __libc_close(fd); ++ if (size == sizeof(__guard)) ++ return; ++#endif + } + + void __stack_smash_handler(char func[], int damaged __attribute__ ((unused))); -- http://linuxfromscratch.org/mailman/listinfo/patches FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page
