This uses the trousers daemon to gather entropy from a local TPM
RNG.
Signed-off-by: Kees Cook <[email protected]>
---
Makefile.am | 6 ++++--
configure.ac | 7 ++++++-
rngd.c | 10 ++++++++++
rngd_entsource.c | 34 ++++++++++++++++++++++++++++++++++
rngd_entsource.h | 3 ++-
5 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 921f2a2..af6648a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,13 +9,14 @@ bin_PROGRAMS = rngtest
man_MANS = rngd.8 rngtest.1
noinst_LIBRARIES = librngd.a
-common_sources = exits.h fips.h stats.h util.h viapadlock_engine.h
+common_sources = exits.h fips.h stats.h util.h viapadlock_engine.h \
+ tpm_engine.h
rngd_SOURCES = $(common_sources) rngd.h rngd.c \
rngd_threads.h rngd_threads.c \
rngd_signals.h rngd_signals.c \
rngd_entsource.h rngd_entsource.c \
rngd_linux.h rngd_linux.c
-rngd_LDADD = librngd.a @LIB_PTHREAD@
+rngd_LDADD = librngd.a @LIB_PTHREAD@ @LIB_TSPI@
rngtest_SOURCES = $(common_sources) rngtest.c
rngtest_LDADD = librngd.a
@@ -23,6 +24,7 @@ rngtest_LDADD = librngd.a
librngd_a_SOURCES = fips.h fips.c \
stats.h stats.c \
util.h util.c \
+ tpm_engine.h tpm_engine.c \
viapadlock_engine.h viapadlock_engine.c
diff --git a/configure.ac b/configure.ac
index 89af262..644d3d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,12 +49,17 @@ dnl Checks for required libraries
dnl -----------------------------
AC_CHECK_LIB([pthread], [pthread_create],
[LIB_PTHREAD="-lpthread"],
- [AC_MSG_ERROR([Can't compile without pthreads])])
+ [AC_MSG_ERROR([Can not compile without pthreads])])
AC_SUBST(LIB_PTHREAD)
dnl -------------------------------------
dnl Checks for optional library functions
dnl -------------------------------------
+AC_CHECK_LIB([tspi], [Tspi_Context_Create],
+ [LIB_TSPI="-ltspi"
+ AC_DEFINE(TPM_ENTSOURCE_DRIVER, 1,
+ [Include code for TPM RNG driver]) ], )
+AC_SUBST(LIB_TSPI)
dnl -----------------
dnl Configure options
diff --git a/rngd.c b/rngd.c
index 27781aa..96fe013 100644
--- a/rngd.c
+++ b/rngd.c
@@ -265,6 +265,13 @@ static struct trng_params trng_parameters[] = {
.entropy = 0.0,
.driver = RNGD_ENTSOURCE_VIAPADLOCK,
},
+ { .name = "TPM RNG",
+ .tag = "tpm",
+ .width = 256,
+ .buffers = 1,
+ .entropy = 0.75,
+ .driver = RNGD_ENTSOURCE_TPM,
+ },
{ NULL },
};
@@ -391,6 +398,9 @@ static error_t parse_opt (int key, char *arg, struct
argp_state *state)
if (! (seen_opt & SEEN_OPT_RNGENTROPY))
arguments->rng_entropy = 0.0;
seen_opt |= SEEN_OPT_RNGDRIVER;
+ } else if (strcasecmp(arg, "tpm") == 0) {
+ arguments->rng_driver = RNGD_ENTSOURCE_TPM;
+ seen_opt |= SEEN_OPT_RNGDRIVER;
} else {
argp_usage(state);
}
diff --git a/rngd_entsource.c b/rngd_entsource.c
index ebe2a44..90a62fc 100644
--- a/rngd_entsource.c
+++ b/rngd_entsource.c
@@ -49,6 +49,7 @@
#include "stats.h"
#include "exits.h"
#include "viapadlock_engine.h"
+#include "tpm_engine.h"
#include "rngd_threads.h"
#include "rngd_signals.h"
#include "rngd_entsource.h"
@@ -87,6 +88,8 @@ const char
*entropy_source_driver_name(entropy_source_driver_t driver)
return "UNIX stream";
case RNGD_ENTSOURCE_VIAPADLOCK:
return "VIA PadLock TRNG";
+ case RNGD_ENTSOURCE_TPM:
+ return "TPM RNG";
default:
return "(unknown)";
};
@@ -130,6 +133,12 @@ static int xread(void *buf, size_t size, unsigned int
abortonsigalrm)
break;
}
#endif
+#ifdef TPM_ENTSOURCE_DRIVER
+ case RNGD_ENTSOURCE_TPM: {
+ r = tpm_rng_read((unsigned char *)buf + off,
size);
+ break;
+ }
+#endif
default:
errno = ENXIO;
return -1;
@@ -231,6 +240,31 @@ void init_entropy_source( void )
die(EXIT_USAGE);
#endif /* VIA_ENTSOURCE_DRIVER */
}
+ case RNGD_ENTSOURCE_TPM: {
+#ifdef TPM_ENTSOURCE_DRIVER
+ switch (tpm_rng_init()) {
+ case 0:
+ message(LOG_ERR,
+ "Could not detect a TPM "
+ "RNG, check that TPM is "
+ "available and enabled.");
+ die(EXIT_OSERR);
+ case 1:
+ break;
+ default:
+ message_strerr(LOG_ERR, errno,
+ "Error initializing TPM "
+ "RNG");
+ die(EXIT_OSERR);
+ }
+ break;
+#else
+ message(LOG_ERR,
+ "Support for the TPM RNG entropy source "
+ "driver has not been compiled in.");
+ die(EXIT_USAGE);
+#endif /* TPM_ENTSOURCE_DRIVER */
+ }
default:
message(LOG_ERR,
"Unknown entropy source driver, internal
program error!");
diff --git a/rngd_entsource.h b/rngd_entsource.h
index c51874d..ada4a58 100644
--- a/rngd_entsource.h
+++ b/rngd_entsource.h
@@ -31,7 +31,8 @@
typedef enum {
RNGD_ENTSOURCE_NONE,
RNGD_ENTSOURCE_UNIXSTREAM,
- RNGD_ENTSOURCE_VIAPADLOCK
+ RNGD_ENTSOURCE_VIAPADLOCK,
+ RNGD_ENTSOURCE_TPM,
} entropy_source_driver_t;
extern const char *entropy_source_driver_name(entropy_source_driver_t driver);
--
1.7.2.3
--
Kees Cook @debian.org
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]