diff --git a/rng-tools-1-Improve-rngd-console-output-readability.patch b/rng-tools-1-Improve-rngd-console-output-readability.patch new file mode 100644 index 0000000..28a1a4f --- /dev/null +++ b/rng-tools-1-Improve-rngd-console-output-readability.patch @@ -0,0 +1,33 @@ +From d989f5690037eb2162eeea7352a7f8eeecc7989b Mon Sep 17 00:00:00 2001 +From: Nikolai Kostrigin +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 +--- + 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 + diff --git a/rng-tools-2-try-to-build-with-rtlsdr-by-default.patch b/rng-tools-2-try-to-build-with-rtlsdr-by-default.patch new file mode 100644 index 0000000..7e7a644 --- /dev/null +++ b/rng-tools-2-try-to-build-with-rtlsdr-by-default.patch @@ -0,0 +1,26 @@ +From e00e2155ad04f8b3a964fd482bddd8c27b5b9999 Mon Sep 17 00:00:00 2001 +From: Jan Palus +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 + diff --git a/rng-tools-3-Create-helpers-for-openssl-AES-use.patch b/rng-tools-3-Create-helpers-for-openssl-AES-use.patch new file mode 100644 index 0000000..537b509 --- /dev/null +++ b/rng-tools-3-Create-helpers-for-openssl-AES-use.patch @@ -0,0 +1,864 @@ +From 0f0580f3ae98fecf41de4a0346f5e11f390418b7 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +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 +--- + 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include "ossl_helpers.h" ++ ++#include ++#include ++#include ++ ++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 + #include + #include +-#include +-#include +-#include +- + + #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 + #include + #include +-#include +-#include +-#include + + #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 + #include + #include +-#include +-#include +-#include + + #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 + + #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 + diff --git a/rng-tools.spec b/rng-tools.spec index 88a47fa..747dd7a 100644 --- a/rng-tools.spec +++ b/rng-tools.spec @@ -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 - 6.12-4 +- Update the rngd.service file +- Add 3 small upstream patches fixing issues + * Wed Apr 28 2021 Vladis Dronov - 6.12-3 - There is no need to hardcode _sbindir anymore, also the old value is incorrect diff --git a/rngd.service b/rngd.service index 0479343..1cc09da 100644 --- a/rngd.service +++ b/rngd.service @@ -1,5 +1,6 @@ [Unit] Description=Hardware RNG Entropy Gatherer Daemon +ConditionVirtualization=!container [Service] ExecStart=/usr/sbin/rngd -f