Home | History | Annotate | Line # | Download | only in kern
subr_cprng.c revision 1.39
      1  1.39  riastrad /*	$NetBSD: subr_cprng.c,v 1.39 2020/05/11 21:38:54 riastradh Exp $	*/
      2   1.1       tls 
      3   1.1       tls /*-
      4  1.36  riastrad  * Copyright (c) 2019 The NetBSD Foundation, Inc.
      5   1.1       tls  * All rights reserved.
      6   1.1       tls  *
      7   1.1       tls  * This code is derived from software contributed to The NetBSD Foundation
      8  1.36  riastrad  * by Taylor R. Campbell.
      9   1.1       tls  *
     10   1.1       tls  * Redistribution and use in source and binary forms, with or without
     11   1.1       tls  * modification, are permitted provided that the following conditions
     12   1.1       tls  * are met:
     13   1.1       tls  * 1. Redistributions of source code must retain the above copyright
     14   1.1       tls  *    notice, this list of conditions and the following disclaimer.
     15   1.1       tls  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1       tls  *    notice, this list of conditions and the following disclaimer in the
     17   1.1       tls  *    documentation and/or other materials provided with the distribution.
     18   1.1       tls  *
     19   1.1       tls  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1       tls  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1       tls  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1       tls  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1       tls  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1       tls  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1       tls  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1       tls  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1       tls  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1       tls  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1       tls  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1       tls  */
     31   1.1       tls 
     32  1.36  riastrad /*
     33  1.36  riastrad  * cprng_strong
     34  1.36  riastrad  *
     35  1.36  riastrad  *	Per-CPU NIST Hash_DRBG, reseeded automatically from the entropy
     36  1.36  riastrad  *	pool when we transition to full entropy, never blocking.  This
     37  1.36  riastrad  *	is slightly different from the old cprng_strong API, but the
     38  1.36  riastrad  *	only users of the old one fell into three categories:
     39  1.36  riastrad  *
     40  1.36  riastrad  *	1. never-blocking, oughta-be-per-CPU (kern_cprng, sysctl_prng)
     41  1.36  riastrad  *	2. never-blocking, used per-CPU anyway (/dev/urandom short reads)
     42  1.36  riastrad  *	3. /dev/random
     43  1.36  riastrad  *
     44  1.36  riastrad  *	This code serves the first two categories without having extra
     45  1.36  riastrad  *	logic for /dev/random.
     46  1.36  riastrad  *
     47  1.36  riastrad  *	kern_cprng - available at IPL_VM or lower
     48  1.36  riastrad  *	user_cprng - available only at IPL_NONE in thread context
     49  1.36  riastrad  *
     50  1.36  riastrad  *	The name kern_cprng is for hysterical raisins.  The name
     51  1.36  riastrad  *	user_cprng serves only to contrast with kern_cprng.
     52  1.36  riastrad  */
     53  1.36  riastrad 
     54  1.18  riastrad #include <sys/cdefs.h>
     55  1.39  riastrad __KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.39 2020/05/11 21:38:54 riastradh Exp $");
     56  1.18  riastrad 
     57   1.1       tls #include <sys/types.h>
     58  1.18  riastrad #include <sys/cprng.h>
     59  1.36  riastrad #include <sys/cpu.h>
     60  1.36  riastrad #include <sys/entropy.h>
     61  1.18  riastrad #include <sys/errno.h>
     62  1.36  riastrad #include <sys/evcnt.h>
     63  1.36  riastrad #include <sys/intr.h>
     64  1.18  riastrad #include <sys/kmem.h>
     65  1.24       tls #include <sys/percpu.h>
     66  1.36  riastrad #include <sys/sysctl.h>
     67   1.1       tls #include <sys/systm.h>
     68  1.18  riastrad 
     69  1.31  riastrad #include <crypto/nist_hash_drbg/nist_hash_drbg.h>
     70   1.1       tls 
     71  1.36  riastrad /*
     72  1.36  riastrad  * struct cprng_strong
     73  1.36  riastrad  */
     74  1.18  riastrad struct cprng_strong {
     75  1.36  riastrad 	struct percpu		*cs_percpu; /* struct cprng_cpu */
     76  1.36  riastrad 	ipl_cookie_t		cs_iplcookie;
     77  1.36  riastrad };
     78  1.21  riastrad 
     79  1.36  riastrad /*
     80  1.36  riastrad  * struct cprng_cpu
     81  1.36  riastrad  *
     82  1.36  riastrad  *	Per-CPU state for a cprng_strong.  The DRBG and evcnt are
     83  1.36  riastrad  *	allocated separately because percpu(9) sometimes moves per-CPU
     84  1.36  riastrad  *	objects around without zeroing them.
     85  1.36  riastrad  */
     86  1.36  riastrad struct cprng_cpu {
     87  1.36  riastrad 	struct nist_hash_drbg	*cc_drbg;
     88  1.36  riastrad 	struct {
     89  1.36  riastrad 		struct evcnt	reseed;
     90  1.36  riastrad 		struct evcnt	intr;
     91  1.36  riastrad 	}			*cc_evcnt;
     92  1.36  riastrad 	unsigned		cc_epoch;
     93  1.18  riastrad };
     94  1.18  riastrad 
     95  1.36  riastrad static int	sysctl_kern_urandom(SYSCTLFN_ARGS);
     96  1.36  riastrad static int	sysctl_kern_arandom(SYSCTLFN_ARGS);
     97  1.36  riastrad static void	cprng_init_cpu(void *, void *, struct cpu_info *);
     98  1.36  riastrad static void	cprng_fini_cpu(void *, void *, struct cpu_info *);
     99  1.36  riastrad 
    100  1.36  riastrad /* Well-known CPRNG instances */
    101  1.36  riastrad struct cprng_strong *kern_cprng __read_mostly; /* IPL_VM */
    102  1.36  riastrad struct cprng_strong *user_cprng __read_mostly; /* IPL_NONE */
    103  1.18  riastrad 
    104  1.36  riastrad static struct sysctllog *cprng_sysctllog __read_mostly;
    105  1.38  riastrad static bool cprng_initialized __read_mostly = false;
    106  1.18  riastrad 
    107  1.18  riastrad void
    108  1.36  riastrad cprng_init(void)
    109   1.8       tls {
    110   1.8       tls 
    111  1.36  riastrad 	if (__predict_false(nist_hash_drbg_initialize() != 0))
    112  1.36  riastrad 		panic("NIST Hash_DRBG failed self-test");
    113  1.36  riastrad 
    114  1.18  riastrad 	/*
    115  1.36  riastrad 	 * Create CPRNG instances at two IPLs: IPL_VM for kernel use
    116  1.36  riastrad 	 * that may occur inside IPL_VM interrupt handlers (!!??!?!?),
    117  1.36  riastrad 	 * and IPL_NONE for userland use which need not block
    118  1.36  riastrad 	 * interrupts.
    119  1.18  riastrad 	 */
    120  1.36  riastrad 	kern_cprng = cprng_strong_create("kern", IPL_VM, 0);
    121  1.36  riastrad 	user_cprng = cprng_strong_create("user", IPL_NONE, 0);
    122   1.8       tls 
    123  1.36  riastrad 	/* Create kern.urandom and kern.arandom sysctl nodes.  */
    124  1.36  riastrad 	sysctl_createv(&cprng_sysctllog, 0, NULL, NULL,
    125  1.36  riastrad 	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_INT, "urandom",
    126  1.36  riastrad 	    SYSCTL_DESCR("Independent uniform random 32-bit integer"),
    127  1.36  riastrad 	    sysctl_kern_urandom, 0, NULL, 0, CTL_KERN, KERN_URND, CTL_EOL);
    128  1.36  riastrad 	sysctl_createv(&cprng_sysctllog, 0, NULL, NULL,
    129  1.36  riastrad 	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_INT /*lie*/, "arandom",
    130  1.36  riastrad 	    SYSCTL_DESCR("Independent uniform random bytes, up to 256 bytes"),
    131  1.36  riastrad 	    sysctl_kern_arandom, 0, NULL, 0, CTL_KERN, KERN_ARND, CTL_EOL);
    132  1.38  riastrad 
    133  1.38  riastrad 	/* Ready to go.  */
    134  1.38  riastrad 	cprng_initialized = true;
    135   1.8       tls }
    136   1.8       tls 
    137  1.18  riastrad /*
    138  1.36  riastrad  * sysctl kern.urandom
    139  1.36  riastrad  *
    140  1.36  riastrad  *	Independent uniform random 32-bit integer.  Read-only.
    141  1.18  riastrad  */
    142  1.18  riastrad static int
    143  1.36  riastrad sysctl_kern_urandom(SYSCTLFN_ARGS)
    144  1.18  riastrad {
    145  1.36  riastrad 	struct sysctlnode node = *rnode;
    146  1.36  riastrad 	int v;
    147  1.36  riastrad 	int error;
    148   1.1       tls 
    149  1.36  riastrad 	/* Generate an int's worth of data.  */
    150  1.36  riastrad 	cprng_strong(user_cprng, &v, sizeof v, 0);
    151   1.7       tls 
    152  1.36  riastrad 	/* Do the sysctl dance.  */
    153  1.36  riastrad 	node.sysctl_data = &v;
    154  1.36  riastrad 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    155  1.36  riastrad 
    156  1.36  riastrad 	/* Clear the buffer before returning the sysctl error.  */
    157  1.36  riastrad 	explicit_memset(&v, 0, sizeof v);
    158  1.36  riastrad 	return error;
    159   1.1       tls }
    160   1.1       tls 
    161  1.36  riastrad /*
    162  1.36  riastrad  * sysctl kern.arandom
    163  1.36  riastrad  *
    164  1.36  riastrad  *	Independent uniform random bytes, up to 256 bytes.  Read-only.
    165  1.36  riastrad  */
    166  1.29  christos static int
    167  1.36  riastrad sysctl_kern_arandom(SYSCTLFN_ARGS)
    168  1.29  christos {
    169  1.36  riastrad 	struct sysctlnode node = *rnode;
    170  1.36  riastrad 	uint8_t buf[256];
    171  1.36  riastrad 	int error;
    172  1.29  christos 
    173  1.36  riastrad 	/*
    174  1.36  riastrad 	 * Clamp to a reasonably small size.  256 bytes is kind of
    175  1.36  riastrad 	 * arbitrary; 32 would be more reasonable, but we used 256 in
    176  1.36  riastrad 	 * the past, so let's not break compatibility.
    177  1.36  riastrad 	 */
    178  1.36  riastrad 	if (*oldlenp > 256)	/* size_t, so never negative */
    179  1.37       nia 		*oldlenp = 256;
    180  1.29  christos 
    181  1.36  riastrad 	/* Generate data.  */
    182  1.36  riastrad 	cprng_strong(user_cprng, buf, *oldlenp, 0);
    183  1.29  christos 
    184  1.36  riastrad 	/* Do the sysctl dance.  */
    185  1.36  riastrad 	node.sysctl_data = buf;
    186  1.36  riastrad 	node.sysctl_size = *oldlenp;
    187  1.36  riastrad 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    188  1.36  riastrad 
    189  1.36  riastrad 	/* Clear the buffer before returning the sysctl error.  */
    190  1.36  riastrad 	explicit_memset(buf, 0, sizeof buf);
    191  1.36  riastrad 	return error;
    192  1.29  christos }
    193  1.29  christos 
    194  1.36  riastrad struct cprng_strong *
    195  1.36  riastrad cprng_strong_create(const char *name, int ipl, int flags)
    196  1.29  christos {
    197  1.36  riastrad 	struct cprng_strong *cprng;
    198  1.29  christos 
    199  1.36  riastrad 	cprng = kmem_alloc(sizeof(*cprng), KM_SLEEP);
    200  1.36  riastrad 	cprng->cs_iplcookie = makeiplcookie(ipl);
    201  1.36  riastrad 	cprng->cs_percpu = percpu_create(sizeof(struct cprng_cpu),
    202  1.36  riastrad 	    cprng_init_cpu, cprng_fini_cpu, __UNCONST(name));
    203  1.29  christos 
    204  1.36  riastrad 	return cprng;
    205  1.29  christos }
    206  1.29  christos 
    207  1.36  riastrad void
    208  1.36  riastrad cprng_strong_destroy(struct cprng_strong *cprng)
    209  1.15       tls {
    210  1.18  riastrad 
    211  1.36  riastrad 	percpu_free(cprng->cs_percpu, sizeof(struct cprng_cpu));
    212  1.36  riastrad 	kmem_free(cprng, sizeof(*cprng));
    213  1.15       tls }
    214  1.15       tls 
    215  1.18  riastrad static void
    216  1.36  riastrad cprng_init_cpu(void *ptr, void *cookie, struct cpu_info *ci)
    217  1.18  riastrad {
    218  1.36  riastrad 	struct cprng_cpu *cc = ptr;
    219  1.36  riastrad 	const char *name = cookie;
    220  1.39  riastrad 	const char *cpuname;
    221  1.36  riastrad 	uint8_t zero[NIST_HASH_DRBG_SEEDLEN_BYTES] = {0};
    222  1.36  riastrad 	char namebuf[64];	/* XXX size? */
    223  1.18  riastrad 
    224  1.18  riastrad 	/*
    225  1.36  riastrad 	 * Format the name as, e.g., kern/8 if we're on cpu8.  This
    226  1.36  riastrad 	 * doesn't get displayed anywhere; it just ensures that if
    227  1.36  riastrad 	 * there were a bug causing us to use the same otherwise secure
    228  1.36  riastrad 	 * seed on multiple CPUs, we would still get independent output
    229  1.36  riastrad 	 * from the NIST Hash_DRBG.
    230  1.18  riastrad 	 */
    231  1.36  riastrad 	snprintf(namebuf, sizeof namebuf, "%s/%u", name, cpu_index(ci));
    232   1.1       tls 
    233  1.18  riastrad 	/*
    234  1.36  riastrad 	 * Allocate the struct nist_hash_drbg and struct evcnt
    235  1.36  riastrad 	 * separately, since percpu(9) may move objects around in
    236  1.36  riastrad 	 * memory without zeroing.
    237  1.18  riastrad 	 */
    238  1.36  riastrad 	cc->cc_drbg = kmem_zalloc(sizeof(*cc->cc_drbg), KM_SLEEP);
    239  1.36  riastrad 	cc->cc_evcnt = kmem_alloc(sizeof(*cc->cc_evcnt), KM_SLEEP);
    240   1.1       tls 
    241  1.18  riastrad 	/*
    242  1.36  riastrad 	 * Initialize the DRBG with no seed.  We do this in order to
    243  1.36  riastrad 	 * defer reading from the entropy pool as long as possible.
    244  1.18  riastrad 	 */
    245  1.36  riastrad 	if (__predict_false(nist_hash_drbg_instantiate(cc->cc_drbg,
    246  1.36  riastrad 		    zero, sizeof zero, NULL, 0, namebuf, strlen(namebuf))))
    247  1.36  riastrad 		panic("nist_hash_drbg_instantiate");
    248  1.36  riastrad 
    249  1.36  riastrad 	/* Attach the event counters.  */
    250  1.39  riastrad 	/* XXX ci_cpuname may not be initialized early enough.  */
    251  1.39  riastrad 	cpuname = ci->ci_cpuname[0] == '\0' ? "cpu0" : ci->ci_cpuname;
    252  1.36  riastrad 	evcnt_attach_dynamic(&cc->cc_evcnt->intr, EVCNT_TYPE_MISC, NULL,
    253  1.39  riastrad 	    cpuname, "cprng_strong intr");
    254  1.36  riastrad 	evcnt_attach_dynamic(&cc->cc_evcnt->reseed, EVCNT_TYPE_MISC, NULL,
    255  1.39  riastrad 	    cpuname, "cprng_strong reseed");
    256  1.36  riastrad 
    257  1.36  riastrad 	/* Set the epoch uninitialized so we reseed on first use.  */
    258  1.36  riastrad 	cc->cc_epoch = 0;
    259  1.18  riastrad }
    260   1.1       tls 
    261  1.18  riastrad static void
    262  1.36  riastrad cprng_fini_cpu(void *ptr, void *cookie, struct cpu_info *ci)
    263  1.18  riastrad {
    264  1.36  riastrad 	struct cprng_cpu *cc = ptr;
    265   1.5       tls 
    266  1.36  riastrad 	evcnt_detach(&cc->cc_evcnt->reseed);
    267  1.36  riastrad 	evcnt_detach(&cc->cc_evcnt->intr);
    268  1.36  riastrad 	if (__predict_false(nist_hash_drbg_destroy(cc->cc_drbg)))
    269  1.36  riastrad 		panic("nist_hash_drbg_destroy");
    270   1.1       tls 
    271  1.36  riastrad 	kmem_free(cc->cc_evcnt, sizeof(*cc->cc_evcnt));
    272  1.36  riastrad 	kmem_free(cc->cc_drbg, sizeof(*cc->cc_drbg));
    273   1.1       tls }
    274   1.1       tls 
    275  1.36  riastrad size_t
    276  1.36  riastrad cprng_strong(struct cprng_strong *cprng, void *buf, size_t len, int flags)
    277   1.1       tls {
    278  1.36  riastrad 	uint32_t seed[NIST_HASH_DRBG_SEEDLEN_BYTES];
    279  1.36  riastrad 	struct cprng_cpu *cc;
    280  1.36  riastrad 	unsigned epoch;
    281  1.36  riastrad 	int s;
    282   1.1       tls 
    283   1.1       tls 	/*
    284  1.38  riastrad 	 * Some device drivers try to use cprng_strong in attach during
    285  1.38  riastrad 	 * autoconf, e.g. to randomly generate MAC addresses, before we
    286  1.38  riastrad 	 * percpu is available -- percpu is not available until after
    287  1.38  riastrad 	 * CPUs have been detected during autoconf.  We should make
    288  1.38  riastrad 	 * percpu available sooner, but for now this works around it.
    289  1.38  riastrad 	 */
    290  1.38  riastrad 	if (__predict_false(!cprng_initialized)) {
    291  1.38  riastrad 		struct nist_hash_drbg drbg;
    292  1.38  riastrad 		entropy_extract(seed, sizeof seed, 0);
    293  1.38  riastrad 		if (__predict_false(nist_hash_drbg_instantiate(&drbg,
    294  1.38  riastrad 			    seed, sizeof seed, NULL, 0, NULL, 0)))
    295  1.38  riastrad 			panic("nist_hash_drbg_instantiate");
    296  1.38  riastrad 		if (__predict_false(nist_hash_drbg_generate(&drbg, buf, len,
    297  1.38  riastrad 			    NULL, 0)))
    298  1.38  riastrad 			panic("nist_hash_drbg_generate");
    299  1.38  riastrad 		return len;
    300  1.38  riastrad 	}
    301  1.38  riastrad 
    302  1.38  riastrad 	/*
    303  1.36  riastrad 	 * Verify maximum request length.  Caller should really limit
    304  1.36  riastrad 	 * their requests to 32 bytes to avoid spending much time with
    305  1.36  riastrad 	 * preemption disabled -- use the 32 bytes to seed a private
    306  1.36  riastrad 	 * DRBG instance if you need more data.
    307   1.1       tls 	 */
    308  1.36  riastrad 	KASSERT(len <= CPRNG_MAX_LEN);
    309  1.18  riastrad 
    310  1.36  riastrad 	/* Verify legacy API use.  */
    311  1.36  riastrad 	KASSERT(flags == 0);
    312   1.1       tls 
    313  1.36  riastrad 	/* Acquire per-CPU state and block interrupts.  */
    314  1.36  riastrad 	cc = percpu_getref(cprng->cs_percpu);
    315  1.36  riastrad 	s = splraiseipl(cprng->cs_iplcookie);
    316  1.36  riastrad 
    317  1.36  riastrad 	if (cpu_intr_p())
    318  1.36  riastrad 		cc->cc_evcnt->intr.ev_count++;
    319  1.36  riastrad 
    320  1.36  riastrad 	/* If the entropy epoch has changed, (re)seed.  */
    321  1.36  riastrad 	epoch = entropy_epoch();
    322  1.36  riastrad 	if (__predict_false(epoch != cc->cc_epoch)) {
    323  1.36  riastrad 		entropy_extract(seed, sizeof seed, 0);
    324  1.36  riastrad 		cc->cc_evcnt->reseed.ev_count++;
    325  1.36  riastrad 		if (__predict_false(nist_hash_drbg_reseed(cc->cc_drbg,
    326  1.36  riastrad 			    seed, sizeof seed, NULL, 0)))
    327  1.36  riastrad 			panic("nist_hash_drbg_reseed");
    328  1.36  riastrad 		explicit_memset(seed, 0, sizeof seed);
    329  1.36  riastrad 		cc->cc_epoch = epoch;
    330  1.36  riastrad 	}
    331   1.1       tls 
    332  1.36  riastrad 	/* Generate data.  Failure here means it's time to reseed.  */
    333  1.36  riastrad 	if (__predict_false(nist_hash_drbg_generate(cc->cc_drbg, buf, len,
    334  1.36  riastrad 		    NULL, 0))) {
    335  1.36  riastrad 		entropy_extract(seed, sizeof seed, 0);
    336  1.36  riastrad 		cc->cc_evcnt->reseed.ev_count++;
    337  1.36  riastrad 		if (__predict_false(nist_hash_drbg_reseed(cc->cc_drbg,
    338  1.36  riastrad 			    seed, sizeof seed, NULL, 0)))
    339  1.36  riastrad 			panic("nist_hash_drbg_reseed");
    340  1.36  riastrad 		explicit_memset(seed, 0, sizeof seed);
    341  1.36  riastrad 		if (__predict_false(nist_hash_drbg_generate(cc->cc_drbg,
    342  1.36  riastrad 			    buf, len, NULL, 0)))
    343  1.36  riastrad 			panic("nist_hash_drbg_generate");
    344  1.36  riastrad 	}
    345  1.23     pooka 
    346  1.36  riastrad 	/* Release state and interrupts.  */
    347  1.36  riastrad 	splx(s);
    348  1.36  riastrad 	percpu_putref(cprng->cs_percpu);
    349  1.23     pooka 
    350  1.36  riastrad 	/* Return the number of bytes generated, for hysterical raisins.  */
    351  1.36  riastrad 	return len;
    352  1.23     pooka }
    353  1.23     pooka 
    354  1.36  riastrad uint32_t
    355  1.36  riastrad cprng_strong32(void)
    356  1.23     pooka {
    357  1.36  riastrad 	uint32_t r;
    358  1.36  riastrad 	cprng_strong(kern_cprng, &r, sizeof(r), 0);
    359  1.36  riastrad 	return r;
    360  1.23     pooka }
    361  1.23     pooka 
    362  1.36  riastrad uint64_t
    363  1.36  riastrad cprng_strong64(void)
    364  1.23     pooka {
    365  1.36  riastrad 	uint64_t r;
    366  1.36  riastrad 	cprng_strong(kern_cprng, &r, sizeof(r), 0);
    367  1.36  riastrad 	return r;
    368  1.23     pooka }
    369