]> git.ipfire.org Git - thirdparty/rng-tools.git/commitdiff
Add RDRAND support
authorBrad Hill <richard.b.hill@intel.com>
Tue, 31 Jul 2012 16:26:51 +0000 (12:26 -0400)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 31 Jul 2012 16:26:51 +0000 (12:26 -0400)
Makefile.am
configure.ac
rdrand_asm.S [new file with mode: 0644]
rngd.8.in
rngd.c
rngd.h
rngd_entsource.c
rngd_entsource.h
rngd_linux.c

index 682218194c324a11b757dc4e1a4ac2edb29ea45b..b86042e998f7afd294ca698b533749603cb70840 100644 (file)
@@ -10,7 +10,7 @@ man_MANS       = rngd.8 rngtest.1
 noinst_LIBRARIES = librngd.a
 
 rngd_SOURCES   = rngd.h rngd.c rngd_entsource.h rngd_entsource.c       \
-                 rngd_linux.h rngd_linux.c util.c
+                 rngd_linux.h rngd_linux.c util.c rdrand_asm.S
 rngd_LDADD     = librngd.a
 
 rngtest_SOURCES        = exits.h stats.h stats.c rngtest.c
index 7b4a4091e22075a5f2bc99c562293ab0da3f7416..aff6103627a8dd5e86de7a209a9063a8aedea7d6 100644 (file)
@@ -51,6 +51,8 @@ dnl -----------------
 dnl Configure options
 dnl -----------------
 
+AM_PROG_AS
+
 dnl --------------------------
 dnl autoconf output generation
 dnl --------------------------
diff --git a/rdrand_asm.S b/rdrand_asm.S
new file mode 100644 (file)
index 0000000..c5567d8
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011, Intel Corporation
+ * Authors: Fenghua Yu <fenghua.yu@intel.com>,
+ *          H. Peter Anvin <hpa@linux.intel.com>
+ *
+ * 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 */
index 2615df9a4dda7a2a526386be4371afb5cfd2ae18..de0c34a35f85c0064f7b544865db9c14e8ee0f82 100644 (file)
--- a/rngd.8.in
+++ b/rngd.8.in
@@ -14,6 +14,7 @@ rngd \- Check and feed random data from hardware device to kernel random device
 [\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\-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]
@@ -71,6 +72,9 @@ entropy pool.  Low values will hurt system performance during entropy
 starves.  Do not set \fIfill-watermark\fR above the size of the
 entropy pool (usually 4096 bits).
 .TP
+\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
diff --git a/rngd.c b/rngd.c
index 46ae23a904398e23e23a4d7c72b158713e4e412d..9819ed5301c4ba2871b7f55c6ae0b06a056918e6 100644 (file)
--- a/rngd.c
+++ b/rngd.c
@@ -99,8 +99,11 @@ static struct argp_option options[] = {
 
        { "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 },
 };
@@ -111,6 +114,7 @@ static struct arguments default_arguments = {
        .random_step    = 64,
        .fill_watermark = 2048,
        .daemon         = true,
+       .enable_drng    = true,
        .enable_tpm     = true,
        .quiet          = false,
        .verbose        = false,
@@ -123,6 +127,12 @@ static struct rng rng_default = {
        .xread          = xread,
 };
 
+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,
@@ -170,6 +180,14 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
        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))
@@ -240,7 +258,7 @@ static void do_loop(int random_step)
                        rc = update_kernel_random(random_step,
                                             buf, iter->fipsctx);
                        if (rc == 0)
-                               continue;       /* succeeded, work done */
+                               break;  /* succeeded, work done */
 
                        iter->failures++;
                        if (iter->failures == MAX_RNG_FAILURES) {
@@ -267,8 +285,9 @@ static void term_signal(int signo)
 
 int main(int argc, char **argv)
 {
-       int rc_rng = 0;
-       int rc_tpm = 0;
+       int rc_rng = 1;
+       int rc_drng = 1;
+       int rc_tpm = 1;
        int pid_fd = -1;
 
        openlog("rngd", 0, LOG_DAEMON);
@@ -278,10 +297,12 @@ int main(int argc, char **argv)
 
        /* Init entropy sources, and open TRNG device */
        rc_rng = init_entropy_source(&rng_default);
+       if (arguments->enable_drng)
+               rc_drng = init_drng_entropy_source(&rng_drng);
        if (arguments->enable_tpm)
                rc_tpm = init_tpm_entropy_source(&rng_tpm);
 
-       if (rc_rng && rc_tpm) {
+       if (rc_rng && rc_drng && rc_tpm) {
                if (!arguments->quiet) {
                        message(LOG_DAEMON|LOG_ERR,
                                "can't open entropy source(tpm or intel/amd rng)");
@@ -295,11 +316,14 @@ int main(int argc, char **argv)
                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,
diff --git a/rngd.h b/rngd.h
index 69343e97f204cdbf28c7613a0916fa3f3c2fbd68..ca321d681c3754ca2d9bc0780fb8d5674a73253b 100644 (file)
--- a/rngd.h
+++ b/rngd.h
@@ -48,6 +48,7 @@ struct arguments {
        bool quiet;
        bool verbose;
        bool daemon;
+       bool enable_drng;
        bool enable_tpm;
 };
 extern struct arguments *arguments;
index 0b2bb59940fd30af5c8517971bbdf9d7d3df4257..9a37081141c9d62b3eeebbfd2e9a27cd9d6e8be0 100644 (file)
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <syslog.h>
 #include <string.h>
+#include <stddef.h>
 
 #include "rngd.h"
 #include "fips.h"
  * it is 14 bytes.*/
 #define TPM_GET_RNG_OVERHEAD   14
 
+/* Checking eflags to confirm cpuid instruction available */
+/* Only necessary for 32 bit processors */
+#if defined (__i386__)
+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 entropy source */
 int xread(void *buf, size_t size, struct rng *ent_src)
 {
@@ -69,6 +113,59 @@ int xread(void *buf, size_t size, struct rng *ent_src)
        return 0;
 }
 
+/* Initialization vector and msg sizes for standard AES usage */
+#define IV_SIZE                        (16*1)
+#define MSG_SIZE               (16*7)
+#define CHUNK_SIZE             (16*8)
+
+/* Read data from the drng
+ * in chunks of 128 bytes for AES scrambling */
+int xread_drng(void *buf, size_t size, struct rng *ent_src)
+{
+       size_t psize = size;
+       size_t off = 0;
+       ssize_t r = 0;
+       int rdrand_round_count = size / 128;
+
+       static unsigned char iv_buf[IV_SIZE] __attribute__((aligned(128)));
+       static unsigned char m_buf[MSG_SIZE] __attribute__((aligned(128)));
+       static unsigned char tmp[CHUNK_SIZE] __attribute__((aligned(128)));
+       static unsigned char fwd[CHUNK_SIZE] __attribute__((aligned(128)));
+       int i;
+
+       while (size > 0 && size <= psize) {
+               for (i = 0; i < rdrand_round_count && size <= psize; i++) {
+                       if (!x86_rdrand_nlong(iv_buf, sizeof(iv_buf)/sizeof(long))) {
+                               r = -1;
+                               break;
+                       }
+                       if (!x86_rdrand_nlong(m_buf, sizeof(m_buf)/sizeof(long))) {
+                               r = -1;
+                               break;
+                       }
+                       memcpy(tmp, iv_buf, IV_SIZE);
+                       memcpy(tmp+IV_SIZE, m_buf, MSG_SIZE);
+
+                       x86_aes_mangle(tmp, fwd);
+                       r = (sizeof(tmp) > size)? size : sizeof(tmp);
+
+                       if (r <= 0)
+                               break;
+                       memcpy(buf+off, tmp, r);
+                       off += r;
+                       size -= r;
+               }
+               if (r <= 0)
+                       break;
+       }
+
+       if (size > 0 && size < psize) {
+               message(LOG_DAEMON|LOG_ERR, "read error\n");
+               return -1;
+       }
+       return 0;
+}
+
 /* tpm rng read call to kernel has 13 bytes of overhead
  * the logic to process this involves reading to a temporary_buf
  * and copying the no generated to buf */
@@ -88,6 +185,7 @@ int xread_tpm(void *buf, size_t size, struct rng *ent_src)
 
        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 +193,7 @@ int xread_tpm(void *buf, size_t size, struct rng *ent_src)
        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 */
@@ -125,14 +224,13 @@ int xread_tpm(void *buf, size_t size, struct rng *ent_src)
                        goto error_out;
                }
                r = read(ent_src->rng_fd, temp_buf,size);
-               if (r <= 0) {
+               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;
                }
-
-               r = (r - TPM_GET_RNG_OVERHEAD);
                bytes_read = bytes_read + r;
                if (bytes_read > size) {
                        memcpy(offset,temp_buf + TPM_GET_RNG_OVERHEAD,
@@ -159,10 +257,10 @@ static int discard_initial_data(struct rng *ent_src)
         * 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 +282,43 @@ int init_entropy_source(struct rng *ent_src)
        return 0;
 }
 
+/*
+ * Confirm RDRAND capabilities for drng entropy source
+ */
+int init_drng_entropy_source(struct rng *ent_src)
+{
+#if defined (__x86_64__) || defined(__i386__)
+       struct cpuid info;
+       int got_intel_cpu = 0;
+
+#if defined (__i386__)
+       uint32_t flag = 0x200000;
+
+       if(!x86_has_eflag(flag)) return 1; //check 32 bit processor for cpuid
+#endif
+
+       cpuid(0,0, &info);
+       if(memcmp((char *)(&info.ebx), "Genu", 4) == 0 &&
+               memcmp((char *)(&info.edx), "ineI", 4) == 0 &&
+               memcmp((char *)(&info.ecx), "ntel", 4) == 0) {
+                       got_intel_cpu = 1;
+       }
+       if(got_intel_cpu == 0) return 1;
+
+       cpuid(1,0,&info);
+       if ((info.ecx & 0x40000000)!=0x40000000) 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
+       //No intel processor, no drng
+       return 1;
+#endif
+}
+
 /*
  * Open tpm entropy source, and initialize it
  */
@@ -191,8 +326,7 @@ int init_tpm_entropy_source(struct rng *ent_src)
 {
        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);
+               message(LOG_ERR|LOG_INFO,"Unable to open file: %s",ent_src->rng_name);
                return 1;
        }
        src_list_add(ent_src);
index dd1d116d04dbbd52561d11185883f71bbdd846b6..64d8e484baf39c0a3631196eb9c8502af0e1ef6b 100644 (file)
 #include <unistd.h>
 #include <stdint.h>
 
+/* Struct for CPUID return values */
+struct cpuid {
+        uint32_t eax, ecx, edx, ebx;
+};
+
 /* Logic and contexts */
 extern fips_ctx_t fipsctx;             /* Context for the FIPS tests */
 extern fips_ctx_t tpm_fipsctx; /* Context for the tpm FIPS tests */
 
+/* Inline assembly to check eflags */
+/* Only necessary on 32 bit processor */
+#if defined (__i386__)
+int x86_has_eflag(uint32_t flag);
+#endif
+
+/* Inline assembly for CPUID call for RDRAND */
+extern int x86_rdrand_nlong(void *ptr, size_t count);  /* RDRAND-access logic */
+extern void x86_aes_mangle(void *data, void *state);   /* Conditioning RDRAND for seed-grade entropy */
+
 /*
  * Initialize entropy source and entropy conditioning
  *
  * 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 */
index 9b76198490aec56cba3c50ae8d43b54e63d10516..128d5601c21478d2b8424628280dee6581f4091a 100644 (file)
@@ -91,7 +91,6 @@ void random_add_entropy(void *buf, size_t size)
 
 void random_sleep()
 {
-       int ent_count;
        struct pollfd pfd = {
                fd:     random_fd,
                events: POLLOUT,