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