aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Hill <richard.b.hill@intel.com>2012-07-31 12:26:51 -0400
committerJeff Garzik <jgarzik@redhat.com>2012-07-31 12:26:51 -0400
commit2a01453686f065ac95916fe49a02407914e05dd4 (patch)
treec6b8cc3c65913c3eabf2032a4bc8f163d0755edb
parenta9b9bb1df997bd979ad2c6f1f72563d8eec7930b (diff)
downloadrng-tools-2a01453686f065ac95916fe49a02407914e05dd4.tar.gz
Add RDRAND support
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac2
-rw-r--r--rdrand_asm.S195
-rw-r--r--rngd.8.in4
-rw-r--r--rngd.c34
-rw-r--r--rngd.h1
-rw-r--r--rngd_entsource.c148
-rw-r--r--rngd_entsource.h17
-rw-r--r--rngd_linux.c1
9 files changed, 390 insertions, 14 deletions
diff --git a/Makefile.am b/Makefile.am
index 6822181..b86042e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
diff --git a/configure.ac b/configure.ac
index 7b4a409..aff6103 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
index 0000000..c5567d8
--- /dev/null
+++ b/rdrand_asm.S
@@ -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 */
diff --git a/rngd.8.in b/rngd.8.in
index 2615df9..de0c34a 100644
--- 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 46ae23a..9819ed5 100644
--- 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 69343e9..ca321d6 100644
--- 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;
diff --git a/rngd_entsource.c b/rngd_entsource.c
index 0b2bb59..9a37081 100644
--- a/rngd_entsource.c
+++ b/rngd_entsource.c
@@ -35,6 +35,7 @@
#include <errno.h>
#include <syslog.h>
#include <string.h>
+#include <stddef.h>
#include "rngd.h"
#include "fips.h"
@@ -46,6 +47,49 @@
* 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);
@@ -185,14 +283,50 @@ int init_entropy_source(struct rng *ent_src)
}
/*
+ * 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
*/
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);
diff --git a/rngd_entsource.h b/rngd_entsource.h
index dd1d116..64d8e48 100644
--- a/rngd_entsource.h
+++ b/rngd_entsource.h
@@ -26,20 +26,37 @@
#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 */
diff --git a/rngd_linux.c b/rngd_linux.c
index 9b76198..128d560 100644
--- a/rngd_linux.c
+++ b/rngd_linux.c
@@ -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,