diff -Naur uClibc-20050202.orig/Makefile uClibc-20050202/Makefile --- uClibc-20050202.orig/Makefile 2005-02-06 11:37:22.806955152 +0000 +++ uClibc-20050202/Makefile 2005-02-07 12:20:13.866250800 +0000 @@ -203,6 +203,10 @@ # Remove getopt header since shadow password support is disabled. $(RM) $(PREFIX)$(DEVEL_PREFIX)include/shadow.h endif +ifneq ($(strip $(UCLIBC_HAS_ARC4RANDOM)),y) + # Remove arv4random header since arc4random support is disabled. + $(RM) $(PREFIX)$(DEVEL_PREFIX)include/arc4random.h +endif -@for i in `find $(PREFIX)$(DEVEL_PREFIX) -type d` ; do \ chmod 755 $$i; chmod 644 $$i/*.h > /dev/null 2>&1; \ done; diff -Naur uClibc-20050202.orig/extra/Configs/Config.in uClibc-20050202/extra/Configs/Config.in --- uClibc-20050202.orig/extra/Configs/Config.in 2005-02-06 11:37:22.839917136 +0000 +++ uClibc-20050202/extra/Configs/Config.in 2005-02-07 11:12:18.514358672 +0000 @@ -1109,6 +1109,39 @@ 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 support the OpenBSD-like arc4random() function. + Arc4random is a wrapper. It can use erandom, urandom, and falls back + to gettimeofday(2) for seed a value. Seeds are run threw the arcfour + stream cipher to produce high quality 32-bit pseudo-random numbers. + This function is supposed to be more dependable than invoking + /dev/{e,u}random directly. This function will also dramatically + inflate the seed, outputing a lot of random data while using little + kernel entropy. + OpenSSL and OpenNTPD currently support this function. + Most people will answer N. + +config ARC4RANDOM_USE_ERANDOM + bool "Make arc4random() use erandom first as the seed source" + depends on UCLIBC_SECURITY + depends on UCLIBC_HAS_ARC4RANDOM + default n + help + Answer Y to use sysctl erandom or /dev/erandom (which ever is found + first) as a seed source for arc4random(). If erandom is not found + at runtime then urandom, and gettimeofday will still be used in turn. + Erandom uses no kernel entopy. + WARNING: The erandom device was never intended for cryptography and + is slighly more vulnerable than urandom. Use this at your own + risk. + This requires a modified kernel. + For more info see: http://frandom.sourceforge.net/. + Most people will answer N. + config UCLIBC_HAS_SSP bool "Support for propolice stack protection" depends on UCLIBC_SECURITY diff -Naur uClibc-20050202.orig/include/arc4random.h uClibc-20050202/include/arc4random.h --- uClibc-20050202.orig/include/arc4random.h 1970-01-01 00:00:00.000000000 +0000 +++ uClibc-20050202/include/arc4random.h 2005-02-07 12:16:52.341887160 +0000 @@ -0,0 +1,37 @@ +/* + * Arc4 random number generator for OpenBSD. + * Copyright 1996 David Mazieres . + * + * Modification and redistribution in source and binary forms is + * permitted provided that due credit is given to the author and the + * OpenBSD project (for instance 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. + */ + +/* Slightly modified to work with linux by Thomas Roessler + * . + */ + +#ifndef _ARC4RANDOM_H +#define _ARC4RANDOM_H + +void arc4random_stir (void); +void arc4random_addrandom (u_char *dat, int datlen); +u_int32_t arc4random(void); + +#endif diff -Naur uClibc-20050202.orig/libc/misc/Makefile uClibc-20050202/libc/misc/Makefile --- uClibc-20050202.orig/libc/misc/Makefile 2005-02-06 11:37:23.195507024 +0000 +++ uClibc-20050202/libc/misc/Makefile 2005-02-07 12:14:28.889096560 +0000 @@ -49,6 +49,9 @@ ifeq ($(strip $(UCLIBC_HAS_GLOB)),y) DIRS += glob endif +ifeq ($(strip $(UCLIBC_HAS_ARC4RANDOM)),y) +DIRS += arc4random +endif all: subdirs diff -Naur uClibc-20050202.orig/libc/misc/arc4random/Makefile uClibc-20050202/libc/misc/arc4random/Makefile --- uClibc-20050202.orig/libc/misc/arc4random/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ uClibc-20050202/libc/misc/arc4random/Makefile 2005-02-07 12:09:46.204399952 +0000 @@ -0,0 +1,43 @@ +# Makefile for uClibc +# +# Copyright (C) 2000 by Lineo, inc. +# Copyright (C) 2000,2001 Erik Andersen +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Library General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more +# details. +# +# You should have received a copy of the GNU Library General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Derived in part from the Linux-8086 C library, the GNU C Library, and several +# other sundry sources. Files within this library are copyright by their +# respective copyright holders. + +TOPDIR=../../../ +include $(TOPDIR)Rules.mak + +CSRC=arc4random.c +COBJS=$(patsubst %.c,%.o, $(CSRC)) +OBJS=$(COBJS) + +OBJ_LIST=../../obj.misc.arc4random + +all: $(OBJ_LIST) + +$(OBJ_LIST): $(OBJS) + echo $(patsubst %, misc/arc4random/%, $(OBJS)) > $(OBJ_LIST) + +$(COBJS): %.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + $(STRIPTOOL) -x -R .note -R .comment $*.o + +clean: + $(RM) *.[oa] *~ core diff -Naur uClibc-20050202.orig/libc/misc/arc4random/arc4random.c uClibc-20050202/libc/misc/arc4random/arc4random.c --- uClibc-20050202.orig/libc/misc/arc4random/arc4random.c 1970-01-01 00:00:00.000000000 +0000 +++ uClibc-20050202/libc/misc/arc4random/arc4random.c 2005-02-07 12:23:00.515463272 +0000 @@ -0,0 +1,190 @@ +/* + * Arc4 random number generator for OpenBSD. + * Copyright 1996 David Mazieres . + * + * 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 for uClibc/Linux by Robert Connolly */ + +#include +#include +#include +#include +#include +#include +#ifdef __ARC4RANDOM_USE_ERANDOM__ +#include +#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]; +}; + +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) +{ + size_t len; + struct { + struct timeval tv; + u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; + } rdat; + + gettimeofday(&rdat.tv, NULL); + int i, fd; +#ifdef __ARC4RANDOM_USE_ERANDOM__ + int mib[3]; + mib[0] = CTL_KERN; + mib[1] = KERN_RANDOM; + mib[2] = RANDOM_ERANDOM; + + 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 + if (i < sizeof(rdat.rnd) / 4) { +#ifdef __ARC4RANDOM_USE_ERANDOM__ + if ((fd = open("/dev/erandom", O_RDONLY)) == (-1)) +#endif + fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + read(fd, rdat.rnd, sizeof(rdat.rnd)); + close(fd); + } + } + + arc4_stir_pid = getpid(); + 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 + */ + for (i = 0; i < 256; i++) + (void)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 +#include + +int main(void) { + int random_number; + random_number = arc4random() % 65536; + printf("%d\n", random_number); + return 0; +} +#endif