]> git.saurik.com Git - apple/xnu.git/blob - osfmk/prng/prng_random.c
31a59996b3c31e3af245a3d125eba747fa4ada43
[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/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/ccdrbg.h>
41 #include <corecrypto/cckprng.h>
42 #include <corecrypto/ccsha2.h>
43
44 static struct cckprng_ctx *prng_ctx;
45
46 static SECURITY_READ_ONLY_LATE(struct cckprng_funcs) prng_funcs;
47 static SECURITY_READ_ONLY_LATE(int) prng_ready;
48
49 extern entropy_data_t EntropyData;
50
51 #define SEED_SIZE (SHA256_DIGEST_LENGTH)
52 static uint8_t bootseed[SEED_SIZE];
53
54 static void
55 bootseed_init_bootloader(const struct ccdigest_info * di, ccdigest_ctx_t ctx)
56 {
57 uint8_t seed[64];
58 uint32_t n;
59
60 n = PE_get_random_seed(seed, sizeof(seed));
61 if (n < sizeof(seed)) {
62 /*
63 * Insufficient entropy is fatal. We must fill the
64 * entire entropy buffer during initializaton.
65 */
66 panic("Expected %lu seed bytes from bootloader, but got %u.\n", sizeof(seed), n);
67 }
68
69 ccdigest_update(di, ctx, sizeof(seed), seed);
70 cc_clear(sizeof(seed), seed);
71 }
72
73 #if defined(__x86_64__)
74 #include <i386/cpuid.h>
75
76 static void
77 bootseed_init_native(const struct ccdigest_info * di, ccdigest_ctx_t ctx)
78 {
79 uint64_t x;
80 uint8_t ok;
81 size_t i = 0;
82 size_t n;
83
84 if (cpuid_leaf7_features() & CPUID_LEAF7_FEATURE_RDSEED) {
85 n = SEED_SIZE / sizeof(x);
86
87 while (i < n) {
88 asm volatile ("rdseed %0; setc %1" : "=r"(x), "=qm"(ok) : : "cc");
89 if (ok) {
90 ccdigest_update(di, ctx, sizeof(x), &x);
91 i += 1;
92 } else {
93 // Intel recommends to pause between unsuccessful rdseed attempts.
94 cpu_pause();
95 }
96 }
97 } else if (cpuid_features() & CPUID_FEATURE_RDRAND) {
98 // The Intel documentation guarantees a reseed every 512 rdrand calls.
99 n = (SEED_SIZE / sizeof(x)) * 512;
100
101 while (i < n) {
102 asm volatile ("rdrand %0; setc %1" : "=r"(x), "=qm"(ok) : : "cc");
103 if (ok) {
104 ccdigest_update(di, ctx, sizeof(x), &x);
105 i += 1;
106 } else {
107 // Intel does not recommend pausing between unsuccessful rdrand attempts.
108 }
109 }
110 }
111
112 cc_clear(sizeof(x), &x);
113 }
114
115 #else
116
117 static void
118 bootseed_init_native(__unused const struct ccdigest_info * di, __unused ccdigest_ctx_t ctx)
119 {
120 }
121
122 #endif
123
124 static void
125 bootseed_init(void)
126 {
127 const struct ccdigest_info * di = &ccsha256_ltc_di;
128
129 ccdigest_di_decl(di, ctx);
130 ccdigest_init(di, ctx);
131
132 bootseed_init_bootloader(di, ctx);
133 bootseed_init_native(di, ctx);
134
135 ccdigest_final(di, ctx, bootseed);
136 ccdigest_di_clear(di, ctx);
137 }
138
139 #define EARLY_RANDOM_STATE_STATIC_SIZE (264)
140
141 static struct {
142 uint8_t drbg_state[EARLY_RANDOM_STATE_STATIC_SIZE];
143 struct ccdrbg_info drbg_info;
144 const struct ccdrbg_nisthmac_custom drbg_custom;
145 } erandom = {.drbg_custom = {
146 .di = &ccsha256_ltc_di,
147 .strictFIPS = 0,
148 }};
149
150 static void read_erandom(void * buf, size_t nbytes);
151
152 /*
153 * Return a uniformly distributed 64-bit random number.
154 *
155 * This interface should have minimal dependencies on kernel services,
156 * and thus be available very early in the life of the kernel.
157 *
158 * This provides cryptographically secure randomness contingent on the
159 * quality of the seed. It is seeded (lazily) with entropy provided by
160 * the Booter.
161 *
162 * The implementation is a NIST HMAC-SHA256 DRBG instance used as
163 * follows:
164 *
165 * - When first called (on macOS this is very early while page tables
166 * are being built) early_random() calls ccdrbg_factory_hmac() to
167 * set-up a ccdbrg info structure.
168 *
169 * - The boot seed (64 bytes) is hashed with SHA256. Where available,
170 * hardware RNG outputs are mixed into the seed. (See
171 * bootseed_init.) The resulting seed is 32 bytes.
172 *
173 * - The ccdrbg state structure is a statically allocated area which
174 * is then initialized by calling the ccdbrg_init method. The
175 * initial entropy is the 32-byte seed described above. The nonce
176 * is an 8-byte timestamp from ml_get_timebase(). The
177 * personalization data provided is a fixed string.
178 *
179 * - 64-bit outputs are generated via read_erandom, a wrapper around
180 * the ccdbrg_generate method. (Since "strict FIPS" is disabled,
181 * the DRBG will never request a reseed.)
182 *
183 * - After the kernel PRNG is initialized, read_erandom defers
184 * generation to it via read_random_generate. (Note that this
185 * function acquires a per-processor mutex.)
186 */
187 uint64_t
188 early_random(void)
189 {
190 uint64_t result;
191 uint64_t nonce;
192 int rc;
193 const char ps[] = "xnu early random";
194 static int init = 0;
195
196 if (init == 0) {
197 bootseed_init();
198
199 /* Init DRBG for NIST HMAC */
200 ccdrbg_factory_nisthmac(&erandom.drbg_info, &erandom.drbg_custom);
201 assert(erandom.drbg_info.size <= sizeof(erandom.drbg_state));
202
203 /*
204 * Init our DBRG from the boot entropy and a timestamp as nonce
205 * and the cpu number as personalization.
206 */
207 assert(sizeof(bootseed) > sizeof(nonce));
208 nonce = ml_get_timebase();
209 rc = ccdrbg_init(&erandom.drbg_info, (struct ccdrbg_state *)erandom.drbg_state, sizeof(bootseed), bootseed, sizeof(nonce), &nonce, sizeof(ps) - 1, ps);
210 if (rc != CCDRBG_STATUS_OK) {
211 panic("ccdrbg_init() returned %d", rc);
212 }
213
214 cc_clear(sizeof(nonce), &nonce);
215
216 init = 1;
217 }
218
219 read_erandom(&result, sizeof(result));
220
221 return result;
222 }
223
224 static void
225 read_random_generate(uint8_t *buffer, size_t numbytes);
226
227 static void
228 read_erandom(void * buf, size_t nbytes)
229 {
230 uint8_t * buffer_bytes = buf;
231 size_t n;
232 int rc;
233
234 // We defer to the kernel PRNG after it has been installed and
235 // initialized. This happens during corecrypto kext
236 // initialization.
237 if (prng_ready) {
238 read_random_generate(buf, nbytes);
239 return;
240 }
241
242 // The DBRG request size is limited, so we break the request into
243 // chunks.
244 while (nbytes > 0) {
245 n = MIN(nbytes, PAGE_SIZE);
246
247 // Since "strict FIPS" is disabled, the DRBG will never
248 // request a reseed; therefore, we panic on any error
249 rc = ccdrbg_generate(&erandom.drbg_info, (struct ccdrbg_state *)erandom.drbg_state, n, buffer_bytes, 0, NULL);
250 if (rc != CCDRBG_STATUS_OK) {
251 panic("read_erandom ccdrbg error %d\n", rc);
252 }
253
254 buffer_bytes += n;
255 nbytes -= n;
256 }
257 }
258
259 void
260 read_frandom(void * buffer, u_int numBytes)
261 {
262 read_erandom(buffer, numBytes);
263 }
264
265 void
266 register_and_init_prng(struct cckprng_ctx *ctx, const struct cckprng_funcs *funcs)
267 {
268 assert(cpu_number() == master_cpu);
269 assert(!prng_ready);
270
271 entropy_buffer_init();
272
273 prng_ctx = ctx;
274 prng_funcs = *funcs;
275
276 uint64_t nonce = ml_get_timebase();
277 prng_funcs.init(prng_ctx, MAX_CPUS, EntropyData.buffer_size, EntropyData.buffer, &EntropyData.sample_count, sizeof(bootseed), bootseed, sizeof(nonce), &nonce);
278 prng_funcs.initgen(prng_ctx, master_cpu);
279 prng_ready = 1;
280
281 cc_clear(sizeof(bootseed), bootseed);
282 cc_clear(sizeof(erandom), &erandom);
283 }
284
285 void
286 random_cpu_init(int cpu)
287 {
288 assert(cpu != master_cpu);
289
290 if (!prng_ready) {
291 panic("random_cpu_init: kernel prng has not been installed");
292 }
293
294 prng_funcs.initgen(prng_ctx, cpu);
295 }
296
297 /* export good random numbers to the rest of the kernel */
298 void
299 read_random(void * buffer, u_int numbytes)
300 {
301 prng_funcs.refresh(prng_ctx);
302 read_random_generate(buffer, numbytes);
303 }
304
305 static void
306 ensure_gsbase(void)
307 {
308 #if defined(__x86_64__) && (DEVELOPMENT || DEBUG)
309 /*
310 * Calling cpu_number() before gsbase is initialized is potentially
311 * catastrophic, so assert that it's not set to the magic value set
312 * in i386_init.c before proceeding with the call. We cannot use
313 * assert here because it ultimately calls panic, which executes
314 * operations that involve accessing %gs-relative data (and additionally
315 * causes a debug trap which will not work properly this early in boot.)
316 */
317 if (rdmsr64(MSR_IA32_GS_BASE) == EARLY_GSBASE_MAGIC) {
318 kprintf("[early_random] Cannot proceed: GSBASE is not initialized\n");
319 hlt();
320 /*NOTREACHED*/
321 }
322 #endif
323 }
324
325 static void
326 read_random_generate(uint8_t *buffer, size_t numbytes)
327 {
328 ensure_gsbase();
329
330 while (numbytes > 0) {
331 size_t n = MIN(numbytes, CCKPRNG_GENERATE_MAX_NBYTES);
332
333 prng_funcs.generate(prng_ctx, cpu_number(), n, buffer);
334
335 buffer += n;
336 numbytes -= n;
337 }
338 }
339
340 int
341 write_random(void * buffer, u_int numbytes)
342 {
343 uint8_t seed[SHA256_DIGEST_LENGTH];
344 SHA256_CTX ctx;
345
346 /* hash the input to minimize the time we need to hold the lock */
347 SHA256_Init(&ctx);
348 SHA256_Update(&ctx, buffer, numbytes);
349 SHA256_Final(seed, &ctx);
350
351 prng_funcs.reseed(prng_ctx, sizeof(seed), seed);
352 cc_clear(sizeof(seed), seed);
353
354 return 0;
355 }
356
357 /*
358 * Boolean PRNG for generating booleans to randomize order of elements
359 * in certain kernel data structures. The algorithm is a
360 * modified version of the KISS RNG proposed in the paper:
361 * http://stat.fsu.edu/techreports/M802.pdf
362 * The modifications have been documented in the technical paper
363 * paper from UCL:
364 * http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
365 */
366
367 /* Initialize the PRNG structures. */
368 void
369 random_bool_init(struct bool_gen * bg)
370 {
371 /* Seed the random boolean generator */
372 read_frandom(bg->seed, sizeof(bg->seed));
373 bg->state = 0;
374 simple_lock_init(&bg->lock, 0);
375 }
376
377 /* Generate random bits and add them to an entropy pool. */
378 void
379 random_bool_gen_entropy(struct bool_gen * bg, unsigned int * buffer, int count)
380 {
381 simple_lock(&bg->lock, LCK_GRP_NULL);
382 int i, t;
383 for (i = 0; i < count; i++) {
384 bg->seed[1] ^= (bg->seed[1] << 5);
385 bg->seed[1] ^= (bg->seed[1] >> 7);
386 bg->seed[1] ^= (bg->seed[1] << 22);
387 t = bg->seed[2] + bg->seed[3] + bg->state;
388 bg->seed[2] = bg->seed[3];
389 bg->state = t < 0;
390 bg->seed[3] = t & 2147483647;
391 bg->seed[0] += 1411392427;
392 buffer[i] = (bg->seed[0] + bg->seed[1] + bg->seed[3]);
393 }
394 simple_unlock(&bg->lock);
395 }
396
397 /* Get some number of bits from the entropy pool, refilling if necessary. */
398 unsigned int
399 random_bool_gen_bits(struct bool_gen * bg, unsigned int * buffer, unsigned int count, unsigned int numbits)
400 {
401 unsigned int index = 0;
402 unsigned int rbits = 0;
403 for (unsigned int bitct = 0; bitct < numbits; bitct++) {
404 /*
405 * Find a portion of the buffer that hasn't been emptied.
406 * We might have emptied our last index in the previous iteration.
407 */
408 while (index < count && buffer[index] == 0) {
409 index++;
410 }
411
412 /* If we've exhausted the pool, refill it. */
413 if (index == count) {
414 random_bool_gen_entropy(bg, buffer, count);
415 index = 0;
416 }
417
418 /* Collect-a-bit */
419 unsigned int bit = buffer[index] & 1;
420 buffer[index] = buffer[index] >> 1;
421 rbits = bit | (rbits << 1);
422 }
423 return rbits;
424 }