linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Stephan Müller" <smueller@chronox.de>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-crypto@vger.kernel.org, LKML <linux-kernel@vger.kernel.org>,
	linux-api@vger.kernel.org,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	"Alexander E. Patrakov" <patrakov@gmail.com>,
	"Ahmed S. Darwish" <darwish.07@gmail.com>,
	"Theodore Y. Ts'o" <tytso@mit.edu>, Willy Tarreau <w@1wt.eu>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	Vito Caputo <vcaputo@pengaru.com>,
	Andreas Dilger <adilger.kernel@dilger.ca>,
	Jan Kara <jack@suse.cz>, Ray Strode <rstrode@redhat.com>,
	William Jon McCann <mccann@jhu.edu>,
	zhangjs <zachary@baishancloud.com>,
	Andy Lutomirski <luto@kernel.org>,
	Florian Weimer <fweimer@redhat.com>,
	Lennart Poettering <mzxreary@0pointer.de>,
	Nicolai Stange <nstange@suse.de>,
	"Peter, Matthias" <matthias.peter@bsi.bund.de>,
	Marcelo Henrique Cerri <marcelo.cerri@canonical.com>,
	Roman Drahtmueller <draht@schaltsekun.de>,
	Neil Horman <nhorman@redhat.com>,
	Randy Dunlap <rdunlap@infradead.org>,
	Julia Lawall <julia.lawall@inria.fr>
Subject: [PATCH v27 12/12] LRNG - add power-on and runtime self-tests
Date: Thu, 09 Jan 2020 09:35:44 +0100	[thread overview]
Message-ID: <2355906.JbblJTOqSk@positron.chronox.de> (raw)
In-Reply-To: <2641155.iNH938UiKq@positron.chronox.de>

Parts of the LFSR are already covered by self-tests, including:

* Self-test of SP800-90A DRBG provided by the Linux kernel crypto API.

* Self-test of the PRNG provided by the Linux kernel crypto API.

* Raw noise source data testing including SP800-90B compliant
  tests when enabling CONFIG_LRNG_HEALTH_TESTS

This patch adds the self tests for the remaining critical functions of
the LRNG that are essential to maintain entropy and provide
cryptographic strong random numbers. The following self tests are
implemented:

* Self-test of the time array maintenance. This test verifies whether
the time stamp array management to store multiple values in one integer
implements a concatenation of the data.

* Self-test of the LFSR operation. This test injects a monotonic
increasing counter into the LFSR. After completion of the injection of
the counter, 3 pool words are compared with known good values. The known
good values are calculated with the newly-developed tool
lfsr_testvector_generation provided as part of the LRNG test tool set at
[1].

* Self-test of the Hash_DF operation ensures that this function operates
compliant to the specification. The self-test performs a Hash_DF
operation of a zeroized entropy pool state. The test vectors are
generated using the newly-developed tool hash_df_testvector_generation
provided as part of the LRNG test tool set at [1].

* Self-test of the ChaCha20 DRNG is based on the self tests that are
already present and implemented with the stand-alone user space
ChaCha20 DRNG implementation available at [2]. The self-tests cover
different use cases of the DRNG seeded with known seed data.

The status of the LRNG self-tests is provided with the selftest_status
SysFS file. If the file contains a zero, the self-tests passed. The
value 0xffffffff means that the self-tests were not executed. Any other
value indicates a self test failure.

The self-test may be compiled to panic the system if the self-test
fails.

All self tests operate on private state data structures. This implies
that none of the self-tests have any impact on the regular LRNG
operations. This allows the self-tests to be repeated at runtime by
writing anything into the selftest_status SysFS file.

[1] https://www.chronox.de/lrng.html
[2] https://www.chronox.de/chacha20.html

CC: "Eric W. Biederman" <ebiederm@xmission.com>
CC: "Alexander E. Patrakov" <patrakov@gmail.com>
CC: "Ahmed S. Darwish" <darwish.07@gmail.com>
CC: "Theodore Y. Ts'o" <tytso@mit.edu>
CC: Willy Tarreau <w@1wt.eu>
CC: Matthew Garrett <mjg59@srcf.ucam.org>
CC: Vito Caputo <vcaputo@pengaru.com>
CC: Andreas Dilger <adilger.kernel@dilger.ca>
CC: Jan Kara <jack@suse.cz>
CC: Ray Strode <rstrode@redhat.com>
CC: William Jon McCann <mccann@jhu.edu>
CC: zhangjs <zachary@baishancloud.com>
CC: Andy Lutomirski <luto@kernel.org>
CC: Florian Weimer <fweimer@redhat.com>
CC: Lennart Poettering <mzxreary@0pointer.de>
CC: Nicolai Stange <nstange@suse.de>
CC: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
CC: Neil Horman <nhorman@redhat.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 drivers/char/lrng/Kconfig         |  25 ++
 drivers/char/lrng/Makefile        |   1 +
 drivers/char/lrng/lrng_selftest.c | 418 ++++++++++++++++++++++++++++++
 3 files changed, 444 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_selftest.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 394066aa5a86..e9827e7df715 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -175,4 +175,29 @@ config LRNG_TESTING
 
 	  If unsure, say N.
 
+config LRNG_SELFTEST
+	bool "Enable power-on and on-demand self-tests"
+	help
+	  The power-on self tests are executed during boot time
+	  covering the ChaCha20 DRNG, the LFSR processing and the
+	  time stamp management of the LRNG.
+
+	  The on-demand self-tests are triggered by writing any
+	  value into the SysFS file selftest_status. At the same
+	  time, when reading this file, the test status is
+	  returned. A zero indicates that all tests were executed
+	  successfully.
+
+	  If unsure, say Y.
+
+if LRNG_SELFTEST
+
+config LRNG_SELFTEST_PANIC
+	bool "Panic the kernel upon self-test failure"
+	help
+	  If the option is enabled, the kernel is terminated if an
+	  LRNG power-on self-test failure is detected.
+
+endif # LRNG_SELFTEST
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index b2ce1979dc4b..92219c565f66 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_LRNG_KCAPI)	+= lrng_kcapi.o
 obj-$(CONFIG_LRNG_JENT)		+= lrng_jent.o
 obj-$(CONFIG_LRNG_HEALTH_TESTS)	+= lrng_health.o
 obj-$(CONFIG_LRNG_TESTING)	+= lrng_testing.o
+obj-$(CONFIG_LRNG_SELFTEST)	+= lrng_selftest.o
diff --git a/drivers/char/lrng/lrng_selftest.c b/drivers/char/lrng/lrng_selftest.c
new file mode 100644
index 000000000000..9df9b59d9491
--- /dev/null
+++ b/drivers/char/lrng/lrng_selftest.c
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG power-on and on-demand self test
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller <smueller@chronox.de>
+ */
+
+/*
+ * In addition to the self tests below, the following LRNG components
+ * are covered with self tests during regular operation:
+ *
+ * * power-on self test: SP800-90A DRBG provided by the Linux kernel crypto API
+ * * power-on self test: PRNG provided by the Linux kernel crypto API
+ * * runtime test: Raw noise source data testing including SP800-90B compliant
+ *		   tests when enabling CONFIG_LRNG_HEALTH_TESTS
+ *
+ * Additional developer tests present with LRNG code:
+ * * SP800-90B APT and RCT test enforcement validation when enabling
+ *   CONFIG_LRNG_APT_BROKEN or CONFIG_LRNG_RCT_BROKEN.
+ * * Collection of raw entropy from the interrupt noise source when enabling
+ *   CONFIG_LRNG_TESTING and pulling the data from the kernel with the provided
+ *   interface.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/lrng.h>
+#include <linux/slab.h>
+
+#include "lrng_chacha20.h"
+#include "lrng_internal.h"
+#include "lrng_lfsr.h"
+#include "lrng_sw_noise.h"
+
+#define LRNG_SELFTEST_PASSED		0
+#define LRNG_SEFLTEST_ERROR_TIME	(1 << 0)
+#define LRNG_SEFLTEST_ERROR_LFSR	(1 << 1)
+#define LRNG_SEFLTEST_ERROR_CHACHA20	(1 << 2)
+#define LRNG_SEFLTEST_ERROR_HASHDF	(1 << 3)
+#define LRNG_SELFTEST_NOT_EXECUTED	0xffffffff
+
+static u32 lrng_time_selftest[LRNG_TIME_ARRAY_SIZE];
+
+static unsigned int lrng_selftest_status = LRNG_SELFTEST_NOT_EXECUTED;
+
+static inline void lrng_time_process_selftest_insert(u32 time)
+{
+	static u32 lrng_time_selftest_ptr = 0;
+	u32 ptr = lrng_time_selftest_ptr++ & LRNG_TIME_WORD_MASK;
+
+	lrng_time_selftest[lrng_time_idx2array(ptr)] |=
+		lrng_time_slot_val(time & LRNG_TIME_SLOTSIZE_MASK,
+				   lrng_time_idx2slot(ptr));
+}
+
+static unsigned int lrng_time_process_selftest(void)
+{
+	u32 time;
+	u32 idx_zero_compare = (0 << 0) | (1 << 8) | (2 << 16) | (3 << 24);
+	u32 idx_one_compare  = (4 << 0) | (5 << 8) | (6 << 16) | (7 << 24);
+	u32 idx_last_compare = ((LRNG_TIME_NUM_VALUES - 4) << 0)  |
+			       ((LRNG_TIME_NUM_VALUES - 3) << 8)  |
+			       ((LRNG_TIME_NUM_VALUES - 2) << 16) |
+			       ((LRNG_TIME_NUM_VALUES - 1) << 24);
+
+	(void)idx_one_compare;
+
+	for (time = 0; time < LRNG_TIME_NUM_VALUES; time++)
+		lrng_time_process_selftest_insert(time);
+
+	if ((lrng_time_selftest[0] != idx_zero_compare) ||
+#if (LRNG_TIME_ARRAY_SIZE > 1)
+	    (lrng_time_selftest[1] != idx_one_compare)  ||
+#endif
+	    (lrng_time_selftest[LRNG_TIME_ARRAY_SIZE - 1] != idx_last_compare))
+	{
+		pr_err("LRNG time array self-test FAILED\n");
+		return LRNG_SEFLTEST_ERROR_TIME;
+	}
+
+	return LRNG_SELFTEST_PASSED;
+}
+
+/*
+ * The test vectors are generated with the lfsr_testvector_generation tool
+ * provided as part of the test tool set of the LRNG.
+ */
+static unsigned int lrng_pool_lfsr_selftest(void)
+{
+	/*
+	 * First, 67th and last entry of entropy pool.
+	 *
+	 * The 67th entry is picked because this one is the first to receive
+	 * an entry. As we start with 1 to inject into the LFSR, the
+	 * 67th entry should be equal to rol(1, 7) >> 3 considering that
+	 * all other values of the LFSR are zero and the the twist value of 0
+	 * is applied.
+	 */
+	static u32 const lrng_lfsr_selftest_result[][3] = {
+		{ 0xf56df24a, 0x00000010, 0x0e014939 },
+		{ 0x4b130726, 0x00000010, 0x2802f509 },
+		{ 0x87279152, 0x00000010, 0x00150000 },
+		{ 0x0b67f997, 0x00000010, 0x00150000 },
+		{ 0x4fea174f, 0x00000010, 0xcbf4a6ae },
+		{ 0x77149108, 0x00000010, 0x77bfadf2 },
+		{ 0x1e96037e, 0x00000010, 0x18017e79 },
+		{ 0xc84acef2, 0x00000010, 0x6345f7a8 },
+		{ 0x6a2eb6df, 0x00000010, 0x03950000 },
+	};
+	struct lrng_pool *lrng_pool, *lrng_pool_aligned;
+	u32 i, ret = LRNG_SELFTEST_PASSED;
+
+	BUILD_BUG_ON(ARRAY_SIZE(lrng_lfsr_selftest_result) <
+							CONFIG_LRNG_POOL_SIZE);
+
+	lrng_pool = kzalloc(sizeof(struct lrng_pool) + sizeof(LRNG_KCAPI_ALIGN),
+			    GFP_KERNEL);
+	if (!lrng_pool)
+		return LRNG_SEFLTEST_ERROR_LFSR;
+	lrng_pool_aligned = PTR_ALIGN(lrng_pool, sizeof(u32));
+
+	for (i = 1; i <= LRNG_POOL_SIZE; i++)
+		_lrng_pool_lfsr_u32(lrng_pool_aligned, i);
+
+	if ((atomic_read_u32(&lrng_pool_aligned->pool[0]) !=
+	     lrng_lfsr_selftest_result[CONFIG_LRNG_POOL_SIZE][0]) ||
+	    (atomic_read_u32(&lrng_pool_aligned->pool[67 &
+						      (LRNG_POOL_SIZE - 1)]) !=
+	     lrng_lfsr_selftest_result[CONFIG_LRNG_POOL_SIZE][1]) ||
+	    (atomic_read_u32(&lrng_pool_aligned->pool[LRNG_POOL_SIZE - 1]) !=
+	     lrng_lfsr_selftest_result[CONFIG_LRNG_POOL_SIZE][2])) {
+		pr_err("LRNG LFSR self-test FAILED\n");
+		ret = LRNG_SEFLTEST_ERROR_LFSR;
+	}
+
+	kfree(lrng_pool);
+	return ret;
+}
+
+/*
+ * The test vectors are generated with the hash_df_testvector_generation tool
+ * provided as part of the test tool set of the LRNG.
+ */
+static unsigned int lrng_hash_df_selftest(void)
+{
+	const struct lrng_crypto_cb *crypto_cb = &lrng_cc20_crypto_cb;
+
+	/*
+	 * The size of 45 bytes is chosen arbitrarily. Yet, this size should
+	 * ensure that we have at least two hash blocks plus some fraction
+	 * of a hash block generated.
+	 */
+	static u8 const lrng_hash_df_selftest_result[][45] = {
+		{
+			0x3b, 0xbe, 0x7a, 0xbd, 0x2b, 0x16, 0x02, 0x4c,
+			0xfc, 0xd3, 0x02, 0x15, 0xf0, 0x86, 0xd4, 0xdb,
+			0x49, 0xec, 0x26, 0x53, 0xd6, 0xc9, 0x6d, 0xad,
+			0x24, 0xca, 0x72, 0x89, 0x2c, 0xfa, 0x48, 0x18,
+			0xf7, 0x47, 0xb5, 0x2f, 0x92, 0xa2, 0x1b, 0xd9,
+			0x24, 0xa7, 0x2f, 0xa2, 0x0b,
+		}, {
+			0xd2, 0xaa, 0xf9, 0x76, 0x26, 0xc6, 0x13, 0xea,
+			0xb8, 0xde, 0xe6, 0x88, 0x8f, 0xc4, 0x7a, 0x7d,
+			0x9c, 0xb4, 0x1b, 0xd1, 0xd1, 0x8a, 0x40, 0xc9,
+			0xaa, 0x45, 0xa6, 0xb6, 0xb5, 0x6f, 0xf6, 0xbc,
+			0xbb, 0x77, 0x37, 0xbc, 0x5a, 0x2d, 0xcc, 0x84,
+			0x25, 0x68, 0x5e, 0xba, 0x16,
+		}, {
+			0x58, 0x66, 0x82, 0x88, 0x29, 0x19, 0xa4, 0xbb,
+			0x33, 0x42, 0xc9, 0x72, 0x0d, 0x68, 0x6e, 0xb9,
+			0xc6, 0xe0, 0x7a, 0xf9, 0x20, 0xca, 0x6d, 0x18,
+			0x35, 0xec, 0xfa, 0x9e, 0xf6, 0x3a, 0xa7, 0xb6,
+			0x92, 0x7a, 0xe5, 0xcd, 0xc5, 0x13, 0x9f, 0x65,
+			0x6a, 0xe1, 0xe4, 0x3f, 0xb9,
+		}, {
+			0xdd, 0xf1, 0x34, 0xca, 0x08, 0xe3, 0xce, 0x8a,
+			0x26, 0x6b, 0xce, 0x99, 0x8a, 0x84, 0xd2, 0x21,
+			0x98, 0x10, 0x95, 0x5f, 0x9f, 0xc3, 0xf2, 0xe4,
+			0x79, 0x75, 0xb5, 0x15, 0xa7, 0xa2, 0xf1, 0xc4,
+			0xdc, 0x67, 0xcb, 0x67, 0x8c, 0xb2, 0x1b, 0xd5,
+			0xd6, 0x8b, 0xc2, 0x34, 0xd6,
+		}, {
+			0xc3, 0x16, 0x9d, 0xf0, 0x78, 0x15, 0xab, 0xf2,
+			0x2f, 0xc9, 0x2e, 0xe1, 0xc6, 0x5e, 0xfa, 0x03,
+			0xaf, 0xd4, 0xd5, 0x47, 0x2a, 0xe8, 0x06, 0xe8,
+			0x7e, 0x0a, 0x71, 0xc7, 0x0d, 0x39, 0xb1, 0xa9,
+			0x5a, 0x49, 0xee, 0x8b, 0x2f, 0xcd, 0xea, 0x96,
+			0xcc, 0x08, 0x71, 0xef, 0x9c,
+		}, {
+			0x1a, 0x3d, 0x70, 0x39, 0xc2, 0x02, 0x4d, 0x3a,
+			0xaa, 0x14, 0x20, 0x88, 0x96, 0x4c, 0x7c, 0xe4,
+			0xaa, 0x49, 0x89, 0x30, 0x50, 0x96, 0xb6, 0xa7,
+			0x55, 0x0a, 0xf8, 0xd2, 0x4e, 0x83, 0x9d, 0x1f,
+			0x56, 0x49, 0x13, 0xc6, 0x46, 0x55, 0x73, 0x0d,
+			0x74, 0xcd, 0x81, 0xe0, 0x65,
+		}, {
+			0x4b, 0xf6, 0x49, 0x89, 0x2a, 0x9f, 0x67, 0xd7,
+			0xb8, 0x1d, 0xbb, 0x5d, 0xf0, 0x1b, 0x60, 0xb6,
+			0xb7, 0xf3, 0x86, 0x6d, 0xe0, 0x04, 0xa1, 0xbc,
+			0x3b, 0xb0, 0x10, 0x91, 0xe8, 0x22, 0x67, 0x5b,
+			0xe8, 0xf0, 0x4f, 0x82, 0x70, 0xc7, 0xe1, 0xc8,
+			0xd8, 0xad, 0x70, 0xcf, 0xf6,
+		}, {
+			0x60, 0x1f, 0x71, 0x07, 0x92, 0xae, 0xa0, 0x24,
+			0xb6, 0xa4, 0x10, 0x70, 0x1f, 0x94, 0x51, 0x9a,
+			0x5a, 0x81, 0xc4, 0x46, 0x78, 0x56, 0x71, 0xdd,
+			0x45, 0x63, 0x01, 0x34, 0x87, 0x79, 0xb4, 0xd5,
+			0x91, 0x79, 0xb9, 0x93, 0x11, 0x44, 0x50, 0xad,
+			0x64, 0x7e, 0x5c, 0xec, 0x16,
+		}, {
+			0x49, 0x2f, 0xa0, 0x45, 0xf8, 0xb0, 0x80, 0x88,
+			0x79, 0xeb, 0xb6, 0x82, 0x1c, 0xf3, 0x67, 0xc4,
+			0x88, 0x88, 0xe9, 0x75, 0x20, 0x54, 0x78, 0xc6,
+			0x5c, 0x59, 0xcf, 0xd9, 0x73, 0x12, 0x17, 0xf4,
+			0x30, 0x9c, 0xb7, 0x21, 0x45, 0xe2, 0xb6, 0x0c,
+			0x0c, 0xeb, 0x1b, 0xdc, 0xdc,
+		}
+	};
+	struct lrng_pool *lrng_pool, *lrng_pool_aligned;
+	u8 hash_df[sizeof(lrng_hash_df_selftest_result[0])]
+							__aligned(sizeof(u32));
+	u32 generated;
+	int ret = 0;
+
+	BUILD_BUG_ON(ARRAY_SIZE(lrng_hash_df_selftest_result) <
+							CONFIG_LRNG_POOL_SIZE);
+
+	lrng_pool = kzalloc(sizeof(struct lrng_pool) + sizeof(LRNG_KCAPI_ALIGN),
+			    GFP_KERNEL);
+	if (!lrng_pool)
+		return LRNG_SEFLTEST_ERROR_HASHDF;
+	lrng_pool_aligned = PTR_ALIGN(lrng_pool, sizeof(u32));
+
+	generated = __lrng_pool_hash_df(crypto_cb, NULL, lrng_pool_aligned,
+					hash_df, sizeof(hash_df) << 3);
+
+	if ((generated >> 3) != sizeof(hash_df) ||
+	    memcmp(hash_df, lrng_hash_df_selftest_result[CONFIG_LRNG_POOL_SIZE],
+		   sizeof(hash_df))) {
+		pr_err("LRNG Hash DF self-test FAILED\n");
+		ret = LRNG_SEFLTEST_ERROR_HASHDF;
+	}
+
+	kfree(lrng_pool);
+	return ret;
+}
+
+/*
+ * The test vectors were generated using the ChaCha20 DRNG from
+ * https://www.chronox.de/chacha20.html
+ */
+static unsigned int lrng_chacha20_drng_selftest(void)
+{
+	const struct lrng_crypto_cb *crypto_cb = &lrng_cc20_crypto_cb;
+	static u8 const seed[CHACHA_KEY_SIZE * 2] = {
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+	};
+	struct chacha20_block chacha20;
+	int ret;
+	u8 outbuf[CHACHA_KEY_SIZE * 2] __aligned(sizeof(u32));
+
+	/*
+	 * Expected result when ChaCha20 DRNG state is zero:
+	 *	* constants are set to "expand 32-byte k"
+	 *	* remaining state is 0
+	 * and pulling one half ChaCha20 DRNG block.
+	 */
+	static u8 const expected_halfblock[CHACHA_KEY_SIZE] = {
+		0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
+		0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
+		0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
+		0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7 };
+
+	/*
+	 * Expected result when ChaCha20 DRNG state is zero:
+	 *	* constants are set to "expand 32-byte k"
+	 *	* remaining state is 0
+	 * followed by a reseed with two keyblocks
+	 *	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	 *	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+	 *	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+	 *	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+	 *	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+	 *	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+	 *	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+	 *	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
+	 * and pulling one ChaCha20 DRNG block.
+	 */
+	static u8 const expected_oneblock[CHACHA_KEY_SIZE * 2] = {
+		0xf5, 0xb4, 0xb6, 0x5a, 0xec, 0xcd, 0x5a, 0x65,
+		0x87, 0x56, 0xe3, 0x86, 0x51, 0x54, 0xfc, 0x90,
+		0x56, 0xff, 0x5e, 0xae, 0x58, 0xf2, 0x01, 0x88,
+		0xb1, 0x7e, 0xb8, 0x2e, 0x17, 0x9a, 0x27, 0xe6,
+		0x86, 0xb3, 0xed, 0x33, 0xf7, 0xb9, 0x06, 0x05,
+		0x8a, 0x2d, 0x1a, 0x93, 0xc9, 0x0b, 0x80, 0x04,
+		0x03, 0xaa, 0x60, 0xaf, 0xd5, 0x36, 0x40, 0x11,
+		0x67, 0x89, 0xb1, 0x66, 0xd5, 0x88, 0x62, 0x6d };
+
+	/*
+	 * Expected result when ChaCha20 DRNG state is zero:
+	 *	* constants are set to "expand 32-byte k"
+	 *	* remaining state is 0
+	 * followed by a reseed with one key block plus one byte
+	 *	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	 *	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+	 *	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+	 *	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+	 *	0x20
+	 * and pulling less than one ChaCha20 DRNG block.
+	 */
+	static u8 const expected_block_nonalinged[CHACHA_KEY_SIZE + 1] = {
+		0x3d, 0x13, 0x47, 0x1e, 0x7f, 0x7c, 0x99, 0x33,
+		0xfc, 0x44, 0xa4, 0xdd, 0xf9, 0x3d, 0xe1, 0x9a,
+		0xd4, 0xe8, 0x7a, 0x7d, 0x42, 0xac, 0xd1, 0xcd,
+		0x10, 0x69, 0xe7, 0xbf, 0xd4, 0xfd, 0x69, 0x4b,
+		0xa7 };
+
+	memset(&chacha20, 0, sizeof(chacha20));
+	lrng_cc20_init_rfc7539(&chacha20);
+
+	/* Generate with zero state */
+	ret = crypto_cb->lrng_drng_generate_helper(&chacha20, outbuf,
+						   sizeof(expected_halfblock));
+	if (ret != sizeof(expected_halfblock))
+		goto err;
+	if (memcmp(outbuf, expected_halfblock, sizeof(expected_halfblock)))
+		goto err;
+
+	/* Clear state of DRNG */
+	memset(&chacha20.key.u[0], 0, 48);
+
+	/* Reseed with 2 key blocks */
+	ret = crypto_cb->lrng_drng_seed_helper(&chacha20, seed,
+					       sizeof(expected_oneblock));
+	if (ret < 0)
+		goto err;
+	ret = crypto_cb->lrng_drng_generate_helper(&chacha20, outbuf,
+						   sizeof(expected_oneblock));
+	if (ret != sizeof(expected_oneblock))
+		goto err;
+	if (memcmp(outbuf, expected_oneblock, sizeof(expected_oneblock)))
+		goto err;
+
+	/* Clear state of DRNG */
+	memset(&chacha20.key.u[0], 0, 48);
+
+	/* Reseed with 1 key block and one byte */
+	ret = crypto_cb->lrng_drng_seed_helper(&chacha20, seed,
+					sizeof(expected_block_nonalinged));
+	if (ret < 0)
+		goto err;
+	ret = crypto_cb->lrng_drng_generate_helper(&chacha20, outbuf,
+					sizeof(expected_block_nonalinged));
+	if (ret != sizeof(expected_block_nonalinged))
+		goto err;
+	if (memcmp(outbuf, expected_block_nonalinged,
+		   sizeof(expected_block_nonalinged)))
+		goto err;
+
+	return LRNG_SELFTEST_PASSED;
+
+err:
+	pr_err("LRNG ChaCha20 DRNG self-test FAILED\n");
+	return LRNG_SEFLTEST_ERROR_CHACHA20;
+}
+
+static int lrng_selftest(void)
+{
+	unsigned int ret = lrng_time_process_selftest();
+
+	ret |= lrng_pool_lfsr_selftest();
+	ret |= lrng_chacha20_drng_selftest();
+	ret |= lrng_hash_df_selftest();
+
+	if (ret) {
+		if (IS_ENABLED(CONFIG_LRNG_SELFTEST_PANIC))
+			panic("LRNG self-tests failed: %u\n", ret);
+	} else {
+		pr_info("LRNG self-tests passed\n");
+	}
+
+	lrng_selftest_status = ret;
+
+	if (lrng_selftest_status)
+		return -EFAULT;
+	return 0;
+}
+
+#ifdef CONFIG_SYSFS
+/* Re-perform self test when any value is written to the sysfs file. */
+static int lrng_selftest_sysfs_set(const char *val,
+				   const struct kernel_param *kp)
+{
+	return lrng_selftest();
+}
+
+static const struct kernel_param_ops lrng_selftest_sysfs = {
+	.set = lrng_selftest_sysfs_set,
+	.get = param_get_uint,
+};
+module_param_cb(selftest_status, &lrng_selftest_sysfs, &lrng_selftest_status,
+		0644);
+#endif	/* CONFIG_SYSFS */
+
+static int __init lrng_selftest_init(void)
+{
+	return lrng_selftest();
+}
+
+module_init(lrng_selftest_init);
-- 
2.24.1





  parent reply	other threads:[~2020-01-09  8:41 UTC|newest]

Thread overview: 162+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-11 18:17 [PATCH v24 00/12] /dev/random - a new approach with full SP800-90B compliance Stephan Müller
2019-11-11 18:18 ` [PATCH v24 01/12] Linux Random Number Generator Stephan Müller
2019-11-11 23:54   ` Thomas Gleixner
2019-11-12  2:25     ` Stephan Müller
2019-11-12 10:16       ` Thomas Gleixner
2019-11-12 22:30   ` kbuild test robot
2019-11-12 23:15     ` Stephan Müller
2019-11-13  0:14   ` kbuild test robot
2019-11-13  0:25     ` Stephan Müller
2019-11-24  4:51   ` Sandy Harris
2019-11-24  9:02     ` Stephan Mueller
2019-11-11 18:19 ` [PATCH v24 02/12] LRNG - allocate one SDRNG instance per NUMA node Stephan Müller
2019-11-11 18:20 ` [PATCH v24 03/12] LRNG - /proc interface Stephan Müller
2019-11-11 18:20 ` [PATCH v24 04/12] LRNG - add switchable DRNG support Stephan Müller
2019-11-11 18:21 ` [PATCH v24 05/12] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2019-11-11 18:21 ` [PATCH v24 06/12] LRNG - add SP800-90A DRBG extension Stephan Müller
2019-11-11 18:22 ` [PATCH v24 07/12] LRNG - add kernel crypto API PRNG extension Stephan Müller
2019-11-11 18:23 ` [PATCH v24 08/12] crypto: provide access to a static Jitter RNG state Stephan Müller
2019-11-11 18:23 ` [PATCH v24 09/12] LRNG - add Jitter RNG fast noise source Stephan Müller
2019-11-11 18:24 ` [PATCH v24 10/12] LRNG - add TRNG support Stephan Müller
2019-11-11 18:26 ` [PATCH v24 11/12] LRNG - add SP800-90B compliant health tests Stephan Müller
2019-11-12 19:58   ` Alexander E. Patrakov
2019-11-12 23:11     ` Stephan Müller
2019-11-13  0:36     ` Stephan Müller
2019-11-13  6:02       ` Alexander E. Patrakov
2019-11-14  1:46         ` Stephan Müller
2019-11-11 18:26 ` [PATCH v24 12/12] LRNG - add interface for gathering of raw entropy Stephan Müller
2019-11-12 20:55   ` kbuild test robot
2019-11-12 23:13     ` Stephan Müller
2019-11-12 13:23 ` [PATCH v24 00/12] /dev/random - a new approach with full SP800-90B compliance Florian Weimer
2019-11-12 22:43   ` Stephan Müller
2019-11-12 15:33 ` Andy Lutomirski
2019-11-12 23:03   ` Stephan Müller
2019-11-12 23:26     ` Stephan Müller
2019-11-13  4:24   ` Stephan Müller
2019-11-13  4:48     ` Andy Lutomirski
2019-11-13 12:16       ` Stephan Müller
2019-11-16  9:32 ` [PATCH v25 00/12] /dev/random - a new approach with full SP800-90B Stephan Müller
2019-11-16  9:33   ` [PATCH v25 01/12] Linux Random Number Generator Stephan Müller
2019-11-16 11:25     ` Thomas Gleixner
2019-11-17 10:30       ` Stephan Müller
2019-11-16 18:13     ` Nicolai Stange
2019-11-17 11:01       ` Stephan Müller
2019-11-16  9:33   ` [PATCH v25 02/12] LRNG - allocate one SDRNG instance per NUMA node Stephan Müller
2019-11-16  9:34   ` [PATCH v25 03/12] LRNG - /proc interface Stephan Müller
2019-11-16 16:39     ` Andy Lutomirski
2019-11-17 12:16       ` Stephan Müller
2019-11-19 10:06         ` Andy Lutomirski
2019-11-19 10:55           ` Stephan Mueller
2019-11-19 17:40             ` Andy Lutomirski
2019-11-16 23:36     ` Eric W. Biederman
2019-11-17 11:37       ` Stephan Müller
2019-11-16  9:34   ` [PATCH v25 04/12] LRNG - add switchable DRNG support Stephan Müller
2019-11-16  9:35   ` [PATCH v25 05/12] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2019-11-16  9:35   ` [PATCH v25 06/12] LRNG - add SP800-90A DRBG extension Stephan Müller
2019-11-16  9:35   ` [PATCH v25 07/12] LRNG - add kernel crypto API PRNG extension Stephan Müller
2019-11-16  9:36   ` [PATCH v25 08/12] crypto: provide access to a static Jitter RNG state Stephan Müller
2019-11-16  9:36   ` [PATCH v25 09/12] LRNG - add Jitter RNG fast noise source Stephan Müller
2019-11-20 13:33     ` Neil Horman
2019-11-20 20:07       ` Stephan Müller
2019-11-21 14:19         ` Neil Horman
2019-11-21 14:33           ` Stephan Mueller
2019-11-16  9:37   ` [PATCH v25 10/12] LRNG - add TRNG support Stephan Müller
2019-11-16 16:09     ` Andy Lutomirski
2019-11-17 11:10       ` Stephan Müller
2019-11-19 10:07         ` Andy Lutomirski
2019-11-19 10:46           ` Stephan Mueller
2019-11-19 12:41           ` Greg Kroah-Hartman
2019-11-20  8:58             ` Stephan Müller
2019-11-20  9:55               ` Alexander E. Patrakov
2019-11-20 13:29               ` Greg Kroah-Hartman
2019-11-20 19:51                 ` Stephan Müller
2019-11-20 19:57                   ` Alexander E. Patrakov
2019-11-20 20:32                   ` Greg Kroah-Hartman
2019-11-21 13:06                     ` Stephan Müller
2019-11-16  9:37   ` [PATCH v25 11/12] LRNG - add SP800-90B compliant health tests Stephan Müller
2019-11-16  9:38   ` [PATCH v25 12/12] LRNG - add interface for gathering of raw entropy Stephan Müller
2019-11-16 16:51     ` Andy Lutomirski
2019-11-17 22:55       ` Stephan Müller
2019-11-19 10:04         ` Andy Lutomirski
2019-11-19 17:17     ` Randy Dunlap
2019-11-20  9:01       ` Stephan Müller
2019-11-21 12:18     ` Nicolai Stange
2019-11-21 15:18       ` Stephan Müller
2019-11-23 20:08   ` [PATCH v26 00/12] /dev/random - a new approach with full SP800-90B Stephan Müller
2019-11-23 20:10     ` [PATCH v26 01/12] Linux Random Number Generator Stephan Müller
2019-11-24 22:44       ` kbuild test robot
2019-11-25  6:29         ` Stephan Mueller
2019-11-23 20:10     ` [PATCH v26 02/12] LRNG - allocate one SDRNG instance per NUMA node Stephan Müller
2019-11-23 20:11     ` [PATCH v26 03/12] LRNG - sysctls and /proc interface Stephan Müller
2019-11-23 20:11     ` [PATCH v26 04/12] LRNG - add switchable DRNG support Stephan Müller
2019-11-23 20:31     ` [PATCH v26 05/12] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2019-11-23 20:32     ` [PATCH v26 06/12] LRNG - add SP800-90A DRBG extension Stephan Müller
2019-11-23 20:32     ` [PATCH v26 07/12] LRNG - add kernel crypto API PRNG extension Stephan Müller
2019-11-23 20:33     ` [PATCH v26 08/12] crypto: provide access to a static Jitter RNG state Stephan Müller
2019-11-23 20:34     ` [PATCH v26 09/12] LRNG - add Jitter RNG fast noise source Stephan Müller
2019-11-23 20:34     ` [PATCH v26 10/12] LRNG - add TRNG support Stephan Müller
2019-11-23 20:34     ` [PATCH v26 11/12] LRNG - add SP800-90B compliant health tests Stephan Müller
2019-11-23 20:35     ` [PATCH v26 12/12] LRNG - add interface for gathering of raw entropy Stephan Müller
2020-01-09  8:29     ` [PATCH v27 00/12] /dev/random - a new approach with full SP800-90B Stephan Müller
2020-01-09  8:30       ` [PATCH v27 01/12] Linux Random Number Generator Stephan Müller
2020-01-16  6:09         ` kbuild test robot
2020-01-16  6:41           ` Stephan Mueller
2020-01-09  8:31       ` [PATCH v27 02/12] LRNG - allocate one DRNG instance per NUMA node Stephan Müller
2020-01-09  8:31       ` [PATCH v27 03/12] LRNG - sysctls and /proc interface Stephan Müller
2020-01-09  8:32       ` [PATCH v27 04/12] LRNG - add switchable DRNG support Stephan Müller
2020-01-11  7:09         ` kbuild test robot
2020-01-12 10:12           ` Stephan Müller
2020-01-09  8:32       ` [PATCH v27 05/12] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2020-01-09  8:32       ` [PATCH v27 06/12] LRNG - add SP800-90A DRBG extension Stephan Müller
2020-01-09  8:33       ` [PATCH v27 07/12] LRNG - add kernel crypto API PRNG extension Stephan Müller
2020-01-09  8:33       ` [PATCH v27 08/12] crypto: provide access to a static Jitter RNG state Stephan Müller
2020-01-09  8:34       ` [PATCH v27 09/12] LRNG - add Jitter RNG fast noise source Stephan Müller
2020-01-10  0:24         ` Randy Dunlap
2020-01-10  7:45           ` Stephan Mueller
2020-01-09  8:34       ` [PATCH v27 10/12] LRNG - add SP800-90B compliant health tests Stephan Müller
2020-01-10  0:20         ` Randy Dunlap
2020-01-10  8:27           ` Stephan Mueller
2020-01-09  8:35       ` [PATCH v27 11/12] LRNG - add interface for gathering of raw entropy Stephan Müller
2020-01-09  8:35       ` Stephan Müller [this message]
2020-01-10  0:22         ` [PATCH v27 12/12] LRNG - add power-on and runtime self-tests Randy Dunlap
2020-01-10  7:48           ` Stephan Mueller
2020-01-13 10:39         ` Dan Carpenter
2020-01-13 10:46           ` Stephan Mueller
2020-01-15 10:31       ` [PATCH v28 00/12] /dev/random - a new approach with full SP800-90B Stephan Müller
2020-01-15 10:31         ` [PATCH v28 01/12] Linux Random Number Generator Stephan Müller
2020-01-16  0:11           ` Randy Dunlap
2020-01-16  7:22             ` Stephan Mueller
2020-01-15 10:32         ` [PATCH v28 02/12] LRNG - allocate one DRNG instance per NUMA node Stephan Müller
2020-01-15 10:32         ` [PATCH v28 03/12] LRNG - sysctls and /proc interface Stephan Müller
2020-01-15 10:32         ` [PATCH v28 04/12] LRNG - add switchable DRNG support Stephan Müller
2020-01-15 10:33         ` [PATCH v28 05/12] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2020-01-15 10:33         ` [PATCH v28 06/12] LRNG - add SP800-90A DRBG extension Stephan Müller
2020-01-16  0:14           ` Randy Dunlap
2020-01-16  6:55             ` Stephan Mueller
2020-01-15 10:34         ` [PATCH v28 07/12] LRNG - add kernel crypto API PRNG extension Stephan Müller
2020-01-16  0:15           ` Randy Dunlap
2020-01-16  6:54             ` Stephan Mueller
2020-01-15 10:34         ` [PATCH v28 08/12] crypto: provide access to a static Jitter RNG state Stephan Müller
2020-01-15 10:34         ` [PATCH v28 09/12] LRNG - add Jitter RNG fast noise source Stephan Müller
2020-01-16  0:17           ` Randy Dunlap
2020-01-16  6:51             ` Stephan Mueller
2020-01-15 10:35         ` [PATCH v28 10/12] LRNG - add SP800-90B compliant health tests Stephan Müller
2020-01-15 10:35         ` [PATCH v28 11/12] LRNG - add interface for gathering of raw entropy Stephan Müller
2020-01-16  0:18           ` Randy Dunlap
2020-01-16  6:43             ` Stephan Mueller
2020-01-16  6:48               ` Randy Dunlap
2020-01-16  6:52                 ` Stephan Mueller
2020-01-15 10:36         ` [PATCH v28 12/12] LRNG - add power-on and runtime self-tests Stephan Müller
2020-01-19 21:12         ` [PATCH v29 00/12] /dev/random - a new approach with full SP800-90B Stephan Müller
2020-01-19 21:13           ` [PATCH v29 01/12] Linux Random Number Generator Stephan Müller
2020-01-19 21:13           ` [PATCH v29 02/12] LRNG - allocate one DRNG instance per NUMA node Stephan Müller
2020-01-19 21:14           ` [PATCH v29 03/12] LRNG - sysctls and /proc interface Stephan Müller
2020-01-19 21:14           ` [PATCH v29 04/12] LRNG - add switchable DRNG support Stephan Müller
2020-01-19 21:15           ` [PATCH v29 05/12] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2020-01-19 21:16           ` [PATCH v29 06/12] LRNG - add SP800-90A DRBG extension Stephan Müller
2020-01-19 21:16           ` [PATCH v29 07/12] LRNG - add kernel crypto API PRNG extension Stephan Müller
2020-01-19 21:17           ` [PATCH v29 08/12] crypto: provide access to a static Jitter RNG state Stephan Müller
2020-01-19 21:18           ` [PATCH v29 09/12] LRNG - add Jitter RNG fast noise source Stephan Müller
2020-01-19 21:18           ` [PATCH v29 10/12] LRNG - add SP800-90B compliant health tests Stephan Müller
2020-01-19 21:19           ` [PATCH v29 11/12] LRNG - add interface for gathering of raw entropy Stephan Müller
2020-01-19 21:20           ` [PATCH v29 12/12] LRNG - add power-on and runtime self-tests Stephan Müller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2355906.JbblJTOqSk@positron.chronox.de \
    --to=smueller@chronox.de \
    --cc=adilger.kernel@dilger.ca \
    --cc=arnd@arndb.de \
    --cc=darwish.07@gmail.com \
    --cc=draht@schaltsekun.de \
    --cc=ebiederm@xmission.com \
    --cc=fweimer@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jack@suse.cz \
    --cc=julia.lawall@inria.fr \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=marcelo.cerri@canonical.com \
    --cc=matthias.peter@bsi.bund.de \
    --cc=mccann@jhu.edu \
    --cc=mjg59@srcf.ucam.org \
    --cc=mzxreary@0pointer.de \
    --cc=nhorman@redhat.com \
    --cc=nstange@suse.de \
    --cc=patrakov@gmail.com \
    --cc=rdunlap@infradead.org \
    --cc=rstrode@redhat.com \
    --cc=tytso@mit.edu \
    --cc=vcaputo@pengaru.com \
    --cc=w@1wt.eu \
    --cc=zachary@baishancloud.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).