xref: /xnu-12377.41.6/osfmk/prng/prng_random.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
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/cchkdf.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 (SHA256_BLOCK_LENGTH)
52 
53 // Seed sizes meant to trigger a compression in the underlying hash function
54 static uint8_t earlyseed[SEED_SIZE];
55 static uint8_t prngseed[SEED_SIZE];
56 static uint8_t entropyseed[SHA512_BLOCK_LENGTH];
57 
58 // Instructions for deriving the above seeds
59 typedef struct dsp {
60 	size_t info_size;
61 	size_t dst_size;
62 	void *info;
63 	void *dst;
64 } derived_seed_param;
65 
66 // These are HKDF-Expand parameters for derived seeds. To add a new one, add a new struct here.
67 static derived_seed_param seed_params[] = {
68 	{
69 		.info = "bootseed_init",
70 		.info_size = 14,
71 		.dst = earlyseed,
72 		.dst_size = sizeof(earlyseed)
73 	},
74 	{
75 		.info = "prngseed_init",
76 		.info_size = 14,
77 		.dst = prngseed,
78 		.dst_size = sizeof(prngseed)
79 	},
80 	{
81 		.info = "entropy_init",
82 		.info_size = 13,
83 		.dst = entropyseed,
84 		.dst_size = sizeof(entropyseed)
85 	}
86 };
87 
88 // Hash the seed to ensure uniformity. But we have a limited-size digest available, so we make two invocations:
89 // out[0:SHA256_DIGEST_LENGTH]          = H(seed || 0)
90 // out[SHA256_DIGEST_LENGTH:SEED_SIZE]  = H(seed || 1)
91 static void
wide_hash(const struct ccdigest_info * di,uint8_t * dst,uint8_t * src)92 wide_hash(const struct ccdigest_info *di, uint8_t *dst, uint8_t *src)
93 {
94 	uint8_t counter;
95 	ccdigest_di_decl(di, ectx_left);
96 	ccdigest_init(di, ectx_left);
97 	ccdigest_update(di, ectx_left, SEED_SIZE, src);
98 	ccdigest_di_decl(di, ectx_right);
99 	ccdigest_copy_state(di, ectx_right, ectx_left);
100 
101 	counter = 0;
102 	ccdigest_update(di, ectx_left, sizeof(counter), &counter);
103 	ccdigest_final(di, ectx_left, dst);
104 
105 	counter = 1;
106 	ccdigest_update(di, ectx_right, sizeof(counter), &counter);
107 	ccdigest_final(di, ectx_right, &dst[SEED_SIZE / 2]);
108 
109 	ccdigest_di_clear(di, ectx_left);
110 	ccdigest_di_clear(di, ectx_right);
111 }
112 
113 static void
bootseed_init_bootloader(const struct ccdigest_info * di,uint8_t * dst)114 bootseed_init_bootloader(const struct ccdigest_info *di, uint8_t *dst)
115 {
116 	uint8_t seed[SEED_SIZE];
117 	uint32_t n;
118 
119 	n = PE_get_random_seed(seed, SEED_SIZE);
120 	if (n < SEED_SIZE) {
121 		/*
122 		 * Insufficient entropy is fatal.  We must fill the
123 		 * entire entropy buffer during initializaton.
124 		 */
125 		panic("Expected %u seed bytes from bootloader, but got %u.", SEED_SIZE, n);
126 	}
127 
128 	wide_hash(di, dst, seed);
129 	cc_clear(SEED_SIZE, seed);
130 }
131 
132 #if defined(__x86_64__)
133 #include <i386/cpuid.h>
134 
135 static void
bootseed_init_native(const struct ccdigest_info * di,uint8_t * dst)136 bootseed_init_native(const struct ccdigest_info *di, uint8_t *dst)
137 {
138 	uint8_t seed[SEED_SIZE];
139 	uint64_t x;
140 	uint8_t ok;
141 	size_t i = 0;
142 	size_t n;
143 
144 	if (cpuid_leaf7_features() & CPUID_LEAF7_FEATURE_RDSEED) {
145 		n = SEED_SIZE / sizeof(x);
146 
147 		while (i < n) {
148 			asm volatile ("rdseed %0; setc %1" : "=r"(x), "=qm"(ok) : : "cc");
149 			if (ok) {
150 				cc_memcpy(&seed[i * sizeof(x)], &x, sizeof(x));
151 				i += 1;
152 			} else {
153 				// Intel recommends to pause between unsuccessful rdseed attempts.
154 				cpu_pause();
155 			}
156 		}
157 	} else if (cpuid_features() & CPUID_FEATURE_RDRAND) {
158 		// The Intel documentation guarantees a reseed every 512 rdrand calls.
159 		n = (SEED_SIZE / sizeof(x)) * 512;
160 
161 		while (i < n) {
162 			asm volatile ("rdrand %0; setc %1" : "=r"(x), "=qm"(ok) : : "cc");
163 			if (ok) {
164 				if (i % 512 == 0) {
165 					cc_memcpy(&dst[(i / 512) * sizeof(x)], &x, sizeof(x));
166 				}
167 				i += 1;
168 			} else {
169 				// Intel does not recommend pausing between unsuccessful rdrand attempts.
170 			}
171 		}
172 	}
173 
174 	wide_hash(di, dst, seed);
175 	cc_clear(SEED_SIZE, seed);
176 	cc_clear(sizeof(x), &x);
177 }
178 
179 #else
180 
181 static void
bootseed_init_native(__unused const struct ccdigest_info * di,uint8_t * dst)182 bootseed_init_native(__unused const struct ccdigest_info *di, uint8_t *dst)
183 {
184 	// Even if we don't have any input, the second input needs to be a fixed input of the same size
185 	// to maintain dual-PRF security for HKDF/HMAC. All zero is fine as long as it is fixed.
186 	cc_clear(SEED_SIZE, dst);
187 }
188 
189 #endif
190 
191 static void
bootseed_init(void)192 bootseed_init(void)
193 {
194 	/*
195 	 *  This is a key combiner. HKDF provides dual-PRF security as long as we sample inputs
196 	 *  from a set of fixed-length, uniformly random inputs. Ideally those inputs will also
197 	 *  be the block size of the underlying digest, which we specify here with SEED_SIZE.
198 	 *
199 	 *  See https://eprint.iacr.org/2023/861 for proof details. The overall construction goes:
200 	 *
201 	 *       H* : {0, 1}* -> {0, 1}^c where c is the block size of the digest underlying HKDF, here 64.
202 	 *       n are long enough to require a compression in the underlying hash function.
203 	 *       prk = HKDF-Extract(H*(bootloader), H*(native))
204 	 *       earlyseed = HKDF-Expand(prk, "bootseed_init", n1)
205 	 *       prngseed = HKDF-Expand(prk, "prngseed_init", n2)
206 	 *		 entropyseed = HKDF-Expand(prk, "entropy_init", n3)
207 	 *
208 	 */
209 
210 	const struct ccdigest_info * di = &ccsha256_ltc_di;
211 	assert3u(SEED_SIZE, ==, di->block_size);
212 
213 	uint8_t bootloader_rand[SEED_SIZE];
214 	uint8_t native_rand[SEED_SIZE];
215 	uint8_t prk[SHA256_DIGEST_LENGTH];
216 
217 	// Sample the two input seeds from the devicetree and any available RDRAND instructions
218 	bootseed_init_bootloader(di, bootloader_rand);
219 	bootseed_init_native(di, native_rand);
220 
221 	// Combine the input seeds into one root seed of size di->output_size. Eventually we want to use a larger digest here:
222 	// rdar://119642787 (Move boot seed derivations to a digest that preserves the full width of the devicetree seed)
223 	int result = cchkdf_extract(di, SEED_SIZE, native_rand, SEED_SIZE, bootloader_rand, prk);
224 	if (result != CCERR_OK) {
225 		panic("Early boot random cchkdf_extract failed with err %d", result);
226 	}
227 
228 	// Derive independent keys for each subsystem
229 	int seeds_expected = sizeof(seed_params) / sizeof(seed_params[0]);
230 	for (int i = 0; i < seeds_expected; i++) {
231 		derived_seed_param sp = seed_params[i];
232 		result = cchkdf_expand(di, di->output_size, prk, sp.info_size, sp.info, sp.dst_size, sp.dst);
233 		if (result != CCERR_OK) {
234 			panic("Early boot random cchkdf_expand %s failed with err %d", sp.info, result);
235 		}
236 	}
237 
238 	cc_clear(di->output_size, prk);
239 	cc_clear(SEED_SIZE, bootloader_rand);
240 	cc_clear(SEED_SIZE, native_rand);
241 }
242 
243 #define EARLY_RANDOM_STATE_STATIC_SIZE (264)
244 
245 static struct {
246 	uint8_t drbg_state[EARLY_RANDOM_STATE_STATIC_SIZE];
247 	struct ccdrbg_info drbg_info;
248 	const struct ccdrbg_nisthmac_custom drbg_custom;
249 } erandom = {.drbg_custom = {
250 		     .di         = &ccsha256_ltc_di,
251 		     .strictFIPS = 0,
252 	     }};
253 
254 __attribute__((noinline))
255 static void
early_random_init(void)256 early_random_init(void)
257 {
258 	uint64_t nonce;
259 	int rc;
260 	const char ps[] = "xnu early random";
261 
262 	bootseed_init();
263 
264 	/* Init DRBG for NIST HMAC */
265 	ccdrbg_factory_nisthmac(&erandom.drbg_info, &erandom.drbg_custom);
266 	assert3u(erandom.drbg_info.size, <=, sizeof(erandom.drbg_state));
267 
268 	/*
269 	 * Init our DBRG from the boot entropy and a timestamp as nonce
270 	 * and the cpu number as personalization.
271 	 */
272 	assert3u(sizeof(earlyseed), >, sizeof(nonce));
273 	nonce = ml_get_timebase();
274 	rc = ccdrbg_init(&erandom.drbg_info, (struct ccdrbg_state *)erandom.drbg_state, sizeof(earlyseed), earlyseed, sizeof(nonce), &nonce, sizeof(ps) - 1, ps);
275 	if (rc != CCDRBG_STATUS_OK) {
276 		panic("ccdrbg_init() returned %d", rc);
277 	}
278 
279 	cc_clear(sizeof(nonce), &nonce);
280 	cc_clear(sizeof(earlyseed), earlyseed);
281 }
282 
283 __static_testable void read_erandom(void * buf, size_t nbytes);
284 
285 /*
286  * Return a uniformly distributed 64-bit random number.
287  *
288  * This interface should have minimal dependencies on kernel services,
289  * and thus be available very early in the life of the kernel.
290  *
291  * This provides cryptographically secure randomness contingent on the
292  * quality of the seed. It is seeded (lazily) with entropy provided by
293  * the Booter.
294  *
295  * The implementation is a NIST HMAC-SHA256 DRBG instance used as
296  * follows:
297  *
298  *  - When first called (on macOS this is very early while page tables
299  *    are being built) early_random() calls ccdrbg_factory_hmac() to
300  *    set-up a ccdbrg info structure.
301  *
302  *  - The boot seed (64 bytes) is hashed with a SHA256-based wide hash
303  *    construction. Where available, hardware RNG outputs are mixed
304  *    into the seed. (See bootseed_init.) The resulting seed is 64
305  *    bytes.
306  *
307  *  - The ccdrbg state structure is a statically allocated area which
308  *    is then initialized by calling the ccdbrg_init method. The
309  *    initial entropy is the 32-byte seed described above. The nonce
310  *    is an 8-byte timestamp from ml_get_timebase(). The
311  *    personalization data provided is a fixed string.
312  *
313  *  - 64-bit outputs are generated via read_erandom, a wrapper around
314  *    the ccdbrg_generate method. (Since "strict FIPS" is disabled,
315  *    the DRBG will never request a reseed.)
316  *
317  *  - After the kernel PRNG is initialized, read_erandom defers
318  *    generation to it via read_random_generate. (Note that this
319  *    function acquires a per-processor mutex.)
320  */
321 uint64_t
early_random(void)322 early_random(void)
323 {
324 	uint64_t result;
325 	static int init = 0;
326 
327 	if (__improbable(init == 0)) {
328 		early_random_init();
329 		init = 1;
330 	}
331 
332 	read_erandom(&result, sizeof(result));
333 
334 	return result;
335 }
336 
337 static void
338 read_random_generate(uint8_t *buffer, size_t numbytes);
339 
340 // This code is used only during early boot (until corecrypto kext is
341 // loaded), so it's better not to inline it.
342 __attribute__((noinline))
343 static void
read_erandom_generate(void * buf,size_t nbytes)344 read_erandom_generate(void * buf, size_t nbytes)
345 {
346 	uint8_t * buffer_bytes = buf;
347 	size_t n;
348 	int rc;
349 
350 	// The DBRG request size is limited, so we break the request into
351 	// chunks.
352 	while (nbytes > 0) {
353 		n = MIN(nbytes, PAGE_SIZE);
354 
355 		// Since "strict FIPS" is disabled, the DRBG will never
356 		// request a reseed; therefore, we panic on any error
357 		rc = ccdrbg_generate(&erandom.drbg_info, (struct ccdrbg_state *)erandom.drbg_state, n, buffer_bytes, 0, NULL);
358 		if (rc != CCDRBG_STATUS_OK) {
359 			panic("read_erandom ccdrbg error %d", rc);
360 		}
361 
362 		buffer_bytes += n;
363 		nbytes -= n;
364 	}
365 }
366 
367 __static_testable __mockable void
read_erandom(void * buf,size_t nbytes)368 read_erandom(void * buf, size_t nbytes)
369 {
370 	// We defer to the kernel PRNG after it has been installed and
371 	// initialized. This happens during corecrypto kext
372 	// initialization.
373 	if (__probable(prng_ready)) {
374 		read_random_generate(buf, nbytes);
375 	} else {
376 		read_erandom_generate(buf, nbytes);
377 	}
378 }
379 
380 void
read_frandom(void * buffer,u_int numBytes)381 read_frandom(void * buffer, u_int numBytes)
382 {
383 	read_erandom(buffer, numBytes);
384 }
385 
386 void
register_and_init_prng(struct cckprng_ctx * ctx,const struct cckprng_funcs * funcs)387 register_and_init_prng(struct cckprng_ctx *ctx, const struct cckprng_funcs *funcs)
388 {
389 	assert3s(cpu_number(), ==, master_cpu);
390 	assert(!prng_ready);
391 
392 	entropy_init(sizeof(entropyseed), entropyseed);
393 
394 	prng_ctx = ctx;
395 	prng_funcs = *funcs;
396 
397 	uint64_t nonce = ml_get_timebase();
398 	prng_funcs.init_with_getentropy(prng_ctx, MAX_CPUS, sizeof(prngseed), prngseed, sizeof(nonce), &nonce, entropy_provide, NULL);
399 	prng_funcs.initgen(prng_ctx, master_cpu);
400 	prng_ready = 1;
401 
402 	cc_clear(sizeof(entropyseed), entropyseed);
403 	cc_clear(sizeof(prngseed), prngseed);
404 	cc_clear(sizeof(erandom), &erandom);
405 }
406 
407 void
random_cpu_init(int cpu)408 random_cpu_init(int cpu)
409 {
410 	assert3s(cpu, !=, master_cpu);
411 
412 	if (!prng_ready) {
413 		panic("random_cpu_init: kernel prng has not been installed");
414 	}
415 
416 	prng_funcs.initgen(prng_ctx, cpu);
417 }
418 
419 /* export good random numbers to the rest of the kernel */
420 __mockable void
read_random(void * buffer,u_int numbytes)421 read_random(void * buffer, u_int numbytes)
422 {
423 	prng_funcs.refresh(prng_ctx);
424 	read_random_generate(buffer, numbytes);
425 }
426 
427 static void
ensure_gsbase(void)428 ensure_gsbase(void)
429 {
430 #if defined(__x86_64__) && (DEVELOPMENT || DEBUG)
431 	/*
432 	 * Calling cpu_number() before gsbase is initialized is potentially
433 	 * catastrophic, so assert that it's not set to the magic value set
434 	 * in i386_init.c before proceeding with the call.  We cannot use
435 	 * assert here because it ultimately calls panic, which executes
436 	 * operations that involve accessing %gs-relative data (and additionally
437 	 * causes a debug trap which will not work properly this early in boot.)
438 	 */
439 	if (rdmsr64(MSR_IA32_GS_BASE) == EARLY_GSBASE_MAGIC) {
440 		kprintf("[early_random] Cannot proceed: GSBASE is not initialized\n");
441 		hlt();
442 		/*NOTREACHED*/
443 	}
444 #endif
445 }
446 
447 static void
read_random_generate(uint8_t * buffer,size_t numbytes)448 read_random_generate(uint8_t *buffer, size_t numbytes)
449 {
450 	ensure_gsbase();
451 
452 	while (numbytes > 0) {
453 		size_t n = MIN(numbytes, CCKPRNG_GENERATE_MAX_NBYTES);
454 
455 		prng_funcs.generate(prng_ctx, cpu_number(), n, buffer);
456 
457 		buffer += n;
458 		numbytes -= n;
459 	}
460 }
461 
462 int
write_random(void * buffer,u_int numbytes)463 write_random(void * buffer, u_int numbytes)
464 {
465 	/*
466 	 * The reseed function requires at least 16 bytes of input entropy,
467 	 * hence we always pass the entire seed below, even if it isn't "full".
468 	 */
469 	uint8_t seed[SHA512_DIGEST_LENGTH] = {0};
470 
471 	if (numbytes > SHA512_DIGEST_LENGTH) {
472 		/* hash the input to minimize the time we need to hold the lock */
473 		SHA512_CTX ctx;
474 		SHA512_Init(&ctx);
475 		SHA512_Update(&ctx, buffer, numbytes);
476 		SHA512_Final(seed, &ctx);
477 	} else {
478 		memcpy(seed, buffer, numbytes);
479 	}
480 
481 	prng_funcs.reseed(prng_ctx, sizeof(seed), seed);
482 	cc_clear(sizeof(seed), seed);
483 
484 	return 0;
485 }
486 
487 /*
488  * Boolean PRNG for generating booleans to randomize order of elements
489  * in certain kernel data structures. The algorithm is a
490  * modified version of the KISS RNG proposed in the paper:
491  * http://stat.fsu.edu/techreports/M802.pdf
492  * The modifications have been documented in the technical paper
493  * paper from UCL:
494  * http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
495  */
496 
497 /* Initialize the PRNG structures. */
498 void
random_bool_init(struct bool_gen * bg)499 random_bool_init(struct bool_gen * bg)
500 {
501 	/* Seed the random boolean generator */
502 	read_frandom(bg->seed, sizeof(bg->seed));
503 	bg->state = 0;
504 	simple_lock_init(&bg->lock, 0);
505 }
506 
507 /* Generate random bits and add them to an entropy pool. */
508 void
random_bool_gen_entropy(struct bool_gen * bg,unsigned int * buffer,int count)509 random_bool_gen_entropy(struct bool_gen * bg, unsigned int * buffer, int count)
510 {
511 	simple_lock(&bg->lock, LCK_GRP_NULL);
512 	int i, t;
513 	for (i = 0; i < count; i++) {
514 		bg->seed[1] ^= (bg->seed[1] << 5);
515 		bg->seed[1] ^= (bg->seed[1] >> 7);
516 		bg->seed[1] ^= (bg->seed[1] << 22);
517 		t           = bg->seed[2] + bg->seed[3] + bg->state;
518 		bg->seed[2] = bg->seed[3];
519 		bg->state   = t < 0;
520 		bg->seed[3] = t & 2147483647;
521 		bg->seed[0] += 1411392427;
522 		buffer[i] = (bg->seed[0] + bg->seed[1] + bg->seed[3]);
523 	}
524 	simple_unlock(&bg->lock);
525 }
526 
527 /* Get some number of bits from the entropy pool, refilling if necessary. */
528 unsigned int
random_bool_gen_bits(struct bool_gen * bg,unsigned int * buffer,unsigned int count,unsigned int numbits)529 random_bool_gen_bits(struct bool_gen * bg, unsigned int * buffer, unsigned int count, unsigned int numbits)
530 {
531 	unsigned int index = 0;
532 	unsigned int rbits = 0;
533 	for (unsigned int bitct = 0; bitct < numbits; bitct++) {
534 		/*
535 		 * Find a portion of the buffer that hasn't been emptied.
536 		 * We might have emptied our last index in the previous iteration.
537 		 */
538 		while (index < count && buffer[index] == 0) {
539 			index++;
540 		}
541 
542 		/* If we've exhausted the pool, refill it. */
543 		if (index == count) {
544 			random_bool_gen_entropy(bg, buffer, count);
545 			index = 0;
546 		}
547 
548 		/* Collect-a-bit */
549 		unsigned int bit = buffer[index] & 1;
550 		buffer[index]    = buffer[index] >> 1;
551 		rbits            = bit | (rbits << 1);
552 	}
553 	return rbits;
554 }
555