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