]> git.saurik.com Git - apple/xnu.git/blob - osfmk/prng/prng_random.c
44c865a17dff55903cf936ea5dc9b682f6c223b6
[apple/xnu.git] / osfmk / prng / prng_random.c
1 /*
2 * Copyright (c) 2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <kern/cpu_data.h>
30 #include <kern/cpu_number.h>
31 #include <kern/kalloc.h>
32 #include <kern/machine.h>
33 #include <kern/misc_protos.h>
34 #include <kern/processor.h>
35 #include <kern/sched.h>
36 #include <kern/startup.h>
37 #include <kern/thread.h>
38 #include <kern/thread_call.h>
39 #include <mach/machine.h>
40 #include <mach/processor.h>
41 #include <machine/cpu_data.h>
42 #include <machine/simple_lock.h>
43 #include <sys/errno.h>
44 #include <sys/kdebug.h>
45 #include <sys/random.h>
46 #include <vm/pmap.h>
47 #include <vm/vm_page.h>
48
49 #include <corecrypto/ccdigest.h>
50 #include <corecrypto/ccdrbg.h>
51 #include <corecrypto/cckprng.h>
52 #include <corecrypto/ccsha1.h>
53 #include <corecrypto/ccsha2.h>
54 #include <prng/random.h>
55
56 #include <IOKit/IOPlatformExpert.h>
57 #include <console/serial_protos.h>
58 #include <pexpert/pexpert.h>
59
60 #include <libkern/section_keywords.h>
61
62 #if defined(__arm__) || defined(__arm64__)
63 #include <arm/cpu_data_internal.h> // For MAX_CPUS
64 #endif
65
66 #if defined(__x86_64__)
67 #include <i386/cpuid.h>
68
69 static int
70 rdseed_step(uint64_t * seed)
71 {
72 uint8_t ok;
73
74 asm volatile ("rdseed %0; setc %1" : "=r"(*seed), "=qm"(ok));
75
76 return (int)ok;
77 }
78
79 static int
80 rdseed_retry(uint64_t * seed, size_t nretries)
81 {
82 size_t i;
83
84 for (i = 0; i < nretries; i += 1) {
85 if (rdseed_step(seed)) {
86 return 1;
87 } else {
88 asm volatile ("pause");
89 }
90 }
91
92 return 0;
93 }
94
95 static size_t
96 rdseed_seed(void * buf, size_t nwords)
97 {
98 uint64_t * buf_words;
99 size_t i;
100
101 if (nwords > 8) {
102 nwords = 8;
103 }
104
105 buf_words = buf;
106 for (i = 0; i < nwords; i += 1) {
107 if (!rdseed_retry(buf_words + i, 10)) {
108 return i;
109 }
110 }
111
112 return nwords;
113 }
114
115 static int
116 rdrand_step(uint64_t * rand)
117 {
118 uint8_t ok;
119
120 asm volatile ("rdrand %0; setc %1" : "=r"(*rand), "=qm"(ok));
121
122 return (int)ok;
123 }
124
125 static int
126 rdrand_retry(uint64_t * rand, size_t nretries)
127 {
128 size_t i;
129
130 for (i = 0; i < nretries; i += 1) {
131 if (rdrand_step(rand)) {
132 return 1;
133 }
134 }
135
136 return 0;
137 }
138
139 static size_t
140 rdrand_seed(void * buf, size_t nwords)
141 {
142 size_t i;
143 uint64_t w;
144 uint8_t hash[CCSHA256_OUTPUT_SIZE];
145 const struct ccdigest_info * di = &ccsha256_ltc_di;
146
147 ccdigest_di_decl(di, ctx);
148 ccdigest_init(di, ctx);
149
150 for (i = 0; i < 1023; i += 1) {
151 if (!rdrand_retry(&w, 10)) {
152 nwords = 0;
153 goto out;
154 }
155 ccdigest_update(di, ctx, sizeof w, &w);
156 }
157
158 ccdigest_final(di, ctx, hash);
159
160 if (nwords > 2) {
161 nwords = 2;
162 }
163
164 memcpy(buf, hash, nwords * sizeof(uint64_t));
165
166 out:
167 ccdigest_di_clear(di, ctx);
168 bzero(hash, sizeof hash);
169 bzero(&w, sizeof w);
170
171 return nwords;
172 }
173
174 static void
175 intel_entropysource(void * buf, size_t * nbytes)
176 {
177 size_t nwords;
178
179 /* only handle complete words */
180 assert(*nbytes % sizeof(uint64_t) == 0);
181
182 nwords = (*nbytes) / sizeof(uint64_t);
183 if (cpuid_leaf7_features() & CPUID_LEAF7_FEATURE_RDSEED) {
184 nwords = rdseed_seed(buf, nwords);
185 *nbytes = nwords * sizeof(uint64_t);
186 } else if (cpuid_features() & CPUID_FEATURE_RDRAND) {
187 nwords = rdrand_seed(buf, nwords);
188 *nbytes = nwords * sizeof(uint64_t);
189 } else {
190 *nbytes = 0;
191 }
192 }
193
194 #endif /* defined(__x86_64__) */
195
196 void entropy_buffer_read(void * buffer, size_t * count);
197
198 typedef void (*entropysource)(void * buf, size_t * nbytes);
199
200 static const entropysource entropysources[] = {
201 entropy_buffer_read,
202 #if defined(__x86_64__)
203 intel_entropysource,
204 #endif
205 };
206
207 static const size_t nsources = sizeof entropysources / sizeof entropysources[0];
208
209 static size_t
210 entropy_readall(void * buf, size_t nbytes_persource)
211 {
212 uint8_t * buf_bytes = buf;
213 size_t i;
214 size_t nbytes_total = 0;
215
216 for (i = 0; i < nsources; i += 1) {
217 size_t nbytes = nbytes_persource;
218 entropysources[i](buf_bytes, &nbytes);
219 bzero(buf_bytes + nbytes, nbytes_persource - nbytes);
220 nbytes_total += nbytes;
221 buf_bytes += nbytes_persource;
222 }
223
224 return nbytes_total;
225 }
226
227 static struct {
228 struct cckprng_ctx ctx;
229 struct {
230 lck_grp_t * group;
231 lck_attr_t * attrs;
232 lck_grp_attr_t * group_attrs;
233 lck_mtx_t * mutex;
234 } lock;
235 } prng;
236
237 static SECURITY_READ_ONLY_LATE(prng_fns_t) prng_fns = NULL;
238
239 static int
240 prng_init(cckprng_ctx_t ctx, size_t nbytes, const void * seed)
241 {
242 int err = prng_fns->init(ctx, nbytes, seed);
243 if (err == CCKPRNG_ABORT) {
244 panic("prng_init");
245 }
246 return err;
247 }
248
249 #define PERMIT_WRITE_RANDOM 0
250
251 #if PERMIT_WRITE_RANDOM
252 static int
253 prng_reseed(cckprng_ctx_t ctx, size_t nbytes, const void * seed)
254 {
255 int err = prng_fns->reseed(ctx, nbytes, seed);
256 if (err == CCKPRNG_ABORT) {
257 panic("prng_reseed");
258 }
259 return err;
260 }
261 #endif
262
263 static int
264 prng_addentropy(cckprng_ctx_t ctx, size_t nbytes, const void * entropy)
265 {
266 int err = prng_fns->addentropy(ctx, nbytes, entropy);
267 if (err == CCKPRNG_ABORT) {
268 panic("prng_addentropy");
269 }
270 return err;
271 }
272
273 static int
274 prng_generate(cckprng_ctx_t ctx, size_t nbytes, void * out)
275 {
276 int err = prng_fns->generate(ctx, nbytes, out);
277 if (err == CCKPRNG_ABORT) {
278 panic("prng_generate");
279 }
280 return err;
281 }
282
283 entropy_data_t EntropyData = {.index_ptr = EntropyData.buffer};
284
285 static struct {
286 uint8_t seed[nsources][EARLY_RANDOM_SEED_SIZE];
287 int seedset;
288 uint8_t master_drbg_state[EARLY_RANDOM_STATE_STATIC_SIZE];
289 struct ccdrbg_state * drbg_states[MAX_CPUS];
290 struct ccdrbg_info drbg_info;
291 const struct ccdrbg_nisthmac_custom drbg_custom;
292 } erandom = {.drbg_custom = {
293 .di = &ccsha1_eay_di,
294 .strictFIPS = 0,
295 }};
296
297 static void read_erandom(void * buf, uint32_t nbytes);
298
299 void
300 entropy_buffer_read(void * buffer, size_t * count)
301 {
302 boolean_t current_state;
303 unsigned int i, j;
304
305 if (!erandom.seedset) {
306 panic("early_random was never invoked");
307 }
308
309 if (*count > ENTROPY_BUFFER_BYTE_SIZE) {
310 *count = ENTROPY_BUFFER_BYTE_SIZE;
311 }
312
313 current_state = ml_early_set_interrupts_enabled(FALSE);
314
315 memcpy(buffer, EntropyData.buffer, *count);
316
317 /* Consider removing this mixing step rdar://problem/31668239 */
318 for (i = 0, j = (ENTROPY_BUFFER_SIZE - 1); i < ENTROPY_BUFFER_SIZE; j = i, i++) {
319 EntropyData.buffer[i] = EntropyData.buffer[i] ^ EntropyData.buffer[j];
320 }
321
322 (void) ml_early_set_interrupts_enabled(current_state);
323
324 #if DEVELOPMENT || DEBUG
325 uint32_t * word = buffer;
326 /* Good for both 32-bit and 64-bit kernels. */
327 for (i = 0; i < ENTROPY_BUFFER_SIZE; i += 4) {
328 /*
329 * We use "EARLY" here so that we can grab early entropy on
330 * ARM, where tracing is not started until after PRNG is
331 * initialized.
332 */
333 KERNEL_DEBUG_EARLY(ENTROPY_READ(i / 4), word[i + 0], word[i + 1], word[i + 2], word[i + 3]);
334 }
335 #endif
336 }
337
338 /*
339 * Return a uniformly distributed 64-bit random number.
340 *
341 * This interface should have minimal dependencies on kernel
342 * services, and thus be available very early in the life
343 * of the kernel.
344 * This provides cryptographically secure randomness.
345 * Each processor has its own generator instance.
346 * It is seeded (lazily) with entropy provided by the Booter.
347 *
348 * For <rdar://problem/17292592> the algorithm switched from LCG to
349 * NIST HMAC DBRG as follows:
350 * - When first called (on OSX this is very early while page tables are being
351 * built) early_random() calls ccdrbg_factory_hmac() to set-up a ccdbrg info
352 * structure.
353 * - The boot processor's ccdrbg state structure is a statically allocated area
354 * which is then initialized by calling the ccdbrg_init method.
355 * The initial entropy is 16 bytes of boot entropy.
356 * The nonce is the first 8 bytes of entropy xor'ed with a timestamp
357 * from ml_get_timebase().
358 * The personalization data provided is null.
359 * - The first 64-bit random value is returned on the boot processor from
360 * an invocation of the ccdbrg_generate method.
361 * - Non-boot processor's DRBG state structures are allocated dynamically
362 * from prng_init(). Each is initialized with the same 16 bytes of entropy
363 * but with a different timestamped nonce and cpu number as personalization.
364 * - Subsequent calls to early_random() pass to read_erandom() to generate
365 * an 8-byte random value. read_erandom() ensures that pre-emption is
366 * disabled and selects the DBRG state from the current processor.
367 * The ccdbrg_generate method is called for the required random output.
368 * If this method returns CCDRBG_STATUS_NEED_RESEED, the erandom.seed buffer
369 * is re-filled with kernel-harvested entropy and the ccdbrg_reseed method is
370 * called with this new entropy. The kernel panics if a reseed fails.
371 */
372 uint64_t
373 early_random(void)
374 {
375 uint32_t cnt = 0;
376 uint64_t result;
377 uint64_t nonce;
378 int rc;
379 int ps;
380 struct ccdrbg_state * state;
381
382 if (!erandom.seedset) {
383 erandom.seedset = 1;
384 cnt = PE_get_random_seed((unsigned char *)EntropyData.buffer, sizeof(EntropyData.buffer));
385
386 if (cnt < sizeof(EntropyData.buffer)) {
387 /*
388 * Insufficient entropy is fatal. We must fill the
389 * entire entropy buffer during initializaton.
390 */
391 panic("EntropyData needed %lu bytes, but got %u.\n", sizeof(EntropyData.buffer), cnt);
392 }
393
394 entropy_readall(&erandom.seed, EARLY_RANDOM_SEED_SIZE);
395
396 /* Init DRBG for NIST HMAC */
397 ccdrbg_factory_nisthmac(&erandom.drbg_info, &erandom.drbg_custom);
398 assert(erandom.drbg_info.size <= sizeof(erandom.master_drbg_state));
399 state = (struct ccdrbg_state *)erandom.master_drbg_state;
400 erandom.drbg_states[master_cpu] = state;
401
402 /*
403 * Init our DBRG from the boot entropy and a timestamp as nonce
404 * and the cpu number as personalization.
405 */
406 assert(sizeof(erandom.seed) > sizeof(nonce));
407 nonce = ml_get_timebase();
408 ps = 0; /* boot cpu */
409 rc = ccdrbg_init(&erandom.drbg_info, state, sizeof(erandom.seed), erandom.seed, sizeof(nonce), &nonce, sizeof(ps), &ps);
410 cc_clear(sizeof(nonce), &nonce);
411 if (rc != CCDRBG_STATUS_OK) {
412 panic("ccdrbg_init() returned %d", rc);
413 }
414
415 /* Generate output */
416 rc = ccdrbg_generate(&erandom.drbg_info, state, sizeof(result), &result, 0, NULL);
417 if (rc != CCDRBG_STATUS_OK) {
418 panic("ccdrbg_generate() returned %d", rc);
419 }
420
421 return result;
422 }
423 ;
424
425 #if defined(__x86_64__)
426 /*
427 * Calling read_erandom() before gsbase is initialized is potentially
428 * catastrophic, so assert that it's not set to the magic value set
429 * in i386_init.c before proceeding with the call. We cannot use
430 * assert here because it ultimately calls panic, which executes
431 * operations that involve accessing %gs-relative data (and additionally
432 * causes a debug trap which will not work properly this early in boot.)
433 */
434 if (rdmsr64(MSR_IA32_GS_BASE) == EARLY_GSBASE_MAGIC) {
435 kprintf("[early_random] Cannot proceed: GSBASE is not initialized\n");
436 hlt();
437 /*NOTREACHED*/
438 }
439 #endif
440 read_erandom(&result, sizeof(result));
441
442 return result;
443 }
444
445 static void
446 read_erandom(void * buffer, u_int numBytes)
447 {
448 int cpu;
449 int rc;
450 size_t nbytes;
451 struct ccdrbg_state * state;
452
453 mp_disable_preemption();
454 cpu = cpu_number();
455 state = erandom.drbg_states[cpu];
456 assert(state);
457 for (;;) {
458 /* Generate output */
459 rc = ccdrbg_generate(&erandom.drbg_info, state, numBytes, buffer, 0, NULL);
460 if (rc == CCDRBG_STATUS_OK) {
461 break;
462 }
463 if (rc == CCDRBG_STATUS_NEED_RESEED) {
464 /* It's time to reseed. Get more entropy */
465 nbytes = entropy_readall(erandom.seed, EARLY_RANDOM_SEED_SIZE);
466 assert(nbytes >= EARLY_RANDOM_SEED_SIZE);
467 rc = ccdrbg_reseed(&erandom.drbg_info, state, sizeof(erandom.seed), erandom.seed, 0, NULL);
468 cc_clear(sizeof(erandom.seed), erandom.seed);
469 if (rc == CCDRBG_STATUS_OK) {
470 continue;
471 }
472 panic("read_erandom reseed error %d\n", rc);
473 }
474 panic("read_erandom ccdrbg error %d\n", rc);
475 }
476 mp_enable_preemption();
477 }
478
479 void
480 read_frandom(void * buffer, u_int numBytes)
481 {
482 uint8_t * buffer_bytes = buffer;
483 int nbytes;
484
485 /*
486 * Split up into requests for blocks smaller than
487 * than the DBRG request limit. iThis limit is private but
488 * for NISTHMAC it's known to be greater then 4096.
489 */
490 while (numBytes) {
491 nbytes = MIN(numBytes, PAGE_SIZE);
492 read_erandom(buffer_bytes, nbytes);
493 buffer_bytes += nbytes;
494 numBytes -= nbytes;
495 }
496 }
497
498 void
499 early_random_cpu_init(int cpu)
500 {
501 uint64_t nonce;
502 int rc;
503 struct ccdrbg_state * state;
504
505 /*
506 * Allocate state and initialize DBRG state for early_random()
507 * for this processor.
508 */
509 assert(cpu != master_cpu);
510 assert(erandom.drbg_states[cpu] == NULL);
511
512 state = kalloc(erandom.drbg_info.size);
513 if (state == NULL) {
514 panic("prng_init kalloc failed\n");
515 }
516 erandom.drbg_states[cpu] = state;
517
518 /*
519 * Init our DBRG from boot entropy, nonce as timestamp
520 * and use the cpu number as the personalization parameter.
521 */
522 nonce = ml_get_timebase();
523 rc = ccdrbg_init(&erandom.drbg_info, state, sizeof(erandom.seed), erandom.seed, sizeof(nonce), &nonce, sizeof(cpu), &cpu);
524 cc_clear(sizeof(nonce), &nonce);
525 if (rc != CCDRBG_STATUS_OK) {
526 panic("ccdrbg_init() returned %d", rc);
527 }
528 }
529
530 void
531 register_and_init_prng(prng_fns_t fns)
532 {
533 uint8_t buf[nsources][ENTROPY_BUFFER_BYTE_SIZE];
534 size_t nbytes;
535
536 assert(cpu_number() == master_cpu);
537 assert(prng_fns == NULL);
538
539 prng_fns = fns;
540
541 /* make a mutex to control access */
542 prng.lock.group_attrs = lck_grp_attr_alloc_init();
543 prng.lock.group = lck_grp_alloc_init("random", prng.lock.group_attrs);
544 prng.lock.attrs = lck_attr_alloc_init();
545 prng.lock.mutex = lck_mtx_alloc_init(prng.lock.group, prng.lock.attrs);
546
547 nbytes = entropy_readall(buf, ENTROPY_BUFFER_BYTE_SIZE);
548 (void)prng_init(&prng.ctx, nbytes, buf);
549 cc_clear(sizeof(buf), buf);
550 }
551
552 static void
553 Reseed(void)
554 {
555 uint8_t buf[nsources][ENTROPY_BUFFER_BYTE_SIZE];
556 size_t nbytes;
557
558 lck_mtx_assert(prng.lock.mutex, LCK_MTX_ASSERT_OWNED);
559
560 nbytes = entropy_readall(buf, ENTROPY_BUFFER_BYTE_SIZE);
561 PRNG_CCKPRNG((void)prng_addentropy(&prng.ctx, nbytes, buf));
562 cc_clear(sizeof(buf), buf);
563 }
564
565 /* export good random numbers to the rest of the kernel */
566 void
567 read_random(void * buffer, u_int numbytes)
568 {
569 int err;
570
571 lck_mtx_lock(prng.lock.mutex);
572
573 /*
574 * Call PRNG, reseeding and retrying if requested.
575 */
576 for (;;) {
577 PRNG_CCKPRNG(err = prng_generate(&prng.ctx, numbytes, buffer));
578 if (err == CCKPRNG_OK) {
579 break;
580 }
581 if (err == CCKPRNG_NEED_ENTROPY) {
582 Reseed();
583 continue;
584 }
585 panic("read_random() error %d\n", err);
586 }
587
588 lck_mtx_unlock(prng.lock.mutex);
589 }
590
591 int
592 write_random(void * buffer, u_int numbytes)
593 {
594 #if PERMIT_WRITE_RANDOM
595 int err;
596
597 lck_mtx_lock(prng.lock.mutex);
598 err = prng_reseed(&prng.ctx, numbytes, buffer);
599 lck_mtx_unlock(prng.lock.mutex);
600
601 return err ? EIO : 0;
602 #else
603 #pragma unused(buffer, numbytes)
604 return 0;
605 #endif
606 }
607
608 /*
609 * Boolean PRNG for generating booleans to randomize order of elements
610 * in certain kernel data structures. The algorithm is a
611 * modified version of the KISS RNG proposed in the paper:
612 * http://stat.fsu.edu/techreports/M802.pdf
613 * The modifications have been documented in the technical paper
614 * paper from UCL:
615 * http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
616 */
617
618 /* Initialize the PRNG structures. */
619 void
620 random_bool_init(struct bool_gen * bg)
621 {
622 /* Seed the random boolean generator */
623 for (int i = 0; i < RANDOM_BOOL_GEN_SEED_COUNT; i++) {
624 bg->seed[i] = (unsigned int)early_random();
625 }
626 bg->state = 0;
627 simple_lock_init(&bg->lock, 0);
628 }
629
630 /* Generate random bits and add them to an entropy pool. */
631 void
632 random_bool_gen_entropy(struct bool_gen * bg, unsigned int * buffer, int count)
633 {
634 simple_lock(&bg->lock, LCK_GRP_NULL);
635 int i, t;
636 for (i = 0; i < count; i++) {
637 bg->seed[1] ^= (bg->seed[1] << 5);
638 bg->seed[1] ^= (bg->seed[1] >> 7);
639 bg->seed[1] ^= (bg->seed[1] << 22);
640 t = bg->seed[2] + bg->seed[3] + bg->state;
641 bg->seed[2] = bg->seed[3];
642 bg->state = t < 0;
643 bg->seed[3] = t & 2147483647;
644 bg->seed[0] += 1411392427;
645 buffer[i] = (bg->seed[0] + bg->seed[1] + bg->seed[3]);
646 }
647 simple_unlock(&bg->lock);
648 }
649
650 /* Get some number of bits from the entropy pool, refilling if necessary. */
651 unsigned int
652 random_bool_gen_bits(struct bool_gen * bg, unsigned int * buffer, unsigned int count, unsigned int numbits)
653 {
654 unsigned int index = 0;
655 unsigned int rbits = 0;
656 for (unsigned int bitct = 0; bitct < numbits; bitct++) {
657 /*
658 * Find a portion of the buffer that hasn't been emptied.
659 * We might have emptied our last index in the previous iteration.
660 */
661 while (index < count && buffer[index] == 0) {
662 index++;
663 }
664
665 /* If we've exhausted the pool, refill it. */
666 if (index == count) {
667 random_bool_gen_entropy(bg, buffer, count);
668 index = 0;
669 }
670
671 /* Collect-a-bit */
672 unsigned int bit = buffer[index] & 1;
673 buffer[index] = buffer[index] >> 1;
674 rbits = bit | (rbits << 1);
675 }
676 return rbits;
677 }