Update .service file and add patches

Update the rngd.service file and add 3 small upstream patches fixing issues.

Resolves: rhbz#1965318

Signed-off-by: Vladis Dronov <vdronov@redhat.com>
This commit is contained in:
Vladis Dronov 2021-05-24 16:54:48 +00:00
parent cb4f65d339
commit cd392c8a78
5 changed files with 933 additions and 3 deletions

View File

@ -0,0 +1,33 @@
From d989f5690037eb2162eeea7352a7f8eeecc7989b Mon Sep 17 00:00:00 2001
From: Nikolai Kostrigin <nickel@altlinux.org>
Date: Fri, 12 Mar 2021 15:11:42 +0300
Subject: Improve rngd console output readability
Prevent messing "None" status message with next section header:
"[...]
Entropy sources that are available but disabled
NoneAvailable and enabled entropy sources:
4: NIST Network Entropy Beacon (nist)
[...]"
Signed-off-by: Nikolai Kostrigin <nickel@altlinux.org>
---
rngd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rngd.c b/rngd.c
index c770259..7d31e68 100644
--- a/rngd.c
+++ b/rngd.c
@@ -860,7 +860,7 @@ int main(int argc, char **argv)
entropy_sources[i].failed_init = false;
}
if (!found)
- message(LOG_CONS|LOG_INFO, "None");
+ message(LOG_CONS|LOG_INFO, "None\n");
msg_squash = true;
} else
message(LOG_DAEMON|LOG_INFO, "Initializing available sources\n");
--
2.26.3

View File

@ -0,0 +1,26 @@
From e00e2155ad04f8b3a964fd482bddd8c27b5b9999 Mon Sep 17 00:00:00 2001
From: Jan Palus <jpalus@fastmail.com>
Date: Tue, 4 May 2021 23:50:47 +0200
Subject: try to build with rtlsdr by default
Fixes #125
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 0e04cb8..c4f15d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,7 +45,7 @@ AC_ARG_WITH([rtlsdr],
AS_HELP_STRING([--without-rtlsdr],
[Disable rtlsdr support. ]),
[],
- [with_rtlsdr=no]
+ [with_rtlsdr=check]
)
AC_ARG_WITH([libargp],
--
2.26.3

View File

@ -0,0 +1,864 @@
From 0f0580f3ae98fecf41de4a0346f5e11f390418b7 Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@amazon.com>
Date: Fri, 21 May 2021 13:46:42 +1000
Subject: Create helpers for openssl AES use
This moves the openssl code that is duplicated in several sources
to some helpers. This also fixes the use of "strlen" on raw random
data which probably didn't do what someone thought it did ...
Signed-off-by: Benjamin Herrenschmidt <benh@amazon.com>
---
Makefile.am | 2 +-
ossl_helpers.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++
ossl_helpers.h | 58 ++++++++++++++++++++++
rngd_darn.c | 90 +++++-----------------------------
rngd_jitter.c | 73 +++------------------------
rngd_nistbeacon.c | 84 ++++++-------------------------
rngd_rdrand.c | 93 +++++------------------------------
rngd_rtlsdr.c | 54 +++++++-------------
8 files changed, 246 insertions(+), 330 deletions(-)
create mode 100644 ossl_helpers.c
create mode 100644 ossl_helpers.h
diff --git a/Makefile.am b/Makefile.am
index fbeff32..6f938bc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,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 ossl_helpers.c
if NISTBEACON
rngd_SOURCES += rngd_nistbeacon.c
diff --git a/ossl_helpers.c b/ossl_helpers.c
new file mode 100644
index 0000000..c3c1fbb
--- /dev/null
+++ b/ossl_helpers.c
@@ -0,0 +1,122 @@
+/*
+ * ossl_helpers.c -- Helper wrappers around openssl functions
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "ossl_helpers.h"
+
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+struct ossl_aes_ctx
+{
+ EVP_CIPHER_CTX *c;
+ const unsigned char *key;
+ const unsigned char *iv;
+};
+
+void ossl_aes_random_key(unsigned char *key, const unsigned char *pepper)
+{
+ static unsigned char default_key[AES_BLOCK] = {
+ 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
+ 0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0
+ }; /* AES data reduction key */
+ unsigned char stack_junk[AES_BLOCK];
+ int fd, i;
+
+ /* Try getting some randomness from the kernel */
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd >= 0) {
+ int r = read(fd, key, sizeof key);
+ close(fd);
+ }
+
+ /* Mix in our default key */
+ for (i = 0; i < AES_BLOCK && pepper; i++)
+ key[i] ^= default_key[i];
+
+ /* Mix in stack junk */
+ for (i = 0; i < AES_BLOCK && pepper; i++)
+ key[i] ^= stack_junk[i];
+
+ /* Spice it up if we can */
+ for (i = 0; i < AES_BLOCK && pepper; i++)
+ key[i] ^= pepper[i];
+}
+
+
+struct ossl_aes_ctx *ossl_aes_init(const unsigned char *key,
+ const unsigned char *iv)
+{
+ struct ossl_aes_ctx *ctx;
+
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx)
+ return NULL;
+
+ ctx->c = EVP_CIPHER_CTX_new();
+ if (!ctx->c) {
+ free(ctx);
+ return NULL;
+ }
+ ctx->key = key;
+ ctx->iv = iv;
+ return ctx;
+}
+
+void ossl_aes_exit(struct ossl_aes_ctx *ctx)
+{
+ EVP_CIPHER_CTX_free(ctx->c);
+ free(ctx);
+}
+
+int ossl_aes_encrypt(struct ossl_aes_ctx *ctx,
+ unsigned char *plaintext, int plaintext_len,
+ unsigned char *ciphertext)
+{
+ int len, ciphertext_len;
+
+ if(1 != EVP_EncryptInit_ex(ctx->c, EVP_aes_128_cbc(), NULL, ctx->key, ctx->iv))
+ return 0;
+
+ /*
+ * Provide the message to be encrypted, and obtain the encrypted output.
+ * EVP_EncryptUpdate can be called multiple times if necessary
+ */
+ if(1 != EVP_EncryptUpdate(ctx->c, ciphertext, &len, plaintext, plaintext_len))
+ return 0;
+
+ ciphertext_len = len;
+
+ /*
+ * Finalise the encryption. Further ciphertext bytes may be written at
+ * this stage.
+ */
+ if(1 != EVP_EncryptFinal_ex(ctx->c, ciphertext + len, &len))
+ return 0;
+ ciphertext_len += len;
+
+ return ciphertext_len;
+}
+
diff --git a/ossl_helpers.h b/ossl_helpers.h
new file mode 100644
index 0000000..e21e331
--- /dev/null
+++ b/ossl_helpers.h
@@ -0,0 +1,58 @@
+/*
+ * ossl_helpers.h -- Helper wrappers around openssl functions
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+ */
+
+#ifndef OSSL_HELPERS__H
+#define OSSL_HELPERS__H
+
+#define AES_BLOCK 16
+
+struct ossl_aes_ctx;
+
+extern int ossl_aes_encrypt(struct ossl_aes_ctx *ctx,
+ unsigned char *plaintext, int plaintext_len,
+ unsigned char *ciphertext);
+
+extern struct ossl_aes_ctx *ossl_aes_init(const unsigned char *key,
+ const unsigned char *iv);
+extern void ossl_aes_exit(struct ossl_aes_ctx *ctx);
+extern void ossl_aes_random_key(unsigned char *key, const unsigned char *pepper);
+
+static inline int ossl_aes_mangle(struct ossl_aes_ctx *ctx, unsigned char *data,
+ size_t size)
+{
+ int ciphertext_len;
+
+ /*
+ * Buffer for ciphertext. Ensure the buffer is long enough for the
+ * ciphertext which may be longer than the plaintext, depending on the
+ * algorithm and mode.
+ *
+ * For AES, one extra AES block should be sufficient.
+ */
+ unsigned char ciphertext[size + AES_BLOCK];
+
+ /* Encrypt the plaintext */
+ ciphertext_len = ossl_aes_encrypt(ctx, data, size, ciphertext);
+ if (!ciphertext_len)
+ return -1;
+
+ memcpy(data, ciphertext, size);
+ return ciphertext_len;
+}
+
+#endif /* OSSL_HELPERS__H */
diff --git a/rngd_darn.c b/rngd_darn.c
index f6b9cd4..bc8edec 100644
--- a/rngd_darn.c
+++ b/rngd_darn.c
@@ -29,15 +29,12 @@
#include <string.h>
#include <limits.h>
#include <sys/auxv.h>
-#include <openssl/conf.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
#include "rngd.h"
#include "fips.h"
#include "exits.h"
#include "rngd_entsource.h"
+#include "ossl_helpers.h"
#define min(x,y) ({ \
typeof(x) _x = (x); \
@@ -49,18 +46,13 @@ static uint64_t get_darn();
static int refill_rand(struct rng *ent_src, bool allow_reinit);
static size_t copy_avail_rand_to_buf(unsigned char *buf, size_t size, size_t copied);
-#define AES_BLOCK 16
#define CHUNK_SIZE AES_BLOCK * 8
#define RDRAND_ROUNDS 512 /* 512:1 data reduction */
-
-static unsigned char key[AES_BLOCK] = {
- 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
- 0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0
-}; /* AES data reduction key */
-
#define THRESH_BITS 14
-static EVP_CIPHER_CTX *ctx = NULL;
+/* ossl AES context */
+static struct ossl_aes_ctx *ossl_ctx;
+static unsigned char key[AES_BLOCK];
static unsigned char iv_buf[AES_BLOCK];
static unsigned char darn_rand_buf[CHUNK_SIZE];
@@ -72,15 +64,10 @@ static size_t rand_bytes_served = 0;
static int init_openssl(struct rng *ent_src)
{
- unsigned char xkey[AES_BLOCK];
- int i;
uint64_t darn_val;
+ int i;
- /*
- * Use stack junk to create a key, shuffle it a bit
- */
- for (i=0; i< sizeof(key); i++)
- key[i] ^= xkey[i];
+ ossl_aes_random_key(key, NULL);
darn_val = get_darn();
if (darn_val == ULONG_MAX)
@@ -92,13 +79,11 @@ static int init_openssl(struct rng *ent_src)
return 1;
memcpy(&iv_buf[8], &darn_val, sizeof(uint64_t));
- if (ctx != NULL) {
- /* Clean up */
- EVP_CIPHER_CTX_free(ctx);
- }
- if(!(ctx = EVP_CIPHER_CTX_new()))
- return 1;
-
+ if (ossl_ctx != NULL)
+ ossl_aes_exit(ossl_ctx);
+ ossl_ctx = ossl_aes_init(key, iv_buf);
+ if (!ossl_ctx)
+ return 1;
rand_bytes_served = 0;
if (refill_rand(ent_src, false))
return 1;
@@ -109,56 +94,6 @@ static int init_openssl(struct rng *ent_src)
return 0;
}
-static int osslencrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
- unsigned char *iv, unsigned char *ciphertext)
-{
- int len;
-
- int ciphertext_len;
-
- if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
- return 0;
- /*
- * Provide the message to be encrypted, and obtain the encrypted output.
- * EVP_EncryptUpdate can be called multiple times if necessary
- */
- if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
- return 0;
-
- ciphertext_len = len;
-
- /*
- * Finalise the encryption. Further ciphertext bytes may be written at
- * this stage.
- */
- if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
- return 0;
- ciphertext_len += len;
-
- return ciphertext_len;
-}
-
-static inline int openssl_mangle(unsigned char *tmp, size_t size, struct rng *ent_src)
-{
- int ciphertext_len;
-
- /*
- * Buffer for ciphertext. Ensure the buffer is long enough for the
- * ciphertext which may be longer than the plaintext, depending on the
- * algorithm and mode.
- */
- unsigned char ciphertext[CHUNK_SIZE * RDRAND_ROUNDS];
-
- /* Encrypt the plaintext */
- ciphertext_len = osslencrypt (tmp, size, key, iv_buf,
- ciphertext);
- if (!ciphertext_len)
- return -1;
-
- memcpy(tmp, ciphertext, size);
- return 0;
-}
-
static int refill_rand(struct rng *ent_src, bool allow_reinit)
{
int i;
@@ -172,9 +107,8 @@ static int refill_rand(struct rng *ent_src, bool allow_reinit)
return 1;
}
- if (openssl_mangle(darn_rand_buf, CHUNK_SIZE, ent_src)) {
+ if (ossl_aes_mangle(ossl_ctx, darn_rand_buf, CHUNK_SIZE) < 0)
return 1;
- }
} else {
uint64_t *ptr = (uint64_t *)darn_rand_buf;
for (i = 0; i < CHUNK_SIZE/sizeof(uint64_t); i++) {
diff --git a/rngd_jitter.c b/rngd_jitter.c
index c803f0d..133c7e4 100644
--- a/rngd_jitter.c
+++ b/rngd_jitter.c
@@ -27,9 +27,6 @@
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
-#include <openssl/conf.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
#include "rng-tools-config.h"
@@ -39,9 +36,9 @@
#include "fips.h"
#include "exits.h"
#include "rngd_entsource.h"
+#include "ossl_helpers.h"
/* Read data from the drng in chunks of 128 bytes for AES scrambling */
-#define AES_BLOCK 16
#define CHUNK_SIZE (AES_BLOCK*8) /* 8 parallel streams */
#define RDRAND_ROUNDS 512 /* 512:1 data reduction */
@@ -71,65 +68,7 @@ unsigned char *aes_buf;
static char key[AES_BLOCK];
static unsigned char iv_buf[CHUNK_SIZE] __attribute__((aligned(128)));
-
-static int osslencrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
- unsigned char *iv, unsigned char *ciphertext)
-{
- EVP_CIPHER_CTX *ctx;
-
- int len;
-
- int ciphertext_len;
-
- /* Create and initialise the context */
- if(!(ctx = EVP_CIPHER_CTX_new()))
- return 0;
-
- if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
- return 0;
- /*
- * Provide the message to be encrypted, and obtain the encrypted output.
- * EVP_EncryptUpdate can be called multiple times if necessary
- */
- if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
- return 0;
-
- ciphertext_len = len;
-
- /*
- * Finalise the encryption. Further ciphertext bytes may be written at
- * this stage.
- */
- if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
- return 0;
- ciphertext_len += len;
-
- /* Clean up */
- EVP_CIPHER_CTX_free(ctx);
-
- return ciphertext_len;
-}
-
-static inline int openssl_mangle(unsigned char *tmp, struct rng *ent_src)
-{
- int ciphertext_len;
-
- /*
- * Buffer for ciphertext. Ensure the buffer is long enough for the
- * ciphertext which may be longer than the plaintext, depending on the
- * algorithm and mode.
- */
- unsigned char ciphertext[CHUNK_SIZE * RDRAND_ROUNDS];
-
- /* Encrypt the plaintext */
- ciphertext_len = osslencrypt (tmp, strlen(tmp), key, iv_buf,
- ciphertext);
- if (!ciphertext_len)
- return -1;
-
- memcpy(tmp, ciphertext, strlen(tmp));
- return 0;
-}
+static struct ossl_aes_ctx *ossl_ctx;
int xread_jitter(void *buf, size_t size, struct rng *ent_src)
{
@@ -152,7 +91,7 @@ try_again:
while(need) {
request = (need >= current->buf_sz) ? current->buf_sz : need;
memcpy(buf, &aes_buf[total], request);
- openssl_mangle(aes_buf, ent_src);
+ ossl_aes_mangle(ossl_ctx, aes_buf, request);
need -= request;
total += request;
}
@@ -462,6 +401,7 @@ int init_jitter_entropy_source(struct rng *ent_src)
} else {
/* re-enable AES */
ent_src->rng_options[JITTER_OPT_USE_AES].int_val = 1;
+ ossl_ctx = ossl_aes_init(key, iv_buf);
}
xread_jitter(aes_buf, tdata[0].buf_sz, ent_src);
} else {
@@ -511,6 +451,9 @@ void close_jitter_entropy_source(struct rng *ent_src)
close(pipefds[0]);
free(tdata);
free(threads);
- return;
+ if (ossl_ctx) {
+ ossl_aes_exit(ossl_ctx);
+ ossl_ctx = NULL;
+ }
}
diff --git a/rngd_nistbeacon.c b/rngd_nistbeacon.c
index 5195d33..5d51d44 100644
--- a/rngd_nistbeacon.c
+++ b/rngd_nistbeacon.c
@@ -56,6 +56,7 @@
#include "fips.h"
#include "exits.h"
#include "rngd_entsource.h"
+#include "ossl_helpers.h"
#define NIST_RECORD_URL "https://beacon.nist.gov/beacon/2.0/pulse/last"
#define NIST_CERT_BASE_URL "https://beacon.nist.gov/beacon/2.0/certificate/"
@@ -133,75 +134,11 @@ X509 *cert = NULL;
EVP_PKEY *pubkey;
uint64_t lastpulse = 0;
-#define AES_BLOCK 16
#define CHUNK_SIZE (AES_BLOCK*8) /* 8 parallel streams */
#define RDRAND_ROUNDS 512 /* 512:1 data reduction */
-static unsigned char key[AES_BLOCK] = {0,};
-
-static int osslencrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
- unsigned char *iv, unsigned char *ciphertext)
-{
- EVP_CIPHER_CTX *ctx;
-
- int len;
-
- int ciphertext_len;
-
- /* Create and initialise the context */
- if(!(ctx = EVP_CIPHER_CTX_new()))
- return 0;
-
- if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
- return 0;
- /*
- * Provide the message to be encrypted, and obtain the encrypted output.
- * EVP_EncryptUpdate can be called multiple times if necessary
- */
- if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
- return 0;
-
- ciphertext_len = len;
-
- /*
- * Finalise the encryption. Further ciphertext bytes may be written at
- * this stage.
- */
- if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
- return 0;
- ciphertext_len += len;
-
- /* Clean up */
- EVP_CIPHER_CTX_free(ctx);
-
- return ciphertext_len;
-}
-
-static inline int openssl_mangle(unsigned char *tmp, size_t size, struct rng *ent_src)
-{
- unsigned char xkey[AES_BLOCK]; /* Material to XOR into the key */
- unsigned char iv_buf[CHUNK_SIZE];
- int i;
- int ciphertext_len;
-
- /*
- * Buffer for ciphertext. Ensure the buffer is long enough for the
- * ciphertext which may be longer than the plaintext, depending on the
- * algorithm and mode.
- */
- unsigned char ciphertext[CHUNK_SIZE * RDRAND_ROUNDS];
-
- for(i=0; i < AES_BLOCK; i++)
- key[i] = key[i] ^ xkey[i];
-
- /* Encrypt the plaintext */
- ciphertext_len = osslencrypt (tmp, size, key, iv_buf,
- ciphertext);
- if (!ciphertext_len)
- return -1;
-
- memcpy(tmp, ciphertext, size);
- return 0;
-}
+static unsigned char mangle_key[AES_BLOCK];
+static unsigned char mangle_iv_buf[CHUNK_SIZE];
+static struct ossl_aes_ctx *ossl_ctx;
static int refill_rand(struct rng *ent_src)
{
@@ -220,7 +157,7 @@ static int refill_rand(struct rng *ent_src)
}
if (block.pulseIndex == lastpulse) {
if (ent_src->rng_options[NIST_OPT_USE_AES].int_val) {
- if (openssl_mangle(nist_rand_buf, NIST_BUF_SIZE, ent_src) != 0) {
+ if (ossl_aes_mangle(ossl_ctx, nist_rand_buf, NIST_BUF_SIZE) < 0) {
message_entsrc(ent_src, LOG_DAEMON|LOG_DEBUG, "Failed mangle\n");
return 1;
}
@@ -712,6 +649,17 @@ int init_nist_entropy_source(struct rng *ent_src)
int rc;
memset(&block, 0, sizeof (struct nist_data_block));
+ if (ent_src->rng_options[NIST_OPT_USE_AES].int_val) {
+ unsigned char *p;
+ int i;
+
+ ossl_aes_random_key(mangle_key, NULL);
+ for (i = 0, p = mangle_iv_buf; i < 8; i++, p += AES_BLOCK)
+ ossl_aes_random_key(p, NULL);
+
+ ossl_ctx = ossl_aes_init(mangle_key, mangle_iv_buf);
+ }
+
rc = refill_rand(ent_src);
if (!rc) {
message_entsrc(ent_src,LOG_DAEMON|LOG_WARNING, "WARNING: NIST Randomness beacon "
diff --git a/rngd_rdrand.c b/rngd_rdrand.c
index b1f597c..cba27a9 100644
--- a/rngd_rdrand.c
+++ b/rngd_rdrand.c
@@ -37,24 +37,22 @@
#include <syslog.h>
#include <string.h>
#include <stddef.h>
-#include <openssl/conf.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
#include "rngd.h"
#include "fips.h"
#include "exits.h"
#include "rngd_entsource.h"
+#include "ossl_helpers.h"
/* Read data from the drng in chunks of 128 bytes for AES scrambling */
-#define AES_BLOCK 16
#define CHUNK_SIZE (AES_BLOCK*8) /* 8 parallel streams */
#define RDRAND_ROUNDS 512 /* 512:1 data reduction */
-static unsigned char key[AES_BLOCK] = {
- 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
- 0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0
-}; /* AES data reduction key */
+/* AES data reduction key */
+static unsigned char key[AES_BLOCK];
+
+/* ossl AES context */
+static struct ossl_aes_ctx *ossl_ctx;
/* Struct for CPUID return values */
struct cpuid {
@@ -142,65 +140,6 @@ static void cpuid(unsigned int leaf, unsigned int subleaf, struct cpuid *out)
static unsigned char iv_buf[CHUNK_SIZE] __attribute__((aligned(128)));
static int have_aesni, have_rdseed;
-static int osslencrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
- unsigned char *iv, unsigned char *ciphertext)
-{
- EVP_CIPHER_CTX *ctx;
-
- int len;
-
- int ciphertext_len;
-
- /* Create and initialise the context */
- if(!(ctx = EVP_CIPHER_CTX_new()))
- return 0;
-
- if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
- return 0;
- /*
- * Provide the message to be encrypted, and obtain the encrypted output.
- * EVP_EncryptUpdate can be called multiple times if necessary
- */
- if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
- return 0;
-
- ciphertext_len = len;
-
- /*
- * Finalise the encryption. Further ciphertext bytes may be written at
- * this stage.
- */
- if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
- return 0;
- ciphertext_len += len;
-
- /* Clean up */
- EVP_CIPHER_CTX_free(ctx);
-
- return ciphertext_len;
-}
-
-static inline int openssl_mangle(unsigned char *tmp, struct rng *ent_src)
-{
- int ciphertext_len;
-
- /*
- * Buffer for ciphertext. Ensure the buffer is long enough for the
- * ciphertext which may be longer than the plaintext, depending on the
- * algorithm and mode.
- */
- unsigned char ciphertext[CHUNK_SIZE * RDRAND_ROUNDS];
-
- /* Encrypt the plaintext */
- ciphertext_len = osslencrypt (tmp, strlen(tmp), key, iv_buf,
- ciphertext);
- if (!ciphertext_len)
- return -1;
-
- memcpy(tmp, ciphertext, strlen(tmp));
- return 0;
-}
-
int xread_drng_with_aes(void *buf, size_t size, struct rng *ent_src)
{
static unsigned char rdrand_buf[CHUNK_SIZE * RDRAND_ROUNDS]
@@ -227,7 +166,7 @@ int xread_drng_with_aes(void *buf, size_t size, struct rng *ent_src)
x86_aes_mangle(rdrand_buf, iv_buf);
data = iv_buf;
chunk = CHUNK_SIZE;
- } else if (!openssl_mangle(rdrand_buf, ent_src)) {
+ } else if (ossl_aes_mangle(ossl_ctx, rdrand_buf, AES_BLOCK) >= 0) {
data = rdrand_buf +
AES_BLOCK * (RDRAND_ROUNDS - 1);
chunk = AES_BLOCK;
@@ -288,9 +227,6 @@ int xread_drng(void *buf, size_t size, struct rng *ent_src)
static int init_aesni(const void *key)
{
- if (!have_aesni)
- return 1;
-
x86_aes_expand_key(key);
return 0;
}
@@ -335,21 +271,16 @@ int init_drng_entropy_source(struct rng *ent_src)
/* Randomize the AES data reduction key the best we can */
if (x86_rdrand_bytes(xkey, sizeof xkey) != sizeof xkey)
return 1;
-
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0) {
- read(fd, key, sizeof key);
- close(fd);
- }
-
- for (i = 0; i < (int)sizeof key; i++)
- key[i] ^= xkey[i];
+ ossl_aes_random_key(key, xkey);
/* Initialize the IV buffer */
if (x86_rdrand_bytes(iv_buf, CHUNK_SIZE) != CHUNK_SIZE)
return 1;
- init_aesni(key);
+ if (have_aesni)
+ init_aesni(key);
+ else
+ ossl_ctx = ossl_aes_init(key, iv_buf);
if (have_rdseed)
message_entsrc(ent_src,LOG_DAEMON|LOG_INFO, "Enabling RDSEED rng support\n");
diff --git a/rngd_rtlsdr.c b/rngd_rtlsdr.c
index 73046cd..949c8b0 100644
--- a/rngd_rtlsdr.c
+++ b/rngd_rtlsdr.c
@@ -19,11 +19,11 @@
#include <openssl/err.h>
#include "rngd.h"
+#include "ossl_helpers.h"
#define RAW_BUF_SZ 4096
#define CHUNK_SIZE (AES_BLOCK*8) /* 8 parallel streams */
-#define AES_BLOCK 16
static rtlsdr_dev_t *radio = NULL;
static char raw_buffera[RAW_BUF_SZ];
@@ -33,6 +33,12 @@ static int sample_min;
static int sample_max;
static int gain = 200;
+/* AES data reduction key */
+static unsigned char key[AES_BLOCK];
+static unsigned char iv[CHUNK_SIZE];
+static struct ossl_aes_ctx *ossl_ctx;
+
+
static int get_random_freq()
{
int range = freq_max - freq_min;
@@ -97,7 +103,13 @@ int init_rtlsdr_entropy_source(struct rng *ent_src)
message_entsrc(ent_src, LOG_DAEMON, "%d: %s %s\n", i, vendor, product);
}
- /*
+ ossl_ctx = ossl_aes_init(key, iv);
+ if (!ossl_ctx) {
+ message_entsrc(ent_src, LOG_DAEMON, "Failed to setup openssl\n");
+ return 1;
+ }
+
+ /*
* Get our default sample rate and freq settings, as well as the devid
* to use
*/
@@ -144,51 +156,19 @@ void close_rtlsdr_entropy_source(struct rng *ent_src)
{
if (radio)
rtlsdr_close(radio);
- return;
+ if (ossl_ctx)
+ ossl_aes_exit(ossl_ctx);
}
static size_t condition_buffer(unsigned char *in, unsigned char *out, size_t insize, size_t outsize)
{
- EVP_CIPHER_CTX *ctx;
- static unsigned char key[AES_BLOCK];
- unsigned char iv[CHUNK_SIZE] __attribute__((aligned(128)));
- int len;
- size_t ciphertext_len = 0;
-
/*
* Setup our key and iv
*/
memcpy(key, in, AES_BLOCK);
memcpy(iv, &in[AES_BLOCK], CHUNK_SIZE);
- /* Create and initialise the context */
- if(!(ctx = EVP_CIPHER_CTX_new()))
- return 0;
-
- if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
- goto out;
- /*
- * Provide the message to be encrypted, and obtain the encrypted output.
- * EVP_EncryptUpdate can be called multiple times if necessary
- */
- if(1 != EVP_EncryptUpdate(ctx, out, &len, in, insize))
- goto out;
-
- ciphertext_len = len;
-
- /*
- * Finalise the encryption. Further ciphertext bytes may be written at
- * this stage.
- */
- if(1 != EVP_EncryptFinal_ex(ctx, out, &len))
- return 0;
- ciphertext_len += len;
-
-out:
- /* Clean up */
- EVP_CIPHER_CTX_free(ctx);
-
- return ciphertext_len;
+ return ossl_aes_encrypt(ossl_ctx, in, insize, out);
}
int xread_rtlsdr(void *buf, size_t size, struct rng *ent_src)
--
2.26.3

View File

@ -11,14 +11,12 @@
Summary: Random number generator related utilities
Name: rng-tools
Version: 6.12
Release: 3%{?dist}
Release: 4%{?dist}
License: GPLv2+
URL: https://github.com/nhorman/rng-tools
Source0: https://github.com/nhorman/rng-tools/archive/v%{version}/rng-tools-%{version}.tar.gz
Source1: rngd.service
# https://sourceforge.net/p/gkernel/patches/111/
BuildRequires: gcc make
BuildRequires: gettext
BuildRequires: systemd systemd-rpm-macros
@ -39,6 +37,10 @@ Requires(preun): systemd
Requires(postun): systemd
Provides: jitterentropy-rngd
Patch1: rng-tools-1-Improve-rngd-console-output-readability.patch
Patch2: rng-tools-2-try-to-build-with-rtlsdr-by-default.patch
Patch3: rng-tools-3-Create-helpers-for-openssl-AES-use.patch
%description
Hardware random number generation tools.
@ -83,6 +85,10 @@ install -Dt %{buildroot}%{_unitdir} -m0644 %{SOURCE1}
%attr(0644,root,root) %{_unitdir}/rngd.service
%changelog
* Mon May 24 2021 Vladis Dronov <vdronov@redhat.com> - 6.12-4
- Update the rngd.service file
- Add 3 small upstream patches fixing issues
* Wed Apr 28 2021 Vladis Dronov <vdronov@redhat.com> - 6.12-3
- There is no need to hardcode _sbindir anymore, also the old value is incorrect

View File

@ -1,5 +1,6 @@
[Unit]
Description=Hardware RNG Entropy Gatherer Daemon
ConditionVirtualization=!container
[Service]
ExecStart=/usr/sbin/rngd -f