Hello community,

here is the log from the commit of package rng-tools for openSUSE:Factory 
checked in at 2012-10-05 13:47:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rng-tools (Old)
 and      /work/SRC/openSUSE:Factory/.rng-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rng-tools", Maintainer is "[email protected]"

Changes:
--------
--- /work/SRC/openSUSE:Factory/rng-tools/rng-tools.changes      2012-01-31 
10:22:07.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.rng-tools.new/rng-tools.changes 2012-10-06 
18:43:06.000000000 +0200
@@ -1,0 +2,14 @@
+Thu Oct  4 14:31:13 UTC 2012 - [email protected]
+
+- update to version 4:
+  * Add RDRAND instruction support
+  * Add -q and -v options for quiet and verbose output
+  * Add -p option for specifying PID file (text file containing daemon's PID)
+  * Disable entropy source if facing continued failures, but be
+    tolerant of the occasional fault.
+  * Default device is now the preferred /dev/hwrng
+  * Do not use TPM device for RNG access, if /dev/hwrng is present
+    (TPM RNG is exported via the kernel, in newer kernels)
+- require $remote_fs in init script as binaries are below /usr
+
+-------------------------------------------------------------------

Old:
----
  rng-tools-3.tar.bz2

New:
----
  rng-tools-4.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rng-tools.spec ++++++
--- /var/tmp/diff_new_pack.9n1iz4/_old  2012-10-06 18:43:07.000000000 +0200
+++ /var/tmp/diff_new_pack.9n1iz4/_new  2012-10-06 18:43:07.000000000 +0200
@@ -16,20 +16,19 @@
 #
 
 
-
 Name:           rng-tools
 BuildRequires:  automake
-BuildRequires:  trousers-devel
 BuildRequires:  systemd
-License:        GPL-3.0+
-Group:          System/Kernel
+BuildRequires:  trousers-devel
 ExclusiveArch:  %ix86 ia64 x86_64
 Summary:        Support daemon for hardware random device
-Version:        3
+License:        GPL-3.0+
+Group:          System/Kernel
+Version:        4
 Release:        0
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Url:            http://sourceforge.net/projects/gkernel/
-Source:         rng-tools-3.tar.bz2 
+Source:         %{name}-%{version}.tar.bz2 
 Source1:        %name.init
 Source2:        %{name}.service
 PreReq:         %fillup_prereq
@@ -75,19 +74,11 @@
 
 %description
 This  daemon  feeds data from a random number generator to the kernel's
- random  number  entropy  pool,  after first checking the data to
+random  number  entropy  pool,  after  first checking the data to
 ensure that it is properly random.
 
-
-
-Authors:
---------
-    Philipp Rumpf <[email protected]>
-    Jeff Garzik <[email protected]>
-    Matt Sottek
-
 %prep
-%setup -q -n rng-tools-3
+%setup -q
 
 %build
 autoreconf --force --install

++++++ rng-tools-3.tar.bz2 -> rng-tools-4.tar.bz2 ++++++
++++ 6055 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/Makefile.am new/rng-tools-4/Makefile.am
--- old/rng-tools-3/Makefile.am 2009-12-24 07:47:24.000000000 +0100
+++ new/rng-tools-4/Makefile.am 2012-08-02 06:18:37.000000000 +0200
@@ -10,7 +10,8 @@
 noinst_LIBRARIES = librngd.a
 
 rngd_SOURCES   = rngd.h rngd.c rngd_entsource.h rngd_entsource.c       \
-                 rngd_linux.h rngd_linux.c
+                 rngd_linux.h rngd_linux.c util.c                      \
+                 rngd_rdrand.c rdrand_asm.S
 rngd_LDADD     = librngd.a
 
 rngtest_SOURCES        = exits.h stats.h stats.c rngtest.c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/NEWS new/rng-tools-4/NEWS
--- old/rng-tools-3/NEWS        2010-07-04 04:54:07.000000000 +0200
+++ new/rng-tools-4/NEWS        2012-08-02 21:01:16.000000000 +0200
@@ -1,4 +1,14 @@
 
+Version 4 (August 2, 2012):
+* Add RDRAND instruction support
+* Add -q and -v options for quiet and verbose output
+* Add -p option for specifying PID file (text file containing daemon's PID)
+* Disable entropy source if facing continued failures, but be
+  tolerant of the occasional fault.
+* Default device is now the preferred /dev/hwrng
+* Do not use TPM device for RNG access, if /dev/hwrng is present
+  (TPM RNG is exported via the kernel, in newer kernels)
+
 Version 3 (July 3, 2010):
 
 * add rngtest program
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/README new/rng-tools-4/README
--- old/rng-tools-3/README      2010-07-04 04:47:35.000000000 +0200
+++ new/rng-tools-4/README      2012-08-02 20:55:42.000000000 +0200
@@ -1,8 +1,13 @@
 
 This is a random number generator daemon.
 
-It monitors a hardware random number generator, and supplies entropy from that
-to the system /dev/random machinery.
+It monitors a hardware random number generator, and supplies entropy
+from that to the system kernel's /dev/random machinery.
+
+It is hoped that future contributions will enable entropy gathering
+from other sources, such as audio hardware or video hardware or CPU
+instruction pointers, to provide entropy even in cases where a true
+hardware RNG is not present.
 
 Home page:
        http://sourceforge.net/projects/gkernel/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/configure.ac new/rng-tools-4/configure.ac
--- old/rng-tools-3/configure.ac        2010-07-04 04:48:19.000000000 +0200
+++ new/rng-tools-4/configure.ac        2012-08-02 20:56:33.000000000 +0200
@@ -17,7 +17,7 @@
 dnl along with this program; if not, write to the Free Software
 dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-AC_INIT(rng-tools, 3, [Jeff Garzik <[email protected]>])
+AC_INIT(rng-tools, 4, [Jeff Garzik <[email protected]>])
 AC_PREREQ(2.52)
 AC_CONFIG_SRCDIR([rngd.c])
 AM_INIT_AUTOMAKE([gnu])
@@ -51,6 +51,8 @@
 dnl Configure options
 dnl -----------------
 
+AM_PROG_AS
+
 dnl --------------------------
 dnl autoconf output generation
 dnl --------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rdrand_asm.S new/rng-tools-4/rdrand_asm.S
--- old/rng-tools-3/rdrand_asm.S        1970-01-01 01:00:00.000000000 +0100
+++ new/rng-tools-4/rdrand_asm.S        2012-08-02 06:18:08.000000000 +0200
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2011, Intel Corporation
+ * Authors: Fenghua Yu <[email protected]>,
+ *          H. Peter Anvin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define ENTRY(x)         \
+       .balign 64      ; \
+       .globl  x       ; \
+x:
+
+#define ENDPROC(x)               \
+       .size   x, .-x          ; \
+       .type   x, @function
+
+#define RDRAND_RETRY_LIMIT     10
+
+#if defined(__x86_64__)
+
+ENTRY(x86_rdrand_nlong)
+1:
+       mov     $RDRAND_RETRY_LIMIT, %eax
+2:
+       .byte   0x48,0x0f,0xc7,0xf2     /* rdrand %rdx */
+       jnc     3f
+       mov     %rdx, (%rdi)
+       add     $8, %rdi
+       sub     $1, %esi
+       jnz     1b
+       ret
+3:
+       sub     $1, %eax
+       rep;nop
+       jnz     2b
+       ret
+ENDPROC(x86_rdrand_nlong)
+
+#define SETPTR(var,ptr)        leaq var(%rip),ptr
+#define PTR0   %rdi
+#define PTR1   %rsi
+#define PTR2   %rcx
+#define NPTR2  1       /* %rcx = %r1, only 0-7 valid here */
+
+#elif defined(__i386__)
+
+ENTRY(x86_rdrand_nlong)
+       push    %ebp
+       mov     %esp, %ebp
+       push    %edi
+       movl    8(%ebp), %ecx
+       movl    12(%ebp), %edx
+1:
+       mov     $RDRAND_RETRY_LIMIT, %eax
+2:
+       .byte   0x0f,0xc7,0xf7          /* rdrand %edi */
+       jnc     3f
+       mov     %edi, (%ecx)
+       add     $4, %ecx
+       sub     $1, %edx
+       jnz     2b
+       pop     %edi
+       pop     %ebp
+       ret
+3:
+       sub     $1, %eax
+       rep;nop
+       jnz     2b
+       pop %edi
+       pop     %ebp
+       ret
+ENDPROC(x86_rdrand_nlong)
+
+#define SETPTR(var,ptr)        movl $(var),ptr
+#define PTR0   %eax
+#define PTR1   %edx
+#define PTR2   %ecx
+#define NPTR2  1       /* %rcx = %r1 */
+
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+
+ENTRY(x86_aes_mangle)
+#if defined(__i386__)
+       push    %ebp
+       mov     %esp, %ebp
+       movl    8(%ebp), %eax
+       movl    12(%ebp), %edx
+#endif
+
+       SETPTR(aes_round_keys, PTR2)
+
+       movdqa  (0*16)(PTR0), %xmm0
+       movdqa  (1*16)(PTR0), %xmm1
+       movdqa  (2*16)(PTR0), %xmm2
+       movdqa  (3*16)(PTR0), %xmm3
+       movdqa  (4*16)(PTR0), %xmm4
+       movdqa  (5*16)(PTR0), %xmm5
+       movdqa  (6*16)(PTR0), %xmm6
+       movdqa  (7*16)(PTR0), %xmm7
+
+       pxor    (0*16)(PTR1), %xmm0
+       pxor    (1*16)(PTR1), %xmm1
+       pxor    (2*16)(PTR1), %xmm2
+       pxor    (3*16)(PTR1), %xmm3
+       pxor    (4*16)(PTR1), %xmm4
+       pxor    (5*16)(PTR1), %xmm5
+       pxor    (6*16)(PTR1), %xmm6
+       pxor    (7*16)(PTR1), %xmm7
+
+       .rept 10
+       .byte   0x66,0x0f,0x38,0xdc,0x00+NPTR2  /* aesenc (PTR2), %xmm0 */
+       .byte   0x66,0x0f,0x38,0xdc,0x08+NPTR2  /* aesenc (PTR2), %xmm1 */
+       .byte   0x66,0x0f,0x38,0xdc,0x10+NPTR2  /* aesenc (PTR2), %xmm2 */
+       .byte   0x66,0x0f,0x38,0xdc,0x18+NPTR2  /* aesenc (PTR2), %xmm3 */
+       .byte   0x66,0x0f,0x38,0xdc,0x20+NPTR2  /* aesenc (PTR2), %xmm4 */
+       .byte   0x66,0x0f,0x38,0xdc,0x28+NPTR2  /* aesenc (PTR2), %xmm5 */
+       .byte   0x66,0x0f,0x38,0xdc,0x30+NPTR2  /* aesenc (PTR2), %xmm6 */
+       .byte   0x66,0x0f,0x38,0xdc,0x38+NPTR2  /* aesenc (PTR2), %xmm7 */
+       add     $16, PTR2
+       .endr
+
+       .byte   0x66,0x0f,0x38,0xdd,0x00+NPTR2  /* aesenclast (PTR2), %xmm0 */
+       .byte   0x66,0x0f,0x38,0xdd,0x08+NPTR2  /* aesenclast (PTR2), %xmm1 */
+       .byte   0x66,0x0f,0x38,0xdd,0x10+NPTR2  /* aesenclast (PTR2), %xmm2 */
+       .byte   0x66,0x0f,0x38,0xdd,0x18+NPTR2  /* aesenclast (PTR2), %xmm3 */
+       .byte   0x66,0x0f,0x38,0xdd,0x20+NPTR2  /* aesenclast (PTR2), %xmm4 */
+       .byte   0x66,0x0f,0x38,0xdd,0x28+NPTR2  /* aesenclast (PTR2), %xmm5 */
+       .byte   0x66,0x0f,0x38,0xdd,0x30+NPTR2  /* aesenclast (PTR2), %xmm6 */
+       .byte   0x66,0x0f,0x38,0xdd,0x38+NPTR2  /* aesenclast (PTR2), %xmm7 */
+
+       movdqa  %xmm0, (0*16)(PTR0)
+       movdqa  %xmm1, (1*16)(PTR0)
+       movdqa  %xmm2, (2*16)(PTR0)
+       movdqa  %xmm3, (3*16)(PTR0)
+       movdqa  %xmm4, (4*16)(PTR0)
+       movdqa  %xmm5, (5*16)(PTR0)
+       movdqa  %xmm6, (6*16)(PTR0)
+       movdqa  %xmm7, (7*16)(PTR0)
+
+       movdqa  %xmm0, (0*16)(PTR1)
+       movdqa  %xmm1, (1*16)(PTR1)
+       movdqa  %xmm2, (2*16)(PTR1)
+       movdqa  %xmm3, (3*16)(PTR1)
+       movdqa  %xmm4, (4*16)(PTR1)
+       movdqa  %xmm5, (5*16)(PTR1)
+       movdqa  %xmm6, (6*16)(PTR1)
+       movdqa  %xmm7, (7*16)(PTR1)
+
+#if defined(__i386__)
+       pop     %ebp
+#endif
+       ret
+ENDPROC(x86_aes_mangle)
+       /*
+        * AES round keys for an arbitrary key:
+        * 00102030405060708090A0B0C0D0E0F0
+        */
+       .section ".rodata","a"
+       .balign 16
+aes_round_keys:
+       .long   0x00102030, 0x40506070, 0x8090A0B0, 0xC0D0E0F0
+       .long   0x89D810E8, 0x855ACE68, 0x2D1843D8, 0xCB128FE4
+       .long   0x4915598F, 0x55E5D7A0, 0xDACA94FA, 0x1F0A63F7
+       .long   0xFA636A28, 0x25B339C9, 0x40668A31, 0x57244D17
+       .long   0x24724023, 0x6966B3FA, 0x6ED27532, 0x88425B6C
+       .long   0xC81677BC, 0x9B7AC93B, 0x25027992, 0xB0261996
+       .long   0xC62FE109, 0xF75EEDC3, 0xCC79395D, 0x84F9CF5D
+       .long   0xD1876C0F, 0x79C4300A, 0xB45594AD, 0xD66FF41F
+       .long   0xFDE3BAD2, 0x05E5D0D7, 0x3547964E, 0xF1FE37F1
+       .long   0xBD6E7C3D, 0xF2B5779E, 0x0B61216E, 0x8B10B689
+       .long   0x69C4E0D8, 0x6A7B0430, 0xD8CDB780, 0x70B4C55A
+       .size   aes_round_keys, .-aes_round_keys
+
+       .bss
+       .balign 16
+aes_fwd_state:
+       .space  16
+       .size   aes_fwd_state, .-aes_fwd_state
+
+#endif /* i386 or x86_64 */
+
+/*
+ * This is necessary to keep the whole executable
+ * from needing a writable stack.
+ */
+                .section        .note.GNU-stack,"",%progbits
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rng-tools-config.h.in new/rng-tools-4/rng-tools-config.h.in
--- old/rng-tools-3/rng-tools-config.h.in       2009-12-24 07:47:31.000000000 
+0100
+++ new/rng-tools-4/rng-tools-config.h.in       2012-06-19 17:03:18.000000000 
+0200
@@ -15,6 +15,9 @@
 /* Define to the one symbol short name of this package. */
 #undef PACKAGE_TARNAME
 
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd.8.in new/rng-tools-4/rngd.8.in
--- old/rng-tools-3/rngd.8.in   2009-12-24 07:47:24.000000000 +0100
+++ new/rng-tools-4/rngd.8.in   2012-07-31 18:19:53.000000000 +0200
@@ -10,10 +10,14 @@
 [\fB\-b\fR, \fB\-\-background\fR]
 [\fB\-f\fR, \fB\-\-foreground\fR]
 [\fB\-o\fR, \fB\-\-random-device=\fIfile\fR]
+[\fB\-p\fR, \fB\-\-pid-file=\fIfile\fR]
 [\fB\-r\fR, \fB\-\-rng-device=\fIfile\fR]
 [\fB\-s\fR, \fB\-\-random-step=\fInnn\fR]
 [\fB\-W\fR, \fB\-\-fill-watermark=\fInnn\fR]
-[\fB\-t\fR, \fB\-\-timeout=\fInnn\fR]
+[\fB\-d\fR, \fB\-\-no-drng=\fI1|0\fR]
+[\fB\-n\fR, \fB\-\-no-tpm=\fI1|0\fR]
+[\fB\-q\fR, \fB\-\-quiet\fR]
+[\fB\-v\fR, \fB\-\-verbose\fR]
 [\fB\-?\fR, \fB\-\-help\fR]
 [\fB\-V\fR, \fB\-\-version\fR]
 .RI
@@ -25,7 +29,7 @@
 .PP
 The \fB\-f\fR or \fB\-\-foreground\fR options can be used to tell
 \fBrngd\fR to avoid forking on startup.  This is typically used for
-debugging.  The \fB\-f\fR or \fB\-\-foreground\fR options, which fork and put
+debugging.  The \fB\-b\fR or \fB\-\-background\fR options, which fork and put
 \fBrngd\fR into the background automatically, are the default.
 .PP
 The \fB\-r\fR or \fB\-\-rng-device\fR options can be used to select an
@@ -45,6 +49,10 @@
 \fB\-f\fR, \fB\-\-foreground\fR
 Do not fork and become a daemon
 .TP
+\fB\-p\fI file\fR, \fB\-\-pid-file=\fIfile\fR
+File used for recording daemon PID, and multiple exclusion
+(default: /var/run/rngd.pid)
+.TP
 \fB\-o\fI file\fR, \fB\-\-random-device=\fIfile\fR
 Kernel device used for random number output
 (default: /dev/random)
@@ -64,8 +72,17 @@
 starves.  Do not set \fIfill-watermark\fR above the size of the
 entropy pool (usually 4096 bits).
 .TP
-\fB\-t\fI nnn\fR, \fB\-\-timeout=\fInnn\fR
-Interval written to random-device when the entropy pool is full, in seconds, 
or 0 to disable (default: 60)
+\fB\-d\fI 1|0\fR, \fB\-\-no-drng=\fI1|0\fR
+Do not use drng as a source of random number input (default:0)
+.TP
+\fB\-n\fI 1|0\fR, \fB\-\-no-tpm=\fI1|0\fR
+Do not use tpm as a source of random number input (default:0)
+.TP
+\fB\-q\fR, \fB\-\-quiet\fR
+Suppress error messages
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Report available entropy sources
 .TP
 \fB\-?\fR, \fB\-\-help\fR
 Give a short summary of all program options.
@@ -79,4 +96,5 @@
 Jeff Garzik \- [email protected]
 .br
 Matt Sottek
-
+.br
+Brad Hill
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd.c new/rng-tools-4/rngd.c
--- old/rng-tools-3/rngd.c      2010-07-04 04:42:56.000000000 +0200
+++ new/rng-tools-4/rngd.c      2012-08-02 06:19:09.000000000 +0200
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <argp.h>
 #include <syslog.h>
+#include <signal.h>
 
 #include "rngd.h"
 #include "fips.h"
@@ -57,7 +58,9 @@
  */
 
 /* Background/daemon mode */
-int am_daemon;                         /* Nonzero if we went daemon */
+bool am_daemon;                                /* True if we went daemon */
+
+bool server_running = true;            /* set to false, to stop daemon */
 
 /* Command line arguments and processing */
 const char *argp_program_version =
@@ -81,7 +84,10 @@
          "Kernel device used for random number output (default: /dev/random)" 
},
 
        { "rng-device", 'r', "file", 0,
-         "Kernel device used for random number input (default: 
/dev/hw_random)" },
+         "Kernel device used for random number input (default: /dev/hwrng)" },
+
+       { "pid-file", 'p', "file", 0,
+         "File used for recording daemon PID, and multiple exclusion (default: 
/var/run/rngd.pid)" },
 
        { "random-step", 's', "nnn", 0,
          "Number of bytes written to random-device at a time (default: 64)" },
@@ -89,38 +95,47 @@
        { "fill-watermark", 'W', "n", 0,
          "Do not stop feeding entropy to random-device until at least n bits 
of entropy are available in the pool (default: 2048), 0 <= n <= 4096" },
 
-       { "timeout", 't', "nnn", 0,
-         "Interval written to random-device when the entropy pool is full, in 
seconds (default: 60)" },
+       { "quiet", 'q', 0, 0, "Suppress error messages" },
+
+       { "verbose" ,'v', 0, 0, "Report available entropy sources" },
+
+       { "no-drng", 'd', "1|0", 0,
+         "Do not use drng as a source of random number input (default: 0)" },
+       
        { "no-tpm", 'n', "1|0", 0,
-         "do not use tpm as a source of random number input (default: 0)" },
+         "Do not use tpm as a source of random number input (default: 0)" },
 
        { 0 },
 };
 
 static struct arguments default_arguments = {
        .random_name    = "/dev/random",
-       .poll_timeout   = 60,
+       .pid_file       = "/var/run/rngd.pid",
        .random_step    = 64,
-       .fill_watermark = 2048,
-       .daemon         = 1,
-       .enable_tpm     = 1,
+       .daemon         = true,
+       .enable_drng    = true,
+       .enable_tpm     = true,
+       .quiet          = false,
+       .verbose        = false,
 };
 struct arguments *arguments = &default_arguments;
 
 static struct rng rng_default = {
-       .rng_name       = "/dev/hw_random",
+       .rng_name       = "/dev/hwrng",
        .rng_fd         = -1,
        .xread          = xread,
-       .fipsctx        = NULL,
-       .next           = NULL,
+};
+
+static struct rng rng_drng = {
+       .rng_name       = "drng",
+       .rng_fd         = -1,
+       .xread          = xread_drng,
 };
 
 static struct rng rng_tpm = {
        .rng_name       = "/dev/tpm0",
        .rng_fd         = -1,
        .xread          = xread_tpm,
-       .fipsctx        = NULL,
-       .next           = NULL,
 };
 
 struct rng *rng_list;
@@ -134,23 +149,17 @@
        case 'o':
                arguments->random_name = arg;
                break;
+       case 'p':
+               arguments->pid_file = arg;
+               break;
        case 'r':
                rng_default.rng_name = arg;
                break;
-       case 't': {
-               float f;
-               if (sscanf(arg, "%f", &f) == 0)
-                       argp_usage(state);
-               else
-                       arguments->poll_timeout = f;
-               break;
-       }
-
        case 'f':
-               arguments->daemon = 0;
+               arguments->daemon = false;
                break;
        case 'b':
-               arguments->daemon = 1;
+               arguments->daemon = true;
                break;
        case 's':
                if (sscanf(arg, "%i", &arguments->random_step) == 0)
@@ -164,12 +173,26 @@
                        arguments->fill_watermark = n;
                break;
        }
+       case 'q':
+               arguments->quiet = true;
+               break;
+       case 'v':
+               arguments->verbose = true;
+               break;
+       case 'd': {
+               int n;
+               if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1))
+                       argp_usage(state);
+               else
+                       arguments->enable_drng = false;
+               break;
+       }
        case 'n': {
                int n;
                if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1))
                        argp_usage(state);
                else
-                       arguments->enable_tpm = 0;
+                       arguments->enable_tpm = false;
                break;
        }
 
@@ -183,62 +206,138 @@
 static struct argp argp = { options, parse_opt, NULL, doc };
 
 
-static int update_kernel_random(int random_step, double poll_timeout,
-       unsigned char *buf, fips_ctx_t *fipsctx)
+static int update_kernel_random(int random_step,
+       unsigned char *buf, fips_ctx_t *fipsctx_in)
 {
        unsigned char *p;
        int fips;
 
-       fips = fips_run_rng_test(fipsctx, buf);
-       if (fips) {
-               message(LOG_DAEMON|LOG_ERR, "failed fips test\n");
+       fips = fips_run_rng_test(fipsctx_in, buf);
+       if (fips)
                return 1;
-       }
 
        for (p = buf; p + random_step <= &buf[FIPS_RNG_BUFFER_SIZE];
                 p += random_step) {
                random_add_entropy(p, random_step);
-               random_sleep(poll_timeout);
+               random_sleep();
        }
        return 0;
 }
 
-static void do_loop(int random_step, double poll_timeout)
+static void do_loop(int random_step)
 {
        unsigned char buf[FIPS_RNG_BUFFER_SIZE];
-       int retval;
+       int retval = 0;
+       int no_work = 0;
 
-       for (;;) {
+       while (no_work < 100) {
                struct rng *iter;
+               bool work_done;
+
+               work_done = false;
                for (iter = rng_list; iter; iter = iter->next)
                {
+                       int rc;
+
+                       if (!server_running)
+                               return;
+
+               retry_same:
+                       if (iter->disabled)
+                               continue;       /* failed, no work */
+
                        retval = iter->xread(buf, sizeof buf, iter);
-                       if (retval == 0)
-                               update_kernel_random(random_step,
-                                                    poll_timeout, buf,
-                                                    iter->fipsctx);
+                       if (retval)
+                               continue;       /* failed, no work */
+
+                       work_done = true;
+
+                       rc = update_kernel_random(random_step,
+                                            buf, iter->fipsctx);
+                       if (rc == 0) {
+                               iter->success++;
+                               if (iter->success >= RNG_OK_CREDIT) {
+                                       if (iter->failures)
+                                               iter->failures--;
+                                       iter->success = 0;
+                               }
+                               break;  /* succeeded, work done */
+                       }
+
+                       iter->failures++;
+                       if (iter->failures <= MAX_RNG_FAILURES/4) {
+                               /* FIPS tests have false positives */
+                               goto retry_same;
+                       } else if (iter->failures >= MAX_RNG_FAILURES) {
+                               if (!arguments->quiet)
+                                       message(LOG_DAEMON|LOG_ERR,
+                                       "too many FIPS failures, disabling 
entropy source\n");
+                               iter->disabled = true;
+                       }
                }
+
+               if (!work_done)
+                       no_work++;
        }
+
+       if (!arguments->quiet)
+               message(LOG_DAEMON|LOG_ERR,
+               "No entropy sources working, exiting rngd\n");
+}
+
+static void term_signal(int signo)
+{
+       server_running = false;
 }
 
 int main(int argc, char **argv)
 {
        int rc_rng = 1;
+       int rc_drng = 1;
        int rc_tpm = 1;
+       int pid_fd = -1;
+
+       openlog("rngd", 0, LOG_DAEMON);
+
+       /* Get the default watermark level for this platform */
+       arguments->fill_watermark = default_watermark();
 
        /* Parsing of commandline parameters */
        argp_parse(&argp, argc, argv, 0, 0, arguments);
 
        /* Init entropy sources, and open TRNG device */
+       if (arguments->enable_drng)
+               rc_drng = init_drng_entropy_source(&rng_drng);
        rc_rng = init_entropy_source(&rng_default);
-       if (arguments->enable_tpm)
+       if (arguments->enable_tpm && rc_rng)
                rc_tpm = init_tpm_entropy_source(&rng_tpm);
 
-       if (rc_rng && rc_tpm) {
-               message(LOG_DAEMON|LOG_ERR,
-                       "can't open entropy source(tpm or intel/amd rng)");
-               message(LOG_DAEMON|LOG_ERR,
-                       "Maybe RNG device modules are not loaded\n");
+       if (rc_rng && rc_drng && rc_tpm) {
+               if (!arguments->quiet) {
+                       message(LOG_DAEMON|LOG_ERR,
+                               "can't open any entropy source");
+                       message(LOG_DAEMON|LOG_ERR,
+                               "Maybe RNG device modules are not loaded\n");
+               }
+               return 1;
+       }
+
+       if (arguments->verbose) {
+               printf("Available entropy sources:\n");
+               if (!rc_rng)
+                       printf("\tIntel/AMD hardware rng\n");
+               if (!rc_drng)
+                       printf("\tDRNG\n");
+               if (!rc_tpm)
+                       printf("\tTPM\n");
+       }
+
+       if (rc_rng
+               && (rc_drng || !arguments->enable_drng)
+               && (rc_tpm || !arguments->enable_tpm)) {
+               if (!arguments->quiet)
+                       message(LOG_DAEMON|LOG_ERR,
+               "No entropy source available, shutting down\n");
                return 1;
        }
 
@@ -246,19 +345,30 @@
        init_kernel_rng(arguments->random_name);
 
        if (arguments->daemon) {
-               am_daemon = 1;
+               am_daemon = true;
 
                if (daemon(0, 0) < 0) {
-                       fprintf(stderr, "can't daemonize: %s\n",
+                       if(!arguments->quiet)
+                               fprintf(stderr, "can't daemonize: %s\n",
                                strerror(errno));
                        return 1;
                }
 
-               openlog("rngd", 0, LOG_DAEMON);
+               /* require valid, locked PID file to proceed */
+               pid_fd = write_pid_file(arguments->pid_file);
+               if (pid_fd < 0)
+                       return 1;
+
+               signal(SIGHUP, SIG_IGN);
+               signal(SIGPIPE, SIG_IGN);
+               signal(SIGINT, term_signal);
+               signal(SIGTERM, term_signal);
        }
 
-       do_loop(arguments->random_step,
-               arguments->poll_timeout ? : -1.0);
+       do_loop(arguments->random_step);
+
+       if (pid_fd >= 0)
+               unlink(arguments->pid_file);
 
        return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd.h new/rng-tools-4/rngd.h
--- old/rng-tools-3/rngd.h      2010-07-04 04:59:36.000000000 +0200
+++ new/rng-tools-4/rngd.h      2012-08-02 06:19:01.000000000 +0200
@@ -27,21 +27,30 @@
 
 #include <unistd.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <syslog.h>
 
 #include "fips.h"
 
+enum {
+       MAX_RNG_FAILURES                = 25,
+       RNG_OK_CREDIT                   = 1000, /* ~1:1250 false positives */
+};
+
 /* Command line arguments and processing */
 struct arguments {
        char *random_name;
+       char *pid_file;
 
        int random_step;
        int fill_watermark;
-       double poll_timeout;
 
-       int daemon;
-       int enable_tpm;
+       bool quiet;
+       bool verbose;
+       bool daemon;
+       bool enable_drng;
+       bool enable_tpm;
 };
 extern struct arguments *arguments;
 
@@ -49,6 +58,9 @@
 struct rng {
        char *rng_name;
        int rng_fd;
+       bool disabled;
+       int failures;
+       int success;
 
        int (*xread) (void *buf, size_t size, struct rng *ent_src);
        fips_ctx_t *fipsctx;
@@ -57,7 +69,7 @@
 };
 
 /* Background/daemon mode */
-extern int am_daemon;                  /* Nonzero if we went daemon */
+extern bool am_daemon;                 /* True if we went daemon */
 
 
 /*
@@ -73,5 +85,6 @@
 } while (0)
 
 extern void src_list_add(struct rng *ent_src);
+extern int write_pid_file(const char *pid_fn);
 #endif /* RNGD__H */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd_entsource.c new/rng-tools-4/rngd_entsource.c
--- old/rng-tools-3/rngd_entsource.c    2010-07-04 04:59:36.000000000 +0200
+++ new/rng-tools-4/rngd_entsource.c    2012-08-02 06:18:37.000000000 +0200
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <syslog.h>
 #include <string.h>
+#include <stddef.h>
 
 #include "rngd.h"
 #include "fips.h"
@@ -88,6 +89,7 @@
 
        ent_src->rng_fd = open(ent_src->rng_name, O_RDWR);
        if (ent_src->rng_fd == -1) {
+               message(LOG_ERR|LOG_INFO,"Unable to open file: 
%s",ent_src->rng_name);
                return -1;
        }
 
@@ -95,6 +97,7 @@
        memset(temp_buf, 0, (size+TPM_GET_RNG_OVERHEAD));
        if (temp_buf == NULL) {
                message(LOG_ERR|LOG_INFO,"No memory");
+               close(ent_src->rng_fd);
                return -1;
        }
        /* 32 bits has been reserved for random byte size */
@@ -126,6 +129,12 @@
                }
                r = read(ent_src->rng_fd, temp_buf,size);
                r = (r - TPM_GET_RNG_OVERHEAD);
+               if(r <= 0) {
+                       message(LOG_ERR|LOG_INFO,
+                       "Error reading from TPM, no entropy gathered");
+                       retval = -1;
+                       goto error_out;
+               }
                bytes_read = bytes_read + r;
                if (bytes_read > size) {
                        memcpy(offset,temp_buf + TPM_GET_RNG_OVERHEAD,
@@ -152,10 +161,10 @@
         * The kernel drivers should be doing this at device powerup,
         * but at least up to 2.4.24, it doesn't. */
        unsigned char tempbuf[4];
-       xread(tempbuf, sizeof tempbuf, ent_src);
+       xread(tempbuf, sizeof(tempbuf), ent_src);
 
        /* Return 32 bits of bootstrap data */
-       xread(tempbuf, sizeof tempbuf, ent_src);
+       xread(tempbuf, sizeof(tempbuf), ent_src);
 
        return tempbuf[0] | (tempbuf[1] << 8) |
                (tempbuf[2] << 16) | (tempbuf[3] << 24);
@@ -184,6 +193,7 @@
 {
        ent_src->rng_fd = open(ent_src->rng_name, O_RDWR);
        if (ent_src->rng_fd == -1) {
+               message(LOG_ERR|LOG_INFO,"Unable to open file: 
%s",ent_src->rng_name);
                return 1;
        }
        src_list_add(ent_src);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd_entsource.h new/rng-tools-4/rngd_entsource.h
--- old/rng-tools-3/rngd_entsource.h    2010-07-04 04:42:56.000000000 +0200
+++ new/rng-tools-4/rngd_entsource.h    2012-08-02 06:18:37.000000000 +0200
@@ -36,10 +36,12 @@
  * sourcedev is the path to the entropy source
  */
 extern int init_entropy_source(struct rng *);
+extern int init_drng_entropy_source(struct rng *);
 extern int init_tpm_entropy_source(struct rng *);
 
 /* Read data from the entropy source */
 extern int xread(void *buf, size_t size, struct rng *ent_src);
+extern int xread_drng(void *buf, size_t size, struct rng *ent_src);
 extern int xread_tpm(void *buf, size_t size, struct rng *ent_src);
 
 #endif /* RNGD_ENTSOURCE__H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd_linux.c new/rng-tools-4/rngd_linux.c
--- old/rng-tools-3/rngd_linux.c        2010-07-04 04:59:36.000000000 +0200
+++ new/rng-tools-4/rngd_linux.c        2012-08-02 06:18:54.000000000 +0200
@@ -53,6 +53,37 @@
 /* Kernel output device */
 static int random_fd;
 
+/*
+ * Get the default watermark
+ */
+int default_watermark(void)
+{
+       char psbuf[64], *p;
+       unsigned long ps;
+       FILE *f;
+       size_t l;
+       unsigned int wm = 2048; /* Default guess */
+
+       f = fopen("/proc/sys/kernel/random/poolsize", "r");
+       if (!f)
+               goto err;
+       l = fread(psbuf, 1, sizeof psbuf, f);
+       if (ferror(f) || !feof(f) || l == 0)
+               goto err;
+       if (psbuf[l-1] != '\n')
+               goto err;
+       psbuf[l-1] = '\0';
+       ps = strtoul(psbuf, &p, 0);
+       if (*p)
+               goto err;
+
+       wm = ps*3/4;
+
+err:
+       if (f)
+               fclose(f);
+       return wm;
+}
 
 /*
  * Initialize the interface to the Linux Kernel
@@ -62,12 +93,29 @@
  */
 void init_kernel_rng(const char* randomdev)
 {
+       FILE *f;
+       int err;
+
        random_fd = open(randomdev, O_RDWR);
        if (random_fd == -1) {
                message(LOG_DAEMON|LOG_ERR, "can't open %s: %s",
                        randomdev, strerror(errno));
                exit(EXIT_USAGE);
        }
+
+       f = fopen("/proc/sys/kernel/random/write_wakeup_threshold", "w");
+       if (!f) {
+               err = 1;
+       } else {
+               fprintf(f, "%u\n", arguments->fill_watermark);
+               /* Note | not || here... we always want to close the file */
+               err = ferror(f) | fclose(f);
+       }
+       if (err) {
+               message(LOG_DAEMON|LOG_WARNING,
+                       "unable to adjust write_wakeup_threshold: %s",
+                       strerror(errno));
+       }
 }
 
 void random_add_entropy(void *buf, size_t size)
@@ -89,19 +137,14 @@
        }
 }
 
-void random_sleep(double poll_timeout)
+void random_sleep(void)
 {
-       int ent_count;
        struct pollfd pfd = {
                fd:     random_fd,
                events: POLLOUT,
        };
 
-       if (ioctl(random_fd, RNDGETENTCNT, &ent_count) == 0 &&
-           ent_count < arguments->fill_watermark)
-               return;
-
-       poll(&pfd, 1, 1000.0 * poll_timeout);
+       poll(&pfd, 1, -1);
 }
 
 void src_list_add(struct rng *ent_src)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd_linux.h new/rng-tools-4/rngd_linux.h
--- old/rng-tools-3/rngd_linux.h        2010-07-04 04:42:56.000000000 +0200
+++ new/rng-tools-4/rngd_linux.h        2012-07-31 21:32:24.000000000 +0200
@@ -26,6 +26,9 @@
 #include <unistd.h>
 #include <stdint.h>
 
+/* The default watermark level for this platform */
+extern int default_watermark(void);
+
 /*
  * Initialize the interface to the Linux Kernel
  * entropy pool (through /dev/random)
@@ -38,7 +41,7 @@
 extern void random_add_entropy(void *buf, size_t size);
 
 /* Sleep until the kernel is hungry for entropy */
-extern void random_sleep(double poll_timeout);
+extern void random_sleep(void);
 
 #endif /* RNGD_LINUX__H */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/rngd_rdrand.c new/rng-tools-4/rngd_rdrand.c
--- old/rng-tools-3/rngd_rdrand.c       1970-01-01 01:00:00.000000000 +0100
+++ new/rng-tools-4/rngd_rdrand.c       2012-08-02 06:18:52.000000000 +0200
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2012, Intel Corporation
+ * Authors: Richard B. Hill <[email protected]>,
+ *          H. Peter Anvin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#ifndef HAVE_CONFIG_H
+#error Invalid or missing autoconf build environment
+#endif
+
+#include "rng-tools-config.h"
+
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "rngd.h"
+#include "fips.h"
+#include "exits.h"
+#include "rngd_entsource.h"
+
+#if defined(__i386__) || defined(__x86_64__)
+
+/* Struct for CPUID return values */
+struct cpuid {
+        uint32_t eax, ecx, edx, ebx;
+};
+
+/* Get data from RDRAND */
+extern int x86_rdrand_nlong(void *ptr, size_t count);
+/* Conditioning RDRAND for seed-grade entropy */
+extern void x86_aes_mangle(void *data, void *state);
+
+/* Checking eflags to confirm cpuid instruction available */
+/* Only necessary for 32 bit processors */
+#if defined (__i386__)
+static int x86_has_eflag(uint32_t flag)
+{
+        uint32_t f0, f1;
+               asm("pushfl ; "
+            "pushfl ; "
+            "popl %0 ; "
+            "movl %0,%1 ; "
+            "xorl %2,%1 ; "
+            "pushl %1 ; "
+            "popfl ; "
+            "pushfl ; "
+            "popl %1 ; "
+            "popfl"
+            : "=&r" (f0), "=&r" (f1)
+            : "ri" (flag));
+        return !!((f0^f1) & flag);
+}
+#endif
+
+/* Calling cpuid instruction to verify rdrand capability */
+static void cpuid(unsigned int leaf, unsigned int subleaf, struct cpuid *out)
+{
+#ifdef __i386__
+    /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */
+    asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0"
+                 : "=r" (out->ebx),
+                   "=a" (out->eax),
+                   "=c" (out->ecx),
+                   "=d" (out->edx)
+                 : "a" (leaf), "c" (subleaf));
+#else
+    asm volatile("cpuid"
+                 : "=b" (out->ebx),
+                   "=a" (out->eax),
+                   "=c" (out->ecx),
+                   "=d" (out->edx)
+                 : "a" (leaf), "c" (subleaf));
+#endif
+}
+
+/* Read data from the drng in chunks of 128 bytes for AES scrambling */
+#define CHUNK_SIZE             (16*8)
+
+static unsigned char iv_buf[CHUNK_SIZE] __attribute__((aligned(128)));
+
+int xread_drng(void *buf, size_t size, struct rng *ent_src)
+{
+       char *p = buf;
+       size_t chunk;
+       const int rdrand_round_count = 512;
+       unsigned char tmp[CHUNK_SIZE] __attribute__((aligned(128)));
+       int i;
+
+       while (size) {
+               for (i = 0; i < rdrand_round_count; i++) {
+                       if (!x86_rdrand_nlong(tmp, CHUNK_SIZE/sizeof(long))) {
+                               message(LOG_DAEMON|LOG_ERR, "read error\n");
+                               return -1;
+                       }
+                       x86_aes_mangle(tmp, iv_buf);
+               }
+               chunk = (sizeof(tmp) > size) ? size : sizeof(tmp);
+               memcpy(p, tmp, chunk);
+               p += chunk;
+               size -= chunk;
+       }
+
+       return 0;
+}
+
+/*
+ * Confirm RDRAND capabilities for drng entropy source
+ */
+int init_drng_entropy_source(struct rng *ent_src)
+{
+       struct cpuid info;
+       /* We need RDRAND and AESni */
+       const uint32_t need_features_ecx1 = (1 << 30) | (1 << 25);
+
+#if defined(__i386__)
+       if (!x86_has_eflag(1 << 21))
+               return 1;       /* No CPUID instruction */
+#endif
+
+       cpuid(0, 0, &info);
+       if (info.eax < 1)
+               return 1;
+       cpuid(1, 0, &info);
+       if ((info.ecx & need_features_ecx1) != need_features_ecx1)
+               return 1;
+
+       /* Initialize the IV buffer */
+       if (!x86_rdrand_nlong(iv_buf, CHUNK_SIZE/sizeof(long)))
+               return 1;
+
+       src_list_add(ent_src);
+       /* Bootstrap FIPS tests */
+       ent_src->fipsctx = malloc(sizeof(fips_ctx_t));
+       fips_init(ent_src->fipsctx, 0);
+       return 0;
+}
+
+#else /* Not i386 or x86-64 */
+
+int init_drng_entropy_source(struct rng *ent_src)
+{
+       (void)ent_src;
+       return 1;
+}
+
+int xread_drng(void *buf, size_t size, struct rng *ent_src)
+{
+       (void)buf;
+       (void)size;
+       (void)ent_src;
+
+       return -1;
+}
+
+#endif /* Not i386 or x86-64 */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/rng-tools-3/util.c new/rng-tools-4/util.c
--- old/rng-tools-3/util.c      1970-01-01 01:00:00.000000000 +0100
+++ new/rng-tools-4/util.c      2012-07-18 02:01:51.000000000 +0200
@@ -0,0 +1,104 @@
+
+/*
+ * Copyright 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#ifndef HAVE_CONFIG_H
+#error Invalid or missing autoconf build environment
+#endif
+
+#include "rng-tools-config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "rngd.h"
+
+int write_pid_file(const char *pid_fn)
+{
+       char str[32], *s;
+       size_t bytes;
+       int fd;
+       struct flock lock;
+       int err;
+
+       /* build file data */
+       sprintf(str, "%u\n", (unsigned int) getpid());
+
+       /* open non-exclusively (works on NFS v2) */
+       fd = open(pid_fn, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+       if (fd < 0) {
+               err = errno;
+
+               message(LOG_DAEMON|LOG_ERR, "Cannot open PID file %s: %s",
+                        pid_fn, strerror(err));
+               return -err;
+       }
+
+       /* lock */
+       memset(&lock, 0, sizeof(lock));
+       lock.l_type = F_WRLCK;
+       lock.l_whence = SEEK_SET;
+       if (fcntl(fd, F_SETLK, &lock) != 0) {
+               err = errno;
+               if (err == EAGAIN) {
+                       message(LOG_DAEMON|LOG_ERR, "PID file %s is already 
locked",
+                                pid_fn);
+               } else {
+                       message(LOG_DAEMON|LOG_ERR, "Cannot lock PID file %s: 
%s",
+                                pid_fn, strerror(err));
+               }
+               close(fd);
+               return -err;
+       }
+
+       /* write file data */
+       bytes = strlen(str);
+       s = str;
+       while (bytes > 0) {
+               ssize_t rc = write(fd, s, bytes);
+               if (rc < 0) {
+                       err = errno;
+                       message(LOG_DAEMON|LOG_ERR, "PID number write failed: 
%s",
+                                strerror(err));
+                       goto err_out;
+               }
+
+               bytes -= rc;
+               s += rc;
+       }
+
+       /* make sure file data is written to disk */
+       if (fsync(fd) < 0) {
+               err = errno;
+               message(LOG_DAEMON|LOG_ERR, "PID file fsync failed: %s", 
strerror(err));
+               goto err_out;
+       }
+
+       return fd;
+
+err_out:
+       unlink(pid_fn);
+       close(fd);
+       return -err;
+}
+

++++++ rng-tools.init ++++++
--- /var/tmp/diff_new_pack.9n1iz4/_old  2012-10-06 18:43:07.000000000 +0200
+++ /var/tmp/diff_new_pack.9n1iz4/_new  2012-10-06 18:43:07.000000000 +0200
@@ -2,8 +2,8 @@
 
 ### BEGIN INIT INFO
 # Provides:          rng-tools
-# Required-Start:    $syslog
-# Required-Stop:     $syslog
+# Required-Start:    $syslog $remote_fs
+# Required-Stop:     $syslog $remote_fs
 # Default-Start:     2 3 5
 # Default-Stop:
 # Short-Description: Support for hardware Random Number Generators (RNGs)

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to