Skip to content

Commit

Permalink
Adding rtlsdr entropy source
Browse files Browse the repository at this point in the history
With the availability of inexpensive software defined radios, we can use
them to gather random static noise as an entropy source.  Leverage the
rtlsdr library to access these devices and gather that entropy

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
  • Loading branch information
nhorman authored and Neil Horman committed Mar 7, 2020
1 parent 4d0a1bd commit 865277d
Show file tree
Hide file tree
Showing 8 changed files with 351 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Expand Up @@ -18,6 +18,9 @@ addons:
libssl-dev
libcurl3-dev
libp11-dev
librtlsdr-dev
libusb-1.0-0-dev


script: rm -rf ./jitterentropy-library/* && ./autogen.sh && ./configure && make

Expand Down
8 changes: 6 additions & 2 deletions Makefile.am
Expand Up @@ -27,14 +27,18 @@ if JITTER
rngd_SOURCES += rngd_jitter.c
endif

rngd_LDADD = librngd.a -lsysfs $(LIBS) ${libp11_LIBS} ${libcrypto_LIBS} ${libcurl_LIBS} ${libxml2_LIBS} ${openssl_LIBS} $(PTHREAD_LIBS)
if RTLSDR
rngd_SOURCES += rngd_rtlsdr.c
endif

rngd_LDADD = librngd.a -lsysfs $(LIBS) $(librtlsdr_LIBS) ${libp11_LIBS} ${libcrypto_LIBS} ${libcurl_LIBS} ${libxml2_LIBS} ${openssl_LIBS} $(PTHREAD_LIBS)

if PKCS11
rngd_SOURCES += rngd_pkcs11.c
pkcs11_ENGINE = -DDEFAULT_PKCS11_ENGINE=\"$(PKCS11_ENGINE)\"
endif

rngd_CFLAGS = ${pkcs11_CFLAGS} ${pkcs11_ENGINE} ${libp11_CFLAGS} ${libcrypto_CFLAGS} ${libxml2_CFLAGS} ${openssl_CFLAGS} $(PTHREAD_CFLAGS)
rngd_CFLAGS = ${pkcs11_CFLAGS} $(librtlsdr_CFLAGS) ${pkcs11_ENGINE} ${libp11_CFLAGS} ${libcrypto_CFLAGS} ${libxml2_CFLAGS} ${openssl_CFLAGS} $(PTHREAD_CFLAGS)
rngd_LDFLAGS = $(PTHREAD_CFLAGS)

rngtest_SOURCES = exits.h stats.h stats.c rngtest.c
Expand Down
36 changes: 22 additions & 14 deletions configure.ac
Expand Up @@ -41,6 +41,13 @@ AC_ARG_WITH([pkcs11],
[with_pkcs11=check]
)

AC_ARG_WITH([rtlsdr],
AS_HELP_STRING([--without-rtlsdr],
[Disable rtlsdr support. ])
[],
[with_rtlsdr=no]
)

AC_ARG_WITH([libargp],
AS_HELP_STRING([--without-libargp],
[Disable libargp support. Systems whose libc lacks argp can use libargp instead. (Default: check if libc lacks argp)]),
Expand Down Expand Up @@ -103,29 +110,30 @@ AS_IF(
PKG_CHECK_MODULES([libp11], [libp11], [], [AC_MSG_ERROR([libp11 is required])])
PKG_CHECK_MODULES([libcrypto], [libcrypto], [], [AC_MSG_ERROR([libcrypto is required])])
AC_DEFINE([HAVE_PKCS11],1,[Enable PKCS11])
AS_CASE([$host_cpu],
[i?86|armv7hl],
[
PKCS11_ENGINE=/usr/lib/opensc-pkcs11.so
],
[
PKCS11_ENGINE=/usr/lib64/opensc-pkcs11.so
])
AC_SUBST([PKCS11_ENGINE])
AS_CASE([$host_cpu],
[i?86|armv7hl],
[
PKCS11_ENGINE=/usr/lib/opensc-pkcs11.so
],
[
PKCS11_ENGINE=/usr/lib64/opensc-pkcs11.so
])
AC_SUBST([PKCS11_ENGINE])
]
)

AS_IF(
[ test "x$with_rtlsdr" != "xno"],
[
PKG_CHECK_MODULES([librtlsdr], [librtlsdr], [], [AC_MSG_ERROR([librtlsdr is required])])
AC_DEFINE([HAVE_RTLSDR],1,[Enable RTLSDR])
]
[ test "x$with_rtlsdr" != "xno"],
[
PKG_CHECK_MODULES([librtlsdr], [librtlsdr], [], [AC_MSG_ERROR([librtlsdr is required])])
AC_DEFINE([HAVE_RTLSDR],1,[Enable RTLSDR])
]
)

PKG_CHECK_MODULES([openssl], [openssl], [], [AC_MSG_ERROR([openssl is required])])
AM_CONDITIONAL([NISTBEACON], [test "x$with_nistbeacon" != "xno"])
AM_CONDITIONAL([PKCS11], [test "x$with_pkcs11" != "xno"])
AM_CONDITIONAL([RTLSDR], [test "x$with_rtlsdr" != "xno"])

dnl Checks for header files.
dnl AC_HEADER_STDC
Expand Down
19 changes: 19 additions & 0 deletions rngd.8.in
Expand Up @@ -192,6 +192,25 @@ Options
be requested at a time, this option allows for the request to be subdivided into
smaller chunks to be satisfied

.TP
.B
RTLSDR (rtlsdr) [Index 7]
Entropy gathered via the rtl software defined radio library, which can gather
entropy using various usb software defined radios listening to random radio
static
.TP
Options
\fBdevid - \fR When multiple devices are available the integer index of the
device to use

\fBfreq_min - \fR The minimum frequence range to scan in

\fBfreq_max - \fR The maximum frequency range to scan in

\fBsample_min - \fR The minimum sample rate of the radio

\fBsample_max - \fR The maximum sample rate of the radio

.SH AUTHORS
Philipp Rumpf
.br
Expand Down
88 changes: 66 additions & 22 deletions rngd.c
Expand Up @@ -152,6 +152,7 @@ static enum {
ENT_NISTBEACON,
ENT_JITTER,
ENT_PKCS11,
ENT_RTLSDR,
ENT_MAX
} entropy_indexes __attribute__((used));

Expand Down Expand Up @@ -234,38 +235,66 @@ static struct rng_option pkcs11_options[] = {
}
};

static struct rng_option rtlsdr_options[] = {
[RTLSDR_OPT_DEVID] = {
.key = "device_id",
.type = VAL_INT,
.int_val = 0,
},
[RTLSDR_OPT_FREQ_MIN] = {
.key = "freq_min",
.type = VAL_INT,
.int_val = 90000000,
},
[RTLSDR_OPT_FREQ_MAX] = {
.key = "freq_max",
.type = VAL_INT,
.int_val = 110000000,
},
[RTLSDR_OPT_SRATE_MIN] = {
.key = "sample_min",
.type = VAL_INT,
.int_val = 1000000,
},
[RTLSDR_OPT_SRATE_MAX] = {
.key = "sample_max",
.type = VAL_INT,
.int_val = 2800000,
}
};

static struct rng entropy_sources[ENT_MAX] = {
/* Note, the special char dev must be the first entry */
{
.rng_name = "Hardware RNG Device",
.rng_sname = "hwrng",
.rng_fname = "/dev/hwrng",
.rng_fd = -1,
.rng_fd = -1,
.flags = { 0 },
.xread = xread,
.init = init_entropy_source,
.xread = xread,
.init = init_entropy_source,
.rng_options = NULL,
},
/* must be at index 1 */
{
.rng_name = "TPM RNG Device",
.rng_sname = "tpm",
.rng_fname = "/dev/tpm0",
.rng_fd = -1,
.rng_fd = -1,
.flags = { 0 },
.xread = xread_tpm,
.init = init_tpm_entropy_source,
.xread = xread_tpm,
.init = init_tpm_entropy_source,
.rng_options = NULL,
.disabled = true,
},
{
.rng_name = "Intel RDRAND Instruction RNG",
.rng_sname = "rdrand",
.rng_fd = -1,
.rng_fd = -1,
.flags = { 0 },
#ifdef HAVE_RDRAND
.xread = xread_drng,
.init = init_drng_entropy_source,
.xread = xread_drng,
.init = init_drng_entropy_source,
#else
.disabled = true,
#endif
Expand All @@ -274,11 +303,11 @@ static struct rng entropy_sources[ENT_MAX] = {
{
.rng_name = "Power9 DARN Instruction RNG",
.rng_sname = "darn",
.rng_fd = -1,
.rng_fd = -1,
.flags = { 0 },
#ifdef HAVE_DARN
.xread = xread_darn,
.init = init_darn_entropy_source,
.xread = xread_darn,
.init = init_darn_entropy_source,
#else
.disabled = true,
#endif
Expand Down Expand Up @@ -330,6 +359,21 @@ static struct rng entropy_sources[ENT_MAX] = {
#endif
.rng_options = pkcs11_options,
},
{
.rng_name = "RTLSDR software defined radio generator",
.rng_sname = "rtlsdr",
.rng_fd = -1,
.flags = { 0 },
#ifdef HAVE_RTLSDR
.xread = xread_rtlsdr,
.init = init_rtlsdr_entropy_source,
.close = close_rtlsdr_entropy_source,
#else
.disabled = false,
#endif
.rng_options = rtlsdr_options,
}

};

static int find_ent_src_idx_by_sname(const char *sname)
Expand Down Expand Up @@ -537,7 +581,7 @@ static int update_kernel_random(struct rng *rng, int random_step,
int rc;

fips = fips_run_rng_test(fipsctx_in, buf);
if (fips)
if (fips && !arguments->ignorefail)
return 1;

for (p = buf; p + random_step <= &buf[FIPS_RNG_BUFFER_SIZE];
Expand Down Expand Up @@ -725,16 +769,16 @@ static int discard_initial_data(struct rng *ent_src)

void close_all_entropy_sources()
{
struct rng *ent_src;
struct rng *ent_src;
int i;
for (i=0; i < ENT_MAX; i++) {
ent_src = &entropy_sources[i];
if (ent_src->disabled == false)
message_entsrc(ent_src, LOG_DAEMON|LOG_INFO, "Shutting down\n");
ent_src = &entropy_sources[i];
if (ent_src->disabled == false)
message_entsrc(ent_src, LOG_DAEMON|LOG_INFO, "Shutting down\n");
if (ent_src->close && ent_src->disabled == false) {
ent_src->close(ent_src);
free(ent_src->fipsctx);
}
}
}
}

Expand All @@ -744,7 +788,7 @@ int main(int argc, char **argv)
int ent_sources = 0;
pid_t pid_fd = -1;
double test_time;
struct rng *ent_src;
struct rng *ent_src;

openlog("rngd", 0, LOG_DAEMON);

Expand Down Expand Up @@ -789,15 +833,15 @@ int main(int argc, char **argv)
/* Init entropy sources */

for (i=0; i < ENT_MAX; i++) {
ent_src = &entropy_sources[i];
ent_src = &entropy_sources[i];
if (ent_src->init && ent_src->disabled == false) {
if (!ent_src->init(ent_src)) {
ent_sources++;
ent_src->fipsctx = malloc(sizeof(fips_ctx_t));
fips_init(ent_src->fipsctx, discard_initial_data(ent_src));
message_entsrc(ent_src, LOG_DAEMON|LOG_INFO, "Initialized\n");
message_entsrc(ent_src, LOG_DAEMON|LOG_INFO, "Initialized\n");
} else {
message_entsrc(ent_src, LOG_DAEMON|LOG_ERR, "Initialization Failed\n");
message_entsrc(ent_src, LOG_DAEMON|LOG_ERR, "Initialization Failed\n");
ent_src->disabled = true;
}
}
Expand Down
12 changes: 12 additions & 0 deletions rngd.h
Expand Up @@ -98,6 +98,18 @@ enum {
PKCS11_OPT_CHUNK = 1,
};

/*
* RTLSDR options
*/
enum {
RTLSDR_OPT_DEVID = 0,
RTLSDR_OPT_FREQ_MIN = 1,
RTLSDR_OPT_FREQ_MAX = 2,
RTLSDR_OPT_SRATE_MIN = 3,
RTLSDR_OPT_SRATE_MAX = 4,
RTLSDR_OPT_MAX,
};

enum option_val_type {
VAL_INT = 0,
VAL_STRING = 1,
Expand Down
8 changes: 8 additions & 0 deletions rngd_entsource.h
Expand Up @@ -54,6 +54,10 @@ extern void cache_jitter_entropy_data(struct rng *);
extern int init_pkcs11_entropy_source(struct rng *);
extern void close_pkcs11_entropy_source(struct rng *);
#endif
#ifdef HAVE_RTLSDR
extern int init_rtlsdr_entropy_source(struct rng *);
extern void close_rtlsdr_entropy_source(struct rng *);
#endif

extern int init_tpm_entropy_source(struct rng *);

Expand All @@ -75,6 +79,10 @@ extern int xread_jitter(void *buf, size_t size, struct rng *ent_src);
extern int xread_pkcs11(void *buf, size_t size, struct rng *ent_src);
#endif

#ifdef HAVE_RTLSDR
extern int xread_rtlsdr(void *buf, size_t size, struct rng *ent_src);
#endif

extern int xread_nist(void *buf, size_t size, struct rng *ent_src);

extern int xread_tpm(void *buf, size_t size, struct rng *ent_src);
Expand Down

0 comments on commit 865277d

Please sign in to comment.