linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Stephan Müller" <smueller@chronox.de>
To: Tso Ted <tytso@mit.edu>, linux-crypto@vger.kernel.org
Cc: Willy Tarreau <w@1wt.eu>, Nicolai Stange <nstange@suse.de>,
	LKML <linux-kernel@vger.kernel.org>,
	Arnd Bergmann <arnd@arndb.de>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	"Alexander E. Patrakov" <patrakov@gmail.com>,
	"Ahmed S. Darwish" <darwish.07@gmail.com>,
	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>,
	Peter Matthias <matthias.peter@bsi.bund.de>,
	Marcelo Henrique Cerri <marcelo.cerri@canonical.com>,
	Neil Horman <nhorman@redhat.com>,
	Randy Dunlap <rdunlap@infradead.org>,
	Julia Lawall <julia.lawall@inria.fr>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	Andy Lavr <andy.lavr@gmail.com>,
	Eric Biggers <ebiggers@kernel.org>,
	"Jason A. Donenfeld" <Jason@zx2c4.com>,
	Petr Tesarik <ptesarik@suse.cz>,
	John Haxby <john.haxby@oracle.com>,
	Alexander Lobakin <alobakin@mailbox.org>,
	Jirka Hladky <jhladky@redhat.com>
Subject: [PATCH v43 09/15] LRNG - add SP800-90A DRBG extension
Date: Sun, 21 Nov 2021 17:44:36 +0100	[thread overview]
Message-ID: <2514269.vYhyI6sBWr@positron.chronox.de> (raw)
In-Reply-To: <2036923.9o76ZdvQCi@positron.chronox.de>

Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: Torsten Duwe <duwe@lst.de>
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>
Reviewed-by: Alexander Lobakin <alobakin@pm.me>
Tested-by: Alexander Lobakin <alobakin@pm.me>
Reviewed-by: Roman Drahtmueller <draht@schaltsekun.de>
Tested-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
Tested-by: Neil Horman <nhorman@redhat.com>
Tested-by: Jirka Hladky <jhladky@redhat.com>
Reviewed-by: Jirka Hladky <jhladky@redhat.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 drivers/char/lrng/Kconfig     |  10 ++
 drivers/char/lrng/Makefile    |   1 +
 drivers/char/lrng/lrng_drbg.c | 198 ++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 531b34b9ae65..d06d0417b025 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -268,6 +268,16 @@ config LRNG_KCAPI_HASH
 	bool
 	select CRYPTO_HASH
 
+config LRNG_DRBG
+	tristate "SP800-90A support for the LRNG"
+	depends on CRYPTO
+	select CRYPTO_DRBG_MENU
+	select CRYPTO_SHA512
+	select LRNG_KCAPI_HASH
+	help
+	  Enable the SP800-90A DRBG support for the LRNG. Once the
+	  module is loaded, output from /dev/random, /dev/urandom,
+	  getrandom(2), or get_random_bytes_full is provided by a DRBG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index cb9b03bdfd00..c00e15b6396e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_NUMA)		+= lrng_numa.o
 obj-$(CONFIG_LRNG_CPU)		+= lrng_es_archrandom.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH)	+= lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)	+= lrng_kcapi_hash.o
+obj-$(CONFIG_LRNG_DRBG)		+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index 000000000000..6ca6b05eccf4
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller <smueller@chronox.de>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <crypto/drbg.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/lrng.h>
+
+#include "lrng_kcapi_hash.h"
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+	const char *hash_name;
+	const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+	{	/* CTR_DRBG with AES-256 using derivation function */
+		.hash_name = "sha512",
+		.drbg_core = "drbg_nopr_ctr_aes256",
+	}, {	/* HMAC_DRBG with SHA-512 */
+		.hash_name = "sha512",
+		.drbg_core = "drbg_nopr_hmac_sha512",
+	}, {	/* Hash_DRBG with SHA-512 using derivation function */
+		.hash_name = "sha512",
+		.drbg_core = "drbg_nopr_sha512"
+	}
+};
+
+static int lrng_drbg_drng_seed_helper(void *drng, const u8 *inbuf, u32 inbuflen)
+{
+	struct drbg_state *drbg = (struct drbg_state *)drng;
+	LIST_HEAD(seedlist);
+	struct drbg_string data;
+	int ret;
+
+	drbg_string_fill(&data, inbuf, inbuflen);
+	list_add_tail(&data.list, &seedlist);
+	ret = drbg->d_ops->update(drbg, &seedlist, drbg->seeded);
+
+	if (ret >= 0)
+		drbg->seeded = true;
+
+	return ret;
+}
+
+static int lrng_drbg_drng_generate_helper(void *drng, u8 *outbuf, u32 outbuflen)
+{
+	struct drbg_state *drbg = (struct drbg_state *)drng;
+
+	return drbg->d_ops->generate(drbg, outbuf, outbuflen, NULL);
+}
+
+static void *lrng_drbg_drng_alloc(u32 sec_strength)
+{
+	struct drbg_state *drbg;
+	int coreref = -1;
+	bool pr = false;
+	int ret;
+
+	drbg_convert_tfm_core(lrng_drbg_types[lrng_drbg_type].drbg_core,
+			      &coreref, &pr);
+	if (coreref < 0)
+		return ERR_PTR(-EFAULT);
+
+	drbg = kzalloc(sizeof(struct drbg_state), GFP_KERNEL);
+	if (!drbg)
+		return ERR_PTR(-ENOMEM);
+
+	drbg->core = &drbg_cores[coreref];
+	drbg->seeded = false;
+	ret = drbg_alloc_state(drbg);
+	if (ret)
+		goto err;
+
+	if (sec_strength > drbg_sec_strength(drbg->core->flags)) {
+		pr_err("Security strength of DRBG (%u bits) lower than requested by LRNG (%u bits)\n",
+			drbg_sec_strength(drbg->core->flags) * 8,
+			sec_strength * 8);
+		goto dealloc;
+	}
+
+	if (sec_strength < drbg_sec_strength(drbg->core->flags))
+		pr_warn("Security strength of DRBG (%u bits) higher than requested by LRNG (%u bits)\n",
+			drbg_sec_strength(drbg->core->flags) * 8,
+			sec_strength * 8);
+
+	pr_info("DRBG with %s core allocated\n", drbg->core->backend_cra_name);
+
+	return drbg;
+
+dealloc:
+	if (drbg->d_ops)
+		drbg->d_ops->crypto_fini(drbg);
+	drbg_dealloc_state(drbg);
+err:
+	kfree(drbg);
+	return ERR_PTR(-EINVAL);
+}
+
+static void lrng_drbg_drng_dealloc(void *drng)
+{
+	struct drbg_state *drbg = (struct drbg_state *)drng;
+
+	if (drbg && drbg->d_ops)
+		drbg->d_ops->crypto_fini(drbg);
+	drbg_dealloc_state(drbg);
+	kfree_sensitive(drbg);
+	pr_info("DRBG deallocated\n");
+}
+
+static void *lrng_drbg_hash_alloc(void)
+{
+	return lrng_kcapi_hash_alloc(lrng_drbg_types[lrng_drbg_type].hash_name);
+}
+
+static const char *lrng_drbg_name(void)
+{
+	return lrng_drbg_types[lrng_drbg_type].drbg_core;
+}
+
+static const char *lrng_hash_name(void)
+{
+	return lrng_drbg_types[lrng_drbg_type].hash_name;
+}
+
+static const struct lrng_crypto_cb lrng_drbg_crypto_cb = {
+	.lrng_drng_name			= lrng_drbg_name,
+	.lrng_hash_name			= lrng_hash_name,
+	.lrng_drng_alloc		= lrng_drbg_drng_alloc,
+	.lrng_drng_dealloc		= lrng_drbg_drng_dealloc,
+	.lrng_drng_seed_helper		= lrng_drbg_drng_seed_helper,
+	.lrng_drng_generate_helper	= lrng_drbg_drng_generate_helper,
+	.lrng_hash_alloc		= lrng_drbg_hash_alloc,
+	.lrng_hash_dealloc		= lrng_kcapi_hash_dealloc,
+	.lrng_hash_digestsize		= lrng_kcapi_hash_digestsize,
+	.lrng_hash_init			= lrng_kcapi_hash_init,
+	.lrng_hash_update		= lrng_kcapi_hash_update,
+	.lrng_hash_final		= lrng_kcapi_hash_final,
+	.lrng_hash_desc_zero		= lrng_kcapi_hash_zero,
+};
+
+static int __init lrng_drbg_init(void)
+{
+	if (lrng_drbg_type >= ARRAY_SIZE(lrng_drbg_types)) {
+		pr_err("lrng_drbg_type parameter too large (given %u - max: %lu)",
+		       lrng_drbg_type,
+		       (unsigned long)ARRAY_SIZE(lrng_drbg_types) - 1);
+		return -EAGAIN;
+	}
+	return lrng_set_drng_cb(&lrng_drbg_crypto_cb);
+}
+
+static void __exit lrng_drbg_exit(void)
+{
+	lrng_set_drng_cb(NULL);
+}
+
+late_initcall(lrng_drbg_init);
+module_exit(lrng_drbg_exit);
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
+MODULE_DESCRIPTION("Linux Random Number Generator - SP800-90A DRBG backend");
-- 
2.31.1





  parent reply	other threads:[~2021-11-21 16:49 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-21 16:39 [PATCH v43 00/15] /dev/random - a new approach Stephan Müller
2021-11-21 16:40 ` [PATCH v43 01/15] Linux Random Number Generator Stephan Müller
2021-11-21 17:23   ` Joe Perches
2021-11-21 22:42   ` Jason A. Donenfeld
2021-11-22  5:34     ` Stephan Mueller
2021-11-22  6:02       ` Greg Kroah-Hartman
2021-11-22  6:42         ` Stephan Mueller
2021-11-22  6:55           ` Greg Kroah-Hartman
2021-11-22 15:09             ` Simo Sorce
2021-11-22 21:06               ` Jeffrey Walton
2021-11-23  5:38                 ` Stephan Mueller
2021-11-26 15:42               ` Greg Kroah-Hartman
2021-11-22 16:56         ` John Haxby
2021-11-26 15:40           ` Greg Kroah-Hartman
2021-11-22 14:59     ` Simo Sorce
2021-11-26 15:44       ` Greg Kroah-Hartman
2021-11-26 16:15         ` Stephan Mueller
2021-11-26 16:22           ` Greg Kroah-Hartman
2021-11-29 15:31             ` Stephan Mueller
2021-11-29 16:25               ` Greg Kroah-Hartman
2021-11-29 16:50                 ` Stephan Mueller
2021-11-30 12:24                 ` Jeffrey Walton
2021-11-30 14:04                   ` Greg Kroah-Hartman
2021-11-30 14:31                     ` Simo Sorce
2021-11-30 15:45                       ` Greg Kroah-Hartman
2021-11-30 17:05                         ` Willy Tarreau
2021-11-30 17:08                         ` Simo Sorce
2021-11-30 18:15                         ` Eric Biggers
2021-11-30 18:39                           ` Jason A. Donenfeld
2021-11-30 19:41                             ` Simo Sorce
2021-12-01 16:02                               ` Jason A. Donenfeld
2021-12-01 17:19                                 ` Simo Sorce
2021-12-01 17:55                                   ` Boris Krasnovskiy
2021-12-01 18:05                                     ` Greg Kroah-Hartman
2021-12-01 18:24                                   ` Jason A. Donenfeld
2021-12-02  0:24                                     ` Jeffrey Walton
2021-12-02  7:12                                       ` Greg Kroah-Hartman
2021-12-02 15:50                                         ` John Haxby
2021-12-01 18:29                                   ` Jason A. Donenfeld
     [not found]                                 ` <BY5PR14MB3416DF44172D8F47D0B078A986689@BY5PR14MB3416.namprd14.prod.outlook.com>
2021-12-01 18:05                                   ` Greg Kroah-Hartman
2021-12-10  1:43                                 ` Marcelo Henrique Cerri
2021-12-10  6:46                                   ` Greg Kroah-Hartman
2021-12-10  9:30                                     ` Marcelo Henrique Cerri
2021-12-10  9:48                                       ` Greg Kroah-Hartman
2021-12-10 17:02                                         ` Simo Sorce
2021-12-11  7:06                                           ` Willy Tarreau
2021-12-11  8:09                                             ` Stephan Müller
2021-12-11  8:57                                               ` Willy Tarreau
2022-01-10 13:23                                   ` Marcelo Henrique Cerri
2022-01-10 14:11                                     ` Jason A. Donenfeld
2022-01-10 14:29                                       ` Theodore Ts'o
2022-01-10 14:38                                         ` Jason A. Donenfeld
2022-01-10 17:38                                           ` Theodore Ts'o
2022-01-10 18:29                                             ` Eric Biggers
2022-01-10 18:44                                               ` Jason A. Donenfeld
2022-01-10 19:41                                                 ` Simo Sorce
2022-01-10 20:05                                                   ` Eric Biggers
2022-01-10 19:49                                                 ` Theodore Ts'o
2022-01-10 22:19                                                   ` Jason A. Donenfeld
2022-01-11  1:44                                                     ` Andy Lutomirski
2022-01-11  3:10                                                       ` Theodore Ts'o
2022-01-11  4:04                                                         ` Willy Tarreau
2022-01-11  4:13                                                         ` Matthew Garrett
2022-01-11 10:01                                                           ` Alexander E. Patrakov
     [not found]                                                           ` <CAN_LGv0CTDi9k=t=TGHvaHZz5YVT+OUEBaRXjP=Xv=kousHY1w@mail.gmail.com>
2022-01-11 17:10                                                             ` Matthew Garrett
2022-01-11 13:16                                                         ` Jason A. Donenfeld
2022-01-11 16:08                                                           ` Theodore Ts'o
2022-01-11 13:06                                                       ` Jason A. Donenfeld
2022-01-11 15:10                                                         ` Andy Lutomirski
2022-01-10 21:38                                                 ` Jason A. Donenfeld
2022-01-10 15:07                                         ` Marcelo Henrique Cerri
2021-11-30 15:13                     ` Jeffrey Walton
2021-11-30 15:39                       ` Greg Kroah-Hartman
2021-11-30  7:32       ` Sandy Harris
2021-11-30  7:55         ` Greg Kroah-Hartman
2021-11-30  8:56           ` Stephan Mueller
2021-11-30  9:12             ` Greg Kroah-Hartman
2021-12-04  9:53           ` Sandy Harris
2021-11-22 10:33   ` kernel test robot
2021-11-22 11:47     ` Stephan Mueller
2021-11-25  5:25       ` [kbuild-all] " Chen, Rong A
2021-11-30  2:55         ` Sandy Harris
2021-11-30  6:06           ` Stephan Müller
2021-11-21 16:40 ` [PATCH v43 02/15] LRNG - IRQ entropy source Stephan Müller
2021-11-21 16:40 ` [PATCH v43 03/15] LRNG - sysctls and /proc interface Stephan Müller
2021-11-21 16:41 ` [PATCH v43 04/15] LRNG - allocate one DRNG instance per NUMA node Stephan Müller
2021-11-21 16:42 ` [PATCH v43 05/15] LRNG - CPU entropy source Stephan Müller
2021-11-22  7:09   ` kernel test robot
2021-11-22 11:48     ` Stephan Mueller
2021-11-21 16:42 ` [PATCH v43 06/15] LRNG - add switchable DRNG support Stephan Müller
2021-11-21 16:43 ` [PATCH v43 07/15] LRNG - add common generic hash support Stephan Müller
2021-11-21 16:43 ` [PATCH v43 08/15] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2021-11-21 16:44 ` Stephan Müller [this message]
2021-11-21 16:45 ` [PATCH v43 10/15] LRNG - add kernel crypto API PRNG extension Stephan Müller
2021-11-21 16:45 ` [PATCH v43 11/15] crypto: move Jitter RNG header include dir Stephan Müller
2021-11-21 16:46 ` [PATCH v43 12/15] LRNG - add Jitter RNG fast noise source Stephan Müller
2021-11-21 16:46 ` [PATCH v43 13/15] LRNG - add SP800-90B compliant health tests Stephan Müller
2021-11-21 16:47 ` [PATCH v43 14/15] LRNG - add interface for gathering of raw entropy Stephan Müller
2021-11-21 16:47 ` [PATCH v43 15/15] LRNG - add power-on and runtime self-tests Stephan Müller
2021-12-11 15:45 ` [PATCH v43 00/15] /dev/random - a new approach Thomas Schoebel-Theuer
2021-12-11 16:04   ` Willy Tarreau

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=2514269.vYhyI6sBWr@positron.chronox.de \
    --to=smueller@chronox.de \
    --cc=Jason@zx2c4.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=alobakin@mailbox.org \
    --cc=andy.lavr@gmail.com \
    --cc=arnd@arndb.de \
    --cc=dan.carpenter@oracle.com \
    --cc=darwish.07@gmail.com \
    --cc=ebiederm@xmission.com \
    --cc=ebiggers@kernel.org \
    --cc=fweimer@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jack@suse.cz \
    --cc=jhladky@redhat.com \
    --cc=john.haxby@oracle.com \
    --cc=julia.lawall@inria.fr \
    --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=ptesarik@suse.cz \
    --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).