xref: /xnu-12377.61.12/osfmk/prng/prng_random.c (revision 4d495c6e23c53686cf65f45067f79024cf5dcee8)
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/locks.h>
30 #include <kern/cpu_number.h>
31 #include <libkern/section_keywords.h>
32 #include <libkern/crypto/sha2.h>
33 #include <machine/machine_cpu.h>
34 #include <machine/machine_routines.h>
35 #include <pexpert/pexpert.h>
36 #include <sys/random.h>
37 #include <prng/random.h>
38 #include <prng/entropy.h>
39 #include <corecrypto/ccdigest.h>
40 #include <corecrypto/ccdigest_priv.h>
41 #include <corecrypto/ccdrbg.h>
42 #include <corecrypto/cckprng.h>
43 #include <corecrypto/ccsha2.h>
44 #include <corecrypto/cchmac.h>
45 
46 static struct cckprng_ctx *prng_ctx;
47 
48 static SECURITY_READ_ONLY_LATE(struct cckprng_funcs) prng_funcs;
49 static SECURITY_READ_ONLY_LATE(int) prng_ready;
50 
51 #define SEED_SIZE SHA512_DIGEST_LENGTH
52 
53 #if defined(__x86_64__)
54 	#define BOOTLOADER_ENTROPY_REQUEST_SIZE 64 // efiboot max
55 #else
56 	#define BOOTLOADER_ENTROPY_REQUEST_SIZE 4*SEED_SIZE
57 #endif
58 
59 static uint8_t kprngseed[SEED_SIZE];
60 static uint8_t earlyseed[SEED_SIZE];
61 static uint8_t entropyseed[SEED_SIZE];
62 static uint8_t kprng_reseed[SEED_SIZE];
63 
64 static void
bootseed_init_bootloader(uint32_t request_size,uint8_t * dst)65 bootseed_init_bootloader(uint32_t request_size, uint8_t *dst)
66 {
67 	uint32_t n;
68 
69 	n = PE_get_random_seed(dst, request_size);
70 	if (n < request_size) {
71 		/*
72 		 * Insufficient entropy is fatal.  We must fill the
73 		 * entire entropy buffer during initializaton.
74 		 */
75 		panic("Expected %u seed bytes from bootloader, but got %u.\n", request_size, n);
76 	}
77 }
78 
79 #if defined(__x86_64__)
80 #include <i386/cpuid.h>
81 
82 static void
bootseed_init_native(uint32_t request_size,uint8_t * dst)83 bootseed_init_native(uint32_t request_size, uint8_t *dst)
84 {
85 	uint64_t x;
86 	uint8_t ok;
87 	size_t i = 0;
88 	size_t n;
89 
90 	assert3u(request_size % sizeof(x), ==, 0);
91 
92 	if (cpuid_leaf7_features() & CPUID_LEAF7_FEATURE_RDSEED) {
93 		n = request_size / sizeof(x);
94 
95 		while (i < n) {
96 			asm volatile ("rdseed %0; setc %1" : "=r"(x), "=qm"(ok) : : "cc");
97 			if (ok) {
98 				cc_memcpy(&dst[i * sizeof(x)], &x, sizeof(x));
99 				i += 1;
100 			} else {
101 				// Intel recommends to pause between unsuccessful rdseed attempts.
102 				cpu_pause();
103 			}
104 		}
105 	} else if (cpuid_features() & CPUID_FEATURE_RDRAND) {
106 		// The Intel documentation guarantees a reseed every 512 rdrand calls.
107 		n = (request_size / sizeof(x)) * 512;
108 
109 		while (i < n) {
110 			asm volatile ("rdrand %0; setc %1" : "=r"(x), "=qm"(ok) : : "cc");
111 			if (ok) {
112 				if (i % 512 == 0) {
113 					cc_memcpy(&dst[(i / 512) * sizeof(x)], &x, sizeof(x));
114 				}
115 				i += 1;
116 			} else {
117 				// Intel does not recommend pausing between unsuccessful rdrand attempts.
118 			}
119 		}
120 	}
121 
122 	cc_clear(sizeof(x), &x);
123 }
124 
125 #else
126 
127 static void
bootseed_init_native(uint32_t request_size,uint8_t * dst)128 bootseed_init_native(uint32_t request_size, uint8_t *dst)
129 {
130 	// Even if we don't have any input, the second input needs to be a fixed input of the same size
131 	// to maintain dual-PRF security for HKDF/HMAC. All zero is fine as long as it is fixed.
132 	cc_clear(request_size, dst);
133 }
134 
135 #endif
136 
137 static void
bootseed_init(void)138 bootseed_init(void)
139 {
140 	// Request our starting entropy from the bootloader
141 	uint8_t bootloader_rand[4 * SEED_SIZE];
142 	bootseed_init_bootloader(BOOTLOADER_ENTROPY_REQUEST_SIZE, bootloader_rand);
143 
144 	#if defined(__x86_64__) && BOOTLOADER_ENTROPY_REQUEST_SIZE == 64
145 	// efiboot can only provide 64 bytes of entropy, so fill the rest of the buffer with zero.
146 	// We compensate for this by sampling from RDRAND/RDSEED in bootseed_init_native.
147 	cc_clear(sizeof(bootloader_rand) - BOOTLOADER_ENTROPY_REQUEST_SIZE, bootloader_rand + BOOTLOADER_ENTROPY_REQUEST_SIZE);
148 	#endif
149 
150 	/*
151 	 *  First, we copy out a direct seed for the kprng from the TRNG packet then clear it to prevent reuse.
152 	 *   | BOOTLOADER_ENTROPY_REQUEST_SIZE |
153 	 *   | KPRNG |     OPAQUE  ENTROPY     |
154 	 *   | 00000 |     OPAQUE  ENTROPY     |
155 	 */
156 	memcpy(kprngseed, bootloader_rand, SEED_SIZE);
157 	cc_clear(SEED_SIZE, bootloader_rand);
158 
159 	uint8_t native_rand[3 * SEED_SIZE];
160 	bootseed_init_native(sizeof(native_rand), native_rand);
161 
162 	const struct ccdigest_info *di = &ccsha512_ltc_di;
163 	assert3u(SEED_SIZE, <, di->block_size);
164 
165 	uint8_t zero_salt[SEED_SIZE] = {0};
166 	uint8_t combined_input[2 * SEED_SIZE];
167 
168 	// First subkey: bootloader_rand[64-127] || native_rand[0-63]
169 	memcpy(combined_input, &bootloader_rand[1 * SEED_SIZE], SEED_SIZE);
170 	memcpy(&combined_input[SEED_SIZE], &native_rand[0 * SEED_SIZE], SEED_SIZE);
171 	cchmac(di, SEED_SIZE, zero_salt, 2 * SEED_SIZE, combined_input, earlyseed);
172 
173 	// Second subkey: bootloader_rand[128-191] || native_rand[64-127]
174 	memcpy(combined_input, &bootloader_rand[2 * SEED_SIZE], SEED_SIZE);
175 	memcpy(&combined_input[SEED_SIZE], &native_rand[1 * SEED_SIZE], SEED_SIZE);
176 	cchmac(di, SEED_SIZE, zero_salt, 2 * SEED_SIZE, combined_input, entropyseed);
177 
178 	// Third subkey: bootloader_rand[192-255] || native_rand[128-191]
179 	memcpy(combined_input, &bootloader_rand[3 * SEED_SIZE], SEED_SIZE);
180 	memcpy(&combined_input[SEED_SIZE], &native_rand[2 * SEED_SIZE], SEED_SIZE);
181 	cchmac(di, SEED_SIZE, zero_salt, 2 * SEED_SIZE, combined_input, kprng_reseed);
182 
183 	cc_clear(sizeof(combined_input), combined_input);
184 
185 	cc_clear(BOOTLOADER_ENTROPY_REQUEST_SIZE, bootloader_rand);
186 	cc_clear(BOOTLOADER_ENTROPY_REQUEST_SIZE, native_rand);
187 }
188 
189 #define EARLY_RANDOM_STATE_STATIC_SIZE (264)
190 
191 static struct {
192 	uint8_t drbg_state[EARLY_RANDOM_STATE_STATIC_SIZE];
193 	struct ccdrbg_info drbg_info;
194 	const struct ccdrbg_nisthmac_custom drbg_custom;
195 } erandom = {.drbg_custom = {
196 		     .di         = &ccsha256_ltc_di,
197 		     .strictFIPS = 0,
198 	     }};
199 
200 __attribute__((noinline))
201 static void
early_random_init(void)202 early_random_init(void)
203 {
204 	uint64_t nonce;
205 	int rc;
206 	const char ps[] = "xnu early random";
207 
208 	bootseed_init();
209 
210 	/* Init DRBG for NIST HMAC */
211 	ccdrbg_factory_nisthmac(&erandom.drbg_info, &erandom.drbg_custom);
212 	assert3u(erandom.drbg_info.size, <=, sizeof(erandom.drbg_state));
213 
214 	/*
215 	 * Init our DBRG from the boot entropy and a timestamp as nonce
216 	 * and the cpu number as personalization.
217 	 */
218 	assert3u(sizeof(earlyseed), >, sizeof(nonce));
219 	nonce = ml_get_timebase();
220 	rc = ccdrbg_init(&erandom.drbg_info, (struct ccdrbg_state *)erandom.drbg_state, sizeof(earlyseed), earlyseed, sizeof(nonce), &nonce, sizeof(ps) - 1, ps);
221 	if (rc != CCDRBG_STATUS_OK) {
222 		panic("ccdrbg_init() returned %d", rc);
223 	}
224 
225 	cc_clear(sizeof(nonce), &nonce);
226 	cc_clear(sizeof(earlyseed), earlyseed);
227 }
228 
229 __static_testable void read_erandom(void * buf, size_t nbytes);
230 
231 /*
232  * Return a uniformly distributed 64-bit random number.
233  *
234  * This interface should have minimal dependencies on kernel services,
235  * and thus be available very early in the life of the kernel.
236  *
237  * This provides cryptographically secure randomness contingent on the
238  * quality of the seed. It is seeded (lazily) with entropy provided by
239  * the Booter.
240  *
241  * The implementation is a NIST HMAC-SHA256 DRBG instance used as
242  * follows:
243  *
244  *  - When first called (on macOS this is very early while page tables
245  *    are being built) early_random() calls ccdrbg_factory_hmac() to
246  *    set-up a ccdbrg info structure.
247  *
248  *  - A 64-byte seed from the bootloader is hashed with HMAC-SHA512.
249  *    Where available, hardware RNG outputs are mixed into the seed.
250  *    (See bootseed_init.) The resulting seed is 64 bytes.
251  *
252  *  - The ccdrbg state structure is a statically allocated area which
253  *    is then initialized by calling the ccdbrg_init method. The
254  *    initial entropy is the 64-byte seed described above. The nonce
255  *    is an 8-byte timestamp from ml_get_timebase(). The
256  *    personalization data provided is a fixed string.
257  *
258  *  - 64-bit outputs are generated via read_erandom, a wrapper around
259  *    the ccdbrg_generate method. (Since "strict FIPS" is disabled,
260  *    the DRBG will never request a reseed.)
261  *
262  *  - After the kernel PRNG is initialized, read_erandom defers
263  *    generation to it via read_random_generate. (Note that this
264  *    function acquires a per-processor mutex.)
265  */
266 uint64_t
early_random(void)267 early_random(void)
268 {
269 	uint64_t result;
270 	static int init = 0;
271 
272 	if (__improbable(init == 0)) {
273 		early_random_init();
274 		init = 1;
275 	}
276 
277 	read_erandom(&result, sizeof(result));
278 
279 	return result;
280 }
281 
282 static void
283 read_random_generate(uint8_t *buffer, size_t numbytes);
284 
285 // This code is used only during early boot (until corecrypto kext is
286 // loaded), so it's better not to inline it.
287 __attribute__((noinline))
288 static void
read_erandom_generate(void * buf,size_t nbytes)289 read_erandom_generate(void * buf, size_t nbytes)
290 {
291 	uint8_t * buffer_bytes = buf;
292 	size_t n;
293 	int rc;
294 
295 	// The DBRG request size is limited, so we break the request into
296 	// chunks.
297 	while (nbytes > 0) {
298 		n = MIN(nbytes, PAGE_SIZE);
299 
300 		// Since "strict FIPS" is disabled, the DRBG will never
301 		// request a reseed; therefore, we panic on any error
302 		rc = ccdrbg_generate(&erandom.drbg_info, (struct ccdrbg_state *)erandom.drbg_state, n, buffer_bytes, 0, NULL);
303 		if (rc != CCDRBG_STATUS_OK) {
304 			panic("read_erandom ccdrbg error %d", rc);
305 		}
306 
307 		buffer_bytes += n;
308 		nbytes -= n;
309 	}
310 }
311 
312 __static_testable __mockable void
read_erandom(void * buf,size_t nbytes)313 read_erandom(void * buf, size_t nbytes)
314 {
315 	// We defer to the kernel PRNG after it has been installed and
316 	// initialized. This happens during corecrypto kext
317 	// initialization.
318 	if (__probable(prng_ready)) {
319 		read_random_generate(buf, nbytes);
320 	} else {
321 		read_erandom_generate(buf, nbytes);
322 	}
323 }
324 
325 void
read_frandom(void * buffer,u_int numBytes)326 read_frandom(void * buffer, u_int numBytes)
327 {
328 	read_erandom(buffer, numBytes);
329 }
330 
331 void
register_and_init_prng(struct cckprng_ctx * ctx,const struct cckprng_funcs * funcs)332 register_and_init_prng(struct cckprng_ctx *ctx, const struct cckprng_funcs *funcs)
333 {
334 	assert3s(cpu_number(), ==, master_cpu);
335 	assert(!prng_ready);
336 
337 	entropy_init(sizeof(entropyseed), entropyseed);
338 
339 	prng_ctx = ctx;
340 	prng_funcs = *funcs;
341 
342 	uint64_t nonce = ml_get_timebase();
343 	prng_funcs.init_with_getentropy(prng_ctx, MAX_CPUS, sizeof(kprngseed), kprngseed, sizeof(nonce), &nonce, entropy_provide, NULL);
344 	prng_funcs.initgen(prng_ctx, master_cpu);
345 	prng_ready = 1;
346 
347 	// Reseed with a key that has been securely combined with kernel-sourced platform randomness, where it was available.
348 	// Otherwise this is just more randomness from the bootloader.
349 	prng_funcs.reseed(prng_ctx, sizeof(kprng_reseed), kprng_reseed);
350 
351 	cc_clear(sizeof(entropyseed), entropyseed);
352 	cc_clear(sizeof(kprngseed), kprngseed);
353 	cc_clear(sizeof(kprng_reseed), kprng_reseed);
354 	cc_clear(sizeof(erandom), &erandom);
355 }
356 
357 void
random_cpu_init(int cpu)358 random_cpu_init(int cpu)
359 {
360 	assert3s(cpu, !=, master_cpu);
361 
362 	if (!prng_ready) {
363 		panic("random_cpu_init: kernel prng has not been installed");
364 	}
365 
366 	prng_funcs.initgen(prng_ctx, cpu);
367 }
368 
369 /* export good random numbers to the rest of the kernel */
370 __mockable void
read_random(void * buffer,u_int numbytes)371 read_random(void * buffer, u_int numbytes)
372 {
373 	prng_funcs.refresh(prng_ctx);
374 	read_random_generate(buffer, numbytes);
375 }
376 
377 static void
ensure_gsbase(void)378 ensure_gsbase(void)
379 {
380 #if defined(__x86_64__) && (DEVELOPMENT || DEBUG)
381 	/*
382 	 * Calling cpu_number() before gsbase is initialized is potentially
383 	 * catastrophic, so assert that it's not set to the magic value set
384 	 * in i386_init.c before proceeding with the call.  We cannot use
385 	 * assert here because it ultimately calls panic, which executes
386 	 * operations that involve accessing %gs-relative data (and additionally
387 	 * causes a debug trap which will not work properly this early in boot.)
388 	 */
389 	if (rdmsr64(MSR_IA32_GS_BASE) == EARLY_GSBASE_MAGIC) {
390 		kprintf("[early_random] Cannot proceed: GSBASE is not initialized\n");
391 		hlt();
392 		/*NOTREACHED*/
393 	}
394 #endif
395 }
396 
397 static void
read_random_generate(uint8_t * buffer,size_t numbytes)398 read_random_generate(uint8_t *buffer, size_t numbytes)
399 {
400 	ensure_gsbase();
401 
402 	while (numbytes > 0) {
403 		size_t n = MIN(numbytes, CCKPRNG_GENERATE_MAX_NBYTES);
404 
405 		prng_funcs.generate(prng_ctx, cpu_number(), n, buffer);
406 
407 		buffer += n;
408 		numbytes -= n;
409 	}
410 }
411 
412 int
write_random(void * buffer,u_int numbytes)413 write_random(void * buffer, u_int numbytes)
414 {
415 	/*
416 	 * The reseed function requires at least 16 bytes of input entropy,
417 	 * hence we always pass the entire seed below, even if it isn't "full".
418 	 */
419 	uint8_t seed[SHA512_DIGEST_LENGTH] = {0};
420 
421 	if (numbytes > SHA512_DIGEST_LENGTH) {
422 		/* hash the input to minimize the time we need to hold the lock */
423 		SHA512_CTX ctx;
424 		SHA512_Init(&ctx);
425 		SHA512_Update(&ctx, buffer, numbytes);
426 		SHA512_Final(seed, &ctx);
427 	} else {
428 		memcpy(seed, buffer, numbytes);
429 	}
430 
431 	prng_funcs.reseed(prng_ctx, sizeof(seed), seed);
432 	cc_clear(sizeof(seed), seed);
433 
434 	return 0;
435 }
436 
437 /*
438  * Boolean PRNG for generating booleans to randomize order of elements
439  * in certain kernel data structures. The algorithm is a
440  * modified version of the KISS RNG proposed in the paper:
441  * http://stat.fsu.edu/techreports/M802.pdf
442  * The modifications have been documented in the technical paper
443  * paper from UCL:
444  * http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
445  */
446 
447 /* Initialize the PRNG structures. */
448 void
random_bool_init(struct bool_gen * bg)449 random_bool_init(struct bool_gen * bg)
450 {
451 	/* Seed the random boolean generator */
452 	read_frandom(bg->seed, sizeof(bg->seed));
453 	bg->state = 0;
454 	simple_lock_init(&bg->lock, 0);
455 }
456 
457 /* Generate random bits and add them to an entropy pool. */
458 void
random_bool_gen_entropy(struct bool_gen * bg,unsigned int * buffer,int count)459 random_bool_gen_entropy(struct bool_gen * bg, unsigned int * buffer, int count)
460 {
461 	simple_lock(&bg->lock, LCK_GRP_NULL);
462 	int i, t;
463 	for (i = 0; i < count; i++) {
464 		bg->seed[1] ^= (bg->seed[1] << 5);
465 		bg->seed[1] ^= (bg->seed[1] >> 7);
466 		bg->seed[1] ^= (bg->seed[1] << 22);
467 		t           = bg->seed[2] + bg->seed[3] + bg->state;
468 		bg->seed[2] = bg->seed[3];
469 		bg->state   = t < 0;
470 		bg->seed[3] = t & 2147483647;
471 		bg->seed[0] += 1411392427;
472 		buffer[i] = (bg->seed[0] + bg->seed[1] + bg->seed[3]);
473 	}
474 	simple_unlock(&bg->lock);
475 }
476 
477 /* Get some number of bits from the entropy pool, refilling if necessary. */
478 unsigned int
random_bool_gen_bits(struct bool_gen * bg,unsigned int * buffer,unsigned int count,unsigned int numbits)479 random_bool_gen_bits(struct bool_gen * bg, unsigned int * buffer, unsigned int count, unsigned int numbits)
480 {
481 	unsigned int index = 0;
482 	unsigned int rbits = 0;
483 	for (unsigned int bitct = 0; bitct < numbits; bitct++) {
484 		/*
485 		 * Find a portion of the buffer that hasn't been emptied.
486 		 * We might have emptied our last index in the previous iteration.
487 		 */
488 		while (index < count && buffer[index] == 0) {
489 			index++;
490 		}
491 
492 		/* If we've exhausted the pool, refill it. */
493 		if (index == count) {
494 			random_bool_gen_entropy(bg, buffer, count);
495 			index = 0;
496 		}
497 
498 		/* Collect-a-bit */
499 		unsigned int bit = buffer[index] & 1;
500 		buffer[index]    = buffer[index] >> 1;
501 		rbits            = bit | (rbits << 1);
502 	}
503 	return rbits;
504 }
505