Blob Blame History Raw
diff -rupN haveged-1.2/AUTHORS haveged-1.3_jh_unsigned_and_ror/AUTHORS
--- haveged-1.2/AUTHORS	2009-04-28 15:27:49.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/AUTHORS	2011-09-25 22:58:42.000000000 +0200
@@ -4,3 +4,5 @@ Contact Information:
 Gary Wuertz (gary_at_issiweb_com)
 http://www.issihosts.com/haveged
 
+Jirka Hladky (hladky_dot_jiri_at_gmail_com)
+
diff -rupN haveged-1.2/ent/test.sh haveged-1.3_jh_unsigned_and_ror/ent/test.sh
--- haveged-1.2/ent/test.sh	2011-01-11 20:38:41.000000000 +0100
+++ haveged-1.3_jh_unsigned_and_ror/ent/test.sh	2011-09-25 22:58:42.000000000 +0200
@@ -1,5 +1,5 @@
 #!/bin/sh
 cd ent
 ./entest -t
-../src/haveged -r 16384 -v 1 $*
+../src/haveged -r 16m -v 1 $*
 ./entest -vf sample
diff -rupN haveged-1.2/init.d/haveged_fedora haveged-1.3_jh_unsigned_and_ror/init.d/haveged_fedora
--- haveged-1.2/init.d/haveged_fedora	1970-01-01 01:00:00.000000000 +0100
+++ haveged-1.3_jh_unsigned_and_ror/init.d/haveged_fedora	2011-09-25 22:58:42.000000000 +0200
@@ -0,0 +1,73 @@
+#!/bin/sh
+#
+# Copyright 2011 Jirka Hladky hladky_dot_jiri_at_gmail_com
+# Copyright 2009-2011 Gary Wuertz gary@issiweb.com
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#
+# haveged: Starts the haveged entropy daemon
+#
+# chkconfig: - 75 25
+# description: havege entropy daemon
+# processname: haveged
+#
+# source function library
+. /etc/init.d/functions
+
+RETVAL=0
+prog="haveged"
+LOCKFILE=/var/lock/subsys/$prog
+
+HAVEGED_BIN=/usr/sbin/haveged
+test -x ${HAVEGED_BIN} || { echo "Cannot find haveged executable at /usr/sbin" 1>&2 ; exit 5 ; }
+
+case "$1" in
+start)
+  echo -n $"Starting $prog: "
+  ${HAVEGED_BIN} -w 1024 -v 1 && success || failure
+  RETVAL=$?
+  [ "$RETVAL" = 0 ] && touch ${LOCKFILE}
+  echo
+  ;;
+
+stop)
+  echo -n $"Stopping $prog: "
+  if [ -e /var/run/$prog.pid ]; then
+    kill `cat /var/run/$prog.pid` && success || failure
+  else
+    failure
+  fi
+  RETVAL=$?
+  [ "$RETVAL" = 0 ] && rm -f ${LOCKFILE}
+  echo
+  ;;
+
+restart|reload)
+  $0 stop
+  $0 start
+  ;;
+
+condrestart)
+  [ -f $LOCKFILE ] && $0 restart
+  ;;
+
+status)
+  status $prog
+  RETVAL=$?
+  ;;
+*)
+  echo $"Usage: $prog {start|stop|status|reload|restart|condrestart}"
+esac
+exit $RETVAL
diff -rupN haveged-1.2/man/haveged.8 haveged-1.3_jh_unsigned_and_ror/man/haveged.8
--- haveged-1.2/man/haveged.8	2009-09-02 18:55:16.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/man/haveged.8	2011-09-30 01:48:55.346081086 +0200
@@ -1,3 +1,7 @@
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
 .TH haveged 8  "August 28, 2009" "version 0.9" "SYSTEM ADMINISTRATION COMMANDS"
 .SH NAME
 haveged \- Feed kernel random device
@@ -39,13 +43,23 @@ installation before the daemon is put in
 Set data cache size to nnn KB. Default is 16 or as determined by cpuid.
 .TP
 -f file, --file=file
-Set sample output file path - default is "sample"
+Set sample output file path, default is "sample". '-' will write to stdout. Please set -r to be bigger than 1 to write to a file.
 .TP
 -i nnn, --inst=nnn
 Set instruction cache size to nnn KB. Default is 16 or as determined by cpuid.
 .TP
 -r n, --run=n
-Set run level 0=daemon,1=config info,>1=Write <r>KB sample file
+Set run level:
+.Sp
+ 0  daemon. Needs to be as run as root. Will fill /dev/random whenever the supply of random bits in /dev/random falls below
+the low water mark of the device.
+.Sp
+-1 config info
+.Sp
+-2 write endless stream of random data to stdout. It implies -f -.
+.Sp
+>1 write stream of n bytes to output file. Units k,m,g,t (lowercase and uppercase) are supported. Floating numbers like 1.5G are supported, too. 
+See also -f option. If -f is not specified then the data are written to the file named "sample". 
 .TP
 -v n, --verbose=n
 Set output level 0=minimal,1=config/fill items
@@ -112,7 +126,37 @@ Select error
 .RS
 Call to select(2) failed.
 
+.SH EXAMPLES
+.TP
+Write 1.5MB of random data to the file /tmp/random
+haveged -r 1.5M -f /tmp/random
+.TP
+Generate a /tmp/keyfile for disk encryption with LUKS
+haveged -r 2048 -f /tmp/keyfile
+.TP
+Ovewrite partition /dev/sda1 with random data. Be carefull, all data on the partition will be lost!
+haveged -r -2 | dd of=/dev/sda1
+.TP
+Generate random ASCII passworts of the length 16 characters
+(haveged -r 1000 -f - 2>/dev/null | tr -cd '[:graph:]' | fold -w 16 && echo ) | head
+.TP
+Write endless stream of random bytes to the pipe. Utility pv measures the speed by which data are written to the pipe.
+haveged -r -2 | pv > /dev/null
+.TP
+Evaluate speed of haveged to generate 1GB of random data
+haveged -r 1g -f - | dd of=/dev/null
+.TP
+Create a random key file contaning 65 random keys for the encryption program aespipe.
+haveged -r 3705 -f - 2>/dev/null | uuencode -m - | head -n 66 | tail -n 65
+.TP
+Test the randomness of the generated data with dieharder test suite
+haveged -r -2 | dieharder -g 200 -a
+
+.SH SEE ALSO
+.TP
+cryptsetup(8), aespipe(1), pv(1), openssl(1), uuencode(1)
+
 .SH AUTHOR
-Gary Wuertz <gary@issiweb.com>
+Gary Wuertz <gary@issiweb.com> and Jirka Hladky.
 .SH SEE ALSO
 http://www.issihosts/haveged/
diff -rupN haveged-1.2/src/havege.c haveged-1.3_jh_unsigned_and_ror/src/havege.c
--- haveged-1.2/src/havege.c	2011-06-26 21:49:31.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/src/havege.c	2011-09-25 00:48:00.000000000 +0200
@@ -242,7 +242,7 @@ static int cache_configure(void)
 /**
  * Debug setup code
  */
-void  havege_debug(H_PTR hptr, char **havege_pts, int *pts)
+void  havege_debug(H_PTR hptr, char **havege_pts, unsigned int *pts)
 {
    int i;
 
@@ -321,7 +321,7 @@ void havege_status(char *buf)
 /**
  * Main access point
  */
-int ndrand()
+unsigned int ndrand()
 {
    if (info.havege_ndpt >= NDSIZECOLLECT) {
       MSC_START();
diff -rupN haveged-1.2/src/havegecollect.c haveged-1.3_jh_unsigned_and_ror/src/havegecollect.c
--- haveged-1.2/src/havegecollect.c	2011-06-26 21:41:08.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/src/havegecollect.c	2011-09-25 23:23:01.000000000 +0200
@@ -55,31 +55,39 @@ typedef void volatile * VVAR;
                                  } \
                               }
 /**
+ * Most compilers should translate this into single 32-bit rotate instruction
+ * http://en.wikipedia.org/wiki/Circular_shift
+**/ 
+inline unsigned int ror32(const unsigned int value, const unsigned int shift) {
+		return (value >> shift) | (value << (32 - shift));
+}
+
+/**
  * Significant variables used in the calculation. The data is declared local to this
  * compile unit but referenced by havege_df() to ensure that a clever optimizer does
  * not decide to ignore the volatile because a variable only has local access.
  */
-static volatile int  havege_bigarray [NDSIZECOLLECT + 16384];
-static volatile int  havege_andpt;
-static volatile int  havege_hardtick;
-static volatile int  loop_idx = LOOP_CT+1;
-static volatile int  *havege_pwalk;
+static volatile unsigned int  havege_bigarray [NDSIZECOLLECT + 16384];
+static volatile unsigned int  havege_andpt;
+static volatile unsigned int  havege_hardtick;
+static volatile unsigned int  loop_idx = LOOP_CT+1;
+static volatile unsigned int  *havege_pwalk;
 static volatile char *havege_pts[LOOP_CT+1];
-static volatile int  *Pt0;
-static volatile int  *Pt1;
-static volatile int  *Pt2;
-static volatile int  *Pt3;
-static volatile int   PT;
-static volatile int   PT2;
-static volatile int   pt2;
-static volatile int   PTtest;
+static volatile unsigned int  *Pt0;
+static volatile unsigned int  *Pt1;
+static volatile unsigned int  *Pt2;
+static volatile unsigned int  *Pt3;
+static volatile unsigned int   PT;
+static volatile unsigned int   PT2;
+static volatile unsigned int   pt2;
+static volatile unsigned int   PTtest;
 /**
  * Local prototypes
  */
 // int havege_collect(volatile H_PTR hptr) __attribute__((optimize(1)));
 
-static int           havege_sp(int i, int n, char *p);
-static volatile int *havege_tune(H_PTR h);
+static unsigned int           havege_sp(unsigned int i, unsigned int n, char *p);
+static volatile unsigned int *havege_tune(H_PTR h);
 /**
  * The collection loop is constructed by repetitions of oneinteration.h with the
  * number of repetitions tailored to the size of the instruction cache. The use
@@ -87,10 +95,10 @@ static volatile int *havege_tune(H_PTR h
  * operations for an iteration but DOES NOT prevent compiler optimization of a
  * sequence of interations.
  */
-int havege_collect(volatile H_PTR hptr)
+unsigned int havege_collect(volatile H_PTR hptr)
 {
-   volatile int * RESULT = havege_bigarray;
-   int i=0,pt=0,inter=0;
+   volatile unsigned int * RESULT = havege_bigarray;
+   unsigned int i=0,pt=0,inter=0;
 
 LOOP(40,39)
    #include "oneiteration.h"
@@ -210,11 +218,11 @@ VVAR *havege_df()
  * sequence. This happens for all points on the collection pass and only for
  * the terminating point thereafter.
  */
-static int havege_sp(int i, int n,char *p)
+static unsigned int havege_sp(unsigned int i, unsigned int n,char *p)
 {
    if (loop_idx < LOOP_CT)
       return i < NDSIZECOLLECT? 1 : 2;
-   havege_pts[(int)n] = CODE_PT(p);
+   havege_pts[(unsigned int)n] = CODE_PT(p);
    if (n==0) loop_idx = 0;
    return 0;
 }
@@ -223,12 +231,12 @@ static int havege_sp(int i, int n,char *
  * based on the instruction cache and allocate the walk array based on the size
  * of the data cache.
  */
-static volatile int *havege_tune(H_PTR hptr)
+static volatile unsigned int *havege_tune(H_PTR hptr)
 {
-   int offsets[LOOP_CT+1];
-   int i,offs,*p,sz;
+   unsigned int offsets[LOOP_CT+1];
+   unsigned int i,offs,*p,sz;
 
-   hptr->havege_buf = (int *)havege_bigarray;
+   hptr->havege_buf = (unsigned int *)havege_bigarray;
    for (i=0;i<=LOOP_CT;i++)
       offsets[i] = abs(havege_pts[i]-havege_pts[LOOP_CT]);
    havege_debug(hptr, (char **)havege_pts, offsets);
@@ -243,7 +251,7 @@ static volatile int *havege_tune(H_PTR h
    hptr->loop_idx = loop_idx = ++i;
    hptr->loop_sz  = offsets[i];
    ANDPT = ((2*hptr->d_cache*1024)/sizeof(int))-1;
-   p    = (int *) malloc((ANDPT + 4097)*sizeof(int));
-   offs = (int)((((long)&p[4096])&0xfff)/sizeof(int));
+   p    = (unsigned int *) malloc((ANDPT + 4097)*sizeof(int));
+   offs = (unsigned int)((((unsigned long)&p[4096])&0xfff)/sizeof(int));
    return &p[4096-offs];
 }
diff -rupN haveged-1.2/src/havegecollect.h haveged-1.3_jh_unsigned_and_ror/src/havegecollect.h
--- haveged-1.2/src/havegecollect.h	2011-06-26 21:46:26.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/src/havegecollect.h	2011-09-25 00:48:00.000000000 +0200
@@ -47,7 +47,7 @@
 /**
  ** The collection mechanism cannot withstand agressive optimization
  */
-int havege_collect(volatile H_PTR hptr) __attribute__((optimize(1)));
+unsigned int havege_collect(volatile H_PTR hptr) __attribute__((optimize(1)));
 /**
  ** For the intel world...
  */
diff -rupN haveged-1.2/src/haveged.c haveged-1.3_jh_unsigned_and_ror/src/haveged.c
--- haveged-1.2/src/haveged.c	2011-06-26 21:48:46.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/src/haveged.c	2011-09-25 00:48:00.000000000 +0200
@@ -26,6 +26,7 @@
 #include <syslog.h>
 #include <signal.h>
 #include <fcntl.h>
+#include <ctype.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -58,7 +59,8 @@ static struct pparams defaults = {
   .sample_size    = 1024,
   .verbose        = 0,
   .version        = "1.1",
-  .watermark      = "/proc/sys/kernel/random/write_wakeup_threshold"
+  .watermark      = "/proc/sys/kernel/random/write_wakeup_threshold",
+  .write_to_stdout= 0
   };
 struct pparams *params = &defaults;
 /**
@@ -67,8 +69,8 @@ struct pparams *params = &defaults;
 void daemonize();
 void error_exit(const char *format, ...);
 void get_info();
-int  get_poolsize(void);
-void run(int poolsize,struct rand_pool_info *output, int *buffer);
+unsigned int  get_poolsize(void);
+void run(unsigned int poolsize,struct rand_pool_info *output, unsigned int *buffer);
 void set_watermark(int level);
 void tidy_exit(int signum);
 /**
@@ -114,15 +116,15 @@ char buf[2048];
 havege_status(buf);
 if (params->detached != 0)
    syslog(LOG_INFO, buf);
-else printf(buf);
+else fprintf(stderr, buf);
 }
 /**
  * Get configured poolsize in bits.
  */
-int get_poolsize(void)
+unsigned int get_poolsize(void)
 {
    FILE *poolsize_fh,*osrel_fh;
-   int max_bits,major,minor;
+   unsigned int max_bits,major,minor;
 
    if (params->run_level==0) {
       poolsize_fh = fopen(params->poolsize, "rb");
@@ -151,9 +153,9 @@ int main(int argc, char **argv)
    static const char* cmds[] = {
       "d", "data",      "1", "Data cache size [KB]",
       "i", "inst",      "1", "Instruction cache size [KB]",
-      "f", "file",      "1", "Sample output file - default: 'sample'",
+      "f", "file",      "1", "Sample output file. Default filename: 'sample'. '-' will write to stdout. Please set -r to be bigger than 1.",
       "F", "Foreground","1", "0=background daemon,!=0 remain attached",
-      "r", "run",       "1", "0=daemon,1=config info,>1=Write <r>KB sample file",
+      "r", "run",       "1", "0=daemon,-1=config info, -2=write Bytes to stdout without limit, implies '-f -', \n\t\t\t >0 write <r> Bytes to file. Units k,m,g,t are supported.",
       "v", "verbose",   "1", "Output level 0=minimal,1=config/fill info",
       "w", "write",     "1", "Set write_wakeup_threshold [BITS]",
       "h", "help",      "0", "This help"
@@ -162,6 +164,9 @@ int main(int argc, char **argv)
    struct option long_options[nopts];
    char short_options[1+nopts*2];
    int c,i,j,poolsize;
+   char suffix;
+   long int dummy;
+
 
    signal(SIGHUP, tidy_exit);
    signal(SIGINT, tidy_exit);
@@ -188,11 +193,48 @@ int main(int argc, char **argv)
             params->i_cache = atoi(optarg);
             break;
          case 'f':
-            params->sample_out = optarg;
+	    if (strcmp(optarg,"-") == 0 ) {
+	      params->write_to_stdout = 1;
+	    } else {
+	      params->sample_out = optarg;
+	    }
+            break;
          case 'r':
-            params->run_level  = atoi(optarg);
-            if (params->run_level>1)
-               params->sample_size = params->run_level;
+	    //check for suffix k (1024), m (1024*1024) and g (1024*1024*1024)
+	    suffix = tolower(optarg[strlen(optarg)-1]);
+
+	    switch(suffix) {
+	      case 'k':
+		optarg[strlen(optarg)-1]=0;
+		params->run_level  = 1;
+		params->sample_size  = ceil(1024.0 * atof(optarg));
+		break;
+	      case 'm':
+		optarg[strlen(optarg)-1]=0;
+		params->run_level  = 1;
+		params->sample_size  = ceil(1024.0 * 1024.0 * atof(optarg));
+		break;
+	      case 'g':
+		optarg[strlen(optarg)-1]=0;
+		params->run_level  = 1;
+		params->sample_size  = ceil(1024.0 * 1024.0 * 1024.0 * atof(optarg));
+		break;
+	      case 't':
+		optarg[strlen(optarg)-1]=0;
+		params->run_level  = 1;
+                params->sample_size  = ceil(1024.0 * 1024.0 * 1024.0 * 1024.0 * atof(optarg));
+		break;
+	      default:
+		dummy  = atol(optarg);
+		if (dummy>0) {
+		  params->sample_size  = dummy;
+		  params-> run_level = 1;
+		} else {
+		  params-> run_level = dummy;
+		}
+	    }
+
+	    
             break;
          case 'v':
             params->verbose  = atoi(optarg);
@@ -215,10 +257,15 @@ int main(int argc, char **argv)
             break;
          }
    } while (c!=-1);
+   
+   if ( params->run_level == -2 && params->write_to_stdout == 0 ) {
+     fprintf(stderr, "run_level -2 has been specified. This run level will write to stdout and will ignore -f option\n");
+   }
+   
    poolsize = get_poolsize();
    if (poolsize>0) {
-      int nbytes = poolsize/8;
-      int  buf[(nbytes+sizeof(int)-1)/sizeof(int)];
+      unsigned int nbytes = poolsize/8;
+      unsigned int  buf[(nbytes+sizeof(int)-1)/sizeof(int)];
       char rb[sizeof(struct rand_pool_info)+nbytes+2];
       run(poolsize,(struct rand_pool_info *)rb,buf);
       }
@@ -228,12 +275,12 @@ int main(int argc, char **argv)
 /**
  * The meat
  */
-void run(int poolsize, struct rand_pool_info *output, int *buffer)
+void run(unsigned int poolsize, struct rand_pool_info *output, unsigned int *buffer)
 {
    FILE *fout = NULL;
    H_RDR h    = havege_state();
    int random_fd = -1;
-   int ct=0;int fills=0;
+   double ct=0;int fills=0;
 
    if (!havege_init(params->i_cache,params->d_cache,params->verbose))
       error_exit("Couldn't initialize HAVEGE rng");
@@ -251,24 +298,48 @@ void run(int poolsize, struct rand_pool_
          if (random_fd == -1)
             error_exit("Couldn't open random device: %m");
          break;
-      case 1:
+      case -1:
          get_info();
          return;
+      case -2:
+	 fprintf(stderr, "Writing infinitely many random bytes to stdout\n");
+	 params->write_to_stdout = 1;
+         get_info();
+	 
+	 const unsigned int nbytes = poolsize/8;
+	 const unsigned int r = (nbytes+sizeof(int)-1)/sizeof(int);
+	 fprintf(stderr, "r : %d\n",r);
+	 for(;;) {
+	    unsigned int i;
+            for(i=0;i<r;i++)
+              buffer[i] = ndrand();
+	    if (fwrite (buffer, 1, nbytes, stdout) == 0) {
+               error_exit("Cannot write on stdout: %m");
+            }
+	 }
+         break;
       default:
-         ct = params->sample_size*1024;
-         if (!(fout = fopen (params->sample_out, "wb")))
-            error_exit("Cannot open file <%s> for writing.\n", params->sample_out);
-         fprintf(stderr, "Writing %d byte sample\n",ct);
+         ct = params->sample_size;
+	 if (params->write_to_stdout == 0 ) {
+	   if (!(fout = fopen (params->sample_out, "wb")))
+	     error_exit("Cannot open file <%s> for writing.\n", params->sample_out);
+	   fprintf(stderr, "Writing %.12G bytes to file \"%s\"\n",ct, params->sample_out);
+	 } else {
+	   fprintf(stderr, "Writing %.12G bytes to stdout\n",ct);
+	 }
          get_info();
       }
+      
    for(;;) {
-      int current,i,nbytes,r;
+      unsigned int current,i,nbytes,r;
+
       if (params->run_level==0) {
+	 //Daemon writing to /dev/random
          fd_set write_fd;
          FD_ZERO(&write_fd);
          FD_SET(random_fd, &write_fd);
          for(;;)  {
-            int rc = select(random_fd+1, NULL, &write_fd, NULL, NULL);
+            unsigned int rc = select(random_fd+1, NULL, &write_fd, NULL, NULL);
             if (rc >= 0) break;
             if (errno != EINTR)
                error_exit("Select error: %m");
@@ -278,14 +349,21 @@ void run(int poolsize, struct rand_pool_
          nbytes = (poolsize  - current)/8;
          }
       else {
-         if (ct<=0) {
-            fclose(fout);
+	 //Writing to file or stdout
+         if (ct<=0.0) {
+	    if ( params->write_to_stdout == 0 ) {
+	       fclose(fout);
+	    }
             break;
             }
          nbytes = poolsize/8;
          ct -= nbytes;
-         }
+      }
+      
       if(nbytes<1)   continue;
+      if(ct<0.0)
+	nbytes += ct;
+      // Generate random bytes
       r = (nbytes+sizeof(int)-1)/sizeof(int);
       for(i=0;i<r;i++)
          buffer[i] = ndrand();
@@ -297,9 +375,15 @@ void run(int poolsize, struct rand_pool_
             error_exit("RNDADDENTROPY failed!");
          }
       else {
-         if (fwrite (output->buf, 1, output->buf_size, fout) == 0)
-            error_exit("Cannot write data in file: %m");
-         }
+	 if ( params->write_to_stdout == 1 ) {
+            if (fwrite (output->buf, 1, output->buf_size, stdout) == 0)
+               error_exit("Cannot write on stdout: %m");
+             }
+         else {
+            if (fwrite (output->buf, 1, output->buf_size, fout) == 0)
+               error_exit("Cannot write data in file: %m");
+            }
+      }
       if ((params->verbose & VERBOSE)!=0 && fills != h->havege_fills) {
          fills = h->havege_fills;
          if (params->detached!=0)
diff -rupN haveged-1.2/src/haveged.h haveged-1.3_jh_unsigned_and_ror/src/haveged.h
--- haveged-1.2/src/haveged.h	2011-01-11 20:23:27.000000000 +0100
+++ haveged-1.3_jh_unsigned_and_ror/src/haveged.h	2011-09-25 22:58:42.000000000 +0200
@@ -23,7 +23,7 @@ struct pparams  {
   char  *daemon;          /* Daemon name - default is "haveged"       */
   int   detached;         /* non-zero of daemonized                   */
   int   foreground;       /* non-zero if running in foreground        */
-  int   run_level;        /* type of run 0=daemon,1=setup,sample kb   */
+  long int  run_level;    /* type of run -2=endless stdout,-1=setup,0=daemon,number of bytes     */
   int   d_cache;          /* size of data cache (kb)                  */
   int   i_cache;          /* size of instruction cache (kb)           */
   int   low_water;        /* write threshold to set - 0 for none      */
@@ -32,8 +32,9 @@ struct pparams  {
   char  *poolsize;        /* path to poolsize                         */
   char  *random_device;   /* path to random device                    */
   char  *sample_out;      /* path to sample file                      */
-  int   sample_size;      /* size of sample (kb)                      */
+  double sample_size;     /* size of sample (Bytes)                   */
   int   verbose;          /* Output level for log or stdout           */
   char  *version;         /* Our version                              */
   char  *watermark;       /* path to write_wakeup_threshold           */
+  int   write_to_stdout;  /* write random bytes directly to stdout    */   
   };
diff -rupN haveged-1.2/src/havege.h haveged-1.3_jh_unsigned_and_ror/src/havege.h
--- haveged-1.2/src/havege.h	2011-01-11 20:39:39.000000000 +0100
+++ haveged-1.3_jh_unsigned_and_ror/src/havege.h	2011-09-25 00:48:00.000000000 +0200
@@ -46,24 +46,24 @@ struct hinfo {
    int   generic;                // idication for generic fallback
    int   i_cache;                // size of instruction cache in kb
    int   d_cache;                // size of data cache in kb
-   int   loop_idx;               // loop index (1-max)
-   int   loop_idxmax;            // max index for collection loop
-   int   loop_sz;                // size of collection loop (bytes)
-   int   loop_szmax;             // max size of collection loop (bytes)
-   int   etime;                  // number of microseconds required by last collection
-   int   havege_fills;           // number of times buffer has been filled
-   int   havege_ndpt;            // get pointer
-   int   havege_opts;            // option flags
-   int   *havege_buf;            // the collection buffer
+   unsigned int   loop_idx;               // loop index (1-max)
+   unsigned int   loop_idxmax;            // max index for collection loop
+   unsigned int   loop_sz;                // size of collection loop (bytes)
+   unsigned int   loop_szmax;             // max size of collection loop (bytes)
+   unsigned int   etime;                  // number of microseconds required by last collection
+   unsigned int   havege_fills;           // number of times buffer has been filled
+   unsigned int   havege_ndpt;            // get pointer
+   unsigned int   havege_opts;            // option flags
+   unsigned int   *havege_buf;            // the collection buffer
 };
 typedef struct hinfo *H_PTR;
 typedef const struct hinfo *H_RDR;
 /**
  * Public prototypes
  */
-void           havege_debug(H_PTR hptr, char ** cpts, int * pts);
+void           havege_debug(H_PTR hptr, char ** cpts, unsigned int * pts);
 int            havege_init(int icache, int dcache, int flags);
 H_RDR          havege_state(void);
 void           havege_status(char *buf);
-int            ndrand();
+unsigned int            ndrand();
 #endif
diff -rupN haveged-1.2/src/Makefile.am haveged-1.3_jh_unsigned_and_ror/src/Makefile.am
--- haveged-1.2/src/Makefile.am	2011-06-26 22:31:37.000000000 +0200
+++ haveged-1.3_jh_unsigned_and_ror/src/Makefile.am	2011-09-25 22:58:42.000000000 +0200
@@ -2,6 +2,8 @@ sbin_PROGRAMS = haveged
 
 AM_CFLAGS=-Wall
 AM_CPPFLAGS = @HA_CPPFLAGS@
+ 
+haveged_LDADD = -lm
 
 haveged_SOURCES = haveged.c havege.c havegecollect.c cpuid-43.h haveged.h havege.h havegecollect.h oneiteration.h
 
diff -rupN haveged-1.2/src/oneiteration.h haveged-1.3_jh_unsigned_and_ror/src/oneiteration.h
--- haveged-1.2/src/oneiteration.h	2011-01-11 20:23:27.000000000 +0100
+++ haveged-1.3_jh_unsigned_and_ror/src/oneiteration.h	2011-09-25 01:30:27.000000000 +0200
@@ -92,11 +92,15 @@
   RESULT[i++] ^= *Pt2;
   RESULT[i++] ^= *Pt3;
 
-  inter = (*Pt0 >> (1)) ^ (*Pt0 << (31)) ^ havege_hardtick;
-  *Pt0  = (*Pt1 >> (2)) ^ (*Pt1 << (30)) ^ havege_hardtick;
+  //inter = (*Pt0 >> (1)) ^ (*Pt0 << (31)) ^ havege_hardtick;
+  inter = ror32(*Pt0,1) ^ havege_hardtick;
+  //*Pt0  = (*Pt1 >> (2)) ^ (*Pt1 << (30)) ^ havege_hardtick;
+  *Pt0  = ror32(*Pt1,2) ^ havege_hardtick;
   *Pt1  = inter;
-  *Pt2  = (*Pt2 >> (3)) ^ (*Pt2 << (29)) ^ havege_hardtick;
-  *Pt3  = (*Pt3 >> (4)) ^ (*Pt3 << (28)) ^ havege_hardtick;
+  //*Pt2  = (*Pt2 >> (3)) ^ (*Pt2 << (29)) ^ havege_hardtick;
+  *Pt2  = ror32(*Pt2, 3) ^ havege_hardtick;
+  //*Pt3  = (*Pt3 >> (4)) ^ (*Pt3 << (28)) ^ havege_hardtick;
+  *Pt3  = ror32(*Pt3, 4) ^ havege_hardtick;
 
   Pt0 = &havege_pwalk[PT  ^ 2];
   Pt1 = &havege_pwalk[PT2 ^ 2];
@@ -109,21 +113,25 @@
   RESULT[i++] ^= *Pt3;
 
   if (PTtest & 1) {
-    volatile int *Ptinter;
+    volatile unsigned int *Ptinter;
     Ptinter = Pt0;
     Pt2 = Pt0;
     Pt0 = Ptinter;
   }
 
   PTtest = (PT2 >> 18);
-  inter  = (*Pt0 >> (5)) ^ (*Pt0 << (27)) ^ havege_hardtick;
-  *Pt0   = (*Pt1 >> (6)) ^ (*Pt1 << (26)) ^ havege_hardtick;
+  //inter  = (*Pt0 >> (5)) ^ (*Pt0 << (27)) ^ havege_hardtick;
+  inter  = ror32(*Pt0, 5) ^ havege_hardtick;
+  //*Pt0   = (*Pt1 >> (6)) ^ (*Pt1 << (26)) ^ havege_hardtick;
+  *Pt0   = ror32(*Pt1, 6) ^ havege_hardtick;
   *Pt1   = inter;
 
   HARDCLOCK(havege_hardtick);
 
-  *Pt2 = (*Pt2 >> (7)) ^ (*Pt2 << (25)) ^ havege_hardtick;
-  *Pt3 = (*Pt3 >> (8)) ^ (*Pt3 << (24)) ^ havege_hardtick;
+  //*Pt2 = (*Pt2 >> (7)) ^ (*Pt2 << (25)) ^ havege_hardtick;
+  *Pt2 = ror32(*Pt2, 7) ^ havege_hardtick;
+  //*Pt3 = (*Pt3 >> (8)) ^ (*Pt3 << (24)) ^ havege_hardtick;
+  *Pt3 = ror32(*Pt3, 8) ^ havege_hardtick;
 
   Pt0 = &havege_pwalk[PT  ^ 4];
   Pt1 = &havege_pwalk[PT2 ^ 1];
@@ -173,11 +181,15 @@
   RESULT[i++] ^= *Pt2;
   RESULT[i++] ^= *Pt3;
 
-  inter = (*Pt0 >> (9))  ^ (*Pt0 << (23)) ^ havege_hardtick;
-  *Pt0  = (*Pt1 >> (10)) ^ (*Pt1 << (22)) ^ havege_hardtick;
+  //inter = (*Pt0 >> (9))  ^ (*Pt0 << (23)) ^ havege_hardtick;
+  inter = ror32(*Pt0 , 9) ^ havege_hardtick;
+  //*Pt0  = (*Pt1 >> (10)) ^ (*Pt1 << (22)) ^ havege_hardtick;
+  *Pt0  = ror32(*Pt1 , 10) ^ havege_hardtick;
   *Pt1  = inter;
-  *Pt2  = (*Pt2 >> (11)) ^ (*Pt2 << (21)) ^ havege_hardtick;
-  *Pt3  = (*Pt3 >> (12)) ^ (*Pt3 << (20)) ^ havege_hardtick;
+  //*Pt2  = (*Pt2 >> (11)) ^ (*Pt2 << (21)) ^ havege_hardtick;
+  *Pt2  = ror32(*Pt2, 11) ^ havege_hardtick;
+  //*Pt3  = (*Pt3 >> (12)) ^ (*Pt3 << (20)) ^ havege_hardtick;
+  *Pt3  = ror32(*Pt3, 12) ^ havege_hardtick;
 
   Pt0 = &havege_pwalk[PT  ^ 6];
   Pt1 = &havege_pwalk[PT2 ^ 3];
@@ -189,11 +201,15 @@
   RESULT[i++] ^= *Pt2;
   RESULT[i++] ^= *Pt3;
 
-  inter = (*Pt0 >> (13)) ^ (*Pt0 << (19)) ^ havege_hardtick;
-  *Pt0  = (*Pt1 >> (14)) ^ (*Pt1 << (18)) ^ havege_hardtick;
+  //inter = (*Pt0 >> (13)) ^ (*Pt0 << (19)) ^ havege_hardtick;
+  inter = ror32(*Pt0, 13) ^ havege_hardtick;
+  //*Pt0  = (*Pt1 >> (14)) ^ (*Pt1 << (18)) ^ havege_hardtick;
+  *Pt0  = ror32(*Pt1, 14) ^ havege_hardtick;
   *Pt1  = inter;
-  *Pt2  = (*Pt2 >> (15)) ^ (*Pt2 << (17)) ^ havege_hardtick;
-  *Pt3  = (*Pt3 >> (16)) ^ (*Pt3 << (16)) ^ havege_hardtick;
+  //*Pt2  = (*Pt2 >> (15)) ^ (*Pt2 << (17)) ^ havege_hardtick;
+  *Pt2  = ror32(*Pt2, 15) ^ havege_hardtick;
+  //*Pt3  = (*Pt3 >> (16)) ^ (*Pt3 << (16)) ^ havege_hardtick;
+  *Pt3  = ror32(*Pt3, 16) ^ havege_hardtick;
 
   /* avoid PT and PT2 to point on the same cache block */
   PT = (((RESULT[(i - 8) ^ pt] ^ havege_pwalk[PT ^ pt ^ 7])) &