2 * Copyright (c) 2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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>
44 #include <vm/vm_page.h>
45 #include <sys/kdebug.h>
46 #include <sys/random.h>
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>
54 #include <pexpert/pexpert.h>
55 #include <console/serial_protos.h>
56 #include <IOKit/IOPlatformExpert.h>
58 #if defined(__x86_64__)
59 #include <i386/cpuid.h>
61 static int rdseed_step(uint64_t *seed
)
65 asm volatile ("rdseed %0; setc %1" : "=r" (*seed
), "=qm" (ok
));
70 static int rdseed_retry(uint64_t *seed
, size_t nretries
)
74 for (i
= 0; i
< nretries
; i
+= 1) {
75 if (rdseed_step(seed
)) {
78 asm volatile ("pause");
85 static size_t rdseed_seed(void *buf
, size_t nwords
)
95 for (i
= 0; i
< nwords
; i
+= 1) {
96 if (!rdseed_retry(buf_words
+ i
, 10)) {
104 static int rdrand_step(uint64_t *rand
)
108 asm volatile ("rdrand %0; setc %1" : "=r" (*rand
), "=qm" (ok
));
113 static int rdrand_retry(uint64_t *rand
, size_t nretries
)
117 for (i
= 0; i
< nretries
; i
+= 1) {
118 if (rdrand_step(rand
)) {
126 static size_t rdrand_seed(void *buf
, size_t nwords
)
130 uint8_t hash
[CCSHA256_OUTPUT_SIZE
];
131 const struct ccdigest_info
*di
= &ccsha256_ltc_di
;
133 ccdigest_di_decl(di
, ctx
);
134 ccdigest_init(di
, ctx
);
136 for (i
= 0; i
< 1023; i
+= 1) {
137 if (!rdrand_retry(&w
, 10)) {
141 ccdigest_update(di
, ctx
, sizeof w
, &w
);
144 ccdigest_final(di
, ctx
, hash
);
150 memcpy(buf
, hash
, nwords
* sizeof (uint64_t));
153 ccdigest_di_clear(di
, ctx
);
154 bzero(hash
, sizeof hash
);
160 static void intel_entropysource(void *buf
, size_t *nbytes
)
164 /* only handle complete words */
165 assert(*nbytes
% sizeof (uint64_t) == 0);
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);
181 typedef void (*entropysource
)(void *buf
, size_t *nbytes
);
183 static const entropysource entropysources
[] = {
185 #if defined(__x86_64__)
190 static const size_t nsources
= sizeof entropysources
/ sizeof entropysources
[0];
192 static size_t entropy_readall(void *buf
, size_t nbytes_persource
)
194 uint8_t *buf_bytes
= buf
;
196 size_t nbytes_total
= 0;
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
;
212 lck_grp_attr_t
*group_attrs
;
216 typedef struct prngContext
{
217 struct ccdrbg_info
*infop
;
218 struct ccdrbg_state
*statep
;
219 uint64_t bytes_generated
;
220 uint64_t bytes_reseeded
;
223 ccdrbg_factory_t prng_ccdrbg_factory
= NULL
;
225 entropy_data_t EntropyData
= {
226 .index_ptr
= EntropyData
.buffer
230 uint8_t seed
[nsources
][EARLY_RANDOM_SEED_SIZE
];
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
;
238 .di
= &ccsha1_eay_di
,
243 static void read_erandom(void *buf
, uint32_t nbytes
);
246 entropy_buffer_read(void *buffer
, size_t *count
)
248 boolean_t current_state
;
251 if (!erandom
.seedset
) {
252 panic("early_random was never invoked");
255 if (*count
> ENTROPY_BUFFER_BYTE_SIZE
) {
256 *count
= ENTROPY_BUFFER_BYTE_SIZE
;
259 current_state
= ml_set_interrupts_enabled(FALSE
);
261 memcpy(buffer
, EntropyData
.buffer
, *count
);
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
];
267 (void) ml_set_interrupts_enabled(current_state
);
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)
274 * We use "EARLY" here so that we can grab early entropy on
275 * ARM, where tracing is not started until after PRNG is
278 KERNEL_DEBUG_EARLY(ENTROPY_READ(i
/4),
279 word
[i
+0], word
[i
+1], word
[i
+2], word
[i
+3]);
284 * Return a uniformly distributed 64-bit random number.
286 * This interface should have minimal dependencies on kernel
287 * services, and thus be available very early in the life
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.
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
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.
325 struct ccdrbg_state
*state
;
327 if (!erandom
.seedset
) {
329 cnt
= PE_get_random_seed((unsigned char *) EntropyData
.buffer
,
330 sizeof(EntropyData
.buffer
));
332 if (cnt
< sizeof(EntropyData
.buffer
)) {
334 * Insufficient entropy is fatal. We must fill the
335 * entire entropy buffer during initializaton.
337 panic("EntropyData needed %lu bytes, but got %u.\n",
338 sizeof(EntropyData
.buffer
), cnt
);
341 entropy_readall(&erandom
.seed
, EARLY_RANDOM_SEED_SIZE
);
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
;
350 * Init our DBRG from the boot entropy and a timestamp as nonce
351 * and the cpu number as personalization.
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
,
360 cc_clear(sizeof(nonce
), &nonce
);
361 if (rc
!= CCDRBG_STATUS_OK
)
362 panic("ccdrbg_init() returned %d", rc
);
364 /* Generate output */
365 rc
= ccdrbg_generate(&erandom
.drbg_info
, state
,
366 sizeof(result
), &result
,
368 if (rc
!= CCDRBG_STATUS_OK
)
369 panic("ccdrbg_generate() returned %d", rc
);
374 read_erandom(&result
, sizeof(result
));
380 read_erandom(void *buffer
, u_int numBytes
)
385 struct ccdrbg_state
*state
;
387 mp_disable_preemption();
389 state
= erandom
.drbg_states
[cpu
];
392 /* Generate output */
393 rc
= ccdrbg_generate(&erandom
.drbg_info
, state
,
396 if (rc
== CCDRBG_STATUS_OK
)
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
,
405 cc_clear(sizeof(erandom
.seed
), erandom
.seed
);
406 if (rc
== CCDRBG_STATUS_OK
)
408 panic("read_erandom reseed error %d\n", rc
);
410 panic("read_erandom ccdrbg error %d\n", rc
);
412 mp_enable_preemption();
416 read_frandom(void *buffer
, u_int numBytes
)
418 uint8_t *buffer_bytes
= buffer
;
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.
427 nbytes
= MIN(numBytes
, PAGE_SIZE
);
428 read_erandom(buffer_bytes
, nbytes
);
429 buffer_bytes
+= nbytes
;
435 * Register a DRBG factory routine to e used in constructing the kernel PRNG.
436 * XXX to be called from the corecrypto kext.
439 prng_factory_register(ccdrbg_factory_t factory
)
441 prng_ccdrbg_factory
= factory
;
442 thread_wakeup((event_t
) &prng_ccdrbg_factory
);
446 prng_cpu_init(int cpu
)
450 struct ccdrbg_state
*state
;
454 * Allocate state and initialize DBRG state for early_random()
455 * for this processor, if necessary.
457 if (erandom
.drbg_states
[cpu
] == NULL
) {
459 state
= kalloc(erandom
.drbg_info
.size
);
461 panic("prng_init kalloc failed\n");
463 erandom
.drbg_states
[cpu
] = state
;
466 * Init our DBRG from boot entropy, nonce as timestamp
467 * and use the cpu number as the personalization parameter.
469 nonce
= ml_get_timebase();
470 rc
= ccdrbg_init(&erandom
.drbg_info
, state
,
471 sizeof(erandom
.seed
), erandom
.seed
,
472 sizeof(nonce
), &nonce
,
474 cc_clear(sizeof(nonce
), &nonce
);
475 if (rc
!= CCDRBG_STATUS_OK
)
476 panic("ccdrbg_init() returned %d", rc
);
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();
485 assert(lock
.mutex
== NULL
); /* Once only, please */
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
);
493 pp
= kalloc(sizeof(*pp
));
495 panic("Unable to allocate prng context");
496 pp
->bytes_generated
= 0;
497 pp
->bytes_reseeded
= 0;
500 /* XXX Temporary registration */
501 prng_factory_register(ccdrbg_factory_yarrow
);
503 master_prng_context() = pp
;
506 static struct ccdrbg_info
*
507 prng_infop(prngContextp pp
)
509 uint8_t buf
[nsources
][ENTROPY_BUFFER_BYTE_SIZE
];
512 lck_mtx_assert(lock
.mutex
, LCK_MTX_ASSERT_OWNED
);
514 /* Usual case: the info is all set */
519 * Possibly wait for the CCDRBG factory routune to be registered
520 * by corecypto. But panic after waiting for more than 10 seconds.
522 while (prng_ccdrbg_factory
== NULL
) {
523 wait_result_t wait_result
;
524 assert_wait_timeout((event_t
) &prng_ccdrbg_factory
, TRUE
,
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
);
532 /* Check we didn't lose the set-up race */
536 pp
->infop
= (struct ccdrbg_info
*) kalloc(sizeof(struct ccdrbg_info
));
537 if (pp
->infop
== NULL
)
538 panic("Unable to allocate prng info");
540 prng_ccdrbg_factory(pp
->infop
, NULL
);
542 pp
->statep
= kalloc(pp
->infop
->size
);
543 if (pp
->statep
== NULL
)
544 panic("Unable to allocate prng state");
546 nbytes
= entropy_readall(buf
, ENTROPY_BUFFER_BYTE_SIZE
);
548 (void) ccdrbg_init(pp
->infop
, pp
->statep
,
552 cc_clear(sizeof (buf
), buf
);
557 Reseed(prngContextp pp
)
559 uint8_t buf
[nsources
][ENTROPY_BUFFER_BYTE_SIZE
];
562 nbytes
= entropy_readall(buf
, ENTROPY_BUFFER_BYTE_SIZE
);
564 PRNG_CCDRBG((void) ccdrbg_reseed(pp
->infop
, pp
->statep
,
568 cc_clear(sizeof (buf
), buf
);
569 pp
->bytes_reseeded
= pp
->bytes_generated
;
573 /* export good random numbers to the rest of the kernel */
575 read_random(void* buffer
, u_int numbytes
)
578 struct ccdrbg_info
*infop
;
581 lck_mtx_lock(lock
.mutex
);
583 pp
= current_prng_context();
584 infop
= prng_infop(pp
);
587 * Call DRBG, reseeding and retrying if requested.
591 ccdrbg_err
= ccdrbg_generate(infop
, pp
->statep
,
594 if (ccdrbg_err
== CCDRBG_STATUS_OK
)
596 if (ccdrbg_err
== CCDRBG_STATUS_NEED_RESEED
) {
600 panic("read_random ccdrbg error %d\n", ccdrbg_err
);
603 pp
->bytes_generated
+= numbytes
;
604 lck_mtx_unlock(lock
.mutex
);
608 write_random(void* buffer
, u_int numbytes
)
614 lck_mtx_lock(lock
.mutex
);
616 pp
= current_prng_context();
618 if (ccdrbg_reseed(prng_infop(pp
), pp
->statep
,
619 bytesToInput
, rdBuffer
, 0, NULL
) != 0)
622 lck_mtx_unlock(lock
.mutex
);
625 #pragma unused(buffer, numbytes)
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
638 * http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
641 /* Initialize the PRNG structures. */
642 void random_bool_init(struct bool_gen
*bg
)
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();
649 simple_lock_init(&bg
->lock
, 0);
652 /* Generate random bits and add them to an entropy pool. */
653 void random_bool_gen_entropy(
655 unsigned int *buffer
,
659 simple_lock(&bg
->lock
);
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];
668 bg
->seed
[3] = t
& 2147483647;
669 bg
->seed
[0] += 1411392427;
670 buffer
[i
] = (bg
->seed
[0] + bg
->seed
[1] + bg
->seed
[3]);
672 simple_unlock(&bg
->lock
);
675 /* Get some number of bits from the entropy pool, refilling if necessary. */
676 unsigned int random_bool_gen_bits(
678 unsigned int *buffer
,
680 unsigned int numbits
)
682 unsigned int index
= 0;
683 unsigned int rbits
= 0;
684 for (unsigned int bitct
= 0; bitct
< numbits
; bitct
++) {
686 * Find a portion of the buffer that hasn't been emptied.
687 * We might have emptied our last index in the previous iteration.
689 while (index
< count
&& buffer
[index
] == 0)
692 /* If we've exhausted the pool, refill it. */
693 if (index
== count
) {
694 random_bool_gen_entropy(bg
, buffer
, count
);
699 unsigned int bit
= buffer
[index
] & 1;
700 buffer
[index
] = buffer
[index
] >> 1;
701 rbits
= bit
| (rbits
<< 1);