Move cprng_init before configure. This makes it available to device drivers, e.g. to generate MAC addresses at random, without initialization order hacks. Requires a minor initialization hack for cpu_name(primary cpu) early on, since that doesn't get set until mi_cpu_attach which may not run until the middle of configure. But this hack is less bad than other initialization order hacks.diff -r1.524 -r1.525 src/sys/kern/init_main.c
(riastradh)
--- src/sys/kern/init_main.c 2020/04/30 03:28:18 1.524
+++ src/sys/kern/init_main.c 2020/05/11 21:38:54 1.525
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: init_main.c,v 1.524 2020/04/30 03:28:18 riastradh Exp $ */ | 1 | /* $NetBSD: init_main.c,v 1.525 2020/05/11 21:38:54 riastradh Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2008, 2009, 2019 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2008, 2009, 2019 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -87,27 +87,27 @@ | @@ -87,27 +87,27 @@ | |||
87 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 87 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
88 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 88 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
89 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 89 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
90 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 90 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
91 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 91 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
92 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 92 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
93 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 93 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
94 | * SUCH DAMAGE. | 94 | * SUCH DAMAGE. | |
95 | * | 95 | * | |
96 | * @(#)init_main.c 8.16 (Berkeley) 5/14/95 | 96 | * @(#)init_main.c 8.16 (Berkeley) 5/14/95 | |
97 | */ | 97 | */ | |
98 | 98 | |||
99 | #include <sys/cdefs.h> | 99 | #include <sys/cdefs.h> | |
100 | __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.524 2020/04/30 03:28:18 riastradh Exp $"); | 100 | __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.525 2020/05/11 21:38:54 riastradh Exp $"); | |
101 | 101 | |||
102 | #include "opt_ddb.h" | 102 | #include "opt_ddb.h" | |
103 | #include "opt_inet.h" | 103 | #include "opt_inet.h" | |
104 | #include "opt_ipsec.h" | 104 | #include "opt_ipsec.h" | |
105 | #include "opt_modular.h" | 105 | #include "opt_modular.h" | |
106 | #include "opt_ntp.h" | 106 | #include "opt_ntp.h" | |
107 | #include "opt_pipe.h" | 107 | #include "opt_pipe.h" | |
108 | #include "opt_syscall_debug.h" | 108 | #include "opt_syscall_debug.h" | |
109 | #include "opt_sysv.h" | 109 | #include "opt_sysv.h" | |
110 | #include "opt_fileassoc.h" | 110 | #include "opt_fileassoc.h" | |
111 | #include "opt_ktrace.h" | 111 | #include "opt_ktrace.h" | |
112 | #include "opt_pax.h" | 112 | #include "opt_pax.h" | |
113 | #include "opt_compat_netbsd.h" | 113 | #include "opt_compat_netbsd.h" | |
@@ -385,26 +385,28 @@ main(void) | @@ -385,26 +385,28 @@ main(void) | |||
385 | size_t splash_size = (&_binary_splash_image_end - | 385 | size_t splash_size = (&_binary_splash_image_end - | |
386 | &_binary_splash_image_start) * sizeof(void *); | 386 | &_binary_splash_image_start) * sizeof(void *); | |
387 | splash_setimage(&_binary_splash_image_start, splash_size); | 387 | splash_setimage(&_binary_splash_image_start, splash_size); | |
388 | #endif | 388 | #endif | |
389 | 389 | |||
390 | /* Initialize sockets. */ | 390 | /* Initialize sockets. */ | |
391 | soinit(); | 391 | soinit(); | |
392 | 392 | |||
393 | /* | 393 | /* | |
394 | * The following things must be done before autoconfiguration. | 394 | * The following things must be done before autoconfiguration. | |
395 | */ | 395 | */ | |
396 | rnd_init(); /* initialize entropy pool */ | 396 | rnd_init(); /* initialize entropy pool */ | |
397 | 397 | |||
398 | cprng_init(); /* initialize cryptographic PRNG */ | |||
399 | ||||
398 | /* Initialize process and pgrp structures. */ | 400 | /* Initialize process and pgrp structures. */ | |
399 | procinit(); | 401 | procinit(); | |
400 | lwpinit(); | 402 | lwpinit(); | |
401 | 403 | |||
402 | /* Must be called after lwpinit (lwpinit_specificdata) */ | 404 | /* Must be called after lwpinit (lwpinit_specificdata) */ | |
403 | psref_init(); | 405 | psref_init(); | |
404 | 406 | |||
405 | /* Initialize signal-related data structures. */ | 407 | /* Initialize signal-related data structures. */ | |
406 | signal_init(); | 408 | signal_init(); | |
407 | 409 | |||
408 | /* Initialize resource management. */ | 410 | /* Initialize resource management. */ | |
409 | resource_init(); | 411 | resource_init(); | |
410 | 412 | |||
@@ -519,28 +521,26 @@ main(void) | @@ -519,28 +521,26 @@ main(void) | |||
519 | soinit1(); | 521 | soinit1(); | |
520 | 522 | |||
521 | /* | 523 | /* | |
522 | * Initialize the bufq strategy sub-system and any built-in | 524 | * Initialize the bufq strategy sub-system and any built-in | |
523 | * strategy modules - they may be needed by some devices during | 525 | * strategy modules - they may be needed by some devices during | |
524 | * auto-configuration | 526 | * auto-configuration | |
525 | */ | 527 | */ | |
526 | bufq_init(); | 528 | bufq_init(); | |
527 | module_init_class(MODULE_CLASS_BUFQ); | 529 | module_init_class(MODULE_CLASS_BUFQ); | |
528 | 530 | |||
529 | /* Configure the system hardware. This will enable interrupts. */ | 531 | /* Configure the system hardware. This will enable interrupts. */ | |
530 | configure(); | 532 | configure(); | |
531 | 533 | |||
532 | cprng_init(); /* initialize cryptographic PRNG */ | |||
533 | ||||
534 | /* Once all CPUs are detected, initialize the per-CPU cprng_fast. */ | 534 | /* Once all CPUs are detected, initialize the per-CPU cprng_fast. */ | |
535 | cprng_fast_init(); | 535 | cprng_fast_init(); | |
536 | 536 | |||
537 | ssp_init(); | 537 | ssp_init(); | |
538 | 538 | |||
539 | ubc_init(); /* must be after autoconfig */ | 539 | ubc_init(); /* must be after autoconfig */ | |
540 | 540 | |||
541 | mm_init(); | 541 | mm_init(); | |
542 | 542 | |||
543 | configure2(); | 543 | configure2(); | |
544 | 544 | |||
545 | ipi_sysinit(); | 545 | ipi_sysinit(); | |
546 | 546 |
--- src/sys/kern/subr_cprng.c 2020/05/11 17:27:48 1.38
+++ src/sys/kern/subr_cprng.c 2020/05/11 21:38:54 1.39
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: subr_cprng.c,v 1.38 2020/05/11 17:27:48 riastradh Exp $ */ | 1 | /* $NetBSD: subr_cprng.c,v 1.39 2020/05/11 21:38:54 riastradh Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2019 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2019 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Taylor R. Campbell. | 8 | * by Taylor R. Campbell. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -42,27 +42,27 @@ | @@ -42,27 +42,27 @@ | |||
42 | * 3. /dev/random | 42 | * 3. /dev/random | |
43 | * | 43 | * | |
44 | * This code serves the first two categories without having extra | 44 | * This code serves the first two categories without having extra | |
45 | * logic for /dev/random. | 45 | * logic for /dev/random. | |
46 | * | 46 | * | |
47 | * kern_cprng - available at IPL_VM or lower | 47 | * kern_cprng - available at IPL_VM or lower | |
48 | * user_cprng - available only at IPL_NONE in thread context | 48 | * user_cprng - available only at IPL_NONE in thread context | |
49 | * | 49 | * | |
50 | * The name kern_cprng is for hysterical raisins. The name | 50 | * The name kern_cprng is for hysterical raisins. The name | |
51 | * user_cprng serves only to contrast with kern_cprng. | 51 | * user_cprng serves only to contrast with kern_cprng. | |
52 | */ | 52 | */ | |
53 | 53 | |||
54 | #include <sys/cdefs.h> | 54 | #include <sys/cdefs.h> | |
55 | __KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.38 2020/05/11 17:27:48 riastradh Exp $"); | 55 | __KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.39 2020/05/11 21:38:54 riastradh Exp $"); | |
56 | 56 | |||
57 | #include <sys/types.h> | 57 | #include <sys/types.h> | |
58 | #include <sys/cprng.h> | 58 | #include <sys/cprng.h> | |
59 | #include <sys/cpu.h> | 59 | #include <sys/cpu.h> | |
60 | #include <sys/entropy.h> | 60 | #include <sys/entropy.h> | |
61 | #include <sys/errno.h> | 61 | #include <sys/errno.h> | |
62 | #include <sys/evcnt.h> | 62 | #include <sys/evcnt.h> | |
63 | #include <sys/intr.h> | 63 | #include <sys/intr.h> | |
64 | #include <sys/kmem.h> | 64 | #include <sys/kmem.h> | |
65 | #include <sys/percpu.h> | 65 | #include <sys/percpu.h> | |
66 | #include <sys/sysctl.h> | 66 | #include <sys/sysctl.h> | |
67 | #include <sys/systm.h> | 67 | #include <sys/systm.h> | |
68 | 68 | |||
@@ -207,26 +207,27 @@ cprng_strong_create(const char *name, in | @@ -207,26 +207,27 @@ cprng_strong_create(const char *name, in | |||
207 | void | 207 | void | |
208 | cprng_strong_destroy(struct cprng_strong *cprng) | 208 | cprng_strong_destroy(struct cprng_strong *cprng) | |
209 | { | 209 | { | |
210 | 210 | |||
211 | percpu_free(cprng->cs_percpu, sizeof(struct cprng_cpu)); | 211 | percpu_free(cprng->cs_percpu, sizeof(struct cprng_cpu)); | |
212 | kmem_free(cprng, sizeof(*cprng)); | 212 | kmem_free(cprng, sizeof(*cprng)); | |
213 | } | 213 | } | |
214 | 214 | |||
215 | static void | 215 | static void | |
216 | cprng_init_cpu(void *ptr, void *cookie, struct cpu_info *ci) | 216 | cprng_init_cpu(void *ptr, void *cookie, struct cpu_info *ci) | |
217 | { | 217 | { | |
218 | struct cprng_cpu *cc = ptr; | 218 | struct cprng_cpu *cc = ptr; | |
219 | const char *name = cookie; | 219 | const char *name = cookie; | |
220 | const char *cpuname; | |||
220 | uint8_t zero[NIST_HASH_DRBG_SEEDLEN_BYTES] = {0}; | 221 | uint8_t zero[NIST_HASH_DRBG_SEEDLEN_BYTES] = {0}; | |
221 | char namebuf[64]; /* XXX size? */ | 222 | char namebuf[64]; /* XXX size? */ | |
222 | 223 | |||
223 | /* | 224 | /* | |
224 | * Format the name as, e.g., kern/8 if we're on cpu8. This | 225 | * Format the name as, e.g., kern/8 if we're on cpu8. This | |
225 | * doesn't get displayed anywhere; it just ensures that if | 226 | * doesn't get displayed anywhere; it just ensures that if | |
226 | * there were a bug causing us to use the same otherwise secure | 227 | * there were a bug causing us to use the same otherwise secure | |
227 | * seed on multiple CPUs, we would still get independent output | 228 | * seed on multiple CPUs, we would still get independent output | |
228 | * from the NIST Hash_DRBG. | 229 | * from the NIST Hash_DRBG. | |
229 | */ | 230 | */ | |
230 | snprintf(namebuf, sizeof namebuf, "%s/%u", name, cpu_index(ci)); | 231 | snprintf(namebuf, sizeof namebuf, "%s/%u", name, cpu_index(ci)); | |
231 | 232 | |||
232 | /* | 233 | /* | |
@@ -236,30 +237,32 @@ cprng_init_cpu(void *ptr, void *cookie, | @@ -236,30 +237,32 @@ cprng_init_cpu(void *ptr, void *cookie, | |||
236 | */ | 237 | */ | |
237 | cc->cc_drbg = kmem_zalloc(sizeof(*cc->cc_drbg), KM_SLEEP); | 238 | cc->cc_drbg = kmem_zalloc(sizeof(*cc->cc_drbg), KM_SLEEP); | |
238 | cc->cc_evcnt = kmem_alloc(sizeof(*cc->cc_evcnt), KM_SLEEP); | 239 | cc->cc_evcnt = kmem_alloc(sizeof(*cc->cc_evcnt), KM_SLEEP); | |
239 | 240 | |||
240 | /* | 241 | /* | |
241 | * Initialize the DRBG with no seed. We do this in order to | 242 | * Initialize the DRBG with no seed. We do this in order to | |
242 | * defer reading from the entropy pool as long as possible. | 243 | * defer reading from the entropy pool as long as possible. | |
243 | */ | 244 | */ | |
244 | if (__predict_false(nist_hash_drbg_instantiate(cc->cc_drbg, | 245 | if (__predict_false(nist_hash_drbg_instantiate(cc->cc_drbg, | |
245 | zero, sizeof zero, NULL, 0, namebuf, strlen(namebuf)))) | 246 | zero, sizeof zero, NULL, 0, namebuf, strlen(namebuf)))) | |
246 | panic("nist_hash_drbg_instantiate"); | 247 | panic("nist_hash_drbg_instantiate"); | |
247 | 248 | |||
248 | /* Attach the event counters. */ | 249 | /* Attach the event counters. */ | |
250 | /* XXX ci_cpuname may not be initialized early enough. */ | |||
251 | cpuname = ci->ci_cpuname[0] == '\0' ? "cpu0" : ci->ci_cpuname; | |||
249 | evcnt_attach_dynamic(&cc->cc_evcnt->intr, EVCNT_TYPE_MISC, NULL, | 252 | evcnt_attach_dynamic(&cc->cc_evcnt->intr, EVCNT_TYPE_MISC, NULL, | |
250 | ci->ci_cpuname, "cprng_strong intr"); | 253 | cpuname, "cprng_strong intr"); | |
251 | evcnt_attach_dynamic(&cc->cc_evcnt->reseed, EVCNT_TYPE_MISC, NULL, | 254 | evcnt_attach_dynamic(&cc->cc_evcnt->reseed, EVCNT_TYPE_MISC, NULL, | |
252 | ci->ci_cpuname, "cprng_strong reseed"); | 255 | cpuname, "cprng_strong reseed"); | |
253 | 256 | |||
254 | /* Set the epoch uninitialized so we reseed on first use. */ | 257 | /* Set the epoch uninitialized so we reseed on first use. */ | |
255 | cc->cc_epoch = 0; | 258 | cc->cc_epoch = 0; | |
256 | } | 259 | } | |
257 | 260 | |||
258 | static void | 261 | static void | |
259 | cprng_fini_cpu(void *ptr, void *cookie, struct cpu_info *ci) | 262 | cprng_fini_cpu(void *ptr, void *cookie, struct cpu_info *ci) | |
260 | { | 263 | { | |
261 | struct cprng_cpu *cc = ptr; | 264 | struct cprng_cpu *cc = ptr; | |
262 | 265 | |||
263 | evcnt_detach(&cc->cc_evcnt->reseed); | 266 | evcnt_detach(&cc->cc_evcnt->reseed); | |
264 | evcnt_detach(&cc->cc_evcnt->intr); | 267 | evcnt_detach(&cc->cc_evcnt->intr); | |
265 | if (__predict_false(nist_hash_drbg_destroy(cc->cc_drbg))) | 268 | if (__predict_false(nist_hash_drbg_destroy(cc->cc_drbg))) |