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